summaryrefslogtreecommitdiff
path: root/plugins/IEView
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/IEView')
-rw-r--r--plugins/IEView/ChatHTMLBuilder.cpp267
-rw-r--r--plugins/IEView/ChatHTMLBuilder.h41
-rw-r--r--plugins/IEView/HTMLBuilder.cpp520
-rw-r--r--plugins/IEView/HTMLBuilder.h90
-rw-r--r--plugins/IEView/HistoryHTMLBuilder.cpp306
-rw-r--r--plugins/IEView/HistoryHTMLBuilder.h45
-rw-r--r--plugins/IEView/IEView.cpp1219
-rw-r--r--plugins/IEView/IEView.h562
-rw-r--r--plugins/IEView/MUCCHTMLBuilder.cpp296
-rw-r--r--plugins/IEView/MUCCHTMLBuilder.h41
-rw-r--r--plugins/IEView/Makefile41
-rw-r--r--plugins/IEView/MakefileUbuntu41
-rw-r--r--plugins/IEView/Options.cpp1811
-rw-r--r--plugins/IEView/Options.h249
-rw-r--r--plugins/IEView/SRMMHTMLBuilder.cpp275
-rw-r--r--plugins/IEView/SRMMHTMLBuilder.h40
-rw-r--r--plugins/IEView/ScriverHTMLBuilder.cpp451
-rw-r--r--plugins/IEView/ScriverHTMLBuilder.h42
-rw-r--r--plugins/IEView/TabSRMMHTMLBuilder.cpp446
-rw-r--r--plugins/IEView/TabSRMMHTMLBuilder.h45
-rw-r--r--plugins/IEView/Template.cpp451
-rw-r--r--plugins/IEView/Template.h124
-rw-r--r--plugins/IEView/TemplateHTMLBuilder.cpp643
-rw-r--r--plugins/IEView/TemplateHTMLBuilder.h50
-rw-r--r--plugins/IEView/TextToken.cpp824
-rw-r--r--plugins/IEView/TextToken.h90
-rw-r--r--plugins/IEView/Utils.cpp420
-rw-r--r--plugins/IEView/Utils.h69
-rw-r--r--plugins/IEView/Version.h28
-rw-r--r--plugins/IEView/Version.rc38
-rw-r--r--plugins/IEView/docs/chat.css37
-rw-r--r--plugins/IEView/docs/ieview-license.txt340
-rw-r--r--plugins/IEView/docs/ieview-readme.txt263
-rw-r--r--plugins/IEView/docs/ieview-templates.txt92
-rw-r--r--plugins/IEView/docs/ieview-translation.txt38
-rw-r--r--plugins/IEView/docs/scriver.css51
-rw-r--r--plugins/IEView/docs/srmm.css36
-rw-r--r--plugins/IEView/docs/tabsrmm.css61
-rw-r--r--plugins/IEView/icos/action.gifbin0 -> 865 bytes
-rw-r--r--plugins/IEView/icos/addstatus.gifbin0 -> 887 bytes
-rw-r--r--plugins/IEView/icos/file.gifbin0 -> 986 bytes
-rw-r--r--plugins/IEView/icos/group_off.icobin0 -> 2038 bytes
-rw-r--r--plugins/IEView/icos/group_on.icobin0 -> 2038 bytes
-rw-r--r--plugins/IEView/icos/info.gifbin0 -> 883 bytes
-rw-r--r--plugins/IEView/icos/join.gifbin0 -> 857 bytes
-rw-r--r--plugins/IEView/icos/kick.gifbin0 -> 857 bytes
-rw-r--r--plugins/IEView/icos/message_in.gifbin0 -> 864 bytes
-rw-r--r--plugins/IEView/icos/message_in_chat.gifbin0 -> 864 bytes
-rw-r--r--plugins/IEView/icos/message_out.gifbin0 -> 864 bytes
-rw-r--r--plugins/IEView/icos/message_out_chat.gifbin0 -> 864 bytes
-rw-r--r--plugins/IEView/icos/nick.gifbin0 -> 865 bytes
-rw-r--r--plugins/IEView/icos/notice.gifbin0 -> 882 bytes
-rw-r--r--plugins/IEView/icos/part.gifbin0 -> 863 bytes
-rw-r--r--plugins/IEView/icos/quit.gifbin0 -> 866 bytes
-rw-r--r--plugins/IEView/icos/removestatus.gifbin0 -> 878 bytes
-rw-r--r--plugins/IEView/icos/rtl_off.icobin0 -> 2038 bytes
-rw-r--r--plugins/IEView/icos/rtl_on.icobin0 -> 2038 bytes
-rw-r--r--plugins/IEView/icos/status.gifbin0 -> 868 bytes
-rw-r--r--plugins/IEView/icos/topic.gifbin0 -> 877 bytes
-rw-r--r--plugins/IEView/icos/url.gifbin0 -> 1018 bytes
-rw-r--r--plugins/IEView/ieview.rc150
-rw-r--r--plugins/IEView/ieview.sln26
-rw-r--r--plugins/IEView/ieview.vcproj334
-rw-r--r--plugins/IEView/ieview.vcxproj206
-rw-r--r--plugins/IEView/ieview.vcxproj.filters115
-rw-r--r--plugins/IEView/ieview_common.h74
-rw-r--r--plugins/IEView/ieview_main.cpp128
-rw-r--r--plugins/IEView/ieview_services.cpp117
-rw-r--r--plugins/IEView/ieview_services.h31
-rw-r--r--plugins/IEView/resource.h87
70 files changed, 11751 insertions, 0 deletions
diff --git a/plugins/IEView/ChatHTMLBuilder.cpp b/plugins/IEView/ChatHTMLBuilder.cpp
new file mode 100644
index 0000000000..22ab1730fa
--- /dev/null
+++ b/plugins/IEView/ChatHTMLBuilder.cpp
@@ -0,0 +1,267 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+#include "ChatHTMLBuilder.h"
+
+#include "Options.h"
+#include "Utils.h"
+#include "m_chat.h"
+
+#define CHATMOD "Chat"
+#define CHATFONTMOD "ChatFonts"
+#define CHAT_ICON_FLAGS "IconFlags"
+
+#define FONTF_BOLD 1
+#define FONTF_ITALIC 2
+#define FONTF_UNDERLINE 4
+
+#define FONT_NUM 17
+
+static const char *classNames[] = {
+ ".timestamp", ".nameIn", ".nameOut", ".userJoined", ".userLeft", ".userDisconnected",
+ ".userKicked", ".nickChange", ".notice",
+ ".messageIn", ".messageOut", ".topicChange", ".information", ".statusEnable", ".statusDisable",
+ ".action", ".highlight"
+};
+
+ChatHTMLBuilder::ChatHTMLBuilder() {
+ setLastEventType(-1);
+ setLastEventTime(time(NULL));
+}
+
+void ChatHTMLBuilder::loadMsgDlgFont(int i, LOGFONTA * lf, COLORREF * colour) {
+ char str[32];
+ int style;
+ DBVARIANT dbv;
+ if (colour) {
+ wsprintfA(str, "Font%dCol", i);
+ *colour = DBGetContactSettingDword(NULL, CHATFONTMOD, str, 0x000000);
+ }
+ if (lf) {
+ wsprintfA(str, "Font%dSize", i);
+ lf->lfHeight = (char) DBGetContactSettingByte(NULL, CHATFONTMOD, str, 10);
+ lf->lfHeight = abs(lf->lfHeight);
+ lf->lfWidth = 0;
+ lf->lfEscapement = 0;
+ lf->lfOrientation = 0;
+ wsprintfA(str, "Font%dSty", i);
+ style = DBGetContactSettingByte(NULL, CHATFONTMOD, str, 0);
+ lf->lfWeight = style & FONTF_BOLD ? FW_BOLD : FW_NORMAL;
+ lf->lfItalic = style & FONTF_ITALIC ? 1 : 0;
+ lf->lfUnderline = style & FONTF_UNDERLINE ? 1 : 0;
+ lf->lfStrikeOut = 0;
+ wsprintfA(str, "Font%dSet", i);
+ lf->lfCharSet = DBGetContactSettingByte(NULL, CHATFONTMOD, str, DEFAULT_CHARSET);
+ lf->lfOutPrecision = OUT_DEFAULT_PRECIS;
+ lf->lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ lf->lfQuality = DEFAULT_QUALITY;
+ lf->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
+ wsprintfA(str, "Font%d", i);
+ if (DBGetContactSetting(NULL, CHATFONTMOD, str, &dbv))
+ lstrcpyA(lf->lfFaceName, "Verdana");
+ else {
+ lstrcpynA(lf->lfFaceName, dbv.pszVal, sizeof(lf->lfFaceName));
+ DBFreeVariant(&dbv);
+ }
+ }
+}
+
+char *ChatHTMLBuilder::timestampToString(time_t time)
+{
+ static char szResult[512];
+ static char str[80];
+ char *pszStamp = "[%H:%M]";
+ //InitSetting( &g_Settings.pszTimeStamp, "HeaderTime", _T("[%H:%M]"));
+ strftime(str, 79, pszStamp, localtime(&time));
+ Utils::UTF8Encode(str, szResult, 500);
+ return szResult;
+}
+
+void ChatHTMLBuilder::buildHead(IEView *view, IEVIEWEVENT *event) {
+ LOGFONTA lf;
+ COLORREF color;
+ char *output = NULL;
+ int outputSize;
+ ProtocolSettings *protoSettings = getChatProtocolSettings(event->pszProto);
+ if (protoSettings == NULL) {
+ return;
+ }
+ if (protoSettings->getChatMode() == Options::MODE_TEMPLATE) {
+// buildHeadTemplate(view, event);
+ return;
+ }
+ if (protoSettings->getChatMode() == Options::MODE_CSS) {
+ const char *externalCSS = protoSettings->getChatCssFilename();
+ Utils::appendText(&output, &outputSize, "<html><head><link rel=\"stylesheet\" href=\"%s\"/></head><body class=\"body\">\n", externalCSS);
+ } else {
+ HDC hdc = GetDC(NULL);
+ int logPixelSY = GetDeviceCaps(hdc, LOGPIXELSY);
+ ReleaseDC(NULL, hdc);
+ Utils::appendText(&output, &outputSize, "<html><head>");
+ Utils::appendText(&output, &outputSize, "<style type=\"text/css\">\n");
+ COLORREF bkgColor = DBGetContactSettingDword(NULL, CHATMOD, "BackgroundLog", 0xFFFFFF);
+ COLORREF inColor, outColor;
+ bkgColor= (((bkgColor & 0xFF) << 16) | (bkgColor & 0xFF00) | ((bkgColor & 0xFF0000) >> 16));
+ inColor = outColor = bkgColor;
+ if (protoSettings->getChatFlags() & Options::LOG_IMAGE_ENABLED) {
+ Utils::appendText(&output, &outputSize, ".body {padding: 2px; text-align: left; background-attachment: %s; background-color: #%06X; background-image: url('%s'); overflow: auto;}\n",
+ protoSettings->getChatFlags() & Options::LOG_IMAGE_SCROLL ? "scroll" : "fixed", (int) bkgColor, protoSettings->getChatBackgroundFilename());
+ } else {
+ Utils::appendText(&output, &outputSize, ".body {margin: 0px; text-align: left; background-color: #%06X; overflow: auto;}\n",
+ (int) bkgColor);
+ }
+ Utils::appendText(&output, &outputSize, ".link {color: #0000FF; text-decoration: underline;}\n");
+ Utils::appendText(&output, &outputSize, ".img {vertical-align: middle;}\n");
+ if (protoSettings->getChatFlags() & Options::LOG_IMAGE_ENABLED) {
+ Utils::appendText(&output, &outputSize, ".divIn {padding-left: 2px; padding-right: 2px; word-wrap: break-word;}\n");
+ Utils::appendText(&output, &outputSize, ".divOut {padding-left: 2px; padding-right: 2px; word-wrap: break-word;}\n");
+ } else {
+ Utils::appendText(&output, &outputSize, ".divIn {padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #%06X;}\n", (int) inColor);
+ Utils::appendText(&output, &outputSize, ".divOut {padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #%06X;}\n", (int) outColor);
+ }
+ for(int i = 0; i < FONT_NUM; i++) {
+ loadMsgDlgFont(i, &lf, &color);
+ Utils::appendText(&output, &outputSize, "%s {font-family: %s; font-size: %dpt; font-weight: %s; color: #%06X; %s }\n",
+ classNames[i],
+ lf.lfFaceName,
+ abs((signed char)lf.lfHeight) * 74 /logPixelSY ,
+ lf.lfWeight >= FW_BOLD ? "bold" : "normal",
+ (int)(((color & 0xFF) << 16) | (color & 0xFF00) | ((color & 0xFF0000) >> 16)),
+ lf.lfItalic ? "font-style: italic;" : "");
+ }
+ Utils::appendText(&output, &outputSize, "</style></head><body class=\"body\">\n");
+ }
+ if (output != NULL) {
+ view->write(output);
+ free(output);
+ }
+ setLastEventType(-1);
+}
+
+/* WORK IN PROGRESS:
+ * The following method is going to be completely rewritten soon. Do not modify or complain for the time being...
+ */
+
+void ChatHTMLBuilder::appendEventNonTemplate(IEView *view, IEVIEWEVENT *event) {
+ DWORD iconFlags = DBGetContactSettingDword(NULL, CHATMOD, CHAT_ICON_FLAGS, 0);
+ IEVIEWEVENTDATA* eventData = event->eventData;
+ for (int eventIdx = 0; eventData!=NULL && (eventIdx < event->count || event->count==-1); eventData = eventData->next, eventIdx++) {
+ //DWORD dwFlags = eventData->dwFlags;
+ const char *iconFile = "";
+ DWORD dwData = eventData->dwData;
+ int isSent = eventData->bIsMe;
+ int outputSize = 0;
+ char *output = NULL;
+ char *szName = NULL, *szText = NULL;
+ const char *className = "";
+ bool showIcon = false;
+
+ if (eventData->dwFlags & IEEDF_UNICODE_TEXT) {
+ szText = encodeUTF8(NULL, event->pszProto, eventData->pszTextW, ENF_ALL | ENF_CHAT_FORMATTING, isSent);
+ } else {
+ szText = encodeUTF8(NULL, event->pszProto, (char *)eventData->pszText, ENF_ALL | ENF_CHAT_FORMATTING, isSent);
+ }
+ if (eventData->dwFlags & IEEDF_UNICODE_NICK) {
+ szName = encodeUTF8(NULL, event->pszProto, eventData->pszNickW, ENF_NAMESMILEYS, true);
+ } else {
+ szName = encodeUTF8(NULL, event->pszProto, (char *) eventData->pszNick, ENF_NAMESMILEYS, true);
+ }
+ if (eventData->iType == IEED_GC_EVENT_MESSAGE) {
+ iconFile = isSent ? "message_out_chat.gif" : "message_in_chat.gif";
+ showIcon = iconFlags & (isSent ? GC_EVENT_MESSAGE : GC_EVENT_MESSAGE);
+ className = isSent ? "messageOut" : "messageIn";
+ } else {
+ if (eventData->iType == IEED_GC_EVENT_ACTION) {
+ iconFile = "action.gif";
+ className = "action";
+ } else if (eventData->iType == IEED_GC_EVENT_JOIN) {
+ iconFile = "join.gif";
+ className = "userJoined";
+ } else if (eventData->iType == IEED_GC_EVENT_PART) {
+ iconFile = "part.gif";
+ className = "userLeft";
+ } else if (eventData->iType == IEED_GC_EVENT_QUIT) {
+ iconFile = "quit.gif";
+ className = "userDisconnected";
+ } else if (eventData->iType == IEED_GC_EVENT_NICK) {
+ iconFile = "nick.gif";
+ className = "nickChange";
+ } else if (eventData->iType == IEED_GC_EVENT_KICK) {
+ iconFile = "kick.gif";
+ className = "userKicked";
+ } else if (eventData->iType == IEED_GC_EVENT_NOTICE) {
+ iconFile = "notice.gif";
+ className = "notice";
+ } else if (eventData->iType == IEED_GC_EVENT_TOPIC) {
+ iconFile = "topic.gif";
+ className = "topicChange";
+ } else if (eventData->iType == IEED_GC_EVENT_ADDSTATUS) {
+ iconFile = "addstatus.gif";
+ className = "statusEnable";
+ } else if (eventData->iType == IEED_GC_EVENT_REMOVESTATUS) {
+ iconFile = "removestatus.gif";
+ className = "statusDisable";
+ } else if (eventData->iType == IEED_GC_EVENT_INFORMATION) {
+ iconFile = "info.gif";
+ className = "information";
+ }
+ }
+ Utils::appendText(&output, &outputSize, "<div class=\"%s\">", isSent ? "divOut" : "divIn");
+ if (dwData & IEEDD_GC_SHOW_ICON) {
+ Utils::appendIcon(&output, &outputSize, iconFile);
+ }
+ if (dwData & IEEDD_GC_SHOW_TIME) {
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">%s </span>",
+ isSent ? "timestamp" : "timestamp", timestampToString(eventData->time));
+ }
+ if ((dwData & IEEDD_GC_SHOW_NICK) && eventData->iType == IEED_GC_EVENT_MESSAGE) {
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">%s: </span>",
+ isSent ? "nameOut" : "nameIn", szName);
+ }
+ if (dwData & IEEDD_GC_MSG_ON_NEW_LINE) {
+ Utils::appendText(&output, &outputSize, "<br>");
+ }
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">", className);
+ Utils::appendText(&output, &outputSize, "%s", szText);
+ Utils::appendText(&output, &outputSize, "</span></div>\n");
+ if (output != NULL) {
+ view->write(output);
+ free(output);
+ }
+ if (szName!=NULL) delete szName;
+ if (szText!=NULL) delete szText;
+ }
+}
+
+void ChatHTMLBuilder::appendEvent(IEView *view, IEVIEWEVENT *event) {
+ ProtocolSettings *protoSettings = getChatProtocolSettings(event->pszProto);
+ if (protoSettings == NULL) {
+ return;
+ }
+// if (protoSettings->getSRMMMode() == Options::MODE_TEMPLATE) {
+ // appendEventTemplate(view, event);
+// } else {
+ appendEventNonTemplate(view, event);
+// }
+}
+
+bool ChatHTMLBuilder::isDbEventShown(DBEVENTINFO * dbei) {
+ return true;
+}
diff --git a/plugins/IEView/ChatHTMLBuilder.h b/plugins/IEView/ChatHTMLBuilder.h
new file mode 100644
index 0000000000..94f02bf77f
--- /dev/null
+++ b/plugins/IEView/ChatHTMLBuilder.h
@@ -0,0 +1,41 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+class ChatHTMLBuilder;
+
+#ifndef CHATTMLBUILDER_INCLUDED
+#define CHATHTMLBUILDER_INCLUDED
+
+#include "HTMLBuilder.h"
+
+class ChatHTMLBuilder:public HTMLBuilder
+{
+protected:
+ void loadMsgDlgFont(int i, LOGFONTA * lf, COLORREF * colour);
+ char *timestampToString(time_t time);
+ void appendEventNonTemplate(IEView *, IEVIEWEVENT *event);
+ bool isDbEventShown(DBEVENTINFO * dbei);
+public:
+ ChatHTMLBuilder();
+ void buildHead(IEView *, IEVIEWEVENT *event);
+ void appendEvent(IEView *, IEVIEWEVENT *event);
+};
+
+#endif
diff --git a/plugins/IEView/HTMLBuilder.cpp b/plugins/IEView/HTMLBuilder.cpp
new file mode 100644
index 0000000000..7c83609eea
--- /dev/null
+++ b/plugins/IEView/HTMLBuilder.cpp
@@ -0,0 +1,520 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+#include "HTMLBuilder.h"
+#include "m_MathModule.h"
+#include "m_metacontacts.h"
+#include "Utils.h"
+//#include "Smiley.h"
+#include "Options.h"
+
+
+int HTMLBuilder::mimFlags = 0;
+
+HTMLBuilder::HTMLBuilder() {
+ lastIEViewEvent.cbSize = sizeof (IEVIEWEVENT);
+ lastIEViewEvent.iType = IEE_LOG_MEM_EVENTS;
+ lastIEViewEvent.codepage = CP_ACP;
+ lastIEViewEvent.pszProto = NULL;
+ lastIEViewEvent.count = 0;
+ lastIEViewEvent.dwFlags = 0;
+ lastIEViewEvent.hContact = NULL;
+ lastIEViewEvent.hwnd = NULL;
+ lastIEViewEvent.eventData = NULL;
+}
+
+HTMLBuilder::~HTMLBuilder() {
+ if (lastIEViewEvent.pszProto != NULL) {
+ delete (char*)lastIEViewEvent.pszProto;
+ }
+}
+
+bool HTMLBuilder::encode(HANDLE hContact, const char *proto, const wchar_t *text, wchar_t **output, int *outputSize, int level, int flags, bool isSent) {
+ TextToken *token = NULL, *token2;
+ switch (level) {
+ case 0:
+ if (flags & ENF_CHAT_FORMATTING) {
+ token = TextToken::tokenizeChatFormatting(text);
+ break;
+ }
+ level++;
+ case 1:
+ if ((Options::getGeneralFlags()&Options::GENERAL_ENABLE_BBCODES) && (flags & ENF_BBCODES)) {
+ token = TextToken::tokenizeBBCodes(text);
+ break;
+ }
+ level++;
+ case 2:
+ if ((Options::getGeneralFlags()&Options::GENERAL_ENABLE_MATHMODULE) && Options::isMathModule()) {
+ token = TextToken::tokenizeMath(text);
+ break;
+ }
+ level++;
+ case 3:
+ token = TextToken::tokenizeLinks(text);
+ break;
+ case 4:
+ if ((flags & ENF_SMILEYS) ||
+ ((Options::getGeneralFlags() & Options::GENERAL_SMILEYINNAMES) && (flags & ENF_NAMESMILEYS))) {
+ token = TextToken::tokenizeSmileys(hContact, proto, text, isSent);
+ }
+ break;
+ }
+ if (token!=NULL) {
+ for (token2 = token;token!=NULL;token=token2) {
+ bool skip = false;
+ token2 = token->getNext();
+ if (token->getType() == TextToken::TEXT) {
+ skip = encode(hContact, proto, token->getTextW(), output, outputSize, level+1, flags, isSent);
+ }
+ if (!skip) {
+ token->toString(output, outputSize);
+ }
+ delete token;
+ }
+ return true;
+ }
+ return false;
+}
+
+wchar_t * HTMLBuilder::encode(HANDLE hContact, const char *proto, const wchar_t *text, int flags, bool isSent) {
+ int outputSize;
+ wchar_t *output = NULL;
+ if (text != NULL) {
+ encode(hContact, proto, text, &output, &outputSize, 0, flags, isSent);
+ }
+ return output;
+}
+
+char * HTMLBuilder::encodeUTF8(HANDLE hContact, const char *proto, const wchar_t *wtext, int flags, bool isSent) {
+ char *outputStr = NULL;
+ if (wtext != NULL) {
+ wchar_t *output = encode(hContact, proto, wtext, flags, isSent);
+ outputStr = Utils::UTF8Encode(output);
+ if (output != NULL) {
+ free(output);
+ }
+ }
+ return outputStr;
+}
+
+char * HTMLBuilder::encodeUTF8(HANDLE hContact, const char *proto, const char *text, int flags, bool isSent) {
+ char *outputStr = NULL;
+ if (text != NULL) {
+ wchar_t *wtext = Utils::convertToWCS(text);
+ outputStr = encodeUTF8(hContact, proto, wtext, flags, isSent);
+ delete wtext;
+ }
+ return outputStr;
+}
+
+char * HTMLBuilder::encodeUTF8(HANDLE hContact, const char *proto, const char *text, int cp, int flags, bool isSent) {
+ char * outputStr = NULL;
+ if (text != NULL) {
+ wchar_t *wtext = Utils::convertToWCS(text, cp);
+ outputStr = encodeUTF8(hContact, proto, wtext, flags, isSent);
+ delete wtext;
+ }
+ return outputStr;
+}
+
+char *HTMLBuilder::getProto(HANDLE hContact) {
+ return Utils::dupString((char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0));
+}
+
+char *HTMLBuilder::getProto(const char *proto, HANDLE hContact) {
+ if (proto != NULL) {
+ return Utils::dupString(proto);
+ }
+ return Utils::dupString((char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0));
+}
+
+char *HTMLBuilder::getRealProto(HANDLE hContact) {
+ if (hContact != NULL) {
+ char *szProto = Utils::dupString((char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0));
+ if (szProto!=NULL && !strcmp(szProto,"MetaContacts")) {
+ hContact = (HANDLE) CallService(MS_MC_GETMOSTONLINECONTACT, (WPARAM) hContact, 0);
+ if (hContact!=NULL) {
+ delete szProto;
+ szProto = Utils::dupString((char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0));
+ }
+ }
+ return szProto;
+ }
+ return NULL;
+}
+
+char *HTMLBuilder::getRealProto(HANDLE hContact, const char *szProto) {
+ if (szProto!=NULL && !strcmp(szProto,"MetaContacts")) {
+ hContact = (HANDLE) CallService(MS_MC_GETMOSTONLINECONTACT, (WPARAM) hContact, 0);
+ if (hContact!=NULL) {
+ return Utils::dupString((char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0));
+ }
+ }
+ return Utils::dupString(szProto);
+}
+
+HANDLE HTMLBuilder::getRealContact(HANDLE hContact) {
+ char *szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ if (szProto != NULL && !strcmp(szProto,"MetaContacts")) {
+ hContact = (HANDLE) CallService(MS_MC_GETMOSTONLINECONTACT, (WPARAM) hContact, 0);
+ }
+ return hContact;
+}
+
+int HTMLBuilder::getLastEventType() {
+ return iLastEventType;
+}
+
+void HTMLBuilder::setLastEventType(int t) {
+ iLastEventType = t;
+}
+
+DWORD HTMLBuilder::getLastEventTime() {
+ return lastEventTime;
+}
+
+void HTMLBuilder::setLastEventTime(DWORD t) {
+ lastEventTime = t;
+}
+
+bool HTMLBuilder::isSameDate(time_t time1, time_t time2) {
+ struct tm tm_t1, tm_t2;
+ tm_t1 = *localtime((time_t *)(&time1));
+ tm_t2 = *localtime((time_t *)(&time2));
+ if (tm_t1.tm_year == tm_t2.tm_year && tm_t1.tm_mon == tm_t2.tm_mon
+ && tm_t1.tm_mday == tm_t2.tm_mday) {
+ return true;
+ }
+ return false;
+}
+
+void HTMLBuilder::getUINs(HANDLE hContact, char *&uinIn, char *&uinOut) {
+ CONTACTINFO ci;
+ char buf[128];
+ char *szProto;
+ hContact = getRealContact(hContact);
+ szProto = getProto(hContact);
+ ZeroMemory(&ci, sizeof(ci));
+ ci.cbSize = sizeof(ci);
+ ci.hContact = hContact;
+ ci.szProto = szProto;
+ ci.dwFlag = CNF_UNIQUEID;
+ buf[0] = 0;
+ if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) {
+ switch (ci.type) {
+ case CNFT_ASCIIZ:
+ mir_snprintf(buf, sizeof(buf), "%s", ci.pszVal);
+ miranda_sys_free(ci.pszVal);
+ break;
+ case CNFT_DWORD:
+ mir_snprintf(buf, sizeof(buf), "%u", ci.dVal);
+ break;
+ }
+ }
+ uinIn = Utils::UTF8Encode(buf);
+ ci.hContact = NULL;
+ buf[0] = 0;
+ if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) {
+ switch (ci.type) {
+ case CNFT_ASCIIZ:
+ mir_snprintf(buf, sizeof(buf), "%s", ci.pszVal);
+ miranda_sys_free(ci.pszVal);
+ break;
+ case CNFT_DWORD:
+ mir_snprintf(buf, sizeof(buf), "%u", ci.dVal);
+ break;
+ }
+ }
+ uinOut = Utils::UTF8Encode(buf);
+ delete szProto;
+}
+
+wchar_t *HTMLBuilder::getContactName(HANDLE hContact, const char* szProto) {
+ CONTACTINFO ci;
+ wchar_t *szName = NULL;
+ ZeroMemory(&ci, sizeof(ci));
+ ci.cbSize = sizeof(ci);
+ ci.hContact = hContact;
+ ci.szProto = (char *)szProto;
+ ci.dwFlag = CNF_DISPLAY | CNF_UNICODE;
+ if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) {
+ if (ci.type == CNFT_ASCIIZ) {
+ if (ci.pszVal) {
+ if(!wcscmp((wchar_t *)ci.pszVal, TranslateW(L"'(Unknown Contact)'"))) {
+ ci.dwFlag &= ~CNF_UNICODE;
+ if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) {
+ szName = Utils::convertToWCS((char *)ci.pszVal);
+ }
+ } else {
+ szName = Utils::dupString((wchar_t *)ci.pszVal);
+ }
+ miranda_sys_free(ci.pszVal);
+ }
+ }
+ }
+ if (szName != NULL) return szName;
+ ci.dwFlag = CNF_UNIQUEID;
+ if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) {
+ if (ci.type == CNFT_ASCIIZ) {
+ if (ci.pszVal) {
+ szName = Utils::convertToWCS((char *)ci.pszVal);
+ miranda_sys_free(ci.pszVal);
+ }
+ }
+ }
+ if (szName != NULL) return szName;
+ char *szNameStr = (char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, 0);
+ if (szNameStr != NULL) {
+ return Utils::convertToWCS(szNameStr);
+ }
+ return Utils::dupString(TranslateT("(Unknown Contact)"));
+}
+
+char *HTMLBuilder::getEncodedContactName(HANDLE hContact, const char* szProto, const char* szSmileyProto) {
+ char *szName = NULL;
+ wchar_t *name = getContactName(hContact, szProto);
+ if (name != NULL) {
+ szName = encodeUTF8(hContact, szSmileyProto, name, ENF_NAMESMILEYS, true);
+ delete name;
+ return szName;
+ }
+ return encodeUTF8(hContact, szSmileyProto, TranslateT("(Unknown Contact)"), ENF_NAMESMILEYS, true);
+}
+
+void HTMLBuilder::appendEventNew(IEView *view, IEVIEWEVENT *event) {
+ setLastIEViewEvent(event);
+ appendEvent(view, event);
+}
+
+void HTMLBuilder::appendEventOld(IEView *view, IEVIEWEVENT *event) {
+ IEVIEWEVENT newEvent;
+ IEVIEWEVENTDATA* eventData;
+ IEVIEWEVENTDATA* prevEventData = NULL;
+ char *szProto = NULL;
+ HANDLE hDbEvent = event->hDbEventFirst;
+ event->hDbEventFirst = NULL;
+ newEvent.cbSize = sizeof (IEVIEWEVENT);
+ newEvent.iType = IEE_LOG_MEM_EVENTS;
+ newEvent.codepage = CP_ACP;
+ if (event->cbSize >= IEVIEWEVENT_SIZE_V2) {
+ newEvent.codepage = event->codepage;
+ }
+ if (event->cbSize >= IEVIEWEVENT_SIZE_V3 && event->pszProto != NULL) {
+ szProto = Utils::dupString(event->pszProto);
+ } else {
+ szProto = getProto(event->hContact);
+ }
+ newEvent.pszProto = szProto;
+ newEvent.count = 0;
+ newEvent.dwFlags = event->dwFlags;
+ newEvent.hContact = event->hContact;
+ newEvent.hwnd = event->hwnd;
+ newEvent.eventData = NULL;
+ for (int eventIdx = 0; hDbEvent!=NULL && (eventIdx < event->count || event->count==-1); eventIdx++) {
+ DBEVENTINFO dbei = { 0 };
+ dbei.cbSize = sizeof(dbei);
+ dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM) hDbEvent, 0);
+ if (dbei.cbBlob == 0xFFFFFFFF) {
+ hDbEvent = (HANDLE) CallService(MS_DB_EVENT_FINDNEXT, (WPARAM) hDbEvent, 0);
+ continue;
+ }
+ dbei.pBlob = (PBYTE) malloc(dbei.cbBlob);
+ CallService(MS_DB_EVENT_GET, (WPARAM) hDbEvent, (LPARAM) & dbei);
+ if (!(dbei.flags & DBEF_SENT) && (dbei.eventType == EVENTTYPE_MESSAGE || dbei.eventType == EVENTTYPE_URL)) {
+ CallService(MS_DB_EVENT_MARKREAD, (WPARAM) event->hContact, (LPARAM) hDbEvent);
+ CallService(MS_CLIST_REMOVEEVENT, (WPARAM) event->hContact, (LPARAM) hDbEvent);
+ } else if (dbei.eventType == EVENTTYPE_STATUSCHANGE) {
+ CallService(MS_DB_EVENT_MARKREAD, (WPARAM) event->hContact, (LPARAM) hDbEvent);
+ }
+ if (!isDbEventShown(&dbei)) {
+ free(dbei.pBlob);
+ hDbEvent = (HANDLE) CallService(MS_DB_EVENT_FINDNEXT, (WPARAM) hDbEvent, 0);
+ continue;
+ }
+ eventData = new IEVIEWEVENTDATA;
+ eventData->cbSize = sizeof(IEVIEWEVENTDATA);
+ eventData->dwFlags = IEEDF_UNICODE_TEXT | IEEDF_UNICODE_NICK | IEEDF_UNICODE_TEXT2 |
+ (dbei.flags & DBEF_READ ? IEEDF_READ : 0) | (dbei.flags & DBEF_SENT ? IEEDF_SENT : 0) | (dbei.flags & DBEF_RTL ? IEEDF_RTL : 0);
+ if (event->dwFlags & IEEF_RTL) {
+ eventData->dwFlags |= IEEDF_RTL;
+ }
+ eventData->time = dbei.timestamp;
+ eventData->pszNickW = NULL;
+ eventData->pszTextW = NULL;
+ eventData->pszText2W = NULL;
+ if (dbei.flags & DBEF_SENT) {
+ eventData->pszNickW = getContactName(NULL, szProto);
+ eventData->bIsMe = TRUE;
+ } else {
+ eventData->pszNickW = getContactName(event->hContact, szProto);
+ eventData->bIsMe = FALSE;
+ }
+ if (dbei.eventType == EVENTTYPE_MESSAGE || dbei.eventType == EVENTTYPE_URL || dbei.eventType == EVENTTYPE_STATUSCHANGE || dbei.eventType == EVENTTYPE_JABBER_CHATSTATES) {
+ DBEVENTGETTEXT temp = { &dbei, DBVT_WCHAR + ((event->dwFlags & IEEF_NO_UNICODE) ? DBVTF_DENYUNICODE : 0), newEvent.codepage };
+ WCHAR* pwszEventText = (WCHAR*)CallService(MS_DB_EVENT_GETTEXT,0,(LPARAM)&temp);
+ eventData->pszTextW = Utils::dupString( pwszEventText );
+ mir_free( pwszEventText );
+ if (dbei.eventType == EVENTTYPE_MESSAGE) {
+ eventData->iType = IEED_EVENT_MESSAGE;
+ } else if (dbei.eventType == EVENTTYPE_URL) {
+ eventData->iType = IEED_EVENT_URL;
+ } else {
+ eventData->iType = IEED_EVENT_STATUSCHANGE;
+ }
+ } else if (dbei.eventType == EVENTTYPE_FILE) {
+ //blob is: sequenceid(DWORD),filename(ASCIIZ),description(ASCIIZ)
+ char* filename = ((char *)dbei.pBlob) + sizeof(DWORD);
+ char* descr = filename + lstrlenA(filename) + 1;
+ TCHAR *tStr = DbGetEventStringT(&dbei, filename);
+ eventData->ptszText = Utils::dupString(tStr);
+ mir_free(tStr);
+ if (*descr != '\0') {
+ tStr = DbGetEventStringT(&dbei, descr);
+ eventData->ptszText2 = Utils::dupString(tStr);
+ mir_free(tStr);
+ }
+ eventData->iType = IEED_EVENT_FILE;
+ } else if (dbei.eventType == EVENTTYPE_AUTHREQUEST) {
+ //blob is: uin(DWORD), hContact(DWORD), nick(ASCIIZ), first(ASCIIZ), last(ASCIIZ), email(ASCIIZ)
+ eventData->ptszText = Utils::dupString(TranslateT(" requested authorisation"));
+ TCHAR *tStr = DbGetEventStringT(&dbei, (char *)dbei.pBlob + 8);
+ eventData->ptszNick = Utils::dupString(tStr);
+ mir_free(tStr);
+ eventData->iType = IEED_EVENT_SYSTEM;
+ } else if (dbei.eventType == EVENTTYPE_ADDED) {
+ //blob is: uin(DWORD), hContact(DWORD), nick(ASCIIZ), first(ASCIIZ), last(ASCIIZ), email(ASCIIZ)
+ eventData->ptszText = Utils::dupString(TranslateT(" was added."));
+ TCHAR *tStr = DbGetEventStringT(&dbei, (char *)dbei.pBlob + 8);
+ eventData->ptszNick = Utils::dupString(tStr);
+ mir_free(tStr);
+ eventData->iType = IEED_EVENT_SYSTEM;
+ }
+ free(dbei.pBlob);
+ eventData->next = NULL;
+ if (prevEventData != NULL) {
+ prevEventData->next = eventData;
+ } else {
+ newEvent.eventData = eventData;
+ }
+ prevEventData = eventData;
+ newEvent.count++;
+ event->hDbEventFirst = hDbEvent;
+ hDbEvent = (HANDLE) CallService(MS_DB_EVENT_FINDNEXT, (WPARAM) hDbEvent, 0);
+ }
+ appendEventNew(view, &newEvent);
+ for ( IEVIEWEVENTDATA* eventData2 = newEvent.eventData; eventData2 != NULL; eventData2 = eventData) {
+ eventData = eventData2->next;
+ if (eventData2->pszTextW != NULL) {
+ delete (wchar_t*)eventData2->pszTextW;
+ }
+ if (eventData2->pszText2W != NULL) {
+ delete (wchar_t*)eventData2->pszText2W;
+ }
+ if (eventData2->pszNickW != NULL) {
+ delete (wchar_t*)eventData2->pszNickW;
+ }
+ delete eventData2;
+ }
+ if (szProto != NULL) {
+ delete szProto;
+ }
+}
+
+ProtocolSettings* HTMLBuilder::getSRMMProtocolSettings(const char *protocolName) {
+ ProtocolSettings *protoSettings = Options::getProtocolSettings(protocolName);
+ if (protoSettings == NULL || !protoSettings->isSRMMEnable()) {
+ protoSettings = Options::getProtocolSettings();
+ }
+ return protoSettings;
+}
+
+ProtocolSettings* HTMLBuilder::getSRMMProtocolSettings(HANDLE hContact) {
+ char *szRealProto = getRealProto(hContact);
+ ProtocolSettings *protoSettings = getSRMMProtocolSettings(szRealProto);
+ delete szRealProto;
+ return protoSettings;
+}
+
+ProtocolSettings* HTMLBuilder::getHistoryProtocolSettings(const char *protocolName) {
+ ProtocolSettings *protoSettings = Options::getProtocolSettings(protocolName);
+ if (protoSettings == NULL || !protoSettings->isHistoryEnable()) {
+ protoSettings = Options::getProtocolSettings();
+ }
+ return protoSettings;
+}
+
+ProtocolSettings* HTMLBuilder::getHistoryProtocolSettings(HANDLE hContact) {
+ ProtocolSettings *protoSettings;
+ if (hContact != NULL) {
+ char *szRealProto = getRealProto(hContact);
+ protoSettings = getHistoryProtocolSettings(szRealProto);
+ delete szRealProto;
+ } else {
+ protoSettings = Options::getProtocolSettings();
+ }
+ return protoSettings;
+}
+
+ProtocolSettings* HTMLBuilder::getChatProtocolSettings(const char *protocolName) {
+ ProtocolSettings *protoSettings = Options::getProtocolSettings(protocolName);
+ if (protoSettings == NULL || !protoSettings->isChatEnable()) {
+ protoSettings = Options::getProtocolSettings();
+ }
+ return protoSettings;
+}
+
+ProtocolSettings* HTMLBuilder::getChatProtocolSettings(HANDLE hContact) {
+ char *szRealProto = getRealProto(hContact);
+ ProtocolSettings *protoSettings = getChatProtocolSettings(szRealProto);
+ delete szRealProto;
+ return protoSettings;
+}
+
+void HTMLBuilder::setLastIEViewEvent(IEVIEWEVENT *event) {
+ lastIEViewEvent.cbSize = sizeof (IEVIEWEVENT);
+ lastIEViewEvent.iType = event->iType;
+ lastIEViewEvent.codepage = CP_ACP;
+ if (event->cbSize >= IEVIEWEVENT_SIZE_V2) {
+ lastIEViewEvent.codepage = event->codepage;
+ }
+ lastIEViewEvent.count = 0;
+ lastIEViewEvent.dwFlags = event->dwFlags;
+ lastIEViewEvent.hContact = event->hContact;
+ lastIEViewEvent.hwnd = event->hwnd;
+ lastIEViewEvent.eventData = NULL;
+ if (lastIEViewEvent.pszProto != NULL) {
+ delete (char *)lastIEViewEvent.pszProto ;
+ }
+ if (event->cbSize >= IEVIEWEVENT_SIZE_V3 && event->pszProto != NULL) {
+ lastIEViewEvent.pszProto = Utils::dupString(event->pszProto);
+ } else {
+ lastIEViewEvent.pszProto = getProto(event->hContact);
+ }
+}
+
+void HTMLBuilder::clear(IEView *view, IEVIEWEVENT *event) {
+ if (event != NULL) {
+ setLastIEViewEvent(event);
+ }
+ if (lastIEViewEvent.pszProto != NULL || event->hContact == NULL) {
+ buildHead(view, &lastIEViewEvent);
+ }
+}
diff --git a/plugins/IEView/HTMLBuilder.h b/plugins/IEView/HTMLBuilder.h
new file mode 100644
index 0000000000..9650d60712
--- /dev/null
+++ b/plugins/IEView/HTMLBuilder.h
@@ -0,0 +1,90 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+class HTMLBuilder;
+
+#ifndef HTMLBUILDER_INCLUDED
+#define HTMLBUILDER_INCLUDED
+
+#define EVENTTYPE_STATUSCHANGE 25368
+#define EVENTTYPE_JABBER_CHATSTATES 2000
+
+#include "IEView.h"
+#include "Options.h"
+#include "TextToken.h"
+
+class HTMLBuilder {
+private:
+ IEVIEWEVENT lastIEViewEvent;
+ static int mimFlags;
+ enum MIMFLAGS {
+ MIM_CHECKED = 1,
+ MIM_UNICODE = 2
+ };
+protected:
+ DWORD lastEventTime;
+ int iLastEventType;
+ enum ENCODEFLAGS {
+ ENF_NONE = 0,
+ ENF_SMILEYS = 1,
+ ENF_NAMESMILEYS = 2,
+ ENF_BBCODES = 4,
+ ENF_LINKS = 8,
+ ENF_ALL = 255,
+ ENF_CHAT_FORMATTING = 256
+ };
+// virtual char *encode(const char *text, const char *proto, bool replaceSmiley);
+ virtual char *encodeUTF8(HANDLE hContact, const char *proto, const wchar_t *text, int flags, bool isSent);
+ virtual char *encodeUTF8(HANDLE hContact, const char *proto, const char *text, int flags, bool isSent);
+ virtual char *encodeUTF8(HANDLE hContact, const char *proto, const char *text, int cp, int flags, bool isSent);
+ virtual wchar_t *encode(HANDLE hContact, const char *proto, const wchar_t *text, int flags, bool isSent);
+ virtual bool encode(HANDLE hContact, const char *proto, const wchar_t *text, wchar_t **output, int *outputSize, int level, int flags, bool isSent);
+ virtual char* getProto(HANDLE hContact);
+ virtual char* getProto(const char *proto, HANDLE hContact);
+ virtual char* getRealProto(HANDLE hContact);
+ virtual char* getRealProto(HANDLE hContact, const char *proto);
+ virtual wchar_t *getContactName(HANDLE hContact, const char* szProto);
+ virtual char *getEncodedContactName(HANDLE hContact, const char *szProto, const char *szSmileyProto);
+ virtual void getUINs(HANDLE hContact, char *&uinIn, char *&uinOut);
+ virtual HANDLE getRealContact(HANDLE hContact);
+ virtual DWORD getLastEventTime();
+ virtual void setLastEventTime(DWORD);
+ virtual int getLastEventType();
+ virtual void setLastEventType(int);
+ virtual bool isSameDate(time_t time1, time_t time2);
+ virtual bool isDbEventShown(DBEVENTINFO * dbei)=0;
+ virtual ProtocolSettings *getSRMMProtocolSettings(const char *protocolName);
+ virtual ProtocolSettings *getSRMMProtocolSettings(HANDLE hContact);
+ virtual ProtocolSettings *getHistoryProtocolSettings(const char *protocolName);
+ virtual ProtocolSettings *getHistoryProtocolSettings(HANDLE hContact);
+ virtual ProtocolSettings *getChatProtocolSettings(const char *protocolName);
+ virtual ProtocolSettings *getChatProtocolSettings(HANDLE hContact);
+ void setLastIEViewEvent(IEVIEWEVENT *event);
+ virtual void buildHead(IEView *, IEVIEWEVENT *event)=0;
+public:
+ HTMLBuilder();
+ virtual ~HTMLBuilder();
+ void appendEventOld(IEView *, IEVIEWEVENT *event);
+ void appendEventNew(IEView *, IEVIEWEVENT *event);
+ void clear(IEView *, IEVIEWEVENT *event);
+ virtual void appendEvent(IEView *, IEVIEWEVENT *event)=0;
+};
+
+#endif
diff --git a/plugins/IEView/HistoryHTMLBuilder.cpp b/plugins/IEView/HistoryHTMLBuilder.cpp
new file mode 100644
index 0000000000..3bce0d8749
--- /dev/null
+++ b/plugins/IEView/HistoryHTMLBuilder.cpp
@@ -0,0 +1,306 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+#include "HistoryHTMLBuilder.h"
+
+#include "Options.h"
+#include "Utils.h"
+
+// srmm stuff
+#define SMF_LOG_SHOWNICK 1
+#define SMF_LOG_SHOWTIME 2
+#define SMF_LOG_SHOWDATES 4
+#define SMF_LOG_SHOWICONS 8
+#define HPPMOD "HistoryPlusPlus"
+
+#define SRMSGSET_SHOWICONS "ShowIcons"
+
+#define FONTF_BOLD 1
+#define FONTF_ITALIC 2
+#define FONTF_UNDERLINE 4
+
+#define DIV_FONT_NUM 7
+
+static const char *divClassNames[] = {
+ ".divMessageOut", ".divMessageIn",
+ ".divFileOut", ".divFileIn",
+ ".divUrlOut", ".divUrlIn",
+ ".divSystem"
+};
+
+static const char *dbDivSettingNames[] = {
+ "OutMes", "IncMes",
+ "OutFil", "IncFil",
+ "OutUrl", "IncUrl",
+ "Added"
+};
+
+#define SPAN_FONT_NUM 4
+
+static const char *spanClassNames[] = {
+ ".nameOut", ".nameIn",
+ ".timeOut", ".timeIn",
+};
+
+static const char *dbSpanSettingNames[] = {
+ "Profile", "Contact",
+ "ProfileDate", "ContactDate",
+};
+
+HistoryHTMLBuilder::HistoryHTMLBuilder() {
+ setLastEventType(-1);
+ setLastEventTime(time(NULL));
+ startedTime = time(NULL);
+}
+
+bool HistoryHTMLBuilder::isDbEventShown(DBEVENTINFO * dbei)
+{
+ switch (dbei->eventType) {
+ case EVENTTYPE_MESSAGE:
+ return 1;
+ case EVENTTYPE_STATUSCHANGE:
+ return 1;
+ }
+ return 1;
+}
+
+char *HistoryHTMLBuilder::timestampToString(DWORD dwFlags, time_t check) {
+ static char szResult[512];
+ char str[80];
+ DBTIMETOSTRING dbtts;
+ dbtts.cbDest = 70;;
+ dbtts.szDest = str;
+ szResult[0] = '\0';
+ dbtts.szFormat = (char *)"d t";
+ CallService(MS_DB_TIME_TIMESTAMPTOSTRING, check, (LPARAM) & dbtts);
+ strncat(szResult, str, 500);
+ Utils::UTF8Encode(szResult, szResult, 500);
+ return szResult;
+}
+
+void HistoryHTMLBuilder::loadMsgDlgFont(const char *dbSetting, LOGFONTA * lf, COLORREF * colour, COLORREF * bkgColour) {
+ char str[128];
+ int style;
+ DBVARIANT dbv;
+ if (bkgColour) {
+ wsprintfA(str, "Back.%s", dbSetting);
+ *bkgColour = DBGetContactSettingDword(NULL, HPPMOD, str, 0xFFFFFF);
+ }
+ if (colour) {
+ wsprintfA(str, "Font.%s.Color", dbSetting);
+ *colour = DBGetContactSettingDword(NULL, HPPMOD, str, 0x000000);
+ }
+ if (lf) {
+ wsprintfA(str, "Font.%s.Size", dbSetting);
+ lf->lfHeight = (char) DBGetContactSettingByte(NULL, HPPMOD, str, 10);
+ lf->lfWidth = 0;
+ lf->lfEscapement = 0;
+ lf->lfOrientation = 0;
+ wsprintfA(str, "Font.%s.Style.Bold", dbSetting);
+ style = DBGetContactSettingByte(NULL, HPPMOD, str, 0);
+ lf->lfWeight = style & FONTF_BOLD ? FW_BOLD : FW_NORMAL;
+ wsprintfA(str, "Font.%s.Style.Italic", dbSetting);
+ style = DBGetContactSettingByte(NULL, HPPMOD, str, 0) << 1;
+ lf->lfItalic = style & FONTF_ITALIC ? 1 : 0;
+ lf->lfUnderline = style & FONTF_UNDERLINE ? 1 : 0;
+ lf->lfStrikeOut = 0;
+ wsprintfA(str, "Font.%s.Charset", dbSetting);
+ lf->lfCharSet = DBGetContactSettingByte(NULL, HPPMOD, str, DEFAULT_CHARSET);
+ lf->lfOutPrecision = OUT_DEFAULT_PRECIS;
+ lf->lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ lf->lfQuality = DEFAULT_QUALITY;
+ lf->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
+ wsprintfA(str, "Font.%s.Name", dbSetting);
+ if (DBGetContactSetting(NULL, HPPMOD, str, &dbv))
+ lstrcpyA(lf->lfFaceName, "Verdana");
+ else {
+ lstrcpynA(lf->lfFaceName, dbv.pszVal, sizeof(lf->lfFaceName));
+ DBFreeVariant(&dbv);
+ }
+ }
+}
+
+const char *HistoryHTMLBuilder::getTemplateFilename(ProtocolSettings * protoSettings) {
+ return protoSettings->getHistoryTemplateFilename();
+}
+
+int HistoryHTMLBuilder::getFlags(ProtocolSettings * protoSettings) {
+ return protoSettings->getHistoryFlags();
+}
+
+void HistoryHTMLBuilder::buildHead(IEView *view, IEVIEWEVENT *event) {
+ LOGFONTA lf;
+ int i;
+ COLORREF color, bkgColor;
+ char *output = NULL;
+ int outputSize;
+ ProtocolSettings *protoSettings = getHistoryProtocolSettings(event->hContact);
+ if (protoSettings == NULL) {
+ return;
+ }
+ if (protoSettings->getHistoryMode() == Options::MODE_TEMPLATE) {
+ buildHeadTemplate(view, event, protoSettings);
+ return;
+ }
+ if (protoSettings->getHistoryMode() == Options::MODE_CSS) {
+ const char *externalCSS = protoSettings->getHistoryCssFilename();
+ Utils::appendText(&output, &outputSize, "<html><head><link rel=\"stylesheet\" href=\"%s\"/></head><body class=\"body\">\n", externalCSS);
+ } else {
+ Utils::appendText(&output, &outputSize, "<html><head>");
+ Utils::appendText(&output, &outputSize, "<style type=\"text/css\">\n");
+ COLORREF lineColor = DBGetContactSettingDword(NULL, HPPMOD, "LineColour", 0xFFFFFF);
+ lineColor= 0;//(((lineColor & 0xFF) << 16) | (lineColor & 0xFF00) | ((lineColor & 0xFF0000) >> 16));
+ bkgColor = 0xFFFFFF;
+ if (protoSettings->getHistoryFlags() & Options::LOG_IMAGE_ENABLED) {
+ Utils::appendText(&output, &outputSize, ".body {padding: 2px; text-align: left; background-attachment: %s; background-color: #%06X; background-image: url('%s'); overflow: auto;}\n",
+ protoSettings->getHistoryFlags() & Options::LOG_IMAGE_SCROLL ? "scroll" : "fixed", (int) bkgColor, protoSettings->getHistoryBackgroundFilename());
+ } else {
+ Utils::appendText(&output, &outputSize, ".body {margin: 0px; text-align: left; background-color: #%06X; overflow: auto;}\n",
+ (int) bkgColor);
+ }
+ Utils::appendText(&output, &outputSize, ".link {color: #0000FF; text-decoration: underline;}\n");
+ Utils::appendText(&output, &outputSize, ".img {float: left; vertical-align: middle;}\n");
+ for(i = 0; i < DIV_FONT_NUM; i++) {
+ loadMsgDlgFont(dbDivSettingNames[i], &lf, &color, &bkgColor);
+ if (protoSettings->getHistoryFlags() & Options::LOG_IMAGE_ENABLED) {
+ Utils::appendText(&output, &outputSize, "%s {float: left; padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #%06X; font-family: %s; font-size: %dpt; font-weight: %s; color: #%06X; %s}\n",
+ divClassNames[i],
+ (int) lineColor,
+ lf.lfFaceName,
+ lf.lfHeight,
+ lf.lfWeight >= FW_BOLD ? "bold" : "normal",
+ (int)(((color & 0xFF) << 16) | (color & 0xFF00) | ((color & 0xFF0000) >> 16)),
+ lf.lfItalic ? "font-style: italic;" : "");
+ } else {
+ Utils::appendText(&output, &outputSize, "%s {float: left; padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #%06X; background-color: #%06X; font-family: %s; font-size: %dpt; font-weight: %s; color: #%06X; %s}\n",
+ divClassNames[i],
+ (int) lineColor,
+ (int)(((bkgColor & 0xFF) << 16) | (bkgColor & 0xFF00) | ((bkgColor & 0xFF0000) >> 16)),
+ lf.lfFaceName,
+ lf.lfHeight,
+ lf.lfWeight >= FW_BOLD ? "bold" : "normal",
+ (int)(((color & 0xFF) << 16) | (color & 0xFF00) | ((color & 0xFF0000) >> 16)),
+ lf.lfItalic ? "font-style: italic;" : "");
+ }
+ }
+ for(i = 0; i < SPAN_FONT_NUM; i++) {
+ loadMsgDlgFont(dbSpanSettingNames[i], &lf, &color, NULL);
+ Utils::appendText(&output, &outputSize, "%s {float: %s; font-family: %s; font-size: %dpt; font-weight: %s; color: #%06X; %s }\n",
+ spanClassNames[i],
+ i < 2 ? "left" : "right; clear: right;",
+ lf.lfFaceName,
+ lf.lfHeight,
+ lf.lfWeight >= FW_BOLD ? "bold" : "normal",
+ (int)(((color & 0xFF) << 16) | (color & 0xFF00) | ((color & 0xFF0000) >> 16)),
+ lf.lfItalic ? "font-style: italic;" : "");
+ }
+ Utils::appendText(&output, &outputSize, "</style></head><body class=\"body\">\n");
+ }
+ if (output != NULL) {
+ view->write(output);
+ free(output);
+ }
+ setLastEventType(-1);
+}
+
+void HistoryHTMLBuilder::appendEventNonTemplate(IEView *view, IEVIEWEVENT *event) {
+
+ DWORD dwFlags = DBGetContactSettingByte(NULL, HPPMOD, SRMSGSET_SHOWICONS, 0) ? SMF_LOG_SHOWICONS : 0;
+ char *szRealProto = getRealProto(event->hContact);
+ IEVIEWEVENTDATA* eventData = event->eventData;
+ for (int eventIdx = 0; eventData!=NULL && (eventIdx < event->count || event->count==-1); eventData = eventData->next, eventIdx++) {
+ int outputSize;
+ char *output;
+ output = NULL;
+ int isSent = eventData->dwFlags & IEEDF_SENT;
+ int isRTL = eventData->dwFlags & IEEDF_RTL;
+ if (eventData->iType == IEED_EVENT_MESSAGE || eventData->iType == IEED_EVENT_STATUSCHANGE
+ || eventData->iType == IEED_EVENT_URL || eventData->iType == IEED_EVENT_FILE) {
+ char *szName = NULL;
+ char *szText = NULL;
+ if (eventData->dwFlags & IEEDF_UNICODE_NICK) {
+ szName = encodeUTF8(event->hContact, szRealProto, eventData->pszNickW, ENF_NAMESMILEYS, true);
+ } else {
+ szName = encodeUTF8(event->hContact, szRealProto, eventData->pszNick, ENF_NAMESMILEYS, true);
+ }
+ if (eventData->dwFlags & IEEDF_UNICODE_TEXT) {
+ szText = encodeUTF8(event->hContact, szRealProto, eventData->pszTextW, eventData->iType == IEED_EVENT_MESSAGE ? ENF_ALL : 0, isSent);
+ } else {
+ szText = encodeUTF8(event->hContact, szRealProto, eventData->pszText, event->codepage, eventData->iType == IEED_EVENT_MESSAGE ? ENF_ALL : 0, isSent);
+ }
+ /* History++-specific formatting */
+ const char *className = NULL;
+ const char *iconFile = NULL;
+ switch (eventData->iType) {
+ case IEED_EVENT_SYSTEM:
+ Utils::appendText(&output, &outputSize, "<div class=\"%s\">", "divSystem");
+ break;
+ case IEED_EVENT_FILE:
+ iconFile = "file.gif";
+ Utils::appendText(&output, &outputSize, "<div class=\"%s\">", isSent ? "divFileOut" : "divFileIn");
+ break;
+ case IEED_EVENT_URL:
+ iconFile = "url.gif";
+ Utils::appendText(&output, &outputSize, "<div class=\"%s\">", isSent ? "divUrlOut" : "divUrlIn");
+ break;
+ default:
+ iconFile = "message.gif";
+ Utils::appendText(&output, &outputSize, "<div class=\"%s\">", isSent ? "divMessageOut" : "divMessageIn");
+ }
+ if (dwFlags & SMF_LOG_SHOWICONS && iconFile != NULL) {
+ Utils::appendIcon(&output, &outputSize, iconFile);
+ } else {
+ Utils::appendText(&output, &outputSize, " ");
+ }
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">%s:</span>", isSent ? "nameOut" : "nameIn", szName);
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">%s</span><br>", isSent ? "timeOut" : "timeIn", timestampToString(dwFlags, eventData->time));
+ if (eventData->iType == IEED_EVENT_FILE) {
+ Utils::appendText(&output, &outputSize, "%s:<br> %s", isSent ? Translate("Outgoing File Transfer") : Translate("Incoming File Transfer"), szText);
+ } else if (eventData->iType == IEED_EVENT_URL) {
+ Utils::appendText(&output, &outputSize, "%s:<br> %s", isSent ? Translate("URL sent") : Translate("URL received"), szText);
+ } else {
+ Utils::appendText(&output, &outputSize, "%s", szText);
+ }
+ Utils::appendText(&output, &outputSize, "</div>\n");
+ setLastEventType(MAKELONG(eventData->dwFlags, eventData->iType));
+ setLastEventTime(eventData->time);
+ if (szName!=NULL) delete szName;
+ if (szText!=NULL) delete szText;
+ }
+ if (output != NULL) {
+ view->write(output);
+ free(output);
+ }
+ }
+ if (szRealProto!=NULL) delete szRealProto;
+ view->documentClose();
+}
+
+void HistoryHTMLBuilder::appendEvent(IEView *view, IEVIEWEVENT *event) {
+ ProtocolSettings *protoSettings = getHistoryProtocolSettings(event->hContact);
+ if (protoSettings == NULL) {
+ return;
+ }
+ if (protoSettings->getHistoryMode() & Options::MODE_TEMPLATE) {
+ appendEventTemplate(view, event, protoSettings);
+ } else{
+ appendEventNonTemplate(view, event);
+ }
+}
diff --git a/plugins/IEView/HistoryHTMLBuilder.h b/plugins/IEView/HistoryHTMLBuilder.h
new file mode 100644
index 0000000000..d5806e4c3a
--- /dev/null
+++ b/plugins/IEView/HistoryHTMLBuilder.h
@@ -0,0 +1,45 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+class HistoryHTMLBuilder;
+
+#ifndef HISTORYHTMLBUILDER_INCLUDED
+#define HISTORYHTMLBUILDER_INCLUDED
+
+#include "TemplateHTMLBuilder.h"
+
+class HistoryHTMLBuilder:public TemplateHTMLBuilder
+{
+protected:
+ void loadMsgDlgFont(const char *, LOGFONTA * lf, COLORREF * colour, COLORREF * bkgColour);
+ char *timestampToString(DWORD dwFlags, time_t check);
+ DWORD startedTime;
+ bool isDbEventShown(DBEVENTINFO * dbei);
+ void appendEventNonTemplate(IEView *, IEVIEWEVENT *event);
+ const char *getTemplateFilename(ProtocolSettings *);
+ const char *getTemplateFilenameRtl(ProtocolSettings *);
+ int getFlags(ProtocolSettings *);
+public:
+ HistoryHTMLBuilder();
+ void buildHead(IEView *, IEVIEWEVENT *event);
+ void appendEvent(IEView *, IEVIEWEVENT *event);
+};
+
+#endif
diff --git a/plugins/IEView/IEView.cpp b/plugins/IEView/IEView.cpp
new file mode 100644
index 0000000000..78b4645420
--- /dev/null
+++ b/plugins/IEView/IEView.cpp
@@ -0,0 +1,1219 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+#include "IEView.h"
+#include "resource.h"
+#include "Options.h"
+#include "Utils.h"
+
+//#include <Urlmon.h>
+
+
+#define WM_WAITWHILEBUSY (WM_USER+600)
+//#define GECKO
+#define DISPID_BEFORENAVIGATE2 250 // hyperlink clicked on
+#define DISPID_NAVIGATECOMPLETE2 252 // UIActivate new document
+#define DISPID_DOCUMENTCOMPLETE 259 // new document goes ReadyState_Complete
+
+IEView * IEView::list = NULL;
+CRITICAL_SECTION IEView::mutex;
+bool IEView::isInited = false;
+
+struct MM_INTERFACE mmi;
+
+
+static LRESULT CALLBACK IEViewServerWindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
+ IEView *view = IEView::get(GetParent(GetParent(hwnd)));
+ if (view != NULL) {
+ switch (message) {
+ case WM_KEYUP:
+ if (LOWORD(wParam) == VK_ESCAPE && !(GetKeyState(VK_SHIFT) & 0x8000)
+ && !(GetKeyState(VK_CONTROL) & 0x8000) && !(GetKeyState(VK_MENU) & 0x8000)) {
+ //if (view->getBuilder() != NULL) {
+ SendMessage(GetParent(GetParent(GetParent(hwnd))), WM_COMMAND, IDCANCEL, 0);
+// } else {
+
+ // }
+ }
+ break;
+ case WM_KEYDOWN:
+ view->translateAccelerator(message, wParam, lParam);
+ break;
+ case WM_SETFOCUS:
+ {
+ RECT rcWindow;
+ POINT cursor;
+ GetWindowRect(hwnd, &rcWindow);
+ GetCursorPos(&cursor);
+ if (cursor.y > rcWindow.bottom || cursor.y < rcWindow.top ||
+ cursor.x > rcWindow.right || cursor.x < rcWindow.left) {
+ } else {
+ view->mouseActivate();
+ }
+ if (view->setFocus((HWND)wParam)) {
+ return TRUE;
+ }
+ }
+ break;
+ case WM_LBUTTONDOWN:
+ POINT pt;
+ pt.x = LOWORD(lParam);
+ pt.y = HIWORD(lParam);
+ if (view->mouseClick(pt)) {
+ return TRUE;
+ }
+ break;
+ }
+ return CallWindowProc(view->getServerWndProc(), hwnd, message, wParam, lParam);
+ }
+ return DefWindowProc (hwnd, message, wParam, lParam);
+}
+
+static LRESULT CALLBACK IEViewDocWindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
+ IEView *view = IEView::get(GetParent(hwnd));
+ if (view!=NULL) {
+ WNDPROC oldWndProc = view->getDocWndProc();
+ if (message == WM_PARENTNOTIFY && wParam == WM_CREATE) {
+ SetWindowLong(hwnd, GWLP_WNDPROC, (LONG_PTR) oldWndProc);
+ view->setServerWndProc((WNDPROC) SetWindowLong((HWND)lParam, GWLP_WNDPROC, (LONG_PTR) IEViewServerWindowProcedure));
+ }
+ return CallWindowProc(oldWndProc, hwnd, message, wParam, lParam);
+ }
+ return DefWindowProc (hwnd, message, wParam, lParam);
+}
+
+static LRESULT CALLBACK IEViewWindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
+ IEView *view = IEView::get(hwnd);
+ if (view!=NULL) {
+ WNDPROC oldWndProc = view->getMainWndProc();
+ if (message == WM_PARENTNOTIFY && wParam == WM_CREATE) {
+ SetWindowLong(hwnd, GWLP_WNDPROC, (LONG_PTR) oldWndProc);
+ view->setDocWndProc((WNDPROC) SetWindowLong((HWND)lParam, GWLP_WNDPROC, (LONG_PTR) IEViewDocWindowProcedure));
+ }
+ return CallWindowProc(oldWndProc, hwnd, message, wParam, lParam);
+ }
+ return DefWindowProc (hwnd, message, wParam, lParam);
+}
+
+IEViewSink::IEViewSink(IEView *smptr) {
+ ieWindow = smptr;
+}
+
+IEViewSink::~IEViewSink() {}
+
+STDMETHODIMP IEViewSink::QueryInterface(REFIID riid, PVOID *ppv) {
+ *ppv=NULL;
+ if (IID_IUnknown==riid) {
+ *ppv=(IUnknown *)this;
+ }
+ if (IID_IDispatch==riid) {
+ *ppv=(IDispatch *)this;
+ }
+ if (DIID_DWebBrowserEvents2==riid) {
+ *ppv=(DWebBrowserEvents2*)this;
+ }
+ if (NULL!=*ppv) {
+ ((LPUNKNOWN)*ppv)->AddRef();
+ return NOERROR;
+ }
+ return E_NOINTERFACE;
+}
+
+STDMETHODIMP_(ULONG) IEViewSink::AddRef(void) {
+ ++m_cRef;
+ return m_cRef;
+}
+
+STDMETHODIMP_(ULONG) IEViewSink::Release(void) {
+ --m_cRef;
+ return m_cRef;
+}
+
+STDMETHODIMP IEViewSink::GetTypeInfoCount(UINT *ptr) { return E_NOTIMPL; }
+STDMETHODIMP IEViewSink::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo) { return S_OK; }
+STDMETHODIMP IEViewSink::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId) { return S_OK; }
+
+STDMETHODIMP IEViewSink::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid , WORD wFlags,
+ DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO*pExcepInfo, UINT*puArgErr) {
+ if (!pDispParams) return E_INVALIDARG;
+ switch (dispIdMember) {
+ case DISPID_BEFORENAVIGATE2:
+ BeforeNavigate2(pDispParams->rgvarg[6].pdispVal,
+ pDispParams->rgvarg[5].pvarVal,
+ pDispParams->rgvarg[4].pvarVal,
+ pDispParams->rgvarg[3].pvarVal,
+ pDispParams->rgvarg[2].pvarVal,
+ pDispParams->rgvarg[1].pvarVal,
+ pDispParams->rgvarg[0].pboolVal);
+ return S_OK;
+ }
+ return DISP_E_MEMBERNOTFOUND;
+}
+// DWebBrowserEvents2
+
+void IEViewSink::StatusTextChange(BSTR text) {}
+void IEViewSink::ProgressChange(long progress, long progressMax) {}
+void IEViewSink::CommandStateChange(long command, VARIANT_BOOL enable) {}
+void IEViewSink::DownloadBegin() {}
+void IEViewSink::DownloadComplete() {}
+void IEViewSink::TitleChange(BSTR text) {}
+void IEViewSink::PropertyChange(BSTR text) {}
+void IEViewSink::BeforeNavigate2(IDispatch* pDisp,VARIANT* url,VARIANT* flags, VARIANT* targetFrameName,
+ VARIANT* postData, VARIANT* headers, VARIANT_BOOL* cancel) {
+ int i = (int)wcslen(url->bstrVal);
+ char *tTemp = new char[i+1];
+ WideCharToMultiByte(CP_ACP, 0, url->bstrVal, -1, tTemp, i+1, NULL, NULL);
+#ifndef GECKO
+ if (strcmp(tTemp, "about:blank")) {
+// if (smileyWindow==NULL) {
+ CallService(MS_UTILS_OPENURL, (WPARAM) 1, (LPARAM) tTemp);
+// } else {
+ // smileyWindow->choose(tTemp);
+ // }
+ *cancel = VARIANT_TRUE;
+ }
+#endif
+ delete tTemp;
+}
+
+void IEViewSink::NewWindow2(IDispatch** ppDisp, VARIANT_BOOL* cancel) {}
+void IEViewSink::NavigateComplete(IDispatch* pDisp, VARIANT* url) {}
+void IEViewSink::DocumentComplete(IDispatch* pDisp, VARIANT* url) {}
+void IEViewSink::OnQuit() {}
+void IEViewSink::OnVisible(VARIANT_BOOL visible) {}
+void IEViewSink::OnToolBar(VARIANT_BOOL visible) {}
+void IEViewSink::OnMenuBar(VARIANT_BOOL visible) {}
+void IEViewSink::OnStatusBar(VARIANT_BOOL visible) {}
+void IEViewSink::OnFullScreen(VARIANT_BOOL visible) {}
+void IEViewSink::OnTheaterMode(VARIANT_BOOL visible) {}
+void IEViewSink::WindowSetResizable(VARIANT_BOOL visible) {}
+void IEViewSink::WindowSetLeft(long val) {}
+void IEViewSink::WindowSetTop(long val) {}
+void IEViewSink::WindowSetWidth(long val) {}
+void IEViewSink::WindowSetHeight(long val) {}
+void IEViewSink::WindowClosing(VARIANT_BOOL isChildWindow, VARIANT_BOOL* cancel) {}
+void IEViewSink::ClientToHostWindow(long *cx, long *cy) {}
+void IEViewSink::SetSecureLockIcon(long val) {}
+void IEViewSink::FileDownload(VARIANT_BOOL* cancel) {}
+
+
+#ifdef GECKO
+
+static void __cdecl StartThread(void *vptr) {
+ IEView *iev = (IEView *) vptr;
+ iev->waitWhileBusy();
+ return;
+}
+#endif
+
+void IEView::waitWhileBusy() {
+ VARIANT_BOOL busy;
+ pWebBrowser->get_Busy(&busy);
+ while (busy == VARIANT_TRUE) {
+ Sleep(10);
+ pWebBrowser->get_Busy(&busy);
+ }
+ PostMessage(hwnd, WM_WAITWHILEBUSY, 0, 0);
+}
+
+void IEView::setBorder() {
+ LONG style = GetWindowLong(hwnd, GWL_EXSTYLE);
+ LONG oldStyle = style;
+ if (Options::getGeneralFlags() & Options::GENERAL_NO_BORDER) {
+#ifndef GECKO
+ style &= ~(WS_EX_STATICEDGE);
+#endif
+ } else {
+ style |= (WS_EX_STATICEDGE);
+ }
+ if (oldStyle != style) {
+ SetWindowLong(hwnd,GWL_EXSTYLE,style);
+ SetWindowPos(getHWND(), NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
+ }
+// RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATENOW);
+}
+
+IEView::IEView(HWND parent, HTMLBuilder* builder, int x, int y, int cx, int cy) {
+ MSG msg;
+ IOleObject* pOleObject = NULL;
+ IOleInPlaceObject *pOleInPlace;
+ isContactSet = false;
+ this->parent = parent;
+ this->builder = builder;
+ prev = next = NULL;
+ hwnd = NULL;
+ sink = NULL;
+ pWebBrowser = NULL;
+ m_pConnectionPoint = NULL;
+ m_cRef = 0;
+ selectedText = NULL;
+ getFocus = false;
+ rcClient.left = x;
+ rcClient.top = y;
+ rcClient.right = x + cx;
+ rcClient.bottom = y + cy;
+#ifdef GECKO
+ if (SUCCEEDED(CoCreateInstance(CLSID_MozillaBrowser, NULL, CLSCTX_INPROC, IID_IWebBrowser2, (LPVOID*)&pWebBrowser))) {
+#else
+ if (SUCCEEDED(CoCreateInstance(CLSID_WebBrowser, NULL, CLSCTX_INPROC, IID_IWebBrowser2, (LPVOID*)&pWebBrowser))) {
+#endif
+// pWebBrowser->put_RegisterAsBrowser(VARIANT_FALSE);
+ if (SUCCEEDED(pWebBrowser->QueryInterface(IID_IOleObject, (void**)&pOleObject))) {
+ pOleObject->SetClientSite(this);
+ pOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, &msg, this, 0, this->parent, &rcClient);
+ pOleObject->Release();
+ } else {
+ MessageBoxA(NULL,"IID_IOleObject failed.","RESULT",MB_OK);
+ }
+
+ if (SUCCEEDED(pWebBrowser->QueryInterface(IID_IOleInPlaceObject, (void**)&pOleInPlace))) {
+ pOleInPlace->GetWindow(&hwnd);
+ pOleInPlace->Release();
+ } else {
+ MessageBoxA(NULL,"IID_IOleInPlaceObject failed.","RESULT",MB_OK);
+ }
+
+ setBorder();
+ IConnectionPointContainer* pCPContainer;
+ // Step 1: Get a pointer to the connection point container.
+ if (SUCCEEDED(pWebBrowser->QueryInterface(IID_IConnectionPointContainer,
+ (void**)&pCPContainer))) {
+ // m_pConnectionPoint is defined like this:
+ // Step 2: Find the connection point.
+ if (SUCCEEDED(pCPContainer->FindConnectionPoint(DIID_DWebBrowserEvents2,
+ &m_pConnectionPoint))) {
+ // Step 3: Advise the connection point that you
+ // want to sink its events.
+ sink = new IEViewSink(this);
+ if (FAILED(m_pConnectionPoint->Advise((IUnknown *)sink, &m_dwCookie))) {
+ MessageBoxA(NULL, "Failed to Advise", "C++ Event Sink", MB_OK);
+ }
+ }
+ pCPContainer->Release();
+ }
+#ifndef GECKO
+ setMainWndProc((WNDPROC)SetWindowLong(hwnd, GWLP_WNDPROC, (LONG_PTR) IEViewWindowProcedure));
+#else
+// setMainWndProc((WNDPROC)SetWindowLong(hwnd, GWLP_WNDPROC, (LONG_PTR) MozillaWindowProcedure));
+#endif
+ }
+ EnterCriticalSection(&mutex);
+ next = list;
+ if (next != NULL) {
+ next->prev = this;
+ }
+ list = this;
+ LeaveCriticalSection(&mutex);
+// clear();
+ pWebBrowser->put_RegisterAsDropTarget(VARIANT_FALSE);
+}
+
+IEView::~IEView() {
+ IOleObject* pOleObject = NULL;
+ EnterCriticalSection(&mutex);
+ if (list == this) {
+ list = next;
+ } else if (prev!=NULL) {
+ prev->next = next;
+ }
+ if (next != NULL) {
+ next->prev = prev;
+ }
+ prev = NULL;
+ next = NULL;
+ LeaveCriticalSection(&mutex);
+ if (SUCCEEDED(pWebBrowser->QueryInterface(IID_IOleObject, (void**)&pOleObject))) {
+ pOleObject->SetClientSite(NULL);
+ pOleObject->Release();
+ } else {
+ MessageBoxA(NULL,"IID_IOleObject failed.","RESULT",MB_OK);
+ }
+ if (builder != NULL) {
+ delete builder;
+ builder = NULL;
+ }
+ if (m_pConnectionPoint != NULL) {
+ m_pConnectionPoint->Unadvise(m_dwCookie);
+ m_pConnectionPoint->Release();
+ }
+ if (sink != NULL) {
+ delete sink;
+ }
+ if (selectedText != NULL) {
+ delete selectedText;
+ }
+#ifndef GECKO
+ pWebBrowser->Release();
+#endif
+ DestroyWindow(hwnd);
+}
+
+void IEView::init() {
+ if (isInited) return;
+ isInited = true;
+ InitializeCriticalSection(&mutex);
+ if (FAILED(OleInitialize(NULL))) {
+ MessageBoxA(NULL,"OleInitialize failed.","ERROR",MB_OK);
+ }
+}
+
+void IEView::release() {
+ EnterCriticalSection(&mutex);
+ while (list != NULL) {
+ delete list;
+ }
+ LeaveCriticalSection(&mutex);
+ DeleteCriticalSection(&mutex);
+}
+
+IEView* IEView::get(HWND hwnd) {
+ IEView *ptr;
+ if (list == NULL) return NULL;
+ EnterCriticalSection(&mutex);
+ for (ptr = list; ptr !=NULL; ptr=ptr->next) {
+ if (ptr->hwnd == hwnd) {
+ break;
+ }
+ }
+ LeaveCriticalSection(&mutex);
+ return ptr;
+}
+
+void IEView::setMainWndProc(WNDPROC wndProc) {
+ mainWndProc = wndProc;
+}
+
+WNDPROC IEView::getMainWndProc() {
+ return mainWndProc;
+}
+
+void IEView::setDocWndProc(WNDPROC wndProc) {
+ docWndProc = wndProc;
+}
+
+WNDPROC IEView::getDocWndProc() {
+ return docWndProc;
+}
+
+void IEView::setServerWndProc(WNDPROC wndProc) {
+ serverWndProc = wndProc;
+}
+
+WNDPROC IEView::getServerWndProc() {
+ return serverWndProc;
+}
+
+// IUnknown
+STDMETHODIMP IEView::QueryInterface(REFIID riid, PVOID *ppv) {
+ *ppv=NULL;
+ if (IID_IUnknown==riid)
+ *ppv=this;
+ if (IID_IOleClientSite==riid)
+ *ppv=(IOleClientSite*)this;//Unknown)m_pIOleClientSite;
+ if (IID_IOleWindow==riid || IID_IOleInPlaceSite==riid)
+ *ppv=(IOleInPlaceSite*)this;//m_pIOleIPSite;
+ if (IID_IDocHostUIHandler==riid)
+ *ppv=(IDocHostUIHandler*)this;//m_pIOleIPSite;
+ if (IID_IInternetSecurityManager==riid)
+ *ppv=(IInternetSecurityManager*)this;
+ if (IID_IServiceProvider==riid) {
+ *ppv=(IServiceProvider*)this;
+ }
+ if (NULL!=*ppv) {
+ ((LPUNKNOWN)*ppv)->AddRef();
+ return NOERROR;
+ }
+ return E_NOINTERFACE;
+}
+
+STDMETHODIMP_(ULONG) IEView::AddRef(void) {
+ ++m_cRef;
+ return m_cRef;
+}
+
+STDMETHODIMP_(ULONG) IEView::Release(void) {
+ --m_cRef;
+ return m_cRef;
+}
+
+// IDispatch
+STDMETHODIMP IEView::GetTypeInfoCount(UINT *ptr) { return E_NOTIMPL; }
+STDMETHODIMP IEView::GetTypeInfo(UINT iTInfo, LCID lcid, LPTYPEINFO* ppTInfo) { return S_OK; }
+STDMETHODIMP IEView::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId) { return S_OK; }
+
+STDMETHODIMP IEView::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid , WORD wFlags,
+ DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO*pExcepInfo, UINT*puArgErr) {
+ switch (dispIdMember) {
+ case DISPID_AMBIENT_DLCONTROL:
+ break;
+ }
+ return DISP_E_MEMBERNOTFOUND;
+}
+
+// IOleWindow
+STDMETHODIMP IEView::GetWindow(HWND *phwnd) {
+ *phwnd = parent;
+ return S_OK;
+}
+
+STDMETHODIMP IEView::ContextSensitiveHelp(BOOL fEnterMode) {
+ return E_NOTIMPL;
+}
+
+// IOleInPlace
+STDMETHODIMP IEView::CanInPlaceActivate(void) {
+ return S_OK;
+}
+
+STDMETHODIMP IEView::OnInPlaceActivate(void) {
+ m_bInPlaceActive = TRUE;
+ return S_OK;
+}
+
+STDMETHODIMP IEView::OnUIActivate(void) {
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP IEView::GetWindowContext(IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc,
+ LPRECT lprcPosRect, LPRECT lprcClipRect,
+ LPOLEINPLACEFRAMEINFO lpFrameInfo) {
+
+ lprcPosRect->left = rcClient.left;
+ lprcPosRect->top = rcClient.top;
+ lprcPosRect->right = rcClient.right;
+ lprcPosRect->bottom = rcClient.bottom;
+ lprcClipRect->left = rcClient.left;
+ lprcClipRect->top = rcClient.top;
+ lprcClipRect->right = rcClient.right;
+ lprcClipRect->bottom = rcClient.bottom;
+ return S_OK;
+}
+
+STDMETHODIMP IEView::Scroll(SIZE scrollExtant) {
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP IEView::OnUIDeactivate(BOOL fUndoable) {
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP IEView::OnInPlaceDeactivate( void) {
+ m_bInPlaceActive = FALSE;
+ return S_OK;
+}
+
+STDMETHODIMP IEView::DiscardUndoState( void) {
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP IEView::DeactivateAndUndo( void) {
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP IEView::OnPosRectChange(LPCRECT lprcPosRect) {
+ return E_NOTIMPL;
+}
+
+// IOleClientSite
+STDMETHODIMP IEView::SaveObject(void) {
+ return E_NOTIMPL;
+}
+STDMETHODIMP IEView::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk) {
+ return E_NOTIMPL;
+}
+STDMETHODIMP IEView::GetContainer(IOleContainer **ppContainer) {
+ return E_NOTIMPL;
+}
+STDMETHODIMP IEView::ShowObject(void) {
+ return E_NOTIMPL;
+}
+STDMETHODIMP IEView::OnShowWindow(BOOL fShow) {
+ return E_NOTIMPL;
+}
+STDMETHODIMP IEView::RequestNewObjectLayout(void) {
+ return E_NOTIMPL;
+}
+// IDocHostUIHandler
+STDMETHODIMP IEView::ShowContextMenu(DWORD dwID, POINT *ppt, IUnknown *pcmdTarget, IDispatch *pdispReserved) {
+ IOleCommandTarget * pOleCommandTarget;
+ IOleWindow * pOleWindow;
+ HWND hSPWnd;
+ if (builder == NULL) {
+ // return S_OK;
+ }
+#ifdef GECKO
+ {
+ return E_NOTIMPL;
+/*
+ HMENU hMenu;
+ hMenu = GetSubMenu(LoadMenu(hInstance, MAKEINTRESOURCE(IDR_CONTEXTMENU)),0);
+ CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)hMenu,0);
+ if (dwID == 6) { // anchor
+ EnableMenuItem(hMenu, ID_MENU_COPYLINK, MF_BYCOMMAND | MF_ENABLED);
+ } else if (dwID == 5) { // text select
+ EnableMenuItem(hMenu, ID_MENU_COPY, MF_BYCOMMAND | MF_ENABLED);
+ } else if (dwID == 1) { // control (image)
+ EnableMenuItem(hMenu, ID_MENU_SAVEIMAGE, MF_BYCOMMAND | MF_ENABLED);
+ }
+ if (builder!=NULL) {
+
+ }
+ int iSelection = TrackPopupMenu(hMenu,
+ TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
+ ppt->x,
+ ppt->y,
+ 0,
+ hwnd,
+ (RECT*)NULL);
+ DestroyMenu(hMenu);
+ if (iSelection == ID_MENU_CLEARLOG) {
+ clear(NULL);
+ } else {
+ SendMessage(hSPWnd, WM_COMMAND, iSelection, (LPARAM) NULL);
+ }
+*/
+ }
+#else
+ if (SUCCEEDED(pcmdTarget->QueryInterface(IID_IOleCommandTarget, (void**)&pOleCommandTarget))) {
+ if (SUCCEEDED(pOleCommandTarget->QueryInterface(IID_IOleWindow, (void**)&pOleWindow))) {
+ pOleWindow->GetWindow(&hSPWnd);
+ HMENU hMenu;
+ hMenu = GetSubMenu(LoadMenu(hInstance, MAKEINTRESOURCE(IDR_CONTEXTMENU)),0);
+ CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)hMenu,0);
+ if (dwID == 5) { // anchor
+ EnableMenuItem(hMenu, ID_MENU_COPYLINK, MF_BYCOMMAND | MF_ENABLED);
+ } else if (dwID == 4) { // text select
+ EnableMenuItem(hMenu, ID_MENU_COPY, MF_BYCOMMAND | MF_ENABLED);
+ } else if (dwID == 1) { // control (image)
+ EnableMenuItem(hMenu, ID_MENU_SAVEIMAGE, MF_BYCOMMAND | MF_ENABLED);
+ }
+ if (builder!=NULL) {
+
+ }
+ int iSelection = TrackPopupMenu(hMenu,
+ TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
+ ppt->x,
+ ppt->y,
+ 0,
+ hwnd,
+ (RECT*)NULL);
+ DestroyMenu(hMenu);
+ if (iSelection == ID_MENU_CLEARLOG) {
+ clear(NULL);
+ } else {
+ SendMessage(hSPWnd, WM_COMMAND, iSelection, (LPARAM) NULL);
+ }
+ pOleWindow->Release();
+ }
+ pOleCommandTarget->Release();
+ }
+#endif
+ return S_OK;
+}
+STDMETHODIMP IEView::GetHostInfo(DOCHOSTUIINFO *pInfo) {
+ pInfo->dwFlags = DOCHOSTUIFLAG_NO3DBORDER;// | DOCHOSTUIFLAG_DISABLE_SCRIPT_INACTIVE;
+ if (builder == NULL) {
+ pInfo->dwFlags |= DOCHOSTUIFLAG_DIALOG;
+ }
+ return S_OK;
+}
+STDMETHODIMP IEView::ShowUI(DWORD dwID, IOleInPlaceActiveObject *pActiveObject, IOleCommandTarget *pCommandTarget,
+ IOleInPlaceFrame *pFrame, IOleInPlaceUIWindow *pDoc) {
+ return S_OK;
+}
+
+STDMETHODIMP IEView::HideUI(void) {return S_OK;}
+STDMETHODIMP IEView::UpdateUI(void) {return S_OK;}
+STDMETHODIMP IEView::EnableModeless(BOOL fEnable) { return E_NOTIMPL; }
+STDMETHODIMP IEView::OnDocWindowActivate(BOOL fEnable) { return E_NOTIMPL; }
+STDMETHODIMP IEView::OnFrameWindowActivate(BOOL fEnable) { return E_NOTIMPL; }
+STDMETHODIMP IEView::ResizeBorder(LPCRECT prcBorder, IOleInPlaceUIWindow *pUIWindow, BOOL fRameWindow) {return E_NOTIMPL;}
+STDMETHODIMP IEView::TranslateAccelerator(LPMSG lpMsg, const GUID *pguidCmdGroup, DWORD nCmdID) { return S_FALSE;}
+STDMETHODIMP IEView::GetOptionKeyPath(LPOLESTR *pchKey, DWORD dw) { return E_NOTIMPL; }
+STDMETHODIMP IEView::GetDropTarget(IDropTarget *pDropTarget, IDropTarget **ppDropTarget) {
+ *ppDropTarget = NULL;
+ return S_OK;
+// return E_NOTIMPL;
+}
+
+STDMETHODIMP IEView::GetExternal(IDispatch **ppDispatch) {
+ *ppDispatch = NULL;
+ return S_FALSE;
+}
+STDMETHODIMP IEView::TranslateUrl(DWORD dwTranslate, OLECHAR *pchURLIn, OLECHAR **ppchURLOut) { return E_NOTIMPL; }
+STDMETHODIMP IEView::FilterDataObject(IDataObject *pDO, IDataObject **ppDORet) { return E_NOTIMPL; }
+
+
+/* IServiceProvider */
+STDMETHODIMP IEView::QueryService(REFGUID guidService, REFIID riid, void** ppvObject) {
+ if (guidService == SID_SInternetSecurityManager && riid == IID_IInternetSecurityManager) {
+ return (HRESULT)this->QueryInterface(riid, ppvObject);
+ } else {
+ *ppvObject = NULL;
+ }
+ return E_NOINTERFACE;
+}
+
+/* IInternetSecurityManager */
+
+STDMETHODIMP IEView::SetSecuritySite(IInternetSecurityMgrSite *pSite) {
+ return INET_E_DEFAULT_ACTION;
+}
+
+STDMETHODIMP IEView::GetSecuritySite(IInternetSecurityMgrSite **ppSite) {
+ return INET_E_DEFAULT_ACTION;
+}
+
+STDMETHODIMP IEView::MapUrlToZone(LPCWSTR pwszUrl, DWORD *pdwZone, DWORD dwFlags) {
+ if (pdwZone!=NULL && pwszUrl!=NULL && !wcscmp(pwszUrl, L"about:blank")) {
+ *pdwZone = URLZONE_LOCAL_MACHINE;
+ return S_OK;
+ }
+ return INET_E_DEFAULT_ACTION;
+}
+
+STDMETHODIMP IEView::GetSecurityId(LPCWSTR pwszUrl, BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved) {
+ return INET_E_DEFAULT_ACTION;
+}
+
+STDMETHODIMP IEView::ProcessUrlAction(LPCWSTR pwszUrl, DWORD dwAction, BYTE *pPolicy, DWORD cbPolicy, BYTE *pContext, DWORD cbContext, DWORD dwFlags, DWORD dwReserved) {
+ DWORD dwPolicy=URLPOLICY_ALLOW;
+ if (pwszUrl!=NULL && !wcscmp(pwszUrl, L"about:blank")) {
+// char str[1024];
+// sprintf(str, "kod: %08X", dwAction);
+// MessageBox(NULL,str, "Security", MB_OK);
+ if (dwAction <= URLACTION_ACTIVEX_MAX && dwAction >= URLACTION_ACTIVEX_MIN) {
+ //dwPolicy = URLPOLICY_DISALLOW;
+ //dwPolicy = URLPOLICY_ALLOW;
+ } else if ((dwAction <= URLACTION_JAVA_MAX && dwAction >= URLACTION_JAVA_MIN) || URLACTION_HTML_JAVA_RUN == dwAction) {
+ // dwPolicy = URLPOLICY_JAVA_PROHIBIT;
+ return INET_E_DEFAULT_ACTION;
+ } else if (dwAction <= URLACTION_SCRIPT_MAX && dwAction >= URLACTION_SCRIPT_MIN) {
+ //dwPolicy = URLPOLICY_DISALLOW;
+ //dwPolicy = URLPOLICY_ALLOW;
+ } else if (dwAction <= URLACTION_HTML_MIN && dwAction >= URLACTION_HTML_MAX) {
+ //dwPolicy = URLPOLICY_DISALLOW;
+ //dwPolicy = URLPOLICY_ALLOW;
+ } else {
+ return INET_E_DEFAULT_ACTION;
+ }
+ if ( cbPolicy >= sizeof (DWORD)) {
+ *(DWORD*) pPolicy = dwPolicy;
+ return S_OK;
+ } else {
+ return S_FALSE;
+ }
+ }
+ return INET_E_DEFAULT_ACTION;
+}
+
+STDMETHODIMP IEView::QueryCustomPolicy(LPCWSTR pwszUrl, REFGUID guidKey, BYTE **ppPolicy, DWORD *pcbPolicy, BYTE *pContext, DWORD cbContext, DWORD dwReserved) {
+ return INET_E_DEFAULT_ACTION;
+}
+
+STDMETHODIMP IEView::SetZoneMapping(DWORD dwZone, LPCWSTR lpszPattern, DWORD dwFlags) {
+ return INET_E_DEFAULT_ACTION;
+}
+
+STDMETHODIMP IEView::GetZoneMappings(DWORD dwZone, IEnumString **ppenumString, DWORD dwFlags) {
+ return INET_E_DEFAULT_ACTION;
+}
+
+
+IHTMLDocument2 *IEView::getDocument() {
+ HRESULT hr = S_OK;
+ IHTMLDocument2 *document = NULL;
+ IDispatch *dispatch = NULL;
+ if (SUCCEEDED(pWebBrowser->get_Document(&dispatch)) && (dispatch != NULL)) {
+ hr = dispatch->QueryInterface(IID_IHTMLDocument2, (void **)&document);
+ dispatch->Release();
+ }
+ return document;
+}
+
+void IEView::setWindowPos(int x, int y, int cx, int cy) {
+ rcClient.left = x;
+ rcClient.top = y;
+ rcClient.right = cx;
+ rcClient.bottom = cy;//y + cy;
+ if (builder == NULL) {
+ //scrollToTop();
+ } else {
+// scrollToBottomSoft();
+ }
+ SetWindowPos(getHWND(), HWND_TOP, x, y, cx, cy, 0);
+ /*
+ IOleInPlaceObject * inPlaceObject;
+ if (SUCCEEDED(pWebBrowser->QueryInterface(IID_IOleInPlaceObject, (void **)&inPlaceObject))) {
+ inPlaceObject->SetObjectRects(&rcClient, &rcClient);
+ inPlaceObject->Release();
+ }
+ */
+ if (builder == NULL) {
+ //scrollToTop();
+ } else {
+// scrollToBottomSoft();
+ }
+}
+
+void IEView::scrollToTop() {
+ IHTMLDocument2 *document = getDocument();
+ if (document != NULL) {
+ IHTMLWindow2* pWindow = NULL;
+ if (SUCCEEDED(document->get_parentWindow( &pWindow )) && pWindow != NULL) {
+ pWindow->scrollBy( -0x01FFFFFF, -0x01FFFFFF );
+ pWindow->Release();
+ }
+ document->Release();
+ }
+}
+
+void IEView::scrollToBottomSoft() {
+ IHTMLDocument2 *document = getDocument();
+ if (document != NULL) {
+ IHTMLWindow2* pWindow = NULL;
+ if (SUCCEEDED(document->get_parentWindow( &pWindow )) && (pWindow != NULL)) {
+ pWindow->scrollBy( -0x01FFFFFF, 0x01FFFFFF );
+ pWindow->Release();
+ }
+ document->Release();
+ }
+}
+
+void IEView::scrollToBottom() {/*
+ IHTMLDocument2 *document = getDocument();
+ if (document != NULL) {
+ wchar_t *p = NULL;
+ if (SUCCEEDED(document->get_readyState(&p))) {
+ int licznik = 0;
+ do {
+ if (FAILED(document->get_readyState(&p))) {
+ break;
+ }
+ licznik++;
+ if (licznik == 1) break;
+ Sleep(10);
+ } while (!wcscmp(p, L"loading"));
+ }
+ IHTMLWindow2* pWindow = NULL;
+ if (SUCCEEDED(document->get_parentWindow( &pWindow )) && pWindow != NULL) {
+ pWindow->scrollBy( 0, 0x01FFFFFF );
+ }
+ document->Release();
+ }*/
+
+ IHTMLDocument2 *document = getDocument();
+ if (document != NULL) {
+ IHTMLElementCollection *collection;
+ IHTMLElement *element;
+ IDispatch *dispatch;
+ if (SUCCEEDED(document->get_all(&collection)) && (collection != NULL)) {
+ long len;
+ if (SUCCEEDED(collection->get_length(&len))) {
+ VARIANT variant;
+ variant.vt = VT_I4;
+ variant.lVal = len-1;
+ if (SUCCEEDED(collection->item(variant, variant, &dispatch)) && (dispatch != NULL)) {
+ if (SUCCEEDED(dispatch->QueryInterface(IID_IHTMLElement,(void**)&element)) && (element != NULL)) {
+ variant.vt = VT_BOOL;
+ variant.boolVal = VARIANT_FALSE;
+ if (SUCCEEDED(element->scrollIntoView(variant))) {
+ }
+ element->Release();
+ }
+ dispatch->Release();
+ }
+ }
+ collection->Release();
+ }
+ IHTMLWindow2* pWindow = NULL;
+ if (SUCCEEDED(document->get_parentWindow( &pWindow )) && (pWindow != NULL)) {
+ pWindow->scrollBy( -0x0000FFFF, 0x0000FFFF );
+ pWindow->Release();
+ }
+ document->Release();
+ }
+}
+
+void IEView::write(const wchar_t *text) {
+ IHTMLDocument2 *document = getDocument();
+ if (document != NULL) {
+ SAFEARRAY *safe_array = SafeArrayCreateVector(VT_VARIANT,0,1);
+ if (safe_array != NULL) {
+ VARIANT *variant;
+ BSTR bstr;
+ SafeArrayAccessData(safe_array,(LPVOID *)&variant);
+ variant->vt = VT_BSTR;
+ variant->bstrVal = bstr = SysAllocString(text);
+ SafeArrayUnaccessData(safe_array);
+ document->write(safe_array);
+ //SysFreeString(bstr); -> SafeArrayDestroy should be enough
+ SafeArrayDestroy(safe_array);
+ }
+ document->Release();
+ }
+}
+
+void IEView::write(const char *text) {
+ int textLen = (int)strlen(text) + 1;
+ wchar_t *wcsTemp = new wchar_t[textLen];
+ MultiByteToWideChar(CP_UTF8, 0, text, -1, wcsTemp, textLen);
+ write(wcsTemp);
+ delete [] wcsTemp;
+}
+
+void IEView::writef(const char *fmt, ...) {
+ char *str;
+ va_list vararg;
+ int strsize;
+ va_start(vararg, fmt);
+ str = (char *) malloc(strsize=2048);
+ while (_vsnprintf(str, strsize, fmt, vararg) == -1)
+ str = (char *) realloc(str, strsize+=2048);
+ va_end(vararg);
+ write(str);
+ free(str);
+}
+
+void IEView::navigate(const char *url) {
+ int textLen = (int)strlen(url) + 1;
+ WCHAR *tTemp = new WCHAR[textLen];
+ MultiByteToWideChar(CP_ACP, 0, url, -1, tTemp, textLen);
+ pWebBrowser->Navigate(tTemp, NULL, NULL, NULL, NULL);
+ delete tTemp;
+}
+
+void IEView::navigate(const wchar_t *url) {
+ pWebBrowser->Navigate((WCHAR *)url, NULL, NULL, NULL, NULL);
+}
+
+void IEView::documentClose() {
+
+#ifdef GECKO
+ /*
+ IHTMLDocument2 *document = getDocument();
+ if (document != NULL) {
+ //write("</body></html>");
+ document->close();
+ document->Release();
+ }
+ */
+#endif
+}
+
+void IEView::appendEventOld(IEVIEWEVENT *event) {
+ if (clearRequired) {
+ clear(event);
+ }
+ if (builder!=NULL) {
+ builder->appendEventOld(this, event);
+ }
+ getFocus = false;
+}
+
+void IEView::appendEvent(IEVIEWEVENT *event) {
+ if (clearRequired) {
+ clear(event);
+ }
+ if (event->eventData == NULL) {return; }
+
+ if (builder!=NULL) {
+ builder->appendEventNew(this, event);
+ }
+ getFocus = false;
+}
+
+void IEView::clear(IEVIEWEVENT *event) {
+#ifdef GECKO
+ pWebBrowser->Navigate(L"about:blank", NULL, NULL, NULL, NULL);
+ Utils::forkThread((void (__cdecl *)(void *))StartThread, 0, (void *) this);
+ MSG msg;
+ BOOL bRet;
+ while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0) {
+ if (bRet == -1) {
+ // handle the error and possibly exit
+ } else {
+ if (msg.message == WM_WAITWHILEBUSY) {
+ break;
+ } else {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+ }
+ {
+ IHTMLDocument2 *document = getDocument();
+ if (document != NULL) {
+ document->close();
+ VARIANT open_name;
+ VARIANT open_features;
+ VARIANT open_replace;
+ IDispatch *open_window = NULL;
+ VariantInit(&open_name);
+ open_name.vt = VT_BSTR;
+ open_name.bstrVal = SysAllocString(L"_self");
+ VariantInit(&open_features);
+ VariantInit(&open_replace);
+
+ HRESULT hr = document->open(SysAllocString(L"text/html"),
+ open_name,
+ open_features,
+ open_replace,
+ &open_window);
+ if (hr == S_OK) {
+ // pWebBrowser->Refresh();
+ }
+ if (open_window != NULL) {
+ open_window->Release();
+ }
+ document->Release();
+ }
+ if (builder!=NULL) {
+ builder->clear(this, event);
+ }
+ clearRequired = false;
+ getFocus = false;
+
+ }
+ return;
+#endif
+ IHTMLDocument2 *document = getDocument();
+ if (document == NULL) {
+ pWebBrowser->Navigate(L"about:blank", NULL, NULL, NULL, NULL);
+ HRESULT hr = S_OK;
+ IHTMLDocument2 *document = NULL;
+ while ((document == NULL) && (hr == S_OK)) {
+ Sleep(0);
+ IDispatch *dispatch = NULL;
+ if (SUCCEEDED(pWebBrowser->get_Document(&dispatch)) && (dispatch != NULL)) {
+ hr = dispatch->QueryInterface(IID_IHTMLDocument2, (void **)&document);
+ dispatch->Release();
+ }
+ }
+ if (document != NULL) {
+ document->Release();
+ }
+ } else {
+ document->close();
+ VARIANT open_name;
+ VARIANT open_features;
+ VARIANT open_replace;
+ IDispatch *open_window = NULL;
+ VariantInit(&open_name);
+ open_name.vt = VT_BSTR;
+ open_name.bstrVal = SysAllocString(L"_self");
+ VariantInit(&open_features);
+ VariantInit(&open_replace);
+
+ HRESULT hr = document->open(SysAllocString(L"text/html"),
+ open_name,
+ open_features,
+ open_replace,
+ &open_window);
+ if (hr == S_OK) {
+ // pWebBrowser->Refresh();
+ }
+ if (open_window != NULL) {
+ open_window->Release();
+ }
+ document->Release();
+ }
+ if (builder!=NULL) {
+ builder->clear(this, event);
+ }
+ clearRequired = false;
+ getFocus = false;
+ setBorder();
+}
+
+void* IEView::getSelection(IEVIEWEVENT *event) {
+ if (selectedText!=NULL) delete selectedText;
+ selectedText = getSelection();
+ if (selectedText == NULL || wcslen(selectedText)== 0) return NULL;
+ if (event->dwFlags & IEEF_NO_UNICODE) {
+ int cp = CP_ACP;
+ if (event->cbSize >= IEVIEWEVENT_SIZE_V2) {
+ cp = event->codepage;
+ }
+ char *str = Utils::convertToString(selectedText, cp);
+ delete selectedText;
+ selectedText = (BSTR) str;
+ }
+ return (void *)selectedText;
+}
+
+
+HWND IEView::getHWND() {
+ return hwnd;
+}
+
+
+void IEView::setContact(HANDLE hContact) {
+ this->hContact = hContact;
+ isContactSet = true;
+}
+
+void IEView::translateAccelerator(UINT uMsg, WPARAM wParam, LPARAM lParam) {
+ IOleInPlaceActiveObject* pIOIPAO;
+ if (SUCCEEDED(pWebBrowser->QueryInterface(IID_IOleInPlaceActiveObject, (void**)&pIOIPAO))) {
+ MSG msg;
+ msg.message = uMsg;
+ msg.wParam = wParam;
+ msg.lParam = lParam;
+ pIOIPAO->TranslateAccelerator(&msg);
+ pIOIPAO->Release();
+ }
+}
+
+/**
+ * Returns the selected text within the active document
+ **/
+BSTR IEView::getSelection() {
+ BSTR text = NULL;
+ IHTMLDocument2 *document = getDocument();
+ if (document != NULL) {
+ IHTMLSelectionObject *pSelection = NULL;
+ if (SUCCEEDED(document->get_selection( &pSelection )) && pSelection != NULL) {
+ IDispatch *pDisp = NULL;
+ if (SUCCEEDED(pSelection->createRange( &pDisp )) && pDisp != NULL) {
+ IHTMLTxtRange *pRange = NULL;
+ if (SUCCEEDED(pDisp->QueryInterface(IID_IHTMLTxtRange, (void**)&pRange))) {
+ if (SUCCEEDED(pRange->get_text(&text))) {
+ text = Utils::dupString(text);
+ }
+ pRange->Release();
+ }
+ pDisp->Release();
+ }
+ pSelection->Release();
+ }
+ document->Release();
+ }
+ return text;
+}
+
+
+/**
+ * Returns the destination url (href) of the given anchor element (or parent anchor element)
+ **/
+BSTR IEView::getHrefFromAnchor(IHTMLElement *element) {
+ if (element != NULL) {
+ IHTMLAnchorElement * pAnchor;
+ if (SUCCEEDED(element->QueryInterface(IID_IHTMLAnchorElement, (void**)&pAnchor)) && (pAnchor!=NULL)) {
+ VARIANT variant;
+ BSTR url;
+ if (SUCCEEDED(element->getAttribute(L"href", 2, &variant) && variant.vt == VT_BSTR)) {
+ url = Utils::dupString(variant.bstrVal);
+ SysFreeString(variant.bstrVal);
+ }
+ //pAnchor->get_href( &url );
+// if (url!=NULL) {
+// url2 = Utils::dupString(url);
+// SysFreeString(url);
+ // url = url2;
+ // }
+ pAnchor->Release();
+ return url;
+ } else {
+ IHTMLElement * parent;
+ if (SUCCEEDED(element->get_parentElement(&parent)) && (parent!=NULL)) {
+ BSTR url = getHrefFromAnchor(parent);
+ parent->Release();
+ return url;
+ }
+ }
+ }
+ return NULL;
+}
+
+bool IEView::mouseActivate() {
+ if (GetFocus() != hwnd) {
+ getFocus = true;
+ }
+ return false;
+}
+
+bool IEView::mouseClick(POINT pt) {
+ bool result = false;
+ if (GetFocus() != hwnd) {
+ getFocus = true;
+ }
+ IHTMLDocument2 *document = getDocument();
+ if (document != NULL) {
+ IHTMLElement *element;
+ if (SUCCEEDED(document->elementFromPoint( pt.x, pt.y, &element ))&& element!=NULL) {
+// IHTMLAnchorElement * pAnchor;
+// if (SUCCEEDED(element->QueryInterface(IID_IHTMLAnchorElement, (void**)&pAnchor)) && (pAnchor!=NULL)) {
+// element->click();
+// result = true;
+// pAnchor->Release();
+// }
+ BSTR url = getHrefFromAnchor(element);
+ if (url != NULL) {
+ if ((GetKeyState(VK_SHIFT) & 0x8000) && !(GetKeyState(VK_CONTROL) & 0x8000)
+ && !(GetKeyState(VK_MENU) & 0x8000)) {
+ SendMessage(GetParent(hwnd), WM_COMMAND, IDCANCEL, 0);
+ }
+ int i = (int)wcslen(url);
+ char *tTemp = new char[i+1];
+ WideCharToMultiByte(CP_ACP, 0, url, -1, tTemp, i+1, NULL, NULL);
+ CallService(MS_UTILS_OPENURL, (WPARAM) 1, (LPARAM) tTemp);
+ delete tTemp;
+ delete url;
+ result = true;
+ }
+ element->Release();
+ }
+ document->Release();
+ }
+ return result;
+}
+
+bool IEView::setFocus(HWND prevFocus) {
+ if (GetFocus() != hwnd && !getFocus) { // && IsChild(prevFocus, hwnd
+ SetFocus(GetParent(getHWND()));
+// SetFocus(prevFocus);
+ return true;
+ }
+ getFocus = false;
+ return false;
+}
+
+void IEView::saveDocument() {
+ IHTMLDocument2 *document = getDocument();
+ if (document != NULL) {
+ BSTR bCmd = SysAllocString(L"SaveAs");
+ VARIANT_BOOL vb;
+ VARIANT vValue;
+ vValue.vt = VT_BOOL;
+ vValue.boolVal = TRUE;
+ document->execCommand(bCmd, VARIANT_FALSE, vValue, &vb);
+ SysFreeString(bCmd);
+ document->Release();
+ }
+}
+
+void IEView::navigate(IEVIEWNAVIGATE * nav) {
+ if (nav->dwFlags & IENF_UNICODE) {
+ navigate(nav->urlW);
+ } else {
+ navigate(nav->url);
+ }
+}
diff --git a/plugins/IEView/IEView.h b/plugins/IEView/IEView.h
new file mode 100644
index 0000000000..156affb2c4
--- /dev/null
+++ b/plugins/IEView/IEView.h
@@ -0,0 +1,562 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+class IEView;
+
+#ifndef IEVIEW_INCLUDED
+#define IEVIEW_INCLUDED
+
+#include "ieview_common.h"
+#include "HTMLBuilder.h"
+//#include "SmileyWindow.h"
+
+static const CLSID CLSID_MozillaBrowser=
+{ 0x1339B54C, 0x3453, 0x11D2,
+ { 0x93, 0xB9, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00 } };
+
+#ifndef DISPID_AMBIENT_DLCONTROL
+#define DISPID_AMBIENT_DLCONTROL (-5512)
+#endif
+
+#ifndef __IDocHostUIHandler_INTERFACE_DEFINED__
+#define __IDocHostUIHandler_INTERFACE_DEFINED__
+
+typedef struct _DOCHOSTUIINFO
+ {
+ ULONG cbSize;
+ DWORD dwFlags;
+ DWORD dwDoubleClick;
+ OLECHAR *pchHostCss;
+ OLECHAR *pchHostNS;
+ } DOCHOSTUIINFO;
+
+const IID IID_IDocHostUIHandler ={0xbd3f23c0,0xd43e,0x11CF,{0x89, 0x3b, 0x00, 0xaa, 0x00, 0xbd, 0xce, 0x1a}};
+
+ MIDL_INTERFACE("bd3f23c0-d43e-11cf-893b-00aa00bdce1a")
+ IDocHostUIHandler : public IUnknown
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE ShowContextMenu(
+ /* [in] */ DWORD dwID,
+ /* [in] */ POINT *ppt,
+ /* [in] */ IUnknown *pcmdtReserved,
+ /* [in] */ IDispatch *pdispReserved) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetHostInfo(
+ /* [out][in] */ DOCHOSTUIINFO *pInfo) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE ShowUI(
+ /* [in] */ DWORD dwID,
+ /* [in] */ IOleInPlaceActiveObject *pActiveObject,
+ /* [in] */ IOleCommandTarget *pCommandTarget,
+ /* [in] */ IOleInPlaceFrame *pFrame,
+ /* [in] */ IOleInPlaceUIWindow *pDoc) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE HideUI( void) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE UpdateUI( void) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE EnableModeless(
+ /* [in] */ BOOL fEnable) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE OnDocWindowActivate(
+ /* [in] */ BOOL fActivate) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE OnFrameWindowActivate(
+ /* [in] */ BOOL fActivate) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE ResizeBorder(
+ /* [in] */ LPCRECT prcBorder,
+ /* [in] */ IOleInPlaceUIWindow *pUIWindow,
+ /* [in] */ BOOL fRameWindow) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator(
+ /* [in] */ LPMSG lpMsg,
+ /* [in] */ const GUID *pguidCmdGroup,
+ /* [in] */ DWORD nCmdID) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetOptionKeyPath(
+ /* [annotation][out] */
+ LPOLESTR *pchKey,
+ /* [in] */ DWORD dw) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetDropTarget(
+ /* [in] */ IDropTarget *pDropTarget,
+ /* [out] */ IDropTarget **ppDropTarget) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetExternal(
+ /* [out] */ IDispatch **ppDispatch) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE TranslateUrl(
+ /* [in] */ DWORD dwTranslate,
+ /* [annotation][in] */
+ OLECHAR *pchURLIn,
+ /* [annotation][out] */
+ OLECHAR **ppchURLOut) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE FilterDataObject(
+ /* [in] */ IDataObject *pDO,
+ /* [out] */ IDataObject **ppDORet) = 0;
+
+ };
+
+typedef enum tagDOCHOSTUIFLAG
+ { DOCHOSTUIFLAG_DIALOG = 0x1,
+ DOCHOSTUIFLAG_DISABLE_HELP_MENU = 0x2,
+ DOCHOSTUIFLAG_NO3DBORDER = 0x4,
+ DOCHOSTUIFLAG_SCROLL_NO = 0x8,
+ DOCHOSTUIFLAG_DISABLE_SCRIPT_INACTIVE = 0x10,
+ DOCHOSTUIFLAG_OPENNEWWIN = 0x20,
+ DOCHOSTUIFLAG_DISABLE_OFFSCREEN = 0x40,
+ DOCHOSTUIFLAG_FLAT_SCROLLBAR = 0x80,
+ DOCHOSTUIFLAG_DIV_BLOCKDEFAULT = 0x100,
+ DOCHOSTUIFLAG_ACTIVATE_CLIENTHIT_ONLY = 0x200,
+ DOCHOSTUIFLAG_OVERRIDEBEHAVIORFACTORY = 0x400,
+ DOCHOSTUIFLAG_CODEPAGELINKEDFONTS = 0x800,
+ DOCHOSTUIFLAG_URL_ENCODING_DISABLE_UTF8 = 0x1000,
+ DOCHOSTUIFLAG_URL_ENCODING_ENABLE_UTF8 = 0x2000,
+ DOCHOSTUIFLAG_ENABLE_FORMS_AUTOCOMPLETE = 0x4000,
+ DOCHOSTUIFLAG_ENABLE_INPLACE_NAVIGATION = 0x10000,
+ DOCHOSTUIFLAG_IME_ENABLE_RECONVERSION = 0x20000,
+ DOCHOSTUIFLAG_THEME = 0x40000,
+ DOCHOSTUIFLAG_NOTHEME = 0x80000,
+ DOCHOSTUIFLAG_NOPICS = 0x100000,
+ DOCHOSTUIFLAG_NO3DOUTERBORDER = 0x200000,
+ DOCHOSTUIFLAG_DISABLE_EDIT_NS_FIXUP = 0x400000,
+ DOCHOSTUIFLAG_LOCAL_MACHINE_ACCESS_CHECK = 0x800000,
+ DOCHOSTUIFLAG_DISABLE_UNTRUSTEDPROTOCOL = 0x1000000,
+ DOCHOSTUIFLAG_HOST_NAVIGATES = 0x2000000,
+ DOCHOSTUIFLAG_ENABLE_REDIRECT_NOTIFICATION = 0x4000000,
+ DOCHOSTUIFLAG_USE_WINDOWLESS_SELECTCONTROL = 0x8000000,
+ DOCHOSTUIFLAG_USE_WINDOWED_SELECTCONTROL = 0x10000000,
+ DOCHOSTUIFLAG_ENABLE_ACTIVEX_INACTIVATE_MODE = 0x20000000,
+ DOCHOSTUIFLAG_DPI_AWARE = 0x40000000
+ } DOCHOSTUIFLAG;
+
+#endif /* __IDocHostUIHandler_INTERFACE_DEFINED__ */
+
+#ifndef __IHTMLAnchorElement_INTERFACE_DEFINED__
+#define __IHTMLAnchorElement_INTERFACE_DEFINED__
+
+/* interface IHTMLAnchorElement */
+/* [object][uuid][dual][oleautomation] */
+
+
+EXTERN_C const IID IID_IHTMLAnchorElement;
+
+ MIDL_INTERFACE("3050f1da-98b5-11cf-bb82-00aa00bdce0b")
+ IHTMLAnchorElement : public IDispatch
+ {
+ public:
+ virtual /* [bindable][displaybind][id][propput] */ HRESULT STDMETHODCALLTYPE put_href(
+ /* [in] */ BSTR v) = 0;
+
+ virtual /* [bindable][displaybind][id][propget] */ HRESULT STDMETHODCALLTYPE get_href(
+ /* [out][retval] */ BSTR *p) = 0;
+
+ virtual /* [bindable][displaybind][id][propput] */ HRESULT STDMETHODCALLTYPE put_target(
+ /* [in] */ BSTR v) = 0;
+
+ virtual /* [bindable][displaybind][id][propget] */ HRESULT STDMETHODCALLTYPE get_target(
+ /* [out][retval] */ BSTR *p) = 0;
+
+ virtual /* [bindable][displaybind][id][propput] */ HRESULT STDMETHODCALLTYPE put_rel(
+ /* [in] */ BSTR v) = 0;
+
+ virtual /* [bindable][displaybind][id][propget] */ HRESULT STDMETHODCALLTYPE get_rel(
+ /* [out][retval] */ BSTR *p) = 0;
+
+ virtual /* [bindable][displaybind][id][propput] */ HRESULT STDMETHODCALLTYPE put_rev(
+ /* [in] */ BSTR v) = 0;
+
+ virtual /* [bindable][displaybind][id][propget] */ HRESULT STDMETHODCALLTYPE get_rev(
+ /* [out][retval] */ BSTR *p) = 0;
+
+ virtual /* [bindable][displaybind][id][propput] */ HRESULT STDMETHODCALLTYPE put_urn(
+ /* [in] */ BSTR v) = 0;
+
+ virtual /* [bindable][displaybind][id][propget] */ HRESULT STDMETHODCALLTYPE get_urn(
+ /* [out][retval] */ BSTR *p) = 0;
+
+ virtual /* [bindable][displaybind][id][propput] */ HRESULT STDMETHODCALLTYPE put_Methods(
+ /* [in] */ BSTR v) = 0;
+
+ virtual /* [bindable][displaybind][id][propget] */ HRESULT STDMETHODCALLTYPE get_Methods(
+ /* [out][retval] */ BSTR *p) = 0;
+
+ virtual /* [bindable][displaybind][id][propput] */ HRESULT STDMETHODCALLTYPE put_name(
+ /* [in] */ BSTR v) = 0;
+
+ virtual /* [bindable][displaybind][id][propget] */ HRESULT STDMETHODCALLTYPE get_name(
+ /* [out][retval] */ BSTR *p) = 0;
+
+ virtual /* [id][propput] */ HRESULT STDMETHODCALLTYPE put_host(
+ /* [in] */ BSTR v) = 0;
+
+ virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_host(
+ /* [out][retval] */ BSTR *p) = 0;
+
+ virtual /* [id][propput] */ HRESULT STDMETHODCALLTYPE put_hostname(
+ /* [in] */ BSTR v) = 0;
+
+ virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_hostname(
+ /* [out][retval] */ BSTR *p) = 0;
+
+ virtual /* [id][propput] */ HRESULT STDMETHODCALLTYPE put_pathname(
+ /* [in] */ BSTR v) = 0;
+
+ virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_pathname(
+ /* [out][retval] */ BSTR *p) = 0;
+
+ virtual /* [id][propput] */ HRESULT STDMETHODCALLTYPE put_port(
+ /* [in] */ BSTR v) = 0;
+
+ virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_port(
+ /* [out][retval] */ BSTR *p) = 0;
+
+ virtual /* [id][propput] */ HRESULT STDMETHODCALLTYPE put_protocol(
+ /* [in] */ BSTR v) = 0;
+
+ virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_protocol(
+ /* [out][retval] */ BSTR *p) = 0;
+
+ virtual /* [id][propput] */ HRESULT STDMETHODCALLTYPE put_search(
+ /* [in] */ BSTR v) = 0;
+
+ virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_search(
+ /* [out][retval] */ BSTR *p) = 0;
+
+ virtual /* [id][propput] */ HRESULT STDMETHODCALLTYPE put_hash(
+ /* [in] */ BSTR v) = 0;
+
+ virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_hash(
+ /* [out][retval] */ BSTR *p) = 0;
+
+ virtual /* [bindable][displaybind][id][propput] */ HRESULT STDMETHODCALLTYPE put_onblur(
+ /* [in] */ VARIANT v) = 0;
+
+ virtual /* [bindable][displaybind][id][propget] */ HRESULT STDMETHODCALLTYPE get_onblur(
+ /* [out][retval] */ VARIANT *p) = 0;
+
+ virtual /* [bindable][displaybind][id][propput] */ HRESULT STDMETHODCALLTYPE put_onfocus(
+ /* [in] */ VARIANT v) = 0;
+
+ virtual /* [bindable][displaybind][id][propget] */ HRESULT STDMETHODCALLTYPE get_onfocus(
+ /* [out][retval] */ VARIANT *p) = 0;
+
+ virtual /* [bindable][displaybind][id][propput] */ HRESULT STDMETHODCALLTYPE put_accessKey(
+ /* [in] */ BSTR v) = 0;
+
+ virtual /* [bindable][displaybind][id][propget] */ HRESULT STDMETHODCALLTYPE get_accessKey(
+ /* [out][retval] */ BSTR *p) = 0;
+
+ virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_protocolLong(
+ /* [out][retval] */ BSTR *p) = 0;
+
+ virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_mimeType(
+ /* [out][retval] */ BSTR *p) = 0;
+
+ virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_nameProp(
+ /* [out][retval] */ BSTR *p) = 0;
+
+ virtual /* [bindable][displaybind][id][propput] */ HRESULT STDMETHODCALLTYPE put_tabIndex(
+ /* [in] */ short v) = 0;
+
+ virtual /* [bindable][displaybind][id][propget] */ HRESULT STDMETHODCALLTYPE get_tabIndex(
+ /* [out][retval] */ short *p) = 0;
+
+ virtual /* [id] */ HRESULT STDMETHODCALLTYPE focus( void) = 0;
+
+ virtual /* [id] */ HRESULT STDMETHODCALLTYPE blur( void) = 0;
+
+ };
+
+#endif /* __IHTMLAnchorElement_INTERFACE_DEFINED__ */
+
+#ifndef __IInternetSecurityManager_INTERFACE_DEFINED__
+#define __IInternetSecurityManager_INTERFACE_DEFINED__
+
+ typedef enum tagURLZONE {
+ URLZONE_INVALID = -1,
+ URLZONE_PREDEFINED_MIN = 0,
+ URLZONE_LOCAL_MACHINE = 0,
+ URLZONE_INTRANET,
+ URLZONE_TRUSTED,
+ URLZONE_INTERNET,
+ URLZONE_UNTRUSTED,
+ URLZONE_PREDEFINED_MAX = 999,
+ URLZONE_USER_MIN = 1000,
+ URLZONE_USER_MAX = 10000
+ } URLZONE;
+
+ #define URLACTION_ACTIVEX_MIN 0x00001200
+ #define URLACTION_ACTIVEX_MAX 0x000013ff
+ #define URLACTION_SCRIPT_MIN 0x00001400
+ #define URLACTION_SCRIPT_MAX 0x000015ff
+ #define URLACTION_HTML_MIN 0x00001600
+ #define URLACTION_HTML_JAVA_RUN 0x00001605 // derive from Java custom policy
+ #define URLACTION_HTML_MAX 0x000017ff
+ #define URLACTION_JAVA_MIN 0x00001C00
+ #define URLACTION_JAVA_MAX 0x00001Cff
+
+ #define INET_E_USE_DEFAULT_PROTOCOLHANDLER 0x800C0011L
+ #define INET_E_USE_DEFAULT_SETTING 0x800C0012L
+ #define INET_E_DEFAULT_ACTION INET_E_USE_DEFAULT_PROTOCOLHANDLER
+ #define INET_E_QUERYOPTION_UNKNOWN 0x800C0013L
+ #define INET_E_REDIRECTING 0x800C0014L
+
+ // Permissions
+ #define URLPOLICY_ALLOW 0x00
+ #define URLPOLICY_QUERY 0x01
+ #define URLPOLICY_DISALLOW 0x03
+
+ static const CLSID IID_IInternetSecurityManager=
+ { 0x79eac9ee, 0xbaf9, 0x11ce,
+ { 0x8c, 0x82, 0x00, 0xaa, 0x00, 0x4b, 0xa9, 0x0b } };
+
+ #define SID_SInternetSecurityManager IID_IInternetSecurityManager
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define INTERFACE IInternetSecurityMgrSite
+DECLARE_INTERFACE_(IInternetSecurityMgrSite,IUnknown)
+{
+ STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ STDMETHOD(GetWindow)(THIS_ HWND*) PURE;
+ STDMETHOD(EnableModeless)(THIS_ BOOL) PURE;
+};
+#undef INTERFACE
+
+#define INTERFACE IInternetSecurityManager
+DECLARE_INTERFACE_(IInternetSecurityManager,IUnknown)
+{
+ STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+
+ STDMETHOD(SetSecuritySite)(THIS_ IInternetSecurityMgrSite*) PURE;
+ STDMETHOD(GetSecuritySite)(THIS_ IInternetSecurityMgrSite**) PURE;
+ STDMETHOD(MapUrlToZone)(THIS_ LPCWSTR,DWORD*,DWORD) PURE;
+ STDMETHOD(GetSecurityId)(THIS_ LPCWSTR,BYTE*,DWORD*,DWORD_PTR) PURE;
+ STDMETHOD(ProcessUrlAction)(THIS_ LPCWSTR,DWORD,BYTE*,DWORD,BYTE*,DWORD,DWORD,DWORD) PURE;
+ STDMETHOD(QueryCustomPolicy)(THIS_ LPCWSTR,REFGUID,BYTE**,DWORD*,BYTE*,DWORD,DWORD) PURE;
+ STDMETHOD(SetZoneMapping)(THIS_ DWORD,LPCWSTR,DWORD) PURE;
+ STDMETHOD(GetZoneMappings)(THIS_ DWORD,IEnumString**,DWORD) PURE;
+};
+#undef INTERFACE
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+class IEViewSink:public DWebBrowserEvents2 {
+private:
+ int m_cRef;
+ IEView *ieWindow;
+public:
+ IEViewSink(IEView *);
+ virtual ~IEViewSink();
+ // IDispatch
+ STDMETHODIMP QueryInterface(REFIID riid, PVOID *ppv);
+ STDMETHODIMP_(ULONG) AddRef(void);
+ STDMETHODIMP_(ULONG) Release(void);
+
+ STDMETHOD(GetTypeInfoCount)(UINT*);
+ STDMETHOD(GetTypeInfo)(UINT, LCID, LPTYPEINFO*);
+ STDMETHOD(GetIDsOfNames)(REFIID,LPOLESTR*,UINT,LCID,DISPID*);
+ STDMETHOD(Invoke)(DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*);
+ // DWebBrowserEvents2
+ STDMETHODIMP_(void)StatusTextChange(BSTR);
+ STDMETHODIMP_(void)ProgressChange(long, long);
+ STDMETHODIMP_(void)CommandStateChange(long, VARIANT_BOOL);
+ STDMETHODIMP_(void)DownloadBegin();
+ STDMETHODIMP_(void)DownloadComplete();
+ STDMETHODIMP_(void)TitleChange(BSTR Text);
+ STDMETHODIMP_(void)PropertyChange(BSTR Text);
+ STDMETHODIMP_(void)BeforeNavigate2(IDispatch*,VARIANT*,VARIANT*,VARIANT*,VARIANT*,VARIANT*,VARIANT_BOOL*);
+ STDMETHODIMP_(void)NewWindow2(IDispatch**, VARIANT_BOOL*);
+ STDMETHODIMP_(void)NavigateComplete(IDispatch*, VARIANT*);
+ STDMETHODIMP_(void)DocumentComplete(IDispatch*, VARIANT*);
+ STDMETHODIMP_(void)OnQuit();
+ STDMETHODIMP_(void)OnVisible(VARIANT_BOOL);
+ STDMETHODIMP_(void)OnToolBar(VARIANT_BOOL);
+ STDMETHODIMP_(void)OnMenuBar(VARIANT_BOOL);
+ STDMETHODIMP_(void)OnStatusBar(VARIANT_BOOL);
+ STDMETHODIMP_(void)OnFullScreen(VARIANT_BOOL);
+ STDMETHODIMP_(void)OnTheaterMode(VARIANT_BOOL);
+ STDMETHODIMP_(void)WindowSetResizable(VARIANT_BOOL);
+ STDMETHODIMP_(void)WindowSetLeft(long);
+ STDMETHODIMP_(void)WindowSetTop(long);
+ STDMETHODIMP_(void)WindowSetWidth(long);
+ STDMETHODIMP_(void)WindowSetHeight(long);
+ STDMETHODIMP_(void)WindowClosing(VARIANT_BOOL, VARIANT_BOOL*);
+ STDMETHODIMP_(void)ClientToHostWindow(long*,long*);
+ STDMETHODIMP_(void)SetSecureLockIcon(long);
+ STDMETHODIMP_(void)FileDownload(VARIANT_BOOL*);
+};
+
+class IEView:public IDispatch, public IOleClientSite, public IOleInPlaceSite, public IDocHostUIHandler, public IInternetSecurityManager, public IServiceProvider {
+private:
+ static IEView *list;
+ static CRITICAL_SECTION mutex;
+ static bool isInited;
+ HWND parent;
+ HWND hwnd;
+ IEView *prev, *next;
+ int m_cRef;
+ RECT rcClient;
+ BOOL m_bInPlaceActive;
+ DWORD m_dwCookie;
+ IConnectionPoint* m_pConnectionPoint;
+ IEViewSink *sink;
+ IWebBrowser2* pWebBrowser;
+ HTMLBuilder *builder;
+
+ WNDPROC mainWndProc, docWndProc, serverWndProc;
+ bool getFocus;
+ bool clearRequired;
+ BSTR selectedText;
+ bool isContactSet;
+ HANDLE hContact;
+
+ // IUnknown
+ STDMETHODIMP QueryInterface(REFIID riid, PVOID *ppv);
+ STDMETHODIMP_(ULONG) AddRef(void);
+ STDMETHODIMP_(ULONG) Release(void);
+
+ // IDispatch
+ STDMETHOD(GetTypeInfoCount)(UINT*);
+ STDMETHOD(GetTypeInfo)(UINT, LCID, LPTYPEINFO*);
+ STDMETHOD(GetIDsOfNames)(REFIID,LPOLESTR*,UINT,LCID,DISPID*);
+ STDMETHOD(Invoke)(DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*);
+ // IOleWindow
+ STDMETHOD(GetWindow)(HWND *phwnd);
+ STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode);
+ // IOleInPlace
+ STDMETHOD(CanInPlaceActivate)(void);
+ STDMETHOD(OnInPlaceActivate)(void);
+ STDMETHOD(OnUIActivate)(void);
+ STDMETHOD(GetWindowContext)(IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc,
+ LPRECT lprcPosRect, LPRECT lprcClipRect,
+ LPOLEINPLACEFRAMEINFO lpFrameInfo);
+ STDMETHOD(Scroll)(SIZE scrollExtant);
+
+ STDMETHOD(OnUIDeactivate)(BOOL fUndoable);
+ STDMETHOD(OnInPlaceDeactivate)( void);
+ STDMETHOD(DiscardUndoState)( void);
+ STDMETHOD(DeactivateAndUndo)( void);
+ STDMETHOD(OnPosRectChange)(LPCRECT lprcPosRect);
+ // IOleClientSite
+ STDMETHOD(SaveObject)(void);
+ STDMETHOD(GetMoniker)(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk);
+ STDMETHOD(GetContainer)(IOleContainer **ppContainer);
+ STDMETHOD(ShowObject)(void);
+ STDMETHOD(OnShowWindow)(BOOL fShow);
+ STDMETHOD(RequestNewObjectLayout)(void);
+
+ // IDocHostUIHandler
+ STDMETHOD(ShowContextMenu)(DWORD dwID, POINT *ppt, IUnknown *pcmdtReserved, IDispatch *pdispReserved);
+ STDMETHOD(GetHostInfo)(DOCHOSTUIINFO *pInfo);
+ STDMETHOD(ShowUI)(DWORD dwID, IOleInPlaceActiveObject *pActiveObject, IOleCommandTarget *pCommandTarget,
+ IOleInPlaceFrame *pFrame, IOleInPlaceUIWindow *pDoc);
+ STDMETHOD(HideUI)(void);
+ STDMETHOD(UpdateUI)(void);
+ STDMETHOD(EnableModeless)(BOOL fEnable);
+ STDMETHOD(OnDocWindowActivate)(BOOL fEnable);
+ STDMETHOD(OnFrameWindowActivate)(BOOL fEnable);
+ STDMETHOD(ResizeBorder)(LPCRECT prcBorder, IOleInPlaceUIWindow *pUIWindow, BOOL fRameWindow);
+ STDMETHOD(TranslateAccelerator)(LPMSG lpMsg, const GUID *pguidCmdGroup, DWORD nCmdID);
+ STDMETHOD(GetOptionKeyPath)(LPOLESTR *pchKey, DWORD dw);
+ STDMETHOD(GetDropTarget)(IDropTarget *pDropTarget, IDropTarget **ppDropTarget);
+ STDMETHOD(GetExternal)(IDispatch **ppDispatch);
+ STDMETHOD(TranslateUrl)(DWORD dwTranslate, OLECHAR *pchURLIn, OLECHAR **ppchURLOut);
+ STDMETHOD(FilterDataObject)(IDataObject *pDO, IDataObject **ppDORet);
+ // IServiceProvider
+ STDMETHOD(QueryService)(REFGUID guidService, REFIID riid, void** ppvObject);
+ // IInternetSecurityManager
+ STDMETHOD(SetSecuritySite)(IInternetSecurityMgrSite *pSite);
+ STDMETHOD(GetSecuritySite)(IInternetSecurityMgrSite **ppSite);
+ STDMETHOD(MapUrlToZone)(LPCWSTR pwszUrl, DWORD *pdwZone, DWORD dwFlags);
+ STDMETHOD(GetSecurityId)(LPCWSTR pwszUrl, BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved);
+ STDMETHOD(ProcessUrlAction)(LPCWSTR pwszUrl, DWORD dwAction, BYTE *pPolicy, DWORD cbPolicy, BYTE *pContext, DWORD cbContext, DWORD dwFlags, DWORD dwReserved);
+ STDMETHOD(QueryCustomPolicy)(LPCWSTR pwszUrl, REFGUID guidKey, BYTE **ppPolicy, DWORD *pcbPolicy, BYTE *pContext, DWORD cbContext, DWORD dwReserved);
+ STDMETHOD(SetZoneMapping)(DWORD dwZone, LPCWSTR lpszPattern, DWORD dwFlags);
+ STDMETHOD(GetZoneMappings)(DWORD dwZone, IEnumString **ppenumString, DWORD dwFlags);
+
+ IHTMLDocument2 *getDocument();
+ BSTR getHrefFromAnchor(IHTMLElement *element);
+ BSTR getSelection();
+ void setBorder();
+protected:
+ void navigate(const char *);
+ void navigate(const wchar_t *);
+public:
+ IEView(HWND parent, HTMLBuilder* builder, int x, int y, int cx, int cy);
+// IEView::IEView(HWND parent, SmileyWindow* smileyWindow, int x, int y, int cx, int cy);
+ virtual ~IEView();
+
+ void waitWhileBusy();
+ HWND getHWND();
+ void translateAccelerator(UINT uMsg, WPARAM wParam, LPARAM lParam);
+ bool mouseClick(POINT pt);
+ bool mouseActivate();
+ bool setFocus(HWND prevFocus);
+ void setWindowPos(int x, int y, int cx, int cy);
+ HTMLBuilder* getBuilder();
+
+ void write(const wchar_t *text);
+ void write(const char *text);
+ void writef(const char *fmt, ...);
+ void documentClose();
+ void rebuildLog();
+ void scrollToBottom();
+ void scrollToBottomSoft();
+ void scrollToTop();
+
+ void setMainWndProc(WNDPROC);
+ WNDPROC getMainWndProc();
+ void setDocWndProc(WNDPROC);
+ WNDPROC getDocWndProc();
+ void setServerWndProc(WNDPROC);
+ WNDPROC getServerWndProc();
+
+ void appendEventOld(IEVIEWEVENT * event);
+ void appendEvent(IEVIEWEVENT * event);
+ void clear(IEVIEWEVENT * event);
+ void* getSelection(IEVIEWEVENT * event);
+ void navigate(IEVIEWNAVIGATE * nav);
+ void saveDocument();
+
+ void setContact(HANDLE hContact);
+
+ static IEView* get(HWND);
+ static void init();
+ static void release();
+ static void setOptions();
+
+};
+#endif
diff --git a/plugins/IEView/MUCCHTMLBuilder.cpp b/plugins/IEView/MUCCHTMLBuilder.cpp
new file mode 100644
index 0000000000..45e7f2113f
--- /dev/null
+++ b/plugins/IEView/MUCCHTMLBuilder.cpp
@@ -0,0 +1,296 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+#include "MUCCHTMLBuilder.h"
+
+#include "Options.h"
+#include "Utils.h"
+
+#define MUCCMOD "MUCC"
+
+#define FONTF_BOLD 1
+#define FONTF_ITALIC 2
+#define FONTF_UNDERLINE 4
+
+#define FONT_NUM 9
+
+static const char *classNames[] = {
+ ".timestamp", ".nameIn", ".nameOut", ".messageIn", ".messageOut", ".userJoined", ".userLeft", ".topicChange",
+ ".error"
+};
+
+MUCCHTMLBuilder::MUCCHTMLBuilder() {
+ setLastEventType(-1);
+ setLastEventTime(time(NULL));
+}
+
+void MUCCHTMLBuilder::loadMsgDlgFont(int i, LOGFONTA * lf, COLORREF * colour) {
+ char str[32];
+ int style;
+ DBVARIANT dbv;
+ if (colour) {
+ wsprintfA(str, "Font%dCol", i);
+ *colour = DBGetContactSettingDword(NULL, MUCCMOD, str, 0x000000);
+ }
+ if (lf) {
+ wsprintfA(str, "Font%dSize", i);
+ lf->lfHeight = (char) DBGetContactSettingByte(NULL, MUCCMOD, str, 10);
+ lf->lfHeight = abs(lf->lfHeight);
+ lf->lfWidth = 0;
+ lf->lfEscapement = 0;
+ lf->lfOrientation = 0;
+ wsprintfA(str, "Font%dStyle", i);
+ style = DBGetContactSettingByte(NULL, MUCCMOD, str, 0);
+ lf->lfWeight = style & FONTF_BOLD ? FW_BOLD : FW_NORMAL;
+ lf->lfItalic = style & FONTF_ITALIC ? 1 : 0;
+ lf->lfUnderline = style & FONTF_UNDERLINE ? 1 : 0;
+ lf->lfStrikeOut = 0;
+ wsprintfA(str, "Font%dSet", i);
+ lf->lfCharSet = DBGetContactSettingByte(NULL, MUCCMOD, str, DEFAULT_CHARSET);
+ lf->lfOutPrecision = OUT_DEFAULT_PRECIS;
+ lf->lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ lf->lfQuality = DEFAULT_QUALITY;
+ lf->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
+ wsprintfA(str, "Font%dFace", i);
+ if (DBGetContactSetting(NULL, MUCCMOD, str, &dbv))
+ lstrcpyA(lf->lfFaceName, "Verdana");
+ else {
+ lstrcpynA(lf->lfFaceName, dbv.pszVal, sizeof(lf->lfFaceName));
+ DBFreeVariant(&dbv);
+ }
+ }
+}
+
+char *MUCCHTMLBuilder::timestampToString(DWORD dwData, time_t check)
+{
+ static char szResult[512];
+ char str[80];
+
+ DBTIMETOSTRING dbtts;
+
+ dbtts.cbDest = 70;;
+ dbtts.szDest = str;
+
+ szResult[0] = '\0';
+ struct tm tm_now, tm_today;
+ time_t now = time(NULL);
+ time_t today;
+ tm_now = *localtime(&now);
+ tm_today = tm_now;
+ tm_today.tm_hour = tm_today.tm_min = tm_today.tm_sec = 0;
+ today = mktime(&tm_today);
+ if (dwData&IEEDD_MUCC_SHOW_DATE && dwData&IEEDD_MUCC_SHOW_TIME) {
+ if (dwData&IEEDD_MUCC_LONG_DATE) {
+ dbtts.szFormat = dwData&IEEDD_MUCC_SECONDS ? (char *)"D s" : (char *)"D t";
+ } else {
+ dbtts.szFormat = dwData&IEEDD_MUCC_SECONDS ? (char *)"d s" : (char *)"d t";
+ }
+ } else if (dwData&IEEDD_MUCC_SHOW_DATE) {
+ dbtts.szFormat = dwData&IEEDD_MUCC_LONG_DATE ? (char *)"D" : (char *)"d";
+ } else if (dwData&IEEDD_MUCC_SHOW_TIME) {
+ dbtts.szFormat = dwData&IEEDD_MUCC_SECONDS ? (char *)"s" : (char *)"t";
+ } else {
+ dbtts.szFormat = (char *)"";
+ }
+ CallService(MS_DB_TIME_TIMESTAMPTOSTRING, check, (LPARAM) & dbtts);
+ strncat(szResult, str, 500);
+ Utils::UTF8Encode(szResult, szResult, 500);
+ return szResult;
+}
+
+void MUCCHTMLBuilder::buildHead(IEView *view, IEVIEWEVENT *event) {
+ LOGFONTA lf;
+ COLORREF color;
+ char *output = NULL;
+ int outputSize;
+ ProtocolSettings *protoSettings = getChatProtocolSettings(event->pszProto);
+ if (protoSettings == NULL) {
+ return;
+ }
+ if (protoSettings->getChatMode() == Options::MODE_TEMPLATE) {
+// buildHeadTemplate(view, event);
+ return;
+ }
+ if (protoSettings->getChatMode() == Options::MODE_CSS) {
+ const char *externalCSS = protoSettings->getChatCssFilename();
+ Utils::appendText(&output, &outputSize, "<html><head><link rel=\"stylesheet\" href=\"%s\"/></head><body class=\"body\">\n", externalCSS);
+ } else {
+ HDC hdc = GetDC(NULL);
+ int logPixelSY = GetDeviceCaps(hdc, LOGPIXELSY);
+ ReleaseDC(NULL, hdc);
+ Utils::appendText(&output, &outputSize, "<html><head>");
+ Utils::appendText(&output, &outputSize, "<style type=\"text/css\">\n");
+ COLORREF bkgColor = DBGetContactSettingDword(NULL, MUCCMOD, "BackgroundLog", 0xFFFFFF);
+ COLORREF inColor, outColor;
+ bkgColor= (((bkgColor & 0xFF) << 16) | (bkgColor & 0xFF00) | ((bkgColor & 0xFF0000) >> 16));
+ inColor = outColor = bkgColor;
+ if (protoSettings->getChatFlags() & Options::LOG_IMAGE_ENABLED) {
+ Utils::appendText(&output, &outputSize, ".body {padding: 2px; text-align: left; background-attachment: %s; background-color: #%06X; background-image: url('%s'); overflow: auto;}\n",
+ protoSettings->getChatFlags() & Options::LOG_IMAGE_SCROLL ? "scroll" : "fixed", (int) bkgColor, protoSettings->getChatBackgroundFilename());
+ } else {
+ Utils::appendText(&output, &outputSize, ".body {margin: 0px; text-align: left; background-color: #%06X; overflow: auto;}\n",
+ (int) bkgColor);
+ }
+ Utils::appendText(&output, &outputSize, ".link {color: #0000FF; text-decoration: underline;}\n");
+ Utils::appendText(&output, &outputSize, ".img {vertical-align: middle;}\n");
+ if (protoSettings->getChatFlags() & Options::LOG_IMAGE_ENABLED) {
+ Utils::appendText(&output, &outputSize, ".divIn {padding-left: 2px; padding-right: 2px; word-wrap: break-word;}\n");
+ Utils::appendText(&output, &outputSize, ".divOut {padding-left: 2px; padding-right: 2px; word-wrap: break-word;}\n");
+ Utils::appendText(&output, &outputSize, ".divUserJoined {padding-left: 2px; padding-right: 2px; word-wrap: break-word;}\n");
+ Utils::appendText(&output, &outputSize, ".divUserLeft {padding-left: 2px; padding-right: 2px; word-wrap: break-word;}\n");
+ Utils::appendText(&output, &outputSize, ".divTopicChange {padding-left: 2px; padding-right: 2px; word-wrap: break-word;}\n");
+ } else {
+ Utils::appendText(&output, &outputSize, ".divIn {padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #%06X;}\n", (int) inColor);
+ Utils::appendText(&output, &outputSize, ".divOut {padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #%06X;}\n", (int) outColor);
+ Utils::appendText(&output, &outputSize, ".divUserJoined {padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #%06X;}\n", (int) inColor);
+ Utils::appendText(&output, &outputSize, ".divUserLeft {padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #%06X;}\n", (int) inColor);
+ Utils::appendText(&output, &outputSize, ".divTopicChange {padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #%06X;}\n", (int) inColor);
+ }
+ for (int i = 0; i < FONT_NUM; i++) {
+ loadMsgDlgFont(i, &lf, &color);
+ Utils::appendText(&output, &outputSize, "%s {font-family: %s; font-size: %dpt; font-weight: %s; color: #%06X; %s }\n",
+ classNames[i],
+ lf.lfFaceName,
+ abs((signed char)lf.lfHeight) * 74 /logPixelSY ,
+ lf.lfWeight >= FW_BOLD ? "bold" : "normal",
+ (int)(((color & 0xFF) << 16) | (color & 0xFF00) | ((color & 0xFF0000) >> 16)),
+ lf.lfItalic ? "font-style: italic;" : "");
+ }
+ Utils::appendText(&output, &outputSize, "</style></head><body class=\"body\">\n");
+ }
+ if (output != NULL) {
+ view->write(output);
+ free(output);
+ }
+ setLastEventType(-1);
+}
+
+void MUCCHTMLBuilder::appendEventNonTemplate(IEView *view, IEVIEWEVENT *event) {
+
+ IEVIEWEVENTDATA* eventData = event->eventData;
+ for (int eventIdx = 0; eventData!=NULL && (eventIdx < event->count || event->count==-1); eventData = eventData->next, eventIdx++) {
+ DWORD dwData = eventData->dwData;
+ char *style = NULL;
+ int styleSize;
+ int isSent = eventData->bIsMe;
+ int outputSize;
+ char *output = NULL;
+ char *szName = NULL, *szText = NULL;
+ if (eventData->iType == IEED_MUCC_EVENT_MESSAGE) {
+ if (eventData->dwFlags & IEEDF_UNICODE_TEXT) {
+ szText = encodeUTF8(NULL, event->pszProto, eventData->pszTextW, ENF_ALL, isSent);
+ } else {
+ szText = encodeUTF8(NULL, event->pszProto, eventData->pszText, ENF_ALL, isSent);
+ }
+ if (eventData->dwFlags & IEEDF_UNICODE_NICK) {
+ szName = encodeUTF8(NULL, event->pszProto, eventData->pszNickW, ENF_NAMESMILEYS, true);
+ } else {
+ szName = encodeUTF8(NULL, event->pszProto, eventData->pszNick, ENF_NAMESMILEYS, true);
+ }
+ Utils::appendText(&output, &outputSize, "<div class=\"%s\">", isSent ? "divOut" : "divIn");
+ if (dwData & IEEDD_MUCC_SHOW_TIME || dwData & IEEDD_MUCC_SHOW_DATE) {
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">%s </span>",
+ isSent ? "timestamp" : "timestamp", timestampToString(dwData, eventData->time));
+ }
+ if (dwData & IEEDD_MUCC_SHOW_NICK) {
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">%s: </span>",
+ isSent ? "nameOut" : "nameIn", szName);
+ }
+ if (dwData & IEEDD_MUCC_MSG_ON_NEW_LINE) {
+ Utils::appendText(&output, &outputSize, "<br>");
+ }
+ const char *className = isSent ? "messageOut" : "messageIn";
+ if (eventData->dwFlags & IEEDF_FORMAT_SIZE && eventData->fontSize > 0) {
+ Utils::appendText(&style, &styleSize, "font-size:%dpt;", eventData->fontSize);
+ }
+ if (eventData->dwFlags & IEEDF_FORMAT_COLOR && eventData->color!=0xFFFFFFFF) {
+ Utils::appendText(&style, &styleSize, "color:#%06X;", ((eventData->color & 0xFF) << 16) | (eventData->color & 0xFF00) | ((eventData->color & 0xFF0000) >> 16));
+ }
+ if (eventData->dwFlags & IEEDF_FORMAT_FONT) {
+ Utils::appendText(&style, &styleSize, "font-family:%s;", eventData->fontName);
+ }
+ if (eventData->dwFlags & IEEDF_FORMAT_STYLE) {
+ Utils::appendText(&style, &styleSize, "font-weight: %s;", eventData->fontStyle & IE_FONT_BOLD ? "bold" : "normal");
+ Utils::appendText(&style, &styleSize, "font-style: %s;", eventData->fontStyle & IE_FONT_ITALIC ? "italic" : "normal");
+ Utils::appendText(&style, &styleSize, "text-decoration: %s;", eventData->fontStyle & IE_FONT_UNDERLINE ? "underline" : "none");
+ }
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\"><span style=\"%s\">%s</span></span>", className, style!=NULL ? style : "", szText);
+ Utils::appendText(&output, &outputSize, "</div>\n");
+ if (style!=NULL) free(style);
+ } else if (eventData->iType == IEED_MUCC_EVENT_JOINED || eventData->iType == IEED_MUCC_EVENT_LEFT || eventData->iType == IEED_MUCC_EVENT_TOPIC) {
+ const char *className, *divName;
+ const char *eventText;
+ if (eventData->iType == IEED_MUCC_EVENT_JOINED) {
+ className = "userJoined";
+ divName = "divUserJoined";
+ eventText = "%s has joined.";
+ szText = encodeUTF8(NULL, event->pszProto, eventData->pszNick, ENF_NONE, isSent);
+ } else if (eventData->iType == IEED_MUCC_EVENT_LEFT) {
+ className = "userLeft";
+ divName = "divUserJoined";
+ eventText = "%s has left.";
+ szText = encodeUTF8(NULL, event->pszProto, eventData->pszNick, ENF_NONE, isSent);
+ } else {
+ className = "topicChange";
+ divName = "divTopicChange";
+ eventText = "The topic is %s.";
+ szText = encodeUTF8(NULL, event->pszProto, eventData->pszText, ENF_ALL, isSent);
+ }
+ Utils::appendText(&output, &outputSize, "<div class=\"%s\">", divName);
+ if (dwData & IEEDD_MUCC_SHOW_TIME || dwData & IEEDD_MUCC_SHOW_DATE) {
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">%s </span>",
+ isSent ? "timestamp" : "timestamp", timestampToString(dwData, eventData->time));
+ }
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">", className);
+ Utils::appendText(&output, &outputSize, Translate(eventText), szText);
+ Utils::appendText(&output, &outputSize, "</span>");
+ Utils::appendText(&output, &outputSize, "</div>\n");
+ } else if (eventData->iType == IEED_MUCC_EVENT_ERROR) {
+ const char *className = "error";
+ szText = encodeUTF8(NULL, event->pszProto, eventData->pszText, ENF_NONE, isSent);
+ Utils::appendText(&output, &outputSize, "<div class=\"%s\">", "divError");
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\"> %s: %s</span>", className, Translate("Error"), szText);
+ Utils::appendText(&output, &outputSize, "</div>\n");
+ }
+ if (szName!=NULL) delete szName;
+ if (szText!=NULL) delete szText;
+ if (output != NULL) {
+ view->write(output);
+ free(output);
+ }
+ }
+// view->scrollToBottom();
+}
+
+void MUCCHTMLBuilder::appendEvent(IEView *view, IEVIEWEVENT *event) {
+ ProtocolSettings *protoSettings = getChatProtocolSettings(event->pszProto);
+ if (protoSettings == NULL) {
+ return;
+ }
+// if (protoSettings->getSRMMMode() == Options::MODE_TEMPLATE) {
+ // appendEventTemplate(view, event);
+// } else {
+ appendEventNonTemplate(view, event);
+// }
+}
+
+bool MUCCHTMLBuilder::isDbEventShown(DBEVENTINFO * dbei) {
+ return true;
+}
diff --git a/plugins/IEView/MUCCHTMLBuilder.h b/plugins/IEView/MUCCHTMLBuilder.h
new file mode 100644
index 0000000000..d6c00df94b
--- /dev/null
+++ b/plugins/IEView/MUCCHTMLBuilder.h
@@ -0,0 +1,41 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+class MUCCHTMLBuilder;
+
+#ifndef MUCCHTMLBUILDER_INCLUDED
+#define MUCCHTMLBUILDER_INCLUDED
+
+#include "HTMLBuilder.h"
+
+class MUCCHTMLBuilder:public HTMLBuilder
+{
+protected:
+ void loadMsgDlgFont(int i, LOGFONTA * lf, COLORREF * colour);
+ char *timestampToString(DWORD dwFlags, time_t check);
+ void appendEventNonTemplate(IEView *, IEVIEWEVENT *event);
+ bool isDbEventShown(DBEVENTINFO * dbei);
+public:
+ MUCCHTMLBuilder();
+ void buildHead(IEView *, IEVIEWEVENT *event);
+ void appendEvent(IEView *, IEVIEWEVENT *event);
+};
+
+#endif
diff --git a/plugins/IEView/Makefile b/plugins/IEView/Makefile
new file mode 100644
index 0000000000..cef8e3a42e
--- /dev/null
+++ b/plugins/IEView/Makefile
@@ -0,0 +1,41 @@
+# Project: ieview
+
+CPP = g++.exe
+CC = gcc.exe
+WINDRES = windres.exe
+RM = rm
+UPX = upx -9 -q --compress-icons=0
+SRC = IEView.cpp ieview_services.cpp ieview_main.cpp HTMLBuilder.cpp ChatHTMLBuilder.cpp MUCCHTMLBuilder.cpp ScriverHTMLBuilder.cpp TabSRMMHTMLBuilder.cpp HistoryHTMLBuilder.cpp Options.cpp Template.cpp TemplateHTMLBuilder.cpp TextToken.cpp Utils.cpp
+RES = ieview.res
+OBJ = $(SRC:.cpp=.o) $(RES)
+BIN = ieview.dll
+INCS = -I"../../include"
+CFLAGS = $(INCS) -DBUILDING_DLL=1 -DUNICODE -fexpensive-optimizations -O3 -Os -fno-exceptions -Wno-error -Wall
+CXXFLAGS = $(INCS) -DBUILDING_DLL=1 -DUNICODE -fexpensive-optimizations -O3 -Os -fno-exceptions -Wno-error -Wall
+# -save-temps
+LIBS = -lversion -lwsock32 -lole32 -lcomctl32 -luuid -loleaut32
+LFLAGS = -s -mdll -mwindows --add-stdcall-alias
+#LFLAGS = -mdll -mwindows -Wl,-Map,ieview.map --no-export-all-symbols --add-stdcall-alias -g3
+RCFLAGS = -I rc -O coff
+# --add-stdcall-alias -s --no-export-all-symbols
+
+.PHONY: all all-before all-after clean clean-custom
+
+all: all-before $(BIN) all-after
+ifdef PACK
+ $(UPX) $(BIN)
+endif
+
+clean: clean-custom
+ $(RM) -f $(OBJ) $(BIN)
+
+depend :
+ $(CPP) -MM $(CFLAGS) $(SRC)>Makefile.dep
+
+$(RES): $(RES:.res=.rc) resource.h
+ $(WINDRES) $(RCFLAGS) -i $(RES:.res=.rc) -o $(RES)
+
+$(BIN): $(OBJ)
+ $(CPP) $(CFLAGS) $(OBJ) $(LIBS) $(LFLAGS) -o $(BIN) -Wl
+
+-include Makefile.dep
diff --git a/plugins/IEView/MakefileUbuntu b/plugins/IEView/MakefileUbuntu
new file mode 100644
index 0000000000..66b4c5be14
--- /dev/null
+++ b/plugins/IEView/MakefileUbuntu
@@ -0,0 +1,41 @@
+# Project: ieview
+
+CXX = i586-mingw32msvc-g++
+CC = i586-mingw32msvc-gcc
+WINDRES = i586-mingw32msvc-windres
+RM = rm
+UPX = upx -9 -q --compress-icons=0
+SRC = IEView.cpp ieview_services.cpp ieview_main.cpp HTMLBuilder.cpp ChatHTMLBuilder.cpp MUCCHTMLBuilder.cpp ScriverHTMLBuilder.cpp TabSRMMHTMLBuilder.cpp HistoryHTMLBuilder.cpp Options.cpp Template.cpp TemplateHTMLBuilder.cpp TextToken.cpp Utils.cpp
+RES = ieview.res
+OBJ = $(SRC:.cpp=.o) $(RES)
+BIN = ieview.dll
+INCS = -I"../../include"
+CFLAGS = $(INCS) -DBUILDING_DLL=1 -DUNICODE -fexpensive-optimizations -O3 -Os -fno-exceptions -Wno-error -Wall
+CXXFLAGS = $(INCS) -DBUILDING_DLL=1 -DUNICODE -fexpensive-optimizations -O3 -Os -fno-exceptions -Wno-error -Wall
+# -save-temps
+LIBS = -lversion -lwsock32 -lole32 -lcomctl32 -luuid -loleaut32
+LFLAGS = -O -s -mdll -mwindows --add-stdcall-alias
+#LFLAGS = -mdll -mwindows -Wl,-Map,ieview.map --no-export-all-symbols --add-stdcall-alias -g3
+RCFLAGS = -J rc -O coff -DUNICODE
+# --add-stdcall-alias -s --no-export-all-symbols
+
+.PHONY: all all-before all-after clean clean-custom
+
+all: all-before $(BIN) all-after
+ifdef PACK
+ $(UPX) $(BIN)
+endif
+
+clean: clean-custom
+ $(RM) -f $(OBJ) $(BIN)
+
+depend :
+ $(CXX) -MM $(CFLAGS) $(SRC)>Makefile.dep
+
+$(RES): $(RES:.res=.rc) resource.h
+ $(WINDRES) $(RCFLAGS) -i $(RES:.res=.rc) -o $(RES)
+
+$(BIN): $(OBJ)
+ $(CXX) $(CFLAGS) $(OBJ) $(LIBS) $(LFLAGS) -o $(BIN) -Wl
+
+-include Makefile.dep
diff --git a/plugins/IEView/Options.cpp b/plugins/IEView/Options.cpp
new file mode 100644
index 0000000000..afd577bf89
--- /dev/null
+++ b/plugins/IEView/Options.cpp
@@ -0,0 +1,1811 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+#define _WIN32_WINNT 0x0501
+#include "Options.h"
+#include "resource.h"
+#include "Template.h"
+#include "Utils.h"
+#include "m_MathModule.h"
+#include "m_avatars.h"
+#include <m_icolib.h>
+
+#define UM_CHECKSTATECHANGE (WM_USER+100)
+HANDLE hHookOptionsChanged;
+static INT_PTR CALLBACK IEViewGeneralOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+static INT_PTR CALLBACK IEViewSRMMOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+static INT_PTR CALLBACK IEViewGroupChatsOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+static INT_PTR CALLBACK IEViewHistoryOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+#define OPTIONS_PAGES 4
+static ProtocolSettings *srmmCurrentProtoItem = NULL;
+static ProtocolSettings *chatCurrentProtoItem = NULL;
+static ProtocolSettings *historyCurrentProtoItem = NULL;
+static HIMAGELIST hProtocolImageList = NULL;
+static HIMAGELIST hImageList = NULL;
+static BOOL (WINAPI *pfnEnableThemeDialogTexture)(HANDLE, DWORD) = 0;
+
+typedef struct TabDefStruct {
+ DLGPROC dlgProc;
+ DWORD dlgId;
+ TCHAR *tabName;
+} TabDef;
+
+static TabDef tabPages[] = {
+ {IEViewGeneralOptDlgProc, IDD_GENERAL_OPTIONS, _T("General")},
+ {IEViewSRMMOptDlgProc, IDD_SRMM_OPTIONS, _T("Message Log")},
+ {IEViewGroupChatsOptDlgProc, IDD_SRMM_OPTIONS, _T("Group Chats")},
+ {IEViewHistoryOptDlgProc, IDD_SRMM_OPTIONS, _T("History")}
+ };
+
+static LPARAM GetItemParam(HWND hwndTreeView, HTREEITEM hItem) {
+ TVITEM tvi = {0};
+ tvi.mask = TVIF_PARAM;
+ tvi.hItem = hItem == NULL ? TreeView_GetSelection(hwndTreeView) : hItem;
+ TreeView_GetItem(hwndTreeView, &tvi);
+ return tvi.lParam;
+}
+
+static void SaveSRMMProtoSettings(HWND hwndDlg, ProtocolSettings *proto) {
+ if (proto != NULL) {
+ char path[MAX_PATH];
+ int i;
+ i = Options::MODE_COMPATIBLE;
+ if (IsDlgButtonChecked(hwndDlg, IDC_MODE_TEMPLATE)) {
+ i = Options::MODE_TEMPLATE;
+ } else if (IsDlgButtonChecked(hwndDlg, IDC_MODE_CSS)) {
+ i = Options::MODE_CSS;
+ }
+ proto->setSRMMModeTemp(i);
+ i = IsDlgButtonChecked(hwndDlg, IDC_BACKGROUND_IMAGE) ? Options::LOG_IMAGE_ENABLED : 0;
+ i |= IsDlgButtonChecked(hwndDlg, IDC_SCROLL_BACKGROUND_IMAGE) ? Options::LOG_IMAGE_SCROLL : 0;
+ i |= IsDlgButtonChecked(hwndDlg, IDC_LOG_SHOW_NICKNAMES) ? Options::LOG_SHOW_NICKNAMES : 0;
+ i |= IsDlgButtonChecked(hwndDlg, IDC_LOG_SHOW_TIME) ? Options::LOG_SHOW_TIME : 0;
+ i |= IsDlgButtonChecked(hwndDlg, IDC_LOG_SHOW_DATE) ? Options::LOG_SHOW_DATE : 0;
+ i |= IsDlgButtonChecked(hwndDlg, IDC_LOG_SHOW_SECONDS) ? Options::LOG_SHOW_SECONDS : 0;
+ i |= IsDlgButtonChecked(hwndDlg, IDC_LOG_LONG_DATE) ? Options::LOG_LONG_DATE : 0;
+ i |= IsDlgButtonChecked(hwndDlg, IDC_LOG_RELATIVE_DATE) ? Options::LOG_RELATIVE_DATE : 0;
+ i |= IsDlgButtonChecked(hwndDlg, IDC_LOG_GROUP_MESSAGES) ? Options::LOG_GROUP_MESSAGES : 0;
+ proto->setSRMMFlagsTemp(i);
+ GetDlgItemTextA(hwndDlg, IDC_BACKGROUND_IMAGE_FILENAME, path, sizeof(path));
+ proto->setSRMMBackgroundFilenameTemp(path);
+ GetDlgItemTextA(hwndDlg, IDC_EXTERNALCSS_FILENAME, path, sizeof(path));
+ proto->setSRMMCssFilenameTemp(path);
+ GetDlgItemTextA(hwndDlg, IDC_TEMPLATES_FILENAME, path, sizeof(path));
+ proto->setSRMMTemplateFilenameTemp(path);
+ }
+}
+
+static void SaveChatProtoSettings(HWND hwndDlg, ProtocolSettings *proto) {
+ if (proto != NULL) {
+ char path[MAX_PATH];
+ int i;
+ i = Options::MODE_COMPATIBLE;
+ if (IsDlgButtonChecked(hwndDlg, IDC_MODE_TEMPLATE)) {
+ i = Options::MODE_TEMPLATE;
+ } else if (IsDlgButtonChecked(hwndDlg, IDC_MODE_CSS)) {
+ i = Options::MODE_CSS;
+ }
+ proto->setChatModeTemp(i);
+ i = IsDlgButtonChecked(hwndDlg, IDC_BACKGROUND_IMAGE) ? Options::LOG_IMAGE_ENABLED : 0;
+ i |= IsDlgButtonChecked(hwndDlg, IDC_SCROLL_BACKGROUND_IMAGE) ? Options::LOG_IMAGE_SCROLL : 0;
+ i |= IsDlgButtonChecked(hwndDlg, IDC_LOG_SHOW_NICKNAMES) ? Options::LOG_SHOW_NICKNAMES : 0;
+ i |= IsDlgButtonChecked(hwndDlg, IDC_LOG_SHOW_TIME) ? Options::LOG_SHOW_TIME : 0;
+ i |= IsDlgButtonChecked(hwndDlg, IDC_LOG_SHOW_DATE) ? Options::LOG_SHOW_DATE : 0;
+ i |= IsDlgButtonChecked(hwndDlg, IDC_LOG_SHOW_SECONDS) ? Options::LOG_SHOW_SECONDS : 0;
+ i |= IsDlgButtonChecked(hwndDlg, IDC_LOG_LONG_DATE) ? Options::LOG_LONG_DATE : 0;
+ i |= IsDlgButtonChecked(hwndDlg, IDC_LOG_RELATIVE_DATE) ? Options::LOG_RELATIVE_DATE : 0;
+ i |= IsDlgButtonChecked(hwndDlg, IDC_LOG_GROUP_MESSAGES) ? Options::LOG_GROUP_MESSAGES : 0;
+ proto->setChatFlagsTemp(i);
+ GetDlgItemTextA(hwndDlg, IDC_BACKGROUND_IMAGE_FILENAME, path, sizeof(path));
+ proto->setChatBackgroundFilenameTemp(path);
+ GetDlgItemTextA(hwndDlg, IDC_EXTERNALCSS_FILENAME, path, sizeof(path));
+ proto->setChatCssFilenameTemp(path);
+ GetDlgItemTextA(hwndDlg, IDC_TEMPLATES_FILENAME, path, sizeof(path));
+ proto->setChatTemplateFilenameTemp(path);
+ }
+}
+
+static void SaveHistoryProtoSettings(HWND hwndDlg, ProtocolSettings *proto) {
+ if (proto != NULL) {
+ char path[MAX_PATH];
+ int i;
+ i = Options::MODE_COMPATIBLE;
+ if (IsDlgButtonChecked(hwndDlg, IDC_MODE_TEMPLATE)) {
+ i = Options::MODE_TEMPLATE;
+ } else if (IsDlgButtonChecked(hwndDlg, IDC_MODE_CSS)) {
+ i = Options::MODE_CSS;
+ }
+ proto->setHistoryModeTemp(i);
+ i = IsDlgButtonChecked(hwndDlg, IDC_BACKGROUND_IMAGE) ? Options::LOG_IMAGE_ENABLED : 0;
+ i |= IsDlgButtonChecked(hwndDlg, IDC_SCROLL_BACKGROUND_IMAGE) ? Options::LOG_IMAGE_SCROLL : 0;
+ i |= IsDlgButtonChecked(hwndDlg, IDC_LOG_SHOW_NICKNAMES) ? Options::LOG_SHOW_NICKNAMES : 0;
+ i |= IsDlgButtonChecked(hwndDlg, IDC_LOG_SHOW_TIME) ? Options::LOG_SHOW_TIME : 0;
+ i |= IsDlgButtonChecked(hwndDlg, IDC_LOG_SHOW_DATE) ? Options::LOG_SHOW_DATE : 0;
+ i |= IsDlgButtonChecked(hwndDlg, IDC_LOG_SHOW_SECONDS) ? Options::LOG_SHOW_SECONDS : 0;
+ i |= IsDlgButtonChecked(hwndDlg, IDC_LOG_LONG_DATE) ? Options::LOG_LONG_DATE : 0;
+ i |= IsDlgButtonChecked(hwndDlg, IDC_LOG_RELATIVE_DATE) ? Options::LOG_RELATIVE_DATE : 0;
+ i |= IsDlgButtonChecked(hwndDlg, IDC_LOG_GROUP_MESSAGES) ? Options::LOG_GROUP_MESSAGES : 0;
+ proto->setHistoryFlagsTemp(i);
+ GetDlgItemTextA(hwndDlg, IDC_BACKGROUND_IMAGE_FILENAME, path, sizeof(path));
+ proto->setHistoryBackgroundFilenameTemp(path);
+ GetDlgItemTextA(hwndDlg, IDC_EXTERNALCSS_FILENAME, path, sizeof(path));
+ proto->setHistoryCssFilenameTemp(path);
+ GetDlgItemTextA(hwndDlg, IDC_TEMPLATES_FILENAME, path, sizeof(path));
+ proto->setHistoryTemplateFilenameTemp(path);
+ }
+}
+
+static void UpdateControlsState(HWND hwndDlg) {
+
+ BOOL bChecked = IsDlgButtonChecked(hwndDlg, IDC_MODE_TEMPLATE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TEMPLATES_FILENAME), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSE_TEMPLATES), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOG_SHOW_NICKNAMES), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOG_SHOW_TIME), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOG_SHOW_DATE), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOG_SHOW_SECONDS), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOG_LONG_DATE), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOG_RELATIVE_DATE), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOG_GROUP_MESSAGES), bChecked);
+
+ bChecked = IsDlgButtonChecked(hwndDlg, IDC_MODE_CSS);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_EXTERNALCSS_FILENAME), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSE_EXTERNALCSS), bChecked);
+
+ bChecked = IsDlgButtonChecked(hwndDlg, IDC_MODE_COMPATIBLE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BACKGROUND_IMAGE), bChecked);
+ bChecked &= IsDlgButtonChecked(hwndDlg, IDC_BACKGROUND_IMAGE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BACKGROUND_IMAGE_FILENAME), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SCROLL_BACKGROUND_IMAGE), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSE_BACKGROUND_IMAGE), bChecked);
+}
+
+static void SetIcon(HWND hwnd, DWORD id, int index, bool condition) {
+ HICON hIcon;
+ if (condition) {
+ hIcon = ImageList_GetIcon(hImageList,index + 1,ILD_NORMAL);
+ } else {
+ hIcon = ImageList_GetIcon(hImageList,index + 0,ILD_NORMAL);
+ }
+ hIcon = (HICON) SendDlgItemMessage(hwnd, id, STM_SETICON,(WPARAM)hIcon, 0);
+ if (hIcon != NULL) {
+ DestroyIcon(hIcon);
+ }
+}
+
+
+static void UpdateTemplateIcons(HWND hwnd, const char *path) {
+ TemplateMap *tmap = TemplateMap::loadTemplates(path, path, true);
+ if (tmap != NULL) {
+ SetIcon(hwnd, IDC_GROUPSUPPORT, 0, tmap->isGrouping());
+ SetIcon(hwnd, IDC_RTLSUPPORT, 2, tmap->isRTL());
+ delete tmap;
+ } else {
+ SetIcon(hwnd, IDC_GROUPSUPPORT, 0, false);
+ SetIcon(hwnd, IDC_RTLSUPPORT, 2, false);
+ }
+}
+
+static void UpdateSRMMProtoInfo(HWND hwndDlg, ProtocolSettings *proto) {
+ if (proto != NULL) {
+ HWND hProtoList = GetDlgItem(hwndDlg, IDC_PROTOLIST);
+ TreeView_SetCheckState(hProtoList, TreeView_GetSelection(hProtoList), proto->isSRMMEnableTemp());
+ CheckDlgButton(hwndDlg, IDC_MODE_TEMPLATE, proto->getSRMMModeTemp() == Options::MODE_TEMPLATE ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_MODE_CSS, proto->getSRMMModeTemp() == Options::MODE_CSS ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_MODE_COMPATIBLE, proto->getSRMMModeTemp() == Options::MODE_COMPATIBLE ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_BACKGROUND_IMAGE, proto->getSRMMFlagsTemp() & Options::LOG_IMAGE_ENABLED ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_SCROLL_BACKGROUND_IMAGE, proto->getSRMMFlagsTemp() & Options::LOG_IMAGE_SCROLL ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_LOG_SHOW_NICKNAMES, proto->getSRMMFlagsTemp() & Options::LOG_SHOW_NICKNAMES ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_LOG_SHOW_TIME, proto->getSRMMFlagsTemp() & Options::LOG_SHOW_TIME ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_LOG_SHOW_DATE, proto->getSRMMFlagsTemp() & Options::LOG_SHOW_DATE ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_LOG_SHOW_SECONDS, proto->getSRMMFlagsTemp() & Options::LOG_SHOW_SECONDS ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_LOG_LONG_DATE, proto->getSRMMFlagsTemp() & Options::LOG_LONG_DATE ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_LOG_RELATIVE_DATE, proto->getSRMMFlagsTemp() & Options::LOG_RELATIVE_DATE ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_LOG_GROUP_MESSAGES, proto->getSRMMFlagsTemp() & Options::LOG_GROUP_MESSAGES ? TRUE : FALSE);
+ if (proto->getSRMMBackgroundFilenameTemp() != NULL) {
+ SetDlgItemTextA(hwndDlg, IDC_BACKGROUND_IMAGE_FILENAME, proto->getSRMMBackgroundFilenameTemp());
+ } else {
+ SetDlgItemTextA(hwndDlg, IDC_BACKGROUND_IMAGE_FILENAME, "");
+ }
+ if (proto->getSRMMCssFilename() != NULL) {
+ SetDlgItemTextA(hwndDlg, IDC_EXTERNALCSS_FILENAME, proto->getSRMMCssFilenameTemp());
+ } else {
+ SetDlgItemTextA(hwndDlg, IDC_EXTERNALCSS_FILENAME, "");
+ }
+ if (proto->getSRMMTemplateFilenameTemp() != NULL) {
+ SetDlgItemTextA(hwndDlg, IDC_TEMPLATES_FILENAME, proto->getSRMMTemplateFilenameTemp());
+ } else {
+ SetDlgItemTextA(hwndDlg, IDC_TEMPLATES_FILENAME, "");
+ }
+ UpdateTemplateIcons(hwndDlg, proto->getSRMMTemplateFilenameTemp());
+ srmmCurrentProtoItem = proto;
+ UpdateControlsState(hwndDlg);
+ }
+}
+
+static void UpdateChatProtoInfo(HWND hwndDlg, ProtocolSettings *proto) {
+ if (proto != NULL) {
+ HWND hProtoList = GetDlgItem(hwndDlg, IDC_PROTOLIST);
+ TreeView_SetCheckState(hProtoList, TreeView_GetSelection(hProtoList), proto->isChatEnableTemp());
+ CheckDlgButton(hwndDlg, IDC_MODE_TEMPLATE, proto->getChatModeTemp() == Options::MODE_TEMPLATE ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_MODE_CSS, proto->getChatModeTemp() == Options::MODE_CSS ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_MODE_COMPATIBLE, proto->getChatModeTemp() == Options::MODE_COMPATIBLE ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_BACKGROUND_IMAGE, proto->getChatFlagsTemp() & Options::LOG_IMAGE_ENABLED ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_SCROLL_BACKGROUND_IMAGE, proto->getChatFlagsTemp() & Options::LOG_IMAGE_SCROLL ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_LOG_SHOW_NICKNAMES, proto->getChatFlagsTemp() & Options::LOG_SHOW_NICKNAMES ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_LOG_SHOW_TIME, proto->getChatFlagsTemp() & Options::LOG_SHOW_TIME ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_LOG_SHOW_DATE, proto->getChatFlagsTemp() & Options::LOG_SHOW_DATE ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_LOG_SHOW_SECONDS, proto->getChatFlagsTemp() & Options::LOG_SHOW_SECONDS ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_LOG_LONG_DATE, proto->getChatFlagsTemp() & Options::LOG_LONG_DATE ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_LOG_RELATIVE_DATE, proto->getChatFlagsTemp() & Options::LOG_RELATIVE_DATE ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_LOG_GROUP_MESSAGES, proto->getChatFlagsTemp() & Options::LOG_GROUP_MESSAGES ? TRUE : FALSE);
+ if (proto->getChatBackgroundFilenameTemp() != NULL) {
+ SetDlgItemTextA(hwndDlg, IDC_BACKGROUND_IMAGE_FILENAME, proto->getChatBackgroundFilenameTemp());
+ } else {
+ SetDlgItemTextA(hwndDlg, IDC_BACKGROUND_IMAGE_FILENAME, "");
+ }
+ if (proto->getChatCssFilename() != NULL) {
+ SetDlgItemTextA(hwndDlg, IDC_EXTERNALCSS_FILENAME, proto->getChatCssFilenameTemp());
+ } else {
+ SetDlgItemTextA(hwndDlg, IDC_EXTERNALCSS_FILENAME, "");
+ }
+ if (proto->getChatTemplateFilenameTemp() != NULL) {
+ SetDlgItemTextA(hwndDlg, IDC_TEMPLATES_FILENAME, proto->getChatTemplateFilenameTemp());
+ } else {
+ SetDlgItemTextA(hwndDlg, IDC_TEMPLATES_FILENAME, "");
+ }
+ UpdateTemplateIcons(hwndDlg, proto->getChatTemplateFilenameTemp());
+ chatCurrentProtoItem = proto;
+ UpdateControlsState(hwndDlg);
+ }
+}
+
+static void UpdateHistoryProtoInfo(HWND hwndDlg, ProtocolSettings *proto) {
+ if (proto != NULL) {
+ HWND hProtoList = GetDlgItem(hwndDlg, IDC_PROTOLIST);
+ TreeView_SetCheckState(hProtoList, TreeView_GetSelection(hProtoList), proto->isHistoryEnableTemp());
+ CheckDlgButton(hwndDlg, IDC_MODE_TEMPLATE, proto->getHistoryModeTemp() == Options::MODE_TEMPLATE ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_MODE_CSS, proto->getHistoryModeTemp() == Options::MODE_CSS ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_MODE_COMPATIBLE, proto->getHistoryModeTemp() == Options::MODE_COMPATIBLE ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_BACKGROUND_IMAGE, proto->getHistoryFlagsTemp() & Options::LOG_IMAGE_ENABLED ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_SCROLL_BACKGROUND_IMAGE, proto->getHistoryFlagsTemp() & Options::LOG_IMAGE_SCROLL ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_LOG_SHOW_NICKNAMES, proto->getHistoryFlagsTemp() & Options::LOG_SHOW_NICKNAMES ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_LOG_SHOW_TIME, proto->getHistoryFlagsTemp() & Options::LOG_SHOW_TIME ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_LOG_SHOW_DATE, proto->getHistoryFlagsTemp() & Options::LOG_SHOW_DATE ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_LOG_SHOW_SECONDS, proto->getHistoryFlagsTemp() & Options::LOG_SHOW_SECONDS ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_LOG_LONG_DATE, proto->getHistoryFlagsTemp() & Options::LOG_LONG_DATE ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_LOG_RELATIVE_DATE, proto->getHistoryFlagsTemp() & Options::LOG_RELATIVE_DATE ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_LOG_GROUP_MESSAGES, proto->getHistoryFlagsTemp() & Options::LOG_GROUP_MESSAGES ? TRUE : FALSE);
+ if (proto->getHistoryBackgroundFilenameTemp() != NULL) {
+ SetDlgItemTextA(hwndDlg, IDC_BACKGROUND_IMAGE_FILENAME, proto->getHistoryBackgroundFilenameTemp());
+ } else {
+ SetDlgItemTextA(hwndDlg, IDC_BACKGROUND_IMAGE_FILENAME, "");
+ }
+ if (proto->getHistoryCssFilename() != NULL) {
+ SetDlgItemTextA(hwndDlg, IDC_EXTERNALCSS_FILENAME, proto->getHistoryCssFilenameTemp());
+ } else {
+ SetDlgItemTextA(hwndDlg, IDC_EXTERNALCSS_FILENAME, "");
+ }
+ if (proto->getHistoryTemplateFilenameTemp() != NULL) {
+ SetDlgItemTextA(hwndDlg, IDC_TEMPLATES_FILENAME, proto->getHistoryTemplateFilenameTemp());
+ } else {
+ SetDlgItemTextA(hwndDlg, IDC_TEMPLATES_FILENAME, "");
+ }
+ UpdateTemplateIcons(hwndDlg, proto->getHistoryTemplateFilenameTemp());
+ historyCurrentProtoItem = proto;
+ UpdateControlsState(hwndDlg);
+ }
+}
+
+static void RefreshProtoIcons() {
+ int i;
+ ProtocolSettings *proto;
+ if (hProtocolImageList != NULL) {
+ ImageList_RemoveAll(hProtocolImageList);
+ } else {
+ for (i=0,proto=Options::getProtocolSettings();proto!=NULL;proto=proto->getNext(),i++);
+ hProtocolImageList = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
+ ILC_MASK | ILC_COLOR32, i, 0);
+ }
+ for (i=0,proto=Options::getProtocolSettings();proto!=NULL;proto=proto->getNext(),i++) {
+ HICON hIcon = NULL;
+ if (i > 0 ) {
+ hIcon=(HICON)CallProtoService(proto->getProtocolName(), PS_LOADICON, PLI_PROTOCOL | PLIF_SMALL, 0);
+ if (hIcon == NULL) {
+ hIcon=(HICON)CallProtoService(proto->getProtocolName(), PS_LOADICON, PLI_PROTOCOL, 0);
+ }
+ ImageList_AddIcon(hProtocolImageList, hIcon);
+ DestroyIcon(hIcon);
+ }
+ if (hIcon == NULL) {
+ hIcon=(HICON)LoadSkinnedIcon(SKINICON_OTHER_MIRANDA);
+ ImageList_AddIcon(hProtocolImageList, hIcon);
+ CallService(MS_SKIN2_RELEASEICON,(WPARAM)hIcon, 0);
+ }
+ }
+}
+
+static void RefreshIcons() {
+ if (hImageList != NULL) {
+ ImageList_RemoveAll(hImageList);
+ } else {
+ hImageList = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_MASK | ILC_COLOR32, 0, 0);
+ }
+ ImageList_AddIcon(hImageList, (HICON) LoadImage(hInstance, MAKEINTRESOURCE(IDI_GROUP_OFF),IMAGE_ICON,0,0,0));
+ ImageList_AddIcon(hImageList, (HICON) LoadImage(hInstance, MAKEINTRESOURCE(IDI_GROUP_ON),IMAGE_ICON,0,0,0));
+ ImageList_AddIcon(hImageList, (HICON) LoadImage(hInstance, MAKEINTRESOURCE(IDI_RTL_OFF),IMAGE_ICON,0,0,0));
+ ImageList_AddIcon(hImageList, (HICON) LoadImage(hInstance, MAKEINTRESOURCE(IDI_RTL_ON),IMAGE_ICON,0,0,0));
+}
+
+static void RefreshProtoList(HWND hwndDlg, int mode, bool protoTemplates) {
+ int i;
+ HTREEITEM hItem = NULL;
+ HWND hProtoList = GetDlgItem(hwndDlg, IDC_PROTOLIST);
+ TreeView_DeleteAllItems(hProtoList);
+ TreeView_SetImageList(hProtoList, hProtocolImageList, TVSIL_NORMAL);
+ ProtocolSettings *proto;
+ for (i=0,proto=Options::getProtocolSettings();proto!=NULL;proto=proto->getNext(),i++) {
+ char protoName[128];
+ TVINSERTSTRUCT tvi = {0};
+ tvi.hParent = TVI_ROOT;
+ tvi.hInsertAfter = TVI_LAST;
+ tvi.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_STATE | TVIF_SELECTEDIMAGE;
+ tvi.item.stateMask = TVIS_SELECTED | TVIS_STATEIMAGEMASK;
+ if (i==0) {
+ strcpy(protoName, Translate("Default"));
+ } else {
+ CallProtoService(proto->getProtocolName(), PS_GETNAME, sizeof(protoName), (LPARAM)protoName);
+// strcat(protoName, " ");
+ // strcat(protoName, Translate("protocol"));
+ }
+ tvi.item.pszText = Utils::convertToWCS(protoName);
+ tvi.item.lParam = (LPARAM)proto;
+ tvi.item.iImage = i;
+ tvi.item.iSelectedImage = i;
+ switch (mode) {
+ case 0:
+ tvi.item.state = INDEXTOSTATEIMAGEMASK(proto->isSRMMEnableTemp() ? 2 : 1);
+ break;
+ case 1:
+ tvi.item.state = INDEXTOSTATEIMAGEMASK(proto->isChatEnableTemp() ? 2 : 1);
+ break;
+ case 2:
+ tvi.item.state = INDEXTOSTATEIMAGEMASK(proto->isHistoryEnableTemp() ? 2 : 1);
+ break;
+ }
+ if (i==0) {
+ hItem = TreeView_InsertItem(hProtoList, &tvi);
+ } else {
+ TreeView_InsertItem(hProtoList, &tvi);
+ }
+ if (!protoTemplates) break;
+ }
+// UpdateSRMMProtoInfo(hwndDlg, Options::getProtocolSettings());
+ TreeView_SelectItem(hProtoList, hItem);
+}
+
+static bool BrowseFile(HWND hwndDlg, char *filter, char *defExt, char *path, int maxLen) {
+ OPENFILENAMEA ofn={0};
+ GetWindowTextA(hwndDlg, path, maxLen);
+ ofn.lStructSize = sizeof(OPENFILENAME);//_SIZE_VERSION_400;
+ ofn.hwndOwner = hwndDlg;
+ ofn.hInstance = NULL;
+ ofn.lpstrFilter = filter;//"Templates (*.ivt)\0*.ivt\0All Files\0*.*\0\0";
+ ofn.lpstrFile = path;
+ ofn.Flags = OFN_FILEMUSTEXIST;
+ ofn.nMaxFile = maxLen;
+ ofn.nMaxFileTitle = maxLen;
+ ofn.lpstrDefExt = defExt;//"ivt";
+ if(GetOpenFileNameA(&ofn)) {
+ SetWindowTextA(hwndDlg, path);
+ return true;
+ }
+ return false;
+}
+
+int IEViewOptInit(WPARAM wParam, LPARAM lParam)
+{
+ DWORD i;
+ OPTIONSDIALOGPAGE odp = { 0 };
+ odp.cbSize = sizeof(odp);
+ odp.position = 0;
+ odp.hInstance = hInstance;
+ odp.ptszGroup = _T("Message Sessions");
+ odp.ptszTitle = _T("IEView");
+ odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR;
+ odp.nIDBottomSimpleControl = 0;
+ odp.pszTemplate = MAKEINTRESOURCEA(tabPages[0].dlgId);
+ odp.pfnDlgProc = tabPages[0].dlgProc;
+ odp.ptszTab = tabPages[0].tabName;
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) & odp);
+ odp.ptszGroup = _T("Skins");
+ odp.ptszTitle = _T("IEView");
+ for (i = 1; i < SIZEOF(tabPages); i++) {
+ odp.pszTemplate = MAKEINTRESOURCEA(tabPages[i].dlgId);
+ odp.pfnDlgProc = tabPages[i].dlgProc;
+ odp.ptszTab = tabPages[i].tabName;
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) & odp);
+ }
+ return 0;
+}
+
+static int initialized = 0;
+static int changed = 0;
+
+static void MarkInitialized(int i) {
+ if (initialized == 0) {
+ Options::resetProtocolSettings();
+ RefreshProtoIcons();
+ RefreshIcons();
+ }
+ initialized |= i;
+}
+
+static void ApplyChanges(int i) {
+ changed &= ~i;
+ initialized &= ~i;
+ if (changed == 0) {
+ Options::saveProtocolSettings();
+ NotifyEventHooks(hHookOptionsChanged, 0, 0);
+ }
+}
+
+static void MarkChanges(int i, HWND hWnd) {
+ SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0);
+ changed |= i;
+}
+
+static INT_PTR CALLBACK IEViewGeneralOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
+ int i;
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ MarkInitialized(1);
+ TranslateDialogDefault(hwndDlg);
+ if (Options::getGeneralFlags() & Options::GENERAL_ENABLE_BBCODES) {
+ CheckDlgButton(hwndDlg, IDC_ENABLE_BBCODES, TRUE);
+ }
+ if (Options::getGeneralFlags() & Options::GENERAL_ENABLE_FLASH) {
+ CheckDlgButton(hwndDlg, IDC_ENABLE_FLASH, TRUE);
+ }
+ if (Options::getGeneralFlags() & Options::GENERAL_ENABLE_MATHMODULE) {
+ CheckDlgButton(hwndDlg, IDC_ENABLE_MATHMODULE, TRUE);
+ }
+ if (Options::getGeneralFlags() & Options::GENERAL_ENABLE_PNGHACK) {
+ CheckDlgButton(hwndDlg, IDC_ENABLE_PNGHACK, TRUE);
+ }
+ if (Options::getGeneralFlags() & Options::GENERAL_SMILEYINNAMES) {
+ CheckDlgButton(hwndDlg, IDC_SMILEYS_IN_NAMES, TRUE);
+ }
+ if (Options::getGeneralFlags() & Options::GENERAL_NO_BORDER) {
+ CheckDlgButton(hwndDlg, IDC_NO_BORDER, TRUE);
+ }
+ if (Options::getGeneralFlags() & Options::GENERAL_ENABLE_EMBED) {
+ CheckDlgButton(hwndDlg, IDC_ENABLE_EMBED, TRUE);
+ }
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE_MATHMODULE), Options::isMathModule());
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SMILEYS_IN_NAMES), Options::isSmileyAdd());
+ EnableWindow(GetDlgItem(hwndDlg, IDC_EMBED_SIZE), IsDlgButtonChecked(hwndDlg, IDC_ENABLE_EMBED));
+ TCHAR* size[] = { _T("320õ205"), _T("480 x 385") , _T("560 x 349"), _T("640 x 390")};
+ for (i = 0; i < SIZEOF(size); ++i){
+ int item=SendDlgItemMessage(hwndDlg,IDC_EMBED_SIZE,CB_ADDSTRING,0,(LPARAM)TranslateTS(size[i]));
+ SendDlgItemMessage(hwndDlg,IDC_EMBED_SIZE,CB_SETITEMDATA,item,(LPARAM)0);
+ }
+ SendDlgItemMessage(hwndDlg,IDC_EMBED_SIZE,CB_SETCURSEL,Options::getEmbedsize(),0);
+ return TRUE;
+ }
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam)) {
+ case IDC_ENABLE_BBCODES:
+ case IDC_ENABLE_FLASH:
+ case IDC_ENABLE_MATHMODULE:
+ case IDC_ENABLE_PNGHACK:
+ case IDC_SMILEYS_IN_NAMES:
+ case IDC_NO_BORDER:
+ case IDC_EMBED_SIZE:
+ MarkChanges(1, hwndDlg);
+ break;
+ case IDC_ENABLE_EMBED:
+ MarkChanges(1, hwndDlg);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_EMBED_SIZE), IsDlgButtonChecked(hwndDlg, IDC_ENABLE_EMBED));
+ break;
+ }
+ }
+ break;
+ case WM_NOTIFY:
+ {
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ i = 0;
+ if (IsDlgButtonChecked(hwndDlg, IDC_ENABLE_BBCODES)) {
+ i |= Options::GENERAL_ENABLE_BBCODES;
+ }
+ if (IsDlgButtonChecked(hwndDlg, IDC_ENABLE_FLASH)) {
+ i |= Options::GENERAL_ENABLE_FLASH;
+ }
+ if (IsDlgButtonChecked(hwndDlg, IDC_ENABLE_MATHMODULE)) {
+ i |= Options::GENERAL_ENABLE_MATHMODULE;
+ }
+ if (IsDlgButtonChecked(hwndDlg, IDC_ENABLE_PNGHACK)) {
+ i |= Options::GENERAL_ENABLE_PNGHACK;
+ }
+ if (IsDlgButtonChecked(hwndDlg, IDC_SMILEYS_IN_NAMES)) {
+ i |= Options::GENERAL_SMILEYINNAMES;
+ }
+ if (IsDlgButtonChecked(hwndDlg, IDC_NO_BORDER)) {
+ i |= Options::GENERAL_NO_BORDER;
+ }
+ if (IsDlgButtonChecked(hwndDlg, IDC_ENABLE_EMBED)) {
+ i |= Options::GENERAL_ENABLE_EMBED;
+ }
+ Options::setGeneralFlags(i);
+ ApplyChanges(1);
+ Options::setEmbedsize(SendDlgItemMessage(hwndDlg,IDC_EMBED_SIZE,CB_GETCURSEL,0,0));
+ return TRUE;
+ }
+ }
+ break;
+ case WM_DESTROY:
+ break;
+ }
+ return FALSE;
+}
+
+static INT_PTR CALLBACK IEViewSRMMOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
+ BOOL bChecked;
+ char path[MAX_PATH], filter[MAX_PATH];
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ MarkInitialized(2);
+ TranslateDialogDefault(hwndDlg);
+ srmmCurrentProtoItem = NULL;
+ RefreshProtoList(hwndDlg, 0, true);
+ return TRUE;
+ }
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam)) {
+ case IDC_BACKGROUND_IMAGE_FILENAME:
+ case IDC_EXTERNALCSS_FILENAME:
+ case IDC_EXTERNALCSS_FILENAME_RTL:
+ case IDC_TEMPLATES_FILENAME:
+ if ((HWND)lParam==GetFocus() && HIWORD(wParam)==EN_CHANGE)
+ MarkChanges(2, hwndDlg);
+ break;
+ case IDC_SCROLL_BACKGROUND_IMAGE:
+ case IDC_LOG_SHOW_NICKNAMES:
+ case IDC_LOG_SHOW_TIME:
+ case IDC_LOG_SHOW_DATE:
+ case IDC_LOG_SHOW_SECONDS:
+ case IDC_LOG_LONG_DATE:
+ case IDC_LOG_RELATIVE_DATE:
+ case IDC_LOG_GROUP_MESSAGES:
+ MarkChanges(2, hwndDlg);
+ break;
+ case IDC_BACKGROUND_IMAGE:
+ bChecked = IsDlgButtonChecked(hwndDlg, IDC_MODE_COMPATIBLE) && IsDlgButtonChecked(hwndDlg, IDC_BACKGROUND_IMAGE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BACKGROUND_IMAGE_FILENAME), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSE_BACKGROUND_IMAGE), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SCROLL_BACKGROUND_IMAGE), bChecked);
+ MarkChanges(2, hwndDlg);
+ break;
+ case IDC_BROWSE_TEMPLATES:
+ mir_snprintf(filter, SIZEOF(filter), "%s (*.ivt)%c*.ivt%c%s%c*.*%c%c", Translate("Template"), 0, 0, Translate("All Files"), 0, 0, 0);
+ if (BrowseFile(hwndDlg, filter, "ivt", path, SIZEOF(path))) {
+ SetDlgItemTextA(hwndDlg, IDC_TEMPLATES_FILENAME, path);
+ UpdateTemplateIcons(hwndDlg, path);
+ MarkChanges(2, hwndDlg);
+ }
+ break;
+ case IDC_BROWSE_BACKGROUND_IMAGE:
+ mir_snprintf(filter, SIZEOF(filter), "%s (*.jpg,*.gif,*.png,*.bmp)%c*.ivt%c%s%c*.*%c%c", Translate("All Images"), 0, 0, Translate("All Files"), 0, 0, 0);
+ if (BrowseFile(hwndDlg, filter, "jpg", path, SIZEOF(path))) {
+ SetDlgItemTextA(hwndDlg,IDC_BACKGROUND_IMAGE_FILENAME,path);
+ MarkChanges(2, hwndDlg);
+ }
+ break;
+ case IDC_BROWSE_EXTERNALCSS:
+ mir_snprintf(filter, SIZEOF(filter), "%s (*.css)%c*.ivt%c%s%c*.*%c%c", Translate("Style Sheet"), 0, 0, Translate("All Files"), 0, 0, 0);
+ if (BrowseFile(hwndDlg, filter, "css", path, SIZEOF(path))) {
+ SetDlgItemTextA(hwndDlg, IDC_EXTERNALCSS_FILENAME, path);
+ MarkChanges(2, hwndDlg);
+ }
+ break;
+ case IDC_BROWSE_EXTERNALCSS_RTL:
+ mir_snprintf(filter, SIZEOF(filter), "%s (*.css)%c*.ivt%c%s%c*.*%c%c", Translate("Style Sheet"), 0, 0, Translate("All Files"), 0, 0, 0);
+ if (BrowseFile(hwndDlg, filter, "css", path, SIZEOF(path))) {
+ SetDlgItemTextA(hwndDlg, IDC_EXTERNALCSS_FILENAME_RTL, path);
+ MarkChanges(2, hwndDlg);
+ }
+ break;
+ case IDC_MODE_COMPATIBLE:
+ case IDC_MODE_CSS:
+ case IDC_MODE_TEMPLATE:
+ UpdateControlsState(hwndDlg);
+ MarkChanges(2, hwndDlg);
+ break;
+ }
+ }
+ break;
+ case UM_CHECKSTATECHANGE:
+ {
+ ProtocolSettings *proto = (ProtocolSettings *)GetItemParam((HWND)wParam, (HTREEITEM) lParam);
+ if (proto != NULL) {
+ if (strcmpi(proto->getProtocolName(), "_default_")) {
+ proto->setSRMMEnableTemp(TreeView_GetCheckState((HWND)wParam, (HTREEITEM) lParam));
+ }
+ }
+ if ((HTREEITEM) lParam != TreeView_GetSelection((HWND)wParam)) {
+ TreeView_SelectItem((HWND)wParam, (HTREEITEM) lParam);
+ } else {
+ UpdateSRMMProtoInfo(hwndDlg, proto);
+ }
+ MarkChanges(2, hwndDlg);
+ }
+ break;
+ case WM_NOTIFY:
+ {
+ if (((LPNMHDR)lParam)->idFrom == IDC_PROTOLIST) {
+ switch (((LPNMHDR)lParam)->code) {
+ case NM_CLICK:
+ {
+ TVHITTESTINFO ht = {0};
+ DWORD dwpos = GetMessagePos();
+ POINTSTOPOINT(ht.pt, MAKEPOINTS(dwpos));
+ MapWindowPoints(HWND_DESKTOP, ((LPNMHDR)lParam)->hwndFrom, &ht.pt, 1);
+ TreeView_HitTest(((LPNMHDR)lParam)->hwndFrom, &ht);
+ if (TVHT_ONITEMSTATEICON & ht.flags) {
+ PostMessage(hwndDlg, UM_CHECKSTATECHANGE, (WPARAM)((LPNMHDR)lParam)->hwndFrom, (LPARAM)ht.hItem);
+ return FALSE;
+ }
+ }
+ break;
+ case TVN_KEYDOWN:
+ if (((LPNMTVKEYDOWN) lParam)->wVKey == VK_SPACE)
+ PostMessage(hwndDlg, UM_CHECKSTATECHANGE, (WPARAM)((LPNMHDR)lParam)->hwndFrom,
+ (LPARAM)TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom));
+ break;
+ case TVN_SELCHANGEDA:
+ case TVN_SELCHANGEDW:
+ {
+ ProtocolSettings *proto = (ProtocolSettings *)GetItemParam(GetDlgItem(hwndDlg, IDC_PROTOLIST), (HTREEITEM) NULL);
+ SaveSRMMProtoSettings(hwndDlg, srmmCurrentProtoItem);
+ UpdateSRMMProtoInfo(hwndDlg, proto);
+ }
+ break;
+ }
+ break;
+ }
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ SaveSRMMProtoSettings(hwndDlg, srmmCurrentProtoItem);
+ ApplyChanges(2);
+ return TRUE;
+ }
+ }
+ break;
+ case WM_DESTROY:
+ break;
+ }
+ return FALSE;
+}
+
+static INT_PTR CALLBACK IEViewHistoryOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
+ BOOL bChecked = FALSE;
+ char path[MAX_PATH], filter[MAX_PATH];
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ MarkInitialized(4);
+ TranslateDialogDefault(hwndDlg);
+ historyCurrentProtoItem = NULL;
+ RefreshProtoList(hwndDlg, 2, true);
+ return TRUE;
+ }
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam)) {
+ case IDC_BACKGROUND_IMAGE_FILENAME:
+ case IDC_EXTERNALCSS_FILENAME:
+ case IDC_EXTERNALCSS_FILENAME_RTL:
+ case IDC_TEMPLATES_FILENAME:
+ if ((HWND)lParam==GetFocus() && HIWORD(wParam)==EN_CHANGE)
+ MarkChanges(4, hwndDlg);
+ break;
+ case IDC_SCROLL_BACKGROUND_IMAGE:
+ case IDC_LOG_SHOW_NICKNAMES:
+ case IDC_LOG_SHOW_TIME:
+ case IDC_LOG_SHOW_DATE:
+ case IDC_LOG_SHOW_SECONDS:
+ case IDC_LOG_LONG_DATE:
+ case IDC_LOG_RELATIVE_DATE:
+ case IDC_LOG_GROUP_MESSAGES:
+ MarkChanges(4, hwndDlg);
+ break;
+ case IDC_BACKGROUND_IMAGE:
+ bChecked = IsDlgButtonChecked(hwndDlg, IDC_MODE_COMPATIBLE) && IsDlgButtonChecked(hwndDlg, IDC_BACKGROUND_IMAGE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BACKGROUND_IMAGE_FILENAME), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSE_BACKGROUND_IMAGE), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SCROLL_BACKGROUND_IMAGE), bChecked);
+ MarkChanges(4, hwndDlg);
+ break;
+ case IDC_BROWSE_TEMPLATES:
+ mir_snprintf(filter, SIZEOF(filter), "%s (*.ivt)%c*.ivt%c%s%c*.*%c%c", Translate("Template"), 0, 0, Translate("All Files"), 0, 0, 0);
+ if (BrowseFile(hwndDlg, filter, "ivt", path, SIZEOF(path))) {
+ SetDlgItemTextA(hwndDlg, IDC_TEMPLATES_FILENAME, path);
+ UpdateTemplateIcons(hwndDlg, path);
+ MarkChanges(4, hwndDlg);
+ }
+ break;
+ case IDC_BROWSE_BACKGROUND_IMAGE:
+ mir_snprintf(filter, SIZEOF(filter), "%s (*.jpg,*.gif,*.png,*.bmp)%c*.ivt%c%s%c*.*%c%c", Translate("All Images"), 0, 0, Translate("All Files"), 0, 0, 0);
+ if (BrowseFile(hwndDlg, filter, "jpg", path, SIZEOF(path))) {
+ SetDlgItemTextA(hwndDlg,IDC_BACKGROUND_IMAGE_FILENAME,path);
+ MarkChanges(4, hwndDlg);
+ }
+ break;
+ case IDC_BROWSE_EXTERNALCSS:
+ mir_snprintf(filter, SIZEOF(filter), "%s (*.css)%c*.ivt%c%s%c*.*%c%c", Translate("Style Sheet"), 0, 0, Translate("All Files"), 0, 0, 0);
+ if (BrowseFile(hwndDlg, filter, "css", path, SIZEOF(path))) {
+ SetDlgItemTextA(hwndDlg, IDC_EXTERNALCSS_FILENAME, path);
+ MarkChanges(4, hwndDlg);
+ }
+ break;
+ case IDC_BROWSE_EXTERNALCSS_RTL:
+ mir_snprintf(filter, SIZEOF(filter), "%s (*.css)%c*.ivt%c%s%c*.*%c%c", Translate("Style Sheet"), 0, 0, Translate("All Files"), 0, 0, 0);
+ if (BrowseFile(hwndDlg, filter, "css", path, SIZEOF(path))) {
+ SetDlgItemTextA(hwndDlg, IDC_EXTERNALCSS_FILENAME_RTL, path);
+ MarkChanges(4, hwndDlg);
+ }
+ break;
+ case IDC_MODE_COMPATIBLE:
+ case IDC_MODE_CSS:
+ case IDC_MODE_TEMPLATE:
+ UpdateControlsState(hwndDlg);
+ MarkChanges(4, hwndDlg);
+ break;
+ }
+ }
+ break;
+ case UM_CHECKSTATECHANGE:
+ {
+ ProtocolSettings *proto = (ProtocolSettings *)GetItemParam((HWND)wParam, (HTREEITEM) lParam);
+ if (proto != NULL) {
+ if (strcmpi(proto->getProtocolName(), "_default_")) {
+ proto->setHistoryEnableTemp(TreeView_GetCheckState((HWND)wParam, (HTREEITEM) lParam));
+ }
+ }
+ if ((HTREEITEM) lParam != TreeView_GetSelection((HWND)wParam)) {
+ TreeView_SelectItem((HWND)wParam, (HTREEITEM) lParam);
+ } else {
+ UpdateHistoryProtoInfo(hwndDlg, proto);
+ }
+ MarkChanges(4, hwndDlg);
+ }
+ break;
+ case WM_NOTIFY:
+ {
+ if (((LPNMHDR)lParam)->idFrom == IDC_PROTOLIST) {
+ switch (((LPNMHDR)lParam)->code) {
+ case NM_CLICK:
+ {
+ TVHITTESTINFO ht = {0};
+ DWORD dwpos = GetMessagePos();
+ POINTSTOPOINT(ht.pt, MAKEPOINTS(dwpos));
+ MapWindowPoints(HWND_DESKTOP, ((LPNMHDR)lParam)->hwndFrom, &ht.pt, 1);
+ TreeView_HitTest(((LPNMHDR)lParam)->hwndFrom, &ht);
+ if (TVHT_ONITEMSTATEICON & ht.flags) {
+ PostMessage(hwndDlg, UM_CHECKSTATECHANGE, (WPARAM)((LPNMHDR)lParam)->hwndFrom, (LPARAM)ht.hItem);
+ return FALSE;
+ }
+ }
+ break;
+ case TVN_KEYDOWN:
+ if (((LPNMTVKEYDOWN) lParam)->wVKey == VK_SPACE)
+ PostMessage(hwndDlg, UM_CHECKSTATECHANGE, (WPARAM)((LPNMHDR)lParam)->hwndFrom,
+ (LPARAM)TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom));
+ break;
+ case TVN_SELCHANGEDA:
+ case TVN_SELCHANGEDW:
+ {
+ ProtocolSettings *proto = (ProtocolSettings *)GetItemParam(GetDlgItem(hwndDlg, IDC_PROTOLIST), (HTREEITEM) NULL);
+ SaveHistoryProtoSettings(hwndDlg, historyCurrentProtoItem);
+ UpdateHistoryProtoInfo(hwndDlg, proto);
+ }
+ break;
+ }
+ break;
+ }
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ SaveHistoryProtoSettings(hwndDlg, historyCurrentProtoItem);
+ ApplyChanges(4);
+ return TRUE;
+ }
+ }
+ break;
+ case WM_DESTROY:
+ break;
+ }
+ return FALSE;
+}
+
+static INT_PTR CALLBACK IEViewGroupChatsOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
+ BOOL bChecked;
+ char path[MAX_PATH], filter[MAX_PATH];
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ MarkInitialized(8);
+ TranslateDialogDefault(hwndDlg);
+ chatCurrentProtoItem = NULL;
+ RefreshProtoList(hwndDlg, 1, true);
+ return TRUE;
+ }
+ break;
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam)) {
+ case IDC_BACKGROUND_IMAGE_FILENAME:
+ case IDC_EXTERNALCSS_FILENAME:
+ case IDC_EXTERNALCSS_FILENAME_RTL:
+ case IDC_TEMPLATES_FILENAME:
+ if ((HWND)lParam==GetFocus() && HIWORD(wParam)==EN_CHANGE)
+ MarkChanges(8, hwndDlg);
+ break;
+ case IDC_SCROLL_BACKGROUND_IMAGE:
+ case IDC_LOG_SHOW_NICKNAMES:
+ case IDC_LOG_SHOW_TIME:
+ case IDC_LOG_SHOW_DATE:
+ case IDC_LOG_SHOW_SECONDS:
+ case IDC_LOG_LONG_DATE:
+ case IDC_LOG_RELATIVE_DATE:
+ case IDC_LOG_GROUP_MESSAGES:
+ MarkChanges(8, hwndDlg);
+ break;
+ case IDC_BACKGROUND_IMAGE:
+ bChecked = IsDlgButtonChecked(hwndDlg, IDC_MODE_COMPATIBLE) && IsDlgButtonChecked(hwndDlg, IDC_BACKGROUND_IMAGE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BACKGROUND_IMAGE_FILENAME), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSE_BACKGROUND_IMAGE), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SCROLL_BACKGROUND_IMAGE), bChecked);
+ MarkChanges(8, hwndDlg);
+ break;
+ case IDC_BROWSE_TEMPLATES:
+ mir_snprintf(filter, SIZEOF(filter), "%s (*.ivt)%c*.ivt%c%s%c*.*%c%c", Translate("Template"), 0, 0, Translate("All Files"), 0, 0, 0);
+ if (BrowseFile(hwndDlg, filter, "ivt", path, SIZEOF(path))) {
+ SetDlgItemTextA(hwndDlg, IDC_TEMPLATES_FILENAME, path);
+ UpdateTemplateIcons(hwndDlg, path);
+ MarkChanges(8, hwndDlg);
+ }
+ break;
+ case IDC_BROWSE_BACKGROUND_IMAGE:
+ mir_snprintf(filter, SIZEOF(filter), "%s (*.jpg,*.gif,*.png,*.bmp)%c*.ivt%c%s%c*.*%c%c", Translate("All Images"), 0, 0, Translate("All Files"), 0, 0, 0);
+ if (BrowseFile(hwndDlg, filter, "jpg", path, SIZEOF(path))) {
+ SetDlgItemTextA(hwndDlg,IDC_BACKGROUND_IMAGE_FILENAME,path);
+ MarkChanges(8, hwndDlg);
+ }
+ break;
+ case IDC_BROWSE_EXTERNALCSS:
+ mir_snprintf(filter, SIZEOF(filter), "%s (*.css)%c*.ivt%c%s%c*.*%c%c", Translate("Style Sheet"), 0, 0, Translate("All Files"), 0, 0, 0);
+ if (BrowseFile(hwndDlg, filter, "css", path, SIZEOF(path))) {
+ SetDlgItemTextA(hwndDlg, IDC_EXTERNALCSS_FILENAME, path);
+ MarkChanges(8, hwndDlg);
+ }
+ break;
+ case IDC_BROWSE_EXTERNALCSS_RTL:
+ mir_snprintf(filter, SIZEOF(filter), "%s (*.css)%c*.ivt%c%s%c*.*%c%c", Translate("Style Sheet"), 0, 0, Translate("All Files"), 0, 0, 0);
+ if (BrowseFile(hwndDlg, filter, "css", path, SIZEOF(path))) {
+ SetDlgItemTextA(hwndDlg, IDC_EXTERNALCSS_FILENAME_RTL, path);
+ MarkChanges(8, hwndDlg);
+ }
+ break;
+ case IDC_MODE_COMPATIBLE:
+ case IDC_MODE_CSS:
+ case IDC_MODE_TEMPLATE:
+ UpdateControlsState(hwndDlg);
+ MarkChanges(8, hwndDlg);
+ break;
+ }
+ }
+ break;
+ case UM_CHECKSTATECHANGE:
+ {
+ ProtocolSettings *proto = (ProtocolSettings *)GetItemParam((HWND)wParam, (HTREEITEM) lParam);
+ if (proto != NULL) {
+ if (strcmpi(proto->getProtocolName(), "_default_")) {
+ proto->setChatEnableTemp(TreeView_GetCheckState((HWND)wParam, (HTREEITEM) lParam));
+ }
+ }
+ if ((HTREEITEM) lParam != TreeView_GetSelection((HWND)wParam)) {
+ TreeView_SelectItem((HWND)wParam, (HTREEITEM) lParam);
+ } else {
+ UpdateChatProtoInfo(hwndDlg, proto);
+ }
+ MarkChanges(8, hwndDlg);
+ }
+ break;
+ case WM_NOTIFY:
+ {
+ if (((LPNMHDR)lParam)->idFrom == IDC_PROTOLIST) {
+ switch (((LPNMHDR)lParam)->code) {
+ case NM_CLICK:
+ {
+ TVHITTESTINFO ht = {0};
+ DWORD dwpos = GetMessagePos();
+ POINTSTOPOINT(ht.pt, MAKEPOINTS(dwpos));
+ MapWindowPoints(HWND_DESKTOP, ((LPNMHDR)lParam)->hwndFrom, &ht.pt, 1);
+ TreeView_HitTest(((LPNMHDR)lParam)->hwndFrom, &ht);
+ if (TVHT_ONITEMSTATEICON & ht.flags) {
+ PostMessage(hwndDlg, UM_CHECKSTATECHANGE, (WPARAM)((LPNMHDR)lParam)->hwndFrom, (LPARAM)ht.hItem);
+ return FALSE;
+ }
+ }
+ break;
+ case TVN_KEYDOWN:
+ if (((LPNMTVKEYDOWN) lParam)->wVKey == VK_SPACE)
+ PostMessage(hwndDlg, UM_CHECKSTATECHANGE, (WPARAM)((LPNMHDR)lParam)->hwndFrom,
+ (LPARAM)TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom));
+ break;
+ case TVN_SELCHANGEDA:
+ case TVN_SELCHANGEDW:
+ {
+ ProtocolSettings *proto = (ProtocolSettings *)GetItemParam(GetDlgItem(hwndDlg, IDC_PROTOLIST), (HTREEITEM) NULL);
+ SaveChatProtoSettings(hwndDlg, chatCurrentProtoItem);
+ UpdateChatProtoInfo(hwndDlg, proto);
+ }
+ break;
+ }
+ break;
+ }
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ SaveChatProtoSettings(hwndDlg, chatCurrentProtoItem);
+ ApplyChanges(8);
+ return TRUE;
+ }
+ }
+ break;
+ case WM_DESTROY:
+ break;
+ }
+ return FALSE;
+}
+
+bool Options::isInited = false;
+bool Options::bMathModule = false;
+bool Options::bSmileyAdd = false;
+int Options::avatarServiceFlags = 0;
+int Options::generalFlags;
+
+ProtocolSettings *Options::protocolList = NULL;
+
+ProtocolSettings::ProtocolSettings(const char *protocolName) {
+ this->protocolName = Utils::dupString(protocolName);
+ next = NULL;
+ srmmEnable = false;
+ srmmMode = Options::MODE_COMPATIBLE;
+ srmmFlags = 0;
+ srmmBackgroundFilename = Utils::dupString("");
+ srmmCssFilename = Utils::dupString("");
+ srmmTemplateFilename = Utils::dupString("");
+
+ srmmBackgroundFilenameTemp = Utils::dupString("");
+ srmmCssFilenameTemp = Utils::dupString("");
+ srmmTemplateFilenameTemp = Utils::dupString("");
+
+ chatEnable = false;
+ chatMode = Options::MODE_COMPATIBLE;
+ chatFlags = 0;
+ chatBackgroundFilename = Utils::dupString("");
+ chatCssFilename = Utils::dupString("");
+ chatTemplateFilename = Utils::dupString("");
+
+ chatBackgroundFilenameTemp = Utils::dupString("");
+ chatCssFilenameTemp = Utils::dupString("");
+ chatTemplateFilenameTemp = Utils::dupString("");
+
+ historyEnable = false;
+ historyMode = Options::MODE_COMPATIBLE;
+ historyFlags = 0;
+ historyBackgroundFilename = Utils::dupString("");
+ historyCssFilename = Utils::dupString("");
+ historyTemplateFilename = Utils::dupString("");
+
+ historyBackgroundFilenameTemp = Utils::dupString("");
+ historyCssFilenameTemp = Utils::dupString("");
+ historyTemplateFilenameTemp = Utils::dupString("");
+
+}
+
+ProtocolSettings::~ProtocolSettings() {
+ delete protocolName;
+ if (srmmBackgroundFilename != NULL) {
+ delete srmmBackgroundFilename;
+ }
+ if (srmmBackgroundFilenameTemp != NULL) {
+ delete srmmBackgroundFilenameTemp;
+ }
+ if (srmmCssFilename != NULL) {
+ delete srmmCssFilename;
+ }
+ if (srmmCssFilenameTemp != NULL) {
+ delete srmmCssFilenameTemp;
+ }
+ if (srmmTemplateFilename != NULL) {
+ delete srmmTemplateFilename;
+ }
+ if (srmmTemplateFilenameTemp != NULL) {
+ delete srmmTemplateFilenameTemp;
+ }
+
+ if (chatBackgroundFilename != NULL) {
+ delete chatBackgroundFilename;
+ }
+ if (chatBackgroundFilenameTemp != NULL) {
+ delete chatBackgroundFilenameTemp;
+ }
+ if (chatCssFilename != NULL) {
+ delete chatCssFilename;
+ }
+ if (chatCssFilenameTemp != NULL) {
+ delete chatCssFilenameTemp;
+ }
+ if (chatTemplateFilename != NULL) {
+ delete chatTemplateFilename;
+ }
+ if (chatTemplateFilenameTemp != NULL) {
+ delete chatTemplateFilenameTemp;
+ }
+
+ if (historyBackgroundFilename != NULL) {
+ delete historyBackgroundFilename;
+ }
+ if (historyBackgroundFilenameTemp != NULL) {
+ delete historyBackgroundFilenameTemp;
+ }
+ if (historyCssFilename != NULL) {
+ delete historyCssFilename;
+ }
+ if (historyCssFilenameTemp != NULL) {
+ delete historyCssFilenameTemp;
+ }
+ if (historyTemplateFilename != NULL) {
+ delete historyTemplateFilename;
+ }
+ if (historyTemplateFilenameTemp != NULL) {
+ delete historyTemplateFilenameTemp;
+ }
+}
+
+void ProtocolSettings::copyToTemp() {
+ setSRMMModeTemp(getSRMMMode());
+ setSRMMFlagsTemp(getSRMMFlags());
+ setSRMMBackgroundFilenameTemp(getSRMMBackgroundFilename());
+ setSRMMCssFilenameTemp(getSRMMCssFilename());
+ setSRMMTemplateFilenameTemp(getSRMMTemplateFilename());
+ setSRMMEnableTemp(isSRMMEnable());
+
+ setChatModeTemp(getChatMode());
+ setChatFlagsTemp(getChatFlags());
+ setChatBackgroundFilenameTemp(getChatBackgroundFilename());
+ setChatCssFilenameTemp(getChatCssFilename());
+ setChatTemplateFilenameTemp(getChatTemplateFilename());
+ setChatEnableTemp(isChatEnable());
+
+ setHistoryModeTemp(getHistoryMode());
+ setHistoryFlagsTemp(getHistoryFlags());
+ setHistoryBackgroundFilenameTemp(getHistoryBackgroundFilename());
+ setHistoryCssFilenameTemp(getHistoryCssFilename());
+ setHistoryTemplateFilenameTemp(getHistoryTemplateFilename());
+ setHistoryEnableTemp(isHistoryEnable());
+}
+
+void ProtocolSettings::copyFromTemp() {
+ setSRMMMode(getSRMMModeTemp());
+ setSRMMFlags(getSRMMFlagsTemp());
+ setSRMMBackgroundFilename(getSRMMBackgroundFilenameTemp());
+ setSRMMCssFilename(getSRMMCssFilenameTemp());
+ setSRMMTemplateFilename(getSRMMTemplateFilenameTemp());
+ setSRMMEnable(isSRMMEnableTemp());
+
+ setChatMode(getChatModeTemp());
+ setChatFlags(getChatFlagsTemp());
+ setChatBackgroundFilename(getChatBackgroundFilenameTemp());
+ setChatCssFilename(getChatCssFilenameTemp());
+ setChatTemplateFilename(getChatTemplateFilenameTemp());
+ setChatEnable(isChatEnableTemp());
+
+ setHistoryMode(getHistoryModeTemp());
+ setHistoryFlags(getHistoryFlagsTemp());
+ setHistoryBackgroundFilename(getHistoryBackgroundFilenameTemp());
+ setHistoryCssFilename(getHistoryCssFilenameTemp());
+ setHistoryTemplateFilename(getHistoryTemplateFilenameTemp());
+ setHistoryEnable(isHistoryEnableTemp());
+}
+
+void ProtocolSettings::setNext(ProtocolSettings *next) {
+ this->next = next;
+}
+
+const char *ProtocolSettings::getProtocolName() {
+ return protocolName;
+}
+
+ProtocolSettings * ProtocolSettings::getNext() {
+ return next;
+}
+
+void ProtocolSettings::setSRMMBackgroundFilename(const char *filename) {
+ if (srmmBackgroundFilename != NULL) {
+ delete srmmBackgroundFilename;
+ }
+ srmmBackgroundFilename = Utils::dupString(filename);
+}
+
+void ProtocolSettings::setSRMMBackgroundFilenameTemp(const char *filename) {
+ if (srmmBackgroundFilenameTemp != NULL) {
+ delete srmmBackgroundFilenameTemp;
+ }
+ srmmBackgroundFilenameTemp = Utils::dupString(filename);
+}
+
+void ProtocolSettings::setSRMMCssFilename(const char *filename) {
+ if (srmmCssFilename != NULL) {
+ delete srmmCssFilename;
+ }
+ srmmCssFilename = Utils::dupString(filename);
+}
+
+void ProtocolSettings::setSRMMCssFilenameTemp(const char *filename) {
+ if (srmmCssFilenameTemp != NULL) {
+ delete srmmCssFilenameTemp;
+ }
+ srmmCssFilenameTemp = Utils::dupString(filename);
+}
+
+void ProtocolSettings::setSRMMTemplateFilename(const char *filename) {
+ if (srmmTemplateFilename != NULL) {
+ delete srmmTemplateFilename;
+ }
+ srmmTemplateFilename = Utils::dupString(filename);
+ TemplateMap::loadTemplates(getSRMMTemplateFilename(), getSRMMTemplateFilename(), false);
+}
+
+void ProtocolSettings::setSRMMTemplateFilenameTemp(const char *filename) {
+ if (srmmTemplateFilenameTemp != NULL) {
+ delete srmmTemplateFilenameTemp;
+ }
+ srmmTemplateFilenameTemp = Utils::dupString(filename);
+}
+
+const char *ProtocolSettings::getSRMMBackgroundFilename() {
+ return srmmBackgroundFilename;
+}
+
+const char *ProtocolSettings::getSRMMBackgroundFilenameTemp() {
+ return srmmBackgroundFilenameTemp;
+}
+
+const char *ProtocolSettings::getSRMMCssFilename() {
+ return srmmCssFilename;
+}
+
+const char *ProtocolSettings::getSRMMCssFilenameTemp() {
+ return srmmCssFilenameTemp;
+}
+
+const char *ProtocolSettings::getSRMMTemplateFilename() {
+ return srmmTemplateFilename;
+}
+
+const char *ProtocolSettings::getSRMMTemplateFilenameTemp() {
+ return srmmTemplateFilenameTemp;
+}
+
+void ProtocolSettings::setSRMMEnable(bool enable) {
+ this->srmmEnable = enable;
+}
+
+bool ProtocolSettings::isSRMMEnable() {
+ return srmmEnable;
+}
+
+void ProtocolSettings::setSRMMEnableTemp(bool enable) {
+ this->srmmEnableTemp = enable;
+}
+
+bool ProtocolSettings::isSRMMEnableTemp() {
+ return srmmEnableTemp;
+}
+
+void ProtocolSettings::setSRMMMode(int mode) {
+ this->srmmMode = mode;
+}
+
+int ProtocolSettings::getSRMMMode() {
+ return srmmMode;
+}
+
+void ProtocolSettings::setSRMMModeTemp(int mode) {
+ this->srmmModeTemp = mode;
+}
+
+int ProtocolSettings::getSRMMModeTemp() {
+ return srmmModeTemp;
+}
+
+void ProtocolSettings::setSRMMFlags(int flags) {
+ this->srmmFlags = flags;
+}
+
+int ProtocolSettings::getSRMMFlags() {
+ return srmmFlags;
+}
+
+void ProtocolSettings::setSRMMFlagsTemp(int flags) {
+ this->srmmFlagsTemp = flags;
+}
+
+int ProtocolSettings::getSRMMFlagsTemp() {
+ return srmmFlagsTemp;
+}
+
+/* */
+
+void ProtocolSettings::setChatBackgroundFilename(const char *filename) {
+ if (chatBackgroundFilename != NULL) {
+ delete chatBackgroundFilename;
+ }
+ chatBackgroundFilename = Utils::dupString(filename);
+}
+
+void ProtocolSettings::setChatBackgroundFilenameTemp(const char *filename) {
+ if (chatBackgroundFilenameTemp != NULL) {
+ delete chatBackgroundFilenameTemp;
+ }
+ chatBackgroundFilenameTemp = Utils::dupString(filename);
+}
+
+void ProtocolSettings::setChatCssFilename(const char *filename) {
+ if (chatCssFilename != NULL) {
+ delete chatCssFilename;
+ }
+ chatCssFilename = Utils::dupString(filename);
+}
+
+void ProtocolSettings::setChatCssFilenameTemp(const char *filename) {
+ if (chatCssFilenameTemp != NULL) {
+ delete chatCssFilenameTemp;
+ }
+ chatCssFilenameTemp = Utils::dupString(filename);
+}
+
+void ProtocolSettings::setChatTemplateFilename(const char *filename) {
+ if (chatTemplateFilename != NULL) {
+ delete chatTemplateFilename;
+ }
+ chatTemplateFilename = Utils::dupString(filename);
+ TemplateMap::loadTemplates(getChatTemplateFilename(), getChatTemplateFilename(), false);
+}
+
+void ProtocolSettings::setChatTemplateFilenameTemp(const char *filename) {
+ if (chatTemplateFilenameTemp != NULL) {
+ delete chatTemplateFilenameTemp;
+ }
+ chatTemplateFilenameTemp = Utils::dupString(filename);
+}
+
+const char *ProtocolSettings::getChatBackgroundFilename() {
+ return chatBackgroundFilename;
+}
+
+const char *ProtocolSettings::getChatBackgroundFilenameTemp() {
+ return chatBackgroundFilenameTemp;
+}
+
+const char *ProtocolSettings::getChatCssFilename() {
+ return chatCssFilename;
+}
+
+const char *ProtocolSettings::getChatCssFilenameTemp() {
+ return chatCssFilenameTemp;
+}
+
+const char *ProtocolSettings::getChatTemplateFilename() {
+ return chatTemplateFilename;
+}
+
+const char *ProtocolSettings::getChatTemplateFilenameTemp() {
+ return chatTemplateFilenameTemp;
+}
+
+void ProtocolSettings::setChatEnable(bool enable) {
+ this->chatEnable = enable;
+}
+
+bool ProtocolSettings::isChatEnable() {
+ return chatEnable;
+}
+
+void ProtocolSettings::setChatEnableTemp(bool enable) {
+ this->chatEnableTemp = enable;
+}
+
+bool ProtocolSettings::isChatEnableTemp() {
+ return chatEnableTemp;
+}
+
+void ProtocolSettings::setChatMode(int mode) {
+ this->chatMode = mode;
+}
+
+int ProtocolSettings::getChatMode() {
+ return chatMode;
+}
+
+void ProtocolSettings::setChatModeTemp(int mode) {
+ this->chatModeTemp = mode;
+}
+
+int ProtocolSettings::getChatModeTemp() {
+ return chatModeTemp;
+}
+
+void ProtocolSettings::setChatFlags(int flags) {
+ this->chatFlags = flags;
+}
+
+int ProtocolSettings::getChatFlags() {
+ return chatFlags;
+}
+
+void ProtocolSettings::setChatFlagsTemp(int flags) {
+ this->chatFlagsTemp = flags;
+}
+
+int ProtocolSettings::getChatFlagsTemp() {
+ return chatFlagsTemp;
+}
+
+/* */
+
+void ProtocolSettings::setHistoryBackgroundFilename(const char *filename) {
+ if (historyBackgroundFilename != NULL) {
+ delete historyBackgroundFilename;
+ }
+ historyBackgroundFilename = Utils::dupString(filename);
+}
+
+void ProtocolSettings::setHistoryBackgroundFilenameTemp(const char *filename) {
+ if (historyBackgroundFilenameTemp != NULL) {
+ delete historyBackgroundFilenameTemp;
+ }
+ historyBackgroundFilenameTemp = Utils::dupString(filename);
+}
+
+void ProtocolSettings::setHistoryCssFilename(const char *filename) {
+ if (historyCssFilename != NULL) {
+ delete historyCssFilename;
+ }
+ historyCssFilename = Utils::dupString(filename);
+}
+
+void ProtocolSettings::setHistoryCssFilenameTemp(const char *filename) {
+ if (historyCssFilenameTemp != NULL) {
+ delete historyCssFilenameTemp;
+ }
+ historyCssFilenameTemp = Utils::dupString(filename);
+}
+
+void ProtocolSettings::setHistoryTemplateFilename(const char *filename) {
+ if (historyTemplateFilename != NULL) {
+ delete historyTemplateFilename;
+ }
+ historyTemplateFilename = Utils::dupString(filename);
+ TemplateMap::loadTemplates(getHistoryTemplateFilename(), getHistoryTemplateFilename(), false);
+}
+
+void ProtocolSettings::setHistoryTemplateFilenameTemp(const char *filename) {
+ if (historyTemplateFilenameTemp != NULL) {
+ delete historyTemplateFilenameTemp;
+ }
+ historyTemplateFilenameTemp = Utils::dupString(filename);
+}
+
+const char *ProtocolSettings::getHistoryBackgroundFilename() {
+ return historyBackgroundFilename;
+}
+
+const char *ProtocolSettings::getHistoryBackgroundFilenameTemp() {
+ return historyBackgroundFilenameTemp;
+}
+
+const char *ProtocolSettings::getHistoryCssFilename() {
+ return historyCssFilename;
+}
+
+const char *ProtocolSettings::getHistoryCssFilenameTemp() {
+ return historyCssFilenameTemp;
+}
+
+const char *ProtocolSettings::getHistoryTemplateFilename() {
+ return historyTemplateFilename;
+}
+
+const char *ProtocolSettings::getHistoryTemplateFilenameTemp() {
+ return historyTemplateFilenameTemp;
+}
+
+void ProtocolSettings::setHistoryEnable(bool enable) {
+ this->historyEnable = enable;
+}
+
+bool ProtocolSettings::isHistoryEnable() {
+ return historyEnable;
+}
+
+void ProtocolSettings::setHistoryEnableTemp(bool enable) {
+ this->historyEnableTemp = enable;
+}
+
+bool ProtocolSettings::isHistoryEnableTemp() {
+ return historyEnableTemp;
+}
+
+void ProtocolSettings::setHistoryMode(int mode) {
+ this->historyMode = mode;
+}
+
+int ProtocolSettings::getHistoryMode() {
+ return historyMode;
+}
+
+void ProtocolSettings::setHistoryModeTemp(int mode) {
+ this->historyModeTemp = mode;
+}
+
+int ProtocolSettings::getHistoryModeTemp() {
+ return historyModeTemp;
+}
+
+void ProtocolSettings::setHistoryFlags(int flags) {
+ this->historyFlags = flags;
+}
+
+int ProtocolSettings::getHistoryFlags() {
+ return historyFlags;
+}
+
+void ProtocolSettings::setHistoryFlagsTemp(int flags) {
+ this->historyFlagsTemp = flags;
+}
+
+int ProtocolSettings::getHistoryFlagsTemp() {
+ return historyFlagsTemp;
+}
+
+void Options::init() {
+ if (isInited) return;
+ isInited = true;
+ DBVARIANT dbv;
+
+ HMODULE hUxTheme = 0;
+ if(IsWinVerXPPlus()) {
+ hUxTheme = GetModuleHandle(_T("uxtheme.dll"));
+ if(hUxTheme)
+ pfnEnableThemeDialogTexture = (BOOL (WINAPI *)(HANDLE, DWORD))GetProcAddress(hUxTheme, "EnableThemeDialogTexture");
+ }
+
+
+ generalFlags = DBGetContactSettingDword(NULL, ieviewModuleName, DBS_BASICFLAGS, 13);
+
+ /* TODO: move to buildProtocolList method */
+ int protoCount;
+ PROTOCOLDESCRIPTOR **pProtos;
+ ProtocolSettings *lastProto = NULL;
+ CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&protoCount, (LPARAM)&pProtos);
+ for (int i = 0; i < protoCount+1; i++) {
+ ProtocolSettings *proto;
+ char tmpPath[MAX_PATH];
+ char dbsName[256];
+ if (i==0) {
+ proto = new ProtocolSettings("_default_");
+ proto->setSRMMEnable(true);
+ } else if ((pProtos[i-1]->type == PROTOTYPE_PROTOCOL) && strcmp(pProtos[i-1]->szName,"MetaContacts")) {
+ if ((CallProtoService(pProtos[i-1]->szName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_IM) == 0) {
+ continue;
+ }
+ proto = new ProtocolSettings(pProtos[i-1]->szName);
+ } else {
+ continue;
+ }
+ /* SRMM settings */
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_SRMM_ENABLE);
+ proto->setSRMMEnable(i==0 ? true : DBGetContactSettingByte(NULL, ieviewModuleName, dbsName, FALSE));
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_SRMM_MODE);
+ proto->setSRMMMode(DBGetContactSettingByte(NULL, ieviewModuleName, dbsName, FALSE));
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_SRMM_FLAGS);
+ proto->setSRMMFlags(DBGetContactSettingDword(NULL, ieviewModuleName, dbsName, 16128));
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_SRMM_BACKGROUND);
+ if (!DBGetContactSetting(NULL, ieviewModuleName, dbsName, &dbv)) {
+ strcpy(tmpPath, dbv.pszVal);
+ if (ServiceExists(MS_UTILS_PATHTOABSOLUTE) && strncmp(tmpPath, "http://", 7)) {
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)dbv.pszVal, (LPARAM)tmpPath);
+ }
+ proto->setSRMMBackgroundFilename(tmpPath);
+ DBFreeVariant(&dbv);
+ }
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_SRMM_CSS);
+ if (!DBGetContactSetting(NULL, ieviewModuleName, dbsName, &dbv)) {
+ strcpy(tmpPath, dbv.pszVal);
+ if (ServiceExists(MS_UTILS_PATHTOABSOLUTE) && strncmp(tmpPath, "http://", 7)) {
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)dbv.pszVal, (LPARAM)tmpPath);
+ }
+ proto->setSRMMCssFilename(tmpPath);
+ DBFreeVariant(&dbv);
+ }
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_SRMM_TEMPLATE);
+ if (!DBGetContactSetting(NULL, ieviewModuleName, dbsName, &dbv)) {
+ strcpy(tmpPath, dbv.pszVal);
+ if (ServiceExists(MS_UTILS_PATHTOABSOLUTE)) {
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)dbv.pszVal, (LPARAM)tmpPath);
+ }
+ proto->setSRMMTemplateFilename(tmpPath);
+ DBFreeVariant(&dbv);
+ }
+
+ /* Group chat settings */
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_CHAT_ENABLE);
+ proto->setChatEnable(i==0 ? true : DBGetContactSettingByte(NULL, ieviewModuleName, dbsName, FALSE));
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_CHAT_MODE);
+ proto->setChatMode(DBGetContactSettingByte(NULL, ieviewModuleName, dbsName, FALSE));
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_CHAT_FLAGS);
+ proto->setChatFlags(DBGetContactSettingDword(NULL, ieviewModuleName, dbsName, 16128));
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_CHAT_BACKGROUND);
+ if (!DBGetContactSetting(NULL, ieviewModuleName, dbsName, &dbv)) {
+ strcpy(tmpPath, dbv.pszVal);
+ if (ServiceExists(MS_UTILS_PATHTOABSOLUTE) && strncmp(tmpPath, "http://", 7)) {
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)dbv.pszVal, (LPARAM)tmpPath);
+ }
+ proto->setChatBackgroundFilename(tmpPath);
+ DBFreeVariant(&dbv);
+ }
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_CHAT_CSS);
+ if (!DBGetContactSetting(NULL, ieviewModuleName, dbsName, &dbv)) {
+ strcpy(tmpPath, dbv.pszVal);
+ if (ServiceExists(MS_UTILS_PATHTOABSOLUTE) && strncmp(tmpPath, "http://", 7)) {
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)dbv.pszVal, (LPARAM)tmpPath);
+ }
+ proto->setChatCssFilename(tmpPath);
+ DBFreeVariant(&dbv);
+ }
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_CHAT_TEMPLATE);
+ if (!DBGetContactSetting(NULL, ieviewModuleName, dbsName, &dbv)) {
+ strcpy(tmpPath, dbv.pszVal);
+ if (ServiceExists(MS_UTILS_PATHTOABSOLUTE)) {
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)dbv.pszVal, (LPARAM)tmpPath);
+ }
+ proto->setChatTemplateFilename(tmpPath);
+ DBFreeVariant(&dbv);
+ }
+
+ /* History settings */
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_HISTORY_ENABLE);
+ proto->setHistoryEnable(i==0 ? true : DBGetContactSettingByte(NULL, ieviewModuleName, dbsName, FALSE));
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_HISTORY_MODE);
+ proto->setHistoryMode(DBGetContactSettingByte(NULL, ieviewModuleName, dbsName, FALSE));
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_HISTORY_FLAGS);
+ proto->setHistoryFlags(DBGetContactSettingDword(NULL, ieviewModuleName, dbsName, 16128));
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_HISTORY_BACKGROUND);
+ if (!DBGetContactSetting(NULL, ieviewModuleName, dbsName, &dbv)) {
+ strcpy(tmpPath, dbv.pszVal);
+ if (ServiceExists(MS_UTILS_PATHTOABSOLUTE) && strncmp(tmpPath, "http://", 7)) {
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)dbv.pszVal, (LPARAM)tmpPath);
+ }
+ proto->setHistoryBackgroundFilename(tmpPath);
+ DBFreeVariant(&dbv);
+ }
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_HISTORY_CSS);
+ if (!DBGetContactSetting(NULL, ieviewModuleName, dbsName, &dbv)) {
+ strcpy(tmpPath, dbv.pszVal);
+ if (ServiceExists(MS_UTILS_PATHTOABSOLUTE) && strncmp(tmpPath, "http://", 7)) {
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)dbv.pszVal, (LPARAM)tmpPath);
+ }
+ proto->setHistoryCssFilename(tmpPath);
+ DBFreeVariant(&dbv);
+ }
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_HISTORY_TEMPLATE);
+ if (!DBGetContactSetting(NULL, ieviewModuleName, dbsName, &dbv)) {
+ strcpy(tmpPath, dbv.pszVal);
+ if (ServiceExists(MS_UTILS_PATHTOABSOLUTE)) {
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)dbv.pszVal, (LPARAM)tmpPath);
+ }
+ proto->setHistoryTemplateFilename(tmpPath);
+ DBFreeVariant(&dbv);
+ }
+ proto->copyToTemp();
+ if (lastProto != NULL) {
+ lastProto->setNext(proto);
+ } else {
+ protocolList = proto;
+ }
+ lastProto = proto;
+ }
+
+ bMathModule = (bool) ServiceExists(MTH_GET_GIF_UNICODE);
+ bSmileyAdd = (bool) ServiceExists(MS_SMILEYADD_BATCHPARSE);
+ avatarServiceFlags = 0;
+ if (ServiceExists(MS_AV_GETAVATARBITMAP)) {
+ avatarServiceFlags = AVATARSERVICE_PRESENT;
+ }
+
+
+// mathModuleFlags = ServiceExists(MTH_GET_HTML_SOURCE) ? GENERAL_ENABLE_MATHMODULE : 0;
+}
+
+void Options::uninit() {
+ ProtocolSettings *p, *p1;
+ for ( p = protocolList; p != NULL; p = p1 ) {
+ p1 = p->getNext();
+ delete p;
+ }
+ if (hImageList != NULL) {
+ ImageList_Destroy(hImageList);
+ }
+ if (hProtocolImageList != NULL) {
+ ImageList_Destroy(hProtocolImageList);
+ }
+}
+
+void Options::setGeneralFlags(int flags) {
+ generalFlags = flags;
+ DBWriteContactSettingDword(NULL, ieviewModuleName, DBS_BASICFLAGS, (DWORD) flags);
+}
+
+int Options::getGeneralFlags() {
+ return generalFlags;
+}
+
+void Options::setEmbedsize(int size){
+ DBWriteContactSettingDword(NULL, ieviewModuleName, "Embedsize", (DWORD) size);
+}
+
+int Options::getEmbedsize(){
+ return DBGetContactSettingDword(NULL, ieviewModuleName, "Embedsize", 0);
+}
+
+bool Options::isMathModule() {
+ return bMathModule;
+}
+
+bool Options::isSmileyAdd() {
+ return bSmileyAdd;
+}
+
+int Options::getAvatarServiceFlags() {
+ return avatarServiceFlags;
+}
+
+ProtocolSettings * Options::getProtocolSettings() {
+ return protocolList;
+}
+
+ProtocolSettings * Options::getProtocolSettings(const char *protocolName) {
+ for (ProtocolSettings *proto=protocolList;proto!=NULL;proto=proto->getNext()) {
+ if (!strcmpi(proto->getProtocolName(), protocolName)) {
+ return proto;
+ }
+ }
+ return NULL;
+}
+
+void Options::resetProtocolSettings() {
+ for (ProtocolSettings *proto=Options::getProtocolSettings();proto!=NULL;proto=proto->getNext()) {
+ proto->copyToTemp();
+ }
+}
+
+void Options::saveProtocolSettings() {
+ ProtocolSettings *proto;
+ int i;
+ for (i=0,proto=Options::getProtocolSettings();proto!=NULL;proto=proto->getNext(),i++) {
+ char dbsName[256];
+ char tmpPath[MAX_PATH];
+ proto->copyFromTemp();
+ /* SRMM settings */
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_SRMM_ENABLE);
+ DBWriteContactSettingByte(NULL, ieviewModuleName, dbsName, proto->isSRMMEnable());
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_SRMM_MODE);
+ DBWriteContactSettingByte(NULL, ieviewModuleName, dbsName, proto->getSRMMMode());
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_SRMM_FLAGS);
+ DBWriteContactSettingDword(NULL, ieviewModuleName, dbsName, proto->getSRMMFlags());
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_SRMM_BACKGROUND);
+ strcpy (tmpPath, proto->getSRMMBackgroundFilename());
+ if (ServiceExists(MS_UTILS_PATHTORELATIVE)) {
+ CallService(MS_UTILS_PATHTORELATIVE, (WPARAM)proto->getSRMMBackgroundFilename(), (LPARAM)tmpPath);
+ }
+ DBWriteContactSettingString(NULL, ieviewModuleName, dbsName, tmpPath);
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_SRMM_CSS);
+ strcpy (tmpPath, proto->getSRMMCssFilename());
+ if (ServiceExists(MS_UTILS_PATHTORELATIVE)) {
+ CallService(MS_UTILS_PATHTORELATIVE, (WPARAM)proto->getSRMMCssFilename(), (LPARAM)tmpPath);
+ }
+ DBWriteContactSettingString(NULL, ieviewModuleName, dbsName, tmpPath);
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_SRMM_TEMPLATE);
+ strcpy (tmpPath, proto->getSRMMTemplateFilename());
+ if (ServiceExists(MS_UTILS_PATHTORELATIVE)) {
+ CallService(MS_UTILS_PATHTORELATIVE, (WPARAM)proto->getSRMMTemplateFilename(), (LPARAM)tmpPath);
+ }
+ DBWriteContactSettingString(NULL, ieviewModuleName, dbsName, tmpPath);
+ /* Group Chat settings */
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_CHAT_ENABLE);
+ DBWriteContactSettingByte(NULL, ieviewModuleName, dbsName, proto->isChatEnable());
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_CHAT_MODE);
+ DBWriteContactSettingByte(NULL, ieviewModuleName, dbsName, proto->getChatMode());
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_CHAT_FLAGS);
+ DBWriteContactSettingDword(NULL, ieviewModuleName, dbsName, proto->getChatFlags());
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_CHAT_BACKGROUND);
+ strcpy (tmpPath, proto->getChatBackgroundFilename());
+ if (ServiceExists(MS_UTILS_PATHTORELATIVE)) {
+ CallService(MS_UTILS_PATHTORELATIVE, (WPARAM)proto->getChatBackgroundFilename(), (LPARAM)tmpPath);
+ }
+ DBWriteContactSettingString(NULL, ieviewModuleName, dbsName, tmpPath);
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_CHAT_CSS);
+ strcpy (tmpPath, proto->getChatCssFilename());
+ if (ServiceExists(MS_UTILS_PATHTORELATIVE)) {
+ CallService(MS_UTILS_PATHTORELATIVE, (WPARAM)proto->getChatCssFilename(), (LPARAM)tmpPath);
+ }
+ DBWriteContactSettingString(NULL, ieviewModuleName, dbsName, tmpPath);
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_CHAT_TEMPLATE);
+ strcpy (tmpPath, proto->getChatTemplateFilename());
+ if (ServiceExists(MS_UTILS_PATHTORELATIVE)) {
+ CallService(MS_UTILS_PATHTORELATIVE, (WPARAM)proto->getChatTemplateFilename(), (LPARAM)tmpPath);
+ }
+ DBWriteContactSettingString(NULL, ieviewModuleName, dbsName, tmpPath);
+ /* History settings */
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_HISTORY_ENABLE);
+ DBWriteContactSettingByte(NULL, ieviewModuleName, dbsName, proto->isHistoryEnable());
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_HISTORY_MODE);
+ DBWriteContactSettingByte(NULL, ieviewModuleName, dbsName, proto->getHistoryMode());
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_HISTORY_FLAGS);
+ DBWriteContactSettingDword(NULL, ieviewModuleName, dbsName, proto->getHistoryFlags());
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_HISTORY_BACKGROUND);
+ strcpy (tmpPath, proto->getHistoryBackgroundFilename());
+ if (ServiceExists(MS_UTILS_PATHTORELATIVE)) {
+ CallService(MS_UTILS_PATHTORELATIVE, (WPARAM)proto->getHistoryBackgroundFilename(), (LPARAM)tmpPath);
+ }
+ DBWriteContactSettingString(NULL, ieviewModuleName, dbsName, tmpPath);
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_HISTORY_CSS);
+ strcpy (tmpPath, proto->getHistoryCssFilename());
+ if (ServiceExists(MS_UTILS_PATHTORELATIVE)) {
+ CallService(MS_UTILS_PATHTORELATIVE, (WPARAM)proto->getHistoryCssFilename(), (LPARAM)tmpPath);
+ }
+ DBWriteContactSettingString(NULL, ieviewModuleName, dbsName, tmpPath);
+ sprintf(dbsName, "%s.%s", proto->getProtocolName(), DBS_HISTORY_TEMPLATE);
+ strcpy (tmpPath, proto->getHistoryTemplateFilename());
+ if (ServiceExists(MS_UTILS_PATHTORELATIVE)) {
+ CallService(MS_UTILS_PATHTORELATIVE, (WPARAM)proto->getHistoryTemplateFilename(), (LPARAM)tmpPath);
+ }
+ DBWriteContactSettingString(NULL, ieviewModuleName, dbsName, tmpPath);
+
+ }
+}
diff --git a/plugins/IEView/Options.h b/plugins/IEView/Options.h
new file mode 100644
index 0000000000..58f758ceaf
--- /dev/null
+++ b/plugins/IEView/Options.h
@@ -0,0 +1,249 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+class ProtocolSettings;
+class Options;
+#ifndef OPTIONS_INCLUDED
+#define OPTIONS_INCLUDED
+//#include "FontList.h"
+#include "ieview_common.h"
+
+#define DBS_BASICFLAGS "GeneralFlags"
+
+#define DBS_SRMM_ENABLE "SRMMEnable"
+#define DBS_SRMM_MODE "SRMMMode"
+#define DBS_SRMM_FLAGS "SRMMFlags"
+#define DBS_SRMM_BACKGROUND "SRMMBackgroundFile"
+#define DBS_SRMM_CSS "SRMMCSSFile"
+#define DBS_SRMM_TEMPLATE "SRMMTemplateFile"
+
+#define DBS_CHAT_ENABLE "ChatEnable"
+#define DBS_CHAT_MODE "ChatMode"
+#define DBS_CHAT_FLAGS "ChatFlags"
+#define DBS_CHAT_BACKGROUND "ChatBackgroundFile"
+#define DBS_CHAT_CSS "ChatCSSFile"
+#define DBS_CHAT_TEMPLATE "ChatTemplateFile"
+
+#define DBS_HISTORY_ENABLE "HistoryEnable"
+#define DBS_HISTORY_MODE "HistoryMode"
+#define DBS_HISTORY_FLAGS "HistoryFlags"
+#define DBS_HISTORY_BACKGROUND "HistoryBackgroundFile"
+#define DBS_HISTORY_CSS "HistoryCSSFile"
+#define DBS_HISTORY_TEMPLATE "HistoryTemplateFile"
+
+extern int IEViewOptInit(WPARAM wParam, LPARAM lParam);
+
+class ProtocolSettings {
+private:
+ char *protocolName;
+ ProtocolSettings *next;
+
+ bool srmmEnable;
+ int srmmMode;
+ int srmmFlags;
+ char *srmmBackgroundFilename;
+ char *srmmCssFilename;
+ char *srmmTemplateFilename;
+
+ bool srmmEnableTemp;
+ int srmmModeTemp;
+ int srmmFlagsTemp;
+ char *srmmBackgroundFilenameTemp;
+ char *srmmCssFilenameTemp;
+ char *srmmTemplateFilenameTemp;
+
+ bool chatEnable;
+ int chatMode;
+ int chatFlags;
+ char *chatBackgroundFilename;
+ char *chatCssFilename;
+ char *chatTemplateFilename;
+
+ bool chatEnableTemp;
+ int chatModeTemp;
+ int chatFlagsTemp;
+ char *chatBackgroundFilenameTemp;
+ char *chatCssFilenameTemp;
+ char *chatCssFilenameRtlTemp;
+ char *chatTemplateFilenameTemp;
+
+ bool historyEnable;
+ int historyMode;
+ int historyFlags;
+ char *historyBackgroundFilename;
+ char *historyCssFilename;
+ char *historyCssFilenameRtl;
+ char *historyTemplateFilename;
+
+ bool historyEnableTemp;
+ int historyModeTemp;
+ int historyFlagsTemp;
+ char *historyBackgroundFilenameTemp;
+ char *historyCssFilenameTemp;
+ char *historyCssFilenameRtlTemp;
+ char *historyTemplateFilenameTemp;
+
+public:
+ ProtocolSettings(const char *protocolName);
+ ~ProtocolSettings();
+ void setNext(ProtocolSettings *next);
+ const char *getProtocolName();
+ ProtocolSettings *getNext();
+ void setSRMMEnable(bool enable);
+ bool isSRMMEnable();
+ void setSRMMMode(int flags);
+ int getSRMMMode();
+ void setSRMMFlags(int flags);
+ int getSRMMFlags();
+ void setSRMMBackgroundFilename(const char *filename);
+ const char *getSRMMBackgroundFilename();
+ void setSRMMCssFilename(const char *filename);
+ const char *getSRMMCssFilename();
+ void setSRMMTemplateFilename(const char *filename);
+ const char *getSRMMTemplateFilename();
+
+ void setSRMMEnableTemp(bool enable);
+ bool isSRMMEnableTemp();
+ void setSRMMModeTemp(int flags);
+ int getSRMMModeTemp();
+ void setSRMMFlagsTemp(int flags);
+ int getSRMMFlagsTemp();
+ void setSRMMBackgroundFilenameTemp(const char *filename);
+ const char *getSRMMBackgroundFilenameTemp();
+ void setSRMMCssFilenameTemp(const char *filename);
+ const char *getSRMMCssFilenameTemp();
+ void setSRMMTemplateFilenameTemp(const char *filename);
+ const char *getSRMMTemplateFilenameTemp();
+
+ void setChatEnable(bool enable);
+ bool isChatEnable();
+ void setChatMode(int flags);
+ int getChatMode();
+ void setChatFlags(int flags);
+ int getChatFlags();
+ void setChatBackgroundFilename(const char *filename);
+ const char *getChatBackgroundFilename();
+ void setChatCssFilename(const char *filename);
+ const char *getChatCssFilename();
+ void setChatCssFilenameRtl(const char *filename);
+ const char *getChatCssFilenameRtl();
+ void setChatTemplateFilename(const char *filename);
+ const char *getChatTemplateFilename();
+
+ void setChatEnableTemp(bool enable);
+ bool isChatEnableTemp();
+ void setChatModeTemp(int flags);
+ int getChatModeTemp();
+ void setChatFlagsTemp(int flags);
+ int getChatFlagsTemp();
+ void setChatBackgroundFilenameTemp(const char *filename);
+ const char *getChatBackgroundFilenameTemp();
+ void setChatCssFilenameTemp(const char *filename);
+ const char *getChatCssFilenameTemp();
+ void setChatTemplateFilenameTemp(const char *filename);
+ const char *getChatTemplateFilenameTemp();
+
+ void setHistoryEnable(bool enable);
+ bool isHistoryEnable();
+ void setHistoryMode(int flags);
+ int getHistoryMode();
+ void setHistoryFlags(int flags);
+ int getHistoryFlags();
+ void setHistoryBackgroundFilename(const char *filename);
+ const char *getHistoryBackgroundFilename();
+ void setHistoryCssFilename(const char *filename);
+ const char *getHistoryCssFilename();
+ void setHistoryTemplateFilename(const char *filename);
+ const char *getHistoryTemplateFilename();
+
+ void setHistoryEnableTemp(bool enable);
+ bool isHistoryEnableTemp();
+ void setHistoryModeTemp(int flags);
+ int getHistoryModeTemp();
+ void setHistoryFlagsTemp(int flags);
+ int getHistoryFlagsTemp();
+ void setHistoryBackgroundFilenameTemp(const char *filename);
+ const char *getHistoryBackgroundFilenameTemp();
+ void setHistoryCssFilenameTemp(const char *filename);
+ const char *getHistoryCssFilenameTemp();
+ void setHistoryTemplateFilenameTemp(const char *filename);
+ const char *getHistoryTemplateFilenameTemp();
+
+ void copyToTemp();
+ void copyFromTemp();
+
+};
+
+class Options {
+private:
+ static int generalFlags;
+ static bool isInited;
+ static bool bMathModule;
+ static bool bSmileyAdd;
+ static int avatarServiceFlags;
+ static ProtocolSettings* protocolList;
+public:
+ enum MODES {
+ MODE_COMPATIBLE = 0,
+ MODE_CSS = 1,
+ MODE_TEMPLATE = 2
+ };
+ enum OPTIONS {
+ GENERAL_ENABLE_BBCODES = 0x000001,
+ GENERAL_ENABLE_MATHMODULE = 0x000002,
+ GENERAL_ENABLE_FLASH = 0x000004,
+ GENERAL_ENABLE_PNGHACK = 0x000008,
+ GENERAL_SMILEYINNAMES = 0x000010,
+ GENERAL_NO_BORDER = 0x000020,
+ GENERAL_ENABLE_EMBED = 0x000040,
+
+ LOG_SHOW_NICKNAMES = 0x000100,
+ LOG_SHOW_TIME = 0x000200,
+ LOG_SHOW_DATE = 0x000400,
+ LOG_SHOW_SECONDS = 0x000800,
+ LOG_LONG_DATE = 0x001000,
+ LOG_RELATIVE_DATE = 0x002000,
+ LOG_GROUP_MESSAGES = 0x004000,
+
+ LOG_IMAGE_ENABLED = 0x010000,
+ LOG_IMAGE_SCROLL = 0x020000
+
+ };
+ enum AVATARSERVICEFLAGS {
+ AVATARSERVICE_PRESENT = 0x0001,
+ };
+
+ static void setGeneralFlags(int flags);
+ static int getGeneralFlags();
+ static void setEmbedsize(int size);
+ static int getEmbedsize();
+
+ static bool isMathModule();
+ static bool isSmileyAdd();
+ static int getAvatarServiceFlags();
+ static void init();
+ static void uninit();
+ static void saveProtocolSettings();
+ static void resetProtocolSettings();
+ static ProtocolSettings*getProtocolSettings();
+ static ProtocolSettings*getProtocolSettings(const char *protocolName);
+};
+
+#endif
diff --git a/plugins/IEView/SRMMHTMLBuilder.cpp b/plugins/IEView/SRMMHTMLBuilder.cpp
new file mode 100644
index 0000000000..f142cf3028
--- /dev/null
+++ b/plugins/IEView/SRMMHTMLBuilder.cpp
@@ -0,0 +1,275 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2008 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+#include "SRMMHTMLBuilder.h"
+
+#include "Options.h"
+#include "Utils.h"
+
+// srmm stuff
+#define SMF_LOG_SHOWNICK 1
+#define SMF_LOG_SHOWTIME 2
+#define SMF_LOG_SHOWDATES 4
+#define SMF_LOG_SHOWICONS 8
+#define SMF_LOG_SHOWSTATUSCHANGES 16
+#define SRMMMOD "SRMM"
+
+#define SRMSGSET_SHOWLOGICONS "ShowLogIcon"
+#define SRMSGSET_HIDENAMES "HideNames"
+#define SRMSGSET_SHOWTIME "ShowTime"
+#define SRMSGSET_SHOWDATE "ShowDate"
+#define SRMSGSET_SHOWSTATUSCHANGES "ShowStatusChanges"
+
+#define FONTF_BOLD 1
+#define FONTF_ITALIC 2
+#define FONTF_UNDERLINE 4
+
+#define FONT_NUM 10
+
+static const char *classNames[] = {
+ ".messageOut", ".messageIn", ".nameOut", ".timeOut", ".colonOut", ".nameIn", ".timeIn", ".colonIn",
+ ".inputArea", ".notices"
+};
+
+bool SRMMHTMLBuilder::isDbEventShown(DBEVENTINFO * dbei)
+{
+ switch (dbei->eventType) {
+ case EVENTTYPE_MESSAGE:
+ return 1;
+ case EVENTTYPE_STATUSCHANGE:
+ if (dbei->flags & DBEF_READ) return 0;
+ return 1;
+ }
+ return 0;
+}
+
+void SRMMHTMLBuilder::loadMsgDlgFont(int i, LOGFONTA * lf, COLORREF * colour) {
+ char str[32];
+ int style;
+ DBVARIANT dbv;
+ if (colour) {
+ wsprintfA(str, "SRMFont%dCol", i);
+ *colour = DBGetContactSettingDword(NULL, SRMMMOD, str, 0x000000);
+ }
+ if (lf) {
+ wsprintfA(str, "SRMFont%dSize", i);
+ lf->lfHeight = (char) DBGetContactSettingByte(NULL, SRMMMOD, str, 10);
+ lf->lfHeight = abs(lf->lfHeight);
+ lf->lfWidth = 0;
+ lf->lfEscapement = 0;
+ lf->lfOrientation = 0;
+ wsprintfA(str, "SRMFont%dSty", i);
+ style = DBGetContactSettingByte(NULL, SRMMMOD, str, 0);
+ lf->lfWeight = style & FONTF_BOLD ? FW_BOLD : FW_NORMAL;
+ lf->lfItalic = style & FONTF_ITALIC ? 1 : 0;
+ lf->lfUnderline = style & FONTF_UNDERLINE ? 1 : 0;
+ lf->lfStrikeOut = 0;
+ wsprintfA(str, "SRMFont%dSet", i);
+ lf->lfCharSet = DBGetContactSettingByte(NULL, SRMMMOD, str, DEFAULT_CHARSET);
+ lf->lfOutPrecision = OUT_DEFAULT_PRECIS;
+ lf->lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ lf->lfQuality = DEFAULT_QUALITY;
+ lf->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
+ wsprintfA(str, "SRMFont%d", i);
+ if (DBGetContactSetting(NULL, SRMMMOD, str, &dbv))
+ lstrcpyA(lf->lfFaceName, "Verdana");
+ else {
+ lstrcpynA(lf->lfFaceName, dbv.pszVal, sizeof(lf->lfFaceName));
+ DBFreeVariant(&dbv);
+ }
+ }
+}
+
+char *SRMMHTMLBuilder::timestampToString(DWORD dwFlags, time_t check) {
+ static char szResult[512];
+ char str[80];
+ DBTIMETOSTRING dbtts;
+ dbtts.cbDest = 70;;
+ dbtts.szDest = str;
+ szResult[0] = '\0';
+ if(!(dwFlags & SMF_LOG_SHOWDATES)) {
+ dbtts.szFormat = (char *)"s";
+ }
+ else {
+ dbtts.szFormat = (char *)"d t";
+ }
+ CallService(MS_DB_TIME_TIMESTAMPTOSTRING, check, (LPARAM) & dbtts);
+ strncat(szResult, str, 500);
+ Utils::UTF8Encode(szResult, szResult, 500);
+ return szResult;
+}
+
+
+void SRMMHTMLBuilder::buildHead(IEView *view, IEVIEWEVENT *event) {
+ LOGFONTA lf;
+ COLORREF color;
+ char *output = NULL;
+ int outputSize;
+ ProtocolSettings *protoSettings = getSRMMProtocolSettings(event->hContact);
+ if (protoSettings == NULL) {
+ return;
+ }
+ if (protoSettings->getSRMMMode() == Options::MODE_TEMPLATE) {
+ buildHeadTemplate(view, event);
+ return;
+ }
+ if (protoSettings->getSRMMMode() == Options::MODE_CSS) {
+ const char *externalCSS = (event->dwFlags & IEEF_RTL) ? protoSettings->getSRMMCssFilenameRtl() : protoSettings->getSRMMCssFilename();
+ Utils::appendText(&output, &outputSize, "<html><head><link rel=\"stylesheet\" href=\"%s\"/></head><body class=\"body\">\n",externalCSS);
+ } else {
+ HDC hdc = GetDC(NULL);
+ int logPixelSY = GetDeviceCaps(hdc, LOGPIXELSY);
+ ReleaseDC(NULL, hdc);
+ Utils::appendText(&output, &outputSize, "<html><head><style type=\"text/css\">\n");
+ COLORREF bkgColor = DBGetContactSettingDword(NULL, SRMMMOD, "BkgColour", 0xFFFFFF);
+ COLORREF inColor, outColor;
+ bkgColor= (((bkgColor & 0xFF) << 16) | (bkgColor & 0xFF00) | ((bkgColor & 0xFF0000) >> 16));
+ inColor = outColor = bkgColor;
+ if (protoSettings->getSRMMFlags() & Options::LOG_IMAGE_ENABLED) {
+ Utils::appendText(&output, &outputSize, ".body {margin: 0px; text-align: left; background-attachment: %s; background-color: #%06X; background-image: url('%s'); overflow: auto;}\n",
+ protoSettings->getSRMMFlags() & Options::LOG_IMAGE_SCROLL ? "scroll" : "fixed", (int) bkgColor, protoSettings->getSRMMBackgroundFilename());
+ } else {
+ Utils::appendText(&output, &outputSize, ".body {margin: 0px; text-align: left; background-color: #%06X; overflow: auto;}\n",
+ (int) bkgColor);
+ }
+ Utils::appendText(&output, &outputSize, ".link {color: #0000FF; text-decoration: underline;}\n");
+ Utils::appendText(&output, &outputSize, ".img {vertical-align: middle;}\n");
+ if (protoSettings->getSRMMFlags() & Options::LOG_IMAGE_ENABLED) {
+ Utils::appendText(&output, &outputSize, ".divIn {padding-left: 2px; padding-right: 2px; word-wrap: break-word;}\n");
+ Utils::appendText(&output, &outputSize, ".divOut {padding-left: 2px; padding-right: 2px; word-wrap: break-word;}\n");
+ } else {
+ Utils::appendText(&output, &outputSize, ".divIn {padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #%06X;}\n", (int) inColor);
+ Utils::appendText(&output, &outputSize, ".divOut {padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #%06X;}\n", (int) outColor);
+ }
+ for(int i = 0; i < FONT_NUM; i++) {
+ loadMsgDlgFont(i, &lf, &color);
+ Utils::appendText(&output, &outputSize, "%s {font-family: %s; font-size: %dpt; font-weight: %s; color: #%06X; %s }\n",
+ classNames[i],
+ lf.lfFaceName,
+ abs((signed char)lf.lfHeight) * 74 /logPixelSY ,
+ lf.lfWeight >= FW_BOLD ? "bold" : "normal",
+ (int)(((color & 0xFF) << 16) | (color & 0xFF00) | ((color & 0xFF0000) >> 16)),
+ lf.lfItalic ? "font-style: italic;" : "");
+ }
+ Utils::appendText(&output, &outputSize, "</style></head><body class=\"body\">\n");
+ }
+ if (output != NULL) {
+ view->write(output);
+ free(output);
+ }
+
+}
+
+void SRMMHTMLBuilder::appendEventNonTemplate(IEView *view, IEVIEWEVENT *event) {
+
+ DWORD dwFlags = DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTIME, 0) ? SMF_LOG_SHOWTIME : 0;
+ dwFlags |= !DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_HIDENAMES, 0) ? SMF_LOG_SHOWNICK : 0;
+ dwFlags |= DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWDATE, 0) ? SMF_LOG_SHOWDATES : 0;
+ dwFlags |= DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWLOGICONS, 0) ? SMF_LOG_SHOWICONS : 0;
+ dwFlags |= DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWSTATUSCHANGES, 0) ? SMF_LOG_SHOWSTATUSCHANGES : 0;
+
+ char *szRealProto = getRealProto(event->hContact);
+ IEVIEWEVENTDATA* eventData = event->eventData;
+ for (int eventIdx = 0; eventData!=NULL && (eventIdx < event->count || event->count==-1); eventData = eventData->next, eventIdx++) {
+ int outputSize;
+ char *output;
+ output = NULL;
+ int isSent = eventData->dwFlags & IEEDF_SENT;
+ int isRTL = eventData->dwFlags & IEEDF_RTL;
+ showColon = false;
+
+ if (eventData->iType == IEED_EVENT_MESSAGE || eventData->iType == IEED_EVENT_STATUSCHANGE) {
+ char *szName = NULL;
+ char *szText = NULL;
+ if (eventData->dwFlags & IEEDF_UNICODE_NICK) {
+ szName = encodeUTF8(eventData->pszNickW, szRealProto, ENF_NAMESMILEYS);
+ } else {
+ szName = encodeUTF8(eventData->pszNick, szRealProto, ENF_NAMESMILEYS);
+ }
+ if (eventData->dwFlags & IEEDF_UNICODE_TEXT) {
+ szText = encodeUTF8(eventData->pszTextW, szRealProto, ENF_ALL);
+ } else {
+ szText = encodeUTF8(eventData->pszText, event->codepage, szRealProto, ENF_ALL);
+ }
+
+ /* SRMM-specific formatting */
+ Utils::appendText(&output, &outputSize, "<div class=\"%s\">", isSent ? "divOut" : "divIn");
+ if (dwFlags & SMF_LOG_SHOWICONS) {
+ const char *iconFile = "";
+ if (dbei.eventType == EVENTTYPE_MESSAGE) {
+ iconFile = isSent ? "message_out.gif" : "message_in.gif";
+ } else if (dbei.eventType == EVENTTYPE_STATUSCHANGE) {
+ iconFile = "status.gif";
+ }
+ Utils::appendText(&output, &outputSize, "<img class=\"img\" src=\"%s/plugins/ieview/%s\"/>",
+ workingDir, iconFile);
+ }
+ if (dwFlags & SMF_LOG_SHOWTIME) {
+ const char *className = "";
+ className = isSent ? "timeOut" : "timeIn";
+ if (!(dwFlags & SMF_LOG_SHOWNICK) || (dbei.eventType == EVENTTYPE_STATUSCHANGE)) {
+ const char *className2 = "";
+ className2 = isSent ? "colonOut" : "colonIn";
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">%s</span><span class=\"%s\">: </span>",
+ className, timestampToString(dwFlags, dbei.timestamp), className2);
+ } else {
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">%s </span>",
+ className, timestampToString(dwFlags, dbei.timestamp));
+ }
+ }
+ if (dwFlags & SMF_LOG_SHOWNICK) {
+ if (dbei.eventType == EVENTTYPE_STATUSCHANGE) {
+ Utils::appendText(&output, &outputSize, "<span class=\"notices\">%s </span>", szName);
+ } else {
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">%s</span><span class=\"%s\">: </span>",
+ isSent ? "nameOut" : "nameIn", szName, isSent ? "colonOut" : "colonIn");
+ }
+ }
+ const char *className = "";
+ if (dbei.eventType == EVENTTYPE_MESSAGE) {
+ className = isSent ? "messageOut" : "messageIn";
+ } else if (dbei.eventType == EVENTTYPE_STATUSCHANGE) {
+ className = "notices";
+ }
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">%s</span>", className, szText);
+ Utils::appendText(&output, &outputSize, "</div>\n");
+ event->hDbEventFirst = hCurDbEvent;
+ if (szName!=NULL) delete szName;
+ if (szText!=NULL) delete szText;
+ }
+ if (output != NULL) {
+ view->write(output);
+ free(output);
+ }
+ }
+ if (szRealProto!=NULL) delete szRealProto;
+}
+
+void SRMMHTMLBuilder::appendEvent(IEView *view, IEVIEWEVENT *event) {
+ ProtocolSettings *protoSettings = getSRMMProtocolSettings(event->hContact);
+ if (protoSettings == NULL) {
+ return;
+ }
+ if (protoSettings->getSRMMMode() == Options::MODE_TEMPLATE) {
+ appendEventTemplate(view, event, protoSettings);
+ } else {
+ appendEventNonTemplate(view, event);
+ }
+}
diff --git a/plugins/IEView/SRMMHTMLBuilder.h b/plugins/IEView/SRMMHTMLBuilder.h
new file mode 100644
index 0000000000..801f1a6359
--- /dev/null
+++ b/plugins/IEView/SRMMHTMLBuilder.h
@@ -0,0 +1,40 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2008 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+class SRMMHTMLBuilder;
+
+#ifndef SRMMHTMLBUILDER_INCLUDED
+#define SRMMHTMLBUILDER_INCLUDED
+
+#include "HTMLBuilder.h"
+
+class SRMMHTMLBuilder:public TemplateHTMLBuilder
+{
+protected:
+ virtual void loadMsgDlgFont(int i, LOGFONTA * lf, COLORREF * colour);
+ char *timestampToString(DWORD dwFlags, time_t check);
+ bool isDbEventShown(DBEVENTINFO * dbei);
+ void appendEventNonTemplate(IEView *, IEVIEWEVENT *event);
+public:
+ void buildHead(IEView *, IEVIEWEVENT *event);
+ void appendEvent(IEView *, IEVIEWEVENT *event);
+};
+
+#endif
diff --git a/plugins/IEView/ScriverHTMLBuilder.cpp b/plugins/IEView/ScriverHTMLBuilder.cpp
new file mode 100644
index 0000000000..288d7e7c18
--- /dev/null
+++ b/plugins/IEView/ScriverHTMLBuilder.cpp
@@ -0,0 +1,451 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+#include "ScriverHTMLBuilder.h"
+
+#include "Options.h"
+#include "Utils.h"
+
+// srmm stuff
+#define SMF_LOG_SHOWNICK 1
+#define SMF_LOG_SHOWTIME 2
+#define SMF_LOG_SHOWDATE 4
+#define SMF_LOG_SHOWICONS 8
+#define SMF_LOG_SHOWSTATUSCHANGES 16
+#define SMF_LOG_SHOWSECONDS 32
+#define SMF_LOG_USERELATIVEDATE 64
+#define SMF_LOG_USELONGDATE 128
+#define SMF_LOG_GROUPMESSAGES 256
+#define SMF_LOG_MARKFOLLOWUPS 512
+#define SMF_LOG_MSGONNEWLINE 1024
+#define SMF_LOG_DRAWLINES 2048
+
+#define SRMMMOD "SRMM"
+
+#define SRMSGSET_SHOWLOGICONS "ShowLogIcon"
+#define SRMSGSET_HIDENAMES "HideNames"
+#define SRMSGSET_SHOWTIME "ShowTime"
+#define SRMSGSET_SHOWDATE "ShowDate"
+#define SRMSGSET_SHOWSTATUSCHANGES "ShowStatusChanges"
+#define SRMSGSET_SHOWSECONDS "ShowSeconds"
+#define SRMSGSET_USERELATIVEDATE "UseRelativeDate"
+#define SRMSGSET_USELONGDATE "UseLongDate"
+#define SRMSGSET_GROUPMESSAGES "GroupMessages"
+#define SRMSGSET_MARKFOLLOWUPS "MarkFollowUps"
+#define SRMSGSET_MESSAGEONNEWLINE "MessageOnNewLine"
+#define SRMSGSET_DRAWLINES "DrawLines"
+
+#define FONTF_BOLD 1
+#define FONTF_ITALIC 2
+#define FONTF_UNDERLINE 4
+
+#define FONT_NUM 10
+
+static const char *classNames[] = {
+ ".messageOut", ".messageIn", ".nameOut", ".timeOut", ".colonOut", ".nameIn", ".timeIn", ".colonIn",
+ ".inputArea", ".notices"
+};
+
+ScriverHTMLBuilder::ScriverHTMLBuilder() {
+ setLastEventType(-1);
+ setLastEventTime(time(NULL));
+ startedTime = time(NULL);
+}
+
+bool ScriverHTMLBuilder::isDbEventShown(DBEVENTINFO * dbei)
+{
+ switch (dbei->eventType) {
+ case EVENTTYPE_MESSAGE:
+ return 1;
+ case EVENTTYPE_STATUSCHANGE:
+ // if (dbei->flags & DBEF_READ) return 0;
+ return 1;
+ case EVENTTYPE_URL:
+ return 1;
+ case EVENTTYPE_FILE:
+ return 1;
+ }
+ return 0;
+}
+
+void ScriverHTMLBuilder::loadMsgDlgFont(int i, LOGFONTA * lf, COLORREF * colour) {
+ char str[32];
+ int style;
+ DBVARIANT dbv;
+ if (colour) {
+ wsprintfA(str, "SRMFont%dCol", i);
+ *colour = DBGetContactSettingDword(NULL, SRMMMOD, str, 0x000000);
+ }
+ if (lf) {
+ wsprintfA(str, "SRMFont%dSize", i);
+ lf->lfHeight = (char) DBGetContactSettingByte(NULL, SRMMMOD, str, 10);
+ lf->lfHeight = abs(lf->lfHeight);
+ lf->lfWidth = 0;
+ lf->lfEscapement = 0;
+ lf->lfOrientation = 0;
+ wsprintfA(str, "SRMFont%dSty", i);
+ style = DBGetContactSettingByte(NULL, SRMMMOD, str, 0);
+ lf->lfWeight = style & FONTF_BOLD ? FW_BOLD : FW_NORMAL;
+ lf->lfItalic = style & FONTF_ITALIC ? 1 : 0;
+ lf->lfUnderline = style & FONTF_UNDERLINE ? 1 : 0;
+ lf->lfStrikeOut = 0;
+ wsprintfA(str, "SRMFont%dSet", i);
+ lf->lfCharSet = DBGetContactSettingByte(NULL, SRMMMOD, str, DEFAULT_CHARSET);
+ lf->lfOutPrecision = OUT_DEFAULT_PRECIS;
+ lf->lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ lf->lfQuality = DEFAULT_QUALITY;
+ lf->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
+ wsprintfA(str, "SRMFont%d", i);
+ if (DBGetContactSetting(NULL, SRMMMOD, str, &dbv))
+ lstrcpyA(lf->lfFaceName, "Verdana");
+ else {
+ lstrcpynA(lf->lfFaceName, dbv.pszVal, sizeof(lf->lfFaceName));
+ DBFreeVariant(&dbv);
+ }
+ }
+}
+
+char *ScriverHTMLBuilder::timestampToString(DWORD dwFlags, time_t check, int mode) {
+ static char szResult[512];
+ char str[80];
+ char format[20];
+ DBTIMETOSTRING dbtts;
+
+ szResult[0] = '\0';
+ format[0] = '\0';
+
+ dbtts.cbDest = 70;;
+ dbtts.szDest = str;
+ dbtts.szFormat = format;
+
+ if ((mode == 0 || mode == 1) && (dwFlags & SMF_LOG_SHOWDATE)) {
+ struct tm tm_now, tm_today;
+ time_t now = time(NULL);
+ time_t today;
+ tm_now = *localtime(&now);
+ tm_today = tm_now;
+ tm_today.tm_hour = tm_today.tm_min = tm_today.tm_sec = 0;
+ today = mktime(&tm_today);
+
+ if(dwFlags & SMF_LOG_USERELATIVEDATE && check >= today) {
+ strcpy(szResult, Translate("Today"));
+ if (mode == 0) {
+ strcat(szResult, ",");
+ }
+ } else if(dwFlags & SMF_LOG_USERELATIVEDATE && check > (today - 86400)) {
+ strcpy(szResult, Translate("Yesterday"));
+ if (mode == 0) {
+ strcat(szResult, ",");
+ }
+ } else {
+ if(dwFlags & SMF_LOG_USELONGDATE)
+ strcpy(format, "D");
+ else
+ strcpy(format, "d");
+ }
+ }
+ if (mode == 0 || mode == 2) {
+ if (mode == 0 && (dwFlags & SMF_LOG_SHOWDATE)) {
+ strcat(format, " ");
+ }
+ strcat(format, (dwFlags & SMF_LOG_SHOWSECONDS) ? "s" : "t");
+ }
+ if (format[0] != '\0') {
+// CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, check, (LPARAM) & dbtts);
+ CallService(MS_DB_TIME_TIMESTAMPTOSTRING, check, (LPARAM) & dbtts);
+ //_tcsncat(szResult, str, 500);
+ strncat(szResult, str, 500);
+ }
+ Utils::UTF8Encode(szResult, szResult, 500);
+ return szResult;
+}
+
+
+void ScriverHTMLBuilder::buildHead(IEView *view, IEVIEWEVENT *event) {
+ LOGFONTA lf;
+ COLORREF color;
+ char *output = NULL;
+ int outputSize;
+ ProtocolSettings *protoSettings = getSRMMProtocolSettings(event->hContact);
+ if (protoSettings == NULL) {
+ return;
+ }
+ if (protoSettings->getSRMMMode() == Options::MODE_TEMPLATE) {
+ buildHeadTemplate(view, event, protoSettings);
+ return;
+ }
+ if (protoSettings->getSRMMMode() == Options::MODE_CSS) {
+ const char *externalCSS = protoSettings->getSRMMCssFilename();
+ if (strncmp(externalCSS, "http://", 7)) {
+ Utils::appendText(&output, &outputSize, "<html><head><link rel=\"stylesheet\" href=\"file://%s\"/></head><body class=\"body\">\n", externalCSS);
+ } else {
+ Utils::appendText(&output, &outputSize, "<html><head><link rel=\"stylesheet\" href=\"%s\"/></head><body class=\"body\">\n", externalCSS);
+ }
+ } else {
+ HDC hdc = GetDC(NULL);
+ int logPixelSY = GetDeviceCaps(hdc, LOGPIXELSY);
+ ReleaseDC(NULL, hdc);
+ Utils::appendText(&output, &outputSize, "<html><head>");
+ Utils::appendText(&output, &outputSize, "<style type=\"text/css\">\n");
+ COLORREF bkgColor = DBGetContactSettingDword(NULL, SRMMMOD, "BkgColour", 0xFFFFFF);
+ COLORREF inColor = DBGetContactSettingDword(NULL, SRMMMOD, "IncomingBkgColour", 0xFFFFFF);
+ COLORREF outColor = DBGetContactSettingDword(NULL, SRMMMOD, "OutgoingBkgColour", 0xFFFFFF);
+ COLORREF lineColor = DBGetContactSettingDword(NULL, SRMMMOD, "LineColour", 0xFFFFFF);
+ bkgColor= (((bkgColor & 0xFF) << 16) | (bkgColor & 0xFF00) | ((bkgColor & 0xFF0000) >> 16));
+ inColor= (((inColor & 0xFF) << 16) | (inColor & 0xFF00) | ((inColor & 0xFF0000) >> 16));
+ outColor= (((outColor & 0xFF) << 16) | (outColor & 0xFF00) | ((outColor & 0xFF0000) >> 16));
+ lineColor= (((lineColor & 0xFF) << 16) | (lineColor & 0xFF00) | ((lineColor & 0xFF0000) >> 16));
+ if (protoSettings->getSRMMFlags() & Options::LOG_IMAGE_ENABLED) {
+ Utils::appendText(&output, &outputSize, ".body {padding: 2px; text-align: left; background-attachment: %s; background-color: #%06X; background-image: url('%s'); overflow: auto;}\n",
+ protoSettings->getSRMMFlags() & Options::LOG_IMAGE_SCROLL ? "scroll" : "fixed", (int) bkgColor, protoSettings->getSRMMBackgroundFilename());
+ } else {
+ Utils::appendText(&output, &outputSize, ".body {margin: 0px; text-align: left; background-color: #%06X; overflow: auto;}\n",
+ (int) bkgColor);
+ }
+ Utils::appendText(&output, &outputSize, ".link {color: #0000FF; text-decoration: underline;}\n");
+ Utils::appendText(&output, &outputSize, ".img {}\n");
+ if (protoSettings->getSRMMFlags() & Options::LOG_IMAGE_ENABLED) {
+ Utils::appendText(&output, &outputSize, ".divIn {padding-left: 2px; padding-right: 2px; word-wrap: break-word;}\n");
+ Utils::appendText(&output, &outputSize, ".divOut {padding-left: 2px; padding-right: 2px; word-wrap: break-word;}\n");
+ Utils::appendText(&output, &outputSize, ".divInGrid {padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #%06X}\n", (int) lineColor);
+ Utils::appendText(&output, &outputSize, ".divOutGrid {padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #%06X}\n", (int) lineColor);
+ Utils::appendText(&output, &outputSize, ".divInRTL {text-align: right; direction:RTL; unicode-bidi:embed; padding-left: 2px; padding-right: 2px; word-wrap: break-word;}\n");
+ Utils::appendText(&output, &outputSize, ".divOutRTL {text-align: right; direction:RTL; unicode-bidi:embed; padding-left: 2px; padding-right: 2px; word-wrap: break-word;}\n");
+ Utils::appendText(&output, &outputSize, ".divInGridRTL {text-align: right; direction:RTL; unicode-bidi:embed; padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #%06X}\n", (int) lineColor);
+ Utils::appendText(&output, &outputSize, ".divOutGridRTL {text-align: right; direction:RTL; unicode-bidi:embed; padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #%06X}\n", (int) lineColor);
+ } else {
+ Utils::appendText(&output, &outputSize, ".divIn {padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #%06X;}\n", (int) inColor);
+ Utils::appendText(&output, &outputSize, ".divOut {padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #%06X;}\n", (int) outColor);
+ Utils::appendText(&output, &outputSize, ".divInGrid {padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #%06X; background-color: #%06X;}\n",
+ (int) lineColor, (int) inColor);
+ Utils::appendText(&output, &outputSize, ".divOutGrid {padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #%06X; background-color: #%06X;}\n",
+ (int) lineColor, (int) outColor);
+ Utils::appendText(&output, &outputSize, ".divInRTL {text-align: right; direction:RTL; unicode-bidi:embed; padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #%06X;}\n", (int) inColor);
+ Utils::appendText(&output, &outputSize, ".divOutRTL {text-align: right; direction:RTL; unicode-bidi:embed; padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #%06X;}\n", (int) outColor);
+ Utils::appendText(&output, &outputSize, ".divInGridRTL {text-align: right; direction:RTL; unicode-bidi:embed; padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #%06X; background-color: #%06X;}\n",
+ (int) lineColor, (int) inColor);
+ Utils::appendText(&output, &outputSize, ".divOutGridRTL {text-align: right; direction:RTL; unicode-bidi:embed; padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #%06X; background-color: #%06X;}\n",
+ (int) lineColor, (int) outColor);
+ }
+ Utils::appendText(&output, &outputSize, ".divNotice {padding-left: 2px; padding-right: 2px; word-wrap: break-word;}\n");
+ Utils::appendText(&output, &outputSize, ".divNoticeGrid {padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #%06X}\n", (int) lineColor);
+ Utils::appendText(&output, &outputSize, ".divNoticeRTL {text-align: right; direction:RTL; unicode-bidi:embed; padding-left: 2px; padding-right: 2px; word-wrap: break-word;}\n");
+ Utils::appendText(&output, &outputSize, ".divNoticeGridRTL {text-align: right; direction:RTL; unicode-bidi:embed; padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #%06X}\n", (int) lineColor);
+ for(int i = 0; i < FONT_NUM; i++) {
+ loadMsgDlgFont(i, &lf, &color);
+ Utils::appendText(&output, &outputSize, "%s {font-family: %s; font-size: %dpt; font-weight: %s; color: #%06X; %s }\n",
+ classNames[i],
+ lf.lfFaceName,
+ abs((signed char)lf.lfHeight) * 74 /logPixelSY ,
+ lf.lfWeight >= FW_BOLD ? "bold" : "normal",
+ (int)(((color & 0xFF) << 16) | (color & 0xFF00) | ((color & 0xFF0000) >> 16)),
+ lf.lfItalic ? "font-style: italic;" : "");
+ }
+ Utils::appendText(&output, &outputSize, "</style></head><body class=\"body\">\n");
+ }
+ if (output != NULL) {
+ view->write(output);
+ free(output);
+ }
+ setLastEventType(-1);
+}
+
+void ScriverHTMLBuilder::appendEventNonTemplate(IEView *view, IEVIEWEVENT *event) {
+ bool showColon;
+ DWORD dwFlags = DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTIME, 0) ? SMF_LOG_SHOWTIME : 0;
+ dwFlags |= !DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_HIDENAMES, 0) ? SMF_LOG_SHOWNICK : 0;
+ dwFlags |= DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWDATE, 0) ? SMF_LOG_SHOWDATE : 0;
+ dwFlags |= DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWLOGICONS, 0) ? SMF_LOG_SHOWICONS : 0;
+ dwFlags |= DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWSTATUSCHANGES, 0) ? SMF_LOG_SHOWSTATUSCHANGES : 0;
+ dwFlags |= DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWSECONDS, 0) ? SMF_LOG_SHOWSECONDS : 0;
+ dwFlags |= DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_USERELATIVEDATE, 0) ? SMF_LOG_USERELATIVEDATE : 0;
+ dwFlags |= DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_USELONGDATE, 0) ? SMF_LOG_USELONGDATE : 0;
+ dwFlags |= DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_GROUPMESSAGES, 0) ? SMF_LOG_GROUPMESSAGES : 0;
+ dwFlags |= DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_MARKFOLLOWUPS, 0) ? SMF_LOG_MARKFOLLOWUPS : 0;
+ dwFlags |= DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_MESSAGEONNEWLINE, 0) ? SMF_LOG_MSGONNEWLINE : 0;
+ dwFlags |= DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_DRAWLINES, 0) ? SMF_LOG_DRAWLINES : 0;
+
+ char *szRealProto = getRealProto(event->hContact);
+ IEVIEWEVENTDATA* eventData = event->eventData;
+ for (int eventIdx = 0; eventData!=NULL && (eventIdx < event->count || event->count==-1); eventData = eventData->next, eventIdx++) {
+ const char *className = "";
+ int outputSize;
+ char *output;
+ output = NULL;
+ int isSent = eventData->dwFlags & IEEDF_SENT;
+ int isRTL = eventData->dwFlags & IEEDF_RTL;
+ showColon = false;
+ if (eventData->iType == IEED_EVENT_MESSAGE || eventData->iType == IEED_EVENT_STATUSCHANGE
+ || eventData->iType == IEED_EVENT_URL || eventData->iType == IEED_EVENT_FILE) {
+ int isGroupBreak = TRUE;
+ if ((dwFlags & SMF_LOG_GROUPMESSAGES) && eventData->dwFlags == LOWORD(getLastEventType())
+ && eventData->iType == IEED_EVENT_MESSAGE && HIWORD(getLastEventType()) == IEED_EVENT_MESSAGE
+ && (isSameDate(eventData->time, getLastEventTime()))
+ && (((eventData->time < startedTime) == (getLastEventTime() < startedTime)) || !(eventData->dwFlags & IEEDF_READ))) {
+ isGroupBreak = FALSE;
+ }
+ char *szName = NULL;
+ char *szText = NULL;
+ if (eventData->dwFlags & IEEDF_UNICODE_NICK) {
+ szName = encodeUTF8(event->hContact, szRealProto, eventData->pszNickW, ENF_NAMESMILEYS, true);
+ } else {
+ szName = encodeUTF8(event->hContact, szRealProto, eventData->pszNick, ENF_NAMESMILEYS, true);
+ }
+ if (eventData->dwFlags & IEEDF_UNICODE_TEXT) {
+ szText = encodeUTF8(event->hContact, szRealProto, eventData->pszTextW, eventData->iType == IEED_EVENT_MESSAGE ? ENF_ALL : 0, isSent);
+ } else {
+ szText = encodeUTF8(event->hContact, szRealProto, eventData->pszText, event->codepage, eventData->iType == IEED_EVENT_MESSAGE ? ENF_ALL : 0, isSent);
+ }
+ /* Scriver-specific formatting */
+ if ((dwFlags & SMF_LOG_DRAWLINES) && isGroupBreak && getLastEventType()!=-1) {
+ if (eventData->iType == IEED_EVENT_MESSAGE) {
+ className = isRTL ? isSent ? "divOutGridRTL" : "divInGridRTL" : isSent ? "divOutGrid" : "divInGrid";
+ } else {
+ className = isRTL ? isSent ? "divNoticeGridRTL" : "divNoticeGridRTL" : isSent ? "divNoticeGrid" : "divNoticeGrid";
+ }
+ } else {
+ if (eventData->iType == IEED_EVENT_MESSAGE) {
+ className = isRTL ? isSent ? "divOutRTL" : "divInRTL" : isSent ? "divOut" : "divIn";
+ } else {
+ className = isRTL ? isSent ? "divNoticeRTL" : "divNoticeRTL" : isSent ? "divNotice" : "divNotice";
+ }
+ }
+ Utils::appendText(&output, &outputSize, "<div class=\"%s\">", className);
+ if ((dwFlags & SMF_LOG_SHOWICONS) && isGroupBreak) {
+ const char *iconFile = "";
+ if (eventData->iType == IEED_EVENT_MESSAGE) {
+ iconFile = isSent ? "message_out.gif" : "message_in.gif";
+ } else if (eventData->iType == IEED_EVENT_FILE) {
+ iconFile = "file.gif";
+ } else if (eventData->iType == IEED_EVENT_URL) {
+ iconFile = "url.gif";
+ } else if (eventData->iType == IEED_EVENT_STATUSCHANGE) {
+ iconFile = "status.gif";
+ }
+ Utils::appendIcon(&output, &outputSize, iconFile);
+ }
+
+ if (dwFlags & SMF_LOG_SHOWTIME &&
+ (eventData->iType != IEED_EVENT_MESSAGE ||
+ (dwFlags & SMF_LOG_MARKFOLLOWUPS || isGroupBreak || !(dwFlags & SMF_LOG_GROUPMESSAGES)))) {
+ char* timestampString = NULL;
+ if (dwFlags & SMF_LOG_GROUPMESSAGES) {
+ if (isGroupBreak) {
+ if (!(dwFlags & SMF_LOG_MARKFOLLOWUPS)) {
+ timestampString = timestampToString(dwFlags, eventData->time, 0);
+ } else if (dwFlags & SMF_LOG_SHOWDATE)
+ timestampString = timestampToString(dwFlags, eventData->time, 1);
+ } else if (dwFlags & SMF_LOG_MARKFOLLOWUPS) {
+ timestampString = timestampToString(dwFlags, eventData->time, 2);
+ }
+ } else
+ timestampString = timestampToString(dwFlags, eventData->time, 0);
+ if (timestampString != NULL) {
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">%s</span>",
+ isSent ? "timeOut" : "timeIn",
+ timestampString);
+ }
+ if (eventData->iType != IEED_EVENT_MESSAGE) {
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">: </span>",
+ isSent ? "colonOut" : "colonIn");
+ }
+ showColon = true;
+ }
+ if ((dwFlags & SMF_LOG_SHOWNICK && eventData->iType == IEED_EVENT_MESSAGE && isGroupBreak) || eventData->iType == IEED_EVENT_STATUSCHANGE ) {
+ if (eventData->iType == IEED_EVENT_MESSAGE) {
+ if (showColon) {
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\"> %s</span>",
+ isSent ? "nameOut" : "nameIn",
+ szName);
+ } else {
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">%s</span>",
+ isSent ? "nameOut" : "nameIn",
+ szName);
+ }
+ showColon = true;
+ if (dwFlags & SMF_LOG_GROUPMESSAGES) {
+ Utils::appendText(&output, &outputSize, "<br>");
+ showColon = false;
+ }
+ } else {
+ Utils::appendText(&output, &outputSize, "<span class=\"notices\">%s </span>", szName);
+ }
+ }
+ if (dwFlags & SMF_LOG_SHOWTIME && dwFlags & SMF_LOG_GROUPMESSAGES && dwFlags & SMF_LOG_MARKFOLLOWUPS
+ && eventData->iType == IEED_EVENT_MESSAGE && isGroupBreak) {
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">%s</span>",
+ isSent ? "timeOut" : "timeIn",
+ timestampToString(dwFlags, eventData->time, 2));
+ showColon = true;
+ }
+ if (showColon && eventData->iType == IEED_EVENT_MESSAGE) {
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">: </span>",
+ isSent ? "colonOut" : "colonIn");
+ }
+ if (eventData->iType == IEED_EVENT_MESSAGE) {
+ if (dwFlags & SMF_LOG_MSGONNEWLINE && showColon) {
+ Utils::appendText(&output, &outputSize, "<br>");
+ }
+ className = isSent ? "messageOut" : "messageIn";
+ } else {
+ className = "notices";
+ }
+ if (eventData->iType == IEED_EVENT_FILE) {
+ if (isSent) {
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">%s: %s</span>", className, Translate("File sent"), szText);
+ } else {
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">%s: %s</span>", className, Translate("File received"), szText);
+ }
+ } else if (eventData->iType == IEED_EVENT_URL) {
+ if (isSent) {
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">%s: %s</span>", className, Translate("URL sent"), szText);
+ } else {
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">%s: %s</span>", className, Translate("URL received"), szText);
+ }
+ } else {
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">%s</span>", className, szText);
+ }
+ Utils::appendText(&output, &outputSize, "</div>\n");
+ setLastEventType(MAKELONG(eventData->dwFlags, eventData->iType));
+ setLastEventTime(eventData->time);
+ if (szName!=NULL) delete szName;
+ if (szText!=NULL) delete szText;
+ }
+ if (output != NULL) {
+ view->write(output);
+ free(output);
+ }
+ }
+ if (szRealProto!=NULL) delete szRealProto;
+ view->documentClose();
+// view->scrollToBottom();
+}
+
+void ScriverHTMLBuilder::appendEvent(IEView *view, IEVIEWEVENT *event) {
+ ProtocolSettings *protoSettings = getSRMMProtocolSettings(event->hContact);
+ if (protoSettings == NULL) {
+ return;
+ }
+ if (protoSettings->getSRMMMode() == Options::MODE_TEMPLATE) {
+ appendEventTemplate(view, event, protoSettings);
+ } else {
+ appendEventNonTemplate(view, event);
+ }
+}
diff --git a/plugins/IEView/ScriverHTMLBuilder.h b/plugins/IEView/ScriverHTMLBuilder.h
new file mode 100644
index 0000000000..6652cedafe
--- /dev/null
+++ b/plugins/IEView/ScriverHTMLBuilder.h
@@ -0,0 +1,42 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+class ScriverHTMLBuilder;
+
+#ifndef SCRIVERHTMLBUILDER_INCLUDED
+#define SCRIVERHTMLBUILDER_INCLUDED
+
+#include "TemplateHTMLBuilder.h"
+
+class ScriverHTMLBuilder:public TemplateHTMLBuilder
+{
+protected:
+ void loadMsgDlgFont(int i, LOGFONTA * lf, COLORREF * colour);
+ char *timestampToString(DWORD dwFlags, time_t check, int groupStart);
+ DWORD startedTime;
+ bool isDbEventShown(DBEVENTINFO * dbei);
+ void appendEventNonTemplate(IEView *, IEVIEWEVENT *event);
+public:
+ ScriverHTMLBuilder();
+ void buildHead(IEView *, IEVIEWEVENT *event);
+ void appendEvent(IEView *, IEVIEWEVENT *event);
+};
+
+#endif
diff --git a/plugins/IEView/TabSRMMHTMLBuilder.cpp b/plugins/IEView/TabSRMMHTMLBuilder.cpp
new file mode 100644
index 0000000000..42bc5fc2c7
--- /dev/null
+++ b/plugins/IEView/TabSRMMHTMLBuilder.cpp
@@ -0,0 +1,446 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+#include "TabSRMMHTMLBuilder.h"
+#include "Options.h"
+#include "Utils.h"
+
+// tabsrmm stuff
+
+#define MWF_LOG_SHOWNICK 512
+#define MWF_LOG_SHOWTIME 1024
+#define MWF_LOG_SHOWSECONDS 2048
+#define MWF_LOG_SHOWDATES 4096
+#define MWF_LOG_NEWLINE 8192
+#define MWF_LOG_INDENT 16384
+#define MWF_LOG_RTL 32768
+#define MWF_LOG_UNDERLINE 65536
+#define MWF_LOG_SWAPNICK 131072
+#define MWF_LOG_SHOWICONS 262144
+
+#define MWF_LOG_INDENTWITHTABS 1048576
+#define MWF_LOG_SYMBOLS 0x200000
+#define MWF_LOG_TEXTFORMAT 0x2000000
+#define MWF_LOG_GRID 0x4000000
+#define MWF_LOG_INDIVIDUALBKG 0x8000000
+
+#define MWF_DIVIDERWANTED 0x40000000
+#define MWF_LOG_GROUPMODE 0x80000000
+#define MWF_LOG_LONGDATES 64
+#define MWF_LOG_USERELATIVEDATES 1
+
+#define MWF_SHOW_URLEVENTS 1
+#define MWF_SHOW_FILEEVENTS 2
+#define MWF_SHOW_INOUTICONS 4
+#define MWF_SHOW_EMPTYLINEFIX 8
+#define MWF_SHOW_MICROLF 16
+#define MWF_SHOW_MARKFOLLOWUPTS 32
+
+#define SRMSGMOD "SRMsg"
+#define SRMSGMOD_T "Tab_SRMsg"
+#define TABSRMM_FONTMODULE "TabSRMM_Fonts"
+
+#define EVENTTYPE_DIVIDER 25367
+#define EVENTTYPE_ERRMSG 25366
+
+#define SRMSGSET_SHOWURLS "ShowURLs"
+#define SRMSGSET_SHOWFILES "ShowFiles"
+#define SRMSGSET_SHOWSTATUSCHANGES "ShowFiles"
+
+#define MWF_LOG_DEFAULT (MWF_LOG_SHOWTIME | MWF_LOG_SHOWNICK | MWF_LOG_SHOWDATES)
+
+#define FONTF_BOLD 1
+#define FONTF_ITALIC 2
+#define FONTF_UNDERLINE 4
+
+#define FONT_NUM 19
+
+static const char *classNames[] = {
+ ".messageOut", ".miscOut", ".messageIn", ".miscIn", ".nameOut", ".timeOut", ".nameIn", ".timeIn",
+ ".hMessageOut", ".hMiscOut", ".hMessageIn", ".hMiscIn", ".hNameOut", ".hTimeOut", ".hNameIn", ".hTimeIn",
+ ".inputArea", ".statusChange", ".dividers"
+};
+
+TabSRMMHTMLBuilder::TabSRMMHTMLBuilder() {
+ setLastEventType(-1);
+ setLastEventTime(time(NULL));
+ lastEventTime = time(NULL);
+ startedTime = time(NULL);
+}
+
+bool TabSRMMHTMLBuilder::isDbEventShown(DWORD dwFlags, DBEVENTINFO * dbei)
+{
+ switch (dbei->eventType) {
+ case EVENTTYPE_MESSAGE:
+ return 1;
+ break;
+ case EVENTTYPE_STATUSCHANGE:
+ return 1;
+ break;
+ case EVENTTYPE_URL:
+ if(dwFlags & MWF_SHOW_URLEVENTS) return 1;
+ break;
+ case EVENTTYPE_FILE:
+ if(dwFlags & MWF_SHOW_FILEEVENTS) return 1;
+ break;
+ }
+ return 0;
+}
+
+bool TabSRMMHTMLBuilder::isDbEventShown(DBEVENTINFO * dbei)
+{
+ DWORD dwFlags2 = DBGetContactSettingByte(NULL, SRMSGMOD_T, SRMSGSET_SHOWURLS, 0) ? MWF_SHOW_URLEVENTS : 0;
+ dwFlags2 |= DBGetContactSettingByte(NULL, SRMSGMOD_T, SRMSGSET_SHOWFILES, 0) ? MWF_SHOW_FILEEVENTS : 0;
+ return isDbEventShown(dwFlags2, dbei);
+}
+
+void TabSRMMHTMLBuilder::loadMsgDlgFont(int i, LOGFONTA * lf, COLORREF * colour) {
+ char str[32];
+ int style;
+ DBVARIANT dbv;
+ if (colour) {
+ wsprintfA(str, "Font%dCol", i);
+ *colour = DBGetContactSettingDword(NULL, TABSRMM_FONTMODULE, str, 0x000000);
+ }
+ if (lf) {
+ HDC hdc = GetDC(NULL);
+ wsprintfA(str, "Font%dSize", i);
+// if(i == H_MSGFONTID_DIVIDERS)
+ // lf->lfHeight = 5;
+ // else {
+ lf->lfHeight = (char) DBGetContactSettingByte(NULL, TABSRMM_FONTMODULE, str, 10);
+// lf->lfHeight= MulDiv(lf->lfHeight, GetDeviceCaps(hdc, LOGPIXELSY), 74);
+ // }
+ ReleaseDC(NULL,hdc);
+ lf->lfWidth = 0;
+ lf->lfEscapement = 0;
+ lf->lfOrientation = 0;
+ wsprintfA(str, "Font%dSty", i);
+ style = DBGetContactSettingByte(NULL, TABSRMM_FONTMODULE, str, 0);
+ lf->lfWeight = style & FONTF_BOLD ? FW_BOLD : FW_NORMAL;
+ lf->lfItalic = style & FONTF_ITALIC ? 1 : 0;
+ lf->lfUnderline = style & FONTF_UNDERLINE ? 1 : 0;
+ lf->lfStrikeOut = 0;
+ wsprintfA(str, "Font%dSet", i);
+ lf->lfCharSet = DBGetContactSettingByte(NULL, TABSRMM_FONTMODULE, str, DEFAULT_CHARSET);
+ lf->lfOutPrecision = OUT_DEFAULT_PRECIS;
+ lf->lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ lf->lfQuality = DEFAULT_QUALITY;
+ lf->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
+ wsprintfA(str, "Font%d", i);
+ if (DBGetContactSetting(NULL, TABSRMM_FONTMODULE, str, &dbv))
+ lstrcpyA(lf->lfFaceName, "Verdana");
+ else {
+ lstrcpynA(lf->lfFaceName, dbv.pszVal, sizeof(lf->lfFaceName));
+ DBFreeVariant(&dbv);
+ }
+ }
+}
+
+char *TabSRMMHTMLBuilder::timestampToString(DWORD dwFlags, time_t check, int isGroupBreak)
+{
+ static char szResult[512];
+ char str[80];
+
+ DBTIMETOSTRING dbtts;
+
+ struct tm tm_now, tm_today;
+ time_t now = time(NULL);
+ time_t today;
+
+ dbtts.cbDest = 70;;
+ dbtts.szDest = str;
+
+ if(!isGroupBreak || !(dwFlags & MWF_LOG_SHOWDATES)) {
+ dbtts.szFormat = (dwFlags & MWF_LOG_SHOWSECONDS) ? (char *)"s" : (char *)"t";
+ szResult[0] = '\0';
+ }
+ else {
+ tm_now = *localtime(&now);
+ tm_today = tm_now;
+ tm_today.tm_hour = tm_today.tm_min = tm_today.tm_sec = 0;
+ today = mktime(&tm_today);
+
+ if(dwFlags & MWF_LOG_USERELATIVEDATES && check >= today) {
+ dbtts.szFormat = (dwFlags & MWF_LOG_SHOWSECONDS) ? (char *)"s" : (char *)"t";
+ strcpy(szResult, Translate("Today"));
+ strcat(szResult, ", ");
+ }
+ else if(dwFlags & MWF_LOG_USERELATIVEDATES && check > (today - 86400)) {
+ dbtts.szFormat = (dwFlags & MWF_LOG_SHOWSECONDS) ? (char *)"s" : (char *)"t";
+ strcpy(szResult, Translate("Yesterday"));
+ strcat(szResult, ", ");
+ }
+ else {
+ if(dwFlags & MWF_LOG_LONGDATES)
+ dbtts.szFormat = (dwFlags & MWF_LOG_SHOWSECONDS) ? (char *)"D s" : (char *)"D t";
+ else
+ dbtts.szFormat = (dwFlags & MWF_LOG_SHOWSECONDS) ? (char *)"d s" : (char *)"d t";
+ szResult[0] = '\0';
+ }
+ }
+ CallService(MS_DB_TIME_TIMESTAMPTOSTRING, check, (LPARAM) & dbtts);
+ strncat(szResult, str, 500);
+ Utils::UTF8Encode(szResult, szResult, 500);
+ return szResult;
+}
+
+
+
+void TabSRMMHTMLBuilder::buildHead(IEView *view, IEVIEWEVENT *event) {
+ LOGFONTA lf;
+ COLORREF color;
+ char *output = NULL;
+ int outputSize;
+ ProtocolSettings *protoSettings = getSRMMProtocolSettings(event->hContact);
+ if (protoSettings == NULL) {
+ return;
+ }
+ if (protoSettings->getSRMMMode() == Options::MODE_TEMPLATE) {
+ buildHeadTemplate(view, event, protoSettings);
+ return;
+ }
+ if (protoSettings->getSRMMMode() == Options::MODE_CSS) {
+ const char *externalCSS = protoSettings->getSRMMCssFilename();
+ if (strncmp(externalCSS, "http://", 7)) {
+ Utils::appendText(&output, &outputSize, "<html><head><link rel=\"stylesheet\" href=\"file://%s\"/></head><body class=\"body\">\n", externalCSS);
+ } else {
+ Utils::appendText(&output, &outputSize, "<html><head><link rel=\"stylesheet\" href=\"%s\"/></head><body class=\"body\">\n", externalCSS);
+ }
+ } else {
+ HDC hdc = GetDC(NULL);
+ int logPixelSY = GetDeviceCaps(hdc, LOGPIXELSY);
+ ReleaseDC(NULL, hdc);
+ DWORD dwFlags = DBGetContactSettingDword(NULL, SRMSGMOD_T, "mwflags", MWF_LOG_DEFAULT);
+ Utils::appendText(&output, &outputSize, "<html><head><style type=\"text/css\">\n");
+ COLORREF inColor, outColor;
+ COLORREF bkgColor = DBGetContactSettingDword(NULL, TABSRMM_FONTMODULE, "BkgColour", 0xFFFFFF);
+ bkgColor= (((bkgColor & 0xFF) << 16) | (bkgColor & 0xFF00) | ((bkgColor & 0xFF0000) >> 16));
+ COLORREF gridColor = DBGetContactSettingDword(NULL, TABSRMM_FONTMODULE, "hgrid", 0xFFFFFF);
+ gridColor= (((gridColor & 0xFF) << 16) | (gridColor & 0xFF00) | ((gridColor & 0xFF0000) >> 16));
+ if (dwFlags & MWF_LOG_INDIVIDUALBKG) {
+ inColor = DBGetContactSettingDword(NULL, TABSRMM_FONTMODULE, "inbg", RGB(224,224,224));
+ outColor = DBGetContactSettingDword(NULL, TABSRMM_FONTMODULE, "outbg", RGB(224,224,224));
+ inColor= (((inColor & 0xFF) << 16) | (inColor & 0xFF00) | ((inColor & 0xFF0000) >> 16));
+ outColor= (((outColor & 0xFF) << 16) | (outColor & 0xFF00) | ((outColor & 0xFF0000) >> 16));
+ } else {
+ inColor = outColor = bkgColor;
+ }
+ if (protoSettings->getSRMMFlags() & Options::LOG_IMAGE_ENABLED) {
+ Utils::appendText(&output, &outputSize, ".body {margin: 0px; text-align: left; background-attachment: %s; background-color: #%06X; background-image: url('%s'); overflow: auto;}\n",
+ protoSettings->getSRMMFlags() & Options::LOG_IMAGE_SCROLL ? "scroll" : "fixed", (int) bkgColor, protoSettings->getSRMMBackgroundFilename());
+ } else {
+ Utils::appendText(&output, &outputSize, ".body {margin: 0px; text-align: left; background-color: #%06X; overflow: auto;}\n",
+ (int) bkgColor);
+ }
+ Utils::appendText(&output, &outputSize, ".link {color: #0000FF; text-decoration: underline;}\n");
+ Utils::appendText(&output, &outputSize, ".img {vertical-align: middle;}\n");
+ if (protoSettings->getSRMMFlags() & Options::LOG_IMAGE_ENABLED) {
+ Utils::appendText(&output, &outputSize, ".divIn {padding-left: 2px; padding-right: 2px; word-wrap: break-word;}\n");
+ Utils::appendText(&output, &outputSize, ".divOut {padding-left: 2px; padding-right: 2px; word-wrap: break-word;}\n");
+ Utils::appendText(&output, &outputSize, ".divInGrid {padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #%06X}\n", (int) gridColor);
+ Utils::appendText(&output, &outputSize, ".divOutGrid {padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #%06X}\n", (int) gridColor);
+ Utils::appendText(&output, &outputSize, ".divInRTL {text-align: right; direction:RTL; unicode-bidi:embed; padding-left: 2px; padding-right: 2px; word-wrap: break-word;}\n");
+ Utils::appendText(&output, &outputSize, ".divOutRTL {text-align: right; direction:RTL; unicode-bidi:embed; padding-left: 2px; padding-right: 2px; word-wrap: break-word;}\n");
+ Utils::appendText(&output, &outputSize, ".divInGridRTL {text-align: right; direction:RTL; unicode-bidi:embed; padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #%06X}\n", (int) gridColor);
+ Utils::appendText(&output, &outputSize, ".divOutGridRTL {text-align: right; direction:RTL; unicode-bidi:embed; padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #%06X}\n", (int) gridColor);
+ } else {
+ Utils::appendText(&output, &outputSize, ".divIn {padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #%06X;}\n", (int) inColor);
+ Utils::appendText(&output, &outputSize, ".divOut {padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #%06X;}\n", (int) outColor);
+ Utils::appendText(&output, &outputSize, ".divInGrid {padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #%06X; background-color: #%06X;}\n",
+ (int) gridColor, (int) inColor);
+ Utils::appendText(&output, &outputSize, ".divOutGrid {padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #%06X; background-color: #%06X;}\n",
+ (int) gridColor, (int) outColor);
+ Utils::appendText(&output, &outputSize, ".divInRTL {text-align: right; direction:RTL; unicode-bidi:embed; padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #%06X;}\n", (int) inColor);
+ Utils::appendText(&output, &outputSize, ".divOutRTL {text-align: right; direction:RTL; unicode-bidi:embed; padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #%06X;}\n", (int) outColor);
+ Utils::appendText(&output, &outputSize, ".divInGridRTL {text-align: right; direction:RTL; unicode-bidi:embed; padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #%06X; background-color: #%06X;}\n",
+ (int) gridColor, (int) inColor);
+ Utils::appendText(&output, &outputSize, ".divOutGridRTL {text-align: right; direction:RTL; unicode-bidi:embed; padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #%06X; background-color: #%06X;}\n",
+ (int) gridColor, (int) outColor);
+ }
+ for(int i = 0; i < FONT_NUM; i++) {
+ loadMsgDlgFont(i, &lf, &color);
+ Utils::appendText(&output, &outputSize, "%s {font-family: %s; font-size: %dpt; font-weight: %s; color: #%06X; %s }\n",
+ classNames[i],
+ lf.lfFaceName,
+ abs((signed char)lf.lfHeight) * 74 /logPixelSY ,
+ lf.lfWeight >= FW_BOLD ? "bold" : "normal",
+ (int)(((color & 0xFF) << 16) | (color & 0xFF00) | ((color & 0xFF0000) >> 16)),
+ lf.lfItalic ? "font-style: italic;" : "");
+ }
+ Utils::appendText(&output, &outputSize, "</style></head><body class=\"body\">\n");
+ }
+ if (output != NULL) {
+ view->write(output);
+ free(output);
+ }
+ setLastEventType(-1);
+}
+
+time_t TabSRMMHTMLBuilder::getStartedTime() {
+ return startedTime;
+}
+
+void TabSRMMHTMLBuilder::appendEventNonTemplate(IEView *view, IEVIEWEVENT *event) {
+// int indentLeft = DBGetContactSettingDword(NULL, SRMSGMOD_T, "IndentAmount", 0);
+// int indentRight = DBGetContactSettingDword(NULL, SRMSGMOD_T, "RightIndent", 0);
+ DWORD today = (DWORD)time(NULL);
+ today = today - today % 86400;
+ DWORD dwFlags = DBGetContactSettingDword(NULL, SRMSGMOD_T, "mwflags", MWF_LOG_DEFAULT);
+ DWORD dwFlags2 = DBGetContactSettingByte(NULL, SRMSGMOD_T, SRMSGSET_SHOWURLS, 0) ? MWF_SHOW_URLEVENTS : 0;
+ dwFlags2 |= DBGetContactSettingByte(NULL, SRMSGMOD_T, SRMSGSET_SHOWFILES, 0) ? MWF_SHOW_FILEEVENTS : 0;
+ dwFlags2 |= DBGetContactSettingByte(NULL, SRMSGMOD_T, "in_out_icons", 0) ? MWF_SHOW_INOUTICONS : 0;
+ dwFlags2 |= DBGetContactSettingByte(NULL, SRMSGMOD_T, "emptylinefix", 1) ? MWF_SHOW_EMPTYLINEFIX : 0;
+ dwFlags2 |= MWF_SHOW_MICROLF;
+ dwFlags2 |= DBGetContactSettingByte(NULL, SRMSGMOD_T, "followupts", 1) ? MWF_SHOW_MARKFOLLOWUPTS : 0;
+
+ char *szRealProto = getRealProto(event->hContact);
+ IEVIEWEVENTDATA* eventData = event->eventData;
+ for (int eventIdx = 0; eventData!=NULL && (eventIdx < event->count || event->count==-1); eventData = eventData->next, eventIdx++) {
+ int outputSize;
+ char *output;
+ output = NULL;
+ if (eventData->iType == IEED_EVENT_MESSAGE || eventData->iType == IEED_EVENT_FILE || eventData->iType == IEED_EVENT_URL || eventData->iType == IEED_EVENT_STATUSCHANGE) {
+ int isGroupBreak = TRUE;
+ int isSent = (eventData->dwFlags & IEEDF_SENT);
+ int isRTL = eventData->dwFlags & IEEDF_RTL;
+ int isHistory = (eventData->time < (DWORD)getStartedTime() && (eventData->dwFlags & IEEDF_READ || eventData->dwFlags & IEEDF_SENT));
+ if (dwFlags & MWF_LOG_GROUPMODE && eventData->dwFlags == LOWORD(getLastEventType())
+ && eventData->iType == IEED_EVENT_MESSAGE && HIWORD(getLastEventType()) == IEED_EVENT_MESSAGE
+ && ((eventData->time < today) == (getLastEventTime() < today))
+ && (((eventData->time < (DWORD)startedTime) == (getLastEventTime() < (DWORD)startedTime)) || !(eventData->dwFlags & IEEDF_READ))) {
+ isGroupBreak = FALSE;
+ }
+ char *szName = NULL;
+ char *szText = NULL;
+ if (eventData->dwFlags & IEEDF_UNICODE_NICK) {
+ szName = encodeUTF8(event->hContact, szRealProto, eventData->pszNickW, ENF_NAMESMILEYS, true);
+ } else {
+ szName = encodeUTF8(event->hContact, szRealProto, eventData->pszNick, ENF_NAMESMILEYS, true);
+ }
+ if (eventData->dwFlags & IEEDF_UNICODE_TEXT) {
+ szText = encodeUTF8(event->hContact, szRealProto, eventData->pszTextW, eventData->iType == IEED_EVENT_MESSAGE ? ENF_ALL : 0, isSent);
+ } else {
+ szText = encodeUTF8(event->hContact, szRealProto, eventData->pszText, event->codepage, eventData->iType == IEED_EVENT_MESSAGE ? ENF_ALL : 0, isSent);
+ }
+ /* TabSRMM-specific formatting */
+ if ((dwFlags & MWF_LOG_GRID) && isGroupBreak && getLastEventType()!=-1) {
+ Utils::appendText(&output, &outputSize, "<div class=\"%s\">", isRTL ? isSent ? "divOutGridRTL" : "divInGridRTL" : isSent ? "divOutGrid" : "divInGrid");
+ } else {
+ Utils::appendText(&output, &outputSize, "<div class=\"%s\">", isRTL ? isSent ? "divOutRTL" : "divInRTL" : isSent ? "divOut" : "divIn");
+ }
+ if (dwFlags & MWF_LOG_SHOWICONS && isGroupBreak) {
+ const char *iconFile = "";
+ if (eventData->iType == IEED_EVENT_MESSAGE) {
+ if (dwFlags2 & MWF_SHOW_INOUTICONS) iconFile = isSent ? "message_out.gif" : "message_in.gif";
+ else iconFile = "message.gif";
+ } else if (eventData->iType == IEED_EVENT_FILE) {
+ iconFile = "file.gif";
+ } else if (eventData->iType == IEED_EVENT_URL) {
+ iconFile = "url.gif";
+ } else if (eventData->iType == IEED_EVENT_STATUSCHANGE) {
+ iconFile = "status.gif";
+ }
+ Utils::appendIcon(&output, &outputSize, iconFile);
+ }
+ if ((dwFlags & MWF_LOG_SWAPNICK) && (dwFlags & MWF_LOG_SHOWNICK) && isGroupBreak && (eventData->iType != IEED_EVENT_STATUSCHANGE)) {
+ const char *className = "";
+ if (!isHistory) className = isSent ? "nameOut" : "nameIn";
+ else className = isSent ? "hNameOut" : "hNameIn";
+ if (dwFlags & MWF_LOG_UNDERLINE) {
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\"><u>%s%s</span>",
+ className, szName, (dwFlags & MWF_LOG_SHOWTIME) ? " </u>" :"</u>: ");
+ } else {
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">%s%s</span>",
+ className, szName, (dwFlags & MWF_LOG_SHOWTIME) ? " " :": ");
+ }
+ }
+ if (dwFlags & MWF_LOG_SHOWTIME && (isGroupBreak || dwFlags2 & MWF_SHOW_MARKFOLLOWUPTS)) {
+ const char *className = "";
+ if (!isHistory) className = isSent ? "timeOut" : "timeIn";
+ else className = isSent ? "hTimeOut" : "hTimeIn";
+ if (dwFlags & MWF_LOG_UNDERLINE) {
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\"><u>%s%s</span>",
+ className, timestampToString(dwFlags, eventData->time, isGroupBreak),
+ (!isGroupBreak || (eventData->iType == IEED_EVENT_STATUSCHANGE) || (dwFlags & MWF_LOG_SWAPNICK) || !(dwFlags & MWF_LOG_SHOWNICK)) ? "</u>: " : " </u>");
+ } else {
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">%s%s</span>",
+ className, timestampToString(dwFlags, eventData->time, isGroupBreak),
+ (!isGroupBreak || (eventData->iType == IEED_EVENT_STATUSCHANGE) || (dwFlags & MWF_LOG_SWAPNICK) || !(dwFlags & MWF_LOG_SHOWNICK)) ? ": " : " ");
+ }
+ }
+ if ((eventData->iType == IEED_EVENT_STATUSCHANGE) || ((dwFlags & MWF_LOG_SHOWNICK) && !(dwFlags & MWF_LOG_SWAPNICK) && isGroupBreak)) {
+ if (eventData->iType == IEED_EVENT_STATUSCHANGE) {
+ Utils::appendText(&output, &outputSize, "<span class=\"statusChange\">%s </span>", szName);
+ } else {
+ const char *className = "";
+ if (!isHistory) className = isSent ? "nameOut" : "nameIn";
+ else className = isSent ? "hNameOut" : "hNameIn";
+ if (dwFlags & MWF_LOG_UNDERLINE) {
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\"><u>%s</u>: </span>",
+ className, szName);
+ } else {
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">%s: </span>",
+ className, szName);
+ }
+ }
+ }
+ if (dwFlags & MWF_LOG_NEWLINE && eventData->iType != IEED_EVENT_STATUSCHANGE && eventData->iType != IEED_EVENT_ERRMSG && isGroupBreak) {
+ Utils::appendText(&output, &outputSize, "<br>");
+ }
+ const char *className = "";
+ if (eventData->iType == IEED_EVENT_MESSAGE) {
+ if (!isHistory) className = isSent ? "messageOut" : "messageIn";
+ else className = isSent ? "hMessageOut" : "hMessageIn";
+ } else if (eventData->iType == IEED_EVENT_FILE) {
+ className = isHistory ? "hMiscIn" : "miscIn";
+ } else if (eventData->iType == IEED_EVENT_URL) {
+ className = isHistory ? "hMiscIn" : "miscIn";
+ } else if (eventData->iType == IEED_EVENT_STATUSCHANGE) {
+ className = "statusChange";
+ }
+ Utils::appendText(&output, &outputSize, "<span class=\"%s\">%s</span>", className, szText);
+ Utils::appendText(&output, &outputSize, "</div>\n");
+ setLastEventType(MAKELONG(eventData->dwFlags, eventData->iType));
+ setLastEventTime(eventData->time);
+ if (szName!=NULL) delete szName;
+ if (szText!=NULL) delete szText;
+ }
+ if (output != NULL) {
+ view->write(output);
+ free(output);
+ }
+ }
+ if (szRealProto!=NULL) delete szRealProto;
+ view->documentClose();
+// view->scrollToBottom();
+}
+
+void TabSRMMHTMLBuilder::appendEvent(IEView *view, IEVIEWEVENT *event) {
+ ProtocolSettings *protoSettings = getSRMMProtocolSettings(event->hContact);
+ if (protoSettings == NULL) {
+ return;
+ }
+ if (protoSettings->getSRMMMode() == Options::MODE_TEMPLATE) {
+ appendEventTemplate(view, event, protoSettings);
+ } else {
+ appendEventNonTemplate(view, event);
+ }
+}
diff --git a/plugins/IEView/TabSRMMHTMLBuilder.h b/plugins/IEView/TabSRMMHTMLBuilder.h
new file mode 100644
index 0000000000..5132851369
--- /dev/null
+++ b/plugins/IEView/TabSRMMHTMLBuilder.h
@@ -0,0 +1,45 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+class TabSRMMHTMLBuilder;
+
+#ifndef TABSRMMHTMLBUILDER_INCLUDED
+#define TABSRMMHTMLBUILDER_INCLUDED
+
+#include "TemplateHTMLBuilder.h"
+
+class TabSRMMHTMLBuilder:public TemplateHTMLBuilder
+{
+protected:
+ virtual void loadMsgDlgFont(int i, LOGFONTA * lf, COLORREF * colour);
+ char *timestampToString(DWORD dwFlags, time_t check, int isGroupBreak);
+ time_t startedTime;
+ time_t getStartedTime();
+ virtual bool isDbEventShown(DWORD dwFlags, DBEVENTINFO * dbei);
+ bool isDbEventShown(DBEVENTINFO * dbei);
+ void appendEventNonTemplate(IEView *, IEVIEWEVENT *event);
+public:
+ TabSRMMHTMLBuilder();
+ void buildHead(IEView *, IEVIEWEVENT *event);
+ void appendEvent(IEView *, IEVIEWEVENT *event);
+
+};
+
+#endif
diff --git a/plugins/IEView/Template.cpp b/plugins/IEView/Template.cpp
new file mode 100644
index 0000000000..9d6ce5246e
--- /dev/null
+++ b/plugins/IEView/Template.cpp
@@ -0,0 +1,451 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+#include "Template.h"
+#include "Utils.h"
+
+TokenDef::TokenDef(const char *tokenString) {
+ this->tokenString = tokenString;
+ this->tokenLen = (int)strlen(tokenString);
+ this->token = 0;
+ this->escape = 0;
+}
+
+TokenDef::TokenDef(const char *tokenString, int token, int escape) {
+ this->tokenString = tokenString;
+ this->token = token;
+ this->tokenLen = (int)strlen(tokenString);
+ this->escape = escape;
+}
+
+Token::Token(int type, const char *text, int escape) {
+ next = NULL;
+ this->type = type;
+ this->escape = escape;
+ if (text!=NULL) {
+ this->text = Utils::dupString(text);
+ } else {
+ this->text = NULL;
+ }
+}
+
+Token::~Token() {
+ if (text!=NULL) {
+ delete text;
+ }
+}
+
+Token * Token::getNext() {
+ return next;
+}
+
+void Token::setNext(Token *ptr) {
+ next = ptr;
+}
+
+int Token::getType() {
+ return type;
+}
+
+int Token::getEscape() {
+ return escape;
+}
+
+const char *Token::getText() {
+ return text;
+}
+
+Template::Template(const char *name, const char *text) {
+ next = NULL;
+ tokens = NULL;
+ this->text = Utils::dupString(text);
+ this->name = Utils::dupString(name);
+ tokenize();
+}
+
+Template::~Template() {
+ if (text != NULL) delete text;
+ if (name != NULL) delete name;
+ Token *ptr = tokens, *ptr2;
+ tokens = NULL;
+ for (;ptr!=NULL;ptr = ptr2) {
+ ptr2 = ptr->getNext();
+ delete ptr;
+ }
+}
+
+const char *Template::getText() {
+ return text;
+}
+
+const char *Template::getName() {
+ return name;
+}
+
+Template* Template::getNext() {
+ return next;
+}
+
+bool Template::equals(const char *name) {
+ if (!strcmp(name, this->name)) {
+ return true;
+ }
+ return false;
+}
+
+static TokenDef tokenNames[] = {
+ TokenDef("%name%", Token::NAME, 0),
+ TokenDef("%time%", Token::TIME, 0),
+ TokenDef("%text%", Token::TEXT, 0),
+ TokenDef("%date%", Token::DATE, 0),
+ TokenDef("%base%", Token::BASE, 0),
+ TokenDef("%avatar%", Token::AVATAR, 0),
+ TokenDef("%cid%", Token::CID, 0),
+ TokenDef("%proto%", Token::PROTO, 0),
+ TokenDef("%avatarIn%", Token::AVATARIN, 0),
+ TokenDef("%avatarOut%", Token::AVATAROUT, 0),
+ TokenDef("%nameIn%", Token::NAMEIN, 0),
+ TokenDef("%nameOut%", Token::NAMEOUT, 0),
+ TokenDef("%uin%", Token::UIN, 0),
+ TokenDef("%uinIn%", Token::UININ, 0),
+ TokenDef("%uinOut%", Token::UINOUT, 0),
+ TokenDef("%nickIn%", Token::NICKIN, 0),
+ TokenDef("%nickOut%", Token::NICKOUT, 1),
+ TokenDef("%statusMsg%", Token::STATUSMSG, 0),
+ TokenDef("%fileDesc%", Token::FILEDESC, 0),
+
+ TokenDef("%\\name%", Token::NAME, 1),
+ TokenDef("%\\time%", Token::TIME, 1),
+ TokenDef("%\\text%", Token::TEXT, 1),
+ TokenDef("%\\date%", Token::DATE, 1),
+ TokenDef("%\\base%", Token::BASE, 1),
+ TokenDef("%\\avatar%", Token::AVATAR, 1),
+ TokenDef("%\\cid%", Token::CID, 1),
+ TokenDef("%\\proto%", Token::PROTO, 1),
+ TokenDef("%\\avatarIn%", Token::AVATARIN, 1),
+ TokenDef("%\\avatarOut%", Token::AVATAROUT, 1),
+ TokenDef("%\\nameIn%", Token::NAMEIN, 1),
+ TokenDef("%\\nameOut%", Token::NAMEOUT, 1),
+ TokenDef("%\\uin%", Token::UIN, 1),
+ TokenDef("%\\uinIn%", Token::UININ, 1),
+ TokenDef("%\\uinOut%", Token::UINOUT, 1),
+ TokenDef("%\\nickIn%", Token::NICKIN, 1),
+ TokenDef("%\\nickOut%", Token::NICKOUT, 1),
+ TokenDef("%\\statusMsg%", Token::STATUSMSG, 1),
+ TokenDef("%\\fileDesc%", Token::FILEDESC, 1)
+};
+
+void Template::tokenize() {
+ if (text!=NULL) {
+// debugView->writef("Tokenizing: %s<br>---<br>", text);
+ char *str = Utils::dupString(text);
+ Token *lastToken = NULL;
+ int lastTokenType = Token::PLAIN;
+ int lastTokenEscape = 0;
+ int l = (int)strlen(str);
+ for (int i=0, lastTokenStart=0; i<=l;) {
+ Token *newToken;
+ int newTokenType = 0, newTokenSize = 0, newTokenEscape = 0;
+ if (str[i]=='\0') {
+ newTokenType = Token::END;
+ newTokenSize = 1;
+ newTokenEscape = 0;
+ } else {
+ bool found = false;
+ for (unsigned int j=0; j<(sizeof(tokenNames)/sizeof(tokenNames[0])); j++) {
+ if (!strncmp(str+i, tokenNames[j].tokenString, tokenNames[j].tokenLen)) {
+ newTokenType = tokenNames[j].token;
+ newTokenSize = tokenNames[j].tokenLen;
+ newTokenEscape = tokenNames[j].escape;
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ newTokenType = Token::PLAIN;
+ newTokenSize = 1;
+ newTokenEscape = 0;
+ }
+ }
+ if (newTokenType != Token::PLAIN) {
+ if (str[i + newTokenSize] == '%') {
+ //newTokenSize++;
+ }
+ str[i] = '\0';
+ }
+ if ((lastTokenType!=newTokenType || lastTokenEscape != newTokenEscape) && i!=lastTokenStart) {
+ if (lastTokenType == Token::PLAIN) {
+ newToken = new Token(lastTokenType, str+lastTokenStart, lastTokenEscape);
+ } else {
+ newToken = new Token(lastTokenType, NULL, lastTokenEscape);
+ }
+ if (lastToken != NULL) {
+ lastToken->setNext(newToken);
+ } else {
+ tokens = newToken;
+ }
+ lastToken = newToken;
+ lastTokenStart = i;
+ }
+ lastTokenEscape = newTokenEscape;
+ lastTokenType = newTokenType;
+ i += newTokenSize;
+ }
+ delete str;
+ }
+}
+
+Token * Template::getTokens() {
+ return tokens;
+}
+
+TemplateMap* TemplateMap::mapList = NULL;
+
+TemplateMap::TemplateMap(const char *name) {
+ entries = NULL;
+ next = NULL;
+ filename = NULL;
+ this->name = Utils::dupString(name);
+ this->grouping = false;
+ this->rtl = false;
+}
+
+TemplateMap::~TemplateMap() {
+ if (name != NULL) {
+ delete name;
+ }
+ if (filename != NULL) {
+ delete filename;
+ }
+ clear();
+}
+
+TemplateMap* TemplateMap::add(const char *id, const char *filename) {
+ TemplateMap *map;
+ for (map=mapList; map!=NULL; map=map->next) {
+ if (!strcmp(map->name, id)) {
+ map->clear();
+ map->setFilename(filename);
+ return map;
+ }
+ }
+ map = new TemplateMap(id);
+ map->setFilename(filename);
+ map->next = mapList;
+ mapList = map;
+ return map;
+}
+
+void TemplateMap::addTemplate(const char *name, const char *text) {
+ Template *tmplate = new Template(name, text);
+ tmplate->next = entries;
+ entries = tmplate;
+}
+
+void TemplateMap::clear() {
+ Template *ptr, *ptr2;
+ ptr = entries;
+ entries = NULL;
+ for (;ptr!=NULL;ptr=ptr2) {
+ ptr2 = ptr->getNext();
+ delete ptr;
+ }
+}
+
+static TokenDef templateNames[] = {
+ TokenDef("<!--HTMLStart-->"),
+ TokenDef("<!--MessageIn-->"),
+ TokenDef("<!--MessageOut-->"),
+ TokenDef("<!--hMessageIn-->"),
+ TokenDef("<!--hMessageOut-->"),
+ TokenDef("<!--File-->"),
+ TokenDef("<!--hFile-->"),
+ TokenDef("<!--URL-->"),
+ TokenDef("<!--hURL-->"),
+ TokenDef("<!--Status-->"),
+ TokenDef("<!--hStatus-->"),
+ TokenDef("<!--MessageInGroupStart-->"),
+ TokenDef("<!--MessageInGroupInner-->"),
+ TokenDef("<!--MessageInGroupEnd-->"),
+ TokenDef("<!--hMessageInGroupStart-->"),
+ TokenDef("<!--hMessageInGroupInner-->"),
+ TokenDef("<!--hMessageInGroupEnd-->"),
+ TokenDef("<!--MessageOutGroupStart-->"),
+ TokenDef("<!--MessageOutGroupInner-->"),
+ TokenDef("<!--MessageOutGroupEnd-->"),
+ TokenDef("<!--hMessageOutGroupStart-->"),
+ TokenDef("<!--hMessageOutGroupInner-->"),
+ TokenDef("<!--hMessageOutGroupEnd-->"),
+ TokenDef("<!--FileIn-->"),
+ TokenDef("<!--hFileIn-->"),
+ TokenDef("<!--FileOut-->"),
+ TokenDef("<!--hFileOut-->"),
+ TokenDef("<!--URLIn-->"),
+ TokenDef("<!--hURLIn-->"),
+ TokenDef("<!--URLOut-->"),
+ TokenDef("<!--hURLOut-->"),
+
+ TokenDef("<!--HTMLStartRTL-->"),
+ TokenDef("<!--MessageInRTL-->"),
+ TokenDef("<!--MessageOutRTL-->"),
+ TokenDef("<!--hMessageInRTL-->"),
+ TokenDef("<!--hMessageOutRTL-->"),
+ TokenDef("<!--MessageInGroupStartRTL-->"),
+ TokenDef("<!--MessageInGroupInnerRTL-->"),
+ TokenDef("<!--MessageInGroupEndRTL-->"),
+ TokenDef("<!--hMessageInGroupStartRTL-->"),
+ TokenDef("<!--hMessageInGroupInnerRTL-->"),
+ TokenDef("<!--hMessageInGroupEndRTL-->"),
+ TokenDef("<!--MessageOutGroupStartRTL-->"),
+ TokenDef("<!--MessageOutGroupInnerRTL-->"),
+ TokenDef("<!--MessageOutGroupEndRTL-->"),
+ TokenDef("<!--hMessageOutGroupStartRTL-->"),
+ TokenDef("<!--hMessageOutGroupInnerRTL-->"),
+ TokenDef("<!--hMessageOutGroupEndRTL-->")
+};
+
+
+TemplateMap* TemplateMap::loadTemplateFile(const char *id, const char *filename, bool onlyInfo) {
+ FILE* fh;
+ char lastTemplate[1024], tmp2[1024];
+ unsigned int i=0;
+ TemplateMap *tmap;
+ if (filename == NULL || strlen(filename) == 0) {
+ return NULL;
+ }
+ fh = fopen(filename, "rt");
+ if (fh == NULL) {
+ return NULL;
+ }
+ if (!onlyInfo) {
+ tmap = TemplateMap::add(id, filename);
+ } else {
+ tmap = new TemplateMap(id);
+ }
+ char store[4096];
+ bool wasTemplate = false;
+ char *templateText = NULL;
+ int templateTextSize = 0;
+ while (fgets(store, sizeof(store), fh) != NULL) {
+ if (sscanf(store, "%s", tmp2) == EOF) continue;
+ //template start
+ bool bFound = false;
+ for (unsigned i = 0; i < sizeof(templateNames) / sizeof (templateNames[0]); i++) {
+ if (!strncmp(store, templateNames[i].tokenString, templateNames[i].tokenLen)) {
+ bFound = true;
+ break;
+ }
+ }
+ if (bFound) {
+ if (wasTemplate) {
+ tmap->addTemplate(lastTemplate, templateText);
+ }
+ if (templateText!=NULL) {
+ free (templateText);
+ }
+ templateText = NULL;
+ templateTextSize = 0;
+ wasTemplate = true;
+ sscanf(store, "<!--%[^-]", lastTemplate);
+ } else if (wasTemplate) {
+ Utils::appendText(&templateText, &templateTextSize, "%s", store);
+ }
+ }
+ if (wasTemplate) {
+ tmap->addTemplate(lastTemplate, templateText);
+ }
+ fclose(fh);
+ static const char *groupTemplates[] = {"MessageInGroupStart", "MessageInGroupInner",
+ "hMessageInGroupStart", "hMessageInGroupInner",
+ "MessageOutGroupStart", "MessageOutGroupInner",
+ "hMessageOutGroupStart", "hMessageOutGroupInner"};
+ tmap->grouping = true;
+ for (i = 0; i<SIZEOF(groupTemplates); i++) {
+ if (tmap->getTemplate(groupTemplates[i])== NULL) {
+ tmap->grouping = false;
+ break;
+ }
+ }
+ static const char *rtlTemplates[] = {"MessageInRTL", "MessageOutRTL"}; //"HTMLStartRTL",
+ tmap->rtl = true;
+ for (i=0; i<SIZEOF(rtlTemplates); i++) {
+ if (tmap->getTemplate(rtlTemplates[i])== NULL) {
+ tmap->rtl = false;
+ break;
+ }
+ }
+ return tmap;
+}
+
+bool TemplateMap::isGrouping() {
+ return grouping;
+}
+
+bool TemplateMap::isRTL() {
+ return rtl;
+}
+
+Template* TemplateMap::getTemplate(const char *text) {
+ Template *ptr;
+ for (ptr=entries; ptr!=NULL; ptr=ptr->getNext()) {
+ if (ptr->equals(text)) {
+ break;
+ }
+ }
+ return ptr;
+}
+
+Template* TemplateMap::getTemplate(const char *proto, const char *text) {
+ TemplateMap *ptr;
+ for (ptr=mapList; ptr!=NULL; ptr=ptr->next) {
+ if (!strcmp(ptr->name, proto)) {
+ return ptr->getTemplate(text);
+ }
+ }
+ return NULL;
+}
+
+TemplateMap* TemplateMap::getTemplateMap(const char *proto) {
+ TemplateMap *ptr;
+ for (ptr=mapList; ptr!=NULL; ptr=ptr->next) {
+ if (!strcmp(ptr->name, proto)) {
+ return ptr;
+ }
+ }
+ return NULL;
+}
+
+const char *TemplateMap::getFilename() {
+ return filename;
+}
+
+void TemplateMap::setFilename(const char *filename) {
+ if (this->filename != NULL) {
+ delete this->filename;
+ }
+ this->filename = Utils::dupString(filename);
+ Utils::convertPath(this->filename);
+}
+
+TemplateMap* TemplateMap::loadTemplates(const char *id, const char *filename, bool onlyInfo) {
+ return loadTemplateFile(id, filename, onlyInfo);
+}
+
+
diff --git a/plugins/IEView/Template.h b/plugins/IEView/Template.h
new file mode 100644
index 0000000000..c0ee5f28fe
--- /dev/null
+++ b/plugins/IEView/Template.h
@@ -0,0 +1,124 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+class TemplateMap;
+class Template;
+#ifndef TEMPLATE_INCLUDED
+#define TEMPLATE_INCLUDED
+
+#include "ieview_common.h"
+
+class TokenDef {
+public:
+ const char *tokenString;
+ int token;
+ int tokenLen;
+ int escape;
+ TokenDef(const char *tokenString);
+ TokenDef(const char *tokenString, int token, int escape);
+};
+
+class Token {
+private:
+ int escape;
+ int type;
+ char *text;
+ Token *next;
+public:
+ enum TOKENS {
+ END = 0,
+ BASE,
+ PLAIN,
+ TEXT,
+ NAME,
+ TIME,
+ DATE,
+ AVATAR,
+ CID,
+ PROTO,
+ AVATARIN,
+ AVATAROUT,
+ NAMEIN,
+ NAMEOUT,
+ UIN,
+ UININ,
+ UINOUT,
+ STATUSMSG,
+ NICKIN,
+ NICKOUT,
+ FILEDESC,
+ };
+ Token(int, const char *, int );
+ ~Token();
+ int getType();
+ int getEscape();
+ const char *getText();
+ Token *getNext();
+ void setNext(Token *);
+};
+
+class Template {
+private:
+ char *name;
+ char *text;
+ Template *next;
+ Token *tokens;
+protected:
+ friend class TemplateMap;
+ bool equals(const char *name);
+ void tokenize();
+ Template * getNext();
+ Template(const char *name, const char *text);
+public:
+ ~Template();
+ const char *getText();
+ const char *getName();
+ Token *getTokens();
+};
+
+class TemplateMap {
+private:
+ static TemplateMap *mapList;
+ char * name;
+ char * filename;
+ bool grouping;
+ bool rtl;
+ Template * entries;
+ TemplateMap * next;
+ TemplateMap(const char *name);
+ void addTemplate(const char *name, const char *text);
+ void setFilename(const char *filename);
+ void clear();
+ static TemplateMap* add(const char *id, const char *filename);
+ static void appendText(char **str, int *sizeAlloced, const char *fmt, ...);
+ static TemplateMap* loadTemplateFile(const char *proto, const char *filename, bool onlyInfo);
+public:
+ ~TemplateMap();
+ static Template * getTemplate(const char *id, const char *name);
+ static TemplateMap *getTemplateMap(const char *id);
+ static TemplateMap* loadTemplates(const char *id, const char *filename, bool onlyInfo);
+ Template * getTemplate(const char *text);
+ const char * getFilename();
+ bool isGrouping();
+ bool isRTL();
+};
+
+
+#endif
diff --git a/plugins/IEView/TemplateHTMLBuilder.cpp b/plugins/IEView/TemplateHTMLBuilder.cpp
new file mode 100644
index 0000000000..f5c49bc6b4
--- /dev/null
+++ b/plugins/IEView/TemplateHTMLBuilder.cpp
@@ -0,0 +1,643 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+#include "TemplateHTMLBuilder.h"
+
+#include <io.h>
+#include <fcntl.h>
+#include "Utils.h"
+#include "m_avatars.h"
+
+#define EVENTTYPE_STATUSCHANGE 25368
+
+TemplateHTMLBuilder::TemplateHTMLBuilder() {
+ iLastEventType = -1;
+ startedTime = time(NULL);
+ lastEventTime = time(NULL);
+ groupTemplate = NULL;
+ flashAvatarsTime[0] = time(NULL);
+ flashAvatarsTime[1] = time(NULL);
+ flashAvatars[0] = NULL;
+ flashAvatars[1] = NULL;
+}
+
+TemplateHTMLBuilder::~TemplateHTMLBuilder() {
+ for (int i = 0; i < 2; i++) {
+ if (flashAvatars[i] != NULL) {
+ delete flashAvatars[i];
+ }
+ }
+}
+
+char *TemplateHTMLBuilder::getAvatar(HANDLE hContact, const char * szProto) {
+ DBVARIANT dbv;
+ TCHAR tmpPath[MAX_PATH];
+ TCHAR *result = NULL;
+
+ if (Options::getAvatarServiceFlags() == Options::AVATARSERVICE_PRESENT) {
+ struct avatarCacheEntry *ace = NULL;
+ if (hContact == NULL) {
+ ace = (struct avatarCacheEntry *)CallService(MS_AV_GETMYAVATAR, (WPARAM)0, (LPARAM)szProto);
+ } else {
+ ace = (struct avatarCacheEntry *)CallService(MS_AV_GETAVATARBITMAP, (WPARAM)hContact, (LPARAM)0);
+ }
+ if (ace!=NULL) {
+ if ( ace->cbSize == sizeof(avatarCacheEntry))
+ result = ace->szFilename;
+ else {
+ // compatibility: in M0.9 it will always be char*
+ #if defined( _UNICODE )
+ MultiByteToWideChar( CP_ACP, 0, (char*)ace->szFilename, -1, tmpPath, SIZEOF(tmpPath));
+ #endif
+ }
+ }
+ }
+ if (!DBGetContactSettingTString(hContact, "ContactPhoto", "File", &dbv)) {
+ if (_tcslen(dbv.ptszVal) > 0) {
+ TCHAR* ext = _tcsrchr(dbv.ptszVal, '.');
+ if (ext && lstrcmpi(ext, _T(".xml")) == 0) {
+ result = ( TCHAR* )getFlashAvatar(dbv.ptszVal, (hContact == NULL) ? 1 : 0);
+ } else {
+ if (result == NULL) {
+ /* relative -> absolute */
+ _tcscpy (tmpPath, dbv.ptszVal);
+ if (ServiceExists(MS_UTILS_PATHTOABSOLUTET) && _tcsncmp(tmpPath, _T("http://"), 7))
+ CallService(MS_UTILS_PATHTOABSOLUTET, (WPARAM)dbv.ptszVal, (LPARAM)tmpPath);
+
+ result = tmpPath;
+ }
+ }
+ }
+ DBFreeVariant(&dbv);
+ }
+ char* res = Utils::UTF8Encode(result);
+ Utils::convertPath(res);
+ return res;
+}
+
+const char *TemplateHTMLBuilder::getFlashAvatar(const TCHAR *file, int index) {
+ if (time(NULL) - flashAvatarsTime[index] > 600 || flashAvatars[index] == NULL) {
+ if (flashAvatars[index] != NULL) {
+ delete flashAvatars[index];
+ flashAvatars[index] = NULL;
+ }
+ flashAvatarsTime[index] = time(NULL);
+ int src = _topen(file, _O_BINARY | _O_RDONLY);
+ if (src != -1) {
+ char pBuf[2048];
+ char *urlBuf;
+ _read(src, pBuf, 2048);
+ _close(src);
+ urlBuf = strstr(pBuf, "<URL>");
+ if(urlBuf) {
+ flashAvatars[index] = Utils::dupString(strtok(urlBuf + 5, "<\t\n\r"));
+ }
+ }
+ }
+ return flashAvatars[index];
+}
+
+TemplateMap *TemplateHTMLBuilder::getTemplateMap(ProtocolSettings * protoSettings) {
+ return TemplateMap::getTemplateMap(protoSettings->getSRMMTemplateFilename());
+}
+
+int TemplateHTMLBuilder::getFlags(ProtocolSettings * protoSettings) {
+ return protoSettings->getSRMMFlags();
+}
+
+char *TemplateHTMLBuilder::timestampToString(DWORD dwFlags, time_t check, int mode) {
+ static char szResult[512];
+ char str[80];
+ DBTIMETOSTRING dbtts;
+ dbtts.cbDest = 70;
+ dbtts.szDest = str;
+ szResult[0] = '\0';
+ if (mode) { //time
+ dbtts.szFormat = (dwFlags & Options::LOG_SHOW_SECONDS) ? (char *)"s" : (char *)"t";
+ CallService(MS_DB_TIME_TIMESTAMPTOSTRING, check, (LPARAM) & dbtts);
+ strncat(szResult, str, 500);
+ } else {//date
+ struct tm tm_now, tm_today;
+ time_t now = time(NULL);
+ time_t today;
+ tm_now = *localtime(&now);
+ tm_today = tm_now;
+ tm_today.tm_hour = tm_today.tm_min = tm_today.tm_sec = 0;
+ today = mktime(&tm_today);
+ if (dwFlags & Options::LOG_RELATIVE_DATE && check >= today) {
+ strcpy(szResult, Translate("Today"));
+ } else if(dwFlags & Options::LOG_RELATIVE_DATE && check > (today - 86400)) {
+ strcpy(szResult, Translate("Yesterday"));
+ } else {
+ dbtts.szFormat = (dwFlags & Options::LOG_LONG_DATE) ? (char *)"D" : (char *)"d";
+ CallService(MS_DB_TIME_TIMESTAMPTOSTRING, check, (LPARAM) & dbtts);
+ strncat(szResult, str, 500);
+ }
+ }
+ Utils::UTF8Encode(szResult, szResult, 500);
+ return szResult;
+}
+
+void TemplateHTMLBuilder::buildHeadTemplate(IEView *view, IEVIEWEVENT *event, ProtocolSettings *protoSettings) {
+ DBVARIANT dbv;
+ CONTACTINFO ci;
+ char tempBase[1024];
+ char tempStr[1024];
+ HANDLE hRealContact;
+ char *szRealProto = NULL;
+ char *szBase=NULL;
+ char *szNoAvatar=NULL;
+ char *szProto = NULL;
+ char *szNameIn = NULL;
+ char *szNameOut = NULL;
+ char *szAvatarIn = NULL;
+ char *szAvatarOut = NULL;
+ char *szUINIn = NULL;
+ char *szUINOut = NULL;
+ char *szNickIn = NULL;
+ char *szNickOut = NULL;
+ char *szStatusMsg = NULL;
+ int outputSize;
+ char *output;
+
+ output = NULL;
+ hRealContact = getRealContact(event->hContact);
+ szRealProto = getProto(hRealContact);
+ szProto = getProto(event->pszProto, event->hContact);
+ tempBase[0]='\0';
+ if (protoSettings == NULL)
+ return;
+
+ TemplateMap *tmpm = getTemplateMap(protoSettings);
+ if (tmpm==NULL)
+ return;
+
+ strcpy(tempBase, "file://");
+ strcat(tempBase, tmpm->getFilename());
+ char* pathrun = tempBase + strlen(tempBase);
+ while ((*pathrun != '\\' && *pathrun != '/') && (pathrun > tempBase)) pathrun--;
+ pathrun++;
+ *pathrun = '\0';
+
+ szBase = Utils::UTF8Encode(tempBase);
+ getUINs(event->hContact, szUINIn, szUINOut);
+ if (getFlags(protoSettings) & Options::LOG_SHOW_NICKNAMES) {
+ szNameOut = getEncodedContactName(NULL, szProto, szRealProto);
+ szNameIn = getEncodedContactName(event->hContact, szProto, szRealProto);
+ } else {
+ szNameOut = Utils::dupString("&nbsp;");
+ szNameIn = Utils::dupString("&nbsp;");
+ }
+ sprintf(tempStr, "%snoavatar.jpg", tempBase);
+ szNoAvatar = Utils::UTF8Encode(tempStr);
+ szAvatarIn = getAvatar(event->hContact, szRealProto);
+ if (szAvatarIn == NULL) {
+ szAvatarIn = Utils::dupString(szNoAvatar);
+ }
+ szAvatarOut = getAvatar(NULL, szRealProto);
+ if (szAvatarOut == NULL) {
+ szAvatarOut = Utils::dupString(szNoAvatar);
+ }
+ if (!DBGetContactSetting(event->hContact, "CList", "StatusMsg",&dbv)) {
+ if (strlen(dbv.pszVal) > 0) {
+ szStatusMsg = Utils::UTF8Encode(dbv.pszVal);
+ }
+ DBFreeVariant(&dbv);
+ }
+ ZeroMemory(&ci, sizeof(ci));
+ ci.cbSize = sizeof(ci);
+ ci.hContact = event->hContact;
+ ci.szProto = szProto;
+ ci.dwFlag = CNF_NICK | CNF_TCHAR;
+ if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) {
+ szNickIn = encodeUTF8(event->hContact, szRealProto, ci.pszVal, ENF_NAMESMILEYS, true);
+ }
+ ZeroMemory(&ci, sizeof(ci));
+ ci.cbSize = sizeof(ci);
+ ci.hContact = NULL;
+ ci.szProto = szProto;
+ ci.dwFlag = CNF_NICK | CNF_TCHAR;
+ if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) {
+ szNickOut = encodeUTF8(event->hContact, szRealProto, ci.pszVal, ENF_NAMESMILEYS, true);
+ }
+
+ Template *tmplt = tmpm->getTemplate(((event->dwFlags & IEEF_RTL) && tmpm->isRTL()) ? "HTMLStartRTL" : "HTMLStart");
+ if (tmplt == NULL) {
+ tmplt = tmpm->getTemplate("HTMLStart");
+ }
+ if (tmplt!=NULL) {
+ for (Token *token = tmplt->getTokens();token!=NULL;token=token->getNext()) {
+ const char *tokenVal;
+ tokenVal = NULL;
+ switch (token->getType()) {
+ case Token::PLAIN:
+ tokenVal = token->getText();
+ break;
+ case Token::BASE:
+ tokenVal = szBase;
+ break;
+ case Token::NAMEIN:
+ tokenVal = szNameIn;
+ break;
+ case Token::NAMEOUT:
+ tokenVal = szNameOut;
+ break;
+ case Token::AVATARIN:
+ tokenVal = szAvatarIn;
+ break;
+ case Token::AVATAROUT:
+ tokenVal = szAvatarOut;
+ break;
+ case Token::PROTO:
+ tokenVal = szRealProto;
+ break;
+ case Token::UININ:
+ tokenVal = szUINIn;
+ break;
+ case Token::UINOUT:
+ tokenVal = szUINOut;
+ break;
+ case Token::STATUSMSG:
+ tokenVal = szStatusMsg;
+ break;
+ case Token::NICKIN:
+ tokenVal = szNickIn;
+ break;
+ case Token::NICKOUT:
+ tokenVal = szNickOut;
+ break;
+ }
+ if (tokenVal != NULL) {
+ if (token->getEscape()) {
+ char *escapedToken = Utils::escapeString(tokenVal);
+ Utils::appendText(&output, &outputSize, "%s", escapedToken);
+ delete escapedToken;
+ } else {
+ Utils::appendText(&output, &outputSize, "%s", tokenVal);
+ }
+ }
+ }
+ }
+ if (output != NULL) {
+ view->write(output);
+ free(output);
+ }
+ if (szBase!=NULL) delete szBase;
+ if (szRealProto!=NULL) delete szRealProto;
+ if (szProto!=NULL) delete szProto;
+ if (szUINIn!=NULL) delete szUINIn;
+ if (szUINOut!=NULL) delete szUINOut;
+ if (szNoAvatar!=NULL) delete szNoAvatar;
+ if (szAvatarIn!=NULL) delete szAvatarIn;
+ if (szAvatarOut!=NULL) delete szAvatarOut;
+ if (szNameIn!=NULL) delete szNameIn;
+ if (szNameOut!=NULL) delete szNameOut;
+ if (szNickIn!=NULL) delete szNickIn;
+ if (szNickOut!=NULL) delete szNickOut;
+ if (szStatusMsg!=NULL) delete szStatusMsg;
+ //view->scrollToBottom();
+ groupTemplate = NULL;
+ iLastEventType = -1;
+}
+
+void TemplateHTMLBuilder::appendEventTemplate(IEView *view, IEVIEWEVENT *event, ProtocolSettings* protoSettings) {
+ DBVARIANT dbv;
+ CONTACTINFO ci;
+ HANDLE hRealContact;
+ char *szRealProto = NULL;
+ char tempBase[1024];
+ char *szBase=NULL;
+ char tempStr[1024];
+ char *szNoAvatar=NULL;
+ char szCID[32];
+ char *szName = NULL;
+ char *szNameIn = NULL;
+ char *szNameOut = NULL;
+ char *szUIN = NULL;
+ char *szUINIn = NULL;
+ char *szUINOut = NULL;
+ char *szNickIn = NULL;
+ char *szNickOut = NULL;
+ char *szStatusMsg = NULL;
+ char *szAvatar = NULL;
+ char *szAvatarIn = NULL;
+ char *szAvatarOut = NULL;
+ char *szText = NULL;
+ char *szProto = NULL;
+ char *szFileDesc = NULL;
+ const char *tmpltName[2];
+ bool isGrouping = false;
+// DWORD today = (DWORD)time(NULL);
+// today = today - today % 86400;
+ if (protoSettings == NULL) {
+ return;
+ }
+ hRealContact = getRealContact(event->hContact);
+ szRealProto = getProto(hRealContact);
+ szProto = getProto(event->pszProto, event->hContact);
+ tempBase[0]='\0';
+ TemplateMap *tmpm = getTemplateMap(protoSettings);
+ if (tmpm!=NULL) {
+ strcpy(tempBase, "file://");
+ strcat(tempBase, tmpm->getFilename());
+ char* pathrun = tempBase + strlen(tempBase);
+ while ((*pathrun != '\\' && *pathrun != '/') && (pathrun > tempBase)) pathrun--;
+ pathrun++;
+ *pathrun = '\0';
+ isGrouping = tmpm->isGrouping();
+ }
+ szBase = Utils::UTF8Encode(tempBase);
+
+ if (event->hContact != NULL) {
+ getUINs(event->hContact, szUINIn, szUINOut);
+ }
+
+ if (event->hContact != NULL) {
+ szNameOut = getEncodedContactName(NULL, szProto, szRealProto);
+ szNameIn = getEncodedContactName(event->hContact, szProto, szRealProto);
+ } else {
+ szNameOut = Utils::dupString("&nbsp;");
+ szNameIn = Utils::dupString("&nbsp;");
+ }
+ sprintf(tempStr, "%snoavatar.jpg", tempBase);
+ szNoAvatar = Utils::UTF8Encode(tempStr);
+
+ if(event->hContact != NULL) {
+ szAvatarIn = getAvatar(event->hContact, szRealProto);
+ }
+ if (szAvatarIn == NULL) {
+ szAvatarIn = Utils::dupString(szNoAvatar);
+ }
+ szAvatarOut = getAvatar(NULL, szRealProto);
+ if (szAvatarOut == NULL) {
+ szAvatarOut = Utils::dupString(szNoAvatar);
+ }
+ if(event->hContact != NULL) {
+ if (!DBGetContactSetting(event->hContact, "CList", "StatusMsg",&dbv)) {
+ if (strlen(dbv.pszVal) > 0) {
+ szStatusMsg = Utils::UTF8Encode(dbv.pszVal);
+ }
+ DBFreeVariant(&dbv);
+ }
+ }
+ ZeroMemory(&ci, sizeof(ci));
+ ci.cbSize = sizeof(ci);
+ ci.hContact = event->hContact;
+ ci.szProto = szProto;
+ ci.dwFlag = CNF_NICK | CNF_TCHAR;
+ if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) {
+ szNickIn = encodeUTF8(event->hContact, szRealProto, ci.pszVal, ENF_NAMESMILEYS, true);
+ }
+ ZeroMemory(&ci, sizeof(ci));
+ ci.cbSize = sizeof(ci);
+ ci.hContact = NULL;
+ ci.szProto = szProto;
+ ci.dwFlag = CNF_NICK | CNF_TCHAR;
+ if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) {
+ szNickOut = encodeUTF8(event->hContact, szRealProto, ci.pszVal, ENF_NAMESMILEYS, true);
+ }
+ IEVIEWEVENTDATA* eventData = event->eventData;
+ for (int eventIdx = 0; eventData!=NULL && (eventIdx < event->count || event->count==-1); eventData = eventData->next, eventIdx++) {
+ int outputSize;
+ char *output;
+ output = NULL;
+ if (eventData->iType == IEED_EVENT_MESSAGE || eventData->iType == IEED_EVENT_STATUSCHANGE || eventData->iType == IEED_EVENT_FILE || eventData->iType == IEED_EVENT_URL || eventData->iType == IEED_EVENT_SYSTEM) {
+ int isSent = (eventData->dwFlags & IEEDF_SENT);
+ int isRTL = (eventData->dwFlags & IEEDF_RTL) && tmpm->isRTL();
+ int isHistory = (eventData->time < (DWORD)getStartedTime() && (eventData->dwFlags & IEEDF_READ || eventData->dwFlags & IEEDF_SENT));
+ int isGroupBreak = TRUE;
+ if ((getFlags(protoSettings) & Options::LOG_GROUP_MESSAGES) && eventData->dwFlags == LOWORD(getLastEventType())
+ && eventData->iType == IEED_EVENT_MESSAGE && HIWORD(getLastEventType()) == IEED_EVENT_MESSAGE
+ && (isSameDate(eventData->time, getLastEventTime()))
+// && ((eventData->time < today) == (getLastEventTime() < today))
+ && (((eventData->time < (DWORD)startedTime) == (getLastEventTime() < (DWORD)startedTime)) || !(eventData->dwFlags & IEEDF_READ))) {
+ isGroupBreak = FALSE;
+ }
+ if (isSent) {
+ szAvatar = szAvatarOut;
+ szUIN = szUINOut;
+ sprintf(szCID, "%d", 0);
+ } else {
+ szAvatar = szAvatarIn;
+ szUIN = szUINIn;
+ sprintf(szCID, "%d", (int)event->hContact);
+ }
+ tmpltName[0] = groupTemplate;
+ tmpltName[1] = NULL;
+ groupTemplate = NULL;
+ szName = NULL;
+ szText = NULL;
+ szFileDesc = NULL;
+ if (event->eventData->dwFlags & IEEDF_UNICODE_NICK) {
+ szName = encodeUTF8(event->hContact, szRealProto, eventData->pszNickW, ENF_NAMESMILEYS, true);
+ } else {
+ szName = encodeUTF8(event->hContact, szRealProto, eventData->pszNick, ENF_NAMESMILEYS, true);
+ }
+ if (eventData->dwFlags & IEEDF_UNICODE_TEXT) {
+ szText = encodeUTF8(event->hContact, szRealProto, eventData->pszTextW, eventData->iType == IEED_EVENT_MESSAGE ? ENF_ALL : 0, isSent);
+ } else {
+ szText = encodeUTF8(event->hContact, szRealProto, eventData->pszText, event->codepage, eventData->iType == IEED_EVENT_MESSAGE ? ENF_ALL : 0, isSent);
+ }
+ if (eventData->dwFlags & IEEDF_UNICODE_TEXT2) {
+ szFileDesc = encodeUTF8(event->hContact, szRealProto, eventData->pszText2W, 0, isSent);
+ } else {
+ szFileDesc = encodeUTF8(event->hContact, szRealProto, eventData->pszText2, event->codepage, 0, isSent);
+ }
+ if ((eventData->iType == IEED_EVENT_MESSAGE)) {
+ if (!isRTL) {
+ if (isGrouping && (getFlags(protoSettings) & Options::LOG_GROUP_MESSAGES)) {
+ if (isGroupBreak) {
+ tmpltName[1] = isHistory ? isSent ? "hMessageOutGroupStart" : "hMessageInGroupStart" : isSent ? "MessageOutGroupStart" : "MessageInGroupStart";
+ } else {
+ tmpltName[0] = isHistory ? isSent ? "hMessageOutGroupInner" : "hMessageInGroupInner" : isSent ? "MessageOutGroupInner" : "MessageInGroupInner";
+ }
+ groupTemplate = isHistory ? isSent ? "hMessageOutGroupEnd" : "hMessageInGroupEnd" : isSent ? "MessageOutGroupEnd" : "MessageInGroupEnd";
+ } else {
+ tmpltName[1] = isHistory ? isSent ? "hMessageOut" : "hMessageIn" : isSent ? "MessageOut" : "MessageIn";
+ }
+ } else {
+ if (isGrouping && (getFlags(protoSettings) & Options::LOG_GROUP_MESSAGES)) {
+ if (isGroupBreak) {
+ tmpltName[1] = isHistory ? isSent ? "hMessageOutGroupStartRTL" : "hMessageInGroupStartRTL" : isSent ? "MessageOutGroupStartRTL" : "MessageInGroupStartRTL";
+ } else {
+ tmpltName[0] = isHistory ? isSent ? "hMessageOutGroupInnerRTL" : "hMessageInGroupInnerRTL" : isSent ? "MessageOutGroupInnerRTL" : "MessageInGroupInnerRTL";
+ }
+ groupTemplate = isHistory ? isSent ? "hMessageOutGroupEndRTL" : "hMessageInGroupEndRTL" : isSent ? "MessageOutGroupEndRTL" : "MessageInGroupEndRTL";
+ } else {
+ tmpltName[1] = isHistory ? isSent ? "hMessageOutRTL" : "hMessageInRTL" : isSent ? "MessageOutRTL" : "MessageInRTL";
+ }
+ }
+ } else if (eventData->iType == IEED_EVENT_FILE) {
+ tmpltName[1] = isHistory ? isSent ? "hFileOut" : "hFileIn" : isSent ? "FileOut" : "FileIn";
+ Template *tmplt = tmpm->getTemplate(tmpltName[1]);
+ if (tmplt == NULL) {
+ tmpltName[1] = isHistory ? "hFile" : "File";
+ }
+ } else if (eventData->iType == IEED_EVENT_URL) {
+ tmpltName[1] = isHistory ? isSent ? "hURLOut" : "hURLIn" : isSent ? "URLOut" : "URLIn";
+ Template *tmplt = tmpm->getTemplate(tmpltName[1]);
+ if (tmplt == NULL) {
+ tmpltName[1] = isHistory ? "hURL" : "URL";
+ }
+ } else if (eventData->iType == IEED_EVENT_STATUSCHANGE || (eventData->iType == IEED_EVENT_SYSTEM)) {
+ tmpltName[1] = isHistory ? "hStatus" : "Status";
+ }
+ /* template-specific formatting */
+ for (int i=0;i<2;i++) {
+ Template *tmplt;
+ if (tmpltName[i] == NULL) continue;
+ tmplt = tmpm->getTemplate(tmpltName[i]);
+ if (tmplt == NULL) continue;
+ for (Token *token = tmplt->getTokens();token!=NULL;token=token->getNext()) {
+ const char *tokenVal;
+ tokenVal = NULL;
+ switch (token->getType()) {
+ case Token::PLAIN:
+ tokenVal = token->getText();
+ break;
+ case Token::NAME:
+ if (getFlags(protoSettings) & Options::LOG_SHOW_NICKNAMES) {
+ tokenVal = szName;
+ } else {
+ tokenVal = "&nbsp;";
+ }
+ break;
+ case Token::TIME:
+ if (getFlags(protoSettings) & Options::LOG_SHOW_TIME) {
+ tokenVal = timestampToString(getFlags(protoSettings), eventData->time, 1);
+ } else {
+ tokenVal = "&nbsp;";
+ }
+ break;
+ case Token::DATE:
+ if (getFlags(protoSettings) & Options::LOG_SHOW_DATE) {
+ tokenVal = timestampToString(getFlags(protoSettings), eventData->time, 0);
+ } else {
+ tokenVal = "&nbsp;";
+ }
+ break;
+ case Token::TEXT:
+ tokenVal = szText;
+ break;
+ case Token::AVATAR:
+ tokenVal = szAvatar;
+ break;
+ case Token::CID:
+ tokenVal = szCID;
+ break;
+ case Token::BASE:
+ tokenVal = szBase;
+ break;
+ case Token::NAMEIN:
+ if (getFlags(protoSettings) & Options::LOG_SHOW_NICKNAMES) {
+ if (event->hContact != NULL) {
+ tokenVal = szNameIn;
+ } else {
+ tokenVal = szName;
+ }
+ } else {
+ tokenVal = "&nbsp;";
+ }
+ break;
+ case Token::NAMEOUT:
+ if (getFlags(protoSettings) & Options::LOG_SHOW_NICKNAMES) {
+ if (event->hContact != NULL) {
+ tokenVal = szNameOut;
+ } else {
+ tokenVal = szName;
+ }
+ } else {
+ tokenVal = "&nbsp;";
+ }
+ break;
+ case Token::AVATARIN:
+ tokenVal = szAvatarIn;
+ break;
+ case Token::AVATAROUT:
+ tokenVal = szAvatarOut;
+ break;
+ case Token::PROTO:
+ tokenVal = szRealProto;
+ break;
+ case Token::UIN:
+ tokenVal = szUIN;
+ break;
+ case Token::UININ:
+ tokenVal = szUINIn;
+ break;
+ case Token::UINOUT:
+ tokenVal = szUINOut;
+ break;
+ case Token::STATUSMSG:
+ tokenVal = szStatusMsg;
+ break;
+ case Token::NICKIN:
+ tokenVal = szNickIn;
+ break;
+ case Token::NICKOUT:
+ tokenVal = szNickOut;
+ break;
+ case Token::FILEDESC:
+ tokenVal = szFileDesc;
+ break;
+ }
+ if (tokenVal != NULL) {
+ if (token->getEscape()) {
+ char *escapedToken = Utils::escapeString(tokenVal);
+ Utils::appendText(&output, &outputSize, "%s", escapedToken);
+ delete escapedToken;
+ } else {
+ Utils::appendText(&output, &outputSize, "%s", tokenVal);
+ }
+ }
+ }
+ }
+ setLastEventType(MAKELONG(eventData->dwFlags, eventData->iType));
+ setLastEventTime(eventData->time);
+ if (szName!=NULL) delete szName;
+ if (szText!=NULL) delete szText;
+ if (szFileDesc!=NULL) delete szFileDesc;
+ }
+ if (output != NULL) {
+ view->write(output);
+ free(output);
+ }
+ }
+ if (szBase!=NULL) delete szBase;
+ if (szRealProto!=NULL) delete szRealProto;
+ if (szProto!=NULL) delete szProto;
+ if (szUINIn!=NULL) delete szUINIn;
+ if (szUINOut!=NULL) delete szUINOut;
+ if (szNoAvatar!=NULL) delete szNoAvatar;
+ if (szAvatarIn!=NULL) delete szAvatarIn;
+ if (szAvatarOut!=NULL) delete szAvatarOut;
+ if (szNameIn!=NULL) delete szNameIn;
+ if (szNameOut!=NULL) delete szNameOut;
+ if (szNickIn!=NULL) delete szNickIn;
+ if (szNickOut!=NULL) delete szNickOut;
+ if (szStatusMsg!=NULL) delete szStatusMsg;
+ view->documentClose();
+}
+
+time_t TemplateHTMLBuilder::getStartedTime() {
+ return startedTime;
+}
+
+
diff --git a/plugins/IEView/TemplateHTMLBuilder.h b/plugins/IEView/TemplateHTMLBuilder.h
new file mode 100644
index 0000000000..a6193db6e1
--- /dev/null
+++ b/plugins/IEView/TemplateHTMLBuilder.h
@@ -0,0 +1,50 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+class TemplateHTMLBuilder;
+
+#ifndef TEMPLATEHTMLBUILDER_INCLUDED
+#define TEMPLATEHTMLBUILDER_INCLUDED
+
+#include "HTMLBuilder.h"
+#include "Template.h"
+
+class TemplateHTMLBuilder:public HTMLBuilder
+{
+protected:
+ char *timestampToString(DWORD dwFlags, time_t check, int mode);
+ time_t startedTime;
+ time_t getStartedTime();
+ const char *groupTemplate;
+ time_t flashAvatarsTime[2];
+ char * flashAvatars[2];
+ const char *getFlashAvatar(const TCHAR *file, int index);
+ char *getAvatar(HANDLE hContact, const char *szProto);
+ void buildHeadTemplate(IEView *, IEVIEWEVENT *event, ProtocolSettings* protoSettings);
+ void appendEventTemplate(IEView *, IEVIEWEVENT *event, ProtocolSettings* protoSettings);
+ virtual TemplateMap *getTemplateMap(ProtocolSettings *);
+ virtual int getFlags(ProtocolSettings *);
+public:
+ TemplateHTMLBuilder();
+ virtual ~TemplateHTMLBuilder();
+// void buildHead(IEView *, IEVIEWEVENT *event);
+};
+
+#endif
diff --git a/plugins/IEView/TextToken.cpp b/plugins/IEView/TextToken.cpp
new file mode 100644
index 0000000000..56512ac119
--- /dev/null
+++ b/plugins/IEView/TextToken.cpp
@@ -0,0 +1,824 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+#include "TextToken.h"
+#include "m_MathModule.h"
+//#include "m_metacontacts.h"
+#include "Utils.h"
+
+TextToken::TextToken(int type, const char *text, int len) {
+ next = NULL;
+ tag = 0;
+ end = false;
+ this->type = type;
+ this->text = Utils::dupString(text, len);
+ this->wtext = Utils::convertToWCS(this->text);
+ this->link = NULL;
+ this->wlink = NULL;
+}
+
+TextToken::TextToken(int type, const wchar_t *wtext, int len) {
+ next = NULL;
+ tag = 0;
+ end = false;
+ this->type = type;
+ this->wtext = Utils::dupString(wtext, len);
+ this->text = Utils::convertToString(this->wtext);
+ this->link = NULL;
+ this->wlink = NULL;
+}
+
+TextToken::~TextToken() {
+ if (text!=NULL) {
+ delete text;
+ }
+ if (wtext!=NULL) {
+ delete wtext;
+ }
+ if (link!=NULL) {
+ delete link;
+ }
+ if (wlink!=NULL) {
+ delete wlink;
+ }
+}
+
+TextToken * TextToken::getNext() {
+ return next;
+}
+
+void TextToken::setNext(TextToken *ptr) {
+ next = ptr;
+}
+
+int TextToken::getType() {
+ return type;
+}
+
+const char *TextToken::getText() {
+ return text;
+}
+
+const wchar_t *TextToken::getTextW() {
+ return wtext;
+}
+
+int TextToken::getTag() {
+ return tag;
+}
+
+void TextToken::setTag(int tag) {
+ this->tag = tag;
+}
+
+bool TextToken::isEnd() {
+ return end;
+}
+
+void TextToken::setEnd(bool b) {
+ this->end = b;
+}
+
+const char *TextToken::getLink() {
+ return link;
+}
+
+const wchar_t *TextToken::getLinkW() {
+ return wlink;
+}
+
+void TextToken::setLink(const char *link) {
+ if (this->link != NULL) {
+ delete this->link;
+ }
+ if (this->wlink != NULL) {
+ delete this->wlink;
+ }
+ this->link = Utils::dupString(link);
+ this->wlink = Utils::convertToWCS(link);
+}
+
+void TextToken::setLink(const wchar_t *link) {
+ if (this->link != NULL) {
+ delete this->link;
+ }
+ if (this->wlink != NULL) {
+ delete this->wlink;
+ }
+ this->link = Utils::convertToString(link);
+ this->wlink = Utils::dupString(link);
+}
+
+static int countNoWhitespace(const wchar_t *str) {
+ int c;
+ for (c=0; *str!='\n' && *str!='\r' && *str!='\t' && *str!=' ' && *str!='\0'; str++, c++);
+ return c;
+}
+
+TextToken* TextToken::tokenizeBBCodes(const wchar_t *text) {
+ return tokenizeBBCodes(text, (int)wcslen(text));
+}
+
+TextToken* TextToken::tokenizeMath(const wchar_t *text) {
+ TextToken *firstToken = NULL, *lastToken = NULL, *mathToken = NULL;
+ static bool mathModInitialized = false;
+ static wchar_t *mathTagName[] = {NULL, NULL};
+ static int mathTagLen[] = {0, 0};
+ int i;
+ if (!mathModInitialized) {
+ if (ServiceExists(MATH_GET_PARAMS)) {
+ char* mthDelStart = (char *)CallService(MATH_GET_PARAMS, (WPARAM)MATH_PARAM_STARTDELIMITER, 0);
+ char* mthDelEnd = (char *)CallService(MATH_GET_PARAMS, (WPARAM)MATH_PARAM_ENDDELIMITER, 0);
+ if (mthDelStart!=NULL) {
+ mathTagName[0] = Utils::convertToWCS(mthDelStart);
+ mathTagLen[0] = (int)wcslen(mathTagName[0]);
+ }
+ if (mthDelEnd!=NULL) {
+ mathTagName[1] = Utils::convertToWCS(mthDelEnd);
+ mathTagLen[1] = (int)wcslen(mathTagName[1]);
+ }
+ CallService(MTH_FREE_MATH_BUFFER,0, (LPARAM) mthDelStart);
+ CallService(MTH_FREE_MATH_BUFFER,0, (LPARAM) mthDelEnd);
+ }
+ mathModInitialized = true;
+ }
+ int textLen = 0;
+ int l = (int)wcslen(text);
+ for (i=0; i<=l;) {
+ bool mathFound = false;
+ int k = 0, tagDataStart=0, newTokenType = 0, newTokenSize = 0;
+ if (mathTagName[0] != NULL && mathTagName[1] != NULL) {
+ if (!wcsnicmp(text+i, mathTagName[0], mathTagLen[0])) {
+ k = tagDataStart = i + mathTagLen[0];
+ for (; k < l; k++) {
+ if (!wcsnicmp(text+k, mathTagName[1], mathTagLen[1])) {
+ k += mathTagLen[1];
+ mathFound = true;
+ break;
+ }
+ }
+ }
+ }
+ if (mathFound) {
+ mathToken = new TextToken(MATH, text + tagDataStart, k - mathTagLen[1] - tagDataStart);
+ char* mathPath=(char*)CallService(MTH_GET_GIF_UNICODE, 0, (LPARAM) mathToken->getTextW());
+ if (mathPath!=NULL) {
+ mathToken->setLink(mathPath);
+ CallService(MTH_FREE_GIFPATH, 0, (LPARAM) mathPath);
+ } else {
+ mathToken->setLink("");
+ }
+ mathToken->setEnd(false);
+ newTokenType = MATH;
+ newTokenSize = k - i;
+ } else {
+ if (i==l) {
+ newTokenType = END;
+ newTokenSize = 1;
+ } else {
+ newTokenType = TEXT;
+ newTokenSize = 1;
+ }
+ }
+ if (newTokenType != TEXT) {
+ if (textLen >0 ) {
+ TextToken *newToken = new TextToken(TEXT, text+i-textLen, textLen);
+ textLen = 0;
+ if (lastToken == NULL) {
+ firstToken = newToken;
+ } else {
+ lastToken->setNext(newToken);
+ }
+ lastToken = newToken;
+ }
+ if (newTokenType == MATH) {
+ if (lastToken == NULL) {
+ firstToken = mathToken;
+ } else {
+ lastToken->setNext(mathToken);
+ }
+ lastToken = mathToken;
+ }
+ } else {
+ textLen += newTokenSize;
+ }
+ i += newTokenSize;
+ }
+ return firstToken;
+}
+// TODO: Add the following BBCodes: code
+#define BB_TAG_NUM 10
+TextToken* TextToken::tokenizeBBCodes(const wchar_t *text, int l) {
+ static const wchar_t *bbTagName[] = {L"b", L"i", L"u", L"s", L"img", L"color", L"size", L"bimg", L"url", L"code"};
+ static int bbTagNameLen[] = {1, 1, 1, 1, 3, 5, 4, 4, 3, 4};
+ static int bbTagArg[] = {0, 0, 0, 0, 0, 1, 1, 0, 1, 0};
+ static int bbTagId[] = {BB_B, BB_I, BB_U, BB_S, BB_IMG, BB_COLOR, BB_SIZE, BB_BIMG, BB_URL, BB_CODE};
+ static int bbTagEnd[BB_TAG_NUM];
+ static int bbTagCount[BB_TAG_NUM];
+ int i,j;
+ TextToken *firstToken = NULL, *lastToken = NULL, * bbToken = NULL;
+ int textLen = 0;
+ for (j = 0; j < BB_TAG_NUM; j++) {
+ bbTagCount[j] = 0;
+ bbTagEnd[j] = 0;
+ }
+ for (i = 0; i <= l;) {
+ int k, tagArgStart=0, tagArgEnd=0, tagDataStart=0, newTokenType = 0, newTokenSize = 0;
+ bool bbFound = false;
+ if (text[i] == '[') {
+ if (text[i+1] != '/') {
+ for (j = 0; j < BB_TAG_NUM; j++) {
+ k = i + 1;
+ if (!wcsnicmp(text+k, bbTagName[j], bbTagNameLen[j])) {
+ tagArgStart = tagArgEnd = 0;
+ k += bbTagNameLen[j];
+ if (bbTagArg[j]) {
+ if (text[k] != '=') continue;
+ k++;
+ tagArgStart = k;
+ for (; text[k]!='\0'; k++) {
+ if (text[k]==']') break;
+ }
+ tagArgEnd = k;
+ }
+ if (text[k] == ']') {
+ k++;
+ tagDataStart = k;
+ if (k < bbTagEnd[j]) k = bbTagEnd[j];
+ for (; k < l; k++) {
+ if (text[k] == '[' && text[k+1] == '/') {
+ k += 2;
+ if (!wcsnicmp(text+k, bbTagName[j], bbTagNameLen[j])) {
+ k += bbTagNameLen[j];
+ if (text[k] == ']') {
+ k++;
+ bbFound = true;
+ break;
+ }
+ }
+ }
+ }
+ if (bbFound) break;
+ }
+ }
+ }
+ if (bbFound) {
+ bbTagEnd[j] = k;
+ switch (bbTagId[j]) {
+ case BB_B:
+ case BB_I:
+ case BB_U:
+ case BB_S:
+ case BB_CODE:
+ case BB_COLOR:
+ case BB_SIZE:
+ bbTagCount[j]++;
+ if (bbTagArg[j]) {
+ bbToken = new TextToken(BBCODE, text + tagArgStart, tagArgEnd - tagArgStart);
+ } else {
+ bbToken = new TextToken(BBCODE, bbTagName[j], bbTagNameLen[j]);
+ }
+ bbToken->setTag(bbTagId[j]);
+ bbToken->setEnd(false);
+ newTokenType = BBCODE;
+ newTokenSize = tagDataStart - i;
+ break;
+ case BB_URL:
+ case BB_IMG:
+ case BB_BIMG:
+ bbToken = new TextToken(BBCODE, text + tagDataStart, k - bbTagNameLen[j] - 3 - tagDataStart);
+ bbToken->setTag(bbTagId[j]);
+ bbToken->setEnd(false);
+ newTokenType = BBCODE;
+ newTokenSize = k - i;
+ if (bbTagArg[j]) {
+ wchar_t *urlLink = Utils::dupString(text + tagArgStart, tagArgEnd - tagArgStart);
+ bbToken->setLink(urlLink);
+ delete urlLink;
+ }
+ break;
+ }
+ }
+ } else {
+ for (j = 0; j < BB_TAG_NUM; j++) {
+ k = i + 2;
+ if (bbTagCount[j]>0 && !wcsnicmp(text+k, bbTagName[j], bbTagNameLen[j])) {
+ k += bbTagNameLen[j];
+ if (text[k] == ']') {
+ k++;
+ bbFound = true;
+ break;
+ }
+ }
+ }
+ if (bbFound) {
+ bbTagCount[j]--;
+ bbToken = new TextToken(BBCODE, bbTagName[j], bbTagNameLen[j]);
+ bbToken->setEnd(true);
+ bbToken->setTag(bbTagId[j]);
+ newTokenType = BBCODE;
+ newTokenSize = k - i;
+ }
+ }
+ }
+ if (!bbFound) {
+ if (i==l) {
+ newTokenType = END;
+ newTokenSize = 1;
+ } else {
+ newTokenType = TEXT;
+ newTokenSize = 1;
+ }
+ }
+ if (newTokenType != TEXT) {
+ if (textLen >0 ) {
+ TextToken *newToken = new TextToken(TEXT, text+i-textLen, textLen);
+ textLen = 0;
+ if (lastToken == NULL) {
+ firstToken = newToken;
+ } else {
+ lastToken->setNext(newToken);
+ }
+ lastToken = newToken;
+ }
+ if (newTokenType == BBCODE) {
+ if (lastToken == NULL) {
+ firstToken = bbToken;
+ } else {
+ lastToken->setNext(bbToken);
+ }
+ lastToken = bbToken;
+ }
+ } else {
+ textLen += newTokenSize;
+ }
+ i += newTokenSize;
+ }
+ return firstToken;
+}
+
+TextToken* TextToken::tokenizeLinks(const wchar_t *text) {
+ TextToken *firstToken = NULL, *lastToken = NULL;
+ int textLen = 0;
+ int l = (int)wcslen(text);
+ for (int i=0; i<=l;) {
+ int newTokenType, newTokenSize;
+ int urlLen = Utils::detectURL(text+i);
+ if (i == l) {
+ newTokenType = END;
+ newTokenSize = 1;
+ } else if (urlLen > 0) {
+ newTokenType = LINK;
+ newTokenSize = urlLen;
+ } else if (!wcsncmp(text+i, L"www.", 4)) {
+ newTokenType = WWWLINK;
+ newTokenSize = countNoWhitespace(text+i);
+ } else if (!wcsncmp(text+i, L"mailto:", 7)) {
+ newTokenType = LINK;
+ newTokenSize = countNoWhitespace(text+i);
+ } else {
+ newTokenType = TEXT;
+ newTokenSize = 1;
+ }
+ if (newTokenType != TEXT) {
+ if (textLen >0 ) {
+ TextToken *newToken = new TextToken(TEXT, text+i-textLen, textLen);
+ textLen = 0;
+ if (lastToken == NULL) {
+ firstToken = newToken;
+ } else {
+ lastToken->setNext(newToken);
+ }
+ lastToken = newToken;
+ }
+ if (newTokenType == WWWLINK || newTokenType == LINK) {
+ TextToken *newToken = new TextToken(newTokenType, text+i, newTokenSize);
+ newToken->setLink(newToken->getText());
+ if (lastToken == NULL) {
+ firstToken = newToken;
+ } else {
+ lastToken->setNext(newToken);
+ }
+ lastToken = newToken;
+ }
+ } else {
+ textLen += newTokenSize;
+ }
+ i += newTokenSize;
+ }
+ return firstToken;
+}
+
+TextToken* TextToken::tokenizeSmileys(HANDLE hContact, const char *proto, const wchar_t *text, bool isSent) {
+ TextToken *firstToken = NULL, *lastToken = NULL;
+ SMADD_BATCHPARSE2 sp;
+ SMADD_BATCHPARSERES *spRes;
+ int l = (int)wcslen(text);
+ if (!Options::isSmileyAdd()) {
+ return new TextToken(TEXT, text, l);
+ }
+ sp.cbSize = sizeof(sp);
+ sp.Protocolname = proto;
+ sp.flag = SAFL_PATH | SAFL_UNICODE | (isSent ? SAFL_OUTGOING : 0);
+ sp.wstr = (wchar_t *)text;
+ sp.hContact = hContact;
+ spRes = (SMADD_BATCHPARSERES *) CallService(MS_SMILEYADD_BATCHPARSE, 0, (LPARAM)&sp);
+ int last_pos = 0;
+ if (spRes != NULL) {
+ for (int i = 0; i < (int)sp.numSmileys; i++) {
+ if (spRes[i].filepath != NULL && strlen((char *)spRes[i].filepath) > 0) {
+ if ((int)spRes[i].startChar - last_pos > 0) {
+ TextToken *newToken = new TextToken(TEXT, text+last_pos, spRes[i].startChar-last_pos);
+ if (lastToken == NULL) {
+ firstToken = newToken;
+ } else {
+ lastToken->setNext(newToken);
+ }
+ lastToken = newToken;
+ }
+ TextToken *newToken = new TextToken(SMILEY, text+spRes[i].startChar, spRes[i].size);
+ if (sp.oflag & SAFL_UNICODE) {
+ newToken->setLink((wchar_t *)spRes[i].filepath);
+ } else {
+ newToken->setLink((char *)spRes[i].filepath);
+ }
+ if (lastToken == NULL) {
+ firstToken = newToken;
+ } else {
+ lastToken->setNext(newToken);
+ }
+ lastToken = newToken;
+ last_pos = spRes[i].startChar + spRes[i].size;
+ }
+ }
+ CallService(MS_SMILEYADD_BATCHFREE, 0, (LPARAM)spRes);
+ }
+ if (last_pos < l) {
+ TextToken *newToken = new TextToken(TEXT, text+last_pos, l-last_pos);
+ if (lastToken == NULL) {
+ firstToken = newToken;
+ } else {
+ lastToken->setNext(newToken);
+ }
+ lastToken = newToken;
+ }
+ return firstToken;
+}
+
+TextToken* TextToken::tokenizeChatFormatting(const wchar_t *text) {
+ TextToken *firstToken = NULL, *lastToken = NULL;
+ int textLen = 0;
+ int l = (int)wcslen(text);
+ wchar_t* tokenBuffer = new wchar_t[l + 1];
+ for (int i=0; i<=l;) {
+ int newTokenType = TEXT;
+ int newTokenSize = 1;
+ int newTokenTag = 0;
+ int newTokenTextLen = 0;
+ const wchar_t * newTokenText = NULL;
+ bool endToken = false;
+
+
+ if (i==l) {
+ newTokenType = END;
+ } else {
+ if (text[i] == '%') {
+ newTokenSize = 2;
+ switch (text[i + 1]) {
+ case '%':
+ break;
+ case 'B':
+ endToken = true;
+ case 'b':
+ newTokenType = BBCODE;
+ newTokenTag = BB_B;
+ break;
+ case 'U':
+ endToken = true;
+ case 'u':
+ newTokenType = BBCODE;
+ newTokenTag = BB_U;
+ break;
+ case 'I':
+ endToken = true;
+ case 'i':
+ newTokenType = BBCODE;
+ newTokenTag = BB_I;
+ break;
+ case 'C':
+ endToken = true;
+ case 'c':
+ newTokenType = BBCODE;
+ newTokenTag = BB_COLOR;
+ if (!endToken) {
+ newTokenText = text + i + 2;
+ newTokenTextLen = 7;
+ newTokenSize = 9;
+ }
+ break;
+ case 'F':
+ endToken = true;
+ case 'f':
+ newTokenType = BBCODE;
+ newTokenTag = BB_BACKGROUND;
+ if (!endToken) {
+ newTokenText = text + i + 2;
+ newTokenTextLen = 7;
+ newTokenSize = 9;
+ }
+ break;
+ default:
+ newTokenSize = 1;
+ }
+ }
+ }
+ if (newTokenType != TEXT) {
+ if (textLen >0 ) {
+ TextToken *newToken = new TextToken(TEXT, tokenBuffer, textLen);
+ textLen = 0;
+ if (lastToken == NULL) {
+ firstToken = newToken;
+ } else {
+ lastToken->setNext(newToken);
+ }
+ lastToken = newToken;
+ }
+ if (newTokenType == BBCODE) {
+ TextToken *newToken = new TextToken(newTokenType, newTokenText, newTokenTextLen);
+ newToken->setEnd(endToken);
+ newToken->setTag(newTokenTag);
+ if (lastToken == NULL) {
+ firstToken = newToken;
+ } else {
+ lastToken->setNext(newToken);
+ }
+ lastToken = newToken;
+ }
+ } else {
+ tokenBuffer[textLen] = text[i];
+ textLen++;
+ }
+ i += newTokenSize;
+ }
+ return firstToken;
+}
+
+wchar_t *TextToken::htmlEncode(const wchar_t *str) {
+ wchar_t *out;
+ const wchar_t *ptr;
+ bool wasSpace;
+ int c;
+ c = 0;
+ wasSpace = false;
+ for (ptr=str; *ptr!='\0'; ptr++) {
+ if (*ptr==' ' && wasSpace) {
+ wasSpace = true;
+ c += 6;
+ } else {
+ wasSpace = false;
+ switch (*ptr) {
+ case '\n': c += 4; break;
+ case '\r': break;
+ case '&': c += 5; break;
+ case '>': c += 4; break;
+ case '<': c += 4; break;
+ case '"': c += 6; break;
+ case ' ': wasSpace = true;
+ default: c += 1; break;
+ }
+ }
+ }
+ wchar_t *output = new wchar_t[c+1];
+ wasSpace = false;
+ for (out=output, ptr=str; *ptr!='\0'; ptr++) {
+ if (*ptr==' ' && wasSpace) {
+ wcscpy(out, L"&nbsp;");
+ out += 6;
+ } else {
+ wasSpace = false;
+ switch (*ptr) {
+ case '\n': wcscpy(out, L"<br>"); out += 4; break;
+ case '\r': break;
+ case '&': wcscpy(out, L"&amp;"); out += 5; break;
+ case '>': wcscpy(out, L"&gt;"); out += 4; break;
+ case '<': wcscpy(out, L"&lt;"); out += 4; break;
+ case '"': wcscpy(out, L"&quot;"); out += 6; break;
+ case ' ': wasSpace = true;
+ default: *out = *ptr; out += 1; break;
+ }
+ }
+ }
+ *out = '\0';
+ return output;
+}
+
+void TextToken::toString(wchar_t **str, int *sizeAlloced) {
+ wchar_t *eText = NULL, *eLink = NULL;
+ switch (type) {
+ case TEXT:
+ eText = htmlEncode(wtext);
+ Utils::appendText(str, sizeAlloced, L"%s", eText);
+ break;
+ case WWWLINK:
+ case LINK:
+ {
+ eText = htmlEncode(wtext);
+ eLink = htmlEncode(wlink);
+ const wchar_t *linkPrefix = type == WWWLINK ? L"http://" : L"";
+ if ((Options::getGeneralFlags()&Options::GENERAL_ENABLE_EMBED)) {
+ wchar_t *match = wcsstr(wlink, L"youtube.com");
+ if (match != NULL) {
+ match = wcsstr(match + 11, L"v=");
+ if (match != NULL) {
+ match += 2;
+ wchar_t *match2 = wcsstr(match, L"&");
+ int len = match2 != NULL ? match2 - match : (int)wcslen(match);
+ match = mir_wstrdup(match);
+ match[len] = 0;
+ int width ;
+ int height;
+ int Embedsize = Options::getEmbedsize();
+ switch (Embedsize){
+ case 0:
+ width = 320;
+ height = 205;
+ break;
+ case 1:
+ width = 480;
+ height = 385;
+ break;
+ case 2:
+ width = 560;
+ height = 349;
+ break;
+ case 3:
+ width = 640;
+ height = 390;
+ break;
+
+ };
+
+ Utils::appendText(str, sizeAlloced, L"<div><object width=\"%d\" height=\"%d\">\
+ <param name=\"movie\" value=\"http://www.youtube.com/v/%s&feature=player_embedded&version=3\"/>\
+ <param name=\"allowFullScreen\" value=\"true\"/>\
+ <param name=\"allowScriptAccess\" value=\"true\"/>\
+ <embed src=\"http://www.youtube.com/v/%s&feature=player_embedded&version=3\" type=\"application/x-shockwave-flash\" allowfullscreen=\"true\" allowScriptAccess=\"always\" width=\"%d\" height=\"%d\"/>\
+ </object></div>", width, height, match, match, width, height);
+ mir_free(match);
+ break;
+ }
+ }
+ }
+ Utils::appendText(str, sizeAlloced, L"<a class=\"link\" target=\"_self\" href=\"%s%s\">%s</a>", linkPrefix, eLink, eText);
+ }
+ break;
+ case SMILEY:
+ eText = htmlEncode(wtext);
+ if ((Options::getGeneralFlags()&Options::GENERAL_ENABLE_FLASH) && (wcsstr(wlink, L".swf")!=NULL)) {
+ Utils::appendText(str, sizeAlloced,
+ L"<span title=\"%s\" class=\"img\"><object classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" \
+ codebase=\"http://active.macromedia.com/flash2/cabs/swflash.cab#version=4,0,0,0\" >\
+ <param NAME=\"movie\" VALUE=\"%s\"><param NAME=\"quality\" VALUE=\"high\"><PARAM NAME=\"loop\" VALUE=\"true\"></object></span><span style=\"position:absolute; visibility:hidden;\">%s</span>",
+ wlink, eText);
+ } else if ((Options::getGeneralFlags()&Options::GENERAL_ENABLE_PNGHACK) && (wcsstr(wlink, L".png")!=NULL)) {
+ Utils::appendText(str, sizeAlloced, L"<img class=\"img\" style=\"height:1px;width:1px;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%s',sizingMethod='image');\" alt=\"%s\"/><span style=\"position:absolute; visibility:hidden;\">%s</span>", wlink, eText, eText);
+ } else {
+ Utils::appendText(str, sizeAlloced, L"<img class=\"img\" src=\"file://%s\" alt=\"%s\" /><span style=\"position:absolute; visibility:hidden;\">%s</span>", wlink, eText, eText);
+ }
+ break;
+ case MATH:
+ eText = htmlEncode(wtext);
+ if ((Options::getGeneralFlags()&Options::GENERAL_ENABLE_PNGHACK) && (wcsstr(wlink, L".png")!=NULL)) {
+ Utils::appendText(str, sizeAlloced, L"<img class=\"img\" style=\"height:1px;width:1px;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%s',sizingMethod='image');\" alt=\"%s\" /><span style=\"position:absolute; visibility:hidden;\">%s</span>",wlink , eText, eText);
+ } else {
+ Utils::appendText(str, sizeAlloced, L"<img class=\"img\" src=\"file://%s\" alt=\"%s\" /><span style=\"position:absolute; visibility:hidden;\">%s</span>", wlink, eText, eText);
+ }
+ break;
+ case BBCODE:
+ if (!end) {
+ switch (tag) {
+ case BB_B:
+ //Utils::appendText(str, sizeAlloced, L"<span style=\"font-weight: bold;\">");
+ Utils::appendText(str, sizeAlloced, L"<b>");
+ break;
+ case BB_I:
+ //Utils::appendText(str, sizeAlloced, L"<span style=\"font-style: italic;\">");
+ Utils::appendText(str, sizeAlloced, L"<i>");
+ break;
+ case BB_U:
+ //Utils::appendText(str, sizeAlloced, L"<span style=\"text-decoration: underline;\">");
+ Utils::appendText(str, sizeAlloced, L"<u>");
+ break;
+ case BB_S:
+ //Utils::appendText(str, sizeAlloced, L"<span style=\"font-style: italic;\">");
+ Utils::appendText(str, sizeAlloced, L"<s>");
+ break;
+ case BB_CODE:
+ //Utils::appendText(str, sizeAlloced, L"<span style=\"font-style: italic;\">");
+ Utils::appendText(str, sizeAlloced, L"<pre class=\"code\">");
+ break;
+ case BB_IMG:
+ eText = htmlEncode(wtext);
+ if ((Options::getGeneralFlags()&Options::GENERAL_ENABLE_FLASH) && (wcsstr(eText, L".swf")!=NULL)) {
+ Utils::appendText(str, sizeAlloced,
+ L"<div style=\"width: 100%%; border: 0; overflow: hidden;\"><object classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" \
+ codebase=\"http://active.macromedia.com/flash2/cabs/swflash.cab#version=4,0,0,0\" width=\"100%%\" >\
+ <param NAME=\"movie\" VALUE=\"%s\"><param NAME=\"quality\" VALUE=\"high\"><PARAM NAME=\"loop\" VALUE=\"true\"></object></div>",
+ eText);
+ } else if ((Options::getGeneralFlags()&Options::GENERAL_ENABLE_PNGHACK) && (wcsstr(eText, L".png")!=NULL)) {
+ Utils::appendText(str, sizeAlloced, L"<img class=\"img\" style=\"height:1px;width:1px;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%s',sizingMethod='image');\" />", eText);
+ } else {
+ if (wcsncmp(eText, L"http://", 7)) {
+ Utils::appendText(str, sizeAlloced, L"<div style=\"width: 100%%; border: 0; overflow: hidden;\"><img class=\"img\" style=\"width: expression((maxw = this.parentNode.offsetWidth ) > this.width ? 'auto' : maxw);\" src=\"file://%s\" /></div>", eText);
+ } else {
+ Utils::appendText(str, sizeAlloced, L"<div style=\"width: 100%%; border: 0; overflow: hidden;\"><img class=\"img\" style=\"width: expression((maxw = this.parentNode.offsetWidth ) > this.width ? 'auto' : maxw);\" src=\"%s\" /></div>", eText);
+ }
+ }
+ break;
+ case BB_BIMG:
+ {
+ wchar_t *absolutePath = Utils::toAbsolute(wtext);
+ eText = htmlEncode(absolutePath);
+ delete absolutePath;
+ }
+ if ((Options::getGeneralFlags()&Options::GENERAL_ENABLE_FLASH) && (wcsstr(eText, L".swf")!=NULL)) {
+ Utils::appendText(str, sizeAlloced,
+ L"<div style=\"width: 100%%; border: 0; overflow: hidden;\"><object classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" \
+ codebase=\"http://active.macromedia.com/flash2/cabs/swflash.cab#version=4,0,0,0\" width=\"100%%\" >\
+ <param NAME=\"movie\" VALUE=\"%s\"><param NAME=\"quality\" VALUE=\"high\"><PARAM NAME=\"loop\" VALUE=\"true\"></object></div>",
+ eText);
+ } else if ((Options::getGeneralFlags()&Options::GENERAL_ENABLE_PNGHACK) && (wcsstr(eText, L".png")!=NULL)) {
+ Utils::appendText(str, sizeAlloced, L"<img class=\"img\" style=\"height:1px;width:1px;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%s',sizingMethod='image');\" />", eText);
+ } else {
+ Utils::appendText(str, sizeAlloced, L"<div style=\"width: 100%%; border: 0; overflow: hidden;\"><img class=\"img\" style=\"width: expression((maxw = this.parentNode.offsetWidth ) > this.width ? 'auto' : maxw);\" src=\"file://%s\" /></div>", eText);
+ }
+ break;
+ case BB_URL:
+ eText = htmlEncode(wtext);
+ eLink = htmlEncode(wlink);
+ Utils::appendText(str, sizeAlloced, L"<a href =\"%s\">%s</a>", eLink, eText);
+ break;
+ case BB_COLOR:
+ eText = htmlEncode(wtext);
+ //Utils::appendText(str, sizeAlloced, L"<span style=\"color: %s;\">", eText);
+ Utils::appendText(str, sizeAlloced, L"<font color =\"%s\">", eText);
+ break;
+ case BB_BACKGROUND:
+ eText = htmlEncode(wtext);
+ Utils::appendText(str, sizeAlloced, L"<span style=\"background: %s;\">", eText);
+ break;
+ case BB_SIZE:
+ eText = htmlEncode(wtext);
+ Utils::appendText(str, sizeAlloced, L"<span style=\"font-size: %s;\">", eText);
+ break;
+ }
+ } else {
+ switch (tag) {
+ case BB_B:
+ Utils::appendText(str, sizeAlloced, L"</b>");
+ break;
+ case BB_I:
+ Utils::appendText(str, sizeAlloced, L"</i>");
+ break;
+ case BB_U:
+ Utils::appendText(str, sizeAlloced, L"</u>");
+ break;
+ case BB_S:
+ Utils::appendText(str, sizeAlloced, L"</s>");
+ break;
+ case BB_CODE:
+ Utils::appendText(str, sizeAlloced, L"</pre>");
+ break;
+ case BB_COLOR:
+ Utils::appendText(str, sizeAlloced, L"</font>");
+ break;
+ case BB_SIZE:
+ Utils::appendText(str, sizeAlloced, L"</span>");
+ break;
+ case BB_BACKGROUND:
+ Utils::appendText(str, sizeAlloced, L"</span>");
+ break;
+ }
+ }
+ break;
+ }
+ if (eText!=NULL) delete eText;
+ if (eLink!=NULL) delete eLink;
+}
diff --git a/plugins/IEView/TextToken.h b/plugins/IEView/TextToken.h
new file mode 100644
index 0000000000..ad6c46d711
--- /dev/null
+++ b/plugins/IEView/TextToken.h
@@ -0,0 +1,90 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef TEXTTOKEN_INCLUDED
+#define TEXTTOKEN_INCLUDED
+#include "IEView.h"
+class TextToken {
+private:
+ int type;
+ bool end;
+ int tag;
+ DWORD value;
+ wchar_t *wtext;
+ char *text;
+ wchar_t *wlink;
+ char *link;
+ TextToken *next;
+ static TextToken* tokenizeBBCodes(const wchar_t *text, int len);
+public:
+ enum TOKENS {
+ END = 0,
+ TEXT,
+ LINK,
+ WWWLINK,
+ SMILEY,
+ BBCODE,
+ MATH,
+ };
+ enum BBCODES {
+ BB_B = 0,
+ BB_I,
+ BB_U,
+ BB_S,
+ BB_COLOR,
+ BB_SIZE,
+ BB_IMG,
+ BB_BIMG,
+ BB_URL,
+ BB_CODE,
+ BB_BACKGROUND
+ };
+ TextToken(int type, const char *text, int len);
+ TextToken(int type, const wchar_t *wtext, int len);
+ ~TextToken();
+ int getType();
+ const char * getText();
+ const wchar_t* getTextW();
+ const char * getLink();
+ const wchar_t * getLinkW();
+ void setLink(const char *link);
+ void setLink(const wchar_t *wlink);
+ int getTag();
+ void setTag(int);
+ bool isEnd();
+ void setEnd(bool);
+ TextToken * getNext();
+ void setNext(TextToken *);
+// void toString(char **str, int *sizeAlloced);
+ void toString(wchar_t **str, int *sizeAlloced);
+// static char * htmlEncode(const char *str);
+// static char * urlEncode2(const char *str);
+// static TextToken* tokenizeLinks(const char *text);
+// static TextToken* tokenizeSmileys(const char *proto, const char *text);
+ // UNICODE
+ wchar_t * htmlEncode(const wchar_t *str);
+ static TextToken* tokenizeLinks(const wchar_t *wtext);
+ static TextToken* tokenizeSmileys(HANDLE hContact, const char *proto, const wchar_t *wtext, bool isSent);
+ static TextToken* tokenizeBBCodes(const wchar_t *text);
+ static TextToken* tokenizeMath(const wchar_t *text);
+ static TextToken* tokenizeChatFormatting(const wchar_t *text);
+};
+#endif
diff --git a/plugins/IEView/Utils.cpp b/plugins/IEView/Utils.cpp
new file mode 100644
index 0000000000..de2d02694b
--- /dev/null
+++ b/plugins/IEView/Utils.cpp
@@ -0,0 +1,420 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+#include "Utils.h"
+#include <ctype.h>
+#include <m_netlib.h>
+wchar_t Utils::base_dir[MAX_PATH];
+unsigned Utils::hookNum = 0;
+unsigned Utils::serviceNum = 0;
+HANDLE* Utils::hHooks = NULL;
+HANDLE* Utils::hServices = NULL;
+
+const wchar_t *Utils::getBaseDir() {
+ char temp[MAX_PATH];
+ base_dir[0] = '\0';
+ long tlen = CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"miranda32.exe", (LPARAM)temp);
+ if (tlen) {
+ temp[tlen - 13]=0;
+ MultiByteToWideChar(CP_ACP, 0, temp, (int)strlen(temp), base_dir, MAX_PATH);
+ }
+ return base_dir;
+}
+
+wchar_t* Utils::toAbsolute(wchar_t* relative) {
+ const wchar_t* bdir = getBaseDir();
+ long len = (int)wcslen(bdir);
+ long tlen = len + (int)wcslen(relative);
+ wchar_t* result = new wchar_t[tlen + 1];
+ if(result){
+ wcscpy(result,bdir);
+ wcscpy(result + len,relative);
+ }
+ return result;
+}
+
+static int countNoWhitespace(const wchar_t *str) {
+ int c;
+ for (c=0; *str!='\n' && *str!='\r' && *str!='\t' && *str!=' ' && *str!='\0'; str++, c++);
+ return c;
+}
+
+void Utils::appendText(char **str, int *sizeAlloced, const char *fmt, ...) {
+ va_list vararg;
+ char *p;
+ int size, len;
+
+ if (str == NULL) return;
+
+ if (*str==NULL || *sizeAlloced<=0) {
+ *sizeAlloced = size = 2048;
+ *str = (char *) malloc(size);
+ len = 0;
+ }
+ else {
+ len = (int)strlen(*str);
+ size = *sizeAlloced - len;
+ }
+
+ if (size < 128) {
+ size += 2048;
+ (*sizeAlloced) += 2048;
+ *str = (char *) realloc(*str, *sizeAlloced);
+ }
+ p = *str + len;
+ va_start(vararg, fmt);
+ while (_vsnprintf(p, size - 1, fmt, vararg) == -1) {
+ size += 2048;
+ (*sizeAlloced) += 2048;
+ *str = (char *) realloc(*str, *sizeAlloced);
+ p = *str + len;
+ }
+ p[ size - 1 ] = '\0';
+ va_end(vararg);
+}
+
+void Utils::appendText(wchar_t **str, int *sizeAlloced, const wchar_t *fmt, ...) {
+ va_list vararg;
+ wchar_t *p;
+ int size, len;
+
+ if (str == NULL) return;
+
+ if (*str==NULL || *sizeAlloced<=0) {
+ *sizeAlloced = size = 2048;
+ *str = (wchar_t *) malloc(size);
+ len = 0;
+ }
+ else {
+ len = (int)wcslen(*str);
+ size = *sizeAlloced - sizeof(wchar_t) * len;
+ }
+
+ if (size < 128) {
+ size += 2048;
+ (*sizeAlloced) += 2048;
+ *str = (wchar_t *) realloc(*str, *sizeAlloced);
+ }
+ p = *str + len;
+ va_start(vararg, fmt);
+ while (_vsnwprintf(p, size / sizeof(wchar_t) - 1, fmt, vararg) == -1) {
+ size += 2048;
+ (*sizeAlloced) += 2048;
+ *str = (wchar_t *) realloc(*str, *sizeAlloced);
+ p = *str + len;
+ }
+ p[ size / sizeof(wchar_t) - 1] = '\0';
+ va_end(vararg);
+}
+
+char *Utils::dupString(const char *a) {
+ if (a!=NULL) {
+ char *b = new char[strlen(a)+1];
+ strcpy(b, a);
+ return b;
+ }
+ return NULL;
+}
+
+char *Utils::dupString(const char *a, int l) {
+ if (a!=NULL) {
+ char *b = new char[l+1];
+ strncpy(b, a, l);
+ b[l] ='\0';
+ return b;
+ }
+ return NULL;
+}
+
+wchar_t *Utils::dupString(const wchar_t *a) {
+ if (a!=NULL) {
+ wchar_t *b = new wchar_t[wcslen(a)+1];
+ wcscpy(b, a);
+ return b;
+ }
+ return NULL;
+}
+
+wchar_t *Utils::dupString(const wchar_t *a, int l) {
+ if (a!=NULL) {
+ wchar_t *b = new wchar_t[l+1];
+ wcsncpy(b, a, l);
+ b[l] ='\0';
+ return b;
+ }
+ return NULL;
+}
+
+
+wchar_t *Utils::convertToWCS(const char *a) {
+ if (a!=NULL) {
+ int len = (int)strlen(a)+1;
+ wchar_t *b = new wchar_t[len];
+ MultiByteToWideChar(CP_ACP, 0, a, len, b, len);
+ return b;
+ }
+ return NULL;
+}
+
+wchar_t *Utils::convertToWCS(const char *a, int cp) {
+ if (a!=NULL) {
+ int len = (int)strlen(a)+1;
+ wchar_t *b = new wchar_t[len];
+ MultiByteToWideChar(cp, 0, a, len, b, len);
+ return b;
+ }
+ return NULL;
+}
+
+char *Utils::convertToString(const wchar_t *a) {
+ if (a!=NULL) {
+ int len = (int)wcslen(a)+1;
+ char *b = new char[len];
+ WideCharToMultiByte(CP_ACP, 0, a, len, b, len, NULL, FALSE);
+ return b;
+ }
+ return NULL;
+}
+
+
+char *Utils::convertToString(const wchar_t *a, int cp) {
+ if (a!=NULL) {
+ int len = (int)wcslen(a)+1;
+ char *b = new char[len];
+ WideCharToMultiByte(cp, 0, a, len, b, len, NULL, FALSE);
+ return b;
+ }
+ return NULL;
+}
+
+void Utils::convertPath(char *path) {
+ if (path != NULL) {
+ for (; *path!='\0'; path++) {
+ if (*path == '\\') *path = '/';
+ }
+ }
+}
+
+void Utils::convertPath(wchar_t *path) {
+ if (path != NULL) {
+ for (; *path!='\0'; path++) {
+ if (*path == '\\') *path = '/';
+ }
+ }
+}
+
+DWORD Utils::safe_wcslen(wchar_t *msg, DWORD maxLen) {
+ DWORD i;
+ for (i = 0; i < maxLen; i++) {
+ if (msg[i] == (wchar_t)0)
+ return i;
+ }
+ return 0;
+}
+
+char * Utils::UTF8Encode(const wchar_t *wtext) {
+ unsigned char *szOut;
+ int len, i;
+ const wchar_t *w;
+
+ if (wtext == NULL) return NULL;
+ for (len=0, w=wtext; *w; w++) {
+ if (*w < 0x0080) len++;
+ else if (*w < 0x0800) len += 2;
+ else len += 3;
+ }
+ szOut = new unsigned char [len+1];
+ if (szOut == NULL) return NULL;
+
+ for (i=0, w=wtext; *w; w++) {
+ if (*w < 0x0080)
+ szOut[i++] = (unsigned char) *w;
+ else if (*w < 0x0800) {
+ szOut[i++] = 0xc0 | ((*w) >> 6);
+ szOut[i++] = 0x80 | ((*w) & 0x3f);
+ }
+ else {
+ szOut[i++] = 0xe0 | ((*w) >> 12);
+ szOut[i++] = 0x80 | (((*w) >> 6) & 0x3f);
+ szOut[i++] = 0x80 | ((*w) & 0x3f);
+ }
+ }
+ szOut[i] = '\0';
+ return (char *) szOut;
+}
+
+char *Utils::UTF8Encode(const char *text) {
+ wchar_t *wtext = Utils::convertToWCS(text);
+ char *atext = UTF8Encode(wtext);
+ delete wtext;
+ return atext;
+}
+
+void Utils::UTF8Encode(const char *text, char *output, int maxLen) {
+ wchar_t *wtext = Utils::convertToWCS(text);
+ char *atext = UTF8Encode(wtext);
+ int slen = (int)strlen(atext) + 1;
+ memcpy(output, atext, slen > maxLen ? maxLen : slen);
+ output[maxLen - 1] = '\0';
+ delete atext;
+ delete wtext;
+}
+
+void Utils::UTF8Encode(const wchar_t *wtext, char *output, int maxLen) {
+ char *atext = UTF8Encode(wtext);
+ int slen = (int)strlen(atext) + 1;
+ memcpy(output, atext, slen > maxLen ? maxLen : slen);
+ output[maxLen - 1] = '\0';
+ delete atext;
+}
+
+int Utils::detectURL(const wchar_t *text) {
+ int i;
+ for (i=0;text[i]!='\0';i++) {
+ if (!((text[i] >= '0' && text[i]<='9') || iswalpha(text[i]))) {
+ break;
+ }
+ }
+ if (i > 0 && text[i]==':' && text[i+1]=='/' && text[i+2]=='/') {
+ i += countNoWhitespace(text+i);
+ for (; i > 0; i --) {
+ if ((text[i-1] >= '0' && text[i-1]<='9') || iswalpha(text[i-1]) || text[i-1]=='/') {
+ break;
+ }
+ }
+ return i;
+ }
+ return 0;
+}
+
+char *Utils::escapeString(const char *a) {
+ int i, l, len;
+ char *out;
+ if (a == NULL) {
+ return NULL;
+ }
+ len = (int)strlen(a);
+ for (i = l = 0; i < len; i++, l++) {
+ if (a[i] == '\\' || a[i] == '\n' || a[i] == '\r' || a[i] == '\"'
+ || a[i] == '\'' || a[i] == '\b' || a[i] == '\t' || a[i] == '\f') {
+ l++;
+ }
+ }
+ out = new char[l+1];
+ for (i = l = 0; i < len; i++, l++) {
+ if (a[i] == '\\' || a[i] == '\n' || a[i] == '\r' || a[i] == '\"'
+ || a[i] == '\'' || a[i] == '\b' || a[i] == '\t' || a[i] == '\f') {
+ out[l++] = '\\';
+ }
+ out[l] = a[i];
+ }
+ out[l] = '\0';
+ return out;
+}
+
+struct FORK_ARG {
+ HANDLE hEvent;
+ void (__cdecl *threadcode)(void*);
+ void *arg;
+};
+
+static void __cdecl forkthread_r(struct FORK_ARG *fa)
+{
+ void (*callercode)(void*) = fa->threadcode;
+ void *arg = fa->arg;
+ CallService(MS_SYSTEM_THREAD_PUSH, 0, 0);
+ SetEvent(fa->hEvent);
+ callercode(arg);
+ CallService(MS_SYSTEM_THREAD_POP, 0, 0);
+ return;
+}
+
+unsigned long Utils::forkThread(void (__cdecl *threadcode)(void*), unsigned long stacksize, void *arg) {
+
+ unsigned long rc;
+ struct FORK_ARG fa;
+
+ fa.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ fa.threadcode = threadcode;
+ fa.arg = arg;
+ rc = _beginthread((void (__cdecl *)(void*))forkthread_r, stacksize, &fa);
+ if ((unsigned long) -1L != rc) {
+ WaitForSingleObject(fa.hEvent, INFINITE);
+ }
+ CloseHandle(fa.hEvent);
+ return rc;
+}
+
+HANDLE Utils::hookEvent_Ex(const char *name, MIRANDAHOOK hook) {
+ hookNum ++;
+ hHooks = (HANDLE *) mir_realloc(hHooks, sizeof(HANDLE) * (hookNum));
+ hHooks[hookNum - 1] = HookEvent(name, hook);
+ return hHooks[hookNum - 1] ;
+}
+
+HANDLE Utils::createServiceFunction_Ex(const char *name, MIRANDASERVICE service) {
+ serviceNum++;
+ hServices = (HANDLE *) mir_realloc(hServices, sizeof(HANDLE) * (serviceNum));
+ hServices[serviceNum - 1] = CreateServiceFunction(name, service);
+ return hServices[serviceNum - 1] ;
+}
+
+void Utils::unhookEvents_Ex() {
+ unsigned i;
+ for (i=0; i<hookNum ; ++i) {
+ if (hHooks[i] != NULL) {
+ UnhookEvent(hHooks[i]);
+ }
+ }
+ mir_free(hHooks);
+ hookNum = 0;
+ hHooks = NULL;
+}
+
+void Utils::destroyServices_Ex() {
+ unsigned i;
+ for (i=0; i<serviceNum; ++i) {
+ if (hServices[i] != NULL) {
+ DestroyServiceFunction(hServices[i]);
+ }
+ }
+ mir_free(hServices);
+ serviceNum = 0;
+ hServices = NULL;
+}
+
+wchar_t *Utils::urlEncode(const wchar_t *text) {
+ char *utf8 = UTF8Encode(text);
+ wchar_t *result = urlEncode(utf8);
+ delete utf8;
+ return result;
+}
+
+wchar_t *Utils::urlEncode(const char *text) {
+ char *pszReturnString = (char *)CallService(MS_NETLIB_URLENCODE, (WPARAM)0, (LPARAM)text);
+ wchar_t *result = convertToWCS(pszReturnString);
+ HeapFree(GetProcessHeap(), 0, pszReturnString);
+ return result;
+}
+
+
+void Utils::appendIcon(char **str, int *sizeAlloced, const char *iconFile) {
+ Utils::appendText(str, sizeAlloced, "<img class=\"img\" src=\"file://%s/plugins/ieview/%s\"/> ", workingDirUtf8, iconFile);
+}
diff --git a/plugins/IEView/Utils.h b/plugins/IEView/Utils.h
new file mode 100644
index 0000000000..17639ede35
--- /dev/null
+++ b/plugins/IEView/Utils.h
@@ -0,0 +1,69 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+class Utils;
+
+#ifndef UTILS_INCLUDED
+#define UTILS_INCLUDED
+
+#include "ieview_common.h"
+
+class Utils {
+private:
+ static unsigned hookNum;
+ static unsigned serviceNum;
+ static HANDLE* hHooks;
+ static HANDLE* hServices;
+ static wchar_t base_dir[MAX_PATH];
+public:
+ static const wchar_t *getBaseDir();
+ static wchar_t* toAbsolute(wchar_t* relative);
+ static void appendIcon(char **str, int *sizeAlloced, const char *iconFile);
+ static void appendText(char **str, int *sizeAlloced, const char *fmt, ...);
+ static void appendText(wchar_t **str, int *sizeAlloced, const wchar_t *fmt, ...);
+ static void convertPath(char *path);
+ static void convertPath(wchar_t *path);
+ static char *dupString(const char *a);
+ static char *dupString(const char *a, int l);
+ static wchar_t *dupString(const wchar_t *a);
+ static wchar_t *dupString(const wchar_t *a, int l);
+ static wchar_t *convertToWCS(const char *a);
+ static wchar_t *convertToWCS(const char *a, int cp);
+ static char *convertToString(const wchar_t *a);
+ static char *convertToString(const wchar_t *a, int cp);
+ static char *escapeString(const char *a);
+ static DWORD safe_wcslen(wchar_t *msg, DWORD maxLen);
+ static char *UTF8Encode(const wchar_t *wtext);
+ static char *UTF8Encode(const char *text);
+ static void UTF8Encode(const char *text, char *output, int maxLen);
+ static void UTF8Encode(const wchar_t *text, char *output, int maxLen);
+ static int detectURL(const wchar_t *text);
+ static HANDLE hookEvent_Ex(const char *name, MIRANDAHOOK hook);
+ static HANDLE createServiceFunction_Ex(const char *name, MIRANDASERVICE service);
+ static void unhookEvents_Ex();
+ static void destroyServices_Ex();
+ static unsigned long forkThread(void (__cdecl *threadcode)(void*),unsigned long stacksize,void *arg);
+ static wchar_t *urlEncode(const wchar_t *a);
+ static wchar_t *urlEncode(const char *a);
+
+};
+
+#endif
+
diff --git a/plugins/IEView/Version.h b/plugins/IEView/Version.h
new file mode 100644
index 0000000000..283b79a98b
--- /dev/null
+++ b/plugins/IEView/Version.h
@@ -0,0 +1,28 @@
+#define __MAJOR_VERSION 1
+#define __MINOR_VERSION 3
+#define __RELEASE_NUM 0
+#define __BUILD_NUM 3
+
+#define __FILEVERSION_STRING __MAJOR_VERSION,__MINOR_VERSION,__RELEASE_NUM,__BUILD_NUM
+#define __FILEVERSION_DOTS __MAJOR_VERSION.__MINOR_VERSION.__RELEASE_NUM.__BUILD_NUM
+
+#define __STRINGIFY_IMPL(x) #x
+#define __STRINGIFY(x) __STRINGIFY_IMPL(x)
+#define __VERSION_STRING __STRINGIFY(__FILEVERSION_DOTS)
+
+#ifdef _UNICODE
+#if defined(WIN64) || defined(_WIN64)
+ #define __PLUGIN_NAME "IEView (Unicode x64)"
+#else
+ #define __PLUGIN_NAME "IEView (Unicode)"
+#endif
+#else
+ #define __PLUGIN_NAME "IEView"
+#endif
+#define __INTERNAL_NAME "IEView"
+#define __FILENAME "IEView.dll"
+#define __DESCRIPTION "IE Based Chat Log."
+#define __AUTHOR "Piotr Piastucki, Francois Mean"
+#define __AUTHOREMAIL "the_leech@users.berlios.de"
+#define __AUTHORWEB "http://developer.berlios.de/projects/mgoodies"
+#define __COPYRIGHT "© 2005-2011 Piotr Piastucki, Francois Mean"
diff --git a/plugins/IEView/Version.rc b/plugins/IEView/Version.rc
new file mode 100644
index 0000000000..e637f0cb33
--- /dev/null
+++ b/plugins/IEView/Version.rc
@@ -0,0 +1,38 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "afxres.h"
+#include "version.h"
+
+#ifdef _WIN32
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+#endif //_WIN32
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION __FILEVERSION_STRING
+ PRODUCTVERSION __FILEVERSION_STRING
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x0L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "FileDescription", __DESCRIPTION
+ VALUE "InternalName", __PLUGIN_NAME
+ VALUE "LegalCopyright", __COPYRIGHT
+ VALUE "OriginalFilename", __FILENAME
+ VALUE "ProductName", __PLUGIN_NAME
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
diff --git a/plugins/IEView/docs/chat.css b/plugins/IEView/docs/chat.css
new file mode 100644
index 0000000000..5741e47996
--- /dev/null
+++ b/plugins/IEView/docs/chat.css
@@ -0,0 +1,37 @@
+/* this changes the way main window background looks like */
+.body {margin: 0px; text-align: left; background-color: #E6E8E6; overflow: auto;}
+/* this changes the way your links look like */
+.link {color: #0000FF; text-decoration: underline;}
+/* this changes the way smileys and log icons look like */
+.img {vertical-align: middle;}
+/* this changes the way incoming (received) events look like including timestamp, name, etc. */
+.divIn {padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #E6E8E6;}
+/* this changes the way outgoing (sent) events look like including timestamp, name, etc. */
+.divOut {padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #E6E8E6;}
+.divUserJoined {padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #E6E8E6;}
+.divUserLeft {padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #E6E8E6;}
+.divUserKicked {padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #E6E8E6;}
+.divUserDisconnected {padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #E6E8E6;}
+.divNickChange {padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #E6E8E6;}
+.divTopicChange {padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #E6E8E6;}
+.divNotice {padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #E6E8E6;}
+.divInformation {padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #E6E8E6;}
+.divError {padding-left: 2px; padding-right: 2px; word-wrap: break-word; background-color: #E6E8E6;}
+.timestamp {font-family: Verdana; font-size: 6pt; font-weight: bold; color: #000000; }
+.nameIn {font-family: Verdana; font-size: 10pt; font-weight: normal; color: #323772; }
+.nameOut {font-family: Verdana; font-size: 10pt; font-weight: bold; color: #A45344; }
+.messageIn {font-family: Verdana; font-size: 10pt; font-weight: normal; color: #000000; }
+.messageOut {font-family: Verdana; font-size: 10pt; font-weight: normal; color: #805050; font-style: italic; }
+.userJoined {font-family: Verdana; font-size: 8pt; font-weight: normal; color: #0F880F; font-style: italic; }
+.userLeft {font-family: Verdana; font-size: 8pt; font-weight: normal; color: #B91313; font-style: italic; }
+.userDisconnected {font-family: Verdana; font-size: 8pt; font-weight: normal; color: #0F880F; font-style: italic; }
+.userKicked {font-family: Verdana; font-size: 8pt; font-weight: normal; color: #0F880F; font-style: italic; }
+.nickChange {font-family: Verdana; font-size: 8pt; font-weight: normal; color: #0F880F; font-style: italic; }
+.topicChange {font-family: Verdana; font-size: 10pt; font-weight: normal; color: #531A99; font-style: italic; }
+.notice {font-family: Verdana; font-size: 8pt; font-weight: normal; color: #0F880F; font-style: italic; }
+.information {font-family: Verdana; font-size: 8pt; font-weight: normal; color: #0F880F; font-style: italic; }
+.statusEnable {font-family: Verdana; font-size: 8pt; font-weight: normal; color: #0F880F; font-style: italic; }
+.statusDisable {font-family: Verdana; font-size: 8pt; font-weight: normal; color: #0F880F; font-style: italic; }
+.action {font-family: Verdana; font-size: 8pt; font-weight: normal; color: #0F880F; font-style: italic; }
+.highlight {font-family: Verdana; font-size: 8pt; font-weight: normal; color: #0F880F; font-style: italic; }
+.error {font-family: Verdana; font-size: 10pt; font-weight: bold; color: #D01010; }
diff --git a/plugins/IEView/docs/ieview-license.txt b/plugins/IEView/docs/ieview-license.txt
new file mode 100644
index 0000000000..ca3fe8d547
--- /dev/null
+++ b/plugins/IEView/docs/ieview-license.txt
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ 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 option) 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/plugins/IEView/docs/ieview-readme.txt b/plugins/IEView/docs/ieview-readme.txt
new file mode 100644
index 0000000000..a51893239e
--- /dev/null
+++ b/plugins/IEView/docs/ieview-readme.txt
@@ -0,0 +1,263 @@
+IEView user's manual & FAQ v1.0
+-------------------------------
+
+1. Overview
+-----------
+
+IEView is a replacement for RichEdit-based log window available in SRMM
+or TabSRMM. It cannot be used as a standalone plugin. It provides new features
+not achievable with RichEdit like:
+- animated emoticons,
+- background images,
+- customization of log appearance with CSS files,
+- look of log window may be built from scratch with HTML templates
+
+IEView works in 3 modes:
+
+A) compatibility mode (either Scriver or TabSRMM)
+It tries to mimic original look of Scriver or TabSRMM, but in addition
+animated emoticons and wallpapers are available. Text formatting and
+other options are taken directly from Scriver or TabSRMM settings.
+Some of TabSRMM features are not supported, for example text indentation.
+Both HTML and CSS styles are automatically generated by IEView.
+
+B) compatibility mode with external CSS
+
+IEView follows SRMM or TabSRMM log formatting settings, but you can change more than
+just colours, because an external, manually adjusted CSS file is used along with computer
+generated HTML code. More information on CSS classes used by IEView are available in included
+CSS examples.
+
+C) template-based mode
+
+IEView does not generate either CSS or HTML, but it uses HTML templates provided
+by the user instead. You can use several variable in templates including message text, date,
+nicknames etc. This part of IEView is still changing, so more information on templates is
+included in a separate file called templates_info.txt.
+
+2. Installation
+---------------
+
+To install IEView please copy ieview.dll and ieview folder into your
+Miranda's plugins directory. Ohter folders included in the pack are as
+follows:
+css - examples of CSS files for tabsrmm, scriver and srmm
+docs - information about templates, translations etc.
+
+In order to use IEView you need Scriver or TabSRMM. Scriver project page is located here:
+http://developer.berlios.de/projects/mgoodies. Scriver v2.2.2.9 or later is recommended.
+If IEVIew is among avtive plugins it will be automatically used by Scriver for message log rendering,
+otherwise regular RichEdit control is used.
+
+In order to use IEView with TabSRMM you need at least TabSRMM 0.9.9.96. Moreover it is necessary
+to turn on support for IEView in TabSRMM configuration.
+Please go to Window Sessions -> Message Window -> Message log options page, locate and
+check "Activate support for external".
+
+3. Configuration
+----------------
+
+Wallpaper - select any image format supported by Internet Explorer (JPG, GIF etc.)
+
+4. FAQ
+------
+Q: Where can I find new versions of IEView, report bugs or request new features ?
+A: http://developer.berlios.de/projects/mgoodies.
+
+Q: Is SmileyAdd required in order to use animated emoticons ?
+A: SmileyAdd is NOT required to see animated emoticons in the log, however,
+ IEView does not provide any button for smiley selection, so no SmileyAdd means no such button.
+
+Q: Does IEView support Unicode ?
+A: Yes, it does.
+
+Q: Does IEView support RTL ?
+A: Yes, it does.
+
+Q: What version of Miranda is required to run IEView ?
+A: IEView DOES require Miranda IM 0.4.
+ It may work with older releases, but there is no guarantee !
+
+Q: I use TabSRMM, why IEView does not work ?
+A: Make sure Window Sessions -> Message Window -> Message log -> Activate support of external log
+ is turned on.
+
+5. Known Issues
+---------------
+
+A) Unicode
+Unicode support in Miranda is rather poor. IEView tries to determin if a message contains Unicode part or not,
+but this may fail sometimes and you will need to switch Unicode off in such cases. There is a possibility to turn
+Unicode off manually in Scriver.
+
+B) Avatars
+Unfortunately each Miranda plugin tends to store avatars in a different way. I am not going to add support
+for all of these possibilities to IEView, because I believe there should be only one standard. As a result
+IEView ALWAYS takes avatars stored in ContactPhoto/File DB entry. TabSRMM, Scriver and mToolTip use this field
+properly and I think authors of other plugins should consider changing their programs in order to use it.
+Alternatively, you may install AvatarService plugin and IEView will automatically detect and use AvatarService.
+
+6. Change Log
+-------------
+1.1.0.0
++ initial support for group chats (compatibility mode)
++ new BBCode - [code]
+* improvements in SmileAdd support
+* improved URL detection
+* improved Jabber chat states handling (patch by Andrey Balaguta)
+* fix for random crash (buffer overflow)
+1.0.9.10
+* support for UTF-8 encoded messages (required by Miranda 0.7 build #30)
+* critical changes in RTL templates (existing template files should be modified and they SHOULD provide HTMLStartRTL, MessageInRTL and MessageOutRTL templates to be recognized as RTL-compliant in the future IEView releases,
+whole layout (including heading - HTMLStartRTL) will change when switching between LTR and RTL contacts, some changes in both TabSRMM and Scriver will be provided in Miranda 0.7 build #31 to improve RTL support in IEView as well)
+* RTL/Grouping info icons
+* removed some redundant reqources
+* other bugfixes
+1.0.9.9
+* bugfixes: TabSRMM compatibility mode, crash on file transfer
+1.0.9.8
+* a lot of bugfixes
+1.0.9.7
+* workaround for Win2k + IE6
+1.0.9.6
+* workaround for IE7 RC1 security issues
+* better support for flash avatars
+* some fixes related to RTL support
+1.0.9.5
++ web browser functionality exposed to other plugins
++ experimental support for Flash avatars
+* RTL support completely changed (see example css and template files)
+* bugfix: #007914 (wrong CP conversion)
+1.0.9.4
++ option to hide window border
+* bugfix: duplicate messages when incorrect smiley pack is used
+1.0.9.3
+* bugfixes: characters allowed in bbcode arguments, incorrect nick name, smiley replacement
+* improved compatibility with Mozilla ActiveX conrol
+1.0.9.2
+* bugfixes
+1.0.9.1
++ [url] bbcode
+* bugfixes
+1.0.9.0
++ flexible, per-protocol settings
++ support for Avatar Service
++ option to replace smileys in nick names
++ support for IEView-based history plugins
+* smileys will not be replaced with "red X" when incompatible emoticon set is used
+* a lot of bugfixes including endless loop when focus was lost
+1.0.5.2
+* bugfix: [bimg]
+1.0.5.1
++ new API for direct event logging (no need to store events in the DB)
++ on-the-fly switching between template and regular mode
++ [bimg] BBCode for showing images with relative paths
+* fixed bug #005790 (Unknown Contact displayed instead of user's id)
+- removed some obsolete options
+1.0.5.0
+- Removed internal support for emoticons (SmileyAdd v0.1.10.1 or higher is now required)
++ option to turn on/off workaround for PNG transparency
++ new BBCode: [s] (strikethrough)
+* workaround for weird bug in _vswnprintf()
+1.0.4.0
++ ME_IEVIEW_OPTIONSCHANGED event
+* improved compatibility with Scriver
+* bugfixes: metacontacts' nicknames, GUI fixes
+1.0.3.9
++ support for Unicode nick names
++ support for png emoticons (thanks to Alex Krivospitsky !)
++ support for drag&drop file transfer
++ possibility to choose smiley selector background color
++ new divUserJoined, divUserLeft, divUserKicked etc. styles (see chat.css)
++ translation file by Raq
+* bugfixes
+1.0.3.8
++ nickOut variable and improved compatibility with metacontacts (patch by Tweety)
++ SHIFT+click opens links and closes message window at the same time
++ option to print log in context menu
++ new smiley configuration page
+* fixed handling of URLs in links
+* fixed some other minor bugs
+1.0.3.7
+* some links were not handled properly
+* fixed Updater compatibility
+1.0.3.6
+* fixed compatibility with TabSRMM
+* bugfix: memory leaks
+1.0.3.5
++ new templates: fileIn, fileOut, hFileIn, hFileOut, URLIn, URLOut, hURLIn, hURLOut
++ new variables: %statusMsg%, %nickIn%, %fileDesc%
++ escaped variables: %\name% %\text% etc.
+* midnight-split message grouping
+* improved Scriver compatibility
+* bugfixes: swf support, memory leaks
+1.0.3.4
++ smileys are now properly copied/quoted (patch by Tweety and Vasilich)
++ uin, uinIn and uinOut variables
+* respective real protocol smileys are used for metacontacts
+* bugfix: message grouping
+* fixed %base% variable encoding
+1.0.3.3
++ support for MathModule (requires MathModule.dll v0.3.1.5 or later)
++ support for Macromedia Flash (.swf) files in smileys and [img] BBCode
++ closing messaging window with ESC key
+* proper handling of "unevenly" aligned BBCodes
+* fixed message grouping
+1.0.3.3
++ support for MathModule (requires MathModule.dll v0.3.1.5 or later)
++ support for Macromedia Flash (.swf) files in smileys and [img] BBCode
++ closing messaging window with ESC key
+* proper handling of "unevenly" aligned BBCodes
+* fixed message grouping
+1.0.3.2
++ support for external CSS files in Tlen group chats
+* rearranged option pages
+* some memory usage optimizations
+1.0.3.1
++ saving images (Save Image As... in context menu)
++ option to replace smileys in user names
+* scrollbar in smiley selection window is visible only when needed
+* fixed encoding of avatar filenames
+* bugfixes in BBCodes support
+1.0.3.0
++ support for (nested) BBCodes ! currently supported: [b][i][u][img][size][color]
++ support for Tlen group chats (requires mucc.dll v1.0.6.2 or higher)
+ support for chat.dll coming soon !
+* bugfixes & improvements
+1.0.2.2
++ internal change: support for getting selected text
++ internal change: support for code page selection
+* better links detection
+* bugfixes
+1.0.2.1
++ support for %%''%% in .asl files
+* fixed UTF8 encoding of date and time
+* other bugfixes
+1.0.2.0
+* improved Unicode support
+* bugfixes
+1.0.1.10
++ Unicode support (I would like to thank Nightwish for his support)
++ RTL support (template and CSS mode)
++ new variables: %avatarIn%, %avatarOut%, %nameIn%, %nameOut%, %proto% (please see ieview-templates.txt for details)
++ auto-scrolling to left
+* bugfixes: memory leaks, focus stealing, message grouping (Nightwish, thanks again) and a lot of other bugfixes
+1.0.1.7
++ animated smileys selection window
+ This feature is not fully available yet, because it requires also changes in TabSRMM source code and
+ you can use it in rather experimental mode at the moment. In order to do that you have to remove
+ SmileyAdd plugin and check "Replace SmileyAdd" on IEVIew->Emoticons options page.
+ Hopefully Nightwish will add support for new IEView smiley selection to TabSRMM soon.
+ Moreover, there is a new setting value available in .asl files. It is called SelectionSize and all
+ authors of .asl files are encouraged to use it in order to finetune the appearance of smileys selection
+ window. Please find more details in emots.asl file included in this package.
+* bugfixes in order to remove crashes and memory leaks in IEView (Nightwish, THX :)
+* better handling of http:// paths to CSS and background image
+* backslashes in URLs are converted to (javascript-friendly) slashes
++ 2 new variables: %avatar% and %cid%
+ %avatar% - link to an avatar file (JPG, GIF etc.), if the file does not exist %avatar% will contain
+ value of %base%/noavatar.jpg.
+ %cid% - contact id, not available in HTMLStart template yet
+
+
+
diff --git a/plugins/IEView/docs/ieview-templates.txt b/plugins/IEView/docs/ieview-templates.txt
new file mode 100644
index 0000000000..e17303a900
--- /dev/null
+++ b/plugins/IEView/docs/ieview-templates.txt
@@ -0,0 +1,92 @@
+Each template begins with template name, which is a special kind of HTML comment, for instance:
+<!--HTMLStart-->
+or
+<!--MessageIn-->
+A template ends whenever a new template begins or EOF is reached.
+
+The following templates may be defined:
+
+<!--HTMLStart-->
+<!--MessageIn-->
+<!--hMessageIn-->
+<!--MessageOut-->
+<!--hMessageOut-->
+<!--File-->
+<!--hFile-->
+<!--URL-->
+<!--hURL-->
+<!--Status-->
+<!--hStatus-->
+<!--MessageInGroupStart-->
+<!--MessageInGroupInner-->
+<!--MessageInGroupEnd-->
+<!--hMessageInGroupStart-->
+<!--hMessageInGroupInner-->
+<!--hMessageInGroupEnd-->
+<!--MessageOutGroupStart-->
+<!--MessageOutGroupInner-->
+<!--MessageOutGroupEnd-->
+<!--hMessageOutGroupStart-->
+<!--hMessageOutGroupInner-->
+<!--hMessageOutGroupEnd-->
+
+<!--HTMLStartRTL-->
+<!--MessageInRTL-->
+<!--hMessageInRTL-->
+<!--MessageOutRTL-->
+<!--hMessageOutRTL-->
+<!--MessageInGroupStartRTL-->
+<!--MessageInGroupInnerRTL-->
+<!--MessageInGroupEndRTL-->
+<!--hMessageInGroupStartRTL-->
+<!--hMessageInGroupInnerRTL-->
+<!--hMessageInGroupEndRTL-->
+<!--MessageOutGroupStartRTL-->
+<!--MessageOutGroupInnerRTL-->
+<!--MessageOutGroupEndRTL-->
+<!--hMessageOutGroupStartRTL-->
+<!--hMessageOutGroupInnerRTL-->
+<!--hMessageOutGroupEndRTL-->
+
+
+All templates of which names begin with 'h' are used to display historical events.
+
+If a template is not present the corresponding event will not be shown in the log at all !
+
+The following variables are available in all templates EXCEPT HTMLStart:
+%base% - base URL
+%name% - contact's name or user's name (depends on context)
+%time% - event's time
+%date% - event's date
+%text% - event's text
+%cid% - contact's ID or user's ID (depends on context)
+%avatar% - link to contact's picture file or user's picure file (depends on context)
+%avatarIn% - link to contact's picture
+%avatarOut% - link to user's picture
+%nameIn% - contact's name
+%nameOut% - users's name
+%proto% - protocol name
+%uin% - contact's ID or user's ID
+%uinIn% - contact's ID
+%uinOut% - user's ID
+%nick% - contact's nick name or user's nick name
+%nickIn% - contact's nick name
+%nickOut% - user's nick name
+%statusMsg% - contact's status message
+%fileDesc% - file description
+
+The following variables are available in HTMLStart:
+%base% - base URL (this variable should be used in <base> tag)
+%avatarIn% - link to contact's picture
+%avatarOut% - link to user's picture
+%nameIn% - contact's name
+%nameOut% - users's name
+%nickIn% - contact's nick name
+%nickOut% - user's nick name
+%uinIn% - contact's ID
+%uinOut% - user's ID
+%proto% - protocol name
+
+All tokens are also available in Javascript friendly (escaped) form.
+In that case please use the follwoing token names: %\base%, %\time%, %\name% etc.
+
diff --git a/plugins/IEView/docs/ieview-translation.txt b/plugins/IEView/docs/ieview-translation.txt
new file mode 100644
index 0000000000..51f89bcde0
--- /dev/null
+++ b/plugins/IEView/docs/ieview-translation.txt
@@ -0,0 +1,38 @@
+;****************************
+;*** IEView Plugin [1.0.3.5]
+; Author: raq <braq@wp.pl>
+;****************************
+
+[IEView plugin]
+[General]
+[Options]
+[Enable BBCodes]
+[Currently the following BBCodes are supported: [b][i][u][img][size][color]]
+[Enable support for Flash files in smileys and BBCodes]
+[Enable MathModule support]
+[Message Log]
+[Mode]
+[Background image]
+[Scroll with text]
+[External CSS file]
+[Templates]
+[Events To Show]
+[Show file events]
+[Show url events]
+[Show status changes]
+[Log Options]
+[Show nicknames]
+[Show time]
+[Show seconds]
+[Show date]
+[Use long date format]
+[Use relative timestamp]
+[Use message grouping]
+[Emotikons]
+[Animated Smiley Libraries]
+[Enable smiley replacement]
+[Specify library for each protocol]
+[Only replace isolated smileys]
+[Surround smileys with spaces]
+[Replace smileys in user names]
+[Group Chats]
diff --git a/plugins/IEView/docs/scriver.css b/plugins/IEView/docs/scriver.css
new file mode 100644
index 0000000000..79ae91886d
--- /dev/null
+++ b/plugins/IEView/docs/scriver.css
@@ -0,0 +1,51 @@
+/* this changes the way main window background looks like */
+.body {margin-left: 0px; margin-right: 0px; margin-top: 0px; margin-bottom: 0px; text-align: left; background-attachment: scroll; background-color: #FFFFFF; background-image: url(D:\mim\mim_bkg.jpg); overflow: auto;}
+/* this changes the way your links look like */
+.link {color: #0000FF; text-decoration: underline;}
+/* this changes the way smileys and log icons look like */
+.img {vertical-align: middle;}
+/* this changes the way incoming (received) events look like including timestamp, name, etc. */
+.divIn {word-wrap: break-word; background-color: #FFFFFF;}
+/* this changes the way outgoing (sent) events look like including timestamp, name, etc. */
+.divOut {word-wrap: break-word; background-color: #FFFFFF;}
+/* this changes the way incoming (received) events look like including timestamp, name, etc. */
+.divInGrid {padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #000000; background-color: #FFFFFF;}
+/* this changes the way outgoing (sent) events look like including timestamp, name, etc. */
+.divOutGrid {padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #000000; background-color: #FFFFFF;}
+/* this changes the way incoming (received) events look like including timestamp, name, etc. */
+.divNotice {padding-left: 2px; padding-right: 2px; word-wrap: break-word;}
+/* this changes the way outgoing (sent) events look like including timestamp, name, etc. */
+.divNoticeGrid {padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #000000}
+/* this changes the way outgoing (sent by you) messages look like */
+.messageOut {font-family: Arial; font-size: 12pt; font-weight: 900; color: #6A6A6A; }
+/* this changes the way incoming (received from your contact) messages look like */
+.messageIn {font-family: Arial; font-size: 12pt; font-weight: 300; color: #000000; font-style: italic}
+/* this changes the way your name looks like in outgoing events */
+.nameOut {font-family: Arial; font-size: 12pt; font-weight: 900; color: #5369C1; }
+/* this changes the way timestamp looks like in outgoing events */
+.timeOut {font-family: Terminal; font-size: 9pt; font-weight: 900; color: #74B928; }
+/* this changes the way a colon looks like in outgoing events */
+.colonOut {font-family: Arial; font-size: 11pt; font-weight: 900; color: #56C099; }
+/* this changes the way a contact's name looks like in incoming events */
+.nameIn {font-family: Arial; font-size: 12pt; font-weight: 900; color: #D70000; }
+/* this changes the way timestamp looks like in incoming events */
+.timeIn {font-family: Terminal; font-size: 9pt; font-weight: 900; color: #000000; }
+/* this changes the way a colon looks like in incoming events */
+.colonIn {font-family: Arial; font-size: 11pt; font-weight: 900; color: #B96A8D; font-style: italic}
+/* NOT USED */
+.inputArea {font-family: Arial; font-size: 12pt; font-weight: 300; color: #000000; }
+/* this changes the way status change event look like */
+.notices {font-family: Arial; font-size: 12pt; font-weight: 300; color: #5A5AA0; }
+/* RTL-related styles */
+/* this changes the way incoming (received) events look like including timestamp, name, etc. */
+.divInRTL {text-align: right; direction:RTL; unicode-bidi:embed; word-wrap: break-word; background-color: #FFFFFF;}
+/* this changes the way outgoing (sent) events look like including timestamp, name, etc. */
+.divOutRTL {text-align: right; direction:RTL; unicode-bidi:embed; word-wrap: break-word; background-color: #FFFFFF;}
+/* this changes the way incoming (received) events look like including timestamp, name, etc. */
+.divInGridRTL {text-align: right; direction:RTL; unicode-bidi:embed; padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #000000; background-color: #FFFFFF;}
+/* this changes the way outgoing (sent) events look like including timestamp, name, etc. */
+.divOutGridRTL {text-align: right; direction:RTL; unicode-bidi:embed; padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #000000; background-color: #FFFFFF;}
+/* this changes the way incoming (received) events look like including timestamp, name, etc. */
+.divNoticeRTL {text-align: right; direction:RTL; unicode-bidi:embed; padding-left: 2px; padding-right: 2px; word-wrap: break-word;}
+/* this changes the way outgoing (sent) events look like including timestamp, name, etc. */
+.divNoticeGridRTL {text-align: right; direction:RTL; unicode-bidi:embed; padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #000000}
diff --git a/plugins/IEView/docs/srmm.css b/plugins/IEView/docs/srmm.css
new file mode 100644
index 0000000000..ad5fadeb49
--- /dev/null
+++ b/plugins/IEView/docs/srmm.css
@@ -0,0 +1,36 @@
+/* this changes the way main window background looks like */
+.body {margin-left: 0px; margin-right: 0px; margin-top: 0px; margin-bottom: 0px; text-align: left; background-attachment: scroll; background-color: #FFFFFF; background-image: url(D:\mim\mim_bkg.jpg); overflow: auto;}
+/* this changes the way your links look like */
+.link {color: #0000FF; text-decoration: underline;}
+/* this changes the way smileys and log icons look like */
+.img {vertical-align: middle;}
+/* this changes the way incoming (received) events look like including timestamp, name, etc. */
+.divIn {word-wrap: break-word; background-color: #FFFFFF;}
+/* this changes the way outgoing (sent) events look like including timestamp, name, etc. */
+.divOut {word-wrap: break-word; background-color: #FFFFFF;}
+/* this changes the way outgoing (sent by you) messages look like */
+.messageOut {font-family: Arial; font-size: 12pt; font-weight: 900; color: #6A6A6A; }
+/* this changes the way incoming (received from your contact) messages look like */
+.messageIn {font-family: Arial; font-size: 12pt; font-weight: 300; color: #000000; font-style: italic}
+/* this changes the way your name looks like in outgoing events */
+.nameOut {font-family: Arial; font-size: 12pt; font-weight: 900; color: #5369C1; }
+/* this changes the way timestamp looks like in outgoing events */
+.timeOut {font-family: Terminal; font-size: 9pt; font-weight: 900; color: #74B928; }
+/* this changes the way a colon looks like in outgoing events */
+.colonOut {font-family: Arial; font-size: 11pt; font-weight: 900; color: #56C099; }
+/* this changes the way a contact's name looks like in incoming events */
+.nameIn {font-family: Arial; font-size: 12pt; font-weight: 900; color: #D70000; }
+/* this changes the way timestamp looks like in incoming events */
+.timeIn {font-family: Terminal; font-size: 9pt; font-weight: 900; color: #000000; }
+/* this changes the way a colon looks like in incoming events */
+.colonIn {font-family: Arial; font-size: 11pt; font-weight: 900; color: #B96A8D; font-style: italic}
+/* NOT USED */
+.inputArea {font-family: Arial; font-size: 12pt; font-weight: 300; color: #000000; }
+/* this changes the way status change event look like */
+.notices {font-family: Arial; font-size: 12pt; font-weight: 300; color: #5A5AA0; }
+
+/* RTL-related styles */
+/* this changes the way incoming (received) events look like including timestamp, name, etc. */
+.divInRTL {text-align: right; direction:RTL; unicode-bidi:embed; word-wrap: break-word; background-color: #FFFFFF;}
+/* this changes the way outgoing (sent) events look like including timestamp, name, etc. */
+.divOutRTL {text-align: right; direction:RTL; unicode-bidi:embed; word-wrap: break-word; background-color: #FFFFFF;}
diff --git a/plugins/IEView/docs/tabsrmm.css b/plugins/IEView/docs/tabsrmm.css
new file mode 100644
index 0000000000..2e3ed0d858
--- /dev/null
+++ b/plugins/IEView/docs/tabsrmm.css
@@ -0,0 +1,61 @@
+/* this changes the way main window background looks like */
+.body {margin-left: 0px; margin-right: 0px; margin-top: 0px; margin-bottom: 0px; text-align: left; background-color: #924AB0; overflow: auto;}
+/* this changes the way your links look like */
+.link {color: #0000FF; text-decoration: underline;}
+/* this changes the way smileys and log icons look like */
+.img {vertical-align: middle;}
+/* this changes the way incoming (received) events look like including timestamp, name, etc. */
+.divIn {word-wrap: break-word; background-color: #F0E399;}
+/* this changes the way outgoing (sent) events look like including timestamp, name, etc. */
+.divOut {word-wrap: break-word; background-color: #7DC6D2;}
+/* the same as divIn, but used when Draw grid lines option is turned on */
+.divInGrid {word-wrap: break-word; border-top: 1px solid #924AB0; background-color: #F0E399;}
+/* the same as divIn, but used when Draw grid lines option is turned on */
+.divOutGrid {word-wrap: break-word; border-top: 1px solid #924AB0; background-color: #7DC6D2;}
+/* this changes the way new outgoing (sent by you) messages look like */
+.messageOut {font-family: Tahoma; font-size: 13pt; font-weight: 300; color: #000000; }
+/* this changes the way outgoing (sent) file events and url events look like - NOT USED */
+.miscOut {font-family: Tahoma; font-size: 13pt; font-weight: 300; color: #C632D1; font-style: italic}
+/* this changes the way new incoming (received from your contact) messages look like */
+.messageIn {font-family: Tahoma; font-size: 13pt; font-weight: 300; color: #A81A3E; }
+/* this changes the way new incoming file events and url events look like */
+.miscIn {font-family: Tahoma; font-size: 13pt; font-weight: 300; color: #5581D2; font-style: italic}
+/* this changes the way your name looks like in new outgoing events */
+.nameOut {font-family: Tahoma; font-size: 13pt; font-weight: 900; color: #223CB3; }
+/* this changes the way a timestamp looks like in new outgoing events */
+.timeOut {font-family: Tahoma; font-size: 8pt; font-weight: 900; color: #808080; }
+/* this changes the way a contact's name looks like in new incoming events */
+.nameIn {font-family: Tahoma; font-size: 10pt; font-weight: 300; color: #000000; }
+/* this changes the way timestamp looks like in new incoming events */
+.timeIn {font-family: Tahoma; font-size: 8pt; font-weight: 900; color: #526F70; }
+/* this changes the way historical outgoing messages look like */
+.hMessageOut {font-family: Tahoma; font-size: 13pt; font-weight: 300; color: #000000; }
+/* this changes the way historical outgoing file events and url events look like - NOT USED */
+.hMiscOut {font-family: Tahoma; font-size: 13pt; font-weight: 300; color: #000000; }
+/* this changes the way historical incoming messages look like */
+.hMessageIn {font-family: Tahoma; font-size: 13pt; font-weight: 300; color: #000000; }
+/* this changes the way historical incoming file events and url events look like */
+.hMiscIn {font-family: Tahoma; font-size: 13pt; font-weight: 300; color: #3F65BE; font-style: italic}
+/* this changes the way your name looks like in historical events */
+.hNameOut {font-family: Tahoma; font-size: 13pt; font-weight: 300; color: #000000; }
+/* this changes the way a timestamp looks like in historical outgoing events */
+.hTimeOut {font-family: Tahoma; font-size: 13pt; font-weight: 300; color: #000000; }
+/* this changes the way a contact's name looks like in incoming events */
+.hNameIn {font-family: Tahoma; font-size: 13pt; font-weight: 300; color: #000000; }
+/* this changes the way a timestamp looks like in incoming events */
+.hTimeIn {font-family: Tahoma; font-size: 13pt; font-weight: 300; color: #A81A3E; }
+/* NOT USED */
+.inputArea {font-family: Tahoma; font-size: 13pt; font-weight: 300; color: #000000; }
+/* this changes the way status change events look like */
+.statusChange {font-family: Tahoma; font-size: 13pt; font-weight: 300; color: #000000; }
+/* NOT USED */
+.dividers {font-family: Tahoma; font-size: 13pt; font-weight: 300; color: #55B9B4; }
+/* RTL-related styles */
+/* this changes the way incoming (received) events look like including timestamp, name, etc. */
+.divInRTL {text-align: right; direction:RTL; unicode-bidi:embed; word-wrap: break-word; background-color: #FFFFFF;}
+/* this changes the way outgoing (sent) events look like including timestamp, name, etc. */
+.divOutRTL {text-align: right; direction:RTL; unicode-bidi:embed; word-wrap: break-word; background-color: #FFFFFF;}
+/* this changes the way incoming (received) events look like including timestamp, name, etc. */
+.divInGridRTL {text-align: right; direction:RTL; unicode-bidi:embed; padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #000000; background-color: #FFFFFF;}
+/* this changes the way outgoing (sent) events look like including timestamp, name, etc. */
+.divOutGridRTL {text-align: right; direction:RTL; unicode-bidi:embed; padding-left: 2px; padding-right: 2px; word-wrap: break-word; border-top: 1px solid #000000; background-color: #FFFFFF;}
diff --git a/plugins/IEView/icos/action.gif b/plugins/IEView/icos/action.gif
new file mode 100644
index 0000000000..75c18b0b0d
--- /dev/null
+++ b/plugins/IEView/icos/action.gif
Binary files differ
diff --git a/plugins/IEView/icos/addstatus.gif b/plugins/IEView/icos/addstatus.gif
new file mode 100644
index 0000000000..d60cc79415
--- /dev/null
+++ b/plugins/IEView/icos/addstatus.gif
Binary files differ
diff --git a/plugins/IEView/icos/file.gif b/plugins/IEView/icos/file.gif
new file mode 100644
index 0000000000..8e24842ef4
--- /dev/null
+++ b/plugins/IEView/icos/file.gif
Binary files differ
diff --git a/plugins/IEView/icos/group_off.ico b/plugins/IEView/icos/group_off.ico
new file mode 100644
index 0000000000..da10759109
--- /dev/null
+++ b/plugins/IEView/icos/group_off.ico
Binary files differ
diff --git a/plugins/IEView/icos/group_on.ico b/plugins/IEView/icos/group_on.ico
new file mode 100644
index 0000000000..aae912eef3
--- /dev/null
+++ b/plugins/IEView/icos/group_on.ico
Binary files differ
diff --git a/plugins/IEView/icos/info.gif b/plugins/IEView/icos/info.gif
new file mode 100644
index 0000000000..17784ec925
--- /dev/null
+++ b/plugins/IEView/icos/info.gif
Binary files differ
diff --git a/plugins/IEView/icos/join.gif b/plugins/IEView/icos/join.gif
new file mode 100644
index 0000000000..3350e82278
--- /dev/null
+++ b/plugins/IEView/icos/join.gif
Binary files differ
diff --git a/plugins/IEView/icos/kick.gif b/plugins/IEView/icos/kick.gif
new file mode 100644
index 0000000000..16d1e821f0
--- /dev/null
+++ b/plugins/IEView/icos/kick.gif
Binary files differ
diff --git a/plugins/IEView/icos/message_in.gif b/plugins/IEView/icos/message_in.gif
new file mode 100644
index 0000000000..ebf9e1b378
--- /dev/null
+++ b/plugins/IEView/icos/message_in.gif
Binary files differ
diff --git a/plugins/IEView/icos/message_in_chat.gif b/plugins/IEView/icos/message_in_chat.gif
new file mode 100644
index 0000000000..04fd84cc0e
--- /dev/null
+++ b/plugins/IEView/icos/message_in_chat.gif
Binary files differ
diff --git a/plugins/IEView/icos/message_out.gif b/plugins/IEView/icos/message_out.gif
new file mode 100644
index 0000000000..2ae3b0e325
--- /dev/null
+++ b/plugins/IEView/icos/message_out.gif
Binary files differ
diff --git a/plugins/IEView/icos/message_out_chat.gif b/plugins/IEView/icos/message_out_chat.gif
new file mode 100644
index 0000000000..a853dec875
--- /dev/null
+++ b/plugins/IEView/icos/message_out_chat.gif
Binary files differ
diff --git a/plugins/IEView/icos/nick.gif b/plugins/IEView/icos/nick.gif
new file mode 100644
index 0000000000..dba582fa61
--- /dev/null
+++ b/plugins/IEView/icos/nick.gif
Binary files differ
diff --git a/plugins/IEView/icos/notice.gif b/plugins/IEView/icos/notice.gif
new file mode 100644
index 0000000000..efff0234bc
--- /dev/null
+++ b/plugins/IEView/icos/notice.gif
Binary files differ
diff --git a/plugins/IEView/icos/part.gif b/plugins/IEView/icos/part.gif
new file mode 100644
index 0000000000..00b461381a
--- /dev/null
+++ b/plugins/IEView/icos/part.gif
Binary files differ
diff --git a/plugins/IEView/icos/quit.gif b/plugins/IEView/icos/quit.gif
new file mode 100644
index 0000000000..533f0ede16
--- /dev/null
+++ b/plugins/IEView/icos/quit.gif
Binary files differ
diff --git a/plugins/IEView/icos/removestatus.gif b/plugins/IEView/icos/removestatus.gif
new file mode 100644
index 0000000000..6caf327b94
--- /dev/null
+++ b/plugins/IEView/icos/removestatus.gif
Binary files differ
diff --git a/plugins/IEView/icos/rtl_off.ico b/plugins/IEView/icos/rtl_off.ico
new file mode 100644
index 0000000000..836357fcd7
--- /dev/null
+++ b/plugins/IEView/icos/rtl_off.ico
Binary files differ
diff --git a/plugins/IEView/icos/rtl_on.ico b/plugins/IEView/icos/rtl_on.ico
new file mode 100644
index 0000000000..ec151abfbb
--- /dev/null
+++ b/plugins/IEView/icos/rtl_on.ico
Binary files differ
diff --git a/plugins/IEView/icos/status.gif b/plugins/IEView/icos/status.gif
new file mode 100644
index 0000000000..e0ff3923f1
--- /dev/null
+++ b/plugins/IEView/icos/status.gif
Binary files differ
diff --git a/plugins/IEView/icos/topic.gif b/plugins/IEView/icos/topic.gif
new file mode 100644
index 0000000000..b2157abc53
--- /dev/null
+++ b/plugins/IEView/icos/topic.gif
Binary files differ
diff --git a/plugins/IEView/icos/url.gif b/plugins/IEView/icos/url.gif
new file mode 100644
index 0000000000..67e7fa75aa
--- /dev/null
+++ b/plugins/IEView/icos/url.gif
Binary files differ
diff --git a/plugins/IEView/ieview.rc b/plugins/IEView/ieview.rc
new file mode 100644
index 0000000000..68a498c834
--- /dev/null
+++ b/plugins/IEView/ieview.rc
@@ -0,0 +1,150 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// àíãëèéñêèé (ÑØÀ) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_CONTEXTMENU MENU
+BEGIN
+ POPUP "", MENUBREAK
+ BEGIN
+ MENUITEM "Copy", ID_MENU_COPY, GRAYED
+ MENUITEM "Copy Link", ID_MENU_COPYLINK, GRAYED
+ MENUITEM SEPARATOR
+ MENUITEM "Select All", ID_MENU_SELECTALL
+ MENUITEM SEPARATOR
+ MENUITEM "Save Image As...", ID_MENU_SAVEIMAGE, GRAYED
+ MENUITEM SEPARATOR
+ MENUITEM "Print", ID_MENU_PRINT
+ MENUITEM "Clear Log", ID_MENU_CLEARLOG
+ MENUITEM "Show source", ID_MENU_SHOWSOURCE
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_RTL_ON ICON "icos/rtl_on.ico"
+IDI_RTL_OFF ICON "icos/rtl_off.ico"
+IDI_GROUP_ON ICON "icos/group_on.ico"
+IDI_GROUP_OFF ICON "icos/group_off.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_GENERAL_OPTIONS DIALOGEX 0, 0, 306, 228
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Options",IDC_STATIC,4,2,297,155
+ CONTROL "Enable BBCodes",IDC_ENABLE_BBCODES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,19,265,10
+ LTEXT "Currently the following BBCodes are supported: [b][i][u][s][img][size][color][url]",IDC_STATIC,26,31,265,12
+ CONTROL "Enable support for Flash files in smileys and BBCodes",IDC_ENABLE_FLASH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,46,265,10
+ CONTROL "Enable workaround for PNG transparency",IDC_ENABLE_PNGHACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,61,265,10
+ CONTROL "Enable MathModule support",IDC_ENABLE_MATHMODULE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,76,265,10
+ CONTROL "Replace smileys in user names",IDC_SMILEYS_IN_NAMES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,91,265,10
+ CONTROL "Hide window border",IDC_NO_BORDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,106,265,10
+ CONTROL "Embed YouTube videos",IDC_ENABLE_EMBED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,121,265,10
+ LTEXT "Size:",IDC_STATIC,26,138,30,8
+ COMBOBOX IDC_EMBED_SIZE,57,136,56,130,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+END
+
+IDD_SRMM_OPTIONS DIALOGEX 0, 0, 306, 228
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Mode",IDC_STATIC,4,2,297,222
+ CONTROL "Compatibility Mode",IDC_MODE_COMPATIBLE,"Button",BS_AUTORADIOBUTTON,118,15,100,10
+ CONTROL "Use External CSS",IDC_MODE_CSS,"Button",BS_AUTORADIOBUTTON,118,58,86,10
+ CONTROL "Use Templates",IDC_MODE_TEMPLATE,"Button",BS_AUTORADIOBUTTON,118,112,86,10
+ CONTROL "",IDC_PROTOLIST,"SysTreeView32",TVS_DISABLEDRAGDROP | TVS_SHOWSELALWAYS | TVS_CHECKBOXES | WS_BORDER | WS_HSCROLL | WS_TABSTOP,10,15,100,143
+ CONTROL "Background image",IDC_BACKGROUND_IMAGE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,26,86,10
+ CONTROL "Scroll with text",IDC_SCROLL_BACKGROUND_IMAGE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,206,26,93,10
+ EDITTEXT IDC_BACKGROUND_IMAGE_FILENAME,118,36,153,12,ES_AUTOHSCROLL
+ PUSHBUTTON "...",IDC_BROWSE_BACKGROUND_IMAGE,278,36,15,11
+ EDITTEXT IDC_EXTERNALCSS_FILENAME,118,68,153,12,ES_AUTOHSCROLL
+ PUSHBUTTON "...",IDC_BROWSE_EXTERNALCSS,278,68,15,11
+ EDITTEXT IDC_TEMPLATES_FILENAME,118,122,153,12,ES_AUTOHSCROLL
+ PUSHBUTTON "...",IDC_BROWSE_TEMPLATES,278,122,15,11
+ ICON IDI_GROUP_OFF,IDC_GROUPSUPPORT,245,135,20,20
+ ICON IDI_RTL_OFF,IDC_RTLSUPPORT,260,135,20,20
+ GROUPBOX "Template Options",IDC_STATIC,10,161,284,57
+ CONTROL "Use message grouping",IDC_LOG_GROUP_MESSAGES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,173,125,10
+ CONTROL "Show nicknames",IDC_LOG_SHOW_NICKNAMES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,183,125,10
+ CONTROL "Show time",IDC_LOG_SHOW_TIME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,193,125,10
+ CONTROL "Show seconds",IDC_LOG_SHOW_SECONDS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,30,203,110,10
+ CONTROL "Show date",IDC_LOG_SHOW_DATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,145,173,120,10
+ CONTROL "Use long date format",IDC_LOG_LONG_DATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,157,183,110,10
+ CONTROL "Use relative timestamp",IDC_LOG_RELATIVE_DATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,157,193,110,10
+END
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // àíãëèéñêèé (ÑØÀ) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plugins/IEView/ieview.sln b/plugins/IEView/ieview.sln
new file mode 100644
index 0000000000..0c87507d40
--- /dev/null
+++ b/plugins/IEView/ieview.sln
@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ieview", "ieview.vcxproj", "{B988F96C-F87A-484C-AB15-D0674B22F291}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug Unicode|Win32 = Debug Unicode|Win32
+ Debug Unicode|x64 = Debug Unicode|x64
+ Release Unicode|Win32 = Release Unicode|Win32
+ Release Unicode|x64 = Release Unicode|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B988F96C-F87A-484C-AB15-D0674B22F291}.Debug Unicode|Win32.ActiveCfg = Debug Unicode|Win32
+ {B988F96C-F87A-484C-AB15-D0674B22F291}.Debug Unicode|Win32.Build.0 = Debug Unicode|Win32
+ {B988F96C-F87A-484C-AB15-D0674B22F291}.Debug Unicode|x64.ActiveCfg = Debug Unicode|x64
+ {B988F96C-F87A-484C-AB15-D0674B22F291}.Debug Unicode|x64.Build.0 = Debug Unicode|x64
+ {B988F96C-F87A-484C-AB15-D0674B22F291}.Release Unicode|Win32.ActiveCfg = Release Unicode|Win32
+ {B988F96C-F87A-484C-AB15-D0674B22F291}.Release Unicode|Win32.Build.0 = Release Unicode|Win32
+ {B988F96C-F87A-484C-AB15-D0674B22F291}.Release Unicode|x64.ActiveCfg = Release Unicode|x64
+ {B988F96C-F87A-484C-AB15-D0674B22F291}.Release Unicode|x64.Build.0 = Release Unicode|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/plugins/IEView/ieview.vcproj b/plugins/IEView/ieview.vcproj
new file mode 100644
index 0000000000..ac243de614
--- /dev/null
+++ b/plugins/IEView/ieview.vcproj
@@ -0,0 +1,334 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="ieview"
+ ProjectGUID="{B988F96C-F87A-484C-AB15-D0674B22F291}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include;../ExternalAPI"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;IEVIEW_EXPORTS;"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="0"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="comctl32.lib"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ FavorSizeOrSpeed="2"
+ WholeProgramOptimization="FALSE"
+ AdditionalIncludeDirectories="../../include;../ExternalAPI"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;IEVIEW_EXPORTS;"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="comctl32.lib"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Debug Unicode|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include;../ExternalAPI"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;IEVIEW_EXPORTS;"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="0"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="comctl32.lib"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release Unicode|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ GlobalOptimizations="TRUE"
+ FavorSizeOrSpeed="2"
+ WholeProgramOptimization="FALSE"
+ AdditionalIncludeDirectories="../../include;../ExternalAPI"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;IEVIEW_EXPORTS;"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="comctl32.lib"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath=".\ChatHTMLBuilder.h">
+ </File>
+ <File
+ RelativePath=".\HistoryHTMLBuilder.h">
+ </File>
+ <File
+ RelativePath=".\HTMLBuilder.h">
+ </File>
+ <File
+ RelativePath=".\IEView.h">
+ </File>
+ <File
+ RelativePath=".\ieview_common.h">
+ </File>
+ <File
+ RelativePath=".\ieview_private.h">
+ </File>
+ <File
+ RelativePath=".\ieview_services.h">
+ </File>
+ <File
+ RelativePath=".\m_avatars.h">
+ </File>
+ <File
+ RelativePath=".\m_ieview.h">
+ </File>
+ <File
+ RelativePath=".\m_MathModule.h">
+ </File>
+ <File
+ RelativePath=".\m_metacontacts.h">
+ </File>
+ <File
+ RelativePath=".\m_smileyadd.h">
+ </File>
+ <File
+ RelativePath=".\mshtmhst.h">
+ </File>
+ <File
+ RelativePath=".\MUCCHTMLBuilder.h">
+ </File>
+ <File
+ RelativePath=".\Options.h">
+ </File>
+ <File
+ RelativePath=".\resource.h">
+ </File>
+ <File
+ RelativePath=".\ScriverHTMLBuilder.h">
+ </File>
+ <File
+ RelativePath=".\TabSRMMHTMLBuilder.h">
+ </File>
+ <File
+ RelativePath=".\Template.h">
+ </File>
+ <File
+ RelativePath=".\TemplateHTMLBuilder.h">
+ </File>
+ <File
+ RelativePath=".\Utils.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ <File
+ RelativePath=".\ieview.rc">
+ </File>
+ </Filter>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath=".\ChatHTMLBuilder.cpp">
+ </File>
+ <File
+ RelativePath=".\HistoryHTMLBuilder.cpp">
+ </File>
+ <File
+ RelativePath=".\HTMLBuilder.cpp">
+ </File>
+ <File
+ RelativePath=".\IEView.cpp">
+ </File>
+ <File
+ RelativePath=".\ieview_main.cpp">
+ </File>
+ <File
+ RelativePath=".\ieview_services.cpp">
+ </File>
+ <File
+ RelativePath=".\MUCCHTMLBuilder.cpp">
+ </File>
+ <File
+ RelativePath=".\Options.cpp">
+ </File>
+ <File
+ RelativePath=".\ScriverHTMLBuilder.cpp">
+ </File>
+ <File
+ RelativePath=".\TabSRMMHTMLBuilder.cpp">
+ </File>
+ <File
+ RelativePath=".\Template.cpp">
+ </File>
+ <File
+ RelativePath=".\TemplateHTMLBuilder.cpp">
+ </File>
+ <File
+ RelativePath=".\Utils.cpp">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/plugins/IEView/ieview.vcxproj b/plugins/IEView/ieview.vcxproj
new file mode 100644
index 0000000000..d4ea767a2d
--- /dev/null
+++ b/plugins/IEView/ieview.vcxproj
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug Unicode|Win32">
+ <Configuration>Debug Unicode</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug Unicode|x64">
+ <Configuration>Debug Unicode</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|Win32">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|x64">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{B988F96C-F87A-484C-AB15-D0674B22F291}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">$(SolutionDir)$(Configuration)64/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">$(SolutionDir)$(Configuration)64/Obj/$(ProjectName)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">$(SolutionDir)$(Configuration)64/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">$(SolutionDir)$(Configuration)64/Obj/$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;IEVIEW_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;IEVIEW_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>TurnOffAllWarnings</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;IEVIEW_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX86</TargetMachine>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;IEVIEW_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="ChatHTMLBuilder.h" />
+ <ClInclude Include="HistoryHTMLBuilder.h" />
+ <ClInclude Include="HTMLBuilder.h" />
+ <ClInclude Include="IEView.h" />
+ <ClInclude Include="ieview_common.h" />
+ <ClInclude Include="ieview_services.h" />
+ <ClInclude Include="m_avatars.h" />
+ <ClInclude Include="m_ieview.h" />
+ <ClInclude Include="m_MathModule.h" />
+ <ClInclude Include="m_metacontacts.h" />
+ <ClInclude Include="m_smileyadd.h" />
+ <ClInclude Include="MUCCHTMLBuilder.h" />
+ <ClInclude Include="Options.h" />
+ <ClInclude Include="resource.h" />
+ <ClInclude Include="ScriverHTMLBuilder.h" />
+ <ClInclude Include="TabSRMMHTMLBuilder.h" />
+ <ClInclude Include="Template.h" />
+ <ClInclude Include="TemplateHTMLBuilder.h" />
+ <ClInclude Include="TextToken.h" />
+ <ClInclude Include="Utils.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="ieview.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="ChatHTMLBuilder.cpp" />
+ <ClCompile Include="HistoryHTMLBuilder.cpp" />
+ <ClCompile Include="HTMLBuilder.cpp" />
+ <ClCompile Include="IEView.cpp" />
+ <ClCompile Include="ieview_main.cpp" />
+ <ClCompile Include="ieview_services.cpp" />
+ <ClCompile Include="MUCCHTMLBuilder.cpp" />
+ <ClCompile Include="Options.cpp" />
+ <ClCompile Include="ScriverHTMLBuilder.cpp" />
+ <ClCompile Include="TabSRMMHTMLBuilder.cpp" />
+ <ClCompile Include="Template.cpp" />
+ <ClCompile Include="TemplateHTMLBuilder.cpp" />
+ <ClCompile Include="TextToken.cpp" />
+ <ClCompile Include="Utils.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/IEView/ieview.vcxproj.filters b/plugins/IEView/ieview.vcxproj.filters
new file mode 100644
index 0000000000..022cb3c0f2
--- /dev/null
+++ b/plugins/IEView/ieview.vcxproj.filters
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="ChatHTMLBuilder.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="HistoryHTMLBuilder.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="HTMLBuilder.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="IEView.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ieview_main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ieview_services.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="MUCCHTMLBuilder.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Options.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ScriverHTMLBuilder.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="TabSRMMHTMLBuilder.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Template.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="TemplateHTMLBuilder.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="TextToken.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Utils.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="ChatHTMLBuilder.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="HistoryHTMLBuilder.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="HTMLBuilder.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="IEView.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ieview_common.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ieview_services.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="MUCCHTMLBuilder.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Options.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ScriverHTMLBuilder.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="TabSRMMHTMLBuilder.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Template.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="TemplateHTMLBuilder.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="TextToken.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Utils.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="m_avatars.h" />
+ <ClInclude Include="m_ieview.h" />
+ <ClInclude Include="m_MathModule.h" />
+ <ClInclude Include="m_metacontacts.h" />
+ <ClInclude Include="m_smileyadd.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="ieview.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{a72da5d2-0d60-47f9-afae-fbccf75ff6c7}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{7fb0c9c3-1e65-40e9-8b79-b660578ee919}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{4691e0ac-0fe6-41ec-abe1-aca54f39e986}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/IEView/ieview_common.h b/plugins/IEView/ieview_common.h
new file mode 100644
index 0000000000..4be574b7d7
--- /dev/null
+++ b/plugins/IEView/ieview_common.h
@@ -0,0 +1,74 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+#if defined( UNICODE ) && !defined( _UNICODE )
+ #define _UNICODE
+#endif
+#ifdef __MINGW32__
+ #define WINVER 0x500
+ #define _WIN32_IE 0x500
+ #define __try
+ #define __except(a)
+#endif
+
+#ifndef IEVIEW_COMMON_H
+#define IEVIEW_COMMON_H
+
+#define MIRANDA_VER 0x0A00
+
+#include <windows.h>
+#include <commctrl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <process.h>
+#include <shlguid.h>
+#include <oleauto.h>
+#ifdef __MINGW32__
+ #include <exdisp.h>
+ #include <servprov.h>
+#endif
+#include <mshtml.h>
+
+#include <win2k.h>
+
+#include <newpluginapi.h>
+#include <m_utils.h>
+#include <m_clist.h>
+#include <m_langpack.h>
+#include <m_system.h>
+#include <m_protomod.h>
+#include <m_protosvc.h>
+#include <m_options.h>
+#include <m_database.h>
+#include <m_skin.h>
+#include <m_message.h>
+#include <m_contacts.h>
+#include "m_smileyadd.h"
+#include "m_ieview.h"
+#include "IEView.h"
+
+extern HINSTANCE hInstance;
+extern IEView *debugView;
+extern char *workingDirUtf8;
+extern char *ieviewModuleName;
+extern HANDLE hHookOptionsChanged;
+
+#endif
diff --git a/plugins/IEView/ieview_main.cpp b/plugins/IEView/ieview_main.cpp
new file mode 100644
index 0000000000..402f6560c0
--- /dev/null
+++ b/plugins/IEView/ieview_main.cpp
@@ -0,0 +1,128 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+#include "IEView.h"
+#include "m_ieview.h"
+#include "ieview_services.h"
+#include "Options.h"
+#include "Utils.h"
+#include "Version.h"
+
+char *ieviewModuleName;
+HINSTANCE hInstance;
+PLUGINLINK *pluginLink;
+char *workingDirUtf8;
+static int ModulesLoaded(WPARAM wParam, LPARAM lParam);
+static int PreShutdown(WPARAM wParam, LPARAM lParam);
+int hLangpack;
+
+PLUGININFOEX pluginInfoEx = {
+ sizeof(PLUGININFOEX),
+ __PLUGIN_NAME,
+ PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM),
+ __DESCRIPTION,
+ __AUTHOR,
+ __AUTHOREMAIL,
+ __COPYRIGHT,
+ __AUTHORWEB,
+ UNICODE_AWARE,
+ 0,
+ {0x0495171b, 0x7137, 0x4ded, {0x97, 0xf8, 0xce, 0x6f, 0xed, 0x67, 0xd6, 0x91}}
+};
+
+extern "C" BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpvReserved)
+{
+ hInstance = hModule;
+ return TRUE;
+}
+
+extern "C" __declspec(dllexport) PLUGININFOEX *MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ if (mirandaVersion < PLUGIN_MAKE_VERSION(0, 9, 0, 0)) {
+ return NULL;
+ }
+ return &pluginInfoEx;
+}
+
+static const MUUID interfaces[] = {MIID_LOGWINDOW, MIID_LAST};
+
+extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
+{
+ return interfaces;
+}
+
+extern "C" int __declspec(dllexport) Load(PLUGINLINK *link)
+{
+ char text[_MAX_PATH];
+ char *p, *q;
+
+ int wdsize = GetCurrentDirectory(0, NULL);
+ TCHAR *workingDir = new TCHAR[wdsize];
+ GetCurrentDirectory(wdsize, workingDir);
+ Utils::convertPath(workingDir);
+ workingDirUtf8 = Utils::UTF8Encode(workingDir);
+ delete workingDir;
+
+ GetModuleFileNameA(hInstance, text, sizeof(text));
+ p = strrchr(text, '\\');
+ p++;
+ q = strrchr(p, '.');
+ *q = '\0';
+ ieviewModuleName = _strdup(p);
+ _strupr(ieviewModuleName);
+
+ pluginLink = link;
+ mir_getMMI( &mmi );
+ mir_getLP(&pluginInfoEx);
+
+ Utils::hookEvent_Ex(ME_OPT_INITIALISE, IEViewOptInit);
+ Utils::hookEvent_Ex(ME_SYSTEM_MODULESLOADED, ModulesLoaded);
+ Utils::hookEvent_Ex(ME_SYSTEM_PRESHUTDOWN, PreShutdown);
+
+ Utils::createServiceFunction_Ex(MS_IEVIEW_WINDOW, HandleIEWindow);
+ Utils::createServiceFunction_Ex(MS_IEVIEW_EVENT, HandleIEEvent);
+ Utils::createServiceFunction_Ex(MS_IEVIEW_EVENT, HandleIENavigate);
+ hHookOptionsChanged = CreateHookableEvent(ME_IEVIEW_OPTIONSCHANGED);
+ return 0;
+}
+
+static int ModulesLoaded(WPARAM wParam, LPARAM lParam)
+{
+ IEView::init();
+ Options::init();
+ return 0;
+}
+
+static int PreShutdown(WPARAM wParam, LPARAM lParam)
+{
+ return 0;
+}
+
+extern "C" int __declspec(dllexport) Unload(void)
+{
+ Options::uninit();
+ Utils::unhookEvents_Ex();
+ Utils::destroyServices_Ex();
+ DestroyHookableEvent(hHookOptionsChanged);
+ IEView::release();
+ delete workingDirUtf8;
+ free( ieviewModuleName );
+ return 0;
+}
diff --git a/plugins/IEView/ieview_services.cpp b/plugins/IEView/ieview_services.cpp
new file mode 100644
index 0000000000..a9745e4184
--- /dev/null
+++ b/plugins/IEView/ieview_services.cpp
@@ -0,0 +1,117 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+#include "ieview_services.h"
+//#include "SRMMHTMLBuilder.h"
+#include "ScriverHTMLBuilder.h"
+#include "TabSRMMHTMLBuilder.h"
+#include "TemplateHTMLBuilder.h"
+#include "MUCCHTMLBuilder.h"
+#include "ChatHTMLBuilder.h"
+#include "HistoryHTMLBuilder.h"
+#include "IEView.h"
+#include "m_ieview.h"
+#include "Options.h"
+#include "ieview_common.h"
+
+INT_PTR HandleIEWindow(WPARAM wParam, LPARAM lParam) {
+ IEVIEWWINDOW *window = (IEVIEWWINDOW *) lParam;
+ IEView::init();
+ Options::init();
+ if (window->iType == IEW_CREATE) {
+ HTMLBuilder *builder = NULL;
+ switch (window->dwMode) {
+ case IEWM_MUCC:
+ builder = new MUCCHTMLBuilder();
+ break;
+ case IEWM_CHAT:
+ builder = new ChatHTMLBuilder();
+ break;
+ case IEWM_TABSRMM:
+ builder = new TabSRMMHTMLBuilder();
+ break;
+ case IEWM_SCRIVER:
+// builder = new HistoryHTMLBuilder();
+ builder = new ScriverHTMLBuilder();
+ break;
+ case IEWM_HISTORY:
+ builder = new HistoryHTMLBuilder();
+ break;
+ case IEWM_BROWSER:
+ builder = NULL;
+ break;
+ default:
+ builder = new ScriverHTMLBuilder();
+ break;
+ }
+ IEView * view = new IEView(window->parent, builder, window->x, window->y, window->cx, window->cy);
+ window->hwnd = view->getHWND();
+ } else if (window->iType == IEW_SETPOS) {
+ IEView * view = IEView::get(window->hwnd);
+ if (view!=NULL) {
+ view->setWindowPos(window->x, window->y, window->cx,window->cy);
+ }
+ } else if (window->iType == IEW_SCROLLBOTTOM) {
+ IEView * view = IEView::get(window->hwnd);
+ if (view!=NULL) {
+ view->scrollToBottom();
+ }
+ } else if (window->iType == IEW_DESTROY) {
+ IEView * view = IEView::get(window->hwnd);
+ if (view!=NULL) {
+ delete view;
+ }
+ }
+ return 0;
+}
+
+INT_PTR HandleIEEvent(WPARAM wParam, LPARAM lParam) {
+ IEVIEWEVENT *event = (IEVIEWEVENT *) lParam;
+ IEView::init();
+ Options::init();
+ IEView * view = IEView::get(event->hwnd);
+ if (view != NULL) {
+ if (event->iType == IEE_LOG_DB_EVENTS) {
+ view->appendEventOld(event);
+ } else if (event->iType == IEE_CLEAR_LOG) {
+ view->clear(event);
+ } else if (event->iType == IEE_GET_SELECTION) {
+ return (int)view->getSelection(event);
+ } else if (event->iType == IEE_SAVE_DOCUMENT) {
+ view->saveDocument();
+ } else if (event->iType == IEE_LOG_MEM_EVENTS) {
+ view->appendEvent(event);
+ }
+ }
+ return 0;
+}
+
+INT_PTR HandleIENavigate(WPARAM wParam, LPARAM lParam) {
+ IEVIEWNAVIGATE *navigate = (IEVIEWNAVIGATE *) lParam;
+ IEView::init();
+ Options::init();
+ IEView * view = IEView::get(navigate->hwnd);
+ if (view != NULL) {
+ if (navigate->iType == IEN_NAVIGATE) {
+ view->navigate(navigate);
+ }
+ }
+ return 0;
+}
diff --git a/plugins/IEView/ieview_services.h b/plugins/IEView/ieview_services.h
new file mode 100644
index 0000000000..a25f8ead97
--- /dev/null
+++ b/plugins/IEView/ieview_services.h
@@ -0,0 +1,31 @@
+/*
+
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+#ifndef IEVIEW_SERVICES_INCLUDED
+#define IEVIEW_SERVICES_INCLUDED
+
+#include "ieview_common.h"
+
+extern INT_PTR HandleIEWindow(WPARAM wParam, LPARAM lParam);
+extern INT_PTR HandleIEEvent(WPARAM wParam, LPARAM lParam);
+extern INT_PTR HandleIENavigate(WPARAM wParam, LPARAM lParam);
+
+#endif
+
diff --git a/plugins/IEView/resource.h b/plugins/IEView/resource.h
new file mode 100644
index 0000000000..073073f64e
--- /dev/null
+++ b/plugins/IEView/resource.h
@@ -0,0 +1,87 @@
+/*
+IEView Plugin for Miranda IM
+Copyright (C) 2005-2010 Piotr Piastucki
+
+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 option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#define ID_MENU_COPY 15
+#define ID_MENU_PRINT 27
+#define ID_MENU_SELECTALL 31
+#define IDI_RTL_ON 100
+#define IDI_RTL_OFF 101
+#define IDI_GROUP_ON 102
+#define IDI_GROUP_OFF 103
+#define IDD_SRMM_OPTIONS 153
+#define IDD_GENERAL_OPTIONS 155
+#define IDR_CONTEXTMENU 200
+#define IDC_BACKGROUND_IMAGE 1000
+#define IDC_BACKGROUND_IMAGE_FILENAME 1001
+#define IDC_BROWSE_BACKGROUND_IMAGE 1002
+#define IDC_SCROLL_BACKGROUND_IMAGE 1003
+#define IDC_ENABLE_BBCODES 1004
+#define IDC_ENABLE_FLASH 1005
+#define IDC_ENABLE_MATHMODULE 1006
+#define IDC_ENABLE_PNGHACK 1007
+#define IDC_SMILEYS_IN_NAMES 1008
+#define IDC_NO_BORDER 1009
+#define IDC_ENABLE_EMBED 1010
+#define IDC_EMBED_SIZE 1011
+#define IDC_EXTERNALCSS 1020
+#define IDC_EXTERNALCSS_FILENAME 1021
+#define IDC_BROWSE_EXTERNALCSS 1022
+#define IDC_EXTERNALCSS_FILENAME_RTL 1023
+#define IDC_BROWSE_EXTERNALCSS_RTL 1024
+#define IDC_TEMPLATES 1030
+#define IDC_TEMPLATES_FILENAME 1031
+#define IDC_BROWSE_TEMPLATES 1032
+#define IDC_TEMPLATES_FILENAME_RTL 1033
+#define IDC_BROWSE_TEMPLATES_RTL 1034
+#define IDC_LOG_SHOW_NICKNAMES 1043
+#define IDC_LOG_SHOW_TIME 1044
+#define IDC_LOG_SHOW_DATE 1045
+#define IDC_LOG_SHOW_SECONDS 1046
+#define IDC_LOG_LONG_DATE 1047
+#define IDC_LOG_RELATIVE_DATE 1048
+#define IDC_LOG_GROUP_MESSAGES 1050
+#define IDC_GROUPCHAT_CSS 1051
+#define IDC_GROUPCHAT_CSS_FILENAME 1052
+#define IDC_GROUPCHAT_CSS_BROWSE 1053
+#define IDC_GROUPCHAT_TEMPLATES_BROWSE 1054
+#define IDC_GROUPCHAT_TEMPLATES_FILENAME 1055
+#define IDC_GROUPCHAT_TEMPLATES 1056
+#define IDC_MODE_COMPATIBLE 1060
+#define IDC_MODE_CSS 1061
+#define IDC_MODE_TEMPLATE 1062
+#define IDC_PROTOLIST 1063
+#define IDC_RTLSUPPORT 1070
+#define IDC_GROUPSUPPORT 1071
+#define IDC_TABS 2000
+#define ID_MENU_SHOWSOURCE 2139
+#define ID_MENU_COPYLINK 2262
+#define ID_MENU_SAVEIMAGE 2270
+#define ID_MENU_SAVEHTML 6012
+#define ID_MENU_CLEARLOG 40000
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif