⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 queueframe.cpp

📁 p2p技术C源代码.rar
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* 
 * Copyright (C) 2001-2003 Jacek Sieka, j_s@telia.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 "QueueFrame.h"
#include "SearchFrm.h"
#include "PrivateFrame.h"

#include "../client/SimpleXML.h"
#include "../client/StringTokenizer.h"
#include "../client/ShareManager.h"

QueueFrame* QueueFrame::frame = NULL;

#define FILE_LIST_NAME "File Lists"

int QueueFrame::columnIndexes[] = { COLUMN_TARGET, COLUMN_STATUS, COLUMN_SIZE, COLUMN_PRIORITY,
COLUMN_USERS, COLUMN_PATH, COLUMN_ERRORS };

int QueueFrame::columnSizes[] = { 200, 300, 75, 75, 200, 200, 200 };

static ResourceManager::Strings columnNames[] = { ResourceManager::FILENAME, ResourceManager::STATUS, ResourceManager::SIZE, 
ResourceManager::PRIORITY, ResourceManager::USERS, ResourceManager::PATH, ResourceManager::ERRORS };

LRESULT QueueFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
	dcassert(frame == NULL);
	frame = this;

	showTree = BOOLSETTING(QUEUEFRAME_SHOW_TREE);
	
	CreateSimpleStatusBar(ATL_IDS_IDLEMESSAGE, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP);
	ctrlStatus.Attach(m_hWndStatusBar);
	
	ctrlQueue.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | 
		WS_HSCROLL | WS_VSCROLL | LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS, WS_EX_CLIENTEDGE, IDC_QUEUE);

	if(BOOLSETTING(FULL_ROW_SELECT)) {
		ctrlQueue.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP);
	}
	else {
		ctrlQueue.SetExtendedListViewStyle(LVS_EX_HEADERDRAGDROP);
	}

	ctrlDirs.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);
	
	ctrlDirs.SetImageList(WinUtil::fileImages, TVSIL_NORMAL);
	ctrlQueue.SetImageList(WinUtil::fileImages, LVSIL_SMALL);
	
	m_nProportionalPos = 2500;
	SetSplitterPanes(ctrlDirs.m_hWnd, ctrlQueue.m_hWnd);

	// Create listview columns
	WinUtil::splitTokens(columnIndexes, SETTING(QUEUEFRAME_ORDER), COLUMN_LAST);
	WinUtil::splitTokens(columnSizes, SETTING(QUEUEFRAME_WIDTHS), COLUMN_LAST);
	
	for(int j=0; j<COLUMN_LAST; j++) {
		int fmt = (j == COLUMN_SIZE) ? LVCFMT_RIGHT : LVCFMT_LEFT;
		ctrlQueue.InsertColumn(j, CSTRING_I(columnNames[j]), fmt, columnSizes[j], j);
	}
	
	ctrlQueue.SetColumnOrderArray(COLUMN_LAST, columnIndexes);
	
	ctrlQueue.SetBkColor(WinUtil::bgColor);
	ctrlQueue.SetTextBkColor(WinUtil::bgColor);
	ctrlQueue.SetTextColor(WinUtil::textColor);

	ctrlDirs.SetBkColor(WinUtil::bgColor);
	ctrlDirs.SetTextColor(WinUtil::textColor);

	ctrlShowTree.Create(ctrlStatus.m_hWnd, rcDefault, "+/-", WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
	ctrlShowTree.SetButtonStyle(BS_AUTOCHECKBOX, false);
	ctrlShowTree.SetCheck(showTree);
	showTreeContainer.SubclassWindow(ctrlShowTree.m_hWnd);
	
	singleMenu.CreatePopupMenu();
	multiMenu.CreatePopupMenu();
	browseMenu.CreatePopupMenu();
	removeMenu.CreatePopupMenu();
	pmMenu.CreatePopupMenu();
	priorityMenu.CreatePopupMenu();
	dirMenu.CreatePopupMenu();
	readdMenu.CreatePopupMenu();

	singleMenu.AppendMenu(MF_STRING, IDC_SEARCH_ALTERNATES, CSTRING(SEARCH_FOR_ALTERNATES));
	singleMenu.AppendMenu(MF_STRING, IDC_MOVE, CSTRING(MOVE));
	singleMenu.AppendMenu(MF_POPUP, (UINT)(HMENU)priorityMenu, CSTRING(SET_PRIORITY));
	singleMenu.AppendMenu(MF_POPUP, (UINT)(HMENU)browseMenu, CSTRING(GET_FILE_LIST));
	singleMenu.AppendMenu(MF_POPUP, (UINT)(HMENU)pmMenu, CSTRING(SEND_PRIVATE_MESSAGE));
	singleMenu.AppendMenu(MF_POPUP, (UINT)(HMENU)readdMenu, CSTRING(READD_SOURCE));
	singleMenu.AppendMenu(MF_SEPARATOR, 0, (LPCTSTR)NULL);
	singleMenu.AppendMenu(MF_POPUP, (UINT)(HMENU)removeMenu, CSTRING(REMOVE_SOURCE));
	singleMenu.AppendMenu(MF_STRING, IDC_REMOVE, CSTRING(REMOVE));

	multiMenu.AppendMenu(MF_POPUP, (UINT)(HMENU)priorityMenu, CSTRING(SET_PRIORITY));
	multiMenu.AppendMenu(MF_STRING, IDC_MOVE, CSTRING(MOVE));
	multiMenu.AppendMenu(MF_SEPARATOR, 0, (LPCTSTR)NULL);
	multiMenu.AppendMenu(MF_STRING, IDC_REMOVE, CSTRING(REMOVE));
	
	priorityMenu.AppendMenu(MF_STRING, IDC_PRIORITY_PAUSED, CSTRING(PAUSED));
	priorityMenu.AppendMenu(MF_STRING, IDC_PRIORITY_LOWEST, CSTRING(LOWEST));
	priorityMenu.AppendMenu(MF_STRING, IDC_PRIORITY_LOW, CSTRING(LOW));
	priorityMenu.AppendMenu(MF_STRING, IDC_PRIORITY_NORMAL, CSTRING(NORMAL));
	priorityMenu.AppendMenu(MF_STRING, IDC_PRIORITY_HIGH, CSTRING(HIGH));
	priorityMenu.AppendMenu(MF_STRING, IDC_PRIORITY_HIGHEST, CSTRING(HIGHEST));

	dirMenu.AppendMenu(MF_POPUP, (UINT)(HMENU)priorityMenu, CSTRING(SET_PRIORITY));
	dirMenu.AppendMenu(MF_STRING, IDC_MOVE, CSTRING(MOVE));
	dirMenu.AppendMenu(MF_SEPARATOR, 0, (LPCTSTR)NULL);
	dirMenu.AppendMenu(MF_STRING, IDC_REMOVE, CSTRING(REMOVE));

	SetWindowText(CSTRING(DOWNLOAD_QUEUE));

	addQueueList(QueueManager::getInstance()->lockQueue());
	QueueManager::getInstance()->unlockQueue();
	QueueManager::getInstance()->addListener(this);

	memset(statusSizes, 0, sizeof(statusSizes));
	statusSizes[0] = 16;
	ctrlStatus.SetParts(6, statusSizes);
	updateStatus();

	bHandled = FALSE;
	return 1;
}

