diff options
author | sje <sje@4f64403b-2f21-0410-a795-97e2b3489a10> | 2006-11-01 14:58:39 +0000 |
---|---|---|
committer | sje <sje@4f64403b-2f21-0410-a795-97e2b3489a10> | 2006-11-01 14:58:39 +0000 |
commit | 0c3d3e587e699d06352f269d887d749a8542559a (patch) | |
tree | 2ebcd55584339b04645f0bb79318f987c7efaa46 /yapp/popup_history.cpp | |
parent | 9a1b2f988762967da30e6f4d2575dc2dfe99a21a (diff) |
git-svn-id: https://server.scottellis.com.au/svn/mim_plugs@26 4f64403b-2f21-0410-a795-97e2b3489a10
Diffstat (limited to 'yapp/popup_history.cpp')
-rw-r--r-- | yapp/popup_history.cpp | 393 |
1 files changed, 393 insertions, 0 deletions
diff --git a/yapp/popup_history.cpp b/yapp/popup_history.cpp new file mode 100644 index 0000000..6e9b59e --- /dev/null +++ b/yapp/popup_history.cpp @@ -0,0 +1,393 @@ +#define STRICT +#define WIN32_LEAN_AND_MEAN + +#include "common.h" +#include "resource.h" +#include "popup_history.h" +#include <time.h> + +#define POPUPMENU_TITLE 100 +#define POPUPMENU_MESSAGE 101 +#define POPUPMENU_TIMESTAMP 102 + +HWND hHistoryWindow = 0; //the history window +PopupHistoryList lstPopupHistory; //defined in main.cpp + +WNDPROC oldPopupsListProc = NULL; + +PopupHistoryList::PopupHistoryList() +{ + size = HISTORY_SIZE; //fixed size (at least for now) + historyData = (PopupHistoryData *) malloc(size * sizeof(PopupHistoryData)); //alloc space for data + count = 0; +} + +PopupHistoryList::~PopupHistoryList() +{ + Clear(); //clear the data strings + free(historyData); //deallocate the data list +} + +void PopupHistoryList::Clear() +{ + int i; + for (i = 0; i < count; i++) + { + DeleteData(i); + } + count = 0; +} + +int PopupHistoryList::Count() +{ + return count; +} + +int PopupHistoryList::Size() +{ + return size; +} + +void PopupHistoryList::RemoveItem(int index) +{ + int i; + DeleteData(index); //free the mem for that particular item + for (i = index + 1; i < count; i++) + { + historyData[i - 1] = historyData[i]; //shift all items to the left + } +} + +void PopupHistoryList::DeleteData(int index) +{ + PopupHistoryData *item = &historyData[index]; + if (item->flags && PHDF_UNICODE) //strings are dupped(), we need to free them + { + free(item->titleW); + free(item->messageW); + } + else{ + free(item->title); + free(item->message); + } + item->timestamp = 0; //invalidate item + item->title = NULL; + item->message = NULL; + item->flags = 0; +} + +void PopupHistoryList::AddItem(PopupHistoryData item) +{ + if (count >= size) + { + RemoveItem(0); //remove first element - the oldest + count--; //it will be inc'ed later + } + historyData[count++] = item; //item has it's relevant strings dupped() + RefreshPopupHistory(hHistoryWindow); +} + +void PopupHistoryList::Add(char *title, char *message, time_t timestamp) +{ + PopupHistoryData item = {0}; //create a history item + item.timestamp = timestamp; + item.title = strdup(title); + item.message = strdup(message); + AddItem(item); //add it (flags = 0) +} + +void PopupHistoryList::Add(wchar_t *title, wchar_t *message, time_t timestamp) +{ + PopupHistoryData item = {0}; //create an unicode history item + item.flags = PHDF_UNICODE; //mark it as unicode + item.timestamp = timestamp; + item.titleW = _wcsdup(title); + item.messageW = _wcsdup(message); + AddItem(item); //add it +} + +PopupHistoryData *PopupHistoryList::Get(int index) +{ + if ((index < 0) || (index >= count)) //a bit of sanity check + { + return NULL; + } + + return &historyData[index]; +} + +//Stucture passed to list sort function +struct SortParams{ + HWND hList; + int column; +}; + +static int lastColumn = -1; //last sort column + +int CALLBACK PopupsCompare(LPARAM lParam1, LPARAM lParam2, LPARAM myParam) +{ + SortParams params = *(SortParams *) myParam; + const int MAX_SIZE = 512; + TCHAR text1[MAX_SIZE]; + TCHAR text2[MAX_SIZE]; + int res; + + ListView_GetItemText(params.hList, (int) lParam1, params.column, text1, MAX_SIZE); + ListView_GetItemText(params.hList, (int) lParam2, params.column, text2, MAX_SIZE); + + res = _tcsicmp(text1, text2); + + res = (params.column == lastColumn) ? -res : res; //do reverse search on second click on same column + + return res; +} + +void RefreshPopupHistory(HWND hWnd) +{ + if (!hWnd) + { + return; + } + HWND hHistoryList = GetDlgItem(hWnd, IDC_LST_HISTORY); + ListView_DeleteAllItems(hHistoryList); + + int i; + LVITEM item = {0}; + item.mask = LVIF_TEXT; + wchar_t buffer[1024]; + struct tm *myTime; + for (i = 0; i < lstPopupHistory.Count(); i++) + { + item.iItem = i; + PopupHistoryData *popupItem = lstPopupHistory.Get(i); + item.pszText = popupItem->titleW; + ListView_InsertItem(hHistoryList, &item); + ListView_SetItemText(hHistoryList, i, 1, popupItem->messageW); + myTime = localtime(&popupItem->timestamp); + wcsftime(buffer, 1024, L"%c", myTime); + ListView_SetItemText(hHistoryList, i, 2, buffer); + } + + SortParams params = {0}; + params.hList = hHistoryList; + params.column = lastColumn; + + ListView_SortItemsEx(hHistoryList, PopupsCompare, ¶ms); +} + +void CopyPopupDataToClipboard(HWND hList, int selection) +{ + if (!selection) + { + return; + } + + if (!GetOpenClipboardWindow()) + { + if (OpenClipboard(hList)) + { + TCHAR buffer[2048]; + buffer[0] = _T('\0'); + TCHAR *clipboard; + int i; + int found = 0; + int count = ListView_GetItemCount(hList); + int textType; +#ifdef _UNICODE + textType = CF_UNICODETEXT; +#else + textType = CF_TEXT; +#endif + + for (i = 0; i < count; i++) + { + if (ListView_GetItemState(hList, i, LVIS_SELECTED)) + { + ListView_GetItemText(hList, i, selection - 100, buffer, 2048); + found = 1; + break; + } + } + if (found) + { + EmptyClipboard(); + int len = _tcslen(buffer); + + HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, (len + 2) * sizeof(TCHAR)); + clipboard = (TCHAR *) GlobalLock(hData); + _tcsncpy(clipboard, buffer, len); + clipboard[len] = _T('\0'); + GlobalUnlock(hData); + if (!SetClipboardData(textType, hData)) + { + PUShowMessage("Could not set clipboard data", SM_WARNING); + } + } + CloseClipboard(); + } + else{ + PUShowMessage("Could not open clipboard", SM_WARNING); + } + } + else{ + PUShowMessage("The clipboard is not available", SM_WARNING); + } +} + +//subclass proc for the list view +BOOL CALLBACK PopupsListSubclassProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_CONTEXTMENU: + { + int x = LOWORD(lParam); + int y = HIWORD(lParam); + int selection; + + HMENU hMenu = CreatePopupMenu(); + AppendMenu(hMenu, MF_STRING, POPUPMENU_TITLE, TranslateT("Copy title to clipboard")); + AppendMenu(hMenu, MF_STRING, POPUPMENU_MESSAGE, TranslateT("Copy message to clipboard")); + AppendMenu(hMenu, MF_STRING, POPUPMENU_TIMESTAMP, TranslateT("Copy timestamp to clipboard")); + selection = TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, x, y, 0, hWnd, NULL); + DestroyMenu(hMenu); + if (selection) + { + CopyPopupDataToClipboard(hWnd, selection); + } + + break; + } + + case WM_KEYUP: + { + switch (wParam) + { + case 'C': + { + if (GetKeyState(VK_CONTROL)) + { + CopyPopupDataToClipboard(hWnd, POPUPMENU_MESSAGE); + } + + break; + } + + case VK_ESCAPE: + { + SendMessage(GetParent(hWnd), WM_CLOSE, 0, 0); + + break; + } + + } + + break; + } + + case WM_SYSKEYDOWN: + { + if (wParam == 'X') + { + SendMessage(GetParent(hWnd), WM_CLOSE, 0, 0); + } + + break; + } + } + + return CallWindowProc(oldPopupsListProc, hWnd, msg, wParam, lParam); +} + +//this is the history list window handler +BOOL CALLBACK DlgProcHistLst(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hWnd); + HWND hHistoryList = GetDlgItem(hWnd, IDC_LST_HISTORY); + + ListView_SetExtendedListViewStyleEx (hHistoryList, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT); + + oldPopupsListProc = (WNDPROC) SetWindowLong(hHistoryList, GWL_WNDPROC, (LONG) PopupsListSubclassProc); + + LVCOLUMN col; + col.mask = LVCF_TEXT | LVCF_WIDTH; + col.pszText = L"Title"; + col.cx = 100; + ListView_InsertColumn(hHistoryList, 0, &col); + col.pszText = L"Message"; + col.cx = 450; + ListView_InsertColumn(hHistoryList, 1, &col); + col.pszText = L"Timestamp"; + col.cx = 115; + ListView_InsertColumn(hHistoryList, 2, &col); + RefreshPopupHistory(hWnd); + + return TRUE; + } + + case WM_DESTROY: + { + hHistoryWindow = NULL; + + break; + } + + case WM_CLOSE: + { + DestroyWindow(hWnd); + + break; + } + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDC_CLOSE: + { + SendMessage(hWnd, WM_CLOSE, 0, 0); + + break; + } + } + + break; + } + + case WM_NOTIFY: + { + switch(((LPNMHDR)lParam)->idFrom) + { + case IDC_LST_HISTORY: + { + switch (((LPNMHDR)lParam)->code) + { + case LVN_COLUMNCLICK: + { + LPNMLISTVIEW lv = (LPNMLISTVIEW) lParam; + int column = lv->iSubItem; + SortParams params = {0}; + params.hList = GetDlgItem(hWnd, IDC_LST_HISTORY); + params.column = column; + + ListView_SortItemsEx(params.hList, PopupsCompare, (LPARAM) ¶ms); + lastColumn = (params.column == lastColumn) ? -1 : params.column; + + break; + } + } + + break; + } + } + + break; + } + } + + return 0; +} |