1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-12-01 09:24:10 +01:00

Merge remote-tracking branch 'remotes/origin/next' into sambas/diffnext

Conflicts:
	shared/uavobjectdefinition/manualcontrolsettings.xml
This commit is contained in:
sambas 2013-04-22 21:22:24 +03:00
commit 731ee3e19d
26 changed files with 887 additions and 867 deletions

View File

@ -122,6 +122,11 @@ extern int32_t PIOS_GCSRCVR_Init(uint32_t *gcsrcvr_id)
if (!gcsrcvr_dev) if (!gcsrcvr_dev)
return -1; return -1;
for (uint8_t i = 0; i < GCSRECEIVER_CHANNEL_NUMELEM; i++) {
/* Flush channels */
gcsreceiverdata.Channel[i] = PIOS_RCVR_TIMEOUT;
}
/* Register uavobj callback */ /* Register uavobj callback */
GCSReceiverConnectCallback (gcsreceiver_updated); GCSReceiverConnectCallback (gcsreceiver_updated);
@ -133,11 +138,18 @@ extern int32_t PIOS_GCSRCVR_Init(uint32_t *gcsrcvr_id)
return 0; return 0;
} }
/**
* Get the value of an input channel
* \param[in] channel Number of the channel desired (zero based)
* \output PIOS_RCVR_INVALID channel not available
* \output PIOS_RCVR_TIMEOUT failsafe condition or missing receiver
* \output >=0 channel value
*/
static int32_t PIOS_GCSRCVR_Get(uint32_t rcvr_id, uint8_t channel) static int32_t PIOS_GCSRCVR_Get(uint32_t rcvr_id, uint8_t channel)
{ {
if (channel >= GCSRECEIVER_CHANNEL_NUMELEM) { if (channel >= GCSRECEIVER_CHANNEL_NUMELEM) {
/* channel is out of range */ /* channel is out of range */
return -1; return PIOS_RCVR_INVALID;
} }
return (gcsreceiverdata.Channel[channel]); return (gcsreceiverdata.Channel[channel]);

View File

@ -166,7 +166,7 @@ out_fail:
* \param[in] channel Number of the channel desired (zero based) * \param[in] channel Number of the channel desired (zero based)
* \output PIOS_RCVR_INVALID channel not available * \output PIOS_RCVR_INVALID channel not available
* \output PIOS_RCVR_TIMEOUT failsafe condition or missing receiver * \output PIOS_RCVR_TIMEOUT failsafe condition or missing receiver
* \output >0 channel value * \output >=0 channel value
*/ */
static int32_t PIOS_SBus_Get(uint32_t rcvr_id, uint8_t channel) static int32_t PIOS_SBus_Get(uint32_t rcvr_id, uint8_t channel)
{ {

View File

@ -348,7 +348,7 @@ static uint16_t PIOS_DSM_RxInCallback(uint32_t context,
* \param[in] channel Number of the channel desired (zero based) * \param[in] channel Number of the channel desired (zero based)
* \output PIOS_RCVR_INVALID channel not available * \output PIOS_RCVR_INVALID channel not available
* \output PIOS_RCVR_TIMEOUT failsafe condition or missing receiver * \output PIOS_RCVR_TIMEOUT failsafe condition or missing receiver
* \output >0 channel value * \output >=0 channel value
*/ */
static int32_t PIOS_DSM_Get(uint32_t rcvr_id, uint8_t channel) static int32_t PIOS_DSM_Get(uint32_t rcvr_id, uint8_t channel)
{ {

View File

@ -146,8 +146,8 @@ extern int32_t PIOS_PPM_Init(uint32_t * ppm_id, const struct pios_ppm_cfg * cfg)
for (uint8_t i = 0; i < PIOS_PPM_IN_MAX_NUM_CHANNELS; i++) { for (uint8_t i = 0; i < PIOS_PPM_IN_MAX_NUM_CHANNELS; i++) {
/* Flush counter variables */ /* Flush counter variables */
ppm_dev->CaptureValue[i] = 0; ppm_dev->CaptureValue[i] = PIOS_RCVR_TIMEOUT;
ppm_dev->CaptureValueNewFrame[i] = 0; ppm_dev->CaptureValueNewFrame[i] = PIOS_RCVR_TIMEOUT;
} }
@ -201,11 +201,12 @@ out_fail:
} }
/** /**
* Get the value of an input channel * Get the value of an input channel
* \param[in] Channel Number of the channel desired * \param[in] channel Number of the channel desired (zero based)
* \output -1 Channel not available * \output PIOS_RCVR_INVALID channel not available
* \output >0 Channel value * \output PIOS_RCVR_TIMEOUT failsafe condition or missing receiver
*/ * \output >=0 channel value
*/
static int32_t PIOS_PPM_Get(uint32_t rcvr_id, uint8_t channel) static int32_t PIOS_PPM_Get(uint32_t rcvr_id, uint8_t channel)
{ {
struct pios_ppm_dev * ppm_dev = (struct pios_ppm_dev *)rcvr_id; struct pios_ppm_dev * ppm_dev = (struct pios_ppm_dev *)rcvr_id;

View File

@ -171,11 +171,12 @@ out_fail:
} }
/** /**
* Get the value of an input channel * Get the value of an input channel
* \param[in] Channel Number of the channel desired * \param[in] channel Number of the channel desired (zero based)
* \output -1 Channel not available * \output PIOS_RCVR_INVALID channel not available
* \output >0 Channel value * \output PIOS_RCVR_TIMEOUT failsafe condition or missing receiver
*/ * \output >=0 channel value
*/
static int32_t PIOS_PWM_Get(uint32_t rcvr_id, uint8_t channel) static int32_t PIOS_PWM_Get(uint32_t rcvr_id, uint8_t channel)
{ {
struct pios_pwm_dev * pwm_dev = (struct pios_pwm_dev *)rcvr_id; struct pios_pwm_dev * pwm_dev = (struct pios_pwm_dev *)rcvr_id;

View File

@ -349,7 +349,7 @@ static uint16_t PIOS_DSM_RxInCallback(uint32_t context,
* \param[in] channel Number of the channel desired (zero based) * \param[in] channel Number of the channel desired (zero based)
* \output PIOS_RCVR_INVALID channel not available * \output PIOS_RCVR_INVALID channel not available
* \output PIOS_RCVR_TIMEOUT failsafe condition or missing receiver * \output PIOS_RCVR_TIMEOUT failsafe condition or missing receiver
* \output >0 channel value * \output >=0 channel value
*/ */
static int32_t PIOS_DSM_Get(uint32_t rcvr_id, uint8_t channel) static int32_t PIOS_DSM_Get(uint32_t rcvr_id, uint8_t channel)
{ {

View File

@ -145,8 +145,8 @@ extern int32_t PIOS_PPM_Init(uint32_t * ppm_id, const struct pios_ppm_cfg * cfg)
for (uint8_t i = 0; i < PIOS_PPM_IN_MAX_NUM_CHANNELS; i++) { for (uint8_t i = 0; i < PIOS_PPM_IN_MAX_NUM_CHANNELS; i++) {
/* Flush counter variables */ /* Flush counter variables */
ppm_dev->CaptureValue[i] = 0; ppm_dev->CaptureValue[i] = PIOS_RCVR_TIMEOUT;
ppm_dev->CaptureValueNewFrame[i] = 0; ppm_dev->CaptureValueNewFrame[i] = PIOS_RCVR_TIMEOUT;
} }
@ -200,11 +200,12 @@ out_fail:
} }
/** /**
* Get the value of an input channel * Get the value of an input channel
* \param[in] Channel Number of the channel desired * \param[in] channel Number of the channel desired (zero based)
* \output -1 Channel not available * \output PIOS_RCVR_INVALID channel not available
* \output >0 Channel value * \output PIOS_RCVR_TIMEOUT failsafe condition or missing receiver
*/ * \output >=0 channel value
*/
static int32_t PIOS_PPM_Get(uint32_t rcvr_id, uint8_t channel) static int32_t PIOS_PPM_Get(uint32_t rcvr_id, uint8_t channel)
{ {
struct pios_ppm_dev * ppm_dev = (struct pios_ppm_dev *)rcvr_id; struct pios_ppm_dev * ppm_dev = (struct pios_ppm_dev *)rcvr_id;

View File

@ -170,11 +170,12 @@ out_fail:
} }
/** /**
* Get the value of an input channel * Get the value of an input channel
* \param[in] Channel Number of the channel desired * \param[in] channel Number of the channel desired (zero based)
* \output -1 Channel not available * \output PIOS_RCVR_INVALID channel not available
* \output >0 Channel value * \output PIOS_RCVR_TIMEOUT failsafe condition or missing receiver
*/ * \output >=0 channel value
*/
static int32_t PIOS_PWM_Get(uint32_t rcvr_id, uint8_t channel) static int32_t PIOS_PWM_Get(uint32_t rcvr_id, uint8_t channel)
{ {
struct pios_pwm_dev * pwm_dev = (struct pios_pwm_dev *)rcvr_id; struct pios_pwm_dev * pwm_dev = (struct pios_pwm_dev *)rcvr_id;

View File

@ -42,11 +42,11 @@ extern int32_t PIOS_RCVR_Read(uint32_t rcvr_id, uint8_t channel);
/*! Define error codes for PIOS_RCVR_Get */ /*! Define error codes for PIOS_RCVR_Get */
enum PIOS_RCVR_errors { enum PIOS_RCVR_errors {
/*! Indicates that a failsafe condition or missing receiver detected for that channel */ /*! Indicates that a failsafe condition or missing receiver detected for that channel */
PIOS_RCVR_TIMEOUT = 0, PIOS_RCVR_TIMEOUT = -1,
/*! Channel is invalid for this driver (usually out of range supported) */ /*! Channel is invalid for this driver (usually out of range supported) */
PIOS_RCVR_INVALID = -1, PIOS_RCVR_INVALID = -2,
/*! Indicates that the driver for this channel has not been initialized */ /*! Indicates that the driver for this channel has not been initialized */
PIOS_RCVR_NODRIVER = -2 PIOS_RCVR_NODRIVER = -3
}; };
#endif /* PIOS_RCVR_H */ #endif /* PIOS_RCVR_H */

View File

@ -26,6 +26,57 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
/*
The GCS locale is set to the system locale by default unless the "hidden" setting General/Locale has a value.
The user can not change General/Locale from the Options dialog.
The GCS language will default to the GCS locale unless the General/OverrideLanguage has a value.
The user can change General/OverrideLanguage to any available language from the Options dialog.
Both General/Locale and General/OverrideLanguage can be set from the command line or through the the factory defaults file.
The -D option is used to permanently set a user setting.
The -reset switch will clear all the user settings and will trigger a reload of the factory defaults.
You can combine it with the -config-file=<file> command line argument to quickly switch between multiple settings files.
[code]
openpilotgcs -reset -config-file ./MyOpenPilotGCS.xml
[/code]
Relative paths are relative to <install dir>/share/openpilotgcs/default_configurations/
The specified file will be used to load the factory defaults from but only when the user settings are empty.
If the user settings are not empty the file will not be used.
This switch is useful on the 1st run when the user settings are empty or in combination with -reset.
Quickly switch configurations
[code]
openpilotgcs -reset -config-file <relative or absolute path>
[/code]
Configuring GCS from installer
The -D option is used to permanently set a user setting.
If the user chooses to start GCS at the end of the installer:
[code]
openpilotgcs -D General/OverrideLanguage=de
[/code]
If the user chooses not to start GCS at the end of the installer, you still need to configure GCS.
In that case you can use -exit-after-config
[code]
openpilotgcs -D General/OverrideLanguage=de -exit-after-config
[/code]
*/
#include "qtsingleapplication.h" #include "qtsingleapplication.h"
#include "utils/xmlconfig.h" #include "utils/xmlconfig.h"
#include "gcssplashscreen.h" #include "gcssplashscreen.h"
@ -35,6 +86,7 @@
#include <extensionsystem/iplugin.h> #include <extensionsystem/iplugin.h>
#include <QtCore/QDir> #include <QtCore/QDir>
#include <QtCore/QElapsedTimer>
#include <QtCore/QTextStream> #include <QtCore/QTextStream>
#include <QtCore/QFileInfo> #include <QtCore/QFileInfo>
#include <QtCore/QDebug> #include <QtCore/QDebug>
@ -48,292 +100,415 @@
#include <QtGui/QApplication> #include <QtGui/QApplication>
#include <QtGui/QMainWindow> #include <QtGui/QMainWindow>
#include <QtGui/QSplashScreen> #include <QtGui/QSplashScreen>
#include <QtGui/QPainter>
#include <QElapsedTimer> namespace {
enum { OptionIndent = 4, DescriptionIndent = 24 }; typedef QList<ExtensionSystem::PluginSpec *> PluginSpecSet;
typedef QMap<QString, bool> AppOptions;
typedef QMap<QString, QString> AppOptionValues;
static const char *appNameC = "OpenPilot GCS"; const int OptionIndent = 4;
static const char *corePluginNameC = "Core"; const int DescriptionIndent = 24;
static const char *fixedOptionsC =
" [OPTION]... [FILE]...\n"
"Options:\n"
" -help Display this help\n"
" -version Display program version\n"
" -client Attempt to connect to already running instance\n"
" -clean-config Delete all existing configuration settings\n"
" -exit-after-config Exit GCS after manipulating configuration settings\n"
" -D key=value Override configuration settings e.g: -D General/OverrideLanguage=de\n"
" -configfile=value Default configuration file to load if settings file is empty\n";
static const char *HELP_OPTION1 = "-h";
static const char *HELP_OPTION2 = "-help";
static const char *HELP_OPTION3 = "/h";
static const char *HELP_OPTION4 = "--help";
static const char *VERSION_OPTION = "-version";
static const char *CLIENT_OPTION = "-client";
static const char *CONFIG_OPTION = "-D";
static const char *CLEAN_CONFIG_OPTION = "-clean-config";
static const char *EXIT_AFTER_CONFIG_OPTION = "-exit-after-config";
typedef QList<ExtensionSystem::PluginSpec *> PluginSpecSet; const QLatin1String APP_NAME("OpenPilot GCS");
// Helpers for displaying messages. Note that there is no console on Windows. const QLatin1String CORE_PLUGIN_NAME("Core");
#ifdef Q_OS_WIN
// Format as <pre> HTML
static inline void toHtml(QString &t)
{
t.replace(QLatin1Char('&'), QLatin1String("&amp;"));
t.replace(QLatin1Char('<'), QLatin1String("&lt;"));
t.replace(QLatin1Char('>'), QLatin1String("&gt;"));
t.insert(0, QLatin1String("<html><pre>"));
t.append(QLatin1String("</pre></html>"));
}
static void displayHelpText(QString t) // No console on Windows. const QLatin1String SETTINGS_ORG_NAME("OpenPilot");
{ const QLatin1String SETTINGS_APP_NAME("OpenPilotGCS_config");
toHtml(t);
QMessageBox::information(0, QLatin1String(appNameC), t);
}
static void displayError(const QString &t) // No console on Windows.
{
QMessageBox::critical(0, QLatin1String(appNameC), t);
}
#else
static void displayHelpText(const QString &t)
{
qWarning("%s", qPrintable(t));
}
static void displayError(const QString &t)
{
qCritical("%s", qPrintable(t));
}
#endif
static void printVersion(const ExtensionSystem::PluginSpec *coreplugin,
const ExtensionSystem::PluginManager &pm)
{
QString version;
QTextStream str(&version);
str << '\n' << appNameC << ' ' << coreplugin->version()<< " based on Qt " << qVersion() << "\n\n";
pm.formatPluginVersions(str);
str << '\n' << coreplugin->copyright() << '\n';
displayHelpText(version);
}
static void printHelp(const QString &a0, const ExtensionSystem::PluginManager &pm)
{
QString help;
QTextStream str(&help);
str << "Usage: " << a0 << fixedOptionsC;
ExtensionSystem::PluginManager::formatOptions(str, OptionIndent, DescriptionIndent);
pm.formatPluginOptions(str, OptionIndent, DescriptionIndent);
displayHelpText(help);
}
static inline QString msgCoreLoadFailure(const QString &why)
{
return QCoreApplication::translate("Application", "Failed to load core: %1").arg(why);
}
static inline QString msgSendArgumentFailed()
{
return QCoreApplication::translate("Application", "Unable to send command line arguments to the already running instance. It appears to be not responding.");
}
// Prepare a remote argument: If it is a relative file, add the current directory
// since the the central instance might be running in a different directory.
static inline QString prepareRemoteArgument(const QString &a)
{
QFileInfo fi(a);
if (!fi.exists())
return a;
if (fi.isRelative())
return fi.absoluteFilePath();
return a;
}
// Send the arguments to an already running instance of OpenPilot GCS
static bool sendArguments(SharedTools::QtSingleApplication &app, const QStringList &arguments)
{
if (!arguments.empty()) {
// Send off arguments
const QStringList::const_iterator acend = arguments.constEnd();
for (QStringList::const_iterator it = arguments.constBegin(); it != acend; ++it) {
if (!app.sendMessage(prepareRemoteArgument(*it))) {
displayError(msgSendArgumentFailed());
return false;
}
}
}
// Special empty argument means: Show and raise (the slot just needs to be triggered)
if (!app.sendMessage(QString())) {
displayError(msgSendArgumentFailed());
return false;
}
return true;
}
static inline QStringList getPluginPaths()
{
QStringList rc;
// Figure out root: Up one from 'bin'
QDir rootDir = QApplication::applicationDirPath();
rootDir.cdUp();
const QString rootDirPath = rootDir.canonicalPath();
// 1) "plugins" (Win/Linux)
QString pluginPath = rootDirPath;
pluginPath += QLatin1Char('/');
pluginPath += QLatin1String(GCS_LIBRARY_BASENAME);
pluginPath += QLatin1Char('/');
pluginPath += QLatin1String("openpilotgcs");
pluginPath += QLatin1Char('/');
pluginPath += QLatin1String("plugins");
rc.push_back(pluginPath);
// 2) "PlugIns" (OS X)
pluginPath = rootDirPath;
pluginPath += QLatin1Char('/');
pluginPath += QLatin1String("Plugins");
rc.push_back(pluginPath);
return rc;
}
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
# define SHARE_PATH "/../Resources" const QLatin1String SHARE_PATH("/../Resources");
#else #else
# define SHARE_PATH "/../share/openpilotgcs" const QLatin1String SHARE_PATH("/../share/openpilotgcs");
#endif #endif
static void overrideSettings(QSettings &settings, int argc, char **argv){ const char *DEFAULT_CONFIG_FILENAME = "OpenPilotGCS.xml";
QMap<QString, QString> settingOptions; const char *fixedOptionsC = " [OPTION]... [FILE]...\n"
// Options like -DMy/setting=test "Options:\n"
QRegExp rx("([^=]+)=(.*)"); " -help Display this help\n"
" -version Display application version\n"
" -no-splash Don't display splash screen\n"
" -client Attempt to connect to already running instance\n"
" -D <key>=<value> Permanently set a user setting, e.g: -D General/OverrideLanguage=de\n"
" -reset Reset user settings to factory defaults.\n"
" -config-file <file> Specify alternate factory defaults settings file (used with -reset)\n"
" -exit-after-config Exit after manipulating configuration settings\n";
for(int i = 0; i < argc; ++i ){ const QLatin1String HELP1_OPTION("-h");
if ( QString(CONFIG_OPTION).compare(QString(argv[i])) == 0 ){ const QLatin1String HELP2_OPTION("-help");
if ( rx.indexIn(argv[++i]) > -1 ){ const QLatin1String HELP3_OPTION("/h");
settingOptions.insert(rx.cap(1), rx.cap(2)); const QLatin1String HELP4_OPTION("--help");
const QLatin1String VERSION_OPTION("-version");
const QLatin1String NO_SPLASH_OPTION("-no-splash");
const QLatin1String CLIENT_OPTION("-client");
const QLatin1String CONFIG_OPTION("-D");
const QLatin1String RESET_OPTION("-reset");
const QLatin1String CONFIG_FILE_OPTION("-config-file");
const QLatin1String EXIT_AFTER_CONFIG_OPTION("-exit-after-config");
// Helpers for displaying messages. Note that there is no console on Windows.
void displayHelpText(QString t)
{
#ifdef Q_OS_WIN
// No console on Windows. (???)
// TODO there is a console on windows and popups are not always desired
t.replace(QLatin1Char('&'), QLatin1String("&amp;"));
t.replace(QLatin1Char('<'), QLatin1String("&lt;"));
t.replace(QLatin1Char('>'), QLatin1String("&gt;"));
t.insert(0, QLatin1String("<html><pre>"));
t.append(QLatin1String("</pre></html>"));
QMessageBox::information(0, APP_NAME, t);
#else
qWarning("%s", qPrintable(t));
#endif
}
void displayError(const QString &t)
{
#ifdef Q_OS_WIN
// No console on Windows. (???)
// TODO there is a console on windows and popups are not always desired
QMessageBox::critical(0, APP_NAME, t);
#else
qCritical("%s", qPrintable(t));
#endif
}
void printVersion(const ExtensionSystem::PluginSpec *corePlugin, const ExtensionSystem::PluginManager &pm)
{
QString version;
QTextStream str(&version);
str << '\n' << APP_NAME << ' ' << corePlugin->version() << " based on Qt " << qVersion() << "\n\n";
pm.formatPluginVersions(str);
str << '\n' << corePlugin->copyright() << '\n';
displayHelpText(version);
}
void printHelp(const QString &appExecName, const ExtensionSystem::PluginManager &pm)
{
QString help;
QTextStream str(&help);
str << "Usage: " << appExecName << fixedOptionsC;
ExtensionSystem::PluginManager::formatOptions(str, OptionIndent, DescriptionIndent);
pm.formatPluginOptions(str, OptionIndent, DescriptionIndent);
displayHelpText(help);
}
inline QString msgCoreLoadFailure(const QString &reason)
{
return QCoreApplication::translate("Application", "Failed to load core plug-in, reason is: %1").arg(reason);
}
inline QString msgSendArgumentFailed()
{
return QCoreApplication::translate("Application",
"Unable to send command line arguments to the already running instance. It appears to be not responding.");
}
// Prepare a remote argument: If it is a relative file, add the current directory
// since the the central instance might be running in a different directory.
inline QString prepareRemoteArgument(const QString &arg)
{
QFileInfo fi(arg);
if (!fi.exists()) {
return arg;
}
if (fi.isRelative()) {
return fi.absoluteFilePath();
}
return arg;
}
// Send the arguments to an already running instance of application
bool sendArguments(SharedTools::QtSingleApplication &app, const QStringList &arguments)
{
if (!arguments.empty()) {
// Send off arguments
const QStringList::const_iterator acend = arguments.constEnd();
for (QStringList::const_iterator it = arguments.constBegin(); it != acend; ++it) {
if (!app.sendMessage(prepareRemoteArgument(*it))) {
displayError(msgSendArgumentFailed());
return false;
}
} }
} }
if ( QString(CLEAN_CONFIG_OPTION).compare(QString(argv[i])) == 0 ){ // Special empty argument means: Show and raise (the slot just needs to be triggered)
settings.clear(); if (!app.sendMessage(QString())) {
displayError(msgSendArgumentFailed());
return false;
}
return true;
}
void systemInit()
{
#ifdef Q_OS_MAC
// increase the number of file that can be opened in application
struct rlimit rl;
getrlimit(RLIMIT_NOFILE, &rl);
rl.rlim_cur = rl.rlim_max;
setrlimit(RLIMIT_NOFILE, &rl);
#endif
#ifdef Q_OS_LINUX
QApplication::setAttribute(Qt::AA_X11InitThreads, true);
#endif
}
inline QStringList getPluginPaths()
{
QStringList rc;
// Figure out root: Up one from 'bin'
QDir rootDir = QApplication::applicationDirPath();
rootDir.cdUp();
const QString rootDirPath = rootDir.canonicalPath();
// 1) "plugins" (Win/Linux)
QString pluginPath = rootDirPath;
pluginPath += QLatin1Char('/');
pluginPath += QLatin1String(GCS_LIBRARY_BASENAME);
pluginPath += QLatin1Char('/');
pluginPath += QLatin1String("openpilotgcs");
pluginPath += QLatin1Char('/');
pluginPath += QLatin1String("plugins");
rc.push_back(pluginPath);
// 2) "PlugIns" (OS X)
pluginPath = rootDirPath;
pluginPath += QLatin1Char('/');
pluginPath += QLatin1String("Plugins");
rc.push_back(pluginPath);
return rc;
}
AppOptions options()
{
AppOptions appOptions;
appOptions.insert(HELP1_OPTION, false);
appOptions.insert(HELP2_OPTION, false);
appOptions.insert(HELP3_OPTION, false);
appOptions.insert(HELP4_OPTION, false);
appOptions.insert(VERSION_OPTION, false);
appOptions.insert(NO_SPLASH_OPTION, false);
appOptions.insert(CLIENT_OPTION, false);
appOptions.insert(CONFIG_OPTION, true);
appOptions.insert(RESET_OPTION, false);
appOptions.insert(CONFIG_FILE_OPTION, true);
appOptions.insert(EXIT_AFTER_CONFIG_OPTION, false);
return appOptions;
}
AppOptionValues parseCommandLine(SharedTools::QtSingleApplication &app,
ExtensionSystem::PluginManager &pluginManager, QString &errorMessage)
{
AppOptionValues appOptionValues;
const QStringList arguments = app.arguments();
if (arguments.size() > 1) {
AppOptions appOptions = options();
pluginManager.parseOptions(arguments, appOptions, &appOptionValues, &errorMessage);
}
return appOptionValues;
}
void loadFactoryDefaults(QSettings &settings, AppOptionValues &appOptionValues)
{
QDir directory(QCoreApplication::applicationDirPath() + SHARE_PATH + QString("/default_configurations"));
qDebug() << "Looking for factory defaults configuration files in:" << directory.absolutePath();
QString fileName;
// check if command line option -config-file contains a file name
QString commandLine = appOptionValues.value(CONFIG_FILE_OPTION);
if (!commandLine.isEmpty()) {
QFileInfo fi(commandLine);
if (fi.isRelative()) {
// file name specified on command line has a relative path
commandLine = directory.absolutePath() + QDir::separator() + commandLine;
}
if (QFile::exists(commandLine)) {
fileName = commandLine;
qDebug() << "Configuration file" << fileName << "specified on command line will be loaded.";
} else {
qWarning() << "Configuration file" << commandLine << "specified on command line does not exist.";
}
}
if (fileName.isEmpty()) {
// check default file
if (QFile::exists(directory.absolutePath() + QDir::separator() + DEFAULT_CONFIG_FILENAME)) {
// use default file name
fileName = directory.absolutePath() + QDir::separator() + DEFAULT_CONFIG_FILENAME;
qDebug() << "Default configuration file" << fileName << "will be loaded.";
} else {
qWarning() << "No default configuration file found in" << directory.absolutePath();
}
}
if (fileName.isEmpty()) {
// TODO should we exit violently?
qCritical() << "No default configuration file found!";
return;
}
// create settings from file
QSettings qs(fileName, XmlConfig::XmlSettingsFormat);
// transfer loaded settings to application settings
QStringList keys = qs.allKeys();
foreach(QString key, keys) {
settings.setValue(key, qs.value(key));
}
qDebug() << "Configuration file" << fileName << "was loaded.";
}
void overrideSettings(QSettings &settings, int argc, char **argv)
{
// Options like -D My/setting=test
QRegExp rx("([^=]+)=(.*)");
for (int i = 0; i < argc; ++i) {
if (CONFIG_OPTION == QString(argv[i])) {
if (rx.indexIn(argv[++i]) > -1) {
QString key = rx.cap(1);
QString value = rx.cap(2);
qDebug() << "User setting" << key << "set to value" << value;
settings.setValue(key, value);
}
}
}
settings.sync();
}
void loadTranslators(QString language, QTranslator &translator, QTranslator &qtTranslator)
{
const QString &creatorTrPath = QCoreApplication::applicationDirPath() + SHARE_PATH
+ QLatin1String("/translations");
if (translator.load(QLatin1String("openpilotgcs_") + language, creatorTrPath)) {
const QString &qtTrPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
const QString &qtTrFile = QLatin1String("qt_") + language;
// Binary installer puts Qt tr files into creatorTrPath
if (qtTranslator.load(qtTrFile, qtTrPath) || qtTranslator.load(qtTrFile, creatorTrPath)) {
QCoreApplication::installTranslator(&translator);
QCoreApplication::installTranslator(&qtTranslator);
} else {
// unload()
translator.load(QString());
}
} }
} }
QList<QString> keys = settingOptions.keys(); } // namespace anonymous
foreach ( QString key, keys ){
settings.setValue(key, settingOptions.value(key));
}
settings.sync();
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
QElapsedTimer timer; QElapsedTimer timer;
timer.start(); timer.start();
#ifdef Q_OS_MAC // low level init
// increase the number of file that can be opened in OpenPilot GCS systemInit();
struct rlimit rl;
getrlimit(RLIMIT_NOFILE, &rl);
rl.rlim_cur = rl.rlim_max;
setrlimit(RLIMIT_NOFILE, &rl);
#endif
#ifdef Q_OS_LINUX
QApplication::setAttribute(Qt::AA_X11InitThreads, true);
#endif
//Set the default locale to EN, if this is not set the system locale will be used // create application
//and as of now we dont want that behaviour. SharedTools::QtSingleApplication app(APP_NAME, argc, argv);
QLocale::setDefault(QLocale::English);
SharedTools::QtSingleApplication app((QLatin1String(appNameC)), argc, argv); // initialize the plugin manager
//Open Splashscreen
GCSSplashScreen splash;
splash.show();
QString locale = QLocale::system().name();
// Must be done before any QSettings class is created
QSettings::setPath(XmlConfig::XmlSettingsFormat, QSettings::SystemScope,
QCoreApplication::applicationDirPath()+QLatin1String(SHARE_PATH));
// keep this in sync with the MainWindow ctor in coreplugin/mainwindow.cpp
QSettings settings(XmlConfig::XmlSettingsFormat, QSettings::UserScope,
QLatin1String("OpenPilot"), QLatin1String("OpenPilotGCS_config"));
overrideSettings(settings, argc, argv);
locale = settings.value("General/OverrideLanguage", locale).toString();
QTranslator translator;
QTranslator qtTranslator;
const QString &creatorTrPath = QCoreApplication::applicationDirPath()
+ QLatin1String(SHARE_PATH "/translations");
if (translator.load(QLatin1String("openpilotgcs_") + locale, creatorTrPath)) {
const QString &qtTrPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
const QString &qtTrFile = QLatin1String("qt_") + locale;
// Binary installer puts Qt tr files into creatorTrPath
if (qtTranslator.load(qtTrFile, qtTrPath) || qtTranslator.load(qtTrFile, creatorTrPath)) {
QCoreApplication::installTranslator(&translator);
QCoreApplication::installTranslator(&qtTranslator);
} else {
translator.load(QString()); // unload()
}
}
app.setProperty("qtc_locale", locale); // Do we need this?
splash.showProgressMessage(QObject::tr("Application starting..."));
// Load
ExtensionSystem::PluginManager pluginManager; ExtensionSystem::PluginManager pluginManager;
pluginManager.setFileExtension(QLatin1String("pluginspec")); pluginManager.setFileExtension(QLatin1String("pluginspec"));
pluginManager.setPluginPaths(getPluginPaths());
const QStringList pluginPaths = getPluginPaths(); // parse command line
pluginManager.setPluginPaths(pluginPaths); qDebug() << "Command line" << app.arguments();
QString errorMessage;
const QStringList arguments = app.arguments(); AppOptionValues appOptionValues = parseCommandLine(app, pluginManager, errorMessage);
QMap<QString, QString> foundAppOptions; if (!errorMessage.isEmpty()) {
if (arguments.size() > 1) { // this will display two popups : one error popup + one usage string popup
QMap<QString, bool> appOptions; // TODO merge two popups into one.
appOptions.insert(QLatin1String(HELP_OPTION1), false); displayError(errorMessage);
appOptions.insert(QLatin1String(HELP_OPTION2), false); printHelp(QFileInfo(app.applicationFilePath()).baseName(), pluginManager);
appOptions.insert(QLatin1String(HELP_OPTION3), false); return -1;
appOptions.insert(QLatin1String(HELP_OPTION4), false);
appOptions.insert(QLatin1String(VERSION_OPTION), false);
appOptions.insert(QLatin1String(CLIENT_OPTION), false);
appOptions.insert(QLatin1String(CONFIG_OPTION), true);
appOptions.insert(QLatin1String(CLEAN_CONFIG_OPTION), false);
appOptions.insert(QLatin1String(EXIT_AFTER_CONFIG_OPTION), false);
QString errorMessage;
if (!pluginManager.parseOptions(arguments,
appOptions,
&foundAppOptions,
&errorMessage)) {
displayError(errorMessage);
printHelp(QFileInfo(app.applicationFilePath()).baseName(), pluginManager);
return -1;
}
} }
// load user settings
// Must be done before any QSettings class is created
// keep this in sync with the MainWindow ctor in coreplugin/mainwindow.cpp
QString settingsPath = QCoreApplication::applicationDirPath() + SHARE_PATH;
qDebug() << "Loading system settings from" << settingsPath;
QSettings::setPath(XmlConfig::XmlSettingsFormat, QSettings::SystemScope, settingsPath);
qDebug() << "Loading user settings from" << SETTINGS_ORG_NAME << "/" << SETTINGS_APP_NAME;
QSettings settings(XmlConfig::XmlSettingsFormat, QSettings::UserScope, SETTINGS_ORG_NAME, SETTINGS_APP_NAME);
// need to reset all user settings?
if (appOptionValues.contains(RESET_OPTION)) {
qDebug() << "Resetting user settings!";
settings.clear();
}
// check if we have user settings
if (!settings.allKeys().count()) {
// no user settings, load the factory defaults
qDebug() << "No user settings found, loading factory defaults...";
loadFactoryDefaults(settings, appOptionValues);
}
// override settings with command line provided values
// take notice that the overridden values will be saved in the user settings and will continue to be effective
// in subsequent GCS runs
overrideSettings(settings, argc, argv);
// initialize GCS locale
// use the value defined by the General/Locale setting or default to system Locale.
// the General/Locale setting is not available in the Options dialog, it is a hidden setting but can still be changed:
// - through the command line
// - editing the factory defaults XML file before 1st launch
// - editing the user XML file
QString localeName = settings.value("General/Locale", QLocale::system().name()).toString();
QLocale::setDefault(localeName);
// some debugging
qDebug() << "main - system locale:" << QLocale::system().name();
qDebug() << "main - GCS locale:" << QLocale().name();
// load translation file
// the language used is defined by the General/OverrideLanguage setting (defaults to GCS locale)
// if the translation file for the given language is not found, GCS will default to built in English.
QString language = settings.value("General/OverrideLanguage", localeName).toString();
qDebug() << "main - language:" << language;
QTranslator translator;
QTranslator qtTranslator;
loadTranslators(language, translator, qtTranslator);
app.setProperty("qtc_locale", localeName); // Do we need this?
if (appOptionValues.contains(EXIT_AFTER_CONFIG_OPTION)) {
qDebug() << "main - exiting after config!";
return 0;
}
// open the splash screen
GCSSplashScreen *splash = 0;
if (!appOptionValues.contains(NO_SPLASH_OPTION)) {
splash = new GCSSplashScreen();
// show splash
splash->showProgressMessage(QObject::tr("Application starting..."));
splash->show();
// connect to track progress of plugin manager
QObject::connect(&pluginManager, SIGNAL(pluginAboutToBeLoaded(ExtensionSystem::PluginSpec*)), splash,
SLOT(showPluginLoadingProgress(ExtensionSystem::PluginSpec*)));
}
// find and load core plugin
const PluginSpecSet plugins = pluginManager.plugins(); const PluginSpecSet plugins = pluginManager.plugins();
ExtensionSystem::PluginSpec *coreplugin = 0; ExtensionSystem::PluginSpec *coreplugin = 0;
foreach (ExtensionSystem::PluginSpec *spec, plugins) { foreach (ExtensionSystem::PluginSpec *spec, plugins) {
if (spec->name() == QLatin1String(corePluginNameC)) { if (spec->name() == CORE_PLUGIN_NAME) {
coreplugin = spec; coreplugin = spec;
break; break;
} }
} }
if(!coreplugin){ if (!coreplugin) {
QString nativePaths = QDir::toNativeSeparators(pluginPaths.join(QLatin1String(","))); QString nativePaths = QDir::toNativeSeparators(getPluginPaths().join(QLatin1String(",")));
const QString reason = QCoreApplication::translate("Application", "Could not find 'Core.pluginspec' in %1").arg(nativePaths); const QString reason = QCoreApplication::translate("Application", "Could not find 'Core.pluginspec' in %1").arg(
nativePaths);
displayError(msgCoreLoadFailure(reason)); displayError(msgCoreLoadFailure(reason));
return 1; return 1;
} }
@ -341,26 +516,21 @@ int main(int argc, char **argv)
displayError(msgCoreLoadFailure(coreplugin->errorString())); displayError(msgCoreLoadFailure(coreplugin->errorString()));
return 1; return 1;
} }
if (foundAppOptions.contains(QLatin1String(VERSION_OPTION))) {
if (appOptionValues.contains(VERSION_OPTION)) {
printVersion(coreplugin, pluginManager); printVersion(coreplugin, pluginManager);
return 0; return 0;
} }
if (foundAppOptions.contains(QLatin1String(EXIT_AFTER_CONFIG_OPTION))) { if (appOptionValues.contains(HELP1_OPTION) || appOptionValues.contains(HELP2_OPTION)
return 0; || appOptionValues.contains(HELP3_OPTION) || appOptionValues.contains(HELP4_OPTION)) {
}
if (foundAppOptions.contains(QLatin1String(HELP_OPTION1))
|| foundAppOptions.contains(QLatin1String(HELP_OPTION2))
|| foundAppOptions.contains(QLatin1String(HELP_OPTION3))
|| foundAppOptions.contains(QLatin1String(HELP_OPTION4))) {
printHelp(QFileInfo(app.applicationFilePath()).baseName(), pluginManager); printHelp(QFileInfo(app.applicationFilePath()).baseName(), pluginManager);
return 0; return 0;
} }
const bool isFirstInstance = !app.isRunning();
if (!isFirstInstance && foundAppOptions.contains(QLatin1String(CLIENT_OPTION)))
return sendArguments(app, pluginManager.arguments()) ? 0 : -1;
QObject::connect(&pluginManager, SIGNAL(pluginAboutToBeLoaded(ExtensionSystem::PluginSpec*)), const bool isFirstInstance = !app.isRunning();
&splash, SLOT(showPluginLoadingProgress(ExtensionSystem::PluginSpec*))); if (!isFirstInstance && appOptionValues.contains(CLIENT_OPTION)) {
return sendArguments(app, pluginManager.arguments()) ? 0 : -1;
}
pluginManager.loadPlugins(); pluginManager.loadPlugins();
@ -371,19 +541,21 @@ int main(int argc, char **argv)
{ {
QStringList errors; QStringList errors;
foreach (ExtensionSystem::PluginSpec *p, pluginManager.plugins()) foreach (ExtensionSystem::PluginSpec *p, pluginManager.plugins()) {
if (p->hasError()) if (p->hasError()) {
errors.append(p->errorString()); errors.append(p->errorString());
if (!errors.isEmpty()) }
}
if (!errors.isEmpty()) {
QMessageBox::warning(0, QMessageBox::warning(0,
QCoreApplication::translate("Application", "OpenPilot GCS - Plugin loader messages"), QCoreApplication::translate("Application", "OpenPilot GCS - Plugin loader messages"),
errors.join(QString::fromLatin1("\n\n"))); errors.join(QString::fromLatin1("\n\n")));
}
} }
if (isFirstInstance) { if (isFirstInstance) {
// Set up lock and remote arguments for the first instance only. // Set up lock and remote arguments for the first instance only.
// Silently fallback to unconnected instances for any subsequent // Silently fallback to unconnected instances for any subsequent instances.
// instances.
app.initialize(); app.initialize();
QObject::connect(&app, SIGNAL(messageReceived(QString)), coreplugin->plugin(), SLOT(remoteArgument(QString))); QObject::connect(&app, SIGNAL(messageReceived(QString)), coreplugin->plugin(), SLOT(remoteArgument(QString)));
} }
@ -392,15 +564,17 @@ int main(int argc, char **argv)
// Do this after the event loop has started // Do this after the event loop has started
QTimer::singleShot(100, &pluginManager, SLOT(startTests())); QTimer::singleShot(100, &pluginManager, SLOT(startTests()));
//Update message and postpone closing of splashscreen 3 seconds if (splash) {
splash.showProgressMessage(QObject::tr("Application started.")); // close and delete splash
QTimer::singleShot(1500, &splash, SLOT(close())); splash->close();
delete splash;
}
qDebug() << "main() took" << timer.elapsed() << "ms"; qDebug() << "main - main took" << timer.elapsed() << "ms";
int ret = app.exec(); int ret = app.exec();
qDebug() << "GCS ran for" << timer.elapsed() << "ms"; qDebug() << "main - GCS ran for" << timer.elapsed() << "ms";
return ret; return ret;
} }

View File

@ -125,23 +125,23 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) :
connect(m_config->wzBack,SIGNAL(clicked()),this,SLOT(wzBack())); connect(m_config->wzBack,SIGNAL(clicked()),this,SLOT(wzBack()));
m_config->stackedWidget->setCurrentIndex(0); m_config->stackedWidget->setCurrentIndex(0);
addUAVObjectToWidgetRelation("ManualControlSettings","FlightModePosition",m_config->fmsModePos1,0,1,true); addUAVObjectToWidgetRelation("ManualControlSettings", "FlightModePosition", m_config->fmsModePos1, 0, 1, true);
addUAVObjectToWidgetRelation("ManualControlSettings","FlightModePosition",m_config->fmsModePos2,1,1,true); addUAVObjectToWidgetRelation("ManualControlSettings", "FlightModePosition", m_config->fmsModePos2, 1, 1, true);
addUAVObjectToWidgetRelation("ManualControlSettings","FlightModePosition",m_config->fmsModePos3,2,1,true); addUAVObjectToWidgetRelation("ManualControlSettings", "FlightModePosition", m_config->fmsModePos3, 2, 1, true);
addUAVObjectToWidgetRelation("ManualControlSettings","FlightModePosition",m_config->fmsModePos4,3,1,true); addUAVObjectToWidgetRelation("ManualControlSettings", "FlightModePosition", m_config->fmsModePos4, 3, 1, true);
addUAVObjectToWidgetRelation("ManualControlSettings","FlightModePosition",m_config->fmsModePos5,4,1,true); addUAVObjectToWidgetRelation("ManualControlSettings", "FlightModePosition", m_config->fmsModePos5, 4, 1, true);
addUAVObjectToWidgetRelation("ManualControlSettings","FlightModePosition",m_config->fmsModePos6,5,1,true); addUAVObjectToWidgetRelation("ManualControlSettings", "FlightModePosition", m_config->fmsModePos6, 5, 1, true);
addUAVObjectToWidgetRelation("ManualControlSettings","FlightModeNumber",m_config->fmsPosNum); addUAVObjectToWidgetRelation("ManualControlSettings", "FlightModeNumber", m_config->fmsPosNum);
addUAVObjectToWidgetRelation("ManualControlSettings","Stabilization1Settings",m_config->fmsSsPos1Roll,"Roll"); addUAVObjectToWidgetRelation("ManualControlSettings", "Stabilization1Settings", m_config->fmsSsPos1Roll, "Roll", 1, true);
addUAVObjectToWidgetRelation("ManualControlSettings","Stabilization2Settings",m_config->fmsSsPos2Roll,"Roll"); addUAVObjectToWidgetRelation("ManualControlSettings", "Stabilization2Settings", m_config->fmsSsPos2Roll, "Roll", 1, true);
addUAVObjectToWidgetRelation("ManualControlSettings","Stabilization3Settings",m_config->fmsSsPos3Roll,"Roll"); addUAVObjectToWidgetRelation("ManualControlSettings", "Stabilization3Settings", m_config->fmsSsPos3Roll, "Roll", 1, true);
addUAVObjectToWidgetRelation("ManualControlSettings","Stabilization1Settings",m_config->fmsSsPos1Pitch,"Pitch"); addUAVObjectToWidgetRelation("ManualControlSettings", "Stabilization1Settings", m_config->fmsSsPos1Pitch, "Pitch", 1, true);
addUAVObjectToWidgetRelation("ManualControlSettings","Stabilization2Settings",m_config->fmsSsPos2Pitch,"Pitch"); addUAVObjectToWidgetRelation("ManualControlSettings", "Stabilization2Settings", m_config->fmsSsPos2Pitch, "Pitch", 1, true);
addUAVObjectToWidgetRelation("ManualControlSettings","Stabilization3Settings",m_config->fmsSsPos3Pitch,"Pitch"); addUAVObjectToWidgetRelation("ManualControlSettings", "Stabilization3Settings", m_config->fmsSsPos3Pitch, "Pitch", 1, true);
addUAVObjectToWidgetRelation("ManualControlSettings","Stabilization1Settings",m_config->fmsSsPos1Yaw,"Yaw"); addUAVObjectToWidgetRelation("ManualControlSettings", "Stabilization1Settings", m_config->fmsSsPos1Yaw, "Yaw", 1, true);
addUAVObjectToWidgetRelation("ManualControlSettings","Stabilization2Settings",m_config->fmsSsPos2Yaw,"Yaw"); addUAVObjectToWidgetRelation("ManualControlSettings", "Stabilization2Settings", m_config->fmsSsPos2Yaw, "Yaw", 1, true);
addUAVObjectToWidgetRelation("ManualControlSettings","Stabilization3Settings",m_config->fmsSsPos3Yaw,"Yaw"); addUAVObjectToWidgetRelation("ManualControlSettings", "Stabilization3Settings", m_config->fmsSsPos3Yaw, "Yaw", 1, true);
addUAVObjectToWidgetRelation("ManualControlSettings","Arming",m_config->armControl); addUAVObjectToWidgetRelation("ManualControlSettings","Arming",m_config->armControl);
addUAVObjectToWidgetRelation("ManualControlSettings","ArmedTimeout",m_config->armTimeout,0,1000); addUAVObjectToWidgetRelation("ManualControlSettings","ArmedTimeout",m_config->armTimeout,0,1000);

View File

@ -64,7 +64,8 @@
<file>images/tx-rx.svg</file> <file>images/tx-rx.svg</file>
<file>qml/images/tab.png</file> <file>qml/images/tab.png</file>
<file>qml/AboutDialog.qml</file> <file>qml/AboutDialog.qml</file>
<file>qml/FlickableWebView.qml</file> <file>qml/AuthorsModel.qml</file>
<file>qml/ScrollDecorator.qml</file>
<file>qml/TabWidget.qml</file> <file>qml/TabWidget.qml</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -1,22 +1,27 @@
TEMPLATE = lib TEMPLATE = lib
TARGET = Core TARGET = Core
DEFINES += CORE_LIBRARY DEFINES += CORE_LIBRARY
QT += declarative \ QT += declarative \
xml \ xml \
network \ network \
script \ script \
svg \ svg \
sql sql
include(../../openpilotgcsplugin.pri) include(../../openpilotgcsplugin.pri)
include(../../libs/utils/utils.pri) include(../../libs/utils/utils.pri)
include(../../shared/scriptwrapper/scriptwrapper.pri) include(../../shared/scriptwrapper/scriptwrapper.pri)
include(coreplugin_dependencies.pri) include(coreplugin_dependencies.pri)
INCLUDEPATH += dialogs \ INCLUDEPATH += dialogs \
uavgadgetmanager \ uavgadgetmanager \
actionmanager actionmanager
DEPENDPATH += dialogs \ DEPENDPATH += dialogs \
uavgadgetmanager \ uavgadgetmanager \
actionmanager actionmanager
SOURCES += mainwindow.cpp \ SOURCES += mainwindow.cpp \
tabpositionindicator.cpp \ tabpositionindicator.cpp \
fancyactionbar.cpp \ fancyactionbar.cpp \
@ -64,8 +69,8 @@ SOURCES += mainwindow.cpp \
workspacesettings.cpp \ workspacesettings.cpp \
uavconfiginfo.cpp \ uavconfiginfo.cpp \
authorsdialog.cpp \ authorsdialog.cpp \
telemetrymonitorwidget.cpp \ telemetrymonitorwidget.cpp
dialogs/importsettings.cpp
HEADERS += mainwindow.h \ HEADERS += mainwindow.h \
tabpositionindicator.h \ tabpositionindicator.h \
fancyactionbar.h \ fancyactionbar.h \
@ -126,20 +131,22 @@ HEADERS += mainwindow.h \
uavconfiginfo.h \ uavconfiginfo.h \
authorsdialog.h \ authorsdialog.h \
iconfigurableplugin.h \ iconfigurableplugin.h \
telemetrymonitorwidget.h \ telemetrymonitorwidget.h
dialogs/importsettings.h
FORMS += dialogs/settingsdialog.ui \ FORMS += dialogs/settingsdialog.ui \
dialogs/shortcutsettings.ui \ dialogs/shortcutsettings.ui \
generalsettings.ui \ generalsettings.ui \
uavgadgetoptionspage.ui \ uavgadgetoptionspage.ui \
workspacesettings.ui \ workspacesettings.ui
dialogs/importsettings.ui
RESOURCES += core.qrc \ RESOURCES += core.qrc \
fancyactionbar.qrc fancyactionbar.qrc
unix:!macx { unix:!macx {
images.files = images/openpilot_logo_*.png images.files = images/openpilot_logo_*.png
images.files = images/qtcreator_logo_*.png images.files = images/qtcreator_logo_*.png
images.path = /share/pixmaps images.path = /share/pixmaps
INSTALLS += images INSTALLS += images
} }
OTHER_FILES += Core.pluginspec OTHER_FILES += Core.pluginspec

View File

@ -1,57 +0,0 @@
#include "importsettings.h"
#include "ui_importsettings.h"
#include <QDir>
#include <QSettings>
#include <utils/xmlconfig.h>
#include <QTimer>
importSettings::importSettings(QWidget *parent) :
QDialog(parent),
ui(new Ui::importSettings)
{
ui->setupUi(this);
connect(ui->cbConfigs, SIGNAL(currentIndexChanged(int)), this, SLOT(updateDetails(int)));
connect(ui->btnLoad, SIGNAL(clicked()), this, SLOT(accept()));
QTimer::singleShot(500, this, SLOT(repaint()));
}
void importSettings::loadFiles(QString path)
{
QDir myDir(path);
QStringList filters;
filters << "*.xml";
QStringList list = myDir.entryList(filters,QDir::Files);
int x = 0;
foreach(QString fileStr, list) {
fileInfo *info = new fileInfo;
QSettings settings(path+QDir::separator() + fileStr, XmlConfig::XmlSettingsFormat);
settings.beginGroup("General");
info->description = settings.value("Description", "None").toString();
info->details = settings.value("Details", "None").toString();
settings.endGroup();
info->file = path + QDir::separator() + fileStr;
configList.insert(x,info);
ui->cbConfigs->addItem(info->description, x);
++x;
}
}
void importSettings::updateDetails(int index)
{
fileInfo *info = configList.value(ui->cbConfigs->itemData(index).toInt());
ui->lblDetails->setText(info->details);
}
QString importSettings::choosenConfig()
{
fileInfo *info = configList.value(ui->cbConfigs->itemData(ui->cbConfigs->currentIndex()).toInt());
return info->file;
}
importSettings::~importSettings()
{
foreach(fileInfo * info,configList.values()) {
delete info;
}
delete ui;
}

View File

@ -1,35 +0,0 @@
#ifndef IMPORTSETTINGS_H
#define IMPORTSETTINGS_H
#include <QDialog>
#include <QMap>
namespace Ui {
class importSettings;
}
class importSettings : public QDialog
{
Q_OBJECT
struct fileInfo {
QString file;
QString description;
QString details;
};
public:
explicit importSettings(QWidget *parent = 0);
~importSettings();
void loadFiles(QString path);
QString choosenConfig();
private:
Ui::importSettings *ui;
QMap<int,fileInfo*> configList;
private slots:
void updateDetails(int);
};
#endif // IMPORTSETTINGS_H

View File

@ -1,82 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>importSettings</class>
<widget class="QDialog" name="importSettings">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>373</width>
<height>167</height>
</rect>
</property>
<property name="windowTitle">
<string>OpenPilotGCS</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>No configuration file could be found.
Please choose from one of the default configurations</string>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cbConfigs"/>
</item>
<item>
<widget class="QLabel" name="lblDetails">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<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="btnLoad">
<property name="text">
<string>Load</string>
</property>
</widget>
</item>
<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>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -45,11 +45,11 @@ using namespace Core::Internal;
GeneralSettings::GeneralSettings(): GeneralSettings::GeneralSettings():
m_saveSettingsOnExit(true), m_saveSettingsOnExit(true),
m_dialog(0),
m_autoConnect(true), m_autoConnect(true),
m_autoSelect(true), m_autoSelect(true),
m_useUDPMirror(false), m_useUDPMirror(false),
m_useExpertMode(false) m_useExpertMode(false),
m_dialog(0)
{ {
} }
@ -88,23 +88,23 @@ void GeneralSettings::fillLanguageBox() const
m_page->languageBox->addItem(tr("<System Language>"), QString()); m_page->languageBox->addItem(tr("<System Language>"), QString());
// need to add this explicitly, since there is no qm file for English // need to add this explicitly, since there is no qm file for English
m_page->languageBox->addItem(QLatin1String("English"), QLatin1String("C")); m_page->languageBox->addItem(QLatin1String("English"), QLatin1String("C"));
if (currentLocale == QLatin1String("C")) if (currentLocale == QLatin1String("C")) {
m_page->languageBox->setCurrentIndex(m_page->languageBox->count() - 1); m_page->languageBox->setCurrentIndex(m_page->languageBox->count() - 1);
}
const QString creatorTrPath = const QString creatorTrPath = Core::ICore::instance()->resourcePath() + QLatin1String("/translations");
Core::ICore::instance()->resourcePath() + QLatin1String("/translations");
const QStringList languageFiles = QDir(creatorTrPath).entryList(QStringList(QLatin1String("openpilotgcs*.qm"))); const QStringList languageFiles = QDir(creatorTrPath).entryList(QStringList(QLatin1String("openpilotgcs*.qm")));
Q_FOREACH(const QString &languageFile, languageFiles) foreach(QString languageFile, languageFiles) {
{ int start = languageFile.indexOf(QLatin1Char('_')) + 1;
int start = languageFile.indexOf(QLatin1Char('_'))+1;
int end = languageFile.lastIndexOf(QLatin1Char('.')); int end = languageFile.lastIndexOf(QLatin1Char('.'));
const QString locale = languageFile.mid(start, end-start); const QString locale = languageFile.mid(start, end - start);
// no need to show a language that creator will not load anyway // no need to show a language that creator will not load anyway
if (hasQmFilesForLocale(locale, creatorTrPath)) { if (hasQmFilesForLocale(locale, creatorTrPath)) {
m_page->languageBox->addItem(QLocale::languageToString(QLocale(locale).language()), locale); m_page->languageBox->addItem(QLocale::languageToString(QLocale(locale).language()), locale);
if (locale == currentLocale) if (locale == currentLocale) {
m_page->languageBox->setCurrentIndex(m_page->languageBox->count() - 1); m_page->languageBox->setCurrentIndex(m_page->languageBox->count() - 1);
}
} }
} }
} }
@ -114,8 +114,11 @@ QWidget *GeneralSettings::createPage(QWidget *parent)
m_page = new Ui::GeneralSettings(); m_page = new Ui::GeneralSettings();
QWidget *w = new QWidget(parent); QWidget *w = new QWidget(parent);
m_page->setupUi(w); m_page->setupUi(w);
fillLanguageBox(); fillLanguageBox();
connect(m_page->checkAutoConnect,SIGNAL(stateChanged(int)),this,SLOT(slotAutoConnect(int)));
connect(m_page->checkAutoConnect, SIGNAL(stateChanged(int)), this, SLOT(slotAutoConnect(int)));
m_page->checkBoxSaveOnExit->setChecked(m_saveSettingsOnExit); m_page->checkBoxSaveOnExit->setChecked(m_saveSettingsOnExit);
m_page->checkAutoConnect->setChecked(m_autoConnect); m_page->checkAutoConnect->setChecked(m_autoConnect);
m_page->checkAutoSelect->setChecked(m_autoSelect); m_page->checkAutoSelect->setChecked(m_autoSelect);
@ -123,8 +126,7 @@ QWidget *GeneralSettings::createPage(QWidget *parent)
m_page->cbExpertMode->setChecked(m_useExpertMode); m_page->cbExpertMode->setChecked(m_useExpertMode);
m_page->colorButton->setColor(StyleHelper::baseColor()); m_page->colorButton->setColor(StyleHelper::baseColor());
connect(m_page->resetButton, SIGNAL(clicked()), connect(m_page->resetButton, SIGNAL(clicked()), this, SLOT(resetInterfaceColor()));
this, SLOT(resetInterfaceColor()));
return w; return w;
} }
@ -148,26 +150,28 @@ void GeneralSettings::finish()
delete m_page; delete m_page;
} }
void GeneralSettings::readSettings(QSettings* qs) void GeneralSettings::readSettings(QSettings *qs)
{ {
qs->beginGroup(QLatin1String("General")); qs->beginGroup(QLatin1String("General"));
m_language = qs->value(QLatin1String("OverrideLanguage"),QLocale::system().name()).toString(); m_language = qs->value(QLatin1String("OverrideLanguage"), QLocale::system().name()).toString();
m_saveSettingsOnExit = qs->value(QLatin1String("SaveSettingsOnExit"),m_saveSettingsOnExit).toBool(); m_saveSettingsOnExit = qs->value(QLatin1String("SaveSettingsOnExit"), m_saveSettingsOnExit).toBool();
m_autoConnect = qs->value(QLatin1String("AutoConnect"),m_autoConnect).toBool(); m_autoConnect = qs->value(QLatin1String("AutoConnect"), m_autoConnect).toBool();
m_autoSelect = qs->value(QLatin1String("AutoSelect"),m_autoSelect).toBool(); m_autoSelect = qs->value(QLatin1String("AutoSelect"), m_autoSelect).toBool();
m_useUDPMirror = qs->value(QLatin1String("UDPMirror"),m_useUDPMirror).toBool(); m_useUDPMirror = qs->value(QLatin1String("UDPMirror"), m_useUDPMirror).toBool();
m_useExpertMode = qs->value(QLatin1String("ExpertMode"),m_useExpertMode).toBool(); m_useExpertMode = qs->value(QLatin1String("ExpertMode"), m_useExpertMode).toBool();
qs->endGroup(); qs->endGroup();
} }
void GeneralSettings::saveSettings(QSettings* qs) void GeneralSettings::saveSettings(QSettings *qs)
{ {
qs->beginGroup(QLatin1String("General")); qs->beginGroup(QLatin1String("General"));
if (m_language.isEmpty()) if (m_language.isEmpty()) {
qs->remove(QLatin1String("OverrideLanguage")); qs->remove(QLatin1String("OverrideLanguage"));
else }
else {
qs->setValue(QLatin1String("OverrideLanguage"), m_language); qs->setValue(QLatin1String("OverrideLanguage"), m_language);
}
qs->setValue(QLatin1String("SaveSettingsOnExit"), m_saveSettingsOnExit); qs->setValue(QLatin1String("SaveSettingsOnExit"), m_saveSettingsOnExit);
qs->setValue(QLatin1String("AutoConnect"), m_autoConnect); qs->setValue(QLatin1String("AutoConnect"), m_autoConnect);
@ -217,8 +221,8 @@ void GeneralSettings::setLanguage(const QString &locale)
{ {
if (m_language != locale) { if (m_language != locale) {
if (!locale.isEmpty()) { if (!locale.isEmpty()) {
QMessageBox::information((QWidget*)Core::ICore::instance()->mainWindow(), tr("Restart required"), QMessageBox::information((QWidget*) Core::ICore::instance()->mainWindow(), tr("Restart required"),
tr("The language change will take effect after a restart of the OpenPilot GCS.")); tr("The language change will take effect after a restart of the OpenPilot GCS."));
} }
m_language = locale; m_language = locale;
} }
@ -251,8 +255,10 @@ bool GeneralSettings::useExpertMode() const
void GeneralSettings::slotAutoConnect(int value) void GeneralSettings::slotAutoConnect(int value)
{ {
if (value==Qt::Checked) if (value==Qt::Checked) {
m_page->checkAutoSelect->setEnabled(false); m_page->checkAutoSelect->setEnabled(false);
else }
else {
m_page->checkAutoSelect->setEnabled(true); m_page->checkAutoSelect->setEnabled(true);
}
} }

View File

@ -85,6 +85,7 @@ private:
QList<QTextCodec *> m_codecs; QList<QTextCodec *> m_codecs;
}; };
} // namespace Internal } // namespace Internal
} // namespace Core } // namespace Core

