mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-02-20 10:54:14 +01:00
Merge branch 'next' into rvonlehe/OP-1740_UAV0_GetSetFunctionsTakeEnum
This commit is contained in:
commit
242d810c37
@ -53,11 +53,11 @@ void path_progress(PathDesiredData *path, float *cur_point, struct path_status *
|
||||
|
||||
break;
|
||||
case PATHDESIRED_MODE_CIRCLERIGHT:
|
||||
return path_circle(path, cur_point, status, mode3D);
|
||||
return path_circle(path, cur_point, status, true);
|
||||
|
||||
break;
|
||||
case PATHDESIRED_MODE_CIRCLELEFT:
|
||||
return path_circle(path, cur_point, status, mode3D);
|
||||
return path_circle(path, cur_point, status, false);
|
||||
|
||||
break;
|
||||
case PATHDESIRED_MODE_GOTOENDPOINT:
|
||||
|
@ -148,18 +148,23 @@ static void SettingsUpdatedCb(__attribute__((unused)) UAVObjEvent *ev)
|
||||
switch (TreatCustomCraftAs) {
|
||||
case VTOLPATHFOLLOWERSETTINGS_TREATCUSTOMCRAFTAS_FIXEDWING:
|
||||
frameType = FRAME_TYPE_FIXED_WING;
|
||||
mode3D = true;
|
||||
break;
|
||||
case VTOLPATHFOLLOWERSETTINGS_TREATCUSTOMCRAFTAS_VTOL:
|
||||
frameType = FRAME_TYPE_MULTIROTOR;
|
||||
mode3D = true;
|
||||
break;
|
||||
case VTOLPATHFOLLOWERSETTINGS_TREATCUSTOMCRAFTAS_GROUND:
|
||||
frameType = FRAME_TYPE_GROUND;
|
||||
mode3D = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (frameType) {
|
||||
case FRAME_TYPE_GROUND:
|
||||
mode3D = false;
|
||||
break;
|
||||
default:
|
||||
mode3D = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -300,7 +300,7 @@ static void receiverTask(__attribute__((unused)) void *parameters)
|
||||
settings.FlightModeNumber < 1 || settings.FlightModeNumber > FLIGHTMODESETTINGS_FLIGHTMODEPOSITION_NUMELEM
|
||||
||
|
||||
// Similar checks for FlightMode channel but only if more than one flight mode has been set. Otherwise don't care
|
||||
((settings.FlightModeNumber > 1)
|
||||
((settings.FlightModeNumber > 1) && (frameType != FRAME_TYPE_GROUND)
|
||||
&& (settings.ChannelGroups.FlightMode >= MANUALCONTROLSETTINGS_CHANNELGROUPS_NONE
|
||||
|| cmd.Channel[MANUALCONTROLSETTINGS_CHANNELGROUPS_FLIGHTMODE] == (uint16_t)PIOS_RCVR_INVALID
|
||||
|| cmd.Channel[MANUALCONTROLSETTINGS_CHANNELGROUPS_FLIGHTMODE] == (uint16_t)PIOS_RCVR_NODRIVER))) {
|
||||
|
@ -5,9 +5,31 @@ TEMPLATE = subdirs
|
||||
# Copy Qt runtime libraries into the build directory (to run or package)
|
||||
equals(copyqt, 1) {
|
||||
|
||||
GCS_LIBRARY_PATH
|
||||
# Copy QtQuick2 complete directories
|
||||
# Some of these directories have a lot of files
|
||||
# Easier to copy everything
|
||||
QT_QUICK2_DIRS = QtQuick/Controls \
|
||||
QtQuick/Dialogs \
|
||||
QtQuick/Layouts \
|
||||
QtQuick/LocalStorage \
|
||||
QtQuick/Particles.2 \
|
||||
QtQuick/PrivateWidgets \
|
||||
QtQuick/Window.2 \
|
||||
QtQuick/XmlListModel \
|
||||
QtQuick.2
|
||||
|
||||
linux-* {
|
||||
# create QtQuick directory
|
||||
data_copy.commands += -@$(MKDIR) $$targetPath(\"$$GCS_QT_QML_PATH/QtQuick\") $$addNewline()
|
||||
|
||||
for(dir, QT_QUICK2_DIRS) {
|
||||
data_copy.commands += @rm -rf $$targetPath(\"$$GCS_QT_QML_PATH/$$dir\") $$addNewline()
|
||||
data_copy.commands += $(COPY_DIR) $$targetPath(\"$$[QT_INSTALL_QML]/$$dir\") $$targetPath(\"$$GCS_QT_QML_PATH/$$dir\") $$addNewline()
|
||||
}
|
||||
|
||||
data_copy.target = FORCE
|
||||
QMAKE_EXTRA_TARGETS += data_copy
|
||||
|
||||
linux {
|
||||
|
||||
QT_LIBS = libQt5Core.so.5 \
|
||||
libQt5Gui.so.5 \
|
||||
@ -63,58 +85,6 @@ GCS_LIBRARY_PATH
|
||||
for(lib, QT_PLUGIN_LIBS) {
|
||||
data_copy.commands += $(COPY_FILE) $$targetPath(\"$$[QT_INSTALL_PLUGINS]/$$lib\") $$targetPath(\"$$GCS_QT_PLUGINS_PATH/$$lib\") $$addNewline()
|
||||
}
|
||||
|
||||
# create QtQuick2 plugin directories
|
||||
QT_QUICK2_DIRS = QtQuick \
|
||||
QtQuick.2 \
|
||||
QtQuick/Layouts \
|
||||
QtQuick/LocalStorage \
|
||||
QtQuick/Particles.2 \
|
||||
QtQuick/PrivateWidgets \
|
||||
QtQuick/Window.2 \
|
||||
QtQuick/XmlListModel
|
||||
for(dir, QT_QUICK2_DIRS) {
|
||||
data_copy.commands += -@$(MKDIR) $$targetPath(\"$$GCS_QT_QML_PATH/$$dir\") $$addNewline()
|
||||
}
|
||||
|
||||
# Copy QtQuick2 complete directories
|
||||
# These directories have a lot of files
|
||||
# Easier to copy everything
|
||||
QTQ_WHOLE_DIRS = QtQuick/Controls \
|
||||
QtQuick/Dialogs
|
||||
for(dir, QTQ_WHOLE_DIRS) {
|
||||
data_copy.commands += $(COPY_DIR) $$targetPath(\"$$[QT_INSTALL_QML]/$$dir\") $$targetPath(\"$$GCS_QT_QML_PATH/$$dir\") $$addNewline()
|
||||
}
|
||||
|
||||
# Remaining QtQuick plugin libs
|
||||
QT_QUICK2_DLLS = QtQuick.2/libqtquick2plugin.so \
|
||||
QtQuick.2/plugins.qmltypes \
|
||||
QtQuick.2/qmldir \
|
||||
QtQuick/Layouts/libqquicklayoutsplugin.so \
|
||||
QtQuick/Layouts/plugins.qmltypes \
|
||||
QtQuick/Layouts/qmldir \
|
||||
QtQuick/LocalStorage/libqmllocalstorageplugin.so \
|
||||
QtQuick/LocalStorage/plugins.qmltypes \
|
||||
QtQuick/LocalStorage/qmldir \
|
||||
QtQuick/Particles.2/libparticlesplugin.so \
|
||||
QtQuick/Particles.2/plugins.qmltypes \
|
||||
QtQuick/Particles.2/qmldir \
|
||||
QtQuick/PrivateWidgets/libwidgetsplugin.so \
|
||||
QtQuick/PrivateWidgets/plugins.qmltypes \
|
||||
QtQuick/PrivateWidgets/qmldir \
|
||||
QtQuick/Window.2/libwindowplugin.so \
|
||||
QtQuick/Window.2/plugins.qmltypes \
|
||||
QtQuick/Window.2/qmldir \
|
||||
QtQuick/XmlListModel/libqmlxmllistmodelplugin.so \
|
||||
QtQuick/XmlListModel/plugins.qmltypes \
|
||||
QtQuick/XmlListModel/qmldir
|
||||
|
||||
for(lib, QT_QUICK2_DLLS) {
|
||||
data_copy.commands += $(COPY_FILE) $$targetPath(\"$$[QT_INSTALL_QML]/$$lib\") $$targetPath(\"$$GCS_QT_QML_PATH/$$lib\") $$addNewline()
|
||||
}
|
||||
|
||||
data_copy.target = FORCE
|
||||
QMAKE_EXTRA_TARGETS += data_copy
|
||||
}
|
||||
|
||||
win32 {
|
||||
@ -179,55 +149,6 @@ GCS_LIBRARY_PATH
|
||||
data_copy.commands += $(COPY_FILE) $$targetPath(\"$$[QT_INSTALL_PLUGINS]/$$dll\") $$targetPath(\"$$GCS_APP_PATH/$$dll\") $$addNewline()
|
||||
}
|
||||
|
||||
# create QtQuick2 plugin directories
|
||||
QT_QUICK2_DIRS = qtquick \
|
||||
qtquick.2 \
|
||||
qtquick/layouts \
|
||||
qtquick/localstorage \
|
||||
qtquick/particles.2 \
|
||||
qtquick/privatewidgets \
|
||||
qtquick/window.2 \
|
||||
qtquick/xmllistmodel
|
||||
for(dir, QT_QUICK2_DIRS) {
|
||||
data_copy.commands += -@$(MKDIR) $$targetPath(\"$$GCS_APP_PATH/$$dir\") $$addNewline()
|
||||
}
|
||||
|
||||
# Copy QtQuick2 complete directories
|
||||
# These directories have a lot of files
|
||||
# Easier to copy everything
|
||||
QTQ_WHOLE_DIRS = qtquick/controls \
|
||||
qtquick/dialogs
|
||||
for(dir, QTQ_WHOLE_DIRS) {
|
||||
data_copy.commands += $(COPY_DIR) $$targetPath(\"$$[QT_INSTALL_QML]/$$dir\") $$targetPath(\"$$GCS_APP_PATH/$$dir\") $$addNewline()
|
||||
}
|
||||
|
||||
# Remaining QtQuick plugin DLLs
|
||||
QT_QUICK2_DLLS = QtQuick.2/qtquick2plugin$${DS}.dll \
|
||||
QtQuick.2/plugins.qmltypes \
|
||||
QtQuick.2/qmldir \
|
||||
qtquick/layouts/qquicklayoutsplugin$${DS}.dll \
|
||||
qtquick/layouts/plugins.qmltypes \
|
||||
qtquick/layouts/qmldir \
|
||||
qtquick/localstorage/qmllocalstorageplugin$${DS}.dll \
|
||||
qtquick/localstorage/plugins.qmltypes \
|
||||
qtquick/localstorage/qmldir \
|
||||
qtquick/particles.2/particlesplugin$${DS}.dll \
|
||||
qtquick/particles.2/plugins.qmltypes \
|
||||
qtquick/particles.2/qmldir \
|
||||
qtquick/privatewidgets/widgetsplugin$${DS}.dll \
|
||||
qtquick/privatewidgets/plugins.qmltypes \
|
||||
qtquick/privatewidgets/qmldir \
|
||||
qtquick/window.2/windowplugin$${DS}.dll \
|
||||
qtquick/window.2/plugins.qmltypes \
|
||||
qtquick/window.2/qmldir \
|
||||
qtquick/XmlListModel/qmlxmllistmodelplugin$${DS}.dll \
|
||||
qtquick/XmlListModel/plugins.qmltypes \
|
||||
qtquick/XmlListModel/qmldir
|
||||
|
||||
for(dll, QT_QUICK2_DLLS) {
|
||||
data_copy.commands += $(COPY_FILE) $$targetPath(\"$$[QT_INSTALL_QML]/$$dll\") $$targetPath(\"$$GCS_APP_PATH/$$dll\") $$addNewline()
|
||||
}
|
||||
|
||||
# copy OpenSSL DLLs
|
||||
OPENSSL_DLLS = \
|
||||
ssleay32.dll \
|
||||
@ -242,35 +163,5 @@ GCS_LIBRARY_PATH
|
||||
for(dll, OPENGL_DLLS) {
|
||||
data_copy.commands += $(COPY_FILE) $$targetPath(\"$${MESAWIN_DIR}/$$dll\") $$targetPath(\"$$GCS_APP_PATH/$$dll\") $$addNewline()
|
||||
}
|
||||
|
||||
data_copy.target = FORCE
|
||||
QMAKE_EXTRA_TARGETS += data_copy
|
||||
}
|
||||
|
||||
|
||||
macx{
|
||||
#NOTE: debug dylib can be copied as they will be cleaned out with packaging scripts
|
||||
#standard plugins directory (will copy just dylib, plugins.qmltypes and qmldir
|
||||
QT_QUICK2_PLUGINS = QtQuick.2 QtQuick/Layouts QtQuick/LocalStorage QtQuick/Particles.2 QtQuick/PrivateWidgets QtQuick/Window.2 QtQuick/XmlListModel
|
||||
#those directories will be fully copied to dest
|
||||
QT_QUICK2_FULL_DIRS = QtQuick/Controls QtQuick/Dialogs
|
||||
|
||||
#create QtQuick dir (that will host all subdirs)
|
||||
data_copy.commands += -@$(MKDIR) $$targetPath(\"$$GCS_QT_QML_PATH/QtQuick\") $$addNewline()
|
||||
|
||||
for(dir, QT_QUICK2_FULL_DIRS) {
|
||||
#data_copy.commands += -@$(MKDIR) $$targetPath(\"$$GCS_QT_QML_PATH/$$dir\") $$addNewline()
|
||||
data_copy.commands += $(COPY_DIR) $$targetPath(\"$$[QT_INSTALL_QML]/$$dir\") $$targetPath(\"$$GCS_QT_QML_PATH/$$dir\") $$addNewline()
|
||||
}
|
||||
|
||||
for(lib, QT_QUICK2_PLUGINS) {
|
||||
data_copy.commands += $(MKDIR) $$targetPath(\"$$GCS_QT_QML_PATH/$$lib\") $$addNewline()
|
||||
data_copy.commands += $(COPY_FILE) $$targetPath(\"$$[QT_INSTALL_QML]/$$lib/\"*.dylib) $$targetPath(\"$$GCS_QT_QML_PATH/$$lib/\") $$addNewline()
|
||||
data_copy.commands += $(COPY_FILE) $$targetPath(\"$$[QT_INSTALL_QML]/$$lib/plugins.qmltypes\") $$targetPath(\"$$GCS_QT_QML_PATH/$$lib/plugins.qmltypes\") $$addNewline()
|
||||
data_copy.commands += $(COPY_FILE) $$targetPath(\"$$[QT_INSTALL_QML]/$$lib/qmldir\") $$targetPath(\"$$GCS_QT_QML_PATH/$$lib/qmldir\") $$addNewline()
|
||||
}
|
||||
|
||||
data_copy.target = FORCE
|
||||
QMAKE_EXTRA_TARGETS += data_copy
|
||||
}
|
||||
}
|
||||
|
@ -119,6 +119,8 @@ macx {
|
||||
|
||||
contains(TEMPLATE, vc.*)|contains(TEMPLATE_PREFIX, vc):vcproj = 1
|
||||
GCS_APP_TARGET = openpilotgcs
|
||||
GCS_QT_QML_PATH = $$GCS_APP_PATH
|
||||
|
||||
copyqt = $$copydata
|
||||
} else {
|
||||
GCS_APP_TARGET = openpilotgcs
|
||||
|
@ -3792,9 +3792,8 @@ uniquement lorsque les valeurs changent</translation>
|
||||
<translation>Flot Données GPS</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location/>
|
||||
<source><html><head/><body><p>Displays the SNR for each detected sat. Satellite number (PRN) is displayed inside the green bar (GPS) or orange bar (SBAS). Sat SNR is displayed above (in dBHz)</p></body></html></source>
|
||||
<translation><html><head/><body><p>Affiche le SNR pour chaque satellite détecté. Le numéro du satellite (PRN) est affiché sur une barre verte (GPS) ou orange (SBAS). Le SNR du satellite est affiché au-dessus (en dBHz)</translation>
|
||||
<translation type="vanished"><html><head/><body><p>Affiche le SNR pour chaque satellite détecté. Le numéro du satellite (PRN) est affiché sur une barre verte (GPS) ou orange (SBAS). Le SNR du satellite est affiché au-dessus (en dBHz)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location/>
|
||||
@ -3807,6 +3806,11 @@ uniquement lorsque les valeurs changent</translation>
|
||||
<extracomment>Location of GCS on the Earth</extracomment>
|
||||
<translation>Position sur la terre</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location/>
|
||||
<source><html><head/><body><p>Displays the SNR for each detected sat. GPS satellites are shown in green, GLONASS in cyan, BeiDou in red and SBAS/QZSS in orange. Satellite number (PRN) is displayed inside the bar. Sat SNR is displayed above (in dBHz)</p></body></html></source>
|
||||
<translation><html><head/><body><p>Affiche le SNR pour chaque satellite détecté. Les satellites GPS sont affichés en vert, GLONASS en bleu clair, Beidou en rouge et SBAS/QZSS en orange. Le numéro du satellite (PRN) est affiché sur la barre Le SNR du satellite est affiché au-dessus (en dBHz)</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>IPconnectionOptionsPage</name>
|
||||
@ -9611,32 +9615,32 @@ Veuillez sélectionner le type de multirotor désiré pour la configuration ci-d
|
||||
</message>
|
||||
<message>
|
||||
<location/>
|
||||
<location filename="../../../src/plugins/setupwizard/pages/outputcalibrationpage.cpp" line="+435"/>
|
||||
<location line="+113"/>
|
||||
<location filename="../../../src/plugins/setupwizard/pages/outputcalibrationpage.cpp" line="+561"/>
|
||||
<location line="+131"/>
|
||||
<source>Start</source>
|
||||
<translation>Démarrer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../src/plugins/setupwizard/pages/outputcalibrationpage.cpp" line="-207"/>
|
||||
<location filename="../../../src/plugins/setupwizard/pages/outputcalibrationpage.cpp" line="-268"/>
|
||||
<location line="+8"/>
|
||||
<location line="+187"/>
|
||||
<location line="+25"/>
|
||||
<location line="+243"/>
|
||||
<location line="+38"/>
|
||||
<source>Output value : <b>%1</b> µs</source>
|
||||
<translation>Valeur de sortie : <b>%1</b> µs</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="-215"/>
|
||||
<location line="-284"/>
|
||||
<source><html><head/><body><p><span style=" font-size:10pt;">To find </span><span style=" font-size:10pt; font-weight:600;">the neutral rate for this reversable motor</span><span style=" font-size:10pt;">, press the Start button below and slide the slider to the right or left until you find the value where the motor doesn't start. <br/><br/>When done press button again to stop.</span></p></body></html></source>
|
||||
<translation><html><head/><body><p><span style=" font-size:10pt;">Pour trouver </span><span style=" font-size:10pt; font-weight:600;">la valeur de neutre de ce moteur inversable</span><span style=" font-size:10pt;">, appuyez sur le bouton Démarrer et bouger le curseur à gauche ou à droite jusqu'à trouver la position centrale où le moteur ne démarre pas. <br/><br/>Lorsque c'est terminé, appuyer à nouveau sur le bouton pour arrêter.</span></p></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+89"/>
|
||||
<location line="+113"/>
|
||||
<location line="+132"/>
|
||||
<location line="+131"/>
|
||||
<source>Stop</source>
|
||||
<translation>Arrêter</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="-52"/>
|
||||
<location line="-59"/>
|
||||
<source>The actuator module is in an error state.
|
||||
|
||||
Please make sure the correct firmware version is used then restart the wizard and try again. If the problem persists please consult the openpilot.org support forum.</source>
|
||||
@ -9644,6 +9648,16 @@ Please make sure the correct firmware version is used then restart the wizard an
|
||||
|
||||
Soyez certain d'utiliser la bonne version de firmware puis redémarrer l'assistant et essayez à nouveau. Si le problème persiste, consultez le forum openpilot.org.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+132"/>
|
||||
<source>Output value : <b>%1</b> µs (Min)</source>
|
||||
<translation>Valeur de sortie : <b>%1</b> µs (Min)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+31"/>
|
||||
<source>Output value : <b>%1</b> µs (Max)</source>
|
||||
<translation>Valeur de sortie : <b>%1</b> µs (Max)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../src/plugins/setupwizard/pages/outputcalibrationpage.ui"/>
|
||||
<source>Reverse</source>
|
||||
@ -9735,6 +9749,11 @@ p, li { white-space: pre-wrap; }
|
||||
<source>Output value: 1000µs</source>
|
||||
<translation>Valeur de sortie : <b>1000</b> µs</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location/>
|
||||
<source>Calibrate all motor outputs at the same time</source>
|
||||
<translation>Calibrer toutes les sorties moteurs en même temps</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>RebootPage</name>
|
||||
@ -10680,7 +10699,7 @@ Voulez-vous toujours continuer ?</translation>
|
||||
<context>
|
||||
<name>ConfigInputWidget</name>
|
||||
<message>
|
||||
<location filename="../../../src/plugins/config/configinputwidget.cpp" line="+388"/>
|
||||
<location filename="../../../src/plugins/config/configinputwidget.cpp" line="+393"/>
|
||||
<source>http://wiki.openpilot.org/x/04Cf</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
@ -10697,7 +10716,7 @@ Voulez-vous toujours continuer ?</translation>
|
||||
<translation>Vous devrez reconfigurer manuellement les paramètres d'armement lorsque l'assistant sera terminé. Après la dernière étape de l'assistant, vous serez redirigé vers l'écran des Paramètres d'Armement.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+212"/>
|
||||
<location line="+222"/>
|
||||
<source>Next</source>
|
||||
<translation>Suivant</translation>
|
||||
</message>
|
||||
@ -10738,7 +10757,7 @@ Vous pouvez appuyer à tout moment sur 'Précédent' pour revenir à l
|
||||
<translation type="vanished">Veuillez sélectionner votre mode de pilotage :</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+45"/>
|
||||
<location line="+47"/>
|
||||
<source>Mode 1: Fore/Aft Cyclic and Yaw on the left, Throttle/Collective and Left/Right Cyclic on the right</source>
|
||||
<translatorcomment>Mode pilotage Hélicoptères: (Notice Graupner)
|
||||
1: Longitudinal, Anti-couple, à gauche et Moteur/Pas, Latéral, à droite
|
||||
@ -10835,7 +10854,16 @@ IMPORTANT: These new settings have not been saved to the board yet. After pressi
|
||||
IMPORTANT : Ces nouveaux paramètres ne sont pas encore enregistrés sur la carte. Après avoir appuyé sur Suivant vous serez dirigé vers l'onglet Paramètres d'Armement où vous pourrez choisir votre séquence d'armement et enregistrer la configuration.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+191"/>
|
||||
<location line="+23"/>
|
||||
<source>Please center all controls and trims and press Next when ready.
|
||||
|
||||
For a ground vehicle, this center position will be used as neutral value of each channel.</source>
|
||||
<translation>Veuillez positionner tous les manches/trims en position centrale et appuyer sur Suivant lorsque vous êtes prêt.
|
||||
|
||||
Pour un véhicule terrestre, ces positions centrales seront utilisées comme neutre de chaque canal.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+178"/>
|
||||
<source>Please enable throttle hold mode.
|
||||
|
||||
Move the Collective Pitch stick.</source>
|
||||
@ -10883,7 +10911,7 @@ Bougez le manche %1.</translation>
|
||||
<translation> Vous avez la possibilité d'appuyer sur Suivant pour ignorer ce canal.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+725"/>
|
||||
<location line="+748"/>
|
||||
<source>Stop Manual Calibration</source>
|
||||
<translation>Arrêter Calibration Manuelle</translation>
|
||||
</message>
|
||||
@ -10898,12 +10926,22 @@ Bougez le manche %1.</translation>
|
||||
<translation>Vous devrez reconfigurer les paramètres d'armement manuellement lorsque la calibration manuelle sera terminée.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+51"/>
|
||||
<location line="+34"/>
|
||||
<source>Ground vehicle</source>
|
||||
<translation>Véhicule terrestre</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source><p>Are you configuring a transmitter for your <b>ground vehicle</b> with reversible motor<br>controlled by throttle stick?</p><p>If so, please make sure you've centered throttle control and press <b>Yes</b> button. Otherwise, press No.</p><p>Attention, if you press <b>Yes</b>, then the <b>Flight Mode Count</b> will be set to 1.</p></source>
|
||||
<translation><p>Confirmez-vous que vous utilisez une radio pour votre <b>véhicule terrestre</b> avec un moteur inversable contrôlé avec le manche Throttle ?</p>Si c'est le cas, soyez certain d'avoir centré le manche throttle et appuyez sur le bouton <b>Oui</b>, sinon appuyez sur Non</p><p>Attention, si vous appuyez sur <b>Oui</b>, le nombre de <b>Modes de Vol</b> sera fixé à 1.</p></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+39"/>
|
||||
<source>Start Manual Calibration</source>
|
||||
<translation>Démarrer Calibration Manuelle</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+28"/>
|
||||
<location line="+35"/>
|
||||
<source>Warning</source>
|
||||
<translation>Attention</translation>
|
||||
</message>
|
||||
@ -11506,14 +11544,22 @@ Double clic sur la légende ou le tracé pour afficher/cacher la légende.</tran
|
||||
<context>
|
||||
<name>SetupWizardPlugin</name>
|
||||
<message>
|
||||
<location filename="../../../src/plugins/setupwizard/setupwizardplugin.cpp" line="+62"/>
|
||||
<source>Vehicle Setup Wizard</source>
|
||||
<translation>Assistant Configuration Véhicule</translation>
|
||||
<translation type="vanished">Assistant Configuration Véhicule</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Export Wizard Vehicle Template</source>
|
||||
<translation type="vanished">Exporter Modèle Assistant Véhicule</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../src/plugins/setupwizard/setupwizardplugin.cpp" line="+61"/>
|
||||
<source>Vehicle Setup Wizard...</source>
|
||||
<translation>Assistant Configuration Véhicule...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+12"/>
|
||||
<source>Export Wizard Vehicle Template</source>
|
||||
<translation>Exporter Modèle Assistant Véhicule</translation>
|
||||
<source>Export/Import Vehicle Template...</source>
|
||||
<translation>Export / Import Modèle Assistant Véhicule...</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@ -11584,7 +11630,7 @@ Double clic sur la légende ou le tracé pour afficher/cacher la légende.</tran
|
||||
<translation>Écriture paramètres de stabilisation</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+146"/>
|
||||
<location line="+144"/>
|
||||
<source>Writing mixer settings</source>
|
||||
<translation>Écriture paramètres mixeur</translation>
|
||||
</message>
|
||||
@ -15102,81 +15148,67 @@ et même conduire au crash. A utiliser avec prudence.</translation>
|
||||
<translation>Page d'Assistant</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location/>
|
||||
<source>Information about the Vehicle in short.</source>
|
||||
<translation>Résumé d'informations sur le Véhicule.</translation>
|
||||
<translation type="vanished">Résumé d'informations sur le Véhicule.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../src/plugins/setupwizard/pages/airframeinitialtuningpage.cpp" line="+120"/>
|
||||
<source>Name of Vehicle: </source>
|
||||
<translation>Nom du Véhicule : </translation>
|
||||
<translation type="vanished">Nom du Véhicule : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Name of Owner: </source>
|
||||
<translation>Nom du Propriétaire : </translation>
|
||||
<translation type="vanished">Nom du Propriétaire : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+5"/>
|
||||
<source>Size: </source>
|
||||
<translation>Taille : </translation>
|
||||
<translation type="vanished">Taille : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Weight: </source>
|
||||
<translation>Masse : </translation>
|
||||
<translation type="vanished">Masse : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Motor(s): </source>
|
||||
<translation>Moteur(s) : </translation>
|
||||
<translation type="vanished">Moteur(s) : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>ESC(s): </source>
|
||||
<translation>Esc(s) : </translation>
|
||||
<translation type="vanished">Esc(s) : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Servo(s): </source>
|
||||
<translation>Servo(s) : </translation>
|
||||
<translation type="vanished">Servo(s) : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Battery: </source>
|
||||
<translation>Batterie : </translation>
|
||||
<translation type="vanished">Batterie : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Propellers(s): </source>
|
||||
<translation>Hélice(s) : </translation>
|
||||
<translation type="vanished">Hélice(s) : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Controller: </source>
|
||||
<translation>Carte Contrôleur : </translation>
|
||||
<translation type="vanished">Carte Contrôleur : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Comments: </source>
|
||||
<translation>Commentaires : </translation>
|
||||
<translation type="vanished">Commentaires : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+3"/>
|
||||
<source>This option will use the current tuning settings saved on the controller, if your controller is currently unconfigured, then the OpenPilot firmware defaults will be used.
|
||||
|
||||
It is suggested that if this is a first time configuration of your controller, rather than use this option, instead select a tuning set that matches your own airframe as close as possible from the list above or if you are not able to fine one, then select the generic item from the list.</source>
|
||||
<translation>Cette option utilise les paramètres de réglage actuels enregistrés dans la carte, si votre contrôleur n'est pas actuellement configuré, alors les paramètres par défaut du firmware OpenPilot seront utilisés.
|
||||
<translation type="vanished">Cette option utilise les paramètres de réglage actuels enregistrés dans la carte, si votre contrôleur n'est pas actuellement configuré, alors les paramètres par défaut du firmware OpenPilot seront utilisés.
|
||||
|
||||
Il est suggéré que si cela est une première configuration de votre contrôleur, plutôt que d'utiliser cette option, sélectionnez à la place un ensemble de réglages qui correspond le mieux à votre propre appareil dans la liste ci-dessus. Si vous n'êtes pas en mesure d'en choisir un, sélectionnez l'élément générique de la liste.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+93"/>
|
||||
<source>Current Tuning</source>
|
||||
<translation>Réglages Actuels</translation>
|
||||
<translation type="vanished">Réglages Actuels</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../src/plugins/setupwizard/pages/airframeinitialtuningpage.ui"/>
|
||||
<location/>
|
||||
<source><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
@ -15315,12 +15347,11 @@ p, li { white-space: pre-wrap; }
|
||||
<context>
|
||||
<name>VehicleTemplateExportDialog</name>
|
||||
<message>
|
||||
<location filename="../../../src/plugins/setupwizard/vehicletemplateexportdialog.ui"/>
|
||||
<source>Vehicle Template Export</source>
|
||||
<translation>Exportation Modèle Véhicule</translation>
|
||||
<translation type="vanished">Exportation Modèle Véhicule</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location/>
|
||||
<location filename="../../../src/plugins/setupwizard/vehicletemplateexportdialog.ui"/>
|
||||
<source>Weight:</source>
|
||||
<translation>Masse :</translation>
|
||||
</message>
|
||||
@ -15475,12 +15506,11 @@ p, li { white-space: pre-wrap; }
|
||||
<translation>Sélectionner image...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location/>
|
||||
<source>Cancel</source>
|
||||
<translation>Annuler</translation>
|
||||
<translation type="vanished">Annuler</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../src/plugins/setupwizard/vehicletemplateexportdialog.cpp" line="+88"/>
|
||||
<location filename="../../../src/plugins/setupwizard/vehicletemplateexportdialog.cpp" line="+109"/>
|
||||
<source>Fixed Wing - Aileron</source>
|
||||
<translation>Voilure Fixe - Aileron</translation>
|
||||
</message>
|
||||
@ -15569,7 +15599,7 @@ p, li { white-space: pre-wrap; }
|
||||
<translation>Non Supporté</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+75"/>
|
||||
<location line="+56"/>
|
||||
<source>Export settings</source>
|
||||
<translation>Exporter réglages</translation>
|
||||
</message>
|
||||
@ -15579,15 +15609,16 @@ p, li { white-space: pre-wrap; }
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+11"/>
|
||||
<location line="+14"/>
|
||||
<source>Settings could not be exported to
|
||||
%1(%2).
|
||||
Please try again.</source>
|
||||
<translation>Les réglages ne peuvent être exportés vers
|
||||
%1(%2).</translation>
|
||||
%1(%2).
|
||||
Veuillez essayer à nouveau.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+9"/>
|
||||
<location line="+61"/>
|
||||
<source>Import Image</source>
|
||||
<translation>Importer Image</translation>
|
||||
</message>
|
||||
@ -15604,7 +15635,37 @@ Please try again.</source>
|
||||
<message>
|
||||
<location/>
|
||||
<source>Put comments here that don't fit in the categories above</source>
|
||||
<translation>Indiquez ici les commentaires ne correspondant pas aux catégories ci-dessus</translation>
|
||||
<translation>Indiquez ici les commentaires ne correspondant pas aux catégories ci-dessus</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location/>
|
||||
<source>Vehicle Templates</source>
|
||||
<translation>Modèles Véhicules</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location/>
|
||||
<source>Export template</source>
|
||||
<translation>Export modèle</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location/>
|
||||
<source>Close</source>
|
||||
<translation>Fermer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location/>
|
||||
<source>Save as</source>
|
||||
<translation>Enregistrer sous</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location/>
|
||||
<source>Import template</source>
|
||||
<translation>Import modèle</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location/>
|
||||
<source>Import</source>
|
||||
<translation>Importer</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@ -16013,9 +16074,8 @@ Vous pouvez appuyer à tout moment sur 'Précédent' pour revenir à l
|
||||
<translation>Hélicoptère : avec pas collectif et commande des gaz</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location/>
|
||||
<source>If selecting the Helicopter option, please engage throttle hold now.</source>
|
||||
<translation>Si vous avez sélectionné l'option Hélicoptère, veuillez enclencher et maintenir les gaz.</translation>
|
||||
<translation type="vanished">Si vous avez sélectionné l'option Hélicoptère, veuillez enclencher et maintenir les gaz.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location/>
|
||||
@ -16050,7 +16110,7 @@ Vous pouvez appuyer à tout moment sur 'Précédent' pour revenir à l
|
||||
<message>
|
||||
<location/>
|
||||
<source>Identify sticks instructions</source>
|
||||
<translation type="unfinished">Identifiez les instructions de manches</translation>
|
||||
<translation>Identifiez les instructions de manches</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location/>
|
||||
@ -16099,6 +16159,16 @@ IMPORTANT : Ces nouveaux paramètres ne sont pas encore enregistrés sur la cart
|
||||
<source>Cancel</source>
|
||||
<translation>Annuler</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location/>
|
||||
<source>Surface: has reversible motor controlled by throttle stick, plus yaw control (2 channels)</source>
|
||||
<translation>Terrestre : A un moteur inversable contrôlé par le manche des gaz plus une direction Yaw (2 canaux)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location/>
|
||||
<source><html><head/><body><p>If selecting the Helicopter option, please engage throttle hold now.</p><p>If selecting the Surface option, the <b>Flight Mode Count</b> will be set to be 1.</p></body></html></source>
|
||||
<translation type="unfinished"><html><head/><body><p>Si l'option Hélicoptère est sélectionnée, veuillez maintenir le manche des gaz maintenant.</p><p>Si l'option Terrestre est sélectionnée, le nombre de <b>Modes de Vol</b> sera fixé à 1.</p></body></html></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ConfigCcpmWidget</name>
|
||||
@ -16168,4 +16238,86 @@ IMPORTANT : Ces nouveaux paramètres ne sont pas encore enregistrés sur la cart
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>VehicleTemplateSelectorWidget</name>
|
||||
<message>
|
||||
<location filename="../../../src/plugins/setupwizard/vehicletemplateselectorwidget.ui"/>
|
||||
<source>Form</source>
|
||||
<translation>Formulaire</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location/>
|
||||
<source>Information about the Vehicle in short.</source>
|
||||
<translation>Résumé d'informations sur le Véhicule.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../src/plugins/setupwizard/vehicletemplateselectorwidget.cpp" line="+100"/>
|
||||
<source>Name of Vehicle: </source>
|
||||
<translation>Nom du Véhicule : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Name of Owner: </source>
|
||||
<translation>Nom du Propriétaire : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+5"/>
|
||||
<source>Size: </source>
|
||||
<translation>Taille : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Weight: </source>
|
||||
<translation>Masse : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Motor(s): </source>
|
||||
<translation>Moteur(s) : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>ESC(s): </source>
|
||||
<translation>Esc(s) : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Servo(s): </source>
|
||||
<translation>Servo(s) : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Battery: </source>
|
||||
<translation>Batterie : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Propellers(s): </source>
|
||||
<translation>Hélice(s) : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Controller: </source>
|
||||
<translation>Carte Contrôleur : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+1"/>
|
||||
<source>Comments: </source>
|
||||
<translation>Commentaires : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+3"/>
|
||||
<source>This option will use the current tuning settings saved on the controller, if your controller is currently unconfigured, then the OpenPilot firmware defaults will be used.
|
||||
|
||||
It is suggested that if this is a first time configuration of your controller, rather than use this option, instead select a tuning set that matches your own airframe as close as possible from the list above or if you are not able to fine one, then select the generic item from the list.</source>
|
||||
<translation>Cette option utilise les paramètres de réglage actuels enregistrés dans la carte, si votre contrôleur n'est pas actuellement configuré, alors les paramètres par défaut du firmware OpenPilot seront utilisés.
|
||||
|
||||
Il est suggéré que si cela est une première configuration de votre contrôleur, plutôt que d'utiliser cette option, sélectionnez à la place un ensemble de réglages qui correspond le mieux à votre propre appareil dans la liste ci-dessus. Si vous n'êtes pas en mesure d'en choisir un, sélectionnez l'élément générique de la liste.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+105"/>
|
||||
<source>Current Tuning</source>
|
||||
<translation>Réglages Actuels</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
@ -72,6 +72,7 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) :
|
||||
accessoryDesiredObj1 = AccessoryDesired::GetInstance(getObjectManager(), 1);
|
||||
accessoryDesiredObj2 = AccessoryDesired::GetInstance(getObjectManager(), 2);
|
||||
actuatorSettingsObj = ActuatorSettings::GetInstance(getObjectManager());
|
||||
systemSettingsObj = SystemSettings::GetInstance(getObjectManager());
|
||||
|
||||
// Only instance 0 is present if the board is not connected.
|
||||
// The other instances are populated lazily.
|
||||
@ -349,6 +350,10 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) :
|
||||
ManualControlSettings::CHANNELGROUPS_ACCESSORY1 <<
|
||||
ManualControlSettings::CHANNELGROUPS_ACCESSORY2;
|
||||
|
||||
groundChannelOrder << ManualControlSettings::CHANNELGROUPS_THROTTLE <<
|
||||
ManualControlSettings::CHANNELGROUPS_YAW <<
|
||||
ManualControlSettings::CHANNELGROUPS_ACCESSORY0;
|
||||
|
||||
updateEnableControls();
|
||||
}
|
||||
|
||||
@ -420,6 +425,10 @@ void ConfigInputWidget::goToWizard()
|
||||
actuatorSettingsData = actuatorSettingsObj->getData();
|
||||
previousActuatorSettingsData = actuatorSettingsData;
|
||||
|
||||
// Stash systemSettings
|
||||
systemSettingsData = systemSettingsObj->getData();
|
||||
previousSystemSettingsData = systemSettingsData;
|
||||
|
||||
// Now reset channel and actuator settings (disable outputs)
|
||||
resetChannelSettings();
|
||||
resetActuatorSettings();
|
||||
@ -463,6 +472,7 @@ void ConfigInputWidget::wzCancel()
|
||||
manualSettingsObj->setData(previousManualSettingsData);
|
||||
flightModeSettingsObj->setData(previousFlightModeSettingsData);
|
||||
actuatorSettingsObj->setData(previousActuatorSettingsData);
|
||||
systemSettingsObj->setData(previousSystemSettingsData);
|
||||
}
|
||||
|
||||
void ConfigInputWidget::registerControlActivity()
|
||||
@ -552,6 +562,11 @@ void ConfigInputWidget::wzNext()
|
||||
throttleError = false;
|
||||
checkThrottleRange();
|
||||
|
||||
// Force flight mode number to be 1 if 2 CH ground vehicle was selected
|
||||
if (transmitterType == ground) {
|
||||
forceOneFlightMode();
|
||||
}
|
||||
|
||||
manualSettingsObj->setData(manualSettingsData);
|
||||
// move to Arming Settings tab
|
||||
ui->stackedWidget->setCurrentIndex(0);
|
||||
@ -629,6 +644,8 @@ void ConfigInputWidget::wizardSetUpStep(enum wizardSteps step)
|
||||
wizardUi->wzBack->setEnabled(true);
|
||||
if (transmitterType == heli) {
|
||||
wizardUi->typeHeli->setChecked(true);
|
||||
} else if (transmitterType == ground) {
|
||||
wizardUi->typeGround->setChecked(true);
|
||||
} else {
|
||||
wizardUi->typeAcro->setChecked(true);
|
||||
}
|
||||
@ -687,6 +704,10 @@ void ConfigInputWidget::wizardSetUpStep(enum wizardSteps step)
|
||||
case wizardIdentifyCenter:
|
||||
setTxMovement(centerAll);
|
||||
wizardUi->pagesStack->setCurrentWidget(wizardUi->identifyCenterPage);
|
||||
if (transmitterType == ground) {
|
||||
wizardUi->identifyCenterInstructions->setText(QString(tr("Please center all controls and trims and press Next when ready.\n\n"
|
||||
"For a ground vehicle, this center position will be used as neutral value of each channel.")));
|
||||
}
|
||||
break;
|
||||
case wizardIdentifyLimits:
|
||||
{
|
||||
@ -752,6 +773,12 @@ void ConfigInputWidget::wizardTearDownStep(enum wizardSteps step)
|
||||
case wizardChooseType:
|
||||
if (wizardUi->typeAcro->isChecked()) {
|
||||
transmitterType = acro;
|
||||
} else if (wizardUi->typeGround->isChecked()) {
|
||||
transmitterType = ground;
|
||||
/* Make sure to tell controller, this is really a ground vehicle. */
|
||||
systemSettingsData = systemSettingsObj->getData();
|
||||
systemSettingsData.AirframeType = SystemSettings::AIRFRAMETYPE_GROUNDVEHICLECAR;
|
||||
systemSettingsObj->setData(systemSettingsData);
|
||||
} else {
|
||||
transmitterType = heli;
|
||||
}
|
||||
@ -885,7 +912,18 @@ void ConfigInputWidget::setChannel(int newChan)
|
||||
*/
|
||||
void ConfigInputWidget::nextChannel()
|
||||
{
|
||||
QList <int> order = (transmitterType == heli) ? heliChannelOrder : acroChannelOrder;
|
||||
QList <int> order;
|
||||
switch (transmitterType) {
|
||||
case heli:
|
||||
order = heliChannelOrder;
|
||||
break;
|
||||
case ground:
|
||||
order = groundChannelOrder;
|
||||
break;
|
||||
default:
|
||||
order = acroChannelOrder;
|
||||
break;
|
||||
}
|
||||
|
||||
if (currentChannelNum == -1) {
|
||||
setChannel(order[0]);
|
||||
@ -906,7 +944,18 @@ void ConfigInputWidget::nextChannel()
|
||||
*/
|
||||
void ConfigInputWidget::prevChannel()
|
||||
{
|
||||
QList <int> order = transmitterType == heli ? heliChannelOrder : acroChannelOrder;
|
||||
QList <int> order;
|
||||
switch (transmitterType) {
|
||||
case heli:
|
||||
order = heliChannelOrder;
|
||||
break;
|
||||
case ground:
|
||||
order = groundChannelOrder;
|
||||
break;
|
||||
default:
|
||||
order = acroChannelOrder;
|
||||
break;
|
||||
}
|
||||
|
||||
// No previous from unset channel or next state
|
||||
if (currentChannelNum == -1) {
|
||||
@ -1014,6 +1063,7 @@ void ConfigInputWidget::identifyLimits()
|
||||
}
|
||||
manualSettingsObj->setData(manualSettingsData);
|
||||
}
|
||||
|
||||
void ConfigInputWidget::setMoveFromCommand(int command)
|
||||
{
|
||||
// ManualControlSettings::ChannelNumberElem:
|
||||
@ -1634,8 +1684,31 @@ void ConfigInputWidget::simpleCalibration(bool enable)
|
||||
manualCommandData = manualCommandObj->getData();
|
||||
manualSettingsData = manualSettingsObj->getData();
|
||||
|
||||
QMessageBox::StandardButton reply;
|
||||
reply = QMessageBox::question(this, tr("Ground vehicle"),
|
||||
tr("<p>Are you configuring a transmitter for your <b>ground vehicle</b> with reversible motor<br>"
|
||||
"controlled by throttle stick?</p>"
|
||||
"<p>If so, please make sure you've centered throttle control and press <b>Yes</b> button. Otherwise, press No.</p>"
|
||||
"<p>Attention, if you press <b>Yes</b>, then the <b>Flight Mode Count</b> will be set to 1.</p>"),
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
|
||||
if (reply == QMessageBox::Yes) {
|
||||
transmitterType = ground;
|
||||
manualSettingsData.ChannelNeutral[ManualControlSettings::CHANNELNEUTRAL_THROTTLE] =
|
||||
manualCommandData.Channel[ManualControlSettings::CHANNELNUMBER_THROTTLE];
|
||||
/* Make sure to tell controller, this is really a ground vehicle. */
|
||||
systemSettingsData = systemSettingsObj->getData();
|
||||
systemSettingsData.AirframeType = SystemSettings::AIRFRAMETYPE_GROUNDVEHICLECAR;
|
||||
systemSettingsObj->setData(systemSettingsData);
|
||||
}
|
||||
|
||||
restoreMdataSingle(manualCommandObj, &manualControlMdata);
|
||||
|
||||
// Force flight mode number to be 1 if 2 channel ground vehicle was confirmed
|
||||
if (transmitterType == ground) {
|
||||
forceOneFlightMode();
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < ManualControlCommand::CHANNEL_NUMELEM; i++) {
|
||||
if ((i == ManualControlSettings::CHANNELNUMBER_FLIGHTMODE) || (i == ManualControlSettings::CHANNELNUMBER_THROTTLE)) {
|
||||
adjustSpecialNeutrals();
|
||||
@ -1667,6 +1740,12 @@ void ConfigInputWidget::adjustSpecialNeutrals()
|
||||
(manualSettingsData.ChannelMax[ManualControlSettings::CHANNELMAX_FLIGHTMODE] +
|
||||
manualSettingsData.ChannelMin[ManualControlSettings::CHANNELMIN_FLIGHTMODE]) / 2;
|
||||
|
||||
// A ground vehicle has a reversible motor, the center position of throttle is the neutral setting.
|
||||
// So do not have to set a special neutral value for it.
|
||||
if (transmitterType == ground) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Force throttle to be near min, add 4% from total range to avoid arming issues
|
||||
manualSettingsData.ChannelNeutral[ManualControlSettings::CHANNELNEUTRAL_THROTTLE] =
|
||||
manualSettingsData.ChannelMin[ManualControlSettings::CHANNELMIN_THROTTLE] +
|
||||
@ -1737,3 +1816,10 @@ void ConfigInputWidget::resetActuatorSettings()
|
||||
actuatorSettingsObj->setData(actuatorSettingsData);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigInputWidget::forceOneFlightMode()
|
||||
{
|
||||
manualCommandData = manualCommandObj->getData();
|
||||
manualSettingsData.FlightModeNumber = 1;
|
||||
manualSettingsObj->setData(manualSettingsData);
|
||||
}
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "flightstatus.h"
|
||||
#include "accessorydesired.h"
|
||||
#include <QPointer>
|
||||
#include "systemsettings.h"
|
||||
|
||||
class Ui_InputWidget;
|
||||
|
||||
@ -62,7 +63,7 @@ public:
|
||||
enum txMode { mode1, mode2, mode3, mode4 };
|
||||
enum txMovements { moveLeftVerticalStick, moveRightVerticalStick, moveLeftHorizontalStick, moveRightHorizontalStick, moveAccess0, moveAccess1, moveAccess2, moveFlightMode, centerAll, moveAll, nothing };
|
||||
enum txMovementType { vertical, horizontal, jump, mix };
|
||||
enum txType { acro, heli };
|
||||
enum txType { acro, heli, ground };
|
||||
void startInputWizard()
|
||||
{
|
||||
goToWizard();
|
||||
@ -111,6 +112,7 @@ private:
|
||||
int currentChannelNum;
|
||||
QList<int> heliChannelOrder;
|
||||
QList<int> acroChannelOrder;
|
||||
QList<int> groundChannelOrder;
|
||||
|
||||
UAVObject::Metadata manualControlMdata;
|
||||
ManualControlCommand *manualCommandObj;
|
||||
@ -138,6 +140,10 @@ private:
|
||||
ReceiverActivity *receiverActivityObj;
|
||||
ReceiverActivity::DataFields receiverActivityData;
|
||||
|
||||
SystemSettings *systemSettingsObj;
|
||||
SystemSettings::DataFields systemSettingsData;
|
||||
SystemSettings::DataFields previousSystemSettingsData;
|
||||
|
||||
QSvgRenderer *m_renderer;
|
||||
|
||||
// Background: background
|
||||
@ -204,6 +210,7 @@ private slots:
|
||||
void updateCalibration();
|
||||
void resetChannelSettings();
|
||||
void resetActuatorSettings();
|
||||
void forceOneFlightMode();
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
|
@ -64,6 +64,13 @@ You can press 'back' at any time to return to the previous screen or press 'Canc
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="typeGround">
|
||||
<property name="text">
|
||||
<string>Surface: has reversible motor controlled by throttle stick, plus yaw control (2 channels)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="typeHeli">
|
||||
<property name="text">
|
||||
@ -74,7 +81,7 @@ You can press 'back' at any time to return to the previous screen or press 'Canc
|
||||
<item>
|
||||
<widget class="QLabel" name="typePageFooter">
|
||||
<property name="text">
|
||||
<string>If selecting the Helicopter option, please engage throttle hold now.</string>
|
||||
<string><html><head/><body><p>If selecting the Helicopter option, please engage throttle hold now.</p><p>If selecting the Surface option, the <b>Flight Mode Count</b> will be set to be 1.</p></body></html></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
@ -89,7 +96,7 @@ You can press 'back' at any time to return to the previous screen or press 'Canc
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
<height>23</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
|
@ -44,7 +44,7 @@ UAVGadgetDecorator::UAVGadgetDecorator(IUAVGadget *gadget, QList<IUAVGadgetConfi
|
||||
m_toolbar->setMinimumContentsLength(15);
|
||||
foreach(IUAVGadgetConfiguration * config, *m_configurations)
|
||||
m_toolbar->addItem(config->name());
|
||||
connect(m_toolbar, SIGNAL(activated(int)), this, SLOT(loadConfiguration(int)));
|
||||
connect(m_toolbar, SIGNAL(currentIndexChanged(int)), this, SLOT(loadConfiguration(int)));
|
||||
updateToolbar();
|
||||
}
|
||||
|
||||
@ -63,15 +63,22 @@ void UAVGadgetDecorator::loadConfiguration(int index)
|
||||
|
||||
void UAVGadgetDecorator::loadConfiguration(IUAVGadgetConfiguration *config)
|
||||
{
|
||||
if (m_activeConfiguration == config) {
|
||||
return;
|
||||
}
|
||||
m_activeConfiguration = config;
|
||||
int index = m_toolbar->findText(config->name());
|
||||
m_toolbar->setCurrentIndex(index);
|
||||
if (m_toolbar->currentIndex() != index) {
|
||||
m_toolbar->setCurrentIndex(index);
|
||||
}
|
||||
m_gadget->loadConfiguration(config);
|
||||
}
|
||||
|
||||
void UAVGadgetDecorator::configurationChanged(IUAVGadgetConfiguration *config)
|
||||
{
|
||||
if (config == m_activeConfiguration) {
|
||||
// force a configuration reload
|
||||
m_activeConfiguration = NULL;
|
||||
loadConfiguration(config);
|
||||
}
|
||||
}
|
||||
@ -133,7 +140,6 @@ void UAVGadgetDecorator::restoreState(QSettings *qSettings)
|
||||
|
||||
foreach(IUAVGadgetConfiguration * config, *m_configurations) {
|
||||
if (config->name() == configName) {
|
||||
m_activeConfiguration = config;
|
||||
loadConfiguration(config);
|
||||
break;
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ void UAVGadgetInstanceManager::readConfigs_1_1_0(QSettings *qs)
|
||||
|
||||
configs = qs->childGroups();
|
||||
foreach(QString configName, configs) {
|
||||
qDebug() << "Loading config: " << classId << "," << configName;
|
||||
qDebug().nospace() << "Loading config: " << classId << ", " << configName;
|
||||
qs->beginGroup(configName);
|
||||
bool locked = qs->value("config.locked").toBool();
|
||||
configInfo.setNameOfConfigurable(classId + "-" + configName);
|
||||
|
@ -34,7 +34,6 @@
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
#include <qmacstyle_mac.h>
|
||||
#endif
|
||||
@ -46,22 +45,28 @@ SplitterOrView::SplitterOrView(Core::UAVGadgetManager *uavGadgetManager, Core::I
|
||||
m_uavGadgetManager(uavGadgetManager),
|
||||
m_splitter(0)
|
||||
{
|
||||
m_view = new UAVGadgetView(m_uavGadgetManager, uavGadget, this);
|
||||
m_layout = new QStackedLayout(this);
|
||||
m_layout->addWidget(m_view);
|
||||
m_view = new UAVGadgetView(m_uavGadgetManager, uavGadget, this);
|
||||
setLayout(new QStackedLayout());
|
||||
layout()->addWidget(m_view);
|
||||
}
|
||||
|
||||
SplitterOrView::SplitterOrView(SplitterOrView &splitterOrView, QWidget *parent) :
|
||||
QWidget(parent),
|
||||
m_uavGadgetManager(splitterOrView.m_uavGadgetManager),
|
||||
m_view(splitterOrView.m_view),
|
||||
m_splitter(splitterOrView.m_splitter)
|
||||
{
|
||||
Q_ASSERT((m_view || m_splitter) && !(m_view && m_splitter));
|
||||
setLayout(new QStackedLayout());
|
||||
if (m_view) {
|
||||
layout()->addWidget(m_view);
|
||||
} else if (m_splitter) {
|
||||
layout()->addWidget(m_splitter);
|
||||
}
|
||||
}
|
||||
|
||||
SplitterOrView::~SplitterOrView()
|
||||
{
|
||||
if (m_view) {
|
||||
delete m_view;
|
||||
m_view = 0;
|
||||
}
|
||||
if (m_splitter) {
|
||||
delete m_splitter;
|
||||
m_splitter = 0;
|
||||
}
|
||||
}
|
||||
{}
|
||||
|
||||
void SplitterOrView::mousePressEvent(QMouseEvent *e)
|
||||
{
|
||||
@ -221,7 +226,7 @@ QSplitter *SplitterOrView::takeSplitter()
|
||||
QSplitter *oldSplitter = m_splitter;
|
||||
|
||||
if (m_splitter) {
|
||||
m_layout->removeWidget(m_splitter);
|
||||
layout()->removeWidget(m_splitter);
|
||||
}
|
||||
m_splitter = 0;
|
||||
return oldSplitter;
|
||||
@ -232,7 +237,7 @@ UAVGadgetView *SplitterOrView::takeView()
|
||||
UAVGadgetView *oldView = m_view;
|
||||
|
||||
if (m_view) {
|
||||
m_layout->removeWidget(m_view);
|
||||
layout()->removeWidget(m_splitter);
|
||||
}
|
||||
m_view = 0;
|
||||
return oldView;
|
||||
@ -255,35 +260,6 @@ QList<IUAVGadget *> SplitterOrView::gadgets()
|
||||
return g;
|
||||
}
|
||||
|
||||
void SplitterOrView::split(Qt::Orientation orientation)
|
||||
{
|
||||
Q_ASSERT(m_view);
|
||||
Q_ASSERT(!m_splitter);
|
||||
m_splitter = new MiniSplitter(this);
|
||||
m_splitter->setOrientation(orientation);
|
||||
connect(m_splitter, SIGNAL(splitterMoved(int, int)), this, SLOT(onSplitterMoved(int, int)));
|
||||
m_layout->addWidget(m_splitter);
|
||||
Core::IUAVGadget *ourGadget = m_view->gadget();
|
||||
|
||||
if (ourGadget) {
|
||||
// Give our gadget to the new left or top SplitterOrView.
|
||||
m_view->removeGadget();
|
||||
m_splitter->addWidget(new SplitterOrView(m_uavGadgetManager, ourGadget));
|
||||
m_splitter->addWidget(new SplitterOrView(m_uavGadgetManager));
|
||||
} else {
|
||||
m_splitter->addWidget(new SplitterOrView(m_uavGadgetManager));
|
||||
m_splitter->addWidget(new SplitterOrView(m_uavGadgetManager));
|
||||
}
|
||||
|
||||
m_layout->setCurrentWidget(m_splitter);
|
||||
|
||||
if (m_view) {
|
||||
m_uavGadgetManager->emptyView(m_view);
|
||||
delete m_view;
|
||||
m_view = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void SplitterOrView::onSplitterMoved(int pos, int index)
|
||||
{
|
||||
Q_UNUSED(pos);
|
||||
@ -292,66 +268,107 @@ void SplitterOrView::onSplitterMoved(int pos, int index)
|
||||
m_sizes = m_splitter->sizes();
|
||||
}
|
||||
|
||||
void SplitterOrView::unsplitAll(IUAVGadget *currentGadget)
|
||||
void SplitterOrView::split(Qt::Orientation orientation)
|
||||
{
|
||||
Q_ASSERT(m_splitter);
|
||||
Q_ASSERT(!m_view);
|
||||
m_splitter->hide();
|
||||
m_layout->removeWidget(m_splitter); // workaround Qt bug
|
||||
unsplitAll_helper();
|
||||
delete m_splitter;
|
||||
m_splitter = 0;
|
||||
Q_ASSERT(m_view);
|
||||
Q_ASSERT(!m_splitter);
|
||||
|
||||
m_view = new UAVGadgetView(m_uavGadgetManager, currentGadget, this);
|
||||
m_layout->addWidget(m_view);
|
||||
MiniSplitter *splitter = new MiniSplitter(this);
|
||||
splitter->setOrientation(orientation);
|
||||
layout()->addWidget(splitter);
|
||||
|
||||
// [OP-1586] make sure that the view never becomes parent less otherwise a rendering bug happens
|
||||
// in osgearth QML views (not all kind of scenes are affected but those containing terrain are)
|
||||
// Making the view parent less will destroy the OpenGL context used by the QQuickFramebufferObject used OSGViewport
|
||||
// A new OpenGL context will be created but for some reason, osgearth does not switch to it gracefully.
|
||||
// Enabling the stats overlay (by pressing the 's' key in the view) will restore proper rendering (?).
|
||||
// Note : avoiding to make the view parent less is a workaround... the real cause of the rendering bug needs to be
|
||||
// understood and fixed (the same workaround is also need in unsplit and unsplitAll)
|
||||
// Important : the changes also apparently make splitting and un-splitting more reactive and less jumpy!
|
||||
|
||||
// Give our view to the new left or top SplitterOrView.
|
||||
splitter->addWidget(new SplitterOrView(*this, splitter));
|
||||
splitter->addWidget(new SplitterOrView(m_uavGadgetManager));
|
||||
|
||||
m_view = 0;
|
||||
m_splitter = splitter;
|
||||
|
||||
connect(m_splitter, SIGNAL(splitterMoved(int, int)), this, SLOT(onSplitterMoved(int, int)));
|
||||
}
|
||||
|
||||
void SplitterOrView::unsplitAll_helper()
|
||||
{
|
||||
if (m_view) {
|
||||
m_uavGadgetManager->emptyView(m_view);
|
||||
}
|
||||
if (m_splitter) {
|
||||
for (int i = 0; i < m_splitter->count(); ++i) {
|
||||
if (SplitterOrView * splitterOrView = qobject_cast<SplitterOrView *>(m_splitter->widget(i))) {
|
||||
splitterOrView->unsplitAll_helper();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SplitterOrView::unsplit()
|
||||
void SplitterOrView::unsplit(IUAVGadget *gadget)
|
||||
{
|
||||
if (!m_splitter) {
|
||||
return;
|
||||
}
|
||||
Q_ASSERT(m_splitter->count() == 1);
|
||||
SplitterOrView *childSplitterOrView = qobject_cast<SplitterOrView *>(m_splitter->widget(0));
|
||||
QSplitter *oldSplitter = m_splitter;
|
||||
m_splitter = 0;
|
||||
|
||||
if (childSplitterOrView->isSplitter()) {
|
||||
Q_ASSERT(childSplitterOrView->view() == 0);
|
||||
m_splitter = childSplitterOrView->takeSplitter();
|
||||
m_layout->addWidget(m_splitter);
|
||||
m_layout->setCurrentWidget(m_splitter);
|
||||
} else {
|
||||
UAVGadgetView *childView = childSplitterOrView->view();
|
||||
Q_ASSERT(childView);
|
||||
if (m_view) {
|
||||
if (IUAVGadget * e = childView->gadget()) {
|
||||
childView->removeGadget();
|
||||
m_view->setGadget(e);
|
||||
}
|
||||
m_uavGadgetManager->emptyView(childView);
|
||||
} else {
|
||||
m_view = childSplitterOrView->takeView();
|
||||
m_layout->addWidget(m_view);
|
||||
}
|
||||
m_layout->setCurrentWidget(m_view);
|
||||
SplitterOrView *view = findView(gadget);
|
||||
if (!view || view == this) {
|
||||
return;
|
||||
}
|
||||
|
||||
// find the other gadgets
|
||||
// TODO handle case where m_splitter->count() > 2
|
||||
SplitterOrView *splitterOrView = NULL;
|
||||
for (int i = 0; i < m_splitter->count(); ++i) {
|
||||
splitterOrView = qobject_cast<SplitterOrView *>(m_splitter->widget(i));
|
||||
if (splitterOrView && (splitterOrView != view)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (splitterOrView) {
|
||||
if (splitterOrView->isView()) {
|
||||
layout()->addWidget(splitterOrView->m_view);
|
||||
} else {
|
||||
layout()->addWidget(splitterOrView->m_splitter);
|
||||
}
|
||||
layout()->removeWidget(m_splitter);
|
||||
|
||||
m_uavGadgetManager->emptyView(view->m_view);
|
||||
delete view;
|
||||
delete m_splitter;
|
||||
|
||||
m_view = splitterOrView->m_view;
|
||||
m_splitter = splitterOrView->m_splitter;
|
||||
}
|
||||
}
|
||||
|
||||
void SplitterOrView::unsplitAll(Core::IUAVGadget *gadget)
|
||||
{
|
||||
Q_ASSERT(m_splitter);
|
||||
Q_ASSERT(!m_view);
|
||||
|
||||
SplitterOrView *splitterOrView = findView(gadget);
|
||||
if (!splitterOrView || splitterOrView == this) {
|
||||
return;
|
||||
}
|
||||
|
||||
// first re-parent the gadget (see split for an explanation)
|
||||
m_view = splitterOrView->m_view;
|
||||
layout()->addWidget(m_view);
|
||||
layout()->removeWidget(m_splitter);
|
||||
// make sure the old m_view is not emptied...
|
||||
splitterOrView->m_view = NULL;
|
||||
|
||||
// cleanup
|
||||
unsplitAll_helper(m_uavGadgetManager, m_splitter);
|
||||
|
||||
delete m_splitter;
|
||||
m_splitter = 0;
|
||||
}
|
||||
|
||||
void SplitterOrView::unsplitAll_helper(UAVGadgetManager *uavGadgetManager, QSplitter *splitter)
|
||||
{
|
||||
for (int i = 0; i < splitter->count(); ++i) {
|
||||
if (SplitterOrView * splitterOrView = qobject_cast<SplitterOrView *>(splitter->widget(i))) {
|
||||
if (splitterOrView->m_view) {
|
||||
uavGadgetManager->emptyView(splitterOrView->m_view);
|
||||
}
|
||||
if (splitterOrView->m_splitter) {
|
||||
unsplitAll_helper(uavGadgetManager, splitterOrView->m_splitter);
|
||||
}
|
||||
delete splitterOrView;
|
||||
}
|
||||
}
|
||||
delete oldSplitter;
|
||||
m_uavGadgetManager->setCurrentGadget(findFirstView()->gadget());
|
||||
}
|
||||
|
||||
void SplitterOrView::saveState(QSettings *qSettings) const
|
||||
|
@ -43,7 +43,11 @@ public:
|
||||
~SplitterOrView();
|
||||
|
||||
void split(Qt::Orientation orientation);
|
||||
void unsplit();
|
||||
|
||||
void unsplit(IUAVGadget *gadget);
|
||||
|
||||
// un-split all and keep only the specified gadget
|
||||
void unsplitAll(IUAVGadget *gadget);
|
||||
|
||||
inline bool isView() const
|
||||
{
|
||||
@ -95,10 +99,7 @@ public:
|
||||
}
|
||||
QSize minimumSizeHint() const;
|
||||
|
||||
void unsplitAll(IUAVGadget *currentGadget);
|
||||
|
||||
protected:
|
||||
// void paintEvent(QPaintEvent *);
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
|
||||
private slots:
|
||||
@ -106,19 +107,19 @@ private slots:
|
||||
void onSplitterMoved(int pos, int index);
|
||||
|
||||
private:
|
||||
void unsplitAll_helper();
|
||||
// private "copy" constructor
|
||||
SplitterOrView(SplitterOrView &splitterOrView, QWidget *parent);
|
||||
|
||||
static void unsplitAll_helper(UAVGadgetManager *uavGadgetManager, QSplitter *splitter);
|
||||
SplitterOrView *findNextView_helper(SplitterOrView *view, bool *found);
|
||||
|
||||
// The gadget manager that controls us.
|
||||
QPointer<UAVGadgetManager> m_uavGadgetManager;
|
||||
|
||||
// Our layout, we use stacked so we can change stuff without visual artifacts (I think...)
|
||||
QPointer<QStackedLayout> m_layout;
|
||||
|
||||
// Our view, if we are a view (showing 1 gadget) and not a splitter.
|
||||
QPointer<UAVGadgetView> m_view;
|
||||
|
||||
// Out splitter, if we are a splitter.
|
||||
// Our splitter, if we are a splitter.
|
||||
QPointer<QSplitter> m_splitter;
|
||||
|
||||
// The splitter sizes. We keep our own copy of these, since after loading they can't realiably be retrieved.
|
||||
|
@ -108,7 +108,7 @@ UAVGadgetManager::UAVGadgetManager(ICore *core, QString name, QIcon icon, int pr
|
||||
this, SLOT(modeChanged(Core::IMode *)));
|
||||
|
||||
// other setup
|
||||
m_splitterOrView = new SplitterOrView(this, 0);
|
||||
m_splitterOrView = new SplitterOrView(this);
|
||||
|
||||
// SplitterOrView with 0 as gadget calls our setCurrentGadget, which relies on currentSplitterOrView(),
|
||||
// which needs our m_splitterorView to be set, which isn't set yet at that time.
|
||||
@ -209,10 +209,10 @@ void UAVGadgetManager::emptyView(Core::Internal::UAVGadgetView *view)
|
||||
}
|
||||
|
||||
IUAVGadget *uavGadget = view->gadget();
|
||||
// emit uavGadgetAboutToClose(uavGadget);
|
||||
// emit uavGadgetAboutToClose(uavGadget);
|
||||
removeGadget(uavGadget);
|
||||
view->removeGadget();
|
||||
// emit uavGadgetsClosed(uavGadgets);
|
||||
// emit uavGadgetsClosed(uavGadgets);
|
||||
}
|
||||
|
||||
|
||||
@ -221,27 +221,22 @@ void UAVGadgetManager::closeView(Core::Internal::UAVGadgetView *view)
|
||||
if (!view) {
|
||||
return;
|
||||
}
|
||||
SplitterOrView *splitterOrView = m_splitterOrView->findView(view);
|
||||
Q_ASSERT(splitterOrView);
|
||||
Q_ASSERT(splitterOrView->view() == view);
|
||||
if (splitterOrView == m_splitterOrView) {
|
||||
return;
|
||||
}
|
||||
|
||||
IUAVGadget *gadget = view->gadget();
|
||||
emptyView(view);
|
||||
|
||||
// find SplitterOrView splitter that contains the view to delete
|
||||
SplitterOrView *splitter = m_splitterOrView->findSplitter(gadget);
|
||||
if (!splitter) {
|
||||
return;
|
||||
}
|
||||
Q_ASSERT(splitter->isSplitter() == true);
|
||||
|
||||
splitter->unsplit(gadget);
|
||||
|
||||
UAVGadgetInstanceManager *im = ICore::instance()->uavGadgetInstanceManager();
|
||||
im->removeGadget(gadget);
|
||||
|
||||
SplitterOrView *splitter = m_splitterOrView->findSplitter(splitterOrView);
|
||||
Q_ASSERT(splitterOrView->hasGadget() == false);
|
||||
Q_ASSERT(splitter->isSplitter() == true);
|
||||
splitterOrView->hide();
|
||||
delete splitterOrView;
|
||||
|
||||
splitter->unsplit();
|
||||
|
||||
SplitterOrView *newCurrent = splitter->findFirstView();
|
||||
SplitterOrView *newCurrent = splitter->findFirstView();
|
||||
Q_ASSERT(newCurrent);
|
||||
if (newCurrent) {
|
||||
setCurrentGadget(newCurrent->gadget());
|
||||
@ -254,8 +249,7 @@ void UAVGadgetManager::addGadgetToContext(IUAVGadget *gadget)
|
||||
return;
|
||||
}
|
||||
m_core->addContextObject(gadget);
|
||||
|
||||
// emit uavGadgetOpened(uavGadget);
|
||||
// emit uavGadgetOpened(uavGadget);
|
||||
}
|
||||
|
||||
void UAVGadgetManager::removeGadget(IUAVGadget *gadget)
|
||||
|
@ -303,12 +303,12 @@ void NotifyPluginOptionsPage::addDynamicFieldWidget(UAVObjectField *objField)
|
||||
if (NotifyPluginOptionsPage::conditionValues.indexOf(_dynamicFieldCondition->currentText()) == NotifyPluginOptionsPage::inrange) {
|
||||
_dynamicFieldWidget = new QLineEdit(_form);
|
||||
|
||||
(static_cast<QLineEdit *>(_dynamicFieldWidget))->setInputMask("#999.99 : #999.99;");
|
||||
(static_cast<QLineEdit *>(_dynamicFieldWidget))->setInputMask("#99999.99 : #99999.99;");
|
||||
(static_cast<QLineEdit *>(_dynamicFieldWidget))->setText("0000000000");
|
||||
(static_cast<QLineEdit *>(_dynamicFieldWidget))->setCursorPosition(0);
|
||||
} else {
|
||||
_dynamicFieldWidget = new QDoubleSpinBox(_form);
|
||||
(dynamic_cast<QDoubleSpinBox *>(_dynamicFieldWidget))->setRange(-999.99, 999.99);
|
||||
(dynamic_cast<QDoubleSpinBox *>(_dynamicFieldWidget))->setRange(-99999.99, 99999.99);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1296,8 +1296,9 @@ int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index
|
||||
}
|
||||
|
||||
|
||||
HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
|
||||
HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
|
||||
{
|
||||
(void)dev; // avoid unused arg warning
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -166,6 +166,7 @@ static void free_hid_device(hid_device *dev)
|
||||
|
||||
static void register_error(hid_device *device, const char *op)
|
||||
{
|
||||
(void)op; // avoid unused arg warning
|
||||
WCHAR *ptr, *msg;
|
||||
|
||||
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
@ -232,7 +233,7 @@ static HANDLE open_device(const char *path, BOOL enumerate)
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_OVERLAPPED,/*FILE_ATTRIBUTE_NORMAL,*/
|
||||
0);
|
||||
DWORD error = GetLastError();
|
||||
/*DWORD error =*/ GetLastError();
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
@ -27,9 +27,9 @@
|
||||
|
||||
#ifndef OPHID_CONST_H
|
||||
#define OPHID_CONST_H
|
||||
#include "QtDebug"
|
||||
|
||||
#define OPHID_DEBUG_ON 1
|
||||
#include <QDebug>
|
||||
|
||||
#ifdef OPHID_DEBUG_ON
|
||||
#define OPHID_DEBUG(fmt, args ...) qDebug("[DEBUG] "fmt,##args)
|
||||
#define OPHID_TRACE(fmt, args ...) qDebug("[TRACE] %s:%s:%d: "fmt, __FILE__, __func__, __LINE__,##args)
|
||||
@ -42,7 +42,6 @@
|
||||
#define OPHID_WARNING(fmt, args ...)
|
||||
#endif
|
||||
|
||||
|
||||
// USB
|
||||
#define USB_MAX_DEVICES 10
|
||||
#define USB_VID 0x20A0
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <QDebug>
|
||||
#include <QString>
|
||||
#include <QMutex>
|
||||
#include "../hidapi/hidapi.h"
|
||||
|
@ -1,24 +1,31 @@
|
||||
TEMPLATE = lib
|
||||
TARGET = opHID
|
||||
|
||||
DEFINES += OPHID_LIBRARY
|
||||
|
||||
//DEFINES += OPHID_DEBUG_ON
|
||||
|
||||
include(../../openpilotgcsplugin.pri)
|
||||
include(ophid_dependencies.pri)
|
||||
|
||||
HEADERS += inc/ophid_global.h \
|
||||
inc/ophid_plugin.h \
|
||||
inc/ophid.h \
|
||||
inc/ophid_hidapi.h \
|
||||
inc/ophid_const.h \
|
||||
inc/ophid_usbmon.h \
|
||||
inc/ophid_usbsignal.h \
|
||||
hidapi/hidapi.h
|
||||
SOURCES += src/ophid_plugin.cpp \
|
||||
src/ophid.cpp \
|
||||
src/ophid_usbsignal.cpp \
|
||||
src/ophid_hidapi.cpp
|
||||
HEADERS += \
|
||||
inc/ophid_global.h \
|
||||
inc/ophid_plugin.h \
|
||||
inc/ophid.h \
|
||||
inc/ophid_hidapi.h \
|
||||
inc/ophid_const.h \
|
||||
inc/ophid_usbmon.h \
|
||||
inc/ophid_usbsignal.h \
|
||||
hidapi/hidapi.h
|
||||
|
||||
SOURCES += \
|
||||
src/ophid_plugin.cpp \
|
||||
src/ophid.cpp \
|
||||
src/ophid_usbsignal.cpp \
|
||||
src/ophid_hidapi.cpp
|
||||
|
||||
FORMS +=
|
||||
RESOURCES +=
|
||||
DEFINES += OPHID_LIBRARY
|
||||
OTHER_FILES += opHID.pluginspec
|
||||
|
||||
INCLUDEPATH += ./inc
|
||||
@ -26,25 +33,30 @@ INCLUDEPATH += ./inc
|
||||
# Platform Specific
|
||||
|
||||
win32 {
|
||||
SOURCES += src/ophid_usbmon_win.cpp \
|
||||
hidapi/windows/hid.c
|
||||
SOURCES += \
|
||||
src/ophid_usbmon_win.cpp \
|
||||
hidapi/windows/hid.c
|
||||
|
||||
LIBS += -lhid -lsetupapi
|
||||
}
|
||||
|
||||
macx {
|
||||
SOURCES += src/ophid_usbmon_mac.cpp \
|
||||
hidapi/mac/hid.c
|
||||
LIBS += -framework CoreFoundation \
|
||||
-framework IOKit
|
||||
SOURCES += \
|
||||
src/ophid_usbmon_mac.cpp \
|
||||
hidapi/mac/hid.c
|
||||
|
||||
LIBS += -framework CoreFoundation -framework IOKit
|
||||
}
|
||||
|
||||
linux {
|
||||
SOURCES += src/ophid_usbmon_linux.cpp
|
||||
SOURCES += \
|
||||
src/ophid_usbmon_linux.cpp
|
||||
|
||||
LIBS += -ludev -lrt -lpthread
|
||||
|
||||
# hidapi library
|
||||
## rawhid
|
||||
# SOURCES += hidapi/linux/hid.c
|
||||
#SOURCES += hidapi/linux/hid.c
|
||||
## libusb
|
||||
SOURCES += hidapi/libusb/hid.c
|
||||
|
||||
|
@ -146,7 +146,7 @@ RawHIDReadThread::~RawHIDReadThread()
|
||||
m_running = false;
|
||||
// wait for the thread to terminate
|
||||
if (wait(10000) == false) {
|
||||
qDebug() << "Cannot terminate RawHIDReadThread";
|
||||
qWarning() << "Cannot terminate RawHIDReadThread";
|
||||
}
|
||||
}
|
||||
|
||||
@ -219,7 +219,7 @@ RawHIDWriteThread::~RawHIDWriteThread()
|
||||
m_running = false;
|
||||
// wait for the thread to terminate
|
||||
if (wait(10000) == false) {
|
||||
qDebug() << "Cannot terminate RawHIDReadThread";
|
||||
qWarning() << "Cannot terminate RawHIDReadThread";
|
||||
}
|
||||
}
|
||||
|
||||
@ -264,9 +264,9 @@ void RawHIDWriteThread::run()
|
||||
} else if (ret < 0) { // < 0 => error
|
||||
// TODO! make proper error handling, this only quick hack for unplug freeze
|
||||
m_running = false;
|
||||
qDebug() << "Error writing to device (" << ret << ")";
|
||||
qCritical() << "Error writing to device (" << ret << ")";
|
||||
} else {
|
||||
qDebug() << "No data written to device ??";
|
||||
qCritical() << "No data written to device ??";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -129,6 +129,10 @@ int opHID_hidapi::enumerate(struct hid_device_info * *current_device_pptr, int *
|
||||
*/
|
||||
int opHID_hidapi::open(int max, int vid, int pid, int usage_page, int usage)
|
||||
{
|
||||
Q_UNUSED(max);
|
||||
Q_UNUSED(usage_page);
|
||||
Q_UNUSED(usage);
|
||||
|
||||
int devices_found = false;
|
||||
struct hid_device_info *current_device_ptr = NULL;
|
||||
struct hid_device_info *tmp_device_ptr = NULL;
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include "ophid_hidapi.h"
|
||||
#include "ophid_const.h"
|
||||
|
||||
|
||||
/**
|
||||
* \brief Constructor
|
||||
*
|
||||
@ -95,7 +94,7 @@ void RawHIDConnection::onDeviceConnected()
|
||||
*/
|
||||
void RawHIDConnection::onDeviceDisconnected()
|
||||
{
|
||||
qDebug() << "onDeviceDisconnected()";
|
||||
OPHID_DEBUG("onDeviceDisconnected()");
|
||||
if (enablePolling) {
|
||||
emit availableDevChanged(this);
|
||||
}
|
||||
|
@ -26,7 +26,6 @@
|
||||
*/
|
||||
|
||||
#include "ophid_usbmon.h"
|
||||
#include <QDebug>
|
||||
#include "ophid_const.h"
|
||||
|
||||
|
||||
@ -41,6 +40,8 @@
|
||||
*/
|
||||
void printPortInfo(struct udev_device *dev)
|
||||
{
|
||||
Q_UNUSED(dev);
|
||||
|
||||
OPHID_DEBUG(" Node: %s", udev_device_get_devnode(dev));
|
||||
OPHID_DEBUG(" Subsystem: %s", udev_device_get_subsystem(dev));
|
||||
OPHID_DEBUG(" Devtype: %s", udev_device_get_devtype(dev));
|
||||
@ -73,7 +74,7 @@ void USBMonitor::deviceEventReceived()
|
||||
// this->monitorNotifier->setEnabled(0);
|
||||
QString action = QString(udev_device_get_action(dev));
|
||||
QString devtype = QString(udev_device_get_devtype(dev));
|
||||
qDebug() << "[DEBUG] Action: " << action << " device: " << devtype;
|
||||
OPHID_DEBUG("Action: %s device: %s", qPrintable(action), qPrintable(devtype));
|
||||
if (action == "add" && devtype == "usb_device") {
|
||||
printPortInfo(dev);
|
||||
emit deviceDiscovered(makePortInfo(dev));
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include <CoreFoundation/CFString.h>
|
||||
#include <CoreFoundation/CFArray.h>
|
||||
#include <QMutexLocker>
|
||||
#include <QDebug>
|
||||
#include "ophid_const.h"
|
||||
|
||||
// Local helper functions
|
||||
@ -72,7 +71,7 @@ USBMonitor::~USBMonitor()
|
||||
*/
|
||||
void USBMonitor::deviceEventReceived()
|
||||
{
|
||||
qDebug() << "Device event";
|
||||
OPHID_DEBUG("Device event");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -119,7 +118,7 @@ void USBMonitor::detach_callback(void *context, IOReturn r, void *hid_mgr, IOHID
|
||||
Q_UNUSED(r);
|
||||
Q_UNUSED(hid_mgr);
|
||||
|
||||
qDebug() << "USBMonitor: Device detached event";
|
||||
OPHID_DEBUG("USBMonitor: Device detached event");
|
||||
instance()->removeDevice(dev);
|
||||
}
|
||||
|
||||
@ -156,7 +155,7 @@ void USBMonitor::attach_callback(void *context, IOReturn r, void *hid_mgr, IOHID
|
||||
|
||||
deviceInfo.dev_handle = dev;
|
||||
|
||||
qDebug() << "USBMonitor: Device attached event";
|
||||
OPHID_DEBUG("USBMonitor: Device attached event");
|
||||
|
||||
// Populate the device info structure
|
||||
got_properties &= HID_GetIntProperty(dev, CFSTR(kIOHIDVendorIDKey), &deviceInfo.vendorID);
|
||||
@ -171,7 +170,7 @@ void USBMonitor::attach_callback(void *context, IOReturn r, void *hid_mgr, IOHID
|
||||
|
||||
// Currently only enumerating objects that have the complete list of properties
|
||||
if (got_properties) {
|
||||
qDebug() << "USBMonitor: Adding device";
|
||||
OPHID_DEBUG("USBMonitor: Adding device");
|
||||
instance()->addDevice(deviceInfo);
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include <QEventLoop>
|
||||
#include <QTimer>
|
||||
#include "ophid_usbmon.h"
|
||||
#include <QDebug>
|
||||
#include "ophid_const.h"
|
||||
|
||||
/* Gordon Schumacher's macros for TCHAR -> QString conversions and vice versa */
|
||||
@ -122,11 +121,9 @@ QList<USBPortInfo> USBMonitor::availableDevices(int vid, int pid, int bcdDeviceM
|
||||
OPHID_TRACE("IN");
|
||||
|
||||
// Print the list
|
||||
qDebug() << "List off (" << knowndevices.length() << ") devices that are tracked:";
|
||||
OPHID_DEBUG("List off (%d) devices that are tracked:", knowndevices.length());
|
||||
foreach(USBPortInfo info, knowndevices /*thePortsWeWant*/) {
|
||||
qDebug() << "product:" << info.product
|
||||
<< " bcdDevice:" << info.bcdDevice
|
||||
<< " devicePath:" << info.devicePath;
|
||||
OPHID_DEBUG("product: %s bcdDevice: %d devicePath: %s", qPrintable(info.product), info.bcdDevice, qPrintable(info.devicePath));
|
||||
|
||||
// Filter to return only the one request (if exists)
|
||||
if ((info.vendorID == vid || vid == -1) &&
|
||||
@ -249,7 +246,7 @@ bool USBMonitor::matchAndDispatchChangedDevice(const QString & deviceID, const G
|
||||
{
|
||||
OPHID_TRACE("IN");
|
||||
|
||||
qDebug() << "[STATUS CHANGE] from device ID: " << deviceID;
|
||||
OPHID_DEBUG("[STATUS CHANGE] from device ID: %s", qPrintable(deviceID));
|
||||
bool rc;
|
||||
SP_DEVINFO_DATA spDevInfoData;
|
||||
DWORD dwFlag = (DBT_DEVICEARRIVAL == wParam) ? DIGCF_PRESENT : 0 /*DIGCF_ALLCLASSES*/;
|
||||
@ -263,13 +260,13 @@ bool USBMonitor::matchAndDispatchChangedDevice(const QString & deviceID, const G
|
||||
DWORD nSize = 0;
|
||||
TCHAR buf[MAX_PATH];
|
||||
rc = SetupDiGetDeviceInstanceId(devInfo, &spDevInfoData, buf, MAX_PATH, &nSize);
|
||||
qDebug() << "Found:" << TCHARToQString(buf);
|
||||
OPHID_DEBUG("Found: %s", qPrintable(TCHARToQString(buf)));
|
||||
if (rc && deviceID.contains(TCHARToQString(buf))) {
|
||||
qDebug() << "[MATCH] " << TCHARToQString(buf);
|
||||
OPHID_DEBUG("[MATCH] %s", qPrintable(TCHARToQString(buf)));
|
||||
USBPortInfo info;
|
||||
info.devicePath = deviceID;
|
||||
if (wParam == DBT_DEVICEARRIVAL) {
|
||||
qDebug() << "[INSERTED]";
|
||||
OPHID_DEBUG("[INSERTED]");
|
||||
if (infoFromHandle(guid, info, devInfo, i) != OPHID_NO_ERROR) {
|
||||
OPHID_ERROR("Not found");
|
||||
break;
|
||||
@ -290,18 +287,14 @@ bool USBMonitor::matchAndDispatchChangedDevice(const QString & deviceID, const G
|
||||
break;
|
||||
}
|
||||
knowndevices.append(info);
|
||||
qDebug() << "[SIGNAL] Device discovered on device:"
|
||||
<< info.product
|
||||
<< info.bcdDevice;
|
||||
OPHID_DEBUG("[SIGNAL] Device discovered on device: %s %d", qPrintable(info.product), info.bcdDevice);
|
||||
emit deviceDiscovered(info);
|
||||
break;
|
||||
} else if (wParam == DBT_DEVICEREMOVECOMPLETE) {
|
||||
for (int x = 0; x < knowndevices.count(); ++x) {
|
||||
USBPortInfo temp = knowndevices.at(x);
|
||||
knowndevices.removeAt(x);
|
||||
qDebug() << "[SIGNAL] Device removed on device:"
|
||||
<< temp.product
|
||||
<< temp.bcdDevice;
|
||||
OPHID_DEBUG("[SIGNAL] Device removed on device: %s %d", qPrintable(temp.product), temp.bcdDevice);
|
||||
}
|
||||
emit deviceRemoved(info);
|
||||
break;
|
||||
@ -362,7 +355,7 @@ void USBMonitor::enumerateDevicesWin(const GUID & guid)
|
||||
}
|
||||
SetupDiDestroyDeviceInfoList(devInfo);
|
||||
}
|
||||
OPHID_DEBUG("Added %d device(s).", j);
|
||||
OPHID_DEBUG("Added %lu device(s).", j);
|
||||
OPHID_TRACE("OUT");
|
||||
}
|
||||
|
||||
@ -429,7 +422,7 @@ int USBMonitor::infoFromHandle(const GUID & guid, USBPortInfo & info, HDEVINFO &
|
||||
goto leave;
|
||||
}
|
||||
|
||||
qDebug() << "Found device with valid PATH: " << qDevicePath;
|
||||
OPHID_DEBUG("Found device with valid PATH: %s", qPrintable(qDevicePath));
|
||||
h = CreateFile(details->DevicePath,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
@ -449,8 +442,7 @@ int USBMonitor::infoFromHandle(const GUID & guid, USBPortInfo & info, HDEVINFO &
|
||||
goto leave;
|
||||
}
|
||||
|
||||
qDebug() << "Problem opening handle, path: "
|
||||
<< QString().fromWCharArray(details->DevicePath);
|
||||
OPHID_DEBUG("Problem opening handle, path: %s", qPrintable(QString::fromWCharArray(details->DevicePath)));
|
||||
|
||||
free(details);
|
||||
ret = OPHID_ERROR_RET;
|
||||
|
@ -26,8 +26,7 @@
|
||||
*/
|
||||
|
||||
#include "ophid_usbsignal.h"
|
||||
#include <QDebug>
|
||||
|
||||
#include "ophid_const.h"
|
||||
|
||||
/**
|
||||
* \brief trigger device discovered signal
|
||||
@ -42,7 +41,7 @@ void USBSignalFilter::m_deviceDiscovered(USBPortInfo port)
|
||||
(port.productID == m_pid || m_pid == -1) &&
|
||||
((port.bcdDevice >> 8) == m_boardModel || m_boardModel == -1) &&
|
||||
((port.bcdDevice & 0x00ff) == m_runState || m_runState == -1)) {
|
||||
qDebug() << "USBSignalFilter emit device discovered";
|
||||
OPHID_DEBUG("USBSignalFilter emit device discovered");
|
||||
emit deviceDiscovered();
|
||||
}
|
||||
}
|
||||
|
@ -35,58 +35,30 @@
|
||||
|
||||
AirframeInitialTuningPage::AirframeInitialTuningPage(SetupWizard *wizard, QWidget *parent) :
|
||||
AbstractWizardPage(wizard, parent),
|
||||
ui(new Ui::AirframeInitialTuningPage), m_dir(NULL), m_photoItem(NULL)
|
||||
ui(new Ui::AirframeInitialTuningPage)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->templateImage->setScene(new QGraphicsScene());
|
||||
connect(ui->templateList, SIGNAL(itemSelectionChanged()), this, SLOT(templateSelectionChanged()));
|
||||
}
|
||||
|
||||
AirframeInitialTuningPage::~AirframeInitialTuningPage()
|
||||
{
|
||||
ui->templateList->clear();
|
||||
foreach(QJsonObject * templ, m_templates.values()) {
|
||||
delete templ;
|
||||
}
|
||||
m_templates.clear();
|
||||
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void AirframeInitialTuningPage::initializePage()
|
||||
{
|
||||
switch (getWizard()->getVehicleType()) {
|
||||
case VehicleConfigurationSource::VEHICLE_FIXEDWING:
|
||||
m_dir = VehicleTemplateExportDialog::EXPORT_FIXEDWING_NAME;
|
||||
break;
|
||||
case VehicleConfigurationSource::VEHICLE_MULTI:
|
||||
m_dir = VehicleTemplateExportDialog::EXPORT_MULTI_NAME;
|
||||
break;
|
||||
case VehicleConfigurationSource::VEHICLE_HELI:
|
||||
m_dir = VehicleTemplateExportDialog::EXPORT_HELI_NAME;
|
||||
break;
|
||||
case VehicleConfigurationSource::VEHICLE_SURFACE:
|
||||
m_dir = VehicleTemplateExportDialog::EXPORT_SURFACE_NAME;
|
||||
break;
|
||||
default:
|
||||
m_dir = NULL;
|
||||
break;
|
||||
}
|
||||
loadValidFiles();
|
||||
setupTemplateList();
|
||||
ui->selectorWidget->setTemplateInfo(getWizard()->getVehicleType(), getWizard()->getVehicleSubType());
|
||||
}
|
||||
|
||||
bool AirframeInitialTuningPage::validatePage()
|
||||
{
|
||||
QJsonObject *templ = NULL;
|
||||
QJsonObject *templ = ui->selectorWidget->selectedTemplate();
|
||||
|
||||
if (ui->templateList->currentRow() >= 0) {
|
||||
templ = ui->templateList->item(ui->templateList->currentRow())->data(Qt::UserRole + 1).value<QJsonObject *>();
|
||||
}
|
||||
if (getWizard()->getVehicleTemplate() != NULL) {
|
||||
delete getWizard()->getVehicleTemplate();
|
||||
}
|
||||
getWizard()->setVehicleTemplate(templ != NULL ? new QJsonObject(*templ) : NULL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -94,159 +66,3 @@ bool AirframeInitialTuningPage::isComplete() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void AirframeInitialTuningPage::updatePhoto(QJsonObject *templ)
|
||||
{
|
||||
QPixmap photo;
|
||||
|
||||
if (m_photoItem != NULL) {
|
||||
ui->templateImage->scene()->removeItem(m_photoItem);
|
||||
}
|
||||
if (templ != NULL && !templ->value("photo").isUndefined()) {
|
||||
QByteArray imageData = QByteArray::fromBase64(templ->value("photo").toString().toLatin1());
|
||||
photo.loadFromData(imageData, "PNG");
|
||||
} else {
|
||||
photo.load(":/core/images/openpilot_logo_500.png");
|
||||
}
|
||||
m_photoItem = ui->templateImage->scene()->addPixmap(photo);
|
||||
ui->templateImage->setSceneRect(ui->templateImage->scene()->itemsBoundingRect());
|
||||
ui->templateImage->fitInView(ui->templateImage->scene()->itemsBoundingRect(), Qt::KeepAspectRatio);
|
||||
}
|
||||
|
||||
void AirframeInitialTuningPage::updateDescription(QJsonObject *templ)
|
||||
{
|
||||
if (templ != NULL) {
|
||||
QString description;
|
||||
description.append("<b>").append(tr("Name of Vehicle: ")).append("</b>").append(templ->value("name").toString()).append("<br>");
|
||||
description.append("<b>").append(tr("Name of Owner: ")).append("</b>").append(templ->value("owner").toString());
|
||||
if (templ->value("nick") != QStringLiteral("")) {
|
||||
description.append(" (").append(templ->value("nick").toString()).append(")");
|
||||
}
|
||||
description.append("<br>");
|
||||
description.append("<b>").append(tr("Size: ")).append("</b>").append(templ->value("size").toString()).append("<br>");
|
||||
description.append("<b>").append(tr("Weight: ")).append("</b>").append(templ->value("weight").toString()).append("<br>");
|
||||
description.append("<b>").append(tr("Motor(s): ")).append("</b>").append(templ->value("motor").toString()).append("<br>");
|
||||
description.append("<b>").append(tr("ESC(s): ")).append("</b>").append(templ->value("esc").toString()).append("<br>");
|
||||
description.append("<b>").append(tr("Servo(s): ")).append("</b>").append(templ->value("servo").toString()).append("<br>");
|
||||
description.append("<b>").append(tr("Battery: ")).append("</b>").append(templ->value("battery").toString()).append("<br>");
|
||||
description.append("<b>").append(tr("Propellers(s): ")).append("</b>").append(templ->value("propeller").toString()).append("<br>");
|
||||
description.append("<b>").append(tr("Controller: ")).append("</b>").append(templ->value("controller").toString()).append("<br>");
|
||||
description.append("<b>").append(tr("Comments: ")).append("</b>").append(templ->value("comment").toString());
|
||||
ui->templateDescription->setText(description);
|
||||
} else {
|
||||
ui->templateDescription->setText(tr("This option will use the current tuning settings saved on the controller, if your controller "
|
||||
"is currently unconfigured, then the OpenPilot firmware defaults will be used.\n\n"
|
||||
"It is suggested that if this is a first time configuration of your controller, rather than "
|
||||
"use this option, instead select a tuning set that matches your own airframe as close as "
|
||||
"possible from the list above or if you are not able to fine one, then select the generic item "
|
||||
"from the list."));
|
||||
}
|
||||
}
|
||||
|
||||
void AirframeInitialTuningPage::templateSelectionChanged()
|
||||
{
|
||||
if (ui->templateList->currentRow() >= 0) {
|
||||
QJsonObject *templ = ui->templateList->item(ui->templateList->currentRow())->data(Qt::UserRole + 1).value<QJsonObject *>();
|
||||
updatePhoto(templ);
|
||||
updateDescription(templ);
|
||||
}
|
||||
}
|
||||
|
||||
bool AirframeInitialTuningPage::airframeIsCompatible(int vehicleType, int vehicleSubType)
|
||||
{
|
||||
if (vehicleType != getWizard()->getVehicleType()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int wizSubType = getWizard()->getVehicleSubType();
|
||||
switch (vehicleType) {
|
||||
case VehicleConfigurationSource::MULTI_ROTOR_QUAD_X:
|
||||
{
|
||||
return wizSubType == VehicleConfigurationSource::MULTI_ROTOR_QUAD_X;
|
||||
}
|
||||
default:
|
||||
return vehicleSubType == wizSubType;
|
||||
}
|
||||
}
|
||||
|
||||
void AirframeInitialTuningPage::loadFilesInDir(QString templateBasePath)
|
||||
{
|
||||
QDir templateDir(templateBasePath);
|
||||
|
||||
qDebug() << "Loading templates from base path:" << templateBasePath;
|
||||
QStringList names;
|
||||
names << "*.optmpl";
|
||||
templateDir.setNameFilters(names);
|
||||
templateDir.setSorting(QDir::Name);
|
||||
QStringList files = templateDir.entryList();
|
||||
foreach(QString fileName, files) {
|
||||
QFile file(QString("%1/%2").arg(templateDir.absolutePath()).arg(fileName));
|
||||
|
||||
if (file.open(QFile::ReadOnly)) {
|
||||
QByteArray jsonData = file.readAll();
|
||||
QJsonParseError error;
|
||||
QJsonDocument templateDoc = QJsonDocument::fromJson(jsonData, &error);
|
||||
if (error.error == QJsonParseError::NoError) {
|
||||
QJsonObject json = templateDoc.object();
|
||||
if (airframeIsCompatible(json["type"].toInt(), json["subtype"].toInt())) {
|
||||
QString uuid = json["uuid"].toString();
|
||||
if (!m_templates.contains(uuid)) {
|
||||
m_templates[json["uuid"].toString()] = new QJsonObject(json);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
qDebug() << "Error parsing json file: "
|
||||
<< fileName << ". Error was:" << error.errorString();
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
void AirframeInitialTuningPage::loadValidFiles()
|
||||
{
|
||||
ui->templateList->clear();
|
||||
foreach(QJsonObject * templ, m_templates.values()) {
|
||||
delete templ;
|
||||
}
|
||||
m_templates.clear();
|
||||
|
||||
loadFilesInDir(QString("%1/%2/").arg(Utils::PathUtils().InsertDataPath("%%DATAPATH%%cloudconfig")).arg(m_dir));
|
||||
loadFilesInDir(QString("%1/%2/").arg(Utils::PathUtils().InsertStoragePath("%%STOREPATH%%cloudconfig")).arg(m_dir));
|
||||
}
|
||||
|
||||
void AirframeInitialTuningPage::setupTemplateList()
|
||||
{
|
||||
QListWidgetItem *item;
|
||||
|
||||
foreach(QString templ, m_templates.keys()) {
|
||||
QJsonObject *json = m_templates[templ];
|
||||
|
||||
item = new QListWidgetItem(json->value("name").toString(), ui->templateList);
|
||||
item->setData(Qt::UserRole + 1, QVariant::fromValue(json));
|
||||
}
|
||||
ui->templateList->sortItems(Qt::AscendingOrder);
|
||||
|
||||
item = new QListWidgetItem(tr("Current Tuning"));
|
||||
item->setData(Qt::UserRole + 1, QVariant::fromValue((QJsonObject *)NULL));
|
||||
ui->templateList->insertItem(0, item);
|
||||
ui->templateList->setCurrentRow(0);
|
||||
// TODO Add generics to top under item Current tuning
|
||||
}
|
||||
|
||||
QString AirframeInitialTuningPage::getTemplateKey(QJsonObject *templ)
|
||||
{
|
||||
return QString(templ->value("name").toString());
|
||||
}
|
||||
|
||||
void AirframeInitialTuningPage::resizeEvent(QResizeEvent *)
|
||||
{
|
||||
ui->templateImage->setSceneRect(ui->templateImage->scene()->itemsBoundingRect());
|
||||
ui->templateImage->fitInView(ui->templateImage->scene()->itemsBoundingRect(), Qt::KeepAspectRatio);
|
||||
}
|
||||
|
||||
void AirframeInitialTuningPage::showEvent(QShowEvent *)
|
||||
{
|
||||
ui->templateImage->setSceneRect(ui->templateImage->scene()->itemsBoundingRect());
|
||||
ui->templateImage->fitInView(ui->templateImage->scene()->itemsBoundingRect(), Qt::KeepAspectRatio);
|
||||
}
|
||||
|
@ -44,28 +44,9 @@ public:
|
||||
void initializePage();
|
||||
bool validatePage();
|
||||
bool isComplete() const;
|
||||
public slots:
|
||||
void templateSelectionChanged();
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *);
|
||||
void showEvent(QShowEvent *);
|
||||
|
||||
private:
|
||||
Ui::AirframeInitialTuningPage *ui;
|
||||
const char *m_dir;
|
||||
QMap<QString, QJsonObject *> m_templates;
|
||||
QGraphicsPixmapItem *m_photoItem;
|
||||
|
||||
void loadValidFiles();
|
||||
void loadFilesInDir(QString templateBasePath);
|
||||
void setupTemplateList();
|
||||
QString getTemplateKey(QJsonObject *templ);
|
||||
void updatePhoto(QJsonObject *templ);
|
||||
void updateDescription(QJsonObject *templ);
|
||||
bool airframeIsCompatible(int vehicleType, int vehicleSubType);
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(QJsonObject *)
|
||||
|
||||
#endif // AIRFRAMEINITIALTUNINGPAGE_H
|
||||
|
@ -33,72 +33,25 @@ p, li { white-space: pre-wrap; }
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="2,0">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,4">
|
||||
<item>
|
||||
<widget class="QListWidget" name="templateList">
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGraphicsView" name="templateImage">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>250</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: rgba(254, 254, 254, 0);</string>
|
||||
</property>
|
||||
<property name="interactive">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="renderHints">
|
||||
<set>QPainter::Antialiasing|QPainter::HighQualityAntialiasing|QPainter::TextAntialiasing</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="templateDescription">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="undoRedoEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>Information about the Vehicle in short.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
<widget class="VehicleTemplateSelectorWidget" name="selectorWidget" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>VehicleTemplateSelectorWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>vehicletemplateselectorwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
@ -41,7 +41,8 @@ HEADERS += setupwizardplugin.h \
|
||||
pages/servopage.h \
|
||||
pages/selectionpage.h \
|
||||
pages/airframeinitialtuningpage.h \
|
||||
vehicletemplateexportdialog.h
|
||||
vehicletemplateexportdialog.h \
|
||||
vehicletemplateselectorwidget.h
|
||||
|
||||
SOURCES += setupwizardplugin.cpp \
|
||||
setupwizard.cpp \
|
||||
@ -74,7 +75,8 @@ SOURCES += setupwizardplugin.cpp \
|
||||
pages/servopage.cpp \
|
||||
pages/selectionpage.cpp \
|
||||
pages/airframeinitialtuningpage.cpp \
|
||||
vehicletemplateexportdialog.cpp
|
||||
vehicletemplateexportdialog.cpp \
|
||||
vehicletemplateselectorwidget.cpp
|
||||
|
||||
OTHER_FILES += SetupWizard.pluginspec
|
||||
|
||||
@ -99,7 +101,8 @@ FORMS += \
|
||||
pages/servopage.ui \
|
||||
pages/selectionpage.ui \
|
||||
pages/airframeinitialtuningpage.ui \
|
||||
vehicletemplateexportdialog.ui
|
||||
vehicletemplateexportdialog.ui \
|
||||
vehicletemplateselectorwidget.ui
|
||||
|
||||
RESOURCES += \
|
||||
wizardResources.qrc
|
||||
|
@ -58,8 +58,7 @@ bool SetupWizardPlugin::initialize(const QStringList & args, QString *errMsg)
|
||||
"SetupWizardPlugin.ShowSetupWizard",
|
||||
QList<int>() <<
|
||||
Core::Constants::C_GLOBAL_ID);
|
||||
cmd->setDefaultKeySequence(QKeySequence("Ctrl+V"));
|
||||
cmd->action()->setText(tr("Vehicle Setup Wizard"));
|
||||
cmd->action()->setText(tr("Vehicle Setup Wizard..."));
|
||||
connect(cmd->action(), SIGNAL(triggered(bool)), this, SLOT(showSetupWizard()));
|
||||
|
||||
Core::ModeManager::instance()->addAction(cmd, 1);
|
||||
@ -71,7 +70,7 @@ bool SetupWizardPlugin::initialize(const QStringList & args, QString *errMsg)
|
||||
"SetupWizardPlugin.ExportJSon",
|
||||
QList<int>() <<
|
||||
Core::Constants::C_GLOBAL_ID);
|
||||
cmd->action()->setText(tr("Export Wizard Vehicle Template"));
|
||||
cmd->action()->setText(tr("Export/Import Vehicle Template..."));
|
||||
connect(cmd->action(), SIGNAL(triggered(bool)), this, SLOT(exportSettings()));
|
||||
|
||||
Core::ModeManager::instance()->addAction(cmd, 1);
|
||||
|
@ -37,12 +37,16 @@
|
||||
#include <QUuid>
|
||||
#include <QDebug>
|
||||
#include <QMessageBox>
|
||||
#include <uavobjecthelper.h>
|
||||
#include <objectpersistence.h>
|
||||
#include "stabilizationsettings.h"
|
||||
#include "stabilizationsettingsbank1.h"
|
||||
#include "stabilizationsettingsbank2.h"
|
||||
#include "stabilizationsettingsbank3.h"
|
||||
#include "mixersettings.h"
|
||||
#include "ekfconfiguration.h"
|
||||
#include <uavtalk/telemetrymanager.h>
|
||||
#include <utils/pathutils.h>
|
||||
|
||||
const char *VehicleTemplateExportDialog::EXPORT_BASE_NAME = "../share/openpilotgcs/cloudconfig";
|
||||
const char *VehicleTemplateExportDialog::EXPORT_FIXEDWING_NAME = "fixedwing";
|
||||
@ -53,7 +57,7 @@ const char *VehicleTemplateExportDialog::EXPORT_CUSTOM_NAME = "custom";
|
||||
|
||||
VehicleTemplateExportDialog::VehicleTemplateExportDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::VehicleTemplateExportDialog)
|
||||
ui(new Ui::VehicleTemplateExportDialog), m_autopilotConnected(false)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
connect(ui->ImportButton, SIGNAL(clicked()), this, SLOT(importImage()));
|
||||
@ -61,12 +65,29 @@ VehicleTemplateExportDialog::VehicleTemplateExportDialog(QWidget *parent) :
|
||||
m_uavoManager = pm->getObject<UAVObjectManager>();
|
||||
ui->Photo->setScene(new QGraphicsScene(this));
|
||||
ui->Type->setText(setupVehicleType());
|
||||
ui->selectionWidget->setTemplateInfo(m_type, m_subType);
|
||||
|
||||
connect(ui->Name, SIGNAL(textChanged(QString)), this, SLOT(updateStatus()));
|
||||
connect(ui->Owner, SIGNAL(textChanged(QString)), this, SLOT(updateStatus()));
|
||||
connect(ui->ForumNick, SIGNAL(textChanged(QString)), this, SLOT(updateStatus()));
|
||||
connect(ui->Size, SIGNAL(textChanged(QString)), this, SLOT(updateStatus()));
|
||||
connect(ui->Weight, SIGNAL(textChanged(QString)), this, SLOT(updateStatus()));
|
||||
|
||||
connect(ui->exportBtn, SIGNAL(clicked()), this, SLOT(exportTemplate()));
|
||||
connect(ui->saveAsBtn, SIGNAL(clicked()), this, SLOT(saveAsTemplate()));
|
||||
connect(ui->importBtn, SIGNAL(clicked()), this, SLOT(importTemplate()));
|
||||
connect(ui->cancelBtn, SIGNAL(clicked()), this, SLOT(reject()));
|
||||
connect(ui->cancelBtn_2, SIGNAL(clicked()), this, SLOT(reject()));
|
||||
|
||||
TelemetryManager *telemManager = pm->getObject<TelemetryManager>();
|
||||
if (telemManager->isConnected()) {
|
||||
onAutoPilotConnect();
|
||||
} else {
|
||||
onAutoPilotDisconnect();
|
||||
}
|
||||
|
||||
connect(telemManager, SIGNAL(connected()), this, SLOT(onAutoPilotConnect()));
|
||||
connect(telemManager, SIGNAL(disconnected()), this, SLOT(onAutoPilotDisconnect()));
|
||||
}
|
||||
|
||||
VehicleTemplateExportDialog::~VehicleTemplateExportDialog()
|
||||
@ -168,17 +189,7 @@ QString VehicleTemplateExportDialog::setupVehicleType()
|
||||
}
|
||||
}
|
||||
|
||||
QString VehicleTemplateExportDialog::fixFilenameString(QString input, int truncate)
|
||||
{
|
||||
return input.replace(' ', "").replace('|', "").replace('/', "")
|
||||
.replace('\\', "").replace(':', "").replace('"', "")
|
||||
.replace('\'', "").replace('?', "").replace('*', "")
|
||||
.replace('>', "").replace('<', "")
|
||||
.replace('}', "").replace('{', "")
|
||||
.left(truncate);
|
||||
}
|
||||
|
||||
void VehicleTemplateExportDialog::accept()
|
||||
void VehicleTemplateExportDialog::saveTemplate(QString path)
|
||||
{
|
||||
QJsonObject exportObject;
|
||||
|
||||
@ -227,20 +238,14 @@ void VehicleTemplateExportDialog::accept()
|
||||
.arg(fixFilenameString(uuid.toString().right(12)))
|
||||
.arg(fileType);
|
||||
|
||||
QString fullPath = QString("%1%2%3%4%5")
|
||||
.arg(EXPORT_BASE_NAME)
|
||||
.arg(QDir::separator())
|
||||
.arg(getTypeDirectory())
|
||||
.arg(QDir::separator())
|
||||
.arg(fileName);
|
||||
|
||||
QDir dir = QFileInfo(fullPath).absoluteDir();
|
||||
if (!dir.exists()) {
|
||||
fullPath = QString("%1%2%3").arg(QDir::homePath(), QDir::separator(), fileName);
|
||||
QString fullPath;
|
||||
if (path.isEmpty()) {
|
||||
fullPath = QString("%1%2%3").arg(QDir::homePath()).arg(QDir::separator()).arg(fileName);
|
||||
fullPath = QFileDialog::getSaveFileName(this, tr("Export settings"), fullPath, QString("%1 (*%2)").arg(tr("OPTemplates"), fileType));
|
||||
} else {
|
||||
fullPath = QString("%1%2%3").arg(path).arg(QDir::separator()).arg(fileName);
|
||||
}
|
||||
|
||||
fullPath = QFileDialog::getSaveFileName(this, tr("Export settings"), fullPath, QString("%1 (*%2)").arg(tr("OPTemplates", fileType)));
|
||||
|
||||
if (!fullPath.isEmpty()) {
|
||||
if (!fullPath.endsWith(fileType)) {
|
||||
fullPath.append(fileType);
|
||||
@ -253,7 +258,59 @@ void VehicleTemplateExportDialog::accept()
|
||||
QMessageBox::information(this, "Export", tr("Settings could not be exported to \n%1(%2).\nPlease try again.")
|
||||
.arg(QFileInfo(saveFile).absoluteFilePath(), saveFile.error()), QMessageBox::Ok);
|
||||
}
|
||||
QDialog::accept();
|
||||
}
|
||||
}
|
||||
|
||||
QString VehicleTemplateExportDialog::fixFilenameString(QString input, int truncate)
|
||||
{
|
||||
return input.replace(' ', "").replace('|', "").replace('/', "")
|
||||
.replace('\\', "").replace(':', "").replace('"', "")
|
||||
.replace('\'', "").replace('?', "").replace('*', "")
|
||||
.replace('>', "").replace('<', "")
|
||||
.replace('}', "").replace('{', "")
|
||||
.left(truncate);
|
||||
}
|
||||
|
||||
void VehicleTemplateExportDialog::exportTemplate()
|
||||
{
|
||||
QString path = QString("%1%2%3%4").arg(Utils::PathUtils().InsertStoragePath("%%STOREPATH%%cloudconfig"))
|
||||
.arg(QDir::separator()).arg(getTypeDirectory()).arg(QDir::separator());
|
||||
QDir dir;
|
||||
|
||||
dir.mkpath(path);
|
||||
saveTemplate(path);
|
||||
}
|
||||
|
||||
void VehicleTemplateExportDialog::saveAsTemplate()
|
||||
{
|
||||
saveTemplate(QString(""));
|
||||
}
|
||||
|
||||
void VehicleTemplateExportDialog::importTemplate()
|
||||
{
|
||||
QJsonObject *tmpl = ui->selectionWidget->selectedTemplate();
|
||||
|
||||
if (tmpl != NULL) {
|
||||
QList<UAVObject *> updatedObjects;
|
||||
m_uavoManager->fromJson(*tmpl, &updatedObjects);
|
||||
UAVObjectUpdaterHelper helper;
|
||||
foreach(UAVObject * object, updatedObjects) {
|
||||
UAVDataObject *dataObj = dynamic_cast<UAVDataObject *>(object);
|
||||
|
||||
if (dataObj != NULL && dataObj->isKnown()) {
|
||||
helper.doObjectAndWait(dataObj);
|
||||
|
||||
ObjectPersistence *objper = ObjectPersistence::GetInstance(m_uavoManager);
|
||||
ObjectPersistence::DataFields data;
|
||||
data.Operation = ObjectPersistence::OPERATION_SAVE;
|
||||
data.Selection = ObjectPersistence::SELECTION_SINGLEOBJECT;
|
||||
data.ObjectID = dataObj->getObjID();
|
||||
data.InstanceID = dataObj->getInstID();
|
||||
objper->setData(data);
|
||||
|
||||
helper.doObjectAndWait(objper);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -269,6 +326,20 @@ void VehicleTemplateExportDialog::importImage()
|
||||
}
|
||||
}
|
||||
|
||||
void VehicleTemplateExportDialog::onAutoPilotConnect()
|
||||
{
|
||||
ui->importBtn->setEnabled(true);
|
||||
m_autopilotConnected = true;
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
void VehicleTemplateExportDialog::onAutoPilotDisconnect()
|
||||
{
|
||||
ui->importBtn->setEnabled(false);
|
||||
m_autopilotConnected = false;
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
QString VehicleTemplateExportDialog::getTypeDirectory()
|
||||
{
|
||||
switch (m_type) {
|
||||
@ -291,7 +362,10 @@ QString VehicleTemplateExportDialog::getTypeDirectory()
|
||||
|
||||
void VehicleTemplateExportDialog::updateStatus()
|
||||
{
|
||||
ui->acceptBtn->setEnabled(ui->Name->text().length() > 3 && ui->Owner->text().length() > 2 &&
|
||||
ui->ForumNick->text().length() > 2 && ui->Size->text().length() > 0 &&
|
||||
ui->Weight->text().length() > 0);
|
||||
bool enabled = m_autopilotConnected && ui->Name->text().length() > 3 && ui->Owner->text().length() > 2 &&
|
||||
ui->ForumNick->text().length() > 2 && ui->Size->text().length() > 0 &&
|
||||
ui->Weight->text().length() > 0;
|
||||
|
||||
ui->exportBtn->setEnabled(enabled);
|
||||
ui->saveAsBtn->setEnabled(enabled);
|
||||
}
|
||||
|
@ -51,11 +51,15 @@ public:
|
||||
~VehicleTemplateExportDialog();
|
||||
|
||||
public slots:
|
||||
void accept();
|
||||
void exportTemplate();
|
||||
void saveAsTemplate();
|
||||
void importTemplate();
|
||||
void updateStatus();
|
||||
|
||||
private slots:
|
||||
void importImage();
|
||||
void onAutoPilotConnect();
|
||||
void onAutoPilotDisconnect();
|
||||
|
||||
private:
|
||||
static const int IMAGE_SCALE_WIDTH = 500;
|
||||
@ -65,10 +69,12 @@ private:
|
||||
VehicleConfigurationSource::VEHICLE_TYPE m_type;
|
||||
VehicleConfigurationSource::VEHICLE_SUB_TYPE m_subType;
|
||||
QPixmap m_image;
|
||||
bool m_autopilotConnected;
|
||||
|
||||
QString fixFilenameString(QString input, int truncate = 100);
|
||||
QString getTypeDirectory();
|
||||
QString setupVehicleType();
|
||||
void saveTemplate(QString path);
|
||||
};
|
||||
|
||||
#endif // VEHICLETEMPLATEEXPORTDIALOG_H
|
||||
|
@ -26,7 +26,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Vehicle Template Export</string>
|
||||
<string>Vehicle Templates</string>
|
||||
</property>
|
||||
<property name="sizeGripEnabled">
|
||||
<bool>false</bool>
|
||||
@ -35,6 +35,592 @@
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>Export template</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<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 row="6" column="2">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Weight:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<widget class="QLineEdit" name="Propeller">
|
||||
<property name="placeholderText">
|
||||
<string>Size and angle</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="2">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>Battery:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLineEdit" name="Size">
|
||||
<property name="placeholderText">
|
||||
<string>Size of the vehicle in mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Motor:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Servo:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<widget class="QLineEdit" name="Servo">
|
||||
<property name="placeholderText">
|
||||
<string>Brand and name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="Owner">
|
||||
<property name="placeholderText">
|
||||
<string>Your name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string>Propeller:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Forum name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="5">
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="4">
|
||||
<widget class="QLineEdit" name="Name">
|
||||
<property name="placeholderText">
|
||||
<string>The name of the vehicle, brand etc</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Owner:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLineEdit" name="Motor">
|
||||
<property name="placeholderText">
|
||||
<string>Brand, size and Kv</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Size:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="3" colspan="2">
|
||||
<widget class="QLineEdit" name="Battery">
|
||||
<property name="placeholderText">
|
||||
<string>How many cells etc?</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="2">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>Controller:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="4">
|
||||
<widget class="QLineEdit" name="Type">
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: rgba(255, 255, 255, 0);</string>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="2">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>ESC:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="3" colspan="2">
|
||||
<widget class="QComboBox" name="Controllers">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>CC</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>CC3D</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Atom</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Revolution</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Nano</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Type:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="3" colspan="2">
|
||||
<widget class="QLineEdit" name="ForumNick">
|
||||
<property name="placeholderText">
|
||||
<string>Forum nickname</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="3" colspan="2">
|
||||
<widget class="QLineEdit" name="Esc">
|
||||
<property name="placeholderText">
|
||||
<string>Brand and name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="3" colspan="2">
|
||||
<widget class="QLineEdit" name="Weight">
|
||||
<property name="placeholderText">
|
||||
<string>Weight in grams</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_6">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<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="QFrame" name="frame_3">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<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 alignment="Qt::AlignTop">
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string>Comment:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="Comment">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>Put comments here that don't fit in the categories above</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_4">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<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="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Photo:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGraphicsView" name="Photo">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: rgba(254, 254, 254, 0);</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="backgroundBrush">
|
||||
<brush brushstyle="NoBrush">
|
||||
<color alpha="255">
|
||||
<red>0</red>
|
||||
<green>0</green>
|
||||
<blue>0</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</property>
|
||||
<property name="interactive">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_7">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<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="QLabel" name="label_15">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Photo will be scaled to 500x500px</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="ImportButton">
|
||||
<property name="text">
|
||||
<string>Select Image...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<zorder>frame_4</zorder>
|
||||
<zorder>frame_3</zorder>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_5">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<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>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="cancelBtn">
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="saveAsBtn">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save as</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="exportBtn">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Export</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>Import template</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="VehicleTemplateSelectorWidget" name="selectionWidget" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_8">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<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>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="cancelBtn_2">
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="importBtn">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Import</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_2">
|
||||
<property name="frameShape">
|
||||
@ -56,490 +642,19 @@
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<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 row="6" column="2">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Weight:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<widget class="QLineEdit" name="Propeller">
|
||||
<property name="placeholderText">
|
||||
<string>Size and angle</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="2">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>Battery:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLineEdit" name="Size">
|
||||
<property name="placeholderText">
|
||||
<string>Size of the vehicle in mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Motor:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Servo:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<widget class="QLineEdit" name="Servo">
|
||||
<property name="placeholderText">
|
||||
<string>Brand and name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="Owner">
|
||||
<property name="placeholderText">
|
||||
<string>Your name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string>Propeller:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Forum name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="5">
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="4">
|
||||
<widget class="QLineEdit" name="Name">
|
||||
<property name="placeholderText">
|
||||
<string>The name of the vehicle, brand etc</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Owner:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLineEdit" name="Motor">
|
||||
<property name="placeholderText">
|
||||
<string>Brand, size and Kv</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Size:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="3" colspan="2">
|
||||
<widget class="QLineEdit" name="Battery">
|
||||
<property name="placeholderText">
|
||||
<string>How many cells etc?</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="2">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>Controller:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="4">
|
||||
<widget class="QLineEdit" name="Type">
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: rgba(255, 255, 255, 0);</string>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="2">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>ESC:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="3" colspan="2">
|
||||
<widget class="QComboBox" name="Controllers">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>CC</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>CC3D</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Atom</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Revolution</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Nano</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Type:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="3" colspan="2">
|
||||
<widget class="QLineEdit" name="ForumNick">
|
||||
<property name="placeholderText">
|
||||
<string>Forum nickname</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="3" colspan="2">
|
||||
<widget class="QLineEdit" name="Esc">
|
||||
<property name="placeholderText">
|
||||
<string>Brand and name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="3" colspan="2">
|
||||
<widget class="QLineEdit" name="Weight">
|
||||
<property name="placeholderText">
|
||||
<string>Weight in grams</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_6">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<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="QFrame" name="frame_3">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<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 alignment="Qt::AlignTop">
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string>Comment:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="Comment">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>Put comments here that don't fit in the categories above</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_4">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<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="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Photo:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGraphicsView" name="Photo">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: rgba(254, 254, 254, 0);</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="backgroundBrush">
|
||||
<brush brushstyle="NoBrush">
|
||||
<color alpha="255">
|
||||
<red>0</red>
|
||||
<green>0</green>
|
||||
<blue>0</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</property>
|
||||
<property name="interactive">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_7">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<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="QLabel" name="label_15">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Photo will be scaled to 500x500px</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="ImportButton">
|
||||
<property name="text">
|
||||
<string>Select Image...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<zorder>frame_4</zorder>
|
||||
<zorder>frame_3</zorder>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_5">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<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>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="cancelBtn">
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="acceptBtn">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Export</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>VehicleTemplateSelectorWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>vehicletemplateselectorwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>Type</tabstop>
|
||||
<tabstop>Name</tabstop>
|
||||
@ -555,43 +670,10 @@
|
||||
<tabstop>Controllers</tabstop>
|
||||
<tabstop>Comment</tabstop>
|
||||
<tabstop>ImportButton</tabstop>
|
||||
<tabstop>acceptBtn</tabstop>
|
||||
<tabstop>exportBtn</tabstop>
|
||||
<tabstop>cancelBtn</tabstop>
|
||||
<tabstop>Photo</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>cancelBtn</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>VehicleTemplateExportDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>458</x>
|
||||
<y>668</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>304</x>
|
||||
<y>349</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>acceptBtn</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>VehicleTemplateExportDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>549</x>
|
||||
<y>668</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>304</x>
|
||||
<y>349</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
@ -0,0 +1,244 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file vehicletemplateselectorwidget.cpp
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
||||
* @addtogroup [Group]
|
||||
* @{
|
||||
* @addtogroup VehicleTemplateSelectorWidget
|
||||
* @{
|
||||
* @brief [Brief]
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "vehicletemplateselectorwidget.h"
|
||||
#include "ui_vehicletemplateselectorwidget.h"
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QDir>
|
||||
#include <QDebug>
|
||||
#include "vehicletemplateexportdialog.h"
|
||||
#include "utils/pathutils.h"
|
||||
|
||||
VehicleTemplateSelectorWidget::VehicleTemplateSelectorWidget(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::VehicleTemplateSelectorWidget), m_photoItem(NULL)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->templateImage->setScene(new QGraphicsScene());
|
||||
connect(ui->templateList, SIGNAL(itemSelectionChanged()), this, SLOT(templateSelectionChanged()));
|
||||
}
|
||||
|
||||
VehicleTemplateSelectorWidget::~VehicleTemplateSelectorWidget()
|
||||
{
|
||||
ui->templateList->clear();
|
||||
foreach(QJsonObject * templ, m_templates.values()) {
|
||||
delete templ;
|
||||
}
|
||||
m_templates.clear();
|
||||
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void VehicleTemplateSelectorWidget::setTemplateInfo(int vehicleType, int vehicleSubType)
|
||||
{
|
||||
m_vehicleType = vehicleType;
|
||||
m_vehicleSubType = vehicleSubType;
|
||||
updateTemplates();
|
||||
}
|
||||
|
||||
QJsonObject *VehicleTemplateSelectorWidget::selectedTemplate() const
|
||||
{
|
||||
if (ui->templateList->currentRow() >= 0) {
|
||||
return ui->templateList->item(ui->templateList->currentRow())->data(Qt::UserRole + 1).value<QJsonObject *>();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void VehicleTemplateSelectorWidget::updateTemplates()
|
||||
{
|
||||
loadValidFiles();
|
||||
setupTemplateList();
|
||||
}
|
||||
|
||||
void VehicleTemplateSelectorWidget::updatePhoto(QJsonObject *templ)
|
||||
{
|
||||
QPixmap photo;
|
||||
|
||||
if (m_photoItem != NULL) {
|
||||
ui->templateImage->scene()->removeItem(m_photoItem);
|
||||
}
|
||||
if (templ != NULL && !templ->value("photo").isUndefined()) {
|
||||
QByteArray imageData = QByteArray::fromBase64(templ->value("photo").toString().toLatin1());
|
||||
photo.loadFromData(imageData, "PNG");
|
||||
} else {
|
||||
photo.load(":/core/images/openpilot_logo_500.png");
|
||||
}
|
||||
m_photoItem = ui->templateImage->scene()->addPixmap(photo);
|
||||
ui->templateImage->setSceneRect(ui->templateImage->scene()->itemsBoundingRect());
|
||||
ui->templateImage->fitInView(ui->templateImage->scene()->itemsBoundingRect(), Qt::KeepAspectRatio);
|
||||
}
|
||||
|
||||
void VehicleTemplateSelectorWidget::updateDescription(QJsonObject *templ)
|
||||
{
|
||||
if (templ != NULL) {
|
||||
QString description;
|
||||
description.append("<b>").append(tr("Name of Vehicle: ")).append("</b>").append(templ->value("name").toString()).append("<br>");
|
||||
description.append("<b>").append(tr("Name of Owner: ")).append("</b>").append(templ->value("owner").toString());
|
||||
if (templ->value("nick") != QStringLiteral("")) {
|
||||
description.append(" (").append(templ->value("nick").toString()).append(")");
|
||||
}
|
||||
description.append("<br>");
|
||||
description.append("<b>").append(tr("Size: ")).append("</b>").append(templ->value("size").toString()).append("<br>");
|
||||
description.append("<b>").append(tr("Weight: ")).append("</b>").append(templ->value("weight").toString()).append("<br>");
|
||||
description.append("<b>").append(tr("Motor(s): ")).append("</b>").append(templ->value("motor").toString()).append("<br>");
|
||||
description.append("<b>").append(tr("ESC(s): ")).append("</b>").append(templ->value("esc").toString()).append("<br>");
|
||||
description.append("<b>").append(tr("Servo(s): ")).append("</b>").append(templ->value("servo").toString()).append("<br>");
|
||||
description.append("<b>").append(tr("Battery: ")).append("</b>").append(templ->value("battery").toString()).append("<br>");
|
||||
description.append("<b>").append(tr("Propellers(s): ")).append("</b>").append(templ->value("propeller").toString()).append("<br>");
|
||||
description.append("<b>").append(tr("Controller: ")).append("</b>").append(templ->value("controller").toString()).append("<br>");
|
||||
description.append("<b>").append(tr("Comments: ")).append("</b>").append(templ->value("comment").toString());
|
||||
ui->templateDescription->setText(description);
|
||||
} else {
|
||||
ui->templateDescription->setText(tr("This option will use the current tuning settings saved on the controller, if your controller "
|
||||
"is currently unconfigured, then the OpenPilot firmware defaults will be used.\n\n"
|
||||
"It is suggested that if this is a first time configuration of your controller, rather than "
|
||||
"use this option, instead select a tuning set that matches your own airframe as close as "
|
||||
"possible from the list above or if you are not able to fine one, then select the generic item "
|
||||
"from the list."));
|
||||
}
|
||||
}
|
||||
|
||||
void VehicleTemplateSelectorWidget::templateSelectionChanged()
|
||||
{
|
||||
if (ui->templateList->currentRow() >= 0) {
|
||||
QJsonObject *templ = selectedTemplate();
|
||||
updatePhoto(templ);
|
||||
updateDescription(templ);
|
||||
}
|
||||
}
|
||||
|
||||
bool VehicleTemplateSelectorWidget::airframeIsCompatible(int vehicleType, int vehicleSubType)
|
||||
{
|
||||
if (vehicleType != m_vehicleType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return vehicleSubType == m_vehicleSubType;
|
||||
}
|
||||
|
||||
QString VehicleTemplateSelectorWidget::getTemplatePath()
|
||||
{
|
||||
switch (m_vehicleType) {
|
||||
case VehicleConfigurationSource::VEHICLE_FIXEDWING:
|
||||
return VehicleTemplateExportDialog::EXPORT_FIXEDWING_NAME;
|
||||
|
||||
case VehicleConfigurationSource::VEHICLE_MULTI:
|
||||
return VehicleTemplateExportDialog::EXPORT_MULTI_NAME;
|
||||
|
||||
case VehicleConfigurationSource::VEHICLE_HELI:
|
||||
return VehicleTemplateExportDialog::EXPORT_HELI_NAME;
|
||||
|
||||
case VehicleConfigurationSource::VEHICLE_SURFACE:
|
||||
return VehicleTemplateExportDialog::EXPORT_SURFACE_NAME;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void VehicleTemplateSelectorWidget::loadFilesInDir(QString templateBasePath)
|
||||
{
|
||||
QDir templateDir(templateBasePath);
|
||||
|
||||
qDebug() << "Loading templates from base path:" << templateBasePath;
|
||||
QStringList names;
|
||||
names << "*.optmpl";
|
||||
templateDir.setNameFilters(names);
|
||||
templateDir.setSorting(QDir::Name);
|
||||
QStringList files = templateDir.entryList();
|
||||
foreach(QString fileName, files) {
|
||||
QFile file(QString("%1/%2").arg(templateDir.absolutePath()).arg(fileName));
|
||||
|
||||
if (file.open(QFile::ReadOnly)) {
|
||||
QByteArray jsonData = file.readAll();
|
||||
QJsonParseError error;
|
||||
QJsonDocument templateDoc = QJsonDocument::fromJson(jsonData, &error);
|
||||
if (error.error == QJsonParseError::NoError) {
|
||||
QJsonObject json = templateDoc.object();
|
||||
if (airframeIsCompatible(json["type"].toInt(), json["subtype"].toInt())) {
|
||||
QString uuid = json["uuid"].toString();
|
||||
if (!m_templates.contains(uuid)) {
|
||||
m_templates[json["uuid"].toString()] = new QJsonObject(json);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
qDebug() << "Error parsing json file: "
|
||||
<< fileName << ". Error was:" << error.errorString();
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
void VehicleTemplateSelectorWidget::loadValidFiles()
|
||||
{
|
||||
ui->templateList->clear();
|
||||
foreach(QJsonObject * templ, m_templates.values()) {
|
||||
delete templ;
|
||||
}
|
||||
m_templates.clear();
|
||||
QString path = getTemplatePath();
|
||||
loadFilesInDir(QString("%1/%2/").arg(Utils::PathUtils().InsertDataPath("%%DATAPATH%%cloudconfig")).arg(path));
|
||||
loadFilesInDir(QString("%1/%2/").arg(Utils::PathUtils().InsertStoragePath("%%STOREPATH%%cloudconfig")).arg(path));
|
||||
}
|
||||
|
||||
void VehicleTemplateSelectorWidget::setupTemplateList()
|
||||
{
|
||||
QListWidgetItem *item;
|
||||
|
||||
foreach(QString templ, m_templates.keys()) {
|
||||
QJsonObject *json = m_templates[templ];
|
||||
|
||||
item = new QListWidgetItem(json->value("name").toString(), ui->templateList);
|
||||
item->setData(Qt::UserRole + 1, QVariant::fromValue(json));
|
||||
}
|
||||
ui->templateList->sortItems(Qt::AscendingOrder);
|
||||
|
||||
item = new QListWidgetItem(tr("Current Tuning"));
|
||||
item->setData(Qt::UserRole + 1, QVariant::fromValue((QJsonObject *)NULL));
|
||||
ui->templateList->insertItem(0, item);
|
||||
ui->templateList->setCurrentRow(0);
|
||||
// TODO Add generics to top under item Current tuning
|
||||
}
|
||||
|
||||
QString VehicleTemplateSelectorWidget::getTemplateKey(QJsonObject *templ)
|
||||
{
|
||||
return QString(templ->value("name").toString());
|
||||
}
|
||||
|
||||
void VehicleTemplateSelectorWidget::resizeEvent(QResizeEvent *)
|
||||
{
|
||||
ui->templateImage->setSceneRect(ui->templateImage->scene()->itemsBoundingRect());
|
||||
ui->templateImage->fitInView(ui->templateImage->scene()->itemsBoundingRect(), Qt::KeepAspectRatio);
|
||||
}
|
||||
|
||||
void VehicleTemplateSelectorWidget::showEvent(QShowEvent *)
|
||||
{
|
||||
ui->templateImage->setSceneRect(ui->templateImage->scene()->itemsBoundingRect());
|
||||
ui->templateImage->fitInView(ui->templateImage->scene()->itemsBoundingRect(), Qt::KeepAspectRatio);
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file vehicletemplateselectorwidget.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
||||
* @addtogroup [Group]
|
||||
* @{
|
||||
* @addtogroup VehicleTemplateSelectorWidget
|
||||
* @{
|
||||
* @brief [Brief]
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef VEHICLETEMPLATESELECTORWIDGET_H
|
||||
#define VEHICLETEMPLATESELECTORWIDGET_H
|
||||
|
||||
#include <QGraphicsItem>
|
||||
#include <QJsonObject>
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui {
|
||||
class VehicleTemplateSelectorWidget;
|
||||
}
|
||||
|
||||
class VehicleTemplateSelectorWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit VehicleTemplateSelectorWidget(QWidget *parent = 0);
|
||||
~VehicleTemplateSelectorWidget();
|
||||
void setTemplateInfo(int vehicleType, int vehicleSubType);
|
||||
QJsonObject *selectedTemplate() const;
|
||||
|
||||
public slots:
|
||||
void templateSelectionChanged();
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *);
|
||||
void showEvent(QShowEvent *);
|
||||
|
||||
private:
|
||||
Ui::VehicleTemplateSelectorWidget *ui;
|
||||
int m_vehicleType;
|
||||
int m_vehicleSubType;
|
||||
|
||||
QMap<QString, QJsonObject *> m_templates;
|
||||
QGraphicsPixmapItem *m_photoItem;
|
||||
|
||||
void loadValidFiles();
|
||||
void loadFilesInDir(QString templateBasePath);
|
||||
void setupTemplateList();
|
||||
QString getTemplateKey(QJsonObject *templ);
|
||||
void updatePhoto(QJsonObject *templ);
|
||||
void updateDescription(QJsonObject *templ);
|
||||
bool airframeIsCompatible(int vehicleType, int vehicleSubType);
|
||||
QString getTemplatePath();
|
||||
|
||||
private slots:
|
||||
void updateTemplates();
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(QJsonObject *)
|
||||
|
||||
#endif // VEHICLETEMPLATESELECTORWIDGET_H
|
@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>VehicleTemplateSelectorWidget</class>
|
||||
<widget class="QWidget" name="VehicleTemplateSelectorWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>626</width>
|
||||
<height>461</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="2,0">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,4">
|
||||
<item>
|
||||
<widget class="QListWidget" name="templateList">
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGraphicsView" name="templateImage">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>250</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: rgba(254, 254, 254, 0);</string>
|
||||
</property>
|
||||
<property name="interactive">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="renderHints">
|
||||
<set>QPainter::Antialiasing|QPainter::HighQualityAntialiasing|QPainter::TextAntialiasing</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="templateDescription">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="undoRedoEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>Information about the Vehicle in short.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
Loading…
x
Reference in New Issue
Block a user