You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1849 lines
54 KiB
1849 lines
54 KiB
/**********************************************************************
|
|
|
|
TopLevel IRC Channel/query Window
|
|
|
|
$$Id$$
|
|
|
|
This is the main window with which the user interacts. It handles
|
|
both normal channel conversations and private conversations.
|
|
|
|
2 classes are defined, the UserControlMenu and KSircToplevel. The
|
|
user control menu is used as a list of user defineable menus used by
|
|
KSircToplevel.
|
|
|
|
KSircTopLevel:
|
|
|
|
Signals:
|
|
|
|
outputLine(QString &):
|
|
output_toplevel(QString):
|
|
|
|
closing(KSircTopLevel *, QString channel):
|
|
|
|
changeChannel(QString old, QString new):
|
|
|
|
currentWindow(KSircTopLevel *):
|
|
|
|
Slots:
|
|
|
|
|
|
|
|
*********************************************************************/
|
|
|
|
#include "toplevel.h"
|
|
#include "alistbox.h"
|
|
#include "chanparser.h"
|
|
#include "ksopts.h"
|
|
#include "control_message.h"
|
|
#include "displayMgr.h"
|
|
#include "NewWindowDialog.h"
|
|
#include "usercontrolmenu.h"
|
|
#include "topic.h"
|
|
#include "charSelector.h"
|
|
#include "ksview.h"
|
|
#include "logfile.h"
|
|
#include "servercontroller.h"
|
|
#include "ioDCC.h"
|
|
|
|
#include "KSTicker/ksticker.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <qaccel.h>
|
|
#include <qclipboard.h>
|
|
#include <qregexp.h>
|
|
#include <qcursor.h>
|
|
#include <qtimer.h>
|
|
#include <qlayout.h>
|
|
#include <qtextcodec.h>
|
|
#include <qvbox.h>
|
|
#include <qlabel.h>
|
|
|
|
#include <kmenubar.h>
|
|
#include <kapplication.h>
|
|
#include <kdebug.h>
|
|
#include <kwin.h>
|
|
#include <knotifyclient.h>
|
|
#include <kpopupmenu.h>
|
|
#include <kmessagebox.h>
|
|
#include <klocale.h>
|
|
#include <kfiledialog.h>
|
|
#include <ktempfile.h>
|
|
#include <kio/netaccess.h>
|
|
#include <kstatusbar.h>
|
|
#include <kstdaction.h>
|
|
#include <kaction.h>
|
|
#include <kcharsets.h>
|
|
#include <kglobalsettings.h>
|
|
#include <kstdguiitem.h>
|
|
|
|
extern DisplayMgr *displayMgr;
|
|
//QPopupMenu *KSircTopLevel::user_controls = 0L;
|
|
QPtrList<UserControlMenu> *KSircTopLevel::user_menu = 0L;
|
|
QStringList KSircTopLevel::cmd_menu;
|
|
|
|
void
|
|
KSircTopLevel::initColors()
|
|
{
|
|
QColorGroup cg_mainw = kapp->palette().active();
|
|
cg_mainw.setColor(QColorGroup::Base, ksopts->backgroundColor);
|
|
cg_mainw.setColor(QColorGroup::Text, ksopts->textColor);
|
|
cg_mainw.setColor(QColorGroup::Link, ksopts->linkColor);
|
|
cg_mainw.setColor(QColorGroup::Highlight, ksopts->selBackgroundColor);
|
|
cg_mainw.setColor(QColorGroup::HighlightedText, ksopts->selForegroundColor);
|
|
mainw->setPalette(QPalette(cg_mainw,cg_mainw, cg_mainw));
|
|
nicks->setPalette(QPalette(cg_mainw,cg_mainw, cg_mainw));
|
|
linee->setPalette(QPalette(cg_mainw,cg_mainw, cg_mainw));
|
|
lag->setPalette(QPalette(cg_mainw,cg_mainw, cg_mainw));
|
|
cg_mainw.setColor(QColorGroup::Background, ksopts->backgroundColor);
|
|
cg_mainw.setColor(QColorGroup::Foreground, ksopts->textColor);
|
|
ksTopic->setPalette(QPalette(cg_mainw,cg_mainw, cg_mainw));
|
|
selector->setFont( ksopts->defaultFont.family() );
|
|
mainw->setFont( ksopts->defaultFont );
|
|
nicks->setFont( ksopts->defaultFont );
|
|
linee->setFont( ksopts->defaultFont );
|
|
ksTopic->setFont( ksopts->defaultFont );
|
|
|
|
}
|
|
|
|
KSircTopLevel::KSircTopLevel(KSircProcess *_proc, const KSircChannel &channelInfo, const char * name)
|
|
: KMainWindow(0, name, 0/*no WDestructiveClose !*/),
|
|
UnicodeMessageReceiver(_proc),
|
|
lastBeep( QTime::currentTime() ),
|
|
m_channelInfo(channelInfo)
|
|
|
|
{
|
|
// prevent us from being quitted when closing a channel-window. Only
|
|
// closing the servercontroller shall quit.
|
|
// KMainWindow will deref() us in closeEvent
|
|
kapp->ref();
|
|
|
|
|
|
m_topic = QString::null;
|
|
|
|
QCString kstl_name = QCString(QObject::name()) + "_" + "toplevel";
|
|
setName(kstl_name);
|
|
|
|
if(!m_channelInfo.channel().isEmpty()) {
|
|
setCaption(m_channelInfo.channel());
|
|
caption = m_channelInfo.channel();
|
|
}
|
|
else
|
|
{
|
|
caption = QString::null;
|
|
}
|
|
|
|
Buffer = FALSE;
|
|
|
|
have_focus = 0;
|
|
tab_pressed = -1; // Tab (nick completion not pressed yet)
|
|
tab_start = -1;
|
|
tab_end = -1;
|
|
|
|
m_gotMsgWithoutFocus = false;
|
|
|
|
KickWinOpen = false;
|
|
current_size = size();
|
|
|
|
ksopts->channelSetup(ksircProcess()->serverName(), m_channelInfo.channel());
|
|
m_channelInfo.setEncoding(ksopts->chan(m_channelInfo).encoding);
|
|
|
|
selector = new charSelector();
|
|
connect(selector, SIGNAL(clicked()), this, SLOT(insertText()));
|
|
selector->setFont(ksopts->defaultFont.family());
|
|
|
|
file = new QPopupMenu(this, QCString(QObject::name()) + "_popup_file");
|
|
file->setCheckable(true);
|
|
|
|
KAction *act = KStdAction::openNew( this, SLOT( newWindow() ), actionCollection() );
|
|
act->plug( file );
|
|
file->insertItem(i18n("New Ser&ver..."), servercontroller::self(), SLOT(new_connection()), Key_F2);
|
|
file->insertSeparator();
|
|
file->insertItem(i18n("&DCC Manager..."), this, SLOT(showDCCMgr()));
|
|
file->insertItem(i18n("&Save to Logfile..."), this, SLOT(saveCurrLog()), CTRL + Key_S);
|
|
|
|
tsitem = file->insertItem(i18n("Time St&"), this, SLOT(toggleTimestamp()), CTRL + Key_T);
|
|
file->setItemChecked(tsitem, ksopts->chan(m_channelInfo).timeStamp);
|
|
|
|
fjpitem = file->insertItem(i18n("Hide Join/Part Messages"), this, SLOT(toggleFilterJoinPart()));
|
|
file->setItemChecked(fjpitem, ksopts->chan(m_channelInfo).filterJoinPart);
|
|
|
|
file->insertItem(i18n("Character &Table"), selector, SLOT(show()), CTRL + Key_H);
|
|
beepitem = file->insertItem(i18n("N&otify on Change"), this, SLOT(toggleBeep()), CTRL + Key_P);
|
|
file->setItemChecked(beepitem, ksopts->chan(m_channelInfo).beepOnMsg);
|
|
|
|
encodingAction = new KSelectAction( i18n( "&Encoding" ), 0, this );
|
|
connect( encodingAction, SIGNAL( activated() ), this, SLOT( setEncoding() ) );
|
|
QStringList encodings = KGlobal::charsets()->descriptiveEncodingNames();
|
|
|
|
topicitem = file->insertItem(i18n("S&how Topic"), this, SLOT(toggleTopic()), CTRL + Key_O);
|
|
if (isPrivateChat() || m_channelInfo.channel().startsWith("!no_channel")) {
|
|
file->setItemEnabled(topicitem, false);
|
|
}
|
|
else {
|
|
file->setItemChecked(topicitem, ksopts->chan(m_channelInfo).topicShow);
|
|
}
|
|
|
|
tickeritem = file->insertItem(i18n("Ticker &Mode"), this, SLOT(toggleTicker()));
|
|
|
|
// remove utf16/ucs2 as it just doesn't work for IRC
|
|
QStringList::Iterator encodingIt = encodings.begin();
|
|
while ( encodingIt != encodings.end() ) {
|
|
if ( ( *encodingIt ).find( "utf16" ) != -1 ||
|
|
( *encodingIt ).find( "iso-10646" ) != -1 )
|
|
encodingIt = encodings.remove( encodingIt );
|
|
else
|
|
++encodingIt;
|
|
}
|
|
encodings.prepend( i18n( "Default" ) );
|
|
|
|
encodingAction->setItems( encodings );
|
|
encodingAction->plug( file );
|
|
|
|
int eindex = encodings.findIndex(ksopts->chan(m_channelInfo).encoding);
|
|
if(eindex == -1)
|
|
encodingAction->setCurrentItem( 0 );
|
|
else
|
|
encodingAction->setCurrentItem(eindex);
|
|
setEncoding();
|
|
|
|
file->insertSeparator();
|
|
act = KStdAction::close( this, SLOT( terminate() ), actionCollection() );
|
|
act->plug( file );
|
|
|
|
kmenu = menuBar();
|
|
kmenu->insertItem(i18n("&Channel"), file, KST_CHANNEL_ID, -1);
|
|
kmenu->setAccel(Key_F, KST_CHANNEL_ID);
|
|
|
|
/*
|
|
* Ok, let's look at the basic widget "layout"
|
|
* Everything belongs to q QFrame F, this is use so we
|
|
* can give the KApplication a single main client widget, which is needs.
|
|
*
|
|
* A QVbox and a QHbox is used to ctronl the 3 sub widget
|
|
* The Modified QListBox is then added side by side with the User list box.
|
|
* The SLE is then fit bello.
|
|
*/
|
|
|
|
// kstInside does not setup fonts, etc, it simply handles sizing
|
|
|
|
top = new QVBox( this );
|
|
|
|
ksTopic = new KSircTopic( top );
|
|
ksTopic->setFont(ksopts->defaultFont);
|
|
connect( ksTopic, SIGNAL( topicChange( const QString & ) ),
|
|
this, SLOT( setTopicIntern( const QString & ) ) );
|
|
|
|
QCString kstn = QCString(QObject::name()) + "_";
|
|
|
|
pan = new QSplitter(QSplitter::Horizontal, top, kstn + "splitter");
|
|
#if KDE_IS_VERSION(3,1,92)
|
|
pan->setOpaqueResize( KGlobalSettings::opaqueResize() );
|
|
#else
|
|
pan->setOpaqueResize( true );
|
|
#endif
|
|
|
|
mainw = new KSircView(ksircProcess(), pan, kstn + "KSircView" );
|
|
mainw->setFocusPolicy(QWidget::NoFocus);
|
|
|
|
nicks_box = new QVBox(pan);
|
|
|
|
channelButtons = new chanButtons(ksircProcess(), nicks_box);
|
|
connect(channelButtons, SIGNAL(mode(QString, int, QString)),
|
|
this, SLOT(setMode(QString, int, QString)));
|
|
|
|
nicks = new aListBox(nicks_box, kstn + "aListBox");
|
|
nicks->setFocusPolicy(QWidget::NoFocus);
|
|
//nicks->hide(); // default = only the main widget
|
|
|
|
lag = new QLabel(nicks_box);
|
|
lag->setFrameStyle(QFrame::Panel|QFrame::Sunken);
|
|
lag->setAlignment(Qt::AlignCenter | Qt::SingleLine);
|
|
lag->setText(i18n("Lag: Wait"));
|
|
|
|
|
|
QValueList<int> sizes;
|
|
sizes << int(width()*0.85) << int(width()*0.15);
|
|
pan->setSizes(sizes);
|
|
pan->setResizeMode( mainw, QSplitter::Stretch );
|
|
pan->setResizeMode( nicks_box, QSplitter::Stretch );
|
|
|
|
// f = new kstInside(top, QString(QObject::name()) + "_" + "kstIFrame");
|
|
top->setStretchFactor(pan, 1);
|
|
|
|
setCentralWidget(top); // Tell the KApplication what the main widget is.
|
|
|
|
logFile = 0;
|
|
if ( ksopts->chan(m_channelInfo).logging && (m_channelInfo.channel() != "!no_channel" ))
|
|
{
|
|
logFile = new LogFile( m_channelInfo.channel(), m_channelInfo.server() );
|
|
logFile->open();
|
|
}
|
|
|
|
// get basic variable
|
|
|
|
// mainw = f->mainw;
|
|
// nicks = f->nicks;
|
|
// pan = f->pan;
|
|
|
|
clearWindow();
|
|
|
|
if(isPrivateChat()){
|
|
KConfig conf("ksirc/winlog/" + channelInfo.server() + "-" + channelInfo.channel(),
|
|
false, false, "data");
|
|
QString group = "Message-History";
|
|
|
|
if(conf.hasGroup( group )){
|
|
conf.setGroup( group );
|
|
|
|
QStringList strlist = conf.readListEntry("History");
|
|
if(strlist.count() > 0){
|
|
mainw->enableTimeStamps(true);
|
|
for ( QStringList::Iterator it = strlist.begin();
|
|
it != strlist.end();
|
|
++it ) {
|
|
mainw->addRichText(*it);
|
|
}
|
|
}
|
|
strlist.clear();
|
|
}
|
|
}
|
|
|
|
mainw->enableTimeStamps(ksopts->chan(m_channelInfo).timeStamp);
|
|
|
|
edit = new QPopupMenu(this);
|
|
act = KStdAction::copy( mainw, SLOT( copy() ), actionCollection() );
|
|
act->plug( edit );
|
|
act = KStdAction::paste( this, SLOT( pasteToWindow() ), actionCollection() );
|
|
act->plug( edit );
|
|
edit->insertItem(i18n("C&lear Window"), this, SLOT(clearWindow()), CTRL + Key_L);
|
|
kmenu->insertItem(i18n("&Edit"), edit, -1, -1);
|
|
|
|
linee = new aHistLineEdit(top, "");
|
|
|
|
initColors();
|
|
|
|
// ksb_main->addWidget(linee, mainw->width());
|
|
// ksb_main->insertItem(, KSB_MAIN_LAG, true);
|
|
|
|
// don't show the nick lists in a private chat or the default window
|
|
if (isPrivateChat() || m_channelInfo.channel().startsWith("!no_channel"))
|
|
{
|
|
nicks_box->hide();
|
|
ksTopic->hide();
|
|
// nicks->hide();
|
|
// lag->hide();
|
|
// channelButtons->hide();
|
|
}
|
|
else
|
|
{
|
|
nicks_box->show();
|
|
|
|
if(file->isItemChecked(topicitem)){
|
|
ksTopic->show();
|
|
// channelButtons->show();
|
|
}
|
|
else{
|
|
ksTopic->hide();
|
|
// channelButtons->hide();
|
|
}
|
|
// channelButtons->show();
|
|
// lag->show();
|
|
// nicks->show();
|
|
}
|
|
|
|
|
|
connect(mainw, SIGNAL(pasteReq( const QString& )),
|
|
this, SLOT( slotTextDropped( const QString& )));
|
|
|
|
nicks->setFont(ksopts->defaultFont);
|
|
|
|
// setup line editor
|
|
|
|
linee->setFocusPolicy(QWidget::StrongFocus);
|
|
linee->setFont(ksopts->defaultFont);
|
|
|
|
if(ksopts->oneLineEntry == true) {
|
|
linee->setWordWrap(QTextEdit::NoWrap);
|
|
}
|
|
else {
|
|
linee->setWordWrap(QTextEdit::WidgetWidth);
|
|
}
|
|
|
|
connect(linee, SIGNAL(gotFocus()),
|
|
this, SLOT(gotFocus()));
|
|
connect(linee, SIGNAL(lostFocus()),
|
|
this, SLOT(lostFocus()));
|
|
connect(linee, SIGNAL(pasteText(const QString&)),
|
|
this, SLOT(slotTextDropped(const QString&)));
|
|
connect(linee, SIGNAL(notTab()),
|
|
this, SLOT(lineeNotTab()));
|
|
|
|
connect( linee, SIGNAL( gotReturnPressed() ),
|
|
this, SLOT( returnPressed() ) );
|
|
|
|
linee->setFocus(); // Give SLE focus
|
|
linee->slotMaybeResize();
|
|
|
|
lines = 0; // Set internal line counter to 0
|
|
|
|
ticker = 0x0;
|
|
|
|
/*
|
|
* Set generic run time variables
|
|
*
|
|
*/
|
|
|
|
opami = FALSE;
|
|
continued_line = FALSE;
|
|
// on_root = FALSE;
|
|
|
|
/*
|
|
* Load basic pics and images
|
|
* This should use on of the KDE finder commands
|
|
*/
|
|
|
|
KWin::setIcons(winId(), kapp->icon(), kapp->miniIcon());
|
|
|
|
/*
|
|
* Create our basic parser object
|
|
*/
|
|
|
|
ChanParser = new ChannelParser(this);
|
|
|
|
|
|
/*
|
|
* Create the user Controls popup menu, and connect it with the
|
|
* nicks list on the lefthand side (highlighted()).
|
|
*
|
|
*/
|
|
|
|
if(user_menu == 0)
|
|
user_menu = UserControlMenu::parseKConfig();
|
|
|
|
user_controls = new QPopupMenu(this);
|
|
kmenu->insertItem(i18n("&Users"), user_controls);
|
|
|
|
command = new QPopupMenu(this);
|
|
|
|
setupCommandMenu();
|
|
|
|
int i = 0;
|
|
QDict<QPopupMenu> cml;
|
|
for(QStringList::Iterator it = cmd_menu.begin();
|
|
it != cmd_menu.end();
|
|
++it){
|
|
QString top, item;
|
|
top = (*it).section('/', 0, 0);
|
|
item = (*it).section('/', 1, 1);
|
|
if(!cml[top]) {
|
|
cml.insert(top, new QPopupMenu(this));
|
|
command->insertItem(top, cml[top]);
|
|
}
|
|
cml[top]->insertItem(item, this, SLOT(cmd_process(int)), 0, i);
|
|
|
|
i++;
|
|
}
|
|
|
|
kmenu->insertItem(i18n("C&ommand"), command);
|
|
|
|
kmenu->insertItem( KStdGuiItem::help().text(), helpMenu( QString::null, false ));
|
|
|
|
connect(user_controls, SIGNAL(activated(int)),
|
|
this, SLOT(UserParseMenu(int)));
|
|
|
|
connect(nicks, SIGNAL(contextMenuRequested(int)), this,
|
|
SLOT(UserSelected(int)));
|
|
connect(nicks, SIGNAL(selectedNick(const QString &)),
|
|
this, SLOT(openQueryFromNick(const QString &)));
|
|
connect(nicks, SIGNAL(mouseButtonClicked ( int, QListBoxItem *, const QPoint &)),
|
|
this, SLOT(pasteToNickList(int, QListBoxItem *, const QPoint &)));
|
|
connect(nicks, SIGNAL(textDropped( const QListBoxItem *, const QString& )),
|
|
this, SLOT(dndTextToNickList(const QListBoxItem *, const QString&)));
|
|
|
|
UserUpdateMenu(); // Must call to update Popup.
|
|
|
|
accel = new QAccel(this, "accel");
|
|
|
|
accel->connectItem(accel->insertItem(SHIFT + Key_PageUp),
|
|
this,
|
|
SLOT(AccelScrollUpPage()));
|
|
accel->connectItem(accel->insertItem(SHIFT + Key_PageDown),
|
|
this,
|
|
SLOT(AccelScrollDownPage()));
|
|
|
|
/*
|
|
* Pageup/dn
|
|
* Added for stupid wheel mice
|
|
*/
|
|
|
|
accel->connectItem(accel->insertItem(Key_PageUp),
|
|
this,
|
|
SLOT(AccelScrollUpPage()));
|
|
accel->connectItem(accel->insertItem(Key_PageDown),
|
|
this,
|
|
SLOT(AccelScrollDownPage()));
|
|
|
|
/*
|
|
* These are not presently implemented, so let's not fill the logs.
|
|
accel->connectItem(accel->insertItem(CTRL + Key_Return),
|
|
this,
|
|
SLOT(AccelPriorMsgNick()));
|
|
|
|
accel->connectItem(accel->insertItem(CTRL + SHIFT + Key_Return),
|
|
this,
|
|
SLOT(AccelNextMsgNick()));
|
|
*/
|
|
|
|
accel->connectItem(accel->insertItem(Key_Tab), // adds TAB accelerator
|
|
this, // connected to the main
|
|
SLOT(TabNickCompletionNormal())); // TabNickCompletion() slot
|
|
accel->connectItem(accel->insertItem(SHIFT+Key_Tab), // adds TAB accelerator
|
|
this, // connected to the main
|
|
SLOT(TabNickCompletionShift())); // TabNickCompletion() slot
|
|
accel->connectItem(accel->insertItem(CTRL + Key_N),
|
|
this, SLOT(newWindow()));
|
|
// accel->connectItem(accel->insertItem(CTRL + Key_S),
|
|
// this, SLOT(toggleTimestamp()));
|
|
|
|
// Drag & Drop
|
|
connect( mainw, SIGNAL( textDropped(const QString&) ),
|
|
SLOT( slotTextDropped(const QString&) ));
|
|
connect( mainw, SIGNAL( urlsDropped(const QStringList&) ),
|
|
SLOT( slotDropURLs(const QStringList&) ));
|
|
connect( nicks, SIGNAL( urlsDropped( const QStringList&, const QString& )),
|
|
SLOT( slotDccURLs( const QStringList&, const QString& )));
|
|
connect( this, SIGNAL( changed(bool, QString) ), this, SLOT( doChange(bool, QString) ));
|
|
|
|
mainw->setAcceptFiles( isPrivateChat() );
|
|
resize(600, 360);
|
|
|
|
}
|
|
|
|
KSircTopLevel::~KSircTopLevel()
|
|
{
|
|
// Cleanup and shutdown
|
|
// if(this == ksircProcess()->getWindowList()["default"])
|
|
// write(sirc_stdin, "/quit\n", 7); // tell dsirc to close
|
|
//
|
|
// if(ksircProcess()->getWindowList()[m_channelInfo.channel()])
|
|
// ksircProcess()->getWindowList().remove(m_channelInfo.channel());
|
|
|
|
// if((m_channelInfo.channel()[0] == '#') || (m_channelInfo.channel()[0] == '&')){
|
|
// QString str = QString("/part ") + m_channelInfo.channel() + "\n";
|
|
// emit outputLine(str);
|
|
// }
|
|
|
|
kdDebug(5008) << "~KSircTopLevel in" << endl;
|
|
if ( ksopts->autoSaveHistory )
|
|
{
|
|
if ( isPublicChat() ) {
|
|
kdDebug(5008) << "*** parting channel: " << m_channelInfo.channel() << endl;
|
|
QString str = QString("/part ") + m_channelInfo.channel() + "\n";
|
|
emit outputUnicodeLine(str);
|
|
}
|
|
else {
|
|
QStringList strlist;
|
|
|
|
mainw->addLine("user|X", ksopts->channelColor, " Saved log of previous messages");
|
|
|
|
mainw->enableTimeStamps(true);
|
|
|
|
for(KSirc::TextParagIterator ksit = mainw->firstParag();
|
|
ksit.atEnd() == 0;
|
|
++ksit) {
|
|
QString rt = ksit.richText();
|
|
if(rt.contains("<img src=\"user|servinfo\">"))
|
|
continue;
|
|
|
|
kdDebug(5008) << rt << endl;
|
|
|
|
strlist += rt;
|
|
|
|
}
|
|
|
|
KConfig conf("ksirc/winlog/" + channelInfo().server() +
|
|
"-" + channelInfo().channel(),
|
|
false, false, "data");
|
|
QString group = "Message-History";
|
|
|
|
conf.setGroup( group );
|
|
|
|
conf.writeEntry("History", strlist);
|
|
conf.sync();
|
|
|
|
}
|
|
}
|
|
delete ticker;
|
|
delete user_controls;
|
|
delete ChanParser;
|
|
delete selector;
|
|
delete channelButtons;
|
|
delete logFile;
|
|
kdDebug(5008) << "~KSircToplevel out" << endl;
|
|
}
|
|
|
|
void KSircTopLevel::setMode(QString mode, int mode_type, QString currentNick)
|
|
{
|
|
QString command;
|
|
if (mode_type == 0)
|
|
command = QString::fromLatin1("/mode %1 %2\n").arg(m_channelInfo.channel()).arg(mode);
|
|
else
|
|
command = QString::fromLatin1("/mode %1 %2\n").arg(currentNick).arg(mode);
|
|
sirc_write(command);
|
|
linee->setFocus();
|
|
}
|
|
|
|
void KSircTopLevel::setEncoding()
|
|
{
|
|
int index = encodingAction->currentItem();
|
|
if ( index == 0 ) {// default (locale) encoding
|
|
ksopts->chan(m_channelInfo).encoding = QString::null;
|
|
UnicodeMessageReceiver::setEncoding( QString::null );
|
|
}
|
|
else {
|
|
ksopts->chan(m_channelInfo).encoding = encodingAction->currentText();
|
|
UnicodeMessageReceiver::setEncoding( KGlobal::charsets()->encodingForName( encodingAction->currentText() ) );
|
|
}
|
|
ksopts->save(KSOptions::Channels);
|
|
}
|
|
|
|
void KSircTopLevel::setupCommandMenu()
|
|
{
|
|
if(cmd_menu.empty() == true){
|
|
cmd_menu.append(i18n("Help") + "/" + "help");
|
|
cmd_menu.append(i18n("Client") + "/" + "alias");
|
|
cmd_menu.append(i18n("User") + "/" + "away");
|
|
cmd_menu.append(i18n("Client") + "/" + "bye");
|
|
cmd_menu.append(i18n("Client") + "/" + "cd");
|
|
cmd_menu.append(i18n("Basic") + "/" + "ctcp");
|
|
cmd_menu.append(i18n("Basic") + "/" + "dcc");
|
|
cmd_menu.append(i18n("Operator") + "/" + "deop");
|
|
cmd_menu.append(i18n("User") + "/" + "describe");
|
|
cmd_menu.append(i18n("Client") + "/" + "eval");
|
|
cmd_menu.append(i18n("Client") + "/" + "exit");
|
|
cmd_menu.append(i18n("Client") + "/" + "hop");
|
|
cmd_menu.append(i18n("Basic") + "/" + "ignore");
|
|
cmd_menu.append(i18n("Server") + "/" + "info");
|
|
cmd_menu.append(i18n("Channel") + "/" + "invite" + "/" + "*chan*");
|
|
cmd_menu.append(i18n("Basic") + "/" + "join");
|
|
cmd_menu.append(i18n("Operator") + "/" + "kick");
|
|
cmd_menu.append(i18n("Oper") + "/" + "kill");
|
|
cmd_menu.append(i18n("Basic") + "/" + "leave");
|
|
cmd_menu.append(i18n("Server") + "/" + "links");
|
|
cmd_menu.append(i18n("Basic") + "/" + "list");
|
|
cmd_menu.append(i18n("Basic") + "/" + "ll");
|
|
cmd_menu.append(i18n("Client") + "/" + "load");
|
|
cmd_menu.append(i18n("Server") + "/" + "lusers");
|
|
cmd_menu.append(i18n("Server") + "/" + "map");
|
|
cmd_menu.append(i18n("Basic") + "/" + "me");
|
|
cmd_menu.append(i18n("Channel") + "/" + "mode" + "/" + "*chan*");
|
|
cmd_menu.append(i18n("Server") + "/" + "motd");
|
|
cmd_menu.append(i18n("Basic") + "/" + "msg");
|
|
cmd_menu.append(i18n("Basic") + "/" + "nick");
|
|
cmd_menu.append(i18n("Basic") + "/" + "notice");
|
|
cmd_menu.append(i18n("Basic") + "/" + "notify");
|
|
cmd_menu.append(i18n("Operator") + "/" + "op");
|
|
cmd_menu.append(i18n("Oper") + "/" + "oper");
|
|
cmd_menu.append(i18n("Basic") + "/" + "query");
|
|
cmd_menu.append(i18n("Channel") + "/" + "part"+ "/" + "*chan*");
|
|
cmd_menu.append(i18n("Basic") + "/" + "ping");
|
|
cmd_menu.append(i18n("Client") + "/" + "quit");
|
|
cmd_menu.append(i18n("Server") + "/" + "quote");
|
|
cmd_menu.append(i18n("Oper") + "/" + "rping");
|
|
cmd_menu.append(i18n("Oper") + "/" + "rehash");
|
|
cmd_menu.append(i18n("Basic") + "/" + "say");
|
|
cmd_menu.append(i18n("Server") + "/" + "stats");
|
|
cmd_menu.append(i18n("Client") + "/" + "system");
|
|
cmd_menu.append(i18n("Server") + "/" + "time");
|
|
cmd_menu.append(i18n("Channel") + "/" + "topic" + "/" + "*chan*");
|
|
cmd_menu.append(i18n("Client") + "/" + "version");
|
|
cmd_menu.append(i18n("Oper") + "/" + "wallops");
|
|
cmd_menu.append(i18n("Channel") + "/" + "who" + "/" + "*chan*");
|
|
cmd_menu.append(i18n("Basic") + "/" + "whois");
|
|
cmd_menu.append(i18n("Basic") + "/" + "whowas");
|
|
cmd_menu.append(i18n("Basic") + "/" + "wi");
|
|
cmd_menu.append(i18n("Help") + "/" + "newuser");
|
|
cmd_menu.append(i18n("Channel") + "/" + "ban");
|
|
cmd_menu.append(i18n("Channel") + "/" + "unban");
|
|
cmd_menu.append(i18n("Channel") + "/" + "clrban" + "/" + "*chan*");
|
|
cmd_menu.append(i18n("Channel") + "/" + "banlist" + "/" + "*chan*");
|
|
cmd_menu.append(i18n("Basic") + "/" + "pig");
|
|
cmd_menu.append(i18n("Channel") + "/" + "wallop");
|
|
cmd_menu.append(i18n("Client") + "/" + "exec");
|
|
cmd_menu.append(i18n("Basic") + "/" + "url");
|
|
cmd_menu.sort();
|
|
}
|
|
}
|
|
|
|
void KSircTopLevel::insertText()
|
|
{
|
|
linee->insert(selector->currentText());
|
|
}
|
|
|
|
void KSircTopLevel::show()
|
|
{
|
|
KMainWindow::show();
|
|
linee->setFocus();
|
|
mainw->scrollToBottom(true);
|
|
}
|
|
|
|
enum {
|
|
KSTUp = 1,
|
|
KSTDown = 2
|
|
};
|
|
|
|
void KSircTopLevel::TabNickCompletionShift()
|
|
{
|
|
TabNickCompletion(KSTDown);
|
|
}
|
|
|
|
void KSircTopLevel::TabNickCompletionNormal()
|
|
{
|
|
TabNickCompletion(KSTUp);
|
|
}
|
|
|
|
void KSircTopLevel::TabNickCompletion(int dir)
|
|
{
|
|
/*
|
|
* Gets current text from lined find the last item and try and perform
|
|
* a nick completion, then return and reset the line.
|
|
*/
|
|
|
|
int start, end;
|
|
int extra = 0;
|
|
bool first = false;
|
|
QString s;
|
|
|
|
if(tab_pressed == -1){
|
|
s = linee->text();
|
|
tab_saved = s;
|
|
end = linee->cursorPosition() - 1;
|
|
start = s.findRev(" ", end, FALSE);
|
|
tab_start = start;
|
|
tab_end = end;
|
|
first = true;
|
|
}
|
|
else{
|
|
s = tab_saved;
|
|
start = tab_start;
|
|
end = tab_end;
|
|
}
|
|
|
|
if(dir == KSTDown){
|
|
if(tab_pressed > 0)
|
|
tab_pressed -= 1;
|
|
}
|
|
else {
|
|
tab_pressed += 1;
|
|
}
|
|
|
|
|
|
if(s.length() == 0){
|
|
if(tab_nick.isEmpty()) {
|
|
KNotifyClient::beep();
|
|
lineeNotTab();
|
|
return;
|
|
}
|
|
QString line = tab_nick + ": "; // tab_nick holds the last night since we haven't overritten it yet.
|
|
linee->setText(line);
|
|
linee->setCursorPosition(line.length());
|
|
connect(linee, SIGNAL(notTab()),
|
|
this, SLOT(lineeNotTab()));
|
|
return;
|
|
}
|
|
|
|
if (start == -1) {
|
|
tab_nick = findNick(s.mid(0, end+1), tab_pressed);
|
|
|
|
if(first && (tab_nick.isNull() == TRUE)){
|
|
KNotifyClient::beep();
|
|
lineeNotTab();
|
|
return;
|
|
}
|
|
else if(tab_nick.isNull() == TRUE){
|
|
tab_pressed -= 1;
|
|
tab_nick = findNick(s.mid(0, end+1), tab_pressed);
|
|
}
|
|
s.replace(0, end + 1, "");
|
|
if(s[0] == ':')
|
|
s.replace(0, 2, "");
|
|
s.prepend(tab_nick + ": ");
|
|
extra = 2;
|
|
}
|
|
else {
|
|
tab_nick = findNick(s.mid(start + 1, end - start), tab_pressed);
|
|
if(first && (tab_nick.isNull() == TRUE)){
|
|
KNotifyClient::beep();
|
|
lineeNotTab();
|
|
return;
|
|
}
|
|
else if(tab_nick.isNull() == TRUE){
|
|
tab_pressed -= 1;
|
|
tab_nick = findNick(s.mid(start + 1, end - start), tab_pressed);
|
|
}
|
|
|
|
if((uint) end == s.length() - 1){ /* if we're at the end add a space */
|
|
s.replace(start + 1, end - start, tab_nick + " ");
|
|
extra = 1;
|
|
}
|
|
else {
|
|
s.replace(start + 1, end - start, tab_nick);
|
|
extra = 0;
|
|
}
|
|
}
|
|
|
|
int tab = tab_pressed;
|
|
|
|
linee->setText(s);
|
|
linee->setCursorPosition(start + tab_nick.length() + 1 + extra);
|
|
|
|
tab_pressed = tab; // setText causes lineeTextChanged to get called and erase tab_pressed
|
|
|
|
connect(linee, SIGNAL(notTab()),
|
|
this, SLOT(lineeNotTab()));
|
|
|
|
}
|
|
|
|
void KSircTopLevel::sirc_receive(QString str, bool broadcast)
|
|
{
|
|
|
|
/*
|
|
* read and parse output from dsirc.
|
|
* call reader, split the read input into lines, parse the lines
|
|
* then print line by line into the main text area.
|
|
*
|
|
* PROBLEMS: if a line terminates in mid line, it will get borken oddly
|
|
*
|
|
*/
|
|
|
|
if(!Buffer){
|
|
if( !str.isEmpty() ){
|
|
LineBuffer.append( BufferedLine( str, broadcast ) );
|
|
}
|
|
|
|
bool addressed = false;
|
|
BufferedLine line;
|
|
|
|
// be careful not to use a QValueList iterator here, as it is possible
|
|
// that we enter a local event loop (think of the ssfeprompt dialog!)
|
|
// which might trigger a socketnotifier activation which in turn
|
|
// might result in the execution of code that modifies the LineBuffer,
|
|
// which would invalidate iterators (Simon)
|
|
while ( LineBuffer.begin() != LineBuffer.end() )
|
|
{
|
|
QString plainText("");
|
|
line = *LineBuffer.begin();
|
|
LineBuffer.remove( LineBuffer.begin() );
|
|
|
|
// Get the need list box item, with colour, etc all set
|
|
if (parse_input(line.message, plainText))
|
|
{
|
|
// If we should add anything, add it.
|
|
// Don't announce server messages as they are
|
|
// spread through all channels anyway
|
|
|
|
bool addressedLine = false;
|
|
|
|
if(line.message.contains( ">~o")){ /* highlighted with our nick */
|
|
addressedLine = true;
|
|
}
|
|
|
|
// detect /msg's -- needed when auto-create-window is off
|
|
if ( line.message.find( QRegExp( "^\\[~b.+~b\\].+$" ) ) == 0 )
|
|
addressedLine = true;
|
|
|
|
if ( addressedLine == true && line.message.startsWith("* " + ksircProcess()->getNick()))
|
|
addressedLine = false;
|
|
|
|
if ( addressedLine )
|
|
addressed = true;
|
|
|
|
if ( !line.wasBroadcast ) {
|
|
// This line is addressed to me if it contains my nick, or is in a private chat
|
|
emit changed( addressedLine || isPrivateChat(), plainText );
|
|
}
|
|
}
|
|
}
|
|
LineBuffer.clear(); // Clear it since it's been added
|
|
}
|
|
else{
|
|
LineBuffer.append( BufferedLine( str, broadcast ) );
|
|
}
|
|
|
|
QValueList<int> list;
|
|
QValueList<int>::iterator it;
|
|
QString values;
|
|
list = pan->sizes();
|
|
it = list.begin();
|
|
while( it != list.end()){
|
|
values += QString("%1 ").arg(*it);
|
|
++it;
|
|
}
|
|
}
|
|
void KSircTopLevel::sirc_line_return(const QString &text)
|
|
{
|
|
|
|
/* Take line from SLE, and output if to dsirc */
|
|
|
|
QString s = text;
|
|
|
|
if(s.length() == 0)
|
|
return;
|
|
|
|
tab_pressed = -1; // new line, zero the counter.
|
|
s += '\n'; // Append a need carriage return :)
|
|
|
|
sirc_write(s);
|
|
|
|
linee->setText("");
|
|
linee->slotMaybeResize();
|
|
|
|
}
|
|
|
|
void KSircTopLevel::sirc_write(const QString &str)
|
|
{
|
|
/*
|
|
* Parse line forcommand we handle
|
|
*/
|
|
QString command = str, plain = str.lower().simplifyWhiteSpace();
|
|
if(plain.startsWith("/join ") ||
|
|
plain.startsWith("/j ") ||
|
|
plain.startsWith("/query ")) {
|
|
|
|
QString s = plain.mid(plain.find(' ')+1);
|
|
|
|
QStringList channels = QStringList::split(",", s);
|
|
QStringList::ConstIterator it = channels.begin();
|
|
|
|
for( ; it != channels.end(); ++it){
|
|
QString name = *it;
|
|
//kdDebug(5008) << "Doing " << name << endl;
|
|
QRegExp rx("(\\S+)\\s*(\\S*)");
|
|
rx.search(name);
|
|
KSircChannel ci(m_channelInfo.server(),
|
|
rx.cap(1), // channel
|
|
rx.cap(2)); // optional key
|
|
linee->setText(QString::null);
|
|
emit open_toplevel(ci);
|
|
/* if(name[0] != '#'){
|
|
emit open_toplevel(name);
|
|
linee->setText(QString::null);
|
|
}
|
|
else {
|
|
emit outputUnicodeLine(plain + "\n");
|
|
emit open_toplevel(encoder()->fromUnicode(name));
|
|
}
|
|
*/
|
|
}
|
|
// Finish sending /join
|
|
return;
|
|
}
|
|
else if(plain.startsWith("/server ")) {
|
|
plain.simplifyWhiteSpace();
|
|
QRegExp rx("/server (\\S+) *(\\S*) *(\\S*)");
|
|
if(rx.search(str) >= 0){
|
|
QString server = rx.cap(1);
|
|
QString port = rx.cap(2);
|
|
QString pass = rx.cap(3);
|
|
|
|
bool ssl = false;
|
|
if(server.startsWith("+")){
|
|
server.replace(0, 1, "");
|
|
ssl = true;
|
|
}
|
|
|
|
KSircServer serv(server, port, QString::null, pass, ssl);
|
|
servercontroller::self()->new_ksircprocess(serv);
|
|
|
|
return;
|
|
}
|
|
}
|
|
else if(plain.startsWith("/part") ||
|
|
plain.startsWith("/leave") ||
|
|
plain.startsWith("/hop")) {
|
|
QApplication::postEvent(this, new QCloseEvent()); // WE'RE DEAD
|
|
linee->setText(QString::null);
|
|
return;
|
|
}
|
|
else if( plain.startsWith( "/bye" ) ||
|
|
plain.startsWith( "/exit" ) ||
|
|
plain.startsWith( "/quit" )) {
|
|
linee->setText( QString::null );
|
|
emit requestQuit( command.ascii() );
|
|
return;
|
|
}
|
|
else if ( plain.startsWith( "/away" ) ) {
|
|
QString awayEvalCommand = QString::fromLatin1( "/eval $publicAway = %1\n" ).arg( ksopts->publicAway ? '1' : '0' );
|
|
emit outputUnicodeLine( awayEvalCommand );
|
|
}
|
|
|
|
//
|
|
// Look at the command, if we're assigned a channel name, default
|
|
// messages, etc to the right place. This include /me, etc
|
|
//
|
|
|
|
if(!isSpecialWindow()) { // channel or private chat
|
|
if(plain[0].latin1() != '/'){
|
|
command.prepend(QString::fromLatin1("/msg %1 ").arg(m_channelInfo.channel()));
|
|
}
|
|
else if(plain.startsWith("/me ")) {
|
|
command.remove(0, 3);
|
|
command.prepend(QString("/de ") + m_channelInfo.channel());
|
|
}
|
|
}
|
|
|
|
// Write out line
|
|
|
|
emit outputUnicodeLine(command);
|
|
/*
|
|
* as opposed to what some might think
|
|
* it doesn't matter when you call stb
|
|
*/
|
|
mainw->scrollToBottom(true);
|
|
}
|
|
|
|
bool KSircTopLevel::parse_input(const QString &string, QString &plainText)
|
|
{
|
|
/*
|
|
* Parsing routines are broken into 3 majour sections
|
|
*
|
|
* 1. Search and replace evil characters. The string is searched for
|
|
* each character in turn (evil[i]), and the character string in
|
|
* evil_rep[i] is replaced.
|
|
*
|
|
* 2. Parse control messages, add pixmaps, and colourize required
|
|
* lines. Caption is also set as required.
|
|
*
|
|
* 3. Create and return the ircListItem.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* No-output get's set to 1 if we should ignore the line
|
|
*/
|
|
|
|
/*
|
|
* This is the second generation parsing code.
|
|
* Each line type is determined by the first 3 characters on it.
|
|
* Each line type is then sent to a parsing function.
|
|
*/
|
|
parseResult *pResult = ChanParser->parse(string);
|
|
|
|
parseSucc *item = dynamic_cast<parseSucc *>(pResult);
|
|
parseError *err = dynamic_cast<parseError *>(pResult);
|
|
|
|
QString logString;
|
|
|
|
if(item)
|
|
{
|
|
parseJoinPart *jp = dynamic_cast<parseJoinPart *>(pResult);
|
|
if(jp &&
|
|
ksopts->chan(m_channelInfo).filterJoinPart){
|
|
delete pResult;
|
|
return true;
|
|
}
|
|
else if (!item->string.isEmpty()) {
|
|
logString = mainw->
|
|
addLine( item->pm, item->colour, item->string );
|
|
if(ticker != NULL){
|
|
ticker->mergeString(item->string, item->colour);
|
|
}
|
|
} else {
|
|
delete pResult;
|
|
return false;
|
|
}
|
|
}
|
|
else if (err)
|
|
{
|
|
if(err->err.isEmpty() == FALSE)
|
|
{
|
|
kdWarning() << err->err << ": " << string << endl;
|
|
delete pResult;
|
|
return false;
|
|
}
|
|
if (!err->str.isEmpty()) {
|
|
logString = mainw->addLine( "user|error", ksopts->errorColor, err->str );
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
logString = mainw->addLine( QString::null, ksopts->textColor, string );
|
|
if(ticker != NULL){
|
|
ticker->mergeString(string);
|
|
}
|
|
// If it contains our nick, move the speaker to the top
|
|
// of the nick completion list
|
|
if(string.contains("~o")){
|
|
QRegExp rx("<(\\S+)>");
|
|
if ( (rx.search(logString) >= 0) &&
|
|
(rx.cap(1) != ksircProcess()->getNick()) ) {
|
|
//kdDebug(5008) << "addCompleteNick: " << rx.cap(1) << endl;
|
|
addCompleteNick( rx.cap(1) );
|
|
}
|
|
}
|
|
|
|
}
|
|
delete pResult;
|
|
|
|
if ( !logString.isEmpty() && logFile )
|
|
logFile->log( logString );
|
|
|
|
if(!plainText.isNull())
|
|
plainText = logString;
|
|
|
|
return true;
|
|
}
|
|
|
|
void KSircTopLevel::returnPressed()
|
|
{
|
|
|
|
QString s = linee->text();
|
|
|
|
uint i;
|
|
QChar c;
|
|
for(i = 0; (c = s[i]); i++){
|
|
switch(c.unicode()){
|
|
case 0336:
|
|
s[i] = 002;
|
|
break;
|
|
case 0327:
|
|
s[i] = 037;
|
|
break;
|
|
case 0237:
|
|
s[i] = 026;
|
|
break;
|
|
case 0252:
|
|
s[i] = 003;
|
|
break;
|
|
}
|
|
}
|
|
|
|
while(s.length() > IRC_SAFE_MAX_LINE){
|
|
int wrap = s.findRev(' ', IRC_SAFE_MAX_LINE);
|
|
if(wrap == -1)
|
|
wrap = IRC_SAFE_MAX_LINE;
|
|
sirc_line_return(s.left(wrap));
|
|
s = s.mid(wrap + 1);
|
|
}
|
|
if(!s.stripWhiteSpace().isEmpty())
|
|
sirc_line_return(s);
|
|
else {
|
|
linee->setText("");
|
|
linee->slotMaybeResize();
|
|
}
|
|
}
|
|
|
|
void KSircTopLevel::UserSelected(int index)
|
|
{
|
|
if(index >= 0)
|
|
user_controls->popup(this->cursor().pos());
|
|
}
|
|
|
|
void KSircTopLevel::UserParseMenu(int id)
|
|
{
|
|
if(nicks->currentItem() < 0)
|
|
return;
|
|
|
|
QString s;
|
|
s = QString("/eval $dest_nick='%1';\n").arg(nicks->text(nicks->currentItem()));
|
|
sirc_write(s);
|
|
// set $$dest_chan variable
|
|
s = QString("/eval $dest_chan='%1';\n").arg(m_channelInfo.channel());
|
|
sirc_write(s);
|
|
QString action = user_menu->at(id)->action;
|
|
if (action.length() && action[0] == '/')
|
|
action.remove(0, 1);
|
|
s = QString("/eval &docommand(eval{\"%1\"});\n").arg(action);
|
|
s.replace(QRegExp("\\$\\$"), "$");
|
|
sirc_write(s);
|
|
}
|
|
|
|
void KSircTopLevel::UserUpdateMenu()
|
|
{
|
|
int i = 0;
|
|
UserControlMenu *ucm;
|
|
|
|
user_controls->clear();
|
|
for(ucm = user_menu->first(); ucm != 0; ucm = user_menu->next(), i++){
|
|
if(ucm->type == UserControlMenu::Seperator){
|
|
user_controls->insertSeparator();
|
|
}
|
|
else{
|
|
user_controls->insertItem(ucm->title, i);
|
|
if(ucm->accel)
|
|
user_controls->setAccel(i, ucm->accel);
|
|
if((ucm->op_only == TRUE) && (opami == FALSE))
|
|
user_controls->setItemEnabled(i, FALSE);
|
|
}
|
|
}
|
|
}
|
|
|
|
void KSircTopLevel::AccelScrollDownPage()
|
|
{
|
|
mainw->verticalScrollBar()->addPage();
|
|
}
|
|
|
|
void KSircTopLevel::AccelScrollUpPage()
|
|
{
|
|
mainw->verticalScrollBar()->subtractPage();
|
|
}
|
|
|
|
void KSircTopLevel::newWindow()
|
|
{
|
|
NewWindowDialog w(KSircChannel(m_channelInfo.server(), QString::null));
|
|
connect(&w, SIGNAL(openTopLevel(const KSircChannel &)), SIGNAL(open_toplevel(const KSircChannel &)));
|
|
w.exec();
|
|
}
|
|
|
|
void KSircTopLevel::closeEvent(QCloseEvent *e)
|
|
{
|
|
KMainWindow::closeEvent( e );
|
|
e->accept();
|
|
|
|
//Let's not part the channel till we are acutally delete.
|
|
// We should always get a close event, *BUT* we will always be deleted.
|
|
// if( isPublicChat() ) {
|
|
// QString str = QString("/part ") + m_channelInfo.channel() + "\n";
|
|
// emit outputLine(str);
|
|
// }
|
|
|
|
// Hide ourselves until we finally die
|
|
hide();
|
|
qApp->flushX();
|
|
// Let's say we're closing
|
|
kdDebug(5008) << "Toplevel closing: " << m_channelInfo.channel() << endl;
|
|
emit closing(this, m_channelInfo.channel());
|
|
}
|
|
|
|
void KSircTopLevel::focusChange(QWidget *w)
|
|
{
|
|
QWidget *me = this;
|
|
if(w == me){
|
|
gotFocus();
|
|
}
|
|
else {
|
|
lostFocus();
|
|
}
|
|
}
|
|
|
|
void KSircTopLevel::gotFocus()
|
|
{
|
|
if(isVisible() == TRUE){
|
|
if(have_focus == 0){
|
|
if(m_channelInfo.channel()[0] != '!' ){
|
|
QString str = QString("/join %1").arg(m_channelInfo.channel());
|
|
if(m_channelInfo.key().length() > 0){
|
|
str.append(" " + m_channelInfo.key());
|
|
}
|
|
kdDebug(5008) << "Doing join: " << str << " / " << m_channelInfo.channel() << endl;
|
|
str.append("\n");
|
|
emit outputUnicodeLine(str);
|
|
}
|
|
have_focus = 1;
|
|
emit currentWindow(this);
|
|
}
|
|
}
|
|
if(m_gotMsgWithoutFocus == true){
|
|
m_gotMsgWithoutFocus = false;
|
|
servercontroller::self()->decreaseNotificationCount(QString("%1 -> %2 got message").arg(ksircProcess()->serverID()).arg(m_channelInfo.channel()));
|
|
}
|
|
|
|
}
|
|
|
|
void KSircTopLevel::lostFocus()
|
|
{
|
|
if(have_focus == 1){
|
|
have_focus = 0;
|
|
}
|
|
}
|
|
|
|
void KSircTopLevel::control_message(int command, QString str)
|
|
{
|
|
switch(command){
|
|
case CHANGE_CHANNEL: // 001 is defined as changeChannel
|
|
{
|
|
KSircChannel ci(m_channelInfo.server(), QString::null);
|
|
QRegExp rx("([^!]+)!+([^!]+)!*([^!]*)");
|
|
if(rx.search(str) < 0){
|
|
ci.setChannel(str);
|
|
}
|
|
else{
|
|
ci.setChannel(rx.cap(2));
|
|
ci.setKey(rx.cap(3));
|
|
}
|
|
//kdDebug(5008) << "CHANGE NAME: " << ci.channel() << " key: " << ci.key() << endl;
|
|
emit changeChannel(m_channelInfo.channel(), ci.channel());
|
|
ksopts->channelSetup(m_channelInfo.server(), m_channelInfo.channel());
|
|
m_channelInfo.setChannel(ci.channel());
|
|
m_channelInfo.setKey(ci.key());
|
|
m_channelInfo.setEncoding(ksopts->chan(m_channelInfo).encoding);
|
|
if ( !logFile && ksopts->chan(m_channelInfo).logging )
|
|
{
|
|
logFile = new LogFile( m_channelInfo.channel(), ksircProcess()->serverName() );
|
|
logFile->open();
|
|
}
|
|
setName(m_channelInfo.server().utf8() + "_" + m_channelInfo.channel().utf8() + "_" + "toplevel");
|
|
pan->setName(QCString(QObject::name()) + "_" + "QSplitter");
|
|
kmenu->setName(QCString(QObject::name()) + "_ktoolframe");
|
|
linee->setName(QCString(QObject::name()) + "_" + "LineEnter");
|
|
kmenu->show();
|
|
setCaption(m_channelInfo.channel());
|
|
emit currentWindow(this);
|
|
|
|
if(m_channelInfo.channel()[0] == '#' || m_channelInfo.channel()[0] == '&'){
|
|
QString str = QString("/join %1 %2\n").arg(m_channelInfo.channel()).arg(m_channelInfo.key());
|
|
kdDebug(5008) << "Doing /join " << m_channelInfo.channel() << " :" << str << endl;
|
|
emit outputUnicodeLine(str);
|
|
emit outputLine("/eval $query=''\n");
|
|
}
|
|
else if (m_channelInfo.channel()[0] != '!')
|
|
{
|
|
emit outputUnicodeLine(QString("/eval $query='%1'\n").arg(m_channelInfo.channel()));
|
|
}
|
|
|
|
bool isPrivate = isPrivateChat();
|
|
|
|
mainw->setAcceptFiles( isPrivate );
|
|
|
|
if ( isPrivate )
|
|
{
|
|
nicks_box->hide();
|
|
ksTopic->hide();
|
|
file->setItemEnabled(topicitem, false);
|
|
}
|
|
else
|
|
{
|
|
file->setItemEnabled(topicitem, true);
|
|
file->setItemChecked(topicitem, ksopts->channel[m_channelInfo.server()][m_channelInfo.channel()].topicShow);
|
|
if(file->isItemChecked(topicitem)){
|
|
ksTopic->show();
|
|
// channelButtons->show();
|
|
}
|
|
nicks_box->show();
|
|
pan->show();
|
|
// channelButtons->show();
|
|
// nicks->show();
|
|
// lag->show();
|
|
}
|
|
if(layout()) {
|
|
//kdDebug(5008) << "Redoeing layout" << endl;
|
|
layout()->invalidate();
|
|
layout()->activate();
|
|
}
|
|
else {
|
|
//kdDebug(5008) << "No layout" << endl;
|
|
}
|
|
pan->refresh();
|
|
|
|
ksopts->channelSetup(m_channelInfo.server(), m_channelInfo.channel());
|
|
file->setItemChecked(topicitem, ksopts->chan(m_channelInfo).topicShow);
|
|
file->setItemChecked(beepitem, ksopts->chan(m_channelInfo).beepOnMsg);
|
|
file->setItemChecked(tsitem, ksopts->chan(m_channelInfo).timeStamp);
|
|
file->setItemChecked(fjpitem, ksopts->chan(m_channelInfo).filterJoinPart);
|
|
int eindex = encodingAction->items().findIndex(ksopts->chan(m_channelInfo).encoding);
|
|
//kdDebug(5008) << "in change channel we want: " << ksopts->chan(m_channelInfo).encoding << " eindex: " << eindex << endl;
|
|
encodingAction->setCurrentItem(eindex < 0 ? 0 : eindex);
|
|
setEncoding();
|
|
mainw->enableTimeStamps(ksopts->chan(m_channelInfo).timeStamp);
|
|
|
|
break;
|
|
}
|
|
case STOP_UPDATES:
|
|
Buffer = TRUE;
|
|
break;
|
|
case RESUME_UPDATES:
|
|
Buffer = FALSE;
|
|
if(LineBuffer.isEmpty() == FALSE)
|
|
sirc_receive(QString::null);
|
|
break;
|
|
case REREAD_CONFIG:
|
|
emit freezeUpdates(TRUE); // Stop the list boxes update
|
|
selector->setFont( ksopts->defaultFont.family() );
|
|
mainw->setFont( ksopts->defaultFont );
|
|
nicks->setFont( ksopts->defaultFont );
|
|
linee->setFont( ksopts->defaultFont );
|
|
ksTopic->setFont( ksopts->defaultFont );
|
|
UserUpdateMenu(); // Must call to update Popup.
|
|
emit freezeUpdates(FALSE); // Stop the list boxes update
|
|
initColors();
|
|
ksopts->channelSetup(m_channelInfo.server(), m_channelInfo.channel());
|
|
file->setItemChecked(topicitem, ksopts->channel[m_channelInfo.server()][m_channelInfo.channel()].topicShow);
|
|
file->setItemChecked(beepitem, ksopts->channel[m_channelInfo.server()][m_channelInfo.channel()].beepOnMsg);
|
|
file->setItemChecked(tsitem, ksopts->channel[m_channelInfo.server()][m_channelInfo.channel()].timeStamp);
|
|
{
|
|
int eindex = encodingAction->items().findIndex(ksopts->channel[m_channelInfo.server()][m_channelInfo.channel()].encoding);
|
|
//kdDebug(5008) << "in re-readconfig we want: " << ksopts->channel[m_channelInfo.server()][m_channelInfo.channel()].encoding << " eindex: " << eindex << endl;
|
|
encodingAction->setCurrentItem(eindex < 0 ? 0 : eindex);
|
|
setEncoding();
|
|
}
|
|
mainw->enableTimeStamps(ksopts->channel[m_channelInfo.server()][m_channelInfo.channel()].timeStamp);
|
|
if(ksopts->oneLineEntry == true) {
|
|
linee->setWordWrap(QTextEdit::NoWrap);
|
|
}
|
|
else {
|
|
linee->setWordWrap(QTextEdit::WidgetWidth);
|
|
}
|
|
mainw->scrollToBottom(true);
|
|
update();
|
|
break;
|
|
case SET_LAG:
|
|
if(str.isNull() == FALSE){
|
|
bool ok = TRUE;
|
|
|
|
str.truncate(6);
|
|
double lag = str.toDouble(&ok);
|
|
if(ok == TRUE){
|
|
lag -= (lag*100.0 - int(lag*100.0))/100.0;
|
|
QString s_lag;
|
|
s_lag.sprintf("Lag: %.2f", lag);
|
|
this->lag->setText(s_lag);
|
|
}
|
|
else{
|
|
this->lag->setText(str);
|
|
}
|
|
}
|
|
break;
|
|
case RESET_NOTIF:
|
|
m_gotMsgWithoutFocus = 0;
|
|
break;
|
|
default:
|
|
kdDebug(5008) << "Unkown control message: " << str << endl;
|
|
}
|
|
}
|
|
|
|
void KSircTopLevel::setTopic( const QString &topic )
|
|
{
|
|
m_topic = topic;
|
|
ksTopic->setText( topic );
|
|
}
|
|
|
|
void KSircTopLevel::toggleTimestamp()
|
|
{
|
|
ksopts->channel[m_channelInfo.server()][m_channelInfo.channel()].timeStamp = !ksopts->channel[m_channelInfo.server()][m_channelInfo.channel()].timeStamp;
|
|
ksopts->save(KSOptions::Channels);
|
|
mainw->enableTimeStamps( ksopts->channel[m_channelInfo.server()][m_channelInfo.channel()].timeStamp );
|
|
file->setItemChecked( tsitem, ksopts->channel[m_channelInfo.server()][m_channelInfo.channel()].timeStamp );
|
|
}
|
|
|
|
void KSircTopLevel::toggleFilterJoinPart()
|
|
{
|
|
ksopts->chan(m_channelInfo).filterJoinPart = !ksopts->chan(m_channelInfo).filterJoinPart;
|
|
ksopts->save(KSOptions::Channels);
|
|
file->setItemChecked( fjpitem, ksopts->chan(m_channelInfo).filterJoinPart );
|
|
}
|
|
|
|
QString KSircTopLevel::findNick(QString part, uint which)
|
|
{
|
|
QStringList matches;
|
|
|
|
for (QStringList::ConstIterator it = completeNicks.begin();
|
|
it != completeNicks.end();
|
|
++it)
|
|
{
|
|
if ((*it).left(part.length()).lower() == part.lower() && nicks->findNick(*it) >= 0) {
|
|
matches.append(*it);
|
|
}
|
|
}
|
|
|
|
for(uint i=0; i < nicks->count(); i++){
|
|
if (matches.contains(nicks->text(i)))
|
|
continue;
|
|
if(nicks->text(i).length() >= part.length()){
|
|
if(nicks->text(i).lower().startsWith( part.lower())){
|
|
if(nicks->text(i) != ksircProcess()->getNick() ){ // Don't match your own nick
|
|
matches.append(nicks->text(i));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(matches.count() > 0){
|
|
if(which < matches.count())
|
|
return *(matches.at(which));
|
|
else
|
|
return QString::null;
|
|
}
|
|
return QString::null;
|
|
|
|
}
|
|
|
|
void KSircTopLevel::removeCompleteNick(const QString &nick)
|
|
{
|
|
QStringList::Iterator it = completeNicks.find(nick);
|
|
if (it != completeNicks.end())
|
|
completeNicks.remove(it);
|
|
}
|
|
|
|
void KSircTopLevel::addCompleteNick(const QString &nick)
|
|
{
|
|
removeCompleteNick(nick);
|
|
completeNicks.prepend(nick);
|
|
}
|
|
|
|
void KSircTopLevel::changeCompleteNick(const QString &oldNick, const QString &newNick)
|
|
{
|
|
QStringList::Iterator it = completeNicks.find(oldNick);
|
|
if (it != completeNicks.end())
|
|
*it = newNick;
|
|
}
|
|
|
|
void KSircTopLevel::openQueryFromNick(const QString &nick)
|
|
{
|
|
KSircChannel ci(m_channelInfo.server(), nick.lower());
|
|
emit open_toplevel(ci);
|
|
}
|
|
|
|
void KSircTopLevel::pasteToWindow()
|
|
{
|
|
// Ctrl-V
|
|
//kdDebug(5008) << "Going to paste: " << KApplication::clipboard()->text( QClipboard::Clipboard ) << endl;
|
|
slotTextDropped(KApplication::clipboard()->text( QClipboard::Clipboard ) );
|
|
}
|
|
|
|
void KSircTopLevel::pasteToNickList(int button,
|
|
QListBoxItem *item,
|
|
const QPoint &)
|
|
{
|
|
if(button == Qt::MidButton && item){
|
|
KSircChannel ci(m_channelInfo.server(), item->text().lower());
|
|
emit open_toplevel(ci);
|
|
|
|
QStringList lines = QStringList::split( '\n',
|
|
KApplication::clipboard()->text( QClipboard::Selection ),
|
|
true );
|
|
QStringList::ConstIterator it = lines.begin();
|
|
QStringList::ConstIterator end = lines.end();
|
|
for (; it != end; ++it )
|
|
{
|
|
if ((*it).isEmpty())
|
|
continue;
|
|
|
|
QString str =
|
|
QString("/msg ") + item->text().lower() + " " +
|
|
*it + "\n";
|
|
emit outputUnicodeLine(str);
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void KSircTopLevel::dndTextToNickList(const QListBoxItem *item,
|
|
const QString& text)
|
|
{
|
|
if(item){
|
|
KSircChannel ci(m_channelInfo.server(), item->text().lower());
|
|
emit open_toplevel(ci);
|
|
|
|
QStringList lines = QStringList::split( '\n',
|
|
text,
|
|
true );
|
|
QStringList::ConstIterator it = lines.begin();
|
|
QStringList::ConstIterator end = lines.end();
|
|
for (; it != end; ++it )
|
|
{
|
|
if ((*it).isEmpty())
|
|
continue;
|
|
|
|
QString str =
|
|
QString("/msg ") + item->text().lower() + " " +
|
|
*it + "\n";
|
|
emit outputUnicodeLine(str);
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
enum KSircTopLevelCommands{ Ask, Parse, Escape };
|
|
void KSircTopLevel::slotTextDropped( const QString& _text )
|
|
{
|
|
if (_text.isEmpty())
|
|
return;
|
|
QString text = linee->text();
|
|
int curPos = linee->cursorPosition();
|
|
|
|
text = text.mid( 0, curPos ) + _text + text.mid( curPos );
|
|
|
|
if (text[text.length()-1] != '\n')
|
|
text += "\n";
|
|
int lines = text.contains("\n");
|
|
int approx_lines = text.length() / 75;
|
|
if ( lines > approx_lines )
|
|
approx_lines = lines;
|
|
if (lines > 4) {
|
|
int result = KMessageBox::warningContinueCancel(this,
|
|
i18n("You are about to send %1 lines of text.\nDo you really want to send that much?").arg(approx_lines),
|
|
QString::null, i18n("Send"));
|
|
if (result != KMessageBox::Continue)
|
|
{
|
|
// linee->setText("");
|
|
return;
|
|
}
|
|
}
|
|
|
|
tab_pressed = -1;
|
|
if(lines > 1){
|
|
linee->setUpdatesEnabled(FALSE);
|
|
|
|
QStringList lines = QStringList::split( '\n', text, true );
|
|
QStringList::ConstIterator it = lines.begin();
|
|
QStringList::ConstIterator end = lines.end();
|
|
KSircTopLevelCommands commands = Ask;
|
|
for (; it != end; ++it )
|
|
{
|
|
if ((*it).isEmpty())
|
|
continue;
|
|
QString line = *it;
|
|
if ( line[0].latin1() == '/' )
|
|
{
|
|
if ( commands == Ask )
|
|
switch ( KMessageBox::questionYesNo( this, i18n(
|
|
"The text you pasted contains lines that start with /.\n"
|
|
"Should they be interpreted as IRC commands?" ), QString::null, i18n("Interpret"), i18n("Do Not Interpret") ) )
|
|
{
|
|
case KMessageBox::Yes:
|
|
commands = Parse;
|
|
break;
|
|
case KMessageBox::No:
|
|
commands = Escape;
|
|
break;
|
|
}
|
|
if ( commands == Escape )
|
|
line.prepend( "/say " );
|
|
}
|
|
linee->setText( line );
|
|
sirc_line_return(line);
|
|
}
|
|
|
|
linee->setText("");
|
|
linee->setUpdatesEnabled(TRUE);
|
|
linee->update();
|
|
}
|
|
else{
|
|
text.replace(QRegExp("\n"), "");
|
|
linee->setText(text);
|
|
linee->setCursorPosition( curPos + _text.length() );
|
|
}
|
|
}
|
|
|
|
void KSircTopLevel::clearWindow()
|
|
{
|
|
kdDebug(5008) << "Doing clear on main window" << endl;
|
|
mainw->clear();
|
|
}
|
|
|
|
void KSircTopLevel::lineeNotTab()
|
|
{
|
|
tab_pressed = -1;
|
|
disconnect(linee, SIGNAL(notTab()),
|
|
this, SLOT(lineeNotTab()));
|
|
addCompleteNick(tab_nick);
|
|
}
|
|
|
|
void KSircTopLevel::toggleRootWindow()
|
|
{
|
|
}
|
|
|
|
bool KSircTopLevel::event( QEvent *e)
|
|
{
|
|
if(e->type() == QEvent::ApplicationPaletteChange ||
|
|
e->type() == QEvent::ApplicationFontChange)
|
|
{
|
|
QTimer::singleShot(750, this, SLOT(initColors()));
|
|
initColors();
|
|
}
|
|
return KMainWindow::event(e);
|
|
}
|
|
|
|
void KSircTopLevel::saveCurrLog()
|
|
{
|
|
KURL url = KURL( KFileDialog::getSaveFileName(QString::null,
|
|
"*.log", 0L,
|
|
i18n("Save Chat/Query Logfile")));
|
|
if( url.isEmpty())
|
|
return;
|
|
|
|
KTempFile temp;
|
|
QTextStream *str = temp.textStream();
|
|
|
|
*str << mainw->plainText();
|
|
|
|
temp.close();
|
|
#if KDE_IS_VERSION(3,1,92)
|
|
KIO::NetAccess::upload(temp.name(), url, this);
|
|
#else
|
|
KIO::NetAccess::upload(temp.name(), url);
|
|
#endif
|
|
}
|
|
|
|
|
|
void KSircTopLevel::slotDropURLs( const QStringList& urls )
|
|
{
|
|
if ( !isPrivateChat() )
|
|
return;
|
|
|
|
slotDccURLs( urls, m_channelInfo.channel() );
|
|
}
|
|
|
|
// sends the list of urls to $dest_nick
|
|
void KSircTopLevel::slotDccURLs( const QStringList& urls, const QString& nick )
|
|
{
|
|
if ( urls.isEmpty() || nick.isEmpty() )
|
|
return;
|
|
|
|
QStringList::ConstIterator it = urls.begin();
|
|
// QString s("/eval &docommand(eval{\"dcc send " + nick + " %1\"});\n");
|
|
QString s("/dcc send " + nick + " %1\n");
|
|
for ( ; it != urls.end(); ++it ) {
|
|
QString file( *it );
|
|
kdDebug(5008) << "........ " << file << endl;
|
|
if ( !file.isEmpty() )
|
|
sirc_write(s.arg( file ));
|
|
}
|
|
}
|
|
|
|
bool KSircTopLevel::isPrivateChat() const
|
|
{
|
|
return ((m_channelInfo.channel()[0] != '!') && (m_channelInfo.channel()[0] != '&') &&
|
|
(m_channelInfo.channel()[0] != '#'));
|
|
}
|
|
|
|
bool KSircTopLevel::isPublicChat() const
|
|
{
|
|
return ((m_channelInfo.channel()[0] == '#') || (m_channelInfo.channel()[0] == '&'));
|
|
}
|
|
|
|
bool KSircTopLevel::isSpecialWindow() const
|
|
{
|
|
return (m_channelInfo.channel()[0] == '!');
|
|
}
|
|
|
|
void KSircTopLevel::outputUnicodeLine( const QString &message )
|
|
{
|
|
emit outputLine( encoder()->fromUnicode( message ) );
|
|
}
|
|
|
|
void KSircTopLevel::setTopicIntern( const QString &topic )
|
|
{
|
|
QString command = QString::fromLatin1( "/topic %1 %2\n" ).arg( m_channelInfo.channel() ).arg( topic );
|
|
sirc_write( command );
|
|
linee->setFocus();
|
|
}
|
|
|
|
void KSircTopLevel::doChange(bool pers, QString text)
|
|
{
|
|
QTime ctime = QTime::currentTime();
|
|
if (ksopts->channel[m_channelInfo.server()][m_channelInfo.channel()].beepOnMsg) {
|
|
// beep only every 2 seconds otherwise it'll get very noisy in the room ;)
|
|
if ( QABS( lastBeep.secsTo( ctime ) ) > 1 ) {
|
|
if ( pers ) {
|
|
int winId = !ticker ? topLevelWidget()->winId() : ticker->winId();
|
|
KNotifyClient::event(winId,
|
|
QString::fromLatin1("ChannelPersonal"),
|
|
i18n("Your nick appeared on channel %1").arg(m_channelInfo.channel()));
|
|
} else {
|
|
int winId = !ticker ? topLevelWidget()->winId() : ticker->winId();
|
|
KNotifyClient::event(winId,
|
|
QString::fromLatin1("ChannelChanged"),
|
|
i18n("Channel %1 changed").arg(m_channelInfo.channel()));
|
|
}
|
|
lastBeep = ctime;
|
|
}
|
|
}
|
|
|
|
if(have_focus == 0 && pers == true && m_gotMsgWithoutFocus == false){
|
|
m_gotMsgWithoutFocus = true;
|
|
servercontroller::self()->increaseNotificationCount(QString("%1 -> %2").arg(ksircProcess()->serverID()).arg(m_channelInfo.channel()), text);
|
|
}
|
|
}
|
|
|
|
void KSircTopLevel::toggleBeep()
|
|
{
|
|
ksopts->channel[m_channelInfo.server()][m_channelInfo.channel()].beepOnMsg = !ksopts->channel[m_channelInfo.server()][m_channelInfo.channel()].beepOnMsg;
|
|
ksopts->save(KSOptions::Channels);
|
|
file->setItemChecked(beepitem, ksopts->channel[m_channelInfo.server()][m_channelInfo.channel()].beepOnMsg);
|
|
}
|
|
|
|
void KSircTopLevel::toggleTopic()
|
|
{
|
|
if(file->isItemChecked(topicitem)){
|
|
ksTopic->hide();
|
|
// channelButtons->hide();
|
|
ksopts->channel[m_channelInfo.server()][m_channelInfo.channel()].topicShow = false;
|
|
}
|
|
else {
|
|
ksTopic->show();
|
|
// channelButtons->show();
|
|
ksopts->channel[m_channelInfo.server()][m_channelInfo.channel()].topicShow = true;
|
|
}
|
|
file->setItemChecked(topicitem, !file->isItemChecked(topicitem));
|
|
ksopts->save(KSOptions::Channels);
|
|
}
|
|
|
|
void KSircTopLevel::toggleTicker()
|
|
{
|
|
//kdDebug(5008) << "Got toggle ticker" << endl;
|
|
if(ticker){
|
|
show();
|
|
displayMgr->show(this);
|
|
linee->setFocus(); // Give focus back to the linee, someone takes it away on new create
|
|
tickerpoint = ticker->pos();
|
|
tickersize = ticker->size();
|
|
delete ticker;
|
|
ticker = 0x0;
|
|
}
|
|
else {
|
|
ticker = new KSTicker(0x0, m_channelInfo.channel().utf8() + "_ticker");
|
|
ticker->setCaption(m_channelInfo.channel());
|
|
if(tickerpoint.isNull() == false)
|
|
ticker->move(tickerpoint);
|
|
if(tickersize.isEmpty() == false)
|
|
ticker->resize(tickersize);
|
|
ticker->show();
|
|
displayMgr->hide(this);
|
|
|
|
connect(ticker, SIGNAL(doubleClick()), this, SLOT(toggleTicker()));
|
|
}
|
|
}
|
|
|
|
bool KSircTopLevel::atBottom()
|
|
{
|
|
return mainw->verticalScrollBar()->maxValue() - mainw->verticalScrollBar()->value() < 20;
|
|
}
|
|
|
|
void KSircTopLevel::cmd_process(int id)
|
|
{
|
|
if(cmd_menu.at(id) != cmd_menu.end()) {
|
|
QString item, arg, out;
|
|
item = cmd_menu[id].section('/', 1, 1);
|
|
arg = cmd_menu[id].section('/', 2, 2);
|
|
|
|
out = "/" + item;
|
|
|
|
if(arg == "*chan*")
|
|
out.append(" " + m_channelInfo.channel());
|
|
|
|
out.append(" ");
|
|
|
|
linee->insertAt(out, 0, 0);
|
|
linee->setCursorPosition(linee->cursorPosition() + out.length());
|
|
}
|
|
}
|
|
|
|
void KSircTopLevel::showDCCMgr()
|
|
{
|
|
KSircMessageReceiver *kmr = ksircProcess()->mrList().find("!dcc");
|
|
if(kmr){
|
|
KSircIODCC *dcc = static_cast<KSircIODCC *>(kmr);
|
|
if(dcc){
|
|
dcc->showMgr();
|
|
}
|
|
}
|
|
}
|
|
|
|
#include "toplevel.moc"
|
|
|
|
// vim: ts=2 sw=2 et
|