4 * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
7 * SungMin Ha <sungmin82.ha@samsung.com>
8 * GiWoong Kim <giwoong.kim@samsung.com>
9 * SeokYeon Hwang <syeon.hwang@samsung.com>
10 * Sangho Park <sangho.p@samsung.com>
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
32 #include "contextmenu.h"
33 #include "resource/ui_strings.h"
34 #include "emulator_common.h"
35 #include "mainwindow.h"
37 #include "menu/advancedmenuitem.h"
38 #include "menu/scalemenuitem.h"
39 #include "emul_state.h"
42 // FIXME: To avoid very complex header inclusion chains
43 void qemu_system_graceful_shutdown_request(unsigned int sec);
44 void qemu_system_reset_request(void);
45 #define MENU_ACTION_REBOOT 1
46 void send_shutdown_request(int action);
48 #define QObject qemu_QObject
49 #include "util/net_helper.h"
50 #include "util/osutil.h"
51 #include "util/device_hotplug.h"
52 #include "util/ui_operations.h"
58 ContextMenu::ContextMenu(QWidget *parent) : QMenu(parent)
60 this->parent = (MainWindow *)parent;
61 this->infoDialog = NULL;
62 this->aboutDialog = NULL;
63 this->screenshotDialog = NULL;
65 this->advancedMenu = NULL;
66 this->switchMenu = NULL;
67 this->scaleMenu = NULL;
68 this->controllerMenu = NULL;
70 this->actionDetailedInfo = NULL;
71 this->actionOnTop = NULL;
72 this->actionShell = NULL;
73 this->actionControlPanel = NULL;
74 this->actionScreenShot = NULL;
75 this->actionAbout = NULL;
76 this->actionForceClose = NULL;
77 this->actionClose = NULL;
79 this->switchMapper = NULL;
80 this->scaleMapper = NULL;
81 this->controllerMapper = NULL;
83 vmName = this->parent->getUiInfo()->getVmName() + " : "
84 + QString::number(get_vm_device_serial_number());
87 sdbHelper = new SdbHelper(this->parent, this->parent->getDisplay());
90 longPressTimer = new QTimer(this);
92 /* for system reset */
93 rebootTimer = new QTimer(this);
94 rebootTimer->setInterval(HARDWARE_REBOOT_INTERVAL);
95 rebootTimer->setSingleShot(true);
96 QObject::connect(rebootTimer, SIGNAL(timeout()), this, SLOT(slotDeviceReset()));
98 createItems(this, this->parent->getUiInfo()->getMenuList());
100 installEventFilter(this);
103 QAction *ContextMenu::getOnTopAction() {
107 void ContextMenu::createItems(QMenu *menu, QList<MenuItem *> &list)
109 MenuItem *item = NULL;
110 for (int i = 0; i < list.count(); i++) {
113 switch (item->getType()) {
114 case MenuItemType::separator:
115 createSeparator(menu);
117 case MenuItemType::advancedItem:
119 createAdvancedItem(menu, item);
121 case MenuItemType::infoItem:
122 /* Detailed Info menu */
123 createInfoItem(menu, item);
125 case MenuItemType::onTopItem:
126 /* Always On Top menu */
127 createOnTopItem(menu, item);
129 case MenuItemType::moveItem:
131 createMoveItem(menu, item);
133 case MenuItemType::switchItem:
135 createSwitchItem(menu, item);
137 case MenuItemType::scaleItem:
139 createScaleItem(menu, item);
141 case MenuItemType::controllerItem:
142 /* Controller menu */
143 createControllerItem(menu, item);
145 case MenuItemType::hostKeyboardItem:
146 /* Host Keyboard menu */
147 createHostKeyboardItem(menu, item);
149 case MenuItemType::shellItem:
151 createShellItem(menu, item);
153 case MenuItemType::controlPanelItem:
154 /* Control Panel menu */
155 createControlPanelItem(menu, item);
157 case MenuItemType::screenShotItem:
158 /* Screen Shot menu */
159 createScreenShotItem(menu, item);
161 case MenuItemType::aboutItem:
163 createAboutItem(menu, item);
165 case MenuItemType::systemResetItem:
166 /* System Reset menu */
167 createSystemResetItem(menu, item);
169 case MenuItemType::forceCloseItem:
170 /* Force Close menu */
171 createForceCloseItem(menu, item);
173 case MenuItemType::closeItem:
175 createCloseItem(menu, item);
178 qWarning("unknown menu item type: %d", item->getType());
183 void ContextMenu::createSeparator(QMenu *menu)
189 menu->addSeparator();
192 void ContextMenu::createAdvancedItem(QMenu *menu, MenuItem *item)
194 if (menu == NULL || item == NULL) {
198 QString menuName = item->getName();
199 advancedMenu = menu->addMenu(QIcon(QPixmap(":/icons/advanced.png")),
200 menuName.isEmpty() ? "Advanced" : menuName);
202 createItems(advancedMenu, ((AdvancedMenuItem *)item)->getMenuList());
205 void ContextMenu::createInfoItem(QMenu *menu, MenuItem *item)
207 if (menu == NULL || item == NULL) {
211 QString menuName = item->getName();
212 actionDetailedInfo = addGeneralAction(
213 menu, QIcon(QPixmap(":/icons/detailed_info.png")),
214 menuName.isEmpty() ? vmName : menuName,
215 item->getShortcuts().isEmpty()? NULL :
216 new QShortcut(item->getShortcuts().begin().value(), parent),
217 SLOT(slotDetailedInfo()));
219 actionDetailedInfo->setIconText(menuName.isEmpty() ? QString(DETAILED_INFO_TITLE) : menuName);
221 item->setSlot(SLOT(slotDetailedInfo()));
222 item->setAction(actionDetailedInfo);
225 void ContextMenu::createOnTopItem(QMenu *menu, MenuItem *item)
227 if (menu == NULL || item == NULL) {
231 QString menuName = item->getName();
232 actionOnTop = menu->addAction(
233 menuName.isEmpty() ? MENU_ONTOP_ITEM_TEXT : menuName);
236 QPixmap pix = QPixmap(QSize(16, 16));
237 pix.fill(Qt::transparent);
238 actionOnTop->setIcon(QIcon(pix));
241 actionOnTop->setCheckable(true);
242 QObject::connect(actionOnTop, SIGNAL(triggered(bool)), this, SLOT(slotOnTop(bool)));
245 if (item->getShortcuts().isEmpty() == false) {
246 QShortcut *shortcut = new QShortcut(
247 item->getShortcuts().begin().value(), parent);
248 attachShortcut(actionOnTop, shortcut, SLOT(slotOnTopShortcut()));
251 item->setSlot(SLOT(slotOnTopShortcut()));
252 item->setAction(actionOnTop);
255 void ContextMenu::createMoveItem(QMenu *menu, MenuItem *item)
257 if (menu == NULL || item == NULL) {
261 QString menuName = item->getName();
262 actionMove = addGeneralAction(menu, QIcon(QPixmap(":/icons/move.png")),
263 menuName.isEmpty() ? MENU_MOVE_ITEM_TEXT : menuName,
264 item->getShortcuts().isEmpty() ? NULL
265 : new QShortcut(item->getShortcuts().begin().value(), parent),
268 item->setSlot(SLOT(slotMove()));
269 item->setAction(actionMove);
272 void ContextMenu::createSwitchItem(QMenu *menu, MenuItem *item)
274 if (menu == NULL || item == NULL) {
278 QList<MainForm *> &mainFormList = parent->getUiInfo()->getMainFormList();
280 if (mainFormList.isEmpty() == false) {
281 QString menuName = item->getName();
282 switchMenu = menu->addMenu(QIcon(QPixmap(":/icons/rotate.png")),
283 menuName.isEmpty() ? MENU_SWITCH_ITEM_TEXT : menuName);
285 switchGroup = new QActionGroup(this);
286 switchMapper = new QSignalMapper(this);
287 QObject::connect(switchMapper, SIGNAL(mapped(int)), this, SLOT(slotSwitch(int)));
290 QAction *switchAction = switchMenu->menuAction();
291 QMap<QString, QKeySequence> shortcuts = item->getShortcuts();
293 if (shortcuts.isEmpty() == false) {
294 QMap<QString, QKeySequence>::const_iterator iter;
295 if ((iter = shortcuts.find("prev")) != shortcuts.end()) {
296 QShortcut *shortcut = new QShortcut(iter.value(), parent);
297 attachShortcut(switchAction, shortcut, SLOT(slotSwitchShortcutPrev()));
299 if ((iter = shortcuts.find("next")) != shortcuts.end()) {
300 QShortcut *shortcut = new QShortcut(iter.value(), parent);
301 attachShortcut(switchAction, shortcut, SLOT(slotSwitchShortcutNext()));
304 if (switchAction->shortcut().isEmpty() == true) {
305 QShortcut *shortcut = new QShortcut(
306 item->getShortcuts().begin().value(), parent);
307 attachShortcut(switchAction, shortcut, SLOT(slotSwitchShortcutNext()));
311 QAction *action = NULL;
312 for (int i = 0; i < mainFormList.count(); i++) {
313 action = switchMenu->addAction(mainFormList.at(i)->getName());
314 action->setActionGroup(switchGroup);
315 action->setCheckable(true);
316 switchMapper->setMapping(action, i);
317 QObject::connect(action, SIGNAL(triggered()), switchMapper, SLOT(map()));
320 action = (QAction *) switchMapper->mapping(
321 parent->getUiState()->getMainFormIndex());
322 action->setChecked(true);
324 qWarning("cannot create a switchItem");
327 item->setSlot(SLOT(slotSwitchShortcutNext()));
328 item->setAction(switchMenu->menuAction());
331 void ContextMenu::createScaleItem(QMenu *menu, MenuItem *item)
333 if (menu == NULL || item == NULL) {
337 QMap<int, QString> factorMap = ((ScaleMenuItem *)item)->getFactorMap();
339 if (factorMap.isEmpty() == false) {
340 QString menuName = item->getName();
341 scaleMenu = menu->addMenu(QIcon(QPixmap(":/icons/scale.png")),
342 menuName.isEmpty() ? MENU_SCALE_ITEM_TEXT : menuName);
344 scaleGroup = new QActionGroup(this);
345 scaleMapper = new QSignalMapper(this);
346 QObject::connect(scaleMapper, SIGNAL(mapped(int)), this, SLOT(slotScale(int)));
349 QAction *scaleAction = scaleMenu->menuAction();
350 QMap<QString, QKeySequence> shortcuts = item->getShortcuts();
352 if (shortcuts.isEmpty() == false) {
353 QMap<QString, QKeySequence>::const_iterator shortcutIter;
354 if ((shortcutIter = shortcuts.find("prev")) != shortcuts.end()) {
355 QShortcut *shortcut = new QShortcut(shortcutIter.value(), parent);
356 attachShortcut(scaleAction, shortcut, SLOT(slotScaleShortcutPrev()));
358 if ((shortcutIter = shortcuts.find("next")) != shortcuts.end()) {
359 QShortcut *shortcut = new QShortcut(shortcutIter.value(), parent);
360 attachShortcut(scaleAction, shortcut, SLOT(slotScaleShortcutNext()));
363 if (scaleAction->shortcut().isEmpty() == true) {
364 QShortcut *shortcut = new QShortcut(
365 item->getShortcuts().begin().value(), parent);
366 attachShortcut(scaleAction, shortcut, SLOT(slotScaleShortcutNext()));
370 QAction *action = NULL;
372 QMapIterator<int, QString> factorIter(factorMap);
374 while(factorIter.hasPrevious() == true) {
375 factorIter.previous();
377 QString factorName = factorIter.value();
378 action = scaleMenu->addAction(
379 factorName.isEmpty() ? (QString::number(factorIter.key()) + '%') : factorName);
380 action->setActionGroup(scaleGroup);
381 action->setCheckable(true);
382 scaleMapper->setMapping(action, factorIter.key());
383 QObject::connect(action, SIGNAL(triggered()), scaleMapper, SLOT(map()));
386 // TODO: interpolation
388 action = (QAction *) scaleMapper->mapping(
389 parent->getUiState()->getScalePct());
390 action->setChecked(true);
392 qWarning("cannot create a scaleItem");
395 item->setSlot(SLOT(slotScaleShortcutNext()));
396 item->setAction(scaleMenu->menuAction());
399 void ContextMenu::createControllerItem(QMenu *menu, MenuItem *item)
401 if (menu == NULL || item == NULL) {
405 QList<ControllerForm *> &conFormList = parent->getUiInfo()->getConFormList();
407 if (conFormList.isEmpty() == false) {
408 QString menuName = item->getName();
412 QPixmap pix = QPixmap(QSize(16, 16));
413 pix.fill(Qt::transparent);
414 controllerMenu = menu->addMenu(QIcon(pix),
415 menuName.isEmpty() ? MENU_CONTROLLER_ITEM_TEXT : menuName);
417 controllerMenu = menu->addMenu(
418 menuName.isEmpty() ? MENU_CONTROLLER_ITEM_TEXT : menuName);
420 controllerGroup = new QActionGroup(this);
421 controllerMapper = new QSignalMapper(this);
422 QObject::connect(controllerMapper, SIGNAL(mapped(int)), this, SLOT(slotController(int)));
425 QAction *conAction = controllerMenu->menuAction();
426 QMap<QString, QKeySequence> shortcuts = item->getShortcuts();
428 if (shortcuts.isEmpty() == false) {
429 QMap<QString, QKeySequence>::const_iterator iter;
430 if ((iter = shortcuts.find("prev")) != shortcuts.end()) {
431 QShortcut *shortcut = new QShortcut(iter.value(), parent);
432 attachShortcut(conAction, shortcut, SLOT(slotConShortcutPrev()));
434 if ((iter = shortcuts.find("next")) != shortcuts.end()) {
435 QShortcut *shortcut = new QShortcut(iter.value(), parent);
436 attachShortcut(conAction, shortcut, SLOT(slotConShortcutNext()));
439 if (conAction->shortcut().isEmpty() == true) {
440 QShortcut *shortcut = new QShortcut(
441 item->getShortcuts().begin().value(), parent);
442 attachShortcut(conAction, shortcut, SLOT(slotConShortcutNext()));
446 QAction *action = NULL;
447 action = controllerMenu->addAction(GENERIC_TEXT_NONE);
448 action->setActionGroup(controllerGroup);
449 action->setCheckable(true);
450 action->setChecked(true);
451 QObject::connect(action, SIGNAL(triggered()), this, SLOT(slotCloseCon()));
453 for (int i = 0; i < conFormList.count(); i++) {
454 action = controllerMenu->addAction(conFormList.at(i)->getName());
455 action->setActionGroup(controllerGroup);
456 action->setCheckable(true);
457 controllerMapper->setMapping(action, i);
458 QObject::connect(action, SIGNAL(triggered()), controllerMapper, SLOT(map()));
461 qWarning("cannot create a controllerItem");
464 item->setSlot(SLOT(slotConShortcutNext()));
465 item->setAction(controllerMenu->menuAction());
468 void ContextMenu::createHostKeyboardItem(QMenu *menu, MenuItem *item)
470 if (menu == NULL || item == NULL) {
474 QString menuName = item->getName();
475 QMenu *keyboardMenu = menu->addMenu(QIcon(),
476 menuName.isEmpty() ? MENU_HOSTKBD_ITEM_TEXT : menuName);
477 keyboardGroup = new QActionGroup(this);
479 QAction *hostKbdAction = keyboardMenu->addAction(MENU_ON_ITEM_TEXT);
480 hostKbdAction->setActionGroup(keyboardGroup);
481 hostKbdAction->setCheckable(true);
482 QObject::connect(hostKbdAction, SIGNAL(toggled(bool)), this, SLOT(slotHostKeyboard(bool)));
487 hostKbdAction = keyboardMenu->addAction(MENU_OFF_ITEM_TEXT);
488 hostKbdAction->setActionGroup(keyboardGroup);
489 hostKbdAction->setCheckable(true);
490 hostKbdAction->setChecked(true);
492 // item->setSlot(slotHostKeyboardShortcut());
493 item->setAction(hostKbdAction);
496 void ContextMenu::createShellItem(QMenu *menu, MenuItem *item)
498 if (menu == NULL || item == NULL) {
502 QString menuName = item->getName();
503 actionShell = addGeneralAction(
504 menu, QIcon(QPixmap(":/icons/shell.png")),
505 menuName.isEmpty() ? MENU_SHELL_ITEM_TEXT : menuName,
506 item->getShortcuts().isEmpty()? NULL :
507 new QShortcut(item->getShortcuts().begin().value(), parent),
510 item->setSlot(SLOT(slotShell()));
511 item->setAction(actionShell);
514 void ContextMenu::createControlPanelItem(QMenu *menu, MenuItem *item)
516 if (menu == NULL || item == NULL) {
520 QString menuName = item->getName();
521 actionControlPanel = addGeneralAction(
522 menu, QIcon(QPixmap(":/icons/control_panel.png")),
523 menuName.isEmpty() ? MENU_ECP_ITEM_TEXT : menuName,
524 item->getShortcuts().isEmpty()? NULL :
525 new QShortcut(item->getShortcuts().begin().value(), parent),
526 SLOT(slotControlPanel()));
528 item->setSlot(SLOT(slotControlPanel()));
529 item->setAction(actionControlPanel);
532 void ContextMenu::createScreenShotItem(QMenu *menu, MenuItem *item)
534 if (menu == NULL || item == NULL) {
538 QString menuName = item->getName();
539 actionScreenShot = addGeneralAction(
540 menu, QIcon(QPixmap(":/icons/screen_shot.png")),
541 menuName.isEmpty() ? MENU_SCREENSHOT_ITEM_TEXT : menuName,
542 item->getShortcuts().isEmpty()? NULL :
543 new QShortcut(item->getShortcuts().begin().value(), parent),
544 SLOT(slotRequestScreenshot()));
546 item->setSlot(SLOT(slotRequestScreenshot()));
547 item->setAction(actionScreenShot);
550 void ContextMenu::createAboutItem(QMenu *menu, MenuItem *item)
552 if (menu == NULL || item == NULL) {
556 QString menuName = item->getName();
557 actionAbout = addGeneralAction(
558 menu, QIcon(QPixmap(":/icons/about.png")),
559 menuName.isEmpty() ? MENU_ABOUT_ITEM_TEXT : menuName,
560 item->getShortcuts().isEmpty()? NULL :
561 new QShortcut(item->getShortcuts().begin().value(), parent),
564 item->setSlot(SLOT(slotAbout()));
565 item->setAction(actionAbout);
568 void ContextMenu::createSystemResetItem(QMenu *menu, MenuItem *item)
570 if (menu == NULL || item == NULL) {
574 QString menuName = item->getName();
575 actionSystemReset = addGeneralAction(
577 menuName.isEmpty() ? MENU_FORCECLOSE_ITEM_TEXT : menuName,
578 item->getShortcuts().isEmpty()? NULL :
579 new QShortcut(item->getShortcuts().begin().value(), parent),
580 SLOT(slotSystemReset()));
582 item->setSlot(SLOT(slotSystemReset()));
583 item->setAction(actionSystemReset);
586 void ContextMenu::createForceCloseItem(QMenu *menu, MenuItem *item)
588 if (menu == NULL || item == NULL) {
592 QString menuName = item->getName();
593 actionForceClose = addGeneralAction(
595 menuName.isEmpty() ? MENU_FORCECLOSE_ITEM_TEXT : menuName,
596 item->getShortcuts().isEmpty()? NULL :
597 new QShortcut(item->getShortcuts().begin().value(), parent),
598 SLOT(slotForceClose()));
600 item->setSlot(SLOT(slotForceClose()));
601 item->setAction(actionForceClose);
604 void ContextMenu::createCloseItem(QMenu *menu, MenuItem *item)
606 if (menu == NULL || item == NULL) {
610 QString menuName = item->getName();
611 actionClose = addGeneralAction(
612 menu, QIcon(QPixmap(":/icons/close.png")),
613 menuName.isEmpty() ? MENU_CLOSE_ITEM_TEXT : menuName,
614 item->getShortcuts().isEmpty()? NULL :
615 new QShortcut(item->getShortcuts().begin().value(), parent),
618 item->setSlot(SLOT(slotClose()));
619 item->setAction(actionClose);
622 QAction *ContextMenu::addGeneralAction(QMenu *menu,
623 const QIcon &icon, const QString &text, QShortcut *shortcut, const char *slot)
625 QAction *action = menu->addAction(text);
630 QPixmap pix = QPixmap(QSize(16, 16));
631 pix.fill(Qt::transparent);
632 action->setIcon(QIcon(pix));
634 action->setIcon(icon);
637 action->setIcon(icon);
639 QObject::connect(action, SIGNAL(triggered()), this, slot);
641 attachShortcut(action, shortcut, slot);
646 void ContextMenu::attachShortcut(
647 QAction *action, QShortcut *shortcut, const char *slot)
649 if (action != NULL && shortcut != NULL) {
650 QObject::connect(shortcut, SIGNAL(activated()), this, slot);
651 QObject::connect(shortcut, SIGNAL(activatedAmbiguously()),
652 this, SLOT(slotAmbiguousShortcut()));
654 action->setShortcut(shortcut->key());
659 bool ContextMenu::eventFilter(QObject *obj, QEvent *event)
661 ContextMenu *menu = dynamic_cast<ContextMenu *>(obj);
663 return QObject::eventFilter(obj, event);
666 if (event->type() == QEvent::MouseButtonPress ||
667 event->type() == QEvent::MouseButtonRelease) {
668 QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent *>(event);
670 if (mouseEvent != NULL && mouseEvent->button() == Qt::RightButton) {
671 /* if menu was selected then filter out the this event */
672 if (mouseEvent->x() >= 0 && mouseEvent->y() >= 0 &&
673 mouseEvent->x() <= geometry().width() &&
674 mouseEvent->y() <= geometry().height()) {
675 mouseEvent->ignore(); /* filtering */
679 } else if (event->type() == QEvent::Show) {
680 if (parent->getMainView()->isGrabWindow() == true) {
681 parent->getMainView()->releaseWindow();
685 return QObject::eventFilter(obj, event);
688 void ContextMenu::slotUndefinedMenu()
690 QMessageBox::warning(parent, EMULATOR_TITLE, MENU_UNDEFINED_ERROR);
693 void ContextMenu::slotAmbiguousShortcut()
695 /* When a shortcut's key sequence is completed, activatedAmbiguously()
696 * is emitted if the key sequence is still ambiguous (i.e., it is the
697 * start of one or more other shortcuts). */
698 qWarning("one shortcut key was overlapped with another");
700 QMessageBox::warning(parent, EMULATOR_TITLE, MENE_AMBIGUOUS_SHORTCUT);
703 void ContextMenu::slotDetailedInfo()
707 if (infoDialog == NULL) {
708 infoDialog = new DetailedInfoDialog((QWidget *)parent);
714 slotOnTop(parent->getUiState()->isOnTop());
718 void ContextMenu::slotOnTop(bool on)
720 qDebug("stays on top: %s", on? "on" : "off");
723 /* On Ubuntu, all of the child windows which are higher than parent window in z-order
724 * should be getting a "ABOVE" state. */
726 QWidgetList list = QApplication::topLevelWidgets();
727 QWidget *widget = NULL;
728 for (int i = 0; i < list.count(); i++) {
730 if (widget->isWindow() && widget->parentWidget() == parent &&
732 UiUtil::setTopMost(widget, on);
737 UiUtil::setTopMost(parent, on);
739 if (actionOnTop != NULL) {
740 actionOnTop->setChecked(on);
742 parent->getUiState()->setOnTop(on);
745 void ContextMenu::slotOnTopShortcut()
748 slotOnTop(!actionOnTop->isChecked());
750 qDebug() << "shortcut:" << actionOnTop->text() << actionOnTop->isChecked();
753 void ContextMenu::slotMove()
755 parent->turnOnMovingMode();
758 void ContextMenu::slotSwitch(int index)
760 qDebug("switch: %d", index);
762 parent->switchForm(index);
765 void ContextMenu::slotSwitchShortcutPrev()
767 QList<QAction *> switchActions = switchGroup->actions();
768 if (switchActions.count() < 2) {
774 QAction *action = switchGroup->checkedAction();
775 if (action != NULL) {
776 index = switchActions.indexOf(action);
778 index = switchActions.count() - 1;
784 QAction *prevAction = switchActions.at(index);
785 prevAction->setChecked(true);
786 prevAction->trigger();
788 qDebug() << "shortcut: prev" << switchMenu->title() << prevAction->text();
791 void ContextMenu::slotSwitchShortcutNext()
793 QList<QAction *> switchActions = switchGroup->actions();
794 if (switchActions.count() < 2) {
800 QAction *action = switchGroup->checkedAction();
801 if (action != NULL) {
802 index = switchActions.indexOf(action);
803 if (index == switchActions.count() - 1) {
810 QAction *nextAction = switchActions.at(index);
811 nextAction->setChecked(true);
812 nextAction->trigger();
814 qDebug() << "shortcut: next" << switchMenu->title() << nextAction->text();
817 void ContextMenu::slotScale(int scale)
819 qDebug("scale: %d", scale);
821 parent->scaleForm(scale);
824 void ContextMenu::slotScaleShortcutPrev()
826 QList<QAction *> scaleActions = scaleGroup->actions();
827 if (scaleActions.count() < 2) {
833 QAction *action = scaleGroup->checkedAction();
834 if (action != NULL) {
835 index = scaleActions.indexOf(action);
837 index = scaleActions.count() - 1;
843 QAction *prevAction = scaleActions.at(index);
844 prevAction->setChecked(true);
845 prevAction->trigger();
847 qDebug() << "shortcut: prev" << scaleMenu->title() << prevAction->text();
850 void ContextMenu::slotScaleShortcutNext()
852 QList<QAction *> scaleActions = scaleGroup->actions();
853 if (scaleActions.count() < 2) {
859 QAction *action = scaleGroup->checkedAction();
860 if (action != NULL) {
861 index = scaleActions.indexOf(action);
862 if (index == scaleActions.count() - 1) {
869 QAction *nextAction = scaleActions.at(index);
870 nextAction->setChecked(true);
871 nextAction->trigger();
873 qDebug() << "shortcut: next" << scaleMenu->title() << nextAction->text();
876 void ContextMenu::slotController(int index)
878 qDebug("controller: %d", index);
880 parent->openController(index,
881 parent->getUiState()->getConState()->getRecentlyDockPos());
883 if (infoDialog != NULL && infoDialog->isVisible() == true) {
884 /* update controller shortcut info */
885 infoDialog->updateShortcutTableItems();
889 void ContextMenu::slotCloseCon()
891 qDebug("controller: None");
893 parent->closeController();
894 parent->getUiState()->getConState()->setConFormIndex(-1);
896 if (infoDialog != NULL && infoDialog->isVisible() == true) {
897 /* update controller shortcut info */
898 infoDialog->updateShortcutTableItems();
902 void ContextMenu::slotConShortcutPrev()
904 QList<QAction *> conActions = controllerGroup->actions();
905 if (conActions.count() < 2) {
911 QAction *action = controllerGroup->checkedAction();
912 if (action != NULL) {
913 index = conActions.indexOf(action);
915 index = conActions.count() - 1;
921 QAction *prevAction = conActions.at(index);
922 prevAction->setChecked(true);
923 prevAction->trigger();
925 qDebug() << "shortcut: prev" << controllerMenu->title() << prevAction->text();
928 void ContextMenu::slotConShortcutNext()
930 QList<QAction *> conActions = controllerGroup->actions();
931 if (conActions.count() < 2) {
937 QAction *action = controllerGroup->checkedAction();
938 if (action != NULL) {
939 index = conActions.indexOf(action);
940 if (index == conActions.count() - 1) {
947 QAction *nextAction = conActions.at(index);
948 qDebug() << "shortcut next:" << controllerMenu->title() <<
949 '<' << nextAction->text();
951 nextAction->setChecked(true);
952 nextAction->trigger();
955 void ContextMenu::slotShell()
959 const QString sdbPath = sdbHelper->getSdbPath();
961 QFileInfo sdbFileInfo(sdbPath);
962 if (sdbFileInfo.exists() == false) {
963 parent->showMsgBox(QMessageBox::Warning, MSG_SDB_NOT_EXIST + sdbPath);
967 if (!is_sdb_daemon_initialized()) {
968 parent->showMsgBox(QMessageBox::Warning, MSG_SDB_NOT_READY);
972 /* start command in a new process */
973 sdbHelper->openShell(vmName);
976 void ContextMenu::launchControlPanel(QString& command,
977 QStringList& arguments)
979 const char *https_proxy_addr = get_https_proxy_addr();
980 if (https_proxy_addr) {
981 char **proxy = g_strsplit(https_proxy_addr, ":", 2);
982 if (proxy[0] && proxy[1]) {
983 QString httpsProxyAddr = "-Dhttps.proxyHost=" + QString(proxy[0]);
984 QString httpsProxyPort = "-Dhttps.proxyPort=" + QString(proxy[1]);
985 if (httpsProxyAddr != NULL && httpsProxyPort != NULL) {
986 arguments << httpsProxyAddr << httpsProxyPort;
993 QString loggingCommand = QString("launching ecp: \"" + command + "\"");
995 QStringList wrapArguments;
996 for (int i = 0; i < arguments.size(); ++i) {
997 QString wrapArgument = QString("\"" + arguments.at(i) + "\"");
998 wrapArguments << wrapArgument;
999 loggingCommand += " " + wrapArgument;
1002 qInfo() << loggingCommand;
1004 QString workingDir = QFileInfo(command).canonicalPath();
1005 #ifndef CONFIG_WIN32
1007 QProcess::startDetached(command, arguments, workingDir);
1008 } catch (QString &error) {
1009 parent->showMsgBox(QMessageBox::Warning, MSG_INVALID_ECP_OPEN + error);
1013 QString winArguments = QString("\"" + command +"\"");
1014 for (int i = 0; i < arguments.size(); ++i) {
1015 winArguments += " \"" + arguments.at(i) + "\"";
1018 PROCESS_INFORMATION pinfo;
1020 STARTUPINFOW startupInfo = { sizeof(STARTUPINFO), 0, 0, 0,
1021 (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT,
1022 (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT,
1023 0, 0, 0, STARTF_USESHOWWINDOW, SW_HIDE, 0, 0, 0, 0, 0
1025 bool success = CreateProcessW(0, (LPWSTR)winArguments.utf16(),
1026 0, 0, FALSE, CREATE_UNICODE_ENVIRONMENT | CREATE_NEW_CONSOLE, 0,
1027 workingDir.isEmpty() ? 0 : (LPCWSTR)workingDir.utf16(),
1028 &startupInfo, &pinfo);
1032 QString error = QString::number(GetLastError());
1033 qWarning() << qPrintable(QString("error occured during launching \
1035 parent->showMsgBox(QMessageBox::Warning, MSG_INVALID_ECP_OPEN + error);
1038 CloseHandle(pinfo.hThread);
1039 CloseHandle(pinfo.hProcess);
1043 void ContextMenu::slotControlPanel()
1045 qDebug("Control Panel");
1048 QStringList arguments;
1050 // check for new ECP
1051 #if defined(CONFIG_WIN32)
1052 QString tmpEcpCommand = QDir(QCoreApplication::applicationDirPath() +
1053 QDir::separator() + SDK_EMULATOR_TOOLS_BIN_PATH +
1054 SDK_ECP_FILE + ".cmd").absolutePath();
1055 QString ecpCommand = QDir::toNativeSeparators(tmpEcpCommand);
1056 #elif defined(CONFIG_LINUX)
1057 QString ecpCommand = QDir(QCoreApplication::applicationDirPath() +
1058 QDir::separator() + SDK_EMULATOR_TOOLS_BIN_PATH +
1059 SDK_ECP_FILE).absolutePath();
1061 QString ecpCommand = QDir(QCoreApplication::applicationDirPath() +
1062 QDir::separator() + SDK_EMULATOR_TOOLS_BIN_PATH +
1063 SDK_ECP_FILE + ".app").absolutePath();
1065 if (QFileInfo(ecpCommand).exists()) {
1066 #if defined(CONFIG_DARWIN)
1067 // In mac os x, launch .app using "open" command
1068 // ex : open emulator-control-panel.app --args vm_name=... platform_version=...
1070 arguments << ecpCommand << "--args";
1072 command = ecpCommand;
1074 QString vmNameOpt = "vm_name=" + parent->getUiInfo()->getVmName();
1075 QString platformVersionOpt = "platform_version=" +
1076 QString::fromLocal8Bit(get_platform_version());
1077 QString profileOpt = "profile=" +
1078 QString::fromLocal8Bit(get_profile_name());
1079 QString basePortOpt =
1080 "base_port=" + QString::number(parent->getUiInfo()->getBasePort());
1082 arguments << vmNameOpt << platformVersionOpt << profileOpt
1085 // we have standalone command for ECP
1086 // we respect standalone command, so nothing to do
1087 launchControlPanel(command, arguments);
1092 // check for old ECP
1093 QString oldJar = QDir(QCoreApplication::applicationDirPath() +
1094 QDir::separator() + SDK_EMULATOR_BIN_PATH +
1095 SDK_ECP_FILE_JAR).absolutePath();
1096 if (QFileInfo(oldJar).exists()) {
1097 // we do not have standalone command for ECP
1098 // we may have SWT based ECP
1102 get_java_path(&path);
1105 command = QString::fromLocal8Bit(path);
1107 // can not enter here...
1108 parent->showMsgBox(QMessageBox::Warning, MSG_INVALID_JAVA_PATH);
1112 #if defined(__x86_64__) || defined(_WIN64)
1113 arguments << "-d64";
1115 #ifdef CONFIG_DARWIN
1116 /* SWT Display must be created on main thread due to Cocoa restrictions */
1117 arguments << "-XstartOnFirstThread";
1119 arguments << "-jar" << oldJar;
1121 QString vmNameOpt = "vmname=" + parent->getUiInfo()->getVmName();
1122 QString profileOpt = "profile=" +
1123 QString::fromLocal8Bit(get_profile_name());
1124 QString basePortOpt = "base.port=" +
1125 QString::number(parent->getUiInfo()->getBasePort());
1127 arguments << vmNameOpt << profileOpt << basePortOpt;
1129 launchControlPanel(command, arguments);
1134 // we can not launch ControlPanel
1135 parent->showMsgBox(QMessageBox::Warning, MSG_ECP_NOT_EXIST);
1140 void ContextMenu::slotRequestScreenshot()
1142 qDebug("request screenshot");
1147 void ContextMenu::slotShowScreenshot(const QPixmap &screenshot)
1149 qDebug("show screenshot");
1151 if (screenshotDialog == NULL) {
1152 screenshotDialog = new ScreenShotDialog(parent);
1155 screenshotDialog->slotRefresh(screenshot);
1156 screenshotDialog->show();
1159 slotOnTop(parent->getUiState()->isOnTop());
1163 void ContextMenu::slotHostKeyboard(bool on)
1165 qDebug("host keyboard: %s", on? "on" : "off");
1168 do_hotplug(ATTACH_HOST_KEYBOARD, NULL, 0);
1170 do_hotplug(DETACH_HOST_KEYBOARD, NULL, 0);
1174 void ContextMenu::slotAbout()
1178 if (aboutDialog == NULL) {
1179 aboutDialog = new AboutDialog((QWidget *)parent);
1182 aboutDialog->show();
1185 slotOnTop(parent->getUiState()->isOnTop());
1189 void ContextMenu::slotDeviceReset()
1191 qDebug("System reset request.");
1192 qemu_system_reset_request();
1193 qDebug("Done for system reset request.");
1196 void ContextMenu::slotSystemReset()
1198 int result = QMessageBox::question(this, EMULATOR_TITLE,
1199 MSG_SYSTEM_RESET_POPUP, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default);
1201 if (result == QMessageBox::Yes) {
1202 qDebug() << "Reboot.";
1204 send_shutdown_request(MENU_ACTION_REBOOT);
1206 rebootTimer->start();
1208 qDebug() << "cancelled to reboot.";
1212 void ContextMenu::slotForceClose()
1214 qDebug("force close");
1219 void ContextMenu::slotPwkeyRelease()
1221 do_hw_key_event(KEY_RELEASED, HARD_KEY_POWER);
1224 void ContextMenu::slotClose()
1228 do_hw_key_event(KEY_PRESSED, HARD_KEY_POWER);
1230 longPressTimer->setInterval(CLOSE_POWER_KEY_INTERVAL);
1231 longPressTimer->setSingleShot(true);
1232 QObject::connect(longPressTimer, SIGNAL(timeout()), this, SLOT(slotPwkeyRelease()));
1233 longPressTimer->start();
1236 QSignalMapper *ContextMenu::getSwitchMapper()
1238 return switchMapper;
1241 QSignalMapper *ContextMenu::getScaleMapper()
1246 QSignalMapper *ContextMenu::getControllerMapper()
1248 return controllerMapper;
1251 ContextMenu::~ContextMenu()
1253 qDebug("destroy menu");
1257 longPressTimer->stop();
1259 rebootTimer->stop();