Qt Embedded for Linux. Keyboard layout switching - qt

I'm developing application with Qt Embedded and run it in linux framebuffer. I need a way to type non-US characters. Is it possible to change keyboard layout with Qt?
I tried to run it on Qt/X11. Layout switching and input are perfectly fine there.
But when I compile it with Qt/Embedded and run it in framebuffer I cannot change layout.
I searched in the documentation and didn't find anything about layout switching.
I think it has something to do with qt keyboard driver as specified at the documentation.
It seems that I should develop my own keyboard driver. But I'm using standard keyboard and I think there must be a standard way to change input language?
What would you suggest?
BTW, I'm using 4.5 version. Maybe 4.6 has something to solve this issue?
Exact the same problem here:
http://lists.trolltech.com/pipermail/qt-embedded-interest/2008-August/000034.html
http://lists.trolltech.com/qt-interest/2004-02/msg00570.html

Version 4.6 has gained keymap support. Solution:
generate kmap file:
ckbcomp -layout xx > xx.kmap
convert kmap to qmap
kmap2qmap xx.kmap xx.qmap
load keymap either by
specifying QWS_KEYBOARD environment variable:
QWS_KEYBOARD="TTY:keymap=xx.qmap"
or loading a keymap dynamically:
QWSKeyboardHandler * currentKeyboardHandler =
QKbdDriverFactory::create("TTY", "keymap=foo.qmap");
Make sure that you delete created handler when you create a new one:
delete currentKeyboardHandler;
currentKeyboardHandler =
QKbdDriverFactory::create("TTY", "keymap=bar.qmap");
Seems like Qt for Embedded linux is superseeded by Project Lighthouse. Not sure though, if it is production ready, neither I know how does it handle keyboard layout switching.
Update
Qt5 doesn't have QWS and all QWS-related APIs are removed. So you'll need some thirdparty solution. Or write a plugin for QPA.

I need a way to type non-US characters
You can change qmap, but even in Qt 4.8.0 there is no way to switch between US and russian (for example). You need to patch kmap2qmap (add AltGr_Lock support), qkbd_qws.cpp (change testmods according to state of AltGr_Lock). It's looks like no one is used QtEmbedded with keyboard. Or all keeps final patches in secret place.

Can't comment, so this is the answer to
You need to patch kmap2qmap (add AltGr_Lock support), qkbd_qws.cpp (change testmods according to state of AltGr_Lock).
This simple patch to qkbd_qws.cpp enables switch beteewn languages by the CapsLock button.
523,526c523,524
< //if (d->m_locks[0] /*CapsLock*/ && (m->flags & QWSKeyboard::IsLetter))
< // testmods ^= QWSKeyboard::ModShift;
< if (d->m_locks[0] /*CapsLock*/)
< testmods ^= QWSKeyboard::ModAltGr;
---
> if (d->m_locks[0] /*CapsLock*/ && (m->flags & QWSKeyboard::IsLetter))
> testmods ^= QWSKeyboard::ModShift;

Related

qt setting QWSServer keymap from code

I need to a keymap for my embedded QWSServer application.
Using environmental variables like this
QWS_KEYBOARD="TTY:keymap=/german_keyboard.qmap"
export QWS_KEYBOARD
works, but isn't optimal for me.
I tried to set it from code using
QWSServer* wsServer = QWSServer::instance();
QWSKeyboardHandler * kh = QKbdDriverFactory::create("TTY", "keymap=/german_keymap.qmap");
wsServer->setKeyboardHandler(kh);
as mentioned here.
However, it is not working. Any ideas how to fix it?
It actually looks like you couldn't do it. According to this manual page you can only set the driver and device for a keyboard handler, but no additional options like keymap.
In this arcticle about the keymap thing only the environment variable way ist mentioned, too.
Because of this, the answer here seems to be wrong.
Beware: According to this answer, Qt5 doesn't have QWS and all QWS-related APIs have been removed.
You can try:
QWSServer::instance()->closeKeyboard();
QWSKeyboardHandler * kh = QKbdDriverFactory::create("TTY", "keymap=/german_keymap.qmap");
It works for me, but only the first time, if I want to change the layout a second time, the closeKeyboard() will crash, as it's trying to delete the driver defined by QWS_KEYBOARD, and it has already been deleted the first time.

How to Right click of File in Windows Explorer by AutoIt

