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

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