00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
#include <qregexp.h>
00013
#include <kurl.h>
00014
#include <kdebug.h>
00015
00016
#include <urlutil.h>
00017
#include <kdevproject.h>
00018
00019
#include <dcopref.h>
00020
#include <cvsjob_stub.h>
00021
#include <cvsservice_stub.h>
00022
00023
#include "cvspart.h"
00024
#include "cvsdir.h"
00025
#include "cvsentry.h"
00026
#include "cvsfileinfoprovider.h"
00027
00028
00030
00032
00033 CVSFileInfoProvider::CVSFileInfoProvider(
CvsServicePart *parent, CvsService_stub *cvsService )
00034 :
KDevVCSFileInfoProvider( parent, "cvsfileinfoprovider" ),
00035 m_requestStatusJob( 0 ), m_cvsService( cvsService ), m_cachedDirEntries( 0 )
00036 {
00037 }
00038
00040
00041 CVSFileInfoProvider::~CVSFileInfoProvider()
00042 {
00043
if (
m_requestStatusJob &&
m_requestStatusJob->isRunning())
00044
m_requestStatusJob->cancel();
00045
delete m_requestStatusJob;
00046
delete m_cachedDirEntries;
00047 }
00048
00050
00051 const VCSFileInfoMap *
CVSFileInfoProvider::status(
const QString &dirPath )
const
00052
{
00053
00054
if (dirPath !=
m_previousDirPath)
00055 {
00056
00057
delete m_cachedDirEntries;
00058
CVSDir cvsdir(
projectDirectory() + QDir::separator() + dirPath );
00059
m_previousDirPath = dirPath;
00060
m_cachedDirEntries = cvsdir.
cacheableDirStatus();
00061 }
00062
return m_cachedDirEntries;
00063 }
00064
00066
00067 bool CVSFileInfoProvider::requestStatus(
const QString &dirPath,
void *callerData )
00068 {
00069
m_savedCallerData = callerData;
00070
if (
m_requestStatusJob)
00071 {
00072
delete m_requestStatusJob;
00073
m_requestStatusJob = 0;
00074 }
00075
00076
if (
m_cachedDirEntries)
00077 {
00078
delete m_cachedDirEntries;
00079
m_cachedDirEntries = 0;
00080
m_previousDirPath = dirPath;
00081 }
00082
00083
00084
DCOPRef job =
m_cvsService->status( dirPath,
true,
false );
00085
m_requestStatusJob =
new CvsJob_stub( job.
app(), job.
obj() );
00086
00087
kdDebug(9006) <<
"Running command : " <<
m_requestStatusJob->cvsCommand() <<
endl;
00088 connectDCOPSignal( job.
app(), job.
obj(),
"jobExited(bool, int)",
"slotJobExited(bool, int)",
true );
00089 connectDCOPSignal( job.
app(), job.
obj(),
"receivedStdout(QString)",
"slotReceivedOutput(QString)",
true );
00090
return m_requestStatusJob->execute();
00091 }
00092
00094
00095 void CVSFileInfoProvider::slotJobExited(
bool normalExit,
int )
00096 {
00097
kdDebug(9006) <<
"CVSFileInfoProvider::slotJobExited(bool,int)" <<
endl;
00098
if (!normalExit)
00099
return;
00100
00101
00102
m_cachedDirEntries =
parse(
m_statusLines );
00103
00104
printOutFileInfoMap( *
m_cachedDirEntries );
00105
00106 emit statusReady( *
m_cachedDirEntries,
m_savedCallerData );
00107 }
00108
00110
00111 void CVSFileInfoProvider::slotReceivedOutput(
QString someOutput )
00112 {
00113
QStringList strings =
m_bufferedReader.
process( someOutput );
00114
if (strings.count() > 0)
00115 {
00116
m_statusLines += strings;
00117 }
00118 }
00119
00121
00122 void CVSFileInfoProvider::slotReceivedErrors(
QString )
00123 {
00124
00125 }
00126
00128
00129 QString CVSFileInfoProvider::projectDirectory()
const
00130
{
00131
return owner()->
project()->
projectDirectory();
00132 }
00133
00135
00136 VCSFileInfoMap *
CVSFileInfoProvider::parse(
QStringList stringStream )
00137 {
00138
QRegExp rx_recordStart(
"^=+$" );
00139
QRegExp rx_fileName(
"^File: (\\.|\\-|\\w)+" );
00140
QRegExp rx_fileStatus(
"Status: (\\.|-|\\s|\\w)+" );
00141
QRegExp rx_fileWorkRev(
"\\bWorking revision:" );
00142
QRegExp rx_fileRepoRev(
"\\bRepository revision:" );
00143
00144
00145
00146
00147
QString fileName,
00148 fileStatus,
00149 workingRevision,
00150 repositoryRevision,
00151 stickyTag,
00152 stickyDate,
00153 stickyOptions;
00154
00155
VCSFileInfoMap *vcsStates =
new VCSFileInfoMap;
00156
00157
int state = 0;
00158
const int lastAcceptableState = 4;
00159
00160
00161
for (QStringList::const_iterator it=stringStream.begin(); it != stringStream.end(); ++it)
00162 {
00163
QString s = (*it).stripWhiteSpace();
00164
kdDebug(9006) <<
">> Parsing: " << s <<
endl;
00165
00166
if (rx_recordStart.exactMatch( s ))
00167 state = 1;
00168
else if (state == 1 && rx_fileName.search( s ) >= 0 && rx_fileStatus.search( s ) >= 0)
00169 {
00170 fileName = rx_fileName.cap().replace(
"File:",
"" ).stripWhiteSpace();
00171 fileStatus = rx_fileStatus.cap().replace(
"Status:",
"" ).stripWhiteSpace();
00172 ++state;
00173
kdDebug(9006) <<
">> " << fileName <<
", " << fileStatus <<
endl;
00174 }
00175
else if (state == 2 && rx_fileWorkRev.search( s ) >= 0)
00176 {
00177 workingRevision = s.replace(
"Working revision:",
"" ).stripWhiteSpace();
00178
00179
QRegExp rx_revision(
"\\b(((\\d)+\\.?)*|New file!)" );
00180
if (rx_revision.search( workingRevision ) >= 0)
00181 {
00182 workingRevision = rx_revision.cap();
00183
kdDebug(9006) <<
">> WorkRev: " << workingRevision <<
endl;
00184 ++state;
00185 }
00186 }
00187
else if (state == 3 && rx_fileRepoRev.search( s ) >= 0)
00188 {
00189 repositoryRevision = s.replace(
"Repository revision:",
"" ).stripWhiteSpace();
00190
00191
QRegExp rx_revision(
"\\b(((\\d)+\\.?)*|No revision control file)" );
00192
if (rx_revision.search( s ) >= 0)
00193 {
00194 repositoryRevision = rx_revision.cap();
00195
kdDebug(9006) <<
">> RepoRev: " << repositoryRevision <<
endl;
00196 ++state;
00197 }
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
else if (state >= lastAcceptableState)
00207 {
00208
00209
VCSFileInfo vcsInfo( fileName, workingRevision, repositoryRevision,
00210
String2EnumState( fileStatus ) );
00211
kdDebug(9006) <<
"== Inserting: " << vcsInfo.
toString() <<
endl;
00212 vcsStates->insert( fileName, vcsInfo );
00213 }
00214 }
00215
return vcsStates;
00216 }
00217
00219
00220 VCSFileInfo::FileState
CVSFileInfoProvider::String2EnumState(
QString stateAsString )
00221 {
00222
00223
00224
00225
00226
if (stateAsString ==
"Up-to-date")
00227
return VCSFileInfo::Uptodate;
00228
else if (stateAsString ==
"Locally Modified")
00229
return VCSFileInfo::Modified;
00230
else if (stateAsString ==
"Locally Added")
00231
return VCSFileInfo::Added;
00232
else if (stateAsString ==
"Unresolved Conflict")
00233
return VCSFileInfo::Conflict;
00234
else if (stateAsString ==
"Needs Patch")
00235
return VCSFileInfo::NeedsPatch;
00236
else if (stateAsString ==
"Needs Checkout")
00237
return VCSFileInfo::NeedsCheckout;
00238
else
00239
return VCSFileInfo::Unknown;
00240 }
00241
00243
00244 void CVSFileInfoProvider::printOutFileInfoMap(
const VCSFileInfoMap &map )
00245 {
00246
kdDebug(9006) <<
"Files parsed:" <<
endl;
00247
for (VCSFileInfoMap::const_iterator it = map.begin(); it != map.end(); ++it)
00248 {
00249
const VCSFileInfo &vcsInfo = *it;
00250
kdDebug(9006) << vcsInfo.
toString() <<
endl;
00251 }
00252 }
00253
00254
#include "cvsfileinfoprovider.moc"