KDevelop API Documentation

parts/diff/diffpart.cpp

Go to the documentation of this file.
00001 /*************************************************************************** 00002 * Copyright (C) 2001 by Harald Fernengel * 00003 * harry@kdevelop.org * 00004 * * 00005 * This program is free software; you can redistribute it and/or modify * 00006 * it under the terms of the GNU General Public License as published by * 00007 * the Free Software Foundation; either version 2 of the License, or * 00008 * (at your option) any later version. * 00009 * * 00010 ***************************************************************************/ 00011 00012 #include <sys/stat.h> 00013 00014 #include <qwhatsthis.h> 00015 #include <qpopupmenu.h> 00016 00017 #include <klocale.h> 00018 #include <kdevgenericfactory.h> 00019 #include <kaction.h> 00020 #include <kfiledialog.h> 00021 #include <kprocess.h> 00022 #include <kio/jobclasses.h> 00023 #include <kio/job.h> 00024 #include <kparts/part.h> 00025 #include <ktexteditor/editinterface.h> 00026 #include <kmessagebox.h> 00027 #include <kdebug.h> 00028 #include <kiconloader.h> 00029 00030 #include "kdevcore.h" 00031 #include "kdevmainwindow.h" 00032 #include "kdevpartcontroller.h" 00033 00034 #include "diffpart.h" 00035 #include "diffdlg.h" 00036 #include "diffwidget.h" 00037 00038 static const KAboutData data("kdevdiff", I18N_NOOP("Difference Viewer"), "1.0"); 00039 00040 typedef KDevGenericFactory<DiffPart> DiffFactory; 00041 K_EXPORT_COMPONENT_FACTORY( libkdevdiff, DiffFactory( &data ) ) 00042 00043 DiffPart::DiffPart(QObject *parent, const char *name, const QStringList &) 00044 : KDevDiffFrontend("Diff", "diff", parent, name ? name : "DiffPart"), proc(0) 00045 { 00046 setInstance(DiffFactory::instance()); 00047 setXMLFile("kdevdiff.rc"); 00048 00049 diffWidget = new DiffWidget(); 00050 diffWidget->setIcon( SmallIcon("editcopy") ); 00051 QString nm( i18n( "Difference Viewer" ) ); 00052 diffWidget->setCaption( nm ); 00053 QWhatsThis::add(diffWidget, i18n("<b>Difference viewer</b><p>Shows output of the diff format. " 00054 "Can utilize every installed component that is able to show diff output. " 00055 "For example if you have Kompare installed, Difference Viewer can use it's graphical diff view.")); 00056 mainWindow()->embedOutputView( diffWidget, nm, i18n("Output of the diff command") ); 00057 00058 KAction *action = new KAction( i18n("Difference Viewer..."), 0, 00059 this, SLOT(slotExecDiff()), 00060 actionCollection(), "tools_diff" ); 00061 action->setToolTip(i18n("Difference viewer")); 00062 action->setWhatsThis(i18n("<b>Difference viewer</b><p>Shows the contents of a patch file.")); 00063 00064 connect( core(), SIGNAL(contextMenu(QPopupMenu *, const Context *)), 00065 this, SLOT(contextMenu(QPopupMenu *, const Context *)) ); 00066 } 00067 00068 static bool urlIsEqual(const KURL &a, const KURL &b) 00069 { 00070 if (a.isLocalFile() && b.isLocalFile()) 00071 { 00072 struct stat aStat, bStat; 00073 00074 if ((::stat(QFile::encodeName(a.fileName()), &aStat) == 0) 00075 && (::stat(QFile::encodeName(b.fileName()), &bStat) == 0)) 00076 { 00077 return (aStat.st_dev == bStat.st_dev) && (aStat.st_ino == bStat.st_ino); 00078 } 00079 } 00080 00081 return a == b; 00082 } 00083 00084 static KParts::ReadWritePart* partForURL(const KURL &url, KDevPartController* pc) 00085 { 00086 if ( !pc ) 00087 return 0; 00088 QPtrListIterator<KParts::Part> it(*(pc->parts())); 00089 for ( ; it.current(); ++it) 00090 { 00091 KParts::ReadWritePart *rw_part = dynamic_cast<KParts::ReadWritePart*>(it.current()); 00092 if ( rw_part && dynamic_cast<KTextEditor::EditInterface*>(it.current()) && urlIsEqual(url, rw_part->url()) ) 00093 return rw_part; 00094 } 00095 00096 return 0; 00097 } 00098 00099 void DiffPart::contextMenu( QPopupMenu* popup, const Context* context ) 00100 { 00101 if (!context->hasType( Context::EditorContext )) 00102 return; 00103 00104 const EditorContext *eContext = static_cast<const EditorContext*>(context); 00105 popupFile = eContext->url(); 00106 00107 if ( !popupFile.isLocalFile() ) 00108 return; 00109 00110 KParts::ReadWritePart* rw_part = partForURL( popupFile, partController() ); 00111 if ( !rw_part || !rw_part->isModified() ) 00112 return; 00113 00114 int id = popup->insertItem( i18n( "Difference to Saved File" ), 00115 this, SLOT(localDiff()) ); 00116 popup->setWhatsThis(id, i18n("<b>Difference to saved file</b><p>Shows the difference between " 00117 "the file contents in editor and file contents saved on a disk.")); 00118 } 00119 00120 DiffPart::~DiffPart() 00121 { 00122 if ( diffWidget ) 00123 mainWindow()->removeView( diffWidget ); 00124 00125 delete proc; 00126 delete (DiffWidget*) diffWidget; 00127 } 00128 00129 void DiffPart::localDiff() 00130 { 00131 KParts::ReadWritePart* rw_part = partForURL( popupFile, partController() ); 00132 if ( !rw_part ) 00133 return; 00134 00135 KTextEditor::EditInterface* editIface = dynamic_cast<KTextEditor::EditInterface*>(rw_part); 00136 if ( !editIface ) 00137 return; 00138 buffer = editIface->text().local8Bit(); 00139 resultBuffer = resultErr = QString::null; 00140 00141 delete proc; 00142 proc = new KProcess(); 00143 00144 *proc << "diff"; 00145 *proc << "-u" << popupFile.path() << "-"; 00146 proc->setWorkingDirectory( popupFile.directory() ); 00147 00148 connect( proc, SIGNAL(processExited( KProcess* )), 00149 this, SLOT(processExited( KProcess* )) ); 00150 connect( proc, SIGNAL(receivedStdout( KProcess*, char*, int )), 00151 this, SLOT(receivedStdout( KProcess*, char*, int )) ); 00152 connect( proc, SIGNAL(receivedStderr( KProcess*, char*, int )), 00153 this, SLOT(receivedStderr( KProcess*, char*, int )) ); 00154 connect( proc, SIGNAL(wroteStdin( KProcess* )), 00155 this, SLOT(wroteStdin( KProcess* )) ); 00156 00157 if ( !proc->start( KProcess::NotifyOnExit, KProcess::All ) ) { 00158 KMessageBox::error( 0, i18n( "Could not invoke the \"diff\" command." ) ); 00159 delete proc; 00160 proc = 0; 00161 return; 00162 } 00163 proc->writeStdin( buffer.data(), buffer.length() ); 00164 } 00165 00166 void DiffPart::processExited( KProcess* p ) 00167 { 00168 // diff has exit status 0 and 1 for success 00169 if ( p->normalExit() && ( p->exitStatus() == 0 || p->exitStatus() == 1 ) ) { 00170 if ( resultBuffer.isEmpty() ) 00171 KMessageBox::information( 0, i18n("DiffPart: No differences found.") ); 00172 else 00173 showDiff( resultBuffer ); 00174 } else { 00175 KMessageBox::error( 0, i18n("Diff command failed (%1):\n").arg( p->exitStatus() ) + resultErr ); 00176 } 00177 resultBuffer = resultErr = QString::null; 00178 delete proc; 00179 proc = 0; 00180 } 00181 00182 void DiffPart::receivedStdout( KProcess* /* p */, char* buf, int buflen ) 00183 { 00184 resultBuffer += QString::fromLocal8Bit( buf, buflen ); 00185 } 00186 00187 void DiffPart::receivedStderr( KProcess* /* p */, char* buf, int buflen ) 00188 { 00189 kdDebug(9033) << "received Stderr: " << QString::fromLocal8Bit( buf, buflen ) << endl; 00190 resultErr += QString::fromLocal8Bit( buf, buflen ); 00191 } 00192 00193 void DiffPart::wroteStdin( KProcess* p ) 00194 { 00195 buffer = 0L; 00196 p->closeStdin(); 00197 } 00198 00199 void DiffPart::openURL( const KURL& url ) 00200 { 00201 diffWidget->slotClear(); 00202 diffWidget->openURL( url ); 00203 mainWindow()->raiseView( diffWidget ); 00204 /* 00205 DiffDlg* diffDlg = new DiffDlg( 0, "diffDlg" ); 00206 00207 diffDlg->openURL( url ); 00208 diffDlg->exec(); 00209 delete diffDlg; 00210 */ 00211 } 00212 00213 void DiffPart::showDiff( const QString& diff ) 00214 { 00215 diffWidget->slotClear(); 00216 diffWidget->setDiff( diff ); 00217 mainWindow()->raiseView( diffWidget ); 00218 /* 00219 DiffDlg* diffDlg = new DiffDlg( 0, "diffDlg" ); 00220 00221 diffDlg->setDiff( diff ); 00222 diffDlg->exec(); 00223 delete diffDlg; 00224 */ 00225 } 00226 00227 void DiffPart::slotExecDiff() 00228 { 00229 KURL url = KFileDialog::getOpenURL( QString::null, QString::null, 0, i18n("Please Select Patch File") ); 00230 00231 if ( url.isEmpty() ) 00232 return; 00233 00234 openURL( url ); 00235 } 00236 00237 #include "diffpart.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 Tue Oct 19 08:01:50 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003