DragonNest/Server/ServiceManagerEx/LogList.cpp
Cussrro 47f7895977 Revert "修复编码问题"
This reverts commit 9e69c01767.
2024-12-21 10:04:04 +08:00

286 lines
5.8 KiB
C++

// LogList.cpp : ±¸Çö ÆÄÀÏÀÔ´Ï´Ù.
//
#include "stdafx.h"
#include "ServiceManagerEx.h"
#include "LogList.h"
#include "Log.h"
#include "LogFindDlg.h"
#include "LogBuilder.h"
#include "ServiceManager.h"
#include "ErrorCode.h"
#include <sstream>
extern CServiceManager* g_pServiceManager;
IMPLEMENT_DYNAMIC(CLogList, CListCtrl)
CLogList::CLogList(BYTE flags)
: m_MenuFlags(flags), m_LineIndex(0)
{
}
CLogList::~CLogList()
{
for each (const LogItem* p in m_Logs)
{
SAFE_DELETE(p);
}
m_Logs.clear();
m_FindLines.clear();
m_LineIndex = 0;
}
BEGIN_MESSAGE_MAP(CLogList, CListCtrl)
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, &CLogList::OnNMCustomdraw)
ON_COMMAND(ID_LIST_CLEAR, &CLogList::OnListClear)
ON_COMMAND(ID_LIST_FIND, &CLogList::OnListFind)
ON_COMMAND(ID_LIST_OPEN, &CLogList::OnListOpen)
ON_WM_CONTEXTMENU()
ON_WM_CHAR()
ON_WM_KEYDOWN()
END_MESSAGE_MAP()
void CLogList::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
{
NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
*pResult = 0;
if (pLVCD->nmcd.dwDrawStage == CDDS_PREPAINT)
{
*pResult = CDRF_NOTIFYITEMDRAW;
}
else if (pLVCD->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
{
LogInfo* pLog = (LogInfo*)pLVCD->nmcd.lItemlParam;
if (pLog)
{
const ViewConfig* pViewConfig = ((CServiceManagerExApp*)::AfxGetApp())->GetConfigEx().GetViewConfig(L"Log");
if (pViewConfig)
{
pLVCD->clrText = pViewConfig->GetFontColor(pLog->type);
pLVCD->clrTextBk = pViewConfig->GetBgColor();
}
else
{
pLVCD->clrText = RGB(192, 192, 192);
pLVCD->clrTextBk = RGB(0, 0, 0);
}
}
*pResult = CDRF_DODEFAULT;
}
}
void CLogList::OnListClear()
{
if (IDYES != ::AfxMessageBox(L"Are you sure to clear list?", MB_ICONQUESTION | MB_YESNO))
return;
Clear();
}
void CLogList::OnListFind()
{
CLogFindDlg dlg;
dlg.DoModal();
wstring findWhat = dlg.GetFindWhat();
BYTE flags = dlg.GetOptionFlags();
m_FindLines.clear();
m_LineIndex = 0;
for each (const LogItem* pLog in m_Logs)
{
wstring word = pLog->text;
if ((flags & MATCH_CASE) != MATCH_CASE)
{
transform(findWhat.begin(), findWhat.end(), findWhat.begin(), towlower);
transform(pLog->text.begin(), pLog->text.end(), word.begin(), towlower);
}
if (wstring::npos != word.find(findWhat))
m_FindLines.push_back(pLog->index);
}
if (m_FindLines.empty())
{
CString message;
message.Format(L"The following specified text was not found:\n\n%s", findWhat.c_str());
::AfxMessageBox(message, MB_ICONASTERISK | MB_OK);
SetFocus();
return;
}
SelectLine(m_LineIndex);
}
void CLogList::OnListOpen()
{
OpenFile();
}
void CLogList::OnContextMenu(CWnd* /*pWnd*/, CPoint point)
{
CMenu menu;
menu.LoadMenu(IDR_MENU_LOG);
CMenu* pPopup = menu.GetSubMenu(0);
if ((m_MenuFlags & MENU_FIND) != MENU_FIND)
pPopup->DeleteMenu(ID_LIST_FIND, MF_BYCOMMAND);
if ((m_MenuFlags & MENU_CLEAR) != MENU_CLEAR)
pPopup->DeleteMenu(ID_LIST_CLEAR, MF_BYCOMMAND);
if ((m_MenuFlags & MENU_OPEN) != MENU_OPEN)
pPopup->DeleteMenu(ID_LIST_OPEN, MF_BYCOMMAND);
pPopup->DeleteMenu(ID_LIST_CLIPBOARD, MF_BYCOMMAND);
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
menu.DestroyMenu();
}
void CLogList::Pop()
{
if (m_Logs.empty())
return;
delete m_Logs.front();
m_Logs.pop_front();
DeleteItem(0);
}
void CLogList::Clear()
{
for each (const LogItem* p in m_Logs)
{
delete p;
}
m_Logs.clear();
DeleteAllItems();
m_FindLines.clear();
m_LineIndex = 0;
}
void CLogList::InsertLog(LogInfo& log)
{
int count = GetItemCount();
LogItem* pItem = new LogItem(log, count);
LV_ITEM lvItem;
lvItem.mask = LVIF_TEXT | LVIF_PARAM;
lvItem.iItem = count;
lvItem.iSubItem = 0;
lvItem.pszText = const_cast<wchar_t*>(log.date.c_str());
lvItem.lParam = (LPARAM)pItem;
InsertItem(&lvItem);
SetItemText(count, 1, log.type.c_str());
size_t pos = log.text.rfind('\n');
if (pos != wstring::npos)
log.text = log.text.substr(0, pos);
pos = log.text.rfind('\r');
if (pos != wstring::npos)
log.text = log.text.substr(0, pos);
SetItemText(count, 2, log.text.c_str());
EnsureVisible(count, FALSE);
m_Logs.push_back(pItem);
}
void CLogList::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: ¿©±â¿¡ ¸Þ½ÃÁö 󸮱â Äڵ带 Ãß°¡ ¹×/¶Ç´Â ±âº»°ªÀ» È£ÃâÇÕ´Ï´Ù.
if (nChar == 6)
{
OnListFind();
}
CListCtrl::OnChar(nChar, nRepCnt, nFlags);
}
void CLogList::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: ¿©±â¿¡ ¸Þ½ÃÁö 󸮱â Äڵ带 Ãß°¡ ¹×/¶Ç´Â ±âº»°ªÀ» È£ÃâÇÕ´Ï´Ù.
if (!m_FindLines.empty())
{
switch (nChar)
{
case VK_F3:
{
if (m_LineIndex > 0)
--m_LineIndex;
SelectLine(m_LineIndex);
}
break;
case VK_F4:
{
if (m_LineIndex < (int)m_FindLines.size() - 1)
++m_LineIndex;
SelectLine(m_LineIndex);
}
break;
}
}
CListCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
}
bool CLogList::OpenFile()
{
CTime time;
wchar_t filter[] = L"Log (ServiceManager*.log, ExceptionReport*.log)|ServiceManager*.log;ExceptionReport*.log|";
CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, filter);
if (IDOK != dlg.DoModal())
return false;
CString path = dlg.GetPathName();
CLogBuilder builder;
try
{
log_error error = builder.Load(path.GetBuffer());
if (error == error_size_overflow)
{
AfxMessageBox(L"Cannot open file, because file is too large.", MB_ICONASTERISK);
return false;
}
}
catch (...)
{
return false;
}
Clear();
const vector<LogInfo*>& logs = builder.GetLogs();
for each (LogInfo* pLog in logs)
{
InsertLog(*pLog);
}
AfxGetMainWnd()->SetWindowText(L"ServiceManagerEx - " + path);
return true;
}
void CLogList::SelectLine(int index)
{
ASSERT(index >= 0 && index < (int)m_FindLines.size());
int line = m_FindLines[index];
SetItemState(-1, 0, LVIS_SELECTED | LVIS_FOCUSED);
SetItemState(line, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
EnsureVisible(line, FALSE);
SetFocus();
}