1 /* 2 Copyright (C) 2005-2008 Remon Sijrier 3 4 This file is part of Traverso 5 6 Traverso is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 20 */ 21 22 #ifndef INPUTENGINE_H 23 #define INPUTENGINE_H 24 25 26 #include <QKeyEvent> 27 #include <QWheelEvent> 28 #include <QString> 29 #include <QObject> 30 #include <QTimer> 31 #include <QHash> 32 #include <QStringList> 33 34 35 class ContextItem; 36 class Command; 37 class CommandPlugin; 38 39 static const int FKEY = 0; // <K> - press one key fast 40 static const int FKEY2 = 1; // <KK> - press two keys fast, together 41 static const int HOLDKEY = 2; // [K] - Hold one key 42 static const int HKEY2 = 3; // [KK] - Hold two keys, together 43 static const int D_FKEY = 4; // <<K>> - double press one key fast 44 static const int D_FKEY2 = 5; // <<KK>> - double press two keys fast, together 45 static const int FHKEY = 6; // <[K]> - press fast and then hold one key 46 static const int FHKEY2 = 7; // <[KK]> - press fast and then hold two keys together 47 static const int S_FKEY_FKEY = 8; // >K>K - press one key and then other key fast and sequentially 48 static const int S_FKEY_FKEY2 = 9; // >K>KK - press one key and then two other keys fast and sequentially 49 static const int S_FKEY2_FKEY = 10; // >KK>K - press two keys and then another one fast and sequentially 50 static const int S_FKEY2_FKEY2 = 11; // >KK>KK - press two keys and then another one fast and sequentially 51 static const int S_FKEY_HKEY = 12; // >K[K] - press fastly one key and then hold another key, sequentially 52 static const int S_FKEY_HKEY2 = 13; // >K[KK] - press fastly one key and then hold two ther ones, sequentially 53 static const int S_FKEY2_HKEY = 14; // >KK[K] - press two keys together fastly and then hold a third one, sequentially 54 static const int S_FKEY2_HKEY2 = 15; // >KK[KK] - press two keys together fastly and then hold a third one, sequentially 55 56 // internal class used for qt event catching 57 class EventCatcher : public QObject 58 { 59 Q_OBJECT 60 public: 61 EventCatcher(); 62 63 QTimer holdTimer; 64 QTimer clearOutputTimer; 65 QTimer secondChanceTimer; 66 67 public slots: 68 void assume_hold(); 69 void quit_second_chance(); 70 void clear_output(); 71 }; 72 73 74 75 struct IEAction 76 { 77 void render_key_sequence(const QString& key1, const QString& key2); 78 ~IEAction(); 79 struct Data { 80 QStringList modes; 81 QVariantList arguments; 82 QList<int > modifierkeys; 83 QString slotsignature; 84 QString pluginname; 85 QString commandname; 86 QString submenu; 87 bool useX; 88 bool useY; 89 int sortorder; 90 }; 91 92 QHash<QString, Data*> objects; 93 QHash<QString, Data*> objectUsingModifierKeys; 94 95 int type; 96 int fact1_key1; 97 int fact1_key2; 98 int fact2_key1; 99 int fact2_key2; 100 bool isInstantaneous; 101 QByteArray keySequence; 102 }; 103 104 105 struct MenuData { smallerMenuData106 static bool smaller(const MenuData left, const MenuData right ) 107 { 108 return left.sortorder < right.sortorder; 109 } greaterMenuData110 static bool greater(const MenuData* left, const MenuData* right ) 111 { 112 return left->sortorder > right->sortorder; 113 } 114 QString keysequence; 115 QString iedata; 116 QString description; 117 QString submenu; 118 int sortorder; 119 QList<int > modifierkeys; 120 }; 121 122 class InputEngine : public QObject 123 { 124 Q_OBJECT 125 public: 126 127 void catch_key_press(QKeyEvent *); 128 void catch_key_release(QKeyEvent *); 129 void catch_mousebutton_press( QMouseEvent * e ); 130 void catch_mousebutton_release( QMouseEvent * e ); 131 void catch_mousebutton_doubleclick( QMouseEvent * e ); 132 void catch_scroll(QWheelEvent * e ); 133 134 int collected_number(); 135 136 bool is_jogging(); 137 bool is_holding(); 138 139 QList<MenuData > create_menudata_for(QObject* item); 140 Command* get_holding_command() const; 141 void create_menudata_for_metaobject(const QMetaObject* mo, QList<MenuData >& list) const; 142 143 int broadcast_action_from_contextmenu(const QString& name); 144 145 void jog(); 146 void bypass_jog_until_mouse_movements_exceeded_manhattenlength(int length=35); 147 148 void activate(); 149 void suspend(); 150 void clear_modifier_keys(); 151 152 Command* succes(); 153 Command* failure(); 154 Command* did_not_implement(); 155 156 157 int init_map(const QString& mapFilename); 158 159 void set_clear_time(int time); 160 void set_hold_sensitiveness(int factor); 161 void set_double_fact_interval(int time); 162 163 void register_command_plugin(CommandPlugin* plugin, const QString& pluginName); 164 165 166 private: 167 InputEngine(); InputEngine(const InputEngine &)168 InputEngine(const InputEngine&) : QObject() {} 169 ~InputEngine(); 170 171 static const int STACK_SIZE = 4; 172 static const int MAX_ACTIONS = 300; 173 static const int PRESS_EVENT = 1; 174 static const int RELEASE_EVENT = 2; 175 176 enum BroadcastResult { 177 SUCCES=1, 178 FAILURE=2, 179 DIDNOTIMPLEMENT=3 180 }; 181 182 183 QList<IEAction* > m_ieActions; 184 QList<int> m_modifierKeys; 185 QList<int> m_activeModifierKeys; 186 QHash<QString, CommandPlugin*> m_commandplugins; 187 QHash<QString, int> m_modes; 188 EventCatcher catcher; 189 Command* holdingCommand; 190 QString sCollectedNumber; 191 QPoint m_jogBypassPos; 192 193 194 bool active; 195 bool isHolding; 196 bool isPressEventLocked; 197 bool isHoldingOutput; 198 bool isFirstFact; 199 bool isDoubleKey; 200 bool isJogging; 201 bool m_cancelHold; 202 bool m_bypassJog; 203 204 int fact1_k1; 205 int fact1_k2; 206 int fact2_k1; 207 int fact2_k2; 208 int fact1Type; 209 int wholeMapIndex; 210 int wholeActionType; 211 int collectedNumber; 212 int stackIndex; 213 int eventType[STACK_SIZE]; 214 int eventStack[STACK_SIZE]; 215 int pressEventCounter; // that avoid more than 2 press events in a same fact 216 int pairOf2; 217 int pairOf3; 218 int clearTime; 219 int assumeHoldTime; 220 int doubleFactWaitTime; 221 long eventTime[STACK_SIZE]; 222 int m_broadcastResult; 223 int m_unbypassJogDistance; 224 225 bool is_fake( int keyval); 226 int identify_first_fact(); 227 int identify_first_and_second_facts_together(); 228 void push_event(int pType, int pKey); 229 void press_checker(); 230 void release_checker(); 231 void push_fact( int k1 , int k2); 232 void give_a_chance_for_second_fact(); 233 void dispatch_action(int mapIndex); 234 void dispatch_hold(); 235 void finish_hold(); 236 void conclusion(); 237 void hold_output(); 238 void stop_collecting(); 239 bool check_number_collection(int eventcode); 240 241 //! call the slot that handler a given action 242 int broadcast_action(IEAction* action, bool autorepeat=false, bool fromContextMenu=false); 243 244 void set_jogging(bool jog); 245 void reset(); 246 void process_press_event(int eventcode, bool isAutoRepeat=false); 247 void process_release_event(int eventcode); 248 int find_index_for_instant_fkey( int key ); 249 int find_index_for_instant_fkey2( int key1, int key2 ); 250 int find_index_for_single_fact(int type, int key1, int key2); 251 bool is_modifier_keyfact(int eventcode); 252 253 int holdEventCode; 254 255 friend class EventCatcher; 256 257 // allow this function to create one instance 258 friend InputEngine& ie(); 259 }; 260 261 // use this function to get the InputEngine object 262 InputEngine& ie(); 263 264 265 #endif 266 267 //eof 268