//
// C++ Implementation: annotationoutput
//
// Description:
//
//
// Author: Andras Mantia <amantia@kde.org>, (C) 2005
//
// Copyright: See COPYING file that comes with this distribution
//
//
# include <tqdict.h>
# include <tqdom.h>
# include <tqfile.h>
# include <tqheader.h>
# include <tqmap.h>
# include <tqregexp.h>
# include <tqstringlist.h>
# include <tqtextstream.h>
# include <tqtimer.h>
# include <kdebug.h>
# include <tdeio/netaccess.h>
# include <klistview.h>
# include <klocale.h>
# include <kmessagebox.h>
# include <kurl.h>
# include "annotationoutput.h"
# include "messageoutput.h"
# include "project.h"
# include "projectlist.h"
# include "qextfileinfo.h"
# include "quantacommon.h"
# include "viewmanager.h"
AnnotationOutput : : AnnotationOutput ( TQWidget * parent , const char * name )
: KTabWidget ( parent , name )
{
m_currentFileAnnotations = new MessageOutput ( this ) ;
addTab ( m_currentFileAnnotations , i18n ( " Current File " ) ) ;
m_yourAnnotations = new KListView ( this ) ;
m_yourAnnotations - > addColumn ( " 1 " , - 1 ) ;
m_yourAnnotations - > addColumn ( " 2 " , 0 ) ;
m_yourAnnotations - > setRootIsDecorated ( true ) ;
m_yourAnnotations - > header ( ) - > hide ( ) ;
m_yourAnnotations - > setSorting ( 1 ) ;
m_yourAnnotations - > setLineWidth ( 2 ) ;
addTab ( m_yourAnnotations , i18n ( " For You " ) ) ;
connect ( m_yourAnnotations , TQT_SIGNAL ( executed ( TQListViewItem * ) ) , TQT_SLOT ( yourAnnotationsItemExecuted ( TQListViewItem * ) ) ) ;
m_allAnnotations = new KListView ( this ) ;
m_allAnnotations - > addColumn ( " 1 " , - 1 ) ;
m_allAnnotations - > addColumn ( " 2 " , 0 ) ;
m_allAnnotations - > setRootIsDecorated ( true ) ;
m_allAnnotations - > header ( ) - > hide ( ) ;
m_allAnnotations - > setSorting ( 1 ) ;
m_allAnnotations - > setLineWidth ( 2 ) ;
connect ( m_allAnnotations , TQT_SIGNAL ( executed ( TQListViewItem * ) ) , TQT_SLOT ( allAnnotationsItemExecuted ( TQListViewItem * ) ) ) ;
addTab ( m_allAnnotations , i18n ( " All Files " ) ) ;
connect ( this , TQT_SIGNAL ( currentChanged ( TQWidget * ) ) , TQT_SLOT ( tabChanged ( TQWidget * ) ) ) ;
m_updateTimer = new TQTimer ( this ) ;
connect ( m_updateTimer , TQT_SIGNAL ( timeout ( ) ) , this , TQT_SLOT ( slotUpdateNextFile ( ) ) ) ;
m_yourAnnotationsNum = 0 ;
}
AnnotationOutput : : ~ AnnotationOutput ( )
{
}
void AnnotationOutput : : tabChanged ( TQWidget * w )
{
if ( w = = m_allAnnotations | | w = = m_yourAnnotations )
readAnnotations ( ) ;
}
void AnnotationOutput : : insertAnnotation ( uint line , const TQString & fileName , const TQPair < TQString , TQString > & annotation )
{
line + + ;
TQString s = i18n ( " Line %1: %2 " ) . arg ( line ) . arg ( annotation . first ) ;
s . replace ( ' \n ' , ' ' ) ;
m_currentFileAnnotations - > showMessage ( line , 1 , fileName , s ) ;
}
void AnnotationOutput : : clearAnnotations ( )
{
m_currentFileAnnotations - > clear ( ) ;
}
void AnnotationOutput : : readAnnotations ( )
{
if ( ! Project : : ref ( ) - > hasProject ( ) )
{
m_allAnnotations - > clear ( ) ;
m_yourAnnotations - > clear ( ) ;
m_yourAnnotationsNum = 0 ;
setTabLabel ( m_yourAnnotations , i18n ( " For You " ) ) ;
return ;
}
KURL baseURL = Project : : ref ( ) - > projectBaseURL ( ) ;
TQStringList openedItems ;
TQListViewItem * item = m_allAnnotations - > firstChild ( ) ;
while ( item )
{
if ( item - > isOpen ( ) )
openedItems + = item - > text ( 0 ) ;
item = item - > nextSibling ( ) ;
}
m_allAnnotations - > clear ( ) ;
m_annotatedFileItems . clear ( ) ;
m_fileNames . clear ( ) ;
m_lines . clear ( ) ;
TQStringList yourOpenedItems ;
item = m_yourAnnotations - > firstChild ( ) ;
while ( item )
{
if ( item - > isOpen ( ) )
yourOpenedItems + = item - > text ( 0 ) ;
item = item - > nextSibling ( ) ;
}
m_yourAnnotations - > clear ( ) ;
m_yourFileItems . clear ( ) ;
m_yourFileNames . clear ( ) ;
m_yourLines . clear ( ) ;
m_yourAnnotationsNum = 0 ;
TQDomElement annotationElement = Project : : ref ( ) - > dom ( ) - > firstChild ( ) . firstChild ( ) . namedItem ( " annotations " ) . toElement ( ) ;
if ( annotationElement . isNull ( ) )
return ;
TQString yourself = Project : : ref ( ) - > yourself ( ) . lower ( ) ;
TQStringList roles = Project : : ref ( ) - > yourRoles ( ) ;
TQDomNodeList nodes = annotationElement . childNodes ( ) ;
int count = nodes . count ( ) ;
for ( int i = 0 ; i < count ; i + + )
{
TQDomElement el = nodes . item ( i ) . toElement ( ) ;
TQString fileName = el . attribute ( " url " ) ;
KURL u = baseURL ;
QuantaCommon : : setUrl ( u , fileName ) ;
u = QExtFileInfo : : toAbsolute ( u , baseURL ) ;
if ( Project : : ref ( ) - > contains ( u ) )
{
bool ok ;
int line = el . attribute ( " line " ) . toInt ( & ok , 10 ) ;
TQString text = el . attribute ( " text " ) ;
TQString receiver = el . attribute ( " receiver " ) ;
text . replace ( ' \n ' , ' ' ) ;
TQString lineText = TQString ( " %1 " ) . arg ( line ) ;
if ( lineText . length ( ) < 20 )
{
TQString s ;
s . fill ( ' 0 ' , 20 - lineText . length ( ) ) ;
lineText . prepend ( s ) ;
}
KListViewItem * fileIt = m_annotatedFileItems [ fileName ] ;
if ( ! fileIt )
{
fileIt = new KListViewItem ( m_allAnnotations , fileName ) ;
m_annotatedFileItems . insert ( fileName , fileIt ) ;
m_fileNames [ fileIt ] = u . url ( ) ;
}
KListViewItem * it = new KListViewItem ( fileIt , fileIt , text , lineText ) ;
if ( openedItems . contains ( fileName ) )
fileIt - > setOpen ( true ) ;
m_fileNames [ it ] = u . url ( ) ;
m_lines [ it ] = line ;
if ( ! yourself . isEmpty ( ) & & ( receiver = = yourself | | roles . contains ( receiver ) ) )
{
m_yourAnnotationsNum + + ;
KListViewItem * fileIt = m_yourFileItems [ fileName ] ;
if ( ! fileIt )
{
fileIt = new KListViewItem ( m_yourAnnotations , fileName ) ;
m_yourFileItems . insert ( fileName , fileIt ) ;
m_yourFileNames [ fileIt ] = u . url ( ) ;
}
KListViewItem * it = new KListViewItem ( fileIt , fileIt , text , lineText ) ;
if ( yourOpenedItems . contains ( fileName ) )
fileIt - > setOpen ( true ) ;
m_yourFileNames [ it ] = u . url ( ) ;
m_yourLines [ it ] = line ;
}
} else
{
annotationElement . removeChild ( el ) ;
}
}
if ( m_yourAnnotationsNum > 0 )
{
setTabLabel ( m_yourAnnotations , i18n ( " For You: %1 " ) . arg ( m_yourAnnotationsNum ) ) ;
} else
{
setTabLabel ( m_yourAnnotations , i18n ( " For You " ) ) ;
}
}
void AnnotationOutput : : writeAnnotations ( const TQString & fileName , const TQMap < uint , TQPair < TQString , TQString > > & a_annotations )
{
m_annotatedFileItems . clear ( ) ;
m_fileNames . clear ( ) ;
m_lines . clear ( ) ;
m_yourFileItems . clear ( ) ;
m_yourFileNames . clear ( ) ;
m_yourLines . clear ( ) ;
bool modified = false ;
TQMap < uint , TQPair < TQString , TQString > > annotations = a_annotations ;
TQDomDocument * dom = Project : : ref ( ) - > dom ( ) ;
TQDomElement annotationElement = dom - > firstChild ( ) . firstChild ( ) . namedItem ( " annotations " ) . toElement ( ) ;
if ( annotationElement . isNull ( ) )
{
annotationElement = dom - > createElement ( " annotations " ) ;
dom - > firstChild ( ) . firstChild ( ) . appendChild ( annotationElement ) ;
}
TQDomNode n = annotationElement . firstChild ( ) ;
while ( ! n . isNull ( ) )
{
TQDomElement el = n . toElement ( ) ;
TQString fName = el . attribute ( " url " ) ;
TQDomNode n2 = n . nextSibling ( ) ;
if ( fileName = = fName )
{
TQString text = el . attribute ( " text " ) ;
bool ok ;
int line = el . attribute ( " line " ) . toInt ( & ok , 10 ) ;
if ( ! annotations . contains ( line ) | | ( annotations [ line ] . first ! = text ) )
{
n . parentNode ( ) . removeChild ( n ) ;
modified = true ;
} else
annotations . remove ( line ) ;
}
n = n2 ;
}
for ( TQMap < uint , TQPair < TQString , TQString > > : : ConstIterator it = annotations . constBegin ( ) ; it ! = annotations . constEnd ( ) ; + + it )
{
TQDomElement el = dom - > createElement ( " annotation " ) ;
el . setAttribute ( " url " , fileName ) ;
el . setAttribute ( " line " , it . key ( ) ) ;
el . setAttribute ( " text " , it . data ( ) . first ) ;
el . setAttribute ( " receiver " , it . data ( ) . second . lower ( ) ) ;
annotationElement . appendChild ( el ) ;
modified = true ;
}
if ( modified )
Project : : ref ( ) - > setModified ( true ) ;
if ( m_allAnnotations - > isVisible ( ) | | m_yourAnnotations - > isVisible ( ) )
readAnnotations ( ) ;
}
void AnnotationOutput : : allAnnotationsItemExecuted ( TQListViewItem * item )
{
if ( dynamic_cast < KListView * > ( item - > parent ( ) ) ! = m_allAnnotations )
{
emit clicked ( m_fileNames [ item ] , m_lines [ item ] , 0 ) ;
} else
emit clicked ( m_fileNames [ item ] , 0 , 0 ) ;
}
void AnnotationOutput : : yourAnnotationsItemExecuted ( TQListViewItem * item )
{
if ( dynamic_cast < KListView * > ( item - > parent ( ) ) ! = m_yourAnnotations )
{
emit clicked ( m_yourFileNames [ item ] , m_yourLines [ item ] , 0 ) ;
} else
emit clicked ( m_yourFileNames [ item ] , 0 , 0 ) ;
}
void AnnotationOutput : : updateAnnotations ( )
{
m_updateTimer - > stop ( ) ;
m_currentFileAnnotations - > clear ( ) ;
readAnnotations ( ) ;
if ( Project : : ref ( ) - > hasProject ( ) & & Project : : ref ( ) - > projectBaseURL ( ) . isLocalFile ( ) )
{
m_files = Project : : ref ( ) - > files ( ) ;
m_fileIndex = 0 ;
m_updateTimer - > start ( 0 , true ) ;
}
}
void AnnotationOutput : : updateAnnotationForFile ( const KURL & url )
{
static const TQRegExp rx ( " -->| \\ */ " ) ;
if ( ! ViewManager : : ref ( ) - > isOpened ( url ) & & QuantaCommon : : checkMimeGroup ( url , " text " ) )
{
// kdDebug(24000) << "Testing " << url << endl;
TQFile f ( url . path ( ) ) ;
if ( f . open ( IO_ReadOnly ) )
{
TQMap < uint , TQPair < TQString , TQString > > annotations ;
uint i = 0 ;
TQTextStream stream ( & f ) ;
stream . setEncoding ( TQTextStream : : UnicodeUTF8 ) ;
TQString line ;
while ( ! stream . atEnd ( ) )
{
line = stream . readLine ( ) ;
int pos = line . find ( " @annotation " ) ;
if ( pos ! = - 1 )
{
TQString receiver ;
pos + = 11 ;
if ( line [ pos ] = = ' ( ' )
{
int p = pos ;
pos = line . find ( ' ) ' ) ;
if ( pos ! = - 1 )
{
receiver = line . mid ( p + 1 , pos - p - 1 ) ;
pos + = 2 ;
}
} else
pos + + ;
int pos2 = line . find ( rx ) ;
annotations . insert ( i , tqMakePair ( line . mid ( pos , pos2 - pos ) . stripWhiteSpace ( ) , receiver ) ) ;
}
+ + i ;
}
f . close ( ) ;
if ( ! annotations . isEmpty ( ) )
{
KURL u = QExtFileInfo : : toRelative ( url , Project : : ref ( ) - > projectBaseURL ( ) ) ;
writeAnnotations ( QuantaCommon : : qUrl ( u ) , annotations ) ;
}
}
}
}
void AnnotationOutput : : slotUpdateNextFile ( )
{
updateAnnotationForFile ( m_files [ m_fileIndex ] ) ;
if ( m_fileIndex < m_files . count ( ) )
{
m_fileIndex + + ;
m_updateTimer - > start ( 2 , true ) ;
} else
if ( m_yourAnnotationsNum > 0 )
{
KMessageBox : : information ( this , i18n ( " <qt>There are annotations addressed for you.<br> To view them select the <i>For You</i> tab in the <i>Annotations</i> toolview.</qt> " ) , i18n ( " New Annotations " ) , " Show Your Annotations " ) ;
}
}
# include "annotationoutput.moc"