示例#1
0
//	Return TRUE if the contact never received any message (which means the contact may need an invitation)
//	Return FALSE if there is at least one message received (which means both parties have communicated successfully)
BOOL
TContact::Contact_FIsInvitationRecommended()
	{
	if ((m_uFlagsContact & FC_kfContactNeedsInvitation) == 0)
		return FALSE;
	if (m_paVaultEvents != NULL)
		{
		// Search the entire Chat Log to find any message received.  Of course this is not the most optimal code, however the Chat Log should be rather short if there has been no communication between the two parties.
		IEvent ** ppEventStop;
		IEvent ** ppEvent = m_paVaultEvents->m_arraypaEvents.PrgpGetEventsStop(OUT &ppEventStop);
		while (ppEvent != ppEventStop)
			{
			IEvent * pEvent = *--ppEventStop;
			AssertValidEvent(pEvent);
			EEventClass eEventClass = pEvent->EGetEventClass();
			if ((eEventClass == eEventClass_eMessageTextSent && pEvent->Event_FHasCompleted()) ||	// If the message was sent successfully (with a confirmation receipt), then there is no need to send an invitation because the remote contact has the JID of the account
				(eEventClass & eEventClass_kfReceivedByRemoteClient))								// Anything received by the remote client means there has been a communication between the two contacts, and therefore there is no need to send an invitaiton
				{
				m_uFlagsContact &= ~FC_kfContactNeedsInvitation;	// Remove the invitation flag
				return FALSE;
				}
			} // while
		} // if
	return TRUE;
	}
示例#2
0
void
CBinXcpStanza::BinXmlAppendAttributeOfContactIdentifierOfGroupSenderForEvent(const IEvent * pEvent)
	{
	AssertValidEvent(pEvent);
	Endorse(m_pContact == NULL);	// Saving to disk
	/*
	TContact * pContact = pEvent->m_pContactGroupSender_YZ;
	if (pContact != NULL && pContact != m_pContact)
		{
		Assert(pContact->EGetRuntimeClass() == RTI(TContact));
		pContact->BinAppendXmlAttributeOfContactIdentifier(INOUT this, d_chXCPa_pContactGroupSender);
		}
	*/
	if (pEvent->m_pContactGroupSender_YZ != m_pContact)
		{
		Endorse(pEvent->m_pContactGroupSender_YZ == NULL);	// The event was sent, or was received on a 1-to-1 conversation.  If this pointer is NULL, then the method BinAppendXmlAttributeOfContactIdentifier() will ignore it
		BinAppendXmlAttributeOfContactIdentifier(d_chXCPa_pContactGroupSender, pEvent->m_pContactGroupSender_YZ);
		}
	}
示例#3
0
void
WChatLog::ChatLog_EventsDisplay(const CArrayPtrEvents & arraypEvents, int iEventStart)
	{
	Assert(iEventStart >= 0);
	Assert(m_oTextBlockComposing.isValid());
//	CSocketXmpp * pSocket = m_pContactOrGroup->Xmpp_PGetSocketOnlyIfReady();

	OCursorSelectBlock oCursor(m_oTextBlockComposing);
	QTextBlock oTextBlockEvent;	// Text block for each event to insert
	IEvent ** ppEventStop;
	IEvent ** ppEventFirst = arraypEvents.PrgpGetEventsStop(OUT &ppEventStop) + iEventStart;
	IEvent ** ppEvent = ppEventFirst;
	if (!m_fDisplayAllMessages)
		{
		// For performance, limit the display to the last 100 events
		if (ppEventStop != NULL)
			{
			IEvent ** ppEventStart = ppEventStop - 100;
			if (ppEventStart > ppEvent)
				{
				ppEvent = ppEventStart;

				QTextBlockFormat oFormat;
				oFormat.setAlignment(Qt::AlignHCenter);
				oFormat.setBackground(c_brushSilver);	// Use a silver color
				oCursor.setBlockFormat(oFormat);
				g_strScratchBufferStatusBar.Format("<a href='" d_SzMakeCambrianAction(d_szCambrianAction_DisplayAllHistory) "'>Display complete history ($I messages)</a>", arraypEvents.GetSize());
				oCursor.insertHtml(g_strScratchBufferStatusBar);
				oCursor.AppendBlockBlank();
				}
			}
		}

	while (ppEvent < ppEventStop)
		{
		IEvent * pEvent = *ppEvent++;
		AssertValidEvent(pEvent);
		if (pEvent->m_tsEventID >= m_tsMidnightNext)
			{
			QDateTime dtl = QDateTime::fromMSecsSinceEpoch(pEvent->m_tsEventID).toLocalTime();
			QDate date = dtl.date();	// Strip the time of the day
			m_tsMidnightNext = QDateTime(date).toMSecsSinceEpoch() + d_ts_cDays;	// I am sure there is a more elegant way to strip the time from a date, however at the moment I don't have time to investigate a better solution (and this code works)

			QTextBlockFormat oFormatBlock;
			oFormatBlock.setAlignment(Qt::AlignHCenter);
			oFormatBlock.setBackground(c_brushSilver);
			oCursor.setBlockFormat(oFormatBlock);
			QTextCharFormat oFormatChar; // = oCursor.charFormat();
			oFormatChar.setFontWeight(QFont::Bold);
			//oFormatChar.setFontItalic(true);
			//oCursor.setCharFormat(oFormatChar);
			oCursor.insertText(date.toString("dddd MMMM d, yyyy"), oFormatChar);
			oCursor.AppendBlockBlank();
			}
		oTextBlockEvent = oCursor.block();	// Get the current block under the cursor
		Endorse(oTextBlockEvent.userData() == NULL);

		if (pEvent->m_uFlagsEvent & IEvent::FE_kfReplacing)
			{
			MessageLog_AppendTextFormatSev(eSeverityComment, "Attempting to replace Event ID $t\n", pEvent->m_tsEventID);
			QTextBlock oTextBlockUpdate;
			QTextBlock oTextBlockTemp = document()->lastBlock();
			IEvent * pEventOld = pEvent;
			const EEventClass eEventClassUpdater = pEvent->Event_FIsEventTypeSent() ? CEventUpdaterSent::c_eEventClass : CEventUpdaterReceived::c_eEventClass;	// Which updater to search for
			// The event is replacing an older event.  This code is a bit complex because the Chat Log may not display all events and therefore we need to find the most recent block displaying the most recent event.
			IEvent ** ppEventStop;
			IEvent ** ppEventFirst = pEvent->m_pVaultParent_NZ->m_arraypaEvents.PrgpGetEventsStop(OUT &ppEventStop);
			IEvent ** ppEventCompare = ppEventStop;	// Search the array from the end, as the event to search is likely to be a recent one
			while (ppEventFirst < ppEventCompare)
				{
				// Find the updater which should be right before the replacing event
				IEvent * pEventTemp = *--ppEventCompare;
				TryAgain:
				if (pEventTemp == pEventOld && ppEventFirst < ppEventCompare)
					{
					CEventUpdaterSent * pEventUpdater = (CEventUpdaterSent *)*--ppEventCompare;	// Get the updater which is just before the event
					if (pEventUpdater->EGetEventClass() != eEventClassUpdater)
						{
						MessageLog_AppendTextFormatSev(eSeverityErrorWarning, "\t Missing Updater for Event ID $t ({tL}); instead found class '$U' with Event ID $t.\n", pEventTemp->m_tsEventID, pEventTemp->m_tsEventID, pEventUpdater->EGetEventClass(), pEventUpdater->m_tsEventID);
						pEvent->m_uFlagsEvent &= ~IEvent::FE_kfReplacing;	// Remove the bit to avoid displaying the error again and again
						pEvent->m_pVaultParent_NZ->SetModified();			// Save the change
						continue;
						}
					const TIMESTAMP tsEventIdOld = pEventUpdater->m_tsEventIdOld;
					MessageLog_AppendTextFormatSev(eSeverityNoise, "\t [$i] Found updater: $t  ->  $t\n", ppEventCompare - ppEventFirst, pEventUpdater->m_tsEventIdNew, tsEventIdOld);
					// Now, search for the block containing the replacement event
					while (oTextBlockTemp.isValid())
						{
						OTextBlockUserDataEvent * pUserData = (OTextBlockUserDataEvent *)oTextBlockTemp.userData();
						if (pUserData != NULL)
							{
							TIMESTAMP_DELTA dtsEvent = (pUserData->m_pEvent->m_tsEventID - tsEventIdOld);
							MessageLog_AppendTextFormatCo(d_coPurple, "Comparing block Event ID $t with $t: dtsEvent = $T\n", pUserData->m_pEvent->m_tsEventID, tsEventIdOld, dtsEvent);
							if (dtsEvent <= 0)
								{
								if (dtsEvent == 0)
									{
									MessageLog_AppendTextFormatSev(eSeverityNoise, "\t Found matching textblock for replacement: Event ID $t  ->  $t\n", pEventOld->m_tsEventID, tsEventIdOld);
									oTextBlockUpdate = oTextBlockTemp;
									}
								break;
								}
							}
						oTextBlockTemp = oTextBlockTemp.previous();
						} // while
					// Keep searching in case there are chained updated events
					while (ppEventFirst < ppEventCompare)
						{
						pEventTemp = *--ppEventCompare;
						if (pEventTemp->m_tsEventID == tsEventIdOld)
							{
							MessageLog_AppendTextFormatSev(eSeverityNoise, "\t [$i] Found chained replacement: Event ID $t  -> $t\n", ppEventCompare - ppEventFirst, pEvent->m_tsEventID, tsEventIdOld);
							pEventTemp->m_uFlagsEvent |= IEvent::FE_kfReplaced;
							pEventOld = pEventTemp;
							goto TryAgain;
							}
						} // while
					} // if
				} // while
			if (oTextBlockUpdate.isValid())
				{
				MessageLog_AppendTextFormatSev(eSeverityNoise, "\t Event ID $t is updating its old Event ID $t\n", pEvent->m_tsEventID, pEventOld->m_tsEventID);
				OCursorSelectBlock oCursorEventOld(oTextBlockUpdate);
				pEvent->ChatLogUpdateTextBlock(INOUT &oCursorEventOld);
				continue;
				}
			MessageLog_AppendTextFormatSev(eSeverityErrorWarning, "Event ID $t is replacing another event which cannot be found\n", pEvent->m_tsEventID);
			} // if (replacing)
		oTextBlockEvent.setUserData(PA_CHILD new OTextBlockUserDataEvent(pEvent));		// Assign an event for each text block
		pEvent->ChatLogUpdateTextBlock(INOUT &oCursor);
		if ((pEvent->m_uFlagsEvent & IEvent::FE_kfEventHidden) == 0)
			oCursor.AppendBlockBlank();	// If the event is visible, then add a new text block (otherwise it will reuse the same old block)
		else
			oTextBlockEvent.setUserData(NULL);	// Since we are reusing the same block, delete its userdata so we may assing another OTextBlockUserDataEvent
		} // while
	m_oTextBlockComposing = oCursor.block();
	ChatLog_ChatStateTextAppend(INOUT oCursor);
	Widget_ScrollToEnd(INOUT this);
	} // ChatLog_EventsDisplay()