GUI Programming: QT4 Event Preeption Part 2-A (temp)
Posted 05-02-2012 at 08:32 PM by rainbowsally
Updated 05-04-2012 at 11:33 AM by rainbowsally (QA check failed ;-))
Updated 05-04-2012 at 11:33 AM by rainbowsally (QA check failed ;-))
[Corrected hash algorithm to return -1 for null string (aka "") input. May 4, 2012]
Today's features
This example is complicated enough to be but actually is not quite ready for prime time, but I do want to point out the advantage of creating hash values for speeding up text searches in tables of data. See the utils.cpp implementation below.
Also, we have a slightly more user friendly (?) implementation of a QApplication subclass (named LQApp) that adds some features for chaining event handlers at the application level.
Consider this to be just an example. We'll eventually figure out how to deal with the recursion problem in a less creative way. ;-)
Let's start with the utils.cpp file which goes into a subdir named src/lib and will be included in other sources to avoid the necessity of using a more complicate linkage scheme. If using mc2, type 'mc2 -fetch qt4' and set 'OUTNAME = MULTI' because there are two executable generated.
Here's the end of a dump from link-test which uses the lib/utils.cpp functions.
Here we go.
file: src/lib/utils.cpp
Continued in part 2-B
Today's features
- conditional compilation (OLD_SCHOOL vs. ?)
- discovery of a potential recursion problem in preemptive event handling (QTextEdit)
This example is complicated enough to be but actually is not quite ready for prime time, but I do want to point out the advantage of creating hash values for speeding up text searches in tables of data. See the utils.cpp implementation below.
Also, we have a slightly more user friendly (?) implementation of a QApplication subclass (named LQApp) that adds some features for chaining event handlers at the application level.
Consider this to be just an example. We'll eventually figure out how to deal with the recursion problem in a less creative way. ;-)
Let's start with the utils.cpp file which goes into a subdir named src/lib and will be included in other sources to avoid the necessity of using a more complicate linkage scheme. If using mc2, type 'mc2 -fetch qt4' and set 'OUTNAME = MULTI' because there are two executable generated.
Here's the end of a dump from link-test which uses the lib/utils.cpp functions.
Code:
... (and then at the end of the dump) ... keyval: Ox1100020 keyname: Key_Camera keyval: Ox1100021 keyname: Key_CameraFocus keyval: Ox1FFFFFF keyname: Key_unknown Total lookups = 365 Total string comparisons = 66795 Total false hits = 0
file: src/lib/utils.cpp
Code:
// utils.cpp #include <QTextEdit> #include <stdio.h> #include "utils.h" /* lq_hash32() is very similar to the ghash algorithm used to look up names in shared objects except that it always sets the high bit so no '0' value can be computed. While it could be argued that hashing is an extra step and it doesn't result in unique ids in all cases, the fact that we can compare ids in a for() loop without calling strcmp() except to do a double check saves quite a bit of time for large lists. If the lists to look through are super-long more time can be saved by creating 'buckets' or 'threads' (where I come from) computed from the hash id. In the following example there's just one 'thread' and it's a fixed size. Obviously, if you need them to 'grow' you need to allocate and reallocate memory for these or use linked lists; */ int lq_hash32(const char* name) { const char *p = name; if(!p) return 0; // returns 0 if null pointer int h = *p; if (h) { for (p += 1; *p != 0; p++) h = ((h << 5) - h) + *p; } // return h < 0 ? h : -h; // corrected per ntubski's observations -rs return h < 0 ? h : ~h; } // a temp definition to help convert from header data to a struct definition #define COMPILE_HASH_ENTRY(name, value) \ {0, #name, value} HASH_ENTRY lq_key_name_tbl[] = { // misc keys COMPILE_HASH_ENTRY(Key_Escape, 0x01000000), COMPILE_HASH_ENTRY(Key_Tab, 0x01000001), COMPILE_HASH_ENTRY(Key_Backtab, 0x01000002), COMPILE_HASH_ENTRY(Key_Backspace, 0x01000003), COMPILE_HASH_ENTRY(Key_Return, 0x01000004), COMPILE_HASH_ENTRY(Key_Enter, 0x01000005), COMPILE_HASH_ENTRY(Key_Insert, 0x01000006), COMPILE_HASH_ENTRY(Key_Delete, 0x01000007), COMPILE_HASH_ENTRY(Key_Pause, 0x01000008), COMPILE_HASH_ENTRY(Key_Print, 0x01000009), COMPILE_HASH_ENTRY(Key_SysReq, 0x0100000a), COMPILE_HASH_ENTRY(Key_Clear, 0x0100000b), // cursor movement COMPILE_HASH_ENTRY(Key_Home, 0x01000010), COMPILE_HASH_ENTRY(Key_End, 0x01000011), COMPILE_HASH_ENTRY(Key_Left, 0x01000012), COMPILE_HASH_ENTRY(Key_Up, 0x01000013), COMPILE_HASH_ENTRY(Key_Right, 0x01000014), COMPILE_HASH_ENTRY(Key_Down, 0x01000015), COMPILE_HASH_ENTRY(Key_PageUp, 0x01000016), COMPILE_HASH_ENTRY(Key_PageDown, 0x01000017), // modifiers COMPILE_HASH_ENTRY(Key_Shift, 0x01000020), COMPILE_HASH_ENTRY(Key_Control, 0x01000021), COMPILE_HASH_ENTRY(Key_Meta, 0x01000022), COMPILE_HASH_ENTRY(Key_Alt, 0x01000023), COMPILE_HASH_ENTRY(Key_CapsLock, 0x01000024), COMPILE_HASH_ENTRY(Key_NumLock, 0x01000025), COMPILE_HASH_ENTRY(Key_ScrollLock, 0x01000026), // function keys COMPILE_HASH_ENTRY(Key_F1, 0x01000030), COMPILE_HASH_ENTRY(Key_F2, 0x01000031), COMPILE_HASH_ENTRY(Key_F3, 0x01000032), COMPILE_HASH_ENTRY(Key_F4, 0x01000033), COMPILE_HASH_ENTRY(Key_F5, 0x01000034), COMPILE_HASH_ENTRY(Key_F6, 0x01000035), COMPILE_HASH_ENTRY(Key_F7, 0x01000036), COMPILE_HASH_ENTRY(Key_F8, 0x01000037), COMPILE_HASH_ENTRY(Key_F9, 0x01000038), COMPILE_HASH_ENTRY(Key_F10, 0x01000039), COMPILE_HASH_ENTRY(Key_F11, 0x0100003a), COMPILE_HASH_ENTRY(Key_F12, 0x0100003b), COMPILE_HASH_ENTRY(Key_F13, 0x0100003c), COMPILE_HASH_ENTRY(Key_F14, 0x0100003d), COMPILE_HASH_ENTRY(Key_F15, 0x0100003e), COMPILE_HASH_ENTRY(Key_F16, 0x0100003f), COMPILE_HASH_ENTRY(Key_F17, 0x01000040), COMPILE_HASH_ENTRY(Key_F18, 0x01000041), COMPILE_HASH_ENTRY(Key_F19, 0x01000042), COMPILE_HASH_ENTRY(Key_F20, 0x01000043), COMPILE_HASH_ENTRY(Key_F21, 0x01000044), COMPILE_HASH_ENTRY(Key_F22, 0x01000045), COMPILE_HASH_ENTRY(Key_F23, 0x01000046), COMPILE_HASH_ENTRY(Key_F24, 0x01000047), // F25 .. F35 only on X11 COMPILE_HASH_ENTRY(Key_F25, 0x01000048), COMPILE_HASH_ENTRY(Key_F26, 0x01000049), COMPILE_HASH_ENTRY(Key_F27, 0x0100004a), COMPILE_HASH_ENTRY(Key_F28, 0x0100004b), COMPILE_HASH_ENTRY(Key_F29, 0x0100004c), COMPILE_HASH_ENTRY(Key_F30, 0x0100004d), COMPILE_HASH_ENTRY(Key_F31, 0x0100004e), COMPILE_HASH_ENTRY(Key_F32, 0x0100004f), COMPILE_HASH_ENTRY(Key_F33, 0x01000050), COMPILE_HASH_ENTRY(Key_F34, 0x01000051), COMPILE_HASH_ENTRY(Key_F35, 0x01000052), // extra keys COMPILE_HASH_ENTRY(Key_Super_L, 0x01000053), COMPILE_HASH_ENTRY(Key_Super_R, 0x01000054), COMPILE_HASH_ENTRY(Key_Menu, 0x01000055), COMPILE_HASH_ENTRY(Key_Hyper_L, 0x01000056), COMPILE_HASH_ENTRY(Key_Hyper_R, 0x01000057), COMPILE_HASH_ENTRY(Key_Help, 0x01000058), COMPILE_HASH_ENTRY(Key_Direction_L, 0x01000059), COMPILE_HASH_ENTRY(Key_Direction_R, 0x01000060), // 7 bit printable ASCII COMPILE_HASH_ENTRY(Key_Space, 0x20), COMPILE_HASH_ENTRY(Key_Any, Qt::Key_Space), COMPILE_HASH_ENTRY(Key_Exclam, 0x21), COMPILE_HASH_ENTRY(Key_QuoteDbl, 0x22), COMPILE_HASH_ENTRY(Key_NumberSign, 0x23), COMPILE_HASH_ENTRY(Key_Dollar, 0x24), COMPILE_HASH_ENTRY(Key_Percent, 0x25), COMPILE_HASH_ENTRY(Key_Ampersand, 0x26), COMPILE_HASH_ENTRY(Key_Apostrophe, 0x27), COMPILE_HASH_ENTRY(Key_ParenLeft, 0x28), COMPILE_HASH_ENTRY(Key_ParenRight, 0x29), COMPILE_HASH_ENTRY(Key_Asterisk, 0x2a), COMPILE_HASH_ENTRY(Key_Plus, 0x2b), COMPILE_HASH_ENTRY(Key_Comma, 0x2c), COMPILE_HASH_ENTRY(Key_Minus, 0x2d), COMPILE_HASH_ENTRY(Key_Period, 0x2e), COMPILE_HASH_ENTRY(Key_Slash, 0x2f), COMPILE_HASH_ENTRY(Key_0, 0x30), COMPILE_HASH_ENTRY(Key_1, 0x31), COMPILE_HASH_ENTRY(Key_2, 0x32), COMPILE_HASH_ENTRY(Key_3, 0x33), COMPILE_HASH_ENTRY(Key_4, 0x34), COMPILE_HASH_ENTRY(Key_5, 0x35), COMPILE_HASH_ENTRY(Key_6, 0x36), COMPILE_HASH_ENTRY(Key_7, 0x37), COMPILE_HASH_ENTRY(Key_8, 0x38), COMPILE_HASH_ENTRY(Key_9, 0x39), COMPILE_HASH_ENTRY(Key_Colon, 0x3a), COMPILE_HASH_ENTRY(Key_Semicolon, 0x3b), COMPILE_HASH_ENTRY(Key_Less, 0x3c), COMPILE_HASH_ENTRY(Key_Equal, 0x3d), COMPILE_HASH_ENTRY(Key_Greater, 0x3e), COMPILE_HASH_ENTRY(Key_Question, 0x3f), COMPILE_HASH_ENTRY(Key_At, 0x40), COMPILE_HASH_ENTRY(Key_A, 0x41), COMPILE_HASH_ENTRY(Key_B, 0x42), COMPILE_HASH_ENTRY(Key_C, 0x43), COMPILE_HASH_ENTRY(Key_D, 0x44), COMPILE_HASH_ENTRY(Key_E, 0x45), COMPILE_HASH_ENTRY(Key_F, 0x46), COMPILE_HASH_ENTRY(Key_G, 0x47), COMPILE_HASH_ENTRY(Key_H, 0x48), COMPILE_HASH_ENTRY(Key_I, 0x49), COMPILE_HASH_ENTRY(Key_J, 0x4a), COMPILE_HASH_ENTRY(Key_K, 0x4b), COMPILE_HASH_ENTRY(Key_L, 0x4c), COMPILE_HASH_ENTRY(Key_M, 0x4d), COMPILE_HASH_ENTRY(Key_N, 0x4e), COMPILE_HASH_ENTRY(Key_O, 0x4f), COMPILE_HASH_ENTRY(Key_P, 0x50), COMPILE_HASH_ENTRY(Key_Q, 0x51), COMPILE_HASH_ENTRY(Key_R, 0x52), COMPILE_HASH_ENTRY(Key_S, 0x53), COMPILE_HASH_ENTRY(Key_T, 0x54), COMPILE_HASH_ENTRY(Key_U, 0x55), COMPILE_HASH_ENTRY(Key_V, 0x56), COMPILE_HASH_ENTRY(Key_W, 0x57), COMPILE_HASH_ENTRY(Key_X, 0x58), COMPILE_HASH_ENTRY(Key_Y, 0x59), COMPILE_HASH_ENTRY(Key_Z, 0x5a), COMPILE_HASH_ENTRY(Key_BracketLeft, 0x5b), COMPILE_HASH_ENTRY(Key_Backslash, 0x5c), COMPILE_HASH_ENTRY(Key_BracketRight, 0x5d), COMPILE_HASH_ENTRY(Key_AsciiCircum, 0x5e), COMPILE_HASH_ENTRY(Key_Underscore, 0x5f), COMPILE_HASH_ENTRY(Key_QuoteLeft, 0x60), COMPILE_HASH_ENTRY(Key_BraceLeft, 0x7b), COMPILE_HASH_ENTRY(Key_Bar, 0x7c), COMPILE_HASH_ENTRY(Key_BraceRight, 0x7d), COMPILE_HASH_ENTRY(Key_AsciiTilde, 0x7e), COMPILE_HASH_ENTRY(Key_nobreakspace, 0x0a0), COMPILE_HASH_ENTRY(Key_exclamdown, 0x0a1), COMPILE_HASH_ENTRY(Key_cent, 0x0a2), COMPILE_HASH_ENTRY(Key_sterling, 0x0a3), COMPILE_HASH_ENTRY(Key_currency, 0x0a4), COMPILE_HASH_ENTRY(Key_yen, 0x0a5), COMPILE_HASH_ENTRY(Key_brokenbar, 0x0a6), COMPILE_HASH_ENTRY(Key_section, 0x0a7), COMPILE_HASH_ENTRY(Key_diaeresis, 0x0a8), COMPILE_HASH_ENTRY(Key_copyright, 0x0a9), COMPILE_HASH_ENTRY(Key_ordfeminine, 0x0aa), COMPILE_HASH_ENTRY(Key_guillemotleft, 0x0ab), COMPILE_HASH_ENTRY(Key_notsign, 0x0ac), COMPILE_HASH_ENTRY(Key_hyphen, 0x0ad), COMPILE_HASH_ENTRY(Key_registered, 0x0ae), COMPILE_HASH_ENTRY(Key_macron, 0x0af), COMPILE_HASH_ENTRY(Key_degree, 0x0b0), COMPILE_HASH_ENTRY(Key_plusminus, 0x0b1), COMPILE_HASH_ENTRY(Key_twosuperior, 0x0b2), COMPILE_HASH_ENTRY(Key_threesuperior, 0x0b3), COMPILE_HASH_ENTRY(Key_acute, 0x0b4), COMPILE_HASH_ENTRY(Key_mu, 0x0b5), COMPILE_HASH_ENTRY(Key_paragraph, 0x0b6), COMPILE_HASH_ENTRY(Key_periodcentered, 0x0b7), COMPILE_HASH_ENTRY(Key_cedilla, 0x0b8), COMPILE_HASH_ENTRY(Key_onesuperior, 0x0b9), COMPILE_HASH_ENTRY(Key_masculine, 0x0ba), COMPILE_HASH_ENTRY(Key_guillemotright, 0x0bb), COMPILE_HASH_ENTRY(Key_onequarter, 0x0bc), COMPILE_HASH_ENTRY(Key_onehalf, 0x0bd), COMPILE_HASH_ENTRY(Key_threequarters, 0x0be), COMPILE_HASH_ENTRY(Key_questiondown, 0x0bf), COMPILE_HASH_ENTRY(Key_Agrave, 0x0c0), COMPILE_HASH_ENTRY(Key_Aacute, 0x0c1), COMPILE_HASH_ENTRY(Key_Acircumflex, 0x0c2), COMPILE_HASH_ENTRY(Key_Atilde, 0x0c3), COMPILE_HASH_ENTRY(Key_Adiaeresis, 0x0c4), COMPILE_HASH_ENTRY(Key_Aring, 0x0c5), COMPILE_HASH_ENTRY(Key_AE, 0x0c6), COMPILE_HASH_ENTRY(Key_Ccedilla, 0x0c7), COMPILE_HASH_ENTRY(Key_Egrave, 0x0c8), COMPILE_HASH_ENTRY(Key_Eacute, 0x0c9), COMPILE_HASH_ENTRY(Key_Ecircumflex, 0x0ca), COMPILE_HASH_ENTRY(Key_Ediaeresis, 0x0cb), COMPILE_HASH_ENTRY(Key_Igrave, 0x0cc), COMPILE_HASH_ENTRY(Key_Iacute, 0x0cd), COMPILE_HASH_ENTRY(Key_Icircumflex, 0x0ce), COMPILE_HASH_ENTRY(Key_Idiaeresis, 0x0cf), COMPILE_HASH_ENTRY(Key_ETH, 0x0d0), COMPILE_HASH_ENTRY(Key_Ntilde, 0x0d1), COMPILE_HASH_ENTRY(Key_Ograve, 0x0d2), COMPILE_HASH_ENTRY(Key_Oacute, 0x0d3), COMPILE_HASH_ENTRY(Key_Ocircumflex, 0x0d4), COMPILE_HASH_ENTRY(Key_Otilde, 0x0d5), COMPILE_HASH_ENTRY(Key_Odiaeresis, 0x0d6), COMPILE_HASH_ENTRY(Key_multiply, 0x0d7), COMPILE_HASH_ENTRY(Key_Ooblique, 0x0d8), COMPILE_HASH_ENTRY(Key_Ugrave, 0x0d9), COMPILE_HASH_ENTRY(Key_Uacute, 0x0da), COMPILE_HASH_ENTRY(Key_Ucircumflex, 0x0db), COMPILE_HASH_ENTRY(Key_Udiaeresis, 0x0dc), COMPILE_HASH_ENTRY(Key_Yacute, 0x0dd), COMPILE_HASH_ENTRY(Key_THORN, 0x0de), COMPILE_HASH_ENTRY(Key_ssharp, 0x0df), COMPILE_HASH_ENTRY(Key_division, 0x0f7), COMPILE_HASH_ENTRY(Key_ydiaeresis, 0x0ff), // see the headers if you need international and multi-key char composition. // multimedia/internet keys - ignored by default. COMPILE_HASH_ENTRY(Key_Back , 0x01000061), COMPILE_HASH_ENTRY(Key_Forward , 0x01000062), COMPILE_HASH_ENTRY(Key_Stop , 0x01000063), COMPILE_HASH_ENTRY(Key_Refresh , 0x01000064), COMPILE_HASH_ENTRY(Key_VolumeDown, 0x01000070), COMPILE_HASH_ENTRY(Key_VolumeMute , 0x01000071), COMPILE_HASH_ENTRY(Key_VolumeUp, 0x01000072), COMPILE_HASH_ENTRY(Key_BassBoost, 0x01000073), COMPILE_HASH_ENTRY(Key_BassUp, 0x01000074), COMPILE_HASH_ENTRY(Key_BassDown, 0x01000075), COMPILE_HASH_ENTRY(Key_TrebleUp, 0x01000076), COMPILE_HASH_ENTRY(Key_TrebleDown, 0x01000077), COMPILE_HASH_ENTRY(Key_MediaPlay , 0x01000080), COMPILE_HASH_ENTRY(Key_MediaStop , 0x01000081), COMPILE_HASH_ENTRY(Key_MediaPrevious , 0x01000082), COMPILE_HASH_ENTRY(Key_MediaNext , 0x01000083), COMPILE_HASH_ENTRY(Key_MediaRecord, 0x01000084), COMPILE_HASH_ENTRY(Key_MediaPause, 0x1000085), COMPILE_HASH_ENTRY(Key_MediaTogglePlayPause, 0x1000086), COMPILE_HASH_ENTRY(Key_HomePage , 0x01000090), COMPILE_HASH_ENTRY(Key_Favorites , 0x01000091), COMPILE_HASH_ENTRY(Key_Search , 0x01000092), COMPILE_HASH_ENTRY(Key_Standby, 0x01000093), COMPILE_HASH_ENTRY(Key_OpenUrl, 0x01000094), COMPILE_HASH_ENTRY(Key_LaunchMail , 0x010000a0), COMPILE_HASH_ENTRY(Key_LaunchMedia, 0x010000a1), COMPILE_HASH_ENTRY(Key_Launch0 , 0x010000a2), COMPILE_HASH_ENTRY(Key_Launch1 , 0x010000a3), COMPILE_HASH_ENTRY(Key_Launch2 , 0x010000a4), COMPILE_HASH_ENTRY(Key_Launch3 , 0x010000a5), COMPILE_HASH_ENTRY(Key_Launch4 , 0x010000a6), COMPILE_HASH_ENTRY(Key_Launch5 , 0x010000a7), COMPILE_HASH_ENTRY(Key_Launch6 , 0x010000a8), COMPILE_HASH_ENTRY(Key_Launch7 , 0x010000a9), COMPILE_HASH_ENTRY(Key_Launch8 , 0x010000aa), COMPILE_HASH_ENTRY(Key_Launch9 , 0x010000ab), COMPILE_HASH_ENTRY(Key_LaunchA , 0x010000ac), COMPILE_HASH_ENTRY(Key_LaunchB , 0x010000ad), COMPILE_HASH_ENTRY(Key_LaunchC , 0x010000ae), COMPILE_HASH_ENTRY(Key_LaunchD , 0x010000af), COMPILE_HASH_ENTRY(Key_LaunchE , 0x010000b0), COMPILE_HASH_ENTRY(Key_LaunchF , 0x010000b1), COMPILE_HASH_ENTRY(Key_MonBrightnessUp, 0x010000b2), COMPILE_HASH_ENTRY(Key_MonBrightnessDown, 0x010000b3), COMPILE_HASH_ENTRY(Key_KeyboardLightOnOff, 0x010000b4), COMPILE_HASH_ENTRY(Key_KeyboardBrightnessUp, 0x010000b5), COMPILE_HASH_ENTRY(Key_KeyboardBrightnessDown, 0x010000b6), COMPILE_HASH_ENTRY(Key_PowerOff, 0x010000b7), COMPILE_HASH_ENTRY(Key_WakeUp, 0x010000b8), COMPILE_HASH_ENTRY(Key_Eject, 0x010000b9), COMPILE_HASH_ENTRY(Key_ScreenSaver, 0x010000ba), COMPILE_HASH_ENTRY(Key_WWW, 0x010000bb), COMPILE_HASH_ENTRY(Key_Memo, 0x010000bc), COMPILE_HASH_ENTRY(Key_LightBulb, 0x010000bd), COMPILE_HASH_ENTRY(Key_Shop, 0x010000be), COMPILE_HASH_ENTRY(Key_History, 0x010000bf), COMPILE_HASH_ENTRY(Key_AddFavorite, 0x010000c0), COMPILE_HASH_ENTRY(Key_HotLinks, 0x010000c1), COMPILE_HASH_ENTRY(Key_BrightnessAdjust, 0x010000c2), COMPILE_HASH_ENTRY(Key_Finance, 0x010000c3), COMPILE_HASH_ENTRY(Key_Community, 0x010000c4), COMPILE_HASH_ENTRY(Key_AudioRewind, 0x010000c5), COMPILE_HASH_ENTRY(Key_BackForward, 0x010000c6), COMPILE_HASH_ENTRY(Key_ApplicationLeft, 0x010000c7), COMPILE_HASH_ENTRY(Key_ApplicationRight, 0x010000c8), COMPILE_HASH_ENTRY(Key_Book, 0x010000c9), COMPILE_HASH_ENTRY(Key_CD, 0x010000ca), COMPILE_HASH_ENTRY(Key_Calculator, 0x010000cb), COMPILE_HASH_ENTRY(Key_ToDoList, 0x010000cc), COMPILE_HASH_ENTRY(Key_ClearGrab, 0x010000cd), COMPILE_HASH_ENTRY(Key_Close, 0x010000ce), COMPILE_HASH_ENTRY(Key_Copy, 0x010000cf), COMPILE_HASH_ENTRY(Key_Cut, 0x010000d0), COMPILE_HASH_ENTRY(Key_Display, 0x010000d1), COMPILE_HASH_ENTRY(Key_DOS, 0x010000d2), COMPILE_HASH_ENTRY(Key_Documents, 0x010000d3), COMPILE_HASH_ENTRY(Key_Excel, 0x010000d4), COMPILE_HASH_ENTRY(Key_Explorer, 0x010000d5), COMPILE_HASH_ENTRY(Key_Game, 0x010000d6), COMPILE_HASH_ENTRY(Key_Go, 0x010000d7), COMPILE_HASH_ENTRY(Key_iTouch, 0x010000d8), COMPILE_HASH_ENTRY(Key_LogOff, 0x010000d9), COMPILE_HASH_ENTRY(Key_Market, 0x010000da), COMPILE_HASH_ENTRY(Key_Meeting, 0x010000db), COMPILE_HASH_ENTRY(Key_MenuKB, 0x010000dc), COMPILE_HASH_ENTRY(Key_MenuPB, 0x010000dd), COMPILE_HASH_ENTRY(Key_MySites, 0x010000de), COMPILE_HASH_ENTRY(Key_News, 0x010000df), COMPILE_HASH_ENTRY(Key_OfficeHome, 0x010000e0), COMPILE_HASH_ENTRY(Key_Option, 0x010000e1), COMPILE_HASH_ENTRY(Key_Paste, 0x010000e2), COMPILE_HASH_ENTRY(Key_Phone, 0x010000e3), COMPILE_HASH_ENTRY(Key_Calendar, 0x010000e4), COMPILE_HASH_ENTRY(Key_Reply, 0x010000e5), COMPILE_HASH_ENTRY(Key_Reload, 0x010000e6), COMPILE_HASH_ENTRY(Key_RotateWindows, 0x010000e7), COMPILE_HASH_ENTRY(Key_RotationPB, 0x010000e8), COMPILE_HASH_ENTRY(Key_RotationKB, 0x010000e9), COMPILE_HASH_ENTRY(Key_Save, 0x010000ea), COMPILE_HASH_ENTRY(Key_Send, 0x010000eb), COMPILE_HASH_ENTRY(Key_Spell, 0x010000ec), COMPILE_HASH_ENTRY(Key_SplitScreen, 0x010000ed), COMPILE_HASH_ENTRY(Key_Support, 0x010000ee), COMPILE_HASH_ENTRY(Key_TaskPane, 0x010000ef), COMPILE_HASH_ENTRY(Key_Terminal, 0x010000f0), COMPILE_HASH_ENTRY(Key_Tools, 0x010000f1), COMPILE_HASH_ENTRY(Key_Travel, 0x010000f2), COMPILE_HASH_ENTRY(Key_Video, 0x010000f3), COMPILE_HASH_ENTRY(Key_Word, 0x010000f4), COMPILE_HASH_ENTRY(Key_Xfer, 0x010000f5), COMPILE_HASH_ENTRY(Key_ZoomIn, 0x010000f6), COMPILE_HASH_ENTRY(Key_ZoomOut, 0x010000f7), COMPILE_HASH_ENTRY(Key_Away, 0x010000f8), COMPILE_HASH_ENTRY(Key_Messenger, 0x010000f9), COMPILE_HASH_ENTRY(Key_WebCam, 0x010000fa), COMPILE_HASH_ENTRY(Key_MailForward, 0x010000fb), COMPILE_HASH_ENTRY(Key_Pictures, 0x010000fc), COMPILE_HASH_ENTRY(Key_Music, 0x010000fd), COMPILE_HASH_ENTRY(Key_Battery, 0x010000fe), COMPILE_HASH_ENTRY(Key_Bluetooth, 0x010000ff), COMPILE_HASH_ENTRY(Key_WLAN, 0x01000100), COMPILE_HASH_ENTRY(Key_UWB, 0x01000101), COMPILE_HASH_ENTRY(Key_AudioForward, 0x01000102), COMPILE_HASH_ENTRY(Key_AudioRepeat, 0x01000103), COMPILE_HASH_ENTRY(Key_AudioRandomPlay, 0x01000104), COMPILE_HASH_ENTRY(Key_Subtitle, 0x01000105), COMPILE_HASH_ENTRY(Key_AudioCycleTrack, 0x01000106), COMPILE_HASH_ENTRY(Key_Time, 0x01000107), COMPILE_HASH_ENTRY(Key_Hibernate, 0x01000108), COMPILE_HASH_ENTRY(Key_View, 0x01000109), COMPILE_HASH_ENTRY(Key_TopMenu, 0x0100010a), COMPILE_HASH_ENTRY(Key_PowerDown, 0x0100010b), COMPILE_HASH_ENTRY(Key_Suspend, 0x0100010c), COMPILE_HASH_ENTRY(Key_ContrastAdjust, 0x0100010d), COMPILE_HASH_ENTRY(Key_LaunchG , 0x0100010e), COMPILE_HASH_ENTRY(Key_LaunchH , 0x0100010f), COMPILE_HASH_ENTRY(Key_MediaLast, 0x0100ffff), // Keypad navigation keys COMPILE_HASH_ENTRY(Key_Select, 0x01010000), COMPILE_HASH_ENTRY(Key_Yes, 0x01010001), COMPILE_HASH_ENTRY(Key_No, 0x01010002), // Newer misc keys COMPILE_HASH_ENTRY(Key_Cancel , 0x01020001), COMPILE_HASH_ENTRY(Key_Printer, 0x01020002), COMPILE_HASH_ENTRY(Key_Execute, 0x01020003), COMPILE_HASH_ENTRY(Key_Sleep , 0x01020004), COMPILE_HASH_ENTRY(Key_Play , 0x01020005), COMPILE_HASH_ENTRY(Key_Zoom , 0x01020006), // Device keys COMPILE_HASH_ENTRY(Key_Context1, 0x01100000), COMPILE_HASH_ENTRY(Key_Context2, 0x01100001), COMPILE_HASH_ENTRY(Key_Context3, 0x01100002), COMPILE_HASH_ENTRY(Key_Context4, 0x01100003), COMPILE_HASH_ENTRY(Key_Call, 0x01100004), COMPILE_HASH_ENTRY(Key_Hangup, 0x01100005), COMPILE_HASH_ENTRY(Key_Flip, 0x01100006), COMPILE_HASH_ENTRY(Key_ToggleCallHangup, 0x01100007), COMPILE_HASH_ENTRY(Key_VoiceDial, 0x01100008), COMPILE_HASH_ENTRY(Key_LastNumberRedial, 0x01100009), COMPILE_HASH_ENTRY(Key_Camera, 0x01100020), COMPILE_HASH_ENTRY(Key_CameraFocus, 0x01100021), COMPILE_HASH_ENTRY(Key_unknown, 0x01ffffff), {0, 0, 0}, }; #undef COMPILE_HASH_ENTRY int lq_key_name_tbl_hash_inited = 0; void init_lq_key_pairs() { for(HASH_ENTRY* p = lq_key_name_tbl;p->name != 0; p++) p->hashid = lq_hash32(p->name); lq_key_name_tbl_hash_inited++; } const char* qkey2name(uint value) { for(HASH_ENTRY* p = lq_key_name_tbl;p->name != 0; p++) { if(p->value == value) return p->name; } return "Key_unknown"; } #ifdef LOOKUP_TEST int hash_false_hits = 0; int hash_lookups = 0; int string_comparisons = 0; #endif uint qname2key(const char* name) { // only need hashes for names. if(!lq_key_name_tbl_hash_inited) init_lq_key_pairs(); int hashid = lq_hash32(name); // normal #ifndef LOOKUP_TEST for(HASH_ENTRY* p = lq_key_name_tbl;p->name != 0; p++) { if((p->hashid == hashid) && (strcmp(p->name, name) == 0)) return p->value; } // test #else int ctr = 0; hash_lookups ++; for(HASH_ENTRY* p = lq_key_name_tbl;p->name != 0; p++) { string_comparisons++; if(p->hashid == hashid) { ctr++; // id's match if (strcmp(p->name, name) == 0) { if(ctr > 1) { hash_false_hits += ctr -1; } return p->value; } // if } // if } #endif // LOOKUP_TEST return 0x01ffffff; // "Key_unknown"; } char* qmodkeys2name(uint value) { static char tmp[256]; *tmp = 0; if(value & 0x40000000) strcat(tmp, "Qt::GroupSwitchModifier | "); if(value & 0x20000000) strcat(tmp, "Qt::KeypadModifier | "); if(value & 0x10000000) strcat(tmp, "Qt::MetaModifier | "); if(value & 0x08000000) strcat(tmp, "Qt::AltModifier | "); if(value & 0x04000000) strcat(tmp, "Qt::ControlModifier | "); if(value & 0x02000000) strcat(tmp, "Qt::ShiftModifier | "); if(*tmp) strrchr(tmp, '|')[-1] = 0; else strcpy(tmp, "NONE"); return tmp; } ////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// // Here's a method extender for QTextEdit. These method // extenders don't contain any additional data, just // methods, so they don't have constructors or destructors // and everything is public so the original class functions // can be obtained through them and funcs or vars not // available publicly can be made accessible through this // interface by reimplimenting them as public. class LQTextEdit : public QTextEdit { public: int count(); // slist style, not implemented const char* get(int idx); // slist style, not implemented int position() { return QTextEdit::textCursor().position();} }; bool handle_return_key(QObject* p) { LQTextEdit* te = static_cast<LQTextEdit*>(p); QTextCursor tc = te->textCursor(); printf("Position: %d\n", te->position()); te->append("\n"); return true; // stop processing, this key is preempted }
Total Comments 2
Comments
-
Code:
int lq_hash32(const char* name) { const char *p = name; if(!p) return 0; // returns 0 if null pointer int h = *p; if (h) { for (p += 1; *p != 0; p++) h = ((h << 5) - h) + *p; } return h < 0 ? h : -h; // returns -1 if null string }
Posted 05-03-2012 at 04:51 PM by ntubski -
Hi ntubski.
Quote:By null string you mean the empty string? That would return 0 actually.
A null string returns a -1. Or...
Heh..
Again, you got me here. I should have used a ~ (not operator) to invert all the bits.
Thanks for the Quality Control check.
But the idea is to never have a 0 value in the table though, because that will be an indication that hash entry is the end of the array (as would be a null string in the table).
This algorithm also generates the hashes for the table which can't be done at compile-time so this ends up being important and you have helped me avoid finding this problem the hard way.
Thanks again. :-)Posted 05-04-2012 at 11:21 AM by rainbowsally