QueueFrame::StringListInfo::StringListInfo(QueueItem* qi) {

	columns[COLUMN_TARGET] = qi->getTargetFileName();
	columns[COLUMN_SIZE] = (qi->getSize() == -1) ? STRING(UNKNOWN) : Util::formatBytes(qi->getSize());
	string tmp;
	
	int online = 0;
	QueueItem::Source::Iter j;
	for(j = qi->getSources().begin(); j != qi->getSources().end(); ++j) {
		if(tmp.size() > 0)
			tmp += ", ";
		
		QueueItem::Source::Ptr sr = *j;
		if(sr->getUser()->isOnline())
			online++;
		
		tmp += sr->getUser()->getFullNick();
	}
	columns[COLUMN_USERS] = tmp.empty() ? STRING(NO_USERS) : tmp;
	tmp = Util::emptyString;
	for(j = qi->getBadSources().begin(); j != qi->getBadSources().end(); ++j) {
		QueueItem::Source::Ptr sr = *j;
		if(!sr->isSet(QueueItem::Source::FLAG_REMOVED)) {
			if(tmp.size() > 0)
				tmp += ", ";
			tmp += sr->getUser()->getNick();
			tmp += " (";
			if(sr->isSet(QueueItem::Source::FLAG_FILE_NOT_AVAILABLE)) {
				tmp += STRING(FILE_NOT_AVAILABLE);
			} else if(sr->isSet(QueueItem::Source::FLAG_PASSIVE)) {
				tmp += STRING(PASSIVE_USER);
			} else if(sr->isSet(QueueItem::Source::FLAG_ROLLBACK_INCONSISTENCY)) {
				tmp += STRING(ROLLBACK_INCONSISTENCY);
			} else if(sr->isSet(QueueItem::Source::FLAG_CRC_FAILED)) {
				tmp += STRING(SFV_INCONSISTENCY);
			}
			tmp += ')';
		}
	}
	columns[COLUMN_ERRORS] = tmp.empty() ? STRING(NO_ERRORS) : tmp;
	
	if(qi->getStatus() == QueueItem::STATUS_WAITING) {
		
		char buf[64];
		if(online > 0) {
			
			if(qi->getSources().size() == 1) {
				columns[COLUMN_STATUS] = STRING(WAITING_USER_ONLINE);
			} else {
				sprintf(buf, CSTRING(WAITING_USERS_ONLINE), online, qi->getSources().size());
				columns[COLUMN_STATUS] = buf;
			}
		} else {
			if(qi->getSources().size() == 0) {
				columns[COLUMN_STATUS] = STRING(NO_USERS_TO_DOWNLOAD_FROM);
			} else if(qi->getSources().size() == 1) {
				columns[COLUMN_STATUS] = STRING(USER_OFFLINE);
			} else if(qi->getSources().size() == 2) {
				columns[COLUMN_STATUS] = STRING(BOTH_USERS_OFFLINE);
			} else if(qi->getSources().size() == 3) {
				columns[COLUMN_STATUS] = STRING(ALL_3_USERS_OFFLINE);
			} else if(qi->getSources().size() == 4) {
				columns[COLUMN_STATUS] = STRING(ALL_4_USERS_OFFLINE);
			} else {
				sprintf(buf, CSTRING(ALL_USERS_OFFLINE), qi->getSources().size());
				columns[COLUMN_STATUS] = buf;
			}
		}
	} else if(qi->getStatus() == QueueItem::STATUS_RUNNING) {
		columns[COLUMN_STATUS] = STRING(RUNNING);
	} 
	
	switch(qi->getPriority()) {
	case QueueItem::PAUSED: columns[COLUMN_PRIORITY] = STRING(PAUSED); break;
	case QueueItem::LOWEST: columns[COLUMN_PRIORITY] = STRING(LOWEST); break;
	case QueueItem::LOW: columns[COLUMN_PRIORITY] = STRING(LOW); break;
	case QueueItem::NORMAL: columns[COLUMN_PRIORITY] = STRING(NORMAL); break;
	case QueueItem::HIGH: columns[COLUMN_PRIORITY] = STRING(HIGH); break;
	case QueueItem::HIGHEST: columns[COLUMN_PRIORITY] = STRING(HIGHEST); break;
	default: dcassert(0); break;
	}
	columns[COLUMN_PATH] = qi->getTarget();
}

