bool PageView::readUp()
{
  if( atTop() )
    return false;
  else {
    // Coordinate of the top of the viewport
    int top = contentsY();

    DocumentWidget* widget = 0;
    // Find the widget(s) that intersect the top of the viewport
    // TODO: It would be better to use a binary search.
    for(Q_UINT16 i=0; i<widgetList->size(); i++)
    {
      widget = widgetList->at(i);
      if (childY(widget) < top && childY(widget) + widget->height() > top)
      {
        // Draw scrollguide
        widget->drawScrollGuide(top - childY(widget));
      }
    }

    int newValue = QMAX( verticalScrollBar()->value() - (int)(height() * 0.9),
                         verticalScrollBar()->minValue() );
    verticalScrollBar()->setValue( newValue );
    return true;
  }
}
bool PageView::readDown()
{
  if( atBottom() )
    return false;
  else {
    // Coordinate of the bottom of the viewport
    int bottom = contentsY() + visibleHeight();

    DocumentWidget* widget = 0;
    // Find the widget(s) that intersect the bottom of the viewport
    // TODO: It would be better to use a binary search.
    for(Q_UINT16 i=0; i<widgetList->size(); i++)
    {
      widget = widgetList->at(i);
      if (childY(widget) < bottom && childY(widget) + widget->height() > bottom)
      {
        // Draw scrollguide
        widget->drawScrollGuide(bottom - childY(widget));
      }
    }

    int newValue = QMIN( verticalScrollBar()->value() + (int)(height() * 0.9),
                         verticalScrollBar()->maxValue() );
    verticalScrollBar()->setValue( newValue );

    return true;
  }
}
void ThumbnailList::notifyViewportChanged( bool /*smoothMove*/ )
{
	// skip notifies for the current page (already selected)
	int newPage = m_document->viewport().pageNumber;
	if ( m_selected && m_selected->pageNumber() == newPage )
		return;

	// deselect previous thumbnail
	if ( m_selected )
		m_selected->setSelected( false );
	m_selected = 0;

	// select the page with viewport and ensure it's centered in the view
	m_vectorIndex = 0;
	QValueVector<ThumbnailWidget *>::iterator tIt = m_thumbnails.begin(), tEnd = m_thumbnails.end();
	for ( ; tIt != tEnd; ++tIt )
	{
		if ( (*tIt)->pageNumber() == newPage )
		{
			m_selected = *tIt;
			m_selected->setSelected( true );
			if ( KpdfSettings::syncThumbnailsViewport() )
			{
				int yOffset = QMAX( visibleHeight() / 4, m_selected->height() / 2 );
				ensureVisible( 0, childY( m_selected ) + m_selected->height()/2, 0, yOffset );
			}
			break;
		}
		m_vectorIndex++;
	}
}
void TLFrameSequenceLayout::moveFrames( int x )
{
    //Move each frame sequence
    TLFrameSequence *frame_sequence_iterator;
    for ( frame_sequence_iterator = list_of_frame_sequences.first(); frame_sequence_iterator; frame_sequence_iterator = list_of_frame_sequences.next() )
    {
	moveChild( frame_sequence_iterator, x, childY( frame_sequence_iterator ) );
    }
}
void TLFrameSequenceLayout::slotMoveFrameSequenceDown()
{
    //If the current frame sequence is the last, do nothing
    if ( current_frame_sequence == last_frame_sequence )
        return;

    //Find the frame sequence above the current and reinsert it into the list in its new position
    TLFrameSequence *frame_sequence_below = list_of_frame_sequences.take( list_of_frame_sequences.find( current_frame_sequence ) + 1 );
    current_frame_sequence -> setPosition( current_frame_sequence -> position() + 1 );
    frame_sequence_below -> setPosition( frame_sequence_below -> position() - 1 );
    list_of_frame_sequences.insert( frame_sequence_below -> position() - 1, frame_sequence_below );
    if ( frame_sequence_below == last_frame_sequence )
        last_frame_sequence = current_frame_sequence;

    //Swap both frame sequences in the scroll view
    moveChild( frame_sequence_below, childX( frame_sequence_below ), childY( frame_sequence_below ) - 24 );
    moveChild( current_frame_sequence, childX( current_frame_sequence ), childY( current_frame_sequence ) + 24 );
    updateContentSize();
}
void 
PolicyViewClass::startAddTransition(PatternWidgetClass* patternWidget)
{
  pickedPatternPtr = patternWidget;
  pickedPattern    = patternWidget->getPatternName();
  addTransitionMode = true;
  arrowFrom_.setX(childX(pickedPatternPtr));
  arrowFrom_.setY(childY(pickedPatternPtr));

  viewport()->setMouseTracking(true);
}
void PageView::calculateCurrentPageNumber(int x, int y)
{
  // Safety check
  if (widgetList == 0)
    return;

  QRect viewportRect(x, y, visibleWidth(), visibleHeight());

  //kdDebug() << "viewportRect(" << viewportRect.x() << ", " << viewportRect.y() << ", "
  //          << viewportRect.width() << ", " << viewportRect.height() << ")" << endl;

  int maxVisiblePixels = 0;
  DocumentWidget* _currentWidget = 0;

  for (Q_UINT16 i = 0; i < widgetList->size(); i++)
  {
    DocumentWidget* documentWidget = widgetList->at(i);
    // Safety check
    if (documentWidget == 0)
      continue;

    // Check if the Widget is visible
    int cx = childX(documentWidget);
    int cy = childY(documentWidget);
    QRect widgetRect(cx, cy, documentWidget->width(), documentWidget->height());
    bool isVisible = widgetRect.intersects(viewportRect);

    if (!isVisible)
      continue;

    // Calculate the number of visible pixels of the widget
    QRect visibleRect = widgetRect.intersect(viewportRect);
    int visiblePixels = visibleRect.width() * visibleRect.height();

    //kdDebug() << visiblePixels << " pixels are visible of page " << documentWidget->getPageNumber() << endl;

    // If a bigger part of this widget as of the previous widgets is visible make it the current widget.
    if (maxVisiblePixels < visiblePixels)
    {
      maxVisiblePixels = visiblePixels;
      _currentWidget = documentWidget;
    }
  }

  // No page is visible
  if (_currentWidget == 0)
    return;

  // Return the number of the current page
  emit currentPageChanged(_currentWidget->getPageNumber());
}
void TLFrameSequenceLayout::slotSwapFrameSequences( int c_pos, int r_pos )
{
    Q_ASSERT( c_pos > 0 && r_pos > 0 );
    TLFrameSequence *release_frame_sequence;

    release_frame_sequence = NULL;

    //Above
    if ( c_pos > r_pos )
    {
        current_frame_sequence = list_of_frame_sequences.take( list_of_frame_sequences.find( current_frame_sequence ) );
        release_frame_sequence = list_of_frame_sequences.take( r_pos - 1 );
        current_frame_sequence -> setPosition( r_pos );
        release_frame_sequence -> setPosition( c_pos );
        list_of_frame_sequences.insert( current_frame_sequence -> position() - 1, current_frame_sequence );
        list_of_frame_sequences.insert( release_frame_sequence -> position() - 1, release_frame_sequence );
    }
    //Below
    else if ( c_pos < r_pos )
    {
        release_frame_sequence = list_of_frame_sequences.take( r_pos - 1 );
        current_frame_sequence = list_of_frame_sequences.take( list_of_frame_sequences.find( current_frame_sequence ) );
        current_frame_sequence -> setPosition( r_pos );
        release_frame_sequence -> setPosition( c_pos );
        list_of_frame_sequences.insert( release_frame_sequence -> position() - 1, release_frame_sequence );
        list_of_frame_sequences.insert( current_frame_sequence -> position() - 1, current_frame_sequence );
    }
    last_frame_sequence = list_of_frame_sequences.getLast();

    int cfs_old_x, cfs_old_y, rfs_old_x, rfs_old_y;
    cfs_old_x = childX( current_frame_sequence );
    cfs_old_y = childY( current_frame_sequence );
    rfs_old_x = childX( release_frame_sequence );
    rfs_old_y = childY( release_frame_sequence );
    moveChild( current_frame_sequence, rfs_old_x, rfs_old_y );
    moveChild( release_frame_sequence, cfs_old_x, cfs_old_y );
    updateContentSize();
}
void PageView::moveViewportToWidget(QWidget* widget, int y)
{
  int verticalPos = 0;
  int verticalPosTop = 0;

  if (y != 0)
  {
    verticalPosTop = childY(widget) +  y - visibleHeight()/2;
    verticalPos = childY(widget) +  y;
  }
  else
  {
    verticalPos = childY(widget) - distanceBetweenWidgets;
    verticalPosTop = verticalPos;
  }

  if (nrCols == 1)
  {
    // In single column viewmodes, we change the vertical position only, to make it
    // easier to work with high zoomlevels where not the whole pagewidth is visible.
    // TODO: Smarter algorithm also for continuous facing viewmode.
    int top = (int)(contentsY() + 0.1 * visibleHeight());
    int bottom = (int)(contentsY() + 0.9 * visibleHeight());

    // Move the viewport if the target is currently not visible, or lies at the edge
    // of the viewport. If y = 0 always move the top of the targetpage to the top edge
    // of the viewport.
    if (verticalPos < top || verticalPos > bottom || y == 0)
    {
      setContentsPos(contentsX(), verticalPosTop);
    }
  }
  else
  {
    setContentsPos(childX(widget) - distanceBetweenWidgets, verticalPosTop);
  }
}
void ThumbnailList::updateWidgets()
{
    // find all widgets that intersects the viewport and update them
    QRect viewportRect( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
    QValueList<ThumbnailWidget *>::iterator vIt = m_visibleThumbnails.begin(), vEnd = m_visibleThumbnails.end();
    for ( ; vIt != vEnd; ++vIt )
    {
        ThumbnailWidget * t = *vIt;
        QRect widgetRect( childX( t ), childY( t ), t->width(), t->height() );
        // update only the exposed area of the widget (saves pixels..)
        QRect relativeRect = viewportRect.intersect( widgetRect );
        if ( !relativeRect.isValid() )
            continue;
        relativeRect.moveBy( -widgetRect.left(), -widgetRect.top() );
        t->update( relativeRect );
    }
}
void ThumbnailList::contentsMousePressEvent( QMouseEvent * e )
{
	if ( e->button() != Qt::LeftButton )
		return;
	int clickY = e->y();
	QValueList<ThumbnailWidget *>::iterator vIt = m_visibleThumbnails.begin(), vEnd = m_visibleThumbnails.end();
	for ( ; vIt != vEnd; ++vIt )
	{
		ThumbnailWidget * t = *vIt;
		int childTop = childY(t);
		if ( clickY > childTop && clickY < (childTop + t->height()) )
		{
			if ( m_document->viewport().pageNumber != t->pageNumber() )
				m_document->setViewportPage( t->pageNumber() );
			break;
		}
	}
}
void ThumbnailList::viewportResizeEvent( QResizeEvent * e )
{
	if ( m_thumbnails.count() < 1 || width() < 1 )
		return;

	// if width changed resize all the Thumbnails, reposition them to the
	// right place and recalculate the contents area
	if ( e->size().width() != e->oldSize().width() )
	{
		// runs the timer avoiding a thumbnail regeneration by 'contentsMoving'
		delayedRequestVisiblePixmaps( 2000 );

		// resize and reposition items
		int totalHeight = 0,
		    newWidth = e->size().width();
		QValueVector<ThumbnailWidget *>::iterator tIt = m_thumbnails.begin(), tEnd = m_thumbnails.end();
		for ( ; tIt != tEnd; ++tIt )
		{
			ThumbnailWidget *t = *tIt;
			moveChild( t, 0, totalHeight );
			t->resizeFitWidth( newWidth );
			totalHeight += t->heightHint() + 4;
		}

		// update scrollview's contents size (sets scrollbars limits)
		resizeContents( newWidth, totalHeight );

		// ensure selected item remains visible
		if ( m_selected )
			ensureVisible( 0, childY( m_selected ) + m_selected->height()/2, 0, visibleHeight()/2 );
	}
	else if ( e->size().height() <= e->oldSize().height() )
		return;

	// invalidate the bookmark overlay
	if ( m_bookmarkOverlay )
	{
		delete m_bookmarkOverlay;
		m_bookmarkOverlay = 0;
	}

	// update Thumbnails since width has changed or height has increased
	delayedRequestVisiblePixmaps( 500 );
}
void TLFrameSequenceLayout::slotRemoveFrameSequence()
{
   if ( number_of_frame_sequences > 1 )
   {
      TLFrameSequence *bridge_frame_sequence;
      number_of_frame_sequences--;

      //Case 1: When the sequence of frames is the last within the list
      if ( current_frame_sequence == last_frame_sequence )
      {
	  list_of_frame_sequences.remove( current_frame_sequence );
	  bridge_frame_sequence = list_of_frame_sequences.getLast();
	  delete current_frame_sequence;
	  current_frame_sequence = bridge_frame_sequence;
	  last_frame_sequence = current_frame_sequence;
	  current_frame = NULL;
      }
      //Case 2: When the sequence of frames is any except the last
      else
      {
	  bridge_frame_sequence = list_of_frame_sequences.at( list_of_frame_sequences.find( current_frame_sequence ) + 1 );

	  //Reaccomodate every frame_sequence next to the frame_sequence that is going to be deleted
	  TLFrameSequence *frame_sequence_iterator;
	  for ( frame_sequence_iterator = bridge_frame_sequence; frame_sequence_iterator; frame_sequence_iterator = list_of_frame_sequences.next() )
	  {
	      moveChild( frame_sequence_iterator, childX( frame_sequence_iterator ), childY( frame_sequence_iterator ) - frame_sequence_iterator -> height() );
	      frame_sequence_iterator -> setPosition( frame_sequence_iterator -> position() - 1 );
	  }

	  list_of_frame_sequences.remove( current_frame_sequence );
	  delete current_frame_sequence;
	  current_frame_sequence = bridge_frame_sequence;
	  current_frame = NULL;
      }
      updateContentSize();
   }
}
//BEGIN internal SLOTS 
void ThumbnailList::slotRequestVisiblePixmaps( int /*newContentsX*/, int newContentsY )
{
    // if an update is already scheduled or the widget is hidden, don't proceed
    if ( (m_delayTimer && m_delayTimer->isActive()) || !isShown() )
        return;

    int vHeight = visibleHeight(),
        vOffset = newContentsY == -1 ? contentsY() : newContentsY;

    // scroll from the top to the last visible thumbnail
    m_visibleThumbnails.clear();
    QValueList< PixmapRequest * > requestedPixmaps;
    QValueVector<ThumbnailWidget *>::iterator tIt = m_thumbnails.begin(), tEnd = m_thumbnails.end();
    for ( ; tIt != tEnd; ++tIt )
    {
        ThumbnailWidget * t = *tIt;
        int top = childY( t ) - vOffset;
        if ( top > vHeight )
            break;
        if ( top + t->height() < 0 )
            continue;
        // add ThumbnailWidget to visible list
        m_visibleThumbnails.push_back( t );
        // if pixmap not present add it to requests
        if ( !t->page()->hasPixmap( THUMBNAILS_ID, t->pixmapWidth(), t->pixmapHeight() ) )
        {
            PixmapRequest * p = new PixmapRequest(
                    THUMBNAILS_ID, t->pageNumber(), t->pixmapWidth(), t->pixmapHeight(), THUMBNAILS_PRIO, true );
            requestedPixmaps.push_back( p );
        }
    }

    // actually request pixmaps
    if ( !requestedPixmaps.isEmpty() )
        m_document->requestPixmaps( requestedPixmaps );
}