[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    branches/work/kdelibs-mousegestures/kdeui
From:       Andreas Hartmetz <ahartmetz () gmail ! com>
Date:       2007-03-13 3:46:49
Message-ID: 1173757609.154777.29363.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 642026 by ahartmetz:

redesign KKeyButton for single QKeySequence, fold KShortcutDialog into it. UI \
improvements in the process. Random stuff. Nowhere near compiling or even working.

 M  +5 -1      dialogs/kkeydialog.cpp  
 M  +13 -14    dialogs/kkeydialog.h  
 M  +5 -11     dialogs/kshortcutdialog.cpp  
 M  +5 -0      itemviews/kextendableitemdelegate.cpp  
 M  +4 -0      itemviews/kextendableitemdelegate.h  
 M  +1 -1      shortcuts/kgesture.cpp  
 M  +1 -1      shortcuts/kgesture.h  
 M  +154 -27   widgets/kkeybutton.cpp  
 M  +18 -12    widgets/kkeybutton.h  


--- branches/work/kdelibs-mousegestures/kdeui/dialogs/kkeydialog.cpp #642025:642026
@@ -26,6 +26,7 @@
 #include "kkeybutton.h"
 
 #include "ui_kkeydialog.h"
+#include "ui_kshortcuteditor.h"
 
 #include <string.h>
 
@@ -205,7 +206,10 @@
 		index = model->index(index.row(), 1, index.parent());
 	}
 	if (!isExtended(index)) {
-		QPushButton *editor = new QPushButton(QString("I could be any QWidget"), \
static_cast<QAbstractItemView*>(parent())->viewport()); +		//TODO:fix the leak!!! \
(make a "real" KShortcutEditor widget) +		Ui::KShortcutEditor *kseui = new \
Ui::KShortcutEditor; +		QWidget *editor = new \
QWidget(static_cast<QAbstractItemView*>(parent())->viewport()) \
+		kseui->setupUi(editor);  extendItem(editor, index);
 	} else {
 		contractItem(index);
--- branches/work/kdelibs-mousegestures/kdeui/dialogs/kkeydialog.h #642025:642026
@@ -171,27 +171,26 @@
 	virtual void showEvent(QShowEvent* event);
  
 private:
-	Q_PRIVATE_SLOT(d, void slotLocalNoKey())
-	Q_PRIVATE_SLOT(d, void slotLocalDefaultKey())
-	Q_PRIVATE_SLOT(d, void slotLocalCustomKey())
-	Q_PRIVATE_SLOT(d, void slotLocalCapturedShortcut( const KShortcut& cut ))
+	Q_PRIVATE_SLOT(d, void slotLocalNoKey());
+	Q_PRIVATE_SLOT(d, void slotLocalDefaultKey());
+	Q_PRIVATE_SLOT(d, void slotLocalCustomKey());
+	Q_PRIVATE_SLOT(d, void slotLocalCapturedShortcut(const KShortcut &cut));
 	
-	Q_PRIVATE_SLOT(d, void slotGlobalNoKey())
-	Q_PRIVATE_SLOT(d, void slotGlobalDefaultKey())
-	Q_PRIVATE_SLOT(d, void slotGlobalCustomKey())
-	Q_PRIVATE_SLOT(d, void slotGlobalCapturedShortcut( const KShortcut& cut ))
+	Q_PRIVATE_SLOT(d, void slotGlobalNoKey());
+	Q_PRIVATE_SLOT(d, void slotGlobalDefaultKey());
+	Q_PRIVATE_SLOT(d, void slotGlobalCustomKey());
+	Q_PRIVATE_SLOT(d, void slotGlobalCapturedShortcut(const KShortcut &cut));
 
-	Q_PRIVATE_SLOT(d, void slotListItemSelected( QTreeWidgetItem *item ))
-	Q_PRIVATE_SLOT(d, void slotSettingsChanged( int ))
+	Q_PRIVATE_SLOT(d, void slotListItemSelected(QTreeWidgetItem *item));
+	Q_PRIVATE_SLOT(d, void slotSettingsChanged(in ));
         
-	Q_PRIVATE_SLOT(d, void captureCurrentItem())
+	Q_PRIVATE_SLOT(d, void captureCurrentItem());
 
 private:
 	friend class KKeyDialog;
 	friend class KKeyChooserPrivate;
 	KKeyChooserPrivate* const d;
-        
-        Q_DISABLE_COPY(KKeyChooser)
+	Q_DISABLE_COPY(KKeyChooser);
 };
 
 Q_DECLARE_OPERATORS_FOR_FLAGS(KKeyChooser::ActionTypes)
@@ -275,7 +274,7 @@
 	friend class KKeyDialogPrivate;
 	class KKeyDialogPrivate* const d;
 
-	Q_DISABLE_COPY(KKeyDialog)          
+	Q_DISABLE_COPY(KKeyDialog);
 };
 
 