I wish to simulate a right click on a file. This is done by opening a Windows Explorer window and then right clicking on it.
The main issue is finding the location of the file in Windows Explorer. I am currently using Autoit v3.3.8.1.
My code 's first line:
RunWait (EXPLORER.EXE /n,/e,/select,<filepath>)
The next step is the problem. Finding the coordinates of the file.
After that, right clicking at that coordinates (it seems to me at this time) is not a problem....
Some background:
OS: Windows 7 64-bit
Software Languages: C#, Autoit (for scripting)
The Autoit script is called by a code similar to that below:
Process p = new Process();
p.StartInfo.FileName = "AutoItScript.exe";
p.StartInfo.UseShellExecute = false;
p.Start();
The code is compiled into a console class file which is run at startup. The autoit script runs as the explorer window opens up.
It seems as though you are taking the wrong approach to the problem, so I'll answer what you are asking and what you should be asking.
First up though, that line of code is not valid, and is not what you want either. You want to automate the explorer window, and RunWait waits for the program to finish. Furthermore you want those items to be strings, that code would never work.
Finding the item in explorer
The explorer window is just a listview, and so you can use normal listview messages to find the coordinates of an item. This is done most simply by AutoIt's GUIListView library:
#include<GUIListView.au3>
Local $filepath = "D:\test.txt"
Local $iPid = Run("explorer.exe /n,/e,/select," & $filepath)
ProcessWait($iPid)
Sleep(1000)
Local $hList = ControlGetHandle("[CLASS:CabinetWClass]", "", "[CLASS:SysListView32; INSTANCE:1]")
Local $aClient = WinGetPos($hList)
Local $aPos = _GUICtrlListView_GetItemPosition($hList, _GUICtrlListView_GetSelectedIndices($hList))
MouseClick("Right", $aClient[0] + $aPos[0] + 4, $aClient[1] + $aPos[1] + 4)
As has already been mentioned, sending the menu key is definitely a better way than having to move the mouse.
Executing a subitem directly
This is how it should be done. Ideally you should never need an explorer window open at all, and everything can be automated in the background. This should always be what you aim to achieve, as AutoIt is more than capable in most cases. It all depends on what item you want to click. If it is one of the first few items for opening the file in various programs, then it is as simple as either:
Using ShellExecute, setting the verb parameter to whatever it is you want to do.
Checking the registry to find the exact command line used by the program. For this you will need to look under HKCR\.ext where ext is the file extension, the default value will be the name of another key in HKCR which has the actions and icon associated with the filetype. This is pretty well documented online, so google it.
If the action is not one of the program actions (so is built into explorer) then it is a little more complex. Usually the best way will be to look at task manager when you start the program and see what it runs. Other things can be found online, for example (un)zipping. Actions like copy, delete, rename, create shortcut, send to... They can all be done directly from AutoIt with the various File* functions.
With more information, it would be possible to give you more specific help.
First, you might want to look at the Microsoft Active Accessibility SDK. In particular look at this interface...
http://msdn.microsoft.com/en-us/library/accessibility.iaccessible.aspx
You can use this to walk the items in the control and find the one with the file name you are looking for and its screen location.
From there, maybe try something like this for simulating the right click.
How can I use automation to right-click with a mouse in Windows 7?
Once you have done the right click, use accessibility again to find the right option on the context menu.
Maybe there's an easier way, you should be able to cobble something together like this if you don't find one. Good luck!
Suppose I have a file named test.txt on D drive. It needs to right click for opening Context Menu. To do this, the following code should work:
Local $filepath = "D:\test.txt"
Local $iPid = Run("explorer.exe /n,/e,/select," & $filepath)
ProcessWait($iPid)
Sleep(1000)
Send('+{F10}')

How do I set alternate keys for a given command?

Preferences is bound to command+, by default. Suppose I want to add an additional key binding so that F2 (for example) also binds to Preferences? It must be possible because a few of the standard commands have alternate keystrokes.
According to the docs this is possible, but only with text commands.
"To add a sequence to an existing one, click the Add (+) button and type the new sequence. This only works for text commands; you cannot assign more than one sequence to a menu command."
You can find that in "Xcode 4.2 Developer Lbrary / Tools & Languages / IDEs / Key Bindings Preferences Help / Customizing Keyboard Shortcuts"

Xcode 4 disable "fix-it" popup

I'm fine with Xcode 4 telling me that I have an error. But that pop-up pretty much always has the wrong solution. Is there any way I can get rid of it permanently?
From what I've seen, it looks like you may need to disable the various types of warnings one by one. A list is found here:
http://developer.apple.com/library/mac/#documentation/DeveloperTools/gcc-4.0.1/gcc/Warning-Options.html#Warning-Options
To change them:
Bring up the project navigator and choose your project. In the main window that appears, choose "All". Under the section "LLVM compiler 2.0 - Warnings", choose "Other Warning Flags". Add the flag "Wno-idiomatic-parentheses" for both "Debug" and "Release." Now clean and recompile ( from if(self = [super init]) - LLVM warning! How are you dealing with it?)
I noted in the apple dev link that the following option should inhibit all warnings:
-w Inhibit all warning messages.

What determines sorting of files in a QFileDialog?

Users open files in our app through a QFileDialog. The order of the filenames is bizarre. What is determining the sorting order, and how can we make it sort by filenames, or otherwise impose our own sorting, perhaps giving it a pointer to our own comparison function?
The documentation and online forums haven't been helpful. Unless it's well hidden, there doesn't seem to be any sorting method, property, etc.
This is a primarily Linux app, but also runs on Macs. (I know nothing about Mac.)
Here is the juicy part of the source code:
QtFileDialog chooser(parent, caption, directory, filter);
/// QtFileDialog is our class derived from QFileDialog
chooser.setModal(true);
chooser.setAcceptMode(acceptMode);
chooser.setFileMode(fileMode);
QStringList hist = chooser.history();
chooser.setHistory(hist);
/* point "x" */
if(chooser.exec()) {
QStringList files = chooser.selectedFiles();
...blah blah blah...
From one of the answers, I tried an evil experiment, adding this ill-informed guesswork code at "point x":
QSortFilterProxyModel *sorter = new QSortFilterProxyModel();
sorter->sort(1); // ???
chooser.setProxyModel(sorter);
But this crashed spectacularly at a point about 33 subroutine calls deep from this level of code. I admit, even after reading the Qt4 documentation and sample code, I have no idea of the proper usage of QSortFilterProxyModel.
Are you using QFileDialog by calling exec()? If you are, you should have a button to switch the view to Detail View. This will give you some column headers that you can click on to sort the files. It should remember that mode the next time the dialog opens but you can force it by calling setViewMode(QFileDialog::Detail) before calling exec().
An alternative is to call the static function QFileDialog::getOpenFileName() which will open a file dialog that is native to the OS on which you are running. Your users may like the familiarity of this option better.
Update 1:
About sort order in screen cap from OP:
This screen capture is actually showing a sorted list. I don't know if the listing behaviour is originating from the Qt dialog or the underlying file system but I know Windows XP and later do it this way.
When sorting filenames with embedded numbers, any runs of consecutive digits are treated as a single number. With the more classic plain string sorting, files would be sorted like this:
A_A_10e0
A_A_9a05
Going character by character, the first 1 sorts before the 9.
.. But with numerical interpretation (as in Windows 7 at least), they are sorted as:
A_A_9a05
A_A_10e0
The 9 sorts before the 10.
So, the sorting you are seeing is alphabetical with numerical interpretation and not just straight character by character. Some deep digging may be required to see if that is Qt behaviour or OS behaviour and whether or not it can be configured.
Update 2:
The QSortFilterProxyModel will sort the strings alphabetically by default so there is not much work to using it to get the behavior you are looking for. Use the following code where you have "point x" in your example.. (you almost had it :)
QSortFilterProxyModel *sorter = new QSortFilterProxyModel();
sorter->setDynamicSortFilter(true); // This ensures the proxy will resort when the model changes
chooser.setProxyModel(sorter);
I think what you need to do is create a QSortFilterProxyModel which you then set in your QFileDialog with QFileDialog::setProxyModel(QAbstractProxyModel * proxyModel)
Here are some relevant links to the Qt 4.6 docs about it.
http://doc.trolltech.com/4.6/qfiledialog.html#setProxyModel
http://doc.trolltech.com/4.6/qsortfilterproxymodel.html#details
I don't think it depends upon the implementation of Qt libraries... But upon the Native OS implementation..
For example in Windows,
if you use QFileDialog, it will display the Files and Directories by Name sorted.. It is the same when used in other applications. In the sense that, if you try to open a file through MS- Word, it indeed displays the Files and directories as Name sorted by default..
And am not sure about other environments since am not used to them...
But in Windows, you can change the sorted order by right-click in the area of Files and Directories display and can select the options you like.. For e.g like Name,size,type, modified... And also which is similar, when you use an MS-Word application...
So, I believe it does depend on the Native OS implementation and not on QFileDialog's...

Resources