diff options
Diffstat (limited to 'src/plugins')
120 files changed, 1591 insertions, 862 deletions
diff --git a/src/plugins/analyzerbase/analyzerrunconfigwidget.cpp b/src/plugins/analyzerbase/analyzerrunconfigwidget.cpp index 65a24e6041..cb7aedeade 100644 --- a/src/plugins/analyzerbase/analyzerrunconfigwidget.cpp +++ b/src/plugins/analyzerbase/analyzerrunconfigwidget.cpp @@ -98,8 +98,8 @@ void AnalyzerRunConfigWidget::chooseSettings(int setting) m_configWidget->setEnabled(isCustom); m_restoreButton->setEnabled(isCustom); m_details->setSummaryText(isCustom - ? tr("Use <strong>Customized Settings<strong>") - : tr("Use <strong>Global Settings<strong>")); + ? tr("Use <strong>Customized Settings</strong>") + : tr("Use <strong>Global Settings</strong>")); } void AnalyzerRunConfigWidget::restoreGlobal() diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index f3cf89e562..91e7b478a5 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -636,7 +636,7 @@ QVector<AndroidDeviceInfo> AndroidConfigurations::androidVirtualDevices() const QString AndroidConfigurations::startAVD(const QString &name, int apiLevel, QString cpuAbi) const { - if (findAvd(apiLevel, cpuAbi) || startAVDAsync(name)) + if (!findAvd(apiLevel, cpuAbi).isEmpty() || startAVDAsync(name)) return waitForAvd(apiLevel, cpuAbi); return QString(); } @@ -658,7 +658,7 @@ bool AndroidConfigurations::startAVDAsync(const QString &avdName) const return true; } -bool AndroidConfigurations::findAvd(int apiLevel, const QString &cpuAbi) const +QString AndroidConfigurations::findAvd(int apiLevel, const QString &cpuAbi) const { QVector<AndroidDeviceInfo> devices = connectedDevices(); foreach (AndroidDeviceInfo device, devices) { @@ -668,37 +668,50 @@ bool AndroidConfigurations::findAvd(int apiLevel, const QString &cpuAbi) const continue; if (device.sdk != apiLevel) continue; - return true; + return device.serialNumber; + } + return QString(); +} + +bool AndroidConfigurations::isConnected(const QString &serialNumber) const +{ + QVector<AndroidDeviceInfo> devices = connectedDevices(); + foreach (AndroidDeviceInfo device, devices) { + if (device.serialNumber == serialNumber) + return true; } return false; } -QString AndroidConfigurations::waitForAvd(int apiLevel, const QString &cpuAbi) const +bool AndroidConfigurations::waitForBooted(const QString &serialNumber, const QFutureInterface<bool> &fi) const { - // we cannot use adb -e wait-for-device, since that doesn't work if a emulator is already running + // found a serial number, now wait until it's done booting... + for (int i = 0; i < 60; ++i) { + if (fi.isCanceled()) + return false; + if (hasFinishedBooting(serialNumber)) { + return true; + } else { + Utils::sleep(2000); + if (!isConnected(serialNumber)) // device was disconnected + return false; + } + } + return false; +} - // 15 rounds of 8s sleeping, a minute for the avd to start +QString AndroidConfigurations::waitForAvd(int apiLevel, const QString &cpuAbi, const QFutureInterface<bool> &fi) const +{ + // we cannot use adb -e wait-for-device, since that doesn't work if a emulator is already running + // 60 rounds of 2s sleeping, two minutes for the avd to start QString serialNumber; - for (int i = 0; i < 15; ++i) { - QVector<AndroidDeviceInfo> devices = connectedDevices(); - foreach (AndroidDeviceInfo device, devices) { - if (!device.serialNumber.startsWith(QLatin1String("emulator"))) - continue; - if (!device.cpuAbi.contains(cpuAbi)) - continue; - if (device.sdk != apiLevel) - continue; - serialNumber = device.serialNumber; - // found a serial number, now wait until it's done booting... - for (int i = 0; i < 15; ++i) { - if (hasFinishedBooting(serialNumber)) - return serialNumber; - else - Utils::sleep(8000); - } + for (int i = 0; i < 60; ++i) { + if (fi.isCanceled()) return QString(); - } - Utils::sleep(8000); + serialNumber = findAvd(apiLevel, cpuAbi); + if (!serialNumber.isEmpty()) + return waitForBooted(serialNumber, fi) ? serialNumber : QString(); + Utils::sleep(2000); } return QString(); } diff --git a/src/plugins/android/androidconfigurations.h b/src/plugins/android/androidconfigurations.h index 1d87f5b27d..f69a830aed 100644 --- a/src/plugins/android/androidconfigurations.h +++ b/src/plugins/android/androidconfigurations.h @@ -36,6 +36,7 @@ #include <QVector> #include <QHash> #include <QMap> +#include <QFutureInterface> #include <projectexplorer/abi.h> #include <utils/fileutils.h> #include <utils/environment.h> @@ -108,8 +109,9 @@ public: QVector<AndroidDeviceInfo> androidVirtualDevices() const; QString startAVD(const QString &name, int apiLevel, QString cpuAbi) const; bool startAVDAsync(const QString &avdName) const; - bool findAvd(int apiLevel, const QString &cpuAbi) const; - QString waitForAvd(int apiLevel, const QString &cpuAbi) const; + QString findAvd(int apiLevel, const QString &cpuAbi) const; + QString waitForAvd(int apiLevel, const QString &cpuAbi, const QFutureInterface<bool> &fi = QFutureInterface<bool>()) const; + // special version for AndroidDeployQt::run QString bestNdkPlatformMatch(const QString &targetAPI) const; QStringList makeExtraSearchDirectories() const; @@ -123,6 +125,8 @@ public: QString getProductModel(const QString &device) const; bool hasFinishedBooting(const QString &device) const; + bool waitForBooted(const QString &serialNumber, const QFutureInterface<bool> &fi) const; + bool isConnected(const QString &serialNumber) const; AndroidDeviceInfo showDeviceDialog(ProjectExplorer::Project *project, int apiLevel, const QString &abi); void setDefaultDevice(ProjectExplorer::Project *project, const QString &abi, const QString &serialNumber); // serial number or avd name diff --git a/src/plugins/android/androiddeployqtstep.cpp b/src/plugins/android/androiddeployqtstep.cpp index 2e42b763f5..c4a5adc67a 100644 --- a/src/plugins/android/androiddeployqtstep.cpp +++ b/src/plugins/android/androiddeployqtstep.cpp @@ -288,7 +288,7 @@ bool AndroidDeployQtStep::init() if (!result) return false; - if (!AndroidConfigurations::instance().findAvd(m_deviceAPILevel, m_targetArch)) + if (AndroidConfigurations::instance().findAvd(m_deviceAPILevel, m_targetArch).isEmpty()) AndroidConfigurations::instance().startAVDAsync(m_avdName); return true; } @@ -296,7 +296,7 @@ bool AndroidDeployQtStep::init() void AndroidDeployQtStep::run(QFutureInterface<bool> &fi) { if (!m_avdName.isEmpty()) { - QString serialNumber = AndroidConfigurations::instance().waitForAvd(m_deviceAPILevel, m_targetArch); + QString serialNumber = AndroidConfigurations::instance().waitForAvd(m_deviceAPILevel, m_targetArch, fi); if (serialNumber.isEmpty()) { fi.reportResult(false); emit finished(); diff --git a/src/plugins/android/androiddeploystep.cpp b/src/plugins/android/androiddeploystep.cpp index d971eb6e71..b33272adb6 100644 --- a/src/plugins/android/androiddeploystep.cpp +++ b/src/plugins/android/androiddeploystep.cpp @@ -389,7 +389,7 @@ void AndroidDeployStep::deployFiles(QProcess *process, const QList<DeployItem> & bool AndroidDeployStep::deployPackage() { if (!m_avdName.isEmpty()) { - if (!AndroidConfigurations::instance().findAvd(m_deviceAPILevel, m_targetArch) + if (AndroidConfigurations::instance().findAvd(m_deviceAPILevel, m_targetArch).isEmpty() && !AndroidConfigurations::instance().startAVDAsync(m_avdName)) return false; m_deviceSerialNumber = AndroidConfigurations::instance().waitForAvd(m_deviceAPILevel, m_targetArch); diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index 73a713372c..9aa782b37a 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -791,7 +791,7 @@ QString AndroidManager::androidNameForApiLevel(int x) case 19: return QLatin1String("Android 4.4"); default: - return QLatin1String("Unknown Android version."); + return tr("Unknown Android version."); } } diff --git a/src/plugins/android/androidmanifesteditorwidget.cpp b/src/plugins/android/androidmanifesteditorwidget.cpp index b6403625cc..3d6b6d1057 100644 --- a/src/plugins/android/androidmanifesteditorwidget.cpp +++ b/src/plugins/android/androidmanifesteditorwidget.cpp @@ -202,7 +202,7 @@ void AndroidManifestEditorWidget::initializePage() m_androidTargetSdkVersion = new QComboBox(packageGroupBox); m_androidTargetSdkVersion->setToolTip( - tr("Sets the target SDK. Set this to the highest tested version." + tr("Sets the target SDK. Set this to the highest tested version. " "This disables compatibility behavior of the system for your application.")); m_androidTargetSdkVersion->addItem(tr("Not set"), 0); diff --git a/src/plugins/android/androidpotentialkit.cpp b/src/plugins/android/androidpotentialkit.cpp index 9083d018f4..abc23682d1 100644 --- a/src/plugins/android/androidpotentialkit.cpp +++ b/src/plugins/android/androidpotentialkit.cpp @@ -76,6 +76,7 @@ AndroidPotentialKitWidget::AndroidPotentialKitWidget(QWidget *parent) : Utils::DetailsWidget(parent) { setSummaryText(QLatin1String("<b>Create Android Kits</b>")); + setIcon(QIcon(QLatin1String(Constants::ANDROID_SETTINGS_CATEGORY_ICON))); //detailsWidget->setState(Utils::DetailsWidget::NoSummary); QWidget *mainWidget = new QWidget(this); setWidget(mainWidget); @@ -84,7 +85,7 @@ AndroidPotentialKitWidget::AndroidPotentialKitWidget(QWidget *parent) layout->setMargin(0); QLabel *label = new QLabel; label->setText(tr("Qt Creator needs additional settings to enable Android support." - "You can configure those settings in the Options dialog.")); + " You can configure those settings in the Options dialog.")); label->setWordWrap(true); layout->addWidget(label, 0, 0, 1, 2); diff --git a/src/plugins/android/androidruncontrol.cpp b/src/plugins/android/androidruncontrol.cpp index 8b8e2ae5fa..46ae55465d 100644 --- a/src/plugins/android/androidruncontrol.cpp +++ b/src/plugins/android/androidruncontrol.cpp @@ -107,7 +107,7 @@ QString AndroidRunControl::displayName() const QIcon AndroidRunControl::icon() const { - return QIcon(QLatin1String(ProjectExplorer::Constants::ICON_DEBUG_SMALL)); + return QIcon(QLatin1String(ProjectExplorer::Constants::ICON_RUN_SMALL)); } } // namespace Internal diff --git a/src/plugins/android/androidsettingswidget.ui b/src/plugins/android/androidsettingswidget.ui index 4c4c1d8bd0..7146434ad2 100644 --- a/src/plugins/android/androidsettingswidget.ui +++ b/src/plugins/android/androidsettingswidget.ui @@ -214,7 +214,7 @@ </sizepolicy> </property> <property name="text"> - <string>Ant location:</string> + <string>Ant executable:</string> </property> <property name="alignment"> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> diff --git a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp index 2891954bf1..a1c9c15984 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp +++ b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp @@ -78,6 +78,7 @@ AutotoolsProject::AutotoolsProject(AutotoolsManager *manager, const QString &fil m_watchedFiles(), m_makefileParserThread(0) { + setId(Constants::AUTOTOOLS_PROJECT_ID); setProjectContext(Core::Context(Constants::PROJECT_CONTEXT)); setProjectLanguages(Core::Context(ProjectExplorer::Constants::LANG_CXX)); @@ -108,11 +109,6 @@ QString AutotoolsProject::displayName() const return m_projectName; } -Core::Id AutotoolsProject::id() const -{ - return Core::Id(Constants::AUTOTOOLS_PROJECT_ID); -} - Core::IDocument *AutotoolsProject::document() const { return m_file; diff --git a/src/plugins/autotoolsprojectmanager/autotoolsproject.h b/src/plugins/autotoolsprojectmanager/autotoolsproject.h index 1af14a6bed..739c2535f5 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsproject.h +++ b/src/plugins/autotoolsprojectmanager/autotoolsproject.h @@ -73,7 +73,6 @@ public: ~AutotoolsProject(); QString displayName() const; - Core::Id id() const; Core::IDocument *document() const; ProjectExplorer::IProjectManager *projectManager() const; ProjectExplorer::ProjectNode *rootProjectNode() const; diff --git a/src/plugins/clearcase/clearcasecontrol.cpp b/src/plugins/clearcase/clearcasecontrol.cpp index 3026262389..c1497f979a 100644 --- a/src/plugins/clearcase/clearcasecontrol.cpp +++ b/src/plugins/clearcase/clearcasecontrol.cpp @@ -83,12 +83,23 @@ bool ClearCaseControl::supportsOperation(Operation operation) const return rc; } -Core::IVersionControl::OpenSupportMode ClearCaseControl::openSupportMode() const -{ - if (m_plugin->isDynamic()) - return IVersionControl::OpenMandatory; // Checkout is the only option for dynamic views - else +Core::IVersionControl::OpenSupportMode ClearCaseControl::openSupportMode(const QString &fileName) const +{ + if (m_plugin->isDynamic()) { + // NB! Has to use managesFile() and not vcsStatus() since the index can only be guaranteed + // to be up to date if the file has been explicitly opened, which is not the case when + // doing a search and replace as a part of a refactoring. + if (m_plugin->managesFile(QFileInfo(fileName).absolutePath(), fileName)) { + // Checkout is the only option for managed files in dynamic views + return IVersionControl::OpenMandatory; + } else { + // Not managed files can be edited without noticing the VCS + return IVersionControl::NoOpen; + } + + } else { return IVersionControl::OpenOptional; // Snapshot views supports Hijack and check out + } } bool ClearCaseControl::vcsOpen(const QString &fileName) @@ -153,6 +164,8 @@ QString ClearCaseControl::vcsOpenText() const QString ClearCaseControl::vcsMakeWritableText() const { + if (m_plugin->isDynamic()) + return QString(); return tr("&Hijack"); } diff --git a/src/plugins/clearcase/clearcasecontrol.h b/src/plugins/clearcase/clearcasecontrol.h index f94ee44052..794cd8b2b4 100644 --- a/src/plugins/clearcase/clearcasecontrol.h +++ b/src/plugins/clearcase/clearcasecontrol.h @@ -53,7 +53,7 @@ public: bool isConfigured() const; bool supportsOperation(Operation operation) const; - OpenSupportMode openSupportMode() const; + OpenSupportMode openSupportMode(const QString &fileName) const; bool vcsOpen(const QString &fileName); SettingsFlags settingsFlags() const; bool vcsAdd(const QString &fileName); diff --git a/src/plugins/clearcase/clearcaseplugin.cpp b/src/plugins/clearcase/clearcaseplugin.cpp index 73d2cfe59d..a08ec4e96d 100644 --- a/src/plugins/clearcase/clearcaseplugin.cpp +++ b/src/plugins/clearcase/clearcaseplugin.cpp @@ -700,6 +700,27 @@ ClearCaseSubmitEditor *ClearCasePlugin::openClearCaseSubmitEditor(const QString return submitEditor; } +QString fileStatusToText(FileStatus fileStatus) +{ + switch (fileStatus.status) + { + case FileStatus::CheckedIn: + return QLatin1String("CheckedIn"); + case FileStatus::CheckedOut: + return QLatin1String("CheckedOut"); + case FileStatus::Hijacked: + return QLatin1String("Hijacked"); + case FileStatus::Missing: + return QLatin1String("Missing"); + case FileStatus::NotManaged: + return QLatin1String("ViewPrivate"); + case FileStatus::Unknown: + return QLatin1String("Unknown"); + default: + return QLatin1String("default"); + } +} + void ClearCasePlugin::updateStatusActions() { FileStatus fileStatus = FileStatus::Unknown; @@ -709,7 +730,8 @@ void ClearCasePlugin::updateStatusActions() fileStatus = m_statusMap->value(absoluteFileName, FileStatus(FileStatus::Unknown)); if (Constants::debug) - qDebug() << Q_FUNC_INFO << absoluteFileName << ", status = " << fileStatus.status; + qDebug() << Q_FUNC_INFO << absoluteFileName << ", status = " + << fileStatusToText(fileStatus.status) << "(" << fileStatus.status << ")"; } m_checkOutAction->setEnabled(hasFile && (fileStatus.status & (FileStatus::CheckedIn | FileStatus::Hijacked))); @@ -717,6 +739,9 @@ void ClearCasePlugin::updateStatusActions() m_undoHijackAction->setEnabled(!m_viewData.isDynamic && hasFile && (fileStatus.status & FileStatus::Hijacked)); m_checkInCurrentAction->setEnabled(hasFile && (fileStatus.status & FileStatus::CheckedOut)); m_addFileAction->setEnabled(hasFile && (fileStatus.status & FileStatus::NotManaged)); + m_diffCurrentAction->setEnabled(hasFile && (fileStatus.status != FileStatus::NotManaged)); + m_historyCurrentAction->setEnabled(hasFile && (fileStatus.status != FileStatus::NotManaged)); + m_annotateCurrentAction->setEnabled(hasFile && (fileStatus.status != FileStatus::NotManaged)); m_checkInActivityAction->setEnabled(m_viewData.isUcm); m_diffActivityAction->setEnabled(m_viewData.isUcm); diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index 68acc76aa6..8708272914 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -92,6 +92,7 @@ CMakeProject::CMakeProject(CMakeManager *manager, const QString &fileName) m_rootNode(new CMakeProjectNode(fileName)), m_watcher(new QFileSystemWatcher(this)) { + setId(Constants::CMAKEPROJECT_ID); setProjectContext(Core::Context(CMakeProjectManager::Constants::PROJECTCONTEXT)); setProjectLanguages(Core::Context(ProjectExplorer::Constants::LANG_CXX)); @@ -512,11 +513,6 @@ QString CMakeProject::displayName() const return m_projectName; } -Core::Id CMakeProject::id() const -{ - return Core::Id(Constants::CMAKEPROJECT_ID); -} - Core::IDocument *CMakeProject::document() const { return m_file; diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.h b/src/plugins/cmakeprojectmanager/cmakeproject.h index c950575e0f..f89081bd43 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.h +++ b/src/plugins/cmakeprojectmanager/cmakeproject.h @@ -80,7 +80,6 @@ public: ~CMakeProject(); QString displayName() const; - Core::Id id() const; Core::IDocument *document() const; CMakeManager *projectManager() const; diff --git a/src/plugins/coreplugin/dialogs/newdialog.cpp b/src/plugins/coreplugin/dialogs/newdialog.cpp index 1353b95ae9..6379a55274 100644 --- a/src/plugins/coreplugin/dialogs/newdialog.cpp +++ b/src/plugins/coreplugin/dialogs/newdialog.cpp @@ -194,7 +194,7 @@ NewDialog::NewDialog(QWidget *parent) : m_ui->frame->setPalette(p); m_okButton = m_ui->buttonBox->button(QDialogButtonBox::Ok); m_okButton->setDefault(true); - m_okButton->setText(tr("&Choose...")); + m_okButton->setText(tr("Choose...")); m_model = new QStandardItemModel(this); m_twoLevelProxyModel = new TwoLevelProxyModel(this); diff --git a/src/plugins/coreplugin/dialogs/readonlyfilesdialog.cpp b/src/plugins/coreplugin/dialogs/readonlyfilesdialog.cpp index e5b92af57c..601251180c 100644 --- a/src/plugins/coreplugin/dialogs/readonlyfilesdialog.cpp +++ b/src/plugins/coreplugin/dialogs/readonlyfilesdialog.cpp @@ -257,33 +257,33 @@ int ReadOnlyFilesDialog::exec() ReadOnlyResult result = RO_Cancel; QStringList failedToMakeWritable; - foreach (ReadOnlyFilesDialogPrivate::ButtonGroupForFile buttengroup, d->buttonGroups) { - result = static_cast<ReadOnlyResult>(buttengroup.group->checkedId()); + foreach (ReadOnlyFilesDialogPrivate::ButtonGroupForFile buttongroup, d->buttonGroups) { + result = static_cast<ReadOnlyResult>(buttongroup.group->checkedId()); switch (result) { case RO_MakeWritable: - if (!Utils::FileUtils::makeWritable(Utils::FileName(QFileInfo(buttengroup.fileName)))) { - failedToMakeWritable << buttengroup.fileName; + if (!Utils::FileUtils::makeWritable(Utils::FileName(QFileInfo(buttongroup.fileName)))) { + failedToMakeWritable << buttongroup.fileName; continue; } break; case RO_OpenVCS: - if (!d->versionControls[buttengroup.fileName]->vcsOpen(buttengroup.fileName)) { - failedToMakeWritable << buttengroup.fileName; + if (!d->versionControls[buttongroup.fileName]->vcsOpen(buttongroup.fileName)) { + failedToMakeWritable << buttongroup.fileName; continue; } break; case RO_SaveAs: if (!EditorManager::saveDocumentAs(d->document)) { - failedToMakeWritable << buttengroup.fileName; + failedToMakeWritable << buttongroup.fileName; continue; } break; default: - failedToMakeWritable << buttengroup.fileName; + failedToMakeWritable << buttongroup.fileName; continue; } - if (!QFileInfo(buttengroup.fileName).isWritable()) - failedToMakeWritable << buttengroup.fileName; + if (!QFileInfo(buttongroup.fileName).isWritable()) + failedToMakeWritable << buttongroup.fileName; } if (!failedToMakeWritable.isEmpty()) { if (d->showWarnings) @@ -366,7 +366,7 @@ void ReadOnlyFilesDialog::updateSelectAll() void ReadOnlyFilesDialog::initDialog(const QStringList &fileNames) { ui->setupUi(this); - ui->buttonBox->addButton(tr("&Change Permission"), QDialogButtonBox::AcceptRole); + ui->buttonBox->addButton(tr("Change &Permission"), QDialogButtonBox::AcceptRole); ui->buttonBox->addButton(QDialogButtonBox::Cancel); QString vcsOpenTextForAll; @@ -389,7 +389,7 @@ void ReadOnlyFilesDialog::initDialog(const QStringList &fileNames) IVersionControl *versionControlForFile = VcsManager::findVersionControlForDirectory(directory); const bool fileManagedByVCS = versionControlForFile - && versionControlForFile->openSupportMode() != IVersionControl::NoOpen; + && versionControlForFile->openSupportMode(fileName) != IVersionControl::NoOpen; if (fileManagedByVCS) { const QString vcsOpenTextForFile = versionControlForFile->vcsOpenText().remove(QLatin1Char('&')); @@ -407,7 +407,7 @@ void ReadOnlyFilesDialog::initDialog(const QStringList &fileNames) vcsMakeWritableTextForAll.clear(); } // Add make writable if it is supported by the reposetory. - if (versionControlForFile->openSupportMode() == IVersionControl::OpenOptional) { + if (versionControlForFile->openSupportMode(fileName) == IVersionControl::OpenOptional) { useMakeWritable = true; createRadioButtonForItem(item, radioButtonGroup, MakeWritable); } diff --git a/src/plugins/coreplugin/documentmanager.cpp b/src/plugins/coreplugin/documentmanager.cpp index 9e7dbbdba3..414fc8ca02 100644 --- a/src/plugins/coreplugin/documentmanager.cpp +++ b/src/plugins/coreplugin/documentmanager.cpp @@ -1368,11 +1368,6 @@ void DocumentManager::executeOpenWithMenuAction(QAction *action) EditorManager::openExternalEditor(entry.fileName, entry.externalEditor->id()); } -void DocumentManager::slotExecuteOpenWithMenuAction(QAction *action) -{ - executeOpenWithMenuAction(action); -} - bool DocumentManager::eventFilter(QObject *obj, QEvent *e) { if (obj == qApp && e->type() == QEvent::ApplicationActivate) { diff --git a/src/plugins/coreplugin/documentmanager.h b/src/plugins/coreplugin/documentmanager.h index 70168a2b23..ef54a55cfc 100644 --- a/src/plugins/coreplugin/documentmanager.h +++ b/src/plugins/coreplugin/documentmanager.h @@ -126,10 +126,8 @@ public: lead to any editors to reload or any other editor manager actions. */ static void notifyFilesChangedInternally(const QStringList &files); - static void executeOpenWithMenuAction(QAction *action); - public slots: - void slotExecuteOpenWithMenuAction(QAction *action); + static void executeOpenWithMenuAction(QAction *action); signals: void currentFileChanged(const QString &filePath); diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index b10cf3d2b2..253662a78f 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -1893,7 +1893,7 @@ void EditorManager::vcsOpenCurrentEditor() const QString directory = QFileInfo(document->filePath()).absolutePath(); IVersionControl *versionControl = VcsManager::findVersionControlForDirectory(directory); - if (!versionControl || versionControl->openSupportMode() == IVersionControl::NoOpen) + if (!versionControl || versionControl->openSupportMode(document->filePath()) == IVersionControl::NoOpen) return; if (!versionControl->vcsOpen(document->filePath())) { @@ -1955,7 +1955,7 @@ void EditorManager::updateMakeWritableWarning() bool promptVCS = false; const QString directory = QFileInfo(document->filePath()).absolutePath(); IVersionControl *versionControl = VcsManager::findVersionControlForDirectory(directory); - if (versionControl && versionControl->openSupportMode() != IVersionControl::NoOpen) { + if (versionControl && versionControl->openSupportMode(document->filePath()) != IVersionControl::NoOpen) { if (versionControl->settingsFlags() & IVersionControl::AutoOpen) { vcsOpenCurrentEditor(); ww = false; diff --git a/src/plugins/coreplugin/iversioncontrol.cpp b/src/plugins/coreplugin/iversioncontrol.cpp index 814bee6859..f903152a97 100644 --- a/src/plugins/coreplugin/iversioncontrol.cpp +++ b/src/plugins/coreplugin/iversioncontrol.cpp @@ -46,8 +46,9 @@ QString IVersionControl::vcsTopic(const QString &) return QString(); } -IVersionControl::OpenSupportMode IVersionControl::openSupportMode() const +IVersionControl::OpenSupportMode IVersionControl::openSupportMode(const QString &fileName) const { + Q_UNUSED(fileName); return NoOpen; } diff --git a/src/plugins/coreplugin/iversioncontrol.h b/src/plugins/coreplugin/iversioncontrol.h index c5a307d731..b603dde306 100644 --- a/src/plugins/coreplugin/iversioncontrol.h +++ b/src/plugins/coreplugin/iversioncontrol.h @@ -100,9 +100,9 @@ public: virtual bool supportsOperation(Operation operation) const = 0; /*! - * Returns the open support mode. + * Returns the open support mode for \a fileName. */ - virtual OpenSupportMode openSupportMode() const; + virtual OpenSupportMode openSupportMode(const QString &fileName) const; /*! * Called prior to save, if the file is read only. Should be implemented if diff --git a/src/plugins/cppeditor/cppeditorplugin.cpp b/src/plugins/cppeditor/cppeditorplugin.cpp index d7dd630a43..3cedeb5800 100644 --- a/src/plugins/cppeditor/cppeditorplugin.cpp +++ b/src/plugins/cppeditor/cppeditorplugin.cpp @@ -306,9 +306,6 @@ bool CppEditorPlugin::initialize(const QStringList & /*arguments*/, QString *err connect(ProgressManager::instance(), SIGNAL(allTasksFinished(Core::Id)), this, SLOT(onAllTasksFinished(Core::Id))); - connect(EditorManager::instance(), SIGNAL(currentEditorChanged(Core::IEditor*)), - SLOT(currentEditorChanged(Core::IEditor*))); - readSettings(); return true; } @@ -390,15 +387,6 @@ void CppEditorPlugin::onAllTasksFinished(Core::Id type) } } -void CppEditorPlugin::currentEditorChanged(IEditor *editor) -{ - if (!editor) - return; - - if (CPPEditorWidget *editorWidget = currentCppEditorWidget()) - editorWidget->semanticRehighlight(/*force = */ true); -} - void CppEditorPlugin::openTypeHierarchy() { if (currentCppEditorWidget()) { diff --git a/src/plugins/cppeditor/cppeditorplugin.h b/src/plugins/cppeditor/cppeditorplugin.h index b5b110feee..0989225538 100644 --- a/src/plugins/cppeditor/cppeditorplugin.h +++ b/src/plugins/cppeditor/cppeditorplugin.h @@ -90,7 +90,6 @@ public slots: private slots: void onTaskStarted(Core::Id type); void onAllTasksFinished(Core::Id type); - void currentEditorChanged(Core::IEditor *editor); #ifdef WITH_TESTS private slots: diff --git a/src/plugins/cpptools/completionsettingspage.ui b/src/plugins/cpptools/completionsettingspage.ui index b500f9095e..e654cf804e 100644 --- a/src/plugins/cpptools/completionsettingspage.ui +++ b/src/plugins/cpptools/completionsettingspage.ui @@ -205,7 +205,7 @@ <item> <widget class="QCheckBox" name="enableDoxygenCheckBox"> <property name="toolTip"> - <string>Automatically create a Doxygen comment upon pressing enter after a /** or /*!</string> + <string>Automatically create a Doxygen comment upon pressing enter after a /**, /*!, //! or ///</string> </property> <property name="text"> <string>Enable Doxygen blocks</string> diff --git a/src/plugins/cpptools/modelmanagertesthelper.cpp b/src/plugins/cpptools/modelmanagertesthelper.cpp index 4d7590e130..9c139c5a7b 100644 --- a/src/plugins/cpptools/modelmanagertesthelper.cpp +++ b/src/plugins/cpptools/modelmanagertesthelper.cpp @@ -39,6 +39,7 @@ TestProject::TestProject(const QString &name, QObject *parent) : m_name (name) { setParent(parent); + setId(Core::Id::fromString(name)); } TestProject::~TestProject() diff --git a/src/plugins/cpptools/modelmanagertesthelper.h b/src/plugins/cpptools/modelmanagertesthelper.h index d4ac671bc1..4ed45195cd 100644 --- a/src/plugins/cpptools/modelmanagertesthelper.h +++ b/src/plugins/cpptools/modelmanagertesthelper.h @@ -48,9 +48,6 @@ public: virtual QString displayName() const { return m_name; } - virtual Core::Id id() const - { return Core::Id::fromString(m_name); } - virtual Core::IDocument *document() const { return 0; } diff --git a/src/plugins/cvs/checkoutwizard.cpp b/src/plugins/cvs/checkoutwizard.cpp index e2a3bb327c..85655f8aee 100644 --- a/src/plugins/cvs/checkoutwizard.cpp +++ b/src/plugins/cvs/checkoutwizard.cpp @@ -68,7 +68,7 @@ VcsBase::Command *CheckoutWizard::createCommand(const QList<QWizardPage*> ¶m const CheckoutWizardPage *cwp = qobject_cast<const CheckoutWizardPage *>(parameterPages.front()); QTC_ASSERT(cwp, return 0); const CvsSettings settings = CvsPlugin::instance()->settings(); - const QString binary = settings.cvsBinaryPath; + const QString binary = settings.binaryPath(); QStringList args; const QString repository = cwp->repository(); args << QLatin1String("checkout") << repository; diff --git a/src/plugins/cvs/cvs.pro b/src/plugins/cvs/cvs.pro index 9ecb32b06e..be1d4af402 100644 --- a/src/plugins/cvs/cvs.pro +++ b/src/plugins/cvs/cvs.pro @@ -2,6 +2,7 @@ include(../../qtcreatorplugin.pri) HEADERS += annotationhighlighter.h \ cvsplugin.h \ + cvsclient.h \ cvscontrol.h \ settingspage.h \ cvseditor.h \ @@ -14,6 +15,7 @@ HEADERS += annotationhighlighter.h \ SOURCES += annotationhighlighter.cpp \ cvsplugin.cpp \ + cvsclient.cpp \ cvscontrol.cpp \ settingspage.cpp \ cvseditor.cpp \ diff --git a/src/plugins/cvs/cvs.qbs b/src/plugins/cvs/cvs.qbs index 8d858a7b24..a1021cfc6e 100644 --- a/src/plugins/cvs/cvs.qbs +++ b/src/plugins/cvs/cvs.qbs @@ -20,6 +20,8 @@ QtcPlugin { "checkoutwizardpage.cpp", "checkoutwizardpage.h", "cvs.qrc", + "cvsclient.cpp", + "cvsclient.h", "cvsconstants.h", "cvscontrol.cpp", "cvscontrol.h", diff --git a/src/plugins/cvs/cvsclient.cpp b/src/plugins/cvs/cvsclient.cpp new file mode 100644 index 0000000000..2dfe577e01 --- /dev/null +++ b/src/plugins/cvs/cvsclient.cpp @@ -0,0 +1,182 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "cvsclient.h" +#include "cvssettings.h" +#include "cvsconstants.h" + +#include <vcsbase/vcsbaseplugin.h> +#include <vcsbase/vcsbaseeditor.h> +#include <vcsbase/vcsbaseconstants.h> +#include <vcsbase/vcsbaseeditorparameterwidget.h> +#include <utils/synchronousprocess.h> + +#include <QDir> +#include <QFileInfo> +#include <QTextStream> +#include <QDebug> + +namespace Cvs { +namespace Internal { + +class CvsDiffExitCodeInterpreter : public Utils::ExitCodeInterpreter +{ + Q_OBJECT +public: + CvsDiffExitCodeInterpreter(QObject *parent) : Utils::ExitCodeInterpreter(parent) {} + Utils::SynchronousProcessResponse::Result interpretExitCode(int code) const; + +}; + +Utils::SynchronousProcessResponse::Result CvsDiffExitCodeInterpreter::interpretExitCode(int code) const +{ + if (code < 0 || code > 2) + return Utils::SynchronousProcessResponse::FinishedError; + return Utils::SynchronousProcessResponse::Finished; +} + +// Collect all parameters required for a diff to be able to associate them +// with a diff editor and re-run the diff with parameters. +struct CvsDiffParameters +{ + QString workingDir; + QStringList extraOptions; + QStringList files; +}; + +// Parameter widget controlling whitespace diff mode, associated with a parameter +class CvsDiffParameterWidget : public VcsBase::VcsBaseEditorParameterWidget +{ + Q_OBJECT +public: + explicit CvsDiffParameterWidget(CvsClient *client, + const CvsDiffParameters &p, + QWidget *parent = 0); + QStringList arguments() const; + void executeCommand(); + +private: + + CvsClient *m_client; + const CvsDiffParameters m_params; +}; + +CvsDiffParameterWidget::CvsDiffParameterWidget(CvsClient *client, + const CvsDiffParameters &p, + QWidget *parent) + : VcsBase::VcsBaseEditorParameterWidget(parent), m_client(client), m_params(p) +{ + mapSetting(addToggleButton(QLatin1String("-w"), tr("Ignore Whitespace")), + client->settings()->boolPointer(CvsSettings::diffIgnoreWhiteSpaceKey)); + mapSetting(addToggleButton(QLatin1String("-B"), tr("Ignore Blank Lines")), + client->settings()->boolPointer(CvsSettings::diffIgnoreBlankLinesKey)); +} + +QStringList CvsDiffParameterWidget::arguments() const +{ + QStringList args; + args = m_client->settings()->stringValue(CvsSettings::diffOptionsKey).split(QLatin1Char(' '), QString::SkipEmptyParts); + args += VcsBaseEditorParameterWidget::arguments(); + return args; +} + +void CvsDiffParameterWidget::executeCommand() +{ + m_client->diff(m_params.workingDir, m_params.files, m_params.extraOptions); +} + +CvsClient::CvsClient(CvsSettings *settings) : + VcsBase::VcsBaseClient(settings) +{ +} + +CvsSettings *CvsClient::settings() const +{ + return dynamic_cast<CvsSettings *>(VcsBase::VcsBaseClient::settings()); +} + +Core::Id CvsClient::vcsEditorKind(VcsCommand cmd) const +{ + switch (cmd) { + case DiffCommand: + return "CVS Diff Editor"; // TODO: replace by string from cvsconstants.h + default: + return Core::Id(); + } +} + +Utils::ExitCodeInterpreter *CvsClient::exitCodeInterpreter(VcsCommand cmd, QObject *parent) const +{ + switch (cmd) { + case DiffCommand: + return new CvsDiffExitCodeInterpreter(parent); + default: + return 0; + } +} + +void CvsClient::diff(const QString &workingDir, const QStringList &files, + const QStringList &extraOptions) +{ + VcsBaseClient::diff(workingDir, files, extraOptions); +} + +QString CvsClient::findTopLevelForFile(const QFileInfo &file) const +{ + Q_UNUSED(file) + return QString(); +} + +QStringList CvsClient::revisionSpec(const QString &revision) const +{ + Q_UNUSED(revision) + return QStringList(); +} + +VcsBase::VcsBaseClient::StatusItem CvsClient::parseStatusLine(const QString &line) const +{ + Q_UNUSED(line) + return VcsBase::VcsBaseClient::StatusItem(); +} + +VcsBase::VcsBaseEditorParameterWidget *CvsClient::createDiffEditor( + const QString &workingDir, const QStringList &files, const QStringList &extraOptions) +{ + Q_UNUSED(extraOptions) + CvsDiffParameters p; + p.workingDir = workingDir; + p.files = files; + p.extraOptions = extraOptions; + return new CvsDiffParameterWidget(this, p); +} + +} // namespace Internal +} // namespace Cvs + +#include "cvsclient.moc" diff --git a/src/plugins/cvs/cvsclient.h b/src/plugins/cvs/cvsclient.h new file mode 100644 index 0000000000..62ad232bcf --- /dev/null +++ b/src/plugins/cvs/cvsclient.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef CVSCLIENT_H +#define CVSCLIENT_H + +#include "cvssettings.h" +#include <vcsbase/vcsbaseclient.h> + +namespace Cvs { +namespace Internal { + +class CvsSettings; + +class CvsClient : public VcsBase::VcsBaseClient +{ + Q_OBJECT + +public: + CvsClient(CvsSettings *settings); + + CvsSettings *settings() const; + void diff(const QString &workingDir, const QStringList &files, + const QStringList &extraOptions = QStringList()); + QString findTopLevelForFile(const QFileInfo &file) const; + QStringList revisionSpec(const QString &revision) const; + StatusItem parseStatusLine(const QString &line) const; + + +protected: + Utils::ExitCodeInterpreter *exitCodeInterpreter(VcsCommand cmd, QObject *parent) const; + Core::Id vcsEditorKind(VcsCommand cmd) const; + VcsBase::VcsBaseEditorParameterWidget *createDiffEditor(const QString &workingDir, + const QStringList &files, + const QStringList &extraOptions); +private: +}; + +} // namespace Internal +} // namespace Cvs + +#endif // CVSCLIENT_H diff --git a/src/plugins/cvs/cvscontrol.cpp b/src/plugins/cvs/cvscontrol.cpp index b22e93eafe..be7a1b1d7f 100644 --- a/src/plugins/cvs/cvscontrol.cpp +++ b/src/plugins/cvs/cvscontrol.cpp @@ -55,7 +55,7 @@ Core::Id CvsControl::id() const bool CvsControl::isConfigured() const { - const QString binary = m_plugin->settings().cvsBinaryPath; + const QString binary = m_plugin->settings().binaryPath(); if (binary.isEmpty()) return false; QFileInfo fi(binary); @@ -81,8 +81,9 @@ bool CvsControl::supportsOperation(Operation operation) const return rc; } -Core::IVersionControl::OpenSupportMode CvsControl::openSupportMode() const +Core::IVersionControl::OpenSupportMode CvsControl::openSupportMode(const QString &fileName) const { + Q_UNUSED(fileName); return OpenOptional; } diff --git a/src/plugins/cvs/cvscontrol.h b/src/plugins/cvs/cvscontrol.h index 7d1fac5607..65328dab3d 100644 --- a/src/plugins/cvs/cvscontrol.h +++ b/src/plugins/cvs/cvscontrol.h @@ -52,7 +52,7 @@ public: bool isConfigured() const; bool supportsOperation(Operation operation) const; - OpenSupportMode openSupportMode() const; + OpenSupportMode openSupportMode(const QString &fileName) const; bool vcsOpen(const QString &fileName); bool vcsAdd(const QString &fileName); bool vcsDelete(const QString &filename); diff --git a/src/plugins/cvs/cvsplugin.cpp b/src/plugins/cvs/cvsplugin.cpp index 9d4a8055f7..4643b4aa7e 100644 --- a/src/plugins/cvs/cvsplugin.cpp +++ b/src/plugins/cvs/cvsplugin.cpp @@ -31,6 +31,7 @@ #include "settingspage.h" #include "cvseditor.h" #include "cvssubmiteditor.h" +#include "cvsclient.h" #include "cvsconstants.h" #include "cvscontrol.h" #include "checkoutwizard.h" @@ -192,6 +193,7 @@ CvsPlugin::CvsPlugin() : CvsPlugin::~CvsPlugin() { + delete m_client; cleanCommitMessageFile(); } @@ -234,7 +236,8 @@ bool CvsPlugin::initialize(const QStringList &arguments, QString *errorMessage) if (!MimeDatabase::addMimeTypes(QLatin1String(":/trolltech.cvs/CVS.mimetypes.xml"), errorMessage)) return false; - m_settings.fromSettings(ICore::settings()); + m_settings.readSettings(ICore::settings()); + m_client = new CvsClient(&m_settings); addAutoReleasedObject(new SettingsPage); @@ -470,7 +473,8 @@ bool CvsPlugin::submitEditorAboutToClose() editor->promptSubmit(tr("Closing CVS Editor"), tr("Do you want to commit the change?"), tr("The commit message check failed. Do you want to commit the change?"), - &newSettings.promptToSubmit, !m_submitActionTriggered); + newSettings.boolPointer(CvsSettings::promptOnSubmitKey), + !m_submitActionTriggered); m_submitActionTriggered = false; switch (answer) { case VcsBaseSubmitEditor::SubmitCanceled: @@ -497,7 +501,7 @@ bool CvsPlugin::submitEditorAboutToClose() void CvsPlugin::diffCommitFiles(const QStringList &files) { - cvsDiff(m_commitRepository, files); + m_client->diff(m_commitRepository, files); } static void setDiffBaseDirectory(IEditor *editor, const QString &db) @@ -506,114 +510,6 @@ static void setDiffBaseDirectory(IEditor *editor, const QString &db) ve->setWorkingDirectory(db); } -// Collect all parameters required for a diff to be able to associate them -// with a diff editor and re-run the diff with parameters. -struct CvsDiffParameters -{ - QString workingDir; - QStringList arguments; - QStringList files; -}; - -// Parameter widget controlling whitespace diff mode, associated with a parameter -// struct. -class CvsDiffParameterWidget : public VcsBaseEditorParameterWidget -{ - Q_OBJECT - -public: - explicit CvsDiffParameterWidget(const CvsDiffParameters &p, QWidget *parent = 0); - -signals: - void reRunDiff(const Cvs::Internal::CvsDiffParameters &); - -public slots: - void triggerReRun(); - -private: - const CvsDiffParameters m_parameters; -}; - -CvsDiffParameterWidget::CvsDiffParameterWidget(const CvsDiffParameters &p, QWidget *parent) : - VcsBaseEditorParameterWidget(parent), m_parameters(p) -{ - setBaseArguments(p.arguments); - addToggleButton(QLatin1String("-w"), tr("Ignore Whitespace")); - addToggleButton(QLatin1String("-B"), tr("Ignore Blank Lines")); - connect(this, SIGNAL(argumentsChanged()), - this, SLOT(triggerReRun())); -} - -void CvsDiffParameterWidget::triggerReRun() -{ - CvsDiffParameters effectiveParameters = m_parameters; - effectiveParameters.arguments = arguments(); - emit reRunDiff(effectiveParameters); -} - -void CvsPlugin::cvsDiff(const QString &workingDir, const QStringList &files) -{ - CvsDiffParameters p; - p.workingDir = workingDir; - p.files = files; - p.arguments = m_settings.cvsDiffOptions.split(QLatin1Char(' '), QString::SkipEmptyParts); - cvsDiff(p); -} - -void CvsPlugin::cvsDiff(const Cvs::Internal::CvsDiffParameters &p) -{ - if (Constants::debug) - qDebug() << Q_FUNC_INFO << p.files; - const QString source = VcsBaseEditorWidget::getSource(p.workingDir, p.files); - QTextCodec *codec = VcsBaseEditorWidget::getCodec(p.workingDir, p.files); - const QString id = VcsBaseEditorWidget::getTitleId(p.workingDir, p.files); - - QStringList args(QLatin1String("diff")); - args.append(p.arguments); - args.append(p.files); - - // CVS returns the diff exit code (1 if files differ), which is - // undistinguishable from a "file not found" error, unfortunately. - const CvsResponse response = - runCvs(p.workingDir, args, m_settings.timeOutMS(), 0, codec); - switch (response.result) { - case CvsResponse::NonNullExitCode: - case CvsResponse::Ok: - break; - case CvsResponse::OtherError: - return; - } - - QString output = fixDiffOutput(response.stdOut); - if (output.isEmpty()) - output = tr("The files do not differ."); - // diff of a single file? re-use an existing view if possible to support - // the common usage pattern of continuously changing and diffing a file - // Show in the same editor if diff has been executed before - const QString tag = VcsBaseEditorWidget::editorTag(DiffOutput, p.workingDir, p.files); - if (IEditor *existingEditor = VcsBaseEditorWidget::locateEditorByTag(tag)) { - existingEditor->document()->setContents(output.toUtf8()); - EditorManager::activateEditor(existingEditor); - setDiffBaseDirectory(existingEditor, p.workingDir); - return; - } - const QString title = QString::fromLatin1("cvs diff %1").arg(id); - IEditor *editor = showOutputInEditor(title, output, DiffOutput, source, codec); - VcsBaseEditorWidget::tagEditor(editor, tag); - setDiffBaseDirectory(editor, p.workingDir); - CvsEditor *diffEditorWidget = qobject_cast<CvsEditor*>(editor->widget()); - QTC_ASSERT(diffEditorWidget, return); - - // Wire up the parameter widget to trigger a re-run on - // parameter change and 'revert' from inside the diff editor. - CvsDiffParameterWidget *pw = new CvsDiffParameterWidget(p); - connect(pw, SIGNAL(reRunDiff(Cvs::Internal::CvsDiffParameters)), - this, SLOT(cvsDiff(Cvs::Internal::CvsDiffParameters))); - connect(diffEditorWidget, SIGNAL(diffChunkReverted(VcsBase::DiffChunk)), - pw, SLOT(triggerReRun())); - diffEditorWidget->setConfigurationWidget(pw); -} - CvsSubmitEditor *CvsPlugin::openCVSSubmitEditor(const QString &fileName) { IEditor *editor = EditorManager::openEditor(fileName, Constants::CVSCOMMITEDITOR_ID); @@ -678,7 +574,7 @@ void CvsPlugin::revertAll() QStringList args; args << QLatin1String("update") << QLatin1String("-C") << state.topLevel(); const CvsResponse revertResponse = - runCvs(state.topLevel(), args, m_settings.timeOutMS(), + runCvs(state.topLevel(), args, m_settings.timeOutMs(), SshPasswordPrompt|ShowStdOutInLogWindow); if (revertResponse.result == CvsResponse::Ok) cvsVersionControl()->emitRepositoryChanged(state.topLevel()); @@ -693,7 +589,7 @@ void CvsPlugin::revertCurrentFile() QStringList args; args << QLatin1String("diff") << state.relativeCurrentFile(); const CvsResponse diffResponse = - runCvs(state.currentFileTopLevel(), args, m_settings.timeOutMS(), 0); + runCvs(state.currentFileTopLevel(), args, m_settings.timeOutMs(), 0); switch (diffResponse.result) { case CvsResponse::Ok: return; // Not modified, diff exit code 0 @@ -715,7 +611,7 @@ void CvsPlugin::revertCurrentFile() args.clear(); args << QLatin1String("update") << QLatin1String("-C") << state.relativeCurrentFile(); const CvsResponse revertResponse = - runCvs(state.currentFileTopLevel(), args, m_settings.timeOutMS(), + runCvs(state.currentFileTopLevel(), args, m_settings.timeOutMs(), SshPasswordPrompt|ShowStdOutInLogWindow); if (revertResponse.result == CvsResponse::Ok) cvsVersionControl()->emitFilesChanged(QStringList(state.currentFile())); @@ -726,7 +622,7 @@ void CvsPlugin::diffProject() const VcsBasePluginState state = currentState(); QTC_ASSERT(state.hasProject(), return); const QString relativeProject = state.relativeCurrentProject(); - cvsDiff(state.currentProjectTopLevel(), + m_client->diff(state.currentProjectTopLevel(), relativeProject.isEmpty() ? QStringList() : QStringList(relativeProject)); } @@ -734,7 +630,7 @@ void CvsPlugin::diffCurrentFile() { const VcsBasePluginState state = currentState(); QTC_ASSERT(state.hasFile(), return); - cvsDiff(state.currentFileTopLevel(), QStringList(state.relativeCurrentFile())); + m_client->diff(state.currentFileTopLevel(), QStringList(state.relativeCurrentFile())); } void CvsPlugin::startCommitCurrentFile() @@ -767,7 +663,7 @@ void CvsPlugin::startCommit(const QString &workingDir, const QString &file) // where we are, so, have stdout/stderr channels merged. QStringList args = QStringList(QLatin1String("status")); const CvsResponse response = - runCvs(workingDir, args, m_settings.timeOutMS(), MergeOutputChannels); + runCvs(workingDir, args, m_settings.timeOutMs(), MergeOutputChannels); if (response.result != CvsResponse::Ok) return; // Get list of added/modified/deleted files and purge out undesired ones @@ -815,7 +711,7 @@ bool CvsPlugin::commit(const QString &messageFile, args << QLatin1String("-F") << messageFile; args.append(fileList); const CvsResponse response = - runCvs(m_commitRepository, args, m_settings.longTimeOutMS(), + runCvs(m_commitRepository, args, 10 * m_settings.timeOutMs(), SshPasswordPrompt|ShowStdOutInLogWindow); return response.result == CvsResponse::Ok ; } @@ -853,7 +749,7 @@ void CvsPlugin::filelog(const QString &workingDir, args << QLatin1String("log"); args.append(file); const CvsResponse response = - runCvs(workingDir, args, m_settings.timeOutMS(), + runCvs(workingDir, args, m_settings.timeOutMs(), SshPasswordPrompt, codec); if (response.result != CvsResponse::Ok) return; @@ -887,7 +783,7 @@ bool CvsPlugin::update(const QString &topLevel, const QString &file) if (!file.isEmpty()) args.append(file); const CvsResponse response = - runCvs(topLevel, args, m_settings.longTimeOutMS(), + runCvs(topLevel, args, 10 * m_settings.timeOutMs(), SshPasswordPrompt|ShowStdOutInLogWindow); const bool ok = response.result == CvsResponse::Ok; if (ok) @@ -934,7 +830,7 @@ bool CvsPlugin::edit(const QString &topLevel, const QStringList &files) QStringList args(QLatin1String("edit")); args.append(files); const CvsResponse response = - runCvs(topLevel, args, m_settings.timeOutMS(), + runCvs(topLevel, args, m_settings.timeOutMs(), ShowStdOutInLogWindow|SshPasswordPrompt); return response.result == CvsResponse::Ok; } @@ -946,7 +842,7 @@ bool CvsPlugin::diffCheckModified(const QString &topLevel, const QStringList &fi QStringList args(QLatin1String("-q")); args << QLatin1String("diff"); args.append(files); - const CvsResponse response = runCvs(topLevel, args, m_settings.timeOutMS(), 0); + const CvsResponse response = runCvs(topLevel, args, m_settings.timeOutMs(), 0); if (response.result == CvsResponse::OtherError) return false; *modified = response.result == CvsResponse::NonNullExitCode; @@ -974,7 +870,7 @@ bool CvsPlugin::unedit(const QString &topLevel, const QStringList &files) args.append(QLatin1String("-y")); args.append(files); const CvsResponse response = - runCvs(topLevel, args, m_settings.timeOutMS(), + runCvs(topLevel, args, m_settings.timeOutMs(), ShowStdOutInLogWindow|SshPasswordPrompt); return response.result == CvsResponse::Ok; } @@ -993,7 +889,7 @@ void CvsPlugin::annotate(const QString &workingDir, const QString &file, args << QLatin1String("-r") << revision; args << file; const CvsResponse response = - runCvs(workingDir, args, m_settings.timeOutMS(), + runCvs(workingDir, args, m_settings.timeOutMs(), SshPasswordPrompt, codec); if (response.result != CvsResponse::Ok) return; @@ -1022,7 +918,7 @@ bool CvsPlugin::status(const QString &topLevel, const QString &file, const QStri if (!file.isEmpty()) args.append(file); const CvsResponse response = - runCvs(topLevel, args, m_settings.timeOutMS(), 0); + runCvs(topLevel, args, m_settings.timeOutMs(), 0); const bool ok = response.result == CvsResponse::Ok; if (ok) showOutputInEditor(title, response.stdOut, OtherContent, topLevel, 0); @@ -1047,7 +943,7 @@ void CvsPlugin::diffRepository() { const VcsBasePluginState state = currentState(); QTC_ASSERT(state.hasTopLevel(), return); - cvsDiff(state.topLevel(), QStringList()); + m_client->diff(state.topLevel(), QStringList()); } void CvsPlugin::statusRepository() @@ -1105,7 +1001,7 @@ bool CvsPlugin::describe(const QString &toplevel, const QString &file, const QStringList args; args << QLatin1String("log") << (QLatin1String("-r") + changeNr) << file; const CvsResponse logResponse = - runCvs(toplevel, args, m_settings.timeOutMS(), SshPasswordPrompt); + runCvs(toplevel, args, m_settings.timeOutMs(), SshPasswordPrompt); if (logResponse.result != CvsResponse::Ok) { *errorMessage = logResponse.message; return false; @@ -1115,7 +1011,7 @@ bool CvsPlugin::describe(const QString &toplevel, const QString &file, const *errorMessage = msgLogParsingFailed(); return false; } - if (m_settings.describeByCommitId) { + if (m_settings.boolValue(CvsSettings::describeByCommitIdKey)) { // Run a log command over the repo, filtering by the commit date // and commit id, collecting all files touched by the commit. const QString commitId = fileLog.front().revisions.front().commitId; @@ -1127,7 +1023,7 @@ bool CvsPlugin::describe(const QString &toplevel, const QString &file, const args << QLatin1String("log") << QLatin1String("-d") << (dateS + QLatin1Char('<') + nextDayS); const CvsResponse repoLogResponse = - runCvs(toplevel, args, m_settings.longTimeOutMS(), SshPasswordPrompt); + runCvs(toplevel, args, 10 * m_settings.timeOutMs(), SshPasswordPrompt); if (repoLogResponse.result != CvsResponse::Ok) { *errorMessage = repoLogResponse.message; return false; @@ -1164,7 +1060,7 @@ bool CvsPlugin::describe(const QString &repositoryPath, QStringList args(QLatin1String("log")); args << (QLatin1String("-r") + it->revisions.front().revision) << it->file; const CvsResponse logResponse = - runCvs(repositoryPath, args, m_settings.timeOutMS(), SshPasswordPrompt); + runCvs(repositoryPath, args, m_settings.timeOutMs(), SshPasswordPrompt); if (logResponse.result != CvsResponse::Ok) { *errorMessage = logResponse.message; return false; @@ -1177,11 +1073,11 @@ bool CvsPlugin::describe(const QString &repositoryPath, if (!isFirstRevision(revision)) { const QString previousRev = previousRevision(revision); QStringList args(QLatin1String("diff")); - args << m_settings.cvsDiffOptions << QLatin1String("-r") << previousRev + args << m_settings.stringValue(CvsSettings::diffOptionsKey) << QLatin1String("-r") << previousRev << QLatin1String("-r") << it->revisions.front().revision << it->file; const CvsResponse diffResponse = - runCvs(repositoryPath, args, m_settings.timeOutMS(), 0, codec); + runCvs(repositoryPath, args, m_settings.timeOutMs(), 0, codec); switch (diffResponse.result) { case CvsResponse::Ok: case CvsResponse::NonNullExitCode: // Diff exit code != 0 @@ -1228,7 +1124,7 @@ CvsResponse CvsPlugin::runCvs(const QString &workingDirectory, unsigned flags, QTextCodec *outputCodec) const { - const QString executable = m_settings.cvsBinaryPath; + const QString executable = m_settings.binaryPath(); CvsResponse response; if (executable.isEmpty()) { response.result = CvsResponse::OtherError; @@ -1300,7 +1196,7 @@ void CvsPlugin::setSettings(const CvsSettings &s) { if (s != m_settings) { m_settings = s; - m_settings.toSettings(ICore::settings()); + m_settings.writeSettings(ICore::settings()); cvsVersionControl()->emitConfigurationChanged(); } } @@ -1316,7 +1212,7 @@ bool CvsPlugin::vcsAdd(const QString &workingDir, const QString &rawFileName) QStringList args; args << QLatin1String("add") << rawFileName; const CvsResponse response = - runCvs(workingDir, args, m_settings.timeOutMS(), + runCvs(workingDir, args, m_settings.timeOutMs(), SshPasswordPrompt|ShowStdOutInLogWindow); return response.result == CvsResponse::Ok; } @@ -1326,7 +1222,7 @@ bool CvsPlugin::vcsDelete(const QString &workingDir, const QString &rawFileName) QStringList args; args << QLatin1String("remove") << QLatin1String("-f") << rawFileName; const CvsResponse response = - runCvs(workingDir, args, m_settings.timeOutMS(), + runCvs(workingDir, args, m_settings.timeOutMs(), SshPasswordPrompt|ShowStdOutInLogWindow); return response.result == CvsResponse::Ok; } @@ -1370,7 +1266,7 @@ bool CvsPlugin::managesFile(const QString &workingDirectory, const QString &file QStringList args; args << QLatin1String("status") << fileName; const CvsResponse response = - runCvs(workingDirectory, args, m_settings.timeOutMS(), SshPasswordPrompt); + runCvs(workingDirectory, args, m_settings.timeOutMs(), SshPasswordPrompt); if (response.result != CvsResponse::Ok) return false; return !response.stdOut.contains(QLatin1String("Status: Unknown")); @@ -1440,5 +1336,3 @@ void CvsPlugin::testLogResolving() } // namespace Cvs Q_EXPORT_PLUGIN(Cvs::Internal::CvsPlugin) - -#include "cvsplugin.moc" diff --git a/src/plugins/cvs/cvsplugin.h b/src/plugins/cvs/cvsplugin.h index 6d8f057b83..6d8eff2263 100644 --- a/src/plugins/cvs/cvsplugin.h +++ b/src/plugins/cvs/cvsplugin.h @@ -56,6 +56,7 @@ namespace Internal { struct CvsDiffParameters; class CvsSubmitEditor; class CvsControl; +class CvsClient; struct CvsResponse { @@ -79,8 +80,6 @@ public: bool initialize(const QStringList &arguments, QString *errorMessage); - void cvsDiff(const QString &workingDir, const QStringList &files); - CvsSubmitEditor *openCVSSubmitEditor(const QString &fileName); CvsSettings settings() const; @@ -124,7 +123,6 @@ private slots: void editCurrentFile(); void uneditCurrentFile(); void uneditCurrentRepository(); - void cvsDiff(const Cvs::Internal::CvsDiffParameters &p); #ifdef WITH_TESTS void testDiffFileResolving_data(); void testDiffFileResolving(); @@ -168,6 +166,8 @@ private: inline CvsControl *cvsVersionControl() const; CvsSettings m_settings; + CvsClient *m_client; + QString m_commitMessageFileName; QString m_commitRepository; diff --git a/src/plugins/cvs/cvssettings.cpp b/src/plugins/cvs/cvssettings.cpp index 113057fc8d..e3b2828e2e 100644 --- a/src/plugins/cvs/cvssettings.cpp +++ b/src/plugins/cvs/cvssettings.cpp @@ -35,71 +35,34 @@ #include <QSettings> #include <QTextStream> -static const char groupC[] = "CVS"; -static const char commandKeyC[] = "Command"; -static const char rootC[] = "Root"; -static const char promptToSubmitKeyC[] = "PromptForSubmit"; -static const char diffOptionsKeyC[] = "DiffOptions"; -static const char describeByCommitIdKeyC[] = "DescribeByCommitId"; -static const char defaultDiffOptions[] = "-du"; -static const char timeOutKeyC[] = "TimeOut"; - -enum { defaultTimeOutS = 30 }; - -static QString defaultCommand() -{ - return QLatin1String("cvs" QTC_HOST_EXE_SUFFIX); -} - namespace Cvs { namespace Internal { -CvsSettings::CvsSettings() : - cvsCommand(defaultCommand()), - cvsDiffOptions(QLatin1String(defaultDiffOptions)), - timeOutS(defaultTimeOutS), - promptToSubmit(true), - describeByCommitId(true) -{ -} +const QLatin1String CvsSettings::cvsRootKey("Root"); +const QLatin1String CvsSettings::diffOptionsKey("DiffOptions"); +const QLatin1String CvsSettings::describeByCommitIdKey("DescribeByCommitId"); +const QLatin1String CvsSettings::diffIgnoreWhiteSpaceKey("DiffIgnoreWhiteSpace"); +const QLatin1String CvsSettings::diffIgnoreBlankLinesKey("DiffIgnoreBlankLines"); -void CvsSettings::fromSettings(QSettings *settings) +CvsSettings::CvsSettings() { - settings->beginGroup(QLatin1String(groupC)); - cvsCommand = settings->value(QLatin1String(commandKeyC), defaultCommand()).toString(); - cvsBinaryPath = Utils::Environment::systemEnvironment().searchInPath(cvsCommand); - promptToSubmit = settings->value(QLatin1String(promptToSubmitKeyC), true).toBool(); - cvsRoot = settings->value(QLatin1String(rootC), QString()).toString(); - cvsDiffOptions = settings->value(QLatin1String(diffOptionsKeyC), QLatin1String(defaultDiffOptions)).toString(); - describeByCommitId = settings->value(QLatin1String(describeByCommitIdKeyC), true).toBool(); - timeOutS = settings->value(QLatin1String(timeOutKeyC), defaultTimeOutS).toInt(); - settings->endGroup(); + setSettingsGroup(QLatin1String("CVS")); + declareKey(binaryPathKey, QLatin1String("cvs" QTC_HOST_EXE_SUFFIX)); + declareKey(cvsRootKey, QLatin1String("")); + declareKey(diffOptionsKey, QLatin1String("-du")); + declareKey(describeByCommitIdKey, true); + declareKey(diffIgnoreWhiteSpaceKey, false); + declareKey(diffIgnoreBlankLinesKey, false); } -void CvsSettings::toSettings(QSettings *settings) const +int CvsSettings::timeOutMs() const { - settings->beginGroup(QLatin1String(groupC)); - settings->setValue(QLatin1String(commandKeyC), cvsCommand); - settings->setValue(QLatin1String(promptToSubmitKeyC), promptToSubmit); - settings->setValue(QLatin1String(rootC), cvsRoot); - settings->setValue(QLatin1String(diffOptionsKeyC), cvsDiffOptions); - settings->setValue(QLatin1String(timeOutKeyC), timeOutS); - settings->setValue(QLatin1String(describeByCommitIdKeyC), describeByCommitId); - settings->endGroup(); -} - -bool CvsSettings::equals(const CvsSettings &s) const -{ - return promptToSubmit == s.promptToSubmit - && describeByCommitId == s.describeByCommitId - && cvsCommand == s.cvsCommand - && cvsRoot == s.cvsRoot - && timeOutS == s.timeOutS - && cvsDiffOptions == s.cvsDiffOptions; + return 1000 * intValue(timeoutKey); } QStringList CvsSettings::addOptions(const QStringList &args) const { + const QString cvsRoot = stringValue(cvsRootKey); if (cvsRoot.isEmpty()) return args; @@ -110,5 +73,19 @@ QStringList CvsSettings::addOptions(const QStringList &args) const return rc; } +void CvsSettings::readLegacySettings(const QSettings *settings) +{ + const QString keyRoot = settingsGroup() + QLatin1Char('/'); + const QString oldBinaryPathKey = keyRoot + QLatin1String("Command"); + const QString oldPromptOnSubmitKey = keyRoot + QLatin1String("PromptForSubmit"); + const QString oldTimeoutKey = keyRoot + QLatin1String("TimeOut"); + if (settings->contains(oldBinaryPathKey)) + this->setValue(binaryPathKey, settings->value(oldBinaryPathKey).toString()); + if (settings->contains(oldPromptOnSubmitKey)) + this->setValue(promptOnSubmitKey, settings->value(oldPromptOnSubmitKey).toBool()); + if (settings->contains(oldTimeoutKey)) + this->setValue(timeoutKey, settings->value(oldTimeoutKey).toInt()); +} + } // namespace Internal } // namespace Cvs diff --git a/src/plugins/cvs/cvssettings.h b/src/plugins/cvs/cvssettings.h index 4eb01fafca..25ff1cfb6a 100644 --- a/src/plugins/cvs/cvssettings.h +++ b/src/plugins/cvs/cvssettings.h @@ -30,44 +30,30 @@ #ifndef CVSSETTINGS_H #define CVSSETTINGS_H -#include <QStringList> - -QT_BEGIN_NAMESPACE -class QSettings; -QT_END_NAMESPACE +#include <vcsbase/vcsbaseclientsettings.h> namespace Cvs { namespace Internal { -struct CvsSettings +class CvsSettings : public VcsBase::VcsBaseClientSettings { - CvsSettings(); +public: + static const QLatin1String cvsRootKey; + static const QLatin1String diffOptionsKey; + static const QLatin1String describeByCommitIdKey; + static const QLatin1String diffIgnoreWhiteSpaceKey; + static const QLatin1String diffIgnoreBlankLinesKey; - void fromSettings(QSettings *); - void toSettings(QSettings *) const; + CvsSettings(); - int timeOutMS() const { return timeOutS * 1000; } - int longTimeOutMS() const { return timeOutS * 10000; } + int timeOutMs() const; - // Add common options to the command line QStringList addOptions(const QStringList &args) const; - bool equals(const CvsSettings &s) const; - - QString cvsCommand; - QString cvsBinaryPath; - QString cvsRoot; - QString cvsDiffOptions; - int timeOutS; - bool promptToSubmit; - bool describeByCommitId; +protected: + void readLegacySettings(const QSettings *settings); }; -inline bool operator==(const CvsSettings &p1, const CvsSettings &p2) - { return p1.equals(p2); } -inline bool operator!=(const CvsSettings &p1, const CvsSettings &p2) - { return !p1.equals(p2); } - } // namespace Internal } // namespace Cvs diff --git a/src/plugins/cvs/settingspage.cpp b/src/plugins/cvs/settingspage.cpp index e5f051579e..2d2dcd755a 100644 --- a/src/plugins/cvs/settingspage.cpp +++ b/src/plugins/cvs/settingspage.cpp @@ -54,24 +54,23 @@ SettingsPageWidget::SettingsPageWidget(QWidget *parent) : CvsSettings SettingsPageWidget::settings() const { CvsSettings rc; - rc.cvsCommand = m_ui.commandPathChooser->rawPath(); - rc.cvsBinaryPath = m_ui.commandPathChooser->path(); - rc.cvsRoot = m_ui.rootLineEdit->text(); - rc.cvsDiffOptions = m_ui.diffOptionsLineEdit->text(); - rc.timeOutS = m_ui.timeOutSpinBox->value(); - rc.promptToSubmit = m_ui.promptToSubmitCheckBox->isChecked(); - rc.describeByCommitId = m_ui.describeByCommitIdCheckBox->isChecked(); + rc.setValue(CvsSettings::binaryPathKey, m_ui.commandPathChooser->rawPath()); + rc.setValue(CvsSettings::cvsRootKey, m_ui.rootLineEdit->text()); + rc.setValue(CvsSettings::diffOptionsKey, m_ui.diffOptionsLineEdit->text()); + rc.setValue(CvsSettings::timeoutKey, m_ui.timeOutSpinBox->value()); + rc.setValue(CvsSettings::promptOnSubmitKey, m_ui.promptToSubmitCheckBox->isChecked()); + rc.setValue(CvsSettings::describeByCommitIdKey, m_ui.describeByCommitIdCheckBox->isChecked()); return rc; } void SettingsPageWidget::setSettings(const CvsSettings &s) { - m_ui.commandPathChooser->setPath(s.cvsCommand); - m_ui.rootLineEdit->setText(s.cvsRoot); - m_ui.diffOptionsLineEdit->setText(s.cvsDiffOptions); - m_ui.timeOutSpinBox->setValue(s.timeOutS); - m_ui.promptToSubmitCheckBox->setChecked(s.promptToSubmit); - m_ui.describeByCommitIdCheckBox->setChecked(s.describeByCommitId); + m_ui.commandPathChooser->setPath(s.binaryPath()); + m_ui.rootLineEdit->setText(s.stringValue(CvsSettings::cvsRootKey)); + m_ui.diffOptionsLineEdit->setText(s.stringValue(CvsSettings::diffOptionsKey)); + m_ui.timeOutSpinBox->setValue(s.intValue(CvsSettings::timeoutKey)); + m_ui.promptToSubmitCheckBox->setChecked(s.boolValue(CvsSettings::promptOnSubmitKey)); + m_ui.describeByCommitIdCheckBox->setChecked(s.boolValue(CvsSettings::describeByCommitIdKey)); } QString SettingsPageWidget::searchKeywords() const diff --git a/src/plugins/cvs/settingspage.h b/src/plugins/cvs/settingspage.h index ecd9c1d52d..7e7e52a5cc 100644 --- a/src/plugins/cvs/settingspage.h +++ b/src/plugins/cvs/settingspage.h @@ -45,7 +45,7 @@ QT_END_NAMESPACE namespace Cvs { namespace Internal { -struct CvsSettings; +class CvsSettings; class SettingsPageWidget : public QWidget { diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index ab3828f477..31be135731 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -1045,7 +1045,7 @@ void DebuggerEnginePrivate::doFinishDebugger() void DebuggerEnginePrivate::setRemoteSetupState(RemoteSetupState state) { - bool allowedTransition = true; + bool allowedTransition = false; if (m_remoteSetupState == RemoteSetupNone) { if (state == RemoteSetupRequested) allowedTransition = true; diff --git a/src/plugins/fakevim/fakevim_test.cpp b/src/plugins/fakevim/fakevim_test.cpp index 6b9144da5d..06e732202b 100644 --- a/src/plugins/fakevim/fakevim_test.cpp +++ b/src/plugins/fakevim/fakevim_test.cpp @@ -1902,6 +1902,19 @@ void FakeVimPlugin::test_vim_letter_case() KEYS("2gUU", " " X "ABC" N "DEF"); KEYS("u", " " X "abc" N "def"); KEYS("<c-r>", " " X "ABC" N "DEF"); + + // undo, redo and dot command + data.setText(" abcde" N " fgh" N " ijk"); + KEYS("3l" "<C-V>2l2j" "U", " a" X "BCDe" N " fGH" N " iJK"); + KEYS("u", " a" X "bcde" N " fgh" N " ijk"); + KEYS("<C-R>", " a" X "BCDe" N " fGH" N " iJK"); + KEYS("u", " a" X "bcde" N " fgh" N " ijk"); + KEYS("h.", " " X "ABCde" N " FGH" N " IJK"); + KEYS("u", " " X "abcde" N " fgh" N " ijk"); + KEYS("h.", " " X " ABcde" N " FGh" N " IJk"); + KEYS("u", " " X " abcde" N " fgh" N " ijk"); + KEYS("j.", " abcde" N " " X " FGh" N " IJk"); + KEYS("u", " abcde" N " " X " fgh" N " ijk"); } void FakeVimPlugin::test_vim_code_autoindent() diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 9540e41933..388e60c7eb 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -4228,7 +4228,9 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input) g.submode = CapitalZSubMode; } else if ((input.is('~') || input.is('u') || input.is('U'))) { g.movetype = MoveExclusive; + pushUndoState(); if (isVisualMode()) { + setDotCommand(visualDotCommand() + QString::number(count()) + input.raw()); if (isVisualLineMode()) g.rangemode = RangeLineMode; else if (isVisualBlockMode()) @@ -4242,7 +4244,6 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input) g.submode = UpCaseSubMode; finishMovement(); } else if (g.gflag || (input.is('~') && hasConfig(ConfigTildeOp))) { - pushUndoState(); if (atEndOfLine()) moveLeft(); setAnchor(); diff --git a/src/plugins/genericprojectmanager/filesselectionwizardpage.cpp b/src/plugins/genericprojectmanager/filesselectionwizardpage.cpp index be2dba58b7..1efe079f6a 100644 --- a/src/plugins/genericprojectmanager/filesselectionwizardpage.cpp +++ b/src/plugins/genericprojectmanager/filesselectionwizardpage.cpp @@ -31,10 +31,10 @@ #include "genericprojectwizard.h" #include "genericprojectconstants.h" -#include "selectablefilesmodel.h" #include <coreplugin/mimedatabase.h> #include <coreplugin/icore.h> +#include <projectexplorer/selectablefilesmodel.h> #include <QVBoxLayout> #include <QLineEdit> @@ -117,12 +117,12 @@ void FilesSelectionWizardPage::initializePage() { m_view->setModel(0); delete m_model; - m_model = new SelectableFilesModel(m_genericProjectWizardDialog->path(), this); + m_model = new ProjectExplorer::SelectableFilesModel(this); connect(m_model, SIGNAL(parsingProgress(QString)), this, SLOT(parsingProgress(QString))); connect(m_model, SIGNAL(parsingFinished()), this, SLOT(parsingFinished())); - m_model->startParsing(); + m_model->startParsing(m_genericProjectWizardDialog->path()); m_hideFilesFilterLabel->setVisible(false); m_hideFilesfilterLineEdit->setVisible(false); @@ -139,7 +139,6 @@ void FilesSelectionWizardPage::initializePage() void FilesSelectionWizardPage::cleanupPage() { m_model->cancel(); - m_model->waitForFinished(); } void FilesSelectionWizardPage::parsingProgress(const QString &text) diff --git a/src/plugins/genericprojectmanager/filesselectionwizardpage.h b/src/plugins/genericprojectmanager/filesselectionwizardpage.h index 0d9c36348a..8085944830 100644 --- a/src/plugins/genericprojectmanager/filesselectionwizardpage.h +++ b/src/plugins/genericprojectmanager/filesselectionwizardpage.h @@ -39,11 +39,14 @@ class QTreeView; class QLineEdit; QT_END_NAMESPACE +namespace ProjectExplorer { + class SelectableFilesModel; +} + namespace GenericProjectManager { namespace Internal { class GenericProjectWizardDialog; -class SelectableFilesModel; class FilesSelectionWizardPage : public QWizardPage { @@ -68,7 +71,7 @@ private: void createApplyButton(QVBoxLayout *layout); GenericProjectWizardDialog *m_genericProjectWizardDialog; - SelectableFilesModel *m_model; + ProjectExplorer::SelectableFilesModel *m_model; QLabel *m_hideFilesFilterLabel; QLineEdit *m_hideFilesfilterLineEdit; diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp index ad39fa8f05..fc9f05e23e 100644 --- a/src/plugins/genericprojectmanager/genericproject.cpp +++ b/src/plugins/genericprojectmanager/genericproject.cpp @@ -69,6 +69,7 @@ GenericProject::GenericProject(Manager *manager, const QString &fileName) : m_manager(manager), m_fileName(fileName) { + setId(Constants::GENERICPROJECT_ID); setProjectContext(Context(GenericProjectManager::Constants::PROJECTCONTEXT)); setProjectLanguages(Context(ProjectExplorer::Constants::LANG_CXX)); @@ -357,11 +358,6 @@ QString GenericProject::displayName() const return m_projectName; } -Id GenericProject::id() const -{ - return Id(Constants::GENERICPROJECT_ID); -} - IDocument *GenericProject::document() const { return m_creatorIDocument; diff --git a/src/plugins/genericprojectmanager/genericproject.h b/src/plugins/genericprojectmanager/genericproject.h index 70d1f09608..91a2a53eff 100644 --- a/src/plugins/genericprojectmanager/genericproject.h +++ b/src/plugins/genericprojectmanager/genericproject.h @@ -60,7 +60,6 @@ public: QString configFileName() const; QString displayName() const; - Core::Id id() const; Core::IDocument *document() const; ProjectExplorer::IProjectManager *projectManager() const; @@ -82,9 +81,6 @@ public: void refresh(RefreshOptions options); - QStringList includePaths() const; - void setIncludePaths(const QStringList &includePaths); - QByteArray defines() const; QStringList projectIncludePaths() const; QStringList files() const; diff --git a/src/plugins/genericprojectmanager/genericprojectmanager.pro b/src/plugins/genericprojectmanager/genericprojectmanager.pro index 65528bcb6c..3ccecd9f86 100644 --- a/src/plugins/genericprojectmanager/genericprojectmanager.pro +++ b/src/plugins/genericprojectmanager/genericprojectmanager.pro @@ -10,7 +10,6 @@ HEADERS = genericproject.h \ pkgconfigtool.h \ genericmakestep.h \ genericbuildconfiguration.h \ - selectablefilesmodel.h \ filesselectionwizardpage.h SOURCES = genericproject.cpp \ genericprojectplugin.cpp \ @@ -21,7 +20,6 @@ SOURCES = genericproject.cpp \ pkgconfigtool.cpp \ genericmakestep.cpp \ genericbuildconfiguration.cpp \ - selectablefilesmodel.cpp \ filesselectionwizardpage.cpp RESOURCES += genericproject.qrc FORMS += genericmakestep.ui diff --git a/src/plugins/genericprojectmanager/genericprojectmanager.qbs b/src/plugins/genericprojectmanager/genericprojectmanager.qbs index 70386b06ca..707264924e 100644 --- a/src/plugins/genericprojectmanager/genericprojectmanager.qbs +++ b/src/plugins/genericprojectmanager/genericprojectmanager.qbs @@ -39,7 +39,5 @@ QtcPlugin { "genericprojectwizard.h", "pkgconfigtool.cpp", "pkgconfigtool.h", - "selectablefilesmodel.cpp", - "selectablefilesmodel.h", ] } diff --git a/src/plugins/genericprojectmanager/genericprojectnodes.cpp b/src/plugins/genericprojectmanager/genericprojectnodes.cpp index 7bd6773f53..19d20e704b 100644 --- a/src/plugins/genericprojectmanager/genericprojectnodes.cpp +++ b/src/plugins/genericprojectmanager/genericprojectnodes.cpp @@ -237,6 +237,7 @@ QList<ProjectNode::ProjectAction> GenericProjectNode::supportedActions(Node *nod return QList<ProjectAction>() << AddNewFile << AddExistingFile + << AddExistingDirectory << RemoveFile << Rename; } diff --git a/src/plugins/genericprojectmanager/genericprojectplugin.cpp b/src/plugins/genericprojectmanager/genericprojectplugin.cpp index 08695a063b..9f2093f94b 100644 --- a/src/plugins/genericprojectmanager/genericprojectplugin.cpp +++ b/src/plugins/genericprojectmanager/genericprojectplugin.cpp @@ -36,7 +36,6 @@ #include "genericprojectfileseditor.h" #include "genericmakestep.h" #include "genericproject.h" -#include "selectablefilesmodel.h" #include <coreplugin/icore.h> #include <coreplugin/mimedatabase.h> @@ -45,7 +44,7 @@ #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorer.h> - +#include <projectexplorer/selectablefilesmodel.h> #include <texteditor/texteditoractionhandler.h> @@ -115,7 +114,7 @@ void GenericProjectPlugin::updateContextMenu(ProjectExplorer::Project *project, void GenericProjectPlugin::editFiles() { GenericProject *genericProject = static_cast<GenericProject *>(m_contextMenuProject); - SelectableFilesDialog sfd(QFileInfo(genericProject->projectFilePath()).path(), genericProject->files(), + ProjectExplorer::SelectableFilesDialogEditFiles sfd(QFileInfo(genericProject->projectFilePath()).path(), genericProject->files(), Core::ICore::mainWindow()); if (sfd.exec() == QDialog::Accepted) genericProject->setFiles(sfd.selectedFiles()); diff --git a/src/plugins/git/gerrit/gerritpushdialog.cpp b/src/plugins/git/gerrit/gerritpushdialog.cpp index 26aa107d84..466048cfa5 100644 --- a/src/plugins/git/gerrit/gerritpushdialog.cpp +++ b/src/plugins/git/gerrit/gerritpushdialog.cpp @@ -33,6 +33,8 @@ #include "../gitplugin.h" #include "../gitclient.h" +#include <coreplugin/coreconstants.h> + #include <QDateTime> #include <QDir> #include <QRegExpValidator> @@ -40,6 +42,23 @@ namespace Gerrit { namespace Internal { +class PushItemDelegate : public Git::Internal::IconItemDelegate +{ +public: + PushItemDelegate(Git::Internal::LogChangeWidget *widget) + : IconItemDelegate(widget, QLatin1String(Core::Constants::ICON_PLUS)) + { + } + +protected: + bool hasIcon(int row) const + { + return row >= currentRow(); + } +}; + + + GerritPushDialog::GerritPushDialog(const QString &workingDir, const QString &reviewerList, QWidget *parent) : QDialog(parent), m_workingDir(workingDir), @@ -55,6 +74,8 @@ GerritPushDialog::GerritPushDialog(const QString &workingDir, const QString &rev if (!m_ui->commitView->init(workingDir, QString(), false)) return; + PushItemDelegate *delegate = new PushItemDelegate(m_ui->commitView); + delegate->setParent(this); QString earliestCommit = m_ui->commitView->earliestCommit(); if (earliestCommit.isEmpty()) return; diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index af2bc36bd1..1b3d521559 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -36,6 +36,8 @@ #include "gitsubmiteditor.h" #include "gitversioncontrol.h" #include "mergetool.h" +#include "branchadddialog.h" +#include "gerrit/gerritplugin.h" #include <vcsbase/submitfilemodel.h> @@ -980,11 +982,9 @@ QString GitClient::findGitDirForRepository(const QString &repositoryDir) const QString &res = repoDirCache[repositoryDir]; if (!res.isEmpty()) return res; - QByteArray outputText; - QStringList arguments; - arguments << QLatin1String("rev-parse") << QLatin1String("--git-dir"); - fullySynchronousGit(repositoryDir, arguments, &outputText, 0, false); - res = QString::fromLocal8Bit(outputText.trimmed()); + + synchronousRevParseCmd(repositoryDir, QLatin1String("--git-dir"), &res); + if (!QDir(res).isAbsolute()) res.prepend(repositoryDir + QLatin1Char('/')); return res; @@ -1546,12 +1546,10 @@ bool GitClient::synchronousCheckout(const QString &workingDirectory, { QByteArray outputText; QByteArray errorText; - QStringList arguments; - arguments << QLatin1String("checkout") << ref; + QStringList arguments = setupCheckoutArguments(workingDirectory, ref); const bool rc = fullySynchronousGit(workingDirectory, arguments, &outputText, &errorText, VcsBasePlugin::ExpectRepoChanges); - const QString output = commandOutputFromLocal8Bit(outputText); - outputWindow()->append(output); + outputWindow()->append(commandOutputFromLocal8Bit(outputText)); if (!rc) { msgCannotRun(arguments, workingDirectory, errorText, errorMessage); return false; @@ -1560,6 +1558,67 @@ bool GitClient::synchronousCheckout(const QString &workingDirectory, return true; } +/* method used to setup arguments for checkout, in case user wants to create local branch */ +QStringList GitClient::setupCheckoutArguments(const QString &workingDirectory, + const QString &ref) +{ + QStringList arguments(QLatin1String("checkout")); + arguments << ref; + + QStringList localBranches = synchronousRepositoryBranches(workingDirectory); + + if (localBranches.contains(ref)) + return arguments; + + if (QMessageBox::question(Core::ICore::mainWindow(), tr("Create Local Branch"), + tr("Would you like to create local branch?"), + QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) { + return arguments; + } + + if (synchronousCurrentLocalBranch(workingDirectory).isEmpty()) + localBranches.removeFirst(); + + QString refSha; + if (!synchronousRevParseCmd(workingDirectory, ref, &refSha)) + return arguments; + + QString output; + QStringList forEachRefArgs(QLatin1String("refs/remotes/")); + forEachRefArgs << QLatin1String("--format=%(objectname) %(refname:short)"); + if (!synchronousForEachRefCmd(workingDirectory, forEachRefArgs, &output)) + return arguments; + + QString remoteBranch; + const QString head(QLatin1String("/HEAD")); + + foreach (const QString &singleRef, output.split(QLatin1Char('\n'))) { + if (singleRef.startsWith(refSha)) { + // branch name might be origin/foo/HEAD + if (!singleRef.endsWith(head) || singleRef.count(QLatin1Char('/')) > 1) { + remoteBranch = singleRef.mid(refSha.length() + 1); + if (remoteBranch == ref) + break; + } + } + } + + BranchAddDialog branchAddDialog(localBranches, true, Core::ICore::mainWindow()); + branchAddDialog.setTrackedBranchName(remoteBranch, true); + + if (branchAddDialog.exec() != QDialog::Accepted) + return arguments; + + arguments.removeLast(); + arguments << QLatin1String("-b") << branchAddDialog.branchName(); + if (branchAddDialog.track()) + arguments << QLatin1String("--track") << remoteBranch; + else + arguments << QLatin1String("--no-track") << ref; + + return arguments; +} + void GitClient::reset(const QString &workingDirectory, const QString &argument, const QString &commit) { QStringList arguments; @@ -1946,25 +2005,28 @@ QString GitClient::synchronousTopic(const QString &workingDirectory) return data.topic = remoteBranch.isEmpty() ? tr("Detached HEAD") : remoteBranch; } +bool GitClient::synchronousRevParseCmd(const QString &workingDirectory, const QString &ref, + QString *output, QString *errorMessage) const +{ + QStringList arguments(QLatin1String("rev-parse")); + arguments << ref; + QByteArray outputText; + QByteArray errorText; + const bool rc = fullySynchronousGit(workingDirectory, arguments, &outputText, &errorText, + VcsBasePlugin::SuppressCommandLogging); + *output = commandOutputFromLocal8Bit(outputText.trimmed()); + if (!rc) + msgCannotRun(arguments, workingDirectory, errorText, errorMessage); + + return rc; +} + // Retrieve head revision QString GitClient::synchronousTopRevision(const QString &workingDirectory, QString *errorMessageIn) { - QByteArray outputTextData; - QByteArray errorText; - QStringList arguments; - QString errorMessage; - // get revision - arguments << QLatin1String("rev-parse") << QLatin1String(HEAD); - if (!fullySynchronousGit(workingDirectory, arguments, &outputTextData, &errorText, - VcsBasePlugin::SuppressCommandLogging)) { - errorMessage = tr("Cannot retrieve top revision of \"%1\": %2") - .arg(QDir::toNativeSeparators(workingDirectory), commandOutputFromLocal8Bit(errorText)); + QString revision; + if (!synchronousRevParseCmd(workingDirectory, QLatin1String(HEAD), &revision, errorMessageIn)) return QString(); - } - QString revision = commandOutputFromLocal8Bit(outputTextData); - revision.remove(QLatin1Char('\n')); - if (revision.isEmpty() && !errorMessage.isEmpty()) - msgCannotRun(errorMessage, errorMessageIn); return revision; } @@ -2458,12 +2520,13 @@ QProcessEnvironment GitClient::processEnvironment() const return environment; } -bool GitClient::beginStashScope(const QString &workingDirectory, const QString &command, StashFlag flag) +bool GitClient::beginStashScope(const QString &workingDirectory, const QString &command, + StashFlag flag, PushAction pushAction) { const QString repoDirectory = findRepositoryForDirectory(workingDirectory); QTC_ASSERT(!repoDirectory.isEmpty(), return false); StashInfo &stashInfo = m_stashInfo[repoDirectory]; - return stashInfo.init(repoDirectory, command, flag); + return stashInfo.init(repoDirectory, command, flag, pushAction); } GitClient::StashInfo &GitClient::stashInfo(const QString &workingDirectory) @@ -2957,6 +3020,11 @@ bool GitClient::getCommitData(const QString &workingDirectory, commitData.commitEncoding = readConfigValue(workingDirectory, QLatin1String("i18n.commitEncoding")); + // Set default commit encoding to 'UTF-8', when it's not set, + // to solve displaying error of commit log with non-latin characters. + if (commitData.commitEncoding.isEmpty()) + commitData.commitEncoding = QLatin1String("UTF-8"); + // Get the commit template or the last commit message switch (commitData.commitType) { case AmendCommit: { @@ -3722,15 +3790,17 @@ unsigned GitClient::synchronousGitVersion(QString *errorMessage) const } GitClient::StashInfo::StashInfo() : - m_client(GitPlugin::instance()->gitClient()) + m_client(GitPlugin::instance()->gitClient()), + m_pushAction(NoPush) { } bool GitClient::StashInfo::init(const QString &workingDirectory, const QString &command, - StashFlag flag) + StashFlag flag, PushAction pushAction) { m_workingDir = workingDirectory; m_flags = flag; + m_pushAction = pushAction; QString errorMessage; QString statusOutput; switch (m_client->gitStatus(m_workingDir, StatusMode(NoUntracked | NoSubmodules), @@ -3829,6 +3899,13 @@ void GitClient::StashInfo::end() if (m_client->stashNameFromMessage(m_workingDir, m_message, &stashName)) m_client->stashPop(m_workingDir, stashName); } + + if (m_pushAction == NormalPush) + m_client->push(m_workingDir); + else if (m_pushAction == PushToGerrit) + GitPlugin::instance()->gerritPlugin()->push(m_workingDir); + + m_pushAction = NoPush; m_stashResult = NotStashed; } } // namespace Internal diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index ff8cc55edc..de86aea73b 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -31,6 +31,7 @@ #define GITCLIENT_H #include "gitsettings.h" +#include "commitdata.h" #include <coreplugin/editormanager/ieditor.h> @@ -110,7 +111,8 @@ public: enum StashResult { StashUnchanged, StashCanceled, StashFailed, Stashed, NotStashed /* User did not want it */ }; - bool init(const QString &workingDirectory, const QString &command, StashFlag flag = Default); + bool init(const QString &workingDirectory, const QString &command, + StashFlag flag = Default, PushAction pushAction = NoPush); bool stashingFailed() const; void end(); StashResult result() const { return m_stashResult; } @@ -125,6 +127,7 @@ public: QString m_workingDir; GitClient *m_client; StashFlag m_flags; + PushAction m_pushAction; }; static const char *stashNamePrefix; @@ -177,9 +180,10 @@ public: QString revision = QString(), QString *errorMessage = 0, bool revertStaging = true); // Checkout branch - bool synchronousCheckout(const QString &workingDirectory, const QString &ref, QString *errorMessage); - bool synchronousCheckout(const QString &workingDirectory, const QString &ref) - { return synchronousCheckout(workingDirectory, ref, 0); } + bool synchronousCheckout(const QString &workingDirectory, const QString &ref, + QString *errorMessage = 0); + + QStringList setupCheckoutArguments(const QString &workingDirectory, const QString &ref); void updateSubmodulesIfNeeded(const QString &workingDirectory, bool prompt); // Do a stash and return identier. @@ -232,6 +236,8 @@ public: bool synchronousHeadRefs(const QString &workingDirectory, QStringList *output, QString *errorMessage = 0); QString synchronousTopic(const QString &workingDirectory); + bool synchronousRevParseCmd(const QString &workingDirectory, const QString &ref, + QString *output, QString *errorMessage = 0) const; QString synchronousTopRevision(const QString &workingDirectory, QString *errorMessage = 0); void synchronousTagsForCommit(const QString &workingDirectory, const QString &revision, QString &precedes, QString &follows); @@ -315,7 +321,8 @@ public: QProcessEnvironment processEnvironment() const; - bool beginStashScope(const QString &workingDirectory, const QString &command, StashFlag flag = Default); + bool beginStashScope(const QString &workingDirectory, const QString &command, + StashFlag flag = Default, PushAction pushAction = NoPush); StashInfo &stashInfo(const QString &workingDirectory); void endStashScope(const QString &workingDirectory); bool isValidRevision(const QString &revision) const; diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index 45bf783147..f055c3f4b3 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -60,6 +60,7 @@ #include <coreplugin/editormanager/ieditor.h> #include <coreplugin/mimedatabase.h> #include <coreplugin/vcsmanager.h> +#include <coreplugin/coreconstants.h> #include <utils/qtcassert.h> #include <utils/parameteraction.h> @@ -802,6 +803,34 @@ void GitPlugin::undoUnstagedFileChanges() undoFileChanges(false); } +class ResetItemDelegate : public LogItemDelegate +{ +public: + ResetItemDelegate(LogChangeWidget *widget) : LogItemDelegate(widget) {} + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const + { + QStyleOptionViewItem o = option; + if (index.row() < currentRow()) + o.font.setStrikeOut(true); + QStyledItemDelegate::paint(painter, o, index); + } +}; + +class RebaseItemDelegate : public IconItemDelegate +{ +public: + RebaseItemDelegate(LogChangeWidget *widget) + : IconItemDelegate(widget, QLatin1String(Core::Constants::ICON_UNDO)) + { + } + +protected: + bool hasIcon(int row) const + { + return row <= currentRow(); + } +}; + void GitPlugin::resetRepository() { if (!ensureAllDocumentsSaved()) @@ -811,6 +840,7 @@ void GitPlugin::resetRepository() QString topLevel = state.topLevel(); LogChangeDialog dialog(true, Core::ICore::mainWindow()); + ResetItemDelegate delegate(dialog.widget()); dialog.setWindowTitle(tr("Undo Changes to %1").arg(QDir::toNativeSeparators(topLevel))); if (dialog.runDialog(topLevel)) m_gitClient->reset(topLevel, dialog.resetFlag(), dialog.commit()); @@ -828,6 +858,7 @@ void GitPlugin::startRebase() if (!m_gitClient->beginStashScope(topLevel, QLatin1String("Rebase-i"))) return; LogChangeDialog dialog(false, Core::ICore::mainWindow()); + RebaseItemDelegate delegate(dialog.widget()); dialog.setWindowTitle(tr("Interactive Rebase")); if (dialog.runDialog(topLevel, QString(), false)) m_gitClient->interactiveRebase(topLevel, dialog.commit(), false); @@ -863,24 +894,22 @@ void GitPlugin::startChangeRelatedAction() if (!ensureAllDocumentsSaved()) return; - bool (GitClient::*commandFunction)(const QString&, const QString&); + switch (dialog.command()) { case CherryPick: - commandFunction = &GitClient::synchronousCherryPick; + m_gitClient->synchronousCherryPick(workingDirectory, change); break; case Revert: - commandFunction = &GitClient::synchronousRevert; + m_gitClient->synchronousRevert(workingDirectory, change); break; case Checkout: if (!m_gitClient->beginStashScope(workingDirectory, QLatin1String("Checkout"))) return; - commandFunction = &GitClient::synchronousCheckout; + m_gitClient->synchronousCheckout(workingDirectory, change); break; default: return; } - - (m_gitClient->*commandFunction)(workingDirectory, change); } void GitPlugin::stageFile() @@ -1103,8 +1132,10 @@ bool GitPlugin::submitEditorAboutToClose() return false; cleanCommitMessageFile(); if (commitType == FixupCommit) { - if (!m_gitClient->beginStashScope(m_submitRepository, QLatin1String("Rebase-fixup"), NoPrompt)) + if (!m_gitClient->beginStashScope(m_submitRepository, QLatin1String("Rebase-fixup"), + NoPrompt, editor->panelData().pushAction)) { return false; + } m_gitClient->interactiveRebase(m_submitRepository, amendSHA1, true); } else { m_gitClient->continueCommandIfNeeded(m_submitRepository); @@ -1477,6 +1508,11 @@ GitClient *GitPlugin::gitClient() const return m_gitClient; } +Gerrit::Internal::GerritPlugin *GitPlugin::gerritPlugin() const +{ + return m_gerritPlugin; +} + #ifdef WITH_TESTS #include <QTest> diff --git a/src/plugins/git/gitplugin.h b/src/plugins/git/gitplugin.h index f451834f30..f72de8c4a3 100644 --- a/src/plugins/git/gitplugin.h +++ b/src/plugins/git/gitplugin.h @@ -99,6 +99,7 @@ public: void setSettings(const GitSettings &s); GitClient *gitClient() const; + Gerrit::Internal::GerritPlugin *gerritPlugin() const; public slots: void startCommit(); diff --git a/src/plugins/git/gitsubmiteditorwidget.cpp b/src/plugins/git/gitsubmiteditorwidget.cpp index 50cffe06b7..03c4fcffee 100644 --- a/src/plugins/git/gitsubmiteditorwidget.cpp +++ b/src/plugins/git/gitsubmiteditorwidget.cpp @@ -109,7 +109,7 @@ void GitSubmitEditorWidget::initialize(CommitType commitType, setPanelData(data); setPanelInfo(info); - if (enablePush && commitType != FixupCommit) { + if (enablePush) { QMenu *menu = new QMenu(this); menu->addAction(tr("&Commit only"), this, SLOT(commitOnlySlot())); menu->addAction(tr("Commit and &Push"), this, SLOT(commitAndPushSlot())); diff --git a/src/plugins/git/logchangedialog.cpp b/src/plugins/git/logchangedialog.cpp index e09e5267f7..6a316765b1 100644 --- a/src/plugins/git/logchangedialog.cpp +++ b/src/plugins/git/logchangedialog.cpp @@ -33,6 +33,8 @@ #include <vcsbase/vcsbaseoutputwindow.h> +#include <utils/qtcassert.h> + #include <QTreeView> #include <QLabel> #include <QPushButton> @@ -41,6 +43,7 @@ #include <QItemSelectionModel> #include <QVBoxLayout> #include <QComboBox> +#include <QPainter> namespace Git { namespace Internal { @@ -55,6 +58,7 @@ enum Columns LogChangeWidget::LogChangeWidget(QWidget *parent) : QTreeView(parent) , m_model(new QStandardItemModel(0, ColumnCount, this)) + , m_hasCustomDelegate(false) { QStringList headers; headers << tr("Sha1")<< tr("Subject"); @@ -104,6 +108,12 @@ QString LogChangeWidget::earliestCommit() const return QString(); } +void LogChangeWidget::setItemDelegate(QAbstractItemDelegate *delegate) +{ + QTreeView::setItemDelegate(delegate); + m_hasCustomDelegate = true; +} + void LogChangeWidget::emitDoubleClicked(const QModelIndex &index) { if (index.isValid()) { @@ -113,6 +123,25 @@ void LogChangeWidget::emitDoubleClicked(const QModelIndex &index) } } +void LogChangeWidget::selectionChanged(const QItemSelection &selected, + const QItemSelection &deselected) +{ + QTreeView::selectionChanged(selected, deselected); + if (!m_hasCustomDelegate) + return; + const QModelIndexList previousIndexes = deselected.indexes(); + QTC_ASSERT(!previousIndexes.isEmpty(), return); + const QModelIndex current = currentIndex(); + int row = current.row(); + int previousRow = previousIndexes.first().row(); + if (row < previousRow) + qSwap(row, previousRow); + for (int r = previousRow; r <= row; ++r) { + update(current.sibling(r, 0)); + update(current.sibling(r, 1)); + } +} + bool LogChangeWidget::populateLog(const QString &repository, const QString &commit, bool includeRemote) { const QString currentCommit = this->commit(); @@ -234,5 +263,40 @@ QString LogChangeDialog::resetFlag() const return m_resetTypeComboBox->itemData(m_resetTypeComboBox->currentIndex()).toString(); } +LogChangeWidget *LogChangeDialog::widget() const +{ + return m_widget; +} + +LogItemDelegate::LogItemDelegate(LogChangeWidget *widget) : m_widget(widget) +{ + m_widget->setItemDelegate(this); +} + +int LogItemDelegate::currentRow() const +{ + return m_widget->commitIndex(); +} + +IconItemDelegate::IconItemDelegate(LogChangeWidget *widget, const QString &icon) + : LogItemDelegate(widget) + , m_icon(icon) +{ +} + +void IconItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QStyleOptionViewItem o = option; + if (index.column() == 0 && hasIcon(index.row())) { + const QSize size = option.decorationSize; + painter->save(); + painter->drawPixmap(o.rect.x(), o.rect.y(), m_icon.pixmap(size.width(), size.height())); + painter->restore(); + o.rect.translate(size.width(), 0); + } + QStyledItemDelegate::paint(painter, o, index); +} + } // namespace Internal } // namespace Git diff --git a/src/plugins/git/logchangedialog.h b/src/plugins/git/logchangedialog.h index 22f6641b73..f95604d84c 100644 --- a/src/plugins/git/logchangedialog.h +++ b/src/plugins/git/logchangedialog.h @@ -31,6 +31,8 @@ #define LOGCHANGEDDIALOG_H #include <QDialog> +#include <QIcon> +#include <QStyledItemDelegate> #include <QTreeView> QT_BEGIN_NAMESPACE @@ -57,6 +59,7 @@ public: QString commit() const; int commitIndex() const; QString earliestCommit() const; + void setItemDelegate(QAbstractItemDelegate *delegate); signals: void doubleClicked(const QString &commit); @@ -65,10 +68,12 @@ private slots: void emitDoubleClicked(const QModelIndex &index); private: + void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); bool populateLog(const QString &repository, const QString &commit, bool includeRemote); const QStandardItem *currentItem(int column = 0) const; QStandardItemModel *m_model; + bool m_hasCustomDelegate; }; class LogChangeDialog : public QDialog @@ -83,6 +88,7 @@ public: QString commit() const; int commitIndex() const; QString resetFlag() const; + LogChangeWidget *widget() const; private: LogChangeWidget *m_widget; @@ -90,6 +96,33 @@ private: QComboBox *m_resetTypeComboBox; }; +class LogItemDelegate : public QStyledItemDelegate +{ +protected: + LogItemDelegate(LogChangeWidget *widget); + + int currentRow() const; + virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const = 0; + +private: + LogChangeWidget *m_widget; +}; + +class IconItemDelegate : public LogItemDelegate +{ +public: + IconItemDelegate(LogChangeWidget *widget, const QString &icon); + + virtual bool hasIcon(int row) const = 0; + + void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const; + +private: + QIcon m_icon; +}; + } // namespace Internal } // namespace Git diff --git a/src/plugins/perforce/perforceversioncontrol.cpp b/src/plugins/perforce/perforceversioncontrol.cpp index e406d84b60..58f87b8032 100644 --- a/src/plugins/perforce/perforceversioncontrol.cpp +++ b/src/plugins/perforce/perforceversioncontrol.cpp @@ -82,8 +82,9 @@ bool PerforceVersionControl::supportsOperation(Operation operation) const return false; } -Core::IVersionControl::OpenSupportMode PerforceVersionControl::openSupportMode() const +Core::IVersionControl::OpenSupportMode PerforceVersionControl::openSupportMode(const QString &fileName) const { + Q_UNUSED(fileName); return OpenOptional; } diff --git a/src/plugins/perforce/perforceversioncontrol.h b/src/plugins/perforce/perforceversioncontrol.h index 38aed32304..96f74542f5 100644 --- a/src/plugins/perforce/perforceversioncontrol.h +++ b/src/plugins/perforce/perforceversioncontrol.h @@ -51,7 +51,7 @@ public: bool isConfigured() const; bool supportsOperation(Operation operation) const; - OpenSupportMode openSupportMode() const; + OpenSupportMode openSupportMode(const QString &fileName) const; bool vcsOpen(const QString &fileName); SettingsFlags settingsFlags() const; bool vcsAdd(const QString &fileName); diff --git a/src/plugins/projectexplorer/clangparser.h b/src/plugins/projectexplorer/clangparser.h index 3734ef8978..23ff723f51 100644 --- a/src/plugins/projectexplorer/clangparser.h +++ b/src/plugins/projectexplorer/clangparser.h @@ -37,7 +37,7 @@ namespace ProjectExplorer { -class ClangParser : public ProjectExplorer::GccParser +class PROJECTEXPLORER_EXPORT ClangParser : public ProjectExplorer::GccParser { Q_OBJECT diff --git a/src/plugins/projectexplorer/gccparser.h b/src/plugins/projectexplorer/gccparser.h index 015b53f053..bd9609c386 100644 --- a/src/plugins/projectexplorer/gccparser.h +++ b/src/plugins/projectexplorer/gccparser.h @@ -38,7 +38,7 @@ namespace ProjectExplorer { -class GccParser : public ProjectExplorer::IOutputParser +class PROJECTEXPLORER_EXPORT GccParser : public ProjectExplorer::IOutputParser { Q_OBJECT diff --git a/src/plugins/projectexplorer/msvcparser.h b/src/plugins/projectexplorer/msvcparser.h index e67547d53c..a54c554c2a 100644 --- a/src/plugins/projectexplorer/msvcparser.h +++ b/src/plugins/projectexplorer/msvcparser.h @@ -38,7 +38,7 @@ namespace ProjectExplorer { -class MsvcParser : public ProjectExplorer::IOutputParser +class PROJECTEXPLORER_EXPORT MsvcParser : public ProjectExplorer::IOutputParser { Q_OBJECT diff --git a/src/plugins/projectexplorer/osparser.h b/src/plugins/projectexplorer/osparser.h index ccc4364ca0..1ccbea39d8 100644 --- a/src/plugins/projectexplorer/osparser.h +++ b/src/plugins/projectexplorer/osparser.h @@ -38,7 +38,7 @@ namespace ProjectExplorer { -class OsParser : public ProjectExplorer::IOutputParser +class PROJECTEXPLORER_EXPORT OsParser : public ProjectExplorer::IOutputParser { Q_OBJECT diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index 070e967fbe..d43a9c20c0 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -84,6 +84,7 @@ public: ProjectPrivate(); ~ProjectPrivate(); + Core::Id m_id; QList<Target *> m_targets; Target *m_activeTarget; EditorConfiguration *m_editorConfiguration; @@ -112,6 +113,12 @@ Project::~Project() delete d; } +Core::Id Project::id() const +{ + QTC_CHECK(d->m_id.isValid()); + return d->m_id; +} + QString Project::projectFilePath() const { return document()->filePath(); @@ -262,6 +269,11 @@ bool Project::setupTarget(Target *t) return true; } +void Project::setId(Core::Id id) +{ + d->m_id = id; +} + Target *Project::restoreTarget(const QVariantMap &data) { Core::Id id = idFromMap(data); diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h index 962512c7b1..8a0560af5c 100644 --- a/src/plugins/projectexplorer/project.h +++ b/src/plugins/projectexplorer/project.h @@ -73,7 +73,7 @@ public: virtual ~Project(); virtual QString displayName() const = 0; - virtual Core::Id id() const = 0; + Core::Id id() const; virtual Core::IDocument *document() const = 0; virtual IProjectManager *projectManager() const = 0; @@ -161,6 +161,7 @@ protected: virtual bool fromMap(const QVariantMap &map); virtual bool setupTarget(Target *t); + void setId(Core::Id id); void setProjectContext(Core::Context context); void setProjectLanguages(Core::Context language); void addProjectLanguage(Core::Id id); diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 413f49d12b..8200a58b30 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -76,6 +76,7 @@ #include "miniprojecttargetselector.h" #include "taskhub.h" #include "customtoolchain.h" +#include "selectablefilesmodel.h" #include <projectexplorer/customwizard/customwizard.h> #include "devicesupport/desktopdevice.h" #include "devicesupport/desktopdevicefactory.h" @@ -199,6 +200,7 @@ struct ProjectExplorerPluginPrivate { QAction *m_cancelBuildAction; QAction *m_addNewFileAction; QAction *m_addExistingFilesAction; + QAction *m_addExistingDirectoryAction; QAction *m_addNewSubprojectAction; QAction *m_removeFileAction; QAction *m_removeProjectAction; @@ -539,7 +541,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er d->m_openWithMenu->setTitle(tr("Open With")); connect(d->m_openWithMenu, SIGNAL(triggered(QAction*)), - DocumentManager::instance(), SLOT(slotExecuteOpenWithMenuAction(QAction*))); + DocumentManager::instance(), SLOT(executeOpenWithMenuAction(QAction*))); // // Separators @@ -796,6 +798,15 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES); mfolderContextMenu->addAction(cmd, Constants::G_FOLDER_FILES); + // add existing directory action + d->m_addExistingDirectoryAction = new QAction(tr("Add Existing Directory..."), this); + cmd = Core::ActionManager::registerAction(d->m_addExistingDirectoryAction, + ProjectExplorer::Constants::ADDEXISTINGDIRECTORY, + projecTreeContext); + mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES); + msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES); + mfolderContextMenu->addAction(cmd, Constants::G_FOLDER_FILES); + // new subproject action d->m_addNewSubprojectAction = new QAction(tr("New Subproject..."), this); cmd = ActionManager::registerAction(d->m_addNewSubprojectAction, ProjectExplorer::Constants::ADDNEWSUBPROJECT, @@ -963,6 +974,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er connect(d->m_closeAllProjects, SIGNAL(triggered()), this, SLOT(closeAllProjects())); connect(d->m_addNewFileAction, SIGNAL(triggered()), this, SLOT(addNewFile())); connect(d->m_addExistingFilesAction, SIGNAL(triggered()), this, SLOT(addExistingFiles())); + connect(d->m_addExistingDirectoryAction, SIGNAL(triggered()), this, SLOT(addExistingDirectory())); connect(d->m_addNewSubprojectAction, SIGNAL(triggered()), this, SLOT(addNewSubproject())); connect(d->m_removeProjectAction, SIGNAL(triggered()), this, SLOT(removeProject())); connect(d->m_openFileAction, SIGNAL(triggered()), this, SLOT(openFile())); @@ -1373,8 +1385,10 @@ QList<Project *> ProjectExplorerPlugin::openProjects(const QStringList &fileName } if (const MimeType mt = MimeDatabase::findByFile(QFileInfo(fileName))) { + bool foundProjectManager = false; foreach (IProjectManager *manager, projectManagers) { if (manager->mimeType() == mt.type()) { + foundProjectManager = true; QString tmp; if (Project *pro = manager->openProject(filePath, &tmp)) { if (pro->restoreSettings()) { @@ -1385,6 +1399,8 @@ QList<Project *> ProjectExplorerPlugin::openProjects(const QStringList &fileName setCurrentNode(pro->rootProjectNode()); openedPro += pro; } else { + appendError(errorString, tr("Failed opening project '%1': Settings could not be restored") + .arg(QDir::toNativeSeparators(fileName))); delete pro; } } @@ -1393,6 +1409,14 @@ QList<Project *> ProjectExplorerPlugin::openProjects(const QStringList &fileName break; } } + if (!foundProjectManager) { + appendError(errorString, tr("Failed opening project '%1': No plugin can open project type '%2'.") + .arg(QDir::toNativeSeparators(fileName)) + .arg((mt.type()))); + } + } else { + appendError(errorString, tr("Failed opening project '%1': Unknown project type.") + .arg(QDir::toNativeSeparators(fileName))); } SessionManager::reportProjectLoadingProgress(); } @@ -2632,6 +2656,7 @@ void ProjectExplorerPlugin::invalidateProject(Project *project) void ProjectExplorerPlugin::updateContextMenuActions() { d->m_addExistingFilesAction->setEnabled(false); + d->m_addExistingDirectoryAction->setEnabled(false); d->m_addNewFileAction->setEnabled(false); d->m_addNewSubprojectAction->setEnabled(false); d->m_removeFileAction->setEnabled(false); @@ -2639,6 +2664,7 @@ void ProjectExplorerPlugin::updateContextMenuActions() d->m_renameFileAction->setEnabled(false); d->m_addExistingFilesAction->setVisible(true); + d->m_addExistingDirectoryAction->setVisible(true); d->m_removeFileAction->setVisible(true); d->m_deleteFileAction->setVisible(true); d->m_runActionContextMenu->setVisible(false); @@ -2676,6 +2702,7 @@ void ProjectExplorerPlugin::updateContextMenuActions() d->m_addNewSubprojectAction->setEnabled(d->m_currentNode->nodeType() == ProjectNodeType && actions.contains(ProjectNode::AddSubProject)); d->m_addExistingFilesAction->setEnabled(actions.contains(ProjectNode::AddExistingFile)); + d->m_addExistingDirectoryAction->setEnabled(actions.contains(ProjectNode::AddExistingDirectory)); d->m_renameFileAction->setEnabled(actions.contains(ProjectNode::Rename)); } else if (qobject_cast<FileNode*>(d->m_currentNode)) { // Enable and show remove / delete in magic ways: @@ -2785,6 +2812,17 @@ void ProjectExplorerPlugin::addExistingFiles() addExistingFiles(fileNames); } +void ProjectExplorerPlugin::addExistingDirectory() +{ + QTC_ASSERT(d->m_currentNode, return); + + const QString path = QFileInfo(d->m_currentNode->path()).absolutePath(); + SelectableFilesDialogAddDirectory dialog(path, QStringList(), Core::ICore::mainWindow()); + + if (dialog.exec() == QDialog::Accepted) + addExistingFiles(dialog.selectedFiles()); +} + void ProjectExplorerPlugin::addExistingFiles(const QStringList &filePaths) { ProjectNode *projectNode = qobject_cast<ProjectNode*>(d->m_currentNode->projectNode()); diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h index 2c24bda6a2..fbb4d5fba7 100644 --- a/src/plugins/projectexplorer/projectexplorer.h +++ b/src/plugins/projectexplorer/projectexplorer.h @@ -186,6 +186,7 @@ private slots: void addNewFile(); void addExistingFiles(); + void addExistingDirectory(); void addNewSubproject(); void removeProject(); void openFile(); diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro index 16eee949d3..03daf8b229 100644 --- a/src/plugins/projectexplorer/projectexplorer.pro +++ b/src/plugins/projectexplorer/projectexplorer.pro @@ -141,7 +141,8 @@ HEADERS += projectexplorer.h \ projectmacroexpander.h \ customparser.h \ customparserconfigdialog.h \ - ipotentialkit.h + ipotentialkit.h \ + selectablefilesmodel.h SOURCES += projectexplorer.cpp \ abi.cpp \ @@ -269,7 +270,8 @@ SOURCES += projectexplorer.cpp \ projectmacroexpander.cpp \ customparser.cpp \ customparserconfigdialog.cpp \ - ipotentialkit.cpp + ipotentialkit.cpp \ + selectablefilesmodel.cpp FORMS += processstep.ui \ editorsettingspropertiespage.ui \ diff --git a/src/plugins/projectexplorer/projectexplorer.qbs b/src/plugins/projectexplorer/projectexplorer.qbs index 357a4c5351..1a10feb66d 100644 --- a/src/plugins/projectexplorer/projectexplorer.qbs +++ b/src/plugins/projectexplorer/projectexplorer.qbs @@ -121,6 +121,7 @@ QtcPlugin { "runconfiguration.cpp", "runconfiguration.h", "runconfigurationmodel.cpp", "runconfigurationmodel.h", "runsettingspropertiespage.cpp", "runsettingspropertiespage.h", + "selectablefilesmodel.cpp", "selectablefilesmodel.h", "session.cpp", "session.h", "sessiondialog.cpp", "sessiondialog.h", "sessiondialog.ui", "settingsaccessor.cpp", "settingsaccessor.h", @@ -141,7 +142,7 @@ QtcPlugin { "toolchainmanager.cpp", "toolchainmanager.h", "toolchainoptionspage.cpp", "toolchainoptionspage.h", "unconfiguredprojectpanel.cpp", "unconfiguredprojectpanel.h", - "vcsannotatetaskhandler.cpp", "vcsannotatetaskhandler.h", + "vcsannotatetaskhandler.cpp", "vcsannotatetaskhandler.h" ] } diff --git a/src/plugins/projectexplorer/projectexplorerconstants.h b/src/plugins/projectexplorer/projectexplorerconstants.h index 45db16556e..f0b8f3f59d 100644 --- a/src/plugins/projectexplorer/projectexplorerconstants.h +++ b/src/plugins/projectexplorer/projectexplorerconstants.h @@ -69,6 +69,7 @@ const char RUNCONTEXTMENU[] = "ProjectExplorer.RunContextMenu"; const char STOP[] = "ProjectExplorer.Stop"; const char ADDNEWFILE[] = "ProjectExplorer.AddNewFile"; const char ADDEXISTINGFILES[] = "ProjectExplorer.AddExistingFiles"; +const char ADDEXISTINGDIRECTORY[] = "ProjectExplorer.AddExistingDirectory"; const char ADDNEWSUBPROJECT[] = "ProjectExplorer.AddNewSubproject"; const char REMOVEPROJECT[] = "ProjectExplorer.RemoveProject"; const char OPENFILE[] = "ProjectExplorer.OpenFile"; @@ -245,6 +246,12 @@ const char VAR_CURRENTBUILD_TYPE[] = "CurrentBuild:Type"; const char VAR_CURRENTSESSION_PREFIX[] = "CurrentSession"; const char VAR_CURRENTSESSION_NAME[] = "CurrentSession:Name"; +const char HIDE_FILE_FILTER_SETTING[] = "GenericProject/FileFilter"; +const char HIDE_FILE_FILTER_DEFAULT[] = "Makefile*; *.o; *.obj; *~; *.files; *.config; *.creator; *.user; *.includes; *.autosave"; + +const char SHOW_FILE_FILTER_SETTING[] = "GenericProject/ShowFileFilter"; +const char SHOW_FILE_FILTER_DEFAULT[] = "*.c; *.cc; *.cpp; *.cp; *.cxx; *.c++; *.h; *.hh; *.hpp; *.hxx;"; + // Unconfigured Panel const char UNCONFIGURED_PANEL_PAGE_ID[] = "UnconfiguredPanel"; diff --git a/src/plugins/projectexplorer/projectnodes.h b/src/plugins/projectexplorer/projectnodes.h index 424a877d80..fe5edc905a 100644 --- a/src/plugins/projectexplorer/projectnodes.h +++ b/src/plugins/projectexplorer/projectnodes.h @@ -184,6 +184,9 @@ public: // the file is added AddNewFile, AddExistingFile, + // Add files, which match user defined filters, + // from an existing directory and its subdirectories + AddExistingDirectory, // Removes a file from the project, optionally also // delete it on disc RemoveFile, diff --git a/src/plugins/genericprojectmanager/selectablefilesmodel.cpp b/src/plugins/projectexplorer/selectablefilesmodel.cpp index 60deb9da16..96595ed317 100644 --- a/src/plugins/genericprojectmanager/selectablefilesmodel.cpp +++ b/src/plugins/projectexplorer/selectablefilesmodel.cpp @@ -28,7 +28,7 @@ ****************************************************************************/ #include "selectablefilesmodel.h" -#include "genericprojectconstants.h" +#include "projectexplorerconstants.h" #include <coreplugin/fileiconprovider.h> #include <coreplugin/icore.h> @@ -41,19 +41,14 @@ #include <QPushButton> #include <QTreeView> #include <QDir> +#include <utils/pathchooser.h> -namespace GenericProjectManager { -namespace Internal { +namespace ProjectExplorer { -SelectableFilesModel::SelectableFilesModel(const QString &baseDir, QObject *parent) - : QAbstractItemModel(parent), m_root(0), m_baseDir(baseDir), m_allFiles(true) +SelectableFilesModel::SelectableFilesModel(QObject *parent) + : QAbstractItemModel(parent), m_root(0), m_allFiles(true) { - // Dummy tree - m_root = new Tree; - m_root->name = QLatin1String("/"); - m_root->parent = 0; - m_root->fullPath = m_baseDir; - m_root->isDir = true; + connect(&m_watcher, SIGNAL(finished()), this, SLOT(buildTreeFinished())); } void SelectableFilesModel::setInitialMarkedFiles(const QStringList &files) @@ -68,20 +63,19 @@ void SelectableFilesModel::setInitialMarkedFiles(const QStringList &files) m_allFiles = false; } -void SelectableFilesModel::init() +void SelectableFilesModel::startParsing(const QString &baseDir) { -} + m_watcher.cancel(); + m_watcher.waitForFinished(); -void SelectableFilesModel::startParsing() -{ + m_baseDir = baseDir; // Build a tree in a future m_rootForFuture = new Tree; m_rootForFuture->name = QLatin1String("/"); m_rootForFuture->parent = 0; - m_rootForFuture->fullPath = m_baseDir; + m_rootForFuture->fullPath = baseDir; m_rootForFuture->isDir = true; - connect(&m_watcher, SIGNAL(finished()), this, SLOT(buildTreeFinished())); m_watcher.setFuture(QtConcurrent::run(&SelectableFilesModel::run, this)); } @@ -101,14 +95,10 @@ void SelectableFilesModel::buildTreeFinished() emit parsingFinished(); } -void SelectableFilesModel::waitForFinished() -{ - m_watcher.waitForFinished(); -} - void SelectableFilesModel::cancel() { m_watcher.cancel(); + m_watcher.waitForFinished(); } bool SelectableFilesModel::filter(Tree *t) @@ -193,11 +183,15 @@ void SelectableFilesModel::buildTree(const QString &baseDir, Tree *tree, QFuture SelectableFilesModel::~SelectableFilesModel() { + m_watcher.cancel(); + m_watcher.waitForFinished(); deleteTree(m_root); } void SelectableFilesModel::deleteTree(Tree *tree) { + if (!tree) + return; foreach (Tree *t, tree->childDirectories) deleteTree(t); foreach (Tree *t, tree->files) @@ -234,6 +228,8 @@ QModelIndex SelectableFilesModel::parent(const QModelIndex &child) const { if (!child.isValid()) return QModelIndex(); + if (!child.internalPointer()) + return QModelIndex(); Tree *parent = static_cast<Tree *>(child.internalPointer())->parent; if (!parent) return QModelIndex(); @@ -398,6 +394,22 @@ void SelectableFilesModel::applyFilter(const QString &showFilesfilter, const QSt applyFilter(createIndex(0, 0, m_root)); } +void SelectableFilesModel::selectAllFiles() +{ + selectAllFiles(m_root); +} + +void SelectableFilesModel::selectAllFiles(Tree *root) +{ + root->checked = Qt::Checked; + + foreach (Tree *t, root->childDirectories) + selectAllFiles(t); + + foreach (Tree *t, root->visibleFiles) + t->checked = Qt::Checked; +} + Qt::CheckState SelectableFilesModel::applyFilter(const QModelIndex &index) { bool allChecked = true; @@ -511,10 +523,10 @@ Qt::CheckState SelectableFilesModel::applyFilter(const QModelIndex &index) } ////////// -// SelectableFilesDialog +// SelectableFilesDialogs ////////// -SelectableFilesDialog::SelectableFilesDialog(const QString &path, const QStringList files, QWidget *parent) +SelectableFilesDialogEditFiles::SelectableFilesDialogEditFiles(const QString &path, const QStringList files, QWidget *parent) : QDialog(parent) { QVBoxLayout *layout = new QVBoxLayout(); @@ -527,7 +539,7 @@ SelectableFilesDialog::SelectableFilesDialog(const QString &path, const QStringL createHideFileFilterControls(layout); createApplyButton(layout); - m_selectableFilesModel = new SelectableFilesModel(path, this); + m_selectableFilesModel = new SelectableFilesModel(this); m_selectableFilesModel->setInitialMarkedFiles(files); m_view->setModel(m_selectableFilesModel); m_view->setMinimumSize(500, 400); @@ -556,10 +568,10 @@ SelectableFilesDialog::SelectableFilesDialog(const QString &path, const QStringL connect(m_selectableFilesModel, SIGNAL(parsingFinished()), this, SLOT(parsingFinished())); - m_selectableFilesModel->startParsing(); + m_selectableFilesModel->startParsing(path); } -void SelectableFilesDialog::createHideFileFilterControls(QVBoxLayout *layout) +void SelectableFilesDialogEditFiles::createHideFileFilterControls(QVBoxLayout *layout) { QHBoxLayout *hbox = new QHBoxLayout; m_hideFilesFilterLabel = new QLabel; @@ -576,7 +588,7 @@ void SelectableFilesDialog::createHideFileFilterControls(QVBoxLayout *layout) layout->addLayout(hbox); } -void SelectableFilesDialog::createShowFileFilterControls(QVBoxLayout *layout) +void SelectableFilesDialogEditFiles::createShowFileFilterControls(QVBoxLayout *layout) { QHBoxLayout *hbox = new QHBoxLayout; m_showFilesFilterLabel = new QLabel; @@ -593,7 +605,7 @@ void SelectableFilesDialog::createShowFileFilterControls(QVBoxLayout *layout) layout->addLayout(hbox); } -void SelectableFilesDialog::createApplyButton(QVBoxLayout *layout) +void SelectableFilesDialogEditFiles::createApplyButton(QVBoxLayout *layout) { QHBoxLayout *hbox = new QHBoxLayout; @@ -608,18 +620,17 @@ void SelectableFilesDialog::createApplyButton(QVBoxLayout *layout) connect(m_applyFilterButton, SIGNAL(clicked()), this, SLOT(applyFilter())); } -SelectableFilesDialog::~SelectableFilesDialog() +SelectableFilesDialogEditFiles::~SelectableFilesDialogEditFiles() { m_selectableFilesModel->cancel(); - m_selectableFilesModel->waitForFinished(); } -void SelectableFilesDialog::parsingProgress(const QString &fileName) +void SelectableFilesDialogEditFiles::parsingProgress(const QString &fileName) { m_progressLabel->setText(tr("Generating file list...\n\n%1").arg(fileName)); } -void SelectableFilesDialog::parsingFinished() +void SelectableFilesDialogEditFiles::parsingFinished() { m_hideFilesFilterLabel->show(); m_hideFilesfilterLineEdit->show(); @@ -642,7 +653,7 @@ void SelectableFilesDialog::parsingFinished() } } -void SelectableFilesDialog::smartExpand(const QModelIndex &index) +void SelectableFilesDialogEditFiles::smartExpand(const QModelIndex &index) { if (m_view->model()->data(index, Qt::CheckStateRole) == Qt::PartiallyChecked) { m_view->expand(index); @@ -652,12 +663,12 @@ void SelectableFilesDialog::smartExpand(const QModelIndex &index) } } -QStringList SelectableFilesDialog::selectedFiles() const +QStringList SelectableFilesDialogEditFiles::selectedFiles() const { return m_selectableFilesModel->selectedFiles(); } -void SelectableFilesDialog::applyFilter() +void SelectableFilesDialogEditFiles::applyFilter() { const QString showFilesFilter = m_showFilesfilterLineEdit->text(); Core::ICore::settings()->setValue(QLatin1String(Constants::SHOW_FILE_FILTER_SETTING), showFilesFilter); @@ -668,7 +679,70 @@ void SelectableFilesDialog::applyFilter() m_selectableFilesModel->applyFilter(showFilesFilter, hideFilesFilter); } -} // namespace Internal -} // namespace GenericProjectManager +SelectableFilesDialogAddDirectory::SelectableFilesDialogAddDirectory(const QString &path, + const QStringList files, QWidget *parent) : + SelectableFilesDialogEditFiles(path, files, parent) +{ + setWindowTitle(tr("Add Existing Directory")); + + connect(m_selectableFilesModel, SIGNAL(parsingFinished()), this, SLOT(parsingFinished())); + + createPathChooser(static_cast<QVBoxLayout*>(layout()), path); +} + +void SelectableFilesDialogAddDirectory::createPathChooser(QVBoxLayout *layout, const QString &path) +{ + QHBoxLayout *hbox = new QHBoxLayout; + + m_pathChooser = new Utils::PathChooser; + m_pathChooser->setPath(path); + + m_sourceDirectoryLabel = new QLabel(tr("Source directory:")); + hbox->addWidget(m_sourceDirectoryLabel); + + hbox->addWidget(m_pathChooser); + layout->insertLayout(0, hbox); + + m_startParsingButton = new QPushButton(tr("Start Parsing")); + hbox->addWidget(m_startParsingButton); + + connect(m_pathChooser, SIGNAL(validChanged(bool)), this, SLOT(validityOfDirectoryChanged(bool))); + connect(m_startParsingButton, SIGNAL(clicked()), this, SLOT(startParsing())); +} + +void SelectableFilesDialogAddDirectory::validityOfDirectoryChanged(bool validState) +{ + m_startParsingButton->setEnabled(validState); +} + +void SelectableFilesDialogAddDirectory::parsingFinished() +{ + m_selectableFilesModel->selectAllFiles(); + m_selectableFilesModel->applyFilter(m_showFilesfilterLineEdit->text(), + m_hideFilesfilterLineEdit->text()); + + setWidgetsEnabled(true); +} + +void SelectableFilesDialogAddDirectory::startParsing() +{ + setWidgetsEnabled(false); + + m_selectableFilesModel->startParsing(m_pathChooser->path()); +} + +void SelectableFilesDialogAddDirectory::setWidgetsEnabled(bool enabled) +{ + m_hideFilesfilterLineEdit->setEnabled(enabled); + m_showFilesfilterLineEdit->setEnabled(enabled); + m_applyFilterButton->setEnabled(enabled); + m_view->setEnabled(enabled); + m_pathChooser->setEnabled(enabled); + m_startParsingButton->setVisible(enabled); + + m_progressLabel->setVisible(!enabled); +} + +} // namespace ProjectExplorer diff --git a/src/plugins/genericprojectmanager/selectablefilesmodel.h b/src/plugins/projectexplorer/selectablefilesmodel.h index fcd09beb5d..d1423c3d36 100644 --- a/src/plugins/genericprojectmanager/selectablefilesmodel.h +++ b/src/plugins/projectexplorer/selectablefilesmodel.h @@ -37,13 +37,15 @@ #include <QDialog> #include <QTreeView> #include <QLabel> +#include "projectexplorer_export.h" + +namespace Utils { class PathChooser; } QT_BEGIN_NAMESPACE class QVBoxLayout; QT_END_NAMESPACE -namespace GenericProjectManager { -namespace Internal { +namespace ProjectExplorer { struct Tree { @@ -81,12 +83,12 @@ struct Glob } }; -class SelectableFilesModel : public QAbstractItemModel +class PROJECTEXPLORER_EXPORT SelectableFilesModel : public QAbstractItemModel { Q_OBJECT public: - SelectableFilesModel(const QString &baseDir, QObject *parent); + SelectableFilesModel(QObject *parent); ~SelectableFilesModel(); void setInitialMarkedFiles(const QStringList &files); @@ -104,12 +106,12 @@ public: QStringList selectedPaths() const; QStringList preservedFiles() const; - // only call this once - void startParsing(); - void waitForFinished(); + void startParsing(const QString &baseDir); void cancel(); void applyFilter(const QString &selectFilesfilter, const QString &hideFilesfilter); + void selectAllFiles(); + signals: void parsingFinished(); void parsingProgress(const QString &filename); @@ -121,7 +123,6 @@ private: QList<Glob> parseFilter(const QString &filter); Qt::CheckState applyFilter(const QModelIndex &index); bool filter(Tree *t); - void init(); void run(QFutureInterface<void> &fi); void collectFiles(Tree *root, QStringList *result) const; void collectPaths(Tree *root, QStringList *result) const; @@ -129,6 +130,7 @@ private: void deleteTree(Tree *tree); void propagateUp(const QModelIndex &index); void propagateDown(const QModelIndex &index); + void selectAllFiles(Tree *root); Tree *m_root; // Used in the future thread need to all not used after calling startParsing QString m_baseDir; @@ -143,13 +145,13 @@ private: QList<Glob> m_showFilesFilter; }; -class SelectableFilesDialog : public QDialog +class PROJECTEXPLORER_EXPORT SelectableFilesDialogEditFiles : public QDialog { Q_OBJECT public: - SelectableFilesDialog(const QString &path, const QStringList files, QWidget *parent); - ~SelectableFilesDialog(); + SelectableFilesDialogEditFiles(const QString &path, const QStringList files, QWidget *parent); + ~SelectableFilesDialogEditFiles(); QStringList selectedFiles() const; private slots: @@ -157,11 +159,12 @@ private slots: void parsingProgress(const QString &fileName); void parsingFinished(); -private: +protected: void smartExpand(const QModelIndex &index); void createShowFileFilterControls(QVBoxLayout *layout); void createHideFileFilterControls(QVBoxLayout *layout); void createApplyButton(QVBoxLayout *layout); + SelectableFilesModel *m_selectableFilesModel; QLabel *m_hideFilesFilterLabel; @@ -177,8 +180,28 @@ private: QLabel *m_progressLabel; }; -} // namespace Internal -} // namespace GenericProjectManager +class SelectableFilesDialogAddDirectory : public SelectableFilesDialogEditFiles +{ + Q_OBJECT + +public: + SelectableFilesDialogAddDirectory(const QString &path, const QStringList files, QWidget *parent); + +private slots: + void validityOfDirectoryChanged(bool validState); + void parsingFinished(); + void startParsing(); + +private: + Utils::PathChooser *m_pathChooser; + QLabel *m_sourceDirectoryLabel; + QPushButton *m_startParsingButton; + + void setWidgetsEnabled(bool enabled); + void createPathChooser(QVBoxLayout *layout, const QString &path); +}; + +} // namespace ProjectExplorer #endif // SELECTABLEFILESMODEL_H diff --git a/src/plugins/projectexplorer/targetselector.cpp b/src/plugins/projectexplorer/targetselector.cpp index d09f83f562..6a9ecd4c95 100644 --- a/src/plugins/projectexplorer/targetselector.cpp +++ b/src/plugins/projectexplorer/targetselector.cpp @@ -116,13 +116,13 @@ void TargetSelector::menuAboutToHide() updateButtons(); } -void TargetSelector::insertTarget(int index, const QString &name) +void TargetSelector::insertTarget(int index, int subIndex, const QString &name) { QTC_ASSERT(index >= 0 && index <= m_targets.count(), return); Target target; target.name = name; - target.currentSubIndex = 0; + target.currentSubIndex = subIndex; m_targets.insert(index, target); diff --git a/src/plugins/projectexplorer/targetselector.h b/src/plugins/projectexplorer/targetselector.h index f882cbf7f4..7abe969682 100644 --- a/src/plugins/projectexplorer/targetselector.h +++ b/src/plugins/projectexplorer/targetselector.h @@ -67,7 +67,7 @@ public: void setTargetMenu(QMenu *menu); public: - void insertTarget(int index, const QString &name); + void insertTarget(int index, int subIndex, const QString &name); void renameTarget(int index, const QString &name); void removeTarget(int index); void setCurrentIndex(int index); diff --git a/src/plugins/projectexplorer/targetsettingspanel.cpp b/src/plugins/projectexplorer/targetsettingspanel.cpp index 95a99377a0..780398e302 100644 --- a/src/plugins/projectexplorer/targetsettingspanel.cpp +++ b/src/plugins/projectexplorer/targetsettingspanel.cpp @@ -181,9 +181,7 @@ void TargetSettingsPanelWidget::setupUi() // Now set the correct target int index = m_targets.indexOf(m_project->activeTarget()); m_selector->setCurrentIndex(index); - m_selector->setCurrentSubIndex(0); - - currentTargetChanged(index, 0); + currentTargetChanged(index, m_selector->currentSubIndex()); connect(m_selector, SIGNAL(currentChanged(int,int)), this, SLOT(currentTargetChanged(int,int))); @@ -488,7 +486,9 @@ void TargetSettingsPanelWidget::targetAdded(ProjectExplorer::Target *target) if (m_targets.count() == pos || m_targets.at(pos)->displayName() > target->displayName()) { m_targets.insert(pos, target); - m_selector->insertTarget(pos, target->displayName()); + m_selector->insertTarget(pos, m_project->hasActiveBuildSettings() ? 0 : 1, + target->displayName()); + break; } } diff --git a/src/plugins/projectexplorer/targetsettingswidget.cpp b/src/plugins/projectexplorer/targetsettingswidget.cpp index 88c53616a0..a83e228c97 100644 --- a/src/plugins/projectexplorer/targetsettingswidget.cpp +++ b/src/plugins/projectexplorer/targetsettingswidget.cpp @@ -83,9 +83,9 @@ TargetSettingsWidget::~TargetSettingsWidget() delete ui; } -void TargetSettingsWidget::insertTarget(int index, const QString &name) +void TargetSettingsWidget::insertTarget(int index, int subIndex, const QString &name) { - m_targetSelector->insertTarget(index, name); + m_targetSelector->insertTarget(index, subIndex, name); } void TargetSettingsWidget::renameTarget(int index, const QString &name) diff --git a/src/plugins/projectexplorer/targetsettingswidget.h b/src/plugins/projectexplorer/targetsettingswidget.h index 1b678c4a20..808e62a93e 100644 --- a/src/plugins/projectexplorer/targetsettingswidget.h +++ b/src/plugins/projectexplorer/targetsettingswidget.h @@ -62,7 +62,7 @@ public: int currentSubIndex() const; public: - void insertTarget(int index, const QString &name); + void insertTarget(int index, int subIndex, const QString &name); void renameTarget(int index, const QString &name); void removeTarget(int index); void setCurrentIndex(int index); diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index cfb50e3454..9c4184c539 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -102,6 +102,7 @@ QbsProject::QbsProject(QbsManager *manager, const QString &fileName) : { m_parsingDelay.setInterval(1000); // delay parsing by 1s. + setId(Constants::PROJECT_ID); setProjectContext(Context(Constants::PROJECT_ID)); setProjectLanguages(Context(ProjectExplorer::Constants::LANG_CXX)); @@ -140,11 +141,6 @@ QString QbsProject::displayName() const return m_projectName; } -Id QbsProject::id() const -{ - return Constants::PROJECT_ID; -} - IDocument *QbsProject::document() const { foreach (IDocument *doc, m_qbsDocuments) { diff --git a/src/plugins/qbsprojectmanager/qbsproject.h b/src/plugins/qbsprojectmanager/qbsproject.h index 1a8d9232d8..d43ead569c 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.h +++ b/src/plugins/qbsprojectmanager/qbsproject.h @@ -74,7 +74,6 @@ public: ~QbsProject(); QString displayName() const; - Core::Id id() const; Core::IDocument *document() const; QbsManager *projectManager() const; diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.cpp b/src/plugins/qmakeprojectmanager/qmakenodes.cpp index 80608630c9..eb3a187bb6 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakenodes.cpp @@ -865,7 +865,7 @@ QList<ProjectNode::ProjectAction> QmakePriFileNode::supportedActions(Node *node) addExistingFiles = addExistingFiles && !deploysFolder(node->path()); if (addExistingFiles) - actions << AddExistingFile; + actions << AddExistingFile << AddExistingDirectory; break; } diff --git a/src/plugins/qmakeprojectmanager/qmakeparser.cpp b/src/plugins/qmakeprojectmanager/qmakeparser.cpp index 100d9a80cb..a64c4c9f61 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparser.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeparser.cpp @@ -33,7 +33,6 @@ #include <projectexplorer/projectexplorerconstants.h> using namespace QmakeProjectManager; -using namespace QmakeProjectManager::Internal; using ProjectExplorer::Task; QMakeParser::QMakeParser() : m_error(QLatin1String("^(.+):(\\d+):\\s(.+)$")) diff --git a/src/plugins/qmakeprojectmanager/qmakeparser.h b/src/plugins/qmakeprojectmanager/qmakeparser.h index 68b73aa15e..e37ee76791 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparser.h +++ b/src/plugins/qmakeprojectmanager/qmakeparser.h @@ -30,14 +30,15 @@ #ifndef QMAKEPARSER_H #define QMAKEPARSER_H +#include "qmakeprojectmanager_global.h" + #include <projectexplorer/ioutputparser.h> #include <QRegExp> namespace QmakeProjectManager { -namespace Internal { -class QMakeParser : public ProjectExplorer::IOutputParser +class QMAKEPROJECTMANAGER_EXPORT QMakeParser : public ProjectExplorer::IOutputParser { Q_OBJECT @@ -49,7 +50,6 @@ private: QRegExp m_error; }; -} // namesapce Internal } // namespace QmakeProjectManager #endif // QMAKEPARSER_H diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index c86f57cd6a..b4ed6335e0 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -343,6 +343,7 @@ QmakeProject::QmakeProject(QmakeManager *manager, const QString &fileName) : m_centralizedFolderWatcher(0), m_activeTarget(0) { + setId(Constants::QMAKEPROJECT_ID); setProjectContext(Core::Context(QmakeProjectManager::Constants::PROJECT_ID)); setProjectLanguages(Core::Context(ProjectExplorer::Constants::LANG_CXX)); @@ -890,11 +891,6 @@ QString QmakeProject::displayName() const return QFileInfo(projectFilePath()).completeBaseName(); } -Core::Id QmakeProject::id() const -{ - return Core::Id(Constants::QMAKEPROJECT_ID); -} - Core::IDocument *QmakeProject::document() const { return m_fileInfo; diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.h b/src/plugins/qmakeprojectmanager/qmakeproject.h index fbab9a573f..74d9bb9fc9 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.h +++ b/src/plugins/qmakeprojectmanager/qmakeproject.h @@ -76,7 +76,6 @@ public: virtual ~QmakeProject(); QString displayName() const; - Core::Id id() const; Core::IDocument *document() const; ProjectExplorer::IProjectManager *projectManager() const; QmakeManager *qmakeProjectManager() const; diff --git a/src/plugins/qmlprojectmanager/qmlapp.cpp b/src/plugins/qmlprojectmanager/qmlapp.cpp index 39fd652911..3e774f94c3 100644 --- a/src/plugins/qmlprojectmanager/qmlapp.cpp +++ b/src/plugins/qmlprojectmanager/qmlapp.cpp @@ -154,7 +154,6 @@ static bool parseTemplateXml(QXmlStreamReader &reader, TemplateInfo *info) static const QLatin1String tag_template("template"); static const QLatin1String tag_displayName("displayname"); static const QLatin1String tag_description("description"); - static const QLatin1String attribute_id("id"); static const QLatin1String attribute_featuresRequired("featuresRequired"); static const QLatin1String attribute_openEditor("openeditor"); static const QLatin1String attribute_priority("priority"); @@ -169,9 +168,6 @@ static bool parseTemplateXml(QXmlStreamReader &reader, TemplateInfo *info) if (reader.attributes().hasAttribute(attribute_priority)) info->priority = reader.attributes().value(attribute_priority).toString(); - if (reader.attributes().hasAttribute(attribute_id)) - info->wizardId = reader.attributes().value(attribute_id).toString(); - if (reader.attributes().hasAttribute(attribute_featuresRequired)) info->featuresRequired = reader.attributes().value(attribute_featuresRequired).toString(); diff --git a/src/plugins/qmlprojectmanager/qmlapp.h b/src/plugins/qmlprojectmanager/qmlapp.h index 9dd566689b..a47bedc6c1 100644 --- a/src/plugins/qmlprojectmanager/qmlapp.h +++ b/src/plugins/qmlprojectmanager/qmlapp.h @@ -47,7 +47,6 @@ public: QString displayName; QString description; QString openFile; - QString wizardId; QString featuresRequired; QString priority; }; diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp index 10d495c467..7d72d08846 100644 --- a/src/plugins/qmlprojectmanager/qmlproject.cpp +++ b/src/plugins/qmlprojectmanager/qmlproject.cpp @@ -111,6 +111,7 @@ QmlProject::QmlProject(Internal::Manager *manager, const QString &fileName) m_modelManager(QmlJS::ModelManagerInterface::instance()), m_activeTarget(0) { + setId("QmlProjectManager.QmlProject"); setProjectContext(Context(QmlProjectManager::Constants::PROJECTCONTEXT)); setProjectLanguages(Context(ProjectExplorer::Constants::LANG_QMLJS)); @@ -324,11 +325,6 @@ QString QmlProject::displayName() const return m_projectName; } -Id QmlProject::id() const -{ - return "QmlProjectManager.QmlProject"; -} - IDocument *QmlProject::document() const { return m_file; diff --git a/src/plugins/qmlprojectmanager/qmlproject.h b/src/plugins/qmlprojectmanager/qmlproject.h index 8e931a9a02..faa060664f 100644 --- a/src/plugins/qmlprojectmanager/qmlproject.h +++ b/src/plugins/qmlprojectmanager/qmlproject.h @@ -61,7 +61,6 @@ public: QString filesFileName() const; QString displayName() const; - Core::Id id() const; Core::IDocument *document() const; ProjectExplorer::IProjectManager *projectManager() const; diff --git a/src/plugins/qnx/blackberrycheckdebugtokenstep.cpp b/src/plugins/qnx/blackberrycheckdebugtokenstep.cpp new file mode 100644 index 0000000000..3094913a8d --- /dev/null +++ b/src/plugins/qnx/blackberrycheckdebugtokenstep.cpp @@ -0,0 +1,156 @@ +/************************************************************************** +** +** Copyright (C) 2013 BlackBerry Limited. All rights reserved. +** +** Contact: BlackBerry (qt@blackberry.com) +** Contact: KDAB (info@kdab.com) +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "blackberrycheckdebugtokenstep.h" + +#include "blackberrycheckdebugtokenstepconfigwidget.h" +#include "blackberrydeviceinformation.h" +#include "qnxconstants.h" + +#include <projectexplorer/buildconfiguration.h> +#include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/target.h> +#include <projectexplorer/task.h> +#include <ssh/sshconnection.h> + +#include <qeventloop.h> + +using namespace Qnx; +using namespace Qnx::Internal; + +BlackBerryCheckDebugTokenStep::BlackBerryCheckDebugTokenStep(ProjectExplorer::BuildStepList *bsl) : + ProjectExplorer::BuildStep(bsl, Core::Id(Constants::QNX_CHECK_DEBUG_TOKEN_BS_ID)) + , m_deviceInfo(0) + , m_eventLoop(0) +{ + setDisplayName(tr("Check Debug Token")); +} + +BlackBerryCheckDebugTokenStep::BlackBerryCheckDebugTokenStep(ProjectExplorer::BuildStepList *bsl, BlackBerryCheckDebugTokenStep *bs) : + ProjectExplorer::BuildStep(bsl, bs) + , m_deviceInfo(0) + , m_eventLoop(0) +{ + setDisplayName(tr("Check Debug Token")); +} + +void BlackBerryCheckDebugTokenStep::checkDeviceInfo(int status) +{ + // Skip debug token check for internal non secure devices and simulators + if (m_deviceInfo->isProductionDevice() && !m_deviceInfo->isSimulator()) { + if (status != BlackBerryDeviceInformation::Success) { + switch (status) { + case BlackBerryDeviceInformation::AuthenticationFailed: + raiseError(tr("Authentication failed.")); + break; + case BlackBerryDeviceInformation::NoRouteToHost: + raiseError(tr("Cannot connect to device.")); + break; + case BlackBerryDeviceInformation::DevelopmentModeDisabled: + raiseError(tr("Device is not in the development mode.")); + break; + case BlackBerryDeviceInformation::InferiorProcessTimedOut: + raiseError(tr("Timeout querying device information.")); + break; + case BlackBerryDeviceInformation::FailedToStartInferiorProcess: + raiseError(tr("Failed to query device information.")); + break; + case BlackBerryDeviceInformation::InferiorProcessCrashed: + raiseError(tr("Process to query device information has crashed.")); + break; + default: + raiseError(tr("Cannot query device information.")); + break; + } + m_eventLoop->exit(false); + return; + } + + if (!m_deviceInfo->debugTokenValid()) { + raiseError(m_deviceInfo->debugTokenValidationError()); + m_eventLoop->exit(false); + return; + } + } + + m_eventLoop->exit(true); +} + +void BlackBerryCheckDebugTokenStep::emitOutputInfo() +{ + emit addOutput(tr("Checking debug token..."), BuildStep::MessageOutput); +} + +bool BlackBerryCheckDebugTokenStep::init() +{ + m_device = BlackBerryDeviceConfiguration::device(target()->kit()); + if (!m_device) + return false; + + if (m_device->sshParameters().host.isEmpty()) { + raiseError(tr("No hostname specified for the device")); + return false; + } + + return true; +} + +void BlackBerryCheckDebugTokenStep::run(QFutureInterface<bool> &fi) +{ + m_eventLoop = new QEventLoop; + m_deviceInfo = new BlackBerryDeviceInformation; + + connect(m_deviceInfo, SIGNAL(started()), this, SLOT(emitOutputInfo())); + connect(m_deviceInfo, SIGNAL(finished(int)), this, SLOT(checkDeviceInfo(int)), Qt::DirectConnection); + m_deviceInfo->setDeviceTarget(m_device->sshParameters().host, m_device->sshParameters().password); + + bool returnValue = m_eventLoop->exec(); + + delete m_eventLoop; + m_eventLoop = 0; + + delete m_deviceInfo; + m_deviceInfo = 0; + + return fi.reportResult(returnValue); +} + +ProjectExplorer::BuildStepConfigWidget *BlackBerryCheckDebugTokenStep::createConfigWidget() +{ + return new BlackBerryCheckDebugTokenConfigWidget(); +} + +void BlackBerryCheckDebugTokenStep::raiseError(const QString &errorMessage) +{ + emit addOutput(errorMessage, BuildStep::ErrorMessageOutput); + emit addTask(ProjectExplorer::Task(ProjectExplorer::Task::Error, errorMessage, Utils::FileName(), -1, + ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT)); +} diff --git a/src/plugins/qnx/blackberrycheckdevmodestep.h b/src/plugins/qnx/blackberrycheckdebugtokenstep.h index 5f5e1bc9d9..84152499fe 100644 --- a/src/plugins/qnx/blackberrycheckdevmodestep.h +++ b/src/plugins/qnx/blackberrycheckdebugtokenstep.h @@ -29,35 +29,49 @@ ** ****************************************************************************/ -#ifndef QNX_INTERNAL_BLACKBERRYCHECKDEVMODESTEP_H -#define QNX_INTERNAL_BLACKBERRYCHECKDEVMODESTEP_H +#ifndef QNX_INTERNAL_BLACKBERRYCHECKDEBUGTOKENSTEP_H +#define QNX_INTERNAL_BLACKBERRYCHECKDEBUGTOKENSTEP_H -#include "blackberryabstractdeploystep.h" +#include "blackberrydeviceconfiguration.h" + +#include <projectexplorer/buildstep.h> + +QT_BEGIN_NAMESPACE +class QEventLoop; +QT_END_NAMESPACE namespace Qnx { namespace Internal { -class BlackBerryCheckDevModeStep : public BlackBerryAbstractDeployStep +class BlackBerryDeviceInformation; +class BlackBerryCheckDebugTokenStep : public ProjectExplorer::BuildStep { Q_OBJECT - friend class BlackBerryCheckDevModeStepFactory; + friend class BlackBerryCheckDebugTokenStepFactory; public: - explicit BlackBerryCheckDevModeStep(ProjectExplorer::BuildStepList *bsl); + explicit BlackBerryCheckDebugTokenStep(ProjectExplorer::BuildStepList *bsl); bool init(); + void run(QFutureInterface<bool> &fi); ProjectExplorer::BuildStepConfigWidget *createConfigWidget(); + void raiseError(const QString& error); + protected: - BlackBerryCheckDevModeStep(ProjectExplorer::BuildStepList *bsl, BlackBerryCheckDevModeStep *bs); + BlackBerryCheckDebugTokenStep(ProjectExplorer::BuildStepList *bsl, BlackBerryCheckDebugTokenStep *bs); - void processStarted(const ProjectExplorer::ProcessParameters ¶ms); +protected slots: + void checkDeviceInfo(int status); + void emitOutputInfo(); private: - QString password() const; + BlackBerryDeviceInformation *m_deviceInfo; + BlackBerryDeviceConfiguration::ConstPtr m_device; + QEventLoop *m_eventLoop; }; } // namespace Internal } // namespace Qnx -#endif // QNX_INTERNAL_BLACKBERRYCHECKDEVMODESTEP_H +#endif // QNX_INTERNAL_BLACKBERRYCHECKDEBUGTOKENSTEP_H diff --git a/src/plugins/qnx/blackberrycheckdevmodestepconfigwidget.cpp b/src/plugins/qnx/blackberrycheckdebugtokenstepconfigwidget.cpp index a6bb9fbfad..de372497bd 100644 --- a/src/plugins/qnx/blackberrycheckdevmodestepconfigwidget.cpp +++ b/src/plugins/qnx/blackberrycheckdebugtokenstepconfigwidget.cpp @@ -29,27 +29,27 @@ ** ****************************************************************************/ -#include "blackberrycheckdevmodestepconfigwidget.h" +#include "blackberrycheckdebugtokenstepconfigwidget.h" using namespace Qnx; using namespace Qnx::Internal; -BlackBerryCheckDevModeStepConfigWidget::BlackBerryCheckDevModeStepConfigWidget() : +BlackBerryCheckDebugTokenConfigWidget::BlackBerryCheckDebugTokenConfigWidget() : ProjectExplorer::BuildStepConfigWidget() { } -QString BlackBerryCheckDevModeStepConfigWidget::displayName() const +QString BlackBerryCheckDebugTokenConfigWidget::displayName() const { - return tr("<b>Check development mode</b>"); + return tr("<b>Check debug token</b>"); } -QString BlackBerryCheckDevModeStepConfigWidget::summaryText() const +QString BlackBerryCheckDebugTokenConfigWidget::summaryText() const { return displayName(); } -bool BlackBerryCheckDevModeStepConfigWidget::showWidget() const +bool BlackBerryCheckDebugTokenConfigWidget::showWidget() const { return false; } diff --git a/src/plugins/qnx/blackberrycheckdevmodestepconfigwidget.h b/src/plugins/qnx/blackberrycheckdebugtokenstepconfigwidget.h index cf14780666..f092754172 100644 --- a/src/plugins/qnx/blackberrycheckdevmodestepconfigwidget.h +++ b/src/plugins/qnx/blackberrycheckdebugtokenstepconfigwidget.h @@ -29,19 +29,19 @@ ** ****************************************************************************/ -#ifndef QNX_INTERNAL_BLACKBERRYCHECKDEVMODESTEPCONFIGWIDGET_H -#define QNX_INTERNAL_BLACKBERRYCHECKDEVMODESTEPCONFIGWIDGET_H +#ifndef QNX_INTERNAL_BLACKBERRYCHECKDEBUGTOKENSTEPCONFIGWIDGET_H +#define QNX_INTERNAL_BLACKBERRYCHECKDEBUGTOKENSTEPCONFIGWIDGET_H #include <projectexplorer/buildstep.h> namespace Qnx { namespace Internal { -class BlackBerryCheckDevModeStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget +class BlackBerryCheckDebugTokenConfigWidget : public ProjectExplorer::BuildStepConfigWidget { Q_OBJECT public: - explicit BlackBerryCheckDevModeStepConfigWidget(); + explicit BlackBerryCheckDebugTokenConfigWidget(); QString displayName() const; QString summaryText() const; diff --git a/src/plugins/qnx/blackberrycheckdevmodestepfactory.cpp b/src/plugins/qnx/blackberrycheckdebugtokenstepfactory.cpp index 58d69de160..3185f2c306 100644 --- a/src/plugins/qnx/blackberrycheckdevmodestepfactory.cpp +++ b/src/plugins/qnx/blackberrycheckdebugtokenstepfactory.cpp @@ -29,9 +29,9 @@ ** ****************************************************************************/ -#include "blackberrycheckdevmodestepfactory.h" +#include "blackberrycheckdebugtokenstepfactory.h" -#include "blackberrycheckdevmodestep.h" +#include "blackberrycheckdebugtokenstep.h" #include "blackberrydeviceconfigurationfactory.h" #include "qnxconstants.h" @@ -43,12 +43,12 @@ using namespace Qnx; using namespace Qnx::Internal; -BlackBerryCheckDevModeStepFactory::BlackBerryCheckDevModeStepFactory(QObject *parent) : +BlackBerryCheckDebugTokenStepFactory::BlackBerryCheckDebugTokenStepFactory(QObject *parent) : ProjectExplorer::IBuildStepFactory(parent) { } -QList<Core::Id> BlackBerryCheckDevModeStepFactory::availableCreationIds(ProjectExplorer::BuildStepList *parent) const +QList<Core::Id> BlackBerryCheckDebugTokenStepFactory::availableCreationIds(ProjectExplorer::BuildStepList *parent) const { if (parent->id() != ProjectExplorer::Constants::BUILDSTEPS_DEPLOY) return QList<Core::Id>(); @@ -57,52 +57,52 @@ QList<Core::Id> BlackBerryCheckDevModeStepFactory::availableCreationIds(ProjectE if (deviceType != BlackBerryDeviceConfigurationFactory::deviceType()) return QList<Core::Id>(); - return QList<Core::Id>() << Core::Id(Constants::QNX_CHECK_DEVELOPMENT_MODE_BS_ID); + return QList<Core::Id>() << Core::Id(Constants::QNX_CHECK_DEBUG_TOKEN_BS_ID); } -QString BlackBerryCheckDevModeStepFactory::displayNameForId(const Core::Id id) const +QString BlackBerryCheckDebugTokenStepFactory::displayNameForId(const Core::Id id) const { - if (id == Constants::QNX_CHECK_DEVELOPMENT_MODE_BS_ID) - return tr("Check Development Mode"); + if (id == Constants::QNX_CHECK_DEBUG_TOKEN_BS_ID) + return tr("Check Debug Token"); return QString(); } -bool BlackBerryCheckDevModeStepFactory::canCreate(ProjectExplorer::BuildStepList *parent, const Core::Id id) const +bool BlackBerryCheckDebugTokenStepFactory::canCreate(ProjectExplorer::BuildStepList *parent, const Core::Id id) const { return availableCreationIds(parent).contains(id); } -ProjectExplorer::BuildStep *BlackBerryCheckDevModeStepFactory::create(ProjectExplorer::BuildStepList *parent, const Core::Id id) +ProjectExplorer::BuildStep *BlackBerryCheckDebugTokenStepFactory::create(ProjectExplorer::BuildStepList *parent, const Core::Id id) { if (!canCreate(parent, id)) return 0; - return new BlackBerryCheckDevModeStep(parent); + return new BlackBerryCheckDebugTokenStep(parent); } -bool BlackBerryCheckDevModeStepFactory::canRestore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map) const +bool BlackBerryCheckDebugTokenStepFactory::canRestore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map) const { return canCreate(parent, ProjectExplorer::idFromMap(map)); } -ProjectExplorer::BuildStep *BlackBerryCheckDevModeStepFactory::restore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map) +ProjectExplorer::BuildStep *BlackBerryCheckDebugTokenStepFactory::restore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map) { if (!canRestore(parent, map)) return 0; - BlackBerryCheckDevModeStep *bs = new BlackBerryCheckDevModeStep(parent); + BlackBerryCheckDebugTokenStep *bs = new BlackBerryCheckDebugTokenStep(parent); if (bs->fromMap(map)) return bs; delete bs; return 0; } -bool BlackBerryCheckDevModeStepFactory::canClone(ProjectExplorer::BuildStepList *parent, ProjectExplorer::BuildStep *product) const +bool BlackBerryCheckDebugTokenStepFactory::canClone(ProjectExplorer::BuildStepList *parent, ProjectExplorer::BuildStep *product) const { return canCreate(parent, product->id()); } -ProjectExplorer::BuildStep *BlackBerryCheckDevModeStepFactory::clone(ProjectExplorer::BuildStepList *parent, ProjectExplorer::BuildStep *product) +ProjectExplorer::BuildStep *BlackBerryCheckDebugTokenStepFactory::clone(ProjectExplorer::BuildStepList *parent, ProjectExplorer::BuildStep *product) { if (!canClone(parent, product)) return 0; - return new BlackBerryCheckDevModeStep(parent, static_cast<BlackBerryCheckDevModeStep *>(product)); + return new BlackBerryCheckDebugTokenStep(parent, static_cast<BlackBerryCheckDebugTokenStep *>(product)); } diff --git a/src/plugins/qnx/blackberrycheckdevmodestepfactory.h b/src/plugins/qnx/blackberrycheckdebugtokenstepfactory.h index f028fd9a7c..36683130e2 100644 --- a/src/plugins/qnx/blackberrycheckdevmodestepfactory.h +++ b/src/plugins/qnx/blackberrycheckdebugtokenstepfactory.h @@ -29,19 +29,19 @@ ** ****************************************************************************/ -#ifndef QNX_INTERNAL_BLACKBERRYCHECKDEVMODESTEPFACTORY_H -#define QNX_INTERNAL_BLACKBERRYCHECKDEVMODESTEPFACTORY_H +#ifndef QNX_INTERNAL_BLACKBERRYCHECKDEBUGTOKENSTEPFACTORY_H +#define QNX_INTERNAL_BLACKBERRYCHECKDEBUGTOKENSTEPFACTORY_H #include <projectexplorer/buildstep.h> namespace Qnx { namespace Internal { -class BlackBerryCheckDevModeStepFactory : public ProjectExplorer::IBuildStepFactory +class BlackBerryCheckDebugTokenStepFactory : public ProjectExplorer::IBuildStepFactory { Q_OBJECT public: - explicit BlackBerryCheckDevModeStepFactory(QObject *parent = 0); + explicit BlackBerryCheckDebugTokenStepFactory(QObject *parent = 0); QList<Core::Id> availableCreationIds(ProjectExplorer::BuildStepList *parent) const; QString displayNameForId(const Core::Id id) const; diff --git a/src/plugins/qnx/blackberrycheckdevmodestep.cpp b/src/plugins/qnx/blackberrycheckdevmodestep.cpp deleted file mode 100644 index 93e45087f9..0000000000 --- a/src/plugins/qnx/blackberrycheckdevmodestep.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/************************************************************************** -** -** Copyright (C) 2013 BlackBerry Limited. All rights reserved. -** -** Contact: BlackBerry (qt@blackberry.com) -** Contact: KDAB (info@kdab.com) -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "blackberrycheckdevmodestep.h" - -#include "blackberrycheckdevmodestepconfigwidget.h" -#include "blackberrydeviceconfiguration.h" -#include "qnxconstants.h" - -#include <projectexplorer/buildconfiguration.h> -#include <projectexplorer/target.h> -#include <ssh/sshconnection.h> - -using namespace Qnx; -using namespace Qnx::Internal; - -BlackBerryCheckDevModeStep::BlackBerryCheckDevModeStep(ProjectExplorer::BuildStepList *bsl) : - BlackBerryAbstractDeployStep(bsl, Core::Id(Constants::QNX_CHECK_DEVELOPMENT_MODE_BS_ID)) -{ - setDisplayName(tr("Check Development Mode")); -} - -BlackBerryCheckDevModeStep::BlackBerryCheckDevModeStep(ProjectExplorer::BuildStepList *bsl, BlackBerryCheckDevModeStep *bs) : - BlackBerryAbstractDeployStep(bsl, bs) -{ - setDisplayName(tr("Check Development Mode")); -} - -bool BlackBerryCheckDevModeStep::init() -{ - if (!BlackBerryAbstractDeployStep::init()) - return false; - - QString deployCmd = target()->activeBuildConfiguration()->environment().searchInPath(QLatin1String(Constants::QNX_BLACKBERRY_DEPLOY_CMD)); - if (deployCmd.isEmpty()) { - raiseError(tr("Could not find command '%1' in the build environment") - .arg(QLatin1String(Constants::QNX_BLACKBERRY_DEPLOY_CMD))); - return false; - } - - BlackBerryDeviceConfiguration::ConstPtr device = BlackBerryDeviceConfiguration::device(target()->kit()); - QString deviceHost = device ? device->sshParameters().host : QString(); - if (deviceHost.isEmpty()) { - raiseError(tr("No hostname specified for device")); - return false; - } - - QStringList args; - args << QLatin1String("-listDeviceInfo"); - args << deviceHost; - if (!device->sshParameters().password.isEmpty()) { - args << QLatin1String("-password"); - args << device->sshParameters().password; - } - - addCommand(deployCmd, args); - - return true; -} - -ProjectExplorer::BuildStepConfigWidget *BlackBerryCheckDevModeStep::createConfigWidget() -{ - return new BlackBerryCheckDevModeStepConfigWidget(); -} - -QString BlackBerryCheckDevModeStep::password() const -{ - BlackBerryDeviceConfiguration::ConstPtr device = BlackBerryDeviceConfiguration::device(target()->kit()); - return device ? device->sshParameters().password : QString(); -} - -void BlackBerryCheckDevModeStep::processStarted(const ProjectExplorer::ProcessParameters ¶ms) -{ - QString arguments = params.prettyArguments(); - if (!password().isEmpty()) { - const QString passwordLine = QLatin1String(" -password ") + password(); - const QString hiddenPasswordLine = QLatin1String(" -password <hidden>"); - arguments.replace(passwordLine, hiddenPasswordLine); - } - - emitOutputInfo(params, arguments); -} diff --git a/src/plugins/qnx/blackberrydeployconfigurationfactory.cpp b/src/plugins/qnx/blackberrydeployconfigurationfactory.cpp index 44228ec761..5f96f4c791 100644 --- a/src/plugins/qnx/blackberrydeployconfigurationfactory.cpp +++ b/src/plugins/qnx/blackberrydeployconfigurationfactory.cpp @@ -32,7 +32,7 @@ #include "blackberrydeployconfigurationfactory.h" #include "qnxconstants.h" -#include "blackberrycheckdevmodestep.h" +#include "blackberrycheckdebugtokenstep.h" #include "blackberrydeployconfiguration.h" #include "blackberrycreatepackagestep.h" #include "blackberrydeploystep.h" @@ -93,7 +93,7 @@ ProjectExplorer::DeployConfiguration *BlackBerryDeployConfigurationFactory::crea return 0; BlackBerryDeployConfiguration *dc = new BlackBerryDeployConfiguration(parent); - dc->stepList()->insertStep(0, new BlackBerryCheckDevModeStep(dc->stepList())); + dc->stepList()->insertStep(0, new BlackBerryCheckDebugTokenStep(dc->stepList())); dc->stepList()->insertStep(1, new BlackBerryCreatePackageStep(dc->stepList())); dc->stepList()->insertStep(2, new BlackBerryDeployStep(dc->stepList())); return dc; diff --git a/src/plugins/qnx/blackberrydeviceinformation.cpp b/src/plugins/qnx/blackberrydeviceinformation.cpp index b9e67d3059..12d24bdb5c 100644 --- a/src/plugins/qnx/blackberrydeviceinformation.cpp +++ b/src/plugins/qnx/blackberrydeviceinformation.cpp @@ -68,6 +68,7 @@ void BlackBerryDeviceInformation::resetResults() m_deviceOS.clear(); m_hardwareId.clear(); m_debugTokenAuthor.clear(); + m_debugTokenValidationError.clear(); m_scmBundle.clear(); m_hostName.clear(); m_debugTokenValid = false; @@ -95,6 +96,11 @@ QString BlackBerryDeviceInformation::debugTokenAuthor() const return m_debugTokenAuthor; } +QString BlackBerryDeviceInformation::debugTokenValidationError() const +{ + return m_debugTokenValidationError; +} + QString BlackBerryDeviceInformation::scmBundle() const { return m_scmBundle; @@ -125,8 +131,9 @@ void BlackBerryDeviceInformation::processData(const QString &line) static const QString devicepin = QLatin1String("devicepin::0x"); static const QString device_os = QLatin1String("device_os::"); static const QString hardwareid = QLatin1String("hardwareid::"); - static const QString debug_token_author = QLatin1String("debug_token_author::"); - static const QString debug_token_valid = QLatin1String("debug_token_valid:b:"); + static const QString debug_token_author = QLatin1String("[n]debug_token_author::"); + static const QString debug_token_validation_error = QLatin1String("[n]debug_token_validation_error::"); + static const QString debug_token_valid = QLatin1String("[n]debug_token_valid:b:"); static const QString simulator = QLatin1String("simulator:b:"); static const QString scmbundle = QLatin1String("scmbundle::"); static const QString hostname = QLatin1String("hostname::"); @@ -140,6 +147,8 @@ void BlackBerryDeviceInformation::processData(const QString &line) m_hardwareId = line.mid(hardwareid.size()).trimmed(); else if (line.startsWith(debug_token_author)) m_debugTokenAuthor = line.mid(debug_token_author.size()).trimmed(); + else if (line.startsWith(debug_token_validation_error)) + m_debugTokenValidationError = line.mid(debug_token_validation_error.size()).trimmed(); else if (line.startsWith(debug_token_valid)) m_debugTokenValid = line.mid(debug_token_valid.size()).trimmed() == QLatin1String("true"); else if (line.startsWith(simulator)) diff --git a/src/plugins/qnx/blackberrydeviceinformation.h b/src/plugins/qnx/blackberrydeviceinformation.h index bbcc4ba4b3..d64f078f0c 100644 --- a/src/plugins/qnx/blackberrydeviceinformation.h +++ b/src/plugins/qnx/blackberrydeviceinformation.h @@ -62,6 +62,7 @@ public: QString deviceOS() const; QString hardwareId() const; QString debugTokenAuthor() const; + QString debugTokenValidationError() const; bool debugTokenValid() const; QString scmBundle() const; QString hostName() const; @@ -75,6 +76,7 @@ private: QString m_debugTokenAuthor; QString m_scmBundle; QString m_hostName; + QString m_debugTokenValidationError; bool m_debugTokenValid; bool m_isSimulator; bool m_isProductionDevice; diff --git a/src/plugins/qnx/blackberryndkprocess.cpp b/src/plugins/qnx/blackberryndkprocess.cpp index 56f52fbee3..d3d9bb3291 100644 --- a/src/plugins/qnx/blackberryndkprocess.cpp +++ b/src/plugins/qnx/blackberryndkprocess.cpp @@ -47,6 +47,7 @@ BlackBerryNdkProcess::BlackBerryNdkProcess(const QString &command, QObject *pare { m_process->setProcessChannelMode(QProcess::MergedChannels); + connect(m_process, SIGNAL(started()), this, SIGNAL(started())); connect(m_process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(processFinished())); connect(m_process, SIGNAL(error(QProcess::ProcessError)), diff --git a/src/plugins/qnx/blackberryndkprocess.h b/src/plugins/qnx/blackberryndkprocess.h index a73a3873d1..96d3279306 100644 --- a/src/plugins/qnx/blackberryndkprocess.h +++ b/src/plugins/qnx/blackberryndkprocess.h @@ -65,6 +65,7 @@ public: signals: void finished(int status); + void started(); protected: explicit BlackBerryNdkProcess(const QString &command, QObject *parent = 0); diff --git a/src/plugins/qnx/qnx.pro b/src/plugins/qnx/qnx.pro index 2f0b403b76..511888f146 100644 --- a/src/plugins/qnx/qnx.pro +++ b/src/plugins/qnx/qnx.pro @@ -69,9 +69,9 @@ SOURCES += qnxplugin.cpp \ blackberrydebugtokenuploader.cpp \ blackberrydebugtokenreader.cpp \ blackberryndkprocess.cpp \ - blackberrycheckdevmodestepfactory.cpp \ - blackberrycheckdevmodestep.cpp \ - blackberrycheckdevmodestepconfigwidget.cpp \ + blackberrycheckdebugtokenstep.cpp \ + blackberrycheckdebugtokenstepconfigwidget.cpp \ + blackberrycheckdebugtokenstepfactory.cpp \ blackberrydeviceconnection.cpp \ blackberrydeviceconnectionmanager.cpp \ blackberrydeviceinformation.cpp \ @@ -167,9 +167,9 @@ HEADERS += qnxplugin.h\ blackberrydebugtokenuploader.h \ blackberrydebugtokenreader.h \ blackberryndkprocess.h \ - blackberrycheckdevmodestepfactory.h \ - blackberrycheckdevmodestep.h \ - blackberrycheckdevmodestepconfigwidget.h \ + blackberrycheckdebugtokenstep.h \ + blackberrycheckdebugtokenstepconfigwidget.h \ + blackberrycheckdebugtokenstepfactory.h \ blackberrydeviceconnection.h \ blackberrydeviceconnectionmanager.h \ blackberrydeviceinformation.h \ diff --git a/src/plugins/qnx/qnx.qbs b/src/plugins/qnx/qnx.qbs index da95f3c55e..4be75bb4df 100644 --- a/src/plugins/qnx/qnx.qbs +++ b/src/plugins/qnx/qnx.qbs @@ -59,12 +59,12 @@ QtcPlugin { "blackberryabstractdeploystep.h", "blackberryapplicationrunner.cpp", "blackberryapplicationrunner.h", - "blackberrycheckdevmodestep.cpp", - "blackberrycheckdevmodestep.h", - "blackberrycheckdevmodestepconfigwidget.cpp", - "blackberrycheckdevmodestepconfigwidget.h", - "blackberrycheckdevmodestepfactory.cpp", - "blackberrycheckdevmodestepfactory.h", + "blackberrycheckdebugtokenstep.cpp", + "blackberrycheckdebugtokenstep.h", + "blackberrycheckdebugtokenstepconfigwidget.cpp", + "blackberrycheckdebugtokenstepconfigwidget.h", + "blackberrycheckdebugtokenstepfactory.cpp", + "blackberrycheckdebugtokenstepfactory.h", "blackberryconfigurationmanager.cpp", "blackberryconfigurationmanager.h", "blackberrycreatepackagestep.cpp", diff --git a/src/plugins/qnx/qnxconstants.h b/src/plugins/qnx/qnxconstants.h index 726657f748..c5c278eddd 100644 --- a/src/plugins/qnx/qnxconstants.h +++ b/src/plugins/qnx/qnxconstants.h @@ -69,7 +69,7 @@ const char QNX_QNX_RUNCONFIGURATION_PREFIX[] = "Qt4ProjectManager.QNX.QNXRunConf const char QNX_CREATE_PACKAGE_BS_ID[] = "Qt4ProjectManager.QnxCreatePackageBuildStep"; const char QNX_DEPLOY_PACKAGE_BS_ID[] = "Qt4ProjectManager.QnxDeployPackageBuildStep"; -const char QNX_CHECK_DEVELOPMENT_MODE_BS_ID[] = "Qt4ProjectManager.QnxCheckDevelopmentModeBuildStep"; +const char QNX_CHECK_DEBUG_TOKEN_BS_ID[] = "Qt4ProjectManager.QnxCheckDebugTokenBuildStep"; const char QNX_PROFILEPATH_KEY[] = "Qt4ProjectManager.QnxRunConfiguration.ProFilePath"; diff --git a/src/plugins/qnx/qnxplugin.cpp b/src/plugins/qnx/qnxplugin.cpp index 37c4216b2e..4184e094f2 100644 --- a/src/plugins/qnx/qnxplugin.cpp +++ b/src/plugins/qnx/qnxplugin.cpp @@ -49,7 +49,7 @@ #include "bardescriptoreditorfactory.h" #include "bardescriptormagicmatcher.h" #include "blackberrykeyspage.h" -#include "blackberrycheckdevmodestepfactory.h" +#include "blackberrycheckdebugtokenstepfactory.h" #include "blackberrydeviceconnectionmanager.h" #include "blackberryconfigurationmanager.h" #include "cascadesimport/cascadesimportwizard.h" @@ -91,7 +91,7 @@ bool QNXPlugin::initialize(const QStringList &arguments, QString *errorString) addAutoReleasedObject(new BlackBerryRunControlFactory); addAutoReleasedObject(new BlackBerryNDKSettingsPage); addAutoReleasedObject(new BlackBerryKeysPage); - addAutoReleasedObject(new BlackBerryCheckDevModeStepFactory); + addAutoReleasedObject(new BlackBerryCheckDebugTokenStepFactory); addAutoReleasedObject(new CascadesImportWizard); BlackBerryDeviceConnectionManager::instance()->initialize(); diff --git a/src/plugins/resourceeditor/resourceeditorw.cpp b/src/plugins/resourceeditor/resourceeditorw.cpp index f81f7b2a82..faef490d58 100644 --- a/src/plugins/resourceeditor/resourceeditorw.cpp +++ b/src/plugins/resourceeditor/resourceeditorw.cpp @@ -110,7 +110,7 @@ ResourceEditorW::ResourceEditorW(const Core::Context &context, // (That is because this editor instance is deleted in executeOpenWithMenuAction // in that case.) connect(m_openWithMenu, SIGNAL(triggered(QAction*)), - Core::DocumentManager::instance(), SLOT(slotExecuteOpenWithMenuAction(QAction*)), + Core::DocumentManager::instance(), SLOT(executeOpenWithMenuAction(QAction*)), Qt::QueuedConnection); connect(m_resourceEditor, SIGNAL(dirtyChanged(bool)), m_resourceDocument, SLOT(dirtyChanged(bool))); diff --git a/src/plugins/subversion/checkoutwizard.cpp b/src/plugins/subversion/checkoutwizard.cpp index ed69c29e37..872cf16cfe 100644 --- a/src/plugins/subversion/checkoutwizard.cpp +++ b/src/plugins/subversion/checkoutwizard.cpp @@ -30,6 +30,7 @@ #include "checkoutwizard.h" #include "checkoutwizardpage.h" #include "subversionplugin.h" +#include "subversionclient.h" #include <coreplugin/iversioncontrol.h> #include <vcsbase/command.h> @@ -78,7 +79,7 @@ VcsBase::Command *CheckoutWizard::createCommand(const QList<QWizardPage*> ¶m if (settings.hasAuthentication()) { const QString user = settings.stringValue(SubversionSettings::userKey); const QString pwd = settings.stringValue(SubversionSettings::passwordKey); - args = SubversionPlugin::addAuthenticationOptions(args, user, pwd); + args = SubversionClient::addAuthenticationOptions(args, user, pwd); } VcsBase::Command *command = new VcsBase::Command(binary, workingDirectory, QProcessEnvironment::systemEnvironment()); diff --git a/src/plugins/subversion/subversion.pro b/src/plugins/subversion/subversion.pro index 6d2d9e21c0..ae8e211b62 100644 --- a/src/plugins/subversion/subversion.pro +++ b/src/plugins/subversion/subversion.pro @@ -2,6 +2,7 @@ include(../../qtcreatorplugin.pri) HEADERS += annotationhighlighter.h \ subversionplugin.h \ + subversionclient.h \ subversioncontrol.h \ settingspage.h \ subversioneditor.h \ @@ -13,6 +14,7 @@ HEADERS += annotationhighlighter.h \ SOURCES += annotationhighlighter.cpp \ subversionplugin.cpp \ + subversionclient.cpp \ subversioncontrol.cpp \ settingspage.cpp \ subversioneditor.cpp \ diff --git a/src/plugins/subversion/subversion.qbs b/src/plugins/subversion/subversion.qbs index d213ce0f77..6c3c48286f 100644 --- a/src/plugins/subversion/subversion.qbs +++ b/src/plugins/subversion/subversion.qbs @@ -23,6 +23,8 @@ QtcPlugin { "settingspage.h", "settingspage.ui", "subversion.qrc", + "subversionclient.cpp", + "subversionclient.h", "subversionconstants.h", "subversioncontrol.cpp", "subversioncontrol.h", diff --git a/src/plugins/subversion/subversionclient.cpp b/src/plugins/subversion/subversionclient.cpp new file mode 100644 index 0000000000..27ad0c655e --- /dev/null +++ b/src/plugins/subversion/subversionclient.cpp @@ -0,0 +1,216 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "subversionclient.h" +#include "subversionsettings.h" + +#include <vcsbase/vcsbaseplugin.h> +#include <vcsbase/vcsbaseconstants.h> +#include <vcsbase/vcsbaseeditorparameterwidget.h> +#include <utils/synchronousprocess.h> + +#include <QDir> +#include <QFileInfo> +#include <QTextStream> +#include <QDebug> + +namespace Subversion { +namespace Internal { + +// Collect all parameters required for a diff to be able to associate them +// with a diff editor and re-run the diff with parameters. +struct SubversionDiffParameters +{ + QString workingDir; + QStringList extraOptions; + QStringList files; +}; + +// Parameter widget controlling whitespace diff mode, associated with a parameter +class SubversionDiffParameterWidget : public VcsBase::VcsBaseEditorParameterWidget +{ + Q_OBJECT +public: + explicit SubversionDiffParameterWidget(SubversionClient *client, + const SubversionDiffParameters &p, + QWidget *parent = 0); + QStringList arguments() const; + void executeCommand(); + +private: + SubversionClient *m_client; + const SubversionDiffParameters m_params; +}; + +SubversionDiffParameterWidget::SubversionDiffParameterWidget(SubversionClient *client, + const SubversionDiffParameters &p, + QWidget *parent) + : VcsBase::VcsBaseEditorParameterWidget(parent), m_client(client), m_params(p) +{ + mapSetting(addToggleButton(QLatin1String("w"), tr("Ignore Whitespace")), + client->settings()->boolPointer(SubversionSettings::diffIgnoreWhiteSpaceKey)); +} + +QStringList SubversionDiffParameterWidget::arguments() const +{ + QStringList args; + // Subversion wants" -x -<ext-args>", default being -u + const QStringList formatArguments = VcsBaseEditorParameterWidget::arguments(); + if (!formatArguments.isEmpty()) { + args << QLatin1String("-x") + << (QLatin1String("-u") + formatArguments.join(QString())); + } + return args; +} + +void SubversionDiffParameterWidget::executeCommand() +{ + m_client->diff(m_params.workingDir, m_params.files, m_params.extraOptions); +} + +SubversionClient::SubversionClient(SubversionSettings *settings) : + VcsBase::VcsBaseClient(settings) +{ +} + +SubversionSettings *SubversionClient::settings() const +{ + return dynamic_cast<SubversionSettings *>(VcsBase::VcsBaseClient::settings()); +} + +Core::Id SubversionClient::vcsEditorKind(VcsCommand cmd) const +{ + switch (cmd) { + case DiffCommand: + return "Subversion Diff Editor"; // TODO: create subversionconstants.h + default: + return Core::Id(); + } +} + +SubversionClient::Version SubversionClient::svnVersion() +{ + if (m_svnVersionBinary != settings()->binaryPath()) { + QStringList args; + args << QLatin1String("--version") << QLatin1String("-q"); + const Utils::SynchronousProcessResponse response = + VcsBase::VcsBasePlugin::runVcs(QDir().absolutePath(), settings()->binaryPath(), + args, settings()->timeOutMs()); + if (response.result == Utils::SynchronousProcessResponse::Finished && + response.exitCode == 0) { + m_svnVersionBinary = settings()->binaryPath(); + m_svnVersion = response.stdOut.trimmed(); + } else { + m_svnVersionBinary.clear(); + m_svnVersion.clear(); + } + } + + SubversionClient::Version v; + if (::sscanf(m_svnVersion.toLatin1().constData(), "%d.%d.%d", + &v.majorVersion, &v.minorVersion, &v.patchVersion) != 3) { + v.majorVersion = v.minorVersion = v.patchVersion = -1; + } + + return v; +} + +// Add authorization options to the command line arguments. +// SVN pre 1.5 does not accept "--userName" for "add", which is most likely +// an oversight. As no password is needed for the option, generally omit it. +QStringList SubversionClient::addAuthenticationOptions(const QStringList &args, + const QString &userName, + const QString &password) +{ + if (userName.isEmpty()) + return args; + if (!args.empty() && args.front() == QLatin1String("add")) + return args; + QStringList rc; + rc.push_back(QLatin1String("--username")); + rc.push_back(userName); + if (!password.isEmpty()) { + rc.push_back(QLatin1String("--password")); + rc.push_back(password); + } + rc.append(args); + return rc; +} + +void SubversionClient::diff(const QString &workingDir, const QStringList &files, + const QStringList &extraOptions) +{ + QStringList args(extraOptions); + Version v = svnVersion(); + + // --internal-diff is new in v1.7.0 + if (v.majorVersion > 1 || (v.majorVersion == 1 && v.minorVersion >= 7)) + args.append(QLatin1String("--internal-diff")); + + const bool hasAuth = settings()->hasAuthentication(); + const QString userName = hasAuth ? settings()->stringValue(SubversionSettings::userKey) : QString(); + const QString password = hasAuth ? settings()->stringValue(SubversionSettings::passwordKey) : QString(); + args = addAuthenticationOptions(args, userName, password); + + VcsBaseClient::diff(workingDir, files, args); +} + +QString SubversionClient::findTopLevelForFile(const QFileInfo &file) const +{ + Q_UNUSED(file) + return QString(); +} + +QStringList SubversionClient::revisionSpec(const QString &revision) const +{ + Q_UNUSED(revision) + return QStringList(); +} + +VcsBase::VcsBaseClient::StatusItem SubversionClient::parseStatusLine(const QString &line) const +{ + Q_UNUSED(line) + return VcsBase::VcsBaseClient::StatusItem(); +} + +VcsBase::VcsBaseEditorParameterWidget *SubversionClient::createDiffEditor( + const QString &workingDir, const QStringList &files, const QStringList &extraOptions) +{ + Q_UNUSED(extraOptions) + SubversionDiffParameters p; + p.workingDir = workingDir; + p.files = files; + p.extraOptions = extraOptions; + return new SubversionDiffParameterWidget(this, p); +} + +} // namespace Internal +} // namespace Subversion + +#include "subversionclient.moc" diff --git a/src/plugins/subversion/subversionclient.h b/src/plugins/subversion/subversionclient.h new file mode 100644 index 0000000000..e95dcea2a7 --- /dev/null +++ b/src/plugins/subversion/subversionclient.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef SUBVERSIONCLIENT_H +#define SUBVERSIONCLIENT_H + +#include "subversionsettings.h" +#include <vcsbase/vcsbaseclient.h> + +namespace Subversion { +namespace Internal { + +class SubversionSettings; + +class SubversionClient : public VcsBase::VcsBaseClient +{ + Q_OBJECT + +public: + SubversionClient(SubversionSettings *settings); + + SubversionSettings *settings() const; + void diff(const QString &workingDir, const QStringList &files, + const QStringList &extraOptions = QStringList()); + QString findTopLevelForFile(const QFileInfo &file) const; + QStringList revisionSpec(const QString &revision) const; + StatusItem parseStatusLine(const QString &line) const; + + class Version { + public: + int majorVersion; + int minorVersion; + int patchVersion; + }; + + Version svnVersion(); + + // Add authorization options to the command line arguments. + static QStringList addAuthenticationOptions(const QStringList &args, + const QString &userName = QString(), + const QString &password = QString()); + +protected: + Core::Id vcsEditorKind(VcsCommand cmd) const; + VcsBase::VcsBaseEditorParameterWidget *createDiffEditor(const QString &workingDir, + const QStringList &files, + const QStringList &extraOptions); +private: + QString m_svnVersionBinary; + QString m_svnVersion; +}; + +} // namespace Internal +} // namespace Subversion + +#endif // SUBVERSIONCLIENT_H diff --git a/src/plugins/subversion/subversionplugin.cpp b/src/plugins/subversion/subversionplugin.cpp index de57be400e..8eb8db8613 100644 --- a/src/plugins/subversion/subversionplugin.cpp +++ b/src/plugins/subversion/subversionplugin.cpp @@ -33,6 +33,7 @@ #include "subversioneditor.h" #include "subversionsubmiteditor.h" +#include "subversionclient.h" #include "subversionconstants.h" #include "subversioncontrol.h" #include "checkoutwizard.h" @@ -209,6 +210,7 @@ SubversionPlugin::SubversionPlugin() : SubversionPlugin::~SubversionPlugin() { + delete m_client; cleanCommitMessageFile(); } @@ -251,6 +253,7 @@ bool SubversionPlugin::initialize(const QStringList & /*arguments */, QString *e return false; m_settings.readSettings(Core::ICore::settings()); + m_client = new SubversionClient(&m_settings); addAutoReleasedObject(new SettingsPage); @@ -497,117 +500,7 @@ bool SubversionPlugin::submitEditorAboutToClose() void SubversionPlugin::diffCommitFiles(const QStringList &files) { - svnDiff(m_commitRepository, files); -} - -// Collect all parameters required for a diff to be able to associate them -// with a diff editor and re-run the diff with parameters. -struct SubversionDiffParameters -{ - QString workingDir; - QStringList arguments; - QStringList files; - QString diffName; -}; - -// Parameter widget controlling whitespace diff mode, associated with a parameter -class SubversionDiffParameterWidget : public VcsBase::VcsBaseEditorParameterWidget -{ - Q_OBJECT -public: - explicit SubversionDiffParameterWidget(const SubversionDiffParameters &p, QWidget *parent = 0); - -signals: - void reRunDiff(const Subversion::Internal::SubversionDiffParameters &); - -private slots: - void triggerReRun(); - -private: - const SubversionDiffParameters m_parameters; -}; - -SubversionDiffParameterWidget::SubversionDiffParameterWidget(const SubversionDiffParameters &p, QWidget *parent) : - VcsBase::VcsBaseEditorParameterWidget(parent), m_parameters(p) -{ - setBaseArguments(p.arguments); - addToggleButton(QLatin1String("w"), tr("Ignore Whitespace")); - connect(this, SIGNAL(argumentsChanged()), this, SLOT(triggerReRun())); -} - -void SubversionDiffParameterWidget::triggerReRun() -{ - SubversionDiffParameters effectiveParameters = m_parameters; - // Subversion wants" -x -<ext-args>", default being -u - const QStringList a = arguments(); - if (!a.isEmpty()) - effectiveParameters.arguments << QLatin1String("-x") << (QLatin1String("-u") + a.join(QString())); - emit reRunDiff(effectiveParameters); -} - -static inline void setWorkingDirectory(Core::IEditor *editor, const QString &wd) -{ - if (VcsBase::VcsBaseEditorWidget *ve = qobject_cast<VcsBase::VcsBaseEditorWidget*>(editor->widget())) - ve->setWorkingDirectory(wd); -} - -void SubversionPlugin::svnDiff(const QString &workingDir, const QStringList &files, QString diffname) -{ - SubversionDiffParameters p; - p.workingDir = workingDir; - p.files = files; - p.diffName = diffname; - svnDiff(p); -} - -void SubversionPlugin::svnDiff(const Subversion::Internal::SubversionDiffParameters &p) -{ - if (Subversion::Constants::debug) - qDebug() << Q_FUNC_INFO << p.files << p.diffName; - const QString source = VcsBase::VcsBaseEditorWidget::getSource(p.workingDir, p.files); - QTextCodec *codec = source.isEmpty() ? static_cast<QTextCodec *>(0) : VcsBase::VcsBaseEditorWidget::getCodec(source); - - const QString diffName = p.files.count() == 1 && p.diffName.isEmpty() ? - QFileInfo(p.files.front()).fileName() : p.diffName; - - QStringList args(QLatin1String("diff")); - Version v = svnVersion(); - if (v.majorVersion > 1 - || (v.majorVersion == 1 && v.minorVersion >= 7)) // --internal-diff is new in v1.7.0 - args.append(QLatin1String("--internal-diff")); - args.append(p.arguments); - args << p.files; - - const SubversionResponse response = - runSvn(p.workingDir, args, m_settings.timeOutMs(), 0, codec); - if (response.error) - return; - - // diff of a single file? re-use an existing view if possible to support - // the common usage pattern of continuously changing and diffing a file - const QString tag = VcsBase::VcsBaseEditorWidget::editorTag(VcsBase::DiffOutput, p.workingDir, p.files); - // Show in the same editor if diff has been executed before - if (Core::IEditor *existingEditor = VcsBase::VcsBaseEditorWidget::locateEditorByTag(tag)) { - existingEditor->document()->setContents(response.stdOut.toUtf8()); - Core::EditorManager::activateEditor(existingEditor); - setWorkingDirectory(existingEditor, p.workingDir); - return; - } - const QString title = QString::fromLatin1("svn diff %1").arg(diffName); - Core::IEditor *editor = showOutputInEditor(title, response.stdOut, VcsBase::DiffOutput, source, codec); - setWorkingDirectory(editor, p.workingDir); - VcsBase::VcsBaseEditorWidget::tagEditor(editor, tag); - SubversionEditor *diffEditorWidget = qobject_cast<SubversionEditor *>(editor->widget()); - QTC_ASSERT(diffEditorWidget, return); - - // Wire up the parameter widget to trigger a re-run on - // parameter change and 'revert' from inside the diff editor. - SubversionDiffParameterWidget *pw = new SubversionDiffParameterWidget(p); - connect(pw, SIGNAL(reRunDiff(Subversion::Internal::SubversionDiffParameters)), - this, SLOT(svnDiff(Subversion::Internal::SubversionDiffParameters))); - connect(diffEditorWidget, SIGNAL(diffChunkReverted(VcsBase::DiffChunk)), - pw, SLOT(triggerReRun())); - diffEditorWidget->setConfigurationWidget(pw); + m_client->diff(m_commitRepository, files); } SubversionSubmitEditor *SubversionPlugin::openSubversionSubmitEditor(const QString &fileName) @@ -724,15 +617,16 @@ void SubversionPlugin::diffProject() { const VcsBase::VcsBasePluginState state = currentState(); QTC_ASSERT(state.hasProject(), return); - svnDiff(state.currentProjectTopLevel(), QStringList(state.relativeCurrentProject()), - state.currentProjectName()); + const QString relativeProject = state.relativeCurrentProject(); + m_client->diff(state.currentProjectTopLevel(), + relativeProject.isEmpty() ? QStringList() : QStringList(relativeProject)); } void SubversionPlugin::diffCurrentFile() { const VcsBase::VcsBasePluginState state = currentState(); QTC_ASSERT(state.hasFile(), return); - svnDiff(state.currentFileTopLevel(), QStringList(state.relativeCurrentFile())); + m_client->diff(state.currentFileTopLevel(), QStringList(state.relativeCurrentFile())); } void SubversionPlugin::startCommitCurrentFile() @@ -842,7 +736,7 @@ void SubversionPlugin::diffRepository() { const VcsBase::VcsBasePluginState state = currentState(); QTC_ASSERT(state.hasTopLevel(), return); - svnDiff(state.topLevel(), QStringList()); + m_client->diff(state.topLevel(), QStringList()); } void SubversionPlugin::statusRepository() @@ -1092,53 +986,6 @@ SubversionResponse arguments, timeOut, flags, outputCodec); } -// Add authorization options to the command line arguments. -// SVN pre 1.5 does not accept "--userName" for "add", which is most likely -// an oversight. As no password is needed for the option, generally omit it. -QStringList SubversionPlugin::addAuthenticationOptions(const QStringList &args, - const QString &userName, const QString &password) -{ - if (userName.isEmpty()) - return args; - if (!args.empty() && args.front() == QLatin1String("add")) - return args; - QStringList rc; - rc.push_back(QLatin1String("--username")); - rc.push_back(userName); - if (!password.isEmpty()) { - rc.push_back(QLatin1String("--password")); - rc.push_back(password); - } - rc.append(args); - return rc; -} - -SubversionPlugin::Version SubversionPlugin::svnVersion() -{ - if (m_svnVersionBinary != m_settings.binaryPath()) { - QStringList args; - args << QLatin1String("--version") << QLatin1String("-q"); - const Utils::SynchronousProcessResponse response = - VcsBase::VcsBasePlugin::runVcs(QDir().absolutePath(), m_settings.binaryPath(), - args, m_settings.timeOutMs()); - if (response.result == Utils::SynchronousProcessResponse::Finished && - response.exitCode == 0) { - m_svnVersionBinary = m_settings.binaryPath(); - m_svnVersion = response.stdOut.trimmed(); - } else { - m_svnVersionBinary.clear(); - m_svnVersion.clear(); - } - } - - SubversionPlugin::Version v; - if (::sscanf(m_svnVersion.toLatin1().constData(), "%d.%d.%d", - &v.majorVersion, &v.minorVersion, &v.patchVersion) != 3) - v.majorVersion = v.minorVersion = v.patchVersion = -1; - - return v; -} - SubversionResponse SubversionPlugin::runSvn(const QString &workingDir, const QString &userName, const QString &password, const QStringList &arguments, int timeOut, @@ -1152,7 +999,7 @@ SubversionResponse SubversionPlugin::runSvn(const QString &workingDir, return response; } - const QStringList completeArguments = SubversionPlugin::addAuthenticationOptions(arguments, userName, password); + const QStringList completeArguments = SubversionClient::addAuthenticationOptions(arguments, userName, password); const Utils::SynchronousProcessResponse sp_resp = VcsBase::VcsBasePlugin::runVcs(workingDir, executable, completeArguments, timeOut, flags, outputCodec); @@ -1446,4 +1293,3 @@ void SubversionPlugin::testLogResolving() Q_EXPORT_PLUGIN(Subversion::Internal::SubversionPlugin) -#include "subversionplugin.moc" diff --git a/src/plugins/subversion/subversionplugin.h b/src/plugins/subversion/subversionplugin.h index 82940f1ae6..d6ddd80ce1 100644 --- a/src/plugins/subversion/subversionplugin.h +++ b/src/plugins/subversion/subversionplugin.h @@ -62,7 +62,7 @@ namespace Internal { class SubversionSubmitEditor; class SubversionControl; -struct SubversionDiffParameters; +class SubversionClient; struct SubversionResponse { @@ -84,8 +84,6 @@ public: bool initialize(const QStringList &arguments, QString *errorMessage); - void svnDiff(const QString &workingDir, const QStringList &files, QString diffname = QString()); - SubversionSubmitEditor *openSubversionSubmitEditor(const QString &fileName); SubversionSettings settings() const; @@ -102,24 +100,9 @@ public: static SubversionPlugin *instance(); - // Add authorization options to the command line arguments. - static QStringList addAuthenticationOptions(const QStringList &args, - const QString &userName = QString(), - const QString &password = QString()); - - class Version { - public: - int majorVersion; - int minorVersion; - int patchVersion; - }; - - Version svnVersion(); - public slots: void vcsAnnotate(const QString &workingDir, const QString &file, const QString &revision = QString(), int lineNumber = -1); - void svnDiff(const Subversion::Internal::SubversionDiffParameters &p); private slots: void addCurrentFile(); @@ -183,6 +166,7 @@ private: const QStringList m_svnDirectories; SubversionSettings m_settings; + SubversionClient *m_client; QString m_commitMessageFileName; QString m_commitRepository; @@ -214,9 +198,6 @@ private: QAction *m_menuAction; bool m_submitActionTriggered; - QString m_svnVersionBinary; - QString m_svnVersion; - static SubversionPlugin *m_subversionPluginInstance; }; diff --git a/src/plugins/subversion/subversionsettings.cpp b/src/plugins/subversion/subversionsettings.cpp index fe17e1c6bf..c066f0f7d6 100644 --- a/src/plugins/subversion/subversionsettings.cpp +++ b/src/plugins/subversion/subversionsettings.cpp @@ -41,6 +41,7 @@ const QLatin1String SubversionSettings::useAuthenticationKey("Authentication"); const QLatin1String SubversionSettings::userKey("User"); const QLatin1String SubversionSettings::passwordKey("Password"); const QLatin1String SubversionSettings::spaceIgnorantAnnotationKey("SpaceIgnorantAnnotation"); +const QLatin1String SubversionSettings::diffIgnoreWhiteSpaceKey("DiffIgnoreWhiteSpace"); SubversionSettings::SubversionSettings() { @@ -51,6 +52,7 @@ SubversionSettings::SubversionSettings() declareKey(userKey, QLatin1String("")); declareKey(passwordKey, QLatin1String("")); declareKey(spaceIgnorantAnnotationKey, true); + declareKey(diffIgnoreWhiteSpaceKey, false); } bool SubversionSettings::hasAuthentication() const diff --git a/src/plugins/subversion/subversionsettings.h b/src/plugins/subversion/subversionsettings.h index a91d9c942d..f986f32aeb 100644 --- a/src/plugins/subversion/subversionsettings.h +++ b/src/plugins/subversion/subversionsettings.h @@ -42,6 +42,7 @@ public: static const QLatin1String userKey; static const QLatin1String passwordKey; static const QLatin1String spaceIgnorantAnnotationKey; + static const QLatin1String diffIgnoreWhiteSpaceKey; SubversionSettings(); bool hasAuthentication() const; diff --git a/src/plugins/vcsbase/vcsbaseclient.cpp b/src/plugins/vcsbase/vcsbaseclient.cpp index 551209eaf2..540c82b421 100644 --- a/src/plugins/vcsbase/vcsbaseclient.cpp +++ b/src/plugins/vcsbase/vcsbaseclient.cpp @@ -367,7 +367,9 @@ void VcsBaseClient::diff(const QString &workingDir, const QStringList &files, QStringList args; const QStringList paramArgs = paramWidget != 0 ? paramWidget->arguments() : QStringList(); args << vcsCmdString << extraOptions << paramArgs << files; + QTextCodec *codec = source.isEmpty() ? static_cast<QTextCodec *>(0) : VcsBase::VcsBaseEditorWidget::getCodec(source); Command *command = createCommand(workingDir, editor); + command->setCodec(codec); enqueueJob(command, args, exitCodeInterpreter(DiffCommand, command)); } |