keyboardmodule.cpp 11.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
/*
This file is generated, but you can safely change it
until you run "gen_actor_source.py" with "--project" flag.

Generated file is just a skeleton for module contents.
You should change it corresponding to functionality.
*/

// Self include
#include "keyboardmodule.h"

// Kumir includes
13 14
#include <kumir2-libs/extensionsystem/kplugin.h>
#include <kumir2/plugininterface.h>
15 16

// Qt includes
Alexander A. Maly's avatar
Alexander A. Maly committed
17 18 19 20 21
#include <QWidget>
#include <QWidgetList>
#include <QApplication>
#include <QKeyEvent>
#include <QDebug>
22

Alexander A. Maly's avatar
Alexander A. Maly committed
23 24
namespace ActorKeyboard
{
25

Alexander A. Maly's avatar
Alexander A. Maly committed
26 27
KeyboardModule::KeyboardModule(ExtensionSystem::KPlugin *parent)
	: KeyboardModuleBase(parent)
28
{
Alexander A. Maly's avatar
Alexander A. Maly committed
29 30
	// Module constructor, called once on plugin load
	// TODO implement me
31 32 33 34
}

/* public static */ QList<ExtensionSystem::CommandLineParameter> KeyboardModule::acceptableCommandLineParameters()
{
Alexander A. Maly's avatar
Alexander A. Maly committed
35 36
	// See "src/shared/extensionsystem/commandlineparameter.h" for constructor details
	return QList<ExtensionSystem::CommandLineParameter>();
37 38 39 40
}

/* public slot */ void KeyboardModule::changeGlobalState(ExtensionSystem::GlobalState old, ExtensionSystem::GlobalState current)
{
Alexander A. Maly's avatar
Alexander A. Maly committed
41
	// Called when changed kumir state. The states are defined as enum ExtensionSystem::GlobalState:
42

Alexander A. Maly's avatar
Alexander A. Maly committed
43 44 45 46 47
	if (Shared::PluginInterface::GS_Running == old) {
		if (Shared::PluginInterface::GS_Observe == current || Shared::PluginInterface::GS_Unlocked == current) {
			finalizeRun();
		}
	}
48 49
}

Alexander A. Maly's avatar
Alexander A. Maly committed
50
/* public slot */ void KeyboardModule::loadActorData(QIODevice *source)
51
{
Alexander A. Maly's avatar
Alexander A. Maly committed
52 53 54
	// Set actor specific data (like environment)
	// The source should be ready-to-read QIODevice like QBuffer or QFile
	Q_UNUSED(source);  // By default do nothing
55 56 57

}

Alexander A. Maly's avatar
Alexander A. Maly committed
58
/* public */ QWidget *KeyboardModule::mainWidget() const
59
{
Alexander A. Maly's avatar
Alexander A. Maly committed
60 61 62 63 64
	// Returns module main view widget, or nullptr if there is no any views
	// NOTE: the method is const and might be called at any time,
	//       so DO NOT create widget here, just return!
	// TODO implement me
	return nullptr;
65 66
}

Alexander A. Maly's avatar
Alexander A. Maly committed
67
/* public */ QWidget *KeyboardModule::pultWidget() const
68
{
Alexander A. Maly's avatar
Alexander A. Maly committed
69 70 71 72 73
	// Returns module control view widget, or nullptr if there is no control view
	// NOTE: the method is const and might be called at any time,
	//       so DO NOT create widget here, just return!
	// TODO implement me
	return nullptr;
74 75
}

Alexander A. Maly's avatar
Alexander A. Maly committed
76
/* public slot */ void KeyboardModule::reloadSettings(ExtensionSystem::SettingsPtr settings, const QStringList &keys)
77
{
Alexander A. Maly's avatar
Alexander A. Maly committed
78 79 80 81 82
	// Updates setting on module load, workspace change or appliyng settings dialog.
	// If @param keys is empty -- should reload all settings, otherwise load only setting specified by @param keys
	// TODO implement me
	Q_UNUSED(settings);  // Remove this line on implementation
	Q_UNUSED(keys);  // Remove this line on implementation
83 84 85 86
}

/* public slot */ void KeyboardModule::reset()
{
Alexander A. Maly's avatar
Alexander A. Maly committed
87 88 89 90 91 92
	runClearKeyBuffer();
	// Register event filter
	QWidgetList widgets = QApplication::allWidgets();
	Q_FOREACH (QWidget *w, widgets) {
		w->installEventFilter(this);
	}
93 94
}

95 96
void KeyboardModule::terminateEvaluation()
{
Alexander A. Maly's avatar
Alexander A. Maly committed
97
	buffer_.reset(KeyEvent());
98 99
}

100 101
void KeyboardModule::finalizeRun()
{
Alexander A. Maly's avatar
Alexander A. Maly committed
102 103 104 105 106
	// Deregister event filter
	QWidgetList widgets = QApplication::allWidgets();
	Q_FOREACH (QWidget *w, widgets) {
		w->removeEventFilter(this);
	}
107 108 109 110
}

/* public slot */ void KeyboardModule::setAnimationEnabled(bool enabled)
{
Alexander A. Maly's avatar
Alexander A. Maly committed
111 112 113 114
	// Sets GUI animation flag on run
	// NOTE this method just setups a flag and might be called anytime, even module not needed
	// TODO implement me
	Q_UNUSED(enabled);  // Remove this line on implementation
115 116 117 118
}

/* public slot */ bool KeyboardModule::runKeyHit()
{
Alexander A. Maly's avatar
Alexander A. Maly committed
119
	/* алг лог клавиша нажата */
120
	bool result = ! buffer_.empty();
Alexander A. Maly's avatar
Alexander A. Maly committed
121
	return result;
122 123 124 125
}

/* public slot */ int KeyboardModule::runKeyCode()
{
Alexander A. Maly's avatar
Alexander A. Maly committed
126
	/* алг цел код клавиши */
127
	int result = buffer_.dequeue().kumirCode;
Alexander A. Maly's avatar
Alexander A. Maly committed
128 129
	return result;

130 131 132 133
}

/* public slot */ void KeyboardModule::runClearKeyBuffer()
{
Alexander A. Maly's avatar
Alexander A. Maly committed
134 135 136 137
	/* алг очистить клавиши */
	lastPressedLock_.lock();
	lastPressed_ = KeyEvent();
	lastPressedLock_.unlock();
138

Alexander A. Maly's avatar
Alexander A. Maly committed
139
	buffer_.clear();
140 141 142 143
}

/* public slot */ int KeyboardModule::runKEY_UP()
{
Alexander A. Maly's avatar
Alexander A. Maly committed
144 145 146
	/* алг цел КЛ_ВВЕРХ */
	return 38;

147 148 149 150
}

/* public slot */ int KeyboardModule::runKEY_DOWN()
{
Alexander A. Maly's avatar
Alexander A. Maly committed
151 152 153
	/* алг цел КЛ_ВНИЗ */
	return 40;

154 155 156 157
}

/* public slot */ int KeyboardModule::runKEY_LEFT()
{
Alexander A. Maly's avatar
Alexander A. Maly committed
158 159 160
	/* алг цел КЛ_ВЛЕВО */
	return 37;

161 162 163 164
}

/* public slot */ int KeyboardModule::runKEY_RIGHT()
{
Alexander A. Maly's avatar
Alexander A. Maly committed
165 166 167
	/* алг цел КЛ_ВПРАВО */
	return 39;

168 169
}

Alexander A. Maly's avatar
Alexander A. Maly committed
170
/* public slot */ Keycode KeyboardModule::runOperatorINPUT(const QString &s, bool &ok)
171
{
Alexander A. Maly's avatar
Alexander A. Maly committed
172 173 174 175 176 177 178 179
	/* алг _клав ввод(лит s, рез лог ok) */
	const QString normalized = s.trimmed().toUpper();
	Keycode result;
	result.code = 0;
	ok = false;
	if (normalized.length() < 4 || !normalized.startsWith(QString::fromUtf8("КЛ_"))) {
		return result;
	}
180 181
#define C(x, y) QPair<QString,int>(QString::fromUtf8(x),y)
#define D(x, y) QPair<QString,int>(QString::fromUtf8(x), static_cast<int>(QString::fromLatin1(y).at(0).toLatin1()))
Alexander A. Maly's avatar
Alexander A. Maly committed
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
	static const QPair<QString, int> CODES[] = {
		C("НАЗАД", 8),
		C("BACKSPACE", 8),
		C("TAB", 9),
		C("ВВОД", 13),
		C("ENTER", 13),
		C("RETURN", 13),
		C("SPACE", 32),
		C("ПРОБЕЛ", 32),
		C("PAGEUP", 33),
		C("PGUP", 33),
		C("PAGEDOWN", 34),
		C("PGDOWN", 34),
		C("END", 35),
		C("HOME", 36),
		C("ВЛЕВО", 37),
		C("ВВЕРХ", 38),
		C("ВПРАВО", 39),
		C("ВНИЗ", 40),
		C("INSERT", 45),
		C("DELETE", 46),
		C("F1", 112), C("F2", 113), C("F3", 114), C("F4", 115), C("F5", 116), C("F6", 117),
		C("F7", 118), C("F8", 119), C("F9", 120), C("F10", 121), C("F11", 122), C("F12", 123),
		D("Й", "Q"), D("Ц", "W"), D("У", "E"), D("К", "R"), D("Е", "T"), D("Н", "Y"), D("Г", "U"), D("Ш", "I"), D("Щ", "O"), D("З", "P"),
		D("Ф", "A"), D("Ы", "S"), D("В", "D"), D("А", "F"), D("П", "G"), D("Р", "H"), D("О", "J"), D("Л", "K"), D("Д", "L"),
		D("Я", "Z"), D("Ч", "X"), D("С", "C"), D("М", "V"), D("И", "B"), D("Т", "N"), D("Ь", "M"),
		C("", 0)
	};
210 211
#undef C
#undef D
Alexander A. Maly's avatar
Alexander A. Maly committed
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
	size_t index = 0;
	const QString keyName = normalized.mid(3);
	while (0 != CODES[index].second) {
		const QString &match = CODES[index].first;
		if (match == keyName) {
			ok = true;
			result.code = CODES[index].second;
			break;
		}
		++index;
	}
	if (!ok && keyName.length() == 1) {
		const QChar aKey = keyName.at(0);
		if ('\0' != aKey.toLatin1()) {
			ok = true;
			result.code = aKey.toLatin1();
		}
	}
	return result;

232 233 234 235
}

QString KeyboardModule::runOperatorOUTPUT(const Keycode &x)
{
Alexander A. Maly's avatar
Alexander A. Maly committed
236
	return QString::number(x.code);
237 238 239 240
}

/* public slot */ Keycode KeyboardModule::runOperatorASSIGN(const int x)
{
Alexander A. Maly's avatar
Alexander A. Maly committed
241 242 243 244
	/* алг _клав :=(цел x) */
	Keycode result;
	result.code = x;
	return result;
245 246 247 248
}

int KeyboardModule::runOperatorASSIGN(const Keycode &x)
{
Alexander A. Maly's avatar
Alexander A. Maly committed
249
	return x.code;
250 251 252 253
}

bool KeyboardModule::runOperatorEQUAL(const Keycode &self, const Keycode &other)
{
Alexander A. Maly's avatar
Alexander A. Maly committed
254
	return self.code == other.code;
255 256
}

257
bool KeyboardModule::runOperatorEQUAL(const Keycode &self, const int other)
258
{
Alexander A. Maly's avatar
Alexander A. Maly committed
259
	return self.code == other;
260 261
}

262
bool KeyboardModule::runOperatorEQUAL(const int other, const Keycode &self)
263
{
Alexander A. Maly's avatar
Alexander A. Maly committed
264
	return self.code == other;
265 266 267 268
}

bool KeyboardModule::runOperatorNOTEQUAL(const Keycode &self, const Keycode &other)
{
Alexander A. Maly's avatar
Alexander A. Maly committed
269
	return self.code != other.code;
270 271
}

272
bool KeyboardModule::runOperatorNOTEQUAL(const Keycode &self, const int other)
273
{
Alexander A. Maly's avatar
Alexander A. Maly committed
274
	return self.code != other;
275 276
}

277
bool KeyboardModule::runOperatorNOTEQUAL(const int other, const Keycode &self)
278
{
Alexander A. Maly's avatar
Alexander A. Maly committed
279
	return self.code != other;
280 281 282 283
}

bool KeyboardModule::runOperatorLESS(const Keycode &self, const Keycode &other)
{
Alexander A. Maly's avatar
Alexander A. Maly committed
284
	return self.code < other.code;
285 286
}

287
bool KeyboardModule::runOperatorLESS(const Keycode &self, const int other)
288
{
Alexander A. Maly's avatar
Alexander A. Maly committed
289
	return self.code < other;
290 291
}

292
bool KeyboardModule::runOperatorLESS(const int self, const Keycode &other)
293
{
Alexander A. Maly's avatar
Alexander A. Maly committed
294
	return self < other.code;
295 296 297 298
}

bool KeyboardModule::runOperatorGREATER(const Keycode &self, const Keycode &other)
{
Alexander A. Maly's avatar
Alexander A. Maly committed
299
	return self.code > other.code;
300 301
}

302
bool KeyboardModule::runOperatorGREATER(const Keycode &self, const int other)
303
{
Alexander A. Maly's avatar
Alexander A. Maly committed
304
	return self.code > other;
305 306
}

307
bool KeyboardModule::runOperatorGREATER(const int self, const Keycode &other)
308
{
Alexander A. Maly's avatar
Alexander A. Maly committed
309
	return self > other.code;
310 311 312 313
}

int KeyboardModule::runOperatorPLUS(const Keycode &self, const Keycode &other)
{
Alexander A. Maly's avatar
Alexander A. Maly committed
314
	return self.code + other.code;
315 316
}

317
int KeyboardModule::runOperatorPLUS(const Keycode &self, const int other)
318
{
Alexander A. Maly's avatar
Alexander A. Maly committed
319
	return self.code + other;
320 321
}

322
int KeyboardModule::runOperatorPLUS(const int self, const Keycode &other)
323
{
Alexander A. Maly's avatar
Alexander A. Maly committed
324
	return self + other.code;
325 326 327 328
}

int KeyboardModule::runOperatorMINUS(const Keycode &self, const Keycode &other)
{
Alexander A. Maly's avatar
Alexander A. Maly committed
329
	return self.code - other.code;
330 331
}

332
int KeyboardModule::runOperatorMINUS(const Keycode &self, const int other)
333
{
Alexander A. Maly's avatar
Alexander A. Maly committed
334
	return self.code - other;
335 336
}

337
int KeyboardModule::runOperatorMINUS(const int self, const Keycode &other)
338
{
Alexander A. Maly's avatar
Alexander A. Maly committed
339
	return self - other.code;
340 341 342 343
}

int KeyboardModule::runOperatorASTERISK(const Keycode &self, const Keycode &other)
{
Alexander A. Maly's avatar
Alexander A. Maly committed
344
	return self.code * other.code;
345 346
}

347
int KeyboardModule::runOperatorASTERISK(const Keycode &self, const int other)
348
{
Alexander A. Maly's avatar
Alexander A. Maly committed
349
	return self.code * other;
350 351
}

352
int KeyboardModule::runOperatorASTERISK(const int self, const Keycode &other)
353
{
Alexander A. Maly's avatar
Alexander A. Maly committed
354
	return self * other.code;
355 356 357 358
}

bool KeyboardModule::eventFilter(QObject *obj, QEvent *event)
{
Alexander A. Maly's avatar
Alexander A. Maly committed
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389
	if (QEvent::KeyPress == event->type()) {
		qDebug() << "From " << obj->metaObject()->className();
		QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
		qDebug() << "Catched Qt code: " << keyEvent->key();
		const int code = polyakovCodeOfKey(keyEvent->key(), keyEvent->text());
		if (code) {
			qDebug() << "Catched code: " << code;

			const KeyEvent keyEvent(code);
			bool addToBuffer = true;
			lastPressedLock_.lock();
			if (lastPressed_.kumirCode) {
				qint64 delta = keyEvent.timestamp - lastPressed_.timestamp;
				if (delta < KeyEvent::MAX_DELTA) {
					addToBuffer = false;
				}
			}
			lastPressed_ = keyEvent;
			lastPressedLock_.unlock();

			if (addToBuffer) {
				buffer_.enqueue(KeyEvent(code));
			}
		}
	}
	return QObject::eventFilter(obj, event);
}

int KeyboardModule::polyakovCodeOfKey(int qtCode, const QString &text)
{
	if (1 == text.length()) {
390
#define D(x, y) QPair<QString,int>(QString::fromUtf8(x), static_cast<int>(QString::fromLatin1(y).at(0).toLatin1()))
Alexander A. Maly's avatar
Alexander A. Maly committed
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408
		const QString normalized = text.toUpper();
		static const QPair<QString, int> CODES[] = {
			D("Й", "Q"), D("Ц", "W"), D("У", "E"), D("К", "R"), D("Е", "T"), D("Н", "Y"), D("Г", "U"), D("Ш", "I"), D("Щ", "O"), D("З", "P"),
			D("Ф", "A"), D("Ы", "S"), D("В", "D"), D("А", "F"), D("П", "G"), D("Р", "H"), D("О", "J"), D("Л", "K"), D("Д", "L"),
			D("Я", "Z"), D("Ч", "X"), D("С", "C"), D("М", "V"), D("И", "B"), D("Т", "N"), D("Ь", "M"),
			QPair<QString, int>("", 0)
		};
		size_t index = 0;
		if (0 != normalized.at(0).toLatin1()) {
			return normalized.at(0).toLatin1();
		}
		while (0 != CODES[index].second) {
			if (normalized == CODES[index].first) {
				return CODES[index].second;
			}
			++index;
		}
		return 0;
409
#undef D
Alexander A. Maly's avatar
Alexander A. Maly committed
410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494
	}

	switch (qtCode) {
	case Qt::Key_Up:
		return 38;
	case Qt::Key_Down:
		return 40;
	case Qt::Key_Left:
		return 37;
	case Qt::Key_Right:
		return 39;
	case Qt::Key_Backspace:
		return 8;
	case Qt::Key_Tab:
		return 9;
	case Qt::Key_Enter:
	case Qt::Key_Return:
		return 13;
	case Qt::Key_Space:
		return 32;
	case Qt::Key_PageUp:
		return 33;
	case Qt::Key_PageDown:
		return 34;
	case Qt::Key_End:
		return 35;
	case Qt::Key_Home:
		return 36;
	case Qt::Key_Insert:
		return 45;
	case Qt::Key_Delete:
		return 46;
	case Qt::Key_F1:
		return 112;
	case Qt::Key_F2:
		return 113;
	case Qt::Key_F3:
		return 114;
	case Qt::Key_F4:
		return 115;
	case Qt::Key_F5:
		return 116;
	case Qt::Key_F6:
		return 117;
	case Qt::Key_F7:
		return 118;
	case Qt::Key_F8:
		return 119;
	case Qt::Key_F9:
		return 120;
	case Qt::Key_F10:
		return 121;
	case Qt::Key_F11:
		return 122;
	case Qt::Key_F12:
		return 123;
	case Qt::Key_0:
		return 48;
	case Qt::Key_1:
		return 49;
	case Qt::Key_2:
		return 50;
	case Qt::Key_3:
		return 51;
	case Qt::Key_4:
		return 52;
	case Qt::Key_5:
		return 53;
	case Qt::Key_6:
		return 54;
	case Qt::Key_7:
		return 55;
	case Qt::Key_8:
		return 56;
	case Qt::Key_9:
		return 57;
	case Qt::Key_Q:
		return 81;
	case Qt::Key_W:
		return 87;
	case Qt::Key_E:
		return 69;
	default:
		return 0;
	}
495 496 497 498 499 500
}




} // namespace ActorKeyboard