예제 #1
0
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;
}
예제 #2
0
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;
		}
	}
}
예제 #3
0
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();
	}
}
예제 #4
0
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);
}