KDevelop API Documentation

parts/diff/diffwidget.cpp

Go to the documentation of this file.
00001 /*************************************************************************** 00002 * Copyright (C) 2001 by Harald Fernengel * 00003 * harry@kdevelop.org * 00004 * * 00005 * This program is free software; you can redistribute it and/or modify * 00006 * it under the terms of the GNU General Public License as published by * 00007 * the Free Software Foundation; either version 2 of the License, or * 00008 * (at your option) any later version. * 00009 * * 00010 ***************************************************************************/ 00011 00012 #include <qlayout.h> 00013 #include <qtextedit.h> 00014 #include <qpopupmenu.h> 00015 #include <qcursor.h> 00016 #include <qfile.h> 00017 00018 #include <kconfig.h> 00019 #include <kapplication.h> 00020 #include <klocale.h> 00021 #include <kservice.h> 00022 #include <ktempfile.h> 00023 #include <kpopupmenu.h> 00024 #include <kiconloader.h> 00025 #include <kfiledialog.h> 00026 #include <kmessagebox.h> 00027 00028 #include <kparts/componentfactory.h> 00029 #include <kparts/part.h> 00030 00031 #include <kio/jobclasses.h> 00032 #include <kio/job.h> 00033 00034 #include "diffwidget.h" 00035 00036 // yup, magic value for the popupmenu-id 00037 static const int POPUP_BASE = 130977; 00038 00039 QStringList KDiffTextEdit::extParts; 00040 QStringList KDiffTextEdit::extPartsTranslated; 00041 00042 KDiffTextEdit::KDiffTextEdit( QWidget* parent, const char* name ): QTextEdit( parent, name ) 00043 { 00044 KConfig* config = kapp->config(); 00045 config->setGroup( "Diff" ); 00046 _highlight = config->readBoolEntry( "Highlight", true ); 00047 00048 searchExtParts(); 00049 } 00050 00051 KDiffTextEdit::~KDiffTextEdit() 00052 { 00053 KConfig* config = kapp->config(); 00054 00055 config->setGroup( "Diff" ); 00056 config->writeEntry( "Highlight", _highlight ); 00057 } 00058 00059 QPopupMenu* KDiffTextEdit::createPopupMenu() 00060 { 00061 return createPopupMenu( QPoint() ); 00062 } 00063 00064 QPopupMenu* KDiffTextEdit::createPopupMenu( const QPoint& p ) 00065 { 00066 QPopupMenu* popup = QTextEdit::createPopupMenu( p ); 00067 if ( !popup ) 00068 popup = new QPopupMenu( this ); 00069 00070 int i = 0; 00071 00072 for ( QStringList::Iterator it = extPartsTranslated.begin(); it != extPartsTranslated.end(); ++it ) { 00073 popup->insertItem( i18n( "Show in %1" ).arg( *it ), i + POPUP_BASE, i ); 00074 i++; 00075 } 00076 if ( !extPartsTranslated.isEmpty() ) 00077 popup->insertSeparator( i ); 00078 connect( popup, SIGNAL(activated(int)), this, SLOT(popupActivated(int)) ); 00079 00080 popup->insertItem( SmallIconSet( "filesaveas" ), i18n( "&Save As..." ), this, SLOT(saveAs()), CTRL + Key_S, POPUP_BASE - 2, 0 ); 00081 popup->setItemEnabled( POPUP_BASE - 2, length() > 0 ); 00082 00083 popup->insertSeparator( 1 ); 00084 00085 popup->insertItem( i18n( "Highlight Syntax" ), this, SLOT(toggleSyntaxHighlight()), 0, POPUP_BASE - 1, 2 ); 00086 popup->setItemChecked( POPUP_BASE - 1, _highlight ); 00087 popup->insertSeparator( 3 ); 00088 00089 return popup; 00090 } 00091 00092 void KDiffTextEdit::saveAs() 00093 { 00094 QString fName = KFileDialog::getSaveFileName(); 00095 if ( fName.isEmpty() ) 00096 return; 00097 00098 QFile f( fName ); 00099 if ( f.open( IO_WriteOnly ) ) { 00100 QTextStream stream( &f ); 00101 int pCount = paragraphs(); 00102 for ( int i = 0; i < pCount; ++i ) 00103 stream << text( i ) << "\n"; 00104 f.close(); 00105 } else { 00106 KMessageBox::sorry( 0, i18n("Unable to open file."), i18n("Diff Frontend") ); 00107 } 00108 } 00109 00110 void KDiffTextEdit::toggleSyntaxHighlight() 00111 { 00112 _highlight = !_highlight; 00113 if ( _highlight ) 00114 applySyntaxHighlight(); 00115 else 00116 clearSyntaxHighlight(); 00117 } 00118 00119 void KDiffTextEdit::applySyntaxHighlight() 00120 { 00121 // the diff has been loaded so we apply a simple highlighting 00122 static QColor cAdded( 190, 190, 237); 00123 static QColor cRemoved( 190, 237, 190 ); 00124 00125 if ( !_highlight ) 00126 return; 00127 00128 int paragCount = paragraphs(); 00129 for ( int i = 0; i < paragCount; ++i ) { 00130 QString txt = text( i ); 00131 if ( txt.length() > 0 ) { 00132 if ( txt.startsWith( "+" ) || txt.startsWith( ">" ) ) { 00133 setParagraphBackgroundColor( i, cAdded ); 00134 } else if ( txt.startsWith( "-" ) || txt.startsWith( "<" ) ) { 00135 setParagraphBackgroundColor( i, cRemoved ); 00136 } 00137 } 00138 } 00139 } 00140 00141 void KDiffTextEdit::clearSyntaxHighlight() 00142 { 00143 int paragCount = paragraphs(); 00144 for ( int i = 0; i < paragCount; ++i ) { 00145 clearParagraphBackground( i ); 00146 } 00147 } 00148 00149 void KDiffTextEdit::searchExtParts() 00150 { 00151 // only execute once 00152 static bool init = false; 00153 if ( init ) 00154 return; 00155 init = true; 00156 00157 // search all parts that can handle text/x-diff 00158 KTrader::OfferList offers = KTrader::self()->query("text/x-diff", "('KParts/ReadOnlyPart' in ServiceTypes) and ('text/x-diff' in ServiceTypes)"); 00159 KTrader::OfferList::const_iterator it; 00160 for ( it = offers.begin(); it != offers.end(); ++it ) { 00161 KService::Ptr ptr = (*it); 00162 extPartsTranslated << ptr->name(); 00163 extParts << ptr->desktopEntryName(); 00164 } 00165 return; 00166 } 00167 00168 void KDiffTextEdit::popupActivated( int id ) 00169 { 00170 id -= POPUP_BASE; 00171 if ( id < 0 || id > (int)extParts.count() ) 00172 return; 00173 00174 emit externalPartRequested( extParts[ id ] ); 00175 } 00176 00177 DiffWidget::DiffWidget( QWidget *parent, const char *name, WFlags f ): 00178 QWidget( parent, name, f ), tempFile( 0 ) 00179 { 00180 job = 0; 00181 extPart = 0; 00182 00183 te = new KDiffTextEdit( this, "Main Diff Viewer" ); 00184 te->setReadOnly( true ); 00185 te->setTextFormat( QTextEdit::PlainText ); 00186 // te->setMinimumSize( 300, 200 ); 00187 connect( te, SIGNAL(externalPartRequested(const QString&)), this, SLOT(loadExtPart(const QString&)) ); 00188 00189 QVBoxLayout* layout = new QVBoxLayout( this ); 00190 layout->addWidget( te ); 00191 } 00192 00193 DiffWidget::~DiffWidget() 00194 { 00195 delete tempFile; 00196 } 00197 00198 void DiffWidget::setExtPartVisible( bool visible ) 00199 { 00200 if ( !extPart || !extPart->widget() ) { 00201 te->show(); 00202 return; 00203 } 00204 if ( visible ) { 00205 te->hide(); 00206 extPart->widget()->show(); 00207 } else { 00208 te->show(); 00209 extPart->widget()->hide(); 00210 } 00211 } 00212 00213 void DiffWidget::loadExtPart( const QString& partName ) 00214 { 00215 if ( extPart ) { 00216 setExtPartVisible( false ); 00217 delete extPart; 00218 extPart = 0; 00219 } 00220 00221 KService::Ptr extService = KService::serviceByDesktopName( partName ); 00222 if ( !extService ) 00223 return; 00224 00225 extPart = KParts::ComponentFactory::createPartInstanceFromService<KParts::ReadOnlyPart>( extService, this, 0, this, 0 ); 00226 if ( !extPart || !extPart->widget() ) 00227 return; 00228 00229 layout()->add( extPart->widget() ); 00230 00231 setExtPartVisible( true ); 00232 00233 if ( te->paragraphs() > 0 ) 00234 populateExtPart(); 00235 } 00236 00237 void DiffWidget::slotClear() 00238 { 00239 te->clear(); 00240 if ( extPart ) 00241 extPart->closeURL(); 00242 } 00243 00244 // internally for the TextEdit only! 00245 void DiffWidget::slotAppend( const QString& str ) 00246 { 00247 te->append( str ); 00248 } 00249 00250 // internally for the TextEdit only! 00251 void DiffWidget::slotAppend( KIO::Job*, const QByteArray& ba ) 00252 { 00253 slotAppend( QString( ba ) ); 00254 } 00255 00256 void DiffWidget::populateExtPart() 00257 { 00258 if ( !extPart ) 00259 return; 00260 00261 bool ok = false; 00262 int paragCount = te->paragraphs(); 00263 if ( extPart->openStream( "text/plain", KURL() ) ) { 00264 for ( int i = 0; i < paragCount; ++i ) 00265 extPart->writeStream( te->text( i ).local8Bit() ); 00266 ok = extPart->closeStream(); 00267 } else { 00268 // workaround for parts that cannot handle streams 00269 delete tempFile; 00270 tempFile = new KTempFile(); 00271 tempFile->setAutoDelete( true ); 00272 for ( int i = 0; i < paragCount; ++i ) 00273 *(tempFile->textStream()) << te->text( i ) << endl; 00274 tempFile->close(); 00275 ok = extPart->openURL( tempFile->name() ); 00276 } 00277 if ( !ok ) 00278 setExtPartVisible( false ); 00279 } 00280 00281 // internally for the TextEdit only! 00282 void DiffWidget::slotFinished() 00283 { 00284 te->applySyntaxHighlight(); 00285 populateExtPart(); 00286 } 00287 00288 void DiffWidget::setDiff( const QString& diff ) 00289 { 00290 slotClear(); 00291 slotAppend( diff ); 00292 slotFinished(); 00293 } 00294 00295 void DiffWidget::openURL( const KURL& url ) 00296 { 00297 if ( job ) 00298 job->kill(); 00299 00300 KIO::TransferJob* job = KIO::get( url ); 00301 if ( !job ) 00302 return; 00303 00304 connect( job, SIGNAL(data( KIO::Job *, const QByteArray & )), 00305 this, SLOT(slotAppend( KIO::Job*, const QByteArray& )) ); 00306 connect( job, SIGNAL(result( KIO::Job * )), 00307 this, SLOT(slotFinished()) ); 00308 } 00309 00310 void DiffWidget::contextMenuEvent( QContextMenuEvent* /* e */ ) 00311 { 00312 QPopupMenu* popup = new QPopupMenu( this ); 00313 00314 if ( !te->isVisible() ) 00315 popup->insertItem( i18n("Display &Raw Output"), this, SLOT(showTextEdit()) ); 00316 00317 popup->exec( QCursor::pos() ); 00318 delete popup; 00319 } 00320 00321 void DiffWidget::showExtPart() 00322 { 00323 setExtPartVisible( true ); 00324 } 00325 00326 void DiffWidget::showTextEdit() 00327 { 00328 setExtPartVisible( false ); 00329 } 00330 00331 #include "diffwidget.moc"
KDE Logo
This file is part of the documentation for KDevelop Version 3.0.4.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Oct 19 08:01:50 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003