X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/f32987d719f4b396ea2679b59a712a8bc288b8d2..11289b4fc3efbc074b668d4516cd896f8ade9761:/src/tagcloud/tagcloud.cpp diff --git a/src/tagcloud/tagcloud.cpp b/src/tagcloud/tagcloud.cpp index e59074fab..2afd62e3b 100644 --- a/src/tagcloud/tagcloud.cpp +++ b/src/tagcloud/tagcloud.cpp @@ -281,10 +281,6 @@ void Nepomuk::TagCloud::Private::sortNodes() void Nepomuk::TagCloud::Private::rebuildCloud() { - if ( nodes.isEmpty() && !newTagButtonEnabled ) { - return; - } - // - Always try to be quadratic // - Always prefer to expand horizontally // - If we cannot fit everything into m_parent->contentsRect(), zoom @@ -297,7 +293,7 @@ void Nepomuk::TagCloud::Private::rebuildCloud() // initialize the nodes' sizes // ---------------------------------------------- for ( QList::iterator it = nodes.begin(); - it != nodes.end(); ++it ) { + it != nodes.end(); ++it ) { TagNode& node = *it; node.rect = QFontMetrics( node.font ).boundingRect( node.text ); } @@ -309,154 +305,156 @@ void Nepomuk::TagCloud::Private::rebuildCloud() // and position the nodes // ---------------------------------------------- rows.clear(); - if ( 0 ) { // FIXME: make it configurable - QRect lineRect; - QRect totalRect; - QList row; - for ( QList::iterator it = nodes.begin(); - it != nodes.end(); /* We do increment it below */ ) { - TagNode& node = *it; + if ( !nodes.isEmpty() || newTagButtonEnabled ) { + if ( 0 ) { // FIXME: make it configurable + QRect lineRect; + QRect totalRect; + QList row; + for ( QList::iterator it = nodes.begin(); + it != nodes.end(); /* We do increment it below */ ) { + TagNode& node = *it; + + int usedSpacing = row.isEmpty() ? 0 : s_hSpacing; + if ( lineRect.width() + usedSpacing + node.rect.width() <= contentsRect.width() ) { + node.rect.moveBottomLeft( QPoint( lineRect.right() + usedSpacing, lineRect.bottom() ) ); + QRect newLineRect = lineRect.united( node.rect ); + newLineRect.moveTopLeft( lineRect.topLeft() ); + lineRect = newLineRect; + row.append( &node ); + + // update all other nodes in this line + Q_FOREACH( TagNode* n, row ) { + n->rect.moveBottom( lineRect.bottom() - ( lineRect.height() - n->rect.height() )/2 ); + } - int usedSpacing = row.isEmpty() ? 0 : s_hSpacing; - if ( lineRect.width() + usedSpacing + node.rect.width() <= contentsRect.width() ) { - node.rect.moveBottomLeft( QPoint( lineRect.right() + usedSpacing, lineRect.bottom() ) ); - QRect newLineRect = lineRect.united( node.rect ); - newLineRect.moveTopLeft( lineRect.topLeft() ); - lineRect = newLineRect; - row.append( &node ); - - // update all other nodes in this line - Q_FOREACH( TagNode* n, row ) { - n->rect.moveBottom( lineRect.bottom() - ( lineRect.height() - n->rect.height() )/2 ); + ++it; + } + else { + rows.append( row ); + row.clear(); + int newLineTop = lineRect.bottom() + s_vSpacing; + lineRect = QRect(); + lineRect.moveTop( newLineTop ); } - - ++it; - } - else { - rows.append( row ); - row.clear(); - int newLineTop = lineRect.bottom() + s_vSpacing; - lineRect = QRect(); - lineRect.moveTop( newLineTop ); } + rows.append( row ); } - rows.append( row ); - } - else { - // initialize first row - rows.append( QList() ); - for ( QList::iterator it = nodes.begin(); - it != nodes.end(); ++it ) { - TagNode& node = *it; - rows.first().append( &node ); - } - if ( newTagButtonEnabled ) { - rows.first().append( &newTagNode ); - } + else { + // initialize first row + rows.append( QList() ); + for ( QList::iterator it = nodes.begin(); + it != nodes.end(); ++it ) { + TagNode& node = *it; + rows.first().append( &node ); + } + if ( newTagButtonEnabled ) { + rows.first().append( &newTagNode ); + } - // calculate the rows - QList > bestRows( rows ); - QSize size( rowLength( rows.first() ), rowHeight( rows.first() ) ); - QSize bestSize( size ); - while ( ( size.height() < size.width() || - size.width() > contentsRect.width() ) && - size.height() <= contentsRect.height() ) { - // find the longest row - int maxRow = 0; - int maxLen = 0; - for ( int i = 0; i < rows.count(); ++i ) { - int rowLen = rowLength( rows[i] ); - if ( rowLen > maxLen ) { - maxLen = rowLen; - maxRow = i; + // calculate the rows + QList > bestRows( rows ); + QSize size( rowLength( rows.first() ), rowHeight( rows.first() ) ); + QSize bestSize( size ); + while ( ( size.height() < size.width() || + size.width() > contentsRect.width() ) && + size.height() <= contentsRect.height() ) { + // find the longest row + int maxRow = 0; + int maxLen = 0; + for ( int i = 0; i < rows.count(); ++i ) { + int rowLen = rowLength( rows[i] ); + if ( rowLen > maxLen ) { + maxLen = rowLen; + maxRow = i; + } } - } - // move the last item from the longest row to the next row - TagNode* node = rows[maxRow].takeLast(); - if ( rows.count() <= maxRow+1 ) { - rows.append( QList() ); - } - rows[maxRow+1].prepend( node ); + // move the last item from the longest row to the next row + TagNode* node = rows[maxRow].takeLast(); + if ( rows.count() <= maxRow+1 ) { + rows.append( QList() ); + } + rows[maxRow+1].prepend( node ); - // update the size - size = cloudSize( rows ); + // update the size + size = cloudSize( rows ); - if ( size.width() < bestSize.width() && - ( size.width() > size.height() || - bestSize.width() > contentsRect.width() ) && - size.height() <= contentsRect.height() ) { - bestSize = size; - bestRows = rows; + if ( size.width() < bestSize.width() && + ( size.width() > size.height() || + bestSize.width() > contentsRect.width() ) && + size.height() <= contentsRect.height() ) { + bestSize = size; + bestRows = rows; + } + } + rows = bestRows; + + // position the tags + int y = 0; + for ( QList >::iterator rowIt = rows.begin(); rowIt != rows.end(); ++rowIt ) { + QList& row = *rowIt; + int h = rowHeight( row ); + int x = 0; + Q_FOREACH( TagNode* node, row ) { + node->rect.moveTop( y + ( h - node->rect.height() )/2 ); + node->rect.moveLeft( x ); + x += s_hSpacing + node->rect.width(); + } + y += h + s_vSpacing; } } - rows = bestRows; - // position the tags - int y = 0; - for ( QList >::iterator rowIt = rows.begin(); rowIt != rows.end(); ++rowIt ) { - QList& row = *rowIt; - int h = rowHeight( row ); - int x = 0; - Q_FOREACH( TagNode* node, row ) { - node->rect.moveTop( y + ( h - node->rect.height() )/2 ); - node->rect.moveLeft( x ); - x += s_hSpacing + node->rect.width(); + + // let's see if we have to zoom + // ---------------------------------------------- + zoomMatrix = QMatrix(); + int w = contentsRect.width(); + if ( zoomEnabled ) { + for ( QList >::iterator rowIt = rows.begin(); rowIt != rows.end(); ++rowIt ) { + QList& row = *rowIt; + w = qMax( w, row.last()->rect.right() ); + } + if ( w > contentsRect.width() ) { + double zoomFactor = ( double )contentsRect.width() / ( double )w; + zoomMatrix.scale( zoomFactor, zoomFactor ); } - y += h + s_vSpacing; } - } - - // let's see if we have to zoom - // ---------------------------------------------- - zoomMatrix = QMatrix(); - int w = contentsRect.width(); - if ( zoomEnabled ) { + // force horizontal alignment + // ---------------------------------------------- for ( QList >::iterator rowIt = rows.begin(); rowIt != rows.end(); ++rowIt ) { QList& row = *rowIt; - w = qMax( w, row.last()->rect.right() ); - } - if ( w > contentsRect.width() ) { - double zoomFactor = ( double )contentsRect.width() / ( double )w; - zoomMatrix.scale( zoomFactor, zoomFactor ); - } - } - - // force horizontal alignment - // ---------------------------------------------- - for ( QList >::iterator rowIt = rows.begin(); rowIt != rows.end(); ++rowIt ) { - QList& row = *rowIt; - int space = /*contentsRect.right()*/w - row.last()->rect.right(); - if ( alignment & ( Qt::AlignRight|Qt::AlignHCenter ) ) { - Q_FOREACH( TagNode* node, row ) { - node->rect.moveLeft( node->rect.left() + ( alignment & Qt::AlignRight ? space : space/2 ) ); + int space = /*contentsRect.right()*/w - row.last()->rect.right(); + if ( alignment & ( Qt::AlignRight|Qt::AlignHCenter ) ) { + Q_FOREACH( TagNode* node, row ) { + node->rect.moveLeft( node->rect.left() + ( alignment & Qt::AlignRight ? space : space/2 ) ); + } } - } - else if ( alignment & Qt::AlignJustify && row.count() > 1 ) { - space /= ( row.count()-1 ); - int i = 0; - Q_FOREACH( TagNode* node, row ) { - node->rect.moveLeft( node->rect.left() + ( space * i++ ) ); + else if ( alignment & Qt::AlignJustify && row.count() > 1 ) { + space /= ( row.count()-1 ); + int i = 0; + Q_FOREACH( TagNode* node, row ) { + node->rect.moveLeft( node->rect.left() + ( space * i++ ) ); + } } } - } - // force vertical alignment - // ---------------------------------------------- - int verticalSpace = contentsRect.bottom() - rows.last().first()->rect.bottom(); - if ( alignment & ( Qt::AlignBottom|Qt::AlignVCenter ) ) { - for ( QList >::iterator rowIt = rows.begin(); rowIt != rows.end(); ++rowIt ) { - Q_FOREACH( TagNode* node, *rowIt ) { - node->rect.moveTop( node->rect.top() + ( alignment & Qt::AlignBottom ? verticalSpace : verticalSpace/2 ) ); + // force vertical alignment + // ---------------------------------------------- + int verticalSpace = contentsRect.bottom() - rows.last().first()->rect.bottom(); + if ( alignment & ( Qt::AlignBottom|Qt::AlignVCenter ) ) { + for ( QList >::iterator rowIt = rows.begin(); rowIt != rows.end(); ++rowIt ) { + Q_FOREACH( TagNode* node, *rowIt ) { + node->rect.moveTop( node->rect.top() + ( alignment & Qt::AlignBottom ? verticalSpace : verticalSpace/2 ) ); + } } } - } - for( QList::iterator it = nodes.begin(); it != nodes.end(); ++it ) { - it->zoomedRect = zoomMatrix.mapRect( it->rect ); + for( QList::iterator it = nodes.begin(); it != nodes.end(); ++it ) { + it->zoomedRect = zoomMatrix.mapRect( it->rect ); + } + newTagNode.zoomedRect = zoomMatrix.mapRect( newTagNode.rect ); } - newTagNode.zoomedRect = zoomMatrix.mapRect( newTagNode.rect ); m_parent->updateGeometry(); m_parent->update(); @@ -466,7 +464,8 @@ void Nepomuk::TagCloud::Private::rebuildCloud() // binary search in row TagNode* Nepomuk::TagCloud::Private::findTagInRow( const QList& row, const QPoint& pos ) { - int x = row.count() * pos.x() / m_parent->width(); + int x = m_parent->width() ? row.count() * pos.x() / m_parent->width() : 0; + int i = 0; while ( 1 ) { if ( x-i >= 0 && x-i < row.count() && row[x-i]->zoomedRect.contains( pos ) ) { @@ -487,7 +486,7 @@ TagNode* Nepomuk::TagCloud::Private::findTagInRow( const QList& row, c // binary search in cloud TagNode* Nepomuk::TagCloud::Private::tagAt( const QPoint& pos ) { - int y = rows.count() * pos.y() / m_parent->height(); + int y = m_parent->height() ? rows.count() * pos.y() / m_parent->height() : 0; int i = 0; while ( 1 ) { @@ -613,6 +612,7 @@ void Nepomuk::TagCloud::setZoomEnabled( bool zoom ) void Nepomuk::TagCloud::setContextMenuEnabled( bool enabled ) { + Q_UNUSED(enabled); } @@ -761,8 +761,6 @@ int Nepomuk::TagCloud::heightForWidth( int contentsWidth ) const // If we have tags d->rebuildCloud() has been called at least once, // thus, we have proper rects (i.e. needed sizes) - // FIXME: add zoom here - if ( d->cachedHfwWidth != contentsWidth ) { // have to keep in mind the frame contentsWidth -= frameWidth()*2; @@ -781,6 +779,7 @@ int Nepomuk::TagCloud::heightForWidth( int contentsWidth ) const bool newRow = true; int rowW = 0; int rowH = 0; + int maxW = 0; for ( int i = 0; i < allNodes.count(); ++i ) { int w = rowW; if ( !newRow ) { @@ -800,6 +799,7 @@ int Nepomuk::TagCloud::heightForWidth( int contentsWidth ) const rowH = allNodes[i]->rect.height(); rowW = allNodes[i]->rect.width(); } + maxW = qMax( maxW, rowW ); } if ( rowH > 0 ) { h += s_vSpacing + rowH; @@ -807,6 +807,11 @@ int Nepomuk::TagCloud::heightForWidth( int contentsWidth ) const d->cachedHfwWidth = contentsWidth; d->cachedHfwHeight = h; + + // zooming + if ( maxW > contentsWidth ) { + d->cachedHfwHeight = d->cachedHfwHeight * contentsWidth / maxW; + } } return d->cachedHfwHeight + frameWidth()*2;