summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordt <qtc-committer@nokia.com>2009-02-19 16:11:29 +0100
committerdt <qtc-committer@nokia.com>2009-02-19 16:29:52 +0100
commit469639fb3c532c54ef03852b08f162ffd227c994 (patch)
tree9438111061709c04dc288a850269a02878ed35e2
parent91707ee07599002074fcedb3f75da4b8d0896352 (diff)
downloadqt-creator-469639fb3c532c54ef03852b08f162ffd227c994.tar.gz
Fixes: Make QtCreator fly even in face of perforce misconfiguration.
Details: If p4 is in path, but the server isn't configured correctly we were pretty slow, this fixes that by running p4 client -o after the settings have changed, if that doesn't return after 2 seconds, then we cache that as a invalid configuration.
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprojectmanager.h4
-rw-r--r--src/plugins/perforce/perforceplugin.cpp65
-rw-r--r--src/plugins/perforce/perforceplugin.h5
-rw-r--r--src/plugins/perforce/perforcesettings.cpp131
-rw-r--r--src/plugins/perforce/perforcesettings.h38
-rw-r--r--src/plugins/perforce/settingspage.cpp42
-rw-r--r--src/plugins/perforce/settingspage.h7
7 files changed, 207 insertions, 85 deletions
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h
index d8a61e6e80..3a8dda54aa 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.h
@@ -71,14 +71,14 @@ class CMakeRunner
{
public:
CMakeRunner();
- void run(QFutureInterface<void> &fi);
void setExecutable(const QString &executable);
QString executable() const;
QString version() const;
bool supportsQtCreator() const;
- void waitForUpToDate() const;
private:
+ void run(QFutureInterface<void> &fi);
+ void waitForUpToDate() const;
QString m_executable;
QString m_version;
bool m_supportsQtCreator;
diff --git a/src/plugins/perforce/perforceplugin.cpp b/src/plugins/perforce/perforceplugin.cpp
index 7d126c4bb9..b4685419c0 100644
--- a/src/plugins/perforce/perforceplugin.cpp
+++ b/src/plugins/perforce/perforceplugin.cpp
@@ -221,7 +221,6 @@ bool PerforcePlugin::initialize(const QStringList &arguments, QString *errorMess
m_coreListener = new CoreListener(this);
addObject(m_coreListener);
-
//register actions
Core::ActionManager *am = Core::ICore::instance()->actionManager();
@@ -682,6 +681,8 @@ void PerforcePlugin::updateActions()
bool PerforcePlugin::managesDirectory(const QString &directory) const
{
+ if (!checkP4Command())
+ return false;
const QString p4Path = directory + QLatin1String("/...");
QStringList args;
args << QLatin1String("fstat") << QLatin1String("-m1") << p4Path;
@@ -758,7 +759,7 @@ PerforceResponse PerforcePlugin::runP4Cmd(const QStringList &args,
tempfile.setAutoRemove(true);
const QChar newLine = QLatin1Char('\n');
const QChar blank = QLatin1Char(' ');
- QStringList actualArgs = basicP4Args();
+ QStringList actualArgs = m_settings.basicP4Args();
if (!extraArgs.isEmpty()) {
if (tempfile.open()) {
QTextStream stream(&tempfile);
@@ -773,7 +774,7 @@ PerforceResponse PerforcePlugin::runP4Cmd(const QStringList &args,
actualArgs << args;
if (logFlags & CommandToWindow) {
- QString command = m_settings.p4Command;
+ QString command = m_settings.p4Command();
command += blank;
command += actualArgs.join(QString(blank));
const QString timeStamp = QTime::currentTime().toString(QLatin1String("HH:mm"));
@@ -799,7 +800,7 @@ PerforceResponse PerforcePlugin::runP4Cmd(const QStringList &args,
connect(&process, SIGNAL(stdOutBuffered(QString,bool)), m_perforceOutputWindow, SLOT(append(QString,bool)));
}
- const Core::Utils::SynchronousProcessResponse sp_resp = process.run(m_settings.p4Command, actualArgs);
+ const Core::Utils::SynchronousProcessResponse sp_resp = process.run(m_settings.p4Command(), actualArgs);
if (Perforce::Constants::debug)
qDebug() << sp_resp;
@@ -817,7 +818,7 @@ PerforceResponse PerforcePlugin::runP4Cmd(const QStringList &args,
response.message = tr("The process terminated abnormally.");
break;
case Core::Utils::SynchronousProcessResponse::StartFailed:
- response.message = tr("Could not start perforce '%1'. Please check your settings in the preferences.").arg(m_settings.p4Command);
+ response.message = tr("Could not start perforce '%1'. Please check your settings in the preferences.").arg(m_settings.p4Command());
break;
case Core::Utils::SynchronousProcessResponse::Hang:
response.message = tr("Perforce did not respond within timeout limit (%1 ms).").arg(p4Timeout );
@@ -969,8 +970,8 @@ bool PerforcePlugin::editorAboutToClose(Core::IEditor *editor)
proc.setEnvironment(environment());
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
- proc.start(m_settings.p4Command,
- basicP4Args() << QLatin1String("submit") << QLatin1String("-i"));
+ proc.start(m_settings.p4Command(),
+ m_settings.basicP4Args() << QLatin1String("submit") << QLatin1String("-i"));
if (!proc.waitForStarted(p4Timeout)) {
showOutput(tr("Cannot execute p4 submit."), true);
QApplication::restoreOverrideCursor();
@@ -1018,8 +1019,8 @@ QString PerforcePlugin::clientFilePath(const QString &serverFilePath)
QApplication::setOverrideCursor(Qt::WaitCursor);
QProcess proc;
proc.setEnvironment(environment());
- proc.start(m_settings.p4Command,
- basicP4Args() << QLatin1String("fstat") << serverFilePath);
+ proc.start(m_settings.p4Command(),
+ m_settings.basicP4Args() << QLatin1String("fstat") << serverFilePath);
QString path;
if (proc.waitForFinished(3000)) {
@@ -1047,22 +1048,9 @@ QString PerforcePlugin::currentFileName()
return fileName;
}
-QStringList PerforcePlugin::basicP4Args() const
-{
- QStringList lst;
- if (!m_settings.defaultEnv) {
- lst << QLatin1String("-c") << m_settings.p4Client;
- lst << QLatin1String("-p") << m_settings.p4Port;
- lst << QLatin1String("-u") << m_settings.p4User;
- }
- return lst;
-}
-
bool PerforcePlugin::checkP4Command() const
{
- if (m_settings.p4Command.isEmpty())
- return false;
- return true;
+ return m_settings.isValid();
}
QString PerforcePlugin::pendingChangesData()
@@ -1074,8 +1062,8 @@ QString PerforcePlugin::pendingChangesData()
QString user;
QProcess proc;
proc.setEnvironment(environment());
- proc.start(m_settings.p4Command,
- basicP4Args() << QLatin1String("info"));
+ proc.start(m_settings.p4Command(),
+ m_settings.basicP4Args() << QLatin1String("info"));
if (proc.waitForFinished(3000)) {
QString output = QString::fromUtf8(proc.readAllStandardOutput());
if (!output.isEmpty()) {
@@ -1087,8 +1075,8 @@ QString PerforcePlugin::pendingChangesData()
}
if (user.isEmpty())
return data;
- proc.start(m_settings.p4Command,
- basicP4Args() << QLatin1String("changes") << QLatin1String("-s") << QLatin1String("pending") << QLatin1String("-u") << user);
+ proc.start(m_settings.p4Command(),
+ m_settings.basicP4Args() << QLatin1String("changes") << QLatin1String("-s") << QLatin1String("pending") << QLatin1String("-u") << user);
if (proc.waitForFinished(3000))
data = QString::fromUtf8(proc.readAllStandardOutput());
return data;
@@ -1139,17 +1127,24 @@ PerforcePlugin::~PerforcePlugin()
}
}
-PerforceSettings PerforcePlugin::settings() const
+const PerforceSettings& PerforcePlugin::settings() const
{
return m_settings;
}
-void PerforcePlugin::setSettings(const PerforceSettings &s)
+void PerforcePlugin::setSettings(const QString &p4Command, const QString &p4Port, const QString &p4Client, const QString p4User, bool defaultEnv)
{
- if (s != m_settings) {
- m_settings = s;
- if (QSettings *settings = Core::ICore::instance()->settings())
- m_settings.toSettings(settings);
+
+ if (m_settings.p4Command() == p4Command
+ && m_settings.p4Port() == p4Port
+ && m_settings.p4Client() == p4Client
+ && m_settings.p4User() == p4User
+ && m_settings.defaultEnv() == defaultEnv)
+ {
+ // Nothing to do
+ } else {
+ m_settings.setSettings(p4Command, p4Port, p4Client, p4User, defaultEnv);
+ m_settings.toSettings(Core::ICore::instance()->settings());
}
}
@@ -1162,9 +1157,9 @@ QString PerforcePlugin::fileNameFromPerforceName(const QString& perforceName,
return perforceName;
// "where" remaps the file to client file tree
QProcess proc;
- QStringList args(basicP4Args());
+ QStringList args(m_settings.basicP4Args());
args << QLatin1String("where") << perforceName;
- proc.start(m_settings.p4Command, args);
+ proc.start(m_settings.p4Command(), args);
if (!proc.waitForFinished()) {
*errorMessage = tr("Timeout waiting for \"where\" (%1).").arg(perforceName);
return QString();
diff --git a/src/plugins/perforce/perforceplugin.h b/src/plugins/perforce/perforceplugin.h
index e5985a28ab..d856685bba 100644
--- a/src/plugins/perforce/perforceplugin.h
+++ b/src/plugins/perforce/perforceplugin.h
@@ -93,7 +93,6 @@ public:
PerforcePlugin();
~PerforcePlugin();
- QStringList basicP4Args() const;
SettingsPage *settingsPage() const { return m_settingsPage; }
bool initialize(const QStringList &arguments, QString *error_message);
@@ -113,8 +112,8 @@ public:
static PerforcePlugin *perforcePluginInstance();
- PerforceSettings settings() const;
- void setSettings(const PerforceSettings &s);
+ const PerforceSettings& settings() const;
+ void setSettings(const QString &p4Command, const QString &p4Port, const QString &p4Client, const QString p4User, bool defaultEnv);
// Map a perforce name "//xx" to its real name in the file system
QString fileNameFromPerforceName(const QString& perforceName, QString *errorMessage) const;
diff --git a/src/plugins/perforce/perforcesettings.cpp b/src/plugins/perforce/perforcesettings.cpp
index 7ba51b78e0..b30d12a414 100644
--- a/src/plugins/perforce/perforcesettings.cpp
+++ b/src/plugins/perforce/perforcesettings.cpp
@@ -33,7 +33,11 @@
#include "perforcesettings.h"
+#include <qtconcurrent/QtConcurrentTools>
+#include <QtCore/QtConcurrentRun>
#include <QtCore/QSettings>
+#include <QtCore/QStringList>
+#include <QtCore/QProcess>
static const char *groupC = "Perforce";
static const char *commandKeyC = "Command";
@@ -55,41 +59,134 @@ static QString defaultCommand()
namespace Perforce {
namespace Internal {
-PerforceSettings::PerforceSettings() :
- p4Command(defaultCommand()),
- defaultEnv(true)
+PerforceSettings::PerforceSettings()
+ : m_valid(false)
{
+ // We do all the initialization in fromSettings
+}
+
+PerforceSettings::~PerforceSettings()
+{
+ // ensure that we are not still running
+ m_future.waitForFinished();
+}
+
+bool PerforceSettings::isValid() const
+{
+ m_future.waitForFinished();
+ m_mutex.lock();
+ bool valid = m_valid;
+ m_mutex.unlock();
+ return valid;
+}
+
+void PerforceSettings::run(QFutureInterface<void> &fi)
+{
+ m_mutex.lock();
+ QString executable = m_p4Command;
+ QStringList arguments = basicP4Args();
+ m_mutex.unlock();
+
+ // TODO actually check
+ bool valid = true;
+
+ QProcess p4;
+ p4.start(m_p4Command, QStringList() << "client"<<"-o");
+ p4.waitForFinished(2000);
+ if (p4.state() != QProcess::NotRunning) {
+ p4.kill();
+ p4.waitForFinished();
+ valid = false;
+ } else {
+ QString response = p4.readAllStandardOutput();
+ if (!response.contains("View:"))
+ valid = false;
+ }
+
+ m_mutex.lock();
+ if (executable == m_p4Command && arguments == basicP4Args()) // Check that those settings weren't changed in between
+ m_valid = valid;
+ m_mutex.unlock();
+ fi.reportFinished();
}
void PerforceSettings::fromSettings(QSettings *settings)
{
+ m_mutex.lock();
settings->beginGroup(QLatin1String(groupC));
- p4Command = settings->value(QLatin1String(commandKeyC), defaultCommand()).toString();
- defaultEnv = settings->value(QLatin1String(defaultKeyC), true).toBool();
- p4Port = settings->value(QLatin1String(portKeyC), QString()).toString();
- p4Client = settings->value(QLatin1String(clientKeyC), QString()).toString();
- p4User = settings->value(QLatin1String(userKeyC), QString()).toString();
+ m_p4Command = settings->value(QLatin1String(commandKeyC), defaultCommand()).toString();
+ m_defaultEnv = settings->value(QLatin1String(defaultKeyC), true).toBool();
+ m_p4Port = settings->value(QLatin1String(portKeyC), QString()).toString();
+ m_p4Client = settings->value(QLatin1String(clientKeyC), QString()).toString();
+ m_p4User = settings->value(QLatin1String(userKeyC), QString()).toString();
settings->endGroup();
+ m_mutex.unlock();
+ m_future = QtConcurrent::run(&PerforceSettings::run, this);
}
void PerforceSettings::toSettings(QSettings *settings) const
{
+ m_mutex.lock();
settings->beginGroup(QLatin1String(groupC));
- settings->setValue(commandKeyC, p4Command);
- settings->setValue(defaultKeyC, defaultEnv);
- settings->setValue(portKeyC, p4Port);
- settings->setValue(clientKeyC, p4Client);
- settings->setValue(userKeyC, p4User);
+ settings->setValue(commandKeyC, m_p4Command);
+ settings->setValue(defaultKeyC, m_defaultEnv);
+ settings->setValue(portKeyC, m_p4Port);
+ settings->setValue(clientKeyC, m_p4Client);
+ settings->setValue(userKeyC, m_p4User);
settings->endGroup();
+ m_mutex.unlock();
}
-bool PerforceSettings::equals(const PerforceSettings &s) const
+void PerforceSettings::setSettings(const QString &p4Command, const QString &p4Port, const QString &p4Client, const QString p4User, bool defaultEnv)
{
- return p4Command == s.p4Command && p4Port == s.p4Port
- && p4Client == s.p4Client && p4User == s.p4User
- && defaultEnv == s.defaultEnv;
+ m_mutex.lock();
+ m_p4Command = p4Command;
+ m_p4Port = p4Port;
+ m_p4Client = p4Client;
+ m_p4User = p4User;
+ m_defaultEnv = defaultEnv;
+ m_valid = false;
+ m_mutex.unlock();
+ m_future = QtConcurrent::run(&PerforceSettings::run, this);
}
+QString PerforceSettings::p4Command() const
+{
+ return m_p4Command;
+}
+
+QString PerforceSettings::p4Port() const
+{
+ return m_p4Port;
+}
+
+QString PerforceSettings::p4Client() const
+{
+ return m_p4Client;
+}
+
+QString PerforceSettings::p4User() const
+{
+ return m_p4User;
+}
+
+bool PerforceSettings::defaultEnv() const
+{
+ return m_defaultEnv;
+}
+
+QStringList PerforceSettings::basicP4Args() const
+{
+ QStringList lst;
+ if (!m_defaultEnv) {
+ lst << QLatin1String("-c") << m_p4Client;
+ lst << QLatin1String("-p") << m_p4Port;
+ lst << QLatin1String("-u") << m_p4User;
+ }
+ return lst;
+}
+
+
} // Internal
} // Perforce
diff --git a/src/plugins/perforce/perforcesettings.h b/src/plugins/perforce/perforcesettings.h
index 4451d4ad61..0ca1147f4f 100644
--- a/src/plugins/perforce/perforcesettings.h
+++ b/src/plugins/perforce/perforcesettings.h
@@ -35,6 +35,7 @@
#define PERFOCESETTINGS_H
#include <QtCore/QString>
+#include <QtCore/QFuture>
QT_BEGIN_NAMESPACE
class QSettings;
@@ -43,23 +44,34 @@ QT_END_NAMESPACE
namespace Perforce {
namespace Internal {
-struct PerforceSettings {
+class PerforceSettings {
+public:
PerforceSettings();
- void fromSettings(QSettings *);
+ ~PerforceSettings();
+ void fromSettings(QSettings *settings);
void toSettings(QSettings *) const;
- bool equals(const PerforceSettings &s) const;
+ void setSettings(const QString &p4Command, const QString &p4Port, const QString &p4Client, const QString p4User, bool defaultEnv);
+ bool isValid() const;
- QString p4Command;
- QString p4Port;
- QString p4Client;
- QString p4User;
- bool defaultEnv;
-};
+ QString p4Command() const;
+ QString p4Port() const;
+ QString p4Client() const;
+ QString p4User() const;
+ bool defaultEnv() const;
+ QStringList basicP4Args() const;
+private:
+ void run(QFutureInterface<void> &fi);
+ mutable QFuture<void> m_future;
+ mutable QMutex m_mutex;
-inline bool operator==(const PerforceSettings &p1, const PerforceSettings &p2)
- { return p1.equals(p2); }
-inline bool operator!=(const PerforceSettings &p1, const PerforceSettings &p2)
- { return !p1.equals(p2); }
+ QString m_p4Command;
+ QString m_p4Port;
+ QString m_p4Client;
+ QString m_p4User;
+ bool m_defaultEnv;
+ bool m_valid;
+ Q_DISABLE_COPY(PerforceSettings);
+};
} // Internal
} // Perforce
diff --git a/src/plugins/perforce/settingspage.cpp b/src/plugins/perforce/settingspage.cpp
index 70ef649b0e..53d32714ff 100644
--- a/src/plugins/perforce/settingspage.cpp
+++ b/src/plugins/perforce/settingspage.cpp
@@ -49,24 +49,38 @@ SettingsPageWidget::SettingsPageWidget(QWidget *parent) :
m_ui.pathChooser->setExpectedKind(PathChooser::Command);
}
-PerforceSettings SettingsPageWidget::settings() const
+QString SettingsPageWidget::p4Command() const
{
- PerforceSettings rc;
- rc.p4Command = m_ui.pathChooser->path();
- rc.defaultEnv = m_ui.defaultCheckBox->isChecked();
- rc.p4Port = m_ui.portLineEdit->text();
- rc.p4Client = m_ui.clientLineEdit->text();
- rc.p4User = m_ui.userLineEdit->text();
- return rc;
+ return m_ui.pathChooser->path();
+}
+
+bool SettingsPageWidget::defaultEnv() const
+{
+ return m_ui.defaultCheckBox->isChecked();
+}
+
+QString SettingsPageWidget::p4Port() const
+{
+ return m_ui.portLineEdit->text();
+}
+
+QString SettingsPageWidget::p4User() const
+{
+ return m_ui.userLineEdit->text();
+}
+
+QString SettingsPageWidget::p4Client() const
+{
+ return m_ui.clientLineEdit->text();
}
void SettingsPageWidget::setSettings(const PerforceSettings &s)
{
- m_ui.pathChooser->setPath(s.p4Command);
- m_ui.defaultCheckBox->setChecked(s.defaultEnv);
- m_ui.portLineEdit->setText(s.p4Port);
- m_ui.clientLineEdit->setText(s.p4Client);
- m_ui.userLineEdit->setText(s.p4User);
+ m_ui.pathChooser->setPath(s.p4Command());
+ m_ui.defaultCheckBox->setChecked(s.defaultEnv());
+ m_ui.portLineEdit->setText(s.p4Port());
+ m_ui.clientLineEdit->setText(s.p4Client());
+ m_ui.userLineEdit->setText(s.p4User());
}
SettingsPage::SettingsPage()
@@ -101,5 +115,5 @@ void SettingsPage::apply()
if (!m_widget)
return;
- PerforcePlugin::perforcePluginInstance()->setSettings(m_widget->settings());
+ PerforcePlugin::perforcePluginInstance()->setSettings(m_widget->p4Command(), m_widget->p4Port(), m_widget->p4Client(), m_widget->p4User(), m_widget->defaultEnv());
}
diff --git a/src/plugins/perforce/settingspage.h b/src/plugins/perforce/settingspage.h
index f5c43599fa..10a3a0c93b 100644
--- a/src/plugins/perforce/settingspage.h
+++ b/src/plugins/perforce/settingspage.h
@@ -51,7 +51,12 @@ class SettingsPageWidget : public QWidget {
public:
explicit SettingsPageWidget(QWidget *parent);
- PerforceSettings settings() const;
+ QString p4Command() const;
+ bool defaultEnv() const;
+ QString p4Port() const;
+ QString p4User() const;
+ QString p4Client() const;
+
void setSettings(const PerforceSettings &);
private: