bool KviIsOnNotifyListManager::handleIsOn(KviIrcMessage * msg) { if(!m_bExpectingIsOn) return false; // Check if it is our ISON // all the nicks must be on the IsOnList KviPointerList<QString> tmplist; tmplist.setAutoDelete(false); KviCString nk; const char * aux = msg->trailing(); while(*aux) { nk = ""; aux = kvi_extractToken(nk, aux, ' '); if(nk.hasData()) { bool bGotIt = false; QString dnk = m_pConnection->decodeText(nk.ptr()); for(QString * s = m_pIsOnList->first(); s && (!bGotIt); s = m_pIsOnList->next()) { if(KviQString::equalCI(*s, dnk)) { tmplist.append(s); bGotIt = true; } } if(!bGotIt) { // ops...not my userhost! if(_OUTPUT_VERBOSE) m_pConsole->output(KVI_OUT_SYSTEMMESSAGE, __tr2qs("Notify list: Hey! You've used ISON behind my back? (I might be confused now...)")); return false; } } } // Ok...looks to be my ison (still not sure at 100%, but can't do better) if(m_pConnection->lagMeter()) m_pConnection->lagMeter()->lagCheckComplete("@notify_ison"); m_bExpectingIsOn = false; m_pOnlineList->clear(); m_pIsOnList->setAutoDelete(false); // Ok...we have an IsOn reply here // The nicks in the IsOnList that are also in the reply are online, and go to the OnlineList // the remaining in the IsOnList are offline QString * s; for(s = tmplist.first(); s; s = tmplist.next()) { m_pIsOnList->removeRef(s); m_pOnlineList->append(s); } m_pIsOnList->setAutoDelete(true); // Ok...all the users that are online, are on the OnlineList // the remaining users are in the m_pIsOnList, and are no longer online // first the easy step: remove the users that have just left irc or have never been online // we're clearling the m_pIsOnList while((s = m_pIsOnList->first())) { if(m_pConsole->notifyListView()->findEntry(*s)) { // has just left IRC... make him part notifyOffLine(*s); } // else has never been here m_pIsOnList->removeFirst(); // autodelete is true } // ok... complex step now: the remaining users in the userhost list are online // if they have been online before, just remove them from the list // otherwise they must be matched for masks // and eventually inserted in the notify view later KviIrcUserDataBase * db = console()->connection()->userDataBase(); KviPointerList<QString> l; l.setAutoDelete(false); for(s = m_pOnlineList->first(); s; s = m_pOnlineList->next()) { if(KviUserListEntry * ent = m_pConsole->notifyListView()->findEntry(*s)) { // the user was online from a previous notify session // might the mask have been changed ? (heh...this is tricky, maybe too much even) if(KVI_OPTION_BOOL(KviOption_boolNotifyListSendUserhostForOnlineUsers)) { // user wants to be sure about online users.... // check if he is on some channels if(ent->globalData()->nRefs() > 1) { // mmmh...we have more than one ref, so the user is at least in one query or channel // look him up on channels, if we find his entry, we can be sure that he is // still the right user KviPointerList<KviChannelWindow> * chlist = m_pConsole->connection()->channelList(); for(KviChannelWindow * ch = chlist->first(); ch; ch = chlist->next()) { if(KviUserListEntry * le = ch->findEntry(*s)) { l.append(s); // ok...found on a channel...we don't need a userhost to match him KviIrcMask mk(*s, le->globalData()->user(), le->globalData()->host()); if(!doMatchUser(*s, mk)) return true; // critical problems = have to restart!!! break; } } } // else Only one ref...we need a userhost to be sure (don't remove from the list) } else { // user wants no userhost for online users...we "hope" that everything will go ok. l.append(s); } //l.append(s); // we will remove him from the list } else { // the user was not online! // check if we have a cached mask if(db) { if(KviIrcUserEntry * ue = db->find(*s)) { // already in the db... do we have a mask ? if(ue->hasUser() && ue->hasHost()) { // yup! we have a complete mask to match on KviIrcMask mk(*s, ue->user(), ue->host()); // lookup the user's name in the m_pRegUserDict if(!doMatchUser(*s, mk)) return true; // critical problems = have to restart!!! l.append(s); // remove anyway } } } } } for(s = l.first(); s; s = l.next()) { m_pOnlineList->removeRef(s); // autodelete is true } if(m_pOnlineList->isEmpty()) { if(m_pNotifyList->isEmpty()) delayedNotifySession(); else delayedIsOnSession(); } else delayedUserhostSession(); return true; }
void KviIrcConnectionRequestQueue::timerSlot() { if(m_channels.isEmpty()) { m_timer.stop(); } else { KviChannelWindow * pChan = m_channels.head(); QByteArray encodedChan = pChan->connection()->encodeText(pChan->target()).data(); /* The following switch will let the execution flow pass-through if any request type * is currently disabled (or not available on the server). Channel's "MODE" request is * the only mandatory request. */ switch(m_curType) { case BanException: if(pChan->serverInfo()->supportedListModes().contains('e') && !KVI_OPTION_BOOL(KviOption_boolDisableBanExceptionListRequestOnJoin) && !( pChan->serverInfo()->getNeedsOpToListModeseI() && !pChan->isMeOp() ) ) { if(!pChan->connection()->sendFmtData("MODE %s e",encodedChan.data())) clearAll(); // disconnected else pChan->setSentListRequest('e'); m_curType = Invite; break; } case Invite: if(pChan->serverInfo()->supportedListModes().contains('I') && !KVI_OPTION_BOOL(KviOption_boolDisableInviteListRequestOnJoin) && !( pChan->serverInfo()->getNeedsOpToListModeseI() && !pChan->isMeOp() ) ) { if(!pChan->connection()->sendFmtData("MODE %s I",encodedChan.data())) clearAll(); // disconnected else pChan->setSentListRequest('I'); m_curType = QuietBan; break; } case QuietBan: if(pChan->serverInfo()->supportedListModes().contains('q') && !KVI_OPTION_BOOL(KviOption_boolDisableQuietBanListRequestOnJoin)) { if(!pChan->connection()->sendFmtData("MODE %s q",encodedChan.data())) clearAll(); // disconnected else pChan->setSentListRequest('q'); m_curType = Who; break; } case Who: if(!KVI_OPTION_BOOL(KviOption_boolDisableWhoRequestOnJoin)) { // TODO: cleanup pChan->connection()->stateData()->setLastSentChannelWhoRequest(kvi_unixTime()); if(pChan->connection()->lagMeter()) { KviCString tmp; if(pChan->serverInfo()->supportsWhox()) tmp.sprintf("WHO %s %acdfhlnrsu",encodedChan.data()); else tmp.sprintf("WHO %s",encodedChan.data()); pChan->connection()->lagMeter()->lagCheckRegister(tmp.ptr(),60); } if(pChan->serverInfo()->supportsWhox()) { if(!pChan->connection()->sendFmtData("WHO %s %acdfhlnrsu",encodedChan.data())) clearAll(); // disconnected else pChan->setSentWhoRequest(); } else { if(!pChan->connection()->sendFmtData("WHO %s",encodedChan.data())) clearAll(); // disconnected else pChan->setSentWhoRequest(); } m_curType = Ban; break; } case Ban: if(!KVI_OPTION_BOOL(KviOption_boolDisableBanListRequestOnJoin)) { if(!pChan->connection()->sendFmtData("MODE %s b",encodedChan.data())) { clearAll(); // disconnected } else { pChan->setSentListRequest('b'); m_channels.dequeue(); } m_curType = Mode; break; } default: // we're at the end of the list m_channels.dequeue(); pChan->checkChannelSync(); m_curType = Mode; if(m_channels.isEmpty()) { m_timer.stop(); return; } pChan = m_channels.head(); encodedChan = pChan->connection()->encodeText(pChan->target()); case Mode: if(!pChan->connection()->sendFmtData("MODE %s",encodedChan.data())) { clearAll(); // disconnected break; } m_curType = BanException; break; } } }
void KviTopicWidget::switchMode() { int iMaxLen=-1; QObject * w = parent(); QString szModes; bool bCanEdit = true; while(w) { if(w->inherits("KviChannelWindow")) { KviChannelWindow *chan = ((KviChannelWindow *)w); iMaxLen = chan->connection()->serverInfo()->maxTopicLen(); chan->getChannelModeString(szModes); if(chan->plainChannelMode().contains('t') && !( chan->isMeHalfOp(true) || chan->connection()->userInfo()->hasUserMode('o') || chan->connection()->userInfo()->hasUserMode('O') ) ) { bCanEdit=false; } break; } w = w->parent(); } if(m_pInput == 0) { m_pInput = new KviInputEditor(this,m_pKviChannelWindow); m_pInput->setObjectName("topicw_inputeditor"); m_pInput->setReadOnly(!bCanEdit); if(iMaxLen>0) m_pInput->setMaxBufferSize(iMaxLen); m_pInput->setGeometry(0,0,width() - (height() << 2)+height(),height()); m_pInput->setText(m_szTopic); connect(m_pInput,SIGNAL(enterPressed()),this,SLOT(acceptClicked())); connect(m_pInput,SIGNAL(escapePressed()),this,SLOT(discardClicked())); m_pInput->installEventFilter(this); m_pHistory = new QPushButton(this); m_pHistory->setObjectName("topicw_historybutton"); m_pHistory->setIcon(QIcon(*(g_pIconManager->getSmallIcon(KviIconManager::History)))); m_pHistory->setGeometry(width() - (height() << 2)+height(),0,height(),height()); KviTalToolTip::add(m_pHistory,__tr2qs("History")); m_pHistory->show(); connect(m_pHistory,SIGNAL(clicked()),this,SLOT(historyClicked())); m_pAccept = new QPushButton(this); m_pAccept->setObjectName("topicw_acceptbutton"); m_pAccept->setIcon(QIcon(*(g_pIconManager->getSmallIcon(KviIconManager::Accept)))); m_pAccept->setGeometry(width() - (height() << 1),0,height(),height()); m_pAccept->setEnabled(bCanEdit); m_pAccept->show(); KviTalToolTip::add(m_pAccept,__tr2qs("Commit changes")); connect(m_pAccept,SIGNAL(clicked()),this,SLOT(acceptClicked())); m_pDiscard = new QPushButton(this); m_pDiscard->setObjectName("topicw_discardbutton"); m_pDiscard->setIcon(QIcon(*(g_pIconManager->getSmallIcon(KviIconManager::Discard)))); m_pDiscard->setGeometry(width() - height(),0,height(),height()); KviTalToolTip::add(m_pDiscard,__tr2qs("Discard changes")); m_pDiscard->show(); connect(m_pDiscard,SIGNAL(clicked()),this,SLOT(discardClicked())); m_pInput->home(); m_pInput->show(); m_pInput->setFocus(); m_pLabel->hide(); } else { deactivate(); } }
void KviIrcView::doLinkToolTip(const QRect &rct,QString &linkCmd,QString &linkText) { if(linkCmd.isEmpty())return; QString szCmd(linkCmd); szCmd.remove(0,1); QString tip; switch(linkCmd[0].unicode()) { case 'u': // url link { if(!KVI_OPTION_BOOL(KviOption_boolEnableUrlLinkToolTip)) return; tip = "<table width=\"100%\">" \ "<tr><td valign=\"center\"><img src=\"" + g_pIconManager->getSmallIconResourceName(KviIconManager::Url) + "\"><u><p style=\"white-space:pre;color:#0022FF\">"; if(linkText.length() > 50) { tip += linkText.left(47); tip += "..."; } else { tip += linkText; } tip+="</p></u></td></tr><tr><td><hr>"; // Check clicks' number if(KVI_OPTION_UINT(KviOption_uintUrlMouseClickNum) == 1) tip += __tr2qs("Click to open this link"); else tip += __tr2qs("Double-click to open this link"); tip += "</td></tr></table>"; } break; case 'h': // host link { if(!KVI_OPTION_BOOL(KviOption_boolEnableHostLinkToolTip)) return; tip = "<table width=\"100%\">" \ "<tr><td valign=\"center\"><img src=\"" + g_pIconManager->getSmallIconResourceName(KviIconManager::Server) + "\"><u><p style=\"white-space:pre;color:#0022FF\">"; if(linkText.length() > 50) { tip += linkText.left(47); tip += "..."; } else { tip += linkText; } tip+="</p></u></td></tr><tr><td><hr>"; if(linkText.indexOf('*') != -1) { if(linkText.length() > 1)tip += __tr2qs("Unable to look up hostname: hostname appears to be masked"); else tip += __tr2qs("Unable to look up hostname: unknown host"); } else { tip += __tr2qs("Double-click to look up this hostname<br>Right-click to view other options"); } tip += "</td></tr></table>"; } break; case 's': // server link { if(!KVI_OPTION_BOOL(KviOption_boolEnableServerLinkToolTip)) return; // FIXME: #warning "Spit out some server info...hub ?...registered ?" tip = "<table width=\"100%\">" \ "<tr><td valign=\"center\"><img src=\"" + g_pIconManager->getSmallIconResourceName(KviIconManager::Server) + "\"><u><p style=\"white-space:pre;color:#0022FF\">"; if(linkText.length() > 50) { tip += linkText.left(47); tip += "..."; } else { tip += linkText; } tip+="</p></u></td></tr><tr><td><hr>"; if(linkText.indexOf('*') != -1) { if(linkText.length() > 1)tip += __tr2qs("Server appears to be a network hub<br>"); else tip += __tr2qs("Unknown server<br>"); // might happen... } tip.append(__tr2qs("Double-click to read the MOTD<br>Right-click to view other options")); tip += "</td></tr></table>"; } break; case 'm': // mode link { if(!KVI_OPTION_BOOL(KviOption_boolEnableModeLinkToolTip)) return; if((linkCmd.length() > 2) && (m_pKviWindow->type() == KviWindow::Channel)) { if(((KviChannelWindow *)m_pKviWindow)->isMeOp()) { QString part = linkCmd.mid(1); KviQString::appendFormatted(tip,QString("<b>mode %Q %Q</b>"),&(m_pKviWindow->windowName()),&part); } else { // I'm not op...no way tip = __tr2qs("You're not an operator: you may not change channel modes"); } } } break; case 'n': // nick link { if(!KVI_OPTION_BOOL(KviOption_boolEnableNickLinkToolTip)) return; if(console()) { if(console()->connection()) { KviIrcUserEntry * e = console()->connection()->userDataBase()->find(linkText); if(e) { QString buffer; console()->getUserTipText(linkText,e,buffer); tip = buffer; } else tip = QString(__tr2qs("Nothing known about %1")).arg(linkText); } else tip = QString(__tr2qs("Nothing known about %1 (no connection)")).arg(linkText); } } break; case 'c': // channel link { if(!KVI_OPTION_BOOL(KviOption_boolEnableChannelLinkToolTip)) return; if(console() && console()->connection()) { QString szChan = linkText; QString buf; tip = "<img src=\"" + g_pIconManager->getSmallIconResourceName(KviIconManager::Channel) + "\"> "; if(szCmd.length()>0) szChan=szCmd; KviChannelWindow * c = console()->connection()->findChannel(szChan); QString szUrl; if(c) { QString chanMode; c->getChannelModeString(chanMode); QString topic = KviControlCodes::stripControlBytes(c->topicWidget()->topic()); KviIrcUrl::join(szUrl,console()->connection()->target()->server()); szUrl.append(szChan); buf = QString(__tr2qs("<b>%1</b><u><p style=\"white-space:pre;color:#0022FF\">" "%2</p></u>+%3 (%4 users)<hr>%5")).arg(KviQString::toHtmlEscaped(szChan),KviQString::toHtmlEscaped(szUrl),KviQString::toHtmlEscaped(chanMode)).arg(c->count()).arg(KviQString::toHtmlEscaped(topic)); } else { KviIrcUrl::join(szUrl,console()->connection()->target()->server()); szUrl.append(szChan); buf = QString(__tr2qs("<b>%1</b><u><p style=\"white-space:pre;color:#0022FF\">" "%2</p></u><hr>Double-click to join %3<br>Right-click to view other options")).arg(KviQString::toHtmlEscaped(szChan),KviQString::toHtmlEscaped(szUrl),KviQString::toHtmlEscaped(szChan)); } tip += buf; } } break; default: { if(!KVI_OPTION_BOOL(KviOption_boolEnableEscapeLinkToolTip)) return; QString dbl,rbt,txt,mbt; getLinkEscapeCommand(dbl,linkCmd,"[!dbl]"); getLinkEscapeCommand(rbt,linkCmd,"[!rbt]"); getLinkEscapeCommand(txt,linkCmd,"[!txt]"); getLinkEscapeCommand(mbt,linkCmd,"[!mbt]"); if(!txt.isEmpty())tip = txt; if(tip.isEmpty() && (!dbl.isEmpty())) { if(!tip.isEmpty())tip.append("<hr>"); KviQString::appendFormatted(tip,__tr2qs("<b>Double-click:</b><br>%Q"),&dbl); } if(tip.isEmpty() && (!mbt.isEmpty())) { if(!tip.isEmpty())tip.append("<hr>"); KviQString::appendFormatted(tip,__tr2qs("<b>Middle-click:</b><br>%Q"),&mbt); } if(tip.isEmpty() && (!rbt.isEmpty())) { if(!tip.isEmpty())tip.append("<hr>"); KviQString::appendFormatted(tip,__tr2qs("<b>Right-click:</b><br>%Q"),&rbt); } } break; } if(tip.isEmpty())return; m_pToolTip->doTip(rct,tip); }