//
// QPerforce is a gui interface to the perforce revision control
// system. It is based on the qt library, and should be easily portable
// across any platform that has this toolkit available.
//
// Copyright (C) 2002 Jacob Gladish
//
//
#include "Change.h"
#include "ConfigOptions.h"
#include "P4Client.h"
#include <qpixmap.h>
#include <qstringlist.h>
namespace Perforce {
Change::ChangesCache Change::_changesCache;
Change::PendingChangesCache Change::_pendingChangesCache;
//========================================================================
//
// static factory method
//
Change* Change::create_change( StrDict* varList )
{
Change* cl = new Change();
QString temp = varList->GetVar( "time" )->Text();
cl->_date.setTime_t( temp.toInt() );
cl->_description = varList->GetVar( "desc" )->Text();
IUpdateable< Change* >::replaceNewlinesWithSpaces( cl->_description );
cl->_name = varList->GetVar( "change" )->Text();
cl->_user = varList->GetVar( "user" )->Text();
cl->_client = varList->GetVar( "client" )->Text();
return cl;
}
bool Change::PendingChangesCache::userHasDefaultChange( const QString& client )
{
bool has = false;
for (Change*c = _cache.first(); c !=NULL; c = _cache.next()) {
ASSERT( c != NULL );
if (c->getClient() == client && c->getName() == "default") {
return true;
}
}
return has;
}
bool Change::addOpenedFile( FileEntry* f )
{
for (FileEntry* e = _openedFiles.first(); e != NULL; e = _openedFiles.next()) {
if (e->getDepotFile() == f->getDepotFile()) {
return false;
}
}
_openedFiles.append( f );
return true;
}
const ChangesList& Change::getChanges()
{
_changesCache.updateCacheIfNecessary();
return _changesCache.getCache();
}
const ChangesList& Change::getPendingChanges()
{
_pendingChangesCache.updateCacheIfNecessary();
return _pendingChangesCache.getCache();
}
void Change::ChangesCache::updateCache()
{
char* p[] = { "-m", "100", "-l", "-s", "submitted" };
RunP4Command( 5, p, "changes", this );
}
void Change::PendingChangesCache::updateCache()
{
// add the default change explicitly
Change* def = new Change();
def->_name = "default";
def->_client = ConfigOptions::getInstance()->getCurrentClient();
def->_description = "This is the default changelist dude";
_cache.append( def );
char* p[] = { "-s", "pending" };
RunP4Command( 2, p, "changes", this );
OpenedFilesUI* ui = new OpenedFilesUI();
ui->_changes = &this->_cache;
RunP4Command( 0, NULL, "opened", ui );
delete ui;
updateOpenedFiles();
}
void Change::updateAllOpenedFiles()
{
_pendingChangesCache.updateOpenedFiles();
}
void Change::ChangesCache::OutputStat( StrDict* varList )
{
// sanity check
QString temp = varList->GetVar( "status" )->Text();
ASSERT( temp.lower() == "submitted" );
Change*cl = create_change( varList );
_cache.append( cl );
}
void Change::PendingChangesCache::OutputStat( StrDict* varList )
{
ASSERT( varList != NULL );
// sanity check
QString temp = varList->GetVar( "status" )->Text();
ASSERT( temp.lower() == "pending" );
Change* cl = create_change( varList );
_cache.append( cl );
if (!userHasDefaultChange(cl->getClient())) {
// add default change for this user...
Change* def = new Change();
def->_client = cl->getClient();
def->_user = cl->getUser();
def->_description = "Default change";
def->_name = "default";
def->_user = def->getUser();
_cache.append( def );
}
}
void Change::ChangesCache::HandleError( Error* err )
{
ASSERT( 0 && "ERROR" );
}
void Change::PendingChangesCache::HandleError( Error* err )
{
ASSERT( 0 && "Error" );
}
void Change::PendingChangesCache::updateOpenedFiles()
{
char* p[] = { "-a" };
OpenedFilesUI* ui = new OpenedFilesUI();
ui->_changes = &this->_cache;
RunP4Command( 1, p, "opened", ui );
delete ui;
}
void Change::OpenedFilesUI::HandleError( Error* err )
{
ASSERT( 0 && "Error Getting opened files" );
}
void Change::OpenedFilesUI::OutputStat( StrDict* varList )
{
ASSERT( varList != NULL );
QString temp;
FileEntry* f = new FileEntry();
f->setDepotFile( varList->GetVar("depotFile")->Text() );
f->setClient( varList->GetVar("clientFile")->Text() );
temp = varList->GetVar( "rev" )->Text();
f->setRevision( temp.toInt() );
f->setAction( varList->GetVar("action")->Text() );
f->setChange( varList->GetVar("change")->Text() );
f->setType( varList->GetVar("type")->Text() );
f->setUser( varList->GetVar("user")->Text() );
f->setClient( varList->GetVar("client")->Text() );
// add this file entry to the proper change
bool foundHome = false;
Change* c = getOpenedFileParent( f->getChange(), f->getClient() );
if (c == NULL) {
Change* def = new Change();
def->_client = f->getClient();
def->_name = f->getChange();
def->_user = f->getUser();
_changes->append( def );
c = getOpenedFileParent( f->getChange(), f->getClient() );
if (c == NULL ) {
qDebug( "FileEntry doesn't have matching change cached!" );
qDebug( "FileEntry.change: %s", f->getChange().latin1() );
qDebug( "FileEntry.Client: %s", f->getClient().latin1() );
qDebug( "Cached changes" );
for (Change* c = _changes->first(); c != NULL; c = _changes->next()) {
ASSERT( c != NULL );
qDebug( "Change.Name=%s", c->getName().latin1() );
qDebug( "Change.Client=%s", c->getClient().latin1() );
}
qDebug( "End cached changes" );
qFatal( "Can't find change for opened file." );
}
}
c->addOpenedFile( f );
// c->_openedFiles.append( f );
}
Change* Change::OpenedFilesUI::getOpenedFileParent( const QString& name,
const QString& client )
{
for (Change* c = _changes->first(); c != NULL; c = _changes->next()) {
ASSERT( c != NULL );
if (c->getClient() == client && c->getName() == name) {
return c;
}
}
return NULL;
}
} // end namespace