summaryrefslogtreecommitdiffstats
path: root/kompare/komparepart
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
commitbd9e6617827818fd043452c08c606f07b78014a0 (patch)
tree425bb4c3168f9c02f10150f235d2cb998dcc6108 /kompare/komparepart
downloadtdesdk-bd9e6617827818fd043452c08c606f07b78014a0.tar.gz
tdesdk-bd9e6617827818fd043452c08c606f07b78014a0.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/kdesdk@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kompare/komparepart')
-rw-r--r--kompare/komparepart/Makefile.am49
-rw-r--r--kompare/komparepart/kompare_part.cpp759
-rw-r--r--kompare/komparepart/kompare_part.h223
-rw-r--r--kompare/komparepart/kompare_qsplitter.h213
-rw-r--r--kompare/komparepart/kompareconnectwidget.cpp285
-rw-r--r--kompare/komparepart/kompareconnectwidget.h95
-rw-r--r--kompare/komparepart/komparelistview.cpp783
-rw-r--r--kompare/komparepart/komparelistview.h225
-rw-r--r--kompare/komparepart/komparepart.desktop24
-rw-r--r--kompare/komparepart/komparepartui.rc44
-rw-r--r--kompare/komparepart/kompareprefdlg.cpp106
-rw-r--r--kompare/komparepart/kompareprefdlg.h54
-rw-r--r--kompare/komparepart/komparesaveoptionsbase.ui336
-rw-r--r--kompare/komparepart/komparesaveoptionswidget.cpp215
-rw-r--r--kompare/komparepart/komparesaveoptionswidget.h51
-rw-r--r--kompare/komparepart/komparesplitter.cpp712
-rw-r--r--kompare/komparepart/komparesplitter.h115
17 files changed, 4289 insertions, 0 deletions
diff --git a/kompare/komparepart/Makefile.am b/kompare/komparepart/Makefile.am
new file mode 100644
index 00000000..f076448b
--- /dev/null
+++ b/kompare/komparepart/Makefile.am
@@ -0,0 +1,49 @@
+#########################################################################
+# KPART SECTION
+#########################################################################
+
+INCLUDES = \
+ -I$(top_srcdir)/kompare/libdialogpages \
+ -I$(top_srcdir)/kompare/libdiff2 \
+ -I$(top_srcdir)/kompare/interfaces \
+ $(all_includes)
+
+noinst_HEADERS = \
+ kompare_part.h \
+ komparesplitter.h \
+ kompareprefdlg.h \
+ komparelistview.h \
+ kompareconnectwidget.h \
+ komparesaveoptionsbase.h \
+ komparesaveoptionswidget.h \
+ kompare_qsplitter.h
+
+# let automoc handle all of the meta source files (moc)
+METASOURCES = AUTO
+
+kde_module_LTLIBRARIES = libkomparepart.la
+
+# the Part's source, library search path, and link libraries
+libkomparepart_la_SOURCES = \
+ kompare_part.cpp \
+ kompareconnectwidget.cpp \
+ komparesplitter.cpp \
+ komparelistview.cpp \
+ kompareprefdlg.cpp \
+ komparesaveoptionsbase.ui \
+ komparesaveoptionswidget.cpp
+
+libkomparepart_la_LDFLAGS = $(KDE_PLUGIN) $(all_libraries)
+libkomparepart_la_LIBADD = $(LIB_KPARTS) $(LIB_KFILE) \
+ ../libdialogpages/libdialogpages.la \
+ ../libdiff2/libdiff2.la \
+ ../interfaces/libkompareinterface.la
+
+# this is where the desktop file will go
+partdesktopdir = $(kde_servicesdir)
+partdesktop_DATA = komparepart.desktop
+
+# this is where the part's XML-GUI resource file goes
+partrcdir = $(kde_datadir)/kompare
+partrc_DATA = komparepartui.rc
+
diff --git a/kompare/komparepart/kompare_part.cpp b/kompare/komparepart/kompare_part.cpp
new file mode 100644
index 00000000..d74945e6
--- /dev/null
+++ b/kompare/komparepart/kompare_part.cpp
@@ -0,0 +1,759 @@
+/***************************************************************************
+ kompare_part.cpp - description
+ -------------------
+ begin : Sun Mar 4 2001
+ copyright : (C) 2001-2004 Otto Bruggeman
+ (C) 2001-2003 John Firebaugh
+ (C) 2004 Jeff Snyder
+ email : otto.bruggeman@home.nl
+ jfirebaugh@kde.org
+ jeff@caffeinated.me.uk
+****************************************************************************/
+
+/***************************************************************************
+**
+** 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 "kompare_qsplitter.h" // make sure we get there first
+
+#include <qlayout.h>
+#include <qwidget.h>
+
+#include <kaction.h>
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kfiletreeview.h>
+#include <kfiledialog.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kstdaction.h>
+#include <kinstance.h>
+#include <ktempfile.h>
+#include <kparts/genericfactory.h>
+//#include <ktempdir.h>
+
+#include <kio/netaccess.h>
+
+#include "diffmodel.h"
+#include "komparelistview.h"
+#include "kompareconnectwidget.h"
+#include "diffsettings.h"
+#include "viewsettings.h"
+#include "kompareprefdlg.h"
+#include "komparesaveoptionswidget.h"
+#include "komparesplitter.h"
+
+#include "kompare_part.h"
+
+typedef KParts::GenericFactory<KomparePart> KomparePartFactory;
+K_EXPORT_COMPONENT_FACTORY( libkomparepart, KomparePartFactory )
+
+ViewSettings* KomparePart::m_viewSettings = 0L;
+DiffSettings* KomparePart::m_diffSettings = 0L;
+
+KomparePart::KomparePart( QWidget *parentWidget, const char *widgetName,
+ QObject *parent, const char *name, const QStringList & /*args*/ ) :
+ KParts::ReadWritePart(parent, name),
+ m_tempDiff( 0 ),
+ m_info()
+{
+ // we need an instance
+ setInstance( KomparePartFactory::instance() );
+
+ if( !m_viewSettings ) {
+ m_viewSettings = new ViewSettings( 0 );
+ }
+ if( !m_diffSettings ) {
+ m_diffSettings = new DiffSettings( 0 );
+ }
+
+ readProperties( kapp->config() );
+
+ // This creates the "Model creator" and connects the signals and slots
+ m_modelList = new Diff2::KompareModelList( m_diffSettings, m_info, this, "komparemodellist" );
+ connect( m_modelList, SIGNAL(status( Kompare::Status )),
+ this, SLOT(slotSetStatus( Kompare::Status )) );
+ connect( m_modelList, SIGNAL(setStatusBarModelInfo( int, int, int, int, int )),
+ this, SIGNAL(setStatusBarModelInfo( int, int, int, int, int )) );
+ connect( m_modelList, SIGNAL(error( QString )),
+ this, SLOT(slotShowError( QString )) );
+ connect( m_modelList, SIGNAL(applyAllDifferences( bool )),
+ this, SLOT(updateActions()) );
+ connect( m_modelList, SIGNAL(applyDifference( bool )),
+ this, SLOT(updateActions()) );
+ connect( m_modelList, SIGNAL(applyAllDifferences( bool )),
+ this, SIGNAL(appliedChanged()) );
+ connect( m_modelList, SIGNAL(applyDifference( bool )),
+ this, SIGNAL(appliedChanged()) );
+
+ connect( m_modelList, SIGNAL( setModified( bool ) ),
+ this, SLOT( slotSetModified( bool ) ) );
+
+ // This is the stuff to connect the "interface" of the kompare part to the model inside
+ connect( m_modelList, SIGNAL(modelsChanged(const Diff2::DiffModelList*)),
+ this, SIGNAL(modelsChanged(const Diff2::DiffModelList*)) );
+
+ connect( m_modelList, SIGNAL(setSelection(const Diff2::DiffModel*, const Diff2::Difference*)),
+ this, SIGNAL(setSelection(const Diff2::DiffModel*, const Diff2::Difference*)) );
+ connect( this, SIGNAL(selectionChanged(const Diff2::DiffModel*, const Diff2::Difference*)),
+ m_modelList, SLOT(slotSelectionChanged(const Diff2::DiffModel*, const Diff2::Difference*)) );
+
+ connect( m_modelList, SIGNAL(setSelection(const Diff2::Difference*)),
+ this, SIGNAL(setSelection(const Diff2::Difference*)) );
+ connect( this, SIGNAL(selectionChanged(const Diff2::Difference*)),
+ m_modelList, SLOT(slotSelectionChanged(const Diff2::Difference*)) );
+
+ connect( m_modelList, SIGNAL(applyDifference(bool)),
+ this, SIGNAL(applyDifference(bool)) );
+ connect( m_modelList, SIGNAL(applyAllDifferences(bool)),
+ this, SIGNAL(applyAllDifferences(bool)) );
+ connect( m_modelList, SIGNAL(applyDifference(const Diff2::Difference*, bool)),
+ this, SIGNAL(applyDifference(const Diff2::Difference*, bool)) );
+
+ // This creates the splitterwidget and connects the signals and slots
+ m_splitter = new KompareSplitter ( m_viewSettings, parentWidget, widgetName );
+
+ connect( m_modelList, SIGNAL(setSelection(const Diff2::DiffModel*, const Diff2::Difference*)),
+ m_splitter, SLOT(slotSetSelection(const Diff2::DiffModel*, const Diff2::Difference*)) );
+// connect( m_splitter, SIGNAL(selectionChanged(const Diff2::Difference*, const Diff2::Difference*)),
+// m_modelList, SLOT(slotSelectionChanged(const Diff2::Difference*, const Diff2::Difference*)) );
+ connect( m_modelList, SIGNAL(setSelection(const Diff2::Difference*)),
+ m_splitter, SLOT(slotSetSelection(const Diff2::Difference*)) );
+ connect( m_splitter, SIGNAL(selectionChanged(const Diff2::Difference*)),
+ m_modelList, SLOT(slotSelectionChanged(const Diff2::Difference*)) );
+
+ connect( m_modelList, SIGNAL(applyDifference(bool)),
+ m_splitter, SLOT(slotApplyDifference(bool)) );
+ connect( m_modelList, SIGNAL(applyAllDifferences(bool)),
+ m_splitter, SLOT(slotApplyAllDifferences(bool)) );
+ connect( m_modelList, SIGNAL(applyDifference(const Diff2::Difference*, bool)),
+ m_splitter, SLOT(slotApplyDifference(const Diff2::Difference*, bool)) );
+ connect( this, SIGNAL(configChanged()), m_splitter, SIGNAL(configChanged()) );
+
+ // notify the part that this is our internal widget
+ setWidget( m_splitter->parentWidget() );
+
+ setupActions();
+
+ // set our XML-UI resource file
+ setXMLFile( "komparepartui.rc" );
+
+ // we are read-write by default -> uhm what if we are opened by lets say konq in RO mode ?
+ // Then we should not be doing this...
+ setReadWrite( true );
+
+ // we are not modified since we haven't done anything yet
+ setModified( false );
+}
+
+KomparePart::~KomparePart()
+{
+ // This is the only place allowed to call cleanUpTemporaryFiles
+ // because before there might still be a use for them (when swapping)
+ cleanUpTemporaryFiles();
+}
+
+void KomparePart::setupActions()
+{
+ // create our actions
+
+ m_saveAll = new KAction( i18n("Save &All"), "save_all", 0,
+ this, SLOT(saveAll()),
+ actionCollection(), "file_save_all" );
+ m_saveDiff = new KAction( i18n("Save .&diff..."), 0,
+ this, SLOT(saveDiff()),
+ actionCollection(), "file_save_diff" );
+ m_swap = new KAction( i18n( "Swap Source with Destination" ), 0,
+ this, SLOT(slotSwap()),
+ actionCollection(), "file_swap" );
+ m_diffStats = new KAction( i18n( "Show Statistics" ), 0,
+ this, SLOT(slotShowDiffstats()),
+ actionCollection(), "file_diffstats" );
+
+ KStdAction::preferences(this, SLOT(optionsPreferences()), actionCollection());
+}
+
+void KomparePart::updateActions()
+{
+ m_saveAll->setEnabled ( m_modelList->isModified() );
+ m_saveDiff->setEnabled ( m_modelList->mode() == Kompare::ComparingFiles || m_modelList->mode() == Kompare::ComparingDirs );
+ m_swap->setEnabled ( m_modelList->mode() == Kompare::ComparingFiles || m_modelList->mode() == Kompare::ComparingDirs );
+ m_diffStats->setEnabled( m_modelList->modelCount() > 0 );
+}
+
+void KomparePart::setEncoding( const QString& encoding )
+{
+ kdDebug() << "Encoding: " << encoding << endl;
+ m_modelList->setEncoding( encoding );
+}
+
+bool KomparePart::openDiff( const KURL& url )
+{
+ kdDebug(8103) << "Url = " << url.url() << endl;
+
+ emit kompareInfo( &m_info );
+
+ m_info.mode = Kompare::ShowingDiff;
+ m_info.source = url;
+ bool result = false;
+ m_info.localSource = fetchURL( url );
+ if ( !m_info.localSource.isEmpty() )
+ {
+ kdDebug(8103) << "Download succeeded " << endl;
+ result = m_modelList->openDiff( m_info.localSource );
+ updateActions();
+ updateCaption();
+ updateStatus();
+ }
+ else
+ {
+ kdDebug(8103) << "Download failed !" << endl;
+ }
+
+ return result;
+}
+
+bool KomparePart::openDiff( const QString& diffOutput )
+{
+ bool value = false;
+
+ emit kompareInfo( &m_info );
+
+ m_info.mode = Kompare::ShowingDiff;
+
+ if ( m_modelList->parseDiffOutput( diffOutput ) == 0 )
+ {
+ value = true;
+ m_modelList->show();
+ updateActions();
+ updateCaption();
+ updateStatus();
+ }
+
+ return value;
+}
+
+bool KomparePart::openDiff3( const KURL& diff3Url )
+{
+ // FIXME: Implement this !!!
+ kdDebug(8103) << "Not implemented yet. Filename is: " << diff3Url.url() << endl;
+ return false;
+}
+
+bool KomparePart::openDiff3( const QString& diff3Output )
+{
+ // FIXME: Implement this !!!
+ kdDebug(8103) << "Not implemented yet. diff3 output is: " << endl;
+ kdDebug(8103) << diff3Output << endl;
+ return false;
+}
+
+bool KomparePart::exists( const QString& url )
+{
+ QFileInfo fi( url );
+ return fi.exists();
+}
+
+const QString KomparePart::fetchURL( const KURL& url )
+{
+ QString tempFileName( "" );
+ if ( !url.isLocalFile() )
+ {
+ if ( ! KIO::NetAccess::download( url, tempFileName, widget() ) )
+ {
+ slotShowError( i18n( "<qt>The URL <b>%1</b> cannot be downloaded.</qt>" ).arg( url.prettyURL() ) );
+ tempFileName = "";
+ }
+ return tempFileName;
+ }
+ else
+ {
+ // is Local already, check if exists
+ if ( exists( url.path() ) )
+ return url.path();
+ else
+ {
+ slotShowError( i18n( "<qt>The URL <b>%1</b> does not exist on your system.</qt>" ).arg( url.prettyURL() ) );
+ return tempFileName;
+ }
+ }
+}
+
+void KomparePart::cleanUpTemporaryFiles()
+{
+ // i hope a local file will not be removed if it was not downloaded...
+ if ( !m_info.localSource.isEmpty() )
+ KIO::NetAccess::removeTempFile( m_info.localSource );
+ if ( !m_info.localDestination.isEmpty() )
+ KIO::NetAccess::removeTempFile( m_info.localDestination );
+}
+
+void KomparePart::compare( const KURL& source, const KURL& destination )
+{
+ m_info.source = source;
+ m_info.destination = destination;
+
+ m_info.localSource = fetchURL( source );
+ m_info.localDestination = fetchURL( destination );
+
+ emit kompareInfo( &m_info );
+
+ if ( !m_info.localSource.isEmpty() && !m_info.localDestination.isEmpty() )
+ {
+ m_modelList->compare( m_info.localSource, m_info.localDestination );
+ updateActions();
+ updateCaption();
+ updateStatus();
+ }
+}
+
+void KomparePart::compareFiles( const KURL& sourceFile, const KURL& destinationFile )
+{
+ emit kompareInfo( &m_info );
+
+ m_info.mode = Kompare::ComparingFiles;
+
+ m_info.source = sourceFile;
+ m_info.destination = destinationFile;
+
+ m_info.localSource = fetchURL( sourceFile );
+ m_info.localDestination = fetchURL( destinationFile );
+
+ if ( !m_info.localSource.isEmpty() && !m_info.localDestination.isEmpty() )
+ {
+ m_modelList->compareFiles( m_info.localSource, m_info.localDestination );
+ updateActions();
+ updateCaption();
+ updateStatus();
+ }
+}
+
+void KomparePart::compareDirs( const KURL& sourceDirectory, const KURL& destinationDirectory )
+{
+ emit kompareInfo( &m_info );
+
+ m_info.mode = Kompare::ComparingDirs;
+
+ m_info.source = sourceDirectory;
+ m_info.destination = destinationDirectory;
+
+ m_info.localSource = fetchURL( sourceDirectory );
+ m_info.localDestination = fetchURL( destinationDirectory );
+
+ if ( !m_info.localSource.isEmpty() && !m_info.localDestination.isEmpty() )
+ {
+ m_modelList->compareDirs( m_info.localSource, m_info.localDestination );
+ updateActions();
+ updateCaption();
+ updateStatus();
+ }
+}
+
+void KomparePart::compare3Files( const KURL& /*originalFile*/, const KURL& /*changedFile1*/, const KURL& /*changedFile2*/ )
+{
+ // FIXME: actually implement this some day :)
+ updateActions();
+ updateCaption();
+ updateStatus();
+}
+
+void KomparePart::openFileAndDiff( const KURL& file, const KURL& diffFile )
+{
+ emit kompareInfo( &m_info );
+
+ m_info.source = file;
+ m_info.destination = diffFile;
+
+ m_info.localSource = fetchURL( file );
+ m_info.localDestination = fetchURL( diffFile );
+ m_info.mode = Kompare::BlendingFile;
+
+ if ( !m_info.localSource.isEmpty() && !m_info.localDestination.isEmpty() )
+ {
+ m_modelList->openFileAndDiff( m_info.localSource, m_info.localDestination );
+ updateActions();
+ updateCaption();
+ updateStatus();
+ }
+}
+
+void KomparePart::openDirAndDiff ( const KURL& dir, const KURL& diffFile )
+{
+ emit kompareInfo( &m_info );
+
+ m_info.source = dir;
+ m_info.destination = diffFile;
+
+ m_info.localSource = fetchURL( dir );
+ m_info.localDestination = fetchURL( diffFile );
+ m_info.mode = Kompare::BlendingDir;
+
+ if ( !m_info.localSource.isEmpty() && !m_info.localDestination.isEmpty() )
+ {
+ m_modelList->openDirAndDiff( m_info.localSource, m_info.localDestination );
+ updateActions();
+ updateCaption();
+ updateStatus();
+ }
+}
+
+bool KomparePart::openFile()
+{
+ // This is called from openURL
+ // This is a little inefficient but i will do it anyway
+ openDiff( m_url );
+ return true;
+}
+
+bool KomparePart::saveAll()
+{
+ bool result = m_modelList->saveAll();
+ updateActions();
+ updateCaption();
+ updateStatus();
+ return result;
+}
+
+void KomparePart::saveDiff()
+{
+ KDialogBase* dlg = new KDialogBase( widget(), "save_options",
+ true /* modal */, i18n("Diff Options"),
+ KDialogBase::Ok|KDialogBase::Cancel );
+ KompareSaveOptionsWidget* w = new KompareSaveOptionsWidget(
+ m_info.localSource,
+ m_info.localDestination,
+ m_diffSettings, dlg );
+ dlg->setMainWidget( w );
+ dlg->setButtonOK( KStdGuiItem::save() );
+
+ if( dlg->exec() ) {
+ w->saveOptions();
+ KConfig* config = instance()->config();
+ saveProperties( config );
+ config->sync();
+
+ while ( 1 )
+ {
+ KURL url = KFileDialog::getSaveURL( m_info.destination.url(),
+ i18n("*.diff *.dif *.patch|Patch Files"), widget(), i18n( "Save .diff" ) );
+ if ( KIO::NetAccess::exists( url, false, widget() ) )
+ {
+ int result = KMessageBox::warningYesNoCancel( widget(), i18n("The file exists or is write-protected; do you want to overwrite it?"), i18n("File Exists"), i18n("Overwrite"), i18n("Do Not Overwrite") );
+ if ( result == KMessageBox::Cancel )
+ {
+ break;
+ }
+ else if ( result == KMessageBox::No )
+ {
+ continue;
+ }
+ else
+ {
+ kdDebug(8103) << "URL = " << url.prettyURL() << endl;
+ kdDebug(8103) << "Directory = " << w->directory() << endl;
+ kdDebug(8103) << "DiffSettings = " << m_diffSettings << endl;
+
+ m_modelList->saveDiff( url.url(), w->directory(), m_diffSettings );
+ break;
+ }
+ }
+ else
+ {
+ kdDebug(8103) << "URL = " << url.prettyURL() << endl;
+ kdDebug(8103) << "Directory = " << w->directory() << endl;
+ kdDebug(8103) << "DiffSettings = " << m_diffSettings << endl;
+
+ m_modelList->saveDiff( url.url(), w->directory(), m_diffSettings );
+ break;
+ }
+ }
+ }
+ delete dlg;
+}
+
+KAboutData *KomparePart::createAboutData()
+{
+ KAboutData *about = new KAboutData("kompare", I18N_NOOP("KomparePart"), "3.2");
+ about->addAuthor("John Firebaugh", "Author", "jfirebaugh@kde.org");
+ about->addAuthor("Otto Bruggeman", "Author", "otto.bruggeman@home.nl" );
+ return about;
+}
+
+void KomparePart::slotSetStatus( enum Kompare::Status status )
+{
+ updateActions();
+
+ switch( status ) {
+ case Kompare::RunningDiff:
+ emit setStatusBarText( i18n( "Running diff..." ) );
+ break;
+ case Kompare::Parsing:
+ emit setStatusBarText( i18n( "Parsing diff output..." ) );
+ break;
+ case Kompare::FinishedParsing:
+ updateStatus();
+ break;
+ case Kompare::FinishedWritingDiff:
+ updateStatus();
+ emit diffURLChanged();
+ break;
+ default:
+ break;
+ }
+}
+
+void KomparePart::updateCaption()
+{
+ QString source = m_info.source.prettyURL();
+ QString destination = m_info.destination.prettyURL();
+
+ QString text;
+
+ switch ( m_info.mode )
+ {
+ case Kompare::ComparingFiles :
+ case Kompare::ComparingDirs :
+ case Kompare::BlendingFile :
+ case Kompare::BlendingDir :
+ text = source + ":" + destination;
+ break;
+ case Kompare::ShowingDiff :
+ text = source;
+ break;
+ default:
+ break;
+ }
+
+ emit setWindowCaption( text );
+}
+
+void KomparePart::updateStatus()
+{
+ QString source = m_info.source.prettyURL();
+ QString destination = m_info.destination.prettyURL();
+
+ QString text;
+
+ switch ( m_info.mode )
+ {
+ case Kompare::ComparingFiles :
+ text = i18n( "Comparing file %1 with file %2" )
+ .arg( source )
+ .arg( destination );
+ break;
+ case Kompare::ComparingDirs :
+ text = i18n( "Comparing files in %1 with files in %2" )
+ .arg( source )
+ .arg( destination );
+ break;
+ case Kompare::ShowingDiff :
+ text = i18n( "Viewing diff output from %1" ).arg( source );
+ break;
+ case Kompare::BlendingFile :
+ text = i18n( "Blending diff output from %1 into file %2" )
+ .arg( source )
+ .arg( destination );
+ break;
+ case Kompare::BlendingDir :
+ text = i18n( "Blending diff output from %1 into folder %2" )
+ .arg( m_info.source.prettyURL() )
+ .arg( m_info.destination.prettyURL() );
+ break;
+ default:
+ break;
+ }
+
+ emit setStatusBarText( text );
+}
+
+void KomparePart::slotShowError( QString error )
+{
+ KMessageBox::error( widget(), error );
+}
+
+void KomparePart::slotSwap()
+{
+ if ( isModified() )
+ {
+ int query = KMessageBox::warningYesNoCancel
+ (
+ widget(),
+ i18n( "You have made changes to the destination file(s).\n"
+ "Would you like to save them?" ),
+ i18n( "Save Changes?" ),
+ KStdGuiItem::save(),
+ KStdGuiItem::discard()
+ );
+
+ if ( query == KMessageBox::Yes )
+ m_modelList->saveAll();
+
+ if ( query == KMessageBox::Cancel )
+ return; // Abort prematurely so no swapping
+ }
+
+ // Swap the info in the Kompare::Info struct
+ KURL url = m_info.source;
+ m_info.source = m_info.destination;
+ m_info.destination = url;
+
+ QString string = m_info.localSource;
+ m_info.localSource = m_info.localDestination;
+ m_info.localDestination = string;
+
+ // Update window caption and statusbar text
+ updateCaption();
+ updateStatus();
+
+ m_modelList->swap();
+}
+
+void KomparePart::slotShowDiffstats( void )
+{
+ // Fetch all the args needed for komparestatsmessagebox
+ // oldfile, newfile, diffformat, noofhunks, noofdiffs
+
+ QString oldFile;
+ QString newFile;
+ QString diffFormat;
+ int filesInDiff;
+ int noOfHunks;
+ int noOfDiffs;
+
+ oldFile = m_modelList->selectedModel() ? m_modelList->selectedModel()->sourceFile() : QString( "" );
+ newFile = m_modelList->selectedModel() ? m_modelList->selectedModel()->destinationFile() : QString( "" );
+
+ if ( m_modelList->selectedModel() )
+ {
+ switch( m_info.format ) {
+ case Kompare::Unified :
+ diffFormat = i18n( "Unified" );
+ break;
+ case Kompare::Context :
+ diffFormat = i18n( "Context" );
+ break;
+ case Kompare::RCS :
+ diffFormat = i18n( "RCS" );
+ break;
+ case Kompare::Ed :
+ diffFormat = i18n( "Ed" );
+ break;
+ case Kompare::Normal :
+ diffFormat = i18n( "Normal" );
+ break;
+ case Kompare::UnknownFormat :
+ default:
+ diffFormat = i18n( "Unknown" );
+ break;
+ }
+ }
+ else
+ {
+ diffFormat = "";
+ }
+
+ filesInDiff = m_modelList->modelCount();
+
+ noOfHunks = m_modelList->selectedModel() ? m_modelList->selectedModel()->hunkCount() : 0;
+ noOfDiffs = m_modelList->selectedModel() ? m_modelList->selectedModel()->differenceCount() : 0;
+
+ if ( m_modelList->modelCount() == 0 ) { // no diff loaded yet
+ KMessageBox::information( 0L, i18n(
+ "No diff file, or no 2 files have been diffed. "
+ "Therefore no stats are available."),
+ i18n("Diff Statistics"), QString::null, false );
+ }
+ else if ( m_modelList->modelCount() == 1 ) { // 1 file in diff, or 2 files compared
+ KMessageBox::information( 0L, i18n(
+ "Statistics:\n"
+ "\n"
+ "Old file: %1\n"
+ "New file: %2\n"
+ "\n"
+ "Format: %3\n"
+ "Number of hunks: %4\n"
+ "Number of differences: %5")
+ .arg(oldFile).arg(newFile).arg(diffFormat)
+ .arg(noOfHunks).arg(noOfDiffs),
+ i18n("Diff Statistics"), QString::null, false );
+ } else { // more than 1 file in diff, or 2 directories compared
+ KMessageBox::information( 0L, i18n(
+ "Statistics:\n"
+ "\n"
+ "Number of files in diff file: %1\n"
+ "Format: %2\n"
+ "\n"
+ "Current old file: %3\n"
+ "Current new file: %4\n"
+ "\n"
+ "Number of hunks: %5\n"
+ "Number of differences: %6")
+ .arg(filesInDiff).arg(diffFormat).arg(oldFile)
+ .arg(newFile).arg(noOfHunks).arg(noOfDiffs),
+ i18n("Diff Statistics"), QString::null, false );
+ }
+}
+
+bool KomparePart::queryClose()
+{
+ if( !isModified() ) return true;
+
+ int query = KMessageBox::warningYesNoCancel
+ (
+ widget(),
+ i18n("You have made changes to the destination file(s).\n"
+ "Would you like to save them?" ),
+ i18n( "Save Changes?" ),
+ KStdGuiItem::save(),
+ KStdGuiItem::discard()
+ );
+
+ if( query == KMessageBox::Cancel )
+ return false;
+
+ if( query == KMessageBox::Yes )
+ return m_modelList->saveAll();
+
+ return true;
+}
+
+int KomparePart::readProperties( KConfig *config )
+{
+ m_viewSettings->loadSettings( config );
+ m_diffSettings->loadSettings( config );
+ emit configChanged();
+ return 0;
+}
+
+int KomparePart::saveProperties( KConfig *config )
+{
+ m_viewSettings->saveSettings( config );
+ m_diffSettings->saveSettings( config );
+ return 0;
+}
+
+void KomparePart::optionsPreferences()
+{
+ // show preferences
+ KomparePrefDlg* pref = new KomparePrefDlg( m_viewSettings, m_diffSettings );
+
+ connect( pref, SIGNAL(applyClicked()), this, SIGNAL(configChanged()) );
+
+ if ( pref->exec() )
+ emit configChanged();
+}
+
+void KomparePart::slotSetModified( bool modified )
+{
+ kdDebug() << "KomparePart::slotSetModified( " << modified << " );" << endl;
+ setModified( modified );
+ updateActions();
+ updateCaption();
+}
+
+#include "kompare_part.moc"
diff --git a/kompare/komparepart/kompare_part.h b/kompare/komparepart/kompare_part.h
new file mode 100644
index 00000000..0a9716c3
--- /dev/null
+++ b/kompare/komparepart/kompare_part.h
@@ -0,0 +1,223 @@
+/***************************************************************************
+ kompare_part.h - description
+ -------------------
+ begin : Sun Mar 4 2001
+ copyright : (C) 2001-2004 Otto Bruggeman
+ (C) 2001-2003 John Firebaugh
+ (C) 2004 Jeff Snyder
+ email : otto.bruggeman@home.nl
+ jfirebaugh@kde.org
+ jeff@caffeinated.me.uk
+****************************************************************************/
+
+/***************************************************************************
+**
+** 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.
+**
+***************************************************************************/
+
+#ifndef KOMPAREPART_H
+#define KOMPAREPART_H
+
+#include <kparts/factory.h>
+#include <kparts/part.h>
+
+#include "kompare.h"
+
+#include "kompareinterface.h"
+
+class QWidget;
+
+class KTempFile;
+class KToggleAction;
+class KURL;
+
+namespace Diff2 {
+class Difference;
+class DiffModel;
+class DiffModelList;
+class KompareModelList;
+}
+class DiffSettings;
+class ViewSettings;
+class KFileTreeView;
+class KompareSplitter;
+class KompareProcess;
+
+/**
+ * This is a "Part". It does all the real work in a KPart
+ * application.
+ *
+ * @short Main Part
+ * @author John Firebaugh <jfirebaugh@kde.org>
+ * @author Otto Bruggeman <bruggie@home.nl>
+ * @version 0.3
+ */
+class KomparePart : public KParts::ReadWritePart,
+ public KompareInterface
+{
+ Q_OBJECT
+public:
+ /**
+ * Default constructor
+ */
+ KomparePart( QWidget *parentWidget, const char *widgetName,
+ QObject *parent, const char *name, const QStringList & /*args*/);
+
+ /**
+ * Destructor
+ */
+ virtual ~KomparePart();
+
+ // Sessionmanagement stuff, added to the kompare iface
+ // because they are not in the Part class where they belong
+ // Should be added when bic changes are allowed again (kde 4.0)
+ virtual int readProperties( KConfig *config );
+ virtual int saveProperties( KConfig *config );
+ // this one is called when the shell_app is about to close.
+ // we need it now to save the properties of the part when apps dont (can't)
+ // use the readProperties and saveProperties methods
+ virtual bool queryClose();
+
+ // bool isModified() const { return m_modelList->isModified(); }
+ // Do we really want to expose this ???
+ const Diff2::KompareModelList* model() const { return m_modelList; };
+
+ static KAboutData *createAboutData();
+
+public:
+ // Reimplemented from the KompareInterface
+ /**
+ * Open and parse the diff file at diffUrl.
+ */
+ virtual bool openDiff( const KURL& diffUrl );
+
+ /** Added on request of Harald Fernengel */
+ virtual bool openDiff( const QString& diffOutput );
+
+ /** Open and parse the diff3 file at diff3Url */
+ virtual bool openDiff3( const KURL& diff3URL );
+
+ /** Open and parse the file diff3Output with the output of diff3 */
+ virtual bool openDiff3( const QString& diff3Output );
+
+ /** Compare, with diff, source with destination */
+ virtual void compare( const KURL& sourceFile, const KURL& destinationFile );
+
+ /** Compare, with diff, source with destination */
+ virtual void compareFiles( const KURL& sourceFile, const KURL& destinationFile );
+
+ /** Compare, with diff, source with destination */
+ virtual void compareDirs ( const KURL& sourceDir, const KURL& destinationDir );
+
+ /** Compare, with diff3, originalFile with changedFile1 and changedFile2 */
+ virtual void compare3Files( const KURL& originalFile, const KURL& changedFile1, const KURL& changedFile2 );
+
+ /** This will show the file and the file with the diff applied */
+ virtual void openFileAndDiff( const KURL& file, const KURL& diffFile );
+
+ /** This will show the directory and the directory with the diff applied */
+ virtual void openDirAndDiff ( const KURL& dir, const KURL& diffFile );
+
+ /** Reimplementing this because this one knows more about the real part then the interface */
+ virtual void setEncoding( const QString& encoding );
+
+ // This is the interpart interface, it is signal and slot based so no "real" interface here
+ // All you have to do is connect the parts from your application.
+ // These just point to their counterpart in the KompareModelList or get called from their
+ // counterpart in KompareModelList.
+signals:
+ void modelsChanged( const Diff2::DiffModelList* models );
+
+ void setSelection( const Diff2::DiffModel* model, const Diff2::Difference* diff );
+ void setSelection( const Diff2::Difference* diff );
+
+ void selectionChanged( const Diff2::DiffModel* model, const Diff2::Difference* diff );
+ void selectionChanged( const Diff2::Difference* diff );
+
+ void applyDifference( bool apply );
+ void applyAllDifferences( bool apply );
+ void applyDifference( const Diff2::Difference*, bool apply );
+
+ void configChanged();
+
+ /*
+ ** This is emitted when a difference is clicked in the kompare view. You can connect to
+ ** it so you can use it to jump to this particular line in the editor in your app.
+ */
+ void differenceClicked( int lineNumber );
+
+ // Stuff that can probably be removed by putting it in the part where it belongs in my opinion
+public slots:
+ /** Save all destinations. */
+ bool saveAll();
+
+ /** Save the results of a comparison as a diff file. */
+ void saveDiff();
+
+ /** This slot is connected to the setModifed( bool ) signal from the KompareModelList */
+ void slotSetModified( bool modified );
+
+signals:
+ void appliedChanged();
+ void diffURLChanged();
+ void kompareInfo( Kompare::Info* info );
+ void setStatusBarModelInfo( int modelIndex, int differenceIndex, int modelCount, int differenceCount, int appliedCount );
+// void setStatusBarText( const QString& text );
+
+protected:
+ /**
+ * This is the method that gets called when the file is opened,
+ * when using openURL( const KURL& ) or in our case also openDiff( const KURL& );
+ * return true when everything went ok, false if there were problems
+ */
+ virtual bool openFile();
+ virtual bool saveFile() { return true; };
+
+ // patchFile
+ bool patchFile(KURL&);
+ bool patchDir();
+
+protected slots:
+ void slotSetStatus( Kompare::Status status );
+ void slotShowError( QString error );
+
+ void slotSwap();
+ void slotShowDiffstats();
+ void optionsPreferences();
+ void updateActions();
+ void updateCaption();
+ void updateStatus();
+
+private:
+ void cleanUpTemporaryFiles();
+ void setupActions();
+ bool exists( const QString& url );
+ bool isDirectory( const KURL& url );
+ const QString fetchURL( const KURL& url );
+
+private:
+ // Uhm why were these static again ???
+ // Ah yes, so multiple instances of kompare use the
+ // same settings after one of them changes them
+ static ViewSettings* m_viewSettings;
+ static DiffSettings* m_diffSettings;
+
+ Diff2::KompareModelList* m_modelList;
+
+ KompareSplitter* m_splitter;
+
+ KAction* m_saveAll;
+ KAction* m_saveDiff;
+ KAction* m_swap;
+ KAction* m_diffStats;
+
+ KTempFile* m_tempDiff;
+
+ struct Kompare::Info m_info;
+};
+
+#endif // KOMPAREPART_H
diff --git a/kompare/komparepart/kompare_qsplitter.h b/kompare/komparepart/kompare_qsplitter.h
new file mode 100644
index 00000000..1f1be49d
--- /dev/null
+++ b/kompare/komparepart/kompare_qsplitter.h
@@ -0,0 +1,213 @@
+/****************************************************************************
+**
+**
+** Definition of QSplitter class
+**
+** Created : 980105
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the widgets module of the Qt GUI Toolkit.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+**********************************************************************/
+
+#ifndef QSPLITTER_H
+#define QSPLITTER_H
+
+#ifndef QT_H
+#include "qframe.h"
+#include "qvaluelist.h"
+#endif // QT_H
+
+#ifndef QT_NO_SPLITTER
+
+
+//class QSplitterHandle;
+class QSplitterLayoutStruct;
+class QTextStream;
+
+class QSplitterPrivate
+{
+public:
+ QSplitterPrivate()
+ : opaque( FALSE ), firstShow( TRUE ), childrenCollapsible( TRUE ),
+ handleWidth( 0 ) { }
+
+ QPtrList<QSplitterLayoutStruct> list;
+ bool opaque : 8;
+ bool firstShow : 8;
+ bool childrenCollapsible : 8;
+ int handleWidth;
+};
+
+class Q_EXPORT QSplitter : public QFrame
+{
+ Q_OBJECT
+ Q_PROPERTY( Orientation orientation READ orientation WRITE setOrientation )
+ Q_PROPERTY( bool opaqueResize READ opaqueResize WRITE setOpaqueResize )
+ Q_PROPERTY( int handleWidth READ handleWidth WRITE setHandleWidth )
+ Q_PROPERTY( bool childrenCollapsible READ childrenCollapsible WRITE setChildrenCollapsible )
+
+public:
+ // ### Qt 4.0: remove Auto from public API
+ enum ResizeMode { Stretch, KeepSize, FollowSizeHint, Auto };
+
+ QSplitter( QWidget* parent = 0, const char* name = 0 );
+ QSplitter( Orientation, QWidget* parent = 0, const char* name = 0 );
+ ~QSplitter();
+
+ virtual void setOrientation( Orientation );
+ Orientation orientation() const { return orient; }
+
+ // ### Qt 4.0: make setChildrenCollapsible() and setCollapsible() virtual
+
+ void setChildrenCollapsible( bool );
+ bool childrenCollapsible() const;
+
+ void setCollapsible( QWidget *w, bool );
+ virtual void setResizeMode( QWidget *w, ResizeMode );
+ virtual void setOpaqueResize( bool = TRUE );
+ bool opaqueResize() const;
+
+ void moveToFirst( QWidget * );
+ void moveToLast( QWidget * );
+
+ void refresh() { recalc( TRUE ); }
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+
+ QValueList<int> sizes() const;
+ void setSizes( QValueList<int> );
+
+ int handleWidth() const;
+ void setHandleWidth( int );
+
+protected:
+ void childEvent( QChildEvent * );
+
+ bool event( QEvent * );
+ void resizeEvent( QResizeEvent * );
+
+ int idAfter( QWidget* ) const;
+
+ void moveSplitter( QCOORD pos, int id );
+ virtual void drawSplitter( QPainter*, QCOORD x, QCOORD y,
+ QCOORD w, QCOORD h );
+ void styleChange( QStyle& );
+ int adjustPos( int, int );
+ virtual void setRubberband( int );
+ void getRange( int id, int *, int * );
+
+public: // private (:
+ enum { DefaultResizeMode = 3 };
+
+ void init();
+ void recalc( bool update = FALSE );
+ void doResize();
+ void storeSizes();
+ void getRange( int id, int *, int *, int *, int * );
+ void addContribution( int, int *, int *, bool );
+ int adjustPos( int, int, int *, int *, int *, int * );
+ bool collapsible( QSplitterLayoutStruct * );
+ void processChildEvents();
+ QSplitterLayoutStruct *findWidget( QWidget * );
+ QSplitterLayoutStruct *addWidget( QWidget *, bool prepend = FALSE );
+ void recalcId();
+ void doMove( bool backwards, int pos, int id, int delta, bool upLeft,
+ bool mayCollapse );
+ void setGeo( QWidget *w, int pos, int size, bool splitterMoved );
+ int findWidgetJustBeforeOrJustAfter( int id, int delta, int &collapsibleSize );
+ void updateHandles();
+
+ inline QCOORD pick( const QPoint &p ) const
+ { return orient == Horizontal ? p.x() : p.y(); }
+ inline QCOORD pick( const QSize &s ) const
+ { return orient == Horizontal ? s.width() : s.height(); }
+
+ inline QCOORD trans( const QPoint &p ) const
+ { return orient == Vertical ? p.x() : p.y(); }
+ inline QCOORD trans( const QSize &s ) const
+ { return orient == Vertical ? s.width() : s.height(); }
+
+ QSplitterPrivate *d;
+
+ Orientation orient;
+ friend class QSplitterHandle;
+
+#ifndef QT_NO_TEXTSTREAM
+// moc doesn't like these.
+// friend Q_EXPORT QTextStream& operator<<( QTextStream&, const QSplitter& );
+// friend Q_EXPORT QTextStream& operator>>( QTextStream&, QSplitter& );
+#endif
+
+public:
+#if defined(Q_DISABLE_COPY)
+ QSplitter( const QSplitter & );
+ QSplitter& operator=( const QSplitter & );
+#endif
+};
+
+#ifndef QT_NO_TEXTSTREAM
+Q_EXPORT QTextStream& operator<<( QTextStream&, const QSplitter& );
+Q_EXPORT QTextStream& operator>>( QTextStream&, QSplitter& );
+#endif
+
+class QSplitterHandle : public QWidget
+{
+ Q_OBJECT
+public:
+ QSplitterHandle( Orientation o,
+ QSplitter *parent, const char* name=0 );
+ void setOrientation( Orientation o );
+ Orientation orientation() const { return orient; }
+
+ bool opaque() const { return s->opaqueResize(); }
+
+ QSize sizeHint() const;
+
+ int id() const { return myId; } // d->list.at(id())->wid == this
+ void setId( int i ) { myId = i; }
+
+protected:
+ void paintEvent( QPaintEvent * );
+ void mouseMoveEvent( QMouseEvent * );
+ void mousePressEvent( QMouseEvent * );
+ void mouseReleaseEvent( QMouseEvent * );
+
+public: // private (:
+ Orientation orient;
+ bool opaq;
+ int myId;
+
+ QSplitter *s;
+};
+
+const uint Default = 2;
+
+class QSplitterLayoutStruct : public Qt
+{
+public:
+ QCOORD sizer;
+ uint isHandle : 1;
+ uint collapsible : 2;
+ uint resizeMode : 2;
+ QWidget *wid;
+
+ QSplitterLayoutStruct()
+ : sizer( -1 ), collapsible( Default ) { }
+ QCOORD getSizer( Orientation orient );
+};
+
+#endif // QT_NO_SPLITTER
+
+#endif // QSPLITTER_H
diff --git a/kompare/komparepart/kompareconnectwidget.cpp b/kompare/komparepart/kompareconnectwidget.cpp
new file mode 100644
index 00000000..eed8e99c
--- /dev/null
+++ b/kompare/komparepart/kompareconnectwidget.cpp
@@ -0,0 +1,285 @@
+/***************************************************************************
+ kompareconnectwidget.cpp - description
+ -------------------
+ begin : Tue Jun 26 2001
+ copyright : (C) 2001-2003 John Firebaugh
+ (C) 2001-2004 Otto Bruggeman
+ (C) 2004 Jeff Snyder
+ email : jfirebaugh@kde.org
+ otto.bruggeman@home.nl
+ jeff@caffeinated.me.uk
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 <qapplication.h>
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qstyle.h>
+#include <qtimer.h>
+
+#include <kdebug.h>
+
+#include "viewsettings.h"
+#include "komparemodellist.h"
+#include "komparelistview.h"
+#include "komparesplitter.h"
+
+#include "kompareconnectwidget.h"
+
+using namespace Diff2;
+
+KompareConnectWidgetFrame::KompareConnectWidgetFrame( KompareListView* left,
+ KompareListView* right,
+ ViewSettings* settings,
+ KompareSplitter* parent,
+ const char* name ) :
+ QSplitterHandle(Horizontal, (QSplitter *)parent, name),
+ m_wid ( left, right, settings, this, name ),
+ m_label ( "", this ),
+ m_layout ( this )
+{
+ setSizePolicy ( QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored) );
+ m_wid.setSizePolicy ( QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored) );
+ m_label.setSizePolicy ( QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed) );
+ m_label.setMargin(3);
+ QFrame* bottomLine = new QFrame(this);
+ bottomLine->setFrameShape(QFrame::HLine);
+ bottomLine->setFrameShadow ( QFrame::Plain );
+ bottomLine->setSizePolicy ( QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed) );
+ bottomLine->setFixedHeight(1);
+ m_layout.setSpacing(0);
+ m_layout.setMargin(0);
+ m_layout.addWidget(&m_label);
+ m_layout.addWidget(bottomLine);
+ m_layout.addWidget(&m_wid);
+}
+
+KompareConnectWidgetFrame::~KompareConnectWidgetFrame()
+{
+}
+
+QSize KompareConnectWidgetFrame::sizeHint() const
+{
+ return QSize(50, style().pixelMetric( QStyle::PM_ScrollBarExtent ) );
+}
+
+static int kMouseOffset;
+
+void KompareConnectWidgetFrame::mouseMoveEvent( QMouseEvent *e )
+{
+ if ( !(e->state()&LeftButton) )
+ return;
+
+ QCOORD pos = s->pick( parentWidget()->mapFromGlobal(e->globalPos()) )
+ - kMouseOffset;
+
+ ((KompareSplitter*)s)->moveSplitter( pos, id() );
+}
+
+void KompareConnectWidgetFrame::mousePressEvent( QMouseEvent *e )
+{
+ if ( e->button() == LeftButton )
+ kMouseOffset = s->pick( e->pos() );
+ QSplitterHandle::mousePressEvent(e);
+}
+
+void KompareConnectWidgetFrame::mouseReleaseEvent( QMouseEvent *e )
+{
+ if ( !opaque() && e->button() == LeftButton ) {
+ QCOORD pos = s->pick( parentWidget()->mapFromGlobal(e->globalPos()) )
+ - kMouseOffset;
+ ((KompareSplitter*)s)->moveSplitter( pos, id() );
+ }
+}
+
+KompareConnectWidget::KompareConnectWidget( KompareListView* left, KompareListView* right,
+ ViewSettings* settings, QWidget* parent, const char* name )
+ : QWidget(parent, name),
+ m_settings( settings ),
+ m_leftView( left ),
+ m_rightView( right ),
+ m_selectedModel( 0 ),
+ m_selectedDifference( 0 )
+{
+// connect( m_settings, SIGNAL( settingsChanged() ), this, SLOT( slotDelayedRepaint() ) );
+ setBackgroundMode( NoBackground );
+ setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Minimum ) );
+ setFocusProxy( parent->parentWidget() );
+}
+
+KompareConnectWidget::~KompareConnectWidget()
+{
+}
+
+void KompareConnectWidget::slotSetSelection( const DiffModel* model, const Difference* diff )
+{
+ if( m_selectedModel == model && m_selectedDifference == diff )
+ return;
+
+ if ( m_selectedModel == model && m_selectedDifference != diff )
+ {
+ m_selectedDifference = diff;
+ slotDelayedRepaint();
+ return;
+ }
+
+ m_selectedModel = model;
+ m_selectedDifference = diff;
+
+ slotDelayedRepaint();
+}
+
+void KompareConnectWidget::slotDelayedRepaint()
+{
+ QTimer::singleShot( 0, this, SLOT( repaint() ) );
+}
+
+void KompareConnectWidget::slotSetSelection( const Difference* diff )
+{
+ if ( m_selectedDifference == diff )
+ return;
+
+ m_selectedDifference = diff;
+
+ slotDelayedRepaint();
+}
+
+void KompareConnectWidget::paintEvent( QPaintEvent* /* e */ )
+{
+// kdDebug(8106) << "KompareConnectWidget::paintEvent()" << endl;
+
+ QPixmap pixbuf(size());
+ QPainter paint(&pixbuf, this);
+ QPainter* p = &paint;
+
+ p->fillRect( 0, 0, pixbuf.width(), pixbuf.height(), white.dark(110) );
+
+ if ( m_selectedModel )
+ {
+ int firstL = m_leftView->firstVisibleDifference();
+ int firstR = m_rightView->firstVisibleDifference();
+ int lastL = m_leftView->lastVisibleDifference();
+ int lastR = m_rightView->lastVisibleDifference();
+
+ int first = firstL < 0 ? firstR : QMIN( firstL, firstR );
+ int last = lastL < 0 ? lastR : QMAX( lastL, lastR );
+
+// kdDebug(8106) << " left: " << firstL << " - " << lastL << endl;
+// kdDebug(8106) << " right: " << firstR << " - " << lastR << endl;
+// kdDebug(8106) << " drawing: " << first << " - " << last << endl;
+ if ( first >= 0 && last >= 0 && first <= last )
+ {
+ const DifferenceList* differences = const_cast<DiffModel*>(m_selectedModel)->differences();
+ DifferenceListConstIterator diffIt = differences->at( first );
+ DifferenceListConstIterator dEnd = differences->at( last + 1 );
+
+ QRect leftRect, rightRect;
+
+ for ( int i = first; i <= last; ++diffIt, ++i )
+ {
+ Difference* diff = *diffIt;
+ bool selected = ( diff == m_selectedDifference );
+
+ if ( QApplication::reverseLayout() )
+ {
+ leftRect = m_rightView->itemRect( i );
+ rightRect = m_leftView->itemRect( i );
+ }
+ else
+ {
+ leftRect = m_leftView->itemRect( i );
+ rightRect = m_rightView->itemRect( i );
+ }
+
+ int tl = leftRect.top();
+ int tr = rightRect.top();
+ int bl = leftRect.bottom();
+ int br = rightRect.bottom();
+
+ // Bah, stupid 16-bit signed shorts in that crappy X stuff...
+ tl = tl >= -32768 ? tl : -32768;
+ tr = tr >= -32768 ? tr : -32768;
+ bl = bl <= 32767 ? bl : 32767;
+ br = br <= 32767 ? br : 32767;
+
+// kdDebug(8106) << "drawing: " << tl << " " << tr << " " << bl << " " << br << endl;
+ QPointArray topBezier = makeTopBezier( tl, tr );
+ QPointArray bottomBezier = makeBottomBezier( bl, br );
+
+ QColor color = m_settings->colorForDifferenceType( diff->type(), selected, diff->applied() ).dark(110);
+ p->setPen( color );
+ p->setBrush( color );
+ p->drawPolygon ( makeConnectPoly( topBezier, bottomBezier ) );
+
+ if ( selected )
+ {
+ p->setPen( color.dark(135) );
+ p->drawPolyline( topBezier );
+ p->drawPolyline( bottomBezier );
+ }
+ }
+ }
+ }
+
+ p->flush();
+ bitBlt(this, 0, 0, &pixbuf);
+}
+
+QPointArray KompareConnectWidget::makeTopBezier( int tl, int tr )
+{
+ int l = 0;
+ int r = width();
+ int o = (int)((double)r*0.4); // 40% of width
+ QPointArray controlPoints;
+
+ if ( tl != tr )
+ {
+ controlPoints.setPoints( 4, l,tl, o,tl, r-o,tr, r,tr );
+ return controlPoints.cubicBezier();
+ }
+ else
+ {
+ controlPoints.setPoints( 2, l,tl, r,tr );
+ return controlPoints;
+ }
+}
+
+QPointArray KompareConnectWidget::makeBottomBezier( int bl, int br )
+{
+ int l = 0;
+ int r = width();
+ int o = (int)((double)r*0.4); // 40% of width
+ QPointArray controlPoints;
+
+ if ( bl != br )
+ {
+ controlPoints.setPoints( 4, r,br, r-o,br, o,bl, l,bl );
+ return controlPoints.cubicBezier();
+ }
+ else
+ {
+ controlPoints.setPoints( 2, r,br, l,bl );
+ return controlPoints;
+ }
+}
+
+QPointArray KompareConnectWidget::makeConnectPoly( const QPointArray& topBezier, const QPointArray& bottomBezier )
+{
+ QPointArray poly( topBezier.size() + bottomBezier.size() );
+ for( uint i = 0; i < topBezier.size(); i++ )
+ poly.setPoint( i, topBezier.point( i ) );
+ for( uint i = 0; i < bottomBezier.size(); i++ )
+ poly.setPoint( i + topBezier.size(), bottomBezier.point( i ) );
+
+ return poly;
+}
+
+#include "kompareconnectwidget.moc"
diff --git a/kompare/komparepart/kompareconnectwidget.h b/kompare/komparepart/kompareconnectwidget.h
new file mode 100644
index 00000000..96160c97
--- /dev/null
+++ b/kompare/komparepart/kompareconnectwidget.h
@@ -0,0 +1,95 @@
+/***************************************************************************
+ kompareconnectwidget.h - description
+ -------------------
+ begin : Tue Jun 26 2001
+ copyright : (C) 2001-2003 John Firebaugh
+ (C) 2001-2004 Otto Bruggeman
+ (C) 2004 Jeff Snyder
+ email : jfirebaugh@kde.org
+ otto.bruggeman@home.nl
+ jeff@caffeinated.me.uk
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef KOMPARECONNECTWIDGET_H
+#define KOMPARECONNECTWIDGET_H
+
+#include "kompare_qsplitter.h"
+#include <qwidget.h>
+
+namespace Diff2 {
+class DiffModel;
+}
+class ViewSettings;
+class KompareListView;
+class KompareSplitter;
+
+class KompareConnectWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ KompareConnectWidget( KompareListView* left, KompareListView* right,
+ ViewSettings* settings, QWidget* parent, const char* name = 0 );
+ ~KompareConnectWidget();
+
+public slots:
+ void slotSetSelection( const Diff2::DiffModel* model, const Diff2::Difference* diff );
+ void slotSetSelection( const Diff2::Difference* diff );
+
+ void slotDelayedRepaint();
+
+signals:
+ void selectionChanged(const Diff2::Difference* diff);
+
+protected:
+ void paintEvent( QPaintEvent* e );
+ QPointArray makeTopBezier( int tl, int tr );
+ QPointArray makeBottomBezier( int bl, int br );
+ QPointArray makeConnectPoly( const QPointArray& topBezier, const QPointArray& bottomBezier );
+
+private:
+ ViewSettings* m_settings;
+
+ KompareListView* m_leftView;
+ KompareListView* m_rightView;
+
+ const Diff2::DiffModel* m_selectedModel;
+ const Diff2::Difference* m_selectedDifference;
+};
+
+class KompareConnectWidgetFrame : public QSplitterHandle
+{
+ Q_OBJECT
+public:
+ KompareConnectWidgetFrame( KompareListView* left, KompareListView* right,
+ ViewSettings* settings, KompareSplitter* parent, const char* name = 0 );
+ ~KompareConnectWidgetFrame();
+
+ QSize sizeHint() const;
+
+ KompareConnectWidget* wid() { return &m_wid; }
+
+protected:
+ // stop the parent QSplitterHandle painting
+ void paintEvent( QPaintEvent* /* e */ ) { }
+
+ void mouseMoveEvent( QMouseEvent * );
+ void mousePressEvent( QMouseEvent * );
+ void mouseReleaseEvent( QMouseEvent * );
+
+private:
+ KompareConnectWidget m_wid;
+ QLabel m_label;
+ QVBoxLayout m_layout;
+};
+
+#endif
diff --git a/kompare/komparepart/komparelistview.cpp b/kompare/komparepart/komparelistview.cpp
new file mode 100644
index 00000000..b86bdef9
--- /dev/null
+++ b/kompare/komparepart/komparelistview.cpp
@@ -0,0 +1,783 @@
+/***************************************************************************
+ komparelistview.h - description
+ -------------------
+ begin : Sun Mar 4 2001
+ copyright : (C) 2001-2004 Otto Bruggeman
+ (C) 2001-2003 John Firebaugh
+ (C) 2004 Jeff Snyder
+ email : otto.bruggeman@home.nl
+ jfirebaugh@kde.org
+ jeff@caffeinated.me.uk
+****************************************************************************/
+
+/***************************************************************************
+**
+** 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 <qheader.h>
+#include <qpainter.h>
+#include <qregexp.h>
+#include <qtimer.h>
+
+#include <kdebug.h>
+#include <kglobal.h>
+#include <kglobalsettings.h>
+
+#include "diffmodel.h"
+#include "diffhunk.h"
+#include "difference.h"
+#include "viewsettings.h"
+#include "komparemodellist.h"
+#include "komparesplitter.h"
+
+#include "komparelistview.h"
+
+#define COL_LINE_NO 0
+#define COL_MAIN 1
+
+#define BLANK_LINE_HEIGHT 3
+#define HUNK_LINE_HEIGHT 5
+
+using namespace Diff2;
+
+KompareListViewFrame::KompareListViewFrame( bool isSource,
+ ViewSettings* settings,
+ KompareSplitter* parent,
+ const char* name ):
+ QFrame ( parent, name ),
+ m_view ( isSource, settings, this, name ),
+ m_label ( isSource?"Source":"Dest", this ),
+ m_layout ( this )
+{
+ setSizePolicy ( QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored) );
+ m_label.setSizePolicy ( QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed) );
+ QFrame *bottomLine = new QFrame(this);
+ bottomLine->setFrameShape(QFrame::HLine);
+ bottomLine->setFrameShadow ( QFrame::Plain );
+ bottomLine->setSizePolicy ( QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed) );
+ bottomLine->setFixedHeight(1);
+ m_label.setMargin(3);
+ m_layout.setSpacing(0);
+ m_layout.setMargin(0);
+ m_layout.addWidget(&m_label);
+ m_layout.addWidget(bottomLine);
+ m_layout.addWidget(&m_view);
+
+ connect( &m_view, SIGNAL(differenceClicked(const Diff2::Difference*)),
+ parent, SLOT(slotDifferenceClicked(const Diff2::Difference*)) );
+
+ connect( parent, SIGNAL(scrollViewsToId(int)), &m_view, SLOT(scrollToId(int)) );
+ connect( parent, SIGNAL(setXOffset(int)), &m_view, SLOT(setXOffset(int)) );
+ connect( &m_view, SIGNAL(resized()), parent, SLOT(slotUpdateScrollBars()) );
+}
+
+void KompareListViewFrame::slotSetModel( const DiffModel* model )
+{
+ if( model )
+ {
+ if( view()->isSource() ) {
+ if( !model->sourceRevision().isEmpty() )
+ m_label.setText( model->sourceFile() + " (" + model->sourceRevision() + ")" );
+ else
+ m_label.setText( model->sourceFile() );
+ } else {
+ if( !model->destinationRevision().isEmpty() )
+ m_label.setText( model->destinationFile() + " (" + model->destinationRevision() + ")" );
+ else
+ m_label.setText( model->destinationFile() );
+ }
+ } else {
+ m_label.setText( QString::null );
+ }
+}
+
+KompareListView::KompareListView( bool isSource,
+ ViewSettings* settings,
+ QWidget* parent, const char* name ) :
+ KListView( parent, name ),
+ m_isSource( isSource ),
+ m_settings( settings ),
+ m_scrollId( -1 ),
+ m_selectedModel( 0 ),
+ m_selectedDifference( 0 )
+{
+ header()->hide();
+ addColumn( "Line Number", 0 );
+ addColumn( "Main" );
+ addColumn( "Blank" );
+ setColumnAlignment( COL_LINE_NO, AlignRight );
+ setAllColumnsShowFocus( true );
+ setRootIsDecorated( false );
+ setSorting( -1 );
+ setItemMargin( 3 );
+ setTreeStepSize( 0 );
+ setColumnWidthMode( COL_LINE_NO, Maximum );
+ setColumnWidthMode( COL_MAIN, Maximum );
+ setResizeMode( LastColumn );
+ setFrameStyle( QFrame::NoFrame );
+ setVScrollBarMode( QScrollView::AlwaysOff );
+ setHScrollBarMode( QScrollView::AlwaysOff );
+ setFocusPolicy( QWidget::NoFocus );
+ setFont( m_settings->m_font );
+ setSpaces( m_settings->m_tabToNumberOfSpaces );
+ setFocusProxy( parent->parentWidget() );
+}
+
+KompareListView::~KompareListView()
+{
+}
+
+KompareListViewItem* KompareListView::itemAtIndex( int i )
+{
+ return m_items[ i ];
+}
+
+int KompareListView::firstVisibleDifference()
+{
+ QListViewItem* item = itemAt( QPoint( 0, 0 ) );
+
+ if( item == 0 )
+ {
+ kdDebug(8104) << "no item at viewport coordinates (0,0)" << endl;
+ }
+
+ while( item ) {
+ KompareListViewLineItem* lineItem = dynamic_cast<KompareListViewLineItem*>(item);
+ if( lineItem && lineItem->diffItemParent()->difference()->type() != Difference::Unchanged )
+ break;
+ item = item->itemBelow();
+ }
+
+ if( item )
+ return m_items.findIndex( ((KompareListViewLineItem*)item)->diffItemParent() );
+
+ return -1;
+}
+
+int KompareListView::lastVisibleDifference()
+{
+ QListViewItem* item = itemAt( QPoint( 0, visibleHeight() - 1 ) );
+
+ if( item == 0 )
+ {
+ kdDebug(8104) << "no item at viewport coordinates (0," << visibleHeight() - 1 << ")" << endl;
+ item = lastItem();
+ }
+
+ while( item ) {
+ KompareListViewLineItem* lineItem = dynamic_cast<KompareListViewLineItem*>(item);
+ if( lineItem && lineItem->diffItemParent()->difference()->type() != Difference::Unchanged )
+ break;
+ item = item->itemAbove();
+ }
+
+ if( item )
+ return m_items.findIndex( ((KompareListViewLineItem*)item)->diffItemParent() );
+
+ return -1;
+}
+
+QRect KompareListView::itemRect( int i )
+{
+ QListViewItem* item = itemAtIndex( i );
+ int x = 0;
+ int y = itemPos( item );
+ int vx, vy;
+ contentsToViewport( x, y, vx, vy );
+ return QRect( vx, vy, 0, item->totalHeight() );
+}
+
+int KompareListView::minScrollId()
+{
+ return visibleHeight() / 2;
+}
+
+int KompareListView::maxScrollId()
+{
+ KompareListViewItem* item = (KompareListViewItem*)firstChild();
+ if(!item) return 0;
+ while( item && item->nextSibling() ) {
+ item = (KompareListViewItem*)item->nextSibling();
+ }
+ int maxId = item->scrollId() + item->maxHeight() - minScrollId();
+ kdDebug(8104) << "Max ID = " << maxId << endl;
+ return maxId;
+}
+
+int KompareListView::contentsWidth()
+{
+ return ( columnWidth(COL_LINE_NO) + columnWidth(COL_MAIN) );
+}
+
+void KompareListView::setXOffset( int x )
+{
+ kdDebug(8104) << "SetXOffset : Scroll to x position: " << x << endl;
+ setContentsPos( x, contentsY() );
+}
+
+void KompareListView::scrollToId( int id )
+{
+// kdDebug(8104) << "ScrollToID : Scroll to id : " << id << endl;
+ KompareListViewItem* item = (KompareListViewItem*)firstChild();
+ while( item && item->nextSibling() ) {
+ if( ((KompareListViewItem*)item->nextSibling())->scrollId() > id )
+ break;
+ item = (KompareListViewItem*)item->nextSibling();
+ }
+
+ if( item ) {
+ int pos = item->itemPos();
+ int itemId = item->scrollId();
+ int height = item->totalHeight();
+ double r = (double)( id - itemId ) / (double)item->maxHeight();
+ int y = pos + (int)( r * (double)height ) - minScrollId();
+// kdDebug(8104) << "scrollToID: " << endl;
+// kdDebug(8104) << " id = " << id << endl;
+// kdDebug(8104) << " id after = " << ( item->nextSibling() ? QString::number( ((KompareListViewItem*)item->nextSibling())->scrollId() ) : "no such sibling..." ) << endl;
+// kdDebug(8104) << " pos = " << pos << endl;
+// kdDebug(8104) << " itemId = " << itemId << endl;
+// kdDebug(8104) << " r = " << r << endl;
+// kdDebug(8104) << " height = " << height << endl;
+// kdDebug(8104) << " minID = " << minScrollId() << endl;
+// kdDebug(8104) << " y = " << y << endl;
+// kdDebug(8104) << "contentsHeight = " << contentsHeight() << endl;
+// kdDebug(8104) << " c - y = " << contentsHeight() - y << endl;
+ setContentsPos( contentsX(), y );
+ }
+
+ m_scrollId = id;
+}
+
+int KompareListView::scrollId()
+{
+ if( m_scrollId < 0 )
+ m_scrollId = minScrollId();
+ return m_scrollId;
+}
+
+void KompareListView::setSelectedDifference( const Difference* diff, bool scroll )
+{
+ kdDebug(8104) << "KompareListView::setSelectedDifference(" << diff << ", " << scroll << ")" << endl;
+
+ // When something other than a click causes this function to be called,
+ // it'll only get called once, and all is simple.
+ //
+ // When the user clicks on a diff, this function will get called once when
+ // komparesplitter::slotDifferenceClicked runs, and again when the
+ // setSelection signal from the modelcontroller arrives.
+ //
+ // the first call (which will always be from the splitter) will have
+ // scroll==false, and the the second call will bail out here.
+ // Which is why clicking on a difference does not cause the listviews to
+ // scroll.
+ if ( m_selectedDifference == diff )
+ return;
+
+ m_selectedDifference = diff;
+
+ KompareListViewItem* item = m_itemDict[ (void*)diff ];
+ if( !item ) {
+ kdDebug(8104) << "KompareListView::slotSetSelection(): couldn't find our selection!" << endl;
+ return;
+ }
+
+ // why does this not happen when the user clicks on a diff? see the comment above.
+ if( scroll )
+ scrollToId(item->scrollId());
+ setSelected( item, true );
+}
+
+void KompareListView::slotSetSelection( const Difference* diff )
+{
+ kdDebug(8104) << "KompareListView::slotSetSelection( const Difference* diff )" << endl;
+
+ setSelectedDifference( diff, true );
+}
+
+void KompareListView::slotSetSelection( const DiffModel* model, const Difference* diff )
+{
+ kdDebug(8104) << "KompareListView::slotSetSelection( const DiffModel* model, const Difference* diff )" << endl;
+
+ if( m_selectedModel && m_selectedModel == model ) {
+ slotSetSelection( diff );
+ return;
+ }
+
+ clear();
+ m_items.clear();
+ m_itemDict.clear();
+ m_selectedModel = model;
+
+ m_itemDict.resize(model->differenceCount());
+
+ DiffHunkListConstIterator hunkIt = model->hunks()->begin();
+ DiffHunkListConstIterator hEnd = model->hunks()->end();
+
+ KompareListViewItem* item = 0;
+ Difference* tmpdiff = 0;
+ DiffHunk* hunk = 0;
+
+
+ for ( ; hunkIt != hEnd; ++hunkIt )
+ {
+ hunk = *hunkIt;
+
+ if( item )
+ item = new KompareListViewHunkItem( this, item, hunk, model->isBlended() );
+ else
+ item = new KompareListViewHunkItem( this, hunk, model->isBlended() );
+
+ DifferenceListConstIterator diffIt = hunk->differences().begin();
+ DifferenceListConstIterator dEnd = hunk->differences().end();
+
+ for ( ; diffIt != dEnd; ++diffIt )
+ {
+ tmpdiff = *diffIt;
+
+ item = new KompareListViewDiffItem( this, item, tmpdiff );
+
+ int type = tmpdiff->type();
+
+ if ( type != Difference::Unchanged )
+ {
+ m_items.append( (KompareListViewDiffItem*)item );
+ m_itemDict.insert( tmpdiff, (KompareListViewDiffItem*)item );
+ }
+ }
+ }
+
+ slotSetSelection( diff );
+}
+
+void KompareListView::contentsMousePressEvent( QMouseEvent* e )
+{
+ QPoint vp = contentsToViewport( e->pos() );
+ KompareListViewLineItem* lineItem = dynamic_cast<KompareListViewLineItem*>( itemAt( vp ) );
+ if( !lineItem )
+ return;
+ KompareListViewDiffItem* diffItem = lineItem->diffItemParent();
+ if( diffItem->difference()->type() != Difference::Unchanged ) {
+ emit differenceClicked( diffItem->difference() );
+ }
+}
+
+void KompareListView::contentsMouseDoubleClickEvent( QMouseEvent* e )
+{
+ QPoint vp = contentsToViewport( e->pos() );
+ KompareListViewLineItem* lineItem = dynamic_cast<KompareListViewLineItem*>( itemAt( vp ) );
+ if ( !lineItem )
+ return;
+ KompareListViewDiffItem* diffItem = lineItem->diffItemParent();
+ if ( diffItem->difference()->type() != Difference::Unchanged ) {
+ // FIXME: make a new signal that does both
+ emit differenceClicked( diffItem->difference() );
+ emit applyDifference( !diffItem->difference()->applied() );
+ }
+}
+
+void KompareListView::slotApplyDifference( bool apply )
+{
+ m_itemDict[ (void*)m_selectedDifference ]->applyDifference( apply );
+}
+
+void KompareListView::slotApplyAllDifferences( bool apply )
+{
+ QPtrDictIterator<KompareListViewDiffItem> it ( m_itemDict );
+ for( ; it.current(); ++it )
+ it.current()->applyDifference( apply );
+ repaint();
+}
+
+void KompareListView::slotApplyDifference( const Difference* diff, bool apply )
+{
+ m_itemDict[ (void*)diff ]->applyDifference( apply );
+}
+
+void KompareListView::setSpaces( int spaces )
+{
+ m_spaces.truncate( 0 );
+ kdDebug( 8104 ) << "tabToNumberOfSpaces: " << spaces << endl;
+ for ( int i = 0; i < spaces; i++ )
+ m_spaces += " ";
+
+ triggerUpdate();
+}
+
+void KompareListView::wheelEvent( QWheelEvent* e )
+{
+ e->ignore(); // we want the parent to catch wheel events
+}
+
+void KompareListView::resizeEvent( QResizeEvent* e )
+{
+ KListView::resizeEvent(e);
+ emit resized();
+ kdDebug() << "resizeEvent " << endl;
+}
+
+KompareListViewItem::KompareListViewItem( KompareListView* parent )
+ : QListViewItem( parent ),
+ m_scrollId( 0 )
+{
+// kdDebug(8104) << "Created KompareListViewItem with scroll id " << m_scrollId << endl;
+}
+
+KompareListViewItem::KompareListViewItem( KompareListView* parent, KompareListViewItem* after )
+ : QListViewItem( parent, after ),
+ m_scrollId( after->scrollId() + after->maxHeight() )
+{
+// kdDebug(8104) << "Created KompareListViewItem with scroll id " << m_scrollId << endl;
+}
+
+KompareListViewItem::KompareListViewItem( KompareListViewItem* parent )
+ : QListViewItem( parent ),
+ m_scrollId( 0 )
+{
+}
+
+KompareListViewItem::KompareListViewItem( KompareListViewItem* parent, KompareListViewItem* /*after*/ )
+ : QListViewItem( parent ),
+ m_scrollId( 0 )
+{
+}
+
+KompareListView* KompareListViewItem::kompareListView() const
+{
+ return (KompareListView*)listView();
+}
+
+void KompareListViewItem::paintFocus( QPainter* /* p */, const QColorGroup& /* cg */, const QRect& /* r */ )
+{
+ // Don't paint anything
+}
+
+KompareListViewDiffItem::KompareListViewDiffItem( KompareListView* parent, Difference* difference )
+ : KompareListViewItem( parent ),
+ m_difference( difference ),
+ m_sourceItem( 0L ),
+ m_destItem( 0L )
+{
+ init();
+}
+
+KompareListViewDiffItem::KompareListViewDiffItem( KompareListView* parent, KompareListViewItem* after, Difference* difference )
+ : KompareListViewItem( parent, after ),
+ m_difference( difference ),
+ m_sourceItem( 0L ),
+ m_destItem( 0L )
+{
+ init();
+}
+
+void KompareListViewDiffItem::init()
+{
+ setExpandable( true );
+ setOpen( true );
+ m_destItem = new KompareListViewLineContainerItem( this, false );
+ m_sourceItem = new KompareListViewLineContainerItem( this, true );
+ setVisibility();
+}
+
+void KompareListViewDiffItem::setup()
+{
+ KompareListViewItem::setup();
+ setHeight( 0 );
+}
+
+void KompareListViewDiffItem::setVisibility()
+{
+ m_sourceItem->setVisible( kompareListView()->isSource() || m_difference->applied() );
+ m_destItem->setVisible( !m_sourceItem->isVisible() );
+}
+
+void KompareListViewDiffItem::applyDifference( bool apply )
+{
+ kdDebug(8104) << "KompareListViewDiffItem::applyDifference( " << apply << " )" << endl;
+ setVisibility();
+ setup();
+ repaint();
+}
+
+int KompareListViewDiffItem::maxHeight()
+{
+ int lines = QMAX( m_difference->sourceLineCount(), m_difference->destinationLineCount() );
+ if( lines == 0 )
+ return BLANK_LINE_HEIGHT;
+ else
+ return lines * listView()->fontMetrics().lineSpacing();
+}
+
+void KompareListViewDiffItem::setSelected( bool b )
+{
+ kdDebug(8104) << "KompareListViewDiffItem::setSelected( " << b << " )" << endl;
+ KompareListViewItem::setSelected( b );
+ QListViewItem* item = m_sourceItem->isVisible() ?
+ m_sourceItem->firstChild() :
+ m_destItem->firstChild();
+ while( item && item->isVisible() ) {
+ item->repaint();
+ item = item->nextSibling();
+ }
+}
+
+KompareListViewLineContainerItem::KompareListViewLineContainerItem( KompareListViewDiffItem* parent, bool isSource )
+ : KompareListViewItem( parent ),
+ m_isSource( isSource )
+{
+// kdDebug(8104) << "isSource ? " << (isSource ? " Yes!" : " No!") << endl;
+ setExpandable( true );
+ setOpen( true );
+
+ int lines = lineCount();
+ int line = lineNumber() + lines - 1;
+// kdDebug(8104) << "LineNumber : " << lineNumber() << endl;
+ if( lines == 0 ) {
+ new KompareListViewBlankLineItem( this );
+ return;
+ }
+
+ for( int i = lines - 1; i >= 0; i--, line-- ) {
+ new KompareListViewLineItem( this, line, lineAt( i ) );
+ }
+}
+
+void KompareListViewLineContainerItem::setup()
+{
+ KompareListViewItem::setup();
+ setHeight( 0 );
+}
+
+KompareListViewDiffItem* KompareListViewLineContainerItem::diffItemParent() const
+{
+ return (KompareListViewDiffItem*)parent();
+}
+
+int KompareListViewLineContainerItem::lineCount() const
+{
+ return m_isSource ? diffItemParent()->difference()->sourceLineCount() :
+ diffItemParent()->difference()->destinationLineCount();
+}
+
+int KompareListViewLineContainerItem::lineNumber() const
+{
+ return m_isSource ? diffItemParent()->difference()->sourceLineNumber() :
+ diffItemParent()->difference()->destinationLineNumber();
+}
+
+DifferenceString* KompareListViewLineContainerItem::lineAt( int i ) const
+{
+ return m_isSource ? diffItemParent()->difference()->sourceLineAt( i ) :
+ diffItemParent()->difference()->destinationLineAt( i );
+}
+
+KompareListViewLineItem::KompareListViewLineItem( KompareListViewLineContainerItem* parent, int line, DifferenceString* text )
+ : KompareListViewItem( parent )
+{
+ setText( COL_LINE_NO, QString::number( line ) );
+ setText( COL_MAIN, text->string() );
+ m_text = text;
+}
+
+void KompareListViewLineItem::setup()
+{
+ KompareListViewItem::setup();
+ setHeight( listView()->fontMetrics().lineSpacing() );
+}
+
+void KompareListViewLineItem::paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int align )
+{
+ QColor bg = cg.base();
+ p->fillRect( 0, 0, width, height(), bg );
+ if ( diffItemParent()->difference()->type() == Difference::Unchanged )
+ {
+ if ( column == COL_LINE_NO )
+ {
+ bg = cg.background();
+ p->fillRect( 0, 0, width, height(), bg );
+ }
+ }
+ else
+ {
+ bg = kompareListView()->settings()->colorForDifferenceType(
+ diffItemParent()->difference()->type(),
+ diffItemParent()->isSelected(),
+ diffItemParent()->difference()->applied() );
+ if ( column != COL_MAIN )
+ p->fillRect( 0, 0, width, height(), bg );
+ }
+
+ p->setPen( cg.foreground() );
+
+ paintText( p, bg, column, width, align );
+
+ if ( diffItemParent()->isSelected() )
+ {
+ p->setPen( bg.dark(135) );
+ if ( this == parent()->firstChild() )
+ p->drawLine( 0, 0, width, 0 );
+ if ( nextSibling() == 0 )
+ p->drawLine( 0, height() - 1, width, height() - 1 );
+ }
+}
+
+void KompareListViewLineItem::paintText( QPainter* p, const QColor& bg, int column, int width, int align )
+{
+ if ( column == COL_MAIN )
+ {
+ QString textChunk;
+ int offset = listView()->itemMargin();
+ unsigned int prevValue = 0;
+ int chunkWidth;
+ QBrush changeBrush( bg, Dense3Pattern );
+ QBrush normalBrush( bg, SolidPattern );
+ QBrush brush;
+
+ if ( m_text->string().isEmpty() )
+ {
+ p->fillRect( 0, 0, width, height(), normalBrush );
+ return;
+ }
+
+ p->fillRect( 0, 0, offset, height(), normalBrush );
+
+ if ( !m_text->markerList().isEmpty() )
+ {
+ MarkerListConstIterator markerIt = m_text->markerList().begin();
+ MarkerListConstIterator mEnd = m_text->markerList().end();
+ Marker* m = *markerIt;
+
+ for ( ; markerIt != mEnd; ++markerIt )
+ {
+ m = *markerIt;
+ textChunk = m_text->string().mid( prevValue, m->offset() - prevValue );
+// kdDebug(8104) << "TextChunk = \"" << textChunk << "\"" << endl;
+// kdDebug(8104) << "c->offset() = " << c->offset() << endl;
+// kdDebug(8104) << "prevValue = " << prevValue << endl;
+ textChunk.replace( QChar('\t'), kompareListView()->spaces() );
+ prevValue = m->offset();
+ if ( m->type() == Marker::End )
+ {
+ QFont font( p->font() );
+ font.setBold( true );
+ p->setFont( font );
+// p->setPen( Qt::blue );
+ brush = changeBrush;
+ }
+ else
+ {
+ QFont font( p->font() );
+ font.setBold( false );
+ p->setFont( font );
+// p->setPen( Qt::black );
+ brush = normalBrush;
+ }
+ chunkWidth = p->fontMetrics().width( textChunk );
+ p->fillRect( offset, 0, chunkWidth, height(), brush );
+ p->drawText( offset, 0,
+ chunkWidth, height(),
+ align, textChunk );
+ offset += chunkWidth;
+ }
+ }
+ if ( prevValue < m_text->string().length() )
+ {
+ // Still have to draw some string without changes
+ textChunk = m_text->string().mid( prevValue, kMax( ( unsigned int )1, m_text->string().length() - prevValue ) );
+ textChunk.replace( QChar('\t'), kompareListView()->spaces() );
+// kdDebug(8104) << "TextChunk = \"" << textChunk << "\"" << endl;
+ QFont font( p->font() );
+ font.setBold( false );
+ p->setFont( font );
+ chunkWidth = p->fontMetrics().width( textChunk );
+ p->fillRect( offset, 0, chunkWidth, height(), normalBrush );
+ p->drawText( offset, 0,
+ chunkWidth, height(),
+ align, textChunk );
+ offset += chunkWidth;
+ }
+ p->fillRect( offset, 0, width - offset, height(), normalBrush );
+ }
+ else
+ {
+ p->fillRect( 0, 0, width, height(), bg );
+ p->drawText( listView()->itemMargin(), 0,
+ width - listView()->itemMargin(), height(),
+ align, text( column ) );
+ }
+}
+
+KompareListViewDiffItem* KompareListViewLineItem::diffItemParent() const
+{
+ KompareListViewLineContainerItem* p = (KompareListViewLineContainerItem*)parent();
+ return p->diffItemParent();
+}
+
+KompareListViewBlankLineItem::KompareListViewBlankLineItem( KompareListViewLineContainerItem* parent )
+ : KompareListViewLineItem( parent, 0, new DifferenceString() )
+{
+}
+
+void KompareListViewBlankLineItem::setup()
+{
+ KompareListViewLineItem::setup();
+ setHeight( BLANK_LINE_HEIGHT );
+}
+
+void KompareListViewBlankLineItem::paintText( QPainter* p, const QColor& bg, int column, int width, int )
+{
+ if ( column == COL_MAIN )
+ {
+ QBrush normalBrush( bg, SolidPattern );
+ p->fillRect( 0, 0, width, height(), normalBrush );
+ }
+}
+
+KompareListViewHunkItem::KompareListViewHunkItem( KompareListView* parent, DiffHunk* hunk, bool zeroHeight )
+ : KompareListViewItem( parent ),
+ m_zeroHeight( zeroHeight ),
+ m_hunk( hunk )
+{
+ setSelectable( false );
+}
+
+KompareListViewHunkItem::KompareListViewHunkItem( KompareListView* parent, KompareListViewItem* after, DiffHunk* hunk, bool zeroHeight )
+ : KompareListViewItem( parent, after ),
+ m_zeroHeight( zeroHeight ),
+ m_hunk( hunk )
+{
+ setSelectable( false );
+}
+
+int KompareListViewHunkItem::maxHeight()
+{
+ if( m_zeroHeight ) {
+ return 0;
+ } else if( m_hunk->function().isEmpty() ) {
+ return HUNK_LINE_HEIGHT;
+ } else {
+ return listView()->fontMetrics().lineSpacing();
+ }
+}
+
+void KompareListViewHunkItem::setup()
+{
+ KompareListViewItem::setup();
+
+ setHeight( maxHeight() );
+}
+
+void KompareListViewHunkItem::paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int align )
+{
+ p->fillRect( 0, 0, width, height(), cg.mid() );
+ if( column == COL_MAIN ) {
+ p->drawText( listView()->itemMargin(), 0, width - listView()->itemMargin(), height(),
+ align, m_hunk->function() );
+ }
+}
+
+#include "komparelistview.moc"
diff --git a/kompare/komparepart/komparelistview.h b/kompare/komparepart/komparelistview.h
new file mode 100644
index 00000000..26a6dacb
--- /dev/null
+++ b/kompare/komparepart/komparelistview.h
@@ -0,0 +1,225 @@
+/***************************************************************************
+ komparelistview.h - description
+ -------------------
+ begin : Sun Mar 4 2001
+ copyright : (C) 2001-2004 Otto Bruggeman
+ (C) 2001-2003 John Firebaugh
+ (C) 2004 Jeff Snyder
+ email : otto.bruggeman@home.nl
+ jfirebaugh@kde.org
+ jeff@caffeinated.me.uk
+****************************************************************************/
+
+/***************************************************************************
+**
+** 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.
+**
+***************************************************************************/
+
+#ifndef KOMPARELISTVIEW_H
+#define KOMPARELISTVIEW_H
+
+#include <qptrlist.h>
+#include <qptrdict.h>
+#include <qlabel.h>
+#include <qlayout.h>
+
+#include <klistview.h>
+
+namespace Diff2 {
+class DiffModel;
+class DiffHunk;
+class Difference;
+class DifferenceString;
+class KompareModelList;
+}
+class ViewSettings;
+class KompareSplitter;
+class KompareListView;
+class KompareListViewItem;
+class KompareListViewDiffItem;
+class KompareListViewLineContainerItem;
+
+class KompareListView : public KListView
+{
+ Q_OBJECT
+
+public:
+ KompareListView( bool isSource, ViewSettings* settings, QWidget* parent, const char* name = 0 );
+ virtual ~KompareListView();
+
+ KompareListViewItem* itemAtIndex( int i );
+ int firstVisibleDifference();
+ int lastVisibleDifference();
+ QRect itemRect( int i );
+ int minScrollId();
+ int maxScrollId();
+ int contentsWidth();
+
+ bool isSource() const { return m_isSource; };
+ ViewSettings* settings() const { return m_settings; };
+
+ void setSelectedDifference( const Diff2::Difference* diff, bool scroll );
+
+ const QString& spaces() const { return m_spaces; };
+ void setSpaces( int spaces );
+
+public slots:
+ void slotSetSelection( const Diff2::DiffModel* model, const Diff2::Difference* diff );
+ void slotSetSelection( const Diff2::Difference* diff );
+ void setXOffset( int x );
+ void scrollToId( int id );
+ int scrollId();
+ void slotApplyDifference( bool apply );
+ void slotApplyAllDifferences( bool apply );
+ void slotApplyDifference( const Diff2::Difference* diff, bool apply );
+
+signals:
+ void differenceClicked( const Diff2::Difference* diff );
+ void applyDifference( bool apply );
+ void resized();
+
+protected:
+ void wheelEvent( QWheelEvent* e );
+ void resizeEvent( QResizeEvent* e );
+ void contentsMousePressEvent ( QMouseEvent * e );
+ void contentsMouseDoubleClickEvent ( QMouseEvent* );
+ void contentsMouseReleaseEvent ( QMouseEvent * ) {};
+ void contentsMouseMoveEvent ( QMouseEvent * ) {};
+
+private:
+ QValueList<KompareListViewDiffItem*> m_items;
+ QPtrDict<KompareListViewDiffItem> m_itemDict;
+ bool m_isSource;
+ ViewSettings* m_settings;
+ int m_scrollId;
+ int m_maxMainWidth;
+ const Diff2::DiffModel* m_selectedModel;
+ const Diff2::Difference* m_selectedDifference;
+ QString m_spaces;
+};
+
+class KompareListViewFrame : public QFrame
+{
+ Q_OBJECT
+
+public:
+ KompareListViewFrame( bool isSource, ViewSettings* settings, KompareSplitter* parent, const char* name = 0 );
+ virtual ~KompareListViewFrame() {};
+ KompareListView* view() { return &m_view; };
+
+public slots:
+ void slotSetModel( const Diff2::DiffModel* model );
+
+private:
+ KompareListView m_view;
+ QLabel m_label;
+ QVBoxLayout m_layout;
+};
+
+class KompareListViewItem : public QListViewItem
+{
+public:
+ KompareListViewItem( KompareListView* parent );
+ KompareListViewItem( KompareListView* parent, KompareListViewItem* after );
+ KompareListViewItem( KompareListViewItem* parent );
+ KompareListViewItem( KompareListViewItem* parent, KompareListViewItem* after );
+
+ void paintFocus( QPainter* p, const QColorGroup& cg, const QRect& r );
+ int scrollId() { return m_scrollId; };
+
+ virtual int maxHeight() = 0;
+
+ KompareListView* kompareListView() const;
+
+private:
+ int m_scrollId;
+};
+
+class KompareListViewDiffItem : public KompareListViewItem
+{
+public:
+ KompareListViewDiffItem( KompareListView* parent, Diff2::Difference* difference );
+ KompareListViewDiffItem( KompareListView* parent, KompareListViewItem* after, Diff2::Difference* difference );
+
+ void setup();
+ void setSelected( bool b );
+ void applyDifference( bool apply );
+
+ Diff2::Difference* difference() { return m_difference; };
+
+ int maxHeight();
+
+private:
+ void init();
+ void setVisibility();
+
+ Diff2::Difference* m_difference;
+ KompareListViewLineContainerItem* m_sourceItem;
+ KompareListViewLineContainerItem* m_destItem;
+};
+
+class KompareListViewLineContainerItem : public KompareListViewItem
+{
+public:
+ KompareListViewLineContainerItem( KompareListViewDiffItem* parent, bool isSource );
+
+ void setup();
+ int maxHeight() { return 0; }
+ KompareListViewDiffItem* diffItemParent() const;
+
+private:
+ int lineCount() const;
+ int lineNumber() const;
+ Diff2::DifferenceString* lineAt( int i ) const;
+
+ bool m_isSource;
+};
+
+class KompareListViewLineItem : public KompareListViewItem
+{
+public:
+ KompareListViewLineItem( KompareListViewLineContainerItem* parent, int line, Diff2::DifferenceString* text );
+
+ virtual void setup();
+ int maxHeight() { return 0; }
+
+ virtual void paintCell( QPainter* p, const QColorGroup& cg, int column, int width, int align );
+ virtual void paintText( QPainter* p, const QColor& bg, int column, int width, int align );
+
+ KompareListViewDiffItem* diffItemParent() const;
+
+private:
+ Diff2::DifferenceString* m_text;
+};
+
+class KompareListViewBlankLineItem : public KompareListViewLineItem
+{
+public:
+ KompareListViewBlankLineItem( KompareListViewLineContainerItem* parent );
+
+ void setup();
+
+ void paintText( QPainter* p, const QColor& bg, int column, int width, int align );
+};
+
+class KompareListViewHunkItem : public KompareListViewItem
+{
+public:
+ KompareListViewHunkItem( KompareListView* parent, Diff2::DiffHunk* hunk, bool zeroHeight = false );
+ KompareListViewHunkItem( KompareListView* parent, KompareListViewItem* after, Diff2::DiffHunk* hunk, bool zeroHeight= false );
+
+ void setup();
+ void paintCell( QPainter* p, const QColorGroup& cg, int column, int width, int align );
+
+ int maxHeight();
+
+private:
+ bool m_zeroHeight;
+ Diff2::DiffHunk* m_hunk;
+};
+
+#endif
diff --git a/kompare/komparepart/komparepart.desktop b/kompare/komparepart/komparepart.desktop
new file mode 100644
index 00000000..3d075d62
--- /dev/null
+++ b/kompare/komparepart/komparepart.desktop
@@ -0,0 +1,24 @@
+[Desktop Entry]
+GenericComment=A part to graphically show the difference between 2 files
+Name=KomparePart
+Name[af]=K-vergelyk-deel
+Name[de]=Einbettungsfähige Komponente von Kompare
+Name[eo]=Komparo-parto
+Name[he]=רכיב Kompare
+Name[hi]=काम्पेयर-पार्ट
+Name[lv]=SalīdzinātDaļu
+Name[pl]=Moduł Kompare
+Name[pt_BR]=Parte do Kompare
+Name[ro]=Componentă Kompare
+Name[ru]=Компонент утилиты сравнения файлов
+Name[sv]=Kompare-del
+Name[ta]=கோம்பெர் உறுப்பு
+Name[tg]=Қисмати утилитҳои баробаркунии файлҳо
+Name[th]=ส่วนเปรียบเทียบ
+Name[zu]=Ingxenye yeKompare
+MimeType=text/x-diff
+ServiceTypes=Kompare/ViewPart,KParts/ReadWritePart,KParts/ReadOnlyPart
+X-KDE-Library=libkomparepart
+Type=Service
+Icon=kompare
+InitialPreference=10
diff --git a/kompare/komparepart/komparepartui.rc b/kompare/komparepart/komparepartui.rc
new file mode 100644
index 00000000..c7140325
--- /dev/null
+++ b/kompare/komparepart/komparepartui.rc
@@ -0,0 +1,44 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="kompare_part" version="5">
+<MenuBar>
+ <Menu name="file"><text>&amp;File</text>
+ <Action name="file_save"/>
+ <Action name="file_save_all"/>
+ <Action name="file_save_as"/>
+ <Action name="file_save_diff"/>
+ <Separator/>
+ <Action name="file_swap"/>
+ <Action name="file_diffstats"/>
+ </Menu>
+ <Menu name="difference"><text>&amp;Difference</text>
+ <Action name="difference_unapplyall"/>
+ <Action name="difference_unapply"/>
+ <Action name="difference_apply"/>
+ <Action name="difference_applyall"/>
+ <Separator/>
+ <Action name="difference_previousfile"/>
+ <Action name="difference_nextfile"/>
+ <Separator/>
+ <Action name="difference_previous"/>
+ <Action name="difference_next"/>
+ </Menu>
+ <Menu name="settings"><text>&amp;Settings</text>
+ <Action name="options_configure"/>
+ </Menu>
+</MenuBar>
+<ToolBar name="mainToolBar">
+ <Action name="file_save"/>
+ <Action name="file_save_all"/>
+ <Separator/>
+ <Action name="difference_previousfile"/>
+ <Action name="difference_nextfile"/>
+ <Separator/>
+ <Action name="difference_previous"/>
+ <Action name="difference_next"/>
+ <Separator/>
+ <Action name="difference_unapplyall"/>
+ <Action name="difference_unapply"/>
+ <Action name="difference_apply"/>
+ <Action name="difference_applyall"/>
+</ToolBar>
+</kpartgui>
diff --git a/kompare/komparepart/kompareprefdlg.cpp b/kompare/komparepart/kompareprefdlg.cpp
new file mode 100644
index 00000000..2d731af3
--- /dev/null
+++ b/kompare/komparepart/kompareprefdlg.cpp
@@ -0,0 +1,106 @@
+/***************************************************************************
+ kompareprefdlg.cpp - description
+ -------------------
+ begin : Sun Mar 4 2001
+ copyright : (C) 2001-2003 by Otto Bruggeman
+ and John Firebaugh
+ email : otto.bruggeman@home.nl
+ jfirebaugh@kde.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 <qvbox.h>
+
+#include <kdebug.h>
+#include <kiconloader.h>
+#include <klocale.h>
+
+#include "diffpage.h"
+#include "viewpage.h"
+
+#include "kompareprefdlg.h"
+
+// implementation
+
+KomparePrefDlg::KomparePrefDlg( ViewSettings* viewSets, DiffSettings* diffSets ) : KDialogBase( IconList, i18n( "Preferences" ), Help|Default|Ok|Apply|Cancel, Ok, 0, 0, true, true )
+{
+ // ok i need some stuff in that pref dlg...
+ setIconListAllVisible(true);
+
+ QVBox* frame;
+ frame = addVBoxPage( i18n( "View" ), i18n( "View Settings" ), UserIcon( "diff_view" ) );
+ m_viewPage = new ViewPage( frame );
+ m_viewPage->setSettings( viewSets );
+
+ frame = addVBoxPage( i18n( "Diff" ), i18n( "Diff Settings" ), UserIcon( "diff_specific" ) );
+ m_diffPage = new DiffPage( frame );
+ m_diffPage->setSettings( diffSets );
+
+// frame = addVBoxPage( i18n( "" ), i18n( "" ), UserIcon( "" ) );
+
+ adjustSize();
+}
+
+KomparePrefDlg::~KomparePrefDlg()
+{
+
+}
+
+/** No descriptions */
+void KomparePrefDlg::slotDefault()
+{
+ kdDebug(8103) << "SlotDefault called -> Settings should be restored to defaults..." << endl;
+ // restore all defaults in the options...
+ m_viewPage->setDefaults();
+ m_diffPage->setDefaults();
+}
+
+/** No descriptions */
+void KomparePrefDlg::slotHelp()
+{
+ // show some help...
+ // figure out the current active page
+ // and give help for that page
+}
+
+/** No descriptions */
+void KomparePrefDlg::slotApply()
+{
+ kdDebug(8103) << "SlotApply called -> Settings should be applied..." << endl;
+ // well apply the settings that are currently selected
+ m_viewPage->apply();
+ m_diffPage->apply();
+
+ emit applyClicked();
+}
+
+/** No descriptions */
+void KomparePrefDlg::slotOk()
+{
+ kdDebug(8103) << "SlotOk called -> Settings should be applied..." << endl;
+ // Apply the settings that are currently selected
+ m_viewPage->apply();
+ m_diffPage->apply();
+
+ KDialogBase::slotOk();
+}
+
+/** No descriptions */
+void KomparePrefDlg::slotCancel()
+{
+ // discard the current settings and use the present ones
+ m_viewPage->restore();
+ m_diffPage->restore();
+
+ KDialogBase::slotCancel();
+}
+
+#include "kompareprefdlg.moc"
diff --git a/kompare/komparepart/kompareprefdlg.h b/kompare/komparepart/kompareprefdlg.h
new file mode 100644
index 00000000..e81da90c
--- /dev/null
+++ b/kompare/komparepart/kompareprefdlg.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ kompareprefdlg.h - description
+ -------------------
+ begin : Sun Mar 4 2001
+ copyright : (C) 2001-2003 by Otto Bruggeman
+ and John Firebaugh
+ email : otto.bruggeman@home.nl
+ jfirebaugh@kde.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.
+**
+***************************************************************************/
+
+#ifndef KOMPAREPREFDLG_H
+#define KOMPAREPREFDLG_H
+
+#include <kdialogbase.h>
+
+class DiffPage;
+class DiffSettings;
+class ViewPage;
+class ViewSettings;
+
+class KomparePrefDlg : public KDialogBase
+{
+Q_OBJECT
+public:
+ KomparePrefDlg( ViewSettings*, DiffSettings* );
+ ~KomparePrefDlg();
+
+protected slots:
+ /** No descriptions */
+ virtual void slotOk();
+ /** No descriptions */
+ virtual void slotApply();
+ /** No descriptions */
+ virtual void slotHelp();
+ /** No descriptions */
+ virtual void slotDefault();
+ /** No descriptions */
+ virtual void slotCancel();
+
+private:
+ ViewPage* m_viewPage;
+ DiffPage* m_diffPage;
+};
+
+#endif
diff --git a/kompare/komparepart/komparesaveoptionsbase.ui b/kompare/komparepart/komparesaveoptionsbase.ui
new file mode 100644
index 00000000..4c49b018
--- /dev/null
+++ b/kompare/komparepart/komparesaveoptionsbase.ui
@@ -0,0 +1,336 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>KompareSaveOptionsBase</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>KompareSaveOptionsBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>558</width>
+ <height>399</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QGroupBox" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>GroupBox2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="title">
+ <string>Run Diff In</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="KURLRequester">
+ <property name="name">
+ <cstring>m_directoryRequester</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QGroupBox" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>m_CommandLineGB</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="title">
+ <string>Command Line</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignLeft</set>
+ </property>
+ <property name="hAlign" stdset="0">
+ </property>
+ <property name="vAlign" stdset="0">
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>m_CommandLineLabel</cstring>
+ </property>
+ <property name="text">
+ <string>cd dir &amp;&amp; diff -udHprNa -- source destination</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QButtonGroup" row="0" column="1">
+ <property name="name">
+ <cstring>m_OptionsGB</cstring>
+ </property>
+ <property name="title">
+ <string>Options</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>m_SmallerChangesCB</cstring>
+ </property>
+ <property name="text">
+ <string>Look for smaller changes</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>m_LargeFilesCB</cstring>
+ </property>
+ <property name="text">
+ <string>Optimize for large files</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>m_IgnoreCaseCB</cstring>
+ </property>
+ <property name="text">
+ <string>Ignore changes in case</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>m_ExpandTabsCB</cstring>
+ </property>
+ <property name="text">
+ <string>Expand tabs to spaces</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>m_IgnoreEmptyLinesCB</cstring>
+ </property>
+ <property name="text">
+ <string>Ignore added or removed empty lines</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>m_IgnoreWhiteSpaceCB</cstring>
+ </property>
+ <property name="text">
+ <string>Ignore changes in whitespace</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>m_FunctionNamesCB</cstring>
+ </property>
+ <property name="text">
+ <string>Show function names</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>m_RecursiveCB</cstring>
+ </property>
+ <property name="text">
+ <string>Compare folders recursively</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>m_NewFilesCB</cstring>
+ </property>
+ <property name="text">
+ <string>Treat new files as empty</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="tristate">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QButtonGroup" row="0" column="0">
+ <property name="name">
+ <cstring>m_FormatBG</cstring>
+ </property>
+ <property name="title">
+ <string>Format</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>m_ContextRB</cstring>
+ </property>
+ <property name="text">
+ <string>Context</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>m_EdRB</cstring>
+ </property>
+ <property name="text">
+ <string>Ed</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>m_NormalRB</cstring>
+ </property>
+ <property name="text">
+ <string>Normal</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>m_RCSRB</cstring>
+ </property>
+ <property name="text">
+ <string>RCS</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>m_UnifiedRB</cstring>
+ </property>
+ <property name="text">
+ <string>Unified</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>m_SideBySideRB</cstring>
+ </property>
+ <property name="text">
+ <string>Side-by-side</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>m_ContextLinesLayout</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>m_ContextLinesLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Number of context lines:</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox">
+ <property name="name">
+ <cstring>m_ContextLinesSB</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="maxValue">
+ <number>65535</number>
+ </property>
+ <property name="value">
+ <number>3</number>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ </grid>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kompare/komparepart/komparesaveoptionswidget.cpp b/kompare/komparepart/komparesaveoptionswidget.cpp
new file mode 100644
index 00000000..866ecc0d
--- /dev/null
+++ b/kompare/komparepart/komparesaveoptionswidget.cpp
@@ -0,0 +1,215 @@
+/***************************************************************************
+ komparesaveoptionswidget.cpp - description
+ -------------------
+ begin : Sun Mar 4 2001
+ copyright : (C) 2001-2003 by Otto Bruggeman
+ and John Firebaugh
+ email : otto.bruggeman@home.nl
+ jfirebaugh@kde.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 <qbuttongroup.h>
+#include <qcheckbox.h>
+#include <qlabel.h>
+#include <qradiobutton.h>
+#include <qspinbox.h>
+
+#include <kdebug.h>
+#include <kfiledialog.h>
+#include <kurlrequester.h>
+
+#include "diffsettings.h"
+#include "komparesaveoptionswidget.h"
+
+KompareSaveOptionsWidget::KompareSaveOptionsWidget( QString source, QString destination,
+ DiffSettings * settings, QWidget * parent )
+ : KompareSaveOptionsBase( parent, "save options" )
+ , m_source( source )
+ , m_destination( destination )
+{
+ m_settings = settings;
+
+ m_directoryRequester->setMode( static_cast<KFile::Mode>(
+ KFile::ExistingOnly | KFile::Directory | KFile::LocalOnly ) );
+
+ KURL sourceURL;
+ KURL destinationURL;
+ sourceURL.setPath( source );
+ destinationURL.setPath( destination );
+
+ // Find a common root.
+ KURL root( sourceURL );
+ while( root.isValid() && !root.isParentOf( destinationURL ) ) {
+ root = root.upURL();
+ }
+
+ // If we found a common root, change to that directory and
+ // strip the common part from source and destination.
+ if( root.isValid() ) {
+ m_directoryRequester->setURL( root.url() );
+ }
+
+ connect( m_SmallerChangesCB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
+ connect( m_LargeFilesCB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
+ connect( m_IgnoreCaseCB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
+ connect( m_ExpandTabsCB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
+ connect( m_IgnoreEmptyLinesCB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
+ connect( m_IgnoreWhiteSpaceCB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
+ connect( m_FunctionNamesCB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
+ connect( m_RecursiveCB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
+ connect( m_NewFilesCB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
+ connect( m_ContextRB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
+ connect( m_EdRB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
+ connect( m_NormalRB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
+ connect( m_RCSRB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
+ connect( m_UnifiedRB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
+ connect( m_SideBySideRB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
+ connect( m_ContextLinesSB, SIGNAL(valueChanged(int)), SLOT(updateCommandLine()) );
+ connect( m_directoryRequester, SIGNAL(textChanged(const QString&)), SLOT(updateCommandLine()) );
+
+ loadOptions();
+}
+
+KompareSaveOptionsWidget::~KompareSaveOptionsWidget()
+{
+
+}
+
+QString KompareSaveOptionsWidget::directory() const
+{
+ return KURL( m_directoryRequester->url() ).path();
+}
+
+void KompareSaveOptionsWidget::updateCommandLine()
+{
+ QString cmdLine = "diff";
+
+ QString options = "";
+
+ switch( static_cast<Kompare::Format>( m_FormatBG->id( m_FormatBG->selected() ) ) ) {
+ case Kompare::Unified :
+ cmdLine += " -U " + QString::number( m_ContextLinesSB->value() );
+ break;
+ case Kompare::Context :
+ cmdLine += " -C " + QString::number( m_ContextLinesSB->value() );
+ break;
+ case Kompare::RCS :
+ options += "n";
+ break;
+ case Kompare::Ed :
+ options += "e";
+ break;
+ case Kompare::SideBySide:
+ options += "y";
+ break;
+ case Kompare::Normal :
+ case Kompare::UnknownFormat :
+ default:
+ break;
+ }
+
+ if ( m_SmallerChangesCB->isChecked() ) {
+ options += "d";
+ }
+
+ if ( m_LargeFilesCB->isChecked() ) {
+ options += "H";
+ }
+
+ if ( m_IgnoreCaseCB->isChecked() ){
+ options += "i";
+ }
+
+ if ( m_ExpandTabsCB->isChecked() ) {
+ options += "t";
+ }
+
+ if ( m_IgnoreEmptyLinesCB->isChecked() ) {
+ options += "B";
+ }
+
+ if ( m_IgnoreWhiteSpaceCB->isChecked() ) {
+ options += "b";
+ }
+
+ if ( m_FunctionNamesCB->isChecked() ) {
+ options += "p";
+ }
+
+// if ( ) {
+// cmdLine += " -w";
+// }
+
+ if ( m_RecursiveCB->isChecked() ) {
+ options += "r";
+ }
+
+ if( m_NewFilesCB->isChecked() ) {
+ options += "N";
+ }
+
+// if( m_AllTextCB->isChecked() ) {
+// options += "a";
+// }
+
+ if( options.length() > 0 ) {
+ cmdLine += " -" + options;
+ }
+
+ cmdLine += " -- ";
+ cmdLine += constructRelativePath( m_directoryRequester->url(), m_source );
+ cmdLine += " ";
+ cmdLine += constructRelativePath( m_directoryRequester->url(), m_destination );
+
+ m_CommandLineLabel->setText( cmdLine );
+}
+
+void KompareSaveOptionsWidget::loadOptions()
+{
+ m_SmallerChangesCB->setChecked ( m_settings->m_createSmallerDiff );
+ m_LargeFilesCB->setChecked ( m_settings->m_largeFiles );
+ m_IgnoreCaseCB->setChecked ( m_settings->m_ignoreChangesInCase );
+ m_ExpandTabsCB->setChecked ( m_settings->m_convertTabsToSpaces );
+ m_IgnoreEmptyLinesCB->setChecked( m_settings->m_ignoreEmptyLines );
+ m_IgnoreWhiteSpaceCB->setChecked( m_settings->m_ignoreWhiteSpace );
+ m_FunctionNamesCB->setChecked ( m_settings->m_showCFunctionChange );
+ m_RecursiveCB->setChecked ( m_settings->m_recursive );
+ m_NewFilesCB->setChecked ( m_settings->m_newFiles );
+// m_AllTextCB->setChecked ( m_settings->m_allText );
+
+ m_ContextLinesSB->setValue ( m_settings->m_linesOfContext );
+
+ m_FormatBG->setButton ( m_settings->m_format );
+
+ updateCommandLine();
+}
+
+void KompareSaveOptionsWidget::saveOptions()
+{
+ m_settings->m_createSmallerDiff = m_SmallerChangesCB->isChecked();
+ m_settings->m_largeFiles = m_LargeFilesCB->isChecked();
+ m_settings->m_ignoreChangesInCase = m_IgnoreCaseCB->isChecked();
+ m_settings->m_convertTabsToSpaces = m_ExpandTabsCB->isChecked();
+ m_settings->m_ignoreEmptyLines = m_IgnoreEmptyLinesCB->isChecked();
+ m_settings->m_ignoreWhiteSpace = m_IgnoreWhiteSpaceCB->isChecked();
+ m_settings->m_showCFunctionChange = m_FunctionNamesCB->isChecked();
+ m_settings->m_recursive = m_RecursiveCB->isChecked();
+ m_settings->m_newFiles = m_NewFilesCB->isChecked();
+// m_settings->m_allText = m_AllTextCB->isChecked();
+
+ m_settings->m_linesOfContext = m_ContextLinesSB->value();
+
+ m_settings->m_format = static_cast<Kompare::Format>( m_FormatBG->id( m_FormatBG->selected() ) );
+
+}
+
+#include "komparesaveoptionswidget.moc"
diff --git a/kompare/komparepart/komparesaveoptionswidget.h b/kompare/komparepart/komparesaveoptionswidget.h
new file mode 100644
index 00000000..6361ca77
--- /dev/null
+++ b/kompare/komparepart/komparesaveoptionswidget.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ komparesaveoptionswidget.h - description
+ -------------------
+ begin : Sun Mar 4 2001
+ copyright : (C) 2001-2003 by Otto Bruggeman
+ and John Firebaugh
+ email : otto.bruggeman@home.nl
+ jfirebaugh@kde.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.
+**
+***************************************************************************/
+
+#ifndef KOMPARESAVEOPTIONSWIDGET_H
+#define KOMPARESAVEOPTIONSWIDGET_H
+
+#include <kurl.h>
+
+#include "komparesaveoptionsbase.h"
+#include "kompare.h"
+
+class DiffSettings;
+
+class KompareSaveOptionsWidget : public KompareSaveOptionsBase, public KompareFunctions
+{
+Q_OBJECT
+public:
+ KompareSaveOptionsWidget( QString source, QString destination, DiffSettings* settings, QWidget* parent );
+ ~KompareSaveOptionsWidget();
+
+ void saveOptions();
+ QString directory() const;
+
+protected slots:
+ void updateCommandLine();
+
+private:
+ void loadOptions();
+
+ DiffSettings* m_settings;
+ QString m_source;
+ QString m_destination;
+};
+
+#endif
diff --git a/kompare/komparepart/komparesplitter.cpp b/kompare/komparepart/komparesplitter.cpp
new file mode 100644
index 00000000..fcf014cb
--- /dev/null
+++ b/kompare/komparepart/komparesplitter.cpp
@@ -0,0 +1,712 @@
+/***************************************************************************
+ komparesplitter.cpp - description
+ -------------------
+ begin : Wed Jan 14 2004
+ copyright : (C) 2004 by Jeff Snyder
+ email : jeff@caffeinated.me.uk
+****************************************************************************/
+
+/***************************************************************************
+**
+** 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 "komparesplitter.h"
+
+#include <qstyle.h>
+#include <qstring.h>
+#include <qtimer.h>
+
+#include <kdebug.h>
+#include <kapplication.h>
+#include <kglobalsettings.h>
+
+#include "diffmodel.h"
+#include "difference.h"
+#include "viewsettings.h"
+#include "kompare_part.h"
+#include "komparelistview.h"
+#include "kompareconnectwidget.h"
+
+using namespace Diff2;
+
+KompareSplitter::KompareSplitter( ViewSettings *settings, QWidget * parent,
+ const char *name) :
+ QSplitter( Horizontal, parent, name ),
+ m_settings( settings )
+{
+ QFrame *scrollFrame = new QFrame( parent, "scrollFrame" );
+ reparent( scrollFrame, *(new QPoint()), false );
+
+ // Set up the scrollFrame
+ scrollFrame->setFrameStyle( QFrame::NoFrame | QFrame::Plain );
+ scrollFrame->setLineWidth(scrollFrame->style().pixelMetric(QStyle::PM_DefaultFrameWidth));
+ QGridLayout *pairlayout = new QGridLayout(scrollFrame, 2, 2, 0);
+ m_vScroll = new QScrollBar( QScrollBar::Vertical, scrollFrame );
+ pairlayout->addWidget( m_vScroll, 0, 1 );
+ m_hScroll = new QScrollBar( QScrollBar::Horizontal, scrollFrame );
+ pairlayout->addWidget( m_hScroll, 1, 0 );
+
+ new KompareListViewFrame(true, m_settings, this, "source");
+ new KompareListViewFrame(false, m_settings, this, "destination");
+ pairlayout->addWidget( this, 0, 0 );
+
+ // set up our looks
+ setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
+ setLineWidth( style().pixelMetric( QStyle::PM_DefaultFrameWidth ) );
+
+ setHandleWidth(50);
+ setChildrenCollapsible( false );
+ setFrameStyle( QFrame::NoFrame );
+ setSizePolicy( QSizePolicy (QSizePolicy::Ignored, QSizePolicy::Ignored ));
+ setOpaqueResize( true );
+ setFocusPolicy( QWidget::WheelFocus );
+
+ connect( this, SIGNAL(configChanged()), SLOT(slotConfigChanged()) );
+ connect( this, SIGNAL(configChanged()), SLOT(slotDelayedRepaintHandles()) );
+ connect( this, SIGNAL(configChanged()), SLOT(slotDelayedUpdateScrollBars()) );
+
+ // scrolling
+ connect( m_vScroll, SIGNAL(valueChanged(int)), SLOT(scrollToId(int)) );
+ connect( m_vScroll, SIGNAL(sliderMoved(int)), SLOT(scrollToId(int)) );
+ connect( m_hScroll, SIGNAL(valueChanged(int)), SIGNAL(setXOffset(int)) );
+ connect( m_hScroll, SIGNAL(sliderMoved(int)), SIGNAL(setXOffset(int)) );
+
+ m_scrollTimer=new QTimer();
+ restartTimer = false;
+ connect (m_scrollTimer, SIGNAL(timeout()), SLOT(timerTimeout()) );
+
+ // we need to receive childEvents now so that d->list is ready for when
+ // slotSetSelection(...) arrives
+ kapp->sendPostedEvents(this, QEvent::ChildInserted);
+
+ // init stuff
+ slotUpdateScrollBars();
+}
+
+KompareSplitter::~KompareSplitter(){}
+
+/*
+ Inserts the widget \a w at the end (or at the beginning if \a
+ prepend is TRUE) of the splitter's list of widgets.
+
+ It is the responsibility of the caller to make sure that \a w is
+ not already in the splitter and to call recalcId() if needed. (If
+ \a prepend is TRUE, then recalcId() is very probably needed.)
+*/
+
+QSplitterLayoutStruct *KompareSplitter::addWidget( KompareListViewFrame *w, bool prepend )
+{
+ /* This function is *not* a good place to make connections to and from
+ * the KompareListView. Make them in the KompareListViewFrame constructor
+ * instad - that way the connections get made upon creation, not upon the
+ * next processing of the event queue. */
+
+ QSplitterLayoutStruct *s;
+ KompareConnectWidgetFrame *newHandle = 0;
+ if ( d->list.count() > 0 ) {
+ s = new QSplitterLayoutStruct;
+ s->resizeMode = KeepSize;
+ QString tmp = "qt_splithandle_";
+ tmp += w->name();
+ KompareListView *lw =
+ ((KompareListViewFrame*)(prepend?w:d->list.last()->wid))->view();
+ KompareListView *rw =
+ ((KompareListViewFrame*)(prepend?d->list.first()->wid:w))->view();
+ newHandle = new KompareConnectWidgetFrame(lw, rw, m_settings, this, tmp.latin1());
+ s->wid = newHandle;
+ newHandle->setId( d->list.count() );
+ s->isHandle = TRUE;
+ s->sizer = pick( newHandle->sizeHint() );
+ if ( prepend )
+ d->list.prepend( s );
+ else
+ d->list.append( s );
+ }
+ s = new QSplitterLayoutStruct;
+ s->resizeMode = DefaultResizeMode;
+ s->wid = w;
+ s->isHandle = FALSE;
+ if ( prepend ) d->list.prepend( s );
+ else d->list.append( s );
+ if ( newHandle && isVisible() )
+ newHandle->show(); // will trigger sending of post events
+ return s;
+}
+
+
+/*!
+ Tells the splitter that the child widget described by \a c has
+ been inserted or removed.
+*/
+
+void KompareSplitter::childEvent( QChildEvent *c )
+{
+ if ( c->type() == QEvent::ChildInserted ) {
+ if ( !c->child()->isWidgetType() )
+ return;
+
+ if ( ((QWidget*)c->child())->testWFlags( WType_TopLevel ) )
+ return;
+
+ QSplitterLayoutStruct *s = d->list.first();
+ while ( s ) {
+ if ( s->wid == c->child() )
+ return;
+ s = d->list.next();
+ }
+ addWidget( (KompareListViewFrame*)c->child() );
+ recalc( isVisible() );
+ } else if ( c->type() == QEvent::ChildRemoved ) {
+ QSplitterLayoutStruct *prev = 0;
+ if ( d->list.count() > 1 )
+ prev = d->list.at( 1 ); // yes, this is correct
+ QSplitterLayoutStruct *curr = d->list.first();
+ while ( curr ) {
+ if ( curr->wid == c->child() ) {
+ d->list.removeRef( curr );
+ if ( prev && prev->isHandle ) {
+ QWidget *w = prev->wid;
+ d->list.removeRef( prev );
+ delete w; // will call childEvent()
+ }
+ recalcId();
+ doResize();
+ return;
+ }
+ prev = curr;
+ curr = d->list.next();
+ }
+ }
+}
+
+// This is from a private qt header (kernel/qlayoutengine_p.h). sorry.
+QSize qSmartMinSize( QWidget *w );
+
+static QPoint toggle( QWidget *w, QPoint pos )
+{
+ QSize minS = qSmartMinSize( w );
+ return -pos - QPoint( minS.width(), minS.height() );
+}
+
+static bool isCollapsed( QWidget *w )
+{
+ return w->x() < 0 || w->y() < 0;
+}
+
+static QPoint topLeft( QWidget *w )
+{
+ if ( isCollapsed(w) ) {
+ return toggle( w, w->pos() );
+ } else {
+ return w->pos();
+ }
+}
+
+static QPoint bottomRight( QWidget *w )
+{
+ if ( isCollapsed(w) ) {
+ return toggle( w, w->pos() ) - QPoint( 1, 1 );
+ } else {
+ return w->geometry().bottomRight();
+ }
+}
+
+void KompareSplitter::moveSplitter( QCOORD p, int id )
+{
+ QSplitterLayoutStruct *s = d->list.at( id );
+ int farMin;
+ int min;
+ int max;
+ int farMax;
+ p = adjustPos( p, id, &farMin, &min, &max, &farMax );
+ int oldP = pick( s->wid->pos() );
+ int* poss = new int[d->list.count()];
+ int* ws = new int[d->list.count()];
+ QWidget *w = 0;
+ bool upLeft;
+ if ( QApplication::reverseLayout() && orient == Horizontal ) {
+ int q = p + s->wid->width();
+ doMove( FALSE, q, id - 1, -1, (p > max), poss, ws );
+ doMove( TRUE, q, id, -1, (p < min), poss, ws );
+ upLeft = (q > oldP);
+ } else {
+ doMove( FALSE, p, id, +1, (p > max), poss, ws );
+ doMove( TRUE, p, id - 1, +1, (p < min), poss, ws );
+ upLeft = (p < oldP);
+ }
+ if ( upLeft ) {
+ int count = d->list.count();
+ for ( int id = 0; id < count; ++id ) {
+ w = d->list.at( id )->wid;
+ if( !w->isHidden() )
+ setGeo( w, poss[id], ws[id], TRUE );
+ }
+ } else {
+ for ( int id = d->list.count() - 1; id >= 0; --id ) {
+ w = d->list.at( id )->wid;
+ if( !w->isHidden() )
+ setGeo( w, poss[id], ws[id], TRUE );
+ }
+ }
+ storeSizes();
+}
+
+void KompareSplitter::doMove( bool backwards, int pos, int id, int delta,
+ bool mayCollapse, int* positions, int* widths )
+{
+ QSplitterLayoutStruct *s;
+ QWidget *w;
+ for ( ; id >= 0 && id < (int)d->list.count();
+ id = backwards ? id - delta : id + delta ) {
+ s = d->list.at( id );
+ w = s->wid;
+ if ( w->isHidden() ) {
+ mayCollapse = TRUE;
+ } else {
+ if ( s->isHandle ) {
+ int dd = s->getSizer( orient );
+ int nextPos = backwards ? pos - dd : pos + dd;
+ positions[id] = pos;
+ widths[id] = dd;
+ pos = nextPos;
+ } else {
+ int dd = backwards ? pos - pick( topLeft(w) )
+ : pick( bottomRight(w) ) - pos + 1;
+ if ( dd > 0 || (!isCollapsed(w) && !mayCollapse) ) {
+ dd = QMAX( pick(qSmartMinSize(w)),
+ QMIN(dd, pick(w->maximumSize())) );
+ } else {
+ dd = 0;
+ }
+ positions[id] = backwards ? pos - dd : pos;
+ widths[id] = dd;
+ pos = backwards ? pos - dd : pos + dd;
+ mayCollapse = TRUE;
+ }
+ }
+ }
+}
+
+void KompareSplitter::slotSetSelection( const DiffModel* model, const Difference* diff )
+{
+ QSplitterLayoutStruct *curr;
+ for ( curr = d->list.first(); curr; curr = d->list.next() )
+ {
+ if ( curr->isHandle )
+ ((KompareConnectWidgetFrame*)
+ curr->wid)->wid()->slotSetSelection( model, diff );
+ else
+ {
+ ((KompareListViewFrame*)
+ curr->wid)->view()->slotSetSelection( model, diff );
+ ((KompareListViewFrame*)
+ curr->wid)->slotSetModel( model );
+ }
+ }
+ slotDelayedRepaintHandles();
+ slotDelayedUpdateScrollBars();
+}
+
+void KompareSplitter::slotSetSelection( const Difference* diff )
+{
+ QSplitterLayoutStruct *curr;
+ for ( curr = d->list.first(); curr; curr = d->list.next() )
+ if ( curr->isHandle )
+ ((KompareConnectWidgetFrame*)
+ curr->wid)->wid()->slotSetSelection( diff );
+ else
+ ((KompareListViewFrame*)
+ curr->wid)->view()->slotSetSelection( diff );
+ slotDelayedRepaintHandles();
+ slotDelayedUpdateScrollBars();
+}
+
+void KompareSplitter::slotApplyDifference( bool apply )
+{
+ QSplitterLayoutStruct *curr;
+ for ( curr = d->list.first(); curr; curr = d->list.next() )
+ if ( !curr->isHandle )
+ ((KompareListViewFrame*)
+ curr->wid)->view()->slotApplyDifference( apply );
+ slotDelayedRepaintHandles();
+}
+
+void KompareSplitter::slotApplyAllDifferences( bool apply )
+{
+ QSplitterLayoutStruct *curr;
+ for ( curr = d->list.first(); curr; curr = d->list.next() )
+ if ( !curr->isHandle )
+ ((KompareListViewFrame*)
+ curr->wid)->view()->slotApplyAllDifferences( apply );
+ slotDelayedRepaintHandles();
+ scrollToId( scrollTo ); // FIXME!
+}
+
+void KompareSplitter::slotApplyDifference( const Difference* diff, bool apply )
+{
+ QSplitterLayoutStruct *curr;
+ for ( curr = d->list.first(); curr; curr = d->list.next() )
+ if ( !curr->isHandle )
+ ((KompareListViewFrame*)
+ curr->wid)->view()->slotApplyDifference( diff, apply );
+ slotDelayedRepaintHandles();
+}
+
+void KompareSplitter::slotDifferenceClicked( const Difference* diff )
+{
+ QSplitterLayoutStruct *curr;
+ for ( curr = d->list.first(); curr; curr = d->list.next() )
+ if ( !curr->isHandle )
+ ((KompareListViewFrame*)
+ curr->wid)->view()->setSelectedDifference( diff, false );
+ emit selectionChanged( diff );
+}
+
+void KompareSplitter::slotConfigChanged()
+{
+ QSplitterLayoutStruct *curr;
+ for ( curr = d->list.first(); curr; curr = d->list.next() ) {
+ if ( !curr->isHandle )
+ {
+ ((KompareListViewFrame*)
+ curr->wid)->view()->setSpaces( m_settings->m_tabToNumberOfSpaces );
+ ((KompareListViewFrame*)
+ curr->wid)->view()->setFont( m_settings->m_font );
+ ((KompareListViewFrame*)
+ curr->wid)->view()->update();
+ }
+ }
+}
+
+void KompareSplitter::slotDelayedRepaintHandles()
+{
+ QSplitterLayoutStruct *curr;
+ for ( curr = d->list.first(); curr; curr = d->list.next() )
+ if ( curr->isHandle )
+ ((KompareConnectWidgetFrame*)curr->wid)->wid()->slotDelayedRepaint();
+}
+
+void KompareSplitter::repaintHandles()
+{
+ QSplitterLayoutStruct *curr;
+ for ( curr = d->list.first(); curr; curr = d->list.next() )
+ if ( curr->isHandle )
+ ((KompareConnectWidgetFrame*)curr->wid)->wid()->repaint();
+}
+
+// Scrolling stuff
+/*
+ * limit updating to once every 50 msec with a qtimer
+ * FIXME: i'm a nasty hack
+ */
+
+void KompareSplitter::wheelEvent( QWheelEvent* e )
+{
+ // scroll lines...
+ if ( e->orientation() == Qt::Vertical )
+ {
+ if ( e->state() & Qt::ControlButton )
+ if ( e->delta() < 0 ) // scroll down one page
+ m_vScroll->addPage();
+ else // scroll up one page
+ m_vScroll->subtractPage();
+ else
+ if ( e->delta() < 0 ) // scroll down
+ m_vScroll->addLine();
+ else // scroll up
+ m_vScroll->subtractLine();
+ }
+ else
+ {
+ if ( e->state() & Qt::ControlButton )
+ if ( e->delta() < 0 ) // scroll right one page
+ m_hScroll->addPage();
+ else // scroll left one page
+ m_hScroll->subtractPage();
+ else
+ if ( e->delta() < 0 ) // scroll to the right
+ m_hScroll->addLine();
+ else // scroll to the left
+ m_hScroll->subtractLine();
+ }
+ e->accept();
+ repaintHandles();
+}
+
+void KompareSplitter::keyPressEvent( QKeyEvent* e )
+{
+ //keyboard scrolling
+ switch ( e->key() ) {
+ case Key_Right:
+ case Key_L:
+ m_hScroll->addLine();
+ break;
+ case Key_Left:
+ case Key_H:
+ m_hScroll->subtractLine();
+ break;
+ case Key_Up:
+ case Key_K:
+ m_vScroll->subtractLine();
+ break;
+ case Key_Down:
+ case Key_J:
+ m_vScroll->addLine();
+ break;
+ case Key_PageDown:
+ m_vScroll->addPage();
+ break;
+ case Key_PageUp:
+ m_vScroll->subtractPage();
+ break;
+ }
+ e->accept();
+ repaintHandles();
+}
+
+void KompareSplitter::timerTimeout()
+{
+ if ( restartTimer )
+ restartTimer = false;
+ else
+ m_scrollTimer->stop();
+
+ slotDelayedRepaintHandles();
+
+ emit scrollViewsToId( scrollTo );
+}
+
+void KompareSplitter::scrollToId( int id )
+{
+ scrollTo = id;
+
+ if( restartTimer )
+ return;
+
+ if( m_scrollTimer->isActive() )
+ {
+ restartTimer = true;
+ }
+ else
+ {
+ emit scrollViewsToId( id );
+ slotDelayedRepaintHandles();
+ m_scrollTimer->start(30, false);
+ }
+}
+
+void KompareSplitter::slotDelayedUpdateScrollBars()
+{
+ QTimer::singleShot( 0, this, SLOT( slotUpdateScrollBars() ) );
+}
+
+void KompareSplitter::slotUpdateScrollBars()
+{
+ int m_scrollDistance = m_settings->m_scrollNoOfLines * lineSpacing();
+ int m_pageSize = pageSize();
+
+ if( needVScrollBar() )
+ {
+ m_vScroll->show();
+
+ m_vScroll->blockSignals( true );
+ m_vScroll->setRange( minVScrollId(),
+ maxVScrollId() );
+ m_vScroll->setValue( scrollId() );
+ m_vScroll->setSteps( m_scrollDistance, m_pageSize );
+ m_vScroll->blockSignals( false );
+ }
+ else
+ {
+ m_vScroll->hide();
+ }
+
+ if( needHScrollBar() )
+ {
+ m_hScroll->show();
+ m_hScroll->blockSignals( true );
+ m_hScroll->setRange( 0, maxHScrollId() );
+ m_hScroll->setValue( maxContentsX() );
+ m_hScroll->setSteps( 10, minVisibleWidth() - 10 );
+ m_hScroll->blockSignals( false );
+ }
+ else
+ {
+ m_hScroll->hide();
+ }
+}
+
+void KompareSplitter::slotDelayedUpdateVScrollValue()
+{
+ QTimer::singleShot( 0, this, SLOT( slotUpdateVScrollValue() ) );
+}
+
+void KompareSplitter::slotUpdateVScrollValue()
+{
+ m_vScroll->setValue( scrollId() );
+}
+
+/* FIXME: this should return the scrollId() from the listview containing the
+ * /base/ of the diff. but there's bigger issues with that atm.
+ */
+
+int KompareSplitter::scrollId()
+{
+ QSplitterLayoutStruct *curr = d->list.first();
+ for ( curr = d->list.first(); curr; curr = d->list.next() )
+ if ( !curr->isHandle )
+ return ((KompareListViewFrame*) curr->wid)->view()->scrollId();
+ return minVScrollId();
+}
+
+int KompareSplitter::lineSpacing()
+{
+ QSplitterLayoutStruct *curr = d->list.first();
+ for ( curr = d->list.first(); curr; curr = d->list.next() )
+ if ( !curr->isHandle )
+ return ((KompareListViewFrame*)
+ curr->wid)->view()->fontMetrics().lineSpacing();
+ return 1;
+}
+
+int KompareSplitter::pageSize()
+{
+ QSplitterLayoutStruct *curr;
+ for ( curr = d->list.first(); curr; curr = d->list.next() )
+ {
+ if ( !curr->isHandle )
+ {
+ KompareListView *view = ((KompareListViewFrame*) curr->wid)->view();
+ return view->visibleHeight() - QStyle::PM_ScrollBarExtent;
+ }
+ }
+ return 1;
+}
+
+bool KompareSplitter::needVScrollBar()
+{
+ QSplitterLayoutStruct *curr;
+ int pagesize = pageSize();
+ for ( curr = d->list.first(); curr; curr = d->list.next() )
+ {
+ if( !curr->isHandle )
+ {
+ KompareListView *view = ((KompareListViewFrame*) curr->wid)->view();
+ if( view ->contentsHeight() > pagesize)
+ return true;
+ }
+ }
+ return false;
+}
+
+int KompareSplitter::minVScrollId()
+{
+
+ QSplitterLayoutStruct *curr;
+ int min = -1;
+ int mSId;
+ for ( curr = d->list.first(); curr; curr = d->list.next() )
+ {
+ if(!curr->isHandle) {
+ KompareListView* view = ((KompareListViewFrame*)curr->wid)->view();
+ mSId = view->minScrollId();
+ if (mSId < min || min == -1) min = mSId;
+ }
+ }
+ return ( min == -1 ) ? 0 : min;
+}
+
+int KompareSplitter::maxVScrollId()
+{
+ QSplitterLayoutStruct *curr;
+ int max = 0;
+ int mSId;
+ for ( curr = d->list.first(); curr; curr = d->list.next() )
+ {
+ if ( !curr->isHandle )
+ {
+ mSId = ((KompareListViewFrame*)curr->wid)->view()->maxScrollId();
+ if ( mSId > max )
+ max = mSId;
+ }
+ }
+ return max;
+}
+
+bool KompareSplitter::needHScrollBar()
+{
+ QSplitterLayoutStruct *curr;
+ for ( curr = d->list.first(); curr; curr = d->list.next() )
+ {
+ if( !curr->isHandle )
+ {
+ KompareListView *view = ((KompareListViewFrame*) curr->wid)->view();
+ if ( view->contentsWidth() > view->visibleWidth() )
+ return true;
+ }
+ }
+ return false;
+}
+
+int KompareSplitter::maxHScrollId()
+{
+ QSplitterLayoutStruct *curr;
+ int max = 0;
+ int mHSId;
+ for ( curr = d->list.first(); curr; curr = d->list.next() )
+ {
+ if( !curr->isHandle )
+ {
+ KompareListView *view = ((KompareListViewFrame*) curr->wid)->view();
+ mHSId = view->contentsWidth() - view->visibleWidth();
+ if ( mHSId > max )
+ max = mHSId;
+ }
+ }
+ return max;
+}
+
+int KompareSplitter::maxContentsX()
+{
+ QSplitterLayoutStruct *curr;
+ int max = 0;
+ int mCX;
+ for ( curr = d->list.first(); curr; curr = d->list.next() )
+ {
+ if ( !curr->isHandle )
+ {
+ mCX = ((KompareListViewFrame*) curr->wid)->view()->contentsX();
+ if ( mCX > max )
+ max = mCX;
+ }
+ }
+ return max;
+}
+
+int KompareSplitter::minVisibleWidth()
+{
+ // Why the hell do we want to know this?
+ // ah yes, its because we use it to set the "page size" for horiz. scrolling.
+ // despite the fact that *noone* has a pgright and pgleft key :P
+ // But we do have mousewheels with horizontal scrolling functionality,
+ // pressing shift and scrolling then goes left and right one page at the time
+ QSplitterLayoutStruct *curr;
+ int min = -1;
+ int vW;
+ for( curr = d->list.first(); curr; curr = d->list.next() )
+ {
+ if ( !curr->isHandle ) {
+ vW = ((KompareListViewFrame*)curr->wid)->view()->visibleWidth();
+ if ( vW < min || min == -1 )
+ min = vW;
+ }
+ }
+ return ( min == -1 ) ? 0 : min;
+}
+
+#include "komparesplitter.moc"
diff --git a/kompare/komparepart/komparesplitter.h b/kompare/komparepart/komparesplitter.h
new file mode 100644
index 00000000..47eee6bf
--- /dev/null
+++ b/kompare/komparepart/komparesplitter.h
@@ -0,0 +1,115 @@
+/***************************************************************************
+ kompareview.cpp - description
+ -------------------
+ begin : Wed Jan 14 2004
+ copyright : (C) 2004 by Jeff Snyder
+ email : jeff@caffeinated.me.uk
+****************************************************************************/
+
+/***************************************************************************
+**
+** 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.
+**
+***************************************************************************/
+
+#ifndef _KOMPARESPLITTER_H_
+#define _KOMPARESPLITTER_H_
+
+#include "kompare_qsplitter.h"
+
+#include <qtimer.h>
+
+#include "komparelistview.h"
+#include "komparemodellist.h"
+
+class QSplitterLayoutStruct;
+class QTextStream;
+class QSplitterHandle;
+
+namespace Diff2 {
+class DiffModel;
+class Difference;
+}
+class ViewSettings;
+
+class KompareSplitter : public QSplitter
+{
+ Q_OBJECT
+
+public:
+ KompareSplitter(ViewSettings *settings, QWidget *parent=0, const char *name = 0);
+ ~KompareSplitter();
+
+signals:
+ void selectionChanged( const Diff2::Difference* diff );
+
+ void configChanged();
+
+ void scrollViewsToId( int id );
+ void setXOffset( int x );
+
+public slots:
+ void slotApplyDifference( bool apply );
+ void slotApplyAllDifferences( bool apply );
+ void slotApplyDifference( const Diff2::Difference* diff, bool apply );
+
+ // to update the list views
+ void slotSetSelection( const Diff2::DiffModel* model, const Diff2::Difference* diff );
+ void slotSetSelection( const Diff2::Difference* diff );
+
+ void slotDifferenceClicked( const Diff2::Difference* diff );
+
+ void slotConfigChanged();
+
+ void scrollToId( int id );
+ void slotDelayedUpdateScrollBars();
+ void slotUpdateScrollBars();
+ void slotDelayedUpdateVScrollValue();
+ void slotUpdateVScrollValue();
+
+protected:
+ void childEvent( QChildEvent * );
+ void wheelEvent( QWheelEvent* e );
+ void keyPressEvent( QKeyEvent* e );
+
+ void moveSplitter( QCOORD pos, int id );
+
+private slots:
+ void slotDelayedRepaintHandles();
+ void timerTimeout();
+
+private:
+ QSplitterLayoutStruct *addWidget(KompareListViewFrame *w,
+ bool prepend = FALSE );
+
+ void doMove( bool backwards, int pos, int id, int delta,
+ bool mayCollapse, int* positions, int* widths );
+
+ void repaintHandles();
+
+ QTimer* m_scrollTimer;
+ bool restartTimer;
+ int scrollTo;
+
+ // Scrollbars. all this just for the goddamn scrollbars. i hate them.
+ int scrollId();
+ int lineSpacing();
+ int pageSize();
+ bool needVScrollBar();
+ int minVScrollId();
+ int maxVScrollId();
+ bool needHScrollBar();
+ int maxHScrollId();
+ int maxContentsX();
+ int minVisibleWidth();
+
+ ViewSettings* m_settings;
+ QScrollBar* m_vScroll;
+ QScrollBar* m_hScroll;
+
+ friend class KompareConnectWidgetFrame;
+};
+#endif //_KOMPARESPLITTER_H_