summaryrefslogtreecommitdiffstats
path: root/parts/diff/diffpart.cpp
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit114a878c64ce6f8223cfd22d76a20eb16d177e5e (patch)
treeacaf47eb0fa12142d3896416a69e74cbf5a72242 /parts/diff/diffpart.cpp
downloadtdevelop-114a878c64ce6f8223cfd22d76a20eb16d177e5e.tar.gz
tdevelop-114a878c64ce6f8223cfd22d76a20eb16d177e5e.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdevelop@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'parts/diff/diffpart.cpp')
-rw-r--r--parts/diff/diffpart.cpp248
1 files changed, 248 insertions, 0 deletions
diff --git a/parts/diff/diffpart.cpp b/parts/diff/diffpart.cpp
new file mode 100644
index 00000000..8f04b060
--- /dev/null
+++ b/parts/diff/diffpart.cpp
@@ -0,0 +1,248 @@
+/***************************************************************************
+ * Copyright (C) 2001 by Harald Fernengel *
+ * harry@kdevelop.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; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#include "diffpart.h"
+
+#include <sys/stat.h>
+
+#include <qwhatsthis.h>
+#include <qpopupmenu.h>
+
+#include <klocale.h>
+#include <kdevgenericfactory.h>
+#include <kaction.h>
+#include <kfiledialog.h>
+#include <kprocess.h>
+#include <kio/jobclasses.h>
+#include <kio/job.h>
+#include <kparts/part.h>
+#include <ktexteditor/editinterface.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+#include <kiconloader.h>
+
+#include "kdevcore.h"
+#include "kdevmainwindow.h"
+#include "kdevpartcontroller.h"
+#include "kdevplugininfo.h"
+
+#include "diffdlg.h"
+#include "diffwidget.h"
+
+static const KDevPluginInfo data("kdevdiff");
+
+typedef KDevGenericFactory<DiffPart> DiffFactory;
+K_EXPORT_COMPONENT_FACTORY( libkdevdiff, DiffFactory( data ) )
+
+DiffPart::DiffPart(QObject *parent, const char *name, const QStringList &)
+ : KDevDiffFrontend(&data, parent, name ? name : "DiffPart"), proc(0)
+{
+ setInstance(DiffFactory::instance());
+ setXMLFile("kdevdiff.rc");
+
+ diffWidget = new DiffWidget(this, 0, "diffWidget");
+ diffWidget->setIcon( SmallIcon("editcopy") );
+ QString nm( i18n( "Diff" ) );
+ diffWidget->setCaption( i18n( "Diff Output" ) );
+ QWhatsThis::add(diffWidget, i18n("<b>Difference viewer</b><p>Shows output of the diff format. "
+ "Can utilize every installed component that is able to show diff output. "
+ "For example if you have Kompare installed, Difference Viewer can use its graphical diff view."));
+ mainWindow()->embedOutputView( diffWidget, nm, i18n("Output of the diff command") );
+ mainWindow()->setViewAvailable( diffWidget, false );
+
+ KAction *action = new KAction( i18n("Difference Viewer..."), 0,
+ this, SLOT(slotExecDiff()),
+ actionCollection(), "tools_diff" );
+ action->setToolTip(i18n("Difference viewer"));
+ action->setWhatsThis(i18n("<b>Difference viewer</b><p>Shows the contents of a patch file."));
+
+ connect( core(), SIGNAL(contextMenu(QPopupMenu *, const Context *)),
+ this, SLOT(contextMenu(QPopupMenu *, const Context *)) );
+}
+
+static bool urlIsEqual(const KURL &a, const KURL &b)
+{
+ if (a.isLocalFile() && b.isLocalFile())
+ {
+ struct stat aStat, bStat;
+
+ if ((::stat(QFile::encodeName(a.fileName()), &aStat) == 0)
+ && (::stat(QFile::encodeName(b.fileName()), &bStat) == 0))
+ {
+ return (aStat.st_dev == bStat.st_dev) && (aStat.st_ino == bStat.st_ino);
+ }
+ }
+
+ return a == b;
+}
+
+static KParts::ReadWritePart* partForURL(const KURL &url, KDevPartController* pc)
+{
+ if ( !pc )
+ return 0;
+ QPtrListIterator<KParts::Part> it(*(pc->parts()));
+ for ( ; it.current(); ++it)
+ {
+ KParts::ReadWritePart *rw_part = dynamic_cast<KParts::ReadWritePart*>(it.current());
+ if ( rw_part && dynamic_cast<KTextEditor::EditInterface*>(it.current()) && urlIsEqual(url, rw_part->url()) )
+ return rw_part;
+ }
+
+ return 0;
+}
+
+void DiffPart::contextMenu( QPopupMenu* popup, const Context* context )
+{
+ if ( context->hasType( Context::EditorContext ) )
+ {
+ const EditorContext *eContext = static_cast<const EditorContext*>(context);
+ popupFile = eContext->url();
+ }
+ else if ( context->hasType( Context::FileContext ) )
+ {
+ const FileContext * fContext = static_cast<const FileContext*>( context );
+ popupFile.setPath( fContext->urls().first().fileName() ); //@fixme - assuming absolute path. is this correct?
+ }
+ else
+ {
+ return;
+ }
+
+ KParts::ReadWritePart* rw_part = partForURL( popupFile, partController() );
+ if ( !rw_part ) return;
+
+ if ( partController()->documentState( rw_part->url() ) != Clean )
+ {
+ int id = popup->insertItem( i18n( "Difference to Disk File" ),
+ this, SLOT(localDiff()) );
+ popup->setWhatsThis(id, i18n("<b>Difference to disk file</b><p>Shows the difference between "
+ "the file contents in this editor and the file contents on disk."));
+ }
+}
+
+DiffPart::~DiffPart()
+{
+ if ( diffWidget )
+ mainWindow()->removeView( diffWidget );
+
+ delete proc;
+ delete (DiffWidget*) diffWidget;
+}
+
+void DiffPart::localDiff()
+{
+ KParts::ReadWritePart* rw_part = partForURL( popupFile, partController() );
+ if ( !rw_part )
+ return;
+
+ KTextEditor::EditInterface* editIface = dynamic_cast<KTextEditor::EditInterface*>(rw_part);
+ if ( !editIface )
+ return;
+ buffer = editIface->text().local8Bit();
+ resultBuffer = resultErr = QString::null;
+
+ delete proc;
+ proc = new KProcess();
+
+ *proc << "diff";
+ *proc << "-u" << popupFile.path() << "-";
+ proc->setWorkingDirectory( popupFile.directory() );
+
+ connect( proc, SIGNAL(processExited( KProcess* )),
+ this, SLOT(processExited( KProcess* )) );
+ connect( proc, SIGNAL(receivedStdout( KProcess*, char*, int )),
+ this, SLOT(receivedStdout( KProcess*, char*, int )) );
+ connect( proc, SIGNAL(receivedStderr( KProcess*, char*, int )),
+ this, SLOT(receivedStderr( KProcess*, char*, int )) );
+ connect( proc, SIGNAL(wroteStdin( KProcess* )),
+ this, SLOT(wroteStdin( KProcess* )) );
+
+ if ( !proc->start( KProcess::NotifyOnExit, KProcess::All ) ) {
+ KMessageBox::error( 0, i18n( "Could not invoke the \"diff\" command." ) );
+ delete proc;
+ proc = 0;
+ return;
+ }
+ proc->writeStdin( buffer.data(), buffer.length() );
+}
+
+void DiffPart::processExited( KProcess* p )
+{
+ // diff has exit status 0 and 1 for success
+ if ( p->normalExit() && ( p->exitStatus() == 0 || p->exitStatus() == 1 ) ) {
+ if ( resultBuffer.isEmpty() )
+ KMessageBox::information( 0, i18n("DiffPart: No differences found.") );
+ else
+ showDiff( resultBuffer );
+ } else {
+ KMessageBox::error( 0, i18n("Diff command failed (%1):\n").arg( p->exitStatus() ) + resultErr );
+ }
+ resultBuffer = resultErr = QString::null;
+ delete proc;
+ proc = 0;
+}
+
+void DiffPart::receivedStdout( KProcess* /* p */, char* buf, int buflen )
+{
+ resultBuffer += QString::fromLocal8Bit( buf, buflen );
+}
+
+void DiffPart::receivedStderr( KProcess* /* p */, char* buf, int buflen )
+{
+ kdDebug(9033) << "received Stderr: " << QString::fromLocal8Bit( buf, buflen ) << endl;
+ resultErr += QString::fromLocal8Bit( buf, buflen );
+}
+
+void DiffPart::wroteStdin( KProcess* p )
+{
+ buffer = 0L;
+ p->closeStdin();
+}
+
+void DiffPart::openURL( const KURL& url )
+{
+ diffWidget->slotClear();
+ diffWidget->openURL( url );
+ mainWindow()->raiseView( diffWidget );
+/*
+ DiffDlg* diffDlg = new DiffDlg( 0, "diffDlg" );
+
+ diffDlg->openURL( url );
+ diffDlg->exec();
+ delete diffDlg;
+*/
+}
+
+void DiffPart::showDiff( const QString& diff )
+{
+ diffWidget->slotClear();
+ diffWidget->setDiff( diff );
+ mainWindow()->setViewAvailable( diffWidget, true );
+ mainWindow()->raiseView( diffWidget );
+/*
+ DiffDlg* diffDlg = new DiffDlg( 0, "diffDlg" );
+
+ diffDlg->setDiff( diff );
+ diffDlg->exec();
+ delete diffDlg;
+*/
+}
+
+void DiffPart::slotExecDiff()
+{
+ KURL url = KFileDialog::getOpenURL( QString::null, QString::null, 0, i18n("Please Select Patch File") );
+
+ if ( url.isEmpty() )
+ return;
+
+ openURL( url );
+}
+
+#include "diffpart.moc"