2009-11-17 12:45:06 +00:00
/****************************************************************
* This file is distributed under the following license :
*
2010-10-26 21:13:35 +00:00
* Copyright ( c ) 2010 , csoler
2009-11-17 12:45:06 +00:00
* Copyright ( c ) 2009 , defnax
* Copyright ( c ) 2009 , lsn752
*
* 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 . , 51 Franklin Street , Fifth Floor ,
* Boston , MA 02110 - 1301 , USA .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-12-28 21:11:00 +00:00
# include <math.h>
2009-11-17 12:45:06 +00:00
# include <QStylePainter>
# include <QDebug>
2010-08-06 09:40:23 +00:00
# include <retroshare/rsfiles.h>
# include <retroshare/rstypes.h>
2010-03-01 22:47:48 +00:00
# include "util/misc.h"
2009-11-17 12:45:06 +00:00
# include "FileTransferInfoWidget.h"
2013-07-14 12:53:38 +00:00
# include <gui/RetroShareLink.h>
2009-11-17 12:45:06 +00:00
2015-07-01 20:04:12 +00:00
// Variables to decide of display behaviour. All variables are expressed as a factor of font height
2009-12-28 21:11:00 +00:00
//
2015-07-01 20:04:12 +00:00
static const float chunk_square_size_factor = 1.0 ;
static const float text_height_factor = 0.9 ; // should be set according to the font size
static const float block_sep_factor = 0.4 ; // separator between blocks
static const float ch_num_size_factor = 5.0 ; // size of field for chunk number
static const float availability_map_size_X_factor = 40.0 ; // length of availability bar
static const float availability_map_size_Y_factor = 2.0 ; // height of availability bar
static const float tab_size_factor = 20.0 ; // size between tabulated entries
2009-12-28 21:11:00 +00:00
2013-10-18 21:10:33 +00:00
FileTransferInfoWidget : : FileTransferInfoWidget ( QWidget * /*parent*/ , Qt : : WindowFlags /*f*/ )
2009-11-17 12:45:06 +00:00
{
QRect TaskGraphRect = geometry ( ) ;
maxWidth = TaskGraphRect . width ( ) ;
2010-02-17 19:48:59 +00:00
maxHeight = 0 ;
2009-11-17 12:45:06 +00:00
pixmap = QPixmap ( size ( ) ) ;
2015-05-26 12:21:48 +00:00
pixmap . fill ( Qt : : transparent ) ;
2009-11-17 12:45:06 +00:00
2015-07-01 20:04:12 +00:00
int S = 0.9 * QFontMetricsF ( font ( ) ) . height ( ) ;
downloadedPixmap = QPixmap ( " :/icons/tile_downloaded_48.png " ) . scaledToHeight ( S , Qt : : SmoothTransformation ) ;
downloadingPixmap = QPixmap ( " :/icons/tile_downloading_48.png " ) . scaledToHeight ( S , Qt : : SmoothTransformation ) ;
notDownloadPixmap = QPixmap ( " :/icons/tile_inactive_48.png " ) . scaledToHeight ( S , Qt : : SmoothTransformation ) ;
checkingPixmap = QPixmap ( " :/icons/tile_checking_48.png " ) . scaledToHeight ( S , Qt : : SmoothTransformation ) ;
2009-11-17 12:45:06 +00:00
setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : Expanding ) ;
}
2011-08-12 14:06:29 +00:00
void FileTransferInfoWidget : : resizeEvent ( QResizeEvent */ * event */ )
2009-11-17 12:45:06 +00:00
{
QRect TaskGraphRect = geometry ( ) ;
maxWidth = TaskGraphRect . width ( ) ;
updateDisplay ( ) ;
}
void FileTransferInfoWidget : : updateDisplay ( )
{
2010-02-08 16:42:26 +00:00
//std::cout << "In TaskGraphPainterWidget::updateDisplay()" << std::endl ;
2009-11-17 12:45:06 +00:00
2010-01-11 16:00:42 +00:00
bool ok = true ;
2009-11-17 12:45:06 +00:00
FileInfo nfo ;
if ( ! rsFiles - > FileDetails ( _file_hash , RS_FILE_HINTS_DOWNLOAD , nfo ) )
2010-01-11 16:00:42 +00:00
ok = false ;
2009-11-17 12:45:06 +00:00
FileChunksInfo info ;
2010-01-11 16:00:42 +00:00
if ( ! rsFiles - > FileDownloadChunksDetails ( _file_hash , info ) )
ok = false ;
2009-11-17 12:45:06 +00:00
2010-02-08 16:42:26 +00:00
//std::cout << "got details for file " << nfo.fname << std::endl ;
2009-11-17 12:45:06 +00:00
pixmap = QPixmap ( maxWidth , maxHeight ) ;
2015-05-26 12:21:48 +00:00
pixmap . fill ( Qt : : transparent ) ;
2009-11-17 12:45:06 +00:00
setFixedHeight ( maxHeight ) ;
QPainter painter ( & pixmap ) ;
painter . initFrom ( this ) ;
2015-07-01 20:04:12 +00:00
float S = QFontMetricsF ( font ( ) ) . height ( ) ;
int chunk_square_size = S * chunk_square_size_factor ;
2010-01-11 16:00:42 +00:00
if ( ok )
{
int blocks = info . chunks . size ( ) ;
int columns = maxWidth / chunk_square_size ;
y = blocks / columns * chunk_square_size ;
x = blocks % columns * chunk_square_size ;
2015-07-01 20:04:12 +00:00
maxHeight = y + 15 * S + info . active_chunks . size ( ) * ( block_sep_factor * S + text_height_factor * S ) ; // warning: this should be computed from the different size parameter and the number of objects drawn, otherwise the last objects to be displayed will be truncated.
2010-01-11 16:00:42 +00:00
2010-02-19 22:46:21 +00:00
draw ( nfo , info , & painter ) ;
2010-01-11 16:00:42 +00:00
}
2009-11-17 12:45:06 +00:00
pixmap2 = pixmap ;
}
2011-08-12 14:06:29 +00:00
void FileTransferInfoWidget : : paintEvent ( QPaintEvent */ * event */ )
2009-11-17 12:45:06 +00:00
{
2010-02-17 02:10:25 +00:00
//std::cout << "In paint event" << std::endl ;
2009-11-17 12:45:06 +00:00
QStylePainter painter ( this ) ;
painter . drawPixmap ( 0 , 0 , pixmap2 ) ;
pixmap = pixmap2 ;
}
2010-02-19 22:46:21 +00:00
void FileTransferInfoWidget : : draw ( const FileInfo & nfo , const FileChunksInfo & info , QPainter * painter )
2009-11-17 12:45:06 +00:00
{
2015-07-01 20:04:12 +00:00
float S = QFontMetricsF ( font ( ) ) . height ( ) ;
2009-11-17 12:45:06 +00:00
x = 0 ;
2015-07-01 20:04:12 +00:00
y = 0.5 * S ;
2009-11-17 12:45:06 +00:00
int blocks = info . chunks . size ( ) ;
uint64_t fileSize = info . file_size ;
uint32_t blockSize = info . chunk_size ;
if ( fileSize % blockSize = = 0 ) blocks - - ;
2015-07-01 20:04:12 +00:00
QRectF source ( 0.0 , 0.0 , 1.05 * S , 1.05 * S ) ;
int chunk_square_size = chunk_square_size_factor * S ;
int availability_map_size_X = availability_map_size_X_factor * S ;
int availability_map_size_Y = availability_map_size_Y_factor * S ;
int text_height = text_height_factor * S ;
int block_sep = block_sep_factor * S ;
int ch_num_size = ch_num_size_factor * S ;
int tab_size = tab_size_factor * S ;
2009-11-17 12:45:06 +00:00
2009-12-28 21:11:00 +00:00
painter - > setPen ( QColor : : fromRgb ( 0 , 0 , 0 ) ) ;
y + = text_height ;
2010-12-27 18:51:16 +00:00
painter - > drawText ( 0 , y , tr ( " Chunk map " ) + " : " ) ;
2009-12-28 21:11:00 +00:00
y + = block_sep ;
// draw the chunk map
//
2009-11-18 23:02:37 +00:00
for ( int i = 0 ; i < blocks ; i + + )
2009-11-17 12:45:06 +00:00
{
2009-12-28 21:11:00 +00:00
if ( x > maxWidth - chunk_square_size )
2009-11-17 12:45:06 +00:00
{
x = 0 ;
2009-12-28 21:11:00 +00:00
y + = chunk_square_size ;
2009-11-17 12:45:06 +00:00
}
2015-07-01 20:04:12 +00:00
QRectF target ( x , y , 1.05 * S , 1.05 * S ) ;
2009-11-17 12:45:06 +00:00
switch ( info . chunks [ i ] )
{
case FileChunksInfo : : CHUNK_DONE : painter - > drawPixmap ( target , downloadedPixmap , source ) ;
break ;
case FileChunksInfo : : CHUNK_ACTIVE : painter - > drawPixmap ( target , downloadingPixmap , source ) ;
break ;
2012-03-15 19:55:43 +00:00
case FileChunksInfo : : CHUNK_CHECKING : painter - > drawPixmap ( target , checkingPixmap , source ) ;
break ;
2009-11-17 12:45:06 +00:00
case FileChunksInfo : : CHUNK_OUTSTANDING : painter - > drawPixmap ( target , notDownloadPixmap , source ) ;
break ;
default : ;
}
2009-12-28 21:11:00 +00:00
x + = chunk_square_size ;
2009-11-17 12:45:06 +00:00
}
2009-12-28 21:11:00 +00:00
y + = chunk_square_size ;
// draw the currently downloaded chunks
//
painter - > setPen ( QColor : : fromRgb ( 70 , 70 , 70 ) ) ;
painter - > drawLine ( 0 , y , maxWidth , y ) ;
2015-07-01 20:04:12 +00:00
uint32_t sizeX = 10 * S ;
uint32_t sizeY = 1 * S ;
2009-12-28 21:11:00 +00:00
y + = block_sep ;
y + = text_height ;
painter - > setPen ( QColor : : fromRgb ( 0 , 0 , 0 ) ) ;
2010-12-27 18:51:16 +00:00
painter - > drawText ( 0 , y , tr ( " Active chunks " ) + " : " ) ;
2009-12-28 21:11:00 +00:00
y + = block_sep ;
for ( uint i = 0 ; i < info . active_chunks . size ( ) ; + + i )
{
painter - > setPen ( QColor : : fromRgb ( 0 , 0 , 0 ) ) ;
2015-07-01 20:04:12 +00:00
painter - > drawText ( 0.5 * S , y + text_height * 0.9 , QString : : number ( info . active_chunks [ i ] . first ) ) ;
2009-12-28 21:11:00 +00:00
2010-10-26 21:13:35 +00:00
int size_of_this_chunk = ( info . active_chunks [ i ] . first = = info . chunks . size ( ) - 1 & & ( ( info . file_size % blockSize ) > 0 ) ) ? ( info . file_size % blockSize ) : blockSize ;
uint32_t s = ( uint32_t ) rint ( sizeX * ( size_of_this_chunk - info . active_chunks [ i ] . second ) / ( float ) size_of_this_chunk ) ;
2009-12-28 21:11:00 +00:00
2011-01-20 21:46:44 +00:00
//std::cerr << "chunk " << info.active_chunks[i].first << ": Last received byte: " << size_of_this_chunk - info.active_chunks[i].second << std::endl;
2010-12-26 10:58:02 +00:00
// Already Downloaded.
//
2009-12-28 21:11:00 +00:00
painter - > fillRect ( ch_num_size , y , s , sizeY , QColor : : fromHsv ( 200 , 200 , 255 ) ) ;
2010-12-26 10:58:02 +00:00
// Remains to download
//
2009-12-28 21:11:00 +00:00
painter - > fillRect ( ch_num_size + s , y , sizeX - s , sizeY , QColor : : fromHsv ( 200 , 50 , 255 ) ) ;
2010-12-26 10:58:02 +00:00
// now draw the slices under pending requests
//
std : : map < uint32_t , std : : vector < FileChunksInfo : : SliceInfo > > : : const_iterator it ( info . pending_slices . find ( info . active_chunks [ i ] . first ) ) ;
if ( it ! = info . pending_slices . end ( ) )
for ( uint k = 0 ; k < it - > second . size ( ) ; + + k )
{
uint32_t s1 = ( uint32_t ) floor ( sizeX * ( it - > second [ k ] . start ) / ( float ) size_of_this_chunk ) ;
uint32_t ss = ( uint32_t ) ceil ( sizeX * ( it - > second [ k ] . size ) / ( float ) size_of_this_chunk ) ;
painter - > fillRect ( ch_num_size + s1 , y , ss , sizeY , QColor : : fromHsv ( 50 , 250 , 250 ) ) ;
}
2009-12-28 21:11:00 +00:00
painter - > setPen ( QColor : : fromRgb ( 0 , 0 , 0 ) ) ;
2010-10-26 21:13:35 +00:00
float percent = ( size_of_this_chunk - info . active_chunks [ i ] . second ) * 100.0 / size_of_this_chunk ;
2009-12-28 21:11:00 +00:00
2015-07-01 20:04:12 +00:00
painter - > drawText ( sizeX + 5.5 * S , y + text_height * 0.9 , QString : : number ( percent , ' f ' , 2 ) + " % " ) ;
2009-12-28 21:11:00 +00:00
y + = sizeY + block_sep ;
}
// draw the availability map
//
painter - > setPen ( QColor : : fromRgb ( 70 , 70 , 70 ) ) ;
painter - > drawLine ( 0 , y , maxWidth , y ) ;
y + = block_sep ;
y + = text_height ;
painter - > setPen ( QColor : : fromRgb ( 0 , 0 , 0 ) ) ;
2010-12-27 18:51:16 +00:00
painter - > drawText ( 0 , y , ( info . compressed_peer_availability_maps . size ( ) = = 1 ? tr ( " Availability map (%1 active source) " ) : tr ( " Availability map (%1 active sources) " ) ) . arg ( info . compressed_peer_availability_maps . size ( ) ) ) ;
2009-12-28 21:11:00 +00:00
y + = block_sep ;
2010-01-31 13:21:37 +00:00
// Note (for non geeks): the !! operator transforms anything positive into 1 and 0 into 0.
//
int nb_chunks = info . file_size / info . chunk_size + ! ! ( info . file_size % info . chunk_size ) ;
2009-12-28 21:11:00 +00:00
2010-06-10 14:13:20 +00:00
for ( int i = 0 ; i < availability_map_size_X ; + + i )
2009-12-28 21:11:00 +00:00
{
int nb_src = 0 ;
int chunk_num = ( int ) floor ( i / float ( availability_map_size_X ) * ( nb_chunks - 1 ) ) ;
2014-03-17 20:56:06 +00:00
for ( std : : map < RsPeerId , CompressedChunkMap > : : const_iterator it ( info . compressed_peer_availability_maps . begin ( ) ) ; it ! = info . compressed_peer_availability_maps . end ( ) ; + + it )
2010-01-11 16:00:42 +00:00
nb_src + = it - > second [ chunk_num ] ;
2009-12-28 21:11:00 +00:00
2012-09-12 19:03:51 +00:00
painter - > setPen ( QColor : : fromHsv ( 200 , std : : min ( 255 , 50 * nb_src ) , 200 ) ) ; // the more sources, the more saturated
2009-12-28 21:11:00 +00:00
painter - > drawLine ( i , y , i , y + availability_map_size_Y ) ;
}
y + = block_sep + availability_map_size_Y ;
painter - > setPen ( QColor : : fromRgb ( 70 , 70 , 70 ) ) ;
painter - > drawLine ( 0 , y , maxWidth , y ) ;
2010-06-10 14:13:20 +00:00
y + = block_sep ;
2009-12-28 21:11:00 +00:00
// various info:
//
painter - > setPen ( QColor : : fromRgb ( 0 , 0 , 0 ) ) ;
2010-12-27 18:51:16 +00:00
y + = text_height ; painter - > drawText ( 0 , y , tr ( " File info " ) + " : " ) ;
2009-12-28 21:11:00 +00:00
y + = block_sep ;
2015-07-01 20:04:12 +00:00
y + = text_height ; painter - > drawText ( 2 * S , y , tr ( " File name " ) + " : " ) ; painter - > drawText ( tab_size , y , QString : : fromUtf8 ( nfo . fname . c_str ( ) ) ) ;
2013-02-22 21:42:27 +00:00
y + = block_sep ;
2015-07-01 20:04:12 +00:00
y + = text_height ; painter - > drawText ( 2 * S , y , tr ( " Destination folder " ) + " : " ) ; painter - > drawText ( tab_size , y , QString : : fromUtf8 ( nfo . path . c_str ( ) ) ) ;
2013-03-15 23:16:33 +00:00
y + = block_sep ;
2015-07-01 20:04:12 +00:00
y + = text_height ; painter - > drawText ( 2 * S , y , tr ( " File hash " ) + " : " ) ; painter - > drawText ( tab_size , y , QString : : fromStdString ( nfo . hash . toStdString ( ) ) ) ;
2010-02-19 22:46:21 +00:00
y + = block_sep ;
2015-07-01 20:04:12 +00:00
y + = text_height ; painter - > drawText ( 2 * S , y , tr ( " File size " ) + " : " ) ; painter - > drawText ( tab_size , y , QString : : number ( info . file_size ) + " " + tr ( " bytes " ) + " " + " ( " + misc : : friendlyUnit ( info . file_size ) + " ) " ) ;
2009-12-28 21:11:00 +00:00
y + = block_sep ;
2015-07-01 20:04:12 +00:00
y + = text_height ; painter - > drawText ( 2 * S , y , tr ( " Chunk size " ) + " : " ) ; painter - > drawText ( tab_size , y , QString : : number ( info . chunk_size ) + " " + tr ( " bytes " ) + " " + " ( " + misc : : friendlyUnit ( info . chunk_size ) + " ) " ) ;
2009-12-28 21:11:00 +00:00
y + = block_sep ;
2015-07-01 20:04:12 +00:00
y + = text_height ; painter - > drawText ( 2 * S , y , tr ( " Number of chunks " ) + " : " ) ; painter - > drawText ( tab_size , y , QString : : number ( info . chunks . size ( ) ) ) ;
2009-12-28 21:11:00 +00:00
y + = block_sep ;
2015-07-01 20:04:12 +00:00
y + = text_height ; painter - > drawText ( 2 * S , y , tr ( " Transferred " ) + " : " ) ; painter - > drawText ( tab_size , y , QString : : number ( nfo . transfered ) + " " + tr ( " bytes " ) + " " + " ( " + misc : : friendlyUnit ( nfo . transfered ) + " ) " ) ;
2010-02-19 22:46:21 +00:00
y + = block_sep ;
2015-07-01 20:04:12 +00:00
y + = text_height ; painter - > drawText ( 2 * S , y , tr ( " Remaining " ) + " : " ) ; painter - > drawText ( tab_size , y , QString : : number ( info . file_size - nfo . transfered ) + " " + tr ( " bytes " ) + " " + " ( " + misc : : friendlyUnit ( info . file_size - nfo . transfered ) + " ) " ) ;
2010-03-28 20:46:45 +00:00
y + = block_sep ;
2015-07-01 20:04:12 +00:00
y + = text_height ; painter - > drawText ( 2 * S , y , tr ( " Number of sources " ) + " : " ) ; painter - > drawText ( tab_size , y , QString : : number ( info . compressed_peer_availability_maps . size ( ) ) ) ;
2010-01-22 23:23:37 +00:00
y + = block_sep ;
2015-07-01 20:04:12 +00:00
y + = text_height ; painter - > drawText ( 2 * S , y , tr ( " Chunk strategy " ) + " : " ) ;
2013-02-28 20:42:01 +00:00
switch ( info . strategy )
{
case FileChunksInfo : : CHUNK_STRATEGY_RANDOM : painter - > drawText ( tab_size , y , " Random " ) ; break ;
case FileChunksInfo : : CHUNK_STRATEGY_PROGRESSIVE : painter - > drawText ( tab_size , y , " Progressive " ) ; break ;
default :
case FileChunksInfo : : CHUNK_STRATEGY_STREAMING : painter - > drawText ( tab_size , y , " Streaming " ) ; break ;
}
2010-01-22 23:23:37 +00:00
y + = block_sep ;
2015-07-01 20:04:12 +00:00
y + = text_height ; painter - > drawText ( 2 * S , y , tr ( " Transfer type " ) + " : " ) ;
2012-11-02 13:52:29 +00:00
if ( nfo . transfer_info_flags & RS_FILE_REQ_ANONYMOUS_ROUTING ) painter - > drawText ( tab_size , y , tr ( " Anonymous F2F " ) ) ;
if ( nfo . transfer_info_flags & RS_FILE_REQ_ASSUME_AVAILABILITY ) painter - > drawText ( tab_size , y , tr ( " Direct friend transfer / Availability assumed " ) ) ;
2009-12-28 21:11:00 +00:00
y + = text_height ;
y + = block_sep ;
2009-11-17 12:45:06 +00:00
maxHeight = y + 15 ;
}
2009-12-28 21:11:00 +00:00