/*
channellist . cpp - IRC Channel Search Widget
Copyright ( c ) 2004 by Jason Keirstead < jason @ keirstead . org >
Kopete ( c ) 2002 - 2004 by the Kopete developers < kopete - devel @ 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 "channellist.h"
# include "kircengine.h"
# include <klocale.h>
# include <kmessagebox.h>
# include <tqvariant.h>
# include <tqlabel.h>
# include <tqpainter.h>
# include <tqapplication.h>
# include <tqsimplerichtext.h>
# include <tqstyle.h>
# include <tqlineedit.h>
# include <tqpushbutton.h>
# include <tqheader.h>
# include <klistview.h>
# include <tqlayout.h>
# include <tqtooltip.h>
# include <tqtimer.h>
# include <tqspinbox.h>
# include <tqwhatsthis.h>
class ChannelListItem : public KListViewItem
{
public :
ChannelListItem ( KListView * parent , TQString arg1 , TQString arg2 , TQString arg3 ) ;
virtual int compare ( TQListViewItem * i , int col , bool ascending ) const ;
virtual void paintCell ( TQPainter * p , const TQColorGroup & cg , int column , int width , int align ) ;
private :
KListView * parentList ;
} ;
ChannelListItem : : ChannelListItem ( KListView * parent , TQString arg1 , TQString arg2 , TQString arg3 ) :
KListViewItem ( parent , parent - > lastItem ( ) ) , parentList ( parent )
{
setText ( 0 , arg1 ) ;
setText ( 1 , arg2 ) ;
setText ( 2 , arg3 ) ;
}
int ChannelListItem : : compare ( TQListViewItem * i , int col , bool ascending ) const
{
if ( col = = 1 )
{
if ( text ( 1 ) . toUInt ( ) < i - > text ( 1 ) . toUInt ( ) )
return - 1 ;
else if ( text ( 1 ) . toUInt ( ) = = i - > text ( 1 ) . toUInt ( ) )
return 0 ;
else
return 1 ;
}
else
return TQListViewItem : : compare ( i , col , ascending ) ;
}
void ChannelListItem : : paintCell ( TQPainter * p , const TQColorGroup & cg , int column , int width , int align )
{
TQPixmap back ( width , height ( ) ) ;
TQPainter paint ( & back ) ;
//KListViewItem::paintCell( &paint, cg, column, width, align );
// PASTED FROM KLISTVIEWITEM:
// set the alternate cell background colour if necessary
TQColorGroup _cg = cg ;
if ( isAlternate ( ) )
if ( listView ( ) - > viewport ( ) - > backgroundMode ( ) = = TQt : : FixedColor )
_cg . setColor ( TQColorGroup : : Background , static_cast < KListView * > ( listView ( ) ) - > alternateBackground ( ) ) ;
else
_cg . setColor ( TQColorGroup : : Base , static_cast < KListView * > ( listView ( ) ) - > alternateBackground ( ) ) ;
// PASTED FROM TQLISTVIEWITEM
{
TQPainter * p = & paint ;
TQListView * lv = listView ( ) ;
if ( ! lv )
return ;
TQFontMetrics fm ( p - > fontMetrics ( ) ) ;
// any text we render is done by the Components, not by this class, so make sure we've nothing to write
TQString t ;
// removed text truncating code from TQt - we do that differently, further on
int marg = lv - > itemMargin ( ) ;
int r = marg ;
// const TQPixmap * icon = pixmap( column );
const BackgroundMode bgmode = lv - > viewport ( ) - > backgroundMode ( ) ;
const TQColorGroup : : ColorRole crole = TQPalette : : backgroundRoleFromMode ( bgmode ) ;
if ( _cg . brush ( crole ) ! = lv - > tqcolorGroup ( ) . brush ( crole ) )
p - > fillRect ( 0 , 0 , width , height ( ) , _cg . brush ( crole ) ) ;
else
{
// all copied from TQListView::paintEmptyArea
//lv->paintEmptyArea( p, TQRect( 0, 0, width, height() ) );
TQStyleOption opt ( lv - > sortColumn ( ) , 0 ) ; // ### hack; in 3.1, add a property in TQListView and TQHeader
TQStyle : : SFlags how = TQStyle : : Style_Default ;
if ( lv - > isEnabled ( ) )
how | = TQStyle : : Style_Enabled ;
lv - > tqstyle ( ) . tqdrawComplexControl ( TQStyle : : CC_ListView ,
p , lv , TQRect ( 0 , 0 , width , height ( ) ) , lv - > tqcolorGroup ( ) ,
how , TQStyle : : SC_ListView , TQStyle : : SC_None ,
opt ) ;
}
if ( isSelected ( ) & &
( column = = 0 | | lv - > allColumnsShowFocus ( ) ) ) {
p - > fillRect ( r - marg , 0 , width - r + marg , height ( ) ,
_cg . brush ( TQColorGroup : : Highlight ) ) ;
// removed text pen setting code from TQt
}
// removed icon drawing code from TQt
// draw the tree gubbins
if ( multiLinesEnabled ( ) & & column = = 0 & & isOpen ( ) & & childCount ( ) ) {
int textheight = fm . size ( align , t ) . height ( ) + 2 * lv - > itemMargin ( ) ;
textheight = TQMAX ( textheight , TQApplication : : globalStrut ( ) . height ( ) ) ;
if ( textheight % 2 > 0 )
textheight + + ;
if ( textheight < height ( ) ) {
int w = lv - > treeStepSize ( ) / 2 ;
lv - > tqstyle ( ) . tqdrawComplexControl ( TQStyle : : CC_ListView , p , lv ,
TQRect ( 0 , textheight , w + 1 , height ( ) - textheight + 1 ) , _cg ,
lv - > isEnabled ( ) ? TQStyle : : Style_Enabled : TQStyle : : Style_Default ,
TQStyle : : SC_ListViewExpand ,
( uint ) TQStyle : : SC_All , TQStyleOption ( this ) ) ;
}
}
}
// END OF PASTE
//do you see a better way to tell the TextComponent we are selected ? - Olivier 2004-09-02
if ( isSelected ( ) )
_cg . setColor ( TQColorGroup : : Text , _cg . highlightedText ( ) ) ;
TQSimpleRichText myrichtext ( text ( column ) , paint . font ( ) ) ;
myrichtext . draw ( & paint , 0 , 0 , paint . window ( ) , _cg ) ;
paint . end ( ) ;
p - > drawPixmap ( 0 , 0 , back ) ;
}
ChannelList : : ChannelList ( TQWidget * parent , KIRC : : Engine * engine )
: TQWidget ( parent ) , m_engine ( engine )
{
ChannelListLayout = new TQVBoxLayout ( this , 11 , 6 , " ChannelListLayout " ) ;
tqlayout72_2 = new TQHBoxLayout ( 0 , 0 , 6 , " tqlayout72_2 " ) ;
textLabel1_2 = new TQLabel ( this , " textLabel1_2 " ) ;
tqlayout72_2 - > addWidget ( textLabel1_2 ) ;
channelSearch = new TQLineEdit ( this , " channelSearch " ) ;
tqlayout72_2 - > addWidget ( channelSearch ) ;
numUsers = new TQSpinBox ( 0 , 32767 , 1 , this , " num_users " ) ;
numUsers - > setSuffix ( i18n ( " members " ) ) ;
tqlayout72_2 - > addWidget ( numUsers ) ;
mSearchButton = new TQPushButton ( this , " mSearchButton " ) ;
tqlayout72_2 - > addWidget ( mSearchButton ) ;
ChannelListLayout - > addLayout ( tqlayout72_2 ) ;
mChannelList = new KListView ( this , " mChannelList " ) ;
mChannelList - > addColumn ( i18n ( " Channel " ) ) ;
mChannelList - > addColumn ( i18n ( " Users " ) ) ;
mChannelList - > header ( ) - > setResizeEnabled ( FALSE , mChannelList - > header ( ) - > count ( ) - 1 ) ;
mChannelList - > addColumn ( i18n ( " Topic " ) ) ;
mChannelList - > setAllColumnsShowFocus ( TRUE ) ;
mChannelList - > setShowSortIndicator ( TRUE ) ;
ChannelListLayout - > addWidget ( mChannelList ) ;
clearWState ( WState_Polished ) ;
textLabel1_2 - > setText ( i18n ( " Search for: " ) ) ;
TQToolTip : : add ( textLabel1_2 , i18n ( " You may search for channels on the IRC server for a text string entered here. " ) ) ;
TQToolTip : : add ( numUsers , i18n ( " Channels returned must have at least this many members. " ) ) ;
TQWhatsThis : : add ( numUsers , i18n ( " Channels returned must have at least this many members. " ) ) ;
TQWhatsThis : : add ( textLabel1_2 , i18n ( " You may search for channels on the IRC server for a text string entered here. For instance, you may type 'linux' to find channels that have something to do with linux. " ) ) ;
TQToolTip : : add ( channelSearch , i18n ( " You may search for channels on the IRC server for a text string entered here. " ) ) ;
TQWhatsThis : : add ( channelSearch , i18n ( " You may search for channels on the IRC server for a text string entered here. For instance, you may type 'linux' to find channels that have something to do with linux. " ) ) ;
mSearchButton - > setText ( i18n ( " S&earch " ) ) ;
TQToolTip : : add ( mSearchButton , i18n ( " Perform a channel search. " ) ) ;
TQWhatsThis : : add ( mSearchButton , i18n ( " Perform a channel search. Please be patient, as this can be slow depending on the number of channels on the server. " ) ) ;
TQToolTip : : add ( mChannelList , i18n ( " Double click on a channel to select it. " ) ) ;
mChannelList - > header ( ) - > setLabel ( 0 , i18n ( " Channel " ) ) ;
mChannelList - > header ( ) - > setLabel ( 1 , i18n ( " Users " ) ) ;
mChannelList - > header ( ) - > setLabel ( 2 , i18n ( " Topic " ) ) ;
// signals and slots connections
connect ( mChannelList , TQT_SIGNAL ( doubleClicked ( TQListViewItem * ) ) ,
this , TQT_SLOT ( slotItemDoubleClicked ( TQListViewItem * ) ) ) ;
connect ( mSearchButton , TQT_SIGNAL ( clicked ( ) ) , this , TQT_SLOT ( search ( ) ) ) ;
connect ( mChannelList , TQT_SIGNAL ( selectionChanged ( TQListViewItem * ) ) , this ,
TQT_SLOT ( slotItemSelected ( TQListViewItem * ) ) ) ;
connect ( m_engine , TQT_SIGNAL ( incomingListedChan ( const TQString & , uint , const TQString & ) ) ,
this , TQT_SLOT ( slotChannelListed ( const TQString & , uint , const TQString & ) ) ) ;
connect ( m_engine , TQT_SIGNAL ( incomingEndOfList ( ) ) , this , TQT_SLOT ( slotListEnd ( ) ) ) ;
connect ( m_engine , TQT_SIGNAL ( statusChanged ( KIRC : : Engine : : tqStatus ) ) ,
this , TQT_SLOT ( slotStatusChanged ( KIRC : : Engine : : tqStatus ) ) ) ;
show ( ) ;
}
void ChannelList : : slotItemDoubleClicked ( TQListViewItem * i )
{
emit channelDoubleClicked ( i - > text ( 0 ) ) ;
}
void ChannelList : : slotItemSelected ( TQListViewItem * i )
{
emit channelSelected ( i - > text ( 0 ) ) ;
}
void ChannelList : : slotStatusChanged ( KIRC : : Engine : : tqStatus newtqStatus )
{
switch ( newtqStatus ) {
case KIRC : : Engine : : Connected :
this - > reset ( ) ;
break ;
case KIRC : : Engine : : Disconnected :
if ( mSearching ) {
KMessageBox : : queuedMessageBox (
this , KMessageBox : : Error ,
i18n ( " You have been disconnected from the IRC server. " ) ,
i18n ( " Disconnected " ) , 0
) ;
}
slotListEnd ( ) ;
break ;
default :
break ;
}
}
void ChannelList : : reset ( )
{
channelCache . clear ( ) ;
clear ( ) ;
}
void ChannelList : : clear ( )
{
mChannelList - > clear ( ) ;
channelSearch - > clear ( ) ;
channelSearch - > setFocus ( ) ;
}
void ChannelList : : search ( )
{
if ( m_engine - > isConnected ( ) | | ! channelCache . isEmpty ( ) )
{
mChannelList - > clear ( ) ;
mChannelList - > setSorting ( - 1 ) ;
mSearchButton - > setEnabled ( false ) ;
mSearch = channelSearch - > text ( ) ;
mSearching = true ;
mUsers = numUsers - > value ( ) ;
if ( channelCache . isEmpty ( ) )
m_engine - > list ( ) ;
else
{
cacheIterator = channelCache . begin ( ) ;
slotSearchCache ( ) ;
}
}
else
{
KMessageBox : : queuedMessageBox (
this , KMessageBox : : Error ,
i18n ( " You must be connected to the IRC server to perform a channel listing. " ) ,
i18n ( " Not Connected " ) , 0
) ;
}
}
void ChannelList : : slotChannelListed ( const TQString & channel , uint users , const TQString & topic )
{
checkSearchResult ( channel , users , topic ) ;
channelCache . insert ( channel , TQPair < uint , TQString > ( users , topic ) ) ;
}
void ChannelList : : checkSearchResult ( const TQString & channel , uint users , const TQString & topic )
{
if ( ( mUsers = = 0 | | mUsers < = users ) & &
( mSearch . isEmpty ( ) | | channel . contains ( mSearch , false ) | | topic . contains ( mSearch , false ) )
)
{
new ChannelListItem ( mChannelList , channel , TQString : : number ( users ) , topic ) ;
}
}
void ChannelList : : slotSearchCache ( )
{
if ( cacheIterator ! = channelCache . end ( ) )
{
checkSearchResult ( cacheIterator . key ( ) , cacheIterator . data ( ) . first , cacheIterator . data ( ) . second ) ;
+ + cacheIterator ;
TQTimer : : singleShot ( 0 , this , TQT_SLOT ( slotSearchCache ( ) ) ) ;
}
else
{
slotListEnd ( ) ;
}
}
void ChannelList : : slotListEnd ( )
{
mChannelList - > setSorting ( 0 , true ) ;
mSearchButton - > setEnabled ( true ) ;
mSearching = false ;
}
# include "channellist.moc"