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

📄 queuectrl.cpp

📁 一个支持FTP,SFTP的客户端程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			pMainFrame->GetLocalPane2()->RefreshFile(transferFile.localfile);

		ASSERT(nIndex < static_cast<unsigned int>(m_nActiveCount));
		if (nIndex < static_cast<unsigned int>(m_nActiveCount))
			m_nActiveCount--;

		if (nApiIndex != -1 && nState == QUEUESTATE_TRANSFER)
			ServerDataMapIter->second.nCurrentActive--;

		queueData.pTransferApi = 0;
		delete queueData.pTransferStatus;
		queueData.pTransferStatus = 0;
		delete queueData.pProgressControl;
		queueData.pProgressControl = 0;
		
		if (api.pTransferApi)
		{
			api.bActive = FALSE;
			api.pLastActiveTime = new CTime;
			*api.pLastActiveTime = CTime::GetCurrentTime();
			m_TransferApiArray[nApiIndex] = api;
		}
		
		if (nReplyCode==FZ_REPLY_OK)
		{
			m_QueueItems.erase(m_QueueItems.begin() + nIndex);
			SetItemCount(m_QueueItems.size() + m_nActiveCount);

			if (queueData.nOpen)
				EditFile(queueData);
					
			if (FindValidIndex(1) == m_QueueItems.begin())
				StopProcessing();
			else if (m_nProcessQueue==2 && FindValidIndex(2) == m_QueueItems.begin())
				StopProcessing();
		}
		else if ( ((nReplyCode&FZ_REPLY_ABORTED || nReplyCode&FZ_REPLY_CANCEL) && queueData.bStop) || queueData.nAutoUsePrimary==3 || bConnectError)
		{
			queueData.bActive = FALSE;
			
			m_QueueItems.erase(m_QueueItems.begin() + nIndex);
			
			if (!queueData.nAutoUsePrimary && !bConnectError)
				queueData.priority=1;
			
			if (queueData.bPaused)
			{
				queueData.priority = 0;
				queueData.action.LoadString(IDS_QUEUESTATUS_PAUSED);
			}
			else
				queueData.action = _T("");
			
			if (queueData.priority == 2)
				m_QueueItems.insert(m_QueueItems.begin() + m_nActiveCount, queueData);
			else if (queueData.bPaused)
				m_QueueItems.insert(FindValidIndex(1), queueData);
			else
				m_QueueItems.insert(FindValidIndex(2), queueData);
			SetItemCount(m_QueueItems.size() + m_nActiveCount);
		}
		else if (nReplyCode&FZ_REPLY_CRITICALERROR || nReplyCode&FZ_REPLY_ABORTED || nReplyCode&FZ_REPLY_CANCEL)
		{
			queueData.bActive = FALSE;

			m_QueueItems.erase(m_QueueItems.begin() + nIndex);
			SetItemCount(m_QueueItems.size() + m_nActiveCount);
			
			queueData.priority = 0;
			if (!queueData.bPaused)
				queueData.retrycount = -1;
			
			if (FindValidIndex(1) == m_QueueItems.begin())
				StopProcessing();
			else if (m_nProcessQueue==2 && FindValidIndex(2) == m_QueueItems.begin())
				StopProcessing();
			
			if (!queueData.bAbort)
			{
				if (queueData.bPaused)
					queueData.action.LoadString(IDS_QUEUESTATUS_PAUSED);
				else
					queueData.action.LoadString((nReplyCode&FZ_REPLY_CRITICALERROR)?IDS_QUEUESTATUS_CRITICALERROR:IDS_QUEUESTATUS_ABORTED);

				m_QueueItems.insert(FindValidIndex(queueData.bPaused?1:0), queueData);
				SetItemCount(m_QueueItems.size() + m_nActiveCount);
			}
		}
		else if (nReplyCode&FZ_REPLY_ERROR)
		{
			queueData.bActive = FALSE;

			queueData.retrycount++;
			if (queueData.retrycount>=COptions::GetOptionVal(OPTION_NUMRETRIES))
			{
				m_QueueItems.erase(m_QueueItems.begin() + nIndex);
				SetItemCount(m_QueueItems.size() + m_nActiveCount);
				
				queueData.retrycount = -1;
				queueData.priority = 0;
				
				if (FindValidIndex(1) == m_QueueItems.begin())
					StopProcessing();
				else if (m_nProcessQueue==2 && FindValidIndex(2) == m_QueueItems.begin())
					StopProcessing();
				
				queueData.action.LoadString(IDS_QUEUESTATUS_TOOMANYERTREIS);

				m_QueueItems.insert(FindValidIndex(0), queueData);
			}
			else
			{
				m_QueueItems.erase(m_QueueItems.begin() + nIndex);
				
				queueData.action.Format(IDS_QUEUESTATUS_ERROR, queueData.retrycount);

				if (queueData.priority==2)
					m_QueueItems.insert(m_QueueItems.begin() + m_nActiveCount, queueData);
				else
					m_QueueItems.insert(FindValidIndex(2), queueData);
				SetItemCount(m_QueueItems.size() + m_nActiveCount);
			}
		}
		else
		{
			ASSERT(FALSE);
		}
	
		if (queueData.bStop)
		{
			queueData.bTransferStarted = FALSE;
			queueData.bTriedAutoResume = false;
		}
		queueData.bStop = FALSE;
		queueData.nState = 0;
	
		SetItemCount(m_QueueItems.size() + m_nActiveCount);
		
		UpdateStatusbar();
		int res = 0;
		if (DoProcessQueue())
		{
			do
			{
				res = TransferNextFile(nApiIndex);
				if (res==-1)
				{
					nReplyCode = FZ_REPLY_ERROR;
					continue;
				}
				else if (res==-2)
				{
					nReplyCode = FZ_REPLY_CRITICALERROR;
					continue;
				}
			}
			while (res==1);
		}
		else if (m_QueueItems.empty())
			m_nActiveCount = 0;
		if (res >= 0)
			break;
	}
	SetItemCount(m_QueueItems.size() + m_nActiveCount);
}

int CQueueCtrl::TransferNextFile(int &nApiIndex)
{
	ASSERT(Validate());
	
	if (!m_nProcessQueue)
		return 0;
	if (FindValidIndex(1) == m_QueueItems.begin())
	{
		StopProcessing();
		return 0;
	}

	if (!m_bUseMultiple && m_nActiveCount)
		return 0;

	if (static_cast<UINT>(m_nActiveCount) >= m_nMaxApiCount)
		return 0;

	//Search for the first idle item
	t_QueueVector::iterator iter;	
	for (iter = m_QueueItems.begin(); iter != m_QueueItems.end(); iter++)
	{
		if (iter->bActive)
			continue;
		if (iter->nAutoUsePrimary>=3 && m_bPrimaryConnectionTransferInProgress)
			continue;
		if (iter->bPaused)
			continue;
		if (!iter->priority)
			return 0;
		if (iter->priority < m_nProcessQueue)
			return 0;

		t_ServerDataMapIter ServerDataMapIter = m_ServerDataMap.find(iter->transferFile.server);
		if (ServerDataMapIter == m_ServerDataMap.end())
		{
			t_ServerData ServerData;
			ServerData.nActiveMax = ServerData.nCurrentActive = ServerData.nFailedConnections = 0;
			m_ServerDataMap[iter->transferFile.server] = ServerData;
			ServerDataMapIter = m_ServerDataMap.find(iter->transferFile.server);
			ASSERT(ServerDataMapIter != m_ServerDataMap.end());
		}
			
		if (ServerDataMapIter->second.nFailedConnections>=3 && ServerDataMapIter->second.nActiveMax && ServerDataMapIter->second.nCurrentActive>=ServerDataMapIter->second.nActiveMax)
			continue;

		if (m_nProcessQueue!=1)
			m_nProcessQueue = iter->priority;
		
		int maxsize = COptions::GetOptionVal(OPTION_TRANSFERPRIMARYMAXSIZE);
		if (iter->nAutoUsePrimary==3 || 
			(m_bMayUsePrimaryConnection && iter->transferFile.size>=0 && iter->transferFile.size < maxsize) ||
			!m_bUseMultiple )
		{
			m_bMayUsePrimaryConnection = FALSE;
			CMainFrame *pMainFrame = DYNAMIC_DOWNCAST(CMainFrame, GetParentFrame());
			if (pMainFrame->IsConnected())
			{
				t_server server;
				CServerPath path;
				if (pMainFrame->m_pCommandQueue->GetLastServer(server, path) && 
					server==iter->transferFile.server)
				{
					if (!pMainFrame->m_pCommandQueue->IsLocked() && !pMainFrame->m_pCommandQueue->IsBusy())
					{
						iter->nAutoUsePrimary=4;
						m_bPrimaryConnectionTransferInProgress=TRUE;
						iter->action.Format(IDS_QUEUESTATUS_TRANSFERRING);
						
						iter->bActive = TRUE;
						iter->nState = QUEUESTATE_TRANSFER;
						
						//Create the progress control
						iter->pProgressControl = new CTextProgressCtrl;
						if (iter->pProgressControl->Create(WS_VISIBLE|WS_CHILD|WS_BORDER, CRect(1, 1, 1, 1), this, 0))
						{
							iter->pProgressControl->SetRange(0,100); //Set the range to between 0 and 100
							iter->pProgressControl->SetStep(1); // Set the step amount
							iter->pProgressControl->ShowWindow(SW_HIDE);
						}
						else
						{
							delete iter->pProgressControl;
							iter->pProgressControl = NULL;
						}
						
						CQueueData queueData = *iter;
						m_QueueItems.erase(iter);
						iter = m_QueueItems.insert(m_QueueItems.begin() + m_nActiveCount, queueData);
						
						m_nActiveCount++;
						SetItemCount(m_QueueItems.size() + m_nActiveCount);
						
						nApiIndex=-1;
						iter->pTransferApi=0;
						if (!pMainFrame->m_pCommandQueue->FileTransfer(iter->transferFile))
							return -1;
						else
							iter->status.Format(IDS_QUEUESTATUS_TRANSFERRING);

						return 1;
					}
					else if (iter->nAutoUsePrimary)
					{
						continue;
					}
				}
				else
					iter->nAutoUsePrimary=0;
			}
			else
				iter->nAutoUsePrimary=0;
	
		}
		
		iter->nAutoUsePrimary=0;
		
		//Chose one api instance
		t_TransferApi api;
		
		int nMatchingApiIndex=-1, nUnconnectedApiIndex=-1, nConnectedApiIndex=-1;
		
		for (std::vector<t_TransferApi>::const_iterator apiiter = m_TransferApiArray.begin(); apiiter != m_TransferApiArray.end(); apiiter++)
			//Find a matching api instance. The best would be an instance already
			//connected to the right server. If no one can be found, use an unconnected
			//instance and if this fails, too, use an instance connected to another server
		{
			if (apiiter->bActive)
				continue; //Skip active instances
			if (apiiter->pTransferApi->IsConnected() == FZ_REPLY_OK) 
			{
				t_server server;
				if (apiiter->pTransferApi->GetCurrentServer(server)==FZ_REPLY_OK)
					if (server == iter->transferFile.server)
					{
						nMatchingApiIndex = apiiter - m_TransferApiArray.begin();
						break;
					}
					else
						nConnectedApiIndex = apiiter - m_TransferApiArray.begin();
				else
					nUnconnectedApiIndex = apiiter - m_TransferApiArray.begin();
			}
			else
				nUnconnectedApiIndex = apiiter - m_TransferApiArray.begin();
		}

		nApiIndex = -1;
		if (nMatchingApiIndex != -1)
			nApiIndex = nMatchingApiIndex;
		else if (!m_RetryServerList.StillWait(iter->transferFile.server))
			if (nUnconnectedApiIndex != -1)
				nApiIndex = nUnconnectedApiIndex;
			else
				nApiIndex = nConnectedApiIndex;
		
		if (nApiIndex == -1)
			continue;

		api = m_TransferApiArray[nApiIndex];
		
		if (api.pLastActiveTime)
		{
			delete api.pLastActiveTime;
			api.pLastActiveTime = 0;
		}
		api.bActive = TRUE;
		m_TransferApiArray[nApiIndex] = api;


		iter->status.Format(IDS_QUEUESTATUS_TRANSFERRING);
		
		iter->bActive = TRUE;
		
		//Create the progress control
		iter->pProgressControl = new CTextProgressCtrl;
		if (iter->pProgressControl->Create(WS_VISIBLE|WS_CHILD|WS_BORDER, CRect(1, 1, 1, 1), this, 0))
		{
			iter->pProgressControl->SetRange(0,100); //Set the range to between 0 and 100
			iter->pProgressControl->SetStep(1); // Set the step amount
			iter->pProgressControl->ShowWindow(SW_HIDE);
		}
		else
		{
			delete iter->pProgressControl;
			iter->pProgressControl = NULL;
		}
		
		const CQueueData queueData = *iter;
		m_QueueItems.erase(iter);
		iter = m_QueueItems.insert(m_QueueItems.begin() + m_nActiveCount, queueData);
		
		m_nActiveCount++;
		SetItemCount(m_QueueItems.size() + m_nActiveCount);
		
		iter->pTransferApi = api.pTransferApi;
		if (api.pTransferApi->IsConnected() == FZ_REPLY_OK)
		{
			t_server server;
			if (api.pTransferApi->GetCurrentServer(server) == FZ_REPLY_OK)
			{
				if (server== iter->transferFile.server)
				{
					iter->nState = QUEUESTATE_TRANSFER;
					int res = api.pTransferApi->FileTransfer(iter->transferFile);
					if (res == FZ_REPLY_WOULDBLOCK)
					{
						iter->status.Format(IDS_QUEUESTATUS_TRANSFERRING);
						ServerDataMapIter->second.nCurrentActive++;
						if (ServerDataMapIter->second.nCurrentActive>ServerDataMapIter->second.nActiveMax)
							ServerDataMapIter->second.nActiveMax++;
						return 1;
					}
					else if (res!=FZ_REPLY_NOTCONNECTED)
						return -2;
				}
				else
				{
					iter->nState = QUEUESTATE_DISCONNECT;
					int res = api.pTransferApi->Disconnect();
					if (res == FZ_REPLY_WOULDBLOCK)
					{
						iter->status.Format(IDS_STATUSMSG_CONNECTING, (iter->transferFile.server.name!="")?iter->transferFile.server.name:iter->transferFile.server.host);
						return 1;
					}
					else if (res!=FZ_REPLY_NOTCONNECTED)
						return -2;
				}
			}
		}
		
		iter->nState = QUEUESTATE_CONNECT;
		if (api.pTransferApi->Connect(iter->transferFile.server) != FZ_REPLY_WOULDBLOCK)
			return -2;
		iter->status.Format(IDS_STATUSMSG_CONNECTING, (iter->transferFile.server.name!="")?iter->transferFile.server.name:iter->transferFile.server.host);
		return 1;
	}
	return 0;
}

void CQueueCtrl::OnContextMenu(CWnd* pWnd, CPoint point) 
{
	CMenu menu;
	menu.LoadMenu(IDR_QUEUECONTEXTMENU);

	CMenu* pPopup = menu.GetSubMenu(0);
	ASSERT(pPopup != NULL);
	CWnd* pWndPopupOwner = this;

	BOOL selected = FALSE;
	for (t_QueueVector::iterator iter = m_QueueItems.begin(); iter != m_QueueItems.end(); iter++)
	{
		if (!(iter->nListItemState & LVIS_SELECTED))
			continue;
		if (!selected)
			selected = TRUE;
		
		int nIndex = iter - m_QueueItems.begin();
		
		if (nIndex < m_nActiveCount)
		{
			pPopup->EnableMenuItem(ID_QUEUECONTEXT_MOVETOTOP, MF_GRAYED);
			pPopup->EnableMenuItem(ID_QUEUECONTEXT_MOVETOBOTTOM, MF_GRAYED);
			pPopup->EnableMenuItem(ID_QUEUECONTEXT_MOVEUP, MF_GRAYED);
			pPopup->EnableMenuItem(ID_QUEUECONTEXT_MOVEDOWN, MF_GRAYED);
			pPopup->EnableMenuItem(ID_QUEUECONTEXT_REMOVEFROMQUEUE, MF_GRAYED);
		}
		if (nIndex >= FindValidIndex(1)-m_QueueItems.begin())
		{
			pPopup->EnableMenuItem(ID_QUEUECONTEXT_MOVETOTOP, MF_GRAYED);
			pPopup->EnableMenuItem(ID_QUEUECONTEXT_MOVETOBOTTOM, MF_GRAYED);
			pPopup->EnableMenuItem(ID_QUEUECONTEXT_MOVEUP, MF_GRAYED);
			pPopup->EnableMenuItem(ID_QUEUECONTEXT_MOVEDOWN, MF_GRAYED);
		}
		if (nIndex==(FindValidIndex(1)-m_QueueItems.begin()-1))
		{
			pPopup->EnableMenuItem(ID_QUEUECONTEXT_MOVEDOWN, MF_GRAYED);

⌨️ 快捷键说明

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