static char* Log_CreateRTF(LOGSTREAMDATA *streamData) { LOGINFO *lin = streamData->lin; MODULEINFO *mi = pci->MM_FindModule(streamData->si->pszModule); // ### RTF HEADER if (0 == mi->pszHeader) mi->pszHeader = Log_CreateRtfHeader(mi); char *header = mi->pszHeader; streamData->crCount = mi->nColorCount; CMStringA str; if (header) str.Append(header); // ### RTF BODY (one iteration per event that should be streamed in) while (lin) { // filter if ((streamData->si->iType != GCW_CHATROOM && streamData->si->iType != GCW_PRIVMESS) || !streamData->si->bFilterEnabled || (streamData->si->iLogFilterFlags & lin->iType) != 0) { if (lin->next != NULL) str.Append("\\par "); if (streamData->dat->dwFlags & MWF_DIVIDERWANTED || lin->dwFlags & MWF_DIVIDERWANTED) { static char szStyle_div[128] = "\0"; if (szStyle_div[0] == 0) mir_snprintf(szStyle_div, "\\f%u\\cf%u\\ul0\\b%d\\i%d\\fs%u", 17, 18, 0, 0, 5); lin->dwFlags |= MWF_DIVIDERWANTED; if (lin->prev || !streamData->bRedraw) str.AppendFormat("\\qc\\sl-1\\highlight%d %s ---------------------------------------------------------------------------------------\\par ", 18, szStyle_div); streamData->dat->dwFlags &= ~MWF_DIVIDERWANTED; } // create new line, and set font and color str.AppendFormat("\\ql\\sl0%s ", pci->Log_SetStyle(0)); str.AppendFormat("\\v~-+%d+-~\\v0 ", lin); // Insert icon if (g_Settings.bLogSymbols) // use symbols str.AppendFormat("%s %c", pci->Log_SetStyle(17), EventToSymbol(lin)); else if (g_Settings.dwIconFlags) { int iIndex = lin->bIsHighlighted ? ICON_HIGHLIGHT : EventToIcon(lin); str.Append("\\f0\\fs14"); str.AppendFormat(pci->pLogIconBmpBits[iIndex], (int)pci->logIconBmpSize[iIndex]); } if (g_Settings.bTimeStampEventColour) { // colored timestamps static char szStyle[256]; LOGFONT &F = pci->aFonts[0].lf; int iii; if (lin->ptszNick && lin->iType == GC_EVENT_MESSAGE) { iii = lin->bIsHighlighted ? 16 : (lin->bIsMe ? 2 : 1); mir_snprintf(szStyle, "\\f0\\cf%u\\ul0\\highlight0\\b%d\\i%d\\ul%d\\fs%u", iii + 1, F.lfWeight >= FW_BOLD ? 1 : 0, F.lfItalic, F.lfUnderline, 2 * abs(F.lfHeight) * 74 / pci->logPixelSY); str.Append(szStyle); } else { iii = lin->bIsHighlighted ? 16 : EventToIndex(lin); mir_snprintf(szStyle, "\\f0\\cf%u\\ul0\\highlight0\\b%d\\i%d\\ul%d\\fs%u", iii + 1, F.lfWeight >= FW_BOLD ? 1 : 0, F.lfItalic, F.lfUnderline, 2 * abs(F.lfHeight) * 74 / pci->logPixelSY); str.Append(szStyle); } } else str.Append(pci->Log_SetStyle(0)); str.AppendChar(' '); // insert a TAB if necessary to put the timestamp in the right position if (g_Settings.dwIconFlags) str.Append("\\tab "); //insert timestamp if (g_Settings.bShowTime) { TCHAR szTimeStamp[30], szOldTimeStamp[30]; _tcsncpy_s(szTimeStamp, pci->MakeTimeStamp(g_Settings.pszTimeStamp, lin->time), _TRUNCATE); _tcsncpy_s(szOldTimeStamp, pci->MakeTimeStamp(g_Settings.pszTimeStamp, streamData->si->LastTime), _TRUNCATE); if (!g_Settings.bShowTimeIfChanged || streamData->si->LastTime == 0 || mir_tstrcmp(szTimeStamp, szOldTimeStamp)) { streamData->si->LastTime = lin->time; Log_AppendRTF(streamData, TRUE, str, _T("%s"), szTimeStamp); } str.Append("\\tab "); } // Insert the nick if (lin->ptszNick && lin->iType == GC_EVENT_MESSAGE) { char pszIndicator[3] = "\0\0"; int crNickIndex = 0; if (g_Settings.bLogClassicIndicators || g_Settings.bColorizeNicksInLog) pszIndicator[0] = GetIndicator(streamData->si, lin->ptszNick, &crNickIndex); str.Append(pci->Log_SetStyle(lin->bIsMe ? 2 : 1)); str.AppendChar(' '); if (g_Settings.bLogClassicIndicators) str.Append(pszIndicator); CMString pszTemp(lin->bIsMe ? g_Settings.pszOutgoingNick : g_Settings.pszIncomingNick); pszTemp.Replace(_T("%n"), _T("%s")); if (!lin->bIsMe) { if (g_Settings.bClickableNicks) pszTemp.Replace(_T("%s"), _T("~~++#%s#++~~")); if (g_Settings.bColorizeNicksInLog && pszIndicator[0]) str.AppendFormat("\\cf%u ", OPTIONS_FONTCOUNT + streamData->crCount + crNickIndex); } Log_AppendRTF(streamData, TRUE, str, pszTemp, lin->ptszNick); str.AppendChar(' '); } // Insert the message str.Append(pci->Log_SetStyle(lin->bIsHighlighted ? 16 : EventToIndex(lin))); str.AppendChar(' '); streamData->lin = lin; AddEventToBuffer(str, streamData); } lin = lin->prev; } // ### RTF END if (streamData->bRedraw) str.Append("\\par}"); else str.Append("}"); return str.Detach(); }
char* Log_CreateRTF(LOGSTREAMDATA *streamData) { MODULEINFO *mi = ci.MM_FindModule(streamData->si->pszModule); // guesstimate amount of memory for the RTF size_t bufferEnd = 0, bufferAlloced = streamData->bRedraw ? 1024 * (streamData->si->iEventCount + 2) : 2048; char *buffer = (char *)mir_alloc(bufferAlloced); buffer[0] = '\0'; // ### RTF HEADER char *header = mi->pszHeader; if (header) Log_Append(buffer, bufferEnd, bufferAlloced, header); // ### RTF BODY (one iteration per event that should be streamed in) for (LOGINFO *lin = streamData->lin; lin; lin = lin->prev) { // filter if (streamData->si->iType == GCW_CHATROOM || streamData->si->iType == GCW_PRIVMESS) if (streamData->si->bFilterEnabled && (streamData->si->iLogFilterFlags & lin->iType) == 0) continue; // create new line, and set font and color if (lin->next != NULL) Log_Append(buffer, bufferEnd, bufferAlloced, "\\par "); Log_Append(buffer, bufferEnd, bufferAlloced, "%s ", Log_SetStyle(0)); // Insert icon if ((lin->iType & g_Settings->dwIconFlags) || lin->bIsHighlighted && (g_Settings->dwIconFlags & GC_EVENT_HIGHLIGHT)) { int iIndex = (lin->bIsHighlighted && g_Settings->dwIconFlags & GC_EVENT_HIGHLIGHT) ? ICON_HIGHLIGHT : EventToIcon(lin); Log_Append(buffer, bufferEnd, bufferAlloced, "\\f0\\fs14"); while (bufferAlloced - bufferEnd < logIconBmpSize[0]) bufferAlloced += 4096; buffer = (char *)mir_realloc(buffer, bufferAlloced); memcpy(buffer + bufferEnd, pLogIconBmpBits[iIndex], logIconBmpSize[iIndex]); bufferEnd += logIconBmpSize[iIndex]; } if (g_Settings->bTimeStampEventColour) { LOGFONT &lf = ci.aFonts[0].lf; // colored timestamps static char szStyle[256]; if (lin->ptszNick && lin->iType == GC_EVENT_MESSAGE) { int iii = lin->bIsHighlighted ? 16 : (lin->bIsMe ? 2 : 1); mir_snprintf(szStyle, _countof(szStyle), "\\f0\\cf%u\\ul0\\highlight0\\b%d\\i%d\\fs%u", iii + 1, lf.lfWeight >= FW_BOLD ? 1 : 0, lf.lfItalic, 2 * abs(lf.lfHeight) * 74 / ci.logPixelSY); Log_Append(buffer, bufferEnd, bufferAlloced, "%s ", szStyle); } else { int iii = lin->bIsHighlighted ? 16 : EventToIndex(lin); mir_snprintf(szStyle, _countof(szStyle), "\\f0\\cf%u\\ul0\\highlight0\\b%d\\i%d\\fs%u", iii + 1, lf.lfWeight >= FW_BOLD ? 1 : 0, lf.lfItalic, 2 * abs(lf.lfHeight) * 74 / ci.logPixelSY); Log_Append(buffer, bufferEnd, bufferAlloced, "%s ", szStyle); } } else Log_Append(buffer, bufferEnd, bufferAlloced, "%s ", Log_SetStyle(0)); if (g_Settings->dwIconFlags) Log_Append(buffer, bufferEnd, bufferAlloced, "\\tab "); //insert timestamp if (g_Settings->bShowTime) { TCHAR szTimeStamp[30], szOldTimeStamp[30]; mir_tstrncpy(szTimeStamp, MakeTimeStamp(g_Settings->pszTimeStamp, lin->time), 30); mir_tstrncpy(szOldTimeStamp, MakeTimeStamp(g_Settings->pszTimeStamp, streamData->si->LastTime), 30); if (!g_Settings->bShowTimeIfChanged || streamData->si->LastTime == 0 || mir_tstrcmp(szTimeStamp, szOldTimeStamp)) { streamData->si->LastTime = lin->time; Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, _T("%s"), szTimeStamp); } Log_Append(buffer, bufferEnd, bufferAlloced, "\\tab "); } // Insert the nick if (lin->ptszNick && lin->iType == GC_EVENT_MESSAGE) { TCHAR pszTemp[300], *p1; Log_Append(buffer, bufferEnd, bufferAlloced, "%s ", Log_SetStyle(lin->bIsMe ? 2 : 1)); mir_tstrncpy(pszTemp, lin->bIsMe ? g_Settings->pszOutgoingNick : g_Settings->pszIncomingNick, 299); p1 = _tcsstr(pszTemp, _T("%n")); if (p1) p1[1] = 's'; Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, pszTemp, lin->ptszNick); Log_Append(buffer, bufferEnd, bufferAlloced, " "); } // Insert the message Log_Append(buffer, bufferEnd, bufferAlloced, "%s ", Log_SetStyle(lin->bIsHighlighted ? 16 : EventToIndex(lin))); streamData->lin = lin; AddEventToBuffer(buffer, bufferEnd, bufferAlloced, streamData); } // ### RTF END if (streamData->bRedraw) Log_Append(buffer, bufferEnd, bufferAlloced, "\\par}"); else Log_Append(buffer, bufferEnd, bufferAlloced, "}"); return buffer; }