@ -287,74 +287,8 @@ public:
struct SortableItem {
struct SortableItem {
QIconViewItem * item ;
QIconViewItem * item ;
} ;
} ;
public :
/* finds the containers that intersect with \a searchRect in the direction \a dir relative to \a relativeTo */
QPtrList < ItemContainer > * findContainers (
QIconView : : Direction dir ,
const QPoint & relativeTo ,
const QRect & searchRect ) const ;
// friend int cmpIconViewItems( const void *n1, const void *n2 );
} ;
} ;
QPtrList < QIconViewPrivate : : ItemContainer > * QIconViewPrivate : : findContainers (
QIconView : : Direction dir ,
const QPoint & relativeTo ,
const QRect & searchRect ) const
{
QPtrList < QIconViewPrivate : : ItemContainer > * list =
new QPtrList < QIconViewPrivate : : ItemContainer > ( ) ;
if ( arrangement = = QIconView : : LeftToRight ) {
if ( dir = = QIconView : : DirLeft | | dir = = QIconView : : DirRight ) {
ItemContainer * c = firstContainer ;
for ( ; c ; c = c - > n )
if ( c - > rect . intersects ( searchRect ) )
list - > append ( c ) ;
} else {
if ( dir = = QIconView : : DirDown ) {
ItemContainer * c = firstContainer ;
for ( ; c ; c = c - > n )
if ( c - > rect . intersects ( searchRect ) & &
c - > rect . bottom ( ) > = relativeTo . y ( ) )
list - > append ( c ) ;
} else {
ItemContainer * c = lastContainer ;
for ( ; c ; c = c - > p )
if ( c - > rect . intersects ( searchRect ) & &
c - > rect . top ( ) < = relativeTo . y ( ) )
list - > append ( c ) ;
}
}
} else {
if ( dir = = QIconView : : DirUp | | dir = = QIconView : : DirDown ) {
ItemContainer * c = firstContainer ;
for ( ; c ; c = c - > n )
if ( c - > rect . intersects ( searchRect ) )
list - > append ( c ) ;
} else {
if ( dir = = QIconView : : DirRight ) {
ItemContainer * c = firstContainer ;
for ( ; c ; c = c - > n )
if ( c - > rect . intersects ( searchRect ) & &
c - > rect . right ( ) > = relativeTo . x ( ) )
list - > append ( c ) ;
} else {
ItemContainer * c = lastContainer ;
for ( ; c ; c = c - > p )
if ( c - > rect . intersects ( searchRect ) & &
c - > rect . left ( ) < = relativeTo . x ( ) )
list - > append ( c ) ;
}
}
}
return list ;
}
# if defined(Q_C_CALLBACKS)
# if defined(Q_C_CALLBACKS)
extern " C " {
extern " C " {
# endif
# endif
@ -2347,14 +2281,15 @@ void QIconViewItem::checkRect()
When an item is inserted the QIconView allocates a position for it .
When an item is inserted the QIconView allocates a position for it .
Existing items are rearranged if autoArrange ( ) is TRUE . The
Existing items are rearranged if autoArrange ( ) is TRUE . The
default arrangement is \ c LeftToRight - - the QIconView fills up
default arrangement is \ c LeftToRight - - the QIconView fills
the \ e left- most column from top to bottom , then moves one colum n
the \ e top- most row from left to right , then moves one row \ e dow n
\ e right and fills that from top to bottom and so on . The
and fills that row from left to right and so on . The
arrangement can be modified with any of the following approaches :
arrangement can be modified with any of the following approaches :
\ list
\ list
\ i Call setArrangement ( ) , e . g . with \ c TopToBottom which will fill
\ i Call setArrangement ( ) , e . g . with \ c TopToBottom which will fill up
the \ e top - most row from left to right , then moves one row \ e down
the \ e left - most column from top to bottom , then moves one column
and fills that row from left to right and so on .
\ e right and fills that from top to bottom and so on .
\ i Construct each QIconViewItem using a constructor which allows
\ i Construct each QIconViewItem using a constructor which allows
you to specify which item the new one is to follow .
you to specify which item the new one is to follow .
\ i Call setSorting ( ) or sort ( ) to sort the items .
\ i Call setSorting ( ) or sort ( ) to sort the items .
@ -5105,6 +5040,7 @@ void QIconView::keyPressEvent( QKeyEvent *e )
}
}
} break ;
} break ;
# endif
# endif
case Key_Home : {
case Key_Home : {
d - > currInputString = QString : : null ;
d - > currInputString = QString : : null ;
if ( ! d - > firstItem )
if ( ! d - > firstItem )
@ -5149,6 +5085,7 @@ void QIconView::keyPressEvent( QKeyEvent *e )
e - > state ( ) & ControlButton , TRUE ) ;
e - > state ( ) & ControlButton , TRUE ) ;
}
}
} break ;
} break ;
case Key_End : {
case Key_End : {
d - > currInputString = QString : : null ;
d - > currInputString = QString : : null ;
if ( ! d - > lastItem )
if ( ! d - > lastItem )
@ -5192,102 +5129,73 @@ void QIconView::keyPressEvent( QKeyEvent *e )
e - > state ( ) & ControlButton , TRUE ) ;
e - > state ( ) & ControlButton , TRUE ) ;
}
}
} break ;
} break ;
case Key_Right : {
case Key_Space : {
d - > currInputString = QString : : null ;
d - > currInputString = QString : : null ;
QIconViewItem * item ;
if ( d - > selectionMode = = Single )
selectCurrent = FALSE ;
break ;
Direction dir = DirRight ;
QRect r ( 0 , d- > currentItem - > y( ) , contentsWidth ( ) , d - > currentItem - > height ( ) ) ;
d- > currentItem - > setSelected( ! d - > currentItem - > isSelected ( ) , TRUE ) ;
item = findItem ( dir , d - > currentItem - > rect ( ) . center ( ) , r ) ;
} break ;
// search the row below from the right
case Key_Enter :
while ( ! item & & r . y ( ) < contentsHeight ( ) ) {
case Key_Return :
r . moveBy ( 0 , d - > currentItem - > height ( ) ) ;
d - > currInputString = QString : : null ;
item = findItem ( dir , QPoint ( 0 , r . center ( ) . y ( ) ) , r ) ;
emit returnPressed ( d - > currentItem ) ;
}
break ;
if ( item ) {
case Key_Right : {
QIconViewItem * old = d - > currentItem ;
d - > currInputString = QString : : null ;
setCurrentItem ( item ) ;
selectCurrent = FALSE ;
ensureItemVisible ( item ) ;
Direction dir = DirRight ;
handleItemChange ( old , e - > state ( ) & ShiftButton , e - > state ( ) & ControlButton ) ;
QIconViewItem * item = findItem ( dir , d - > currentItem ) ;
if ( item ) {
QIconViewItem * old = d - > currentItem ;
setCurrentItem ( item ) ;
ensureItemVisible ( item ) ;
handleItemChange ( old , e - > state ( ) & ShiftButton , e - > state ( ) & ControlButton ) ;
}
}
} break ;
} break ;
case Key_Left : {
case Key_Left : {
d - > currInputString = QString : : null ;
d - > currInputString = QString : : null ;
QIconViewItem * item ;
selectCurrent = FALSE ;
selectCurrent = FALSE ;
Direction dir = DirLeft ;
Direction dir = DirLeft ;
QIconViewItem * item = findItem ( dir , d - > currentItem ) ;
QRect r ( 0 , d - > currentItem - > y ( ) , contentsWidth ( ) , d - > currentItem - > height ( ) ) ;
if ( item ) {
item = findItem ( dir , d - > currentItem - > rect ( ) . center ( ) , r ) ;
QIconViewItem * old = d - > currentItem ;
setCurrentItem ( item ) ;
// search the row above from the left
ensureItemVisible ( item ) ;
while ( ! item & & r . y ( ) > = 0 ) {
handleItemChange ( old , e - > state ( ) & ShiftButton , e - > state ( ) & ControlButton ) ;
r . moveBy ( 0 , - d - > currentItem - > height ( ) ) ;
item = findItem ( dir , QPoint ( contentsWidth ( ) , r . center ( ) . y ( ) ) , r ) ;
}
if ( item ) {
QIconViewItem * old = d - > currentItem ;
setCurrentItem ( item ) ;
ensureItemVisible ( item ) ;
handleItemChange ( old , e - > state ( ) & ShiftButton , e - > state ( ) & ControlButton ) ;
}
}
} break ;
} break ;
case Key_Space : {
d - > currInputString = QString : : null ;
if ( d - > selectionMode = = Single )
break ;
d - > currentItem - > setSelected ( ! d - > currentItem - > isSelected ( ) , TRUE ) ;
} break ;
case Key_Enter : case Key_Return :
d - > currInputString = QString : : null ;
emit returnPressed ( d - > currentItem ) ;
break ;
case Key_Down : {
case Key_Down : {
d - > currInputString = QString : : null ;
d - > currInputString = QString : : null ;
QIconViewItem * item ;
selectCurrent = FALSE ;
selectCurrent = FALSE ;
Direction dir = DirDown ;
Direction dir = DirDown ;
QIconViewItem * item = findItem ( dir , d - > currentItem ) ;
QRect r ( d - > currentItem - > x ( ) , 0 , d - > currentItem - > width ( ) , contentsHeight ( ) ) ;
if ( item ) {
item = findItem ( dir , d - > currentItem - > rect ( ) . center ( ) , r ) ;
QIconViewItem * old = d - > currentItem ;
setCurrentItem ( item ) ;
// finding the closest item below and to the right
ensureItemVisible ( item ) ;
while ( ! item & & r . x ( ) < contentsWidth ( ) ) {
handleItemChange ( old , e - > state ( ) & ShiftButton , e - > state ( ) & ControlButton ) ;
r . moveBy ( r . width ( ) , 0 ) ;
item = findItem ( dir , QPoint ( r . center ( ) . x ( ) , 0 ) , r ) ;
}
}
QIconViewItem * i = d - > currentItem ;
setCurrentItem ( item ) ;
item = i ;
handleItemChange ( item , e - > state ( ) & ShiftButton , e - > state ( ) & ControlButton ) ;
} break ;
} break ;
case Key_Up : {
case Key_Up : {
d - > currInputString = QString : : null ;
d - > currInputString = QString : : null ;
QIconViewItem * item ;
selectCurrent = FALSE ;
selectCurrent = FALSE ;
Direction dir = DirUp ;
Direction dir = DirUp ;
QIconViewItem * item = findItem ( dir , d - > currentItem ) ;
QRect r ( d - > currentItem - > x ( ) , 0 , d - > currentItem - > width ( ) , contentsHeight ( ) ) ;
if ( item ) {
item = findItem ( dir , d - > currentItem - > rect ( ) . center ( ) , r ) ;
QIconViewItem * old = d - > currentItem ;
setCurrentItem ( item ) ;
// finding the closest item above and to the left
ensureItemVisible ( item ) ;
while ( ! item & & r . x ( ) > = 0 ) {
handleItemChange ( old , e - > state ( ) & ShiftButton , e - > state ( ) & ControlButton ) ;
r . moveBy ( - r . width ( ) , 0 ) ;
item = findItem ( dir , QPoint ( r . center ( ) . x ( ) , contentsHeight ( ) ) , r ) ;
}
}
QIconViewItem * i = d - > currentItem ;
setCurrentItem ( item ) ;
item = i ;
handleItemChange ( item , e - > state ( ) & ShiftButton , e - > state ( ) & ControlButton ) ;
} break ;
} break ;
case Key_Next : {
case Key_Next : {
d - > currInputString = QString : : null ;
d - > currInputString = QString : : null ;
selectCurrent = FALSE ;
selectCurrent = FALSE ;
@ -5310,6 +5218,7 @@ void QIconView::keyPressEvent( QKeyEvent *e )
handleItemChange ( item , e - > state ( ) & ShiftButton , e - > state ( ) & ControlButton ) ;
handleItemChange ( item , e - > state ( ) & ShiftButton , e - > state ( ) & ControlButton ) ;
}
}
} break ;
} break ;
case Key_Prior : {
case Key_Prior : {
d - > currInputString = QString : : null ;
d - > currInputString = QString : : null ;
selectCurrent = FALSE ;
selectCurrent = FALSE ;
@ -5332,6 +5241,7 @@ void QIconView::keyPressEvent( QKeyEvent *e )
handleItemChange ( item , e - > state ( ) & ShiftButton , e - > state ( ) & ControlButton ) ;
handleItemChange ( item , e - > state ( ) & ShiftButton , e - > state ( ) & ControlButton ) ;
}
}
} break ;
} break ;
default :
default :
if ( ! e - > text ( ) . isEmpty ( ) & & e - > text ( ) [ 0 ] . isPrint ( ) ) {
if ( ! e - > text ( ) . isEmpty ( ) & & e - > text ( ) [ 0 ] . isPrint ( ) ) {
selectCurrent = FALSE ;
selectCurrent = FALSE ;
@ -5402,79 +5312,193 @@ void QIconView::keyPressEvent( QKeyEvent *e )
}
}
/*
/*
Finds the closest item in the Direction \ a dir relative from the point \ a relativeTo
Finds the closest item in the direction \ a dir starting from the specified \ a fromItem .
which intersects with the searchRect .
If the arrangement is LeftToRight ( icon view mode ) : use ( center , top ) as item reference
If the arrangement is TopToBottom ( multicolumn view mode ) : use ( left , top ) as item reference
Th e function choses the closest item with its center in the searchRect .
Th is is to allow for smooth scrolling when using the keyboard arrow keys .
*/
*/
QIconViewItem * QIconView : : findItem ( Direction dir ,
QIconViewItem * QIconView : : findItem ( Direction dir , const QIconViewItem * fromItem ) const
const QPoint & relativeTo ,
const QRect & searchRect ) const
{
{
QIconViewItem * item ;
QIconViewItem * closestItem = NULL ;
QIconViewItem * centerMatch = 0 ;
int distPri = 0 , distSec = 0 ;
int centerMatchML = 0 ;
int itemDistancePri = 0 , itemDistanceSec = 0 ;
// gets list of containers with potential items
QPoint pos = fromItem - > rect ( ) . topLeft ( ) ;
QPtrList < QIconViewPrivate : : ItemContainer > * cList =
if ( d - > arrangement = = LeftToRight ) {
d - > findContainers ( dir , relativeTo , searchRect ) ;
pos . setX ( fromItem - > rect ( ) . center ( ) . x ( ) ) ;
cList - > first ( ) ;
while ( cList - > current ( ) & & ! centerMatch ) {
QPtrList < QIconViewItem > & list = ( cList - > current ( ) ) - > items ;
for ( item = list . first ( ) ; item ; item = list . next ( ) ) {
if ( neighbourItem ( dir , relativeTo , item ) & &
searchRect . contains ( item - > rect ( ) . center ( ) ) & &
item ! = currentItem ( ) ) {
int ml = ( relativeTo - item - > rect ( ) . center ( ) ) . manhattanLength ( ) ;
if ( centerMatch ) {
if ( ml < centerMatchML ) {
centerMatch = item ;
centerMatchML = ml ;
}
}
} else {
centerMatch = item ;
QRect searchRect ;
centerMatchML = ml ;
switch ( dir ) {
case DirDown :
searchRect . setCoords ( pos . x ( ) , 0 , contentsWidth ( ) , contentsHeight ( ) ) ;
break ;
case DirUp :
searchRect . setCoords ( 0 , 0 , pos . x ( ) , contentsHeight ( ) ) ;
break ;
case DirRight :
searchRect . setCoords ( 0 , pos . y ( ) , contentsWidth ( ) , contentsHeight ( ) ) ;
break ;
case DirLeft :
searchRect . setCoords ( 0 , 0 , contentsWidth ( ) , pos . y ( ) ) ;
break ;
}
}
for ( QIconViewPrivate : : ItemContainer * c = d - > firstContainer ; c ; c = c - > n ) {
if ( c - > rect . intersects ( searchRect ) ) {
QPtrList < QIconViewItem > & list = c - > items ;
for ( QIconViewItem * item = list . first ( ) ; item ; item = list . next ( ) ) {
if ( item ! = fromItem ) {
bool itemOK = true ;
const QRect & ir = item - > rect ( ) ;
// DirDown/DirUp : primary distance X, secondary distance Y
// DirLeft/DirRight: primary distance Y, secondary distance X
if ( d - > arrangement = = LeftToRight ) {
// Left to right arrangement (icon view mode): use (center, top) as item reference
switch ( dir ) {
case DirDown :
if ( ir . center ( ) . x ( ) > pos . x ( ) ) {
distPri = ir . center ( ) . x ( ) - pos . x ( ) ;
distSec = ir . top ( ) ;
}
}
else if ( ir . center ( ) . x ( ) = = pos . x ( ) & & ir . top ( ) > pos . y ( ) ) {
distPri = 0 ;
distSec = ir . top ( ) - pos . y ( ) ;
}
}
cList - > next ( ) ;
else {
itemOK = false ;
}
}
delete cList ;
break ;
return centerMatch ;
}
/*
Returns TRUE if the items orientation compared to
the point \ a relativeTo is correct .
*/
bool QIconView : : neighbourItem ( Direction dir ,
const QPoint & relativeTo ,
const QIconViewItem * item ) const
{
switch ( dir ) {
case DirUp :
case DirUp :
if ( item - > rect ( ) . center ( ) . y ( ) < relativeTo . y ( ) )
if ( ir . center ( ) . x ( ) < pos . x ( ) ) {
return TRUE ;
distPri = pos . x ( ) - ir . center ( ) . x ( ) ;
distSec = contentsHeight ( ) - ir . top ( ) ;
}
else if ( ir . center ( ) . x ( ) = = pos . x ( ) & & ir . top ( ) < pos . y ( ) ) {
distPri = 0 ;
distSec = pos . y ( ) - ir . top ( ) ;
}
else {
itemOK = false ;
}
break ;
break ;
case DirDown :
if ( item - > rect ( ) . center ( ) . y ( ) > relativeTo . y ( ) )
case DirRight :
return TRUE ;
if ( ir . top ( ) > pos . y ( ) ) {
distPri = ir . top ( ) - pos . y ( ) ;
distSec = ir . center ( ) . x ( ) ;
}
else if ( ir . top ( ) = = pos . y ( ) & & ir . center ( ) . x ( ) > pos . x ( ) ) {
distPri = 0 ;
distSec = ir . center ( ) . x ( ) - pos . x ( ) ;
}
else {
itemOK = false ;
}
break ;
break ;
case DirLeft :
case DirLeft :
if ( item - > rect ( ) . center ( ) . x ( ) < relativeTo . x ( ) )
if ( ir . top ( ) < pos . y ( ) ) {
return TRUE ;
distPri = pos . y ( ) - ir . top ( ) ;
distSec = contentsWidth ( ) - ir . center ( ) . x ( ) ;
}
else if ( ir . top ( ) = = pos . y ( ) & & ir . center ( ) . x ( ) < pos . x ( ) ) {
distPri = 0 ;
distSec = pos . x ( ) - ir . center ( ) . x ( ) ;
}
else {
itemOK = false ;
}
break ;
default :
itemOK = false ;
break ;
}
}
else {
// Top to bottom arrangement (multicolumn view mode): use (left, top) as item reference
switch ( dir ) {
case DirDown :
if ( ir . left ( ) > pos . x ( ) ) {
distPri = ir . left ( ) - pos . x ( ) ;
distSec = ir . top ( ) ;
}
else if ( ir . left ( ) = = pos . x ( ) & & ir . top ( ) > pos . y ( ) ) {
distPri = 0 ;
distSec = ir . top ( ) - pos . y ( ) ;
}
else {
itemOK = false ;
}
break ;
break ;
case DirUp :
if ( ir . left ( ) < pos . x ( ) ) {
distPri = pos . x ( ) - ir . left ( ) ;
distSec = contentsHeight ( ) - ir . top ( ) ;
}
else if ( ir . left ( ) = = pos . x ( ) & & ir . top ( ) < pos . y ( ) ) {
distPri = 0 ;
distSec = pos . y ( ) - ir . top ( ) ;
}
else {
itemOK = false ;
}
break ;
case DirRight :
case DirRight :
if ( item - > rect ( ) . center ( ) . x ( ) > relativeTo . x ( ) )
if ( ir . top ( ) > pos . y ( ) ) {
return TRUE ;
distPri = ir . top ( ) - pos . y ( ) ;
distSec = ir . left ( ) ;
}
else if ( ir . top ( ) = = pos . y ( ) & & ir . left ( ) > pos . x ( ) ) {
distPri = 0 ;
distSec = ir . left ( ) - pos . x ( ) ;
}
else {
itemOK = false ;
}
break ;
case DirLeft :
if ( ir . top ( ) < pos . y ( ) ) {
distPri = pos . y ( ) - ir . top ( ) ;
distSec = contentsWidth ( ) - ir . left ( ) ;
}
else if ( ir . top ( ) = = pos . y ( ) & & ir . left ( ) < pos . x ( ) ) {
distPri = 0 ;
distSec = pos . x ( ) - ir . left ( ) ;
}
else {
itemOK = false ;
}
break ;
break ;
default :
default :
// nothing
itemOK = false ;
break ;
break ;
}
}
return FALSE ;
}
if ( itemOK ) {
if ( ! closestItem | |
( ( distPri < itemDistancePri ) | |
( distPri = = itemDistancePri & & distSec < itemDistanceSec ) ) ) {
closestItem = item ;
itemDistancePri = distPri ;
itemDistanceSec = distSec ;
}
}
}
}
}
}
return closestItem ;
}
}
/*!
/*!
@ -6040,7 +6064,7 @@ QIconViewItem *QIconView::makeRowLayout( QIconViewItem *begin, int &y, bool &cha
}
}
} else { // -------------------------------- SOUTH ------------------------------
} else { // -------------------------------- TopToBottom ------------------------------
int x = y ;
int x = y ;
@ -6075,6 +6099,7 @@ QIconViewItem *QIconView::makeRowLayout( QIconViewItem *begin, int &y, bool &cha
// now move the items
// now move the items
item = begin ;
item = begin ;
QIconViewItem * prevVisibleItem = NULL ;
for ( ; ; ) {
for ( ; ; ) {
item - > dirty = FALSE ;
item - > dirty = FALSE ;
if ( d - > itemTextPos = = Bottom ) {
if ( d - > itemTextPos = = Bottom ) {
@ -6082,15 +6107,16 @@ QIconViewItem *QIconView::makeRowLayout( QIconViewItem *begin, int &y, bool &cha
changed = item - > move ( x + ( w - item - > width ( ) ) / 2 , d - > spacing ) | | changed ;
changed = item - > move ( x + ( w - item - > width ( ) ) / 2 , d - > spacing ) | | changed ;
else
else
changed = item - > move ( x + ( w - item - > width ( ) ) / 2 ,
changed = item - > move ( x + ( w - item - > width ( ) ) / 2 ,
item- > prev - > y ( ) + item- > prev - > height ( ) + d - > spacing ) | | changed ;
prevV isibleI tem- > y ( ) + prevV isibleI tem- > height ( ) + d - > spacing ) | | changed ;
} else {
} else {
if ( item = = begin )
if ( item = = begin )
changed = item - > move ( x , d - > spacing ) | | changed ;
changed = item - > move ( x , d - > spacing ) | | changed ;
else
else
changed = item - > move ( x , item- > prev - > y ( ) + item- > prev - > height ( ) + d - > spacing ) | | changed ;
changed = item - > move ( x , prevV isibleI tem- > y ( ) + prevV isibleI tem- > height ( ) + d - > spacing ) | | changed ;
}
}
if ( item = = end )
if ( item = = end )
break ;
break ;
prevVisibleItem = item ;
item = item - > next ;
item = item - > next ;
while ( item & & ( item - > isVisible ( ) = = FALSE ) ) {
while ( item & & ( item - > isVisible ( ) = = FALSE ) ) {
item = item - > next ;
item = item - > next ;