Commit d1ef970a authored by Knut Petter Svendsen's avatar Knut Petter Svendsen Committed by Orgad Shaneh
Browse files

Add support for base ClearCase.



Current implementation only works for UCM views, which is a bug.
UCM is layered on top of base ClearCase. UCM has concepts such as
projects, streams and activities. When a view is base ClearCase
disable all prompting for activity, UCM menu entries and dialogs.

Change-Id: I81fb1a014373ece97d3f681623d314344a59b75a
Reviewed-by: Orgad Shaneh's avatarOrgad Shaneh <orgads@gmail.com>
parent 8676b58f
......@@ -49,6 +49,8 @@ ActivitySelector::ActivitySelector(QWidget *parent) :
m_plugin(ClearCasePlugin::instance()),
m_changed(false)
{
QTC_ASSERT(m_plugin->isUcm(), return);
QHBoxLayout *hboxLayout = new QHBoxLayout(this);
hboxLayout->setContentsMargins(0, 0, 0, 0);
......
......@@ -31,8 +31,8 @@
**************************************************************************/
#include "checkoutdialog.h"
#include "clearcaseplugin.h"
#include "ui_checkoutdialog.h"
#include "activityselector.h"
#include <QList>
#include <QPair>
......@@ -41,11 +41,23 @@
namespace ClearCase {
namespace Internal {
CheckOutDialog::CheckOutDialog(const QString &fileName, QWidget *parent) :
QDialog(parent), ui(new Ui::CheckOutDialog)
CheckOutDialog::CheckOutDialog(const QString &fileName, bool isUcm, QWidget *parent) :
QDialog(parent), ui(new Ui::CheckOutDialog), m_actSelector(0)
{
ui->setupUi(this);
ui->lblFileName->setText(fileName);
if (isUcm) {
m_actSelector = new ActivitySelector(this);
ui->verticalLayout->insertWidget(0, m_actSelector);
QFrame *line = new QFrame(this);
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
ui->verticalLayout->insertWidget(1, line);
}
}
CheckOutDialog::~CheckOutDialog()
......@@ -55,7 +67,7 @@ CheckOutDialog::~CheckOutDialog()
QString CheckOutDialog::activity() const
{
return ui->actSelector->activity();
return m_actSelector ? m_actSelector->activity() : QString();
}
QString CheckOutDialog::comment() const
......
......@@ -42,12 +42,14 @@ namespace Ui {
class CheckOutDialog;
}
class ActivitySelector;
class CheckOutDialog : public QDialog
{
Q_OBJECT
public:
explicit CheckOutDialog(const QString &fileName, QWidget *parent = 0);
explicit CheckOutDialog(const QString &fileName, bool isUcm, QWidget *parent = 0);
~CheckOutDialog();
QString activity() const;
QString comment() const;
......@@ -62,6 +64,7 @@ private slots:
private:
Ui::CheckOutDialog *ui;
ActivitySelector *m_actSelector;
};
} // namespace Internal
......
......@@ -21,16 +21,6 @@
</property>
</widget>
</item>
<item>
<widget class="ActivitySelector" name="actSelector" native="true"/>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblComment">
<property name="text">
......@@ -110,14 +100,6 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ActivitySelector</class>
<extends>QWidget</extends>
<header>activityselector.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
......
......@@ -84,18 +84,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,7 @@ 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),
......@@ -226,6 +229,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;
......@@ -562,7 +566,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,
......@@ -573,18 +577,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(!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)
......@@ -928,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);
......@@ -941,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());
......@@ -991,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);
}
......@@ -1053,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)"));
......@@ -1297,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();
......@@ -1310,8 +1332,9 @@ bool ClearCasePlugin::vcsOpen(const QString &workingDir, const QString &fileName
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();
......@@ -1444,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;
......@@ -1452,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);
......@@ -1474,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())
......@@ -1670,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");
......@@ -1682,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()
......@@ -1695,7 +1739,7 @@ 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_isDynamic);
m_view = ccGetView(m_topLevel, &m_isDynamic, &m_isUcm);
m_updateViewAction->setParameter(m_isDynamic ? QString() : m_view);
}
......
......@@ -118,7 +118,7 @@ public:
bool initialize(const QStringList &arguments, QString *error_message);
ClearCaseSubmitEditor *openClearCaseSubmitEditor(const QString &fileName);
ClearCaseSubmitEditor *openClearCaseSubmitEditor(const QString &fileName, bool isUcm);
const ClearCaseSettings &settings() const;
void setSettings(const ClearCaseSettings &s);
......@@ -148,6 +148,9 @@ public:
FileStatus vcsStatus(const QString &file) const;
QString currentView() const { return m_view; }
void refreshActivities();
inline bool isUcm() const { return m_isUcm; }
bool ccCheckUcm(const QString &viewname, const QString &workingDir) const;
public slots:
void vcsAnnotate(const QString &workingDir, const QString &file,
......@@ -216,7 +219,7 @@ private:
static void rmdir(const QString &path);
QString runExtDiff(const QString &workingDir, const QStringList &arguments,
int timeOut, QTextCodec *outputCodec = 0);
QString ccGetView(const QString &workingDir, bool *isDynamic = 0) const;
QString ccGetView(const QString &workingDir, bool *isDynamic = 0, bool *isUcm = 0) const;
ClearCaseSettings m_settings;
......@@ -226,6 +229,7 @@ private:
QString m_stream;
QString m_view;
bool m_isDynamic;
bool m_isUcm;
QString m_intStream;
QString m_activity;
QString m_diffPrefix;
......
......@@ -50,6 +50,11 @@ ClearCaseSubmitEditorWidget *ClearCaseSubmitEditor::submitEditorWidget()
return static_cast<ClearCaseSubmitEditorWidget *>(widget());
}
void ClearCaseSubmitEditor::setIsUcm(bool isUcm)
{
submitEditorWidget()->addActivitySelector(isUcm);
}
void ClearCaseSubmitEditor::setStatusList(const QStringList &statusOutput)
{
typedef QStringList::const_iterator ConstIterator;
......
......@@ -54,8 +54,11 @@ public:
void setStatusList(const QStringList &statusOutput);
ClearCaseSubmitEditorWidget *submitEditorWidget();
void setIsUcm(bool isUcm);
protected:
virtual QByteArray fileContents() const;
};
} // namespace Internal
......
......@@ -42,32 +42,26 @@
using namespace ClearCase::Internal;
ClearCaseSubmitEditorWidget::ClearCaseSubmitEditorWidget(QWidget *parent) :
Utils::SubmitEditorWidget(parent)
Utils::SubmitEditorWidget(parent),
m_actSelector(0)
{
setDescriptionMandatory(false);
QWidget *checkInWidget = new QWidget(this);
QVBoxLayout *verticalLayout = new QVBoxLayout(checkInWidget);
m_actSelector = new ActivitySelector;
verticalLayout->addWidget(m_actSelector);
QFrame *line = new QFrame;
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
verticalLayout->addWidget(line);
m_verticalLayout = new QVBoxLayout(checkInWidget);
m_chkIdentical = new QCheckBox(tr("Chec&k in even if identical to previous version"));
verticalLayout->addWidget(m_chkIdentical);
m_verticalLayout->addWidget(m_chkIdentical);
m_chkPTime = new QCheckBox(tr("&Preserve file modification time"));
verticalLayout->addWidget(m_chkPTime);
m_verticalLayout->addWidget(m_chkPTime);
insertTopWidget(checkInWidget);
}
QString ClearCaseSubmitEditorWidget::activity() const
{
return m_actSelector->activity();
return m_actSelector ? m_actSelector->activity() : QString();
}
bool ClearCaseSubmitEditorWidget::isIdentical() const
......@@ -82,17 +76,34 @@ bool ClearCaseSubmitEditorWidget::isPreserve() const
void ClearCaseSubmitEditorWidget::setActivity(const QString &act)
{
m_actSelector->setActivity(act);
if (m_actSelector)
m_actSelector->setActivity(act);
}
bool ClearCaseSubmitEditorWidget::activityChanged() const
{
return m_actSelector->changed();
return m_actSelector ? m_actSelector->changed() : false;
}
void ClearCaseSubmitEditorWidget::addKeep()
{
m_actSelector->addKeep();
if (m_actSelector)
m_actSelector->addKeep();
}
//! Add the ActivitySelector if \a isUcm is set
void ClearCaseSubmitEditorWidget::addActivitySelector(bool isUcm)
{
if (!isUcm || m_actSelector)
return;
m_actSelector = new ActivitySelector;
m_verticalLayout->insertWidget(0, m_actSelector);
QFrame* line = new QFrame;
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
m_verticalLayout->insertWidget(1, line);
}
QString ClearCaseSubmitEditorWidget::commitName() const
......
......@@ -37,6 +37,7 @@
QT_BEGIN_NAMESPACE
class QCheckBox;
class QVBoxLayout;
QT_END_NAMESPACE
namespace ClearCase {
......@@ -56,6 +57,7 @@ public:
void setActivity(const QString &act);
bool activityChanged() const;
void addKeep();
void addActivitySelector(bool isUcm);
protected:
QString commitName() const;
......@@ -64,6 +66,7 @@ private:
ActivitySelector *m_actSelector;
QCheckBox *m_chkIdentical;
QCheckBox *m_chkPTime;
QVBoxLayout *m_verticalLayout;
};
} // namespace Internal
......
#include "clearcasesync.h"
#include "clearcaseconstants.h"
#include <QDir>
#include <QFutureInterface>
......@@ -30,7 +31,8 @@ void ClearCaseSync::run(QFutureInterface<void> &future, const QString &topLevel,
total = settings.totalFiles.value(view, total);
// refresh activities list
m_plugin->refreshActivities();
if (m_plugin->isUcm())
m_plugin->refreshActivities();
if (settings.disableIndexer)
return;
......@@ -66,6 +68,7 @@ void ClearCaseSync::run(QFutureInterface<void> &future, const QString &topLevel,
future.setProgressRange(0, total + 1);
QProcess process;
process.setWorkingDirectory(topLevel);
process.start(program, args);
if (!process.waitForStarted())
return;
......@@ -75,6 +78,7 @@ void ClearCaseSync::run(QFutureInterface<void> &future, const QString &topLevel,
process.bytesAvailable() && !future.isCanceled())
{
QString line = QString::fromLocal8Bit(process.readLine().constData());
buffer += line;
if (buffer.endsWith(QLatin1Char('\n')) || process.atEnd()) {
int atatpos = buffer.indexOf(QLatin1String("@@"));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment