-rw-r--r-- | libopie2/opieui/okeyconfigwidget.cpp | 242 | ||||
-rw-r--r-- | libopie2/opieui/okeyconfigwidget.h | 11 | ||||
-rw-r--r-- | libopie2/opieui/okeyconfigwidget_p.h | 33 |
3 files changed, 216 insertions, 70 deletions
diff --git a/libopie2/opieui/okeyconfigwidget.cpp b/libopie2/opieui/okeyconfigwidget.cpp index 41be1be..3e08416 100644 --- a/libopie2/opieui/okeyconfigwidget.cpp +++ b/libopie2/opieui/okeyconfigwidget.cpp @@ -1,29 +1,31 @@ #include "okeyconfigwidget.h" +#include "okeyconfigwidget_p.h" -#include <opie2/olistview.h> #include <qgroupbox.h> #include <qradiobutton.h> #include <qpushbutton.h> #include <qbuttongroup.h> #include <qaccel.h> #include <qlayout.h> #include <qlabel.h> +#include <qtimer.h> using namespace Opie::Ui; + /** * The default Constructor of a OKeyPair. * A Key and a Modifier ( Alt/Shift/Ctrl ) * needs to be supplied. * Use Qt::Key for the information. * The default arguments create an Empty OKeyPair. If you * want to get an empty OKeyPair use the static method for getting * the emptyKey() * * @see OKeyPair OKeyPair::emptyKey() */ OKeyPair::OKeyPair( int key, int mod ) @@ -530,46 +532,26 @@ void OKeyConfigManager::save() { * cofigure two keys. * * Make sure you call e->ignore if you don't want to handle this event */ OKeyConfigItem OKeyConfigManager::handleKeyEvent( QKeyEvent* e ) { /* * Fix Up issues with Qt/E, my keybard, and virtual input * methods * First my Keyboard delivers 256,512,1024 for shift/ctrl/alt instead of the button state * Also key() on virtual inputmethods are zero and only ascii. We need to fix upper and lower * case ascii */ - int key = e->key(); - int mod = e->state(); - -/* - * virtual keyboard - * else change the button mod only - */ - if ( key == 0 ) { - key = e->ascii(); - if ( key > 96 && key < 123) - key -= 32; - }else{ - int new_mod = 0; - if ( mod & 256 ) - new_mod |= Qt::ShiftButton; - else if ( mod & 512 ) - new_mod |= Qt::ControlButton; - else if ( mod & 1024 ) - new_mod |= Qt::AltButton; - - mod = new_mod == 0? mod : new_mod; - } + int key, mod; + Opie::Ui::Private::fixupKeys( key, mod, e ); OKeyConfigItem::List _keyList = keyList( key ); if ( _keyList.isEmpty() ) return OKeyConfigItem(); OKeyConfigItem item; for ( OKeyConfigItem::List::Iterator it = _keyList.begin(); it != _keyList.end(); ++it ) { if ( (*it).keyPair().modifier() == mod ) { item = *it; break; } @@ -723,50 +705,27 @@ OKeyConfigItem::List OKeyConfigManager::keyList( int keycode) { break; } } /* check if we added it */ if ( add ) (*m_map)[pair.keycode()].append( *it ); } } return (*m_map)[keycode]; } - -///////////////////////// -//////// Widget Starts Here namespace Opie { namespace Ui { namespace Private { - static QString keyToString( const OKeyPair& ); - class OKeyListViewItem : public Opie::Ui::OListViewItem { - public: - OKeyListViewItem( const OKeyConfigItem& item, OKeyConfigManager*, Opie::Ui::OListViewItem* parent); - ~OKeyListViewItem(); - - void setDefault(); - - OKeyConfigItem& item(); - OKeyConfigItem origItem()const; - void setItem( const OKeyConfigItem& item ); - void updateText(); - - OKeyConfigManager *manager(); - private: - OKeyConfigItem m_item; - OKeyConfigItem m_origItem; - OKeyConfigManager* m_manager; - - }; OKeyListViewItem::OKeyListViewItem( const OKeyConfigItem& item, OKeyConfigManager* man, OListViewItem* parent) : Opie::Ui::OListViewItem( parent ), m_manager( man ) { m_origItem = item; setItem( item ); } OKeyListViewItem::~OKeyListViewItem() {} OKeyConfigItem &OKeyListViewItem::item(){ return m_item; } OKeyConfigItem OKeyListViewItem::origItem() const{ return m_origItem; @@ -792,24 +751,48 @@ namespace Private { QString keyToString( const OKeyPair& pair ) { int mod = 0; if ( pair.modifier() & Qt::ShiftButton ) mod |= Qt::SHIFT; if ( pair.modifier() & Qt::ControlButton ) mod |= Qt::CTRL; if ( pair.modifier() & Qt::AltButton ) mod |= Qt::ALT; return QAccel::keyToString( mod + pair.keycode() ); } + void fixupKeys( int& key, int &mod, QKeyEvent* e ) { + key = e->key(); + mod = e->state(); + /* + * virtual keyboard + * else change the button mod only + */ + if ( key == 0 ) { + key = e->ascii(); + if ( key > 96 && key < 123) + key -= 32; + }else{ + int new_mod = 0; + if ( mod & 256 ) + new_mod |= Qt::ShiftButton; + else if ( mod & 512 ) + new_mod |= Qt::ControlButton; + else if ( mod & 1024 ) + new_mod |= Qt::AltButton; + + mod = new_mod == 0? mod : new_mod; + } + } + struct OKeyConfigWidgetPrivate{ OKeyConfigWidgetPrivate(const QString& = QString::null, OKeyConfigManager* = 0); bool operator==( const OKeyConfigWidgetPrivate& ); QString name; OKeyConfigManager *manager; }; OKeyConfigWidgetPrivate::OKeyConfigWidgetPrivate( const QString& _name, OKeyConfigManager* man ) : name( _name ), manager( man ){} @@ -818,25 +801,26 @@ namespace Private { if ( name != item.name ) return false; return true; } } } } //////////////////////// - +//////////////////////// +//////// Widget Starts Here /** * * This is a c'tor. You still need to pass the OKeyConfigManager * and then issue a load. * The default mode is Immediate * */ OKeyConfigWidget::OKeyConfigWidget( QWidget* parent, const char *name, WFlags fl ) @@ -1030,80 +1014,198 @@ void OKeyConfigWidget::slotNoKey() { m_btn ->setEnabled( false ); m_def ->setChecked( false ); if ( !m_view->currentItem() || !m_view->currentItem()->parent() ) return; /* * If immediate we need to remove and readd the key */ Opie::Ui::Private::OKeyListViewItem *item = static_cast<Opie::Ui::Private::OKeyListViewItem*>(m_view->currentItem()); - if ( m_mode == Imediate ) - item->manager()->removeKeyConfig( item->item() ); - item->item().setKeyPair( OKeyPair::emptyKey() ); - item->updateText(); - - if ( m_mode == Imediate ) - item->manager()->addKeyConfig( item->item() ); - + updateItem( item, OKeyPair::emptyKey() ); } void OKeyConfigWidget::slotDefaultKey() { m_none->setChecked( false ); m_cus ->setChecked( false ); m_btn ->setEnabled( false ); m_def ->setChecked( true ); if ( !m_view->currentItem() || !m_view->currentItem()->parent() ) return; Opie::Ui::Private::OKeyListViewItem *item = static_cast<Opie::Ui::Private::OKeyListViewItem*>(m_view->currentItem()); - - /* - * If immediate we need to remove and readd the key - */ - if ( m_mode == Imediate ) - item->manager()->removeKeyConfig( item->item() ); - - item->item().setKeyPair( item->item().defaultKeyPair() ); - item->updateText(); - - if ( m_mode == Imediate ) - item->manager()->addKeyConfig( item->item() ); + updateItem( item, item->item().defaultKeyPair() ); } void OKeyConfigWidget::slotCustomKey() { m_cus ->setChecked( true ); m_btn ->setEnabled( true ); m_def ->setChecked( false ); m_none->setChecked( false ); if ( !m_view->currentItem() || !m_view->currentItem()->parent() ) return; + } void OKeyConfigWidget::slotConfigure() { + if ( !m_view->currentItem() || !m_view->currentItem()->parent() ) + return; + + /* FIXME make use of OModalHelper */ + OKeyChooserConfigDialog dlg( this, "Dialog Name", true ); + dlg.setCaption(tr("Configure Key")); + connect(&dlg, SIGNAL(keyCaptured()), &dlg, SLOT(accept()) ); + + if ( QPEApplication::execDialog( &dlg ) == QDialog::Accepted ) { + Opie::Ui::Private::OKeyListViewItem *item = static_cast<Opie::Ui::Private::OKeyListViewItem*>(m_view->currentItem()); + updateItem( item, dlg.keyPair() ); + } + + +} + +void OKeyConfigWidget::updateItem( Opie::Ui::Private::OKeyListViewItem *item, + const OKeyPair& newItem) { + /* sanity check + * check against the blacklist of the manager + * check if another item uses this key which is o(n) at least + */ + if ( !newItem.isEmpty() ) { + + } + /* + * If immediate we need to remove and readd the key + */ + if ( m_mode == Imediate ) + item->manager()->removeKeyConfig( item->item() ); + + item->item().setKeyPair( newItem ); + item->updateText(); + + if ( m_mode == Imediate ) + item->manager()->addKeyConfig( item->item() ); } + +///// OKeyChooserConfigDialog::OKeyChooserConfigDialog( QWidget* par, const char* nam, bool mod, WFlags fl ) - : QDialog( par, nam, mod, fl ) { + : QDialog( par, nam, mod, fl ), m_virtKey( false ), m_keyPair( OKeyPair::emptyKey() ) , + m_key( 0 ), m_mod( 0 ) { + setFocusPolicy( StrongFocus ); + + QHBoxLayout *lay = new QHBoxLayout( this ); + + QLabel *lbl = new QLabel( tr("Configure Key" ), this ); + lay->addWidget( lbl ); + lbl->setFocusPolicy( NoFocus ); + + m_lbl = new QLabel( this ); + lay->addWidget( m_lbl ); + m_lbl->setFocusPolicy( NoFocus ); + + m_timer = new QTimer( this ); + connect(m_timer, SIGNAL(timeout()), + this, SLOT(slotTimeUp()) ); } OKeyChooserConfigDialog::~OKeyChooserConfigDialog() { } Opie::Ui::OKeyPair OKeyChooserConfigDialog::keyPair()const{ + return m_keyPair; } void OKeyChooserConfigDialog::keyPressEvent( QKeyEvent* ev ) { - ev->ignore(); + QDialog::keyPressEvent( ev ); + + if ( ev->isAutoRepeat() ) + return; + + qWarning( "Key Press Event" ); + int mod, key; + Opie::Ui::Private::fixupKeys( key,mod, ev ); + + /* either we used software keyboard + * or we've true support + */ + if ( !m_virtKey && !ev->key()) { + m_virtKey = true; + m_keyPair = OKeyPair( key, mod ); + }else{ + mod = 0; + switch( key ) { + case Qt::Key_Control: + mod = Qt::ControlButton; + break; + case Qt::Key_Shift: + mod = Qt::ShiftButton; + break; + case Qt::Key_Alt: + mod = Qt::AltButton; + break; + default: + break; + } + if (mod ) { + m_mod |= mod; + }else + m_key = key; + + if ( ( !mod || m_key ) && !m_timer->isActive() ) + m_timer->start( 50, true ); + + m_keyPair = OKeyPair( m_key, m_mod ); + } + + m_lbl->setText( Opie::Ui::Private::keyToString( m_keyPair ) ); + } void OKeyChooserConfigDialog::keyReleaseEvent( QKeyEvent* ev ) { - ev->ignore(); + m_timer->stop(); + QDialog::keyPressEvent( ev ); + + if ( ev->isAutoRepeat() ) + return; + + + if ( m_virtKey && !ev->key()) { + m_virtKey = false; + slotTimeUp(); + }else { + int mod = 0; + int key = ev->key(); + switch( key ) { + case Qt::Key_Control: + mod = Qt::ControlButton; + break; + case Qt::Key_Shift: + mod = Qt::ShiftButton; + break; + case Qt::Key_Alt: + mod = Qt::AltButton; + break; + default: + break; + } + if (mod ) + m_mod &= ~mod; + else + m_key = key; + m_keyPair = OKeyPair( m_key, m_mod ); + m_lbl->setText( Opie::Ui::Private::keyToString( m_keyPair ) ); + } +} + + +void OKeyChooserConfigDialog::slotTimeUp() { + m_mod = m_key = 0; + QTimer::singleShot(0, this, SIGNAL(keyCaptured()) ); } diff --git a/libopie2/opieui/okeyconfigwidget.h b/libopie2/opieui/okeyconfigwidget.h index 8d2a1ef..9e26719 100644 --- a/libopie2/opieui/okeyconfigwidget.h +++ b/libopie2/opieui/okeyconfigwidget.h @@ -12,30 +12,32 @@ #include <qstring.h> #include <qpixmap.h> #include <qcstring.h> #include <qhbox.h> #include <qvaluelist.h> class QKeyEvent; class QLabel; class QPushButton; class QListViewItem; class QRadioButton; +class QTimer; namespace Opie { namespace Ui { namespace Private { class OKeyConfigWidgetPrivate; typedef QValueList<OKeyConfigWidgetPrivate> OKeyConfigWidgetPrivateList; + class OKeyListViewItem; } class OListViewItem; class OListView; /** * \brief small class representing a Key with possible modifiers * This class holds information about key code and possible * modifier state. That is the lowest level of the key input * functions. * There are also static methods to get special keys. * OKeyPair will be used with \see OKeyConfigItem * @@ -242,24 +244,26 @@ public: void load(); void save(); private slots: void slotListViewItem( QListViewItem* ); void slotNoKey(); void slotDefaultKey(); void slotCustomKey(); void slotConfigure(); private: + void updateItem( Opie::Ui::Private::OKeyListViewItem* man, + const OKeyPair& newItem); void initUi(); Opie::Ui::OListView *m_view; Opie::Ui::Private::OKeyConfigWidgetPrivateList m_list; QLabel *m_lbl; QPushButton *m_btn; QRadioButton *m_def, *m_cus, *m_none; QWidget* m_box; ChangeMode m_mode; class Private; Private *d; }; @@ -287,23 +291,30 @@ public: OKeyChooserConfigDialog( QWidget* parent = 0, const char* name = 0, bool modal = false, WFlags fl = 0 ); ~OKeyChooserConfigDialog(); OKeyPair keyPair()const; protected: void keyPressEvent( QKeyEvent* ); void keyReleaseEvent( QKeyEvent* ); signals: void keyCaptured(); +private slots: + void slotTimeUp(); + private: + QTimer *m_timer; + QLabel *m_lbl; + bool m_virtKey : 1; OKeyPair m_keyPair; + int m_key, m_mod; class Private; Private *d; }; } } #endif diff --git a/libopie2/opieui/okeyconfigwidget_p.h b/libopie2/opieui/okeyconfigwidget_p.h new file mode 100644 index 0000000..e7eaba6 --- a/dev/null +++ b/libopie2/opieui/okeyconfigwidget_p.h @@ -0,0 +1,33 @@ +/* + * Only Internal implemented in the same .cpp file anyway + */ +#include <opie2/olistview.h> + + +namespace Opie { +namespace Ui { +namespace Private { + static QString keyToString( const OKeyPair& ); + static void fixupKeys( int&, int&, QKeyEvent* ); + class OKeyListViewItem : public Opie::Ui::OListViewItem { + public: + OKeyListViewItem( const OKeyConfigItem& item, OKeyConfigManager*, Opie::Ui::OListViewItem* parent); + ~OKeyListViewItem(); + + void setDefault(); + + OKeyConfigItem& item(); + OKeyConfigItem origItem()const; + void setItem( const OKeyConfigItem& item ); + void updateText(); + + OKeyConfigManager *manager(); + private: + OKeyConfigItem m_item; + OKeyConfigItem m_origItem; + OKeyConfigManager* m_manager; + + }; +} +} +} |