/***************************************************************************
* 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 <tqlayout.h>
# include <tqtextedit.h>
# include <tqpopupmenu.h>
# include <tqcursor.h>
# include <tqfile.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 <kdevmainwindow.h>
# include "diffpart.h"
# include "diffwidget.h"
// yup, magic value for the popupmenu-id
static const int POPUP_BASE = 130977 ;
TQStringList KDiffTextEdit : : extParts ;
TQStringList KDiffTextEdit : : extPartsTranslated ;
KDiffTextEdit : : KDiffTextEdit ( TQWidget * parent , const char * name ) : TQTextEdit ( 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 ) ;
}
TQPopupMenu * KDiffTextEdit : : createPopupMenu ( )
{
return createPopupMenu ( TQPoint ( ) ) ;
}
TQPopupMenu * KDiffTextEdit : : createPopupMenu ( const TQPoint & p )
{
TQPopupMenu * popup = TQTextEdit : : createPopupMenu ( p ) ;
if ( ! popup )
popup = new TQPopupMenu ( this ) ;
int i = 0 ;
for ( TQStringList : : Iterator it = extPartsTranslated . begin ( ) ; it ! = extPartsTranslated . end ( ) ; + + it ) {
popup - > insertItem ( i18n ( " Show in %1 " ) . tqarg ( * it ) , i + POPUP_BASE , i ) ;
i + + ;
}
if ( ! extPartsTranslated . isEmpty ( ) )
popup - > insertSeparator ( i ) ;
connect ( popup , TQT_SIGNAL ( activated ( int ) ) , this , TQT_SLOT ( popupActivated ( int ) ) ) ;
popup - > insertItem ( SmallIconSet ( " filesaveas " ) , i18n ( " &Save As... " ) , this , TQT_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 , TQT_SLOT ( toggleSyntaxHighlight ( ) ) , 0 , POPUP_BASE - 1 , 2 ) ;
popup - > setItemChecked ( POPUP_BASE - 1 , _highlight ) ;
popup - > insertSeparator ( 3 ) ;
popup - > insertSeparator ( ) ;
popup - > insertItem ( i18n ( " Hide view " ) , parent ( ) , TQT_SLOT ( hideView ( ) ) ) ;
return popup ;
}
void KDiffTextEdit : : saveAs ( )
{
TQString fName = KFileDialog : : getSaveFileName ( ) ;
if ( fName . isEmpty ( ) )
return ;
TQFile f ( fName ) ;
if ( f . open ( IO_WriteOnly ) ) {
TQTextStream stream ( & f ) ;
int pCount = paragraphs ( ) ;
for ( int i = 0 ; i < pCount ; + + i )
stream < < text ( i ) < < " \n " ;
f . close ( ) ;
} else {
KMessageBox : : sorry ( 0 , 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 TQColor cAdded ( 190 , 190 , 237 ) ;
static TQColor cRemoved ( 190 , 237 , 190 ) ;
if ( ! _highlight )
return ;
int paragCount = paragraphs ( ) ;
for ( int i = 0 ; i < paragCount ; + + i ) {
TQString 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) and (DesktopEntryName != 'katepart') " ) ;
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 ( DiffPart * part , TQWidget * parent , const char * name , WFlags f ) :
TQWidget ( parent , name , f ) , m_part ( part ) , tempFile ( 0 )
{
job = 0 ;
extPart = 0 ;
te = new KDiffTextEdit ( this , " Main Diff Viewer " ) ;
te - > setReadOnly ( true ) ;
te - > setTextFormat ( TQTextEdit : : PlainText ) ;
// te->setMinimumSize( 300, 200 );
connect ( te , TQT_SIGNAL ( externalPartRequested ( const TQString & ) ) , this , TQT_SLOT ( loadExtPart ( const TQString & ) ) ) ;
TQVBoxLayout * tqlayout = new TQVBoxLayout ( this ) ;
tqlayout - > addWidget ( te ) ;
}
DiffWidget : : ~ DiffWidget ( )
{
m_part = 0 ;
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 TQString & 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 , TQT_TQOBJECT ( this ) , 0 ) ;
if ( ! extPart | | ! extPart - > widget ( ) )
return ;
tqlayout ( ) - > add ( extPart - > widget ( ) ) ;
setExtPartVisible ( true ) ;
if ( te - > paragraphs ( ) > 0 )
populateExtPart ( ) ;
}
void DiffWidget : : slotClear ( )
{
rawDiff = TQString ( ) ;
te - > clear ( ) ;
if ( extPart )
extPart - > closeURL ( ) ;
}
// internally for the TextEdit only!
void DiffWidget : : slotAppend ( const TQString & str )
{
te - > append ( str ) ;
}
// internally for the TextEdit only!
void DiffWidget : : slotAppend ( KIO : : Job * , const TQByteArray & ba )
{
slotAppend ( TQString ( 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 ( rawDiff . local8Bit ( ) ) ;
ok = extPart - > closeStream ( ) ;
} else {
// workaround for parts that cannot handle streams
delete tempFile ;
tempFile = new KTempFile ( ) ;
tempFile - > setAutoDelete ( true ) ;
* ( tempFile - > textStream ( ) ) < < rawDiff . local8Bit ( ) < < endl ;
tempFile - > close ( ) ;
ok = extPart - > openURL ( KURL : : fromPathOrURL ( tempFile - > name ( ) ) ) ;
}
if ( ! ok )
setExtPartVisible ( false ) ;
}
// internally for the TextEdit only!
void DiffWidget : : slotFinished ( )
{
te - > applySyntaxHighlight ( ) ;
populateExtPart ( ) ;
}
void DiffWidget : : setDiff ( const TQString & diff )
{
slotClear ( ) ;
rawDiff = diff ;
slotAppend ( diff ) ;
slotFinished ( ) ;
}
void DiffWidget : : openURL ( const KURL & url )
{
if ( job )
job - > kill ( ) ;
KIO : : TransferJob * job = KIO : : get ( url ) ;
if ( ! job )
return ;
connect ( job , TQT_SIGNAL ( data ( KIO : : Job * , const TQByteArray & ) ) ,
this , TQT_SLOT ( slotAppend ( KIO : : Job * , const TQByteArray & ) ) ) ;
connect ( job , TQT_SIGNAL ( result ( KIO : : Job * ) ) ,
this , TQT_SLOT ( slotFinished ( ) ) ) ;
}
void DiffWidget : : contextMenuEvent ( TQContextMenuEvent * /* e */ )
{
TQPopupMenu * popup = new TQPopupMenu ( this ) ;
if ( ! te - > isVisible ( ) )
{
popup - > insertItem ( i18n ( " Display &Raw Output " ) , this , TQT_SLOT ( showTextEdit ( ) ) ) ;
popup - > insertSeparator ( ) ;
popup - > insertItem ( i18n ( " Hide view " ) , this , TQT_SLOT ( hideView ( ) ) ) ;
}
popup - > exec ( TQCursor : : pos ( ) ) ;
delete popup ;
}
void DiffWidget : : showExtPart ( )
{
setExtPartVisible ( true ) ;
}
void DiffWidget : : showTextEdit ( )
{
setExtPartVisible ( false ) ;
}
void DiffWidget : : hideView ( )
{
m_part - > mainWindow ( ) - > setViewAvailable ( this , false ) ;
}
# include "diffwidget.moc"