AlbumShaper  1.0a3
Public Slots | Signals | Public Member Functions | Protected Member Functions | Private Slots | Private Member Functions | Private Attributes
PhotosIconView Class Reference

Extension of iconview, used to list all photos in a subalbum. supports drag-n-drop within iconview. More...

#include <photosIconView.h>

Inheritance diagram for PhotosIconView:
Inheritance graph
[legend]
Collaboration diagram for PhotosIconView:
Collaboration graph
[legend]

List of all members.

Public Slots

void clearPseudoSelection ()
void repaintGroup (QIconViewItem *pseudoSelection)

Signals

void itemHasMoved ()
void addPhotos (QStringList)
void removeSelectedPhotos ()
void rotate90SelectedPhotos ()
void rotate270SelectedPhotos ()
void editSelectedPhoto ()

Public Member Functions

 PhotosIconView (QWidget *parent)
int numSelected ()

Protected Member Functions

QDragObject * dragObject ()
void drawContents (QPainter *p, int clipx, int clipy, int clipw, int cliph)
void drawBackground (QPainter *p, const QRect &r)
void contextMenuEvent (QContextMenuEvent *e)
void contentsMouseMoveEvent (QMouseEvent *e)
void contentsMousePressEvent (QMouseEvent *e)
void keyPressEvent (QKeyEvent *e)

Private Slots

void setAlbumImage ()
void setSubalbumImage ()
void captureClick (QIconViewItem *, const QPoint &)

Private Member Functions

void contentsDropEvent (QDropEvent *e)
bool findNearestUnselectedPhoto (const QPoint &pos, QIconViewItem **nearestItem, bool &posIsleftOfItem)

Private Attributes

PhotoPreviewWidgetrightClickedPhoto
QPixmap * backgroundImage
QPixmap bufferPixmap
QPixmap * dragIcon
PhotoPreviewWidgetcurrentPseudoSelection
bool handCursorShown
QPoint dragStartPos
PhotoDescEditcurPhotoDescEdit

Detailed Description

Extension of iconview, used to list all photos in a subalbum. supports drag-n-drop within iconview.

Definition at line 29 of file photosIconView.h.


Constructor & Destructor Documentation

PhotosIconView::PhotosIconView ( QWidget parent)

Definition at line 46 of file photosIconView.cpp.

References backgroundImage, captureClick(), clearPseudoSelection(), curPhotoDescEdit, currentPseudoSelection, dragIcon, handCursorShown, IMAGE_PATH, repaintGroup(), and rightClickedPhoto.

                                                : QIconView( parent, "iconView", WNoAutoErase )
{
  viewport()->setBackgroundMode( Qt::NoBackground );

  currentPseudoSelection = NULL;
  handCursorShown = false;
  
  curPhotoDescEdit = NULL;

  //by default no photo has been right clicked on
  rightClickedPhoto = NULL;

  //load background image
  backgroundImage = new QPixmap( QString(IMAGE_PATH)+"miscImages/backgroundImage.png" );

  //load drag icon
  dragIcon = new QPixmap( QString(IMAGE_PATH)+"miscImages/moveImage.png" );

  //connect mouse over events to paint pseudo selection in ligher blue
  connect( this, SIGNAL(onItem(QIconViewItem*)),
                this, SLOT(repaintGroup(QIconViewItem*)) );

  //clear any pseudo selection when mouse moves off icons
  connect( this, SIGNAL(onViewport()),
                this, SLOT(clearPseudoSelection()) );

  connect( this, SIGNAL(pressed( QIconViewItem*, const QPoint& )),
                 this, SLOT(captureClick(QIconViewItem*, const QPoint&)) );
}

Member Function Documentation

void PhotosIconView::addPhotos ( QStringList  ) [signal]

Referenced by contentsDropEvent().

void PhotosIconView::captureClick ( QIconViewItem item,
const QPoint &  point 
) [private, slot]

Definition at line 394 of file photosIconView.cpp.

References curPhotoDescEdit, and topLeft.

Referenced by PhotosIconView().

{
  //if no item has been clicked then ignore
  if(item == NULL)
    return;

  //get info button rect
  QRect infoButtonRec = ((PhotoPreviewWidget*)item)->getPhotoInfoRect();

  //remove scroll offset
  infoButtonRec.moveBy( -contentsX(), -contentsY() );

  //convert to screen coordinates by shifting by offset of topleft of widget
  QPoint topLeft = mapToGlobal( QPoint(0,0) );
  infoButtonRec.moveBy( topLeft.x(), topLeft.y() );

  //if screen coordinates of mouse click are in rectangle then button pressed
  if( infoButtonRec.contains( point.x(), point.y() ) )
  {
    //make sure all events have been processed first. if were just
    //editing a differnt photo description it is first necessary to 
    //repaint before we start editing the next
    qApp->processEvents();

    if( curPhotoDescEdit != NULL ) { delete curPhotoDescEdit; }

    PhotoPreviewWidget* ppw = (PhotoPreviewWidget*)item;
    curPhotoDescEdit = new PhotoDescEdit( ppw,
        ((Window*)qApp->mainWidget())->getConfig()->getBool( "layout", "animation" ) );
  }
}
void PhotosIconView::clearPseudoSelection ( ) [slot]

Definition at line 376 of file photosIconView.cpp.

References currentPseudoSelection, and PhotoPreviewWidget::setMousedOver().

Referenced by PhotosIconView(), and repaintGroup().

{
  //check to make sure mouse is still off item. when a user expands an image to edit
  //it's description, the selection is cleard (since hte mouse is over a new window). however,
  //when that window disappears repaintGroup never got recalled (if the mouse was still on the original window),
  //so just ignore the original clear (it was invalid anyways right?)
 if( findItem( viewport()->mapFromGlobal( QCursor::pos() )+=QPoint( contentsX(), contentsY() )  ) == currentPseudoSelection )
   return;

  //if old pseudo selection unselect it
  if(currentPseudoSelection != NULL)
  {
    currentPseudoSelection->setMousedOver(false);
    repaintItem(currentPseudoSelection);
    currentPseudoSelection = NULL;
  }
}
void PhotosIconView::contentsDropEvent ( QDropEvent *  e) [private]

Definition at line 223 of file photosIconView.cpp.

References addPhotos(), findNearestUnselectedPhoto(), and itemHasMoved().

{
  QIconView::contentsDropEvent( e );
  
  //if item is from the viewport emit item moved signal
  if(e->source() == viewport() )
  { 
    //find nearest unselected item
    QIconViewItem* item; bool leftOf;
    if( !findNearestUnselectedPhoto( e->pos(), &item, leftOf ) )
    {
      //unable to find nearest item. this should be impossible
    //  cout << "ERROR! Failed to find nearest item!\n";
      emit itemHasMoved();
    }  
    
    //selected photos dropped on LEFT of nearest item
    if( leftOf )
    {
      //count number of items being moved
      int num=0;
      QIconViewItem* current = firstItem();
      while(current != NULL)
      {
        if(current->isSelected()) { num++; }
        current = current->nextItem();
      }
    
      //move items to their new locations
      int xpos = item->x() - num;
      current = firstItem();
      while(current != NULL)
      {
        if(current->isSelected())
        {
          current->move(xpos, item->y()); 
          xpos++;
        }
        current = current->nextItem();
      }
    }
    //selected phtos dropped on RIGHT of nearest item
    else
    {
      //move items to their new locations
      int xpos = item->x() + (item->width()/2) + 1;
      QIconViewItem* current = firstItem();
      while(current != NULL)
      {
        if(current->isSelected())
        {
          current->move(xpos, item->y());
          xpos++;
        }
        current = current->nextItem();
      }
    }

    //items have moved!
    emit itemHasMoved();
  }
  //else it's from off the viewport, if we can get filename then try adding photos being added to subalbum
  else
  {
    QStringList fileNames;
    if( QUriDrag::decodeLocalFiles( e, fileNames ) )
    {
      //for some reason the order in which we receive file names is entire illogical.
      //it does not appear to be based on filename, data, modified data, size, anything!
      //thus, before adding files, first sort by ascending filename
      fileNames.sort();
      emit addPhotos(fileNames);
    }
  }
  
}
void PhotosIconView::contentsMouseMoveEvent ( QMouseEvent *  e) [protected]

Definition at line 432 of file photosIconView.cpp.

References currentPseudoSelection, PhotoPreviewWidget::getPhotoInfoRect(), and handCursorShown.

{
  QIconView::contentsMouseMoveEvent( e );

  //if no item is under mouse then return
  if(currentPseudoSelection == NULL)
  {
    if(handCursorShown)
    {
      setCursor( QCursor( Qt::ArrowCursor ) );
      handCursorShown = false;
    }
    return;
  }

  QRect photoInfoRect = currentPseudoSelection->getPhotoInfoRect();

  //if hand not shown but over hover over image then turn hand cursor on
  if( !handCursorShown && photoInfoRect.contains( e->x(), e->y() ) )
  {
    setCursor( QCursor( Qt::PointingHandCursor ) );
    handCursorShown = true;
    return;
  }

  //if hand cursor shown but nolonger over hover over image set cursor back to normal
  if( handCursorShown && !photoInfoRect.contains( e->x(), e->y() ) )
  {
    setCursor( QCursor( Qt::ArrowCursor ) );
    handCursorShown = false;
    return;
  }
}
void PhotosIconView::contentsMousePressEvent ( QMouseEvent *  e) [protected]

Definition at line 426 of file photosIconView.cpp.

References dragStartPos.

void PhotosIconView::contextMenuEvent ( QContextMenuEvent *  e) [protected]

Definition at line 313 of file photosIconView.cpp.

References IMAGE_PATH, rightClickedPhoto, setAlbumImage(), and setSubalbumImage().

{
  rightClickedPhoto = (PhotoPreviewWidget*) findItem( QPoint(e->x(), e->y()+contentsY()) );
  if(rightClickedPhoto == NULL)
    return;

  QPopupMenu contextMenu( this );

  contextMenu.insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/setAlbumImage.png") ),
                          tr("Set album image"), this, SLOT(setAlbumImage()) );

  contextMenu.insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/setSubalbumImage.png") ),
                          tr("Set collection image"), this, SLOT(setSubalbumImage()) );

  contextMenu.exec( QPoint(e->globalX(), e->globalY()) );
}
QDragObject * PhotosIconView::dragObject ( ) [protected]

!!!!!!!!!!!!!!!!!!!

!!!!!!!!!!!!!!!!!!!

Definition at line 76 of file photosIconView.cpp.

References dragIcon.

{
  //no item selected?
  if( !currentItem() )
    return 0;
  
  //create drag object
//  PhotoDrag *drag = new PhotoDrag( viewport() );
  QIconDrag *drag = new QIconDrag( viewport() );
  
  //use small icon to represent drag, does not cover up too much of the screen
  drag->setPixmap( *dragIcon );
  
  //TODO find out how we can add filenames and PREVENT them from being MOVED to new location
  //like whendropping photoson the desktop!!!
  //create stringlist of all selected photo filenames
  //QStringList filenames;
  //QIconViewItem* current = firstItem();
  //while(current != NULL)
  //{
  //  if(current->isSelected())
  //  { 
  //    filenames.append( ((PhotoPreviewWidget*)current)->getPhoto()->getImageFilename() ); 
  //  }
  //  
  //  current = current->nextItem();
  //}
  //  drag->setFileNames( filenames );

  return drag;
}
void PhotosIconView::drawBackground ( QPainter *  p,
const QRect &  r 
) [protected]

Definition at line 342 of file photosIconView.cpp.

References backgroundImage.

{
  QBrush brush;
  brush.setPixmap( *backgroundImage );
  p->fillRect( r, brush );
}
void PhotosIconView::drawContents ( QPainter *  p,
int  clipx,
int  clipy,
int  clipw,
int  cliph 
) [protected]

Definition at line 349 of file photosIconView.cpp.

References bufferPixmap.

{
    if( bufferPixmap.size() != size())
    {  bufferPixmap.resize( size() ); }
    QPainter bufferPainter( &bufferPixmap, viewport() );
    int xOffset = clipx - contentsX();
    int yOffset = clipy - contentsY();

    bufferPainter.translate( -contentsX(), -contentsY() );
    QIconView::drawContents( &bufferPainter, clipx, clipy, clipw, cliph );
    bitBlt(p->device(), xOffset, yOffset, &bufferPixmap, xOffset, yOffset, clipw, cliph );
}
void PhotosIconView::editSelectedPhoto ( ) [signal]

Referenced by keyPressEvent().

