summaryrefslogtreecommitdiff
path: root/plugins/NewStory/src
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/NewStory/src')
-rw-r--r--plugins/NewStory/src/history.cpp46
-rw-r--r--plugins/NewStory/src/history.h5
-rw-r--r--plugins/NewStory/src/history_control.cpp810
-rw-r--r--plugins/NewStory/src/history_control.h3
4 files changed, 423 insertions, 441 deletions
diff --git a/plugins/NewStory/src/history.cpp b/plugins/NewStory/src/history.cpp
index 8cb8868891..143246d1be 100644
--- a/plugins/NewStory/src/history.cpp
+++ b/plugins/NewStory/src/history.cpp
@@ -220,7 +220,7 @@ class CHistoryDlg : public CDlgBase
// main controls
HWND m_hwndTimeTree;
- HWND m_hwndLog;
+
// searchbar
HWND m_hwndBtnCloseSearch;
// statusbar
@@ -386,7 +386,7 @@ class CHistoryDlg : public CDlgBase
hSearch += WND_SPACING;
}
- hDwp = DeferWindowPos(hDwp, m_hwndLog, 0,
+ hDwp = DeferWindowPos(hDwp, m_histControl.GetHwnd(), 0,
WND_SPACING, hToolBar + hFilterBar + WND_SPACING,
w - WND_SPACING * 2, h - WND_SPACING * 2 - hFilterBar - hToolBar - hSearch - hStatus,
SWP_NOZORDER);
@@ -394,6 +394,7 @@ class CHistoryDlg : public CDlgBase
EndDeferWindowPos(hDwp);
}
+ CCtrlBase m_histControl;
CCtrlEdit edtSearchText;
CCtrlMButton btnUserInfo, btnSendMsg, btnUserMenu, btnCopy, btnOptions, btnFilter;
CCtrlMButton btnCalendar, btnSearch, btnExport, btnClose, btnFindNext, btnFindPrev;
@@ -404,6 +405,7 @@ public:
CDlgBase(g_plugin, IDD_HISTORY),
m_hContact(_hContact),
m_timeTree(this, IDC_TIMETREE),
+ m_histControl(this, IDC_ITEMS2),
edtSearchText(this, IDC_SEARCHTEXT),
btnCopy(this, IDC_COPY, g_plugin.getIcon(ICO_COPY), LPGEN("Copy")),
btnClose(this, IDC_CLOSE, g_plugin.getIcon(ICO_CLOSE), LPGEN("Close")),
@@ -475,7 +477,6 @@ public:
m_hwndBtnToolbar[TBTN_DATEPOPUP] = btnCalendar.GetHwnd();
m_hwndBtnToolbar[TBTN_CLOSE] = btnClose.GetHwnd();
- m_hwndLog = GetDlgItem(m_hwnd, IDC_ITEMS2);
m_hwndBtnCloseSearch = GetDlgItem(m_hwnd, IDC_SEARCHICON);
m_hwndStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0, m_hwnd, NULL, g_plugin.getInst(), NULL);
SendMessage(m_hwndStatus, SB_SETMINHEIGHT, GetSystemMetrics(SM_CYSMICON), 0);
@@ -560,9 +561,9 @@ public:
}
if (m_hContact != INVALID_CONTACT_ID)
- PostMessage(GetDlgItem(m_hwnd, IDC_ITEMS2), WM_USER, (WPARAM)m_hContact, 0);
+ PostMessage(m_histControl.GetHwnd(), WM_USER, m_hContact, 0);
- SendMessage(m_hwnd, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)g_plugin.getIcon(ICO_NEWSTORY));
+ Window_SetIcon_IcoLib(m_hwnd, g_plugin.getIconHandle(ICO_NEWSTORY));
SendMessage(GetDlgItem(m_hwnd, IDC_SEARCHICON), STM_SETICON, (WPARAM)g_plugin.getIcon(ICO_SEARCH), 0);
@@ -582,7 +583,7 @@ public:
SendMessage(ibTotal.hwndIcoIn, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_plugin.getIcon(ICO_MSGIN));
SendMessage(ibTotal.hwndIcoOut, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_plugin.getIcon(ICO_MSGOUT));
- SetFocus(GetDlgItem(m_hwnd, IDC_ITEMS2));
+ SetFocus(m_histControl.GetHwnd());
ShowHideControls();
return true;
@@ -590,11 +591,11 @@ public:
void OnDestroy() override
{
- WindowList_Remove(hNewstoryWindows, m_hwnd);
-
g_plugin.setDword(m_hContact, "showFlags", showFlags);
Utils_SaveWindowPosition(m_hwnd, m_hContact, MODULENAME, "wnd_");
+ Window_FreeIcon_IcoLib(m_hwnd);
+ WindowList_Remove(hNewstoryWindows, m_hwnd);
}
void onClick_Calendar(CCtrlButton *pButton)
@@ -604,7 +605,7 @@ public:
time_t tm_jump = CalendarTool_Show(m_hwnd, rc.left, rc.bottom);
if (tm_jump)
- PostMessage(m_hwnd, UM_JUMP2TIME, tm_jump, 0);
+ m_histControl.SendMsg(NSM_SEEKTIME, tm_jump, 0);
}
void onClick_Close(CCtrlButton *)
@@ -614,7 +615,7 @@ public:
void onClick_Copy(CCtrlButton *)
{
- SendMessage(GetDlgItem(m_hwnd, IDC_ITEMS2), NSM_COPY, 0, 0);
+ m_histControl.SendMsg(NSM_COPY, 0, 0);
}
void onClick_Export(CCtrlButton *)
@@ -636,12 +637,12 @@ public:
void onClick_FindNext(CCtrlButton *)
{
- SendMessage(GetDlgItem(m_hwnd, IDC_ITEMS2), NSM_FINDNEXT, ptrW(edtSearchText.GetText()), 0);
+ m_histControl.SendMsg(NSM_FINDNEXT, ptrW(edtSearchText.GetText()), 0);
}
void onClick_FindPrev(CCtrlButton *)
{
- SendMessage(GetDlgItem(m_hwnd, IDC_ITEMS2), NSM_FINDPREV, ptrW(edtSearchText.GetText()), 0);
+ m_histControl.SendMsg(NSM_FINDPREV, ptrW(edtSearchText.GetText()), 0);
}
@@ -709,7 +710,7 @@ public:
INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override
{
if ((msg >= NSM_FIRST) && (msg < NSM_LAST)) {
- LPARAM result = SendMessage(GetDlgItem(m_hwnd, IDC_ITEMS2), msg, wParam, lParam);
+ LPARAM result = m_histControl.SendMsg(msg, wParam, lParam);
SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, result);
return result;
}
@@ -858,25 +859,6 @@ public:
// ShowWindow(GetDlgItem(m_hwnd, IDC_TIMETREE), SW_SHOW);
// ShowWindow(GetDlgItem(m_hwnd, IDC_ITEMS2), SW_SHOW);
// ShowWindow(GetDlgItem(m_hwnd, IDC_SEARCHICON), SW_SHOW);
-
- /*
- case UM_JUMP2TIME:
- {
- for (int i = 0; i < eventCount; i++)
- {
- ItemData *idata = (ItemData *)SendMessage(GetDlgItem(m_hwnd, IDC_ITEMS), LB_GETITEMDATA, i, 0);
- if (idbe->timestamp >= wParam)
- {
- SendMessage(GetDlgItem(m_hwnd, IDC_ITEMS), LB_SETCARETINDEX, i, 0);
- SendMessage(GetDlgItem(m_hwnd, IDC_ITEMS), LB_SETTOPINDEX, i, 0);
- SendMessage(GetDlgItem(m_hwnd, IDC_ITEMS), LB_SELITEMRANGE, FALSE, MAKELPARAM(0,eventCount));
- SendMessage(GetDlgItem(m_hwnd, IDC_ITEMS), LB_SELITEMRANGE, TRUE, MAKELPARAM(i,i));
- break;
- }
- }
- return TRUE;
- }
- */
};
INT_PTR svcShowNewstory(WPARAM hContact, LPARAM)
diff --git a/plugins/NewStory/src/history.h b/plugins/NewStory/src/history.h
index ff0104c790..00e9ccfded 100644
--- a/plugins/NewStory/src/history.h
+++ b/plugins/NewStory/src/history.h
@@ -24,10 +24,7 @@ enum
UM_GETEVENT,
UM_GETEVENTTEXT,
UM_GETEVENTCONTACT,
- UM_GETEVENTHANDLE,
- // UM_GETEVENTDATA,
-
- UM_JUMP2TIME
+ UM_GETEVENTHANDLE
};
extern MWindowList hNewstoryWindows;
diff --git a/plugins/NewStory/src/history_control.cpp b/plugins/NewStory/src/history_control.cpp
index d7fb75cc37..da8dcecd5b 100644
--- a/plugins/NewStory/src/history_control.cpp
+++ b/plugins/NewStory/src/history_control.cpp
@@ -1,23 +1,7 @@
#include "stdafx.h"
-LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
-
HANDLE htuLog = 0;
-void InitNewstoryControl()
-{
- htuLog = MTextRegister("Newstory", MTEXT_FANCY_DEFAULT | MTEXT_SYSTEM_HICONS);
-
- WNDCLASS wndclass = {};
- wndclass.style = /*CS_HREDRAW | CS_VREDRAW | */CS_DBLCLKS | CS_GLOBALCLASS;
- wndclass.lpfnWndProc = NewstoryListWndProc;
- wndclass.cbWndExtra = sizeof(void *);
- wndclass.hInstance = g_plugin.getInst();
- wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wndclass.lpszClassName = _T(NEWSTORYLIST_CLASS);
- RegisterClass(&wndclass);
-}
-
/////////////////////////////////////////////////////////////////////////
// Control utilities, types and constants
@@ -25,11 +9,11 @@ struct NewstoryListData : public MZeroedObject
{
HistoryArray items;
- DWORD scrollTopItem; // topmost item
+ int scrollTopItem; // topmost item
int scrollTopPixel; // y coord of topmost item, this should be negative or zero
- DWORD caret;
+ int caret;
int cachedWindowHeight;
- DWORD cachedMaxTopItem; // the largest ID of top item to avoid empty space
+ int cachedMaxTopItem; // the largest ID of top item to avoid empty space
int cachedMaxTopPixel;
RECT rcLastPaint;
@@ -40,13 +24,6 @@ struct NewstoryListData : public MZeroedObject
#define AVERAGE_ITEM_HEIGHT 100
-//static HFONT CopyFont(HFONT hfnt)
-//{
-// LOGFONT lf;
-// GetObject(hfnt, sizeof(lf), &lf);
-// return CreateFontIndirect(&lf);
-//}
-
static void ScrollListBy(HWND hwnd, NewstoryListData *data, int scrollItems, int scrollPixels);
static void EnsureVisible(HWND hwnd, NewstoryListData *data, int item);
static void FixScrollPosition(HWND hwnd, NewstoryListData *data);
@@ -56,7 +33,6 @@ static void EndEditItem(HWND hwnd, NewstoryListData *data);
static int LayoutItem(HWND hwnd, HistoryArray *items, int index);
static int PaintItem(HDC hdc, HistoryArray *items, int index, int top, int width);
-
// Edit box
static WNDPROC OldEditWndProc;
static LRESULT CALLBACK HistoryEditWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -94,7 +70,378 @@ static LRESULT CALLBACK HistoryEditWndProc(HWND hwnd, UINT msg, WPARAM wParam, L
}
/////////////////////////////////////////////////////////////////////////
+// Utilities
+
+static void ScrollListBy(HWND hwnd, NewstoryListData *data, int scrollItems, int scrollPixels)
+{
+ if (scrollItems) {
+ data->scrollTopItem += scrollItems;
+ data->scrollTopPixel = 0;
+ }
+ else if (scrollPixels) {
+ data->scrollTopPixel += scrollPixels;
+ if (data->scrollTopPixel > 0) {
+ while ((data->scrollTopPixel > 0) && data->scrollTopItem) {
+ data->scrollTopItem--;
+ int itemHeight = LayoutItem(hwnd, &data->items, data->scrollTopItem);
+ data->scrollTopPixel -= itemHeight;
+ }
+
+ if (data->scrollTopPixel > 0) {
+ data->scrollTopPixel = 0;
+ }
+ }
+ else if (data->scrollTopPixel < 0) {
+ int maxItem = data->items.getCount();
+ int itemHeight = LayoutItem(hwnd, &data->items, data->scrollTopItem);
+ while ((-data->scrollTopPixel > itemHeight) && (data->scrollTopItem < maxItem)) {
+ data->scrollTopPixel += itemHeight;
+ data->scrollTopItem++;
+ itemHeight = LayoutItem(hwnd, &data->items, data->scrollTopItem);
+ }
+ }
+ }
+
+ FixScrollPosition(hwnd, data);
+}
+
+static void EnsureVisible(HWND hwnd, NewstoryListData *data, int item)
+{
+ if (data->scrollTopItem >= item) {
+ data->scrollTopItem = item;
+ data->scrollTopPixel = 0;
+ }
+ else {
+ RECT rc; GetClientRect(hwnd, &rc);
+ int height = rc.bottom - rc.top;
+ int top = data->scrollTopPixel;
+ int idx = data->scrollTopItem;
+ int itemHeight = LayoutItem(hwnd, &data->items, idx);
+ bool found = false;
+ while (top < height) {
+ if (idx == item) {
+ itemHeight = LayoutItem(hwnd, &data->items, idx);
+ if (top + itemHeight > height)
+ ScrollListBy(hwnd, data, 0, height - top - itemHeight);
+ found = true;
+ break;
+ }
+ top += itemHeight;
+ idx++;
+ itemHeight = LayoutItem(hwnd, &data->items, idx);
+ }
+ if (!found) {
+ data->scrollTopItem = item;
+ data->scrollTopPixel = 0;
+ }
+ }
+ FixScrollPosition(hwnd, data);
+}
+
+static void FixScrollPosition(HWND hwnd, NewstoryListData *data)
+{
+ EndEditItem(hwnd, data);
+
+ RECT rc;
+ GetWindowRect(hwnd, &rc);
+ int windowHeight = rc.bottom - rc.top;
+
+ if (windowHeight != data->cachedWindowHeight) {
+ int maxTopItem = 0;
+ int tmp = 0;
+ for (maxTopItem = data->items.getCount(); (maxTopItem > 0) && (tmp < windowHeight); maxTopItem--)
+ tmp += LayoutItem(hwnd, &data->items, maxTopItem - 1);
+ data->cachedMaxTopItem = maxTopItem;
+ data->cachedWindowHeight = windowHeight;
+ data->cachedMaxTopPixel = (windowHeight < tmp) ? windowHeight - tmp : 0;
+ }
+
+ if (data->scrollTopItem < 0) {
+ data->scrollTopItem = 0;
+ }
+
+ if ((data->scrollTopItem > data->cachedMaxTopItem) ||
+ ((data->scrollTopItem == data->cachedMaxTopItem) && (data->scrollTopPixel < data->cachedMaxTopPixel))) {
+ data->scrollTopItem = data->cachedMaxTopItem;
+ data->scrollTopPixel = data->cachedMaxTopPixel;
+ }
+ RecalcScrollBar(hwnd, data);
+}
+
+static void RecalcScrollBar(HWND hwnd, NewstoryListData *data)
+{
+ SCROLLINFO si = { 0 };
+ RECT clRect;
+ GetClientRect(hwnd, &clRect);
+ si.cbSize = sizeof(si);
+ si.fMask = SIF_ALL;
+ si.nMin = 0;
+ si.nMax = data->items.getCount() * AVERAGE_ITEM_HEIGHT;
+ si.nPage = clRect.bottom;
+ si.nPos = data->scrollTopItem * AVERAGE_ITEM_HEIGHT;
+ SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
+}
+
+static void BeginEditItem(HWND hwnd, NewstoryListData *data, int index)
+{
+ if (data->hwndEditBox)
+ EndEditItem(hwnd, data);
+
+ if (data->scrollTopItem > index)
+ return;
+
+ RECT rc; GetClientRect(hwnd, &rc);
+ int height = rc.bottom - rc.top;
+
+ int top = data->scrollTopPixel;
+ int idx = data->scrollTopItem;
+ int itemHeight = LayoutItem(hwnd, &data->items, idx);
+ while (top < height) {
+ if (idx == index) {
+ HistoryArray::ItemData *item = data->items.get(index, ELM_DATA);
+
+ int tpl;
+ int fontid;
+ int colorid;
+ switch (item->dbe.eventType) {
+ case EVENTTYPE_MESSAGE:
+ tpl = TPL_COPY_MESSAGE;
+ fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INMSG : FONT_OUTMSG;
+ colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INMSG : COLOR_OUTMSG;
+ break;
+
+ case EVENTTYPE_FILE:
+ tpl = TPL_COPY_FILE;
+ fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INFILE : FONT_OUTFILE;
+ colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INFILE : COLOR_OUTFILE;
+ break;
+
+ case EVENTTYPE_STATUSCHANGE:
+ tpl = TPL_COPY_SIGN;
+ fontid = FONT_STATUS;
+ colorid = COLOR_STATUS;
+ break;
+
+ case EVENTTYPE_AUTHREQUEST:
+ tpl = TPL_COPY_AUTH;
+ fontid = FONT_INOTHER;
+ colorid = COLOR_INOTHER;
+ break;
+
+ case EVENTTYPE_ADDED:
+ tpl = TPL_COPY_ADDED;
+ fontid = FONT_INOTHER;
+ colorid = COLOR_INOTHER;
+ break;
+
+ case EVENTTYPE_JABBER_PRESENCE:
+ tpl = TPL_COPY_PRESENCE;
+ fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
+ colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER;
+ break;
+
+ default:
+ tpl = TPL_COPY_OTHER;
+ fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
+ colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER;
+ break;
+ }
+
+ ptrW text(TplFormatString(tpl, item->hContact, item));
+ data->hwndEditBox = CreateWindow(L"EDIT", text, WS_CHILD | WS_BORDER | ES_READONLY | ES_MULTILINE | ES_AUTOVSCROLL, 0, top, rc.right - rc.left, itemHeight, hwnd, NULL, g_plugin.getInst(), NULL);
+ OldEditWndProc = (WNDPROC)SetWindowLongPtr(data->hwndEditBox, GWLP_WNDPROC, (LONG_PTR)HistoryEditWndProc);
+ SendMessage(data->hwndEditBox, WM_SETFONT, (WPARAM)fonts[fontid].hfnt, 0);
+ SendMessage(data->hwndEditBox, EM_SETMARGINS, EC_RIGHTMARGIN, 100);
+ SendMessage(data->hwndEditBox, EM_SETSEL, 0, (LPARAM)(-1));
+ ShowWindow(data->hwndEditBox, SW_SHOW);
+ SetFocus(data->hwndEditBox);
+ break;
+ }
+ top += itemHeight;
+ idx++;
+ itemHeight = LayoutItem(hwnd, &data->items, idx);
+ }
+}
+
+static void EndEditItem(HWND, NewstoryListData *data)
+{
+ DestroyWindow(data->hwndEditBox);
+ data->hwndEditBox = 0;
+}
+
+static int LayoutItem(HWND hwnd, HistoryArray *items, int index)
+{
+ HDC hdc = GetDC(hwnd);
+ RECT rc; GetClientRect(hwnd, &rc);
+ int width = rc.right - rc.left;
+
+ HistoryArray::ItemData *item = items->get(index, ELM_DATA);
+ if (!item) return 0;
+
+ int tpl;
+ int fontid;
+ switch (item->dbe.eventType) {
+ case EVENTTYPE_MESSAGE:
+ tpl = TPL_MESSAGE;
+ fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INMSG : FONT_OUTMSG;
+ break;
+
+ case EVENTTYPE_FILE:
+ tpl = TPL_FILE;
+ fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INFILE : FONT_OUTFILE;
+ break;
+
+ case EVENTTYPE_STATUSCHANGE:
+ tpl = TPL_SIGN;
+ fontid = FONT_STATUS;
+ break;
+
+ case EVENTTYPE_AUTHREQUEST:
+ tpl = TPL_AUTH;
+ fontid = FONT_INOTHER;
+ break;
+
+ case EVENTTYPE_ADDED:
+ tpl = TPL_ADDED;
+ fontid = FONT_INOTHER;
+ break;
+
+ case EVENTTYPE_JABBER_PRESENCE:
+ tpl = TPL_PRESENCE;
+ fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
+ break;
+
+ default:
+ tpl = TPL_OTHER;
+ fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
+ break;
+ }
+
+ HFONT hfnt = (HFONT)SelectObject(hdc, fonts[fontid].hfnt);
+ if (!item->data)
+ item->data = MTextCreateW(htuLog, ptrW(TplFormatString(tpl, item->hContact, item)));
+
+ SIZE sz;
+ sz.cx = width - 6;
+ MTextMeasure(hdc, &sz, (HANDLE)item->data);
+
+ SelectObject(hdc, hfnt);
+
+ ReleaseDC(hwnd, hdc);
+ return sz.cy + 5;
+}
+
+static int PaintItem(HDC hdc, HistoryArray *items, int index, int top, int width)
+{
+ if (!items) return 0;
+ HistoryArray::ItemData *item = items->get(index, ELM_DATA);
+
+ // LOGFONT lfText;
+ COLORREF clText, clBack, clLine;
+ int tpl;
+ int fontid;
+ int colorid;
+ switch (item->dbe.eventType) {
+ case EVENTTYPE_MESSAGE:
+ tpl = TPL_MESSAGE;
+ fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INMSG : FONT_OUTMSG;
+ colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INMSG : COLOR_OUTMSG;
+ break;
+
+ case EVENTTYPE_FILE:
+ tpl = TPL_FILE;
+ fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INFILE : FONT_OUTFILE;
+ colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INFILE : COLOR_OUTFILE;
+ break;
+
+ case EVENTTYPE_STATUSCHANGE:
+ tpl = TPL_SIGN;
+ fontid = FONT_STATUS;
+ colorid = COLOR_STATUS;
+ break;
+
+ case EVENTTYPE_AUTHREQUEST:
+ tpl = TPL_AUTH;
+ fontid = FONT_INOTHER;
+ colorid = COLOR_INOTHER;
+ break;
+
+ case EVENTTYPE_ADDED:
+ tpl = TPL_ADDED;
+ fontid = FONT_INOTHER;
+ colorid = COLOR_INOTHER;
+ break;
+
+ case EVENTTYPE_JABBER_PRESENCE:
+ tpl = TPL_PRESENCE;
+ fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
+ colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER;
+ break;
+
+ default:
+ tpl = TPL_OTHER;
+ fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
+ colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER;
+ break;
+ }
+ clText = fonts[fontid].cl;
+ if (item->flags & HIF_SELECTED) {
+ MTextSendMessage(0, item->data, EM_SETSEL, 0, -1);
+ clText = colors[COLOR_SELTEXT].cl;
+ clLine = GetSysColor(COLOR_HIGHLIGHTTEXT);
+ clBack = GetSysColor(COLOR_HIGHLIGHT);
+ }
+ else {
+ MTextSendMessage(0, item->data, EM_SETSEL, 0, 0);
+ clLine = colors[COLOR_SELECTED].cl;
+ clBack = colors[colorid].cl;
+ }
+
+ if (!item->data) {
+ wchar_t *buf = TplFormatString(tpl, item->hContact, item);
+ item->data = MTextCreateW(htuLog, buf);
+ mir_free(buf);
+ if (!item->data)
+ return 0;
+ }
+
+ SIZE sz;
+ sz.cx = width - 6;
+ HFONT hfnt = (HFONT)SelectObject(hdc, fonts[fontid].hfnt);
+ MTextMeasure(hdc, &sz, (HANDLE)item->data);
+ SelectObject(hdc, hfnt);
+ int height = sz.cy + 5;
+
+ RECT rc;
+ SetRect(&rc, 0, top, width, top + height);
+
+ HBRUSH hbr;
+ hbr = CreateSolidBrush(clBack);
+ FillRect(hdc, &rc, hbr);
+
+ SetTextColor(hdc, clText);
+ SetBkMode(hdc, TRANSPARENT);
+
+ POINT pos;
+ pos.x = 3;
+ pos.y = top + 2;
+ hfnt = (HFONT)SelectObject(hdc, fonts[fontid].hfnt);
+ MTextDisplay(hdc, pos, sz, (HANDLE)item->data);
+ SelectObject(hdc, hfnt);
+
+ DeleteObject(hbr);
+
+ HPEN hpn = (HPEN)SelectObject(hdc, CreatePen(PS_SOLID, 1, clLine));
+ MoveToEx(hdc, rc.left, rc.bottom - 1, 0);
+ LineTo(hdc, rc.right, rc.bottom - 1);
+ DeleteObject(SelectObject(hdc, hpn));
+
+ return height;
+}
+
+/////////////////////////////////////////////////////////////////////////
// WndProc
+
LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
NewstoryListData *data = (NewstoryListData *)GetWindowLongPtr(hwnd, 0);
@@ -114,7 +461,7 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
InvalidateRect(hwnd, 0, FALSE);
break;
- // History list control messages
+ // History list control messages
case NSM_GETCOUNT:
return data->items.getCount();
@@ -216,19 +563,14 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
}
case NSM_SETCARET:
- {
- if ((wParam >= 0) && (wParam < data->items.getCount())) {
- data->caret = wParam;
- if (lParam) {
- SendMessage(hwnd, NSM_ENSUREVISIBLE, data->caret, 0);
- }
- }
+ if ((wParam >= 0) && (wParam < data->items.getCount())) {
+ data->caret = wParam;
+ if (lParam)
+ SendMessage(hwnd, NSM_ENSUREVISIBLE, data->caret, 0);
}
case NSM_GETCARET:
- {
- return data->caret;
- }
+ return data->caret;
case NSM_FINDNEXT:
{
@@ -250,6 +592,19 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
return id;
}
+ case NSM_SEEKTIME:
+ {
+ int eventCount = data->items.getCount();
+ for (int i = 0; i < eventCount; i++) {
+ auto *item = data->items.get(i, ELM_NOTHING);
+ if (item->dbe.timestamp >= wParam) {
+ SendMessage(hwnd, NSM_SETCARET, i, TRUE);
+ break;
+ }
+ }
+ }
+ return TRUE;
+
case NSM_COPY:
{
CMStringW res;
@@ -462,7 +817,7 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
case WM_MOUSEWHEEL:
{
- DWORD s_scrollTopItem = data->scrollTopItem;
+ int s_scrollTopItem = data->scrollTopItem;
int s_scrollTopPixel = data->scrollTopPixel;
UINT scrollLines;
@@ -477,7 +832,7 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
case WM_VSCROLL:
{
- DWORD s_scrollTopItem = data->scrollTopItem;
+ int s_scrollTopItem = data->scrollTopItem;
int s_scrollTopPixel = data->scrollTopPixel;
switch (LOWORD(wParam)) {
@@ -540,371 +895,16 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
return DefWindowProc(hwnd, msg, wParam, lParam);
}
-/////////////////////////////////////////////////////////////////////////
-// Utilities
-static void ScrollListBy(HWND hwnd, NewstoryListData *data, int scrollItems, int scrollPixels)
-{
- if (scrollItems) {
- data->scrollTopItem += scrollItems;
- data->scrollTopPixel = 0;
- }
- else if (scrollPixels) {
- data->scrollTopPixel += scrollPixels;
- if (data->scrollTopPixel > 0) {
- while ((data->scrollTopPixel > 0) && data->scrollTopItem) {
- data->scrollTopItem--;
- int itemHeight = LayoutItem(hwnd, &data->items, data->scrollTopItem);
- data->scrollTopPixel -= itemHeight;
- }
-
- if (data->scrollTopPixel > 0) {
- data->scrollTopPixel = 0;
- }
- }
- else if (data->scrollTopPixel < 0) {
- int maxItem = data->items.getCount();
- int itemHeight = LayoutItem(hwnd, &data->items, data->scrollTopItem);
- while ((-data->scrollTopPixel > itemHeight) && (data->scrollTopItem < maxItem)) {
- data->scrollTopPixel += itemHeight;
- data->scrollTopItem++;
- itemHeight = LayoutItem(hwnd, &data->items, data->scrollTopItem);
- }
- }
- }
-
- FixScrollPosition(hwnd, data);
-}
-
-static void EnsureVisible(HWND hwnd, NewstoryListData *data, int item)
-{
- if (data->scrollTopItem >= item) {
- data->scrollTopItem = item;
- data->scrollTopPixel = 0;
- }
- else {
- RECT rc; GetClientRect(hwnd, &rc);
- int height = rc.bottom - rc.top;
- int top = data->scrollTopPixel;
- int idx = data->scrollTopItem;
- int itemHeight = LayoutItem(hwnd, &data->items, idx);
- bool found = false;
- while (top < height) {
- if (idx == item) {
- itemHeight = LayoutItem(hwnd, &data->items, idx);
- if (top + itemHeight > height)
- ScrollListBy(hwnd, data, 0, height - top - itemHeight);
- found = true;
- break;
- }
- top += itemHeight;
- idx++;
- itemHeight = LayoutItem(hwnd, &data->items, idx);
- }
- if (!found) {
- data->scrollTopItem = item;
- data->scrollTopPixel = 0;
- }
- }
- FixScrollPosition(hwnd, data);
-}
-
-static void FixScrollPosition(HWND hwnd, NewstoryListData *data)
-{
- EndEditItem(hwnd, data);
-
- RECT rc;
- GetWindowRect(hwnd, &rc);
- int windowHeight = rc.bottom - rc.top;
-
- if (windowHeight != data->cachedWindowHeight) {
- int maxTopItem = 0;
- int tmp = 0;
- for (maxTopItem = data->items.getCount(); (maxTopItem > 0) && (tmp < windowHeight); maxTopItem--)
- tmp += LayoutItem(hwnd, &data->items, maxTopItem - 1);
- data->cachedMaxTopItem = maxTopItem;
- data->cachedWindowHeight = windowHeight;
- data->cachedMaxTopPixel = (windowHeight < tmp) ? windowHeight - tmp : 0;
- }
-
- if (data->scrollTopItem < 0) {
- data->scrollTopItem = 0;
- }
-
- if ((data->scrollTopItem > data->cachedMaxTopItem) ||
- ((data->scrollTopItem == data->cachedMaxTopItem) && (data->scrollTopPixel < data->cachedMaxTopPixel))) {
- data->scrollTopItem = data->cachedMaxTopItem;
- data->scrollTopPixel = data->cachedMaxTopPixel;
- }
- RecalcScrollBar(hwnd, data);
-}
-
-static void RecalcScrollBar(HWND hwnd, NewstoryListData *data)
-{
- SCROLLINFO si = { 0 };
- RECT clRect;
- GetClientRect(hwnd, &clRect);
- si.cbSize = sizeof(si);
- si.fMask = SIF_ALL;
- si.nMin = 0;
- si.nMax = data->items.getCount() * AVERAGE_ITEM_HEIGHT;
- si.nPage = clRect.bottom;
- si.nPos = data->scrollTopItem * AVERAGE_ITEM_HEIGHT;
- SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
-}
-
-static void BeginEditItem(HWND hwnd, NewstoryListData *data, int index)
-{
- if (data->hwndEditBox)
- EndEditItem(hwnd, data);
-
- if (data->scrollTopItem > index)
- return;
-
- RECT rc; GetClientRect(hwnd, &rc);
- int height = rc.bottom - rc.top;
-
- int top = data->scrollTopPixel;
- int idx = data->scrollTopItem;
- int itemHeight = LayoutItem(hwnd, &data->items, idx);
- while (top < height) {
- if (idx == index) {
- HistoryArray::ItemData *item = data->items.get(index, ELM_DATA);
-
- int tpl;
- int fontid;
- int colorid;
- switch (item->dbe.eventType) {
- case EVENTTYPE_MESSAGE:
- tpl = TPL_COPY_MESSAGE;
- fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INMSG : FONT_OUTMSG;
- colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INMSG : COLOR_OUTMSG;
- break;
-
- case EVENTTYPE_FILE:
- tpl = TPL_COPY_FILE;
- fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INFILE : FONT_OUTFILE;
- colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INFILE : COLOR_OUTFILE;
- break;
-
- case EVENTTYPE_STATUSCHANGE:
- tpl = TPL_COPY_SIGN;
- fontid = FONT_STATUS;
- colorid = COLOR_STATUS;
- break;
-
- case EVENTTYPE_AUTHREQUEST:
- tpl = TPL_COPY_AUTH;
- fontid = FONT_INOTHER;
- colorid = COLOR_INOTHER;
- break;
-
- case EVENTTYPE_ADDED:
- tpl = TPL_COPY_ADDED;
- fontid = FONT_INOTHER;
- colorid = COLOR_INOTHER;
- break;
-
- case EVENTTYPE_JABBER_PRESENCE:
- tpl = TPL_COPY_PRESENCE;
- fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
- colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER;
- break;
-
- default:
- tpl = TPL_COPY_OTHER;
- fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
- colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER;
- break;
- }
-
- ptrW text(TplFormatString(tpl, item->hContact, item));
- data->hwndEditBox = CreateWindow(L"EDIT", text, WS_CHILD | WS_BORDER | ES_READONLY | ES_MULTILINE | ES_AUTOVSCROLL, 0, top, rc.right - rc.left, itemHeight, hwnd, NULL, g_plugin.getInst(), NULL);
- OldEditWndProc = (WNDPROC)SetWindowLongPtr(data->hwndEditBox, GWLP_WNDPROC, (LONG_PTR)HistoryEditWndProc);
- SendMessage(data->hwndEditBox, WM_SETFONT, (WPARAM)fonts[fontid].hfnt, 0);
- SendMessage(data->hwndEditBox, EM_SETMARGINS, EC_RIGHTMARGIN, 100);
- SendMessage(data->hwndEditBox, EM_SETSEL, 0, (LPARAM)(-1));
- ShowWindow(data->hwndEditBox, SW_SHOW);
- SetFocus(data->hwndEditBox);
- break;
- }
- top += itemHeight;
- idx++;
- itemHeight = LayoutItem(hwnd, &data->items, idx);
- }
-}
-
-static void EndEditItem(HWND, NewstoryListData *data)
-{
- DestroyWindow(data->hwndEditBox);
- data->hwndEditBox = 0;
-}
-
-static int LayoutItem(HWND hwnd, HistoryArray *items, int index)
-{
- HDC hdc = GetDC(hwnd);
- RECT rc; GetClientRect(hwnd, &rc);
- int width = rc.right - rc.left;
-
- HistoryArray::ItemData *item = items->get(index, ELM_DATA);
- if (!item) return 0;
-
- int tpl;
- int fontid;
- switch (item->dbe.eventType) {
- case EVENTTYPE_MESSAGE:
- tpl = TPL_MESSAGE;
- fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INMSG : FONT_OUTMSG;
- break;
-
- case EVENTTYPE_FILE:
- tpl = TPL_FILE;
- fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INFILE : FONT_OUTFILE;
- break;
-
- case EVENTTYPE_STATUSCHANGE:
- tpl = TPL_SIGN;
- fontid = FONT_STATUS;
- break;
-
- case EVENTTYPE_AUTHREQUEST:
- tpl = TPL_AUTH;
- fontid = FONT_INOTHER;
- break;
-
- case EVENTTYPE_ADDED:
- tpl = TPL_ADDED;
- fontid = FONT_INOTHER;
- break;
-
- case EVENTTYPE_JABBER_PRESENCE:
- tpl = TPL_PRESENCE;
- fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
- break;
-
- default:
- tpl = TPL_OTHER;
- fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
- break;
- }
-
- HFONT hfnt = (HFONT)SelectObject(hdc, fonts[fontid].hfnt);
- if (!item->data)
- item->data = MTextCreateW(htuLog, ptrW(TplFormatString(tpl, item->hContact, item)));
-
- SIZE sz;
- sz.cx = width - 6;
- MTextMeasure(hdc, &sz, (HANDLE)item->data);
-
- SelectObject(hdc, hfnt);
-
- ReleaseDC(hwnd, hdc);
- return sz.cy + 5;
-}
-
-static int PaintItem(HDC hdc, HistoryArray *items, int index, int top, int width)
+void InitNewstoryControl()
{
- if (!items) return 0;
- HistoryArray::ItemData *item = items->get(index, ELM_DATA);
-
- // LOGFONT lfText;
- COLORREF clText, clBack, clLine;
- int tpl;
- int fontid;
- int colorid;
- switch (item->dbe.eventType) {
- case EVENTTYPE_MESSAGE:
- tpl = TPL_MESSAGE;
- fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INMSG : FONT_OUTMSG;
- colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INMSG : COLOR_OUTMSG;
- break;
-
- case EVENTTYPE_FILE:
- tpl = TPL_FILE;
- fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INFILE : FONT_OUTFILE;
- colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INFILE : COLOR_OUTFILE;
- break;
-
- case EVENTTYPE_STATUSCHANGE:
- tpl = TPL_SIGN;
- fontid = FONT_STATUS;
- colorid = COLOR_STATUS;
- break;
-
- case EVENTTYPE_AUTHREQUEST:
- tpl = TPL_AUTH;
- fontid = FONT_INOTHER;
- colorid = COLOR_INOTHER;
- break;
-
- case EVENTTYPE_ADDED:
- tpl = TPL_ADDED;
- fontid = FONT_INOTHER;
- colorid = COLOR_INOTHER;
- break;
-
- case EVENTTYPE_JABBER_PRESENCE:
- tpl = TPL_PRESENCE;
- fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
- colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER;
- break;
-
- default:
- tpl = TPL_OTHER;
- fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
- colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER;
- break;
- }
- clText = fonts[fontid].cl;
- if (item->flags & HIF_SELECTED) {
- MTextSendMessage(0, item->data, EM_SETSEL, 0, -1);
- // clText = colors[COLOR_SELTEXT].cl;
- clLine = GetSysColor(COLOR_HIGHLIGHTTEXT);
- clBack = GetSysColor(COLOR_HIGHLIGHT); //colors[COLOR_SELECTED].cl;
- }
- else {
- MTextSendMessage(0, item->data, EM_SETSEL, 0, 0);
- clLine = colors[COLOR_SELECTED].cl;
- clBack = colors[colorid].cl;
- }
-
- if (!item->data) {
- wchar_t *buf = TplFormatString(tpl, item->hContact, item);
- item->data = MTextCreateW(htuLog, buf);
- mir_free(buf);
- if (!item->data)
- return 0;
- }
-
- SIZE sz;
- sz.cx = width - 6;
- HFONT hfnt = (HFONT)SelectObject(hdc, fonts[fontid].hfnt);
- MTextMeasure(hdc, &sz, (HANDLE)item->data);
- SelectObject(hdc, hfnt);
- int height = sz.cy + 5;
-
- RECT rc;
- SetRect(&rc, 0, top, width, top + height);
-
- HBRUSH hbr;
- hbr = CreateSolidBrush(clBack);
- FillRect(hdc, &rc, hbr);
-
- SetTextColor(hdc, clText);
- SetBkMode(hdc, TRANSPARENT);
-
- POINT pos;
- pos.x = 3;
- pos.y = top + 2;
- hfnt = (HFONT)SelectObject(hdc, fonts[fontid].hfnt);
- MTextDisplay(hdc, pos, sz, (HANDLE)item->data);
- SelectObject(hdc, hfnt);
-
- DeleteObject(hbr);
-
- HPEN hpn = (HPEN)SelectObject(hdc, CreatePen(PS_SOLID, 1, clLine));
- MoveToEx(hdc, rc.left, rc.bottom - 1, 0);
- LineTo(hdc, rc.right, rc.bottom - 1);
- DeleteObject(SelectObject(hdc, hpn));
+ htuLog = MTextRegister("Newstory", MTEXT_FANCY_DEFAULT | MTEXT_SYSTEM_HICONS);
- return height;
+ WNDCLASS wndclass = {};
+ wndclass.style = /*CS_HREDRAW | CS_VREDRAW | */CS_DBLCLKS | CS_GLOBALCLASS;
+ wndclass.lpfnWndProc = NewstoryListWndProc;
+ wndclass.cbWndExtra = sizeof(void *);
+ wndclass.hInstance = g_plugin.getInst();
+ wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wndclass.lpszClassName = _T(NEWSTORYLIST_CLASS);
+ RegisterClass(&wndclass);
}
diff --git a/plugins/NewStory/src/history_control.h b/plugins/NewStory/src/history_control.h
index 3b857bac75..f17da39fdb 100644
--- a/plugins/NewStory/src/history_control.h
+++ b/plugins/NewStory/src/history_control.h
@@ -57,6 +57,9 @@ enum
//
NSM_GETCOUNT,
+ //
+ NSM_SEEKTIME,
+
NSM_LAST
};