Krazy/EBN: changes for null strings
[kphotoalbum.git] / ThumbnailView / KeyboardEventHandler.cpp
blob22f4779895029818351046a9f4043f44ca76bdf6
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"
19 #include "Cell.h"
20 #include "enums.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;
39 bool hadHit = false;
41 IdSet selection = model()->selectionSet();
42 for( IdSet::const_iterator it = selection.begin(); it != selection.end(); ++it ) {
43 DB::ImageInfoPtr info = (*it).fetchInfo();
44 if ( ! hadHit ) {
45 mustRemoveToken = info->hasCategoryInfo( QString::fromLatin1("Tokens"), token );
46 hadHit = true;
49 if ( mustRemoveToken )
50 info->removeCategoryInfo( QString::fromLatin1("Tokens"), token );
51 else
52 info->addCategoryInfo( QString::fromLatin1("Tokens"), token );
54 widget()->updateCell( *it );
57 if ( hadHit )
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 ) ) {
63 bool ok;
64 short rating = event->text().left(1).toShort(&ok, 10);
65 if (ok) {
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 )
79 emit showSelection();
81 if ( event->key() == Qt::Key_Space )
82 model()->toggleSelection( model()->currentItem() );
85 /**
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.
96 else {
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() );
130 Cell newPos;
131 switch (event->key() ) {
132 case Qt::Key_Left:
133 newPos = currentPos;
134 newPos.col()--;
136 if ( newPos.col() < 0 )
137 newPos = Cell( newPos.row()-1, widget()->numCols()-1 );
138 break;
140 case Qt::Key_Right:
141 newPos = currentPos;
142 newPos.col()++;
143 if ( newPos.col() == widget()->numCols() )
144 newPos = Cell( newPos.row()+1, 0 );
145 break;
147 case Qt::Key_Down:
148 newPos = Cell( currentPos.row()+1, currentPos.col() );
149 break;
151 case Qt::Key_Up:
152 newPos = Cell( currentPos.row()-1, currentPos.col() );
153 break;
155 case Qt::Key_PageDown:
156 case Qt::Key_PageUp:
158 int rows = (event->key() == Qt::Key_PageDown) ? 1 : -1;
159 if ( event->modifiers() & (Qt::AltModifier | Qt::MetaModifier) )
160 rows *= widget()->numRows() / 20;
161 else
162 rows *= widget()->numRowsPerPage();
164 newPos = Cell( currentPos.row() + rows, currentPos.col() );
165 break;
167 case Qt::Key_Home:
168 newPos = Cell( 0, 0 );
169 break;
171 case Qt::Key_End:
172 newPos = widget()->lastCell();
173 break;
176 // Check for overruns
177 if ( newPos > widget()->lastCell() )
178 newPos = widget()->lastCell();
179 if ( newPos < Cell(0,0) )
180 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 );