📄 cdiskusersview.cpp
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: CDiskUsersView.cpp,v 1.12 2002/09/24 19:58:28 wjb Exp $
____________________________________________________________________________*/
#include "pgpClassesConfig.h"
#include <stdio.h>
#include "UString.h"
#include "CBitmap.h"
#include "CBrush.h"
#include "CDC.h"
#include "CFont.h"
#include "CIcon.h"
#include "CImageList.h"
#include "CMenu.h"
#include "CMessageBox.h"
#include "CPen.h"
#include "CRect.h"
#include "UModuleInstance.h"
#include "UCommonStrings.h"
#include "CPGPdiskEngine.h"
#include "CPGPKey.h"
#include "CPGPKeyDB.h"
#include "CDiskUsersView.h"
#include "CPGPKeySearcher.h"
#include "ImageIDs.h"
#include "pgpUnicode.h"
#include "Resource.h"
_USING_PGP
_UNNAMED_BEGIN
// Constants
const float kUserNameColRatio = 0.48F;
const float kReadOnlyColRatio = 0.14F;
const float kKindColRatio = 0.36F;
_UNNAMED_END
// Types
struct CDiskUsersView::DiskUserItem :
public CListableObject<CDiskUsersView::DiskUserItem>
{
CPGPdiskUser user;
CString userName;
CString kindText;
PGPBoolean isPubAndNotInRing;
PGPUInt32 icon;
};
struct CDiskUsersView::DKViewDrawElements
{
COLORREF barColor;
CBrush stdBarBrush;
CBrush spcBarBrush;
CPen gSelTextPen;
CPen gUnselTextPen;
CPen hilightPen;
CPen shadowPen;
CPen buttonPen;
CBrush barBGBrush;
CBrush highBrush;
CBrush backBrush;
CFont hFont;
CFont hBold;
CFont hItalic;
CFont hStrikeOut;
CFont hItalicStrikeOut;
CFont hBoldStrikeOut;
CImageList image;
};
// Class CDiskUsersView member functions
CDiskUsersView::CDiskUsersView() :
mPContext(NULL), mPDiskUsers(NULL), mPDE(NULL), mUserNameColIndex(0),
mReadOnlyColIndex(0), mKindColIndex(0)
{
}
PGPBoolean
CDiskUsersView::AreUnknownUsers() const
{
DiskUserItem *pItem = mItemList.Head();
while (IsntNull(pItem))
{
if (pItem->isPubAndNotInRing)
return TRUE;
pItem = mItemList.Next(pItem);
}
return FALSE;
}
void
CDiskUsersView::SelectIndex(PGPInt32 i)
{
SetItemState(i, LVIS_FOCUSED | LVIS_SELECTED,
LVIS_FOCUSED | LVIS_SELECTED);
RedrawItems(i, i);
}
void
CDiskUsersView::SelectAllItems()
{
PGPInt32 count = GetItemCount();
for (PGPInt32 i = 0; i < count; i++)
{
if (i == 0)
{
SetItemState(i, LVIS_FOCUSED | LVIS_SELECTED,
LVIS_FOCUSED | LVIS_SELECTED);
}
else
{
SetItemState(i, LVIS_SELECTED, LVIS_SELECTED);
}
}
RedrawItems(0, count);
}
void
CDiskUsersView::GetSelectedUsers(CPGPdiskUserSet *pUsers) const
{
PGPUInt32 itemCount = GetItemCount();
for (PGPUInt32 i = 0; i < itemCount; i++)
{
if (GetItemState(i, LVIS_SELECTED))
pUsers->Add(GetUserAtIndex(i));
}
}
void
CDiskUsersView::SetActiveColumns(PGPUInt32 columns)
{
mActiveColumns = columns;
UpdateColumns();
InvalidateRect(NULL, TRUE);
}
void
CDiskUsersView::SortOnColumn(PGPUInt32 column)
{
if (mLastSortColumn == column)
mSortAscending = !mSortAscending;
else
mSortAscending = TRUE;
mLastSortColumn = column;
SortItems(DiskUserViewCompareProc, reinterpret_cast<LPARAM>(this));
}
void
CDiskUsersView::LookupUnknownKeys()
{
CList<CPGPKeySearcher::SearchItem> searchItems;
try
{
// Look for users for which we have only the key ID.
DiskUserItem *pItem = mItemList.Head();
while (IsntNull(pItem))
{
if (pItem->isPubAndNotInRing)
{
auto_ptr<CPGPKeySearcher::SearchItem> pSearchItem(
new CPGPKeySearcher::SearchItem);
pItem->user.GetPGPKeyID(pSearchItem->keyID);
pSearchItem->userData = pItem;
searchItems.AddTail(pSearchItem.release());
}
pItem = mItemList.Next(pItem);
}
// Look up the keys.
if (searchItems.Count() > 0)
{
CPGPKeyDB keyDB(mPContext->PGPKeyDB());
PGPBoolean wasAKeyNotFound = FALSE;
CPGPKeySearcher::SearchKeys(*mPContext, GetParent(),
searchItems, keyDB);
CPGPKeySearcher::SearchItem *pSearchItem = searchItems.Head();
while (IsntNull(pSearchItem))
{
// Update found keys in the UI.
if (pSearchItem->wasFound)
{
pItem = static_cast<DiskUserItem *>(
pSearchItem->userData);
CalcItemDisplayData(pItem, TRUE);
}
else
{
wasAKeyNotFound = TRUE;
}
pSearchItem = searchItems.Next(pSearchItem);
}
// warn if at least one key not found
if (wasAKeyNotFound)
{
using namespace UCommonStrings;
CMessageBox messageBox;
messageBox.Display(Get(kTellUnknownKeyNotFound),
Get(kEditorMsgBoxTitle), Handle(), CMessageBox::kWarningTone);
}
}
searchItems.EmptyWithDelete();
}
catch (CComboError& error)
{
using namespace UCommonStrings;
ReportError(kTellSearchForKeysFailed, kDiskUserViewMsgBoxTitle,
error, Handle());
searchItems.EmptyWithDelete();
throw;
}
}
void
CDiskUsersView::Fill(
const CPGPdiskContext *pContext,
const CPGPdiskUserSet& diskUsers,
PGPBoolean singleSelect)
{
pgpAssert(WeSubclassed());
Clear();
CreateDrawElements();
mPDiskUsers = new CPGPdiskUserSet;
if (IsNull(mPContext))
{
// First time.
mPContext = pContext;
mSingleSelect = singleSelect;
mSortAscending = FALSE;
mLastSortColumn = 0;
if (singleSelect)
SetStyle(GetStyle() | LVS_SINGLESEL);
else
SetStyle(GetStyle() & ~LVS_SINGLESEL);
SetActiveColumns(kUserNameColFlag | kReadOnlyColFlag | kKindColFlag);
GenerateMeasureItem();
}
// Update internal key list.
CPGPdiskUserIter curUsersIter(*mPDiskUsers), newUsersIter(diskUsers);
CPGPdiskUser curUser, newUser;
while (curUsersIter.Next(curUser))
{
if (!newUsersIter.FindEqualUser(curUser, newUser))
RemoveUser(curUser);
}
newUsersIter.Rewind();
while (newUsersIter.Next(newUser))
{
if (curUsersIter.FindEqualUser(newUser, curUser))
UpdateUser(newUser, TRUE);
else
AddUser(newUser);
}
}
void
CDiskUsersView::Clear()
{
DeleteAllItems();
mItemList.EmptyWithDelete();
if (IsntNull(mPDiskUsers))
{
delete mPDiskUsers;
mPDiskUsers = NULL;
}
if (IsntNull(mPDE))
DeleteDrawElements();
}
void
CDiskUsersView::Create(
HWND parent,
PGPUInt32 id,
PGPInt32 xOffset,
PGPInt32 yOffset,
PGPInt32 width,
PGPInt32 height)
{
CListView::Create(parent, id, WS_TABSTOP | LVS_REPORT |
LVS_OWNERDRAWFIXED, WS_EX_CLIENTEDGE | WS_EX_NOPARENTNOTIFY,
xOffset, yOffset, width, height);
}
int
CDiskUsersView::DiskUserViewCompareProcAux(
const DiskUserItem *pKey1,
const DiskUserItem *pKey2)
{
pgpAssertAddrValid(pKey1, DiskUserItem);
pgpAssertAddrValid(pKey2, DiskUserItem);
if (mLastSortColumn == mUserNameColIndex)
{
if (mSortAscending)
return strcmp(pKey1->userName, pKey2->userName);
else
return strcmp(pKey2->userName, pKey1->userName);
}
else if (mLastSortColumn == mReadOnlyColIndex)
{
if (mSortAscending)
return (!pKey1->user.IsReadOnly() && pKey2->user.IsReadOnly());
else
return (!pKey2->user.IsReadOnly() && pKey1->user.IsReadOnly());
}
else if (mLastSortColumn == mKindColIndex)
{
if (mSortAscending)
return strcmp(pKey1->kindText, pKey2->kindText);
else
return strcmp(pKey2->kindText, pKey1->kindText);
}
return 0;
}
int
CALLBACK
CDiskUsersView::DiskUserViewCompareProc(
LPARAM lParam1,
LPARAM lParam2,
LPARAM lParamSort)
{
CDiskUsersView *pView = reinterpret_cast<CDiskUsersView *>(lParamSort);
pgpAssertAddrValid(pView, CDiskUsersView);
return pView->DiskUserViewCompareProcAux(
reinterpret_cast<DiskUserItem *>(lParam1),
reinterpret_cast<DiskUserItem *>(lParam2));
}
void
CDiskUsersView::DrawTrueFalseButton(
CDC& itemDC,
const CRect& ptrBarRect,
PGPBoolean trueFalse,
PGPBoolean isSelected) const
{
if (isSelected)
itemDC.FillRect(ptrBarRect, mPDE->highBrush);
else
itemDC.FillRect(ptrBarRect, mPDE->backBrush);
if (ptrBarRect.Width() >= CIcon::kSmallIconWidth)
{
PGPUInt32 noviceIcon;
if (trueFalse)
{
noviceIcon = ImageIDs::kADKPushed;
mPDE->image.Draw(noviceIcon, itemDC,
ptrBarRect.Left() +
(ptrBarRect.Width() - CIcon::kSmallIconWidth)/2,
ptrBarRect.Top() +
(ptrBarRect.Height() - CIcon::kSmallIconWidth)/2,
ILD_TRANSPARENT);
}
}
}
// _______________________________________________
//
// Truncate text string
static BOOL sTruncateText (
HDC hdc,
WCHAR* wsz,
int xmax)
{
BOOL bShowToolTip = FALSE;
SIZE s;
int l, w;
// truncate at <newline>, if present
l = 0;
while (wsz[l])
{
if (wsz[l] == '\n')
{
wsz[l] = 0;
bShowToolTip = TRUE;
break;
}
l++;
}
GetTextExtentPoint32W (hdc, wsz, lstrlenW (wsz), &s);
w = s.cx + 4;
l = lstrlenW (wsz);
if (l < 3)
{
if (w > xmax)
{
bShowToolTip = TRUE;
wsz[0] = 0;
}
}
else
{
l = lstrlenW (wsz) - 3;
while ((w > xmax) && (l >= 0))
{
bShowToolTip = TRUE;
lstrcpyW (&wsz[l], L"...");
GetTextExtentPoint32W (hdc, wsz, lstrlenW (wsz), &s);
w = s.cx + 4;
l--;
}
if (l < 0)
wsz[0] = 0;
}
return bShowToolTip;
}
#define MAXUSERIDSTRING kPGPMaxUserIDSize + 32
void
CDiskUsersView::DrawItemColumn(
CDC& itemDC,
const char *userID,
const CRect& prcClip) const
{
WCHAR wsz[MAXUSERIDSTRING];
PGPUInt32 ulen;
// CString cuserID(userID);
// itemDC.FitStringToWidth(cuserID, prcClip.Width());
// itemDC.ExtTextOut(prcClip.Left() + 2, prcClip.Top() + 1,
// ETO_CLIPPED | ETO_OPAQUE, prcClip, cuserID, cuserID.Length(), NULL);
pgpUTF8StringToUCS2 (userID, kPGPUnicodeNullTerminated,
wsz, MAXUSERIDSTRING, &ulen);
sTruncateText (itemDC.DC(), wsz, prcClip.Right() - prcClip.Left());
// print the text
ExtTextOutW(itemDC.DC(), prcClip.Left() + 2, prcClip.Top() + 1,
ETO_CLIPPED | ETO_OPAQUE,
prcClip,
wsz,
lstrlenW(wsz),
NULL);
}
void
CDiskUsersView::DrawUserItemAux(
LPDRAWITEMSTRUCT pDIS,
PGPBoolean isFocused) const
{
DiskUserItem *pItem = reinterpret_cast<DiskUserItem *>(
pDIS->itemData);
pgpAssertAddrValid(pItem, DiskUserItem);
CDC itemDC(pDIS->hDC);
CRect itemRect = pDIS->rcItem;
mPDE->image.Draw(pItem->icon, itemDC, kPixelsLeftMargin, itemRect.Top(),
ILD_TRANSPARENT);
itemRect.Left() = CIcon::kSmallIconWidth + kPixelsLeftMargin;
if (mActiveColumns & kUserNameColFlag)
{
itemRect.Right() = GetColumnWidth(mUserNameColIndex);
CFont oldFont(itemDC.SelectObject(mPDE->hFont.Get()));
CRect origRect(itemRect);
if (pItem->user.IsAdminUser())
itemDC.SelectObject(mPDE->hBold.Get());
else if (pItem->user.IsDisabled())
itemDC.SelectObject(mPDE->hItalic.Get());
// See if we need the lock icon.
if (pItem->user.IsLocked())
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -