/********************************************************************** 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(TQString &): output_toplevel(TQString): closing(KSircTopLevel *, TQString channel): changeChannel(TQString old, TQString 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern DisplayMgr *displayMgr; //TQPopupMenu *KSircTopLevel::user_controls = 0L; TQPtrList *KSircTopLevel::user_menu = 0L; TQStringList KSircTopLevel::cmd_menu; void KSircTopLevel::initColors() { TQColorGroup cg_mainw = kapp->palette().active(); cg_mainw.setColor(TQColorGroup::Base, ksopts->backgroundColor); cg_mainw.setColor(TQColorGroup::Text, ksopts->textColor); cg_mainw.setColor(TQColorGroup::Link, ksopts->linkColor); cg_mainw.setColor(TQColorGroup::Highlight, ksopts->selBackgroundColor); cg_mainw.setColor(TQColorGroup::HighlightedText, ksopts->selForegroundColor); mainw->setPalette(TQPalette(cg_mainw,cg_mainw, cg_mainw)); nicks->setPalette(TQPalette(cg_mainw,cg_mainw, cg_mainw)); linee->setPalette(TQPalette(cg_mainw,cg_mainw, cg_mainw)); lag->setPalette(TQPalette(cg_mainw,cg_mainw, cg_mainw)); cg_mainw.setColor(TQColorGroup::Background, ksopts->backgroundColor); cg_mainw.setColor(TQColorGroup::Foreground, ksopts->textColor); ksTopic->setPalette(TQPalette(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) : TDEMainWindow(0, name, 0/*no WDestructiveClose !*/), UnicodeMessageReceiver(_proc), lastBeep( TQTime::currentTime() ), m_channelInfo(channelInfo) { // prevent us from being quitted when closing a channel-window. Only // closing the servercontroller shall quit. // TDEMainWindow will deref() us in closeEvent kapp->ref(); m_topic = TQString(); TQCString kstl_name = TQCString(TQT_TQOBJECT(this)->name()) + "_" + "toplevel"; setName(kstl_name); if(!m_channelInfo.channel().isEmpty()) { setCaption(m_channelInfo.channel()); caption = m_channelInfo.channel(); } else { caption = TQString(); } 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, TQT_SIGNAL(clicked()), this, TQT_SLOT(insertText())); selector->setFont(ksopts->defaultFont.family()); file = new TQPopupMenu(this, TQCString(TQT_TQOBJECT(this)->name()) + "_popup_file"); file->setCheckable(true); TDEAction *act = KStdAction::openNew( TQT_TQOBJECT(this), TQT_SLOT( newWindow() ), actionCollection() ); act->plug( file ); file->insertItem(i18n("New Ser&ver..."), servercontroller::self(), TQT_SLOT(new_connection()), Key_F2); file->insertSeparator(); file->insertItem(i18n("&DCC Manager..."), this, TQT_SLOT(showDCCMgr())); file->insertItem(i18n("&Save to Logfile..."), this, TQT_SLOT(saveCurrLog()), CTRL + Key_S); tsitem = file->insertItem(i18n("Time St&"), this, TQT_SLOT(toggleTimestamp()), CTRL + Key_T); file->setItemChecked(tsitem, ksopts->chan(m_channelInfo).timeStamp); fjpitem = file->insertItem(i18n("Hide Join/Part Messages"), this, TQT_SLOT(toggleFilterJoinPart())); file->setItemChecked(fjpitem, ksopts->chan(m_channelInfo).filterJoinPart); file->insertItem(i18n("Character &Table"), selector, TQT_SLOT(show()), CTRL + Key_H); beepitem = file->insertItem(i18n("N&otify on Change"), this, TQT_SLOT(toggleBeep()), CTRL + Key_P); file->setItemChecked(beepitem, ksopts->chan(m_channelInfo).beepOnMsg); encodingAction = new TDESelectAction( i18n( "&Encoding" ), 0, TQT_TQOBJECT(this) ); connect( encodingAction, TQT_SIGNAL( activated() ), this, TQT_SLOT( setEncoding() ) ); TQStringList encodings = TDEGlobal::charsets()->descriptiveEncodingNames(); topicitem = file->insertItem(i18n("S&how Topic"), this, TQT_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, TQT_SLOT(toggleTicker())); // remove utf16/ucs2 as it just doesn't work for IRC TQStringList::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( TQT_TQOBJECT(this), TQT_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 TQFrame F, this is use so we * can give the TDEApplication a single main client widget, which is needs. * * A TQVbox and a TQHbox is used to ctronl the 3 sub widget * The Modified TQListBox 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 TQVBox( this ); ksTopic = new KSircTopic( top ); ksTopic->setFont(ksopts->defaultFont); connect( ksTopic, TQT_SIGNAL( topicChange( const TQString & ) ), this, TQT_SLOT( setTopicIntern( const TQString & ) ) ); TQCString kstn = TQCString(TQT_TQOBJECT(this)->name()) + "_"; pan = new TQSplitter(Qt::Horizontal, top, kstn + "splitter"); #if KDE_IS_VERSION(3,1,92) pan->setOpaqueResize( TDEGlobalSettings::opaqueResize() ); #else pan->setOpaqueResize( true ); #endif mainw = new KSircView(ksircProcess(), pan, kstn + "KSircView" ); mainw->setFocusPolicy(TQ_NoFocus); nicks_box = new TQVBox(pan); channelButtons = new chanButtons(ksircProcess(), nicks_box); connect(channelButtons, TQT_SIGNAL(mode(TQString, int, TQString)), this, TQT_SLOT(setMode(TQString, int, TQString))); nicks = new aListBox(nicks_box, kstn + "aListBox"); nicks->setFocusPolicy(TQ_NoFocus); //nicks->hide(); // default = only the main widget lag = new TQLabel(nicks_box); lag->setFrameStyle(TQFrame::Panel|TQFrame::Sunken); lag->setAlignment(TQt::AlignCenter | TQt::SingleLine); lag->setText(i18n("Lag: Wait")); TQValueList sizes; sizes << int(width()*0.85) << int(width()*0.15); pan->setSizes(sizes); pan->setResizeMode( mainw, TQSplitter::Stretch ); pan->setResizeMode( nicks_box, TQSplitter::Stretch ); // f = new kstInside(top, TQString(TQObject::name()) + "_" + "kstIFrame"); top->setStretchFactor(pan, 1); setCentralWidget(top); // Tell the TDEApplication 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()){ TDEConfig conf("ksirc/winlog/" + channelInfo.server() + "-" + channelInfo.channel(), false, false, "data"); TQString group = "Message-History"; if(conf.hasGroup( group )){ conf.setGroup( group ); TQStringList strlist = conf.readListEntry("History"); if(strlist.count() > 0){ mainw->enableTimeStamps(true); for ( TQStringList::Iterator it = strlist.begin(); it != strlist.end(); ++it ) { mainw->addRichText(*it); } } strlist.clear(); } } mainw->enableTimeStamps(ksopts->chan(m_channelInfo).timeStamp); edit = new TQPopupMenu(this); act = KStdAction::copy( TQT_TQOBJECT(mainw), TQT_SLOT( copy() ), actionCollection() ); act->plug( edit ); act = KStdAction::paste( TQT_TQOBJECT(this), TQT_SLOT( pasteToWindow() ), actionCollection() ); act->plug( edit ); edit->insertItem(i18n("C&lear Window"), this, TQT_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, TQT_SIGNAL(pasteReq( const TQString& )), this, TQT_SLOT( slotTextDropped( const TQString& ))); nicks->setFont(ksopts->defaultFont); // setup line editor linee->setFocusPolicy(TQ_StrongFocus); linee->setFont(ksopts->defaultFont); if(ksopts->oneLineEntry == true) { linee->setWordWrap(TQTextEdit::NoWrap); } else { linee->setWordWrap(TQTextEdit::WidgetWidth); } connect(linee, TQT_SIGNAL(gotFocus()), this, TQT_SLOT(gotFocus())); connect(linee, TQT_SIGNAL(lostFocus()), this, TQT_SLOT(lostFocus())); connect(linee, TQT_SIGNAL(pasteText(const TQString&)), this, TQT_SLOT(slotTextDropped(const TQString&))); connect(linee, TQT_SIGNAL(notTab()), this, TQT_SLOT(lineeNotTab())); connect( linee, TQT_SIGNAL( gotReturnPressed() ), this, TQT_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::parseTDEConfig(); user_controls = new TQPopupMenu(this); kmenu->insertItem(i18n("&Users"), user_controls); command = new TQPopupMenu(this); setupCommandMenu(); int i = 0; TQDict cml; for(TQStringList::Iterator it = cmd_menu.begin(); it != cmd_menu.end(); ++it){ TQString top, item; top = (*it).section('/', 0, 0); item = (*it).section('/', 1, 1); if(!cml[top]) { cml.insert(top, new TQPopupMenu(this)); command->insertItem(top, cml[top]); } cml[top]->insertItem(item, this, TQT_SLOT(cmd_process(int)), 0, i); i++; } kmenu->insertItem(i18n("C&ommand"), command); kmenu->insertItem( KStdGuiItem::help().text(), helpMenu( TQString(), false )); connect(user_controls, TQT_SIGNAL(activated(int)), this, TQT_SLOT(UserParseMenu(int))); connect(nicks, TQT_SIGNAL(contextMenuRequested(int)), this, TQT_SLOT(UserSelected(int))); connect(nicks, TQT_SIGNAL(selectedNick(const TQString &)), this, TQT_SLOT(openQueryFromNick(const TQString &))); connect(nicks, TQT_SIGNAL(mouseButtonClicked ( int, TQListBoxItem *, const TQPoint &)), this, TQT_SLOT(pasteToNickList(int, TQListBoxItem *, const TQPoint &))); connect(nicks, TQT_SIGNAL(textDropped( const TQListBoxItem *, const TQString& )), this, TQT_SLOT(dndTextToNickList(const TQListBoxItem *, const TQString&))); UserUpdateMenu(); // Must call to update Popup. accel = new TQAccel(this, "accel"); accel->connectItem(accel->insertItem(SHIFT + Key_PageUp), this, TQT_SLOT(AccelScrollUpPage())); accel->connectItem(accel->insertItem(SHIFT + Key_PageDown), this, TQT_SLOT(AccelScrollDownPage())); /* * Pageup/dn * Added for stupid wheel mice */ accel->connectItem(accel->insertItem(Key_PageUp), this, TQT_SLOT(AccelScrollUpPage())); accel->connectItem(accel->insertItem(Key_PageDown), this, TQT_SLOT(AccelScrollDownPage())); /* * These are not presently implemented, so let's not fill the logs. accel->connectItem(accel->insertItem(CTRL + Key_Return), this, TQT_SLOT(AccelPriorMsgNick())); accel->connectItem(accel->insertItem(CTRL + SHIFT + Key_Return), this, TQT_SLOT(AccelNextMsgNick())); */ accel->connectItem(accel->insertItem(Key_Tab), // adds TAB accelerator this, // connected to the main TQT_SLOT(TabNickCompletionNormal())); // TabNickCompletion() slot accel->connectItem(accel->insertItem(SHIFT+Key_Tab), // adds TAB accelerator this, // connected to the main TQT_SLOT(TabNickCompletionShift())); // TabNickCompletion() slot accel->connectItem(accel->insertItem(CTRL + Key_N), this, TQT_SLOT(newWindow())); // accel->connectItem(accel->insertItem(CTRL + Key_S), // this, TQT_SLOT(toggleTimestamp())); // Drag & Drop connect( mainw, TQT_SIGNAL( textDropped(const TQString&) ), TQT_SLOT( slotTextDropped(const TQString&) )); connect( mainw, TQT_SIGNAL( urlsDropped(const TQStringList&) ), TQT_SLOT( slotDropURLs(const TQStringList&) )); connect( nicks, TQT_SIGNAL( urlsDropped( const TQStringList&, const TQString& )), TQT_SLOT( slotDccURLs( const TQStringList&, const TQString& ))); connect( this, TQT_SIGNAL( changed(bool, TQString) ), this, TQT_SLOT( doChange(bool, TQString) )); 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] == '&')){ // TQString str = TQString("/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; TQString str = TQString("/part ") + m_channelInfo.channel() + "\n"; emit outputUnicodeLine(str); } else { TQStringList 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) { TQString rt = ksit.richText(); if(rt.contains("")) continue; kdDebug(5008) << rt << endl; strlist += rt; } TDEConfig conf("ksirc/winlog/" + channelInfo().server() + "-" + channelInfo().channel(), false, false, "data"); TQString 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(TQString mode, int mode_type, TQString currentNick) { TQString command; if (mode_type == 0) command = TQString::fromLatin1("/mode %1 %2\n").arg(m_channelInfo.channel()).arg(mode); else command = TQString::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 = TQString(); UnicodeMessageReceiver::setEncoding( TQString() ); } else { ksopts->chan(m_channelInfo).encoding = encodingAction->currentText(); UnicodeMessageReceiver::setEncoding( TDEGlobal::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() { TDEMainWindow::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; TQString 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; } TQString 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, TQT_SIGNAL(notTab()), this, TQT_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, TQT_SIGNAL(notTab()), this, TQT_SLOT(lineeNotTab())); } void KSircTopLevel::sirc_receive(TQString 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 TQValueList 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() ) { TQString 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( TQRegExp( "^\\[~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 ) ); } TQValueList list; TQValueList::iterator it; TQString values; list = pan->sizes(); it = list.begin(); while( it != list.end()){ values += TQString("%1 ").arg(*it); ++it; } } void KSircTopLevel::sirc_line_return(const TQString &text) { /* Take line from SLE, and output if to dsirc */ TQString 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 TQString &str) { /* * Parse line forcommand we handle */ TQString command = str, plain = str.lower().simplifyWhiteSpace(); if(plain.startsWith("/join ") || plain.startsWith("/j ") || plain.startsWith("/query ")) { TQString s = plain.mid(plain.find(' ')+1); TQStringList channels = TQStringList::split(",", s); TQStringList::ConstIterator it = channels.begin(); for( ; it != channels.end(); ++it){ TQString name = *it; //kdDebug(5008) << "Doing " << name << endl; TQRegExp rx("(\\S+)\\s*(\\S*)"); rx.search(name); KSircChannel ci(m_channelInfo.server(), rx.cap(1), // channel rx.cap(2)); // optional key linee->setText(TQString()); emit open_toplevel(ci); /* if(name[0] != '#'){ emit open_toplevel(name); linee->setText(TQString()); } else { emit outputUnicodeLine(plain + "\n"); emit open_toplevel(encoder()->fromUnicode(name)); } */ } // Finish sending /join return; } else if(plain.startsWith("/server ")) { plain.simplifyWhiteSpace(); TQRegExp rx("/server (\\S+) *(\\S*) *(\\S*)"); if(rx.search(str) >= 0){ TQString server = rx.cap(1); TQString port = rx.cap(2); TQString pass = rx.cap(3); bool ssl = false; if(server.startsWith("+")){ server.replace(0, 1, ""); ssl = true; } KSircServer serv(server, port, TQString(), pass, ssl); servercontroller::self()->new_ksircprocess(serv); return; } } else if(plain.startsWith("/part") || plain.startsWith("/leave") || plain.startsWith("/hop")) { TQApplication::postEvent(this, new TQCloseEvent()); // WE'RE DEAD linee->setText(TQString()); return; } else if( plain.startsWith( "/bye" ) || plain.startsWith( "/exit" ) || plain.startsWith( "/quit" )) { linee->setText( TQString() ); emit requestQuit( command.ascii() ); return; } else if ( plain.startsWith( "/away" ) ) { TQString awayEvalCommand = TQString::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(TQString::fromLatin1("/msg %1 ").arg(m_channelInfo.channel())); } else if(plain.startsWith("/me ")) { command.remove(0, 3); command.prepend(TQString("/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 TQString &string, TQString &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(pResult); parseError *err = dynamic_cast(pResult); TQString logString; if(item) { parseJoinPart *jp = dynamic_cast(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( TQString(), 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")){ TQRegExp 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() { TQString s = linee->text(); uint i; TQChar 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; TQString s; s = TQString("/eval $dest_nick='%1';\n").arg(nicks->text(nicks->currentItem())); sirc_write(s); // set $$dest_chan variable s = TQString("/eval $dest_chan='%1';\n").arg(m_channelInfo.channel()); sirc_write(s); TQString action = user_menu->at(id)->action; if (action.length() && action[0] == '/') action.remove(0, 1); s = TQString("/eval &docommand(eval{\"%1\"});\n").arg(action); s.replace(TQRegExp("\\$\\$"), "$"); 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(), TQString())); connect(&w, TQT_SIGNAL(openTopLevel(const KSircChannel &)), TQT_SIGNAL(open_toplevel(const KSircChannel &))); w.exec(); } void KSircTopLevel::closeEvent(TQCloseEvent *e) { TDEMainWindow::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() ) { // TQString str = TQString("/part ") + m_channelInfo.channel() + "\n"; // emit outputLine(str); // } // Hide ourselves until we finally die hide(); tqApp->flushX(); // Let's say we're closing kdDebug(5008) << "Toplevel closing: " << m_channelInfo.channel() << endl; emit closing(this, m_channelInfo.channel()); } void KSircTopLevel::focusChange(TQWidget *w) { TQWidget *me = this; if(w == me){ gotFocus(); } else { lostFocus(); } } void KSircTopLevel::gotFocus() { if(isVisible() == TRUE){ if(have_focus == 0){ if(m_channelInfo.channel()[0] != '!' ){ TQString str = TQString("/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(TQString("%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, TQString str) { switch(command){ case CHANGE_CHANNEL: // 001 is defined as changeChannel { KSircChannel ci(m_channelInfo.server(), TQString()); TQRegExp 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(TQCString(TQT_TQOBJECT(this)->name()) + "_" + TQSPLITTER_OBJECT_NAME_STRING); kmenu->setName(TQCString(TQT_TQOBJECT(this)->name()) + "_tdetoolframe"); linee->setName(TQCString(TQT_TQOBJECT(this)->name()) + "_" + "LineEnter"); kmenu->show(); setCaption(m_channelInfo.channel()); emit currentWindow(this); if(m_channelInfo.channel()[0] == '#' || m_channelInfo.channel()[0] == '&'){ TQString str = TQString("/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(TQString("/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(TQString()); 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(TQTextEdit::NoWrap); } else { linee->setWordWrap(TQTextEdit::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; TQString 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 TQString &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 ); } TQString KSircTopLevel::findNick(TQString part, uint which) { TQStringList matches; for (TQStringList::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 TQString(); } return TQString(); } void KSircTopLevel::removeCompleteNick(const TQString &nick) { TQStringList::Iterator it = completeNicks.find(nick); if (it != completeNicks.end()) completeNicks.remove(it); } void KSircTopLevel::addCompleteNick(const TQString &nick) { removeCompleteNick(nick); completeNicks.prepend(nick); } void KSircTopLevel::changeCompleteNick(const TQString &oldNick, const TQString &newNick) { TQStringList::Iterator it = completeNicks.find(oldNick); if (it != completeNicks.end()) *it = newNick; } void KSircTopLevel::openQueryFromNick(const TQString &nick) { KSircChannel ci(m_channelInfo.server(), nick.lower()); emit open_toplevel(ci); } void KSircTopLevel::pasteToWindow() { // Ctrl-V //kdDebug(5008) << "Going to paste: " << TDEApplication::clipboard()->text( TQClipboard::Clipboard ) << endl; slotTextDropped(TDEApplication::clipboard()->text( TQClipboard::Clipboard ) ); } void KSircTopLevel::pasteToNickList(int button, TQListBoxItem *item, const TQPoint &) { if(button == Qt::MidButton && item){ KSircChannel ci(m_channelInfo.server(), item->text().lower()); emit open_toplevel(ci); TQStringList lines = TQStringList::split( '\n', TDEApplication::clipboard()->text( TQClipboard::Selection ), true ); TQStringList::ConstIterator it = lines.begin(); TQStringList::ConstIterator end = lines.end(); for (; it != end; ++it ) { if ((*it).isEmpty()) continue; TQString str = TQString("/msg ") + item->text().lower() + " " + *it + "\n"; emit outputUnicodeLine(str); } } } void KSircTopLevel::dndTextToNickList(const TQListBoxItem *item, const TQString& text) { if(item){ KSircChannel ci(m_channelInfo.server(), item->text().lower()); emit open_toplevel(ci); TQStringList lines = TQStringList::split( '\n', text, true ); TQStringList::ConstIterator it = lines.begin(); TQStringList::ConstIterator end = lines.end(); for (; it != end; ++it ) { if ((*it).isEmpty()) continue; TQString str = TQString("/msg ") + item->text().lower() + " " + *it + "\n"; emit outputUnicodeLine(str); } } } enum KSircTopLevelCommands{ Ask, Parse, Escape }; void KSircTopLevel::slotTextDropped( const TQString& _text ) { if (_text.isEmpty()) return; TQString 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), TQString(), i18n("Send")); if (result != KMessageBox::Continue) { // linee->setText(""); return; } } tab_pressed = -1; if(lines > 1){ linee->setUpdatesEnabled(FALSE); TQStringList lines = TQStringList::split( '\n', text, true ); TQStringList::ConstIterator it = lines.begin(); TQStringList::ConstIterator end = lines.end(); KSircTopLevelCommands commands = Ask; for (; it != end; ++it ) { if ((*it).isEmpty()) continue; TQString 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?" ), TQString(), 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(TQRegExp("\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, TQT_SIGNAL(notTab()), this, TQT_SLOT(lineeNotTab())); addCompleteNick(tab_nick); } void KSircTopLevel::toggleRootWindow() { } bool KSircTopLevel::event( TQEvent *e) { if(e->type() == TQEvent::ApplicationPaletteChange || e->type() == TQEvent::ApplicationFontChange) { TQTimer::singleShot(750, this, TQT_SLOT(initColors())); initColors(); } return TDEMainWindow::event(e); } void KSircTopLevel::saveCurrLog() { KURL url = KURL( KFileDialog::getSaveFileName(TQString(), "*.log", 0L, i18n("Save Chat/Query Logfile"))); if( url.isEmpty()) return; KTempFile temp; TQTextStream *str = temp.textStream(); *str << mainw->plainText(); temp.close(); #if KDE_IS_VERSION(3,1,92) TDEIO::NetAccess::upload(temp.name(), url, this); #else TDEIO::NetAccess::upload(temp.name(), url); #endif } void KSircTopLevel::slotDropURLs( const TQStringList& urls ) { if ( !isPrivateChat() ) return; slotDccURLs( urls, m_channelInfo.channel() ); } // sends the list of urls to $dest_nick void KSircTopLevel::slotDccURLs( const TQStringList& urls, const TQString& nick ) { if ( urls.isEmpty() || nick.isEmpty() ) return; TQStringList::ConstIterator it = urls.begin(); // TQString s("/eval &docommand(eval{\"dcc send " + nick + " %1\"});\n"); TQString s("/dcc send " + nick + " %1\n"); for ( ; it != urls.end(); ++it ) { TQString 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 TQString &message ) { emit outputLine( encoder()->fromUnicode( message ) ); } void KSircTopLevel::setTopicIntern( const TQString &topic ) { TQString command = TQString::fromLatin1( "/topic %1 %2\n" ).arg( m_channelInfo.channel() ).arg( topic ); sirc_write( command ); linee->setFocus(); } void KSircTopLevel::doChange(bool pers, TQString text) { TQTime ctime = TQTime::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 ( TQABS( lastBeep.secsTo( ctime ) ) > 1 ) { if ( pers ) { int winId = !ticker ? topLevelWidget()->winId() : ticker->winId(); KNotifyClient::event(winId, TQString::fromLatin1("ChannelPersonal"), i18n("Your nick appeared on channel %1").arg(m_channelInfo.channel())); } else { int winId = !ticker ? topLevelWidget()->winId() : ticker->winId(); KNotifyClient::event(winId, TQString::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(TQString("%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, TQT_SIGNAL(doubleClick()), this, TQT_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()) { TQString 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(kmr); if(dcc){ dcc->showMgr(); } } } #include "toplevel.moc" // vim: ts=2 sw=2 et