diff options
author | Eike Ziller <[email protected]> | 2012-09-26 10:01:04 +0200 |
---|---|---|
committer | Eike Ziller <[email protected]> | 2012-09-26 10:01:04 +0200 |
commit | a55d47544a104bbe8270bd6b5a72a1215018059c (patch) | |
tree | a922470562cd187d1b986a8db0df776e37cdc248 /src/plugins/clearcase/clearcaseplugin.cpp | |
parent | 996122b7e9c05c5baca56809d8cd2cf1b58a9f39 (diff) | |
parent | 471f44aae3ca09d445ae4f424b2242b371580a3e (diff) |
Merge remote-tracking branch 'origin/2.6'
Conflicts:
qtcreator.qbp
src/plugins/qtsupport/baseqtversion.cpp
src/tools/tools.pro
Change-Id: I43c391328ae747b3dc566f9db2384fedc1a6d0a5
Diffstat (limited to 'src/plugins/clearcase/clearcaseplugin.cpp')
-rw-r--r-- | src/plugins/clearcase/clearcaseplugin.cpp | 126 |
1 files changed, 100 insertions, 26 deletions
diff --git a/src/plugins/clearcase/clearcaseplugin.cpp b/src/plugins/clearcase/clearcaseplugin.cpp index 2adbd379d12..65169666ab4 100644 --- a/src/plugins/clearcase/clearcaseplugin.cpp +++ b/src/plugins/clearcase/clearcaseplugin.cpp @@ -85,18 +85,20 @@ #include <QMenu> #include <QMessageBox> #include <QMutex> -#include <QTemporaryFile> -#include <QTextCodec> #include <QProcess> +#include <QRegExp> #include <QSharedPointer> +#include <QtConcurrentRun> +#include <QTemporaryFile> +#include <QTextCodec> #include <QTimer> +#include <QtPlugin> #include <QUrl> #include <QUuid> #include <QVariant> #include <QVBoxLayout> #include <QXmlStreamReader> -#include <QtConcurrentRun> -#include <QtPlugin> + namespace ClearCase { namespace Internal { @@ -161,6 +163,8 @@ ClearCasePlugin *ClearCasePlugin::m_clearcasePluginInstance = 0; ClearCasePlugin::ClearCasePlugin() : VcsBase::VcsBasePlugin(QLatin1String(ClearCase::Constants::CLEARCASECHECKINEDITOR_ID)), + m_isDynamic(false), + m_isUcm(false), m_commandLocator(0), m_checkOutAction(0), m_checkInCurrentAction(0), @@ -211,6 +215,14 @@ bool ClearCasePlugin::isCheckInEditorOpen() const return !m_checkInMessageFileName.isEmpty(); } +/*! Find top level for view that contains \a directory + * + * - Snapshot Views will have the CLEARCASE_ROOT_FILE (view.dat) in its top dir + * - Dynamic views can either be + * - M:/view_name, + * - or mapped to a drive letter, like Z:/ + * (drive letters are just examples) + */ QString ClearCasePlugin::findTopLevel(const QString &directory) const { // Snapshot view @@ -218,6 +230,7 @@ QString ClearCasePlugin::findTopLevel(const QString &directory) const findRepositoryForDirectory(directory, QLatin1String(ClearCase::Constants::CLEARCASE_ROOT_FILE)); if (!topLevel.isEmpty() || !clearCaseControl()->isConfigured()) return topLevel; + // Dynamic view if (directory.startsWith(m_topLevel) && directory.at(m_topLevel.size()) == QLatin1Char('/')) return m_topLevel; @@ -554,7 +567,7 @@ QString ClearCasePlugin::ccGetFileActivity(const QString &workingDir, const QStr return response.stdOut; } -ClearCaseSubmitEditor *ClearCasePlugin::openClearCaseSubmitEditor(const QString &fileName) +ClearCaseSubmitEditor *ClearCasePlugin::openClearCaseSubmitEditor(const QString &fileName, bool isUcm) { Core::IEditor *editor = Core::EditorManager::openEditor(fileName, @@ -565,18 +578,28 @@ ClearCaseSubmitEditor *ClearCasePlugin::openClearCaseSubmitEditor(const QString submitEditor->registerActions(m_submitUndoAction, m_submitRedoAction, m_checkInSelectedAction, m_checkInDiffAction); connect(submitEditor, SIGNAL(diffSelectedFiles(QStringList)), this, SLOT(diffCheckInFiles(QStringList))); submitEditor->setCheckScriptWorkingDirectory(m_checkInView); + submitEditor->setIsUcm(isUcm); return submitEditor; } void ClearCasePlugin::updateStatusActions() { bool hasFile = currentState().hasFile(); - FileStatus fileStatus = m_statusMap->value(currentState().relativeCurrentFile(), FileStatus(FileStatus::Unknown)); + QString fileName = currentState().relativeCurrentFile(); + + FileStatus fileStatus = m_statusMap->value(fileName, FileStatus(FileStatus::Unknown)); + + if (ClearCase::Constants::debug) + qDebug() << Q_FUNC_INFO << fileName << ", status = " << fileStatus.status; + m_checkOutAction->setEnabled(hasFile && (fileStatus.status & (FileStatus::CheckedIn | FileStatus::Hijacked))); m_undoCheckOutAction->setEnabled(hasFile && (fileStatus.status & FileStatus::CheckedOut)); - m_undoHijackAction->setEnabled(hasFile && (fileStatus.status & FileStatus::Hijacked)); + m_undoHijackAction->setEnabled(!m_isDynamic && hasFile && (fileStatus.status & FileStatus::Hijacked)); m_checkInCurrentAction->setEnabled(hasFile && (fileStatus.status & FileStatus::CheckedOut)); m_addFileAction->setEnabled(hasFile && (fileStatus.status & FileStatus::NotManaged)); + + m_checkInActivityAction->setEnabled(m_isUcm); + m_diffActivityAction->setEnabled(m_isUcm); } void ClearCasePlugin::updateActions(VcsBase::VcsBasePlugin::ActionState as) @@ -591,7 +614,7 @@ void ClearCasePlugin::updateActions(VcsBase::VcsBasePlugin::ActionState as) if (hasTopLevel) m_topLevel = state.topLevel(); - m_updateViewAction->setParameter(m_view); + m_updateViewAction->setParameter(m_isDynamic ? QString() : m_view); const QString fileName = state.currentFileName(); m_checkOutAction->setParameter(fileName); @@ -679,6 +702,12 @@ bool ClearCasePlugin::vcsUndoCheckOut(const QString &workingDir, const QString & return !response.error; } + +/*! Undo a hijacked file in a snapshot view + * + * Runs cleartool update -overwrite \a fileName in \a workingDir + * if \a keep is true, renames hijacked files to <filename>.keep. Otherwise it is overwritten + */ bool ClearCasePlugin::vcsUndoHijack(const QString &workingDir, const QString &fileName, bool keep) { if (ClearCase::Constants::debug) @@ -913,8 +942,11 @@ void ClearCasePlugin::startCheckInAll() void ClearCasePlugin::startCheckInActivity() { + QTC_ASSERT(isUcm(), return); + const VcsBase::VcsBasePluginState state = currentState(); QTC_ASSERT(state.hasProject(), return); + QDialog dlg; QVBoxLayout *layout = new QVBoxLayout(&dlg); ActivitySelector *actSelector = new ActivitySelector(&dlg); @@ -926,6 +958,7 @@ void ClearCasePlugin::startCheckInActivity() dlg.setWindowTitle(tr("Check In Activity")); if (!dlg.exec()) return; + QString topLevel = state.topLevel(); int topLevelLen = topLevel.length(); QStringList versions = ccGetActivityVersions(topLevel, actSelector->activity()); @@ -976,9 +1009,10 @@ void ClearCasePlugin::startCheckIn(const QString &workingDir, const QStringList m_checkInMessageFileName = saver.fileName(); m_checkInView = workingDir; // Create a submit editor and set file list - ClearCaseSubmitEditor *editor = openClearCaseSubmitEditor(m_checkInMessageFileName); + ClearCaseSubmitEditor *editor = openClearCaseSubmitEditor(m_checkInMessageFileName, m_isUcm); editor->setStatusList(files); - if (files.size() == 1) { + + if (m_isUcm && (files.size() == 1)) { QString activity = ccGetFileActivity(workingDir, files.first()); editor->submitEditorWidget()->setActivity(activity); } @@ -1038,6 +1072,8 @@ void ClearCasePlugin::history(const QString &workingDir, void ClearCasePlugin::viewStatus() { + if (m_view.isEmpty()) + m_view = ccGetView(m_topLevel); QTC_ASSERT(!m_view.isEmpty() && !m_settings.disableIndexer, return); VcsBase::VcsBaseOutputWindow *outputwindow = VcsBase::VcsBaseOutputWindow::instance(); outputwindow->appendCommand(QLatin1String("Indexed files status (C=Checked Out, H=Hijacked, ?=Missing)")); @@ -1282,7 +1318,8 @@ bool ClearCasePlugin::vcsOpen(const QString &workingDir, const QString &fileName const QString file = QDir::toNativeSeparators(relFile); const QString title = QString::fromLatin1("Checkout %1").arg(file); - CheckOutDialog coDialog(title); + CheckOutDialog coDialog(title, m_isUcm); + if (!m_settings.disableIndexer && (fi.isWritable() || m_statusMap->value(relFile).status == FileStatus::Unknown)) QtConcurrent::run(&sync, topLevel, QStringList(relFile)).waitForFinished(); @@ -1290,12 +1327,14 @@ bool ClearCasePlugin::vcsOpen(const QString &workingDir, const QString &fileName QMessageBox::information(0, tr("ClearCase Checkout"), tr("File is already checked out.")); return true; } - bool isHijacked = (m_statusMap->value(relFile).status & FileStatus::Hijacked); + // Only snapshot views can have hijacked files + bool isHijacked = (!m_isDynamic && (m_statusMap->value(relFile).status & FileStatus::Hijacked)); if (!isHijacked) coDialog.hideHijack(); if (coDialog.exec() == QDialog::Accepted) { - if (!vcsSetActivity(topLevel, title, coDialog.activity())) + if (m_isUcm && !vcsSetActivity(topLevel, title, coDialog.activity())) return false; + Core::FileChangeBlocker fcb(absPath); QStringList args(QLatin1String("checkout")); QString comment = coDialog.comment(); @@ -1311,6 +1350,14 @@ bool ClearCasePlugin::vcsOpen(const QString &workingDir, const QString &fileName if (coDialog.isPreserveTime()) args << QLatin1String("-ptime"); if (isHijacked) { + if (ClearCase::Constants::debug) + qDebug() << Q_FUNC_INFO << file << " seems to be hijacked"; + + // A hijacked files means that the file is modified but was + // not checked out. By checking it out now changes will + // be lost, unless handled. This can be done by renaming + // the hijacked file, undoing the hijack and updating the file + // -usehijack not supported in old cleartool versions... // args << QLatin1String("-usehijack"); if (coDialog.isUseHijacked()) @@ -1420,7 +1467,7 @@ bool ClearCasePlugin::ccFileOp(const QString &workingDir, const QString &title, const QString file = QDir::toNativeSeparators(fileName); bool noCheckout = false; QVBoxLayout *verticalLayout; - ActivitySelector *actSelector; + ActivitySelector *actSelector = 0; QLabel *commentLabel; QTextEdit *commentEdit; QDialogButtonBox *buttonBox; @@ -1428,8 +1475,10 @@ bool ClearCasePlugin::ccFileOp(const QString &workingDir, const QString &title, fileOpDlg.setWindowTitle(title); verticalLayout = new QVBoxLayout(&fileOpDlg); - actSelector = new ActivitySelector; - verticalLayout->addWidget(actSelector); + if (m_isUcm) { + actSelector = new ActivitySelector; + verticalLayout->addWidget(actSelector); + } commentLabel = new QLabel(tr("Enter &comment:")); verticalLayout->addWidget(commentLabel); @@ -1450,9 +1499,11 @@ bool ClearCasePlugin::ccFileOp(const QString &workingDir, const QString &title, if (!fileOpDlg.exec()) return true; + QString comment = commentEdit->toPlainText(); - if (actSelector->changed()) + if (m_isUcm && actSelector->changed()) vcsSetActivity(workingDir, fileOpDlg.windowTitle(), actSelector->activity()); + QString dirName = QDir::toNativeSeparators(QFileInfo(workingDir, fileName).absolutePath()); QStringList commentArg; if (comment.isEmpty()) @@ -1500,26 +1551,32 @@ bool ClearCasePlugin::ccFileOp(const QString &workingDir, const QString &title, return true; } +static QString baseName(const QString &fileName) +{ + return fileName.mid(fileName.lastIndexOf(QLatin1Char('/')) + 1); +} + bool ClearCasePlugin::vcsAdd(const QString &workingDir, const QString &fileName) { - return ccFileOp(workingDir, tr("ClearCase Add File"), + return ccFileOp(workingDir, tr("ClearCase Add File %1").arg(baseName(fileName)), QStringList() << QLatin1String("mkelem") << QLatin1String("-ci"), fileName); } bool ClearCasePlugin::vcsDelete(const QString &workingDir, const QString &fileName) { - const QString title(tr("ClearCase Remove Element")); + const QString title(tr("ClearCase Remove Element %1").arg(baseName(fileName))); if (QMessageBox::warning(0, title, tr("This operation is irreversible. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) return true; - return ccFileOp(workingDir, tr("ClearCase Remove File"), + return ccFileOp(workingDir, tr("ClearCase Remove File %1").arg(baseName(fileName)), QStringList() << QLatin1String("rmname") << QLatin1String("-force"), fileName); } bool ClearCasePlugin::vcsMove(const QString &workingDir, const QString &from, const QString &to) { - return ccFileOp(workingDir, tr("ClearCase Rename File"), + return ccFileOp(workingDir, tr("ClearCase Rename File %1 -> %2") + .arg(baseName(from)).arg(baseName(to)), QStringList() << QLatin1String("move"), from, to); } @@ -1533,7 +1590,7 @@ QString ClearCasePlugin::vcsGetRepositoryURL(const QString & /*directory*/) return currentState().topLevel(); } -// ClearCase has "view.dat" file in the root directory it manages. +// ClearCase has "view.dat" file in the root directory it manages for snapshot views. bool ClearCasePlugin::managesDirectory(const QString &directory, QString *topLevel /* = 0 */) const { QString topLevelFound = findTopLevel(directory); @@ -1640,7 +1697,18 @@ bool ClearCasePlugin::newActivity() return (!response.error); } -QString ClearCasePlugin::ccGetView(const QString &workingDir, bool *isDynamic) const +// check if the view is UCM +bool ClearCasePlugin::ccCheckUcm(const QString &viewname, const QString &workingDir) const +{ + QStringList catcsArgs(QLatin1String("catcs")); + catcsArgs << QLatin1String("-tag") << viewname; + QString catcsData = runCleartoolSync(workingDir, catcsArgs); + + // check output for the word "ucm" + return QRegExp(QLatin1String("(^|\\n)ucm\\n")).indexIn(catcsData) != -1; +} + +QString ClearCasePlugin::ccGetView(const QString &workingDir, bool *isDynamic, bool *isUcm) const { QStringList args(QLatin1String("lsview")); args << QLatin1String("-cview"); @@ -1652,7 +1720,13 @@ QString ClearCasePlugin::ccGetView(const QString &workingDir, bool *isDynamic) c } if (isDynamic) *isDynamic = !data.isEmpty() && (data.at(0) == QLatin1Char('*')); - return data.mid(2, data.indexOf(QLatin1Char(' '), 2) - 2); + + QString viewname = data.mid(2, data.indexOf(QLatin1Char(' '), 2) - 2); + if (isUcm) + *isUcm = ccCheckUcm(viewname, workingDir); + + return viewname; + } void ClearCasePlugin::updateStreamAndView() @@ -1665,8 +1739,8 @@ void ClearCasePlugin::updateStreamAndView() QRegExp intStreamExp(QLatin1String("stream:([^@]*)")); if (intStreamExp.indexIn(sresponse.mid(tabPos + 1)) != -1) m_intStream = intStreamExp.cap(1); - m_view = ccGetView(m_topLevel); - m_updateViewAction->setParameter(m_view); + m_view = ccGetView(m_topLevel, &m_isDynamic, &m_isUcm); + m_updateViewAction->setParameter(m_isDynamic ? QString() : m_view); } void ClearCasePlugin::projectChanged(ProjectExplorer::Project *project) |