📄 directorylistingfrm.cpp
字号:
/*
* Copyright (C) 2001-2006 Jacek Sieka, arnetheduck on gmail point com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "stdafx.h"
#include "../client/DCPlusPlus.h"
#include "Resource.h"
#include "DirectoryListingFrm.h"
#include "WinUtil.h"
#include "LineDlg.h"
#include "../client/File.h"
#include "../client/QueueManager.h"
#include "../client/StringTokenizer.h"
#include "../client/ADLSearch.h"
#include "../client/MerkleTree.h"
#include "../client/User.h"
#include "../client/ClientManager.h"
DirectoryListingFrame::FrameMap DirectoryListingFrame::frames;
int DirectoryListingFrame::columnIndexes[] = { COLUMN_FILENAME, COLUMN_TYPE, COLUMN_EXACTSIZE, COLUMN_SIZE, COLUMN_TTH };
int DirectoryListingFrame::columnSizes[] = { 300, 60, 100, 100, 200 };
static ResourceManager::Strings columnNames[] = { ResourceManager::FILE, ResourceManager::TYPE, ResourceManager::EXACT_SIZE, ResourceManager::SIZE, ResourceManager::TTH_ROOT };
DirectoryListingFrame::UserMap DirectoryListingFrame::lists;
void DirectoryListingFrame::openWindow(const tstring& aFile, const User::Ptr& aUser, int64_t aSpeed) {
UserIter i = lists.find(aUser);
if(i != lists.end()) {
if(!BOOLSETTING(POPUNDER_FILELIST)) {
i->second->speed = aSpeed;
i->second->MDIActivate(i->second->m_hWnd);
}
} else {
DirectoryListingFrame* frame = new DirectoryListingFrame(aUser, aSpeed);
if(BOOLSETTING(POPUNDER_FILELIST)) {
WinUtil::hiddenCreateEx(frame);
} else {
frame->CreateEx(WinUtil::mdiClient);
}
frame->loadFile(aFile);
frames.insert( FramePair( frame->m_hWnd, frame ) );
}
}
void DirectoryListingFrame::openWindow(const User::Ptr& aUser, const string& txt, int64_t aSpeed) {
UserIter i = lists.find(aUser);
if(i != lists.end()) {
i->second->speed = aSpeed;
i->second->loadXML(txt);
} else {
DirectoryListingFrame* frame = new DirectoryListingFrame(aUser, aSpeed);
if(BOOLSETTING(POPUNDER_FILELIST)) {
WinUtil::hiddenCreateEx(frame);
} else {
frame->CreateEx(WinUtil::mdiClient);
}
frame->loadXML(txt);
frames.insert( FramePair( frame->m_hWnd, frame ) );
}
}
DirectoryListingFrame::DirectoryListingFrame(const User::Ptr& aUser, int64_t aSpeed) :
statusContainer(STATUSCLASSNAME, this, STATUS_MESSAGE_MAP), treeContainer(WC_TREEVIEW, this, CONTROL_MESSAGE_MAP),
listContainer(WC_LISTVIEW, this, CONTROL_MESSAGE_MAP), historyIndex(0),
treeRoot(NULL), skipHits(0), files(0), speed(aSpeed), updating(false), dl(new DirectoryListing(aUser)), searching(false)
{
lists.insert(make_pair(aUser, this));
}
void DirectoryListingFrame::loadFile(const tstring& name) {
try {
dl->loadFile(Text::fromT(name));
ADLSearchManager::getInstance()->matchListing(*dl);
refreshTree(Text::toT(WinUtil::getInitialDir(dl->getUser())));
} catch(const Exception& e) {
error = WinUtil::getNicks(dl->getUser()) + Text::toT(": " + e.getError());
}
initStatus();
}
void DirectoryListingFrame::loadXML(const string& txt) {
try {
refreshTree(Text::toT(Util::toNmdcFile(dl->loadXML(txt, true))));
} catch(const Exception& e) {
error = WinUtil::getNicks(dl->getUser()) + Text::toT(": " + e.getError());
}
initStatus();
}
LRESULT DirectoryListingFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) {
CreateSimpleStatusBar(ATL_IDS_IDLEMESSAGE, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP);
ctrlStatus.Attach(m_hWndStatusBar);
statusContainer.SubclassWindow(ctrlStatus.m_hWnd);
ctrlTree.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_HASLINES | TVS_SHOWSELALWAYS | TVS_DISABLEDRAGDROP, WS_EX_CLIENTEDGE, IDC_DIRECTORIES);
treeContainer.SubclassWindow(ctrlTree);
ctrlList.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS, WS_EX_CLIENTEDGE, IDC_FILES);
listContainer.SubclassWindow(ctrlList);
ctrlList.SetExtendedListViewStyle(LVS_EX_LABELTIP | LVS_EX_HEADERDRAGDROP | LVS_EX_FULLROWSELECT);
ctrlList.SetBkColor(WinUtil::bgColor);
ctrlList.SetTextBkColor(WinUtil::bgColor);
ctrlList.SetTextColor(WinUtil::textColor);
ctrlTree.SetBkColor(WinUtil::bgColor);
ctrlTree.SetTextColor(WinUtil::textColor);
WinUtil::splitTokens(columnIndexes, SETTING(DIRECTORLISTINGFRAME_ORDER), COLUMN_LAST);
WinUtil::splitTokens(columnSizes, SETTING(DIRECTORLISTINGFRAME_WIDTHS), COLUMN_LAST);
for(int j = 0; j < COLUMN_LAST; j++)
{
int fmt = ((j == COLUMN_SIZE) || (j == COLUMN_EXACTSIZE)) ? LVCFMT_RIGHT : LVCFMT_LEFT;
ctrlList.InsertColumn(j, CTSTRING_I(columnNames[j]), fmt, columnSizes[j], j);
}
ctrlList.SetColumnOrderArray(COLUMN_LAST, columnIndexes);
ctrlList.setSortColumn(COLUMN_FILENAME);
ctrlTree.SetImageList(WinUtil::fileImages, TVSIL_NORMAL);
ctrlList.SetImageList(WinUtil::fileImages, LVSIL_SMALL);
ctrlFind.Create(ctrlStatus.m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
BS_PUSHBUTTON, 0, IDC_FIND);
ctrlFind.SetWindowText(CTSTRING(FIND));
ctrlFind.SetFont(WinUtil::systemFont);
ctrlFindNext.Create(ctrlStatus.m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
BS_PUSHBUTTON, 0, IDC_NEXT);
ctrlFindNext.SetWindowText(CTSTRING(NEXT));
ctrlFindNext.SetFont(WinUtil::systemFont);
ctrlMatchQueue.Create(ctrlStatus.m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
BS_PUSHBUTTON, 0, IDC_MATCH_QUEUE);
ctrlMatchQueue.SetWindowText(CTSTRING(MATCH_QUEUE));
ctrlMatchQueue.SetFont(WinUtil::systemFont);
ctrlListDiff.Create(ctrlStatus.m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
BS_PUSHBUTTON, 0, IDC_FILELIST_DIFF);
ctrlListDiff.SetWindowText(CTSTRING(FILE_LIST_DIFF));
ctrlListDiff.SetFont(WinUtil::systemFont);
SetSplitterExtendedStyle(SPLIT_PROPORTIONAL);
SetSplitterPanes(ctrlTree.m_hWnd, ctrlList.m_hWnd);
m_nProportionalPos = 2500;
string nick = ClientManager::getInstance()->getNicks(dl->getUser()->getCID())[0];
treeRoot = ctrlTree.InsertItem(TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT | TVIF_PARAM, Text::toT(nick).c_str(), WinUtil::getDirIconIndex(), WinUtil::getDirIconIndex(), 0, 0, (LPARAM)dl->getRoot(), NULL, TVI_SORT);
memset(statusSizes, 0, sizeof(statusSizes));
statusSizes[STATUS_FILE_LIST_DIFF] = WinUtil::getTextWidth(TSTRING(FILE_LIST_DIFF), m_hWnd) + 8;
statusSizes[STATUS_MATCH_QUEUE] = WinUtil::getTextWidth(TSTRING(MATCH_QUEUE), m_hWnd) + 8;
statusSizes[STATUS_FIND] = WinUtil::getTextWidth(TSTRING(FIND), m_hWnd) + 8;
statusSizes[STATUS_NEXT] = WinUtil::getTextWidth(TSTRING(NEXT), m_hWnd) + 8;
ctrlStatus.SetParts(STATUS_LAST, statusSizes);
fileMenu.CreatePopupMenu();
targetMenu.CreatePopupMenu();
directoryMenu.CreatePopupMenu();
targetDirMenu.CreatePopupMenu();
fileMenu.AppendMenu(MF_STRING, IDC_DOWNLOAD, CTSTRING(DOWNLOAD));
fileMenu.AppendMenu(MF_POPUP, (UINT_PTR)(HMENU)targetMenu, CTSTRING(DOWNLOAD_TO));
fileMenu.AppendMenu(MF_STRING, IDC_VIEW_AS_TEXT, CTSTRING(VIEW_AS_TEXT));
fileMenu.AppendMenu(MF_SEPARATOR);
fileMenu.AppendMenu(MF_STRING, IDC_SEARCH_ALTERNATES, CTSTRING(SEARCH_FOR_ALTERNATES));
fileMenu.AppendMenu(MF_STRING, IDC_BITZI_LOOKUP, CTSTRING(LOOKUP_AT_BITZI));
fileMenu.AppendMenu(MF_STRING, IDC_COPY_MAGNET, CTSTRING(COPY_MAGNET));
fileMenu.SetMenuDefaultItem(IDC_DOWNLOAD);
directoryMenu.AppendMenu(MF_STRING, IDC_DOWNLOADDIR, CTSTRING(DOWNLOAD));
directoryMenu.AppendMenu(MF_POPUP, (UINT_PTR)(HMENU)targetDirMenu, CTSTRING(DOWNLOAD_TO));
setWindowTitle();
bHandled = FALSE;
return 1;
}
void DirectoryListingFrame::updateTree(DirectoryListing::Directory* aTree, HTREEITEM aParent) {
for(DirectoryListing::Directory::Iter i = aTree->directories.begin(); i != aTree->directories.end(); ++i) {
tstring name;
if(dl->getUtf8()) {
name = Text::toT((*i)->getName());
} else {
name = Text::toT(Text::acpToUtf8((*i)->getName()));
}
int index = (*i)->getComplete() ? WinUtil::getDirIconIndex() : WinUtil::getDirMaskedIndex();
HTREEITEM ht = ctrlTree.InsertItem(TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT | TVIF_PARAM, name.c_str(), index, index, 0, 0, (LPARAM)*i, aParent, TVI_SORT);
if((*i)->getAdls())
ctrlTree.SetItemState(ht, TVIS_BOLD, TVIS_BOLD);
updateTree(*i, ht);
}
}
void DirectoryListingFrame::refreshTree(const tstring& root) {
ctrlTree.SetRedraw(FALSE);
HTREEITEM ht = findItem(treeRoot, root);
if(ht == NULL) {
ht = treeRoot;
}
DirectoryListing::Directory* d = (DirectoryListing::Directory*)ctrlTree.GetItemData(ht);
HTREEITEM next = NULL;
while((next = ctrlTree.GetChildItem(ht)) != NULL) {
ctrlTree.DeleteItem(next);
}
updateTree(d, ht);
ctrlTree.Expand(treeRoot);
int index = d->getComplete() ? WinUtil::getDirIconIndex() : WinUtil::getDirMaskedIndex();
ctrlTree.SetItemImage(ht, index, index);
ctrlTree.SelectItem(NULL);
selectItem(root);
ctrlTree.SetRedraw(TRUE);
}
void DirectoryListingFrame::updateStatus() {
if(!searching && !updating && ctrlStatus.IsWindow()) {
int cnt = ctrlList.GetSelectedCount();
int64_t total = 0;
if(cnt == 0) {
cnt = ctrlList.GetItemCount ();
total = ctrlList.forEachT(ItemInfo::TotalSize()).total;
} else {
total = ctrlList.forEachSelectedT(ItemInfo::TotalSize()).total;
}
tstring tmp = Text::toT(STRING(ITEMS) + ": " + Util::toString(cnt));
bool u = false;
int w = WinUtil::getTextWidth(tmp, ctrlStatus.m_hWnd);
if(statusSizes[STATUS_SELECTED_FILES] < w) {
statusSizes[STATUS_SELECTED_FILES] = w;
u = true;
}
ctrlStatus.SetText(STATUS_SELECTED_FILES, tmp.c_str());
tmp = Text::toT(STRING(SIZE) + ": " + Util::formatBytes(total));
w = WinUtil::getTextWidth(tmp, ctrlStatus.m_hWnd);
if(statusSizes[STATUS_SELECTED_SIZE] < w) {
statusSizes[STATUS_SELECTED_SIZE] = w;
u = true;
}
ctrlStatus.SetText(STATUS_SELECTED_SIZE, tmp.c_str());
if(u)
UpdateLayout(TRUE);
}
}
void DirectoryListingFrame::initStatus() {
files = dl->getTotalFileCount();
size = Util::formatBytes(dl->getTotalSize());
tstring tmp = Text::toT(STRING(FILES) + ": " + Util::toString(dl->getTotalFileCount(true)));
statusSizes[STATUS_TOTAL_FILES] = WinUtil::getTextWidth(tmp, m_hWnd);
ctrlStatus.SetText(STATUS_TOTAL_FILES, tmp.c_str());
tmp = Text::toT(STRING(SIZE) + ": " + Util::formatBytes(dl->getTotalSize(true)));
statusSizes[STATUS_TOTAL_SIZE] = WinUtil::getTextWidth(tmp, m_hWnd);
ctrlStatus.SetText(STATUS_TOTAL_SIZE, tmp.c_str());
tmp = Text::toT(STRING(SPEED) + ": " + Util::formatBytes(speed) + "/s");
statusSizes[STATUS_SPEED] = WinUtil::getTextWidth(tmp, m_hWnd);
ctrlStatus.SetText(STATUS_SPEED, tmp.c_str());
UpdateLayout(FALSE);
}
LRESULT DirectoryListingFrame::onSelChangedDirectories(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) {
NMTREEVIEW* p = (NMTREEVIEW*) pnmh;
if(p->itemNew.state & TVIS_SELECTED) {
DirectoryListing::Directory* d = (DirectoryListing::Directory*)p->itemNew.lParam;
changeDir(d, TRUE);
addHistory(dl->getPath(d));
}
return 0;
}
void DirectoryListingFrame::addHistory(const string& name) {
history.erase(history.begin() + historyIndex, history.end());
while(history.size() > 25)
history.pop_front();
history.push_back(name);
historyIndex = history.size();
}
void DirectoryListingFrame::changeDir(DirectoryListing::Directory* d, BOOL enableRedraw)
{
ctrlList.SetRedraw(FALSE);
updating = true;
clearList();
for(DirectoryListing::Directory::Iter i = d->directories.begin(); i != d->directories.end(); ++i) {
ctrlList.insertItem(ctrlList.GetItemCount(), new ItemInfo(*i, dl->getUtf8()), (*i)->getComplete() ? WinUtil::getDirIconIndex() : WinUtil::getDirMaskedIndex());
}
for(DirectoryListing::File::Iter j = d->files.begin(); j != d->files.end(); ++j) {
ItemInfo* ii = new ItemInfo(*j, dl->getUtf8());
ctrlList.insertItem(ctrlList.GetItemCount(), ii, WinUtil::getIconIndex(ii->getText(COLUMN_FILENAME)));
}
ctrlList.resort();
ctrlList.SetRedraw(enableRedraw);
updating = false;
updateStatus();
if(!d->getComplete()) {
if(dl->getUser()->isOnline()) {
QueueManager::getInstance()->addPfs(dl->getUser(), dl->getPath(d));
ctrlStatus.SetText(STATUS_TEXT, CTSTRING(DOWNLOADING_LIST));
} else {
ctrlStatus.SetText(STATUS_TEXT, CTSTRING(USER_OFFLINE));
}
}
}
void DirectoryListingFrame::up() {
HTREEITEM t = ctrlTree.GetSelectedItem();
if(t == NULL)
return;
t = ctrlTree.GetParentItem(t);
if(t == NULL)
return;
ctrlTree.SelectItem(t);
}
void DirectoryListingFrame::back() {
if(history.size() > 1 && historyIndex > 1) {
size_t n = min(historyIndex, history.size()) - 1;
deque<string> tmp = history;
selectItem(Text::toT(history[n - 1]));
historyIndex = n;
history = tmp;
}
}
void DirectoryListingFrame::forward() {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -