KDevelop API Documentation

vcs/perforce/perforcepart.cpp

Go to the documentation of this file.
00001 /*************************************************************************** 00002 * Copyright (C) 1999-2001 by Bernd Gehrmann * 00003 * bernd@kdevelop.org * 00004 * Extended 2002 by Harald Fernengel <harry@kdevelop.org> * 00005 * * 00006 * This program is free software; you can redistribute it and/or modify * 00007 * it under the terms of the GNU General Public License as published by * 00008 * the Free Software Foundation; either version 2 of the License, or * 00009 * (at your option) any later version. * 00010 * * 00011 ***************************************************************************/ 00012 00013 #include "perforcepart.h" 00014 00015 #include <qfileinfo.h> 00016 #include <qpopupmenu.h> 00017 #include <qregexp.h> 00018 #include <kpopupmenu.h> 00019 #include <kdebug.h> 00020 #include <kdevgenericfactory.h> 00021 #include <klocale.h> 00022 #include <kprocess.h> 00023 #include <kmessagebox.h> 00024 #include <kapplication.h> 00025 #include <kaction.h> 00026 #include <kurl.h> 00027 #include <kparts/part.h> 00028 00029 #include "kdevpartcontroller.h" 00030 #include "kdevcore.h" 00031 #include "kdevmakefrontend.h" 00032 #include "kdevdifffrontend.h" 00033 #include "commitdlg.h" 00034 #include "execcommand.h" 00035 00036 static const KAboutData data("kdevperforce", I18N_NOOP("Perforce"), "1.0"); 00037 00038 typedef KDevGenericFactory<PerforcePart> PerforceFactory; 00039 K_EXPORT_COMPONENT_FACTORY( libkdevperforce, PerforceFactory( &data ) ) 00040 00041 PerforcePart::PerforcePart( QObject *parent, const char *name, const QStringList & ) 00042 : KDevPlugin( "Perforce", "perforce", parent, name ? name : "PerforcePart" ) 00043 { 00044 setInstance(PerforceFactory::instance()); 00045 setXMLFile( "kdevperforcepart.rc" ); 00046 00047 setupActions(); 00048 00049 connect( core(), SIGNAL(contextMenu(QPopupMenu *, const Context *)), 00050 this, SLOT(contextMenu(QPopupMenu *, const Context *)) ); 00051 } 00052 00053 00054 PerforcePart::~PerforcePart() 00055 {} 00056 00057 void PerforcePart::setupActions() 00058 { 00059 actionEdit = new KAction( i18n("Edit"), 0, this, SLOT(slotActionEdit()), 00060 actionCollection(), "perforce_edit" ); 00061 actionEdit->setToolTip(i18n("Edit")); 00062 actionEdit->setWhatsThis(i18n("<b>Edit</b><p>Opens file(s) in a client workspace for edit.")); 00063 actionRevert = new KAction( i18n("Revert"), 0, this, SLOT(slotActionRevert()), 00064 actionCollection(), "perforce_revert" ); 00065 actionRevert->setToolTip(i18n("Revert")); 00066 actionRevert->setWhatsThis(i18n("<b>Revert</b><p>Discards changes made to open files.")); 00067 actionSubmit = new KAction( i18n("Submit"), 0, this, SLOT(slotActionCommit()), 00068 actionCollection(), "perforce_submit" ); 00069 actionSubmit->setToolTip(i18n("Submit")); 00070 actionSubmit->setWhatsThis(i18n("<b>Submit</b><p>Sends changes made to open files to the depot.")); 00071 actionSync = new KAction( i18n("Sync"), 0, this, SLOT(slotActionUpdate()), 00072 actionCollection(), "perforce_sync" ); 00073 actionSync->setToolTip(i18n("Sync")); 00074 actionSync->setWhatsThis(i18n("<b>Sync</b><p>Copies files from the depot into the workspace.")); 00075 actionDiff = new KAction( i18n("Diff Against Repository"), 0, this, SLOT(slotActionDiff()), 00076 actionCollection(), "perforce_diff" ); 00077 actionDiff->setToolTip(i18n("Diff against repository")); 00078 actionDiff->setWhatsThis(i18n("<b>Diff against repository</b><p>Compares a client workspace file to a revision in the depot.")); 00079 actionAdd = new KAction( i18n("Add to Repository"), 0, this, SLOT(slotActionAdd()), 00080 actionCollection(), "perforce_add" ); 00081 actionAdd->setToolTip(i18n("Add to repository")); 00082 actionAdd->setWhatsThis(i18n("<b>Add to repository</b><p>Open file(s) in a client workspace for addition to the depot.")); 00083 actionRemove = new KAction( i18n("Remove From Repository"), 0, this, SLOT(slotActionRemove()), 00084 actionCollection(), "perforce_remove" ); 00085 actionRemove->setToolTip(i18n("Remove from repository")); 00086 actionRemove->setWhatsThis(i18n("<b>Remove from repository</b><p>Open file(s) in a client workspace for deletion from the depot.")); 00087 } 00088 00089 void PerforcePart::contextMenu(QPopupMenu *popup, const Context *context) 00090 { 00091 if (context->hasType( Context::FileContext )) { 00092 const FileContext *fcontext = static_cast<const FileContext*>(context); 00093 popupfile = fcontext->fileName(); 00094 QFileInfo fi( popupfile ); 00095 popup->insertSeparator(); 00096 00097 KPopupMenu *sub = new KPopupMenu(popup); 00098 QString name = fi.fileName(); 00099 sub->insertTitle( i18n("Actions for %1").arg(name) ); 00100 00101 int id = sub->insertItem( i18n("Edit"), 00102 this, SLOT(slotEdit()) ); 00103 sub->setWhatsThis(id, i18n("<b>Edit</b><p>Opens file(s) in a client workspace for edit.")); 00104 id = sub->insertItem( i18n("Revert"), 00105 this, SLOT(slotRevert()) ); 00106 sub->setWhatsThis(id, i18n("<b>Revert</b><p>Discards changes made to open files.")); 00107 id = sub->insertItem( i18n("Submit"), 00108 this, SLOT(slotCommit()) ); 00109 sub->setWhatsThis(id, i18n("<b>Submit</b><p>Sends changes made to open files to the depot.")); 00110 id = sub->insertItem( i18n("Sync"), 00111 this, SLOT(slotUpdate()) ); 00112 sub->setWhatsThis(id, i18n("<b>Sync</b><p>Copies files from the depot into the workspace.")); 00113 sub->insertSeparator(); 00114 id = sub->insertItem( i18n("Diff Against Repository"), 00115 this, SLOT(slotDiff()) ); 00116 sub->setWhatsThis(id, i18n("<b>Diff against repository</b><p>Compares a client workspace file to a revision in the depot.")); 00117 id = sub->insertItem( i18n("Add to Repository"), 00118 this, SLOT(slotAdd()) ); 00119 sub->setWhatsThis(id, i18n("<b>Add to repository</b><p>Open file(s) in a client workspace for addition to the depot.")); 00120 id = sub->insertItem( i18n("Remove From Repository"), 00121 this, SLOT(slotRemove()) ); 00122 sub->setWhatsThis(id, i18n("<b>Remove from repository</b><p>Open file(s) in a client workspace for deletion from the depot.")); 00123 id = popup->insertItem(i18n("Perforce"), sub); 00124 } 00125 } 00126 00127 void PerforcePart::execCommand( const QString& cmd, const QString& filename ) 00128 { 00129 if ( filename.isEmpty() ) 00130 return; 00131 00132 QFileInfo fi( filename ); 00133 if (fi.isDir()) { 00134 KMessageBox::error( 0, i18n("Cannot handle directories, please select single files") ); 00135 return; 00136 } 00137 QString dir = fi.dirPath(); 00138 QString name = fi.fileName(); 00139 00140 QString command("cd "); 00141 command += dir; 00142 command += " && p4 " + cmd + " "; 00143 command += name; 00144 00145 makeFrontend()->queueCommand(dir, command); 00146 } 00147 00148 void PerforcePart::edit( const QString& filename ) 00149 { 00150 execCommand( "edit", filename ); 00151 } 00152 00153 void PerforcePart::revert( const QString& filename ) 00154 { 00155 if ( KMessageBox::questionYesNo( 0, 00156 i18n("Do you really want to revert " 00157 "the file %1 and lose all your changes?").arg( filename ) ) == KMessageBox::Yes ) { 00158 execCommand( "revert", filename ); 00159 } 00160 } 00161 00162 void PerforcePart::commit( const QString& filename ) 00163 { 00164 if ( filename.isEmpty() ) 00165 return; 00166 00167 QFileInfo fi( filename ); 00168 if ( fi.isDir() ) { 00169 KMessageBox::error( 0, i18n("Submitting of subdirectories is not supported") ); 00170 return; 00171 } 00172 00173 CommitDialog d; 00174 QStringList lst; 00175 lst << filename; 00176 d.setFiles( lst ); 00177 if (d.exec() == QDialog::Rejected) 00178 return; 00179 00180 QString message = d.changeList(); 00181 if (!message.isEmpty()) 00182 message = KShellProcess::quote(message); 00183 00184 QString command("echo " + message); 00185 command += " | p4 submit -i"; 00186 00187 makeFrontend()->queueCommand("", command); 00188 } 00189 00190 00191 void PerforcePart::update( const QString& filename ) 00192 { 00193 if ( filename.isEmpty() ) 00194 return; 00195 00196 QString dir, name; 00197 QFileInfo fi( filename ); 00198 if (fi.isDir()) { 00199 dir = fi.absFilePath(); 00200 name = "..."; // three dots means "recoursive" 00201 } else { 00202 dir = fi.dirPath(); 00203 name = fi.fileName(); 00204 } 00205 00206 QString command("cd "); 00207 command += dir; 00208 command += " && p4 sync "; 00209 command += name; 00210 00211 makeFrontend()->queueCommand(dir, command); 00212 } 00213 00214 00215 void PerforcePart::add( const QString& filename ) 00216 { 00217 execCommand( "add", filename ); 00218 } 00219 00220 00221 void PerforcePart::remove( const QString& filename ) 00222 { 00223 execCommand( "delete", filename ); 00224 } 00225 00226 void PerforcePart::diff( const QString& filename ) 00227 { 00228 if ( filename.isEmpty() ) 00229 return; 00230 00231 QString name; 00232 QFileInfo fi( filename ); 00233 00234 if ( fi.isDir() ) { 00235 name = fi.absFilePath() + "..."; 00236 } else { 00237 name = filename; 00238 } 00239 QStringList args; 00240 00241 args << "diff"; 00242 args << name; 00243 ExecCommand* cmv = new ExecCommand( "p4", args, QString::null, QStringList(), this ); 00244 connect( cmv, SIGNAL(finished( const QString&, const QString& )), 00245 this, SLOT(slotDiffFinished( const QString&, const QString& )) ); 00246 } 00247 00248 void PerforcePart::slotDiffFinished( const QString& diff, const QString& err ) 00249 { 00250 if ( diff.isNull() && err.isNull() ) { 00251 kdDebug(9000) << "p4 diff cancelled" << endl; 00252 return; // user pressed cancel or an error occured 00253 } 00254 00255 if ( diff.isEmpty() && !err.isEmpty() ) { 00256 KMessageBox::detailedError( 0, i18n("P4 outputted errors during diff."), err, i18n("Errors During Diff") ); 00257 return; 00258 } 00259 00260 if ( !err.isEmpty() ) { 00261 int s = KMessageBox::warningContinueCancelList( 0, i18n("P4 outputted errors during diff. Do you still want to continue?"), 00262 QStringList::split( "\n", err, false ), i18n("Errors During Diff") ); 00263 if ( s != KMessageBox::Continue ) 00264 return; 00265 } 00266 00267 if ( diff.isEmpty() ) { 00268 KMessageBox::information( 0, i18n("There is no difference to the repository."), i18n("No Differences Found") ); 00269 return; 00270 } 00271 00272 // strip the ==== headers 00273 static QRegExp rx( "(^|\\n)====.*====\\n" ); 00274 rx.setMinimal( true ); 00275 QString strippedDiff = diff; 00276 strippedDiff.replace( rx, QString::null ); 00277 00278 Q_ASSERT( diffFrontend() ); 00279 diffFrontend()->showDiff( strippedDiff ); 00280 } 00281 00282 QString PerforcePart::currentFile() 00283 { 00284 KParts::ReadOnlyPart *part = dynamic_cast<KParts::ReadOnlyPart*>( partController()->activePart() ); 00285 if ( part ) { 00286 KURL url = part->url(); 00287 if ( url.isLocalFile() ) 00288 return url.path(); 00289 } 00290 return QString::null; 00291 } 00292 00293 void PerforcePart::slotActionCommit() 00294 { 00295 commit( currentFile() ); 00296 } 00297 00298 void PerforcePart::slotActionUpdate() 00299 { 00300 update( currentFile() ); 00301 } 00302 void PerforcePart::slotActionAdd() 00303 { 00304 add( currentFile() ); 00305 } 00306 00307 void PerforcePart::slotActionRemove() 00308 { 00309 remove( currentFile() ); 00310 } 00311 00312 void PerforcePart::slotActionEdit() 00313 { 00314 edit( currentFile() ); 00315 } 00316 00317 void PerforcePart::slotActionRevert() 00318 { 00319 revert( currentFile() ); 00320 } 00321 00322 void PerforcePart::slotActionDiff() 00323 { 00324 diff( currentFile() ); 00325 } 00326 00327 void PerforcePart::slotCommit() 00328 { 00329 commit( popupfile ); 00330 } 00331 00332 void PerforcePart::slotUpdate() 00333 { 00334 update( popupfile ); 00335 } 00336 00337 void PerforcePart::slotAdd() 00338 { 00339 add( popupfile ); 00340 } 00341 00342 void PerforcePart::slotRemove() 00343 { 00344 remove( popupfile ); 00345 } 00346 00347 void PerforcePart::slotEdit() 00348 { 00349 edit( popupfile ); 00350 } 00351 00352 void PerforcePart::slotRevert() 00353 { 00354 revert( popupfile ); 00355 } 00356 00357 void PerforcePart::slotDiff() 00358 { 00359 diff( popupfile ); 00360 } 00361 00362 #include "perforcepart.moc"
KDE Logo
This file is part of the documentation for KDevelop Version 3.0.4.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Oct 6 17:39:14 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003