--- branches/work/kdelibs-mousegestures/kdeui/dialogs/kshortcutdialog.cpp \
#642025:642026 @@ -69,7 +69,6 @@
 	KShortcut shortcut;
 	bool bGrab;
 	KPushButton* ptxtCurrent;
-	uint iSeq;
 	uint iKey;
 	bool bRecording;
 	uint mod;
@@ -404,20 +403,16 @@
 	bool change = true;
 	switch( e->key() ) {
 		case Qt::Key_Shift:
-			if (d->mod & Qt::SHIFT)
-				d->mod ^= Qt::SHIFT;
+			d->mod &= ~Qt::SHIFT;
 			break;
 		case Qt::Key_Control:
-			if (d->mod & Qt::CTRL)
-				d->mod ^= Qt::CTRL;
+			d->mod &= ~Qt::CTRL;
 			break;
 		case Qt::Key_Alt:
-			if (d->mod & Qt::ALT)
-				d->mod ^= Qt::ALT;
+			d->mod &= ~Qt::ALT;
 			break;
 		case Qt::Key_Meta:
-			if (d->mod & Qt::META)
-				d->mod ^= Qt::META;
+			d->mod &= ~Qt::META;
 			break;
 		default:
 			change = false;
@@ -437,8 +432,7 @@
 	if (bRecording != recording) {
 		bRecording = recording;
 		if (bRecording) {
-			q->grabKeyboard();
-		} else {
+			q->grabKeyboard(); } else {
 			q->releaseKeyboard();
 		}
 	}
--- branches/work/kdelibs-mousegestures/kdeui/itemviews/kextendableitemdelegate.cpp \
#642025:642026 @@ -36,6 +36,11 @@
 		return;
 	//maintain the invariant "zero or one extender per row"
 	contractItem(indexOfExtendedColumnInSameRow(index));
+	//reparent to viewport, as promised in the docs
+	QAbstractItemView *aiv = qobject_cast<QAbstractItemView *>(parent());
+	if (!aiv)
+		return;
+	ext->setParent(aiv->viewport());
 	m_extenders.insert(index, ext);
 	m_extenderIndices.insert(ext, index);
 	m_hasExtenders = true;
--- branches/work/kdelibs-mousegestures/kdeui/itemviews/kextendableitemdelegate.h \
#642025:642026 @@ -32,6 +32,10 @@
 	virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex \
&index) const;  virtual void paint(QPainter *painter, const QStyleOptionViewItem \
&option, const QModelIndex &index) const;  
+	/** ...
+	 * If you need a parent for the extender at construction time, use the itemview's \
viewport(). +	 * The extender will be reparented and resized to the viewport by this \
function. +	 */
 	void extendItem(QWidget *extender, const QModelIndex &index);
 	void contractItem(const QModelIndex &index);
 	bool isExtended(const QModelIndex &index) const;
--- branches/work/kdelibs-mousegestures/kdeui/shortcuts/kgesture.cpp #642025:642026
@@ -99,7 +99,7 @@
     m_friendlyName = friendlyName;
 }
 
-QString KShapeGesture::shapeName()
+QString KShapeGesture::shapeName() const
 {
     return m_friendlyName;
 }
--- branches/work/kdelibs-mousegestures/kdeui/shortcuts/kgesture.h #642025:642026
@@ -77,7 +77,7 @@
     /**
      * Return the user-visible name for this gesture's shape, like "triangle" or \
                "line".
      */
-    QString shapeName();
+    QString shapeName() const;
 
     /**
      * Return true if this gesture is valid.
--- branches/work/kdelibs-mousegestures/kdeui/widgets/kkeybutton.cpp #642025:642026
@@ -63,24 +63,34 @@
 /* Initially added by Mark Donohoe <donohoe@kde.org>                   */
 /*                                                                     */
 /***********************************************************************/
-
+ 
 class KKeyButton::KKeyButtonPrivate
 {
 public:
 	KKeyButtonPrivate(KKeyButton *q): q(q) {}
-  
+
+	static appendToSequence(const QKeySequence& seq, int keyQt);
+	void updateShortcutDisplay();
+
+	//private slots
+	void captureShortcut();
+	void clearShortcut();
+	void setMultiKeyMode(bool enabled);
+
 	KKeyButton *q;
-	KShortcut m_cut;
-	bool m_bEditing;
+	QKeySequence keySequence;
+	uint nKey;
+	uint modifierKeys;
+	bool isRecording;
 };
 
 KKeyButton::KKeyButton(QWidget *parent)
-:	QPushButton( parent ), d(new KKeyButtonPrivate(this))
+: QPushButton( parent ), d(new KKeyButtonPrivate(this))
 {
 	setFocusPolicy( Qt::StrongFocus );
-	d->m_bEditing = false;
-	connect( this, SIGNAL(clicked()), this, SLOT(captureShortcut()) );
-	setShortcut( KShortcut() );
+	d->isRecording = false;
+	connect(this, SIGNAL(clicked()), d, SLOT(captureShortcut()));
+	setShortcut(QKeySequence());
 }
 
 KKeyButton::~KKeyButton ()
@@ -88,9 +98,9 @@
 	delete d;
 }
 
-const KShortcut& KKeyButton::shortcut() const
+QKeySequence KKeyButton::shortcut() const
 {
-	return d->m_cut;
+	return d->keySequence;
 }
 
 void KKeyButton::setShortcut( const KShortcut& cut )
@@ -107,29 +117,28 @@
 	setFixedSize( sizeHint().width()+12, sizeHint().height()+8 );
 }
 
-void KKeyButton::captureShortcut()
+void KKeyButton::startRecording()
 {
-	KShortcut cut;
-
-	d->m_bEditing = true;
+	d->nKey == 0;
+	d->modifierKeys = 0;
+	d->isRecording = true;
+	grabKeyboard();
+	//### it's not clear to me when exactly to repaint. try stuff.
 	repaint();
+}
 