void QueueFrame::onQueueAdded(QueueItem* aQI) {
	QueueItem* qi = new QueueItem(*aQI);
	{
		Lock l(cs);
		dcassert(queue.find(aQI) == queue.end());
		queue[aQI] = qi;
	}

	speak(ADD_ITEM,	qi);
}

void QueueFrame::addQueueItem(QueueItem* qi) {
	if(!qi->isSet(QueueItem::FLAG_USER_LIST)) {
		queueSize+=qi->getSize();
	}
	queueItems++;
	dirty = true;
	
	string dir = Util::getFilePath(qi->getTarget());
	
	bool updateDir = (directories.find(dir) == directories.end());
	directories.insert(make_pair(dir, qi));
	
	if(updateDir) {
		addDirectory(dir, qi->isSet(QueueItem::FLAG_USER_LIST));
	} 
	if(!showTree || (curDir == dir)) {
		StringListInfo sli(qi);
		StringList l;
		
		for(int j = 0; j < COLUMN_LAST; j++) {
			l.push_back(sli.columns[j]);
		}
		dcassert(ctrlQueue.find((LPARAM)qi) == -1);
		ctrlQueue.insert(l, WinUtil::getIconIndex(qi->getTarget()), (LPARAM)qi);
	}
}

void QueueFrame::addQueueList(const QueueItem::StringMap& li) {
	ctrlQueue.SetRedraw(FALSE);
	ctrlDirs.SetRedraw(FALSE);
	for(QueueItem::StringMap::const_iterator j = li.begin(); j != li.end(); ++j) {
		QueueItem* aQI = j->second;
		QueueItem* qi = new QueueItem(*aQI);
		dcassert(queue.find(aQI) == queue.end());
		queue[aQI] = qi;
		addQueueItem(qi);
	}
	ctrlQueue.SetRedraw(TRUE);
	ctrlQueue.resort();
	ctrlDirs.SetRedraw(TRUE);
	ctrlDirs.Invalidate();
}

