Maemo: Add interface for ssh library (completely #ifdef'ed out for now).

This will replace the current ssh-via-QProcess approach, which
has severe drawbacks.
This commit is contained in:
ck
2009-12-23 10:53:57 +01:00
parent 1c1394c1eb
commit a266e638d6
12 changed files with 673 additions and 116 deletions

View File

@@ -68,7 +68,7 @@ class DevConfIdMatcher
{ {
public: public:
DevConfIdMatcher(quint64 id) : m_id(id) {} DevConfIdMatcher(quint64 id) : m_id(id) {}
bool operator()(const MaemoDeviceConfigurations::DeviceConfig &devConfig) bool operator()(const MaemoDeviceConfig &devConfig)
{ {
return devConfig.internalId == m_id; return devConfig.internalId == m_id;
} }
@@ -76,7 +76,7 @@ private:
const quint64 m_id; const quint64 m_id;
}; };
MaemoDeviceConfigurations::DeviceConfig::DeviceConfig(const QString &name) MaemoDeviceConfig::MaemoDeviceConfig(const QString &name)
: name(name), : name(name),
type(Physical), type(Physical),
port(22), port(22),
@@ -87,8 +87,8 @@ MaemoDeviceConfigurations::DeviceConfig::DeviceConfig(const QString &name)
{ {
} }
MaemoDeviceConfigurations::DeviceConfig::DeviceConfig(const QSettings &settings, MaemoDeviceConfig::MaemoDeviceConfig(const QSettings &settings,
quint64 &nextId) quint64 &nextId)
: name(settings.value(NameKey).toString()), : name(settings.value(NameKey).toString()),
type(static_cast<DeviceType>(settings.value(TypeKey, Physical).toInt())), type(static_cast<DeviceType>(settings.value(TypeKey, Physical).toInt())),
host(settings.value(HostKey).toString()), host(settings.value(HostKey).toString()),
@@ -104,17 +104,17 @@ MaemoDeviceConfigurations::DeviceConfig::DeviceConfig(const QSettings &settings,
++nextId; ++nextId;
} }
MaemoDeviceConfigurations::DeviceConfig::DeviceConfig() MaemoDeviceConfig::MaemoDeviceConfig()
: internalId(InvalidId) : internalId(InvalidId)
{ {
} }
bool MaemoDeviceConfigurations::DeviceConfig::isValid() const bool MaemoDeviceConfig::isValid() const
{ {
return internalId != InvalidId; return internalId != InvalidId;
} }
void MaemoDeviceConfigurations::DeviceConfig::save(QSettings &settings) const void MaemoDeviceConfig::save(QSettings &settings) const
{ {
settings.setValue(NameKey, name); settings.setValue(NameKey, name);
settings.setValue(TypeKey, type); settings.setValue(TypeKey, type);
@@ -128,7 +128,7 @@ void MaemoDeviceConfigurations::DeviceConfig::save(QSettings &settings) const
settings.setValue(InternalIdKey, internalId); settings.setValue(InternalIdKey, internalId);
} }
void MaemoDeviceConfigurations::setDevConfigs(const QList<DeviceConfig> &devConfigs) void MaemoDeviceConfigurations::setDevConfigs(const QList<MaemoDeviceConfig> &devConfigs)
{ {
m_devConfigs = devConfigs; m_devConfigs = devConfigs;
save(); save();
@@ -162,7 +162,6 @@ MaemoDeviceConfigurations::MaemoDeviceConfigurations(QObject *parent)
load(); load();
} }
void MaemoDeviceConfigurations::load() void MaemoDeviceConfigurations::load()
{ {
QSettings *settings = Core::ICore::instance()->settings(); QSettings *settings = Core::ICore::instance()->settings();
@@ -171,26 +170,26 @@ void MaemoDeviceConfigurations::load()
int count = settings->beginReadArray(ConfigListKey); int count = settings->beginReadArray(ConfigListKey);
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
settings->setArrayIndex(i); settings->setArrayIndex(i);
m_devConfigs.append(DeviceConfig(*settings, m_nextId)); m_devConfigs.append(MaemoDeviceConfig(*settings, m_nextId));
} }
settings->endArray(); settings->endArray();
settings->endGroup(); settings->endGroup();
} }
MaemoDeviceConfigurations::DeviceConfig MaemoDeviceConfigurations::find(const QString &name) const MaemoDeviceConfig MaemoDeviceConfigurations::find(const QString &name) const
{ {
QList<DeviceConfig>::ConstIterator resultIt = QList<MaemoDeviceConfig>::ConstIterator resultIt =
std::find_if(m_devConfigs.constBegin(), m_devConfigs.constEnd(), std::find_if(m_devConfigs.constBegin(), m_devConfigs.constEnd(),
DevConfNameMatcher(name)); DevConfNameMatcher(name));
return resultIt == m_devConfigs.constEnd() ? DeviceConfig() : *resultIt; return resultIt == m_devConfigs.constEnd() ? MaemoDeviceConfig() : *resultIt;
} }
MaemoDeviceConfigurations::DeviceConfig MaemoDeviceConfigurations::find(int id) const MaemoDeviceConfig MaemoDeviceConfigurations::find(int id) const
{ {
QList<DeviceConfig>::ConstIterator resultIt = QList<MaemoDeviceConfig>::ConstIterator resultIt =
std::find_if(m_devConfigs.constBegin(), m_devConfigs.constEnd(), std::find_if(m_devConfigs.constBegin(), m_devConfigs.constEnd(),
DevConfIdMatcher(id)); DevConfIdMatcher(id));
return resultIt == m_devConfigs.constEnd() ? DeviceConfig() : *resultIt; return resultIt == m_devConfigs.constEnd() ? MaemoDeviceConfig() : *resultIt;
} }
MaemoDeviceConfigurations *MaemoDeviceConfigurations::m_instance = 0; MaemoDeviceConfigurations *MaemoDeviceConfigurations::m_instance = 0;

