2009-11-17 07:45:06 -05:00
/****************************************************************
* This file is distributed under the following license :
*
2010-10-26 17:13:35 -04:00
* Copyright ( c ) 2010 , csoler
2009-11-17 07:45:06 -05: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 16:11:00 -05:00
# include <math.h>
2009-11-17 07:45:06 -05:00
# include <QStylePainter>
# include <QDebug>
2010-08-06 05:40:23 -04:00
# include <retroshare/rsfiles.h>
# include <retroshare/rstypes.h>
2010-03-01 17:47:48 -05:00
# include "util/misc.h"
2009-11-17 07:45:06 -05:00
# include "FileTransferInfoWidget.h"
2013-02-22 16:42:27 -05:00
# include "RetroShareLink.h"
2009-11-17 07:45:06 -05:00
2009-12-28 16:11:00 -05:00
// Variables to decide of display behaviour. Should be adapted to window size.
//
static const int chunk_square_size = 13 ;
static const int text_height = 10 ; // should be set according to the font size
static const int block_sep = 3 ; // separator between blocks
static const int ch_num_size = 50 ; // size of field for chunk number
static const int availability_map_size_X = 400 ; // length of availability bar
static const int availability_map_size_Y = 20 ; // height of availability bar
static const int tab_size = 200 ; // size between tabulated entries
2011-08-12 10:06:29 -04:00
FileTransferInfoWidget : : FileTransferInfoWidget ( QWidget * /*parent*/ , Qt : : WFlags /*f*/ )
2009-11-17 07:45:06 -05:00
{
QRect TaskGraphRect = geometry ( ) ;
maxWidth = TaskGraphRect . width ( ) ;
2010-02-17 14:48:59 -05:00
maxHeight = 0 ;
2009-11-17 07:45:06 -05:00
pixmap = QPixmap ( size ( ) ) ;
pixmap . fill ( this , 0 , 0 ) ;
downloadedPixmap . load ( " :images/graph-downloaded.png " ) ;
downloadingPixmap . load ( " :images/graph-downloading.png " ) ;
notDownloadPixmap . load ( " :images/graph-notdownload.png " ) ;
2012-03-15 15:55:43 -04:00
checkingPixmap . load ( " :images/graph-checking.png " ) ;
2009-11-17 07:45:06 -05:00
setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : Expanding ) ;
}
2011-08-12 10:06:29 -04:00
void FileTransferInfoWidget : : resizeEvent ( QResizeEvent */ * event */ )
2009-11-17 07:45:06 -05:00
{
QRect TaskGraphRect = geometry ( ) ;
maxWidth = TaskGraphRect . width ( ) ;
updateDisplay ( ) ;
}
void FileTransferInfoWidget : : updateDisplay ( )
{
2010-02-08 11:42:26 -05:00
//std::cout << "In TaskGraphPainterWidget::updateDisplay()" << std::endl ;
2009-11-17 07:45:06 -05:00
2010-01-11 11:00:42 -05:00
bool ok = true ;
2009-11-17 07:45:06 -05:00
FileInfo nfo ;
if ( ! rsFiles - > FileDetails ( _file_hash , RS_FILE_HINTS_DOWNLOAD , nfo ) )
2010-01-11 11:00:42 -05:00
ok = false ;
2009-11-17 07:45:06 -05:00
FileChunksInfo info ;
2010-01-11 11:00:42 -05:00
if ( ! rsFiles - > FileDownloadChunksDetails ( _file_hash , info ) )
ok = false ;
2009-11-17 07:45:06 -05:00
2010-02-08 11:42:26 -05:00
//std::cout << "got details for file " << nfo.fname << std::endl ;
2009-11-17 07:45:06 -05:00
2011-05-23 17:45:25 -04:00
// pixmap = QPixmap(size());
// pixmap.fill(this, 0, 0);
2009-11-17 07:45:06 -05:00
pixmap = QPixmap ( maxWidth , maxHeight ) ;
pixmap . fill ( this , 0 , 0 ) ;
setFixedHeight ( maxHeight ) ;
QPainter painter ( & pixmap ) ;
painter . initFrom ( this ) ;
2010-01-11 11:00:42 -05: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 ;
maxHeight = y + 150 + info . active_chunks . size ( ) * ( block_sep + text_height ) ; // 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-02-19 17:46:21 -05:00
draw ( nfo , info , & painter ) ;
2010-01-11 11:00:42 -05:00
}
2009-11-17 07:45:06 -05:00
pixmap2 = pixmap ;
}
2011-08-12 10:06:29 -04:00
void FileTransferInfoWidget : : paintEvent ( QPaintEvent */ * event */ )
2009-11-17 07:45:06 -05:00
{
2010-02-16 21:10:25 -05:00
//std::cout << "In paint event" << std::endl ;
2009-11-17 07:45:06 -05:00
QStylePainter painter ( this ) ;
painter . drawPixmap ( 0 , 0 , pixmap2 ) ;
pixmap = pixmap2 ;
}
2010-02-19 17:46:21 -05:00
void FileTransferInfoWidget : : draw ( const FileInfo & nfo , const FileChunksInfo & info , QPainter * painter )
2009-11-17 07:45:06 -05:00
{
x = 0 ;
2013-02-22 16:42:27 -05:00
y = 5 ;
2009-11-17 07:45:06 -05:00
int blocks = info . chunks . size ( ) ;
uint64_t fileSize = info . file_size ;
uint32_t blockSize = info . chunk_size ;
if ( fileSize % blockSize = = 0 ) blocks - - ;
QRectF source ( 0.0 , 0.0 , 12.0 , 12.0 ) ;
2009-12-28 16:11:00 -05:00
painter - > setPen ( QColor : : fromRgb ( 0 , 0 , 0 ) ) ;
y + = text_height ;
2010-12-27 13:51:16 -05:00
painter - > drawText ( 0 , y , tr ( " Chunk map " ) + " : " ) ;
2009-12-28 16:11:00 -05:00
y + = block_sep ;
// draw the chunk map
//
2009-11-18 18:02:37 -05:00
for ( int i = 0 ; i < blocks ; i + + )
2009-11-17 07:45:06 -05:00
{
2009-12-28 16:11:00 -05:00
if ( x > maxWidth - chunk_square_size )
2009-11-17 07:45:06 -05:00
{
x = 0 ;
2009-12-28 16:11:00 -05:00
y + = chunk_square_size ;
2009-11-17 07:45:06 -05:00
}
QRectF target ( x , y , 12.0 , 12.0 ) ;
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 15:55:43 -04:00
case FileChunksInfo : : CHUNK_CHECKING : painter - > drawPixmap ( target , checkingPixmap , source ) ;
break ;
2009-11-17 07:45:06 -05:00
case FileChunksInfo : : CHUNK_OUTSTANDING : painter - > drawPixmap ( target , notDownloadPixmap , source ) ;
break ;
default : ;
}
2009-12-28 16:11:00 -05:00
x + = chunk_square_size ;
2009-11-17 07:45:06 -05:00
}
2009-12-28 16:11:00 -05:00
y + = chunk_square_size ;
// draw the currently downloaded chunks
//
painter - > setPen ( QColor : : fromRgb ( 70 , 70 , 70 ) ) ;
painter - > drawLine ( 0 , y , maxWidth , y ) ;
uint32_t sizeX = 100 ;
uint32_t sizeY = 10 ;
y + = block_sep ;
y + = text_height ;
painter - > setPen ( QColor : : fromRgb ( 0 , 0 , 0 ) ) ;
2010-12-27 13:51:16 -05:00
painter - > drawText ( 0 , y , tr ( " Active chunks " ) + " : " ) ;
2009-12-28 16:11:00 -05:00
y + = block_sep ;
for ( uint i = 0 ; i < info . active_chunks . size ( ) ; + + i )
{
painter - > setPen ( QColor : : fromRgb ( 0 , 0 , 0 ) ) ;
painter - > drawText ( 5 , y + text_height , QString : : number ( info . active_chunks [ i ] . first ) ) ;
2010-10-26 17:13:35 -04: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 16:11:00 -05:00
2011-01-20 16:46:44 -05: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 05:58:02 -05:00
// Already Downloaded.
//
2009-12-28 16:11:00 -05:00
painter - > fillRect ( ch_num_size , y , s , sizeY , QColor : : fromHsv ( 200 , 200 , 255 ) ) ;
2010-12-26 05:58:02 -05:00
// Remains to download
//
2009-12-28 16:11:00 -05:00
painter - > fillRect ( ch_num_size + s , y , sizeX - s , sizeY , QColor : : fromHsv ( 200 , 50 , 255 ) ) ;
2010-12-26 05:58:02 -05: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 16:11:00 -05:00
painter - > setPen ( QColor : : fromRgb ( 0 , 0 , 0 ) ) ;
2010-10-26 17:13:35 -04:00
float percent = ( size_of_this_chunk - info . active_chunks [ i ] . second ) * 100.0 / size_of_this_chunk ;
2009-12-28 16:11:00 -05:00
2011-01-20 16:46:44 -05:00
painter - > drawText ( sizeX + 55 , y + text_height , QString : : number ( percent , ' f ' , 2 ) + " % " ) ;
2009-12-28 16:11:00 -05: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 13:51:16 -05: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 16:11:00 -05:00
y + = block_sep ;
2010-01-31 08:21:37 -05: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 16:11:00 -05:00
2010-06-10 10:13:20 -04:00
for ( int i = 0 ; i < availability_map_size_X ; + + i )
2009-12-28 16:11:00 -05:00
{
int nb_src = 0 ;
int chunk_num = ( int ) floor ( i / float ( availability_map_size_X ) * ( nb_chunks - 1 ) ) ;
2010-01-11 11:00:42 -05:00
for ( std : : map < std : : string , CompressedChunkMap > : : const_iterator it ( info . compressed_peer_availability_maps . begin ( ) ) ; it ! = info . compressed_peer_availability_maps . end ( ) ; + + it )
nb_src + = it - > second [ chunk_num ] ;
2009-12-28 16:11:00 -05:00
2012-09-12 15:03:51 -04:00
painter - > setPen ( QColor : : fromHsv ( 200 , std : : min ( 255 , 50 * nb_src ) , 200 ) ) ; // the more sources, the more saturated
2009-12-28 16:11:00 -05: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 10:13:20 -04:00
y + = block_sep ;
2009-12-28 16:11:00 -05:00
// various info:
//
painter - > setPen ( QColor : : fromRgb ( 0 , 0 , 0 ) ) ;
2010-12-27 13:51:16 -05:00
y + = text_height ; painter - > drawText ( 0 , y , tr ( " File info " ) + " : " ) ;
2009-12-28 16:11:00 -05:00
y + = block_sep ;
2013-02-22 16:42:27 -05:00
y + = text_height ; painter - > drawText ( 20 , y , tr ( " File name " ) + " : " ) ; painter - > drawText ( tab_size , y , QString : : fromStdString ( nfo . fname ) ) ;
y + = block_sep ;
2010-12-27 13:51:16 -05:00
y + = text_height ; painter - > drawText ( 20 , y , tr ( " File hash " ) + " : " ) ; painter - > drawText ( tab_size , y , QString : : fromStdString ( nfo . hash ) ) ;
2010-02-19 17:46:21 -05:00
y + = block_sep ;
2010-12-27 13:51:16 -05:00
y + = text_height ; painter - > drawText ( 20 , y , tr ( " File size " ) + " : " ) ; painter - > drawText ( tab_size , y , QString : : number ( info . file_size ) + " " + tr ( " bytes " ) + " " + " ( " + misc : : friendlyUnit ( info . file_size ) + " ) " ) ;
2009-12-28 16:11:00 -05:00
y + = block_sep ;
2010-12-27 13:51:16 -05:00
y + = text_height ; painter - > drawText ( 20 , y , tr ( " Chunk size " ) + " : " ) ; painter - > drawText ( tab_size , y , QString : : number ( info . chunk_size ) + " " + tr ( " bytes " ) + " " + " ( " + misc : : friendlyUnit ( info . chunk_size ) + " ) " ) ;
2009-12-28 16:11:00 -05:00
y + = block_sep ;
2010-12-27 13:51:16 -05:00
y + = text_height ; painter - > drawText ( 20 , y , tr ( " Number of chunks " ) + " : " ) ; painter - > drawText ( tab_size , y , QString : : number ( info . chunks . size ( ) ) ) ;
2009-12-28 16:11:00 -05:00
y + = block_sep ;
2012-10-11 06:28:24 -04:00
y + = text_height ; painter - > drawText ( 20 , y , tr ( " Transferred " ) + " : " ) ; painter - > drawText ( tab_size , y , QString : : number ( nfo . transfered ) + " " + tr ( " bytes " ) + " " + " ( " + misc : : friendlyUnit ( nfo . transfered ) + " ) " ) ;
2010-02-19 17:46:21 -05:00
y + = block_sep ;
2010-12-27 13:51:16 -05:00
y + = text_height ; painter - > drawText ( 20 , 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 16:46:45 -04:00
y + = block_sep ;
2010-12-27 13:51:16 -05:00
y + = text_height ; painter - > drawText ( 20 , y , tr ( " Number of sources " ) + " : " ) ; painter - > drawText ( tab_size , y , QString : : number ( info . compressed_peer_availability_maps . size ( ) ) ) ;
2010-01-22 18:23:37 -05:00
y + = block_sep ;
2013-02-28 15:42:01 -05:00
y + = text_height ; painter - > drawText ( 20 , y , tr ( " Chunk strategy " ) + " : " ) ;
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 18:23:37 -05:00
y + = block_sep ;
2010-12-27 13:51:16 -05:00
y + = text_height ; painter - > drawText ( 20 , y , tr ( " Transfer type " ) + " : " ) ;
2012-11-02 09:52:29 -04: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 16:11:00 -05:00
y + = text_height ;
y + = block_sep ;
2009-11-17 07:45:06 -05:00
maxHeight = y + 15 ;
}
2009-12-28 16:11:00 -05:00