HTREEITEM QueueFrame::addDirectory(const string& dir, bool isFileList /* = false */) {
	TVINSERTSTRUCT tvi;
	tvi.hInsertAfter = TVI_SORT;
	tvi.item.mask = TVIF_IMAGE | TVIF_PARAM | TVIF_SELECTEDIMAGE | TVIF_TEXT;
	tvi.item.iImage = tvi.item.iSelectedImage = WinUtil::getDirIconIndex();

	if(isFileList) {
		// We assume we haven't added it yet, and that all filelists go to the same
		// directory...
		dcassert(fileLists == NULL);
		tvi.hParent = NULL;
		tvi.item.pszText = FILE_LIST_NAME;
		tvi.item.lParam = (LPARAM) new string(dir);
		fileLists = ctrlDirs.InsertItem(&tvi);
		return fileLists;
	} 

	// More complicated, we have to find the last available tree item and then see...
	string::size_type i = 0;
	string::size_type j;

	HTREEITEM next = ctrlDirs.GetRootItem();
	HTREEITEM parent = NULL;

	if((next != NULL) && (next == fileLists)) {
		next = ctrlDirs.GetNextSiblingItem(next);
	}

	if(next == NULL) {
		// First addition, set commonStart to the dir minus the last part...
		i = dir.rfind('\\', dir.length()-2);
		if(i != string::npos) {
			commonStart = dir.substr(0, i+1);
			string name = commonStart.substr(0, commonStart.length() - 1);
			tvi.hParent = NULL;
			tvi.item.pszText = const_cast<char*>(name.c_str());
			tvi.item.lParam = (LPARAM)new string(commonStart);
			parent = ctrlDirs.InsertItem(&tvi);
			next = NULL;
			i++;
		} else {
			// No commonStart...
			i = 0;
		}
	} else {
		// Check if commonStart is the same as this dir start...
		if(commonStart.empty()) {
			// nothing...
		} else if(Util::strnicmp(dir, commonStart, commonStart.length()) == 0) {
			// Ok, np, commonstart is equal...
			i = commonStart.length();
			dcassert(next != NULL);
			parent = next;
			next = ctrlDirs.GetChildItem(next);
		} else {
			string oldCommon = commonStart;
			i = 0;
			for(;;) {
				j = dir.find('\\', i);
				if(j == string::npos) {
					commonStart = dir.substr(0, i);
					break;
				}
				if(Util::strnicmp(dir, commonStart, j) == 0) {
					i = j + 1;
				} else {
					commonStart = dir.substr(0, i);
					break;
				}
			}
			if(commonStart.empty()) {
				// We insert the first part, if not, addDirectory will return the old commonStart
				// Since this gets sorted before oldCommon, it should work =)
				i = oldCommon.find('\\');
				dcassert(i != string::npos);
				string* tmp = new string(oldCommon.substr(0, i+1));
				string name = tmp->substr(0, tmp->length() - 1);
				tvi.hParent = NULL;
				tvi.item.pszText = const_cast<char*>(name.c_str());
				tvi.item.lParam = (LPARAM)tmp;
				ctrlDirs.InsertItem(&tvi);
				HTREEITEM ht = addDirectory(oldCommon);
				HTREEITEM ht2 = ctrlDirs.GetChildItem(next);
				while(ht2 != NULL) {
					moveNode(ht2, ht);
					ht2 = ctrlDirs.GetChildItem(next);
				}
				delete (string*)ctrlDirs.GetItemData(next);
				ctrlDirs.DeleteItem(next);
				next = ctrlDirs.GetRootItem();
				if((next != NULL) && (next == fileLists)) {
					next = ctrlDirs.GetNextSiblingItem(next);
				}
				i = 0;
			} else {
				string name = commonStart.substr(0, commonStart.length() - 1);
				tvi.hParent = NULL;
				tvi.item.pszText = const_cast<char*>(name.c_str());

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -