PhotosIconView Class Reference

#include <photosIconView.h>

Inheritance diagram for PhotosIconView:

Inheritance graph
[legend]
Collaboration diagram for PhotosIconView:

Collaboration graph
[legend]

List of all members.


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.


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

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.

00046                                                 : QIconView( parent, "iconView", WNoAutoErase )
00047 {
00048   viewport()->setBackgroundMode( Qt::NoBackground );
00049 
00050   currentPseudoSelection = NULL;
00051   handCursorShown = false;
00052   
00053   curPhotoDescEdit = NULL;
00054 
00055   //by default no photo has been right clicked on
00056   rightClickedPhoto = NULL;
00057 
00058   //load background image
00059   backgroundImage = new QPixmap( QString(IMAGE_PATH)+"miscImages/backgroundImage.png" );
00060 
00061   //load drag icon
00062   dragIcon = new QPixmap( QString(IMAGE_PATH)+"miscImages/moveImage.png" );
00063 
00064   //connect mouse over events to paint pseudo selection in ligher blue
00065   connect( this, SIGNAL(onItem(QIconViewItem*)),
00066                 this, SLOT(repaintGroup(QIconViewItem*)) );
00067 
00068   //clear any pseudo selection when mouse moves off icons
00069   connect( this, SIGNAL(onViewport()),
00070                 this, SLOT(clearPseudoSelection()) );
00071 
00072   connect( this, SIGNAL(pressed( QIconViewItem*, const QPoint& )),
00073                  this, SLOT(captureClick(QIconViewItem*, const QPoint&)) );
00074 }


Member Function Documentation

int PhotosIconView::numSelected (  ) 

Definition at line 300 of file photosIconView.cpp.

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

00301 {
00302   int num = 0;
00303   QIconViewItem* current = firstItem();
00304   while(current != NULL)
00305   {
00306     if(current->isSelected())
00307       num++;
00308     current = current->nextItem();
00309   }
00310   return num;
00311 }

void PhotosIconView::clearPseudoSelection (  )  [slot]

Definition at line 376 of file photosIconView.cpp.

References currentPseudoSelection, and PhotoPreviewWidget::setMousedOver().

Referenced by PhotosIconView(), and repaintGroup().

00377 {
00378   //check to make sure mouse is still off item. when a user expands an image to edit
00379   //it's description, the selection is cleard (since hte mouse is over a new window). however,
00380   //when that window disappears repaintGroup never got recalled (if the mouse was still on the original window),
00381   //so just ignore the original clear (it was invalid anyways right?)
00382  if( findItem( viewport()->mapFromGlobal( QCursor::pos() )+=QPoint( contentsX(), contentsY() )  ) == currentPseudoSelection )
00383    return;
00384 
00385   //if old pseudo selection unselect it
00386   if(currentPseudoSelection != NULL)
00387   {
00388     currentPseudoSelection->setMousedOver(false);
00389     repaintItem(currentPseudoSelection);
00390     currentPseudoSelection = NULL;
00391   }
00392 }

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

Definition at line 362 of file photosIconView.cpp.

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

Referenced by PhotosIconView().

00363 {
00364   //if old pseudo selection unselect it
00365   clearPseudoSelection();
00366 
00367   //paint new selection
00368   if(pseudoSelection != NULL)
00369   {
00370     currentPseudoSelection = (PhotoPreviewWidget*)pseudoSelection;
00371     currentPseudoSelection->setMousedOver(true);
00372     repaintItem(currentPseudoSelection);
00373   }
00374 }

void PhotosIconView::itemHasMoved (  )  [signal]

Referenced by contentsDropEvent().

void PhotosIconView::addPhotos ( QStringList   )  [signal]

Referenced by contentsDropEvent().

void PhotosIconView::removeSelectedPhotos (  )  [signal]

Referenced by keyPressEvent().

void PhotosIconView::rotate90SelectedPhotos (  )  [signal]

Referenced by keyPressEvent().

void PhotosIconView::rotate270SelectedPhotos (  )  [signal]

Referenced by keyPressEvent().

void PhotosIconView::editSelectedPhoto (  )  [signal]

Referenced by keyPressEvent().

QDragObject * PhotosIconView::dragObject (  )  [protected]

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

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

Definition at line 76 of file photosIconView.cpp.

References dragIcon.

00077 {
00078   //no item selected?
00079   if( !currentItem() )
00080     return 0;
00081   
00082   //create drag object
00083 //  PhotoDrag *drag = new PhotoDrag( viewport() );
00084   QIconDrag *drag = new QIconDrag( viewport() );
00085   
00086   //use small icon to represent drag, does not cover up too much of the screen
00087   drag->setPixmap( *dragIcon );
00088   
00090   //TODO find out how we can add filenames and PREVENT them from being MOVED to new location
00091   //like whendropping photoson the desktop!!!
00092   //create stringlist of all selected photo filenames
00093   //QStringList filenames;
00094   //QIconViewItem* current = firstItem();
00095   //while(current != NULL)
00096   //{
00097   //  if(current->isSelected())
00098   //  { 
00099   //    filenames.append( ((PhotoPreviewWidget*)current)->getPhoto()->getImageFilename() ); 
00100   //  }
00101   //  
00102   //  current = current->nextItem();
00103   //}
00104   //  drag->setFileNames( filenames );
00106 
00107   return drag;
00108 }

void PhotosIconView::drawContents ( QPainter *  p,
int  clipx,
int  clipy,
int  clipw,
int  cliph 
) [protected]

Definition at line 349 of file photosIconView.cpp.

References bufferPixmap.

00350 {
00351     if( bufferPixmap.size() != size())
00352     {  bufferPixmap.resize( size() ); }
00353     QPainter bufferPainter( &bufferPixmap, viewport() );
00354     int xOffset = clipx - contentsX();
00355     int yOffset = clipy - contentsY();
00356 
00357     bufferPainter.translate( -contentsX(), -contentsY() );
00358     QIconView::drawContents( &bufferPainter, clipx, clipy, clipw, cliph );
00359     bitBlt(p->device(), xOffset, yOffset, &bufferPixmap, xOffset, yOffset, clipw, cliph );
00360 }

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

Definition at line 342 of file photosIconView.cpp.

References backgroundImage.

00343 {
00344   QBrush brush;
00345   brush.setPixmap( *backgroundImage );
00346   p->fillRect( r, brush );
00347 }

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

Definition at line 313 of file photosIconView.cpp.

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

00314 {
00315   rightClickedPhoto = (PhotoPreviewWidget*) findItem( QPoint(e->x(), e->y()+contentsY()) );
00316   if(rightClickedPhoto == NULL)
00317     return;
00318 
00319   QPopupMenu contextMenu( this );
00320 
00321   contextMenu.insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/setAlbumImage.png") ),
00322                           tr("Set album image"), this, SLOT(setAlbumImage()) );
00323 
00324   contextMenu.insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/setSubalbumImage.png") ),
00325                           tr("Set collection image"), this, SLOT(setSubalbumImage()) );
00326 
00327   contextMenu.exec( QPoint(e->globalX(), e->globalY()) );
00328 }

void PhotosIconView::contentsMouseMoveEvent ( QMouseEvent *  e  )  [protected]

Definition at line 432 of file photosIconView.cpp.

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

00433 {
00434   QIconView::contentsMouseMoveEvent( e );
00435 
00436   //if no item is under mouse then return
00437   if(currentPseudoSelection == NULL)
00438   {
00439     if(handCursorShown)
00440     {
00441       setCursor( QCursor( Qt::ArrowCursor ) );
00442       handCursorShown = false;
00443     }
00444     return;
00445   }
00446 
00447   QRect photoInfoRect = currentPseudoSelection->getPhotoInfoRect();
00448 
00449   //if hand not shown but over hover over image then turn hand cursor on
00450   if( !handCursorShown && photoInfoRect.contains( e->x(), e->y() ) )
00451   {
00452     setCursor( QCursor( Qt::PointingHandCursor ) );
00453     handCursorShown = true;
00454     return;
00455   }
00456 
00457   //if hand cursor shown but nolonger over hover over image set cursor back to normal
00458   if( handCursorShown && !photoInfoRect.contains( e->x(), e->y() ) )
00459   {
00460     setCursor( QCursor( Qt::ArrowCursor ) );
00461     handCursorShown = false;
00462     return;
00463   }
00464 }

void PhotosIconView::contentsMousePressEvent ( QMouseEvent *  e  )  [protected]

Definition at line 426 of file photosIconView.cpp.

References dragStartPos.

00427 {
00428   dragStartPos = e->pos();
00429   QIconView::contentsMousePressEvent( e );
00430 }

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

Definition at line 466 of file photosIconView.cpp.

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

00467 {
00468   //next handle additional keys
00469   switch( e->key() )
00470   {
00471     //edit selected photo
00472     case Qt::Key_Enter:
00473     case Qt::Key_Return:
00474       //only edit photo if one is selected
00475       if(numSelected() == 1)
00476       {
00477         if( curPhotoDescEdit != NULL ) { delete curPhotoDescEdit; }
00478 
00479         PhotoPreviewWidget* ppw = (PhotoPreviewWidget*)currentItem();
00480         curPhotoDescEdit = new PhotoDescEdit( ppw, ((Window*)qApp->mainWidget())->getConfig()->getBool
00481                                               ( "layout", "animation" ) );
00482       }
00483       break;
00484     //delete - remove selected photos
00485     case Qt::Key_Delete:
00486       if(numSelected() > 0) emit removeSelectedPhotos();
00487       break;
00488     //ctrl + r - rotate photo right
00489     case Qt::Key_R:
00490       if( e->state() & Qt::ControlButton && numSelected() > 0)
00491         emit rotate90SelectedPhotos();
00492       break;
00493     //ctrl + l - rotate photo left
00494     case Qt::Key_L:
00495       if(e->state() & Qt::ControlButton && numSelected() > 0) 
00496         emit rotate270SelectedPhotos();
00497       break;
00498     //e - edit photo using editing interface
00499     case Qt::Key_E:
00500       if(e->state() & Qt::ControlButton && numSelected() >= 1) emit editSelectedPhoto();
00501       break;
00502     //allow base class to handle key event
00503     default:
00504       QIconView::keyPressEvent(e);
00505       break;
00506   }
00507 }

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

Definition at line 330 of file photosIconView.cpp.

References PhotoPreviewWidget::getPhoto(), and rightClickedPhoto.

Referenced by contextMenuEvent().

00331 {
00332   ((Window*)qApp->mainWidget())->getTitle()->setAlbumImage( rightClickedPhoto->getPhoto() );
00333   rightClickedPhoto = NULL;
00334 }

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

Definition at line 336 of file photosIconView.cpp.

References PhotoPreviewWidget::getPhoto(), and rightClickedPhoto.

Referenced by contextMenuEvent().

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

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().

