diff options
| author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 | 
|---|---|---|
| committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 | 
| commit | 114a878c64ce6f8223cfd22d76a20eb16d177e5e (patch) | |
| tree | acaf47eb0fa12142d3896416a69e74cbf5a72242 /vcs/cvsservice/diffwidget.cpp | |
| download | tdevelop-114a878c64ce6f8223cfd22d76a20eb16d177e5e.tar.gz tdevelop-114a878c64ce6f8223cfd22d76a20eb16d177e5e.zip | |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdevelop@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'vcs/cvsservice/diffwidget.cpp')
| -rw-r--r-- | vcs/cvsservice/diffwidget.cpp | 331 | 
1 files changed, 331 insertions, 0 deletions
| diff --git a/vcs/cvsservice/diffwidget.cpp b/vcs/cvsservice/diffwidget.cpp new file mode 100644 index 00000000..c51c16b0 --- /dev/null +++ b/vcs/cvsservice/diffwidget.cpp @@ -0,0 +1,331 @@ +/*************************************************************************** + *   Copyright (C) 2001 by Harald Fernengel                                * + *   harry@kdevelop.org                                                    * + *                                                                         * + *   This program is free software; you can redistribute it and/or modify  * + *   it under the terms of the GNU General Public License as published by  * + *   the Free Software Foundation; either version 2 of the License, or     * + *   (at your option) any later version.                                   * + *                                                                         * + ***************************************************************************/ + +#include <qlayout.h> +#include <qtextedit.h> +#include <qpopupmenu.h> +#include <qcursor.h> +#include <qfile.h> + +#include <kconfig.h> +#include <kapplication.h> +#include <klocale.h> +#include <kservice.h> +#include <ktempfile.h> +#include <kpopupmenu.h> +#include <kiconloader.h> +#include <kfiledialog.h> +#include <kmessagebox.h> + +#include <kparts/componentfactory.h> +#include <kparts/part.h> + +#include <kio/jobclasses.h> +#include <kio/job.h> + +#include "diffwidget.h" + +// yup, magic value for the popupmenu-id +static const int POPUP_BASE = 130977; + +QStringList KDiffTextEdit::extParts; +QStringList KDiffTextEdit::extPartsTranslated; + +KDiffTextEdit::KDiffTextEdit( QWidget* parent, const char* name ): QTextEdit( parent, name ) +{ +  KConfig* config = kapp->config(); +  config->setGroup( "Diff" ); +  _highlight = config->readBoolEntry( "Highlight", true ); + +  searchExtParts(); +} + +KDiffTextEdit::~KDiffTextEdit() +{ +  KConfig* config = kapp->config(); + +  config->setGroup( "Diff" ); +  config->writeEntry( "Highlight", _highlight ); +} + +QPopupMenu* KDiffTextEdit::createPopupMenu() +{ +  return createPopupMenu( QPoint() ); +} + +QPopupMenu* KDiffTextEdit::createPopupMenu( const QPoint& p ) +{ +  QPopupMenu* popup = QTextEdit::createPopupMenu( p ); +  if ( !popup ) +    popup = new QPopupMenu( this ); + +  int i = 0; + +  for ( QStringList::Iterator it = extPartsTranslated.begin(); it != extPartsTranslated.end(); ++it ) { +    popup->insertItem( i18n( "Show in %1" ).arg( *it ), i + POPUP_BASE, i ); +    i++; +  } +  if ( !extPartsTranslated.isEmpty() ) +    popup->insertSeparator( i ); +  connect( popup, SIGNAL(activated(int)), this, SLOT(popupActivated(int)) ); + +  popup->insertItem( SmallIconSet( "filesaveas" ), i18n( "&Save As..." ), this, SLOT(saveAs()), CTRL + Key_S, POPUP_BASE - 2, 0 ); +  popup->setItemEnabled( POPUP_BASE - 2, length() > 0 ); + +  popup->insertSeparator( 1 ); + +  popup->insertItem( i18n( "Highlight Syntax" ), this, SLOT(toggleSyntaxHighlight()), 0, POPUP_BASE - 1, 2 ); +  popup->setItemChecked( POPUP_BASE - 1, _highlight ); +  popup->insertSeparator( 3 ); + +  return popup; +} + +void KDiffTextEdit::saveAs() +{ +  QString fName = KFileDialog::getSaveFileName(); +  if ( fName.isEmpty() ) +    return; + +  QFile f( fName ); +  if ( f.open( IO_WriteOnly ) ) { +    QTextStream stream( &f ); +    int pCount = paragraphs(); +    for ( int i = 0; i < pCount; ++i ) +      stream << text( i ) << "\n"; +    f.close(); +  } else { +    KMessageBox::sorry( this, i18n("Unable to open file."), i18n("Diff Frontend") ); +  } +} + +void KDiffTextEdit::toggleSyntaxHighlight() +{ +  _highlight = !_highlight; +  if ( _highlight ) +    applySyntaxHighlight(); +  else +    clearSyntaxHighlight(); +} + +void KDiffTextEdit::applySyntaxHighlight() +{ +  // the diff has been loaded so we apply a simple highlighting +  static QColor cAdded( 190, 190, 237); +  static QColor cRemoved( 190, 237, 190 ); + +  if ( !_highlight ) +    return; + +  int paragCount = paragraphs(); +  for ( int i = 0; i < paragCount; ++i ) { +    QString txt = text( i ); +    if ( txt.length() > 0 ) { +      if ( txt.startsWith( "+" ) || txt.startsWith( ">" ) ) { +        setParagraphBackgroundColor( i, cAdded ); +      } else if ( txt.startsWith( "-" ) || txt.startsWith( "<" ) ) { +        setParagraphBackgroundColor( i, cRemoved ); +      } +    } +  } +} + +void KDiffTextEdit::clearSyntaxHighlight() +{ +  int paragCount = paragraphs(); +  for ( int i = 0; i < paragCount; ++i ) { +    clearParagraphBackground( i ); +  } +} + +void KDiffTextEdit::searchExtParts() +{ +  // only execute once +  static bool init = false; +  if ( init ) +    return; +  init = true; + +  // search all parts that can handle text/x-diff +  KTrader::OfferList offers = KTrader::self()->query("text/x-diff", "('KParts/ReadOnlyPart' in ServiceTypes) and ('text/x-diff' in ServiceTypes)"); +  KTrader::OfferList::const_iterator it; +  for ( it = offers.begin(); it != offers.end(); ++it ) { +    KService::Ptr ptr = (*it); +    extPartsTranslated << ptr->name(); +    extParts << ptr->desktopEntryName(); +  } +  return; +} + +void KDiffTextEdit::popupActivated( int id ) +{ +  id -= POPUP_BASE; +  if ( id < 0 || id > (int)extParts.count() ) +    return; + +  emit externalPartRequested( extParts[ id ] ); +} + +DiffWidget::DiffWidget( QWidget *parent, const char *name, WFlags f ): +    QWidget( parent, name, f ), tempFile( 0 ) +{ +  job = 0; +  extPart = 0; + +  te = new KDiffTextEdit( this, "Main Diff Viewer" ); +  te->setReadOnly( true ); +  te->setTextFormat( QTextEdit::PlainText ); +//  te->setMinimumSize( 300, 200 ); +  connect( te, SIGNAL(externalPartRequested(const QString&)), this, SLOT(loadExtPart(const QString&)) ); + +  QVBoxLayout* layout = new QVBoxLayout( this ); +  layout->addWidget( te ); +} + +DiffWidget::~DiffWidget() +{ +    delete tempFile; +} + +void DiffWidget::setExtPartVisible( bool visible ) +{ +  if ( !extPart || !extPart->widget() ) { +    te->show(); +    return; +  } +  if ( visible ) { +    te->hide(); +    extPart->widget()->show(); +  } else { +    te->show(); +    extPart->widget()->hide(); +  } +} + +void DiffWidget::loadExtPart( const QString& partName ) +{ +  if ( extPart ) { +    setExtPartVisible( false ); +    delete extPart; +    extPart = 0; +  } + +  KService::Ptr extService = KService::serviceByDesktopName( partName ); +  if ( !extService ) +    return; + +  extPart = KParts::ComponentFactory::createPartInstanceFromService<KParts::ReadOnlyPart>( extService, this, 0, this, 0 ); +  if ( !extPart || !extPart->widget() ) +    return; + +  layout()->add( extPart->widget() ); + +  setExtPartVisible( true ); + +  if ( te->paragraphs() > 0 ) +    populateExtPart(); +} + +void DiffWidget::slotClear() +{ +  te->clear(); +  if ( extPart ) +    extPart->closeURL(); +} + +// internally for the TextEdit only! +void DiffWidget::slotAppend( const QString& str ) +{ +  te->append( str ); +} + +// internally for the TextEdit only! +void DiffWidget::slotAppend( KIO::Job*, const QByteArray& ba ) +{ +  slotAppend( QString( ba ) ); +} + +void DiffWidget::populateExtPart() +{ +  if ( !extPart ) +    return; + +  bool ok = false; +  int paragCount = te->paragraphs(); +  if ( extPart->openStream( "text/plain", KURL() ) ) { +    for ( int i = 0; i < paragCount; ++i ) +      extPart->writeStream( te->text( i ).local8Bit() ); +    ok = extPart->closeStream(); +  } else { +      // workaround for parts that cannot handle streams +      delete tempFile; +      tempFile = new KTempFile(); +      tempFile->setAutoDelete( true ); +      for ( int i = 0; i < paragCount; ++i ) +        *(tempFile->textStream()) << te->text( i ) << endl; +      tempFile->close(); +      ok = extPart->openURL( KURL( tempFile->name() ) ); +  } +  if ( !ok ) +    setExtPartVisible( false ); +} + +// internally for the TextEdit only! +void DiffWidget::slotFinished() +{ +    te->applySyntaxHighlight(); +    populateExtPart(); +} + +void DiffWidget::setDiff( const QString& diff ) +{ +  slotClear(); +  slotAppend( diff ); +  slotFinished(); +} + +void DiffWidget::openURL( const KURL& url ) +{ +  if ( job ) +    job->kill(); + +  KIO::TransferJob* job = KIO::get( url ); +  if ( !job ) +    return; + +  connect( job, SIGNAL(data( KIO::Job *, const QByteArray & )), +           this, SLOT(slotAppend( KIO::Job*, const QByteArray& )) ); +  connect( job, SIGNAL(result( KIO::Job * )), +           this, SLOT(slotFinished()) ); +} + +void DiffWidget::contextMenuEvent( QContextMenuEvent* /* e */ ) +{ +  QPopupMenu* popup = new QPopupMenu( this ); + +  if ( !te->isVisible() ) +    popup->insertItem( i18n("Display &Raw Output"), this, SLOT(showTextEdit()) ); + +  popup->exec( QCursor::pos() ); +  delete popup; +} + +void DiffWidget::showExtPart() +{ +  setExtPartVisible( true ); +} + +void DiffWidget::showTextEdit() +{ +  setExtPartVisible( false ); +} + +#include "diffwidget.moc" | 