View File

@@ -47,53 +47,55 @@ QT_END_NAMESPACE
namespace Qt4ProjectManager { namespace Qt4ProjectManager {
namespace Internal { namespace Internal {
class MaemoDeviceConfig
{
public:
enum DeviceType { Physical, Simulator };
enum AuthType { Password, Key };
MaemoDeviceConfig();
MaemoDeviceConfig(const QString &name);
MaemoDeviceConfig(const QSettings &settings, quint64 &nextId);
void save(QSettings &settings) const;
bool isValid() const;
QString name;
DeviceType type;
QString host;
int port;
QString uname;
AuthType authentication;
QString pwd;
QString keyFile;
int timeout;
quint64 internalId;
private:
static const quint64 InvalidId = 0;
};
class DevConfNameMatcher
{
public:
DevConfNameMatcher(const QString &name) : m_name(name) {}
bool operator()(const MaemoDeviceConfig &devConfig)
{
return devConfig.name == m_name;
}
private:
const QString m_name;
};
class MaemoDeviceConfigurations : public QObject class MaemoDeviceConfigurations : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_DISABLE_COPY(MaemoDeviceConfigurations) Q_DISABLE_COPY(MaemoDeviceConfigurations)
public: public:
class DeviceConfig
{
public:
enum DeviceType { Physical, Simulator };
enum AuthType { Password, Key };
DeviceConfig();
DeviceConfig(const QString &name);
DeviceConfig(const QSettings &settings, quint64 &nextId);
void save(QSettings &settings) const;
bool isValid() const;
QString name;
DeviceType type;
QString host;
int port;
QString uname;
AuthType authentication;
QString pwd;
QString keyFile;
int timeout;
quint64 internalId;
private:
static const quint64 InvalidId = 0;
};
class DevConfNameMatcher
{
public:
DevConfNameMatcher(const QString &name) : m_name(name) {}
bool operator()(const MaemoDeviceConfigurations::DeviceConfig &devConfig)
{
return devConfig.name == m_name;
}
private:
const QString m_name;
};
static MaemoDeviceConfigurations &instance(QObject *parent = 0); static MaemoDeviceConfigurations &instance(QObject *parent = 0);
QList<DeviceConfig> devConfigs() const { return m_devConfigs; } QList<MaemoDeviceConfig> devConfigs() const { return m_devConfigs; }
void setDevConfigs(const QList<DeviceConfig> &devConfigs); void setDevConfigs(const QList<MaemoDeviceConfig> &devConfigs);
DeviceConfig find(const QString &name) const; MaemoDeviceConfig find(const QString &name) const;
DeviceConfig find(int id) const; MaemoDeviceConfig find(int id) const;
signals: signals:
void updated(); void updated();
@@ -104,9 +106,9 @@ private:
void save(); void save();
static MaemoDeviceConfigurations *m_instance; static MaemoDeviceConfigurations *m_instance;
QList<DeviceConfig> m_devConfigs; QList<MaemoDeviceConfig> m_devConfigs;
quint64 m_nextId; quint64 m_nextId;
friend class MaemoDeviceConfigurations::DeviceConfig; friend class MaemoDeviceConfig;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -88,7 +88,7 @@ private slots:
void updateTargetInformation(); void updateTargetInformation();
private: private:
void setSimInfoVisible(const MaemoDeviceConfigurations::DeviceConfig &devConf); void setSimInfoVisible(const MaemoDeviceConfig &devConf);
QLineEdit *m_configNameLineEdit; QLineEdit *m_configNameLineEdit;
QLineEdit *m_argsLineEdit; QLineEdit *m_argsLineEdit;
@@ -130,7 +130,7 @@ private slots:
protected: protected:
ErrorDumper dumper; ErrorDumper dumper;
MaemoRunConfiguration *runConfig; // TODO this pointer can be invalid MaemoRunConfiguration *runConfig; // TODO this pointer can be invalid
const MaemoDeviceConfigurations::DeviceConfig devConfig; const MaemoDeviceConfig devConfig;
private: private:
virtual void handleDeploymentFinished(bool success)=0; virtual void handleDeploymentFinished(bool success)=0;
@@ -399,13 +399,12 @@ bool MaemoRunConfiguration::fileNeedsDeployment(const QString &path,
|| QFileInfo(path).lastModified() > lastDeployed; || QFileInfo(path).lastModified() > lastDeployed;
} }
void MaemoRunConfiguration::setDeviceConfig( void MaemoRunConfiguration::setDeviceConfig(const MaemoDeviceConfig &devConf)
const MaemoDeviceConfigurations::DeviceConfig &devConf)
{ {
m_devConfig = devConf; m_devConfig = devConf;
} }
MaemoDeviceConfigurations::DeviceConfig MaemoRunConfiguration::deviceConfig() const MaemoDeviceConfig MaemoRunConfiguration::deviceConfig() const
{ {
return m_devConfig; return m_devConfig;
} }
@@ -774,17 +773,15 @@ void MaemoRunConfigurationWidget::updateSimulatorPath()
void MaemoRunConfigurationWidget::deviceConfigurationChanged(const QString &name) void MaemoRunConfigurationWidget::deviceConfigurationChanged(const QString &name)
{ {
const MaemoDeviceConfigurations::DeviceConfig &devConfig = const MaemoDeviceConfig &devConfig
MaemoDeviceConfigurations::instance().find(name); = MaemoDeviceConfigurations::instance().find(name);
setSimInfoVisible(devConfig); setSimInfoVisible(devConfig);
m_runConfiguration->setDeviceConfig(devConfig); m_runConfiguration->setDeviceConfig(devConfig);
} }
void MaemoRunConfigurationWidget::setSimInfoVisible( void MaemoRunConfigurationWidget::setSimInfoVisible(const MaemoDeviceConfig &devConf)
const MaemoDeviceConfigurations::DeviceConfig &devConf)
{ {
const bool isSimulator = const bool isSimulator = devConf.type == MaemoDeviceConfig::Simulator;
devConf.type == MaemoDeviceConfigurations::DeviceConfig::Simulator;
m_simPathNameLabel->setVisible(isSimulator); m_simPathNameLabel->setVisible(isSimulator);
m_simPathValueLabel->setVisible(isSimulator); m_simPathValueLabel->setVisible(isSimulator);
} }
@@ -792,13 +789,12 @@ void MaemoRunConfigurationWidget::setSimInfoVisible(
void MaemoRunConfigurationWidget::resetDeviceConfigurations() void MaemoRunConfigurationWidget::resetDeviceConfigurations()
{ {
m_devConfBox->clear(); m_devConfBox->clear();
const QList<MaemoDeviceConfigurations::DeviceConfig> &devConfs = const QList<MaemoDeviceConfig> &devConfs =
MaemoDeviceConfigurations::instance().devConfigs(); MaemoDeviceConfigurations::instance().devConfigs();
foreach (const MaemoDeviceConfigurations::DeviceConfig &devConf, devConfs) foreach (const MaemoDeviceConfig &devConf, devConfs)
m_devConfBox->addItem(devConf.name); m_devConfBox->addItem(devConf.name);
m_devConfBox->addItem(MaemoDeviceConfigurations::DeviceConfig().name); m_devConfBox->addItem(MaemoDeviceConfig().name);
const MaemoDeviceConfigurations::DeviceConfig &devConf = const MaemoDeviceConfig &devConf = m_runConfiguration->deviceConfig();
m_runConfiguration->deviceConfig();
m_devConfBox->setCurrentIndex(m_devConfBox->findText(devConf.name)); m_devConfBox->setCurrentIndex(m_devConfBox->findText(devConf.name));
setSimInfoVisible(devConf); setSimInfoVisible(devConf);
} }
@@ -992,8 +988,7 @@ QWidget* MaemoRunControlFactory::configurationWidget(RunConfiguration *config)
AbstractMaemoRunControl::AbstractMaemoRunControl(RunConfiguration *rc) AbstractMaemoRunControl::AbstractMaemoRunControl(RunConfiguration *rc)
: RunControl(rc) : RunControl(rc)
, runConfig(qobject_cast<MaemoRunConfiguration *>(rc)) , runConfig(qobject_cast<MaemoRunConfiguration *>(rc))
, devConfig(runConfig ? runConfig->deviceConfig() , devConfig(runConfig ? runConfig->deviceConfig() : MaemoDeviceConfig())
: MaemoDeviceConfigurations::DeviceConfig())
{ {
setProcessEnvironment(deployProcess); setProcessEnvironment(deployProcess);
@@ -1117,8 +1112,8 @@ const QString AbstractMaemoRunControl::remoteDir() const
const QStringList AbstractMaemoRunControl::options() const const QStringList AbstractMaemoRunControl::options() const
{ {
const bool usePassword = const bool usePassword
devConfig.authentication == MaemoDeviceConfigurations::DeviceConfig::Password; = devConfig.authentication == MaemoDeviceConfig::Password;
const QLatin1String opt("-o"); const QLatin1String opt("-o");
QStringList optionList; QStringList optionList;
if (!usePassword) if (!usePassword)

View File

@@ -91,8 +91,8 @@ public:
const QString sysRoot() const; const QString sysRoot() const;
const QStringList arguments() const; const QStringList arguments() const;
void setArguments(const QStringList &args); void setArguments(const QStringList &args);
void setDeviceConfig(const MaemoDeviceConfigurations::DeviceConfig &deviceConfig); void setDeviceConfig(const MaemoDeviceConfig &deviceConfig);
MaemoDeviceConfigurations::DeviceConfig deviceConfig() const; MaemoDeviceConfig deviceConfig() const;
QString simulator() const; QString simulator() const;
QString simulatorArgs() const; QString simulatorArgs() const;
@@ -158,7 +158,7 @@ private:
QString m_gdbPath; QString m_gdbPath;
MaemoDeviceConfigurations::DeviceConfig m_devConfig; MaemoDeviceConfig m_devConfig;
QStringList m_arguments; QStringList m_arguments;
QDateTime m_lastDeployed; QDateTime m_lastDeployed;

View File

@@ -42,10 +42,12 @@
#include <qt4projectmanager/qt4projectmanagerconstants.h> #include <qt4projectmanager/qt4projectmanagerconstants.h>
#include "maemodeviceconfigurations.h" #include "maemodeviceconfigurations.h"
#include "maemosshrunner.h"
#include "ui_maemosettingswidget.h" #include "ui_maemosettingswidget.h"
#include "maemosettingspage.h" #include "maemosettingspage.h"
#include <QtCore/QRegExp>
#include <QtGui/QIntValidator> #include <QtGui/QIntValidator>
#include <algorithm> #include <algorithm>
@@ -56,11 +58,11 @@ namespace Internal {
#define PAGE_ID "ZZ.Maemo Device Configurations" #define PAGE_ID "ZZ.Maemo Device Configurations"
#define PAGE_ID_TR "Maemo Device Configurations" #define PAGE_ID_TR "Maemo Device Configurations"
bool configNameExists(const QList<MaemoDeviceConfigurations::DeviceConfig> &devConfs, bool configNameExists(const QList<MaemoDeviceConfig> &devConfs,
const QString &name) const QString &name)
{ {
return std::find_if(devConfs.constBegin(), devConfs.constEnd(), return std::find_if(devConfs.constBegin(), devConfs.constEnd(),
MaemoDeviceConfigurations::DevConfNameMatcher(name)) != devConfs.constEnd(); DevConfNameMatcher(name)) != devConfs.constEnd();
} }
class PortAndTimeoutValidator : public QIntValidator class PortAndTimeoutValidator : public QIntValidator
@@ -86,7 +88,7 @@ private:
class NameValidator : public QValidator class NameValidator : public QValidator
{ {
public: public:
NameValidator(const QList<MaemoDeviceConfigurations::DeviceConfig> &devConfs) NameValidator(const QList<MaemoDeviceConfig> &devConfs)
: m_devConfs(devConfs) : m_devConfs(devConfs)
{ {
} }
@@ -110,7 +112,7 @@ public:
private: private:
QString m_oldName; QString m_oldName;
const QList<MaemoDeviceConfigurations::DeviceConfig> &m_devConfs; const QList<MaemoDeviceConfig> &m_devConfs;
}; };
@@ -134,20 +136,31 @@ private slots:
void userNameEditingFinished(); void userNameEditingFinished();
void passwordEditingFinished(); void passwordEditingFinished();
void keyFileEditingFinished(); void keyFileEditingFinished();
void testConfig();
void enableTestStop();
void processSshOutput(const QString &data);
void handleSshFinished();
void stopConfigTest();
private: private:
void initGui(); void initGui();
void display(const MaemoDeviceConfigurations::DeviceConfig &devConfig); void display(const MaemoDeviceConfig &devConfig);
MaemoDeviceConfigurations::DeviceConfig &currentConfig(); MaemoDeviceConfig &currentConfig();
void setPortOrTimeout(const QLineEdit *lineEdit, int &confVal, void setPortOrTimeout(const QLineEdit *lineEdit, int &confVal,
PortAndTimeoutValidator &validator); PortAndTimeoutValidator &validator);
void clearDetails(); void clearDetails();
QString parseTestOutput();
Ui_maemoSettingsWidget *m_ui; Ui_maemoSettingsWidget *m_ui;
QList<MaemoDeviceConfigurations::DeviceConfig> m_devConfs; QList<MaemoDeviceConfig> m_devConfs;
PortAndTimeoutValidator m_portValidator; PortAndTimeoutValidator m_portValidator;
PortAndTimeoutValidator m_timeoutValidator; PortAndTimeoutValidator m_timeoutValidator;
NameValidator m_nameValidator; NameValidator m_nameValidator;
#ifdef USE_SSH_LIBS
MaemoSshRunner *m_deviceTester;
#endif
QString m_deviceTestOutput;
QString m_defaultTestOutput;
}; };
MaemoSettingsPage::MaemoSettingsPage(QObject *parent) MaemoSettingsPage::MaemoSettingsPage(QObject *parent)
@@ -200,6 +213,9 @@ MaemoSettingsWidget::MaemoSettingsWidget(QWidget *parent)
m_ui(new Ui_maemoSettingsWidget), m_ui(new Ui_maemoSettingsWidget),
m_devConfs(MaemoDeviceConfigurations::instance().devConfigs()), m_devConfs(MaemoDeviceConfigurations::instance().devConfigs()),
m_nameValidator(m_devConfs) m_nameValidator(m_devConfs)
#ifdef USE_SSH_LIBS
, m_deviceTester(0)
#endif
{ {
initGui(); initGui();
@@ -216,11 +232,13 @@ void MaemoSettingsWidget::initGui()
m_ui->portLineEdit->setValidator(&m_portValidator); m_ui->portLineEdit->setValidator(&m_portValidator);
m_ui->timeoutLineEdit->setValidator(&m_timeoutValidator); m_ui->timeoutLineEdit->setValidator(&m_timeoutValidator);
m_ui->keyFileLineEdit->setExpectedKind(Utils::PathChooser::File); m_ui->keyFileLineEdit->setExpectedKind(Utils::PathChooser::File);
foreach(const MaemoDeviceConfigurations::DeviceConfig &devConf, m_devConfs) foreach(const MaemoDeviceConfig &devConf, m_devConfs)
m_ui->configListWidget->addItem(devConf.name); m_ui->configListWidget->addItem(devConf.name);
m_defaultTestOutput = m_ui->testResultEdit->toPlainText();
#ifndef USE_SSH_LIB // Password authentication does not currently work due to ssh/scp issues.
#if 1 // Password authentication does not currently work due to ssh/scp issues. m_ui->testConfigButton->hide();
m_ui->testResultEdit->hide();
m_ui->authTypeLabel->hide(); m_ui->authTypeLabel->hide();
m_ui->authTypeButtonsWidget->hide(); m_ui->authTypeButtonsWidget->hide();
m_ui->passwordLabel->hide(); m_ui->passwordLabel->hide();
@@ -239,7 +257,7 @@ void MaemoSettingsWidget::addConfig()
isUnique = !configNameExists(m_devConfs, newName); isUnique = !configNameExists(m_devConfs, newName);
} while (!isUnique); } while (!isUnique);
m_devConfs.append(MaemoDeviceConfigurations::DeviceConfig(newName)); m_devConfs.append(MaemoDeviceConfig(newName));
m_ui->configListWidget->addItem(newName); m_ui->configListWidget->addItem(newName);
m_ui->configListWidget->setCurrentRow(m_ui->configListWidget->count() - 1); m_ui->configListWidget->setCurrentRow(m_ui->configListWidget->count() - 1);
m_ui->nameLineEdit->selectAll(); m_ui->nameLineEdit->selectAll();
@@ -264,14 +282,14 @@ void MaemoSettingsWidget::deleteConfig()
selectionChanged(); selectionChanged();
} }
void MaemoSettingsWidget::display(const MaemoDeviceConfigurations::DeviceConfig &devConfig) void MaemoSettingsWidget::display(const MaemoDeviceConfig &devConfig)
{ {
m_ui->nameLineEdit->setText(devConfig.name); m_ui->nameLineEdit->setText(devConfig.name);
if (devConfig.type == MaemoDeviceConfigurations::DeviceConfig::Physical) if (devConfig.type == MaemoDeviceConfig::Physical)
m_ui->deviceButton->setChecked(true); m_ui->deviceButton->setChecked(true);
else else
m_ui->simulatorButton->setChecked(true); m_ui->simulatorButton->setChecked(true);
if (devConfig.authentication == MaemoDeviceConfigurations::DeviceConfig::Password) if (devConfig.authentication == MaemoDeviceConfig::Password)
m_ui->passwordButton->setChecked(true); m_ui->passwordButton->setChecked(true);
else else
m_ui->keyButton->setChecked(true); m_ui->keyButton->setChecked(true);
@@ -293,7 +311,7 @@ void MaemoSettingsWidget::saveSettings()
MaemoDeviceConfigurations::instance().setDevConfigs(m_devConfs); MaemoDeviceConfigurations::instance().setDevConfigs(m_devConfs);
} }
MaemoDeviceConfigurations::DeviceConfig &MaemoSettingsWidget::currentConfig() MaemoDeviceConfig &MaemoSettingsWidget::currentConfig()
{ {
Q_ASSERT(m_ui->configListWidget->count() == m_devConfs.count()); Q_ASSERT(m_ui->configListWidget->count() == m_devConfs.count());
const QList<QListWidgetItem *> &selectedItems = const QList<QListWidgetItem *> &selectedItems =
@@ -316,16 +334,16 @@ void MaemoSettingsWidget::deviceTypeChanged()
{ {
currentConfig().type = currentConfig().type =
m_ui->deviceButton->isChecked() m_ui->deviceButton->isChecked()
? MaemoDeviceConfigurations::DeviceConfig::Physical ? MaemoDeviceConfig::Physical
: MaemoDeviceConfigurations::DeviceConfig::Simulator; : MaemoDeviceConfig::Simulator;
} }
void MaemoSettingsWidget::authenticationTypeChanged() void MaemoSettingsWidget::authenticationTypeChanged()
{ {
const bool usePassword = m_ui->passwordButton->isChecked(); const bool usePassword = m_ui->passwordButton->isChecked();
currentConfig().authentication = usePassword currentConfig().authentication = usePassword
? MaemoDeviceConfigurations::DeviceConfig::Password ? MaemoDeviceConfig::Password
: MaemoDeviceConfigurations::DeviceConfig::Key; : MaemoDeviceConfig::Key;
m_ui->pwdLineEdit->setEnabled(usePassword); m_ui->pwdLineEdit->setEnabled(usePassword);
m_ui->passwordLabel->setEnabled(usePassword); m_ui->passwordLabel->setEnabled(usePassword);
m_ui->keyFileLineEdit->setEnabled(!usePassword); m_ui->keyFileLineEdit->setEnabled(!usePassword);
@@ -372,17 +390,129 @@ void MaemoSettingsWidget::keyFileEditingFinished()
currentConfig().keyFile = m_ui->keyFileLineEdit->path(); currentConfig().keyFile = m_ui->keyFileLineEdit->path();
} }
void MaemoSettingsWidget::testConfig()
{
#ifdef USE_SSH_LIBS
qDebug("Oh yes, this config will be tested!");
if (m_deviceTester)
return;
m_ui->testResultEdit->setPlainText(m_defaultTestOutput);
QLatin1String sysInfoCmd("uname -rsm");
QLatin1String qtInfoCmd("dpkg -l |grep libqt "
"|sed 's/[[:space:]][[:space:]]*/ /g' "
"|cut -d ' ' -f 2,3 |sed 's/~.*//g'");
QString command(sysInfoCmd + " && " + qtInfoCmd);
m_deviceTester = new MaemoSshRunner(currentConfig(), command);
connect(m_deviceTester, SIGNAL(connectionEstablished()),
this, SLOT(enableTestStop()));
connect(m_deviceTester, SIGNAL(remoteOutput(QString)),
this, SLOT(processSshOutput(QString)));
connect(m_deviceTester, SIGNAL(finished()),
this, SLOT(handleSshFinished()));
m_deviceTester->start();
#endif
}
void MaemoSettingsWidget::enableTestStop()
{
m_ui->testConfigButton->disconnect();
m_ui->testConfigButton->setText(tr("Stop test"));
connect(m_ui->testConfigButton, SIGNAL(clicked()),
this, SLOT(stopConfigTest()));
}
void MaemoSettingsWidget::processSshOutput(const QString &data)
{
qDebug("%s", qPrintable(data));
m_deviceTestOutput.append(data);
}
void MaemoSettingsWidget::handleSshFinished()
{
#ifdef USE_SSH_LIBS
qDebug("================> %s", Q_FUNC_INFO);
if (!m_deviceTester)
return;
QString output;
if (m_deviceTester->hasError()) {
output = tr("Device configuration test failed:\n");
output.append(m_deviceTester->error());
} else {
output = parseTestOutput();
}
m_ui->testResultEdit->setPlainText(output);
stopConfigTest();
#endif
}
void MaemoSettingsWidget::stopConfigTest()
{
#ifdef USE_SSH_LIBS
qDebug("================> %s", Q_FUNC_INFO);
if (m_deviceTester) {
qDebug("Actually doing something");
m_deviceTester->disconnect();
const bool buttonWasEnabled = m_ui->testConfigButton->isEnabled();
m_ui->testConfigButton->setEnabled(false);
m_deviceTester->stop();
delete m_deviceTester;
m_deviceTester = 0;
m_deviceTestOutput.clear();
m_ui->testConfigButton->setText(tr("Test"));
m_ui->testConfigButton->disconnect();
connect(m_ui->testConfigButton, SIGNAL(clicked()),
this, SLOT(testConfig()));
m_ui->testConfigButton->setEnabled(buttonWasEnabled);
}
#endif
}
QString MaemoSettingsWidget::parseTestOutput()
{
QString output;
const QRegExp unamePattern(QLatin1String("Linux (\\S+)\\s(\\S+)"));
int index = unamePattern.indexIn(m_deviceTestOutput);
if (index == -1) {
output = tr("Device configuration test failed: Unexpected output:\n");
output.append(m_deviceTestOutput);
return output;
}
output = tr("Hardware architecture: %1\n").arg(unamePattern.cap(2));
output.append(tr("Kernel version: %1\n").arg(unamePattern.cap(1)));
output.prepend(tr("Device configuration successful.\n"));
const QRegExp dkpgPattern(QLatin1String("libqt\\S+ \\d\\.\\d\\.\\d"));
index = dkpgPattern.indexIn(m_deviceTestOutput);
if (index == -1) {
output.append("No Qt packages installed.");
return output;
}
output.append("List of installed Qt packages:\n");
do {
output.append(QLatin1String("\t") + dkpgPattern.cap(0)
+ QLatin1String("\n"));
index = dkpgPattern.indexIn(m_deviceTestOutput, index + 1);
} while (index != -1);
return output;
}
void MaemoSettingsWidget::selectionChanged() void MaemoSettingsWidget::selectionChanged()
{ {
const QList<QListWidgetItem *> &selectedItems = const QList<QListWidgetItem *> &selectedItems =
m_ui->configListWidget->selectedItems(); m_ui->configListWidget->selectedItems();
Q_ASSERT(selectedItems.count() <= 1); Q_ASSERT(selectedItems.count() <= 1);
stopConfigTest();
m_ui->testResultEdit->setPlainText(m_defaultTestOutput);
if (selectedItems.isEmpty()) { if (selectedItems.isEmpty()) {
m_ui->removeConfigButton->setEnabled(false); m_ui->removeConfigButton->setEnabled(false);
m_ui->testConfigButton->setEnabled(false);
clearDetails(); clearDetails();
m_ui->detailsWidget->setEnabled(false); m_ui->detailsWidget->setEnabled(false);
} else { } else {
m_ui->removeConfigButton->setEnabled(true); m_ui->removeConfigButton->setEnabled(true);
m_ui->testConfigButton->setEnabled(true);
display(currentConfig()); display(currentConfig());
} }
} }

View File

@@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>515</width> <width>515</width>
<height>387</height> <height>487</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@@ -32,6 +32,9 @@
<bool>false</bool> <bool>false</bool>
</property> </property>
<layout class="QFormLayout" name="formLayout"> <layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="label"> <widget class="QLabel" name="label">
<property name="text"> <property name="text">
@@ -175,6 +178,20 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<widget class="QTextEdit" name="testResultEdit">
<property name="readOnly">
<bool>true</bool>
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;No current test results available.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
@@ -197,6 +214,16 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="testConfigButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Test</string>
</property>
</widget>
</item>
<item> <item>
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">
@@ -427,8 +454,8 @@
<slot>keyFileEditingFinished()</slot> <slot>keyFileEditingFinished()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>268</x> <x>150</x>
<y>337</y> <y>357</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>257</x> <x>257</x>
@@ -443,8 +470,8 @@
<slot>keyFileEditingFinished()</slot> <slot>keyFileEditingFinished()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>268</x> <x>150</x>
<y>337</y> <y>357</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>257</x> <x>257</x>
@@ -452,6 +479,22 @@
</hint> </hint>
</hints> </hints>
</connection> </connection>
<connection>
<sender>testConfigButton</sender>
<signal>clicked()</signal>
<receiver>maemoSettingsWidget</receiver>
<slot>testConfig()</slot>
<hints>
<hint type="sourcelabel">
<x>450</x>
<y>96</y>
</hint>
<hint type="destinationlabel">
<x>428</x>
<y>367</y>
</hint>
</hints>
</connection>
</connections> </connections>
<slots> <slots>
<slot>configNameEditingFinished()</slot> <slot>configNameEditingFinished()</slot>
@@ -466,5 +509,6 @@
<slot>deleteConfig()</slot> <slot>deleteConfig()</slot>
<slot>authenticationTypeChanged()</slot> <slot>authenticationTypeChanged()</slot>
<slot>keyFileEditingFinished()</slot> <slot>keyFileEditingFinished()</slot>
<slot>testConfig()</slot>
</slots> </slots>
</ui> </ui>

View File

@@ -0,0 +1,133 @@
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Creator.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "maemosshconnection.h"
#ifdef USE_SSH_LIB
#include "maemodeviceconfigurations.h"
#include "/opt/ne7ssh/include/ne7ssh.h"
#include <QtCore/QMutex>
#include <QtCore/QMutexLocker>
namespace Qt4ProjectManager {
namespace Internal {
namespace {
ne7ssh ssh;
}
MaemoSshConnection::Ptr MaemoSshConnection::connect(
const MaemoDeviceConfig &devConf, bool shell)
{
return MaemoSshConnection::Ptr(new MaemoSshConnection(devConf, shell));
}
MaemoSshConnection::MaemoSshConnection(const MaemoDeviceConfig &devConf,
bool shell)
: m_channel(-1), m_prompt(0), m_stopRequested(false)
{
const QString *authString;
int (ne7ssh::*connFunc)(const char *, int, const char *, const char *, bool, int);
if (devConf.authentication == MaemoDeviceConfig::Password) {
authString = &devConf.pwd;
connFunc = &ne7ssh::connectWithPassword;
} else {
authString = &devConf.keyFile;
connFunc = &ne7ssh::connectWithKey;
}
m_channel = (ssh.*connFunc)(devConf.host.toAscii(), devConf.port,
devConf.uname.toAscii(), authString->toAscii(), shell, devConf.timeout);
if (m_channel == -1)
throw MaemoSshException(tr("Could not connect to host"));
if (shell) {
m_prompt = devConf.uname == QLatin1String("root") ? "# " : "$ ";
if (!ssh.waitFor(m_channel, m_prompt, devConf.timeout)) {
const QString error = tr("Could not start remote shell: %1").
arg(ssh.errors()->pop(m_channel));
ssh.close(m_channel);
throw MaemoSshException(error);
}
}
}
MaemoSshConnection::~MaemoSshConnection()
{
qDebug("%s", Q_FUNC_INFO);
if (m_prompt) {
ssh.send("exit\n", m_channel);
ssh.waitFor(m_channel, m_prompt, 1);
}
ssh.close(m_channel);
}
void MaemoSshConnection::runCommand(const QString &command)
{
if (!ssh.send((command + QLatin1String("\n")).toLatin1().data(),
m_channel)) {
throw MaemoSshException(tr("Error running command: %1")
.arg(ssh.errors()->pop(m_channel)));
}
bool done;
do {
done = ssh.waitFor(m_channel, m_prompt, 3);
const char * const error = ssh.errors()->pop(m_channel);
if (error)
throw MaemoSshException(tr("SSH error: %1").arg(error));
const char * const output = ssh.read(m_channel);
if (output)
emit remoteOutput(QLatin1String(output));
} while (!done && !m_stopRequested);
}
void MaemoSshConnection::stopCommand()
{
m_stopRequested = true;
}
} // namespace Internal
} // namespace Qt4ProjectManager
#endif

View File

@@ -0,0 +1,96 @@
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Creator.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef MAEMOSSHCONNECTION_H
#define MAEMOSSHCONNECTION_H
#ifdef USE_SSH_LIB
#include <QtCore/QCoreApplication>
#include <QtCore/QScopedPointer>
#include <QtCore/QSharedPointer>
class ne7ssh;
namespace Qt4ProjectManager {
namespace Internal {
class MaemoDeviceConfig;
class MaemoSshException
{
public:
MaemoSshException(const QString &error) : m_error(error) {}
const QString &error() const { return m_error; }
private:
const QString m_error;
};
class MaemoSshConnection : public QObject
{
Q_OBJECT
Q_DISABLE_COPY(MaemoSshConnection)
friend class MaemoSshFacility;
public:
typedef QSharedPointer<MaemoSshConnection> Ptr;
static Ptr connect(const MaemoDeviceConfig &devConf, bool shell);
void runCommand(const QString &command);
void stopCommand();
~MaemoSshConnection();
signals:
void remoteOutput(const QString &output);
private:
MaemoSshConnection(const MaemoDeviceConfig &devConf, bool shell);
int m_channel;
const char *m_prompt;
volatile bool m_stopRequested;
};
} // namespace Internal
} // namespace Qt4ProjectManager
#endif
#endif // MAEMOSSHCONNECTION_H

View File

@@ -0,0 +1,77 @@
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Creator.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "maemosshrunner.h"
#ifdef USE_SSH_LIB
namespace Qt4ProjectManager {
namespace Internal {
MaemoSshRunner::MaemoSshRunner(const MaemoDeviceConfig &devConf, const QString &command)
: m_devConf(devConf), m_command(command)
{
}
void MaemoSshRunner::run()
{
try {
m_connection = MaemoSshConnection::connect(m_devConf, true);
emit connectionEstablished();
connect(m_connection.data(), SIGNAL(remoteOutput(QString)),
this, SIGNAL(remoteOutput(QString)));
m_connection->runCommand(m_command);
} catch (const MaemoSshException &e) {
m_error = e.error();
}
}
void MaemoSshRunner::stop()
{
if (!m_connection.isNull())
m_connection->stopCommand();
wait();
}
} // namespace Internal
} // namespace Qt4ProjectManager
#endif

View File

@@ -0,0 +1,82 @@
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Creator.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef MAEMOSSHRUNNER_H
#define MAEMOSSHRUNNER_H
#include "maemodeviceconfigurations.h"
#include "maemosshconnection.h"
#ifdef USE_SSH_LIB
#include <QtCore/QString>
#include <QtCore/QThread>
namespace Qt4ProjectManager {
namespace Internal {
class MaemoSshRunner : public QThread
{
Q_OBJECT
public:
MaemoSshRunner(const MaemoDeviceConfig &devConf, const QString &command);
QString error() const { return m_error; }
bool hasError() const { return !m_error.isEmpty(); }
void stop();
virtual void run();
signals:
void connectionEstablished();
void remoteOutput(const QString &output);
private:
const MaemoDeviceConfig m_devConf;
const QString m_command;
QString m_error;
MaemoSshConnection::Ptr m_connection;
};
} // namespace Internal
} // namespace Qt4ProjectManager
#endif
#endif // MAEMOSSHRUNNER_H

View File

@@ -68,13 +68,7 @@ ToolChain::ToolChainType MaemoToolChain::type() const
QList<HeaderPath> MaemoToolChain::systemHeaderPaths() QList<HeaderPath> MaemoToolChain::systemHeaderPaths()
{ {
if (m_systemHeaderPaths.isEmpty()) { return GccToolChain::systemHeaderPaths();
GccToolChain::systemHeaderPaths();
m_systemHeaderPaths
.append(HeaderPath(QString("%1/usr/include").arg(sysrootRoot()),
HeaderPath::GlobalHeaderPath));
}
return m_systemHeaderPaths;
} }
void MaemoToolChain::addToEnvironment(ProjectExplorer::Environment &env) void MaemoToolChain::addToEnvironment(ProjectExplorer::Environment &env)

View File

@@ -2,17 +2,22 @@ SUPPORT_QT_MAEMO = $$(QTCREATOR_WITH_MAEMO)
!isEmpty(SUPPORT_QT_MAEMO) { !isEmpty(SUPPORT_QT_MAEMO) {
message("Adding experimental support for Qt/Maemo applications.") message("Adding experimental support for Qt/Maemo applications.")
DEFINES += QTCREATOR_WITH_MAEMO DEFINES += QTCREATOR_WITH_MAEMO
# DEFINES += USE_SSH_LIB
# LIBS += -L/opt/ne7ssh/lib/ -lnet7ssh
HEADERS += $$PWD/maemorunconfiguration.h \ HEADERS += $$PWD/maemorunconfiguration.h \
$$PWD/maemomanager.h \ $$PWD/maemomanager.h \
$$PWD/maemotoolchain.h \ $$PWD/maemotoolchain.h \
$$PWD/maemodeviceconfigurations.h \ $$PWD/maemodeviceconfigurations.h \
$$PWD/maemosettingspage.h $$PWD/maemosettingspage.h \
$$PWD/maemosshconnection.h \
$$PWD/maemosshrunner.h
SOURCES += $$PWD/maemorunconfiguration.cpp \ SOURCES += $$PWD/maemorunconfiguration.cpp \
$$PWD/maemomanager.cpp \ $$PWD/maemomanager.cpp \
$$PWD/maemotoolchain.cpp \ $$PWD/maemotoolchain.cpp \
$$PWD/maemodeviceconfigurations.cpp \ $$PWD/maemodeviceconfigurations.cpp \
$$PWD/maemosettingspage.cpp $$PWD/maemosettingspage.cpp \
FORMS += $$PWD/maemosettingswidget.ui $$PWD/maemosshconnection.cpp \
$$PWD/maemosshrunner.cpp
FORMS += $$PWD/maemosettingswidget.ui
RESOURCES += $$PWD/qt-maemo.qrc RESOURCES += $$PWD/qt-maemo.qrc
} }