00395 {
00396   //if no item has been clicked then ignore
00397   if(item == NULL)
00398     return;
00399 
00400   //get info button rect
00401   QRect infoButtonRec = ((PhotoPreviewWidget*)item)->getPhotoInfoRect();
00402 
00403   //remove scroll offset
00404   infoButtonRec.moveBy( -contentsX(), -contentsY() );
00405 
00406   //convert to screen coordinates by shifting by offset of topleft of widget
00407   QPoint topLeft = mapToGlobal( QPoint(0,0) );
00408   infoButtonRec.moveBy( topLeft.x(), topLeft.y() );
00409 
00410   //if screen coordinates of mouse click are in rectangle then button pressed
00411   if( infoButtonRec.contains( point.x(), point.y() ) )
00412   {
00413     //make sure all events have been processed first. if were just
00414     //editing a differnt photo description it is first necessary to 
00415     //repaint before we start editing the next
00416     qApp->processEvents();
00417 
00418     if( curPhotoDescEdit != NULL ) { delete curPhotoDescEdit; }
00419 
00420     PhotoPreviewWidget* ppw = (PhotoPreviewWidget*)item;
00421     curPhotoDescEdit = new PhotoDescEdit( ppw,
00422         ((Window*)qApp->mainWidget())->getConfig()->getBool( "layout", "animation" ) );
00423   }
00424 }

void PhotosIconView::contentsDropEvent ( QDropEvent *  e  )  [private]

Definition at line 223 of file photosIconView.cpp.

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

00224 {
00225   QIconView::contentsDropEvent( e );
00226   
00227   //if item is from the viewport emit item moved signal
00228   if(e->source() == viewport() )
00229   { 
00230     //find nearest unselected item
00231     QIconViewItem* item; bool leftOf;
00232     if( !findNearestUnselectedPhoto( e->pos(), &item, leftOf ) )
00233     {
00234       //unable to find nearest item. this should be impossible
00235     //  cout << "ERROR! Failed to find nearest item!\n";
00236       emit itemHasMoved();
00237     }  
00238     
00239     //selected photos dropped on LEFT of nearest item
00240     if( leftOf )
00241     {
00242       //count number of items being moved
00243       int num=0;
00244       QIconViewItem* current = firstItem();
00245       while(current != NULL)
00246       {
00247         if(current->isSelected()) { num++; }
00248         current = current->nextItem();
00249       }
00250     
00251       //move items to their new locations
00252       int xpos = item->x() - num;
00253       current = firstItem();
00254       while(current != NULL)
00255       {
00256         if(current->isSelected())
00257         {
00258           current->move(xpos, item->y()); 
00259           xpos++;
00260         }
00261         current = current->nextItem();
00262       }
00263     }
00264     //selected phtos dropped on RIGHT of nearest item
00265     else
00266     {
00267       //move items to their new locations
00268       int xpos = item->x() + (item->width()/2) + 1;
00269       QIconViewItem* current = firstItem();
00270       while(current != NULL)
00271       {
00272         if(current->isSelected())
00273         {
00274           current->move(xpos, item->y());
00275           xpos++;
00276         }
00277         current = current->nextItem();
00278       }
00279     }
00280 
00281     //items have moved!
00282     emit itemHasMoved();
00283   }
00284   //else it's from off the viewport, if we can get filename then try adding photos being added to subalbum
00285   else
00286   {
00287     QStringList fileNames;
00288     if( QUriDrag::decodeLocalFiles( e, fileNames ) )
00289     {
00290       //for some reason the order in which we receive file names is entire illogical.
00291       //it does not appear to be based on filename, data, modified data, size, anything!
00292       //thus, before adding files, first sort by ascending filename
00293       fileNames.sort();
00294       emit addPhotos(fileNames);
00295     }
00296   }
00297   
00298 }

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

Definition at line 110 of file photosIconView.cpp.

References width.

Referenced by contentsDropEvent().