-	{
-		KShortcutDialog dlg( d->m_cut, this );
-		if( dlg.exec() == KDialog::Accepted )
-			cut = dlg.shortcut();
-	} // emit the signal after the dialog is destroyed, otherwise it still has grab
-
-	if( !cut.isEmpty() )
-		emit capturedShortcut( cut );
-
-	d->m_bEditing = false;
-	repaint();
+void KKeyButton::doneRecording()
+{
+	//### other things that need to be done
+	d->isRecording = false;
+	releaseKeyboard();
+	emit capturedShortcut(d->keySequence);
 }
 
 void KKeyButton::paintEvent( QPaintEvent* )
 {
   QPainter painter(this);
+  painter.setRenderHint(QPainter::Antialiasing, true);
 
   QPolygon a( 4 );
   a.setPoint( 0, 0, 0) ;
@@ -156,7 +165,7 @@
   if( width() > 12 && height() > 8 )
     qDrawShadePanel( &painter, 6, 4, width() - 12, height() - 8,
                      palette(), true, 1, 0L );
-  if ( d->m_bEditing )
+  if (d->isRecording)
   {
     painter.setPen( palette().color( QPalette::Base ) );
     painter.setBrush( palette().color( QPalette::Base ) );
@@ -175,7 +184,7 @@
                          palette(), isEnabled(), text() );
 
   painter.setBrush( Qt::NoBrush );
-  if( hasFocus() || d->m_bEditing )
+  if( hasFocus() || d->isRecording )
   {
     if( width() > 16 && height() > 12 )
       painter.drawRect( 8, 6, width() - 16, height() - 12 );
@@ -183,5 +192,123 @@
 
 }
 
+void KKeyButtonPrivate::updateShortcutDisplay()
+{
+	//empty string if no non-modifier was pressed
+	QString s = keySequence.toString();
+	s.replace('&', QLatin1String("&&"));
 
+	//### really needed???
+	q->setFocus();
+	if(isRecording) {
+		// Display modifiers for the first key in the QKeySequence
+		if( iKey == 0 ) {
+			if(modifierKeys) {
+#if defined(Q_WS_MAC)
+				if(modifierKeys & Qt::META)  s += KKeyServer::modToStringUser(Qt::META) + '+';
+				if(modifierKeys & Qt::ALT)   s += KKeyServer::modToStringUser(Qt::ALT) + '+';
+				if(modifierKeys & Qt::CTRL)  s += KKeyServer::modToStringUser(Qt::CTRL) + '+';
+				if(modifierKeys & Qt::SHIFT) s += KKeyServer::modToStringUser(Qt::SHIFT) + '+';
+#elif defined(Q_WS_X11)
+				if(modifierKeys & Qt::META)  s += KKeyServer::modToStringUser(Qt::META) + '+';
+				if(modifierKeys & Qt::CTRL)  s += KKeyServer::modToStringUser(Qt::CTRL) + '+';
+				if(modifierKeys & Qt::ALT)   s += KKeyServer::modToStringUser(Qt::ALT) + '+';
+				if(modifierKeys & Qt::SHIFT) s += KKeyServer::modToStringUser(Qt::SHIFT) + '+';
+#endif
+			} else
+				s = i18nc("What the user inputs now will be taken as the new shortcut", \
"Capturing shortcut"); +		}
+	}
+	//make it clear that input is still going on
+	s += '...';
+
+	q->setText(s);
+}
+
+
+void KKeyButton::keyPressEvent( QKeyEvent * e )
+{
+	QPushButton::keyPressEvent(e);
+
+	//if key is a letter, it must be stored as lowercase
+	int keyQt = QChar( e->key() & 0xff ).isLetter() ?
+		(QChar( e->key() & 0xff ).toLower().toLatin1() | (e->key() & 0xffff00) )
+		: e->key();
+
+	uint newModfiers = e->modifiers() & (Qt::SHIFT | Qt::CTRL | Qt::ALT | Qt::META);
+	
+	if (!d->isRecording) {
+		if (keyQt == Qt::Key_Return) {
+			startRecording();
+			d->modifierKeys = newModifiers;
+			d->updateShortcutDisplay();
+		}
+		return;
+	}
+
+	if (d->modifierKeys != newModfiers && d->nKey == 0)
+		d->modifierKeys = newModfiers;
+
+	switch(keyQt) {
+	case Qt::Key_Shift:
+	case Qt::Key_Control:
+	case Qt::Key_Alt:
+	case Qt::Key_Meta:
+	case Qt::Key_Menu: //unused (yes, but why?)
+		break;
+	default:
+		if(keyQt == Qt::Key_Return && d->nKey > 0)
+			doneRecording();
+		else if (keyQt) {
+			if (d->nKey == 0)
+				d->keySequence = KKeyButtonPrivate::appendToSequence(d->keySequence, keyQt | \
d->modifierKeys); +			else
+				d->keySequence = KKeyButtonPrivate::appendToSequence(d->keySequence, keyQt);
+
+			d->nKey++;
+			d->updateShortcutDisplay();
+		}
+		return;
+	}
+
+	// If we are editing the first key in the sequence,
+	// display modifier keys which are held down
+	if( d->nKey == 0 )
+		d->updateShortcutDisplay();
+}
+
+void KKeyButton::keyReleaseEvent(QKeyEvent *e)
+{
+	KDialog::keyReleaseEvent(e);
+	if (!d->isRecording)
+		return;
+
+	uint newModfiers = e->modifiers() & (Qt::SHIFT | Qt::CTRL | Qt::ALT | Qt::META);
+
+	//if a modifier that belongs to the shortcut was released...
+	if ((newModifiers & d->modifierKeys) < d->modifierKeys) {
+		if (d->nKey == 0) {
+			d->modifiers = newModifiers;
+			d->updateShortcutDisplay();
+		} else
+			doneRecording();
+	}
+}
+
+QKeySequence KKeyButtonPrivate::appendToSequence(const QKeySequence& seq, int keyQt)
+{
+	switch (seq.count()) {
+	case 0:
+		return QKeySequence(keyQt);
+	case 1:
+		return QKeySequence(seq[0], keyQt);
+	case 2:
+		return QKeySequence(seq[0], seq[1], keyQt);
+	case 3:
+		return QKeySequence(seq[0], seq[1], seq[2], keyQt);
+	default:
+		return seq;
+	}
+}
+
 #include "kkeybutton.moc"
--- branches/work/kdelibs-mousegestures/kdeui/widgets/kkeybutton.h #642025:642026
@@ -46,22 +46,22 @@
 	/**
 	* Constructs  key button widget.
 	*/
-	explicit KKeyButton( QWidget *parent = 0 );
+	explicit KKeyButton(QWidget *parent = 0);
 	/**
 	* Destructs the key button widget.
 	*/
 	virtual ~KKeyButton();
 
-	void setShortcut( const KShortcut& cut );
-	const KShortcut& shortcut() const;
+	void setShortcut(const QKeySequence &cut);
+	QKeySequence shortcut() const;
 
 	/**
 	* Reimplemented for internal purposes.
 	*/
-	void setText( const QString& text );
+	void setText(const QString &text);
 
  Q_SIGNALS:
-	void capturedShortcut( const KShortcut& );
+	void capturedShortcut(const KShortcut &);
 
  public Q_SLOTS:
 	/**
@@ -74,14 +74,20 @@
 	/**
 	* Reimplemented for internal reasons.
 	*/
-	void paintEvent( QPaintEvent* pe );
+	void paintEvent(QPaintEvent *pe);
+	virtual void keyPressEvent(QKeyEvent *event);
+	virtual void keyReleaseEvent(QKeyEvent *event);
 
- private:
-        class KKeyButtonPrivate;
-        friend class KKeyButtonPrivate;
-	KKeyButtonPrivate* const d;
-        
-        Q_DISABLE_COPY(KKeyButton)
+private:
+	void doneRecording();
+	class KKeyButtonPrivate;
+	friend class KKeyButtonPrivate;
+	KKeyButtonPrivate *const d;
+	Q_PRIVATE_SLOT(d, void startRecording());
+	Q_PRIVATE_SLOT(d, void clearShortcut());
+	Q_PRIVATE_SLOT(d, void setMultiKeyMode(bool multiEnable));
+
+	Q_DISABLE_COPY(KKeyButton);
 };
 
 #endif


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic