linuxdcpp-team team mailing list archive
-
linuxdcpp-team team
-
Mailing list archive
-
Message #05874
[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 3007: improve the dev plugin
------------------------------------------------------------
revno: 3007
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Fri 2012-07-20 15:04:43 +0200
message:
improve the dev plugin
modified:
plugins/Dev/Dialog.cpp
plugins/Dev/Dialog.h
plugins/Dev/Plugin.cpp
plugins/Dev/resource.h
plugins/Dev/resource.rc
--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk
Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'plugins/Dev/Dialog.cpp'
--- plugins/Dev/Dialog.cpp 2012-07-19 22:00:20 +0000
+++ plugins/Dev/Dialog.cpp 2012-07-20 13:04:43 +0000
@@ -23,14 +23,11 @@
#include <vector>
-#include <boost/algorithm/string.hpp>
-#include <boost/format.hpp>
-#include <boost/lambda/lambda.hpp>
-
#include <CriticalSection.h>
-#include <richedit.h>
+#include <commctrl.h>
+using std::move;
using std::vector;
using dcpp::CriticalSection;
@@ -41,52 +38,171 @@
namespace {
// store the messages to be displayed here; process them with a timer.
+struct Message { bool sending; string ip; string peer; string message; };
+vector<Message> messages;
+
CriticalSection mutex;
-vector<string> messages;
uint16_t counter = 0;
-
-// RTF formatting taken from dwt's RichTextBox
-
-typedef boost::iterator_range<boost::range_const_iterator<string>::type> string_range;
-
-string unicodeEscapeFormatter(const string_range& match) {
- if(match.empty())
- return string();
- return (boost::format("\\ud\\u%dh")%(int(*match.begin()))).str();
-}
-
-string escapeUnicode(const string& str) {
- string ret;
- boost::find_format_all_copy(std::back_inserter(ret), str,
- boost::first_finder(L"\x7f", std::greater<char>()), unicodeEscapeFormatter);
- return ret;
-}
-
-string rtfEscapeFormatter(const string_range& match) {
- if(match.empty())
- return string();
- string s(1, *match.begin());
- if (s == "\r") return "";
- if (s == "\n") return "\\line\n";
- return "\\" + s;
-}
-
-string rtfEscape(const string& str) {
- using boost::lambda::_1;
- string escaped;
- boost::find_format_all_copy(std::back_inserter(escaped), str,
- boost::first_finder("\x7f", _1 == '{' || _1 == '}' || _1 == '\\' || _1 == '\n' || _1 == '\r'), rtfEscapeFormatter);
- return escaped;
-}
-
-string formatText(const string& text) {
- return "{\\urtf " + escapeUnicode(rtfEscape(Util::toString(++counter) + " " + text)) + "}";
-}
+bool scroll = true;
+
+struct Item {
+ tstring index;
+ tstring dir;
+ tstring ip;
+ tstring peer;
+ tstring message;
+};
BOOL init(HWND hwnd) {
+ auto control = GetDlgItem(hwnd, IDC_MESSAGES);
+
+ ListView_SetExtendedListViewStyle(control, LVS_EX_DOUBLEBUFFER | LVS_EX_HEADERDRAGDROP | LVS_EX_FULLROWSELECT | LVS_EX_LABELTIP);
+
+ RECT rect;
+ GetClientRect(control, &rect);
+
+ LVCOLUMN col = { LVCF_FMT | LVCF_TEXT | LVCF_WIDTH, LVCFMT_LEFT, 50, _T("N�") };
+ ListView_InsertColumn(control, 0, &col);
+
+ col.pszText = _T("Dir");
+ ListView_InsertColumn(control, 1, &col);
+
+ col.cx = 100;
+ col.pszText = _T("IP");
+ ListView_InsertColumn(control, 2, &col);
+
+ col.cx = 200;
+ col.pszText = _T("Peer info");
+ ListView_InsertColumn(control, 3, &col);
+
+ col.cx = rect.right - rect.left - 50 - 50 - 100 - 200 - 30;
+ col.pszText = _T("Message");
+ ListView_InsertColumn(control, 4, &col);
+
+ SendMessage(GetDlgItem(hwnd, IDC_SCROLL), BM_SETCHECK, BST_CHECKED, 0);
+
+ SetTimer(hwnd, 1, 500, 0);
+
return TRUE;
}
+void timer(HWND hwnd) {
+ decltype(messages) messages_;
+ {
+ Lock l(mutex);
+ messages_.swap(messages);
+ }
+ if(messages_.empty()) {
+ return;
+ }
+
+ auto control = GetDlgItem(hwnd, IDC_MESSAGES);
+
+ LVITEM lvi = { 0 };
+
+ for(auto& message: messages_) {
+ auto item = new Item;
+ item->index = Util::toT(Util::toString(counter));
+ item->dir = message.sending ? _T("Out") : _T("In");
+ item->ip = Util::toT(message.ip);
+ item->peer = Util::toT(message.peer);
+ item->message = Util::toT(message.message);
+
+ // first column; include the lParam.
+ lvi.mask = LVIF_PARAM | LVIF_TEXT;
+ lvi.iItem = counter;
+ lvi.iSubItem = 0;
+ lvi.pszText = const_cast<LPTSTR>(item->index.c_str());
+ lvi.lParam = reinterpret_cast<LPARAM>(item);
+ ListView_InsertItem(control, &lvi);
+
+ // no lParam for other columns (ie sub-items).
+ lvi.mask = LVIF_TEXT;
+
+ lvi.iSubItem = 1;
+ lvi.pszText = const_cast<LPTSTR>(item->dir.c_str());
+ ListView_SetItem(control, &lvi);
+
+ lvi.iSubItem = 2;
+ lvi.pszText = const_cast<LPTSTR>(item->ip.c_str());
+ ListView_SetItem(control, &lvi);
+
+ lvi.iSubItem = 3;
+ lvi.pszText = const_cast<LPTSTR>(item->peer.c_str());
+ ListView_SetItem(control, &lvi);
+
+ lvi.iSubItem = 4;
+ lvi.pszText = const_cast<LPTSTR>(item->message.c_str());
+ ListView_SetItem(control, &lvi);
+
+ ++counter;
+ }
+
+ if(scroll) {
+ ListView_EnsureVisible(control, lvi.iItem, FALSE);
+ }
+}
+
+void copy(HWND hwnd) {
+ tstring str;
+
+ auto control = GetDlgItem(hwnd, IDC_MESSAGES);
+ LVITEM lvi = { LVIF_PARAM };
+ int i = -1;
+ while((i = ListView_GetNextItem(control, i, LVNI_SELECTED)) != -1) {
+ lvi.iItem = i;
+ if(ListView_GetItem(control, &lvi)) {
+ auto& item = *reinterpret_cast<Item*>(lvi.lParam);
+ if(!str.empty()) { str += _T("\r\n"); }
+ str += item.index + _T(" ") + item.ip + _T(" (") + item.peer + _T("): ") + item.message;
+ }
+ }
+
+ // the following has been taken from WinUtil::setClipboard
+
+ if(!::OpenClipboard(hwnd)) {
+ return;
+ }
+
+ EmptyClipboard();
+
+ // Allocate a global memory object for the text.
+ HGLOBAL hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (str.size() + 1) * sizeof(TCHAR));
+ if(hglbCopy == NULL) {
+ CloseClipboard();
+ return;
+ }
+
+ // Lock the handle and copy the text to the buffer.
+ TCHAR* lptstrCopy = (TCHAR*) GlobalLock(hglbCopy);
+ _tcscpy(lptstrCopy, str.c_str());
+ GlobalUnlock(hglbCopy);
+
+ // Place the handle on the clipboard.
+ SetClipboardData(CF_UNICODETEXT, hglbCopy);
+
+ CloseClipboard();
+}
+
+void switchScroll(HWND hwnd) {
+ scroll = SendMessage(GetDlgItem(hwnd, IDC_SCROLL), BM_GETCHECK, 0, 0) == BST_CHECKED;
+}
+
+void clear(HWND hwnd) {
+ auto control = GetDlgItem(hwnd, IDC_MESSAGES);
+
+ LVITEM lvi = { LVIF_PARAM };
+ for(decltype(counter) i = 0; i < counter; ++i) {
+ lvi.iItem = i;
+ if(ListView_GetItem(control, &lvi)) {
+ delete reinterpret_cast<Item*>(lvi.lParam);
+ }
+ }
+
+ ListView_DeleteAllItems(control);
+ counter = 0;
+}
+
void command(HWND hwnd, UINT id) {
switch(id) {
case IDOK:
@@ -95,27 +211,25 @@
SendMessage(hwnd, WM_CLOSE, 0, 0);
break;
}
- }
-}
-
-void timer(HWND hwnd) {
- auto control = GetDlgItem(hwnd, IDC_MESSAGES);
-
- SendMessage(control, WM_SETREDRAW, FALSE, 0);
-
- {
- SETTEXTEX config = { ST_SELECTION, CP_ACP };
-
- Lock l(mutex);
- for(auto& text: messages) {
- SendMessage(control, EM_SETSEL, static_cast<WPARAM>(-1), static_cast<LPARAM>(-1));
- SendMessage(control, EM_SETTEXTEX, reinterpret_cast<WPARAM>(&config), reinterpret_cast<LPARAM>(formatText(text).c_str()));
- }
- messages.clear();
- }
-
- SendMessage(control, WM_SETREDRAW, TRUE, 0);
- RedrawWindow(control, 0, 0, RDW_ERASE | RDW_INVALIDATE);
+
+ case IDC_COPY:
+ {
+ copy(hwnd);
+ break;
+ }
+
+ case IDC_SCROLL:
+ {
+ switchScroll(hwnd);
+ break;
+ }
+
+ case IDC_CLEAR:
+ {
+ clear(hwnd);
+ break;
+ }
+ }
}
INT_PTR CALLBACK DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
@@ -124,19 +238,24 @@
{
return init(hwnd);
}
+ case WM_TIMER:
+ {
+ timer(hwnd);
+ break;
+ }
+ case WM_COMMAND:
+ {
+ command(hwnd, LOWORD(wParam));
+ break;
+ }
case WM_CLOSE:
{
DestroyWindow(hwnd);
break;
}
- case WM_COMMAND:
- {
- command(hwnd, LOWORD(wParam));
- break;
- }
- case WM_TIMER:
- {
- timer(hwnd);
+ case WM_DESTROY:
+ {
+ clear(hwnd);
break;
}
}
@@ -145,7 +264,7 @@
} // unnamed namespace
-Dialog::Dialog() : hwnd(nullptr), richEditLib(nullptr)
+Dialog::Dialog() : hwnd(nullptr)
{
}
@@ -153,14 +272,9 @@
if(hwnd) {
DestroyWindow(hwnd);
}
- if(richEditLib) {
- FreeLibrary(richEditLib);
- }
}
void Dialog::create(HWND parent) {
- richEditLib = LoadLibrary(_T("msftedit.dll"));
-
hwnd = CreateDialog(instance, MAKEINTRESOURCE(IDD_PLUGINDLG), hwnd, DialogProc);
#ifdef _DEBUG
@@ -170,14 +284,10 @@
MessageBox(parent, buf, _T("Error creating the dev plugin's dialog"), MB_OK);
}
#endif
-
- /// @todo what about when the limit is hit?
- SendMessage(GetDlgItem(hwnd, IDC_MESSAGES), EM_LIMITTEXT, 10 * 64 * 1024, 0);
-
- SetTimer(hwnd, 1, 500, 0);
}
-void Dialog::write(string&& text) {
+void Dialog::write(bool sending, string ip, string peer, string message) {
+ Message msg = { sending, move(ip), move(peer), move(message) };
Lock l(mutex);
- messages.push_back(std::move(text));
+ messages.push_back(move(msg));
}
=== modified file 'plugins/Dev/Dialog.h'
--- plugins/Dev/Dialog.h 2012-07-19 22:00:20 +0000
+++ plugins/Dev/Dialog.h 2012-07-20 13:04:43 +0000
@@ -28,13 +28,12 @@
~Dialog();
void create(HWND parent);
- void write(string&& text);
+ void write(bool sending, string ip, string peer, string message);
static HINSTANCE instance;
private:
HWND hwnd;
- HMODULE richEditLib;
};
#endif
=== modified file 'plugins/Dev/Plugin.cpp'
--- plugins/Dev/Plugin.cpp 2012-07-19 22:00:20 +0000
+++ plugins/Dev/Plugin.cpp 2012-07-20 13:04:43 +0000
@@ -98,22 +98,22 @@
}
Bool Plugin::onHubDataIn(HubDataPtr hHub, const char* message) {
- dialog.write("From " + string(hHub->ip) + " (" + string(hHub->url) + "): " + string(message) + "\n");
+ dialog.write(false, hHub->ip, "Hub " + string(hHub->url), message);
return False;
}
Bool Plugin::onHubDataOut(HubDataPtr hHub, const char* message, Bool* bBreak) {
- dialog.write("To " + string(hHub->ip) + " (" + string(hHub->url) + "): " + string(message) + "\n");
+ dialog.write(true, hHub->ip, "Hub " + string(hHub->url), message);
return False;
}
Bool Plugin::onConnectionDataIn(ConnectionDataPtr hConn, const char* message) {
- dialog.write("From " + string(hConn->ip) + " (" + string(reinterpret_cast<UserDataPtr>(hConn->object)->nick) + "): " + string(message) + "\n");
+ dialog.write(false, hConn->ip, "User " + string(reinterpret_cast<UserDataPtr>(hConn->object)->nick), message);
return False;
}
Bool Plugin::onConnectionDataOut(ConnectionDataPtr hConn, const char* message) {
- dialog.write("To " + string(hConn->ip) + " (" + string(reinterpret_cast<UserDataPtr>(hConn->object)->nick) + "): " + string(message) + "\n");
+ dialog.write(true, hConn->ip, "User " + string(reinterpret_cast<UserDataPtr>(hConn->object)->nick), message);
return False;
}
=== modified file 'plugins/Dev/resource.h'
--- plugins/Dev/resource.h 2012-07-19 22:00:20 +0000
+++ plugins/Dev/resource.h 2012-07-20 13:04:43 +0000
@@ -5,6 +5,9 @@
#define VERSION_INFO 1
#define IDD_PLUGINDLG 101
#define IDC_MESSAGES 1001
+#define IDC_COPY 1002
+#define IDC_CLEAR 1003
+#define IDC_SCROLL 1004
// Next default values for new objects
//
@@ -12,7 +15,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1002
+#define _APS_NEXT_CONTROL_VALUE 1005
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
=== modified file 'plugins/Dev/resource.rc'
--- plugins/Dev/resource.rc 2012-07-19 22:00:20 +0000
+++ plugins/Dev/resource.rc 2012-07-20 13:04:43 +0000
@@ -89,14 +89,17 @@
// Dialog
//
-IDD_PLUGINDLG DIALOGEX 0, 0, 659, 479
+IDD_PLUGINDLG DIALOGEX 0, 0, 723, 479
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Dev plugin"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
- DEFPUSHBUTTON "OK",IDOK,545,458,50,14
- PUSHBUTTON "Cancel",IDCANCEL,602,458,50,14
- CONTROL "",IDC_MESSAGES,"RICHEDIT50W",WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP | 0x884,7,7,645,441
+ DEFPUSHBUTTON "Close",IDOK,666,458,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,615,458,50,14,NOT WS_VISIBLE | WS_DISABLED
+ CONTROL "",IDC_MESSAGES,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP,7,7,709,441
+ PUSHBUTTON "Copy selected messages",IDC_COPY,7,458,129,14
+ PUSHBUTTON "Clear the list",IDC_CLEAR,282,458,88,14
+ CONTROL "Auto-scroll",IDC_SCROLL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,181,462,58,10
END
@@ -111,9 +114,10 @@
IDD_PLUGINDLG, DIALOG
BEGIN
LEFTMARGIN, 7
- RIGHTMARGIN, 652
+ RIGHTMARGIN, 716
TOPMARGIN, 7
BOTTOMMARGIN, 472
+ HORZGUIDE, 458
END
END
#endif // APSTUDIO_INVOKED