00113 {
00114   //if there are no items we can't find one now can we?
00115   if ( firstItem() == NULL )
00116     return false;
00117   
00118   //------------------------------------------------
00119   //first see if there is an unselected photo here
00120   QIconViewItem* item = firstItem();
00121   while(item != NULL)
00122   {
00123     if( !item->isSelected() && item->contains(pos) )
00124     {
00125       (*nearestItem) = item;
00126       posIsleftOfItem = pos.x() < item->x() + (item->width()/2);
00127       return true;
00128     }
00129     
00130     item = item->nextItem();
00131   }
00132   //------------------------------------------------
00133   //see if drop occurred below the last unselected photo
00134   
00135   //find last unselected photo
00136   item = lastItem();
00137   while( item != NULL && item->isSelected() )
00138   { item = item->prevItem(); }
00139     
00140   //is point below last unselected photo?
00141   if( item != NULL && pos.y() > (item->y() + item->height()) )
00142   {
00143     (*nearestItem) = item;
00144     posIsleftOfItem = false;
00145     return true;
00146   }
00147   //------------------------------------------------
00148   //see if drop occurred above the first unselected photo
00149   
00150   //find first unselected photo
00151   item = firstItem();
00152   while( item != NULL && item->isSelected() )
00153   { item = item->nextItem(); }
00154   
00155   //is point below last unselected photo?
00156   if( item != NULL && pos.y() < item->y() )
00157   {
00158     (*nearestItem) = item;
00159     posIsleftOfItem = true;
00160     return true;
00161   }
00162   //------------------------------------------------
00163   //next try checking within this row, walk left first
00164   int x;
00165   for(x = pos.x()-1; x>=0; x--)
00166   {
00167     item = findItem( QPoint(x, pos.y()) );
00168     if( item == NULL || item->isSelected() ) continue;
00169     else
00170     {
00171       (*nearestItem) = item;
00172       posIsleftOfItem = false;
00173       return true;
00174     }
00175   }
00176   //walking left failed, try walking right
00177   for(x = pos.x()+1; x<width(); x++)
00178   {
00179     item = findItem( QPoint(x, pos.y()) );
00180     if( item == NULL || item->isSelected() ) continue;
00181     else
00182     {
00183       (*nearestItem) = item;
00184       posIsleftOfItem = true;
00185       return true;
00186     }
00187   }
00188   //------------------------------------------------ 
00189   //ok, no unselected item is at this point, to the left, to the right, and the point
00190   //is not above the first unselected photo or below the last unselected photo. the
00191   //only way this is possible is if the point is between two rows of photos in the margin.
00192 
00193   //while it's certain there are photos both above and below, it is possible 
00194   //either of the adjacent rows of photos only contain selected photos so searching 
00195   //a single row will not necessarily find the nearest photo.
00196   
00197   //however, we are guaranteed to find an unselected photo both above and below 
00198   //this point, somewhere, so only searching up or down is necessary. we'll search 
00199   //up and the first unselected photo we find we'll use as the nearst. All selects 
00200   //photos must come after (aka to the right of) this photo.
00201   int itemWidth  = firstItem()->width();
00202   int itemHeight = firstItem()->height();
00203   int y;
00204   for(y = pos.y()-(itemHeight/2); y >= 0; y-=(itemHeight/2) )
00205   {
00206     for(x = width(); x >= 0; x-=(itemWidth/2))
00207     {
00208       item = findItem( QPoint(x, y) );
00209       if( item == NULL || item->isSelected() ) { continue; }
00210       else
00211       {
00212         (*nearestItem) = item;
00213         posIsleftOfItem = false;
00214         return true;
00215       }
00216     }
00217   }
00218   //------------------------------------------------ 
00219   //unable to find nearest unselected item
00220   return false;
00221 }


Member Data Documentation

Definition at line 71 of file photosIconView.h.

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

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().

QPixmap* PhotosIconView::dragIcon [private]

Definition at line 74 of file photosIconView.h.

Referenced by dragObject(), and PhotosIconView().

Definition at line 76 of file photosIconView.h.

Referenced by contentsMouseMoveEvent(), and PhotosIconView().

QPoint PhotosIconView::dragStartPos [private]

Definition at line 77 of file photosIconView.h.

Referenced by contentsMousePressEvent().

Definition at line 79 of file photosIconView.h.

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


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

Generated on Thu Jun 19 15:09:02 2008 for AlbumShaper by  doxygen 1.5.6