Ejemplo n.º 1
0
BOOL CUploadTransferDC::OnWrite()
{
	ASSUME_LOCK( Transfers.m_pSection );
	ASSERT( m_pClient );

	m_mOutput.tLast = m_pClient->m_mOutput.tLast;

	if ( m_pClient->GetOutputLength() != 0 )
		// There is data in output buffer
		return TRUE;

	if ( m_nState == upsUploading )
	{
		ASSERT( m_nLength != SIZE_UNKNOWN );

		// No file data left to transfer
		if ( m_nPosition >= m_nLength )
		{
			// File completed

			Uploads.SetStable( GetAverageSpeed() );

			m_nState = upsRequest;
			m_tRequest = GetTickCount();

			m_pBaseFile->AddFragment( m_nOffset, m_nLength );

			theApp.Message( MSG_INFO, IDS_UPLOAD_FINISHED, (LPCTSTR)m_sName, (LPCTSTR)m_sAddress );
		}
		else
		{
			// Reading next data chunk of file
			QWORD nToRead = min( m_nLength - m_nPosition, (QWORD)Settings.Uploads.ChunkSize );	// ~1000 KB
			QWORD nRead = 0;
			auto_array< BYTE > pBuffer( new BYTE[ nToRead ] );
			if ( ! ReadFile( m_nFileBase + m_nOffset + m_nPosition, pBuffer.get(), nToRead, &nRead ) || nToRead != nRead )
			{
				// File error
				return FALSE;
			}
			m_pClient->Write( pBuffer.get(), (DWORD)nRead );

			m_nPosition += nRead;
			m_nUploaded += nRead;

			Statistics.Current.Uploads.Volume += ( nRead / 1024 );
		}
	}
	else if ( m_nState >= upsResponse )
	{
		// Current transfer completed
		m_nState	= ( m_nState == upsPreQueue ) ? upsQueued : upsRequest;
		m_tRequest	= GetTickCount();
	}

	return TRUE;
}
Ejemplo n.º 2
0
void CStatusLineCtrl::OnPaint(wxPaintEvent&)
{
	wxPaintDC dc(this);

	wxRect rect = GetRect();

	int refresh = 0;
	if (!m_data.IsOk() || rect.GetWidth() != m_data.GetWidth() || rect.GetHeight() != m_data.GetHeight()) {
		m_mdc.reset();
		m_data = wxBitmap(rect.GetWidth(), rect.GetHeight());
		m_mdc = std::make_unique<wxMemoryDC>(m_data);
		// Use same layout direction as the DC which bitmap is drawn on.
		// This avoids problem with mirrored characters on RTL locales.
		m_mdc->SetLayoutDirection(dc.GetLayoutDirection());
		refresh = 31;
	}

	fz::duration elapsed;
	int left = -1;
	wxFileOffset rate;
	wxString bytes_and_rate;
	int bar_split = -1;
	int permill = -1;

	if (status_.empty()) {
		if (m_previousStatusText != m_statusText) {
			// Clear background
			m_mdc->SetFont(GetFont());
			m_mdc->SetPen(GetBackgroundColour());
			m_mdc->SetBrush(GetBackgroundColour());
			m_mdc->SetTextForeground(GetForegroundColour());
			m_mdc->DrawRectangle(0, 0, rect.GetWidth(), rect.GetHeight());
			wxCoord h = (rect.GetHeight() - m_textHeight) / 2;
			m_mdc->DrawText(m_statusText, 50, h);
			m_previousStatusText = m_statusText;
			refresh = 0;
		}
	}
	else {
		if (!m_previousStatusText.empty()) {
			m_previousStatusText.clear();
			refresh = 31;
		}

		int elapsed_milli_seconds = 0;
		if (!status_.started.empty()) {
			elapsed = fz::datetime::now() - status_.started;
			elapsed_milli_seconds = static_cast<int>(elapsed.get_milliseconds()); // Assume it doesn't overflow
		}

		if (elapsed_milli_seconds / 1000 != m_last_elapsed_seconds) {
			refresh |= 1;
			m_last_elapsed_seconds = elapsed_milli_seconds / 1000;
		}

		if (COptions::Get()->GetOptionVal(OPTION_SPEED_DISPLAY))
			rate = GetMomentarySpeed();
		else
			rate = GetAverageSpeed(elapsed_milli_seconds);

		if (status_.totalSize > 0 && elapsed_milli_seconds >= 1000 && rate > 0) {
			wxFileOffset r = status_.totalSize - status_.currentOffset;
			left = r / rate + 1;
			if (r)
				++left;

			if (left < 0)
				left = 0;
		}

		if (m_last_left != left) {
			refresh |= 2;
			m_last_left = left;
		}

		const wxString bytestr = CSizeFormat::Format(status_.currentOffset, true, CSizeFormat::bytes, COptions::Get()->GetOptionVal(OPTION_SIZE_USETHOUSANDSEP) != 0, 0);
		if (elapsed_milli_seconds >= 1000 && rate > -1) {
			CSizeFormat::_format format = static_cast<CSizeFormat::_format>(COptions::Get()->GetOptionVal(OPTION_SIZE_FORMAT));
			if (format == CSizeFormat::bytes)
				format = CSizeFormat::iec;
			const wxString ratestr = CSizeFormat::Format(rate, true,
														 format,
														 COptions::Get()->GetOptionVal(OPTION_SIZE_USETHOUSANDSEP) != 0,
														 COptions::Get()->GetOptionVal(OPTION_SIZE_DECIMALPLACES));
			bytes_and_rate.Printf(_("%s (%s/s)"), bytestr, ratestr );
		}
		else
			bytes_and_rate.Printf(_("%s (? B/s)"), bytestr);

		if (m_last_bytes_and_rate != bytes_and_rate) {
			refresh |= 8;
			m_last_bytes_and_rate = bytes_and_rate;
		}

		if (status_.totalSize > 0) {
			bar_split = static_cast<int>(status_.currentOffset * (PROGRESSBAR_WIDTH - 2) / status_.totalSize);
			if (bar_split > (PROGRESSBAR_WIDTH - 2))
				bar_split = PROGRESSBAR_WIDTH - 2;

			if (status_.currentOffset > status_.totalSize)
				permill = 1001;
			else
				permill = static_cast<int>(status_.currentOffset * 1000 / status_.totalSize);
		}

		if (m_last_bar_split != bar_split || m_last_permill != permill) {
			refresh |= 4;
			m_last_bar_split = bar_split;
			m_last_permill = permill;
		}
	}

	if (refresh) {
		m_mdc->SetFont(GetFont());
		m_mdc->SetPen(GetBackgroundColour());
		m_mdc->SetBrush(GetBackgroundColour());
		m_mdc->SetTextForeground(GetForegroundColour());

		// Get character height so that we can center the text vertically.
		wxCoord h = (rect.GetHeight() - m_textHeight) / 2;

		if (refresh & 1) {
			m_mdc->DrawRectangle(0, 0, m_fieldOffsets[0], rect.GetHeight());
			DrawRightAlignedText(*m_mdc, wxTimeSpan::Milliseconds(elapsed.get_milliseconds()).Format(_("%H:%M:%S elapsed")), m_fieldOffsets[0], h);
		}
		if (refresh & 2) {
			m_mdc->DrawRectangle(m_fieldOffsets[0], 0, m_fieldOffsets[1] - m_fieldOffsets[0], rect.GetHeight());
			if (left != -1) {
				wxTimeSpan timeLeft(0, 0, left);
				DrawRightAlignedText(*m_mdc, timeLeft.Format(_("%H:%M:%S left")), m_fieldOffsets[1], h);
			}
			else
				DrawRightAlignedText(*m_mdc, _("--:--:-- left"), m_fieldOffsets[1], h);
		}
		if (refresh & 8) {
			m_mdc->DrawRectangle(m_fieldOffsets[3], 0, rect.GetWidth() - m_fieldOffsets[3], rect.GetHeight());
			m_mdc->DrawText(bytes_and_rate, m_fieldOffsets[3], h);
		}
		if (refresh & 16) {
			m_mdc->DrawRectangle(m_fieldOffsets[1], 0, m_fieldOffsets[2] - m_fieldOffsets[1], rect.GetHeight());
		}
		if (refresh & 4) {
			m_mdc->DrawRectangle(m_fieldOffsets[2], 0, m_fieldOffsets[3] - m_fieldOffsets[2], rect.GetHeight());
			if (bar_split != -1)
				DrawProgressBar(*m_mdc, m_fieldOffsets[2], 1, rect.GetHeight() - 2, bar_split, permill);
		}
	}
	dc.Blit(0, 0, rect.GetWidth(), rect.GetHeight(), m_mdc.get(), 0, 0);
}