You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
556 lines
17 KiB
556 lines
17 KiB
/***************************************************************************
|
|
cvsservice.cpp - description
|
|
------------------------------
|
|
begin : Sun May 16 17:50:25 2004
|
|
copyright : (C) 2004, 2005 by Andras Mantia <amantia@kde.org>
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; version 2
|
|
*
|
|
***************************************************************************/
|
|
|
|
//qt include
|
|
#include <tqfile.h>
|
|
#include <tqfileinfo.h>
|
|
#include <tqradiobutton.h>
|
|
#include <tqtextedit.h>
|
|
#include <tqtextstream.h>
|
|
#include <tqtimer.h>
|
|
|
|
//kde includes
|
|
#include <kaction.h>
|
|
#include <kapplication.h>
|
|
#include <kcombobox.h>
|
|
#include <tdeversion.h>
|
|
#include <kiconloader.h>
|
|
#include <klineedit.h>
|
|
#include <klistbox.h>
|
|
#include <klocale.h>
|
|
#include <kmessagebox.h>
|
|
#include <kpopupmenu.h>
|
|
|
|
// CvsService
|
|
#include <repository_stub.h>
|
|
#include <cvsservice_stub.h>
|
|
#include <cvsjob_stub.h>
|
|
|
|
#include "cvsservice.h"
|
|
#include "cvscommitdlgs.h"
|
|
#include "cvsupdatetodlgs.h"
|
|
|
|
#define CVSSERVICE_TIMEOUT 1000*60
|
|
|
|
CVSService::CVSService(KActionCollection *ac)
|
|
{
|
|
m_menu = new KPopupMenu();
|
|
KAction *action = new KAction(i18n("&Commit..."), "vcs_commit", 0, this, TQT_SLOT(slotCommit()), ac, "vcs_commit");
|
|
action->plug(m_menu);
|
|
action = new KAction(i18n("&Update"), "vcs_update", 0, this, TQT_SLOT(slotUpdate()), ac, "vcs_update");
|
|
action->plug(m_menu);
|
|
KPopupMenu *updateToMenu = new KPopupMenu(m_menu);
|
|
m_menu->insertItem(SmallIconSet("vcs_update"), i18n("Update &To"), updateToMenu);
|
|
action = new KAction(i18n("&Tag/Date..."), "vcs_update", 0, this, TQT_SLOT(slotUpdateToTag()), ac, "vcs_update_tag_date");
|
|
action->plug(updateToMenu);
|
|
action = new KAction(i18n("&HEAD"), "vcs_update", 0, this, TQT_SLOT(slotUpdateToHead()), ac, "vcs_update_head");
|
|
action->plug(updateToMenu);
|
|
action = new KAction(i18n("Re&vert"), "reload", 0, this, TQT_SLOT(slotRevert()), ac, "vcs_revert");
|
|
action->plug(m_menu);
|
|
m_menu->insertSeparator();
|
|
action = new KAction(i18n("&Add to Repository..."), "vcs_add", 0, this, TQT_SLOT(slotAdd()), ac, "vcs_add");
|
|
action->plug(m_menu);
|
|
action = new KAction(i18n("&Remove From Repository..."), "vcs_remove", 0, this, TQT_SLOT(slotRemove()), ac, "vcs_remove");
|
|
action->plug(m_menu);
|
|
action = new KAction(i18n("&Ignore in CVS Operations"), 0, this, TQT_SLOT(slotAddToCVSIgnore()), ac);
|
|
action->plug(m_menu);
|
|
action = new KAction(i18n("Do &Not Ignore in CVS Operations"), 0, this, TQT_SLOT(slotRemoveFromCVSIgnore()), ac);
|
|
action->plug(m_menu);
|
|
|
|
m_menu->insertSeparator();
|
|
action = new KAction(i18n("Show &Log Messages"), 0, this, TQT_SLOT(slotBrowseLog()), ac);
|
|
action->plug(m_menu);
|
|
|
|
m_cvsJob = 0L;
|
|
m_repository = 0L;
|
|
m_cvsService =0L;
|
|
m_commitDlg = new CVSCommitDlgS();
|
|
m_updateToDlg = new CVSUpdateToDlgS();
|
|
m_timer = new TQTimer(this);
|
|
connect(m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotTimeout()));
|
|
}
|
|
|
|
CVSService::~CVSService()
|
|
{
|
|
if (m_cvsService)
|
|
m_cvsService->quit();
|
|
delete m_cvsService;
|
|
delete m_menu;
|
|
delete m_repository;
|
|
m_repository = 0L;
|
|
m_cvsService = 0L;
|
|
delete m_commitDlg;
|
|
delete m_updateToDlg;
|
|
}
|
|
|
|
void CVSService::setAppId(const TQCString &id)
|
|
{
|
|
m_appId = id;
|
|
m_cvsService = new CvsService_stub(m_appId, "CvsService");
|
|
m_timer->start(CVSSERVICE_TIMEOUT, true);
|
|
}
|
|
|
|
void CVSService::setRepository(const TQString &repository)
|
|
{
|
|
startService();
|
|
delete m_repository;
|
|
m_repository = new Repository_stub(m_appId, "CvsRepository");
|
|
if (m_repository->setWorkingCopy(repository))
|
|
{
|
|
m_repositoryPath = repository;
|
|
if (!m_repositoryPath.endsWith("/"))
|
|
m_repositoryPath += "/";
|
|
}
|
|
}
|
|
|
|
void CVSService::slotUpdate()
|
|
{
|
|
TQStringList files;
|
|
if (!m_defaultFile.isEmpty())
|
|
{
|
|
if (m_defaultFile.startsWith(m_repositoryPath))
|
|
{
|
|
files += m_defaultFile.remove(m_repositoryPath);
|
|
slotUpdate(files);
|
|
} else
|
|
{
|
|
notInRepository();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CVSService::slotUpdate(const TQStringList &files)
|
|
{
|
|
startService();
|
|
if (m_repository && !m_appId.isEmpty())
|
|
{
|
|
emit clearMessages();
|
|
emit showMessage(i18n("Running CVS update...") + "\n", false);
|
|
m_files = files;
|
|
m_job = m_cvsService->update(files, true, true, true, "");
|
|
m_cvsCommand = "update";
|
|
m_cvsJob = new CvsJob_stub(m_job.app(), m_job.obj());
|
|
|
|
connectDCOPSignal(m_job.app(), m_job.obj(), "jobExited(bool, int)", "slotJobExited(bool, int)", true);
|
|
connectDCOPSignal(m_job.app(), m_job.obj(), "receivedStdout(TQString)", "slotReceivedStdout(TQString)", true);
|
|
connectDCOPSignal(m_job.app(), m_job.obj(), "receivedStderr(TQString)", "slotReceivedStderr(TQString)", true);
|
|
m_cvsJob->execute();
|
|
}
|
|
}
|
|
|
|
void CVSService::slotUpdateToTag()
|
|
{
|
|
TQStringList files;
|
|
if (!m_defaultFile.isEmpty())
|
|
{
|
|
if (m_defaultFile.startsWith(m_repositoryPath))
|
|
{
|
|
files += m_defaultFile.remove(m_repositoryPath);
|
|
slotUpdateToTag(files);
|
|
} else
|
|
{
|
|
notInRepository();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CVSService::slotUpdateToTag(const TQStringList &files)
|
|
{
|
|
startService();
|
|
if (m_repository && !m_appId.isEmpty() && m_updateToDlg->exec())
|
|
{
|
|
TQString extraOpts;
|
|
TQString commandStr;
|
|
if (m_updateToDlg->tagRadioButton->isChecked())
|
|
{
|
|
extraOpts = "-r " + m_updateToDlg->tagCombo->currentText();
|
|
commandStr = i18n("Updating to revision %1 ...").arg(m_updateToDlg->tagCombo->currentText());
|
|
} else
|
|
{
|
|
extraOpts = "-D " + m_updateToDlg->dateLineEdit->text();
|
|
commandStr = i18n("Updating to the version from %1 ...").arg(+ m_updateToDlg->dateLineEdit->text());
|
|
}
|
|
emit clearMessages();
|
|
emit showMessage(commandStr + "\n", false);
|
|
m_files = files;
|
|
m_job = m_cvsService->update(files, true, true, true, extraOpts);
|
|
m_cvsCommand = "update";
|
|
m_cvsJob = new CvsJob_stub(m_job.app(), m_job.obj());
|
|
|
|
connectDCOPSignal(m_job.app(), m_job.obj(), "jobExited(bool, int)", "slotJobExited(bool, int)", true);
|
|
connectDCOPSignal(m_job.app(), m_job.obj(), "receivedStdout(TQString)", "slotReceivedStdout(TQString)", true);
|
|
connectDCOPSignal(m_job.app(), m_job.obj(), "receivedStderr(TQString)", "slotReceivedStderr(TQString)", true);
|
|
m_cvsJob->execute();
|
|
}
|
|
}
|
|
|
|
void CVSService::slotUpdateToHead()
|
|
{
|
|
TQStringList files;
|
|
if (!m_defaultFile.isEmpty())
|
|
{
|
|
if (m_defaultFile.startsWith(m_repositoryPath))
|
|
{
|
|
files += m_defaultFile.remove(m_repositoryPath);
|
|
slotUpdateToHead(files);
|
|
} else
|
|
{
|
|
notInRepository();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CVSService::slotUpdateToHead(const TQStringList &files)
|
|
{
|
|
startService();
|
|
if (m_repository && !m_appId.isEmpty())
|
|
{
|
|
emit clearMessages();
|
|
emit showMessage(i18n("Updating to HEAD...") + "\n", false);
|
|
m_files = files;
|
|
m_job = m_cvsService->update(files, true, true, true, "-A");
|
|
m_cvsCommand = "update";
|
|
m_cvsJob = new CvsJob_stub(m_job.app(), m_job.obj());
|
|
|
|
connectDCOPSignal(m_job.app(), m_job.obj(), "jobExited(bool, int)", "slotJobExited(bool, int)", true);
|
|
connectDCOPSignal(m_job.app(), m_job.obj(), "receivedStdout(TQString)", "slotReceivedStdout(TQString)", true);
|
|
connectDCOPSignal(m_job.app(), m_job.obj(), "receivedStderr(TQString)", "slotReceivedStderr(TQString)", true);
|
|
m_cvsJob->execute();
|
|
}
|
|
}
|
|
|
|
void CVSService::slotCommit()
|
|
{
|
|
TQStringList files;
|
|
if (!m_defaultFile.isEmpty())
|
|
{
|
|
if (m_defaultFile.startsWith(m_repositoryPath))
|
|
{
|
|
files += m_defaultFile.remove(m_repositoryPath);
|
|
slotCommit(files);
|
|
} else
|
|
{
|
|
notInRepository();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CVSService::slotCommit(const TQStringList &files)
|
|
{
|
|
startService();
|
|
m_commitDlg->fileList->clear();
|
|
m_commitDlg->fileList->insertStringList(files);
|
|
m_commitDlg->logEdit->clear();
|
|
m_commitDlg->messageCombo->insertItem(i18n("Current"), 0);
|
|
m_commitDlg->messageCombo->setCurrentItem(0);
|
|
|
|
if (m_repository && !m_appId.isEmpty() && m_commitDlg->exec())
|
|
{
|
|
m_commitDlg->messageCombo->removeItem(0);
|
|
TQString message = m_commitDlg->logEdit->text();
|
|
if (message != m_commitDlg->messageCombo->currentText())
|
|
m_commitDlg->messageCombo->insertItem(message, 0);
|
|
emit clearMessages();
|
|
emit showMessage(i18n("Running CVS commit...") + "\n", false);
|
|
m_files = files;
|
|
m_job = m_cvsService->commit(files, message, true);
|
|
m_cvsCommand = "commit";
|
|
m_cvsJob = new CvsJob_stub(m_job.app(), m_job.obj());
|
|
|
|
connectDCOPSignal(m_job.app(), m_job.obj(), "jobExited(bool, int)", "slotJobExited(bool, int)", true);
|
|
connectDCOPSignal(m_job.app(), m_job.obj(), "receivedStdout(TQString)", "slotReceivedStdout(TQString)", true);
|
|
connectDCOPSignal(m_job.app(), m_job.obj(), "receivedStderr(TQString)", "slotReceivedStderr(TQString)", true);
|
|
m_cvsJob->execute();
|
|
}
|
|
}
|
|
|
|
void CVSService::slotRevert()
|
|
{
|
|
TQStringList files;
|
|
if (!m_defaultFile.isEmpty())
|
|
{
|
|
if (m_defaultFile.startsWith(m_repositoryPath))
|
|
{
|
|
files += m_defaultFile.remove(m_repositoryPath);
|
|
slotRevert(files);
|
|
} else
|
|
{
|
|
notInRepository();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CVSService::slotRevert(const TQStringList &files)
|
|
{
|
|
startService();
|
|
if (m_repository && !m_appId.isEmpty())
|
|
{
|
|
emit clearMessages();
|
|
emit showMessage(i18n("Reverting to the version from the repository...") + "\n", false);
|
|
m_files = files;
|
|
m_job = m_cvsService->update(files, true, true, true, "-C");
|
|
m_cvsCommand = "update";
|
|
m_cvsJob = new CvsJob_stub(m_job.app(), m_job.obj());
|
|
|
|
connectDCOPSignal(m_job.app(), m_job.obj(), "jobExited(bool, int)", "slotJobExited(bool, int)", true);
|
|
connectDCOPSignal(m_job.app(), m_job.obj(), "receivedStdout(TQString)", "slotReceivedStdout(TQString)", true);
|
|
connectDCOPSignal(m_job.app(), m_job.obj(), "receivedStderr(TQString)", "slotReceivedStderr(TQString)", true);
|
|
m_cvsJob->execute();
|
|
}
|
|
}
|
|
|
|
void CVSService::slotAdd()
|
|
{
|
|
TQStringList files;
|
|
if (!m_defaultFile.isEmpty())
|
|
{
|
|
if (m_defaultFile.startsWith(m_repositoryPath))
|
|
{
|
|
files += m_defaultFile.remove(m_repositoryPath);
|
|
slotAdd(files);
|
|
} else
|
|
{
|
|
notInRepository();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CVSService::slotAdd(const TQStringList &files)
|
|
{
|
|
startService();
|
|
if (m_repository && !m_appId.isEmpty() && (KMessageBox::questionYesNoList(0, i18n("Add the following files to repository?"), files, i18n("CVS Add"), KStdGuiItem::add(), i18n("Do Not Add")) == KMessageBox::Yes))
|
|
{
|
|
emit clearMessages();
|
|
emit showMessage(i18n("Adding file to the repository...") + "\n", false);
|
|
m_files = files;
|
|
m_job = m_cvsService->add(files, false);
|
|
m_cvsCommand = "add";
|
|
m_cvsJob = new CvsJob_stub(m_job.app(), m_job.obj());
|
|
|
|
connectDCOPSignal(m_job.app(), m_job.obj(), "jobExited(bool, int)", "slotJobExited(bool, int)", true);
|
|
connectDCOPSignal(m_job.app(), m_job.obj(), "receivedStdout(TQString)", "slotReceivedStdout(TQString)", true);
|
|
connectDCOPSignal(m_job.app(), m_job.obj(), "receivedStderr(TQString)", "slotReceivedStderr(TQString)", true);
|
|
m_cvsJob->execute();
|
|
}
|
|
}
|
|
|
|
void CVSService::slotRemove()
|
|
{
|
|
TQStringList files;
|
|
if (!m_defaultFile.isEmpty())
|
|
{
|
|
if (m_defaultFile.startsWith(m_repositoryPath))
|
|
{
|
|
files += m_defaultFile.remove(m_repositoryPath);
|
|
slotRemove(files);
|
|
} else
|
|
{
|
|
notInRepository();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CVSService::slotRemove(const TQStringList &files)
|
|
{
|
|
startService();
|
|
if (m_repository && !m_appId.isEmpty() && (KMessageBox::warningContinueCancelList(0, i18n("<qt>Remove the following files from the repository?<br>This will remove your <b>working copy</b> as well.</qt>"), files, i18n("CVS Remove")) == KMessageBox::Continue))
|
|
{
|
|
emit clearMessages();
|
|
emit showMessage(i18n("Removing files from the repository...") + "\n", false);
|
|
m_files = files;
|
|
m_job = m_cvsService->remove(files, true);
|
|
m_cvsCommand = "remove";
|
|
m_cvsJob = new CvsJob_stub(m_job.app(), m_job.obj());
|
|
|
|
connectDCOPSignal(m_job.app(), m_job.obj(), "jobExited(bool, int)", "slotJobExited(bool, int)", true);
|
|
connectDCOPSignal(m_job.app(), m_job.obj(), "receivedStdout(TQString)", "slotReceivedStdout(TQString)", true);
|
|
connectDCOPSignal(m_job.app(), m_job.obj(), "receivedStderr(TQString)", "slotReceivedStderr(TQString)", true);
|
|
m_cvsJob->execute();
|
|
}
|
|
}
|
|
|
|
void CVSService::slotBrowseLog()
|
|
{
|
|
startService();
|
|
if (!m_defaultFile.isEmpty())
|
|
{
|
|
if (m_defaultFile.startsWith(m_repositoryPath))
|
|
{
|
|
TQString file = m_defaultFile.remove(m_repositoryPath);
|
|
if (m_repository && !m_appId.isEmpty() )
|
|
{
|
|
emit clearMessages();
|
|
emit showMessage(i18n("Showing CVS log...") + "\n", false);
|
|
m_files += file;
|
|
m_job = m_cvsService->log(file);
|
|
m_cvsCommand = "log";
|
|
m_cvsJob = new CvsJob_stub(m_job.app(), m_job.obj());
|
|
|
|
connectDCOPSignal(m_job.app(), m_job.obj(), "jobExited(bool, int)", "slotJobExited(bool, int)", true);
|
|
connectDCOPSignal(m_job.app(), m_job.obj(), "receivedStdout(TQString)", "slotReceivedStdout(TQString)", true);
|
|
connectDCOPSignal(m_job.app(), m_job.obj(), "receivedStderr(TQString)", "slotReceivedStderr(TQString)", true);
|
|
m_cvsJob->execute();
|
|
}
|
|
} else
|
|
{
|
|
notInRepository();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CVSService::slotAddToCVSIgnore()
|
|
{
|
|
if (!m_defaultFile.isEmpty())
|
|
{
|
|
if (m_defaultFile.startsWith(m_repositoryPath))
|
|
{
|
|
emit clearMessages();
|
|
TQFileInfo fInfo(m_defaultFile);
|
|
TQFile f(fInfo.dirPath()+ "/.cvsignore");
|
|
if (f.open(IO_ReadWrite))
|
|
{
|
|
bool found = false;
|
|
TQTextStream str(&f);
|
|
str.setEncoding(TQTextStream::UnicodeUTF8);
|
|
TQString line;
|
|
while (!str.atEnd())
|
|
{
|
|
line = str.readLine().stripWhiteSpace();
|
|
if (line == fInfo.fileName())
|
|
{
|
|
emit showMessage(i18n("\"%1\" is already in the CVS ignore list.").arg(fInfo.fileName()) + "\n", false);
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!found)
|
|
{
|
|
str << fInfo.fileName() << endl;
|
|
emit showMessage(i18n("\"%1\" added to the CVS ignore list.").arg(fInfo.fileName()) + "\n", false);
|
|
}
|
|
f.close();
|
|
}
|
|
|
|
} else
|
|
{
|
|
notInRepository();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CVSService::slotRemoveFromCVSIgnore()
|
|
{
|
|
if (!m_defaultFile.isEmpty())
|
|
{
|
|
if (m_defaultFile.startsWith(m_repositoryPath))
|
|
{
|
|
emit clearMessages();
|
|
TQString content;
|
|
TQFileInfo fInfo(m_defaultFile);
|
|
TQFile f(fInfo.dirPath()+ "/.cvsignore");
|
|
bool found = false;
|
|
if (f.open(IO_ReadWrite))
|
|
{
|
|
TQTextStream str(&f);
|
|
str.setEncoding(TQTextStream::UnicodeUTF8);
|
|
TQString line;
|
|
while (!str.atEnd())
|
|
{
|
|
line = str.readLine().stripWhiteSpace();
|
|
if (line != fInfo.fileName())
|
|
{
|
|
content += line + "\n";
|
|
} else
|
|
found = true;
|
|
}
|
|
if (!found)
|
|
{
|
|
emit showMessage(i18n("\"%1\" is not in the CVS ignore list.").arg(fInfo.fileName()) + "\n", false);
|
|
}
|
|
f.close();
|
|
}
|
|
if (found && f.open(IO_WriteOnly))
|
|
{
|
|
TQTextStream str(&f);
|
|
str.setEncoding(TQTextStream::UnicodeUTF8);
|
|
str << content;
|
|
emit showMessage(i18n("\"%1\" removed from the CVS ignore list.").arg(fInfo.fileName()) + "\n", false);
|
|
f.close();
|
|
}
|
|
|
|
} else
|
|
{
|
|
notInRepository();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CVSService::slotJobExited(bool normalExit, int exitStatus)
|
|
{
|
|
if (!normalExit)
|
|
{
|
|
KMessageBox::sorry(0, i18n("<qt>The CVS command <b>%1</b> has failed. The error code was <i>%2</i>.</qt>").arg(m_cvsCommand).arg(exitStatus), i18n("Command Failed"));
|
|
}
|
|
if (exitStatus == 0)
|
|
{
|
|
emit commandExecuted(m_cvsCommand, m_files);
|
|
}
|
|
disconnectDCOPSignal(m_job.app(), m_job.obj(), "jobExited(bool, int)", "slotJobExited(bool, int)");
|
|
disconnectDCOPSignal(m_job.app(), m_job.obj(), "receivedStdout(TQString)", "slotReceivedStdout(TQString)");
|
|
disconnectDCOPSignal(m_job.app(), m_job.obj(), "receivedStderr(TQString)", "slotReceivedStderr(TQString)");
|
|
//delete m_cvsJob;
|
|
//m_cvsJob = 0L;
|
|
emit showMessage(i18n("CVS command finished."), false);
|
|
emit showMessage(" ", false);
|
|
}
|
|
|
|
void CVSService::slotReceivedStdout(TQString output)
|
|
{
|
|
emit showMessage(output, true);
|
|
}
|
|
|
|
void CVSService::slotReceivedStderr(TQString output)
|
|
{
|
|
emit showMessage(output, true);
|
|
}
|
|
|
|
void CVSService::notInRepository()
|
|
{
|
|
emit clearMessages();
|
|
emit showMessage(i18n("Error: \"%1\" is not part of the\n\"%2\" repository.").arg(m_defaultFile).arg(m_repositoryPath) + "\n", false);
|
|
}
|
|
|
|
void CVSService::startService()
|
|
{
|
|
if (!m_cvsService)
|
|
{
|
|
TQString error;
|
|
KApplication::startServiceByDesktopName("cvsservice", TQStringList(), &error,
|
|
&m_appId);
|
|
m_cvsService = new CvsService_stub(m_appId, "CvsService");
|
|
}
|
|
m_timer->start(CVSSERVICE_TIMEOUT, true);
|
|
}
|
|
|
|
void CVSService::slotTimeout()
|
|
{
|
|
if (m_cvsService)
|
|
m_cvsService->quit();
|
|
delete m_cvsService;
|
|
m_cvsService = 0L;
|
|
}
|
|
|
|
#include "cvsservice.moc"
|