View Issue Details

IDProjectCategoryView StatusLast Update
0015239ScribusGeneralpublic2018-04-07 14:33
Reporterale Assigned To 
PrioritynormalSeverityminorReproducibilityalways
Status newResolutionopen 
Product Version1.5.4.svn 
Summary0015239: impossible to set ctrl+= as a shortcut (on a swiss keyboard)
Descriptionon a swiss keyboard it's not possible to set ctrl+= as a shortcut from the UI.
but it works if i manually set it in the preference file.

on swiss keybards the = is obtained by pressing shift+0

in the preferences > shortcuts, if i press ctrl+shift+0, i get as a result ctrl+shift+= written in the preferences.

the issue might be related with the fact that i can tweak the preferences file with both ctrl+shift+0 and ctrl+= and in both cases i can use the desired shortcut in scribus.

i wonder if this is a qt issue or if there is some too well meant "optimization" in scribus....
TagsNo tags attached.
PatchNo

Activities

jghali

2018-04-07 14:33

administrator   ~0045153

@ale, I did an experiment by replacing our keyboard shortcut editor by Qt's keysequence edit widget. You'll find a patch attached to this note.

I'm not sure we'll be able to use it as is, as it seems this widget has some issues, however i'd like you to test its behavior in respect to your issue. On Windows, it seems the qt keyboard shortcut editor flat out refuses some sequence which may be ambiguous (like your ctrl+shift+0) depending on keyboard layout.
15239_qkeysequenceedit.patch (12,212 bytes)   
Index: scribus/ui/prefs_keyboardshortcuts.cpp
===================================================================
--- scribus/ui/prefs_keyboardshortcuts.cpp	(revision 22454)
+++ scribus/ui/prefs_keyboardshortcuts.cpp	(working copy)
@@ -10,6 +10,7 @@
 #include <QFileDialog>
 #include <QInputDialog>
 #include <QMessageBox>
+#include <QSignalBlocker>
 
 #include "actionmanager.h"
 #include "commonstrings.h"
@@ -61,17 +62,17 @@
 	lviToMenuMap.clear();
 	keyTable->clear();
 	keyMap.clear();
-	keyCode = 0;
-	keyDisplay->setMinimumWidth(fontMetrics().width("CTRL+ALT+SHIFT+W"));
-	keyDisplay->setText("");
+
+	keySeqEdit->setMinimumWidth(fontMetrics().width("CTRL+ALT+SHIFT+W"));
+	keySeqEdit->clear();
 	selectedLVI = NULL;
 
 	clearSearchButton->setIcon(IconManager::instance()->loadIcon("clear_right.png"));
 	// signals and slots connections
 	connect( keyTable, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
 			 this, SLOT(dispKey(QTreeWidgetItem *, QTreeWidgetItem *)));
+	connect( keySeqEdit, SIGNAL(editingFinished()), this, SLOT(seqEditingFinished()));
 	connect( noKey, SIGNAL(clicked()), this, SLOT(setNoKey()));
-	connect( setKeyButton, SIGNAL(clicked()), this, SLOT(setKeyText()));
 	connect( loadSetButton, SIGNAL(clicked()), this, SLOT(loadKeySetFile()));
 	connect( importSetButton, SIGNAL(clicked()), this, SLOT(importKeySetFile()));
 	connect( exportSetButton, SIGNAL(clicked()), this, SLOT(exportKeySetFile()));
@@ -103,16 +104,42 @@
 	prefsData->keyShortcutPrefs.KeyActions=keyMap;
 }
 
+void Prefs_KeyboardShortcuts::seqEditingFinished()
+{
+	QSignalBlocker blocker(keySeqEdit);
+
+	if (!selectedLVI)
+		return;
+
+	QString actionName = lviToActionMap[selectedLVI];
+	QKeySequence newKeySequence = keySeqEdit->keySequence();
+	if (checkKey(newKeySequence))
+	{
+		ScMessageBox::information(this, CommonStrings::trWarning,
+			tr("The %1 key sequence is already in use by \"%2\"")
+			.arg(getTrKeyText(newKeySequence))
+			.arg(getAction(newKeySequence)));
+		selectedLVI->setText(1, keyMap[actionName].keySequence.toString(QKeySequence::NativeText));
+		keySeqEdit->setKeySequence(keyMap[actionName].keySequence);
+	}
+	else
+	{
+		selectedLVI->setText(1, newKeySequence.toString(QKeySequence::NativeText));
+		keyMap[actionName].keySequence = newKeySequence;
+		userDef->setChecked(true);
+	}
+}
+
 void Prefs_KeyboardShortcuts::setNoKey()
 {
 	if (noKey->isChecked())
 	{
-		if (selectedLVI!=0)
+		if (selectedLVI != 0)
 		{
 			selectedLVI->setText(1,"");
 			keyMap[lviToActionMap[selectedLVI]].keySequence=QKeySequence();
 		}
-		keyDisplay->setText("");
+		keySeqEdit->clear();
 		noKey->setChecked(true);
 	}
 }
@@ -148,15 +175,15 @@
 	{
 		//import the file into qdomdoc
 		QDomDocument doc( "keymapentries" );
-		QFile file1( filename );
-		if ( !file1.open( QIODevice::ReadOnly ) )
+		QFile file1(filename);
+		if (!file1.open(QIODevice::ReadOnly))
 			return;
 		QTextStream ts(&file1);
 		ts.setCodec("UTF-8");
 		QString errorMsg;
 		int eline;
 		int ecol;
-		if ( !doc.setContent( ts.readAll(), &errorMsg, &eline, &ecol ))
+		if (!doc.setContent( ts.readAll(), &errorMsg, &eline, &ecol ))
 		{
 			qDebug("%s", QString("Could not open key set file: %1\nError:%2 at line: %3, row: %4").arg(filename).arg(errorMsg).arg(eline).arg(ecol).toLatin1().constData());
 			file1.close();
@@ -175,10 +202,10 @@
 
 			//load in new set
 			QDomNode n = docElem.firstChild();
-			while( !n.isNull() )
+			while (!n.isNull())
 			{
 				QDomElement e = n.toElement(); // try to convert the node to an element.
-				if( !e.isNull() )
+				if (!e.isNull())
 				{
 					if (e.hasAttribute("name")  && e.hasAttribute( "shortcut" ))
 					{
@@ -285,32 +312,16 @@
 	return QStringList();
 }
 
-QString Prefs_KeyboardShortcuts::getKeyText(QKeySequence KeyC)
+QString Prefs_KeyboardShortcuts::getKeyText(const QKeySequence& keySeq)
 {
-	return KeyC.toString();
+	return keySeq.toString();
 }
 
-QString Prefs_KeyboardShortcuts::getTrKeyText(QKeySequence KeyC)
+QString Prefs_KeyboardShortcuts::getTrKeyText(const QKeySequence& keySeq)
 {
-	return KeyC.toString(QKeySequence::NativeText);
+	return keySeq.toString(QKeySequence::NativeText);
 }
 
-void Prefs_KeyboardShortcuts::setKeyText()
-{
-	if (keyTable->currentItem()==0)
-	{
-		setKeyButton->setChecked(false);
-		return;
-	}
-	if (setKeyButton->isChecked())
-	{
-		keyCode = 0;
-		grabKeyboard();
-	}
-	else
-		releaseKeyboard();
-}
-
 void Prefs_KeyboardShortcuts::insertActions()
 {
 	lviToActionMap.clear();
@@ -436,18 +447,13 @@
 
 void Prefs_KeyboardShortcuts::dispKey(QTreeWidgetItem* qlvi, QTreeWidgetItem*)
 {
-	if (setKeyButton->isChecked())
-	{
-		releaseKeyboard();
-		setKeyButton->setChecked(false);
-	}
 	if (qlvi!=0 && lviToActionMap.contains(qlvi))
 	{
 		selectedLVI = qlvi;
-		QString actionName=lviToActionMap[qlvi];
+		QString actionName = lviToActionMap[qlvi];
 		if (actionName.isEmpty())
 			return;
-		keyDisplay->setText(keyMap[actionName].keySequence.toString(QKeySequence::NativeText));
+		keySeqEdit->setKeySequence(keyMap[actionName].keySequence);
 		if (keyMap[actionName].keySequence.isEmpty())
 			noKey->setChecked(true);
 		else
@@ -456,97 +462,20 @@
 	else
 	{
 		noKey->setChecked(true);
-		keyDisplay->setText("");
+		keySeqEdit->clear();
 		selectedLVI = 0;
 	}
 	noKey->setEnabled(selectedLVI != 0);
 	userDef->setEnabled(selectedLVI != 0);
-	setKeyButton->setEnabled(selectedLVI != 0);
-	keyDisplay->setEnabled(selectedLVI != 0);
+	keySeqEdit->setEnabled(selectedLVI != 0);
 }
 
-bool Prefs_KeyboardShortcuts::event( QEvent* ev )
+QString Prefs_KeyboardShortcuts::getAction(const QKeySequence& keySeq)
 {
-	bool ret = QWidget::event( ev );
-	if ( ev->type() == QEvent::KeyPress )
-		keyPressEvent((QKeyEvent*)ev);
-	if ( ev->type() == QEvent::KeyRelease )
-		keyReleaseEvent((QKeyEvent*)ev);
-	return ret;
-}
-
-void Prefs_KeyboardShortcuts::keyPressEvent(QKeyEvent *k)
-{
-	if (setKeyButton->isChecked())
-	{
-		switch (k->key())
-		{
-			case Qt::Key_Meta:
-				keyCode |= Qt::META;
-				break;
-			case Qt::Key_Shift:
-				keyCode |= Qt::SHIFT;
-				break;
-			case Qt::Key_Alt:
-				keyCode |= Qt::ALT;
-				break;
-			case Qt::Key_Control:
-				keyCode |= Qt::CTRL;
-				break;
-			default:
-				keyCode |= k->key();
-				keyDisplay->setText(getTrKeyText(keyCode));
-				releaseKeyboard();
-				if (selectedLVI)
-				{
-					QString actionName = lviToActionMap[selectedLVI];
-					if (checkKey(keyCode))
-					{
-						ScMessageBox::information(this, CommonStrings::trWarning,
-												tr("The %1 key sequence is already in use by \"%2\"")
-													.arg(getTrKeyText(keyCode))
-													.arg(getAction(keyCode)));
-						selectedLVI->setText(1,keyMap[actionName].keySequence.toString(QKeySequence::NativeText));
-						keyDisplay->setText(keyMap[actionName].keySequence.toString(QKeySequence::NativeText));
-					}
-					else
-					{
-						QKeySequence newKeySequence(keyCode);
-						selectedLVI->setText(1, newKeySequence.toString(QKeySequence::NativeText));
-						keyMap[actionName].keySequence=newKeySequence;
-						userDef->setChecked(true);
-					}
-				}
-				setKeyButton->setChecked(false);
-		}
-	}
-	if (setKeyButton->isChecked())
-		keyDisplay->setText(getTrKeyText(keyCode));
-}
-
-void Prefs_KeyboardShortcuts::keyReleaseEvent(QKeyEvent *k)
-{
-	if (setKeyButton->isChecked())
-	{
-		if (k->key() == Qt::Key_Meta)
-			keyCode &= ~Qt::META;
-		if (k->key() == Qt::Key_Shift)
-			keyCode &= ~Qt::SHIFT;
-		if (k->key() == Qt::Key_Alt)
-			keyCode &= ~Qt::ALT;
-		if (k->key() == Qt::Key_Control)
-			keyCode &= ~Qt::CTRL;
-		keyDisplay->setText(getTrKeyText(keyCode));
-	}
-}
-
-QString Prefs_KeyboardShortcuts::getAction(int code)
-{
 	QString ret;
-	QKeySequence key = QKeySequence(code);
 	for (QMap<QString,Keys>::Iterator it=keyMap.begin(); it!=keyMap.end(); ++it)
 	{
-		if (key.matches(it.value().keySequence) != QKeySequence::NoMatch)
+		if (keySeq.matches(it.value().keySequence) != QKeySequence::NoMatch)
 		{
 			ret = it->cleanMenuText;
 			break;
@@ -555,13 +484,12 @@
 	return ret;
 }
 
-bool Prefs_KeyboardShortcuts::checkKey(int code)
+bool Prefs_KeyboardShortcuts::checkKey(const QKeySequence& keySeq)
 {
 	bool ret = false;
-	QKeySequence key = QKeySequence(code);
 	for (QMap<QString,Keys>::Iterator it=keyMap.begin(); it!=keyMap.end(); ++it)
 	{
-		if (key.matches(it.value().keySequence) != QKeySequence::NoMatch)
+		if (keySeq.matches(it.value().keySequence) != QKeySequence::NoMatch)
 		{
 			ret = true;
 			break;
Index: scribus/ui/prefs_keyboardshortcuts.h
===================================================================
--- scribus/ui/prefs_keyboardshortcuts.h	(revision 22454)
+++ scribus/ui/prefs_keyboardshortcuts.h	(working copy)
@@ -25,21 +25,18 @@
 {
 	Q_OBJECT
 
-	public:
-		Prefs_KeyboardShortcuts(QWidget* parent, ScribusDoc* doc=NULL);
-		~Prefs_KeyboardShortcuts();
-		virtual void restoreDefaults(struct ApplicationPrefs *prefsData);
-		virtual void saveGuiToPrefs(struct ApplicationPrefs *prefsData) const;
+public:
+	Prefs_KeyboardShortcuts(QWidget* parent, ScribusDoc* doc=NULL);
+	~Prefs_KeyboardShortcuts();
 
-		bool event( QEvent* ev );
-		void keyPressEvent(QKeyEvent *k);
-		void keyReleaseEvent(QKeyEvent *k);
+	virtual void restoreDefaults(struct ApplicationPrefs *prefsData);
+	virtual void saveGuiToPrefs(struct ApplicationPrefs *prefsData) const;
 
-		static QString getKeyText(QKeySequence KeyC);
-		static QString getTrKeyText(QKeySequence KeyC);
+	static QString getKeyText(const QKeySequence& keySeq);
+	static QString getTrKeyText(const QKeySequence& keySeq);
 
-	public slots:
-		void languageChange();
+public slots:
+	void languageChange();
 
 protected:
 	QMap<QString,Keys> keyMap;
@@ -50,18 +47,17 @@
 	QVector< QPair<QString, QStringList> >* defMenus;
 	QVector< QPair<QString, QStringList> >* defNonMenuActions;
 	QTreeWidgetItem * selectedLVI;
-	int keyCode;
 
 	void insertActions();
 	void importKeySet(QString);
 	bool exportKeySet(QString);
 	QStringList scanForSets();
-	bool checkKey(int code);
-	QString getAction(int code);
+	bool checkKey(const QKeySequence& keySeq);
+	QString getAction(const QKeySequence& keySeq);
 
 protected slots:
-	void setKeyText();
 	void dispKey(QTreeWidgetItem* current, QTreeWidgetItem* previous=0);
+	void seqEditingFinished();
 	void setNoKey();
 	void loadKeySetFile();
 	void importKeySetFile();
Index: scribus/ui/prefs_keyboardshortcutsbase.ui
===================================================================
--- scribus/ui/prefs_keyboardshortcutsbase.ui	(revision 22454)
+++ scribus/ui/prefs_keyboardshortcutsbase.ui	(working copy)
@@ -45,8 +45,8 @@
        <rect>
         <x>0</x>
         <y>0</y>
-        <width>789</width>
-        <height>504</height>
+        <width>791</width>
+        <height>503</height>
        </rect>
       </property>
       <layout class="QVBoxLayout" name="verticalLayout_2">
@@ -163,40 +163,8 @@
           </spacer>
          </item>
          <item>
-          <widget class="QPushButton" name="setKeyButton">
-           <property name="text">
-            <string>Set &amp;Key</string>
-           </property>
-           <property name="shortcut">
-            <string>Alt+K</string>
-           </property>
-           <property name="checkable">
-            <bool>true</bool>
-           </property>
-          </widget>
+          <widget class="QKeySequenceEdit" name="keySeqEdit"/>
          </item>
-         <item>
-          <widget class="QLabel" name="keyDisplay">
-           <property name="frameShape">
-            <enum>QFrame::Panel</enum>
-           </property>
-           <property name="frameShadow">
-            <enum>QFrame::Sunken</enum>
-           </property>
-           <property name="text">
-            <string>CTRL+ALT+SHIFT+W</string>
-           </property>
-           <property name="textFormat">
-            <enum>Qt::RichText</enum>
-           </property>
-           <property name="alignment">
-            <set>Qt::AlignCenter</set>
-           </property>
-           <property name="wordWrap">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
         </layout>
        </item>
        <item>
15239_qkeysequenceedit.patch (12,212 bytes)   

Issue History

Date Modified Username Field Change
2018-04-03 12:47 ale New Issue
2018-04-03 13:11 jghali Category - => General
2018-04-07 14:33 jghali File Added: 15239_qkeysequenceedit.patch
2018-04-07 14:33 jghali Note Added: 0045153