View File

@ -85,14 +85,12 @@
#include <QtGui/QMessageBox> #include <QtGui/QMessageBox>
#include <QDesktopServices> #include <QDesktopServices>
#include <QElapsedTimer> #include <QElapsedTimer>
#include "dialogs/importsettings.h"
#include <QDir> #include <QDir>
using namespace Core; using namespace Core;
using namespace Core::Internal; using namespace Core::Internal;
static const char *uriListMimeFormatC = "text/uri-list"; static const char *uriListMimeFormatC = "text/uri-list";
static const char *DEFAULT_CONFIG_FILENAME = "OpenPilotGCS.xml";
enum { debugMainWindow = 0 }; enum { debugMainWindow = 0 };
@ -269,66 +267,9 @@ void MainWindow::modeChanged(Core::IMode */*mode*/)
void MainWindow::extensionsInitialized() void MainWindow::extensionsInitialized()
{ {
QSettings *qs = m_settings; QSettings *qs = m_settings;
if (!qs->allKeys().count()) {
// no user settings, so try to load some default ones
QDir directory(QCoreApplication::applicationDirPath());
#ifdef Q_OS_MAC
directory.cdUp();
directory.cd("Resources");
#else
directory.cdUp();
directory.cd("share");
directory.cd("openpilotgcs");
#endif
directory.cd("default_configurations");
qDebug() << "Looking for configuration files in:" << directory.absolutePath();
QString filename;
// check if command line contains a config file name
QString commandLine;
foreach(QString str, qApp->arguments()) {
if (str.contains("configfile")) {
commandLine = str.split("=").at(1);
}
}
if (!commandLine.isEmpty() && QFile::exists(directory.absolutePath() + QDir::separator() + commandLine)) {
// use file name specified on command line
filename = directory.absolutePath() + QDir::separator() + commandLine;
qDebug() << "Configuration file" << filename << "specified on command line will be loaded.";
} else if (QFile::exists(directory.absolutePath() + QDir::separator() + DEFAULT_CONFIG_FILENAME)) {
// use default file name
filename = directory.absolutePath() + QDir::separator() + DEFAULT_CONFIG_FILENAME;
qDebug() << "Default configuration file" << filename << "will be loaded.";
} else {
// prompt user for default file name
qDebug() << "Default configuration file" << directory.absolutePath() << QDir::separator()
<< DEFAULT_CONFIG_FILENAME << "was not found.";
importSettings *dialog = new importSettings(this);
dialog->loadFiles(directory.absolutePath());
dialog->exec();
filename = dialog->choosenConfig();
delete dialog;
qDebug() << "Configuration file" << filename << "was selected and will be loaded.";
}
// create settings from file
qs = new QSettings(filename, XmlConfig::XmlSettingsFormat);
// transfer loaded settings to application settings
QStringList keys = qs->allKeys();
foreach(QString key, keys) {
m_settings->setValue(key, qs->value(key));
}
// and delete loaded settings
delete qs;
qs = m_settings;
qDebug() << "Configuration file" << filename << "was loaded.";
}
qs->beginGroup("General"); qs->beginGroup("General");
m_config_description = qs->value("Description", "none").toString(); m_config_description = qs->value("Description", "none").toString();
m_config_details = qs->value("Details", "none").toString(); m_config_details = qs->value("Details", "none").toString();
m_config_stylesheet = qs->value("StyleSheet", "none").toString(); m_config_stylesheet = qs->value("StyleSheet", "none").toString();

View File

@ -39,72 +39,74 @@
****************************************************************************/ ****************************************************************************/
import QtQuick 1.1 import QtQuick 1.1
import QtWebKit 1.0
// This is a tabbed pane element. Add a nested Rectangle to add a tab. // This is a tabbed pane element. Add a nested Rectangle to add a tab.
TabWidget { TabWidget {
id: tabs // Define AuthorsModel as type
width: 640; height: 480 property AuthorsModel authors: AuthorsModel {}
// This tab is for the GCS version information
Rectangle { id: tabs
property string title: "OpenPilot GCS" width: 640; height: 480
anchors.fill: parent // This tab is for the GCS version information
color: "#e3e3e3" Rectangle {
property string title: "OpenPilot GCS"
Rectangle { anchors.fill: parent
anchors.fill: parent; anchors.margins: 20 color: "#e3e3e3"
color: "#e3e3e3"
Image { Rectangle {
source: "../images/openpilot_logo_128.png" anchors.fill: parent; anchors.margins: 20
x: 0; y: 0; z: 100 color: "#e3e3e3"
fillMode: Image.PreserveAspectFit Image {
} source: "../images/openpilot_logo_128.png"
Flickable { x: 0; y: 0; z: 100
anchors.fill: parent fillMode: Image.PreserveAspectFit
anchors.centerIn: parent }
Text { Flickable {
id: versionLabel anchors.fill: parent
x: 156; y: 0 anchors.centerIn: parent
width: 430; height: 379 Text {
horizontalAlignment: Qt.AlignLeft id: versionLabel
font.pixelSize: 12 x: 156; y: 0
wrapMode: Text.WordWrap width: 430; height: 379
// @var version exposed in authorsdialog.cpp horizontalAlignment: Qt.AlignLeft
text: version font.pixelSize: 12
} wrapMode: Text.WordWrap
} // @var version exposed in authorsdialog.cpp
text: version
}
} }
} }
// This is a stub for the Plugins. }
// Rectangle {
// property string title: "Plugins" // This tab is for the authors/contributors/credits
// anchors.fill: parent Rectangle {
// color: "#e3e3e3" property string title: "Authors"
// anchors.fill: parent; color: "#e3e3e3"
// Rectangle {
// anchors.fill: parent; anchors.margins: 20
// color: "#7fff7f"
// Text {
// width: parent.width - 20
// anchors.centerIn: parent; horizontalAlignment: Qt.AlignHCenter
// font.pixelSize: 20
// wrapMode: Text.WordWrap
// }
// }
// }
// This tab is for the authors/contributors/credits
Rectangle { Rectangle {
property string title: "Authors" anchors.fill: parent; anchors.margins: 20
anchors.fill: parent; color: "#e3e3e3" color: "#e3e3e3"
Rectangle { Text {
anchors.fill: parent; anchors.margins: 20 id: description
color: "#e3e3e3" text: "<h4>These people have been key contributors to the OpenPilot project. Without the work of the people in this list, OpenPilot would not be what it is today.</h4><p>This list is sorted alphabetically by name</p>"
FlickableWebView { width: 600
id: webView wrapMode: Text.WordWrap
z: 0
url: "../CREDITS.html" }
anchors { top: parent.top; left: parent.left; right: parent.right; bottom: parent.bottom } ListView {
} id: authorsView
} y: description.y + description.height + 20
} width: parent.width; height: parent.height - description.height - 20
} spacing: 3
model: authors
delegate: Text {
text: name
}
clip: true
}
ScrollDecorator {
flickableItem: authorsView
}
}
}
}

View File

@ -0,0 +1,151 @@
/*
This list model was created for the AuthorsDialog.
*/
import QtQuick 1.1
ListModel {
ListElement{ name:"Connor Abbott" }
ListElement{ name:"David Ankers" }
ListElement{ name:"Sergiy Anikeyev" }
ListElement{ name:"Pedro Assuncao" }
ListElement{ name:"Fredrik Arvidsson" }
ListElement{ name:"Werner Backes" }
ListElement{ name:"Jose Barros" }
ListElement{ name:"Pete Boehl" }
ListElement{ name:"David Carlson" }
ListElement{ name:"James Cotton" }
ListElement{ name:"Steve Doll" }
ListElement{ name:"Piotr Esden-Tempski" }
ListElement{ name:"Richard Flay" }
ListElement{ name:"Peter Farnworth" }
ListElement{ name:"Ed Faulkner" }
ListElement{ name:"Darren Furniss" }
ListElement{ name:"Frederic Goddeeris" }
ListElement{ name:"Daniel Godin" }
ListElement{ name:"Bani Greyling" }
ListElement{ name:"Nuno Guedes" }
ListElement{ name:"Erik Gustavsson" }
ListElement{ name:"Peter Gunnarsson" }
ListElement{ name:"Dean Hall" }
ListElement{ name:"Joe Hlebasko" }
ListElement{ name:"Andy Honecker" }
ListElement{ name:"Ryan Hunt" }
ListElement{ name:"Mark James" }
ListElement{ name:"Sami Korhonen" }
ListElement{ name:"Thorsten Klose" }
ListElement{ name:"Hallvard Kristiansen" }
ListElement{ name:"Edouard Lafargue" }
ListElement{ name:"Mike Labranche" }
ListElement{ name:"Fredrik Larsson" }
ListElement{ name:"Pablo Lema" }
ListElement{ name:"David Llama" }
ListElement{ name:"Matt Lipski" }
ListElement{ name:"Les Newell" }
ListElement{ name:"Ken Northup" }
ListElement{ name:"Greg Matthews" }
ListElement{ name:"Guy McCaldin" }
ListElement{ name:"Gary Mortimer" }
ListElement{ name:"Alessio Morale" }
ListElement{ name:"Cathy Moss" }
ListElement{ name:"Angus Peart" }
ListElement{ name:"Dmytro Poplavskiy" }
ListElement{ name:"Eric Price" }
ListElement{ name:"Richard Querin" }
ListElement{ name:"Randy Ram" }
ListElement{ name:"Laurent Ribon" }
ListElement{ name:"Julien Rouviere" }
ListElement{ name:"Jackson Russell" }
ListElement{ name:"Zik Saleeba" }
ListElement{ name:"Professor Dale Schinstock" }
ListElement{ name:"Professor Kenn Sebesta" }
ListElement{ name:"Oleg Semyonov" }
ListElement{ name:"Stacey Sheldon" }
ListElement{ name:"Troy Schultz" }
ListElement{ name:"Dr. Erhard Siegl" }
ListElement{ name:"Mike Smith" }
ListElement{ name:"Alex Sowa" }
ListElement{ name:"Pete Stapley" }
ListElement{ name:"Rowan Taubitz" }
ListElement{ name:"Andrew Thoms" }
ListElement{ name:"Jasper van Loenen" }
ListElement{ name:"Vassilis Varveropoulos" }
ListElement{ name:"Kevin Vertucio" }
ListElement{ name:"Alex Vrubel" }
ListElement{ name:"Brian Webb" }
ListElement{ name:"Justin Welander" }
ListElement{ name:"Mat Wellington" }
ListElement{ name:"Kendal Wells" }
ListElement{ name:"Dmitriy Zaitsev" }
}

View File

@ -1,196 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the QtDeclarative module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 1.0
import QtWebKit 1.0
Flickable {
property alias title: webView.title
property alias icon: webView.icon
property alias progress: webView.progress
property alias url: webView.url
property alias back: webView.back
property alias stop: webView.stop
property alias reload: webView.reload
property alias forward: webView.forward
id: flickable
width: parent.width
contentWidth: Math.max(parent.width,webView.width)
contentHeight: Math.max(parent.height,webView.height)
// anchors.top: headerSpace.bottom
anchors.bottom: parent.top
anchors.left: parent.left
anchors.right: parent.right
pressDelay: 200
clip: true
onWidthChanged : {
// Expand (but not above 1:1) if otherwise would be smaller that available width.
if (width > webView.width*webView.contentsScale && webView.contentsScale < 1.0)
webView.contentsScale = width / webView.width * webView.contentsScale;
}
WebView {
id: webView
transformOrigin: Item.TopLeft
function fixUrl(url)
{
if (url == "") return url
if (url[0] == "/") return "file://"+url
if (url.indexOf(":")<0) {
if (url.indexOf(".")<0 || url.indexOf(" ")>=0) {
// Fall back to a search engine; hard-code Wikipedia
return "http://en.wikipedia.org/w/index.php?search="+url
} else {
return "http://"+url
}
}
return url
}
url: fixUrl(webBrowser.urlString)
smooth: false // We don't want smooth scaling, since we only scale during (fast) transitions
focus: true
onAlert: console.log(message)
function doZoom(zoom,centerX,centerY)
{
if (centerX) {
var sc = zoom*contentsScale;
scaleAnim.to = sc;
flickVX.from = flickable.contentX
flickVX.to = Math.max(0,Math.min(centerX-flickable.width/2,webView.width*sc-flickable.width))
finalX.value = flickVX.to
flickVY.from = flickable.contentY
flickVY.to = Math.max(0,Math.min(centerY-flickable.height/2,webView.height*sc-flickable.height))
finalY.value = flickVY.to
quickZoom.start()
}
}
Keys.onLeftPressed: webView.contentsScale -= 0.1
Keys.onRightPressed: webView.contentsScale += 0.1
preferredWidth: flickable.width
preferredHeight: flickable.height
contentsScale: 1
onContentsSizeChanged: {
// zoom out
contentsScale = Math.min(1,flickable.width / contentsSize.width)
}
onUrlChanged: {
// got to topleft
flickable.contentX = 0
flickable.contentY = 0
// if (url != null) { header.editUrl = url.toString(); }
}
onDoubleClick: {
if (!heuristicZoom(clickX,clickY,2.5)) {
var zf = flickable.width / contentsSize.width
if (zf >= contentsScale)
zf = 2.0*contentsScale // zoom in (else zooming out)
doZoom(zf,clickX*zf,clickY*zf)
}
}
SequentialAnimation {
id: quickZoom
PropertyAction {
target: webView
property: "renderingEnabled"
value: false
}
ParallelAnimation {
NumberAnimation {
id: scaleAnim
target: webView
property: "contentsScale"
// the to property is set before calling
easing.type: Easing.Linear
duration: 200
}
NumberAnimation {
id: flickVX
target: flickable
property: "contentX"
easing.type: Easing.Linear
duration: 200
from: 0 // set before calling
to: 0 // set before calling
}
NumberAnimation {
id: flickVY
target: flickable
property: "contentY"
easing.type: Easing.Linear
duration: 200
from: 0 // set before calling
to: 0 // set before calling
}
}
// Have to set the contentXY, since the above 2
// size changes may have started a correction if
// contentsScale < 1.0.
PropertyAction {
id: finalX
target: flickable
property: "contentX"
value: 0 // set before calling
}
PropertyAction {
id: finalY
target: flickable
property: "contentY"
value: 0 // set before calling
}
PropertyAction {
target: webView
property: "renderingEnabled"
value: true
}
}
onZoomTo: doZoom(zoom,centerX,centerY)
}
}

View File

@ -0,0 +1,40 @@
import QtQuick 1.1
Rectangle {
id: scrollDecorator
property Flickable flickableItem: null
Loader {
id: scrollLoader
sourceComponent: scrollDecorator.flickableItem ? scrollBar : undefined
}
Component.onDestruction: scrollLoader.sourceComponent = undefined
Component {
id: scrollBar
Rectangle {
property Flickable flickable: scrollDecorator.flickableItem
parent: flickable
anchors.right: parent.right
smooth: true
radius: 2
color: "gray"
border.color: "lightgray"
border.width: 1.0
opacity: flickable.moving ? 0.8 : 0.4
Behavior on opacity {
NumberAnimation { duration: 500 }
}
width: 4
height: flickable.height * (flickable.height / flickable.contentHeight)
y: flickable.height * (flickable.contentY / flickable.contentHeight)
visible: flickable.height < flickable.contentHeight
}
}
}

View File

@ -101,18 +101,27 @@ void UAVObjectField::constructorInitialize(const QString& name, const QString& u
void UAVObjectField::limitsInitialize(const QString &limits) void UAVObjectField::limitsInitialize(const QString &limits)
{ {
/// format // Limit string format:
/// (TY)->type (EQ-equal;NE-not equal;BE-between;BI-bigger;SM-smaller) // % - start char
/// (VALX)->value // XXXX - optional BOARD_TYPE and BOARD_REVISION (4 hex digits)
/// %TY:VAL1:VAL2:VAL3,%TY,VAL1,VAL2,VAL3 // TY - rule type (EQ-equal, NE-not equal, BE-between, BI-bigger, SM-smaller)
/// example: first element bigger than 3 and second element inside [2.3,5] // VAL - values for TY separated by colon
/// "%BI:3,%BE:2.3:5" // , - rule separator (may have leading or trailing spaces)
// ; - element separator (may have leading or trailing spaces)
//
// Examples:
// Disable few flight modes for Revo (00903):
// "%0903NE:Autotune:VelocityControl:PositionHold:ReturnToBase:Land:PathPlanner"
// Original CC board (rev 1), first element bigger than 3 and second element inside [2.3-5.0]:
// "%0401BI:3; %BE:2.3:5"
// Set applicable range [0-500] for 3 elements of array for all boards:
// "%BE:0:500; %BE:0:500; %BE:0:500"
if(limits.isEmpty()) if(limits.isEmpty())
return; return;
QStringList stringPerElement=limits.split(","); QStringList stringPerElement = limits.split(";");
quint32 index=0; quint32 index=0;
foreach (QString str, stringPerElement) { foreach (QString str, stringPerElement) {
QStringList ruleList=str.split(";"); QStringList ruleList = str.split(",");
QList<LimitStruct> limitList; QList<LimitStruct> limitList;
foreach(QString rule,ruleList) foreach(QString rule,ruleList)
{ {

View File

@ -20,13 +20,55 @@
<field name="Arming" units="" type="enum" elements="1" options="Always Disarmed,Always Armed,Roll Left,Roll Right,Pitch Forward,Pitch Aft,Yaw Left,Yaw Right" defaultvalue="Always Disarmed"/> <field name="Arming" units="" type="enum" elements="1" options="Always Disarmed,Always Armed,Roll Left,Roll Right,Pitch Forward,Pitch Aft,Yaw Left,Yaw Right" defaultvalue="Always Disarmed"/>
<!-- Note these options should be identical to those in StabilizationDesired.StabilizationMode --> <!-- Note these options should be identical to those in StabilizationDesired.StabilizationMode -->
<field name="Stabilization1Settings" units="" type="enum" elementnames="Roll,Pitch,Yaw" options="None,Rate,Attitude,AxisLock,WeakLeveling,VirtualBar,RelayRate,RelayAttitude" defaultvalue="Attitude,Attitude,Rate"/> <field name="Stabilization1Settings" units="" type="enum"
<field name="Stabilization2Settings" units="" type="enum" elementnames="Roll,Pitch,Yaw" options="None,Rate,Attitude,AxisLock,WeakLeveling,VirtualBar,RelayRate,RelayAttitude" defaultvalue="Attitude,Attitude,Rate"/> elementnames="Roll,Pitch,Yaw"
<field name="Stabilization3Settings" units="" type="enum" elementnames="Roll,Pitch,Yaw" options="None,Rate,Attitude,AxisLock,WeakLeveling,VirtualBar,RelayRate,RelayAttitude" defaultvalue="Attitude,Attitude,Rate"/> options="None,Rate,Attitude,AxisLock,WeakLeveling,VirtualBar,RelayRate,RelayAttitude"
defaultvalue="Attitude,Attitude,Rate"
limits="%NE:RelayRate:RelayAttitude; %NE:RelayRate:RelayAttitude; %NE:RelayRate:RelayAttitude;"/>
<field name="Stabilization2Settings" units="" type="enum"
elementnames="Roll,Pitch,Yaw"
options="None,Rate,Attitude,AxisLock,WeakLeveling,VirtualBar,RelayRate,RelayAttitude"
defaultvalue="Attitude,Attitude,Rate"
limits="%NE:RelayRate:RelayAttitude; %NE:RelayRate:RelayAttitude; %NE:RelayRate:RelayAttitude;"/>
<field name="Stabilization3Settings" units="" type="enum"
elementnames="Roll,Pitch,Yaw"
options="None,Rate,Attitude,AxisLock,WeakLeveling,VirtualBar,RelayRate,RelayAttitude"
defaultvalue="Attitude,Attitude,Rate"
limits="%NE:RelayRate:RelayAttitude; %NE:RelayRate:RelayAttitude; %NE:RelayRate:RelayAttitude;"/>
<!-- Note these options values should be identical to those defined in FlightMode --> <!-- Note these options values should be identical to those defined in FlightMode -->
<field name="FlightModeNumber" units="" type="uint8" elements="1" defaultvalue="3"/> <field name="FlightModeNumber" units="" type="uint8" elements="1" defaultvalue="3"/>
<field name="FlightModePosition" units="" type="enum" elements="6" options="Manual,Stabilized1,Stabilized2,Stabilized3,Autotune,AltitudeHold,VelocityControl,PositionHold,ReturnToBase,Land,PathPlanner,POI" defaultvalue="Manual,Stabilized1,Stabilized2,Stabilized3,AltitudeHold,PositionHold" limits="%0401NE:AltitudeHold:VelocityControl:PositionHold:Autotune:POI;%0402NE:AltitudeHold:VelocityControl:PositionHold:Autotune:POI,%0401NE:AltitudeHold:VelocityControl:PositionHold:Autotune:POI;%0402NE:AltitudeHold:VelocityControl:PositionHold:Autotune:POI,%0401NE:AltitudeHold:VelocityControl:PositionHold:Autotune:POI;%0402NE:AltitudeHold:VelocityControl:PositionHold:Autotune:POI,%0401NE:AltitudeHold:VelocityControl:PositionHold:Autotune:POI;%0402NE:AltitudeHold:VelocityControl:PositionHold:Autotune:POI,%0401NE:AltitudeHold:VelocityControl:PositionHold:Autotune:POI;%0402NE:AltitudeHold:VelocityControl:PositionHold:Autotune:POI,%0401NE:AltitudeHold:VelocityControl:PositionHold:Autotune:POI;%0402NE:AltitudeHold:VelocityControl:PositionHold:Autotune:POI"/> <!-- Currently only some modes are enabled for UI using limits attribute per board. Update when more modes will be operational -->
<field name="FlightModePosition"
units=""
type="enum"
elements="6"
options="Manual,Stabilized1,Stabilized2,Stabilized3,Autotune,AltitudeHold,VelocityControl,PositionHold,ReturnToBase,Land,PathPlanner,POI"
defaultvalue="Manual,Stabilized1,Stabilized2,Stabilized3,AltitudeHold,PositionHold"
limits="\
%0401NE:Autotune:AltitudeHold:VelocityControl:PositionHold:ReturnToBase:Land:PathPlanner:POI,\
%0402NE:Autotune:AltitudeHold:VelocityControl:PositionHold:ReturnToBase:Land:PathPlanner:POI,\
%0903NE:Autotune:VelocityControl;\
\
%0401NE:Autotune:AltitudeHold:VelocityControl:PositionHold:ReturnToBase:Land:PathPlanner:POI,\
%0402NE:Autotune:AltitudeHold:VelocityControl:PositionHold:ReturnToBase:Land:PathPlanner:POI,\
%0903NE:Autotune:VelocityControl;\
\
%0401NE:Autotune:AltitudeHold:VelocityControl:PositionHold:ReturnToBase:Land:PathPlanner:POI,\
%0402NE:Autotune:AltitudeHold:VelocityControl:PositionHold:ReturnToBase:Land:PathPlanner:POI,\
%0903NE:Autotune:VelocityControl;\
\
%0401NE:Autotune:AltitudeHold:VelocityControl:PositionHold:ReturnToBase:Land:PathPlanner:POI,\
%0402NE:Autotune:AltitudeHold:VelocityControl:PositionHold:ReturnToBase:Land:PathPlanner:POI,\
%0903NE:Autotune:VelocityControl;\
\
%0401NE:Autotune:AltitudeHold:VelocityControl:PositionHold:ReturnToBase:Land:PathPlanner:POI,\
%0402NE:Autotune:AltitudeHold:VelocityControl:PositionHold:ReturnToBase:Land:PathPlanner:POI,\
%0903NE:Autotune:VelocityControl;\
\
%0401NE:Autotune:AltitudeHold:VelocityControl:PositionHold:ReturnToBase:Land:PathPlanner:POI,\
%0402NE:Autotune:AltitudeHold:VelocityControl:PositionHold:ReturnToBase:Land:PathPlanner:POI,\
%0903NE:Autotune:VelocityControl"/>
<field name="ArmedTimeout" units="ms" type="uint16" elements="1" defaultvalue="30000"/> <field name="ArmedTimeout" units="ms" type="uint16" elements="1" defaultvalue="30000"/>
<field name="FailsafeBehavior" units="" type="enum" elements="1" options="None" defaultvalue="None"/> <field name="FailsafeBehavior" units="" type="enum" elements="1" options="None" defaultvalue="None"/>

View File

@ -4,15 +4,15 @@
<field name="RollMax" units="degrees" type="uint8" elements="1" defaultvalue="60" limits="%BE:0:180"/> <field name="RollMax" units="degrees" type="uint8" elements="1" defaultvalue="60" limits="%BE:0:180"/>
<field name="PitchMax" units="degrees" type="uint8" elements="1" defaultvalue="60" limits="%BE:0:180"/> <field name="PitchMax" units="degrees" type="uint8" elements="1" defaultvalue="60" limits="%BE:0:180"/>
<field name="YawMax" units="degrees" type="uint8" elements="1" defaultvalue="60" limits="%BE:0:180"/> <field name="YawMax" units="degrees" type="uint8" elements="1" defaultvalue="60" limits="%BE:0:180"/>
<field name="ManualRate" units="degrees/sec" type="float" elementnames="Roll,Pitch,Yaw" defaultvalue="200,200,200" limits="%BE:0:500,%BE:0:500,%BE:0:500"/> <field name="ManualRate" units="degrees/sec" type="float" elementnames="Roll,Pitch,Yaw" defaultvalue="200,200,200" limits="%BE:0:500; %BE:0:500; %BE:0:500"/>
<field name="MaximumRate" units="degrees/sec" type="float" elementnames="Roll,Pitch,Yaw" defaultvalue="300,300,300" limits="%BE:0:500,%BE:0:500,%BE:0:500"/> <field name="MaximumRate" units="degrees/sec" type="float" elementnames="Roll,Pitch,Yaw" defaultvalue="300,300,300" limits="%BE:0:500; %BE:0:500; %BE:0:500"/>
<field name="RollRatePID" units="" type="float" elementnames="Kp,Ki,Kd,ILimit" defaultvalue="0.003,0.003,0.00002,0.3" limits="%BE:0:0.01,%BE:0:0.01,, "/> <field name="RollRatePID" units="" type="float" elementnames="Kp,Ki,Kd,ILimit" defaultvalue="0.003,0.003,0.00002,0.3" limits="%BE:0:0.01; %BE:0:0.01; ; "/>
<field name="PitchRatePID" units="" type="float" elementnames="Kp,Ki,Kd,ILimit" defaultvalue="0.003,0.003,0.00002,0.3" limits="%BE:0:0.01,%BE:0:0.01,, "/> <field name="PitchRatePID" units="" type="float" elementnames="Kp,Ki,Kd,ILimit" defaultvalue="0.003,0.003,0.00002,0.3" limits="%BE:0:0.01; %BE:0:0.01; ; "/>
<field name="YawRatePID" units="" type="float" elementnames="Kp,Ki,Kd,ILimit" defaultvalue="0.0035,0.0035,0,0.3" limits="%BE:0:0.01,%BE:0:0.01,, "/> <field name="YawRatePID" units="" type="float" elementnames="Kp,Ki,Kd,ILimit" defaultvalue="0.0035,0.0035,0,0.3" limits="%BE:0:0.01; %BE:0:0.01 ; ; "/>
<field name="RollPI" units="" type="float" elementnames="Kp,Ki,ILimit" defaultvalue="2.5,0,50" limits="%BE:0:10,%BE:0:10,"/> <field name="RollPI" units="" type="float" elementnames="Kp,Ki,ILimit" defaultvalue="2.5,0,50" limits="%BE:0:10; %BE:0:10; "/>
<field name="PitchPI" units="" type="float" elementnames="Kp,Ki,ILimit" defaultvalue="2.5,0,50" limits="%BE:0:10,%BE:0:10,"/> <field name="PitchPI" units="" type="float" elementnames="Kp,Ki,ILimit" defaultvalue="2.5,0,50" limits="%BE:0:10; %BE:0:10; "/>
<field name="YawPI" units="" type="float" elementnames="Kp,Ki,ILimit" defaultvalue="2,0,50" limits="%BE:0:10,%BE:0:10,"/> <field name="YawPI" units="" type="float" elementnames="Kp,Ki,ILimit" defaultvalue="2,0,50" limits="%BE:0:10; %BE:0:10; "/>
<field name="VbarSensitivity" units="frac" type="float" elementnames="Roll,Pitch,Yaw" defaultvalue="0.5,0.5,0.5"/> <field name="VbarSensitivity" units="frac" type="float" elementnames="Roll,Pitch,Yaw" defaultvalue="0.5,0.5,0.5"/>
<field name="VbarRollPI" units="1/(deg/s)" type="float" elementnames="Kp,Ki" defaultvalue="0.005,0.002"/> <field name="VbarRollPI" units="1/(deg/s)" type="float" elementnames="Kp,Ki" defaultvalue="0.005,0.002"/>