//============================================================================= // // File : kvi_channel.cpp // Creation date : Tue Aug 1 2000 02:20:22 by Szymon Stefanek // // This file is part of the KVirc irc client distribution // Copyright (C) 1999-2004 Szymon Stefanek (pragma at kvirc dot net) // // This program is FREE software. You can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your opinion) any later version. // // This program is distributed in the HOPE that it will be USEFUL, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, write to the Free Software Foundation, // Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // //============================================================================= // // Channel widget : abstraction of an IRC channel // #define __KVIRC__ #include "kvi_toolwindows_container.h" #include "kvi_styled_controls.h" #include "kvi_channel.h" #include "kvi_console.h" #include "kvi_iconmanager.h" #include "kvi_ircview.h" #include "kvi_input.h" #include "kvi_options.h" #include "kvi_locale.h" #include "kvi_topicw.h" #include "kvi_ircsocket.h" #include "kvi_out.h" #include "kvi_malloc.h" #include "kvi_taskbar.h" #include "kvi_frame.h" #include "kvi_config.h" #include "kvi_themedlabel.h" #include "kvi_maskeditor.h" #include "kvi_mirccntrl.h" #include "kvi_settings.h" #include "kvi_parameterlist.h" #include "kvi_modeeditor.h" #include "kvi_app.h" #include "kvi_useraction.h" #include "kvi_ircconnection.h" #include "kvi_ircconnectionserverinfo.h" #include "kvi_defaults.h" #include "kvi_sparser.h" #include "kvi_modew.h" #include "kvi_mirccntrl.h" #ifdef COMPILE_CRYPT_SUPPORT #include "kvi_crypt.h" #include "kvi_cryptcontroller.h" #endif #include "kvi_kvs_script.h" #include "kvi_kvs_eventtriggers.h" #include #include #include #include #include #include #include "kvi_tal_popupmenu.h" #include "kvi_pointerhashtable.h" #include #include "kvi_tal_widgetstack.h" #ifndef AVERAGE_CHANNEL_USERS #define AVERAGE_CHANNEL_USERS 101 #endif // FIXME: #warning "+a Anonymous channel mode!" // FIXME: #warning "+r channel mode (reop)" // FIXME: #warning "OnChannelFlood event...." KviChannel::KviChannel(KviFrame * lpFrm,KviConsole * lpConsole,const char * name) : KviWindow(KVI_WINDOW_TYPE_CHANNEL,lpFrm,name,lpConsole) { // Init some member variables m_pInput = 0; m_iStateFlags = 0; m_pBanList = new KviPointerList; m_pBanList->setAutoDelete(true); m_pBanExceptionList = new KviPointerList; m_pBanExceptionList->setAutoDelete(true); m_pInviteList = new KviPointerList; m_pInviteList->setAutoDelete(true); m_pActionHistory = new KviPointerList; m_pActionHistory->setAutoDelete(true); m_uActionHistoryHotActionCount = 0; m_pTmpHighLighted = new KviPointerHashTable(); m_pTmpHighLighted->setAutoDelete(true); // Register ourselves connection()->registerChannel(this); // And create the widgets layout // Button box m_pButtonBox = new KviTalHBox(this); m_pTopSplitter = new TQSplitter(Qt::Horizontal,m_pButtonBox); m_pButtonBox->setStretchFactor(m_pTopSplitter,1); m_pButtonContainer = new KviTalHBox(m_pButtonBox); // Topic widget on the left m_pTopicWidget = new KviTopicWidget(m_pTopSplitter,"topic_widget"); connect(m_pTopicWidget,TQT_SIGNAL(topicSelected(const TQString &)), this,TQT_SLOT(topicSelected(const TQString &))); // mode label follows the topic widget m_pModeWidget = new KviModeWidget(m_pTopSplitter,this,"mode_"); KviTalToolTip::add(m_pModeWidget,__tr2qs("Channel mode")); createTextEncodingButton(m_pButtonContainer); // Central splitter m_pSplitter = new TQSplitter(Qt::Horizontal,this); #ifdef COMPILE_USE_QT4 m_pSplitter->setObjectName(name); #else m_pSplitter->setName(name); #endif m_pSplitter->setOpaqueResize(false); // Spitted vertially on the left m_pVertSplitter = new TQSplitter(Qt::Vertical,m_pSplitter); m_pVertSplitter->setOpaqueResize(false); // With the IRC view over m_pIrcView = new KviIrcView(m_pVertSplitter,lpFrm,this); #ifdef COMPILE_USE_QT4 m_pIrcView->setObjectName(name); #else m_pIrcView->setName(name); #endif connect(m_pIrcView,TQT_SIGNAL(rightClicked()),this,TQT_SLOT(textViewRightClicked())); // And the double view (that may be unused) m_pMessageView = 0; // The userlist on the right //m_pEditorsContainer= new KviToolWindowsContainer(m_pSplitter); // and the related buttons m_pDoubleViewButton = createToolButton(m_pButtonContainer,"double_view_button",KVI_SMALLICON_HIDEDOUBLEVIEW,KVI_SMALLICON_SHOWDOUBLEVIEW,__tr2qs("Split View"),false); connect(m_pDoubleViewButton,TQT_SIGNAL(clicked()),this,TQT_SLOT(toggleDoubleView())); m_pListViewButton = new KviWindowToolPageButton(KVI_SMALLICON_HIDELISTVIEW,KVI_SMALLICON_SHOWLISTVIEW,__tr2qs("User List"),buttonContainer(),true,"list_view_button"); connect(m_pListViewButton,TQT_SIGNAL(clicked()),this,TQT_SLOT(toggleListView())); m_pBanEditorButton = new KviWindowToolPageButton(KVI_SMALLICON_UNBAN,KVI_SMALLICON_BAN,__tr2qs("Ban Editor"),buttonContainer(),false,"ban_editor_button"); connect(m_pBanEditorButton,TQT_SIGNAL(clicked()),this,TQT_SLOT(toggleBanEditor())); if(m_pConsole->connection()->serverInfo()->supportedListModes().contains('e')) { m_pBanExceptionEditorButton =new KviWindowToolPageButton(KVI_SMALLICON_BANUNEXCEPT,KVI_SMALLICON_BANEXCEPT,__tr2qs("Ban Exception Editor"),buttonContainer(),false,"ban_exception_editor_button"); connect(m_pBanExceptionEditorButton,TQT_SIGNAL(clicked()),this,TQT_SLOT(toggleBanExceptionEditor())); } else { m_pBanExceptionEditorButton=0; } if(m_pConsole->connection()->serverInfo()->supportedListModes().contains('I')) { m_pInviteEditorButton =new KviWindowToolPageButton(KVI_SMALLICON_INVITEUNEXCEPT,KVI_SMALLICON_INVITEEXCEPT,__tr2qs("Invite Exception Editor"),buttonContainer(),false,"invite_exception_editor_button"); connect(m_pInviteEditorButton,TQT_SIGNAL(clicked()),this,TQT_SLOT(toggleInviteEditor())); } else { m_pInviteEditorButton = 0; } m_pModeEditorButton = new KviWindowToolPageButton(KVI_SMALLICON_CHANMODEHIDE,KVI_SMALLICON_CHANMODE,__tr2qs("Mode Editor"),buttonContainer(),false,"mode_editor_button"); connect(m_pModeEditorButton,TQT_SIGNAL(clicked()),this,TQT_SLOT(toggleModeEditor())); m_pModeEditor = 0; #ifdef COMPILE_CRYPT_SUPPORT createCryptControllerButton(m_pButtonContainer); #endif m_pHideToolsButton = new KviStyledToolButton(m_pButtonBox,"hide_container_button"); #ifndef COMPILE_USE_QT4 m_pHideToolsButton->setUsesBigPixmap(false); #else m_pHideToolsButton->setAutoRaise(true); #endif m_pHideToolsButton->setFixedWidth(10); if(g_pIconManager->getBigIcon("kvi_horizontal_left.png")) m_pHideToolsButton->setPixmap(*(g_pIconManager->getBigIcon("kvi_horizontal_left.png"))); connect(m_pHideToolsButton,TQT_SIGNAL(clicked()),this,TQT_SLOT(toggleToolButtons())); m_pUserListView = new KviUserListView(m_pSplitter,m_pListViewButton,connection()->userDataBase(),this, AVERAGE_CHANNEL_USERS,__tr2qs("User List"),"user_list_view"); // m_pEditorsContainer->addWidget(m_pUserListView); // m_pEditorsContainer->raiseWidget(m_pUserListView); // And finally the input line on the bottom m_pInput = new KviInput(this,m_pUserListView); // no mask editors yet m_pBanEditor = 0; m_pBanExceptionEditor = 0; m_pInviteEditor = 0; // Ensure proper focusing //setFocusHandler(m_pInput,this); // And turn on the secondary IRC view if needed if(KVI_OPTION_BOOL(KviOption_boolAutoLogChannels))m_pIrcView->startLogging(); applyOptions(); m_joinTime = TQDateTime::currentDateTime(); m_tLastReceivedWhoReply = (kvi_time_t)m_joinTime.toTime_t(); } KviChannel::~KviChannel() { // Unregister ourself if(type() == KVI_WINDOW_TYPE_DEADCHANNEL)context()->unregisterDeadChannel(this); else connection()->unregisterChannel(this); // Then remove all the users and free mem m_pUserListView->enableUpdates(false); m_pUserListView->partAll(); delete m_pActionHistory; delete m_pBanList; delete m_pBanExceptionList; delete m_pInviteList; delete m_pTmpHighLighted; } void KviChannel::toggleToolButtons() { if(!buttonContainer()) return; toggleButtonContainer(); TQPixmap* pix= buttonContainer()->isVisible() ? g_pIconManager->getBigIcon("kvi_horizontal_left.png") : g_pIconManager->getBigIcon("kvi_horizontal_right.png"); if(pix) m_pHideToolsButton->setPixmap(*pix); } void KviChannel::triggerCreationEvents() { KVS_TRIGGER_EVENT_0(KviEvent_OnChannelWindowCreated,this); } void KviChannel::textViewRightClicked() { KVS_TRIGGER_EVENT_0(KviEvent_OnChannelPopupRequest,this); } void KviChannel::getBaseLogFileName(TQString &buffer) { TQString szChan(windowName()); szChan.replace(".","%2e"); if (console()->connection()) { buffer=szChan; buffer.append("."); buffer.append(console()->currentNetworkName()); } else { buffer=szChan; buffer.append("."); buffer.append(console()->ircContextId()); } } void KviChannel::applyOptions() { m_pUserListView->applyOptions(); m_pTopicWidget->applyOptions(); if(m_pMessageView)m_pMessageView->applyOptions(); m_pModeWidget->applyOptions(); // this applies options for IrcView and Input and forces the window to relayout KviWindow::applyOptions(); } void KviChannel::getConfigGroupName(TQString &buf) { buf = windowName(); } void KviChannel::saveProperties(KviConfig *cfg) { KviWindow::saveProperties(cfg); cfg->writeEntry("TopSplitter",m_pTopSplitter->sizes()); cfg->writeEntry("Splitter",m_pSplitter->sizes()); #ifdef COMPILE_USE_QT4 TQPtrList tmp = m_pVertSplitter->sizes(); KviValueList tmp2; for(TQPtrList::Iterator it = tmp.begin();it != tmp.end();++it) tmp2.append(*it); cfg->writeEntry("VertSplitter",m_pMessageView ? tmp2 : m_VertSplitterSizesList); #else cfg->writeEntry("VertSplitter",m_pMessageView ? m_pVertSplitter->sizes() : m_VertSplitterSizesList); #endif cfg->writeEntry("PrivateBackground",m_privateBackground); cfg->writeEntry("DoubleView",m_pMessageView ? true : false); if(m_pUserListView) cfg->writeEntry("UserListHidden",m_pUserListView->isHidden()); cfg->writeEntry("ToolButtonsHidden",buttonContainer()->isHidden()); } void KviChannel::loadProperties(KviConfig *cfg) { int w = width(); KviValueList def; def.append((w * 75) / 100); def.append((w * 15) / 100); def.append((w * 10) / 100); m_pTopSplitter->setSizes(cfg->readIntListEntry("TopSplitter",def)); def.clear(); def.append((w * 82) / 100); def.append((w * 18) / 100); m_pSplitter->setSizes(cfg->readIntListEntry("Splitter",def)); //debug("SETTING DEFAULT SIZES"); def.clear(); def.append((w * 60) / 100); def.append((w * 40) / 100); m_VertSplitterSizesList=cfg->readIntListEntry("VertSplitter",def); showDoubleView(cfg->readBoolEntry("DoubleView",false)); //def.append((w * 50) / 100); //def.append((w * 50) / 100); m_privateBackground = cfg->readPixmapEntry("PrivateBackground",KviPixmap()); if(m_privateBackground.pixmap()) { m_pIrcView->setPrivateBackgroundPixmap(*(m_privateBackground.pixmap())); if(m_pMessageView)m_pMessageView->setPrivateBackgroundPixmap(*(m_privateBackground.pixmap())); } KviWindow::loadProperties(cfg); if(m_pUserListView) { bool bHidden=cfg->readBoolEntry("UserListHidden",0); m_pUserListView->setHidden(bHidden); resizeEvent(0); } if(cfg->readBoolEntry("ToolButtonsHidden",KVI_OPTION_BOOL(KviOption_boolHideWindowToolButtons))!=buttonContainer()->isHidden()) toggleToolButtons(); } void KviChannel::showDoubleView(bool bShow) { if(m_pMessageView) { if(bShow)return; m_pIrcView->joinMessagesFrom(m_pMessageView); m_VertSplitterSizesList=m_pVertSplitter->sizes(); delete m_pMessageView; m_pMessageView = 0; if(m_pDoubleViewButton->isOn())m_pDoubleViewButton->setOn(false); } else { if(!bShow)return; m_pMessageView = new KviIrcView(m_pVertSplitter,m_pFrm,this); m_pVertSplitter->setSizes(m_VertSplitterSizesList); //setFocusHandler(m_pInput,m_pMessageView); //socket it! if(!(m_pDoubleViewButton->isOn()))m_pDoubleViewButton->setOn(true); if(m_privateBackground.pixmap()) { m_pMessageView->setPrivateBackgroundPixmap(*(m_privateBackground.pixmap())); } connect(m_pMessageView,TQT_SIGNAL(rightClicked()),this,TQT_SLOT(textViewRightClicked())); m_pMessageView->setMasterView(m_pIrcView); m_pIrcView->splitMessagesTo(m_pMessageView); m_pMessageView->show(); } } void KviChannel::toggleDoubleView() { showDoubleView(!m_pMessageView); } void KviChannel::toggleListView() { if(m_pUserListView->isVisible()) { m_pUserListView->hide(); if(m_pListViewButton->isOn())m_pListViewButton->setOn(false); } else { m_pUserListView->show(); if(!(m_pListViewButton->isOn()))m_pListViewButton->setOn(true); } } void KviChannel::toggleModeEditor() { if(m_pModeEditor) { delete m_pModeEditor; m_pModeEditor = 0; m_pSplitter->setMinimumHeight(20); //gfgf if(m_pModeEditorButton->isOn()) m_pModeEditorButton->setOn(false); resizeEvent(0); } else { m_pModeEditor = new KviModeEditor(m_pSplitter,m_pModeEditorButton,"mode_editor",console(),m_szChannelMode,m_szChannelKey,m_szChannelLimit.ptr()); connect(m_pModeEditor,TQT_SIGNAL(setMode(const char *)),this,TQT_SLOT(setMode(const char *))); connect(m_pModeEditor,TQT_SIGNAL(done()),this,TQT_SLOT(modeSelectorDone())); m_pModeEditor->show(); //setFocusHandlerNoClass(m_pInput,m_pModeEditor,TQLINEEDIT_OBJECT_NAME_STRING); if(!m_pModeEditorButton->isOn())m_pModeEditorButton->setOn(true); } } void KviChannel::modeSelectorDone() { if(m_pModeEditor)toggleModeEditor(); } void KviChannel::setMode(const char * mode) { if(!connection())return; KviTQCString tmp = connection()->encodeText(m_szName); connection()->sendFmtData("MODE %s %s",tmp.data(),mode); } void KviChannel::toggleBanEditor() { toggleEditor(&m_pBanEditor,&m_pBanEditorButton, m_pBanList,'b',"ban_editor"); } void KviChannel::toggleBanExceptionEditor() { toggleEditor(&m_pBanExceptionEditor,&m_pBanExceptionEditorButton, m_pBanExceptionList,'e',"ban_exception_editor"); } void KviChannel::toggleInviteEditor() { toggleEditor(&m_pInviteEditor,&m_pInviteEditorButton, m_pInviteList,'I',"invite_exception_editor"); } void KviChannel::toggleEditor(KviMaskEditor ** ppEd,KviWindowToolPageButton ** ppBtn,KviPointerList *l,char flag,const char *edName) { if(*ppEd) { delete *ppEd; *ppEd = 0; if(!(*ppBtn))return; if((*ppBtn)->isOn()) (*ppBtn)->setOn(false); } else { bool bHasList = true; switch(flag) { case 'b': if(!(bHasList = hasBanList())) { m_pBanList->clear(); setSentBanListRequest(); } break; case 'e': if(!(bHasList = hasBanExceptionList())) { m_pBanExceptionList->clear(); setSentBanExceptionListRequest(); } break; case 'I': if(!(bHasList = hasInviteList())) { m_pInviteList->clear(); setSentInviteListRequest(); } break; } if(!bHasList) { if(connection()) { KviTQCString szName = connection()->encodeText(m_szName); connection()->sendFmtData("MODE %s %c",szName.data(),flag); } } *ppEd = new KviMaskEditor(m_pSplitter,*ppBtn,l,flag,edName); connect(*ppEd,TQT_SIGNAL(removeMasks(KviMaskEditor *,KviPointerList *)), this,TQT_SLOT(removeMasks(KviMaskEditor *,KviPointerList *))); //setFocusHandler(m_pInput,*ppEd); //socket it! (*ppEd)->show(); if(!(*ppBtn))return; if(!((*ppBtn)->isOn()))(*ppBtn)->setOn(true); } } void KviChannel::removeMasks(KviMaskEditor *ed,KviPointerList *l) { KviStr masks; KviStr flags; unsigned int count = 0; for(KviMaskEntry * e = l->first();e;e = l->next()) { if(masks.hasData())masks.append(' '); masks.append(e->szMask); flags.append(ed->flag()); count++; if(count == connection()->serverInfo()->maxModeChanges()) { if(connection()) { KviTQCString szName = connection()->encodeText(m_szName); connection()->sendFmtData("MODE %s -%s %s",szName.data(),flags.ptr(),connection()->encodeText(TQString(masks)).data()); } flags = ""; masks = ""; count = 0; } } if(masks.hasData()) { if(connection()) { KviTQCString szName = connection()->encodeText(m_szName); connection()->sendFmtData("MODE %s -%s %s",szName.data(),flags.ptr(),connection()->encodeText(TQString(masks)).data()); } } } TQPixmap * KviChannel::myIconPtr() { return g_pIconManager->getSmallIcon((m_iStateFlags & KVI_CHANNEL_STATE_DEADCHAN) ? KVI_SMALLICON_DEADCHANNEL : KVI_SMALLICON_CHANNEL); } void KviChannel::resizeEvent(TQResizeEvent *e) { #ifdef COMPILE_USE_QT4 int hght = m_pInput->heightHint(); int hght2 = m_pTopicWidget->sizeHint().height(); m_pButtonBox->setGeometry(0,0,width(),hght2); m_pSplitter->setGeometry(0,hght2,width(),height() - (hght + hght2)); m_pInput->setGeometry(0,height() - hght,width(),hght); #else int hght = m_pInput->heightHint(); int hght2 = m_pButtonBox->sizeHint().height(); m_pButtonBox->setGeometry(0,0,width(),hght2); m_pSplitter->setGeometry(0,hght2,width(),height() - (hght + hght2)); m_pInput->setGeometry(0,height() - hght,width(),hght); #endif } TQSize KviChannel::sizeHint() const { TQSize ret(m_pSplitter->sizeHint().width(), m_pIrcView->sizeHint().height() + m_pInput->heightHint() + m_pButtonBox->sizeHint().height()); return ret; } void KviChannel::setChannelMode(char mode,bool bAdd) { if(!m_pConsole->connection()->serverInfo()->supportedListModes().contains(mode)){ if(bAdd) { if(!(m_szChannelMode.contains(mode)))m_szChannelMode.append(mode); } else { if(m_szChannelMode.contains(mode)) { m_szChannelMode.replace(mode,""); } } updateModeLabel(); updateCaption(); } } void KviChannel::setChannelKey(const char * key) { m_szChannelKey = key; updateModeLabel(); updateCaption(); } void KviChannel::setChannelLimit(const char * limit) { m_szChannelLimit = limit; updateModeLabel(); updateCaption(); } void KviChannel::addHighlightedUser(const char * nick) { if(!m_pUserListView->findEntry(nick))return; else m_pTmpHighLighted->replace(nick,new TQString()); } void KviChannel::removeHighlightedUser(const char * nick) { m_pTmpHighLighted->remove(nick); } void KviChannel::getChannelModeString(TQString &buffer) { buffer = m_szChannelMode; if(!m_szChannelKey.isEmpty())buffer.append('k'); if(m_szChannelLimit.hasData())buffer.append('l'); } void KviChannel::setDeadChan() { m_iStateFlags |= KVI_CHANNEL_STATE_DEADCHAN; m_iStateFlags &= ~(KVI_CHANNEL_STATE_NOCLOSEONPART | KVI_CHANNEL_STATE_SENTSYNCWHOREQUEST); m_pUserListView->enableUpdates(false); m_pUserListView->partAll(); m_pUserListView->enableUpdates(true); m_pUserListView->setUserDataBase(0); m_pBanList->clear(); m_pBanExceptionList->clear(); m_pInviteList->clear(); m_pActionHistory->clear(); m_uActionHistoryHotActionCount = 0; m_szChannelMode = ""; m_szChannelKey = ""; m_szChannelLimit = ""; // this should be moved to irc context! connection()->unregisterChannel(this); context()->registerDeadChannel(this); setType(KVI_WINDOW_TYPE_DEADCHANNEL); updateIcon(); updateModeLabel(); updateCaption(); } void KviChannel::setAliveChan() { // Rise like phoenix! m_iStateFlags = 0; setType(KVI_WINDOW_TYPE_CHANNEL); m_pUserListView->setUserDataBase(connection()->userDataBase()); m_joinTime = TQDateTime::currentDateTime(); context()->unregisterDeadChannel(this); connection()->registerChannel(this); // Update log file name if(m_pIrcView->isLogging())m_pIrcView->startLogging(); updateIcon(); updateCaption(); m_pTopicWidget->reset(); // reset the topic (fixes bug #20 signaled by Klaus Weidenbach) } void KviChannel::getTalkingUsersStats(TQString &buffer,TQStringList &l,bool bPast) { if(l.count() < 1)return; if(l.count() == 1) { buffer += ""; buffer += l.first(); buffer += ""; buffer += " "; buffer += bPast ? __tr2qs("said something recently") : __tr2qs("is talking"); } else if(l.count() == 2) { buffer += ""; buffer += l.first(); buffer += " "; buffer += __tr2qs("and"); buffer += " "; l.remove(l.begin()); buffer += l.first(); buffer += " "; buffer += bPast ? __tr2qs("were talking recently") : __tr2qs("are talking"); } else { buffer += ""; buffer += l.first(); buffer += ", "; l.remove(l.begin()); buffer += l.first(); if(l.count() == 2) { buffer += " "; buffer += __tr2qs("and"); buffer += " "; l.remove(l.begin()); buffer += l.first(); buffer += ""; } else { // (l.count() - 1) is > 1 buffer += " "; buffer += __tr2qs("and other %1 users").arg(l.count() - 1); } buffer += " "; buffer += bPast ? __tr2qs("were talking recently") : __tr2qs("are talking"); } } void KviChannel::getTaskBarTipText(TQString &buffer) { static TQString html_bold(""); static TQString html_tab("  "); static TQString html_eofbold(" "); static TQString p5(" ("); // p6 == p4 static TQString p7(" ("); static TQString p8(": "); static TQString p9(")"); static TQString p10("
"); static TQString end_of_doc = ""; static TQString end_of_fontboldrow = END_TABLE_BOLD_ROW; static TQString start_of_row = ""; static TQString end_of_row = ""; buffer = "" \ "" \ ""\ START_TABLE_BOLD_ROW; if(m_iStateFlags & KVI_CHANNEL_STATE_DEADCHAN) { buffer += __tr2qs("Dead channel"); buffer += end_of_fontboldrow; buffer += end_of_doc; return; } KviUserListViewUserStats s; m_pUserListView->userStats(&s); buffer += m_szPlainTextCaption; buffer += end_of_fontboldrow; buffer += start_of_row; TQString op = __tr2qs("operator"); TQString ops = __tr2qs("operators"); ////////////////////// buffer += html_tab; buffer += html_bold; TQString num; num.setNum(s.uActive); buffer += num; buffer += html_eofbold; buffer += (s.uActive == 1 ? __tr2qs("active user") : __tr2qs("active users")); buffer += p5; buffer += html_bold; num.setNum(s.uActiveOp); buffer += num; buffer += html_eofbold; buffer += (s.uActiveOp == 1 ? op : ops); buffer += p9; /* * #warning FIXME: What is this supposed to mean? buffer += ""; buffer += p7; buffer += __tr2qs("humanity"); buffer += p8; buffer += html_bold; num.setNum(s.iAvgTemperature); buffer += num; buffer += ""; buffer += p9; */ buffer += p10; buffer += ""; ////////////////////// buffer += html_tab; buffer += html_bold; num.setNum(s.uHot); buffer += num; buffer += html_eofbold; buffer += (s.uHot == 1 ? __tr2qs("hot user") : __tr2qs("hot users")); buffer += p5; buffer += html_bold; num.setNum(s.uHotOp); buffer += num; buffer += html_eofbold; buffer += (s.uHotOp == 1 ? op : ops); buffer += p9; ///////////// buffer += end_of_row; buffer += start_of_row; /////////////////// if(s.uChanOwner > 0) { buffer += html_tab; buffer += html_bold; num.setNum(s.uChanOwner); buffer += num; buffer += html_eofbold; buffer += (s.uChanOwner == 1 ? __tr2qs("channel owner") : __tr2qs("channel owners")); buffer += p10; } if(s.uChanAdmin > 0) { buffer += html_tab; buffer += html_bold; num.setNum(s.uChanAdmin); buffer += num; buffer += html_eofbold; buffer += (s.uChanAdmin == 1 ? __tr2qs("channel administrator") : __tr2qs("channel administrators")); buffer += p10; } if(s.uOp > 0) { buffer += html_tab; buffer += html_bold; num.setNum(s.uOp); buffer += num; buffer += html_eofbold; buffer += (s.uOp == 1 ? op : ops); buffer += p10; } if(s.uHalfOp > 0) { buffer += html_tab; buffer += html_bold; num.setNum(s.uHalfOp); buffer += num; buffer += html_eofbold; buffer += (s.uHalfOp == 1 ? __tr2qs("half-operator") : __tr2qs("half-operators")); buffer += p10; } if(s.uVoiced > 0) { buffer += html_tab; buffer += html_bold; num.setNum(s.uVoiced); buffer += num; buffer += html_eofbold; buffer += (s.uVoiced == 1 ? __tr2qs("voiced user") : __tr2qs("voiced users")); buffer += p10; } if(s.uUserOp > 0) { buffer += html_tab; buffer += html_bold; num.setNum(s.uUserOp); buffer += num; buffer += html_eofbold; buffer += (s.uUserOp == 1 ? __tr2qs("user-operator") : __tr2qs("user-operators")); buffer += p10; } buffer += html_tab; buffer += html_bold; num.setNum(s.uTotal); buffer += num; buffer += html_eofbold; buffer += (s.uTotal == 1 ? __tr2qs("user total") : __tr2qs("users total")); buffer += end_of_row; KviChannelActivityStats cas; getChannelActivityStats(&cas); if(cas.lTalkingUsers.count() > 0) { if((cas.lTalkingUsers.count() < 3) && (cas.lWereTalkingUsers.count() > 0)) { buffer += ""; buffer += end_of_doc; } void KviChannel::fillCaptionBuffers() { static TQString begin(""); static TQString endofbold(" "); static TQString end(""); if(!connection()) { TQString dead = __tr2qs("[Dead channel]"); m_szNameWithUserFlag = m_szName; m_szPlainTextCaption = m_szName; m_szPlainTextCaption += " : "; m_szPlainTextCaption += dead; m_szHtmlActiveCaption = begin; m_szHtmlActiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name(); m_szHtmlActiveCaption += boldbegin; m_szHtmlActiveCaption += m_szName; m_szHtmlActiveCaption += endofbold; m_szHtmlActiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextActive2).name(); m_szHtmlActiveCaption += endoffont; m_szHtmlActiveCaption += dead; m_szHtmlActiveCaption += end; m_szHtmlInactiveCaption = begin; m_szHtmlInactiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name(); m_szHtmlInactiveCaption += boldbegin; m_szHtmlInactiveCaption += m_szName; m_szHtmlInactiveCaption += endofbold; m_szHtmlInactiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive2).name(); m_szHtmlInactiveCaption += endoffont; m_szHtmlInactiveCaption += dead; m_szHtmlInactiveCaption += end; return; } char uFlag = getUserFlag(connection()->currentNickName()); if(uFlag) { m_szNameWithUserFlag = TQChar(uFlag); m_szNameWithUserFlag += m_szName; } else { m_szNameWithUserFlag = m_szName; } TQString szChanMode; getChannelModeString(szChanMode); m_szPlainTextCaption = m_szNameWithUserFlag; if(!szChanMode.isEmpty()) { m_szPlainTextCaption += " (+"; m_szPlainTextCaption += szChanMode; m_szPlainTextCaption += TQChar(')'); } TQString szNickOnServer = TQChar('['); szNickOnServer += connection()->currentNickName(); szNickOnServer += __tr2qs(" on "); szNickOnServer += connection()->currentServerName(); szNickOnServer += TQChar(']'); m_szPlainTextCaption += TQChar(' '); m_szPlainTextCaption += szNickOnServer; m_szHtmlActiveCaption = begin; m_szHtmlActiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name(); m_szHtmlActiveCaption += boldbegin; m_szHtmlActiveCaption += m_szNameWithUserFlag; m_szHtmlActiveCaption += endofbold; m_szHtmlActiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextActive2).name(); m_szHtmlActiveCaption += endoffont; m_szHtmlActiveCaption += szNickOnServer; m_szHtmlActiveCaption += end; m_szHtmlInactiveCaption = begin; m_szHtmlInactiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name(); m_szHtmlInactiveCaption += boldbegin; m_szHtmlInactiveCaption += m_szNameWithUserFlag; m_szHtmlInactiveCaption += endofbold; m_szHtmlInactiveCaption += KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive2).name(); m_szHtmlInactiveCaption += endoffont; m_szHtmlInactiveCaption += szNickOnServer; m_szHtmlInactiveCaption += end; } void KviChannel::ownMessage(const TQString &buffer) { if(!connection())return; KviTQCString szName = connection()->encodeText(windowName()); KviTQCString szData = encodeText(buffer); const char * d = szData.data(); if(!d)return; #ifdef COMPILE_CRYPT_SUPPORT if(cryptSessionInfo()) { if(cryptSessionInfo()->bDoEncrypt) { if(*d != KVI_TEXT_CRYPTESCAPE) { KviStr encrypted; cryptSessionInfo()->pEngine->setMaxEncryptLen(500 - szName.length()); switch(cryptSessionInfo()->pEngine->encrypt(d,encrypted)) { case KviCryptEngine::Encrypted: if(!connection()->sendFmtData("PRIVMSG %s :%s",szName.data(),encrypted.ptr()))return; m_pConsole->outputPrivmsg(this,KVI_OUT_OWNPRIVMSGCRYPTED, TQString(),TQString(),TQString(),buffer,KviConsole::NoNotifications); break; case KviCryptEngine::Encoded: { if(!connection()->sendFmtData("PRIVMSG %s :%s",szName.data(),encrypted.ptr()))return; // ugly ,but we must redecode here TQString szRedecoded = decodeText(encrypted.ptr()); m_pConsole->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG, TQString(),TQString(),TQString(),szRedecoded,KviConsole::NoNotifications); } break; default: // also case KviCryptEngine::EncryptError { TQString szEngineError = cryptSessionInfo()->pEngine->lastError(); output(KVI_OUT_SYSTEMERROR, __tr2qs("The crypto engine was unable to encrypt the current message (%Q): %Q, no data sent to the server"), &buffer,&szEngineError); } break; } userAction(connection()->currentNickName(),KVI_USERACTION_PRIVMSG); return; } else { d++; //eat the escape code TQString tmp = buffer.right(buffer.length() - 1); if(!connection()->sendFmtData("PRIVMSG %s :%s",szName.data(),d))return; m_pConsole->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG,TQString(),TQString(),TQString(),tmp,KviConsole::NoNotifications); userAction(connection()->currentNickName(),KVI_USERACTION_PRIVMSG); return; } } } #endif if(connection()->sendFmtData("PRIVMSG %s :%s",szName.data(),d)) { m_pConsole->outputPrivmsg(this,KVI_OUT_OWNPRIVMSG,TQString(),TQString(),TQString(),buffer,KviConsole::NoNotifications); userAction(connection()->currentNickName(),KVI_USERACTION_PRIVMSG); } } void KviChannel::ownAction(const TQString &buffer) { if(!connection())return; KviTQCString szName = connection()->encodeText(m_szName); KviTQCString szData = encodeText(buffer); const char * d = szData.data(); if(!d)return; if(!connection()->sendFmtData("PRIVMSG %s :%cACTION %s%c",szName.data(),0x01,d,0x01))return; if(KVS_TRIGGER_EVENT_1_HALTED(KviEvent_OnMeAction,this,TQString(d)))return; TQString szBuffer = "\r!nc\r"; szBuffer += connection()->currentNickName(); szBuffer += "\r "; szBuffer += buffer; outputMessage(KVI_OUT_ACTION,szBuffer); userAction(connection()->currentNickName(),KVI_USERACTION_ACTION); } bool KviChannel::nickChange(const TQString &oldNick,const TQString &newNick) { bool bWasHere = m_pUserListView->nickChange(oldNick,newNick); if(bWasHere)channelAction(newNick,KVI_USERACTION_NICK,kvi_getUserActionTemperature(KVI_USERACTION_NICK)); return bWasHere; } bool KviChannel::part(const TQString &nick) { bool bWasHere = m_pUserListView->part(nick); if(bWasHere)channelAction(nick,KVI_USERACTION_PART,kvi_getUserActionTemperature(KVI_USERACTION_PART)); return bWasHere; } #define KVI_CHANACTIVITY_LIMIT_ICE 5 #define KVI_CHANACTIVITY_LIMIT_VERYCOLD 10 #define KVI_CHANACTIVITY_LIMIT_COLD 20 #define KVI_CHANACTIVITY_LIMIT_UNDEFINED 30 #define KVI_CHANACTIVITY_LIMIT_HOT 50 #define KVI_CHANACTIVITY_LIMIT_VERYHOT 70 bool KviChannel::activityMeter(unsigned int * puActivityValue,unsigned int * puActivityTemperature) { fixActionHistory(); unsigned int uHotActionPercent; double dActionsPerMinute; if(m_pActionHistory->count() < 1) { // nothing is happening uHotActionPercent = 0; dActionsPerMinute = 0; } else { kvi_time_t tNow = kvi_unixTime(); KviChannelAction * a = m_pActionHistory->last(); double dSpan = (double)(tNow - a->tTime); if(m_pActionHistory->count() < KVI_CHANNEL_ACTION_HISTORY_MAX_COUNT) { if(m_joinTime.secsTo(TQDateTime::currentDateTime()) < KVI_CHANNEL_ACTION_HISTORY_MAX_TIMESPAN) { // we can't exactly estimate if(dSpan < 60.0)dSpan = 60.0; } else { // there are less actions at all or they have been pushed out because of the timespan dSpan = KVI_CHANNEL_ACTION_HISTORY_MAX_TIMESPAN; } } // else the actions have been pushed out of the history because they were too much if(dSpan > 0.0) dActionsPerMinute = (((double)(m_pActionHistory->count())) / (dSpan)) * 60.0; else dActionsPerMinute = (double)(m_pActionHistory->count()); // ??? uHotActionPercent = (m_uActionHistoryHotActionCount * 100) / (m_pActionHistory->count()); } if(dActionsPerMinute < 0.3)*puActivityValue = KVI_ACTIVITY_NONE; else if(dActionsPerMinute < 1.0)*puActivityValue = KVI_ACTIVITY_VERYLOW; else if(dActionsPerMinute < 4.0)*puActivityValue = KVI_ACTIVITY_LOW; else if(dActionsPerMinute < 10.0)*puActivityValue = KVI_ACTIVITY_MEDIUM; else if(dActionsPerMinute < 30.0)*puActivityValue = KVI_ACTIVITY_HIGH; else *puActivityValue = KVI_ACTIVITY_VERYHIGH; if(uHotActionPercent < KVI_CHANACTIVITY_LIMIT_ICE)*puActivityTemperature = KVI_ACTIVITY_ICE; else if(uHotActionPercent < KVI_CHANACTIVITY_LIMIT_VERYCOLD)*puActivityTemperature = KVI_ACTIVITY_VERYCOLD; else if(uHotActionPercent < KVI_CHANACTIVITY_LIMIT_COLD)*puActivityTemperature = KVI_ACTIVITY_COLD; else if(uHotActionPercent < KVI_CHANACTIVITY_LIMIT_UNDEFINED)*puActivityTemperature = KVI_ACTIVITY_UNDEFINED; else if(uHotActionPercent < KVI_CHANACTIVITY_LIMIT_HOT)*puActivityTemperature = KVI_ACTIVITY_HOT; else if(uHotActionPercent < KVI_CHANACTIVITY_LIMIT_VERYHOT)*puActivityTemperature = KVI_ACTIVITY_VERYHOT; else *puActivityTemperature = KVI_ACTIVITY_FIRE; return true; } void KviChannel::channelAction(const TQString &nick,unsigned int uActionType,int iTemperature) { KviChannelAction * a = new KviChannelAction; a->tTime = kvi_unixTime(); a->uActionType = uActionType; a->iTemperature = iTemperature; a->szNick = nick; if(iTemperature > 0)m_uActionHistoryHotActionCount++; m_pActionHistory->append(a); fixActionHistory(); } void KviChannel::fixActionHistory() { while(m_pActionHistory->count() > KVI_CHANNEL_ACTION_HISTORY_MAX_COUNT)m_pActionHistory->removeFirst(); KviChannelAction * a = m_pActionHistory->last(); if(!a)return; kvi_time_t tMinimum = a->tTime - KVI_CHANNEL_ACTION_HISTORY_MAX_TIMESPAN; KviChannelAction * act = m_pActionHistory->first(); while(act && (act->tTime < tMinimum)) { if(act->iTemperature > 0)m_uActionHistoryHotActionCount--; m_pActionHistory->removeFirst(); act = m_pActionHistory->first(); } } void KviChannel::lostUserFocus() { KviWindow::lostUserFocus(); if(!m_pMessageView)return; if(m_pMessageView->hasLineMark())m_pMessageView->clearLineMark(true); } void KviChannel::getChannelActivityStats(KviChannelActivityStats * s) { fixActionHistory(); s->uActionCount = m_pActionHistory->count(); s->iAverageActionTemperature = 0; s->uActionsInTheLastMinute = 0; s->uHotActionCount = 0; s->uHotActionPercent = 0; s->bStatsInaccurate = false; if(s->uActionCount < 1) { // nothing is happening s->uLastActionTimeSpan = 0; s->uFirstActionTimeSpan = 0; s->dActionsPerMinute = 0; return; } kvi_time_t tNow = kvi_unixTime(); KviChannelAction * a = m_pActionHistory->last(); s->uLastActionTimeSpan = tNow - a->tTime; a = m_pActionHistory->first(); s->uFirstActionTimeSpan = tNow - a->tTime; double dSpan = (double)s->uFirstActionTimeSpan; if(s->uActionCount < KVI_CHANNEL_ACTION_HISTORY_MAX_COUNT) { if(m_joinTime.secsTo(TQDateTime::currentDateTime()) < KVI_CHANNEL_ACTION_HISTORY_MAX_TIMESPAN) { // we can't exactly estimate s->bStatsInaccurate = true; if(dSpan < 60.0)dSpan = 60.0; } else { // there are less actions at all or they have been pushed out because of the timespan dSpan = KVI_CHANNEL_ACTION_HISTORY_MAX_TIMESPAN; } } // else the actions have been pushed out of the history because they were too much if(dSpan > 0.0) s->dActionsPerMinute = (((double)s->uActionCount) / (dSpan)) * 60.0; else s->dActionsPerMinute = (double)s->uActionCount; // ??? kvi_time_t tTwoMinsAgo = tNow; tTwoMinsAgo-= 120; tNow -= 60; KviPointerHashTable userDict; userDict.setAutoDelete(false); int fake; s->lTalkingUsers.clear(); s->lWereTalkingUsers.clear(); for(a = m_pActionHistory->last();a;a = m_pActionHistory->prev()) { if(a->tTime >= tNow)s->uActionsInTheLastMinute++; if(a->iTemperature > 0)s->uHotActionCount++; s->iAverageActionTemperature += a->iTemperature; if((a->uActionType == KVI_USERACTION_PRIVMSG) || (a->uActionType == KVI_USERACTION_NOTICE) || (a->uActionType == KVI_USERACTION_ACTION)) { if(!userDict.find(a->szNick)) { if(isOn(a->szNick.ascii())) { if(a->tTime >= tTwoMinsAgo)s->lTalkingUsers.append(a->szNick); else s->lWereTalkingUsers.append(a->szNick); userDict.insert(a->szNick,&fake); } } } } s->iAverageActionTemperature = s->iAverageActionTemperature / (int)s->uActionCount; s->uHotActionPercent = (s->uHotActionCount * 100) / s->uActionCount; } void KviChannel::userAction(const TQString &nick,const TQString &user,const TQString &host,unsigned int uActionType) { int iTemperature = kvi_getUserActionTemperature(uActionType); channelAction(nick,uActionType,iTemperature); m_pUserListView->userAction(nick,user,host,iTemperature); } void KviChannel::userAction(const TQString &nick,unsigned int uActionType) { int iTemperature = kvi_getUserActionTemperature(uActionType); channelAction(nick,uActionType,iTemperature); m_pUserListView->userAction(nick,iTemperature); } void KviChannel::userAction(KviIrcMask * user,unsigned int uActionType) { int iTemperature = kvi_getUserActionTemperature(uActionType); channelAction(user->nick(),uActionType,iTemperature); m_pUserListView->userAction(user,iTemperature); } void KviChannel::topicSelected(const TQString & topic) { if(!connection())return; KviTQCString szEncoded = encodeText(topic); KviTQCString szName = connection()->encodeText(m_szName); connection()->sendFmtData("TOPIC %s :%s",szName.data(),szEncoded.length() ? szEncoded.data() : ""); } void KviChannel::closeEvent(TQCloseEvent *e) { if((m_iStateFlags & KVI_CHANNEL_STATE_SENTPART) || (m_iStateFlags & KVI_CHANNEL_STATE_DEADCHAN) || !(m_pConsole->isConnected())) { m_pContext->unregisterDeadChannel(this); KviWindow::closeEvent(e); } else { e->ignore(); // FIXME: #warning "THIS PART SHOULD BECOME A COMMAND /PART $option()..so the identifiers are parsed" if(connection()) { TQString tmp = KVI_OPTION_STRING(KviOption_stringPartMessage); tmp.replace(";","\\;"); tmp.replace("\n"," "); KviKvsVariant vRet; if(KviKvsScript::evaluate(tmp,this,0,&vRet))vRet.asString(tmp); KviTQCString dat = encodeText(tmp); partMessageSent(); KviTQCString szName = connection()->encodeText(m_szName); connection()->sendFmtData("PART %s :%s",szName.data(),dat.data() ? dat.data() : ""); // be sure to not reference ourselves here.. we could be disconnected! } else { partMessageSent(); // huh ? } } } void KviChannel::partMessageSent(bool bCloseOnPart,bool bShowMessage) { m_iStateFlags |= KVI_CHANNEL_STATE_SENTPART; if(!bCloseOnPart)m_iStateFlags |= KVI_CHANNEL_STATE_NOCLOSEONPART; if(bShowMessage)outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Sent part request, waiting for reply...")); } #define IS_FNC(__name,__ulvname) \ bool KviChannel::__name(bool bAtLeast) \ { \ if(!connection())return false; \ return m_pUserListView->__ulvname(connection()->currentNickName(),bAtLeast); \ } IS_FNC(isMeChanOwner,isChanOwner) IS_FNC(isMeChanAdmin,isChanAdmin) IS_FNC(isMeOp,isOp) IS_FNC(isMeVoice,isVoice) IS_FNC(isMeHalfOp,isHalfOp) IS_FNC(isMeUserOp,isUserOp) int KviChannel::myFlags() { if(!connection())return 0; return m_pUserListView->flags(connection()->currentNickName()); } void KviChannel::setMask(char flag, const TQString &mask,bool bAdd,const TQString &setBy,unsigned int setAt) { if(!connection())return; KviPointerList * list = m_pBanList; KviMaskEditor * editor = m_pBanEditor; switch(flag) { case 'b': m_iStateFlags ^= KVI_CHANNEL_STATE_HAVEBANLIST; break; case 'e': m_iStateFlags ^= KVI_CHANNEL_STATE_HAVEBANEXCEPTIONLIST; list = m_pBanExceptionList; editor = m_pBanExceptionEditor; break; case 'I': m_iStateFlags ^= KVI_CHANNEL_STATE_HAVEINVITELIST; list = m_pInviteList; editor = m_pInviteEditor; break; } internalMask(mask,bAdd,setBy,setAt,list,&editor); m_pUserListView->setMaskEntries(flag,(int)list->count()); } void KviChannel::internalMask(const TQString &mask,bool bAdd,const TQString &setBy,unsigned int setAt,KviPointerList *l,KviMaskEditor **ppEd) { KviMaskEntry * e = 0; if(bAdd) { for(e = l->first();e;e = l->next()) { if(KviTQString::equalCI(e->szMask,mask))return; //already there } e = new KviMaskEntry; e->szMask = mask; e->szSetBy = (!setBy.isEmpty()) ? setBy : __tr2qs("(Unknown)"); e->uSetAt = setAt; l->append(e); if(*ppEd)(*ppEd)->addMask(e); } else { for(e = l->first();e;e = l->next()) { if(KviTQString::equalCI(e->szMask,mask))break; } if(e) { if(*ppEd)(*ppEd)->removeMask(e); l->removeRef(e); } } } void KviChannel::updateModeLabel() { TQString tmp = m_szChannelMode; TQString tip = __tr2qs("Channel mode:"); //const char * aux = m_szChannelMode.utf8().data(); leaks memory and will not work with getChannelModeDescription() (can channel modes be multibyte ?) KviStr mod = m_szChannelMode; const char * aux = mod.ptr(); while(*aux) { KviTQString::appendFormatted(tip,"
%c: %Q",*aux,&(m_pConsole->connection()->serverInfo()->getChannelModeDescription(*aux))); ++aux; } if(!m_szChannelKey.isEmpty()) { if(!tmp.isEmpty())tmp.append(' '); KviTQString::appendFormatted(tmp,"k:%s",m_szChannelKey.utf8().data()); KviTQString::appendFormatted(tip,__tr2qs("
Key: %s"),m_szChannelKey.utf8().data()); } if(m_szChannelLimit.hasData()) { if(!tmp.isEmpty())tmp.append(' '); KviTQString::appendFormatted(tmp,"l:%s",m_szChannelLimit.ptr()); KviTQString::appendFormatted(tip,__tr2qs("
Limit: %s"),m_szChannelLimit.ptr()); } m_pModeWidget->refreshModes(); KviTalToolTip::remove(m_pModeWidget); KviTalToolTip::add(m_pModeWidget,tip); } /* void KviChannel::outputMessage(int msg_type,const char *format,...) { kvi_wchar_t txt_ptr[512]; //It should be enough for all outputs... kvi_va_list list; kvi_va_start(list,format); if(kvi_wvsnprintcf(txt_ptr,512,format,list) < 0){ //Just in case... kvi_va_end(list); int len = 512; kvi_wchar_t *long_txt_ptr = 0; int result; do{ len += 512; //first time long_txt_ptr == 0 so it is equivalent to malloc //At least the man page says that... long_txt_ptr = (kvi_wchar_t *)kvi_realloc((void *)long_txt_ptr,len * sizeof(kvi_wchar_t)); kvi_va_start(list,format); result = kvi_wvsnprintcf(long_txt_ptr,len,format,list); kvi_va_end(list); } while(result < 0); internalOutput(m_pMessageView ? m_pMessageView : m_pIrcView,msg_type,long_txt_ptr); kvi_free((void *)long_txt_ptr); } else { //Succesful vsnprintf kvi_va_end(list); internalOutput(m_pMessageView ? m_pMessageView : m_pIrcView,msg_type,txt_ptr); } } */ void KviChannel::outputMessage(int msg_type,const TQString &msg) { TQString szBuf(msg); preprocessMessage(szBuf); const TQChar * pC = KviTQString::nullTerminatedArray(szBuf); if(!pC)return; internalOutput(m_pMessageView ? m_pMessageView : m_pIrcView,msg_type,(const kvi_wchar_t *)pC); } void KviChannel::checkChannelSync() { if(m_iStateFlags & KVI_CHANNEL_STATE_SYNCHRONIZED)return; if(m_iStateFlags & KVI_CHANNEL_STATE_SENTWHOREQUEST) { if(!(m_iStateFlags & KVI_CHANNEL_STATE_HAVEWHOLIST))return; } if(m_iStateFlags & KVI_CHANNEL_STATE_SENTBANLISTREQUEST) { if(!(m_iStateFlags & KVI_CHANNEL_STATE_HAVEBANLIST))return; } if(m_iStateFlags & KVI_CHANNEL_STATE_SENTBANEXCEPTIONLISTREQUEST) { if(!(m_iStateFlags & KVI_CHANNEL_STATE_HAVEBANEXCEPTIONLIST))return; } if(m_iStateFlags & KVI_CHANNEL_STATE_SENTINVITELISTREQUEST) { if(!(m_iStateFlags & KVI_CHANNEL_STATE_HAVEINVITELIST))return; } m_iStateFlags |= KVI_CHANNEL_STATE_SYNCHRONIZED; // we already have all the spontaneous server replies // (so probably mode, topic (or no topic is set),names) // we have already received the I and e lists (if requested) kvs_int_t iSyncTime = m_joinTime.time().msecsTo(TQTime::currentTime()); if(iSyncTime < 0)iSyncTime += 86400000; bool bStop = KVS_TRIGGER_EVENT_1_HALTED(KviEvent_OnChannelSync,this,iSyncTime); if(!bStop && KVI_OPTION_BOOL(KviOption_boolShowChannelSyncTime)) { output(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Channel synchronized in %d.%d seconds"),iSyncTime / 1000,iSyncTime % 1000); } } bool KviChannel::eventFilter(TQObject * o, TQEvent * e) { if(e->type() == TQEvent::FocusOut && TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(m_pTopicWidget) && \ m_pTopicWidget->isVisible()) m_pTopicWidget->deactivate(); return KviWindow::eventFilter(o, e); } void KviChannel::preprocessMessage(TQString & szMessage) { TQStringList strings = TQStringList::split(" ",szMessage, TRUE); for ( TQStringList::Iterator it = strings.begin(); it != strings.end(); ++it ) { if((*it).contains('\r')) continue; TQString tmp = KviMircCntrl::stripControlBytes(*it); if( findEntry(*it) ) *it=TQString("\r!n\r%1\r").arg(*it); if(m_pConsole) if(m_pConsole->connection()) if(m_pConsole->connection()->serverInfo()->supportedChannelTypes().contains(tmp[0])) if((*it)==tmp) *it=TQString("\r!c\r%1\r").arg(*it); else *it=TQString("\r!c%1\r%2\r").arg(tmp).arg(*it); } szMessage=strings.join(" "); } void KviChannel::unhighlight() { if(!m_pTaskBarItem)return; m_pTaskBarItem->unhighlight(); } #include "kvi_channel.moc"
"; getTalkingUsersStats(buffer,cas.lWereTalkingUsers,true); buffer += end_of_row; } buffer += "
"; getTalkingUsersStats(buffer,cas.lTalkingUsers,false); buffer += end_of_row; } else { if(cas.lWereTalkingUsers.count() > 0) { buffer += "
"; getTalkingUsersStats(buffer,cas.lWereTalkingUsers,true); buffer += end_of_row; } } buffer += "
"; if(cas.dActionsPerMinute < 0.1)buffer += __tr2qs("No activity"); else if(cas.dActionsPerMinute < 0.3)buffer += __tr2qs("Minimal activity"); else if(cas.dActionsPerMinute < 1.0)buffer += __tr2qs("Very low activity"); else if(cas.dActionsPerMinute < 3.0)buffer += cas.bStatsInaccurate ? __tr2qs("Might be low activity") : __tr2qs("Low activity"); else if(cas.dActionsPerMinute < 10.0)buffer += cas.bStatsInaccurate ? __tr2qs("Might be medium activity") : __tr2qs("Medium activity"); else if(cas.dActionsPerMinute < 30.0)buffer += cas.bStatsInaccurate ? __tr2qs("Might be high activity") : __tr2qs("High activity"); else if(cas.dActionsPerMinute < 60.0)buffer += cas.bStatsInaccurate ? __tr2qs("Might be very high activity") : __tr2qs("Very high activity"); else buffer += cas.bStatsInaccurate ? __tr2qs("Might be flooded with messages") : __tr2qs("Flooded with messages"); if(cas.dActionsPerMinute >= 0.1) { TQString num; num.sprintf(" [%u%% ",cas.uHotActionPercent); buffer += num; buffer += __tr2qs("human"); buffer += "]"; } buffer += "