bool PhotosIconView::findNearestUnselectedPhoto ( const QPoint &  pos,
QIconViewItem **  nearestItem,
bool &  posIsleftOfItem 
) [private]

Definition at line 110 of file photosIconView.cpp.

References width.

Referenced by contentsDropEvent().

{
  //if there are no items we can't find one now can we?
  if ( firstItem() == NULL )
    return false;
  
  //------------------------------------------------
  //first see if there is an unselected photo here
  QIconViewItem* item = firstItem();
  while(item != NULL)
  {
    if( !item->isSelected() && item->contains(pos) )
    {
      (*nearestItem) = item;
      posIsleftOfItem = pos.x() < item->x() + (item->width()/2);
      return true;
    }
    
    item = item->nextItem();
  }
  //------------------------------------------------
  //see if drop occurred below the last unselected photo
  
  //find last unselected photo
  item = lastItem();
  while( item != NULL && item->isSelected() )
  { item = item->prevItem(); }
    
  //is point below last unselected photo?
  if( item != NULL && pos.y() > (item->y() + item->height()) )
  {
    (*nearestItem) = item;
    posIsleftOfItem = false;
    return true;
  }
  //------------------------------------------------
  //see if drop occurred above the first unselected photo
  
  //find first unselected photo
  item = firstItem();
  while( item != NULL && item->isSelected() )
  { item = item->nextItem(); }
  
  //is point below last unselected photo?
  if( item != NULL && pos.y() < item->y() )
  {
    (*nearestItem) = item;
    posIsleftOfItem = true;
    return true;
  }
  //------------------------------------------------
  //next try checking within this row, walk left first
  int x;
  for(x = pos.x()-1; x>=0; x--)
  {
    item = findItem( QPoint(x, pos.y()) );
    if( item == NULL || item->isSelected() ) continue;
    else
    {
      (*nearestItem) = item;
      posIsleftOfItem = false;
      return true;
    }
  }
  //walking left failed, try walking right
  for(x = pos.x()+1; x<width(); x++)
  {
    item = findItem( QPoint(x, pos.y()) );
    if( item == NULL || item->isSelected() ) continue;
    else
    {
      (*nearestItem) = item;
      posIsleftOfItem = true;
      return true;
    }
  }
  //------------------------------------------------ 
  //ok, no unselected item is at this point, to the left, to the right, and the point
  //is not above the first unselected photo or below the last unselected photo. the
  //only way this is possible is if the point is between two rows of photos in the margin.

  //while it's certain there are photos both above and below, it is possible 
  //either of the adjacent rows of photos only contain selected photos so searching 
  //a single row will not necessarily find the nearest photo.
  
  //however, we are guaranteed to find an unselected photo both above and below 
  //this point, somewhere, so only searching up or down is necessary. we'll search 
  //up and the first unselected photo we find we'll use as the nearst. All selects 
  //photos must come after (aka to the right of) this photo.
  int itemWidth  = firstItem()->width();
  int itemHeight = firstItem()->height();
  int y;
  for(y = pos.y()-(itemHeight/2); y >= 0; y-=(itemHeight/2) )
  {
    for(x = width(); x >= 0; x-=(itemWidth/2))
    {
      item = findItem( QPoint(x, y) );
      if( item == NULL || item->isSelected() ) { continue; }
      else
      {
        (*nearestItem) = item;
        posIsleftOfItem = false;
        return true;
      }
    }
  }
  //------------------------------------------------ 
  //unable to find nearest unselected item
  return false;
}
void PhotosIconView::itemHasMoved ( ) [signal]

Referenced by contentsDropEvent().

void PhotosIconView::keyPressEvent ( QKeyEvent *  e) [protected]

Definition at line 466 of file photosIconView.cpp.

References curPhotoDescEdit, editSelectedPhoto(), numSelected(), removeSelectedPhotos(), rotate270SelectedPhotos(), and rotate90SelectedPhotos().

