1 /* Copyright (C) 2003-2009 Jesper K. Pedersen <blackie@kde.org>
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public
5 License as published by the Free Software Foundation; either
6 version 2 of the License, or (at your option) any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; see the file COPYING. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
18 #include "KeyboardEventHandler.h"
21 #include "DB/CategoryCollection.h"
22 #include "ThumbnailWidget.h"
23 #include "MainWindow/DirtyIndicator.h"
24 #include "DB/ImageDB.h"
25 #include "ThumbnailModel.h"
27 ThumbnailView::KeyboardEventHandler::KeyboardEventHandler( ThumbnailFactory
* factory
)
28 : ThumbnailComponent( factory
),
29 _cellOnFirstShiftMovementKey(Cell::invalidCell())
34 void ThumbnailView::KeyboardEventHandler::keyPressEvent( QKeyEvent
* event
)
36 if ( event
->modifiers() == Qt::NoModifier
&& ( event
->key() >= Qt::Key_A
&& event
->key() <= Qt::Key_Z
) ) {
37 QString token
= event
->text().toUpper().left(1);
38 bool mustRemoveToken
= false;
41 IdSet selection
= model()->selectionSet();
42 for( IdSet::const_iterator it
= selection
.begin(); it
!= selection
.end(); ++it
) {
43 DB::ImageInfoPtr info
= (*it
).fetchInfo();
45 mustRemoveToken
= info
->hasCategoryInfo( QString::fromLatin1("Tokens"), token
);
49 if ( mustRemoveToken
)
50 info
->removeCategoryInfo( QString::fromLatin1("Tokens"), token
);
52 info
->addCategoryInfo( QString::fromLatin1("Tokens"), token
);
54 widget()->updateCell( *it
);
58 widget()->updateCellSize();
60 DB::ImageDB::instance()->categoryCollection()->categoryForName( QString::fromLatin1("Tokens") )->addItem( token
);
61 MainWindow::DirtyIndicator::markDirty();
62 } else if ( event
->modifiers() == Qt::NoModifier
&& ( event
->key() >= Qt::Key_0
&& event
->key() <= Qt::Key_5
) ) {
64 short rating
= event
->text().left(1).toShort(&ok
, 10);
66 IdSet selection
= model()->selectionSet();
67 for( IdSet::const_iterator it
= selection
.begin(); it
!= selection
.end(); ++it
) {
68 DB::ImageInfoPtr info
= (*it
).fetchInfo();
69 info
->setRating(rating
* 2);
71 MainWindow::DirtyIndicator::markDirty();
75 if ( isMovementKey( event
->key() ) )
76 keyboardMoveEvent( event
);
78 if ( event
->key() == Qt::Key_Return
)
81 if ( event
->key() == Qt::Key_Space
)
82 model()->toggleSelection( model()->currentItem() );
86 Handle key release event.
87 \return true if the event should propogate
89 bool ThumbnailView::KeyboardEventHandler::keyReleaseEvent( QKeyEvent
* event
)
91 if ( widget()->_wheelResizing
&& event
->key() == Qt::Key_Control
) {
92 widget()->_wheelResizing
= false;
93 widget()->repaintScreen();
94 return false; // Don't propogate the event - I'm not sure why.
97 if ( event
->key() == Qt::Key_Shift
)
98 _cellOnFirstShiftMovementKey
= Cell::invalidCell();
99 return true; // Do propogate the event
103 void ThumbnailView::KeyboardEventHandler::keyboardMoveEvent( QKeyEvent
* event
)
105 if ( !( event
->modifiers()& Qt::ShiftModifier
) && !( event
->modifiers() & Qt::ControlModifier
) ) {
106 model()->clearSelection();
109 // Decide the next keyboard focus cell
110 Cell
currentPos(0,0);
111 if ( !model()->currentItem().isNull() )
112 currentPos
= model()->positionForMediaId( model()->currentItem() );
114 // Update current position if it is outside view and we do not have any modifiers
115 // that is if we just scroll arround.
117 // Use case is following: There is a selected item which is not
118 // visible because user has scrolled by other means than the
119 // keyboard (scrollbar or mouse wheel). In that case if the user
120 // presses keyboard movement key, the selection is forgotten and
121 // instead a currently visible cell is selected. So no scrolling
122 // of the view will be done.
123 if ( !( event
->modifiers()& Qt::ShiftModifier
) && !( event
->modifiers() & Qt::ControlModifier
) ) {
124 if ( currentPos
.row() < widget()->firstVisibleRow( PartlyVisible
) )
125 currentPos
= Cell( widget()->firstVisibleRow( FullyVisible
), currentPos
.col() );
126 else if ( currentPos
.row() > widget()->lastVisibleRow( PartlyVisible
) )
127 currentPos
= Cell( widget()->lastVisibleRow( FullyVisible
), currentPos
.col() );
131 switch (event
->key() ) {
136 if ( newPos
.col() < 0 )
137 newPos
= Cell( newPos
.row()-1, widget()->numCols()-1 );
143 if ( newPos
.col() == widget()->numCols() )
144 newPos
= Cell( newPos
.row()+1, 0 );
148 newPos
= Cell( currentPos
.row()+1, currentPos
.col() );
152 newPos
= Cell( currentPos
.row()-1, currentPos
.col() );
155 case Qt::Key_PageDown
:
158 int rows
= (event
->key() == Qt::Key_PageDown
) ? 1 : -1;
159 if ( event
->modifiers() & (Qt::AltModifier
| Qt::MetaModifier
) )
160 rows
*= widget()->numRows() / 20;
162 rows
*= widget()->numRowsPerPage();
164 newPos
= Cell( currentPos
.row() + rows
, currentPos
.col() );
168 newPos
= Cell( 0, 0 );
172 newPos
= widget()->lastCell();
176 // Check for overruns
177 if ( newPos
> widget()->lastCell() )
178 newPos
= widget()->lastCell();
179 if ( newPos
< Cell(0,0) )
182 if ( event
->modifiers() & Qt::ShiftModifier
) {
183 if ( _cellOnFirstShiftMovementKey
== Cell::invalidCell() ) {
184 _cellOnFirstShiftMovementKey
= currentPos
;
185 _selectionOnFirstShiftMovementKey
= model()->selectionSet();
188 model()->setSelection( _selectionOnFirstShiftMovementKey
);
189 model()->selectRange( _cellOnFirstShiftMovementKey
, newPos
);
192 if ( ! (event
->modifiers() & Qt::ControlModifier
) ) {
193 model()->select( newPos
);
194 widget()->updateCell( currentPos
.row(), currentPos
.col() );
196 widget()->scrollToCell( newPos
);
199 bool ThumbnailView::KeyboardEventHandler::isMovementKey( int key
)
201 return ( key
== Qt::Key_Up
|| key
== Qt::Key_Down
|| key
== Qt::Key_Left
|| key
== Qt::Key_Right
||
202 key
== Qt::Key_Home
|| key
== Qt::Key_End
|| key
== Qt::Key_PageUp
|| key
== Qt::Key_PageDown
);