{
  //next handle additional keys
  switch( e->key() )
  {
    //edit selected photo
    case Qt::Key_Enter:
    case Qt::Key_Return:
      //only edit photo if one is selected
      if(numSelected() == 1)
      {
        if( curPhotoDescEdit != NULL ) { delete curPhotoDescEdit; }

        PhotoPreviewWidget* ppw = (PhotoPreviewWidget*)currentItem();
        curPhotoDescEdit = new PhotoDescEdit( ppw, ((Window*)qApp->mainWidget())->getConfig()->getBool
                                              ( "layout", "animation" ) );
      }
      break;
    //delete - remove selected photos
    case Qt::Key_Delete:
      if(numSelected() > 0) emit removeSelectedPhotos();
      break;
    //ctrl + r - rotate photo right
    case Qt::Key_R:
      if( e->state() & Qt::ControlButton && numSelected() > 0)
        emit rotate90SelectedPhotos();
      break;
    //ctrl + l - rotate photo left
    case Qt::Key_L:
      if(e->state() & Qt::ControlButton && numSelected() > 0) 
        emit rotate270SelectedPhotos();
      break;
    //e - edit photo using editing interface
    case Qt::Key_E:
      if(e->state() & Qt::ControlButton && numSelected() >= 1) emit editSelectedPhoto();
      break;
    //allow base class to handle key event
    default:
      QIconView::keyPressEvent(e);
      break;
  }
}
int PhotosIconView::numSelected ( )

Definition at line 300 of file photosIconView.cpp.

Referenced by keyPressEvent(), SubalbumWidget::rotate270ImageAction(), and SubalbumWidget::rotate90ImageAction().

{
  int num = 0;
  QIconViewItem* current = firstItem();
  while(current != NULL)
  {
    if(current->isSelected())
      num++;
    current = current->nextItem();
  }
  return num;
}
void PhotosIconView::removeSelectedPhotos ( ) [signal]

Referenced by keyPressEvent().

void PhotosIconView::repaintGroup ( QIconViewItem pseudoSelection) [slot]

Definition at line 362 of file photosIconView.cpp.

References clearPseudoSelection(), currentPseudoSelection, and PhotoPreviewWidget::setMousedOver().

Referenced by PhotosIconView().

{
  //if old pseudo selection unselect it
  clearPseudoSelection();

  //paint new selection
  if(pseudoSelection != NULL)
  {
    currentPseudoSelection = (PhotoPreviewWidget*)pseudoSelection;
    currentPseudoSelection->setMousedOver(true);
    repaintItem(currentPseudoSelection);
  }
}
void PhotosIconView::rotate270SelectedPhotos ( ) [signal]

Referenced by keyPressEvent().

void PhotosIconView::rotate90SelectedPhotos ( ) [signal]

Referenced by keyPressEvent().

void PhotosIconView::setAlbumImage ( ) [private, slot]

Definition at line 330 of file photosIconView.cpp.

References PhotoPreviewWidget::getPhoto(), and rightClickedPhoto.

Referenced by contextMenuEvent().

{
  ((Window*)qApp->mainWidget())->getTitle()->setAlbumImage( rightClickedPhoto->getPhoto() );
  rightClickedPhoto = NULL;
}
void PhotosIconView::setSubalbumImage ( ) [private, slot]

Definition at line 336 of file photosIconView.cpp.

References PhotoPreviewWidget::getPhoto(), and rightClickedPhoto.

Referenced by contextMenuEvent().

{
  ((Window*)qApp->mainWidget())->getTitle()->setSubalbumImage( rightClickedPhoto->getPhoto() );
  rightClickedPhoto = NULL;
}

Member Data Documentation

QPixmap* PhotosIconView::backgroundImage [private]

Definition at line 72 of file photosIconView.h.

Referenced by drawBackground(), and PhotosIconView().

QPixmap PhotosIconView::bufferPixmap [private]

Definition at line 73 of file photosIconView.h.

Referenced by drawContents().

Definition at line 79 of file photosIconView.h.

Referenced by captureClick(), keyPressEvent(), and PhotosIconView().

QPixmap* PhotosIconView::dragIcon [private]

Definition at line 74 of file photosIconView.h.

Referenced by dragObject(), and PhotosIconView().

QPoint PhotosIconView::dragStartPos [private]

Definition at line 77 of file photosIconView.h.

Referenced by contentsMousePressEvent().

Definition at line 76 of file photosIconView.h.

Referenced by contentsMouseMoveEvent(), and PhotosIconView().

Definition at line 71 of file photosIconView.h.

Referenced by contextMenuEvent(), PhotosIconView(), setAlbumImage(), and setSubalbumImage().


The documentation for this class was generated from the following files: