From 85c0ec99d0dc1e0d98c6ef155baebbc59c3eaed7 Mon Sep 17 00:00:00 2001 From: WAZAAAAA WAZAAAAA00 Date: Thu, 7 Apr 2016 13:06:55 +0200 Subject: [PATCH] first upload --- AntiMicro Future Developments.mm | 30 + BuildOptions.md | 57 + CMakeLists.txt | 836 +++ Changelog | 1038 +++ ProfileTips.md | 78 + README.md | 350 + Resources.txt | 15 + cmake_uninstall.cmake.in | 21 + gpl.txt | 674 ++ other/40-uinput.rules | 1 + other/CMakeLists.txt | 7 + other/antimicro.1 | 63 + other/antimicro.desktop | 17 + other/antimicro.xml | 8 + other/appdata/CMakeLists.txt | 16 + other/appdata/PO_files/en.po | 81 + other/appdata/antimicro.appdata.xml.in | 35 + other/appdata/appdata.its | 9 + .../screenshots/controller_configure01.png | Bin 0 -> 53337 bytes .../screenshots/controller_configure02.png | Bin 0 -> 58045 bytes .../screenshots/controller_mapping01.png | Bin 0 -> 105539 bytes share/antimicro/blank.txt | 0 share/antimicro/translations/CMakeLists.txt | 27 + share/antimicro/translations/antimicro.ts | 5880 ++++++++++++++++ share/antimicro/translations/antimicro_br.ts | 5881 ++++++++++++++++ share/antimicro/translations/antimicro_de.ts | 5966 ++++++++++++++++ share/antimicro/translations/antimicro_en.ts | 5880 ++++++++++++++++ share/antimicro/translations/antimicro_fr.ts | 5920 ++++++++++++++++ share/antimicro/translations/antimicro_ja.ts | 5880 ++++++++++++++++ share/antimicro/translations/antimicro_ru.ts | 5911 ++++++++++++++++ share/antimicro/translations/antimicro_sr.ts | 6032 ++++++++++++++++ share/antimicro/translations/antimicro_uk.ts | 5919 ++++++++++++++++ .../antimicro/translations/antimicro_zh_CN.ts | 6078 +++++++++++++++++ share/blank.txt | 0 src/aboutdialog.cpp | 115 + src/aboutdialog.h | 44 + src/aboutdialog.ui | 445 ++ src/addeditautoprofiledialog.cpp | 569 ++ src/addeditautoprofiledialog.h | 84 + src/addeditautoprofiledialog.ui | 237 + src/advancebuttondialog.cpp | 1554 +++++ src/advancebuttondialog.h | 124 + src/advancebuttondialog.ui | 1280 ++++ src/advancestickassignmentdialog.cpp | 1364 ++++ src/advancestickassignmentdialog.h | 90 + src/advancestickassignmentdialog.ui | 645 ++ src/antimicro.exe.manifest | 17 + src/antimicro.exe.uiaccess.manifest | 17 + src/antimicro.rc | 8 + src/antimicrosettings.cpp | 78 + src/antimicrosettings.h | 51 + src/antkeymapper.cpp | 144 + src/antkeymapper.h | 85 + src/applaunchhelper.cpp | 181 + src/applaunchhelper.h | 63 + src/autoprofileinfo.cpp | 158 + src/autoprofileinfo.h | 77 + src/autoprofilewatcher.cpp | 484 ++ src/autoprofilewatcher.h | 74 + src/axiseditdialog.cpp | 653 ++ src/axiseditdialog.h | 78 + src/axiseditdialog.ui | 575 ++ src/axisvaluebox.cpp | 208 + src/axisvaluebox.h | 61 + src/buttoneditdialog.cpp | 450 ++ src/buttoneditdialog.h | 76 + src/buttoneditdialog.ui | 327 + src/capturedwindowinfodialog.cpp | 200 + src/capturedwindowinfodialog.h | 71 + src/capturedwindowinfodialog.ui | 230 + src/commandlineutility.cpp | 779 +++ src/commandlineutility.h | 225 + src/common.cpp | 185 + src/common.h | 152 + src/config.h.in | 8 + src/dpadcontextmenu.cpp | 406 ++ src/dpadcontextmenu.h | 50 + src/dpadeditdialog.cpp | 400 ++ src/dpadeditdialog.h | 57 + src/dpadeditdialog.ui | 337 + src/dpadpushbutton.cpp | 84 + src/dpadpushbutton.h | 51 + src/dpadpushbuttongroup.cpp | 204 + src/dpadpushbuttongroup.h | 66 + src/editalldefaultautoprofiledialog.cpp | 99 + src/editalldefaultautoprofiledialog.h | 55 + src/editalldefaultautoprofiledialog.ui | 107 + src/event.cpp | 640 ++ src/event.h | 37 + src/eventhandlerfactory.cpp | 156 + src/eventhandlerfactory.h | 95 + src/eventhandlers/baseeventhandler.cpp | 68 + src/eventhandlers/baseeventhandler.h | 56 + src/eventhandlers/uinputeventhandler.cpp | 584 ++ src/eventhandlers/uinputeventhandler.h | 75 + .../winsendinputeventhandler.cpp | 239 + src/eventhandlers/winsendinputeventhandler.h | 51 + src/eventhandlers/winvmultieventhandler.cpp | 393 ++ src/eventhandlers/winvmultieventhandler.h | 72 + src/eventhandlers/xtesteventhandler.cpp | 214 + src/eventhandlers/xtesteventhandler.h | 48 + src/extraprofilesettingsdialog.cpp | 59 + src/extraprofilesettingsdialog.h | 47 + src/extraprofilesettingsdialog.ui | 160 + src/flashbuttonwidget.cpp | 132 + src/flashbuttonwidget.h | 60 + src/gamecontroller/gamecontroller.cpp | 961 +++ src/gamecontroller/gamecontroller.h | 87 + src/gamecontroller/gamecontrollerdpad.cpp | 80 + src/gamecontroller/gamecontrollerdpad.h | 45 + src/gamecontroller/gamecontrollerset.cpp | 348 + src/gamecontroller/gamecontrollerset.h | 55 + src/gamecontroller/gamecontrollertrigger.cpp | 199 + src/gamecontroller/gamecontrollertrigger.h | 63 + .../gamecontrollertriggerbutton.cpp | 55 + .../gamecontrollertriggerbutton.h | 43 + src/gamecontrollerexample.cpp | 104 + src/gamecontrollerexample.h | 52 + src/gamecontrollermappingdialog.cpp | 657 ++ src/gamecontrollermappingdialog.h | 90 + src/gamecontrollermappingdialog.ui | 445 ++ src/icons/16x16/actions/application-exit.png | Bin 0 -> 781 bytes src/icons/16x16/actions/archive-insert.png | Bin 0 -> 433 bytes src/icons/16x16/actions/dialog-cancel.png | Bin 0 -> 848 bytes src/icons/16x16/actions/dialog-close.png | Bin 0 -> 813 bytes src/icons/16x16/actions/dialog-ok.png | Bin 0 -> 601 bytes src/icons/16x16/actions/document-close.png | Bin 0 -> 678 bytes .../16x16/actions/document-open-folder.png | Bin 0 -> 659 bytes src/icons/16x16/actions/document-open.png | Bin 0 -> 784 bytes .../16x16/actions/document-revert-small.png | Bin 0 -> 948 bytes src/icons/16x16/actions/document-revert.png | Bin 0 -> 948 bytes src/icons/16x16/actions/document-save-as.png | Bin 0 -> 773 bytes src/icons/16x16/actions/document-save.png | Bin 0 -> 694 bytes src/icons/16x16/actions/edit-clear-list.png | Bin 0 -> 669 bytes src/icons/16x16/actions/edit-clear.png | Bin 0 -> 739 bytes src/icons/16x16/actions/edit-delete.png | Bin 0 -> 1031 bytes src/icons/16x16/actions/edit-select.png | Bin 0 -> 368 bytes .../16x16/actions/edit-table-delete-row.png | Bin 0 -> 863 bytes .../actions/edit-table-insert-row-below.png | Bin 0 -> 852 bytes .../16x16/actions/games-config-custom.png | Bin 0 -> 1112 bytes .../16x16/actions/games-config-options.png | Bin 0 -> 1069 bytes src/icons/16x16/actions/help-about.png | Bin 0 -> 669 bytes src/icons/16x16/actions/text-field.png | Bin 0 -> 335 bytes src/icons/16x16/actions/view-fullscreen.png | Bin 0 -> 559 bytes src/icons/16x16/actions/view-refresh.png | Bin 0 -> 922 bytes src/icons/16x16/actions/view-restore.png | Bin 0 -> 444 bytes src/icons/README.txt | 15 + src/icons/index.theme | 7 + src/icons/lgpl-2.1.txt | 502 ++ src/icons/lgpl-3.0.txt | 165 + src/images/antimicro.ico | Bin 0 -> 14426 bytes src/images/antimicro.png | Bin 0 -> 3525 bytes src/images/antimicro_trayicon.png | Bin 0 -> 3525 bytes src/images/axis.png | Bin 0 -> 1806 bytes src/images/button.png | Bin 0 -> 1895 bytes src/images/controllermap.png | Bin 0 -> 33351 bytes src/images/profile.jpg | Bin 0 -> 11061 bytes src/inputdaemon.cpp | 1073 +++ src/inputdaemon.h | 122 + src/inputdevice.cpp | 2289 +++++++ src/inputdevice.h | 242 + src/inputdevicebitarraystatus.cpp | 132 + src/inputdevicebitarraystatus.h | 51 + src/joyaxis.cpp | 1167 ++++ src/joyaxis.h | 217 + src/joyaxiscontextmenu.cpp | 463 ++ src/joyaxiscontextmenu.h | 52 + src/joyaxiswidget.cpp | 99 + src/joyaxiswidget.h | 51 + src/joybutton.cpp | 5868 ++++++++++++++++ src/joybutton.h | 600 ++ src/joybuttoncontextmenu.cpp | 181 + src/joybuttoncontextmenu.h | 44 + src/joybuttonmousehelper.cpp | 121 + src/joybuttonmousehelper.h | 51 + src/joybuttonslot.cpp | 775 +++ src/joybuttonslot.h | 109 + src/joybuttonstatusbox.cpp | 62 + src/joybuttonstatusbox.h | 47 + src/joybuttontypes/joyaxisbutton.cpp | 208 + src/joybuttontypes/joyaxisbutton.h | 59 + src/joybuttontypes/joycontrolstickbutton.cpp | 284 + src/joybuttontypes/joycontrolstickbutton.h | 67 + .../joycontrolstickmodifierbutton.cpp | 148 + .../joycontrolstickmodifierbutton.h | 54 + src/joybuttontypes/joydpadbutton.cpp | 164 + src/joybuttontypes/joydpadbutton.h | 59 + src/joybuttontypes/joygradientbutton.cpp | 526 ++ src/joybuttontypes/joygradientbutton.h | 37 + src/joybuttonwidget.cpp | 80 + src/joybuttonwidget.h | 51 + src/joycontrolstick.cpp | 4177 +++++++++++ src/joycontrolstick.h | 298 + src/joycontrolstickbuttonpushbutton.cpp | 123 + src/joycontrolstickbuttonpushbutton.h | 53 + src/joycontrolstickcontextmenu.cpp | 399 ++ src/joycontrolstickcontextmenu.h | 49 + src/joycontrolstickdirectionstype.h | 30 + src/joycontrolstickeditdialog.cpp | 549 ++ src/joycontrolstickeditdialog.h | 65 + src/joycontrolstickeditdialog.ui | 848 +++ src/joycontrolstickpushbutton.cpp | 89 + src/joycontrolstickpushbutton.h | 51 + src/joycontrolstickstatusbox.cpp | 522 ++ src/joycontrolstickstatusbox.h | 55 + src/joydpad.cpp | 1236 ++++ src/joydpad.h | 160 + src/joydpadbuttonwidget.cpp | 44 + src/joydpadbuttonwidget.h | 37 + src/joykeyrepeathelper.cpp | 86 + src/joykeyrepeathelper.h | 54 + src/joystick.cpp | 120 + src/joystick.h | 59 + src/joystickstatuswindow.cpp | 198 + src/joystickstatuswindow.h | 48 + src/joystickstatuswindow.ui | 463 ++ src/joytabwidget.cpp | 2460 +++++++ src/joytabwidget.h | 217 + src/joytabwidgetcontainer.cpp | 113 + src/joytabwidgetcontainer.h | 50 + src/keyboard/virtualkeyboardmousewidget.cpp | 854 +++ src/keyboard/virtualkeyboardmousewidget.h | 104 + src/keyboard/virtualkeypushbutton.cpp | 199 + src/keyboard/virtualkeypushbutton.h | 56 + src/keyboard/virtualmousepushbutton.cpp | 76 + src/keyboard/virtualmousepushbutton.h | 49 + src/localantimicroserver.cpp | 65 + src/localantimicroserver.h | 43 + src/logger.cpp | 357 + src/logger.h | 149 + src/main.cpp | 803 +++ src/mainsettingsdialog.cpp | 1990 ++++++ src/mainsettingsdialog.h | 104 + src/mainsettingsdialog.ui | 1237 ++++ src/mainwindow.cpp | 1809 +++++ src/mainwindow.h | 167 + src/mainwindow.ui | 423 ++ src/mousedialog/mouseaxissettingsdialog.cpp | 391 ++ src/mousedialog/mouseaxissettingsdialog.h | 75 + src/mousedialog/mousebuttonsettingsdialog.cpp | 274 + src/mousedialog/mousebuttonsettingsdialog.h | 61 + .../mousecontrolsticksettingsdialog.cpp | 366 + .../mousecontrolsticksettingsdialog.h | 74 + src/mousedialog/mousedpadsettingsdialog.cpp | 330 + src/mousedialog/mousedpadsettingsdialog.h | 66 + src/mousedialog/springmoderegionpreview.cpp | 178 + src/mousedialog/springmoderegionpreview.h | 43 + .../mouseaxissettingsdialoghelper.cpp | 69 + .../uihelpers/mouseaxissettingsdialoghelper.h | 47 + .../mousebuttonsettingsdialoghelper.cpp | 66 + .../mousebuttonsettingsdialoghelper.h | 50 + .../mousecontrolsticksettingsdialoghelper.cpp | 62 + .../mousecontrolsticksettingsdialoghelper.h | 47 + .../mousedpadsettingsdialoghelper.cpp | 27 + .../uihelpers/mousedpadsettingsdialoghelper.h | 40 + src/mousehelper.cpp | 58 + src/mousehelper.h | 48 + src/mousesettingsdialog.cpp | 406 ++ src/mousesettingsdialog.h | 71 + src/mousesettingsdialog.ui | 1004 +++ src/qkeydisplaydialog.cpp | 178 + src/qkeydisplaydialog.h | 44 + src/qkeydisplaydialog.ui | 231 + src/qtkeymapperbase.cpp | 87 + src/qtkeymapperbase.h | 96 + src/qtuinputkeymapper.cpp | 537 ++ src/qtuinputkeymapper.h | 47 + src/qtvmultikeymapper.cpp | 181 + src/qtvmultikeymapper.h | 46 + src/qtwinkeymapper.cpp | 410 ++ src/qtwinkeymapper.h | 45 + src/qtx11keymapper.cpp | 382 ++ src/qtx11keymapper.h | 43 + src/quicksetdialog.cpp | 333 + src/quicksetdialog.h | 57 + src/quicksetdialog.ui | 80 + src/resources.qrc | 12 + src/resources_windows.qrc | 30 + src/sdleventreader.cpp | 289 + src/sdleventreader.h | 79 + src/setaxisthrottledialog.cpp | 47 + src/setaxisthrottledialog.h | 51 + src/setaxisthrottledialog.ui | 79 + src/setjoystick.cpp | 1099 +++ src/setjoystick.h | 177 + src/setnamesdialog.cpp | 59 + src/setnamesdialog.h | 47 + src/setnamesdialog.ui | 168 + src/simplekeygrabberbutton.cpp | 359 + src/simplekeygrabberbutton.h | 62 + src/slotitemlistwidget.cpp | 56 + src/slotitemlistwidget.h | 39 + src/springmousemoveinfo.h | 41 + src/stickpushbuttongroup.cpp | 197 + src/stickpushbuttongroup.h | 65 + src/uihelpers/advancebuttondialoghelper.cpp | 53 + src/uihelpers/advancebuttondialoghelper.h | 47 + src/uihelpers/buttoneditdialoghelper.cpp | 38 + src/uihelpers/buttoneditdialoghelper.h | 43 + src/uihelpers/dpadcontextmenuhelper.cpp | 82 + src/uihelpers/dpadcontextmenuhelper.h | 46 + src/uihelpers/dpadeditdialoghelper.cpp | 89 + src/uihelpers/dpadeditdialoghelper.h | 47 + .../gamecontrollermappingdialoghelper.cpp | 58 + .../gamecontrollermappingdialoghelper.h | 45 + src/uihelpers/joyaxiscontextmenuhelper.cpp | 50 + src/uihelpers/joyaxiscontextmenuhelper.h | 45 + .../joycontrolstickcontextmenuhelper.cpp | 88 + .../joycontrolstickcontextmenuhelper.h | 45 + .../joycontrolstickeditdialoghelper.cpp | 97 + .../joycontrolstickeditdialoghelper.h | 46 + src/uihelpers/joytabwidgethelper.cpp | 152 + src/uihelpers/joytabwidgethelper.h | 62 + src/uinputhelper.cpp | 320 + src/uinputhelper.h | 51 + src/unixcapturewindowutility.cpp | 138 + src/unixcapturewindowutility.h | 44 + src/unixwindowinfodialog.cpp | 139 + src/unixwindowinfodialog.h | 62 + src/unixwindowinfodialog.ui | 209 + src/vdpad.cpp | 299 + src/vdpad.h | 61 + src/winappprofiletimerdialog.cpp | 25 + src/winappprofiletimerdialog.h | 32 + src/winappprofiletimerdialog.ui | 96 + src/winextras.cpp | 502 ++ src/winextras.h | 49 + src/x11extras.cpp | 864 +++ src/x11extras.h | 99 + src/xmlconfigmigration.cpp | 181 + src/xmlconfigmigration.h | 50 + src/xmlconfigreader.cpp | 190 + src/xmlconfigreader.h | 62 + src/xmlconfigwriter.cpp | 95 + src/xmlconfigwriter.h | 53 + windows/AntiMicro.wxs | 229 + windows/AntiMicro_64.wxs | 233 + 337 files changed, 135564 insertions(+) create mode 100644 AntiMicro Future Developments.mm create mode 100644 BuildOptions.md create mode 100644 CMakeLists.txt create mode 100644 Changelog create mode 100644 ProfileTips.md create mode 100644 README.md create mode 100644 Resources.txt create mode 100644 cmake_uninstall.cmake.in create mode 100644 gpl.txt create mode 100644 other/40-uinput.rules create mode 100644 other/CMakeLists.txt create mode 100644 other/antimicro.1 create mode 100644 other/antimicro.desktop create mode 100644 other/antimicro.xml create mode 100644 other/appdata/CMakeLists.txt create mode 100644 other/appdata/PO_files/en.po create mode 100644 other/appdata/antimicro.appdata.xml.in create mode 100644 other/appdata/appdata.its create mode 100644 other/appdata/screenshots/controller_configure01.png create mode 100644 other/appdata/screenshots/controller_configure02.png create mode 100644 other/appdata/screenshots/controller_mapping01.png create mode 100644 share/antimicro/blank.txt create mode 100644 share/antimicro/translations/CMakeLists.txt create mode 100644 share/antimicro/translations/antimicro.ts create mode 100644 share/antimicro/translations/antimicro_br.ts create mode 100644 share/antimicro/translations/antimicro_de.ts create mode 100644 share/antimicro/translations/antimicro_en.ts create mode 100644 share/antimicro/translations/antimicro_fr.ts create mode 100644 share/antimicro/translations/antimicro_ja.ts create mode 100644 share/antimicro/translations/antimicro_ru.ts create mode 100644 share/antimicro/translations/antimicro_sr.ts create mode 100644 share/antimicro/translations/antimicro_uk.ts create mode 100644 share/antimicro/translations/antimicro_zh_CN.ts create mode 100644 share/blank.txt create mode 100644 src/aboutdialog.cpp create mode 100644 src/aboutdialog.h create mode 100644 src/aboutdialog.ui create mode 100644 src/addeditautoprofiledialog.cpp create mode 100644 src/addeditautoprofiledialog.h create mode 100644 src/addeditautoprofiledialog.ui create mode 100644 src/advancebuttondialog.cpp create mode 100644 src/advancebuttondialog.h create mode 100644 src/advancebuttondialog.ui create mode 100644 src/advancestickassignmentdialog.cpp create mode 100644 src/advancestickassignmentdialog.h create mode 100644 src/advancestickassignmentdialog.ui create mode 100644 src/antimicro.exe.manifest create mode 100644 src/antimicro.exe.uiaccess.manifest create mode 100644 src/antimicro.rc create mode 100644 src/antimicrosettings.cpp create mode 100644 src/antimicrosettings.h create mode 100644 src/antkeymapper.cpp create mode 100644 src/antkeymapper.h create mode 100644 src/applaunchhelper.cpp create mode 100644 src/applaunchhelper.h create mode 100644 src/autoprofileinfo.cpp create mode 100644 src/autoprofileinfo.h create mode 100644 src/autoprofilewatcher.cpp create mode 100644 src/autoprofilewatcher.h create mode 100644 src/axiseditdialog.cpp create mode 100644 src/axiseditdialog.h create mode 100644 src/axiseditdialog.ui create mode 100644 src/axisvaluebox.cpp create mode 100644 src/axisvaluebox.h create mode 100644 src/buttoneditdialog.cpp create mode 100644 src/buttoneditdialog.h create mode 100644 src/buttoneditdialog.ui create mode 100644 src/capturedwindowinfodialog.cpp create mode 100644 src/capturedwindowinfodialog.h create mode 100644 src/capturedwindowinfodialog.ui create mode 100644 src/commandlineutility.cpp create mode 100644 src/commandlineutility.h create mode 100644 src/common.cpp create mode 100644 src/common.h create mode 100644 src/config.h.in create mode 100644 src/dpadcontextmenu.cpp create mode 100644 src/dpadcontextmenu.h create mode 100644 src/dpadeditdialog.cpp create mode 100644 src/dpadeditdialog.h create mode 100644 src/dpadeditdialog.ui create mode 100644 src/dpadpushbutton.cpp create mode 100644 src/dpadpushbutton.h create mode 100644 src/dpadpushbuttongroup.cpp create mode 100644 src/dpadpushbuttongroup.h create mode 100644 src/editalldefaultautoprofiledialog.cpp create mode 100644 src/editalldefaultautoprofiledialog.h create mode 100644 src/editalldefaultautoprofiledialog.ui create mode 100644 src/event.cpp create mode 100644 src/event.h create mode 100644 src/eventhandlerfactory.cpp create mode 100644 src/eventhandlerfactory.h create mode 100644 src/eventhandlers/baseeventhandler.cpp create mode 100644 src/eventhandlers/baseeventhandler.h create mode 100644 src/eventhandlers/uinputeventhandler.cpp create mode 100644 src/eventhandlers/uinputeventhandler.h create mode 100644 src/eventhandlers/winsendinputeventhandler.cpp create mode 100644 src/eventhandlers/winsendinputeventhandler.h create mode 100644 src/eventhandlers/winvmultieventhandler.cpp create mode 100644 src/eventhandlers/winvmultieventhandler.h create mode 100644 src/eventhandlers/xtesteventhandler.cpp create mode 100644 src/eventhandlers/xtesteventhandler.h create mode 100644 src/extraprofilesettingsdialog.cpp create mode 100644 src/extraprofilesettingsdialog.h create mode 100644 src/extraprofilesettingsdialog.ui create mode 100644 src/flashbuttonwidget.cpp create mode 100644 src/flashbuttonwidget.h create mode 100644 src/gamecontroller/gamecontroller.cpp create mode 100644 src/gamecontroller/gamecontroller.h create mode 100644 src/gamecontroller/gamecontrollerdpad.cpp create mode 100644 src/gamecontroller/gamecontrollerdpad.h create mode 100644 src/gamecontroller/gamecontrollerset.cpp create mode 100644 src/gamecontroller/gamecontrollerset.h create mode 100644 src/gamecontroller/gamecontrollertrigger.cpp create mode 100644 src/gamecontroller/gamecontrollertrigger.h create mode 100644 src/gamecontroller/gamecontrollertriggerbutton.cpp create mode 100644 src/gamecontroller/gamecontrollertriggerbutton.h create mode 100644 src/gamecontrollerexample.cpp create mode 100644 src/gamecontrollerexample.h create mode 100644 src/gamecontrollermappingdialog.cpp create mode 100644 src/gamecontrollermappingdialog.h create mode 100644 src/gamecontrollermappingdialog.ui create mode 100644 src/icons/16x16/actions/application-exit.png create mode 100644 src/icons/16x16/actions/archive-insert.png create mode 100644 src/icons/16x16/actions/dialog-cancel.png create mode 100644 src/icons/16x16/actions/dialog-close.png create mode 100644 src/icons/16x16/actions/dialog-ok.png create mode 100644 src/icons/16x16/actions/document-close.png create mode 100644 src/icons/16x16/actions/document-open-folder.png create mode 100644 src/icons/16x16/actions/document-open.png create mode 100644 src/icons/16x16/actions/document-revert-small.png create mode 100644 src/icons/16x16/actions/document-revert.png create mode 100644 src/icons/16x16/actions/document-save-as.png create mode 100644 src/icons/16x16/actions/document-save.png create mode 100644 src/icons/16x16/actions/edit-clear-list.png create mode 100644 src/icons/16x16/actions/edit-clear.png create mode 100644 src/icons/16x16/actions/edit-delete.png create mode 100644 src/icons/16x16/actions/edit-select.png create mode 100644 src/icons/16x16/actions/edit-table-delete-row.png create mode 100644 src/icons/16x16/actions/edit-table-insert-row-below.png create mode 100644 src/icons/16x16/actions/games-config-custom.png create mode 100644 src/icons/16x16/actions/games-config-options.png create mode 100644 src/icons/16x16/actions/help-about.png create mode 100644 src/icons/16x16/actions/text-field.png create mode 100644 src/icons/16x16/actions/view-fullscreen.png create mode 100644 src/icons/16x16/actions/view-refresh.png create mode 100644 src/icons/16x16/actions/view-restore.png create mode 100644 src/icons/README.txt create mode 100644 src/icons/index.theme create mode 100644 src/icons/lgpl-2.1.txt create mode 100644 src/icons/lgpl-3.0.txt create mode 100644 src/images/antimicro.ico create mode 100644 src/images/antimicro.png create mode 100644 src/images/antimicro_trayicon.png create mode 100644 src/images/axis.png create mode 100644 src/images/button.png create mode 100644 src/images/controllermap.png create mode 100644 src/images/profile.jpg create mode 100644 src/inputdaemon.cpp create mode 100644 src/inputdaemon.h create mode 100644 src/inputdevice.cpp create mode 100644 src/inputdevice.h create mode 100644 src/inputdevicebitarraystatus.cpp create mode 100644 src/inputdevicebitarraystatus.h create mode 100644 src/joyaxis.cpp create mode 100644 src/joyaxis.h create mode 100644 src/joyaxiscontextmenu.cpp create mode 100644 src/joyaxiscontextmenu.h create mode 100644 src/joyaxiswidget.cpp create mode 100644 src/joyaxiswidget.h create mode 100644 src/joybutton.cpp create mode 100644 src/joybutton.h create mode 100644 src/joybuttoncontextmenu.cpp create mode 100644 src/joybuttoncontextmenu.h create mode 100644 src/joybuttonmousehelper.cpp create mode 100644 src/joybuttonmousehelper.h create mode 100644 src/joybuttonslot.cpp create mode 100644 src/joybuttonslot.h create mode 100644 src/joybuttonstatusbox.cpp create mode 100644 src/joybuttonstatusbox.h create mode 100644 src/joybuttontypes/joyaxisbutton.cpp create mode 100644 src/joybuttontypes/joyaxisbutton.h create mode 100644 src/joybuttontypes/joycontrolstickbutton.cpp create mode 100644 src/joybuttontypes/joycontrolstickbutton.h create mode 100644 src/joybuttontypes/joycontrolstickmodifierbutton.cpp create mode 100644 src/joybuttontypes/joycontrolstickmodifierbutton.h create mode 100644 src/joybuttontypes/joydpadbutton.cpp create mode 100644 src/joybuttontypes/joydpadbutton.h create mode 100644 src/joybuttontypes/joygradientbutton.cpp create mode 100644 src/joybuttontypes/joygradientbutton.h create mode 100644 src/joybuttonwidget.cpp create mode 100644 src/joybuttonwidget.h create mode 100644 src/joycontrolstick.cpp create mode 100644 src/joycontrolstick.h create mode 100644 src/joycontrolstickbuttonpushbutton.cpp create mode 100644 src/joycontrolstickbuttonpushbutton.h create mode 100644 src/joycontrolstickcontextmenu.cpp create mode 100644 src/joycontrolstickcontextmenu.h create mode 100644 src/joycontrolstickdirectionstype.h create mode 100644 src/joycontrolstickeditdialog.cpp create mode 100644 src/joycontrolstickeditdialog.h create mode 100644 src/joycontrolstickeditdialog.ui create mode 100644 src/joycontrolstickpushbutton.cpp create mode 100644 src/joycontrolstickpushbutton.h create mode 100644 src/joycontrolstickstatusbox.cpp create mode 100644 src/joycontrolstickstatusbox.h create mode 100644 src/joydpad.cpp create mode 100644 src/joydpad.h create mode 100644 src/joydpadbuttonwidget.cpp create mode 100644 src/joydpadbuttonwidget.h create mode 100644 src/joykeyrepeathelper.cpp create mode 100644 src/joykeyrepeathelper.h create mode 100644 src/joystick.cpp create mode 100644 src/joystick.h create mode 100644 src/joystickstatuswindow.cpp create mode 100644 src/joystickstatuswindow.h create mode 100644 src/joystickstatuswindow.ui create mode 100644 src/joytabwidget.cpp create mode 100644 src/joytabwidget.h create mode 100644 src/joytabwidgetcontainer.cpp create mode 100644 src/joytabwidgetcontainer.h create mode 100644 src/keyboard/virtualkeyboardmousewidget.cpp create mode 100644 src/keyboard/virtualkeyboardmousewidget.h create mode 100644 src/keyboard/virtualkeypushbutton.cpp create mode 100644 src/keyboard/virtualkeypushbutton.h create mode 100644 src/keyboard/virtualmousepushbutton.cpp create mode 100644 src/keyboard/virtualmousepushbutton.h create mode 100644 src/localantimicroserver.cpp create mode 100644 src/localantimicroserver.h create mode 100644 src/logger.cpp create mode 100644 src/logger.h create mode 100644 src/main.cpp create mode 100644 src/mainsettingsdialog.cpp create mode 100644 src/mainsettingsdialog.h create mode 100644 src/mainsettingsdialog.ui create mode 100644 src/mainwindow.cpp create mode 100644 src/mainwindow.h create mode 100644 src/mainwindow.ui create mode 100644 src/mousedialog/mouseaxissettingsdialog.cpp create mode 100644 src/mousedialog/mouseaxissettingsdialog.h create mode 100644 src/mousedialog/mousebuttonsettingsdialog.cpp create mode 100644 src/mousedialog/mousebuttonsettingsdialog.h create mode 100644 src/mousedialog/mousecontrolsticksettingsdialog.cpp create mode 100644 src/mousedialog/mousecontrolsticksettingsdialog.h create mode 100644 src/mousedialog/mousedpadsettingsdialog.cpp create mode 100644 src/mousedialog/mousedpadsettingsdialog.h create mode 100644 src/mousedialog/springmoderegionpreview.cpp create mode 100644 src/mousedialog/springmoderegionpreview.h create mode 100644 src/mousedialog/uihelpers/mouseaxissettingsdialoghelper.cpp create mode 100644 src/mousedialog/uihelpers/mouseaxissettingsdialoghelper.h create mode 100644 src/mousedialog/uihelpers/mousebuttonsettingsdialoghelper.cpp create mode 100644 src/mousedialog/uihelpers/mousebuttonsettingsdialoghelper.h create mode 100644 src/mousedialog/uihelpers/mousecontrolsticksettingsdialoghelper.cpp create mode 100644 src/mousedialog/uihelpers/mousecontrolsticksettingsdialoghelper.h create mode 100644 src/mousedialog/uihelpers/mousedpadsettingsdialoghelper.cpp create mode 100644 src/mousedialog/uihelpers/mousedpadsettingsdialoghelper.h create mode 100644 src/mousehelper.cpp create mode 100644 src/mousehelper.h create mode 100644 src/mousesettingsdialog.cpp create mode 100644 src/mousesettingsdialog.h create mode 100644 src/mousesettingsdialog.ui create mode 100644 src/qkeydisplaydialog.cpp create mode 100644 src/qkeydisplaydialog.h create mode 100644 src/qkeydisplaydialog.ui create mode 100644 src/qtkeymapperbase.cpp create mode 100644 src/qtkeymapperbase.h create mode 100644 src/qtuinputkeymapper.cpp create mode 100644 src/qtuinputkeymapper.h create mode 100644 src/qtvmultikeymapper.cpp create mode 100644 src/qtvmultikeymapper.h create mode 100644 src/qtwinkeymapper.cpp create mode 100644 src/qtwinkeymapper.h create mode 100644 src/qtx11keymapper.cpp create mode 100644 src/qtx11keymapper.h create mode 100644 src/quicksetdialog.cpp create mode 100644 src/quicksetdialog.h create mode 100644 src/quicksetdialog.ui create mode 100644 src/resources.qrc create mode 100644 src/resources_windows.qrc create mode 100644 src/sdleventreader.cpp create mode 100644 src/sdleventreader.h create mode 100644 src/setaxisthrottledialog.cpp create mode 100644 src/setaxisthrottledialog.h create mode 100644 src/setaxisthrottledialog.ui create mode 100644 src/setjoystick.cpp create mode 100644 src/setjoystick.h create mode 100644 src/setnamesdialog.cpp create mode 100644 src/setnamesdialog.h create mode 100644 src/setnamesdialog.ui create mode 100644 src/simplekeygrabberbutton.cpp create mode 100644 src/simplekeygrabberbutton.h create mode 100644 src/slotitemlistwidget.cpp create mode 100644 src/slotitemlistwidget.h create mode 100644 src/springmousemoveinfo.h create mode 100644 src/stickpushbuttongroup.cpp create mode 100644 src/stickpushbuttongroup.h create mode 100644 src/uihelpers/advancebuttondialoghelper.cpp create mode 100644 src/uihelpers/advancebuttondialoghelper.h create mode 100644 src/uihelpers/buttoneditdialoghelper.cpp create mode 100644 src/uihelpers/buttoneditdialoghelper.h create mode 100644 src/uihelpers/dpadcontextmenuhelper.cpp create mode 100644 src/uihelpers/dpadcontextmenuhelper.h create mode 100644 src/uihelpers/dpadeditdialoghelper.cpp create mode 100644 src/uihelpers/dpadeditdialoghelper.h create mode 100644 src/uihelpers/gamecontrollermappingdialoghelper.cpp create mode 100644 src/uihelpers/gamecontrollermappingdialoghelper.h create mode 100644 src/uihelpers/joyaxiscontextmenuhelper.cpp create mode 100644 src/uihelpers/joyaxiscontextmenuhelper.h create mode 100644 src/uihelpers/joycontrolstickcontextmenuhelper.cpp create mode 100644 src/uihelpers/joycontrolstickcontextmenuhelper.h create mode 100644 src/uihelpers/joycontrolstickeditdialoghelper.cpp create mode 100644 src/uihelpers/joycontrolstickeditdialoghelper.h create mode 100644 src/uihelpers/joytabwidgethelper.cpp create mode 100644 src/uihelpers/joytabwidgethelper.h create mode 100644 src/uinputhelper.cpp create mode 100644 src/uinputhelper.h create mode 100644 src/unixcapturewindowutility.cpp create mode 100644 src/unixcapturewindowutility.h create mode 100644 src/unixwindowinfodialog.cpp create mode 100644 src/unixwindowinfodialog.h create mode 100644 src/unixwindowinfodialog.ui create mode 100644 src/vdpad.cpp create mode 100644 src/vdpad.h create mode 100644 src/winappprofiletimerdialog.cpp create mode 100644 src/winappprofiletimerdialog.h create mode 100644 src/winappprofiletimerdialog.ui create mode 100644 src/winextras.cpp create mode 100644 src/winextras.h create mode 100644 src/x11extras.cpp create mode 100644 src/x11extras.h create mode 100644 src/xmlconfigmigration.cpp create mode 100644 src/xmlconfigmigration.h create mode 100644 src/xmlconfigreader.cpp create mode 100644 src/xmlconfigreader.h create mode 100644 src/xmlconfigwriter.cpp create mode 100644 src/xmlconfigwriter.h create mode 100644 windows/AntiMicro.wxs create mode 100644 windows/AntiMicro_64.wxs diff --git a/AntiMicro Future Developments.mm b/AntiMicro Future Developments.mm new file mode 100644 index 0000000..7b8915b --- /dev/null +++ b/AntiMicro Future Developments.mm @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BuildOptions.md b/BuildOptions.md new file mode 100644 index 0000000..41ef5b6 --- /dev/null +++ b/BuildOptions.md @@ -0,0 +1,57 @@ +# Build Options for CMake + +There are a few application specific options that can be used when running +cmake to build antimicro. The following file will attempt to list some of those +options and describe their use in the project. + +## Universal Options + + -DUPDATE_TRANSLATIONS + +Default: OFF. Set updateqm target to call lupdate in order to update +translation files from source. + + -DUSE_SDL_2 + +Default: ON. Compile the program with SDL 2 instead of SDL 1.2. + +## Linux Options + + -DAPPDATA + +Default: OFF. Build the project with AppData support. + + -DWITH_UINPUT + +Default: OFF. Compile the program with uinput support. + + -DWITH_X11 + +Default: ON. Compile the program with X11 support. + + -DWITH_XTEST + +Default: ON. Compile the program with XTest support. + + +## Windows Options + + -DPORTABLE_PACKAGE + +Default: OFF. Compile the program with extra changes used for containing the +final program to a single directory. + + -DTARGET_ARCH + +Default: x86. Options: {x86, x86_64}. Choose which version of some libraries to +use; mainly concerned with Qt and SDL libs. + + -DWITH_VMULTI + +Default: OFF. Compile the program with support for the vmulti driver. + + -DPERFORM_SIGNING + +Default: OFF. This option is only included for testing. It should not be used +currently. + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..7055d1a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,836 @@ +## antimicro Gamepad to KB+M event mapper +## Copyright (C) 2015 Travis Nickles +## +## This program is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see . + + +# Debian Wheezy has a package for version 2.8.9 so +# that will be the minimum supported version. +cmake_minimum_required(VERSION 2.8.9) +project(antimicro) + +if(WIN32) + # Cause cmake to fail if Qt location is not specified. + if(NOT CMAKE_PREFIX_PATH) + message(FATAL_ERROR "Please set CMAKE_PREFIX_PATH to the Qt installation directory. Exiting.") + endif(NOT CMAKE_PREFIX_PATH) + + # CMP0020: Automatically link Qt executables to qtmain target on Windows. + cmake_policy(SET CMP0020 NEW) +endif(WIN32) + +# The version number. +set(ANTIMICRO_MAJOR_VERSION 2) +set(ANTIMICRO_MINOR_VERSION 21) +set(ANTIMICRO_PATCH_VERSION 0) + +option(USE_SDL_2 "Use SDL 2 libraries rather than SDL 1." ON) + +if(UNIX) + option(WITH_X11 "Compile with support for X11." ON) + option(WITH_UINPUT "Compile with support for uinput. uinput will be usable to simulate events." OFF) + option(WITH_XTEST "Compile with support for XTest. XTest will be usable to simulate events." ON) + option(APPDATA "Build project with AppData file support." OFF) +endif(UNIX) + +option(UPDATE_TRANSLATIONS "Call lupdate to update translation files from source." OFF) + +if(WIN32) + option(PORTABLE_PACKAGE "Create portable Windows package" OFF) + option(TARGET_ARCH "Choose which version of some libraries to use. (x86, x86_64)" "x86") + option(WITH_VMULTI "Compile with support for vmulti." OFF) + option(PERFORM_SIGNING "Sign final executable." OFF) + + if(PORTABLE_PACKAGE) + message("Portable package mode build") + + add_definitions(-DWIN_PORTABLE_PACKAGE) + + # Only way to force install target to be dependent on createprofiledir. + add_custom_target(createprofiledir) + add_custom_command(TARGET createprofiledir PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/profiles" + ) + install(CODE "execute_process(COMMAND ${CMAKE_BUILD_TOOL} createprofiledir WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\")") + install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/profiles" DESTINATION ${CMAKE_INSTALL_PREFIX}) + endif(PORTABLE_PACKAGE) + + if(TARGET_ARCH) + set(ARCH_OPTIONS "x86" "x86_64") + list(FIND ARCH_OPTIONS ${TARGET_ARCH} ARCH_INDEX) + if(ARCH_INDEX EQUAL -1) + message(FATAL_ERROR "No valid architecture choice used. Exiting.") + endif(ARCH_INDEX EQUAL -1) + endif(TARGET_ARCH) + + if(WITH_VMULTI) + add_definitions(-DWITH_VMULTI) + endif(WITH_VMULTI) +endif(WIN32) + +# Use pkg-config to find SDL library. +if(UNIX) + find_package(PkgConfig REQUIRED) + include(FindPkgConfig) + + if(USE_SDL_2) + pkg_check_modules(SDL2 REQUIRED sdl2) + elseif(NOT USE_SDL_2) + pkg_check_modules(SDL REQUIRED sdl) + endif(USE_SDL_2) + + if(WITH_X11) + find_package(X11 REQUIRED) + endif(WITH_X11) + + if(WITH_XTEST AND NOT WITH_X11) + set(WITH_XTEST OFF) + message("Cannot use XTest without X11. Disabling XTest support.") + endif(WITH_XTEST AND NOT WITH_X11) + + if(WITH_XTEST) + message("XTest support allowed for simulating events.") + endif(WITH_XTEST) + + if(WITH_UINPUT) + message("uinput support allowed for simulating events.") + endif(WITH_UINPUT) + + if(NOT WITH_XTEST AND NOT WITH_UINPUT) + message(FATAL_ERROR "No system is defined for simulating events.") + endif(NOT WITH_XTEST AND NOT WITH_UINPUT) +endif(UNIX) + +set(antimicro_SOURCES src/main.cpp + src/mainwindow.cpp + src/joybuttonwidget.cpp + src/joystick.cpp + src/joybutton.cpp + src/joybuttontypes/joygradientbutton.cpp + src/event.cpp + src/inputdaemon.cpp + src/joyaxis.cpp + src/joyaxiswidget.cpp + src/joydpad.cpp + src/joybuttontypes/joydpadbutton.cpp + src/axiseditdialog.cpp + src/xmlconfigreader.cpp + src/xmlconfigwriter.cpp + src/joytabwidget.cpp + src/axisvaluebox.cpp + src/advancebuttondialog.cpp + src/simplekeygrabberbutton.cpp + src/joybuttonslot.cpp + src/joybuttontypes/joyaxisbutton.cpp + src/aboutdialog.cpp + src/setjoystick.cpp + src/sdleventreader.cpp + src/setaxisthrottledialog.cpp + src/keyboard/virtualkeypushbutton.cpp + src/keyboard/virtualkeyboardmousewidget.cpp + src/keyboard/virtualmousepushbutton.cpp + src/buttoneditdialog.cpp + src/commandlineutility.cpp + src/joycontrolstick.cpp + src/joybuttontypes/joycontrolstickbutton.cpp + src/joybuttontypes/joycontrolstickmodifierbutton.cpp + src/joycontrolstickeditdialog.cpp + src/joycontrolstickpushbutton.cpp + src/joycontrolstickbuttonpushbutton.cpp + src/joycontrolstickstatusbox.cpp + src/advancestickassignmentdialog.cpp + src/dpadpushbutton.cpp + src/dpadeditdialog.cpp + src/vdpad.cpp + src/joydpadbuttonwidget.cpp + src/quicksetdialog.cpp + src/mousehelper.cpp + src/mousesettingsdialog.cpp + src/mousedialog/mousecontrolsticksettingsdialog.cpp + src/mousedialog/mouseaxissettingsdialog.cpp + src/mousedialog/mousebuttonsettingsdialog.cpp + src/mousedialog/mousedpadsettingsdialog.cpp + src/joytabwidgetcontainer.cpp + src/mousedialog/springmoderegionpreview.cpp + src/joystickstatuswindow.cpp + src/joybuttonstatusbox.cpp + src/qtkeymapperbase.cpp + src/flashbuttonwidget.cpp + src/xmlconfigmigration.cpp + src/qkeydisplaydialog.cpp + src/antkeymapper.cpp + src/inputdevice.cpp + src/mainsettingsdialog.cpp + src/gamecontroller/gamecontrollertriggerbutton.cpp + src/setnamesdialog.cpp + src/autoprofileinfo.cpp + src/addeditautoprofiledialog.cpp + src/editalldefaultautoprofiledialog.cpp + src/common.cpp + src/localantimicroserver.cpp + src/extraprofilesettingsdialog.cpp + src/antimicrosettings.cpp + src/joybuttoncontextmenu.cpp + src/joycontrolstickcontextmenu.cpp + src/dpadcontextmenu.cpp + src/joyaxiscontextmenu.cpp + src/stickpushbuttongroup.cpp + src/dpadpushbuttongroup.cpp + src/joybuttonmousehelper.cpp + src/logger.cpp + src/inputdevicebitarraystatus.cpp + src/applaunchhelper.cpp + src/slotitemlistwidget.cpp + src/eventhandlers/baseeventhandler.cpp + src/eventhandlerfactory.cpp + src/uihelpers/advancebuttondialoghelper.cpp + src/uihelpers/buttoneditdialoghelper.cpp + src/uihelpers/joytabwidgethelper.cpp + src/uihelpers/joyaxiscontextmenuhelper.cpp + src/uihelpers/joycontrolstickcontextmenuhelper.cpp + src/uihelpers/dpadcontextmenuhelper.cpp + src/uihelpers/dpadeditdialoghelper.cpp + src/uihelpers/joycontrolstickeditdialoghelper.cpp + src/uihelpers/gamecontrollermappingdialoghelper.cpp + src/mousedialog/uihelpers/mouseaxissettingsdialoghelper.cpp + src/mousedialog/uihelpers/mousebuttonsettingsdialoghelper.cpp + src/mousedialog/uihelpers/mousecontrolsticksettingsdialoghelper.cpp + src/mousedialog/uihelpers/mousedpadsettingsdialoghelper.cpp +) + +set(antimicro_HEADERS src/mainwindow.h + src/joybuttonwidget.h + src/joystick.h + src/joybutton.h + src/joybuttontypes/joygradientbutton.h + src/inputdaemon.h + src/joyaxis.h + src/joyaxiswidget.h + src/joydpad.h + src/joybuttontypes/joydpadbutton.h + src/axiseditdialog.h + src/xmlconfigreader.h + src/xmlconfigwriter.h + src/joytabwidget.h + src/axisvaluebox.h + src/advancebuttondialog.h + src/simplekeygrabberbutton.h + src/joybuttonslot.h + src/joybuttontypes/joyaxisbutton.h + src/aboutdialog.h + src/setjoystick.h + src/sdleventreader.h + src/setaxisthrottledialog.h + src/keyboard/virtualkeypushbutton.h + src/keyboard/virtualkeyboardmousewidget.h + src/keyboard/virtualmousepushbutton.h + src/buttoneditdialog.h + src/commandlineutility.h + src/joycontrolstick.h + src/joybuttontypes/joycontrolstickbutton.h + src/joybuttontypes/joycontrolstickmodifierbutton.h + src/joycontrolstickeditdialog.h + src/joycontrolstickpushbutton.h + src/joycontrolstickbuttonpushbutton.h + src/joycontrolstickstatusbox.h + src/advancestickassignmentdialog.h + src/dpadpushbutton.h + src/dpadeditdialog.h + src/vdpad.h + src/joydpadbuttonwidget.h + src/quicksetdialog.h + src/mousehelper.h + src/mousesettingsdialog.h + src/mousedialog/mousecontrolsticksettingsdialog.h + src/mousedialog/mouseaxissettingsdialog.h + src/mousedialog/mousebuttonsettingsdialog.h + src/mousedialog/mousedpadsettingsdialog.h + src/joytabwidgetcontainer.h + src/mousedialog/springmoderegionpreview.h + src/joystickstatuswindow.h + src/joybuttonstatusbox.h + src/qtkeymapperbase.h + src/flashbuttonwidget.h + src/xmlconfigmigration.h + src/qkeydisplaydialog.h + src/antkeymapper.h + src/inputdevice.h + src/mainsettingsdialog.h + src/gamecontroller/gamecontrollertriggerbutton.h + src/setnamesdialog.h + src/autoprofileinfo.h + src/addeditautoprofiledialog.h + src/editalldefaultautoprofiledialog.h + src/localantimicroserver.h + src/extraprofilesettingsdialog.h + src/antimicrosettings.h + src/joybuttoncontextmenu.h + src/joycontrolstickcontextmenu.h + src/dpadcontextmenu.h + src/joyaxiscontextmenu.h + src/stickpushbuttongroup.h + src/dpadpushbuttongroup.h + src/joybuttonmousehelper.h + src/logger.h + src/inputdevicebitarraystatus.h + src/applaunchhelper.h + src/slotitemlistwidget.h + src/eventhandlers/baseeventhandler.h + src/eventhandlerfactory.h + src/uihelpers/advancebuttondialoghelper.h + src/uihelpers/buttoneditdialoghelper.h + src/uihelpers/joytabwidgethelper.h + src/uihelpers/joyaxiscontextmenuhelper.h + src/uihelpers/joycontrolstickcontextmenuhelper.h + src/uihelpers/dpadcontextmenuhelper.h + src/uihelpers/dpadeditdialoghelper.h + src/uihelpers/joycontrolstickeditdialoghelper.h + src/uihelpers/gamecontrollermappingdialoghelper.h + src/mousedialog/uihelpers/mouseaxissettingsdialoghelper.h + src/mousedialog/uihelpers/mousebuttonsettingsdialoghelper.h + src/mousedialog/uihelpers/mousecontrolsticksettingsdialoghelper.h + src/mousedialog/uihelpers/mousedpadsettingsdialoghelper.h +) + +set(antimicro_FORMS src/mainwindow.ui + src/axiseditdialog.ui + src/advancebuttondialog.ui + src/aboutdialog.ui + src/setaxisthrottledialog.ui + src/buttoneditdialog.ui + src/joycontrolstickeditdialog.ui + src/advancestickassignmentdialog.ui + src/dpadeditdialog.ui + src/quicksetdialog.ui + src/mousesettingsdialog.ui + src/joystickstatuswindow.ui + src/qkeydisplaydialog.ui + src/gamecontrollermappingdialog.ui + src/mainsettingsdialog.ui + src/setnamesdialog.ui + src/addeditautoprofiledialog.ui + src/editalldefaultautoprofiledialog.ui + src/extraprofilesettingsdialog.ui + src/capturedwindowinfodialog.ui +) + +set(antimicro_RESOURCES src/resources.qrc) + +# Files that require SDL 2 support. +if(USE_SDL_2) + LIST(APPEND antimicro_SOURCES src/gamecontroller/gamecontroller.cpp + src/gamecontroller/gamecontrollerdpad.cpp + src/gamecontroller/gamecontrollerset.cpp + src/gamecontroller/gamecontrollertrigger.cpp + src/gamecontrollermappingdialog.cpp + src/gamecontrollerexample.cpp + ) + LIST(APPEND antimicro_HEADERS src/gamecontroller/gamecontroller.h + src/gamecontroller/gamecontrollerdpad.h + src/gamecontroller/gamecontrollerset.h + src/gamecontroller/gamecontrollertrigger.h + src/gamecontrollermappingdialog.h + src/gamecontrollerexample.h + ) +endif(USE_SDL_2) + +# Platform dependent files. +if(UNIX) + if(WITH_X11) + LIST(APPEND antimicro_SOURCES src/x11extras.cpp + src/qtx11keymapper.cpp + src/unixcapturewindowutility.cpp + src/autoprofilewatcher.cpp + src/capturedwindowinfodialog.cpp + ) + LIST(APPEND antimicro_HEADERS src/x11extras.h + src/qtx11keymapper.h + src/unixcapturewindowutility.h + src/autoprofilewatcher.h + src/capturedwindowinfodialog.h + ) + + if(WITH_XTEST) + LIST(APPEND antimicro_SOURCES src/eventhandlers/xtesteventhandler.cpp) + LIST(APPEND antimicro_HEADERS src/eventhandlers/xtesteventhandler.h) + endif(WITH_XTEST) + endif(WITH_X11) + + if(WITH_UINPUT) + LIST(APPEND antimicro_SOURCES src/qtuinputkeymapper.cpp + src/uinputhelper.cpp + src/eventhandlers/uinputeventhandler.cpp + ) + LIST(APPEND antimicro_HEADERS src/qtuinputkeymapper.h + src/uinputhelper.h + src/eventhandlers/uinputeventhandler.h + ) + endif(WITH_UINPUT) + +elseif(WIN32) + LIST(APPEND antimicro_SOURCES src/winextras.cpp + src/qtwinkeymapper.cpp + src/winappprofiletimerdialog.cpp + src/autoprofilewatcher.cpp + src/capturedwindowinfodialog.cpp + src/eventhandlers/winsendinputeventhandler.cpp + src/joykeyrepeathelper.cpp + ) + LIST(APPEND antimicro_HEADERS src/winextras.h + src/qtwinkeymapper.h + src/winappprofiletimerdialog.h + src/autoprofilewatcher.h + src/capturedwindowinfodialog.h + src/eventhandlers/winsendinputeventhandler.h + src/joykeyrepeathelper.h + ) + LIST(APPEND antimicro_FORMS src/winappprofiletimerdialog.ui) + # Add Windows specific resource file used for application icons. + LIST(APPEND antimicro_RESOURCES src/resources_windows.qrc) + + if(WITH_VMULTI) + list(APPEND antimicro_SOURCES src/qtvmultikeymapper.cpp + src/eventhandlers/winvmultieventhandler.cpp +# vmulti/client/client.c + ) + list(APPEND antimicro_HEADERS src/qtvmultikeymapper.h + src/eventhandlers/winvmultieventhandler.h + ) + endif(WITH_VMULTI) +endif(UNIX) + +set(USE_QT5 OFF) +set(USE_QT4 OFF) + +if(UNIX) + # Check if Qt 4 or 5 was specified using an environment variable + # or by specifying -DQT_QMAKE_EXECUTABLE. + # Otherwise, check for Qt libraries. + if("$ENV{QT_SELECT}" EQUAL 5) + set(USE_QT5 ON) + elseif(QT_QMAKE_EXECUTABLE MATCHES ".*/qmake-qt5") + set(USE_QT5 ON) + elseif ("$ENV{QT_SELECT}" EQUAL 4) + set(USE_QT4 ON) + elseif(QT_QMAKE_EXECUTABLE MATCHES ".*/qmake-qt4") + set(USE_QT4 ON) + else() + find_package(Qt5Core QUIET) + if(Qt5Core_FOUND) + set(USE_QT5 ON) + else() + find_package(Qt4 QUIET) + if(QT_FOUND) + set(USE_QT4 ON) + else() + message(FATAL_ERROR "No Qt libraries could be found.") + endif(QT_FOUND) + endif(Qt5Core_FOUND) + endif("$ENV{QT_SELECT}" EQUAL 5) +elseif(WIN32) + # Use Qt5 on Windows. + set(USE_QT5 ON) +endif(UNIX) + +if(USE_QT5) + message("Compiling with Qt5 support") +elseif(USE_QT4) + message("Compiling with Qt4 support") + if(NOT WITH_X11) + message(FATAL_ERROR "Cannot build application using Qt4 without X11 support.") + endif(NOT WITH_X11) +else() + message(FATAL_ERROR "No Qt version was specified.") +endif(USE_QT5) + +if(USE_SDL_2) + add_definitions(-DUSE_SDL_2) +endif(USE_SDL_2) + +if (WIN32) + if(PERFORM_SIGNING) + add_definitions(-DPERFORM_SIGNING) + endif(PERFORM_SIGNING) +endif (WIN32) + +if(UNIX) + if(WITH_X11) + add_definitions(-DWITH_X11) + endif(WITH_X11) + + if(WITH_XTEST) + add_definitions(-DWITH_XTEST) + endif(WITH_XTEST) + + if(WITH_UINPUT) + add_definitions(-DWITH_UINPUT) + endif(WITH_UINPUT) +endif(UNIX) + +if (UNIX) + if (USE_QT5) + # Find includes in corresponding build directories + #set(CMAKE_INCLUDE_CURRENT_DIR ON) + # Instruct CMake to run moc automatically when needed. + set(CMAKE_AUTOMOC ON) + + find_package(Qt5Widgets REQUIRED) + find_package(Qt5Core REQUIRED) + find_package(Qt5Gui REQUIRED) + find_package(Qt5Network REQUIRED) + find_package(Qt5LinguistTools REQUIRED) + + QT5_WRAP_CPP(antimicro_HEADERS_MOC ${antimicro_HEADERS}) + QT5_WRAP_UI(antimicro_FORMS_HEADERS ${antimicro_FORMS}) + QT5_ADD_RESOURCES(antimicro_RESOURCES_RCC ${antimicro_RESOURCES}) + add_subdirectory("share/antimicro/translations") + + include_directories(${Qt5Widgets_INCLUDE_DIRS}) + add_definitions(${Qt5Widgets_DEFINITIONS}) + include_directories(${Qt5Core_INCLUDE_DIRS}) + add_definitions(${Qt5Core_DEFINITIONS}) + include_directories(${Qt5Gui_INCLUDE_DIRS}) + add_definitions(${Qt5Gui_DEFINITIONS}) + include_directories(${Qt5Network_INCLUDE_DIRS}) + add_definitions(${Qt5Network_DEFINITIONS}) + + set(CMAKE_POSITION_INDEPENDENT_CODE ON) + + # Add compiler flags for building executables (-fPIE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}") + + LIST(APPEND LIBS ${Qt5Widgets_LIBRARIES} + ${Qt5Core_LIBRARIES} + ${Qt5Gui_LIBRARIES} + ${Qt5Network_LIBRARIES} + ) + else() + find_package(Qt4 REQUIRED) + set(QT_USE_QTNETWORK TRUE) + + QT4_WRAP_CPP(antimicro_HEADERS_MOC ${antimicro_HEADERS}) + QT4_WRAP_UI(antimicro_FORMS_HEADERS ${antimicro_FORMS}) + QT4_ADD_RESOURCES(antimicro_RESOURCES_RCC ${antimicro_RESOURCES}) + + add_subdirectory("share/antimicro/translations") + + include(${QT_USE_FILE}) + add_definitions(${QT_DEFINITIONS}) + list(APPEND LIBS ${QT_LIBRARIES}) + endif(USE_QT5) + +elseif(WIN32) + # Find includes in corresponding build directories + #set(CMAKE_INCLUDE_CURRENT_DIR ON) + # Instruct CMake to run moc automatically when needed. + set(CMAKE_AUTOMOC ON) + + find_package(Qt5Widgets REQUIRED) + find_package(Qt5Core REQUIRED) + find_package(Qt5Gui REQUIRED) + find_package(Qt5Network REQUIRED) + find_package(Qt5LinguistTools REQUIRED) + + QT5_WRAP_CPP(antimicro_HEADERS_MOC ${antimicro_HEADERS}) + QT5_WRAP_UI(antimicro_FORMS_HEADERS ${antimicro_FORMS}) + QT5_ADD_RESOURCES(antimicro_RESOURCES_RCC ${antimicro_RESOURCES}) + add_subdirectory("share/antimicro/translations") + + include_directories(${Qt5Widgets_INCLUDE_DIRS}) + add_definitions(${Qt5Widgets_DEFINITIONS}) + include_directories(${Qt5Core_INCLUDE_DIRS}) + add_definitions(${Qt5Core_DEFINITIONS}) + include_directories(${Qt5Gui_INCLUDE_DIRS}) + add_definitions(${Qt5Gui_DEFINITIONS}) + include_directories(${Qt5Network_INCLUDE_DIRS}) + add_definitions(${Qt5Network_DEFINITIONS}) + + set(CMAKE_POSITION_INDEPENDENT_CODE ON) + + # Add compiler flags for building executables (-fPIE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}") + + LIST(APPEND LIBS ${Qt5Widgets_LIBRARIES} + ${Qt5Core_LIBRARIES} + ${Qt5Gui_LIBRARIES} + ${Qt5Network_LIBRARIES} + ) +endif(UNIX) + +if(UNIX) + if(WITH_X11) + LIST(APPEND LIBS ${X11_X11_LIB}) + LIST(APPEND LIBS ${X11_Xi_LIB}) + endif(WITH_X11) + + if(WITH_XTEST) + LIST(APPEND LIBS ${X11_XTest_LIB}) + endif(WITH_XTEST) + + if(USE_SDL_2) + list(APPEND LIBS ${SDL2_LIBRARIES}) + else() + list(APPEND LIBS ${SDL_LIBRARIES}) + endif(USE_SDL_2) +elseif (WIN32) + if(USE_SDL_2) + # Perform extra voodoo to get proper library paths and include + # proper headers. + if(TARGET_ARCH STREQUAL "x86_64") + find_library(SDL2_LIBRARY SDL2 "${PROJECT_SOURCE_DIR}/SDL2-2.0.4/x86_64-w64-mingw32/lib") + list(APPEND LIBS ${SDL2_LIBRARY}) + include_directories("${PROJECT_SOURCE_DIR}/SDL2-2.0.4/x86_64-w64-mingw32/include") + else() + find_library(SDL2_LIBRARY SDL2 "${PROJECT_SOURCE_DIR}/SDL2-2.0.4/i686-w64-mingw32/lib") + list(APPEND LIBS ${SDL2_LIBRARY}) + include_directories("${PROJECT_SOURCE_DIR}/SDL2-2.0.4/i686-w64-mingw32/include") + endif(TARGET_ARCH STREQUAL "x86_64") + + add_definitions(-DUNICODE -D_UNICODE) + endif(USE_SDL_2) + + list(APPEND LIBS "psapi") + + if(WITH_VMULTI) + include_directories("${PROJECT_SOURCE_DIR}/vmulti/inc") + list(APPEND LIBS "hid" "setupapi") + endif(WITH_VMULTI) +endif (UNIX) + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) +include_directories("${PROJECT_SOURCE_DIR}/src") + +if(UNIX) + # Store executable in a bin subdir. Needed here so translations can be loaded. + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin") +endif(UNIX) + +if(USE_QT5) + if(UNIX) + add_executable(antimicro ${antimicro_SOURCES} + ${antimicro_FORMS_HEADERS} + ${antimicro_RESOURCES_RCC} + ) + elseif(WIN32) + # The WIN32 is required to specify a GUI application. + add_executable(antimicro WIN32 ${antimicro_SOURCES} + ${antimicro_FORMS_HEADERS} + ${antimicro_RESOURCES_RCC} + src/antimicro.rc + ) + endif(UNIX) + +else() + add_executable(antimicro ${antimicro_SOURCES} + ${antimicro_HEADERS_MOC} + ${antimicro_FORMS_HEADERS} + ${antimicro_RESOURCES_RCC} + ) + +endif(USE_QT5) + +# Add link libraries. +#message(${LIBS}) +target_link_libraries(antimicro ${LIBS}) + +# Specify out directory for final executable. +if(UNIX) + install(TARGETS antimicro RUNTIME DESTINATION "bin") +elseif(WIN32) + install(TARGETS antimicro RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}) +endif(UNIX) + +if(UNIX) + install(FILES src/images/antimicro.png DESTINATION "share/pixmaps") + install(FILES other/antimicro.desktop DESTINATION "share/applications") + install(FILES other/antimicro.xml DESTINATION "share/mime/packages") +endif(UNIX) + +# Add man page for *nix platforms. +if(UNIX) + add_subdirectory(other) + + # Only way to force install target to be dependent on manpage. + install(CODE "execute_process(COMMAND ${CMAKE_BUILD_TOOL} manpage WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\")") + + if(APPDATA) + # Only way to force install target to be dependent on appdata. + install(CODE "execute_process(COMMAND ${CMAKE_BUILD_TOOL} appdata WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\")") + endif(APPDATA) +endif(UNIX) + +# uninstall target +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + IMMEDIATE @ONLY) + +add_custom_target(uninstall + COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) + + +# Only way to force install target to be dependent on updateqm. +install(CODE "execute_process(COMMAND ${CMAKE_BUILD_TOOL} updateqm WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\")") + +# Use this to use some variables created here in the actual project. +# Modify the config.h.in file using the appropriate variables. +configure_file( + "${PROJECT_SOURCE_DIR}/src/config.h.in" + "${PROJECT_BINARY_DIR}/config.h" +) + +# Copy current Changelog file to location that the resource file expects. +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/Changelog DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/src/) + +install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E remove \"${PROJECT_SOURCE_DIR}/src/Changelog\")") + +if(WIN32) + if(TARGET_ARCH STREQUAL "x86_64") + # Copy SDL2.dll to find installation directory. + add_custom_target(copy_sdl_dll + COMMAND ${CMAKE_COMMAND} -E copy "${PROJECT_SOURCE_DIR}/SDL2-2.0.4/x86_64-w64-mingw32/bin/SDL2.dll" ${CMAKE_CURRENT_BINARY_DIR} + ) + else() + # Copy SDL2.dll to find installation directory. + add_custom_target(copy_sdl_dll + COMMAND ${CMAKE_COMMAND} -E copy "${PROJECT_SOURCE_DIR}/SDL2-2.0.4/i686-w64-mingw32/bin/SDL2.dll" ${CMAKE_CURRENT_BINARY_DIR} + ) + endif(TARGET_ARCH STREQUAL "x86_64") + + + # Obtain location of Qt5 DLL files and assign them to a list. + # This list will only be used for Release builds. + get_target_property(QTCORE_DLL_LOCATION Qt5::Core LOCATION) + string(REPLACE "/Qt5Core.dll" "" QTCORE_DLL_LOCATION ${QTCORE_DLL_LOCATION}) + set(EXTRA_DLL_FILES "${QTCORE_DLL_LOCATION}/libwinpthread-1.dll" + "${QTCORE_DLL_LOCATION}/Qt5Core.dll" + "${QTCORE_DLL_LOCATION}/Qt5Gui.dll" + "${QTCORE_DLL_LOCATION}/Qt5Network.dll" + "${QTCORE_DLL_LOCATION}/Qt5Widgets.dll" + "${QTCORE_DLL_LOCATION}/libstdc++-6.dll" + ) + + # Copy relevant DLL files depending on the chosen architecture. + if(TARGET_ARCH STREQUAL "x86_64") + list(APPEND EXTRA_DLL_FILES "${QTCORE_DLL_LOCATION}/icudt54.dll" + "${QTCORE_DLL_LOCATION}/icuin54.dll" + "${QTCORE_DLL_LOCATION}/icuuc54.dll" + "${QTCORE_DLL_LOCATION}/libgcc_s_sjlj-1.dll" + "${QTCORE_DLL_LOCATION}/libGLESv2.dll" + "${PROJECT_SOURCE_DIR}/SDL2-2.0.4/x86_64-w64-mingw32/bin/SDL2.dll" + ) + else() + list(APPEND EXTRA_DLL_FILES "${QTCORE_DLL_LOCATION}/icudt54.dll" + "${QTCORE_DLL_LOCATION}/icuin54.dll" + "${QTCORE_DLL_LOCATION}/icuuc54.dll" + "${QTCORE_DLL_LOCATION}/libgcc_s_dw2-1.dll" + "${PROJECT_SOURCE_DIR}/SDL2-2.0.4/i686-w64-mingw32/bin/SDL2.dll" + ) + endif(TARGET_ARCH STREQUAL "x86_64") + + # Target to copy Qt DLL files. + add_custom_target(install_extra_dlls) + + # Create destination directory if it does not exist. + add_custom_command(TARGET install_extra_dlls PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_INSTALL_PREFIX}/" + ) + + foreach(CURRENT_DLL_FILE ${EXTRA_DLL_FILES}) + add_custom_command(TARGET install_extra_dlls PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${CURRENT_DLL_FILE} "${CMAKE_INSTALL_PREFIX}/" + ) + endforeach() + + # Target to copy qwindows.dll platforms file. + add_custom_target(install_platforms_dll) + add_custom_command(TARGET install_platforms_dll PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy "${QTCORE_DLL_LOCATION}/../plugins/platforms/qwindows.dll" + "${CMAKE_INSTALL_PREFIX}/platforms/qwindows.dll" + ) + + # Combine the two targets into a single target that will be used + # while bundling the program. + add_custom_target(install_dlls) + add_dependencies(install_dlls + install_extra_dlls + install_platforms_dll + ) + + # Copy bundled Qt translation files. + file(GLOB QT_TRANSLATION_FILES "${CMAKE_PREFIX_PATH}/translations/qt_[^help]*.qm") + add_custom_target(copy_qt_translations) + foreach(CURRENT_QM_FILE ${QT_TRANSLATION_FILES}) + set(CURRENT_QM_FILENAME "") + string(REPLACE "${CMAKE_PREFIX_PATH}/translations/" "" CURRENT_QM_FILENAME ${CURRENT_QM_FILE}) + add_custom_command(TARGET copy_qt_translations PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy "${CURRENT_QM_FILE}" + "${CMAKE_INSTALL_PREFIX}/share/qt/translations/${CURRENT_QM_FILENAME}" + ) + endforeach() + + # Sign final executable + if(PERFORM_SIGNING) + install(CODE "execute_process(COMMAND \"C:/Program Files (x86)/Windows Kits/8.1/bin/x64/signtool.exe\" + sign /v /a /s ROOT /n antimicro ${CMAKE_INSTALL_PREFIX}/antimicro.exe)") + endif(PERFORM_SIGNING) + + # Set variables needed for MSI building. + set(MSIFOLDER "${PROJECT_SOURCE_DIR}/windows") + set(WIXENV $ENV{WIX}) + + # Use a different file for each architecture due + # to some DLL differences. + if(TARGET_ARCH STREQUAL "x86_64") + set(WIXWXS "${MSIFOLDER}/antimicro_64.wxs") + else() + set(WIXWXS "${MSIFOLDER}/antimicro.wxs") + endif(TARGET_ARCH STREQUAL "x86_64") + + set(WIXOBJ "${MSIFOLDER}/antimicro.wixobj") + + # Change output file depending on the target architecture. + if(TARGET_ARCH STREQUAL "x86_64") + set(WIXMSI "${MSIFOLDER}/antimicro_64.msi") + else() + set(WIXMSI "${MSIFOLDER}/antimicro.msi") + endif(TARGET_ARCH STREQUAL "x86_64") + + if(NOT WIXENV) + # Display message when WIX is not set up. No extra target will be added. + message("MSI package building not possible: WIX environment variable not defined.") + else() + # Target to build .msi installer file. + add_custom_target(buildmsi) + + # Change arch value passed to candle.exe + set(WIXARCH "") + if(TARGET_ARCH STREQUAL "x86_64") + set(WIXARCH "x64") + else() + set(WIXARCH "x86") + endif(TARGET_ARCH STREQUAL "x86_64") + + add_custom_command(TARGET buildmsi PRE_BUILD + COMMAND "${WIXENV}\\bin\\candle.exe" ${WIXWXS} -out ${WIXOBJ} -sw1113 -arch ${WIXARCH} && + "${WIXENV}\\bin\\light.exe" ${WIXOBJ} -out ${WIXMSI} -sw1076 -spdb + ) + set(WIXFILES ${WIXOBJ} ${WIXMSI}) + set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${WIXFILES}") + endif(NOT WIXENV) + + # Copy extra files to include in the final archive. + install(FILES gpl.txt Changelog README.md ProfileTips.md + DESTINATION ${CMAKE_INSTALL_PREFIX}) +endif(WIN32) diff --git a/Changelog b/Changelog new file mode 100644 index 0000000..225e6af --- /dev/null +++ b/Changelog @@ -0,0 +1,1038 @@ +2016-01-10 Travis Nickles + +Version 2.21 + +* Changed unplug routine slightly. The old behavior was slightly wrong anyway +but the old behavior did not work with SDL 2.0.4. + +* Custom Qt builds are being used for the 64 bit Windows build and noSSE +Windows build. + +* Updated Windows build to use Qt 5.5.1. + +* Updated Windows build to use SDL 2.0.4. This should clear up a couple +of problems for people running Windows 10. + +* Changes to some acceleration curves. Both the output values and the input +offsets were changed to make mouse movement looser. + +* Removed First Run Wizard from program. In the end, that wizard was causing +more problems for other users than it was worth. + +* Add arguments property for Execute slots. + +* Allow a real absolute mouse to be used with uinput support. Previously, +relative mouse movement was being used to fake an absolute position for the +mouse pointer. The WiimoteGlue project provided a way to allow uinput to +send absolute mouse pointer events when using uinput. + +* Fixed set changing with analog triggers. + + +2015-10-19 Travis Nickles + +Version 2.20.2 + +* Change Enhanced Precision and Easing Quad/Cubic acceleration +curves + +* Skipped straight to 2.20.2 since version 2.20 actually had 2.20.1 marked +as its version in the application + + +2015-10-10 Travis Nickles + +Version 2.20 + +* Replace usage of QElapsedTimer with QTime for mouse movement calculations. + +* Start using Qt 5 with Ubuntu Vivid package. + +* Change XTest pointer acceleration when starting the program. + +* Allow release slot to have a 0 ms interval. This is useful for people who +use a gamepad poll rate less than 10 ms. + +* Change minimize to tray code to work better with later versions of Gnome 3 +and Unity. + +* Transfer travel distance axis changes when switching sets. + + +2015-09-29 Travis Nickles + +Version 2.19.3 + +* Japanese translation provided by tou omiya. + +* Make sure Game Controller Mapping dialog window reads raw joystick events. +This should fix problems regarding improper mapping causing controller elements +to no longer be mappable. + +* Make Set Change slots activate on button release instead of button press. + +* Tweaked the locking being performed in various portions of the program. + +* Fixed a problem with blank info window appearing when escaping from window +capture utility dialog. + +* Fixed issues with document-save-as icon staying displayed after resetting +a profile. + +* Fixed "Media Next" key binding for virtual keyboard. + +* Fixed various issues regarding binding slots in the Advanced Edit dialog window. + + +2015-09-15 Travis Nickles + +Version 2.19.2 + +* Add --next to allow multiple profiles to be loaded in one command call. + +* Add a flag to settings file when wizard is finished. Don't depend on any +other settings being changed during an application run. + +* Fixed issue with inserting Pause slots. + +* Fixed issue with blank application filepath being matched for auto profile +support. + + +2015-09-03 Travis Nickles + +Version 2.19.1 + +* Fixed SDL 1.2 build support. + +* Fixed issue with SDL thread not being stopped due to connections not being +made in some situations. + +* Fixed loading of a profile from a second instance. + +* Fixed problem with main window not being populated after the App Settings +Wizard was finished. + +* Fixed another portion of the program that assumed that a controller would be +connected at startup. Fixes excessive CPU load. + + +2015-08-31 Travis Nickles + +Version 2.19 + +* Added curve options for extra acceleration. + +* Fixed bug when App Settings Wizard would pop up when not needed. + +* Simplified Chinese translation updated. + + +2015-08-24 Travis Nickles + +Version 2.18.2 + +* Fixed overly active timer used to reset acceleration distances when +no events are returned from SDL in a given gamepad poll. + +* Sebian translation updated by Jay Alexander Fleming. + +* Changed behavior of 4 Way Cardinal mode for DPads. Diagonals are no longer +counted as a dead zone. This change is more likely temporary. +Up+Right - Up, Down+Right - Right, Down+Left - Down, Up+Left - Left + + +2015-08-18 Travis Nickles + +Version 2.18.1 + +* Fixed some threading issues when using X11. + +* Fixed excessive CPU load on startup when no controller is connected. + + +2015-08-15 Travis Nickles + +Version 2.18 + +* Perform event simulation in its own thread. Timer used for mouse speed +calculations has improved as a result. + +* Slow down Enhanced Precision mouse acceleration curve slightly. Changes +were mainly due to overall mouse emulation being tweaked. + +* Distributing 64 bit builds for Windows again. + +* Using a simulated event to click the minimize button in title bar now works +on Windows. The move to using a dedicated thread for event simulation allows +that to work now. + +* Simplified Chinese translation added thanks to zzpxyx. + + +2015-08-02 Travis Nickles + +Version 2.17 + +* Changed Enhanced Precision acceleration curve. The curve has been slowed down +slightly. + +* Changed how initial mouse movement is performed when the gamepad poll rate +and the mouse refresh rate differ. + +* Flash interface buttons after restoring the main window from the tray icon. + +* Tweaked mouse movement remainder routine. Remainders now only apply when +the direction along an axis is the same. + +* Raised maximum cycle reset time to 60 seconds. + +* Fixed improper cycle reset interval. + + +2015-07-22 Travis Nickles + +Version 2.16 + +* Loosen initial mouse movement experienced after going outside the dead zone. + +* Added option in the mouse settings section that would allow antimicro to +reset the acceleration values being used for the uinput virtual mouse pointer. +This is useful after playing older Linux games that change the acceleration +settings for all mouse pointers after a game exits. Postal 2 and Doom 3 are two +examples of games in my game library that exhibit this behavior. + +* Queue all events before performing any actions. The priority of various events +has been changed as well. + +* Added option to change the gamepad poll rate used by the application. By +default, the old 10 ms poll rate will be used. + +* Bundle a few backup icon files. Mainly useful on SteamOS since the themes +used don't bundle a couple of essential icons that are expected to be present. + +* Compiled vmulti support into Windows build. The driver is not currently +provided. The program needs to be started with the arguments --eventgen vmulti. + +* Temporarily stop packaging a 64 bit version of the program for Windows. +Unfortunately, the version of Qt being used has a problem regarding timer +accuracy that is not experienced with the 32 bit version of Qt being used. +At this time, working around the problem is not feasible so there will be no +64 bit release. Please use the 32 bit version. + +* Change shortcuts used for the .msi package. + +* Bundle Qt translation files for Windows version. + + +2015-06-27 Travis Nickles + +Version 2.15 + +* Changed routine for extra acceleration for mouse movement. The new version +is a bit faster and more responsive than the previous version. + +* Added release circle setting for spring mouse mode. This can be used to have +the mouse return to a region around a character based on the last detected +direction of an analog stick. + +* Added a sub-menu to the virtual keyboard. Some multimedia and browser keys +can now be selected. + +* Added Execute slot type. A program can be set to launch when a slot is +activated. + +* Added Text Entry slot type. You can now have a string of text typed +when a slot is activated. This can be useful for inputting common commands in +games. + +* Added proper interpolation to determine the start of diagonal regions of +analog sticks. This is used for mouse movement in order to determine the proper +starting dead zone point. + +* Changed Enhanced Precision mouse acceleration curve. The new changes in the +curve should be much looser than before. + +* Fixed --unload command line option. Enforce reloading of config file +when finished. + +* Fixed issue with spring mouse mode where the mouse would temporarily return +to center when switching stick directions quickly. + +* Fixed some bindings in the virtual keyboard when using SendInput for the +event generator. + +* Fixed issue with widgets used to update stick and dpad delay. The spinbox can +now be used to edit the delay. + +* Reduced multiple instances of some objects. Reduces memory usage slightly. + + +2015-05-01 Travis Nickles + +Version 2.14 + +* Refactored extra axis acceleration. This revision uses individual gamepad +polls again. Other changes in the code have made switching back feasible. With +minor adjustments, the mouse will be looser but very controllable. + +* Added longer duration for extra axis acceleration. This allows extra +acceleration to be performed over a period of time as opposed to just one +gamepad poll. + +* Changed key repeat routine when using SendInput on Windows. Key releases +restart the last active key repeat delay. + +* Now using Qt64-NG for the 64 bit Windows builds. + +* Initial experiments with vmulti support in the Windows version. Using that +driver would allow antimicro to use a virtual keyboard and mouse rather than +using SendInput. That would allow antimicro to work around UAC problems and +anti-cheat programs. Support is not currently compiled into the Windows builds +due to not being able to properly distribute the vmulti driver. + +* Do not write empty names tag in profiles if no custom button names have been +specified. + +* Allow mouse history buffer size to go up to 100. + +* Allow diagonal range to go up to 90 degrees. + +* Remove old mouse speeds from mouse history buffer if stick has been returned +to the dead zone. History buffer will be filled with zeroes. + +* Omit hotplugging dependent code when compiling against SDL 1.2. + +* Fixed dpad pointer bug when certain QueuedConnection slots are executed. + + +2015-03-31 Travis Nickles + +Version 2.13 + +* Updated extra axis acceleration routine. Now, extra acceleration is +calculated after an axis has stopped moving past the assigned threshold +in one gamepad poll. + +* Stick presets now change the diagonal range of a stick. This is mainly +beneficial for mouse control changes so that 65 degrees is used by default. + +* Added a screen selector for Spring mouse mode in settings menu. + +* Added a small language selection portion to the settings menu. + +* Added a small logger. Please run antimicro with "--log-level debug" in order +to get output about button presses. + + +2015-03-22 Travis Nickles + +Version 2.12.1 + +* Implemented a small wizard that will be run when antimicro is launched +for the first time. It currently only has a page for editing some of the mouse +settings and a page for associating antimicro with .amgp files on Windows. + +* Show slots that are active for a stick modifier button on the main interface. +The text for the main stick direction buttons will be prefixed with the +currently active slots of the stick modifier button. + +* Corrected issue with stick and dpad events not getting activated on a set +change. Events were being queued but not executed. + + +2015-03-15 Travis Nickles + +Version 2.12 + +* Added option for extra mouse acceleration. Enabling that option will +increase the speed of the mouse based on the amount an axis has travelled in one +gamepad poll and the set multiplier. This will greatly affect how the mouse +behaves and it will make mouse movement looser. Using this feature can be +problematic if the analog stick on your controller is worn out and loose. + +* Corrected issue with extra mouse sync events occurring when not needed (0,0 +events). This change seems to have smoothed out mouse movement on the low end +of an axis a bit. + +* Tweaked controller unplug workaround to still invoke release events for +axes and buttons. For triggers, the release value is modified from what is +provided by SDL so an unplug event will cause a release event to occur for the +triggers. + + +2015-02-25 Travis Nickles + +Version 2.11.1 + +* Added workaround to allow gamepad unplugging on Windows to not +activate bindings for the triggers. This was caused by the way controller +unplugging is handled by SDL (primarily with the Windows version). +SDL sends a release value for all elements of an unplugged joystick a brief +period before sending the expected SDL_JOYDEVICEREMOVED event. The problem is +that the released value used for triggers assumes that the dead zone is half the +trigger's full range. This would cause bindings for triggers to usually activate +for a brief period before SDL would send the final SDL_JOYDEVICEREMOVED event +which would then deactivate those bindings. + +* Changes for the portable Windows version. Allow relative profile paths for +use in the portable package on Windows. Associate profiles registry change +prompt skipped. + +* Queue stick and dpad events. Allows for better control of 8-way sticks +and dpads. + + +2015-02-07 Travis Nickles + +Version 2.11 + +* Adjusted the Enhanced Precision, Easing Quadratic, and Easing Cubic +mouse acceleration curves. The low end of each curve has been loosened a bit +and the rest of the curves have been adjusted accordingly. Comparing the two +versions, the resulting mouse speed for a given axis point is slightly lower +in the new versions for most of the curve. The extreme low end and the extreme +high end of the curves will be slightly faster. + +* Updated Qt to version 5.4.0 for the Windows builds. + +* Compiled a 64 bit version for Windows thanks to the Qt-x64 project. + +* Added a set changing slot. + +* Added AppData for use when packaging on Linux thanks to Jeff Backus. + +* Fixed bug with mouse wheel event methods for axes which resulted in negative +values being passed to the event timer. + + +2014-12-29 Travis Nickles + +Version 2.10.1 + +* Changed event handler fallback method under Linux. + +* Changed interface of Assignments page in Advanced Button Dialog. + +* Reset set number upon changing profiles. + +* Added "About Development" tab to About Dialog. + +* Fixed dynamic text resizing in Button Edit Dialog under Linux. + +* Fixed launching a second instance in order to load a profile in the +first instance. + + +2014-12-10 Travis Nickles + +Version 2.10 + +* Changed allowed values for easing duration. The minimum value has been +lowered to 0.0 and the maximum value has been increased to 5.0. + +* Added a stick modifier button. This button is primarily meant to be used +to assign walk/run functionality to an analog stick. Instead of having to +create distance zones and assign keyboard modifier keys to each stick button, +you can now make the assignment on the stick modifier button and it +will apply to the stick as a whole. It makes assigning walk/run functionality +to an analog stick much less cumbersome. The DreadOut demo has already shown a +use case where only the stick modifier button was needed due to the demo not +handling running when using the left stick on an Xbox 360 controller. + +* Increased idle mouse timer interval to 100 ms. + +* Added a load profile slot. You can now tell the program to load a different +profile upon pressing a button. + +* Added gradient functionality for the high end of the Easing Quadratic and +Easing Cubic mouse acceleration curves. + +* Raise process priority on Windows. Now, the antimicro process will run +with High priority. This allows internal timers to work better and be less +susceptible to the activity of other running programs. On Linux, the priority of +the main thread has been increased. + +* Take multiple direction buttons into account when assigning set switching +to stick buttons. + +* If uinput is enabled but not usable at runtime then XTest will be used +as a fallback option for the Linux version. + +* Tweaked Gradient and Pulse turbo modes to make them a bit tighter. A lower +delay will be needed in profiles to achieve a similar control from previous +versions. On the plus side, this has been tested to work with FlatOut 2 fairly +well. It is good enough to use and actually win some races against AI opponents. + +* Added analog control for mouse wheel buttons that are mapped to an axis +button. + +* Tweaked mouse movement code to improve mouse accuracy. This is mainly due +to discovering the QElapsedTimer class that is included in Qt. + +* Fixed middle mouse button binding when using the uinput event handler +on Linux. + +* Fixed memory leaks that were discovered by Valgrind. + + +2014-11-19 Travis Nickles + +Version 2.9 + +* Added mouse refresh rate as an option. Please be mindful of how your +system behaves if you set the refresh rate to a low value like 1 ms. +In the worst case scenario, you could end up dedicating one CPU core on +just the antimicro process. Also, on Windows, you will want to make sure +to disable the "Enhance Pointer Precision" option if you use a low value +otherwise Windows will severely slow down the mouse pointer. + +* Added an application level mouse smoothing option. The older button level +smoothing option has been removed. The old option didn't do much since it only +dealt with the partial distance remainder. + +* Button responsiveness has been improved. The old mouse movement code was +creating a bottleneck for button processing which would result in a slight +delay. + +* Changed mouse movement code. The overall mouse movement should be smoother +now. + +* Allow the Windows setting "Enhance Pointer Precision" to be disabled while +antimicro is running. This will make sure Windows does not directly manipulate +the mouse events sent to the system. This will allow mouse control on an analog +stick to be more accurate on Windows. + +* Changes to Auto Profile to allow more variables for matching. Multiple +window properties can be specified which will cause antimicro to count an +entry as a match only if all specified properties match. + +* Changed how windows are grabbed in X on Linux. + +* Minor fix for Gradient and Pulse turbo modes. There were times when the +timer interval controlling those modes could be negative and cause problems. + + +2014-11-05 Travis Nickles + +Version 2.8.1 + +* Fixed some buttons in virtual keyboard when program is using uinput support. + +* Fixed Update Joysticks option for SDL 1.2 users. + + +2014-10-28 Travis Nickles + +Version 2.8 + +* Added delay settings for analog sticks and dpads. This is meant to +keep some games from overreacting when switching directions quickly. +A delay is especially useful for games that utilize a dash on a key double tap. +This will also be very useful while playing rougelike games. The new +delay setting allows for more responsive controls than the old alternative of +using hold zones on individual direction buttons. + +* Added two new mouse acceleration curves: Easing Quadratic and +Easing Cubic. These new mouse acceleration curves are meant to mimic the +camera control that is used for gamepad support in some recent first person +shooters such as Borderlands 2. Once a stick direction has reached a threshold +(80%) then the mouse speed will gradually accelerate over a period of time +before the mouse speed reaches its peak. The duration of the easing method is +set at 0.50 seconds by default but the setting is configurable per +button. + +* Major refactor to mouse event generation. The new routine requires +fewer system resources and it is more accurate. + +* Made uinput support a runtime option for Linux users. The program can +now be compiled with both XTest and uinput support and the event +generator can be specified using the --eventgen flag. It defaults +to XTest if available. The option is only available when the program +is compiled with both XTest and uinput support. + +* Added right click context menus for buttons in main interface. + +* Fixed issue with Game Controller Mapping dialog. Controller DPads that +are exposed as 4 buttons can now be bound to the DPad of an SDL Game +Controller. + +* Fixed an issue with incorrect profile names being displayed in the +profile combobox. + +* Fixed issue introduced in version 2.7 regarding mouse movement calculations +for the left direction of analog sticks. A major portion of the +safe zone for that direction was being skipped. + +* Changed button groups in the main interface to update immediately +when a stick or dpad mode has been changed. + +* Initial removal of old joystick abstraction support in interface when using +SDL 2. + + +2014-10-14 Travis Nickles + +Version 2.7 + +* Added a UAC workaround for use in Windows. antimicro can be restarted +as Administrator in case a game is running with elevated permissions and +the events generated by antimicro are not detected by a game. + +* Added more key aliases for uinput support. + +* Force higher dead zones for axes in Game Controller Mapping window. + +* Fixed virtual keyboard in Button Edit Dialog window for Linux users +utilizing XTest support. + +* Display some minor mouse stats in Mouse Settings dialog. + +* Alter Analog Stick dialog window to show some new stats. Also, +show square stick coordinates as well as adjusted circle +stick coordinates. + +* Added square stick to circle stick conversion. + +* Fixed issue with VK_LSHIFT and VK_RSHIFT aliases not being saved properly +on Windows. + +* xinput is used for the uinput virtual pointer in order to +disable mouse acceleration for the pointer. This allows spring mode to work +as intended. + +* Added some code to guess which axes of a gamepad should be considered +triggers by default while in old Joystick mode. The initial values of +axes are taken from SDL and those are used as the point of the axes +while centered. If the initial value of an axis is below -30,000 then +an axis is considered to be a trigger. + + +2014-09-16 Travis Nickles + +Version 2.6 + +* Added two new Turbo modes. Gradient mode is used to change the key press +time depending on the position of an axis (useful for racing games). +Pulse mode is used to change how many times a key press is invoked depending +on the position of an axis (scrolling in a web browser using arrow keys). + +* Fixed profile resetting in a couple of places. + +* A Russian translation has been provided by Dima Koshel. + +* Added option to invoke Game Controller mapping window from command line. +The final mapping string will be printed to stdout. This is useful +for saving a SDL_GAMECONTROLLERCONFIG for your controller that +can be used system wide. Any SDL 2 game can then be set up to use +that mapping and it can be changed if needed. + +* Profiles now use a unique .amgp file extension. Older xml profiles will +continue to be supported. + +* Fixed spring mouse mode so that it uses proper axis distance values. + +* Set changing has been fixed for analog sticks and virtual dpads. + +* EXPERIMENTAL. uinput support has been added to the source code. Binary +Linux packages will continue to utilize XTest for event generation for the +time being. If you would like to test uinput integration then you will have +to compile the program using -DWITH_UINPUT=ON and -DWITH_XTEST=OFF +when running cmake. Playing Warsow 1.51 in Linux using antimicro requires +using uinput integration. Also, keys can now be pressed in a tty. + + +2014-08-01 Travis Nickles + +Version 2.5 + +* Fixed packaging the Windows version so the program will work on +Windows XP again. + +* Delay rendering of flashing buttons. This helps improve controller +responsiveness when the main window is not hidden. + +* Reduced the size of written profiles. Only changed values are +now stored in profiles. + +* Updated German translation provided by phob and Leonard Koenig. + +* Allow a profile to be listed as the final argument on the command line. +Ex: antimicro ~/antimicro-profiles/profile.xml. + +* Added diagonal distance support for distance slots for Standard +mode on Sticks and DPads. This was necessary for some modifier assignments +to work properly. The best example is for assigning walking in Half-Life 1. + +* Allow generated events to be sent to a different X display than the +application is running on. This change was mainly done to better work +with SteamOS. AntiMicro can be run via ssh with X tunneling in order +to configure profiles on one system but the program will send events to the +X display that is running Steam and games. + +* Auto Profile support has improved for SteamOS. Application grabbing can +now be done while in the SteamOS BPM Session. Steam BPM can be grabbed as +well. + +* Only show active or soon to be active slots for buttons in the main +window. The text displayed on the buttons will update when a +new zone has been reached due to using slots such as distance or hold. + +* Allow no profile to be assigned to an application for an Auto Profile entry. +This means that the program will choose an empty profile when the application +for that Auto Profile entry has focus. This will help with disabling AntiMicro +for applications that already have controller support. + +* Controller Mapping dialog now stops processing events until all elements +have been released on a controller. + + +2014-05-30 Travis Nickles + +Version 2.4 + +* Relative spring mode added. + +* Key repeating changes in Windows. + +* Updated Windows version to use Qt 5.3.0. + +* Set copying added. + +* Corrected application checks used for Auto Profile support +in Windows. + + +2014-05-23 Travis Nickles + +Version 2.3.3 + +* Tweaked Enhanced Precision mouse acceleration curve. + +* Tweaked "all" option in Auto Profile. No profile assigned to "all" now +implies that a blank configuration should be loaded. + +* Manpage created by Jeff Backus. + +* Migrated to the CMake build system. + + +2014-05-15 Travis Nickles + +Version 2.3.2 + +* Fixed problem with old profiles not being usable in the +program. + + +2014-05-13 Travis Nickles + +Version 2.3.1 + +* Added new Enhanced Precision mouse curve. It is now the default +mouse curve. The new mouse curve will make the cursor move slowly +towards the low end of an axis and the cursor movement will be +accelerated towards the high end of an axis. + +* Added unsaved profile dialogs. + +* Added key repeating behavior under Windows. + +* Increased maximum turbo interval. + +* Added more options to the Edit Settings dialog. + +* Added profile name display editing. + +* Fixed invalid pointer issue for Hold events. + + +2014-05-02 Travis Nickles + +Version 2.3 + +* Added a daemon mode. + +* Added joystick profile compatibility parser for game controllers. +Old profiles are now usable when using SDL Game Controller support. +Old profiles have to be mapped against the same controller that +is connected. + +* Added cycle reset support. Sequences with cycles can now get +returned to the first cycle zone in a sequence after a period of +time. + +* Changed Auto Profile support to work properly in SteamOS +while running the SteamOS Big Picture Mode session. On many +tested games (Duke Nukem 3D, SuperTux, World of Goo), the +game had to be run in windowed mode in order for Auto Profile +support to be able to detect the application. It is recommended +that you run games in windowed mode when using Auto Profile support +in the SteamOS BPM session. This is not an issue when running the Steam +desktop client in desktop mode. + +* Added a delay slot type. A delay slot can be used for +key presses in a key combination. Unlike other macro slots, slots +placed before a delay slot will remain active after the specified +time has passed. + +* Added option to allow the program to start on Windows startup. + +* Changed dialogs for secondary set buttons to display the set +that the button is currently in. + +* Changed turbo mode to give more control. Key presses are now given +more time to be active. Key presses and releases now run for a +duration of t/2 seconds. + +* Altered tray menu to display a single list when only one controller +is connected. An option has been added to allow for a single +list to also be used when multiple controllers are detected. + +* Fixed issue with Windows XP Auto Profile workaround. +On the plus side, now the program is confirmed to work in +Windows XP. + +* Fixed issues with Auto Profile support saving and precedence. + + +2014-04-19 Travis Nickles + +Version 2.2 + +* Added example controller display to Game Controller Mapping +dialog window. + +* Added Auto Profile support. Allows for profiles to be associated +with specific applications. + +* Added button icons in Windows version. + +* Added a press time slot type. That slot type is used +to have keys active for a specific period of time. + +* Allow Pause slots to have a 0 second interval. Allows +for a forced key release. + +* Windows version is now built with SDL 2.0.3. + +* Fixed 8-Way D-Pad mode. + +* Fixed preset options in various dialogs to account for new aliases. + +* Fixed ampersand rendering in set buttons. + +* Fixed spring mouse mode dimension support. + +* Fixed spring mouse mode accuracy under Windows. + + +2014-02-28 Travis Nickles + +Version 2.1 + +* Added new stick and dpad modes. + +* Added set names. + +* Minor fixes for Windows. + +* Fixed QSettings usage to reduce reads and write to config file. + + +2014-02-10 Travis Nickles + +Version 2.0.1 + +* Active keyboard keys now use a reference count. This will +be useful for keeping modifier keys held when moving a stick +from a diagonal direction to a cardinal direction. This will allow a run +to be maintained properly. + +* A release delay has been added to release slot events. This is needed +for some games where a key press and release might happen too quickly +for a game, such as The Elder Scrolls IV: Oblivion, to catch it. + +* Altered data sent to SendInput under Windows. The change should allow +games that rely exclusively on scancode data to detect keyboard +key presses now. Previously, keyboard emulation would not work +while playing The Elder Scrolls IV: Oblivion on Windows. + +* Improved key associations under Windows. VK_OEM_* keys associations +are now generated at runtime which will allow associations +to be more layout independent. + +* Changed some portions of the Windows version so that the Numpad +Enter key can be emulated. + +* The recent profile list is now updated when a profile is added +or removed from the list as opposed to when the program is closed. +This allows the list to be in sync while utilizing hotplugging. + + +2014-01-04 Travis Nickles + +Version 2.0 + +* Migrated profiles to use Qt key values as opposed to using native key code +values. Allows for better cross-platform compatibility. Current +joystick profiles will be migrated when first loaded by the program. + +* Program can now be compiled against SDL 2. + +* The Game Controller API provided by SDL 2 has been integrated into the +application. The API is used to abstract various gamepads to a unified +standard. Profiles made against the Game Controller API can be used with +any controller that is supported. Unsupported controllers will have to be +mapped in the program. + +* A simple Game Controller mapping window has been made so people that are using +an unsupported controller can map that controller so that it can be used with +the Game Controller API. Any saved mapping string will be loaded into +SDL when AntiMicro is first launched or when you select the +"Update Joysticks" option in the main window. + +* Any new saved profile will include the device type that it is +associated with in the filename. Joysticks and game controllers use slightly +different file specifications. + +* Joystick hotplugging support has been added thanks to SDL 2. + +* On Windows, XInput support is now available. This allows the Xbox 360 +controller guide button to be usable and both gamepad triggers can be used at +the same time. Previously, only DirectInput was being used so both triggers were +being mapped to one axis so they would negate each other if used at the same +time. This problem would really affect people trying to play Call of Duty with a +360 controller when the "Hold Aim Down the Sight" option is enabled in the game. + +* The list of recent profiles is now tied to a joystick GUID or joystick name +if the GUID is not available (compiled against SDL 1.2). + +* Program options window has been made. For right now, it is only being used to +allow users to be able to disable Game Controller integration for specific +controllers. + +* Mouse events are queued before a mouse event is sent to the system. This +allows for smoother diagonal mouse movement. This really helped improve camera +control for me in Warsow. + +* Key checker dialog has been made so you can check the alias values that are +being used for keyboard keys. This is mainly for debugging purposes. If you +find that a keyboard key that you use does not have a built-in alias, please +let me know so an alias can be added. Although, the key can still be used in +the program and saved to a profile. The major downside is that a profile +that uses an unsupported key will not be cross-platform compatible. + + +2013-12-13 Travis Nickles + +Version 1.2 + +* Improved while held set changing so that the program should not get stuck on +the wrong set. The changes made should behave roughly like the old while held +workaround that used turbo. + +* Windows port of AntiMicro has been made. + +* Tweaked code used for button presses and releases in order +to improve responsiveness. + +* Allow time-dependent action slots to have an interval +as low as 0.01 seconds. + +* Tweaked Release action slot. Release slots can now be placed at the +beginning of the assigned slots. This can be useful for +Tap and Hold slot configurations. + +* Pause slots can now be used with Release slots. + +* Profiles can be removed from the recent configs list. + +* Spring mouse mode preview has now been enabled. + +* Mouse speed modifier action slot has been added. This can be used to modify +the mouse speed settings used with any controller element while the slot is +active. The setting will modify the mouse speed by the percentage that is +specified. The mouse speed modifier can be used to allow for the mouse speed +to be slowed down while sniping. + +* Button and action names have been added. Names can be used to describe +the action that a slot sequence performs in the game. + +* Mouse wheel buttons are now used as a form of mouse movement. Mouse wheel +scrolling is now possible without using turbo. The speed that the wheel is +rotated can be specified in the mouse settings dialog window. + +* Added support for two extra mouse buttons. + +* A new controller properties window has been made. This window shows various +bits of information provided by SDL about a controller as well as the current +values of all the controller elements. + +* Added quick assign functionality for sticks and virtual dpads. + +* Windows version of the program now uses LocalAppData variable to know +where to place the program's settings file. + +* New translations provided by the translation team. + + +2013-10-03 Travis Nickles + +Version 1.1 + +* Added spring mouse mode. This mode is used to move the mouse cursor +from the center of the screen based on how much an axis has been moved +from the dead zone. The mouse cursor will be returned to the center +of the screen when the axis is released. + +* Added mouse curve options from QJoyPad. + +* Tweaked mouse movement in cursor mode to improve axis responsiveness +and to allow mouse movement to be less jittery. + +* Added optional mouse smoothing for a further reduction +in jitter in exchange for slightly delayed responsiveness. + +* Moved various mouse settings into a new dialog window. +Several other dialog windows have been changed to point to the +new dialog window to allow for mouse setting adjustments. + +* Added an option to start the program hidden. + +* Tray menu has been tweaked to allow configuration profiles to be +disabled. A blank new profile will be enabled in the program +for a controller. This is equivalent to selecting in the main window +combobox. + +* Serbian translation provided by Jay Alexander Fleming. + +* Brazilian Portuguese translation provided by VaGNaroK. + + +2013-07-12 Travis Nickles + +Version 1.0 + +* 8-way controls have been implemented. This allows keys to be mapped +to the diagonal directions of controller sticks and dpads. 8-way controls +allow rougelike games to be playable. + +* Virtual Dpad support has been added. Axes and buttons can be mapped +to a virtual dpad. This is useful for mapping dpads that are detected as a +pair of axes in SDL. + +* A Quick Set option has been added. Using the Quick Set option, you +can press a button on the controller and the program will bring up the edit +window for that specific button. The button can then be mapped to an +assignment from the edit window. The Quick Set option also works for axes, +controller sticks, and dpads. This is more of a convenience function than +anything but I have found it really useful since implementing it. + +* Main interface button text is now updated whenever the assigned slots +are changed. This allows the buttons' text to be in sync in many situations +that was not possible before. + +* Toggle and Turbo can be used together to create automated key macros for +use in MMORPGs. + diff --git a/ProfileTips.md b/ProfileTips.md new file mode 100644 index 0000000..152dce5 --- /dev/null +++ b/ProfileTips.md @@ -0,0 +1,78 @@ +Profile Tips +============ + +## Sticks + +### Dead Zones + +The XInput standard of 8,000 will typically be used in profiles for analog +sticks. For an Xbox 360 controller, that value tends to be the best minimum +value to ensure that no unintentional events are produced due to what position +a stick will be centered at. + +When using a different controller, you will likely want to play with the value +of the dead zone used for the analog sticks and find what works best for +your controller. As an example, when I make profiles for my Logitech F310 +gamepad, I find that using a dead zone value of 2,000 for the analog sticks +works best. + +### Left Stick (Keyboard) + +The default diagonal range of 45 degrees is recommended when mapping keyboard +keys to an analog stick when using the **standard** stick mode. If only one +action should ever occur at a time and the diagonal direction doesn't matter as +much, you might want to look into **4-way cardinal** stick mode. That can be +useful for navigating menus or mapping weapon hotkeys to an analog stick. + +Some games will overreact when mapping WASD or other keyboard keys to an +analog stick. This is mainly due to how quickly directions can be changed +especially if you have the stick positioned right around where a diagonal zone +resides. If you encounter problems in game or you just want to make movement a +little more definitive, you can adjust the **stick delay** value used for that +stick. That will cause direction changes to be slightly delayed. Even setting +the value to 0.01 seconds can greatly increase control in some games. + +### Right Stick (Mouse) + +To allow for better mouse control with an analog stick, it is recommended +that you use a diagonal range of at least 65 degrees instead of the +normal 45 degree value. If you want more twitchy mouse control, you will +likely want to set the diagonal range of the stick to 89 degrees or 90 degrees. +This will minimize the range used for the absolute cardinal directions. + +Another tip that will allow for more twitchy mouse control is related +to the dead zone used for the analog stick. Decreasing the value used for +the stick dead zone can help make mouse control feel more responsive than +when using the standard value of 8,000 even when using an Xbox 360 controller. + +Based on my experience, even decreasing the value to 6,000 can make a +huge difference. The big compromise is that there might be some mouse +cursor drift if the analog stick does not center back to the assigned dead +zone. On my Xbox 360 controller, I find that the stick can get stuck slightly +in the southwest region of the stick; the other directions don't have this +issue. However, the mouse cursor drift is very minimal and you can easily +compensate while playing a game. It doesn't hinder gameplay and the benefit +obtained far outweights the minor problem. + +One final thing that you can do to make mouse movement more twitchy is to +enable extra acceleration for mouse events. Changing the **extra duration** of +acceleration will have the biggest impact on mouse movement. Increasing the +maximum extra duration of the acceleration will loosen the mouse movement. +Changing the **multiplier** is another option that will change how mouse +movement behaves. One final option that can be changed is to use a different +curve for extra acceleration. **Linear** is still the default setting since it +was the only option available for many versions but I find myself using +**Ease Out Quad** lately. Besides altering the final multiplier used, it also +changes the final duration experienced. + +With all the options available for extra acceleration, you will have an easier +time performing a quick 180 degree turn while still having precision on the low +end of a stick for aiming at targets. + +## Action Names + +It is generally recommended that you specify action names when making profiles +that you will share with other people. This will allow other people to more +easily decipher what buttons are used for in a profile. Specifying action names +can also be a helpful reminder for yourself in order to document a more complex +action. diff --git a/README.md b/README.md new file mode 100644 index 0000000..a0d845c --- /dev/null +++ b/README.md @@ -0,0 +1,350 @@ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This is a backup of the latest versions of antimicro plus the source code, which were removed from https://github.com/Ryochan7/antimicro +I have downgraded SDL2.dll in the Windows releases from 2.0.4 to 2.0.3 (using msi2xml for the .msi files). It had to be done because SDL 2.0.4 broke DInput controllers detection. +Backup of some pages: http://www.mediafire.com/download/hla0doflg49th41/AntimicroPagesBackup.zip +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# antimicro + +[![Join the chat at https://gitter.im/Ryochan7/antimicro](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Ryochan7/antimicro?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +## Lower Priority Development + +As of June 04, 2015, development of antimicro has resumed but updates will be +less frequent than in the past. Other tasks will take priority. + +## Description + +antimicro is a graphical program used to map keyboard keys and mouse controls +to a gamepad. This program is useful for playing PC games using a gamepad that +do not have any form of built-in gamepad support. However, you can use this +program to control any desktop application with a gamepad; on Linux, this +means that your system has to be running an X environment in order to run +this program. + +This program is currently supported under various Linux +distributions, Windows (Vista and later), and FreeBSD. At the time of writing +this, antimicro works in Windows XP but, since Windows XP is no longer +supported, running the program in Windows XP will not be officially supported. +However, efforts will be made to not intentionally break compatibility +with Windows XP. + +Also, FreeBSD support will be minimal for now. I don't use BSD on +a daily basis so the main support for FreeBSD is being offered by Anton. He +has graciously made a port of antimicro for FreeBSD that you can find +at the following URL: [http://www.freshports.org/x11/antimicro/](http://www.freshports.org/x11/antimicro/). + +## License + +This program is licensed under the GPL v.3. Please read the gpl.txt text document +included with the source code if you would like to read the terms of the license. +The license can also be found online at +[http://www.gnu.org/licenses/gpl.txt](http://www.gnu.org/licenses/gpl.txt). + +## Download +Download links are currently available from the antimicro Releases section on +GitHub. Currently, the Windows archive, Debian Jessie deb files, and source code +archives can be found in the Releases section. + +[https://github.com/Ryochan7/antimicro/releases](https://github.com/Ryochan7/antimicro/releases) + +For Ubuntu users, there is now a PPA available that you can use to have your +package manager grab the latest antimicro updates automatically. For more details, +check out the antimicro page on Launchpad. + +[https://launchpad.net/~ryochan7/+archive/ubuntu/antimicro](https://launchpad.net/~ryochan7/+archive/ubuntu/antimicro) + +## Command line + + Usage: antimicro [options] [profile] + + Options: + -h, --help Print help text. + -v, --version Print version information. + --tray Launch program in system tray only. + --no-tray Launch program with the tray menu disabled. + --hidden Launch program without the main window + displayed. + --profile Launch program with the configuration file + selected as the default for selected + controllers. Defaults to all controllers. + --profile-controller Apply configuration file to a specific + controller. Value can be a + controller index, name, or GUID. + --unload [] Unload currently enabled profile(s). + Value can be a controller index, name, or GUID. + --startSet [] Start joysticks on a specific set. + Value can be a controller index, name, or GUID. + -d, --daemon Launch program as a daemon. + --log-level (debug|info) Enable logging. + --eventgen (xtest|uinput) Choose between using XTest support and uinput + support for event generation. Default: xtest. + -l, --list Print information about joysticks detected by + SDL. + --map Open game controller mapping window of selected + controller. Value can be a controller index or + GUID. + +## Pre-made Profiles + +There is a repository for pre-made antimicro profiles. Using a pre-made +profile, you can have a controller layout that is suitable for playing a +game without having to map everything yourself. It makes using antimicro +really convenient. In order to use those pre-made profiles, you have to be +running at least antimicro version 2.0 and antimicro must have been compiled +with SDL 2 support. + +[https://github.com/Ryochan7/antimicro-profiles](https://github.com/Ryochan7/antimicro-profiles) + +## Wiki + +An effort is now being done to utilize the Wiki section on GitHub more. +Please check out the Wiki at [https://github.com/Ryochan7/antimicro/wiki](https://github.com/Ryochan7/antimicro/wiki) +to read various help pages that have been created. The Wiki is currently +open to all GitHub users so feel free to add a new page or modify an +existing page. + +## Build Dependencies + +This program is written in C++ using the [Qt](http://qt-project.org/) +framework. A C++ compiler and a proper C++ build environment will need to be +installed on your system prior to building this program. Under Debian and +Debian-based distributions like Ubuntu, the +easiest way to get a base build environment set up is to install the +meta-package **build-essential**. The following packages are required to be +installed on your system in order to build this program: + +* g++ +* cmake +* libqt4-dev (Qt 4 support) or qttools5-dev and qttools5-dev-tools (Qt 5 +support) +* libsdl1.2-dev (SDL 1.2) or libsdl2-dev (SDL 2) +* libxi-dev (optional. Needed to compile with X11 and uinput support) +* libxtst-dev (optional. Needed to compile with XTest support) +* libX11-dev (optional when compiled with Qt 5 support) + +## Building under Linux + +In order to build this program, open a terminal and cd into the antimicro +directory. Enter the following commands in order to build the program: + + cd antimicro + mkdir build && cd build + cmake .. + make + sudo make install + +The installation path of antimicro can be customized by specifying the +CMAKE_INSTALL_PREFIX variable while running cmake. + + cmake -DCMAKE_INSTALL_PREFIX=/usr .. + +This will install the antimicro executable to /usr/bin/antimicro. +By default, the executable will be installed to /usr/local/bin/antimicro. + +The cmake step will use pkg-config to attempt to find any SDL +libraries that you have installed. The project is set up to +look for a copy of SDL 2 followed by SDL 1.2. This behavior should work +fine for most people. You can override this behavior by using the -DUSE_SDL_2 +option when you run cmake. Using -DUSE_SDL_2=ON when you run cmake will mean +that you want antimicro compiled with SDL 2 support. Using -DUSE_SDL_2=OFF when +you run cmake will mean that you want antimicro compiled with SDL 1.2 support. + +Here is an example of how to specify that you want antimicro to be compiled +with SDL 2 support when you run qmake. + + cmake -DUSE_SDL_2=ON .. + +## Building under Windows + +**Instructions provided by aybe @ https://github.com/aybe. +Modified by Travis Nickles.** + +* Download and install CMake: http://www.cmake.org/cmake/resources/software.html + +* You will need Qt with MinGW support: http://qt-project.org/downloads. The +current version of Qt that is being used to create builds is 5.4.0. + +* download SDL development package : http://www.libsdl.org/release/SDL2-devel-2.0.3-mingw.tar.gz + +* open the archive and drop the 'SDL2-2.0.3' folder in the 'antimicro' folder + +* open the project (CMakeLists.txt) in Qt Creator The CMake Wizard will appear +the first time you open the project in Qt Creator. + +* Choose a Build Location. The recommendation is to create a "build" folder +under the root antimicro folder and choose that for the build location. + +* In the Run CMake section, in the Arguments field, please input +```-DCMAKE_PREFIX_PATH=``` +-DCMAKE_BUILD_TYPE=Release. Replace "``````" +with the actual path to your Qt installation. The default path for version +Qt 5.4.0 is C:\Qt\Qt5.4.0\5.4\mingw491_32\. + +* Choose "MinGW Generator" for the Generator option in the Run CMake section + +* Click the Run CMake button and then click Finish + +* In the main IDE window, open the Build menu and select "Build All" (Ctrl+Shift+B) + +* The application will need SDL2.DLL. A build step has been added to +CMakeLists.txt in order to automate the process. Click the "Projects" icon +in the sidebar to bring up the "Build Settings" section. Within +"Build Steps", click the "Details" button on the Make entry. In the expanded +menu, uncheck the "all" checkbox and then check the "copy_sdl_dll" checkbox +and run "Build All". + +* At this point, antimicro has been built for Windows and is runnable +from Qt Creator. A couple more steps are required in order to make a +distributable package. + +* Under "Build Settings", expand the Make menu and check the "install" and +"install_dlls" checkboxes. + +* Under the "Build" menu in the main window, select "Run CMake" and +add ```-DCMAKE_INSTALL_PREFIX=``` option and replace `````` with the directory +that you want to install the application. The default for me is +C:\Program Files (x86)\AntiMicro\ although I use a different directory +when bundling the Window version for other users. + +* Run "Build All" to have the application and required DLLs installed +into the final location that will be ready for distribution. + +### 64 bit build + +* Some additional steps are required in order to compile a 64 bit version of +antimicro. The first step is to download a packaged version of Qt and MinGW +compiled for 64 bit from the Qt-x64 project @ +http://sourceforge.net/projects/qtx64/. + +* You will have to manually create a new Kit in Qt Creator. In the main Qt +Creator window, click the "Projects" button in the sidebar to bring up the +"Build Settings" page for the project. Click on the "Manage Kits" button +near the top of the page. Manually add the 64 bit compiled Qt version under +"Qt Versions", add the 64 bit MinGW under "Compilers", and add the 64 bit +gdb.exe under "Debuggers". + +* After creating a new kit in Qt Creator, bring up the "Build Settings" page +for the project. Hover over the currently selected kit name and click the +arrow that appears, hover over "Change Kit" and select the proper 64 bit kit +that you created earlier. + +* Perform a clean on the project or delete the build directory that CMake is +using. After that, choose the "Run CMake" option under the "Build" menu entry. +The arguments that you pass to CMake will have to be changed. You will have +to edit ```-DCMAKE_PREFIX_PATH=``` variable +and have it point to the 64 bit compiled version Qt. Also, make sure to add +```-DTARGET_ARCH=x86_64``` so that CMake will use the proper SDL libraries while +building the program and copy the proper Qt and SDL DLLs if you perform an +**install_dlls**. + +## Building the Windows Installer Package (MSI) + +(these instructions have been tested with WiX 3.8) + +* you need to have WiX installed, grab it at http://wixtoolset.org/ + +* the building process relies on the WIX environment, it is recommended that you download the installer instead of the binaries as it it will set it up for you + +* if Qt Creator is running while you install or upgrade to a newer version then make sure to restart it as it will either not find that environment variable or fetch the old (incorrect) value from the previous version + +* to build the MSI package, click on the "Projects" icon in the sidebar, +click the "Details" button on the make entry, uncheck all other options +and check the "buildmsi" box. + +* currently it relies on INSTALL to copy files at the location they are harvested, this might change in the future + +Notes about the WXS file and the building process : + +* the WXS file has been generated with WixEdit and manually modified to contain relative paths, it will only work from the 'windows' sub-folder (or any other) + +* WixCop can be run against the WXS file and it should not point out any errors as the WXS has been corrected previously with the -F switch + +* CNDL1113 warning : shortucts are advertised, left as-is as a nice feature about them is that if the program gets corrupted it will be repaired by Windows Installer, by design the shortcuts will not point to antimicro.exe as a regular LNK file + +* LGHT1073 warning : SDL2.DLL does not specify its language in the language column, not a big deal; it could be recompiled but it's pretty much a time waste as it would only prevent this warning + +* all of these warnings have been made silent through the use of command-line switches. + +* built MSI package will be placed in /windows + +## Testing under Linux + +If you are having problems with antimicro detecting a controller or +detecting all axes and buttons, you should test the controller outside of +antimicro to check if the problem is with antimicro or not. The two endorsed +programs for testing gamepads outside of antimicro are **sdl-jstest** +(**sdl2-jstest**) and **evtest**. SDL 2 utilizes evdev on Linux so performing +testing with older programs that use joydev won't be as helpful since some +devices behave a bit differently between the two systems. + +[https://github.com/Grumbel/sdl-jstest/](https://github.com/Grumbel/sdl-jstest/) + +## Support + +In order to obtain support, you can post an issue on the antimicro GitHub page +or you can email me at nickles.travis@gmail.com. Please include **antimicro** +somewhere in the subject line of the email message or it might be skipped. + +[https://github.com/Ryochan7/antimicro](https://github.com/Ryochan7/antimicro) + +## Ideas For Future Features + +This section is where some of the ideas for future features +for this program will be written. + +* Allow buttons to be bound to actions. +* Use uinput by default and fallback to XTest if necessary. (MOSTLY DONE) +* Move simulated event generation to a new thread. +* ~~Allow logging as long as it doesn't cause button lag.~~ +* Allow notes to be added to a profile in various places. + +Along with this, I will put the simple mind map that I am using to +write ideas for future development into the repository for this +program. The mind map will include extra notes that are not available in +this README. Opening the mind map will require the use of the program +FreeMind which can be downloaded from +[http://freemind.sourceforge.net/wiki/index.php/Main_Page](http://freemind.sourceforge.net/wiki/index.php/Main_Page). + +## Shoutout + +A big inspiration for this program was the program QJoyPad +([http://qjoypad.sourceforge.net/](http://qjoypad.sourceforge.net/)). +I was a user of the program for years and it is unfortunate that the +program is no longer being maintained. The source code for QJoyPad was an +invaluable resource when I made the first version of this program and the UI +for this program mostly resembles QJoyPad. + +## Credits + +### Main Developer +Travis Nickles + +### Contributors + +Zerro Alvein +aybe +Jeff Backus +Arthur Moore +Anton Tornqvist + +### Translators + +VaGNaroK - Brazilian Portuguese +zzpxyx - Chinese +Belleguic Terence - French +Leonard Koenig - German +phob - German +tou omiya - Japanese +Dmitriy Koshel - Russian +Jay Alexander Fleming - Serbian +burunduk - Ukrainian + +## Donate + +If you would like to help fund future development of this project, +please send a donation via PayPal to ryoohki7@yahoo.com +([PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=L6MHH9R4WUGY6)). +Any financial help would be greatly appreciated. As a disclaimer, I should +mention that any donations received might go towards buying games to test +against. Some donations might just go towards groceries so that I can eat. diff --git a/Resources.txt b/Resources.txt new file mode 100644 index 0000000..9c69a2c --- /dev/null +++ b/Resources.txt @@ -0,0 +1,15 @@ +Generate GUIDs for use in .wxs files + +http://www.guidgen.com/ + +Site used to check out the behavior of different easing curves + +http://easings.net/ + +Repository of code examples for many different easing curves + +https://github.com/jesusgollonet/ofpennereasing + +Site used to generate acceleration curve images + +http://rechneronline.de/function-graphs/ diff --git a/cmake_uninstall.cmake.in b/cmake_uninstall.cmake.in new file mode 100644 index 0000000..2037e36 --- /dev/null +++ b/cmake_uninstall.cmake.in @@ -0,0 +1,21 @@ +if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") +endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + +file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +foreach(file ${files}) + message(STATUS "Uninstalling $ENV{DESTDIR}${file}") + if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + exec_program( + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + if(NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") + endif(NOT "${rm_retval}" STREQUAL 0) + else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + message(STATUS "File $ENV{DESTDIR}${file} does not exist.") + endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") +endforeach(file) diff --git a/gpl.txt b/gpl.txt new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/gpl.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/other/40-uinput.rules b/other/40-uinput.rules new file mode 100644 index 0000000..f28c715 --- /dev/null +++ b/other/40-uinput.rules @@ -0,0 +1 @@ +SUBSYSTEM=="misc", KERNEL=="uinput", MODE="0660", GROUP="uinput" diff --git a/other/CMakeLists.txt b/other/CMakeLists.txt new file mode 100644 index 0000000..bb8977b --- /dev/null +++ b/other/CMakeLists.txt @@ -0,0 +1,7 @@ +add_subdirectory(appdata) + +add_custom_target(manpage) +add_custom_command(TARGET manpage PRE_BUILD + COMMAND gzip -c "${PROJECT_SOURCE_DIR}/other/antimicro.1" > "antimicro.1.gz" VERBATIM +) +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/antimicro.1.gz" DESTINATION "share/man/man1") diff --git a/other/antimicro.1 b/other/antimicro.1 new file mode 100644 index 0000000..c575739 --- /dev/null +++ b/other/antimicro.1 @@ -0,0 +1,63 @@ +.\" Manpage for antimicro. +.\" Contact jeff.backus@gmail.com to correct errors or typos. +.TH ANTIMICRO "1" "10 January 2016" "antimicro 2.21" "User Commands" +.SH NAME +antimicro \- map keyboard keys and mouse controls to a gamepad +.SH SYNOPSIS +.B antimicro +[\fIOPTION\fR] [\fIPROFILE\fR] +.SH DESCRIPTION +.PP +antimicro is a graphical program used to map keyboard keys and mouse controls to a gamepad. This program is useful for playing PC games using a gamepad that do not have any form of built-in gamepad support. However, you can use this program to control any desktop application with a gamepad. +.TP +\fB\-\-tray\fR +launch program in system tray only +.TP +\fB\-\-no\-tray\fR +launch program with the tray menu disabled +.TP +\fB\-h\fR, \fB\-\-help\fR +display this help and exit +.TP +\fB\-v\fR, \fB\-\-version\fR +output version information and exit +.TP +\fB\-\-profile\fR \fI\fR +use specified profile as default for selected controllers. Defaults to all controllers. +.TP +\fB\-\-profile-controller\fR \fI\fR +apply configuration file to a specific controller. can be an controller index, name, or GUID. +.TP +\fB\-\-hidden\fR +launch program without the main window +.TP +\fB\-\-unload\fR \fI[]\fR +unload currently enabled profile(s). Value can be a controller index, name, or GUID. +.TP +\fB\-\-startSet\fR \fI\fR \fI[]\fR +start joysticks on a specific set. Value can be a controller index, name, or GUID. +.TP +\fB\-\-next\fR +Advance profile loading set options. +.TP +\fB\-d\fR, \fB\-\-daemon\fR +launch program as a daemon. +.TP +\fB\-\-log\-level\fR \fI{debug,info}\fR +Enable logging. +.TP +\fB\-l\fR, \fB\-\-list\fR +Print information about joysticks detected by SDL. +.TP +\fB\-\-map\fR \fI\fR +Open game controller mapping window of selected controller. Value can be a controller index or GUID. +.TP +\fB\-\-eventgen\fR \fI{xtest,uinput}\fR +Choose between using XTest support and uinput support for event generation. Default: xtest. + +.SH BUGS +No known bugs. +.SH AUTHOR +Travis Nickles (nickles.travis@gmail.com) +.SH "REPORTING BUGS" +Report dir bugs to antimicro home page: https://github.com/Ryochan7/antimicro diff --git a/other/antimicro.desktop b/other/antimicro.desktop new file mode 100644 index 0000000..4b7610a --- /dev/null +++ b/other/antimicro.desktop @@ -0,0 +1,17 @@ +[Desktop Entry] +Name=AntiMicro +Comment=Use a gamepad to control a variety of programs +Name[sr]=Анти-микро +Comment[sr]=Користите џојстик или играћу тастатуру за управљање различитим програмима +Name[fr]=AntiMicro +Comment[fr]=Utilisez une manette de jeu pour commander un logiciel +Name[de]=AntiMicro +Comment[de]=Nutze das Gamepad um Programme/Spiele zu steuern +Comment[uk]=Використовуйте ігровий маніпулятор для керування програмами +Exec=antimicro +Icon=antimicro +StartupNotify=true +Terminal=false +Type=Application +Categories=Qt;Utility; +MimeType=application/x-amgp; diff --git a/other/antimicro.xml b/other/antimicro.xml new file mode 100644 index 0000000..886b59d --- /dev/null +++ b/other/antimicro.xml @@ -0,0 +1,8 @@ + + + + AntiMicro Profile + AntiMicro профіль + + + diff --git a/other/appdata/CMakeLists.txt b/other/appdata/CMakeLists.txt new file mode 100644 index 0000000..8fe97cc --- /dev/null +++ b/other/appdata/CMakeLists.txt @@ -0,0 +1,16 @@ +# Make appdata optional when installing an application. +if(APPDATA) + add_custom_target(appdata) + + file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/PO_files/") + + add_custom_command(TARGET appdata PRE_BUILD + # Add an entry per language + COMMAND msgfmt "${PROJECT_SOURCE_DIR}/other/appdata/PO_files/en.po" -o "${CMAKE_CURRENT_BINARY_DIR}/PO_files/en.mo" + + COMMAND itstool -i "${PROJECT_SOURCE_DIR}/other/appdata/appdata.its" -j "${PROJECT_SOURCE_DIR}/other/appdata/antimicro.appdata.xml.in" -o "antimicro.appdata.xml" "${CMAKE_CURRENT_BINARY_DIR}/PO_files/*.mo" + ) + + # Only install an appdata file if the user requested to have one built. + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/antimicro.appdata.xml" DESTINATION "share/appdata") +endif(APPDATA) diff --git a/other/appdata/PO_files/en.po b/other/appdata/PO_files/en.po new file mode 100644 index 0000000..1c7e857 --- /dev/null +++ b/other/appdata/PO_files/en.po @@ -0,0 +1,81 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2014-12-06 21:37-0500\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. (itstool) path: component/id +#: antimicro.appdata.xml.in:4 +msgid "antimicro.desktop" +msgstr "" + +#. (itstool) path: component/metadata_license +#: antimicro.appdata.xml.in:5 +msgid "MIT" +msgstr "" + +#. (itstool) path: component/project_license +#: antimicro.appdata.xml.in:6 +msgid "GPL-3.0+" +msgstr "" + +#. (itstool) path: component/name +#: antimicro.appdata.xml.in:7 +msgid "AntiMicro" +msgstr "" + +#. (itstool) path: component/summary +#: antimicro.appdata.xml.in:8 +msgid "Graphical program used to map keyboard buttons and mouse controls to a gamepad" +msgstr "" + +#. (itstool) path: description/p +#: antimicro.appdata.xml.in:10 +msgid "AntiMicro is a graphical program used to map keyboard keys and mouse controls to a gamepad. This program is useful for playing PC games using a gamepad that do not have any form of built-in gamepad support. AntiMicro was inspired by QJoyPad but has additional features." +msgstr "" + +#. (itstool) path: screenshot/image +#: antimicro.appdata.xml.in:19 +msgid "https://raw.githubusercontent.com/jsbackus/antimicro/appdata/other/appdata/screenshots/controller_configure01.png" +msgstr "" + +#. (itstool) path: screenshot/caption +#: antimicro.appdata.xml.in:20 +msgid "Profile Configuration Dialog" +msgstr "" + +#. (itstool) path: screenshot/image +#: antimicro.appdata.xml.in:23 +msgid "https://raw.githubusercontent.com/jsbackus/antimicro/appdata/other/appdata/screenshots/controller_configure02.png" +msgstr "" + +#. (itstool) path: screenshot/caption +#: antimicro.appdata.xml.in:24 +msgid "Key Assignment Dialog" +msgstr "" + +#. (itstool) path: screenshot/image +#: antimicro.appdata.xml.in:27 +msgid "https://raw.githubusercontent.com/jsbackus/antimicro/appdata/other/appdata/screenshots/controller_mapping01.png" +msgstr "" + +#. (itstool) path: screenshot/caption +#: antimicro.appdata.xml.in:28 +msgid "Controller Mapping Dialog" +msgstr "" + +#. (itstool) path: component/url +#: antimicro.appdata.xml.in:31 +msgid "https://github.com/Ryochan7/antimicro" +msgstr "" + +#. (itstool) path: component/updatecontact +#: antimicro.appdata.xml.in:32 +msgid "jeff.backus_at_gmail.com" +msgstr "" + diff --git a/other/appdata/antimicro.appdata.xml.in b/other/appdata/antimicro.appdata.xml.in new file mode 100644 index 0000000..a7051d0 --- /dev/null +++ b/other/appdata/antimicro.appdata.xml.in @@ -0,0 +1,35 @@ + + + + antimicro.desktop + CC0-1.0 + GPL-3.0+ + AntiMicro + Graphical program used to map keyboard buttons and mouse controls to a gamepad + +

+ AntiMicro is a graphical program used to map keyboard keys and mouse + controls to a gamepad. This program is useful for playing PC games using a + gamepad that do not have any form of built-in gamepad support. +

+

+ AntiMicro was inspired by QJoyPad but has additional features. +

+
+ + + https://raw.githubusercontent.com/jsbackus/antimicro/appdata/other/appdata/screenshots/controller_configure01.png + Profile Configuration Dialog + + + https://raw.githubusercontent.com/jsbackus/antimicro/appdata/other/appdata/screenshots/controller_configure02.png + Key Assignment Dialog + + + https://raw.githubusercontent.com/jsbackus/antimicro/appdata/other/appdata/screenshots/controller_mapping01.png + Controller Mapping Dialog + + + https://github.com/Ryochan7/antimicro + jeff.backus_at_gmail.com +
diff --git a/other/appdata/appdata.its b/other/appdata/appdata.its new file mode 100644 index 0000000..9a7f0e8 --- /dev/null +++ b/other/appdata/appdata.its @@ -0,0 +1,9 @@ + + + + + diff --git a/other/appdata/screenshots/controller_configure01.png b/other/appdata/screenshots/controller_configure01.png new file mode 100644 index 0000000000000000000000000000000000000000..9bca4c53c32d00fa05dff3dd717516db35848f06 GIT binary patch literal 53337 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
{BaU>qJxS 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
    SVra9k`Co{d;e@4ftdw~I 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 literal 0 HcmV?d00001 diff --git a/other/appdata/screenshots/controller_mapping01.png b/other/appdata/screenshots/controller_mapping01.png new file mode 100644 index 0000000000000000000000000000000000000000..513aaef8a82873949dbb2cd56d4de7c5c459246e GIT binary patch literal 105539 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 #H?&S-;}+ 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 b!G`eq5wYiY=BvG-H`BPO{Rj5C_0#_a>E{lP literal 0 HcmV?d00001 diff --git a/share/antimicro/blank.txt b/share/antimicro/blank.txt new file mode 100644 index 0000000..e69de29 diff --git a/share/antimicro/translations/CMakeLists.txt b/share/antimicro/translations/CMakeLists.txt new file mode 100644 index 0000000..86d4764 --- /dev/null +++ b/share/antimicro/translations/CMakeLists.txt @@ -0,0 +1,27 @@ +# This will ensure that the *.qm files will be stored +# in the right place within the build directory. +file(GLOB antimicro_TRANSLATIONS antimicro_*.ts) +list(APPEND antimicro_TRANSLATIONS antimicro.ts) +file(GLOB_RECURSE antimicro_BASE_SOURCES ${PROJECT_SOURCE_DIR}/src/*.cpp) +file(GLOB_RECURSE antimicro_BASE_FORMS ${PROJECT_SOURCE_DIR}/src/*.ui) + +if(USE_QT5) + if(UPDATE_TRANSLATIONS) + QT5_CREATE_TRANSLATION(antimicro_QMFILES ${antimicro_BASE_SOURCES} + ${antimicro_BASE_FORMS} ${antimicro_TRANSLATIONS} + OPTIONS "-no-obsolete") + else() + QT5_ADD_TRANSLATION(antimicro_QMFILES ${antimicro_TRANSLATIONS}) + endif(UPDATE_TRANSLATIONS) +else() + if(UPDATE_TRANSLATIONS) + QT4_CREATE_TRANSLATION(antimicro_QMFILES ${antimicro_BASE_SOURCES} + ${antimicro_BASE_FORMS} ${antimicro_TRANSLATIONS} + OPTIONS "-no-obsolete") + else() + QT4_ADD_TRANSLATION(antimicro_QMFILES ${antimicro_TRANSLATIONS}) + endif(UPDATE_TRANSLATIONS) +endif(USE_QT5) + +add_custom_target(updateqm DEPENDS ${antimicro_QMFILES}) +install(FILES ${antimicro_QMFILES} DESTINATION "share/antimicro/translations") diff --git a/share/antimicro/translations/antimicro.ts b/share/antimicro/translations/antimicro.ts new file mode 100644 index 0000000..9a864a0 --- /dev/null +++ b/share/antimicro/translations/antimicro.ts @@ -0,0 +1,5880 @@ + + + + + AboutDialog + + + About + + + + + Version + + + + + Info + + + + + Changelog + + + + + Since December 30, 2012, I have been working on antimicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. + +The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. + +Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. + +Once the Steam controller is finally released to the public, the need for this program might not exist anymore. Just based on the concept of the controller alone, the Steam controller would have so many advantages over using a program like this to provide KB+M emulation. + + + + + Copyright: 2013 - 2015 + + + + + Credits + + + + + antimicro + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Travis Nickles &lt;nickles.travis@gmail.com&gt;</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Contributors:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;"><br /></span>Zerro Alvein</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">aybe</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Jeff Backus &lt;jeff.backus@gmail.com&gt;</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Arthur Moore<br />Anton Tornqvist &lt;antont@inbox.lv&gt;</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Translators:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt; font-weight:600;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">zzpxyx - Chinese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">phob - German</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tou omiya - Japanese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">burunduk - Ukrainian</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Version 3, 29 June 2007</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Preamble</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">TERMS AND CONDITIONS</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">0. Definitions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">1. Source Code.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">2. Basic Permissions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">4. Conveying Verbatim Copies.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">5. Conveying Modified Source Versions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">6. Conveying Non-Source Forms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">7. Additional Terms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">8. Termination.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">11. Patents.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">14. Revised Versions of this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">15. Disclaimer of Warranty.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">16. Limitation of Liability.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> + + + + + About Development + + + + + License + + + + + Program Version %1 + + + + + Program Compiled on %1 at %2 + + + + + Built Against SDL %1 + + + + + Running With SDL %1 + + + + + Using Qt %1 + + + + + Using Event Handler: %1 + + + + + AddEditAutoProfileDialog + + + Auto Profile Dialog + + + + + Profile: + + + + + + Browse + + + + + Window: + + + + + + Select Window. Click on the appropriate application +window and the application file path will be populated +in the form. + + + + + Detect Window Properties + + + + + Class: + + + + + Title: + + + + + Application: + + + + + Select + + + + + Devices: + + + + + + Select this profile to be the default loaded for +the specified device. The selection will be used instead +of the all default profile option. + + + + + Set as Default for Controller + + + + + + A different profile is already selected as the default for this device. + + + + + Current (%1) + + + + + Open Config + + + + + + Select Program + + + + + Programs (*.exe) + + + + + Please use the main default profile selection. + + + + + Please select a window by using the mouse. Press Escape if you want to cancel. + + + + + Capture Application Window + + + + + Could not obtain information for the selected window. + + + + + Application Capture Failed + + + + + Profile file path is invalid. + + + + + No window matching property was specified. + + + + + Program path is invalid or not executable. + + + + + File is not an .exe file. + + + + + No window matching property was selected. + + + + + AdvanceButtonDialog + + + + Advanced + + + + + Assignments + + + + + Toggle + + + + + Turbo + + + + + Set Selector + + + + + Blank or KB/M + + + + + Hold + + + + + Pause + + + + + Cycle + + + + + Distance + + + + + Insert + + + + + Delete + + + + + Clear All + + + + + Time: + + + + + 0.01s + + + + + 0s + + + + + Insert a pause that occurs in between key presses. + + + + + Release + + + + + + Insert a new blank slot. + + + + + Delete a slot. + + + + + Clear all currently assigned slots. + + + + + Specify the duration of an inserted Pause or Hold slot. + + + + + 0m + + + + + + Specify the range past an axis dead zone in which a sequence of actions will execute. + + + + + Distance: + + + + + + % + + + + + Mouse Mod + + + + + Press Time + + + + + Delay + + + + + Execute + + + + + Load + + + + + Set Change + + + + + Text Entry + + + + + Placeholder + + + + + + 0 + + + + + Mouse Speed Mod: + + + + + Set the percentage that mouse speeds will be modified by. + + + + + Auto Reset Cycle After + + + + + seconds + + + + + ... + + + + + + + Enabled + + + + + Mode: + + + + + <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> + + + + + Normal + + + + + Gradient + + + + + Pulse + + + + + Delay: + + + + + 0.10s + + + + + Rate: + + + + + 10.0/s + + + + + + Disabled + + + + + Select Set 1 One Way + + + + + Select Set 1 Two Way + + + + + Select Set 1 While Held + + + + + Select Set 2 One Way + + + + + Select Set 2 Two Way + + + + + Select Set 2 While Held + + + + + Select Set 3 One Way + + + + + Select Set 3 Two Way + + + + + Select Set 3 While Held + + + + + Select Set 4 One Way + + + + + Select Set 4 Two Way + + + + + Select Set 4 While Held + + + + + Select Set 5 One Way + + + + + Select Set 5 Two Way + + + + + Select Set 5 While Held + + + + + Select Set 6 One Way + + + + + Select Set 6 Two Way + + + + + Select Set 6 While Held + + + + + Select Set 7 One Way + + + + + Select Set 7 Two Way + + + + + Select Set 7 While Held + + + + + Select Set 8 One Way + + + + + Select Set 8 Two Way + + + + + Select Set 8 While Held + + + + + sec. + + + + + /sec. + + + + + Set %1 + + + + + + Select Set %1 + + + + + One Way + + + + + Two Way + + + + + While Held + + + + + Choose Executable + + + + + Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. + + + + + Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. + + + + + Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. + + + + + Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. + + + + + Chose a profile to load when this slot is activated. + + + + + Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. + + + + + Specify the time that keys past this slot should be held down. + + + + + Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. + + + + + Change to selected set once slot is activated. + + + + + Full string will be typed when a slot is activated. + + + + + Execute program when slot is activated. + + + + + + Choose Profile + + + + + Config Files (*.amgp *.xml) + + + + + AdvanceStickAssignmentDialog + + + Stick/Pad Assignment + + + + + Sticks + + + + + DPads + + + + + + %1 (Joystick %2) + + + + + Stick 1 + + + + + + + Enabled + + + + + + + + + + Assign + + + + + + X Axis: + + + + + + Y Axis: + + + + + Stick 2 + + + + + Number of Physical DPads: %1 + + + + + Virtual DPad 1 + + + + + Up: + + + + + Down: + + + + + Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. + + + + + Left: + + + + + Right: + + + + + + + + Axis %1 + + + + + + + + Axis %1 - + + + + + + + + Axis %1 + + + + + + + + + Button %1 + + + + + Move stick 1 along the X axis + + + + + Move stick 1 along the Y axis + + + + + Move stick 2 along the X axis + + + + + Move stick 2 along the Y axis + + + + + + + + Press a button or move an axis + + + + + AxisEditDialog + + + Axis + + + + + + Mouse (Horizontal) + + + + + + Mouse (Inverted Horizontal) + + + + + + Mouse (Vertical) + + + + + + Mouse (Inverted Vertical) + + + + + + Arrows: Up | Down + + + + + + Arrows: Left | Right + + + + + + Keys: W | S + + + + + + Keys: A | D + + + + + + NumPad: KP_8 | KP_2 + + + + + + NumPad: KP_4 | KP_6 + + + + + + + None + + + + + + Set the value to use as the limit for an axis. Useful for a +worn out analog stick. + + + + + Negative Half Throttle + + + + + Positive Half Throttle + + + + + Name: + + + + + Specify the name of an axis. + + + + + Mouse Settings + + + + + + Set the value of the dead zone for an axis. + + + + + Presets: + + + + + Dead Zone: + + + + + Max Zone: + + + + + + [NO KEY] + + + + + Throttle setting that determines the behavior of how to +interpret an axis hold or release. + + + + + Negative Throttle + + + + + Normal + + + + + Positive Throttle + + + + + Current Value: + + + + + Set + + + + + Set %1 + + + + + Left Mouse Button + + + + + Right Mouse Button + + + + + ButtonEditDialog + + + Dialog + + + + + To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab + + + + + Placeholder + + + + + Toggle + + + + + Enables a key press or release to only occur when a controller button is pressed. + + + + + Enables rapid key presses and releases. Turbo controller. + + + + + Turbo + + + + + Current: + + + + + Slots + + + + + Na&me: + + + + + Specify the name of a button. + + + + + Action: + + + + + Specify the action that will be performed in game while +this button is being used. + + + + + Advanced + + + + + Set + + + + + Set %1 + + + + + CapturedWindowInfoDialog + + + Captured Window Properties + + + + + Information About Window + + + + + Class: + + + + + + + TextLabel + + + + + Title: + + + + + Path: + + + + + Match By Properties + + + + + Class + + + + + Title + + + + + Path + + + + + Full Path + + + + + File Name + + + + + CommandLineUtility + + + + Profile location %1 is not an XML file. + + + + + + Profile location %1 does not exist. + + + + + An invalid set number '%1' was specified. + + + + + Controller identifier '%s'' is not a valid value. + + + + + No display string was specified. + + + + + + + Controller identifier is not a valid value. + + + + + No set number was specified. + + + + + No controller was specified. + + + + + An invalid event generator was specified. + + + + + No event generator string was specified. + + + + + Qt style flag was detected but no style was specified. + + + + + No log level specified. + + + + + + + + antimicro version + + + + + + Usage: antimicro [options...] [profile] + + + + + + Options + + + + + + Print help text. + + + + + + Print version information. + + + + + + Launch program in system tray only. + + + + + + Launch program with the tray menu disabled. + + + + + + Launch program without the main window + displayed. + + + + + + Launch program with the configuration file + selected as the default for selected + controllers. Defaults to all controllers. + + + + + + Apply configuration file to a specific + controller. Value can be a + controller index, name, or GUID. + + + + + + Unload currently enabled profile(s). + Value can be a controller index, name, or GUID. + + + + + + Start joysticks on a specific set. + Value can be a controller index, name, or GUID. + + + + + + Advance profile loading set options. + + + + + + Launch program as a daemon. + + + + + + Enable logging. + + + + + + Use specified display for X11 calls. + Useful for ssh. + + + + + + Choose between using XTest support and uinput + support for event generation. Default: xtest. + + + + + + Choose between using SendInput and vmulti + support for event generation. Default: sendinput. + + + + + + Print information about joysticks detected by + SDL. + + + + + + Open game controller mapping window of selected + controller. Value can be a controller index or + GUID. + + + + + DPadContextMenu + + + Mouse (Normal) + + + + + Mouse (Inverted Horizontal) + + + + + Mouse (Inverted Vertical) + + + + + Mouse (Inverted Horizontal + Vertical) + + + + + Arrows + + + + + Keys: W | A | S | D + + + + + NumPad + + + + + None + + + + + Standard + + + + + Eight Way + + + + + 4 Way Cardinal + + + + + 4 Way Diagonal + + + + + Mouse Settings + + + + + DPadEditDialog + + + Dialog + + + + + Presets: + + + + + Mouse (Normal) + + + + + Mouse (Inverted Horizontal) + + + + + Mouse (Inverted Vertical) + + + + + Mouse (Inverted Horizontal + Vertical) + + + + + Arrows + + + + + Keys: W | A | S | D + + + + + NumPad + + + + + None + + + + + Dpad Mode: + + + + + &Name: + + + + + 4 Way Cardinal + + + + + 4 Way Diagonal + + + + + DPad Delay: + + + + + + Time lapsed before a direction change is taken into effect. + + + + + s + + + + + Specify the name of a dpad. + + + + + Mouse Settings + + + + + Standard + + + + + Standard: 8 region dpad with two direction buttons active +when the dpad is in a diagonal region. + +Eight Way: 8 region dpad with each direction having its +own dedicated button. Only one button is ever active at +at time. Useful for rougelike games. + +4 Way Cardinal: 4 region dpad with regions corresponding to +the cardinal directions of the dpad. Useful for menus. + +4 Way Diagonal: 4 region dpad with each region corresponding +to a diagonal zone. + + + + + Eight Way + + + + + Set + + + + + Set %1 + + + + + EditAllDefaultAutoProfileDialog + + + Default Profile + + + + + Profile: + + + + + Browse + + + + + Open Config + + + + + Profile file path is invalid. + + + + + ExtraProfileSettingsDialog + + + Extra Profile Settings + + + + + Key Press Time: + + + + + 0.00 ms + + + + + Profile Name: + + + + + + + s + + + + + GameController + + + Game Controller + + + + + GameControllerDPad + + + + + DPad + + + + + GameControllerMappingDialog + + + Game Controller Mapping + + + + + <html><head/><body><p>antimicro makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicro will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> + + + + + A + + + + + B + + + + + X + + + + + Y + + + + + Back + + + + + Start + + + + + Guide + + + + + Left Shoulder + + + + + Right Shoulder + + + + + Left Stick Click + + + + + Right Stick Click + + + + + Left Stick X + + + + + Left Stick Y + + + + + Right Stick X + + + + + Right Stick Y + + + + + Left Trigger + + + + + Right Trigger + + + + + DPad Up + + + + + DPad Left + + + + + DPad Down + + + + + DPad Right + + + + + Mapping + + + + + SDL 2 Game Controller Mapping String + + + + + Last Axis Event: + + + + + Current Axis Detection Dead Zone: + + + + + 5000 + + + + + 10000 + + + + + 15000 + + + + + 20000 + + + + + 25000 + + + + + 30000 + + + + + 32000 + + + + + Game Controller Mapping (%1) (#%2) + + + + + Discard Controller Mapping? + + + + + Discard mapping for this controller? + +If discarded, the controller will be reverted to a joystick once you refresh all joysticks. + + + + + GameControllerSet + + + Back + + + + + Guide + + + + + Start + + + + + LS Click + + + + + RS Click + + + + + L Shoulder + + + + + R Shoulder + + + + + L Trigger + + + + + R Trigger + + + + + GameControllerTrigger + + + + + Trigger + + + + + JoyAxis + + + + + Axis + + + + + JoyAxisButton + + + Negative + + + + + Positive + + + + + Unknown + + + + + + + Button + + + + + JoyAxisContextMenu + + + Mouse (Horizontal) + + + + + Mouse (Inverted Horizontal) + + + + + Mouse (Vertical) + + + + + Mouse (Inverted Vertical) + + + + + Arrows: Up | Down + + + + + Arrows: Left | Right + + + + + Keys: W | S + + + + + Keys: A | D + + + + + NumPad: KP_8 | KP_2 + + + + + NumPad: KP_4 | KP_6 + + + + + + None + + + + + + Mouse Settings + + + + + Left Mouse Button + + + + + Right Mouse Button + + + + + JoyButton + + + Processing turbo for #%1 - %2 + + + + + Finishing turbo for button #%1 - %2 + + + + + Processing press for button #%1 - %2 + + + + + Processing release for button #%1 - %2 + + + + + Distance change for button #%1 - %2 + + + + + + + Button + + + + + + + + [NO KEY] + + + + + [Set %1 1W] + + + + + [Set %1 2W] + + + + + [Set %1 WH] + + + + + JoyButtonContextMenu + + + Toggle + + + + + Turbo + + + + + Clear + + + + + Set Select + + + + + Disabled + + + + + Set %1 + + + + + Set %1 1W + + + + + Set %1 2W + + + + + Set %1 WH + + + + + JoyButtonSlot + + + + Mouse + + + + + Up + + + + + Down + + + + + Left + + + + + Right + + + + + LB + + + + + MB + + + + + RB + + + + + B4 + + + + + B5 + + + + + Pause + + + + + Hold + + + + + Cycle + + + + + Distance + + + + + Release + + + + + Mouse Mod + + + + + Press Time + + + + + Delay + + + + + Load %1 + + + + + Set Change %1 + + + + + [Text] %1 + + + + + [Exec] %1 + + + + + [NO KEY] + + + + + JoyControlStick + + + + + Stick + + + + + JoyControlStickButton + + + + + Up + + + + + + + Down + + + + + + + Left + + + + + + + Right + + + + + + + Button + + + + + JoyControlStickContextMenu + + + Mouse (Normal) + + + + + Mouse (Inverted Horizontal) + + + + + Mouse (Inverted Vertical) + + + + + Mouse (Inverted Horizontal + Vertical) + + + + + Arrows + + + + + Keys: W | A | S | D + + + + + NumPad + + + + + None + + + + + Standard + + + + + Eight Way + + + + + 4 Way Cardinal + + + + + 4 Way Diagonal + + + + + Mouse Settings + + + + + JoyControlStickEditDialog + + + Dialog + + + + + X: + + + + + + + + + 0 + + + + + Y: + + + + + Distance: + + + + + Presets: + + + + + Mouse (Normal) + + + + + Mouse (Inverted Horizontal) + + + + + Mouse (Inverted Vertical) + + + + + Mouse (Inverted Horizontal + Vertical) + + + + + Arrows + + + + + Keys: W | A | S | D + + + + + NumPad + + + + + None + + + + + Stick Mode: + + + + + Standard: 8 region stick with two direction buttons active +when the stick is in a diagonal region. + +Eight Way: 8 region stick with each direction having its +own dedicated button. Only one button is ever active at +at time. Useful for rougelike games. + +4 Way Cardinal: 4 region stick with regions corresponding to +the cardinal directions of the stick. Useful for menus. + +4 Way Diagonal: 4 region stick with each region corresponding +to a diagonal zone of the stick. + + + + + 4 Way Cardinal + + + + + 4 Way Diagonal + + + + + + Dead zone value to use for an analog stick. + + + + + + Value when an analog stick is considered moved 100%. + + + + + + The area (in degrees) that each diagonal region occupies. + + + + + Square Stick: + + + + + + Percentage to modify a square stick coordinates to confine values to a circle + + + + + % + + + + + Stick Delay: + + + + + + Time lapsed before a direction change is taken into effect. + + + + + s + + + + + Modifier: + + + + + Edit button that is active while the stick is active. + +This button is useful for assigning zones with +modifier keys that can be used to assign walk/run +functionality to an analog stick. + + + + + PushButton + + + + + Name: + + + + + Specify the name of an analog stick. + + + + + Mouse Settings + + + + + Standard + + + + + Bearing: + + + + + % Safe Zone: + + + + + Eight Way + + + + + Dead Zone: + + + + + Max Zone: + + + + + Diagonal Range: + + + + + Set + + + + + Set %1 + + + + + JoyControlStickModifierButton + + + + + Modifier + + + + + JoyDPad + + + + + DPad + + + + + JoyDPadButton + + + + + Up + + + + + + + Down + + + + + + + Left + + + + + + + Right + + + + + + + Button + + + + + JoyTabWidget + + + + + + + + <New> + + + + + + Remove + + + + + + Remove configuration from recent list. + + + + + + Load + + + + + + Load configuration file. + + + + + + Save + + + + + + Save changes to configuration file. + + + + + + Save As + + + + + + Save changes to a new configuration file. + + + + + + Sets + + + + + Copy from Set + + + + + Settings + + + + + + Set 1 + + + + + + Set 2 + + + + + + Set 3 + + + + + + Set 4 + + + + + + Set 5 + + + + + + Set 6 + + + + + + Set 7 + + + + + + Set 8 + + + + + + Stick/Pad Assign + + + + + + Controller Mapping + + + + + + Quick Set + + + + + + Names + + + + + + Toggle button name displaying. + + + + + + Pref + + + + + + Change global profile settings. + + + + + + + Reset + + + + + + Revert changes to the configuration. Reload configuration file. + + + + + Open Config + + + + + Config Files (*.amgp *.xml) + + + + + + + Config File (*.%1.amgp) + + + + + + Save Profile Changes? + + + + + + Changes to the new profile have not been saved. Would you like to save or discard the current profile? + + + + + + Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? + + + + + Sticks + + + + + + DPads + + + + + No buttons have been assigned. Please use Quick Set to assign keys +to buttons or disable hiding empty buttons. + + + + + + Set %1: %2 + + + + + + Set %1 + + + + + Copy Set Assignments + + + + + Are you sure you want to copy the assignments and device properties from %1? + + + + + + + Save Config + + + + + + Set + + + + + Joystick + + + Joystick + + + + + JoystickStatusWindow + + + Properties + + + + + Details + + + + + Name: + + + + + + + + + + + %1 + + + + + Number: + + + + + Axes: + + + + + Buttons: + + + + + Hats: + + + + + GUID: + + + + + Game Controller: + + + + + Axes + + + + + Buttons + + + + + Hats + + + + + %1 (#%2) Properties + + + + + Axis %1 + + + + + Hat %1 + + + + + No + + + + + Yes + + + + + MainSettingsDialog + + + Edit Settings + + + + + General + + + + + Controller Mappings + + + + + Language + + + + + Auto Profile + + + + + Mouse + + + + + <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> + + + + + Recent Profile Count: + + + + + <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> + + + + + Gamepad Poll Rate: + + + + + Change the poll rate that the program uses to discover new +events from gamepads. Defaults to 10 ms. + +Reducing the poll rate value could cause the application to +use more CPU power so please test the setting that you use +before using antimicro unattended. + + + + + Hide main window when the main window close button is +clicked instead of quitting the program. + + + + + Close To Tray + + + + + Have Windows start antimicro at system startup. + + + + + Launch At Windows Startup + + + + + Display recent profiles for all controllers +as a single list in the tray menu. Defaults +to using sub-menus. + + + + + Single Profile List in Tray + + + + + Have the program minimize to the taskbar. +By default, the program minimizes to the system +tray if available. + + + + + Minimize to Taskbar + + + + + This option will cause the program to hide all +buttons that have no slots assigned to them. +The Quick Set dialog window will have to be used +to bring up the edit dialog for gamepad buttons. + + + + + Hide Empty Buttons + + + + + When the program is launched, open the last +known profile that was opened during the +previous session. + + + + + Auto Load Last Opened Profile + + + + + Only show the system tray icon when the program +first launches. + + + + + Launch in Tray + + + + + Associate .amgp files with antimicro in Windows Explorer. + + + + + Associate Profiles + + + + + Key Repeat + + + + + Active keys will be repeatedly pressed when this +option is enabled. + + + + + + Enable + + + + + Specifies how much time should elapse before key repeating +begins. + + + + + Specifies how many times key presses will be performed +per seconds. + + + + + <html><head/><body><p>antimicro has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make antimicro load a different translation depending on the language that you choose from the list below.</p></body></html> + + + + + French + + + + + Japanese + + + + + Russian + + + + + Serbian + + + + + Simplified Chinese + + + + + Ukrainian + + + + + Class + + + + + Title + + + + + Program + + + + + Disable the "Enhanced Pointer Precision" Windows setting +while antimicro is running. Disabling "Enhanced Pointer Precision" +will allow mouse movement within antimicro to be more +precise. + + + + + Disable Enhance Pointer Precision + + + + + Smoothing + + + + + Histor&y Size: + + + + + Weight &Modifier: + + + + + Refresh Rate: + + + + + The refresh rate is the amount of time that will elapse +in between mouse events. Please be cautious when +editing this setting as it will cause the program to use +more CPU power. Setting this value too low can cause +system instability. Please test the setting before using +it unattended. + + + + + Spring + + + + + Screen: + + + + + Utilize the specified screen for spring mode. On Linux, the +default is to use the primary screen. On Windows, the default +is to use all available screens. + + + + + Accel Numerator: + + + + + + + 0 + + + + + Accel Denominator: + + + + + Accel Threshold: + + + + + If the acceleration values for the virtual mouse have been +changed by a different process, particularly when quitting +an older game, then you might want to reset the acceleration +values used by the virtual mouse. + + + + + Reset Acceleration + + + + + Delay: + + + + + Profi&le Directory: + + + + + ms + + + + + Rate: + + + + + times/s + + + + + Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. + +Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. + + + + + GUID + + + + + Mapping String + + + + + Disable? + + + + + + Delete + + + + + Insert + + + + + + Default + + + + + Brazilian Portuguese + + + + + English + + + + + German + + + + + + Active + + + + + Devices: + + + + + + All + + + + + Device + + + + + Profile + + + + + Default? + + + + + Add + + + + + Edit + + + + + Also, Windows users who want to use a low value should also check the +"Disable Enhance Pointer Precision" checkbox if you haven't disabled +the option in Windows. + + + + + Select Default Profile Directory + + + + + Are you sure you want to delete the profile? + + + + + MainWindow + + + antimicro + + + + + No Joysticks have been found. + Please plug in a joystick and then choose the "Update Joysticks" option in the main menu + + + + + If events are not seen by a game, please click here to run this application as the Adminstrator. + + + + + &App + + + + + &Options + + + + + &Help + + + + + + &Quit + + + + + Ctrl+Q + + + + + + &Update Joysticks + + + + + Ctrl+U + + + + + + &Hide + + + + + Ctrl+H + + + + + &About + + + + + Ctrl+A + + + + + About Qt + + + + + Properties + + + + + Key Checker + + + + + Home Page + + + + + GitHub Page + + + + + Game Controller Mapping + + + + + Settings + + + + + Stick/Pad Assign + + + + + Wiki + + + + + Could not find a proper controller identifier. Exiting. + + + + + + + + + + + (%1) + + + + + + Open File + + + + + &Restore + + + + + Run as Administrator? + + + + + Are you sure that you want to run this program as Adminstrator? + +Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. + + + + + Failed to elevate program + + + + + Failed to restart this program as the Administrator + + + + + Could not find controller. Exiting. + + + + + MouseAxisSettingsDialog + + + Mouse Settings - + + + + + Set %1 + + + + + MouseButtonSettingsDialog + + + Mouse Settings - + + + + + Set %1 + + + + + MouseControlStickSettingsDialog + + + Mouse Settings + + + + + Set %1 + + + + + MouseDPadSettingsDialog + + + Mouse Settings + + + + + Set %1 + + + + + MouseSettingsDialog + + + Mouse Settings + + + + + Mouse Mode: + + + + + Cursor mode is used to move the mouse cursor +around the screen relative to its current position +depending on how much you move an axis +or if a button is pressed. + +Spring mode is used to move the mouse cursor +from the center of the screen depending on how +much you move an axis. The mouse cursor will +be returned to the center of the screen when the +axis is moved back to the dead zone. + + + + + Cursor + + + + + Spring + + + + + Acceleration: + + + + + Enhanced Precision + + + + + + Linear + + + + + Quadratic + + + + + Cubic + + + + + Quadratic Extreme + + + + + Power Function + + + + + Easing Quadratic + + + + + Easing Cubic + + + + + Mouse Speed Settings + + + + + Enable to change the horizontal and vertical speed +boxes at the same time. + + + + + Change Together + + + + + Horizontal +Speed: + + + + + + 1 = 20 pps + + + + + Vertical +Speed: + + + + + Wheel Hori. +Speed: + + + + + Set the speed used for horizontal mouse wheel movement +according to number of simulated notches per second. + + + + + Set the speed used for vertical mouse wheel movement +according to number of simulated notches per second. + + + + + For Power Function acceleration curve. Specifies +the factor to use for curve sensitivity. When the value +is above 1.0, the mouse movement will be accelerated +faster at the low end of an axis. + + + + + Easing Duration: + + + + + + s + + + + + Extra Acceleration + + + + + Multiplier: + + + + + Highest value to accelerate mouse movement by + + + + + x + + + + + Start %: + + + + + Acceleration begins at this percentage of the base multiplier + + + + + Min +Threshold: + + + + + Minimum amount of axis travel required for acceleration to begin + + + + + Max +Threshold: + + + + + Maximum axis travel before acceleration has reached the multiplier value + + + + + Curve: + + + + + Ease Out Sine + + + + + Ease Out Quad + + + + + Ease Out Cubic + + + + + Release Radius: + + + + + Specifies that the spring area will be relative to the +mouse position set by a non-relative spring. + + + + + Relative + + + + + Mouse Status + + + + + X: + + + + + + 0 (0 pps) + + + + + Y: + + + + + + 1 = 1 notch(es)/s + + + + + Enhanced: Three tier curve that makes the mouse move +slow on the low end of an axis and fast on the high end. + +Linear: Mouse moves proportionally to axis. + +Quadratic: Mouse accelerates slowly on low end. + +Cubic: Mouse accelerates slower than Quadratic. + +Quadratic Extreme: Raises mouse speed 1.5 times once +95% axis travel has been reached. + +Power Function: Allows for a more custom curve option. + +Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. + +Easing Cubic: Axis high end is gradually accelerated over +a period of time using a Cubic curve. + + + + + Wheel Vert. +Speed: + + + + + Sensitivity: + + + + + Specifies the amount of time (in seconds) that will +be required before the mouse is fully accelerated +after reaching the high end of an axis. + + + + + Options for adding extra acceleration to the mouse +movement beyond what the acceleration curve would +produce. This is meant to help work around some of +the issues of the very limited input range available using +typical gamepad analog sticks. + + + + + + + + % + + + + + Extra Duration: + + + + + Extend the time that extra acceleration is applied. Axis travel +will be taken into account. A slower flick will decrease the +actual time that extra acceleration will be applied. + + + + + Spring Settings + + + + + Spring Width: + + + + + Changes the width of the region that the cursor +can move in spring mode. 0 will use the entire width +of your screen. + + + + + Spring Height: + + + + + Changes the height of the region that the cursor +can move in spring mode. 0 will use the entire height +of your screen. + + + + + + %n notch(es)/s + + %n notch/s + %n notches/s + + + + + QKeyDisplayDialog + + + Key Checker + + + + + <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by antimicro.</p><p>The antimicro key value and the Qt key value will usually be the same. antimicro tries to use the key values defined in Qt when possible. Check the page <a href="http://qt-project.org/doc/qt-4.8/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://qt-project.org/doc/qt-4.8/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to antimicro's <a href="https://github.com/Ryochan7/antimicro"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> + + + + + Event Handler: + + + + + Native Key Value: + + + + + + + 0x00000000 + + + + + Qt Key Value: + + + + + antimicro Key Value: + + + + + QObject + + + Super + + + + + Menu + + + + + Mute + + + + + Vol+ + + + + + Vol- + + + + + Play/Pause + + + + + Play + + + + + Pause + + + + + Prev + + + + + Next + + + + + Mail + + + + + Home + + + + + Media + + + + + Search + + + + + Daemon launched + + + + + Failed to launch daemon + + + + + Launching daemon + + + + + + Display string "%1" is not valid. + + + + + Failed to set a signature id for the daemon + + + + + Failed to change working directory to / + + + + + Quitting Program + + + + + # of joysticks found: %1 + + + + + List Joysticks: + + + + + --------------- + + + + + Joystick %1: + + + + + Index: %1 + + + + + GUID: %1 + + + + + Name: %1 + + + + + Yes + + + + + No + + + + + Game Controller: %1 + + + + + # of Axes: %1 + + + + + # of Buttons: %1 + + + + + # of Hats: %1 + + + + + Attempting to use fallback option %1 for event generation. + + + + + Failed to open event generator. Exiting. + + + + + Using %1 as the event generator. + + + + + Could not raise process priority. + + + + + QuickSetDialog + + + Quick Set + + + + + <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> + + + + + Quick Set %1 + + + + + SetAxisThrottleDialog + + + Throttle Change + + + + + The throttle setting for Axis %1 has been changed. + +Would you like to distribute this throttle change to all sets? + + + + + SetJoystick + + + Set %1: %2 + + + + + Set %1 + + + + + SetNamesDialog + + + Set Name Settings + + + + + Set 1 + + + + + Set 2 + + + + + Set 3 + + + + + Set 4 + + + + + Set 5 + + + + + Set 6 + + + + + Set 7 + + + + + Set 8 + + + + + Name + + + + + SimpleKeyGrabberButton + + + Mouse + + + + + SpringModeRegionPreview + + + Spring Mode Preview + + + + + UInputEventHandler + + + Could not find a valid uinput device file. +Please check that you have the uinput module loaded. +lsmod | grep uinput + + + + + Could not open uinput device file +Please check that you have permission to write to the device + + + + + Using uinput device file %1 + + + + + UInputHelper + + + a + + + + + b + + + + + c + + + + + d + + + + + e + + + + + f + + + + + g + + + + + h + + + + + i + + + + + j + + + + + k + + + + + l + + + + + m + + + + + n + + + + + o + + + + + p + + + + + q + + + + + r + + + + + s + + + + + t + + + + + u + + + + + v + + + + + w + + + + + x + + + + + y + + + + + z + + + + + Esc + + + + + F1 + + + + + F2 + + + + + F3 + + + + + F4 + + + + + F5 + + + + + F6 + + + + + F7 + + + + + F8 + + + + + F9 + + + + + F10 + + + + + F11 + + + + + F12 + + + + + ` + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + 9 + + + + + 0 + + + + + + - + + + + + = + + + + + BackSpace + + + + + Tab + + + + + [ + + + + + ] + + + + + \ + + + + + CapsLock + + + + + ; + + + + + ' + + + + + Enter + + + + + Shift_L + + + + + , + + + + + + . + + + + + + / + + + + + Ctrl_L + + + + + + Super_L + + + + + Alt_L + + + + + Space + + + + + Alt_R + + + + + Menu + + + + + Ctrl_R + + + + + Shift_R + + + + + Up + + + + + Left + + + + + Down + + + + + Right + + + + + PrtSc + + + + + Ins + + + + + Del + + + + + Home + + + + + End + + + + + PgUp + + + + + PgDn + + + + + NumLock + + + + + * + + + + + + + + + + + KP_Enter + + + + + KP_1 + + + + + KP_2 + + + + + KP_3 + + + + + KP_4 + + + + + KP_5 + + + + + KP_6 + + + + + KP_7 + + + + + KP_8 + + + + + KP_9 + + + + + KP_0 + + + + + SCLK + + + + + Pause + + + + + Super_R + + + + + Mute + + + + + VolDn + + + + + VolUp + + + + + Play + + + + + Stop + + + + + Prev + + + + + Next + + + + + [NO KEY] + + + + + UnixWindowInfoDialog + + + Captured Window Properties + + + + + Information About Window + + + + + Class: + + + + + + + TextLabel + + + + + Title: + + + + + Path: + + + + + Match By Properties + + + + + Class + + + + + Title + + + + + Path + + + + + VDPad + + + + + VDPad + + + + + VirtualKeyPushButton + + + Space + + + + + Tab + + + + + Shift (L) + + + + + Shift (R) + + + + + Ctrl (L) + + + + + Ctrl (R) + + + + + Alt (L) + + + + + + Alt (R) + + + + + ` + + + + + ~ + + + + + + - + + + + + = + + + + + [ + + + + + ] + + + + + \ + + + + + Caps + + + + + ; + + + + + ' + + + + + , + + + + + + . + + + + + + / + + + + + ESC + + + + + PRTSC + + + + + SCLK + + + + + INS + + + + + PGUP + + + + + DEL + + + + + PGDN + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + 9 + + + + + 0 + + + + + NUM +LK + + + + + + * + + + + + + + + + + + E +N +T +E +R + + + + + < + + + + + : + + + + + Super (L) + + + + + Menu + + + + + Up + + + + + Down + + + + + Left + + + + + Right + + + + + VirtualKeyboardMouseWidget + + + + Keyboard + + + + + + Mouse + + + + + Mouse Settings + + + + + Left + Mouse + + + + + Up + Mouse + + + + + Left Button + Mouse + + + + + Middle Button + Mouse + + + + + Right Button + Mouse + + + + + Wheel Up + Mouse + + + + + Wheel Left + Mouse + + + + + Wheel Right + Mouse + + + + + Wheel Down + Mouse + + + + + Down + Mouse + + + + + Right + Mouse + + + + + Button 4 + Mouse + + + + + Mouse 8 + Mouse + + + + + Button 5 + Mouse + + + + + Mouse 9 + Mouse + + + + + NONE + + + + + Applications + + + + + Browser Back + + + + + Browser Favorites + + + + + Browser Forward + + + + + Browser Home + + + + + Browser Refresh + + + + + Browser Search + + + + + Browser Stop + + + + + Calc + + + + + Email + + + + + Media + + + + + Media Next + + + + + Media Play + + + + + Media Previous + + + + + Media Stop + + + + + Search + + + + + Volume Down + + + + + Volume Mute + + + + + Volume Up + + + + + VirtualMousePushButton + + + INVALID + + + + + WinAppProfileTimerDialog + + + + Capture Application + + + + + After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. + + + + + Timer: + + + + + Seconds + + + + + Cancel + + + + + WinExtras + + + [NO KEY] + + + + + AntiMicro Profile + + + + + X11Extras + + + ESC + + + + + Tab + + + + + Space + + + + + DEL + + + + + Return + + + + + KP_Enter + + + + + Backspace + + + + + xinput extension was not found. No mouse acceleration changes will occur. + + + + + + xinput version must be at least 2.0. No mouse acceleration changes will occur. + + + + + Virtual pointer found with id=%1. + + + + + PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 + + + + + Changing mouse acceleration for device with id=%1 + + + + + XMLConfigReader + + + Could not write updated profile XML to file %1. + + + + + XMLConfigWriter + + + Could not write to profile at %1. + + + + diff --git a/share/antimicro/translations/antimicro_br.ts b/share/antimicro/translations/antimicro_br.ts new file mode 100644 index 0000000..31eeb79 --- /dev/null +++ b/share/antimicro/translations/antimicro_br.ts @@ -0,0 +1,5881 @@ + + + + + AboutDialog + + + About + Sobre + + + + Version + Versão + + + + Info + + + + + Changelog + + + + + Since December 30, 2012, I have been working on antimicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. + +The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. + +Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. + +Once the Steam controller is finally released to the public, the need for this program might not exist anymore. Just based on the concept of the controller alone, the Steam controller would have so many advantages over using a program like this to provide KB+M emulation. + + + + + Copyright: 2013 - 2015 + + + + + Credits + Créditos + + + + antimicro + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Travis Nickles &lt;nickles.travis@gmail.com&gt;</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Contributors:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;"><br /></span>Zerro Alvein</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">aybe</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Jeff Backus &lt;jeff.backus@gmail.com&gt;</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Arthur Moore<br />Anton Tornqvist &lt;antont@inbox.lv&gt;</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Translators:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt; font-weight:600;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">zzpxyx - Chinese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">phob - German</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tou omiya - Japanese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">burunduk - Ukrainian</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Version 3, 29 June 2007</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Preamble</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">TERMS AND CONDITIONS</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">0. Definitions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">1. Source Code.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">2. Basic Permissions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">4. Conveying Verbatim Copies.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">5. Conveying Modified Source Versions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">6. Conveying Non-Source Forms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">7. Additional Terms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">8. Termination.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">11. Patents.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">14. Revised Versions of this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">15. Disclaimer of Warranty.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">16. Limitation of Liability.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> + + + + + About Development + + + + + License + Licença + + + + Program Version %1 + + + + + Program Compiled on %1 at %2 + + + + + Built Against SDL %1 + + + + + Running With SDL %1 + + + + + Using Qt %1 + + + + + Using Event Handler: %1 + + + + + AddEditAutoProfileDialog + + + Auto Profile Dialog + + + + + Profile: + + + + + + Browse + + + + + Window: + + + + + + Select Window. Click on the appropriate application +window and the application file path will be populated +in the form. + + + + + Detect Window Properties + + + + + Class: + + + + + Title: + + + + + Application: + + + + + Select + + + + + Devices: + + + + + + Select this profile to be the default loaded for +the specified device. The selection will be used instead +of the all default profile option. + + + + + Set as Default for Controller + + + + + + A different profile is already selected as the default for this device. + + + + + Current (%1) + + + + + Open Config + Abrir Configuração + + + + + Select Program + + + + + Programs (*.exe) + + + + + Please use the main default profile selection. + + + + + Please select a window by using the mouse. Press Escape if you want to cancel. + + + + + Capture Application Window + + + + + Could not obtain information for the selected window. + + + + + Application Capture Failed + + + + + Profile file path is invalid. + + + + + No window matching property was specified. + + + + + Program path is invalid or not executable. + + + + + File is not an .exe file. + + + + + No window matching property was selected. + + + + + AdvanceButtonDialog + + + + Advanced + Avançado + + + + Assignments + Atribuições + + + + Toggle + Alternar + + + + Turbo + Turbo + + + + Set Selector + Definir Seletor + + + + Blank or KB/M + + + + + Hold + Segurar + + + + Pause + Pausar + + + + Cycle + Ciclo + + + + Distance + Distância + + + + Insert + Inserir + + + + Delete + Deletar + + + + Clear All + Limpar tudo + + + + Time: + Tempo: + + + + 0.01s + + + + + 0s + + + + + Insert a pause that occurs in between key presses. + Inserir uma pausa que ocorre entre teclas pressionadas. + + + + Release + Liberar + + + + + Insert a new blank slot. + Inserir um novo slot vazio. + + + + Delete a slot. + Deletar um slot. + + + + Clear all currently assigned slots. + Limpar todos os slots atribuido atualmente. + + + + Specify the duration of an inserted Pause or Hold slot. + Especificar a duração de uma pausa inserida ou manter o slot. + + + + 0m + 0m + + + + + Specify the range past an axis dead zone in which a sequence of actions will execute. + Especifique o intervalo passado em uma zona morta, no eixo em que uma seqüência de ações será executado. + + + + Distance: + Distância: + + + + + % + + + + + Mouse Mod + + + + + Press Time + + + + + Delay + + + + + Execute + + + + + Load + Carregar + + + + Set Change + + + + + Text Entry + + + + + Placeholder + Espaço Reservado + + + + + 0 + 0 + + + + Mouse Speed Mod: + + + + + Set the percentage that mouse speeds will be modified by. + + + + + Auto Reset Cycle After + + + + + seconds + + + + + ... + + + + + + + Enabled + Habilitar + + + + Mode: + + + + + <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> + + + + + Normal + Normal + + + + Gradient + + + + + Pulse + + + + + Delay: + Atrasar: + + + + 0.10s + + + + + Rate: + Taxa: + + + + 10.0/s + + + + + + Disabled + Inválido + + + + Select Set 1 One Way + Selecionar e definir uma maneira + + + + Select Set 1 Two Way + Selecionar e definir duas maneiras + + + + Select Set 1 While Held + Selecionar e Definir um Enquanto Realiza + + + + Select Set 2 One Way + Selecionar e definir 2 uma maneira + + + + Select Set 2 Two Way + Selecionar e definir 2 duas maneiras + + + + Select Set 2 While Held + Selecionar e Definir 2 Enquanto Realiza + + + + Select Set 3 One Way + Selecionar e definir 3 uma maneira + + + + Select Set 3 Two Way + Selecionar e definir 3 duas maneiras + + + + Select Set 3 While Held + Selecionar e definir 3 Enquanto Realiza + + + + Select Set 4 One Way + Selecionar e definir 4 uma maneira + + + + Select Set 4 Two Way + Selecionar e definir 4 duas maneiras + + + + Select Set 4 While Held + Selecionar e definir 4 enquanto realiza + + + + Select Set 5 One Way + Selecionar e definir 5 uma maneiras + + + + Select Set 5 Two Way + Selecionar e definir 5 duas maneiras + + + + Select Set 5 While Held + Selecionar e definir 5 enquanto realiza + + + + Select Set 6 One Way + Selecionar e definir 6 uma maneiras + + + + Select Set 6 Two Way + Selecionar e definir 6 duas maneiras + + + + Select Set 6 While Held + Selecionar e definir 6 enquanto realiza + + + + Select Set 7 One Way + Selecionar e definir 7 uma maneiras + + + + Select Set 7 Two Way + Selecionar e definir 7 duas maneiras + + + + Select Set 7 While Held + Selecionar e definir 7 enquanto realiza + + + + Select Set 8 One Way + Selecionar e definir 8 uma maneiras + + + + Select Set 8 Two Way + Selecionar e definir 8 duas maneiras + + + + Select Set 8 While Held + Selecionar e definir 8 enquanto realiza + + + + sec. + + + + + /sec. + + + + + Set %1 + + + + + + Select Set %1 + + + + + One Way + + + + + Two Way + + + + + While Held + + + + + Choose Executable + + + + + Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. + + + + + Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. + + + + + Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. + + + + + Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. + + + + + Chose a profile to load when this slot is activated. + + + + + Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. + + + + + Specify the time that keys past this slot should be held down. + + + + + Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. + + + + + Change to selected set once slot is activated. + + + + + Full string will be typed when a slot is activated. + + + + + Execute program when slot is activated. + + + + + + Choose Profile + + + + + Config Files (*.amgp *.xml) + + + + + AdvanceStickAssignmentDialog + + + Stick/Pad Assignment + Atribuir Stick/Pad + + + + Sticks + Analógicos + + + + DPads + Direcionais + + + + + %1 (Joystick %2) + + + + + Stick 1 + Analógico 1 + + + + + + Enabled + Habilitado + + + + + + + + + Assign + + + + + + X Axis: + Eixo X: + + + + + Y Axis: + Aixo Y: + + + + Stick 2 + Analógico 2 + + + + Number of Physical DPads: %1 + Número de Dpads físico:%1 + + + + Virtual DPad 1 + DPad 1 Virtual + + + + Up: + Cima: + + + + Down: + Baixo: + + + + Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. + + + + + Left: + Esquerda: + + + + Right: + Direita: + + + + + + + Axis %1 + Eixo %1 + + + + + + + Axis %1 - + Eixo %1- + + + + + + + Axis %1 + + Eixo %1+ + + + + + + + Button %1 + Botão %1 + + + + Move stick 1 along the X axis + + + + + Move stick 1 along the Y axis + + + + + Move stick 2 along the X axis + + + + + Move stick 2 along the Y axis + + + + + + + + Press a button or move an axis + + + + + AxisEditDialog + + + Axis + Eixo + + + + + Mouse (Horizontal) + Mouse (Horizontal) + + + + + Mouse (Inverted Horizontal) + Mouse (Horizontal Invertido) + + + + + Mouse (Vertical) + Mouse (Vertical) + + + + + Mouse (Inverted Vertical) + Mouse (Vertical Invertido) + + + + + Arrows: Up | Down + Setas: Cima | Baixo + + + + + Arrows: Left | Right + Setas: Esquerda | Direita + + + + + Keys: W | S + Teclas: W | S + + + + + Keys: A | D + Teclas: A | D + + + + + NumPad: KP_8 | KP_2 + Pad Numérico: KP_8 | KP_2 + + + + + NumPad: KP_4 | KP_6 + Pad Numérico: KP_4 | KP_6 + + + + + + None + Nada + + + + + Set the value to use as the limit for an axis. Useful for a +worn out analog stick. + + + + + Negative Half Throttle + + + + + Positive Half Throttle + + + + + Name: + + + + + Specify the name of an axis. + + + + + Mouse Settings + Configurações do Mouse + + + + + Set the value of the dead zone for an axis. + Defina o valor da zona morta para um eixo. + + + + Presets: + Predefinido: + + + + Dead Zone: + Zona Morta: + + + + Max Zone: + Zona Máxima: + + + + + [NO KEY] + [SEM TECLA] + + + + Throttle setting that determines the behavior of how to +interpret an axis hold or release. + Posição do acelerador, que determina o comportamento de como +interpretar um eixo ou liberação. + + + + Negative Throttle + Acelerador Negativo + + + + Normal + Normal + + + + Positive Throttle + Aceleração Positiva + + + + Current Value: + Valor Atual: + + + + Set + Definir + + + + Set %1 + + + + + Left Mouse Button + + + + + Right Mouse Button + + + + + ButtonEditDialog + + + Dialog + Diálogo + + + + To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab + Para fazer uma nova atribuição, pressionar qualquer tecla do teclado ou clicar em um botão na guia do teclado ou mouse + + + + Placeholder + Espaço Reservado + + + + Toggle + Alternar + + + + Enables a key press or release to only occur when a controller button is pressed. + Permite um pressionamento ou a liberação para ocorrer apenas quando um botão é pressionado no controlador. + + + + Enables rapid key presses and releases. Turbo controller. + Permite o rápido pressionamento de teclas e lançamentos. Turbo controlador. + + + + Turbo + Turbo + + + + Current: + Atual: + + + + Slots + Slot + + + + Na&me: + + + + + Specify the name of a button. + + + + + Action: + + + + + Specify the action that will be performed in game while +this button is being used. + + + + + Advanced + Avançado + + + + Set + Definir + + + + Set %1 + + + + + CapturedWindowInfoDialog + + + Captured Window Properties + + + + + Information About Window + + + + + Class: + + + + + + + TextLabel + + + + + Title: + + + + + Path: + + + + + Match By Properties + + + + + Class + + + + + Title + + + + + Path + + + + + Full Path + + + + + File Name + + + + + CommandLineUtility + + + + Profile location %1 is not an XML file. + A localização do perfil %1 não é um arquivo XML. + + + + + Profile location %1 does not exist. + A localização do perfil %1 não existe. + + + + An invalid set number '%1' was specified. + + + + + Controller identifier '%s'' is not a valid value. + + + + + No display string was specified. + + + + + + + Controller identifier is not a valid value. + + + + + No set number was specified. + + + + + No controller was specified. + + + + + An invalid event generator was specified. + + + + + No event generator string was specified. + + + + + Qt style flag was detected but no style was specified. + + + + + No log level specified. + + + + + + + + antimicro version + + + + + + Usage: antimicro [options...] [profile] + + + + + + Options + Opções + + + + + Print help text. + Imprimir texto de ajuda. + + + + + Print version information. + Imprimir informações da versão. + + + + + Launch program in system tray only. + Lançar programa na bandeja do sistema. + + + + + Launch program with the tray menu disabled. + Lançar programa com o menu da bandeja desativado. + + + + + Launch program without the main window + displayed. + + + + + + Launch program with the configuration file + selected as the default for selected + controllers. Defaults to all controllers. + + + + + + Apply configuration file to a specific + controller. Value can be a + controller index, name, or GUID. + + + + + + Unload currently enabled profile(s). + Value can be a controller index, name, or GUID. + + + + + + Start joysticks on a specific set. + Value can be a controller index, name, or GUID. + + + + + + Advance profile loading set options. + + + + + + Launch program as a daemon. + + + + + + Enable logging. + + + + + + Use specified display for X11 calls. + Useful for ssh. + + + + + + Choose between using XTest support and uinput + support for event generation. Default: xtest. + + + + + + Choose between using SendInput and vmulti + support for event generation. Default: sendinput. + + + + + + Print information about joysticks detected by + SDL. + + + + + + Open game controller mapping window of selected + controller. Value can be a controller index or + GUID. + + + + + DPadContextMenu + + + Mouse (Normal) + Mouse (Normal) + + + + Mouse (Inverted Horizontal) + Mouse (Horizontal Invertido) + + + + Mouse (Inverted Vertical) + + + + + Mouse (Inverted Horizontal + Vertical) + Mouse (Horizontal + Vertical Invertido) + + + + Arrows + Setas + + + + Keys: W | A | S | D + Teclas: W | A | S | D + + + + NumPad + Pad Numérico + + + + None + Nada + + + + Standard + Padrão + + + + Eight Way + Oito Maneiras + + + + 4 Way Cardinal + + + + + 4 Way Diagonal + + + + + Mouse Settings + + + + + DPadEditDialog + + + Dialog + Diálogo + + + + Presets: + Predefinido: + + + + Mouse (Normal) + Mouse (Normal) + + + + Mouse (Inverted Horizontal) + Mouse (Horizontal Invertido) + + + + Mouse (Inverted Vertical) + Mouse (Vertical Invertido) + + + + Mouse (Inverted Horizontal + Vertical) + Mouse (Horizontal + Vertical Invertido) + + + + Arrows + Setas + + + + Keys: W | A | S | D + Teclas: W | A | S | D + + + + NumPad + Pad Numérico + + + + None + Nada + + + + Dpad Mode: + Modo Pad: + + + + &Name: + + + + + 4 Way Cardinal + + + + + 4 Way Diagonal + + + + + DPad Delay: + + + + + + Time lapsed before a direction change is taken into effect. + + + + + s + + + + + Specify the name of a dpad. + + + + + Mouse Settings + Configuração do Mouse + + + + Standard + Padrão + + + + Standard: 8 region dpad with two direction buttons active +when the dpad is in a diagonal region. + +Eight Way: 8 region dpad with each direction having its +own dedicated button. Only one button is ever active at +at time. Useful for rougelike games. + +4 Way Cardinal: 4 region dpad with regions corresponding to +the cardinal directions of the dpad. Useful for menus. + +4 Way Diagonal: 4 region dpad with each region corresponding +to a diagonal zone. + + + + + Eight Way + Oito Maneiras + + + + Set + Definir + + + + Set %1 + + + + + EditAllDefaultAutoProfileDialog + + + Default Profile + + + + + Profile: + + + + + Browse + + + + + Open Config + Abrir Configuração + + + + Profile file path is invalid. + + + + + ExtraProfileSettingsDialog + + + Extra Profile Settings + + + + + Key Press Time: + + + + + 0.00 ms + + + + + Profile Name: + + + + + + + s + s + + + + GameController + + + Game Controller + + + + + GameControllerDPad + + + + + DPad + Direcional + + + + GameControllerMappingDialog + + + Game Controller Mapping + + + + + <html><head/><body><p>antimicro makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicro will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> + + + + + A + + + + + B + + + + + X + + + + + Y + + + + + Back + + + + + Start + + + + + Guide + + + + + Left Shoulder + + + + + Right Shoulder + + + + + Left Stick Click + + + + + Right Stick Click + + + + + Left Stick X + + + + + Left Stick Y + + + + + Right Stick X + + + + + Right Stick Y + + + + + Left Trigger + + + + + Right Trigger + + + + + DPad Up + + + + + DPad Left + + + + + DPad Down + + + + + DPad Right + + + + + Mapping + + + + + SDL 2 Game Controller Mapping String + + + + + Last Axis Event: + + + + + Current Axis Detection Dead Zone: + + + + + 5000 + 5000 + + + + 10000 + 10000 + + + + 15000 + 15000 + + + + 20000 + 20000 + + + + 25000 + 25000 + + + + 30000 + 30000 + + + + 32000 + 32000 + + + + Game Controller Mapping (%1) (#%2) + + + + + Discard Controller Mapping? + + + + + Discard mapping for this controller? + +If discarded, the controller will be reverted to a joystick once you refresh all joysticks. + + + + + GameControllerSet + + + Back + + + + + Guide + + + + + Start + + + + + LS Click + + + + + RS Click + + + + + L Shoulder + + + + + R Shoulder + + + + + L Trigger + + + + + R Trigger + + + + + GameControllerTrigger + + + + + Trigger + + + + + JoyAxis + + + + + Axis + Eixo + + + + JoyAxisButton + + + Negative + Negativo + + + + Positive + Positivo + + + + Unknown + Desconhecido + + + + + + Button + Botão + + + + JoyAxisContextMenu + + + Mouse (Horizontal) + Mouse (Horizontal) + + + + Mouse (Inverted Horizontal) + Mouse (Horizontal Invertido) + + + + Mouse (Vertical) + Mouse (Vertical) + + + + Mouse (Inverted Vertical) + + + + + Arrows: Up | Down + Setas: Cima | Baixo + + + + Arrows: Left | Right + Setas: Esquerda | Direita + + + + Keys: W | S + Teclas: W | S + + + + Keys: A | D + Teclas: A | D + + + + NumPad: KP_8 | KP_2 + Pad Numérico: KP_8 | KP_2 + + + + NumPad: KP_4 | KP_6 + Pad Numérico: KP_4 | KP_6 + + + + + None + Nada + + + + + Mouse Settings + + + + + Left Mouse Button + + + + + Right Mouse Button + + + + + JoyButton + + + Processing turbo for #%1 - %2 + + + + + Finishing turbo for button #%1 - %2 + + + + + Processing press for button #%1 - %2 + + + + + Processing release for button #%1 - %2 + + + + + Distance change for button #%1 - %2 + + + + + + + Button + Botão + + + + + + + [NO KEY] + [SEM TECLA] + + + + [Set %1 1W] + + + + + [Set %1 2W] + + + + + [Set %1 WH] + + + + + JoyButtonContextMenu + + + Toggle + Alternar + + + + Turbo + Turbo + + + + Clear + + + + + Set Select + + + + + Disabled + Inválido + + + + Set %1 + + + + + Set %1 1W + + + + + Set %1 2W + + + + + Set %1 WH + + + + + JoyButtonSlot + + + + Mouse + Mover + + + + Up + Cima + + + + Down + Baixo + + + + Left + Esquerda + + + + Right + Direita + + + + LB + LB + + + + MB + MB + + + + RB + RB + + + + B4 + + + + + B5 + + + + + Pause + Pausar + + + + Hold + Segurar + + + + Cycle + Ciclo + + + + Distance + Distância + + + + Release + Soltar + + + + Mouse Mod + + + + + Press Time + + + + + Delay + + + + + Load %1 + + + + + Set Change %1 + + + + + [Text] %1 + + + + + [Exec] %1 + + + + + [NO KEY] + [SEM TECLA] + + + + JoyControlStick + + + + + Stick + Analógico + + + + JoyControlStickButton + + + + + Up + Cima + + + + + + Down + Baixo + + + + + + Left + Esquerda + + + + + + Right + Direita + + + + + + Button + Botão + + + + JoyControlStickContextMenu + + + Mouse (Normal) + Mouse (Normal) + + + + Mouse (Inverted Horizontal) + Mouse (Horizontal Invertido) + + + + Mouse (Inverted Vertical) + + + + + Mouse (Inverted Horizontal + Vertical) + Mouse (Horizontal + Vertical Invertido) + + + + Arrows + Setas + + + + Keys: W | A | S | D + Teclas: W | A | S | D + + + + NumPad + Pad Numérico + + + + None + Nada + + + + Standard + Padrão + + + + Eight Way + Oito Maneiras + + + + 4 Way Cardinal + + + + + 4 Way Diagonal + + + + + Mouse Settings + + + + + JoyControlStickEditDialog + + + Dialog + Diálogo + + + + X: + X: + + + + + + + + 0 + 0 + + + + Y: + Y: + + + + Distance: + Distância: + + + + Presets: + Predefinido: + + + + Mouse (Normal) + Mouse (Normal) + + + + Mouse (Inverted Horizontal) + Mouse (Horizontal Invertido) + + + + Mouse (Inverted Vertical) + Mouse (Vertical invertido) + + + + Mouse (Inverted Horizontal + Vertical) + Mouse (Horizontal + Vertical Invertido) + + + + Arrows + Setas + + + + Keys: W | A | S | D + Teclas: W | A | S | D + + + + NumPad + Pad Numérico + + + + None + Nada + + + + Stick Mode: + Modo Analógico: + + + + Standard: 8 region stick with two direction buttons active +when the stick is in a diagonal region. + +Eight Way: 8 region stick with each direction having its +own dedicated button. Only one button is ever active at +at time. Useful for rougelike games. + +4 Way Cardinal: 4 region stick with regions corresponding to +the cardinal directions of the stick. Useful for menus. + +4 Way Diagonal: 4 region stick with each region corresponding +to a diagonal zone of the stick. + + + + + 4 Way Cardinal + + + + + 4 Way Diagonal + + + + + + Dead zone value to use for an analog stick. + + + + + + Value when an analog stick is considered moved 100%. + + + + + + The area (in degrees) that each diagonal region occupies. + + + + + Square Stick: + + + + + + Percentage to modify a square stick coordinates to confine values to a circle + + + + + % + + + + + Stick Delay: + + + + + + Time lapsed before a direction change is taken into effect. + + + + + s + + + + + Modifier: + + + + + Edit button that is active while the stick is active. + +This button is useful for assigning zones with +modifier keys that can be used to assign walk/run +functionality to an analog stick. + + + + + PushButton + + + + + Name: + + + + + Specify the name of an analog stick. + + + + + Mouse Settings + Configurações do Mouse + + + + Standard + Padrão + + + + Bearing: + + + + + % Safe Zone: + + + + + Eight Way + Oito Maneiras + + + + Dead Zone: + Zona da Morte: + + + + Max Zone: + Zona Máxima: + + + + Diagonal Range: + Alcance Diagonal: + + + + Set + Definir + + + + Set %1 + + + + + JoyControlStickModifierButton + + + + + Modifier + + + + + JoyDPad + + + + + DPad + Direcional + + + + JoyDPadButton + + + + + Up + Cima + + + + + + Down + Baixo + + + + + + Left + Esquerda + + + + + + Right + Direita + + + + + + Button + Botão + + + + JoyTabWidget + + + + + + + + <New> + Novo + + + + + Remove + + + + + + Remove configuration from recent list. + + + + + + Load + Carregar + + + + + Load configuration file. + + + + + + Save + Salvar + + + + + Save changes to configuration file. + + + + + + Save As + Salvar Como + + + + + Save changes to a new configuration file. + + + + + + Sets + + + + + Copy from Set + + + + + Settings + + + + + + Set 1 + + + + + + Set 2 + + + + + + Set 3 + + + + + + Set 4 + + + + + + Set 5 + + + + + + Set 6 + + + + + + Set 7 + + + + + + Set 8 + + + + + + Stick/Pad Assign + Atribuir Analógico/Direcional + + + + + Controller Mapping + + + + + + Quick Set + Definir Rápido + + + + + Names + + + + + + Toggle button name displaying. + + + + + + Pref + + + + + + Change global profile settings. + + + + + + + Reset + Resetar + + + + + Revert changes to the configuration. Reload configuration file. + + + + + Open Config + Abrir Configuração + + + + Config Files (*.amgp *.xml) + + + + + + + Config File (*.%1.amgp) + + + + + + Save Profile Changes? + + + + + + Changes to the new profile have not been saved. Would you like to save or discard the current profile? + + + + + + Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? + + + + + Sticks + Analógicos + + + + + DPads + Direcionais + + + + No buttons have been assigned. Please use Quick Set to assign keys +to buttons or disable hiding empty buttons. + + + + + + Set %1: %2 + + + + + + Set %1 + + + + + Copy Set Assignments + + + + + Are you sure you want to copy the assignments and device properties from %1? + + + + + + + Save Config + Salvar Configuração + + + + + Set + Definir + + + + Joystick + + + Joystick + Analógico + + + + JoystickStatusWindow + + + Properties + + + + + Details + + + + + Name: + + + + + + + + + + + %1 + + + + + Number: + + + + + Axes: + + + + + Buttons: + + + + + Hats: + + + + + GUID: + + + + + Game Controller: + + + + + Axes + + + + + Buttons + + + + + Hats + + + + + %1 (#%2) Properties + + + + + Axis %1 + Eixo %1 + + + + Hat %1 + + + + + No + + + + + Yes + + + + + MainSettingsDialog + + + Edit Settings + + + + + General + + + + + Controller Mappings + + + + + Language + + + + + Auto Profile + + + + + Mouse + + + + + <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> + + + + + Recent Profile Count: + + + + + <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> + + + + + Gamepad Poll Rate: + + + + + Change the poll rate that the program uses to discover new +events from gamepads. Defaults to 10 ms. + +Reducing the poll rate value could cause the application to +use more CPU power so please test the setting that you use +before using antimicro unattended. + + + + + Hide main window when the main window close button is +clicked instead of quitting the program. + + + + + Close To Tray + + + + + Have Windows start antimicro at system startup. + + + + + Launch At Windows Startup + + + + + Display recent profiles for all controllers +as a single list in the tray menu. Defaults +to using sub-menus. + + + + + Single Profile List in Tray + + + + + Have the program minimize to the taskbar. +By default, the program minimizes to the system +tray if available. + + + + + Minimize to Taskbar + + + + + This option will cause the program to hide all +buttons that have no slots assigned to them. +The Quick Set dialog window will have to be used +to bring up the edit dialog for gamepad buttons. + + + + + Hide Empty Buttons + + + + + When the program is launched, open the last +known profile that was opened during the +previous session. + + + + + Auto Load Last Opened Profile + + + + + Only show the system tray icon when the program +first launches. + + + + + Launch in Tray + + + + + Associate .amgp files with antimicro in Windows Explorer. + + + + + Associate Profiles + + + + + Key Repeat + + + + + Active keys will be repeatedly pressed when this +option is enabled. + + + + + + Enable + + + + + Specifies how much time should elapse before key repeating +begins. + + + + + Specifies how many times key presses will be performed +per seconds. + + + + + <html><head/><body><p>antimicro has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make antimicro load a different translation depending on the language that you choose from the list below.</p></body></html> + + + + + French + + + + + Japanese + + + + + Russian + + + + + Serbian + + + + + Simplified Chinese + + + + + Ukrainian + + + + + Class + + + + + Title + + + + + Program + + + + + Disable the "Enhanced Pointer Precision" Windows setting +while antimicro is running. Disabling "Enhanced Pointer Precision" +will allow mouse movement within antimicro to be more +precise. + + + + + Disable Enhance Pointer Precision + + + + + Smoothing + + + + + Histor&y Size: + + + + + Weight &Modifier: + + + + + Refresh Rate: + + + + + The refresh rate is the amount of time that will elapse +in between mouse events. Please be cautious when +editing this setting as it will cause the program to use +more CPU power. Setting this value too low can cause +system instability. Please test the setting before using +it unattended. + + + + + Spring + Pular + + + + Screen: + + + + + Utilize the specified screen for spring mode. On Linux, the +default is to use the primary screen. On Windows, the default +is to use all available screens. + + + + + Accel Numerator: + + + + + + + 0 + 0 + + + + Accel Denominator: + + + + + Accel Threshold: + + + + + If the acceleration values for the virtual mouse have been +changed by a different process, particularly when quitting +an older game, then you might want to reset the acceleration +values used by the virtual mouse. + + + + + Reset Acceleration + + + + + Delay: + Atrasar: + + + + Profi&le Directory: + + + + + ms + + + + + Rate: + Taxa: + + + + times/s + + + + + Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. + +Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. + + + + + GUID + + + + + Mapping String + + + + + Disable? + + + + + + Delete + Deletar + + + + Insert + Inserir + + + + + Default + + + + + Brazilian Portuguese + + + + + English + + + + + German + + + + + + Active + + + + + Devices: + + + + + + All + + + + + Device + + + + + Profile + + + + + Default? + + + + + Add + + + + + Edit + + + + + Also, Windows users who want to use a low value should also check the +"Disable Enhance Pointer Precision" checkbox if you haven't disabled +the option in Windows. + + + + + Select Default Profile Directory + + + + + Are you sure you want to delete the profile? + + + + + MainWindow + + + No Joysticks have been found. + Please plug in a joystick and then choose the "Update Joysticks" option in the main menu + Nenhum joystick foi encontrados. Por favor, conecte um joystick e, em seguida, escolha a opção "Atualizar Joysticks" no menu principal + + + + &App + + + + + Stick/Pad Assign + Atribuir Analógico/Dpad + + + + &Options + &Opções + + + + antimicro + + + + + If events are not seen by a game, please click here to run this application as the Adminstrator. + + + + + &Help + &Ajuda + + + + + &Quit + &Sair + + + + Ctrl+Q + Ctrl+Q + + + + + &Update Joysticks + &Atualizar joysticks + + + + Ctrl+U + Ctrl+U + + + + + &Hide + &Esconder + + + + Ctrl+H + Ctrl+H + + + + &About + &Sobre + + + + Ctrl+A + Ctrl+A + + + + About Qt + Sobre Qt + + + + Properties + + + + + Key Checker + + + + + Home Page + + + + + GitHub Page + + + + + Game Controller Mapping + + + + + Settings + + + + + Wiki + + + + + Could not find a proper controller identifier. Exiting. + + + + + + + + + + + (%1) + + + + + + Open File + Abrir Arquivo + + + + &Restore + &Restaurar + + + + Run as Administrator? + + + + + Are you sure that you want to run this program as Adminstrator? + +Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. + + + + + Failed to elevate program + + + + + Failed to restart this program as the Administrator + + + + + Could not find controller. Exiting. + + + + + MouseAxisSettingsDialog + + + Mouse Settings - + Configuração do Mouse + + + + Set %1 + + + + + MouseButtonSettingsDialog + + + Mouse Settings - + Configuração do Mouse + + + + Set %1 + + + + + MouseControlStickSettingsDialog + + + Mouse Settings + + + + + Set %1 + + + + + MouseDPadSettingsDialog + + + Mouse Settings + + + + + Set %1 + + + + + MouseSettingsDialog + + + Mouse Settings + Configuração do Mouse + + + + Mouse Mode: + Modo do Mouse: + + + + Cursor mode is used to move the mouse cursor +around the screen relative to its current position +depending on how much you move an axis +or if a button is pressed. + +Spring mode is used to move the mouse cursor +from the center of the screen depending on how +much you move an axis. The mouse cursor will +be returned to the center of the screen when the +axis is moved back to the dead zone. + + + + + Cursor + Cursor + + + + Spring + Pular + + + + Acceleration: + Aceleração: + + + + Enhanced Precision + + + + + + Linear + Linear + + + + Quadratic + Quadrático + + + + Cubic + Cúbico + + + + Quadratic Extreme + Extremo Quadrático + + + + Power Function + Função Pwer + + + + Easing Quadratic + + + + + Easing Cubic + + + + + Mouse Speed Settings + Configuração da velocidade do Mouse + + + + Enable to change the horizontal and vertical speed +boxes at the same time. + + + + + Change Together + Alterar Junto + + + + Horizontal +Speed: + Velocidade Horizontal: + + + + + 1 = 20 pps + 1 = 20 pps + + + + Vertical +Speed: + Velocidade Vertical: + + + + Wheel Hori. +Speed: + + + + + Set the speed used for horizontal mouse wheel movement +according to number of simulated notches per second. + + + + + Set the speed used for vertical mouse wheel movement +according to number of simulated notches per second. + + + + + For Power Function acceleration curve. Specifies +the factor to use for curve sensitivity. When the value +is above 1.0, the mouse movement will be accelerated +faster at the low end of an axis. + + + + + Easing Duration: + + + + + + s + + + + + Extra Acceleration + + + + + Multiplier: + + + + + Highest value to accelerate mouse movement by + + + + + x + x + + + + Start %: + + + + + Acceleration begins at this percentage of the base multiplier + + + + + Min +Threshold: + + + + + Minimum amount of axis travel required for acceleration to begin + + + + + Max +Threshold: + + + + + Maximum axis travel before acceleration has reached the multiplier value + + + + + Curve: + + + + + Ease Out Sine + + + + + Ease Out Quad + + + + + Ease Out Cubic + + + + + Release Radius: + + + + + Specifies that the spring area will be relative to the +mouse position set by a non-relative spring. + + + + + Relative + + + + + Mouse Status + + + + + X: + X: + + + + + 0 (0 pps) + + + + + Y: + Y: + + + + + 1 = 1 notch(es)/s + + + + + Enhanced: Three tier curve that makes the mouse move +slow on the low end of an axis and fast on the high end. + +Linear: Mouse moves proportionally to axis. + +Quadratic: Mouse accelerates slowly on low end. + +Cubic: Mouse accelerates slower than Quadratic. + +Quadratic Extreme: Raises mouse speed 1.5 times once +95% axis travel has been reached. + +Power Function: Allows for a more custom curve option. + +Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. + +Easing Cubic: Axis high end is gradually accelerated over +a period of time using a Cubic curve. + + + + + Wheel Vert. +Speed: + + + + + Sensitivity: + Sensibilidade: + + + + Specifies the amount of time (in seconds) that will +be required before the mouse is fully accelerated +after reaching the high end of an axis. + + + + + Options for adding extra acceleration to the mouse +movement beyond what the acceleration curve would +produce. This is meant to help work around some of +the issues of the very limited input range available using +typical gamepad analog sticks. + + + + + + + + % + + + + + Extra Duration: + + + + + Extend the time that extra acceleration is applied. Axis travel +will be taken into account. A slower flick will decrease the +actual time that extra acceleration will be applied. + + + + + Spring Settings + Configuração do Pulo + + + + Spring Width: + Pulo de Largura: + + + + Changes the width of the region that the cursor +can move in spring mode. 0 will use the entire width +of your screen. + + + + + Spring Height: + Pulo de Altura: + + + + Changes the height of the region that the cursor +can move in spring mode. 0 will use the entire height +of your screen. + + + + + + %n notch(es)/s + + + + + + + + QKeyDisplayDialog + + + Key Checker + + + + + <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by antimicro.</p><p>The antimicro key value and the Qt key value will usually be the same. antimicro tries to use the key values defined in Qt when possible. Check the page <a href="http://qt-project.org/doc/qt-4.8/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://qt-project.org/doc/qt-4.8/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to antimicro's <a href="https://github.com/Ryochan7/antimicro"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> + + + + + Event Handler: + + + + + Native Key Value: + + + + + + + 0x00000000 + + + + + Qt Key Value: + + + + + antimicro Key Value: + + + + + QObject + + + Super + + + + + Menu + Menu + + + + Mute + + + + + Vol+ + + + + + Vol- + + + + + Play/Pause + + + + + Play + + + + + Pause + Pausar + + + + Prev + + + + + Next + Next + + + + Mail + + + + + Home + Home + + + + Media + + + + + Search + + + + + Daemon launched + + + + + Failed to launch daemon + + + + + Launching daemon + + + + + + Display string "%1" is not valid. + + + + + Failed to set a signature id for the daemon + + + + + Failed to change working directory to / + + + + + Quitting Program + + + + + # of joysticks found: %1 + + + + + List Joysticks: + + + + + --------------- + + + + + Joystick %1: + + + + + Index: %1 + + + + + GUID: %1 + + + + + Name: %1 + + + + + Yes + + + + + No + + + + + Game Controller: %1 + + + + + # of Axes: %1 + + + + + # of Buttons: %1 + + + + + # of Hats: %1 + + + + + Attempting to use fallback option %1 for event generation. + + + + + Failed to open event generator. Exiting. + + + + + Using %1 as the event generator. + + + + + Could not raise process priority. + + + + + QuickSetDialog + + + Quick Set + Definir rápido + + + + <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> + + + + + Quick Set %1 + + + + + SetAxisThrottleDialog + + + Throttle Change + Suprimir Rápido + + + + The throttle setting for Axis %1 has been changed. + +Would you like to distribute this throttle change to all sets? + A configuração do acelerador para o eixo %1 foi alterada. Gostaria de distribuir essa mudança de aceleração para todos os conjuntos? + + + + SetJoystick + + + Set %1: %2 + + + + + Set %1 + + + + + SetNamesDialog + + + Set Name Settings + + + + + Set 1 + + + + + Set 2 + + + + + Set 3 + + + + + Set 4 + + + + + Set 5 + + + + + Set 6 + + + + + Set 7 + + + + + Set 8 + + + + + Name + + + + + SimpleKeyGrabberButton + + + Mouse + Mouse + + + + SpringModeRegionPreview + + + Spring Mode Preview + + + + + UInputEventHandler + + + Could not find a valid uinput device file. +Please check that you have the uinput module loaded. +lsmod | grep uinput + + + + + Could not open uinput device file +Please check that you have permission to write to the device + + + + + Using uinput device file %1 + + + + + UInputHelper + + + a + a + + + + b + b + + + + c + c + + + + d + d + + + + e + e + + + + f + f + + + + g + g + + + + h + h + + + + i + i + + + + j + j + + + + k + k + + + + l + l + + + + m + m + + + + n + n + + + + o + o + + + + p + p + + + + q + q + + + + r + r + + + + s + s + + + + t + t + + + + u + u + + + + v + v + + + + w + w + + + + x + x + + + + y + y + + + + z + z + + + + Esc + + + + + F1 + F1 + + + + F2 + F2 + + + + F3 + F3 + + + + F4 + F4 + + + + F5 + F5 + + + + F6 + F6 + + + + F7 + F7 + + + + F8 + F8 + + + + F9 + F9 + + + + F10 + F10 + + + + F11 + F11 + + + + F12 + F12 + + + + ` + ` + + + + 1 + 1 + + + + 2 + 2 + + + + 3 + 3 + + + + 4 + 4 + + + + 5 + 5 + + + + 6 + 6 + + + + 7 + 7 + + + + 8 + 8 + + + + 9 + 9 + + + + 0 + 0 + + + + + - + - + + + + = + = + + + + BackSpace + BackSpace + + + + Tab + Tab + + + + [ + [ + + + + ] + ] + + + + \ + \ + + + + CapsLock + + + + + ; + ; + + + + ' + ' + + + + Enter + + + + + Shift_L + Shift_L + + + + , + , + + + + + . + . + + + + + / + / + + + + Ctrl_L + + + + + + Super_L + Super_L + + + + Alt_L + Alt_L + + + + Space + Espaço + + + + Alt_R + Alt_R + + + + Menu + Menu + + + + Ctrl_R + + + + + Shift_R + Shift_R + + + + Up + Cima + + + + Left + Esquerda + + + + Down + Baixo + + + + Right + Direita + + + + PrtSc + + + + + Ins + + + + + Del + + + + + Home + Home + + + + End + End + + + + PgUp + + + + + PgDn + + + + + NumLock + + + + + * + * + + + + + + + + + + + KP_Enter + KP_Enter + + + + KP_1 + KP_1 + + + + KP_2 + KP_2 + + + + KP_3 + KP_3 + + + + KP_4 + KP_4 + + + + KP_5 + KP_5 + + + + KP_6 + KP_6 + + + + KP_7 + KP_7 + + + + KP_8 + KP_8 + + + + KP_9 + KP_9 + + + + KP_0 + KP_0 + + + + SCLK + SCLK + + + + Pause + Pausar + + + + Super_R + + + + + Mute + + + + + VolDn + + + + + VolUp + + + + + Play + + + + + Stop + + + + + Prev + + + + + Next + Next + + + + [NO KEY] + [SEM TECLA] + + + + UnixWindowInfoDialog + + + Captured Window Properties + + + + + Information About Window + + + + + Class: + + + + + + + TextLabel + + + + + Title: + + + + + Path: + + + + + Match By Properties + + + + + Class + + + + + Title + + + + + Path + + + + + VDPad + + + + + VDPad + VDPad + + + + VirtualKeyPushButton + + + Space + Espaço + + + + Tab + Tab + + + + Shift (L) + Shift (L) + + + + Shift (R) + Shift (R) + + + + Ctrl (L) + Ctrl (L) + + + + Ctrl (R) + Ctrl (R) + + + + Alt (L) + Alt (L) + + + + + Alt (R) + Alt (R) + + + + ` + ` + + + + ~ + ~ + + + + + - + - + + + + = + = + + + + [ + [ + + + + ] + ] + + + + \ + \ + + + + Caps + Caps + + + + ; + ; + + + + ' + ' + + + + , + , + + + + + . + . + + + + + / + / + + + + ESC + ESC + + + + PRTSC + PRTSC + + + + SCLK + SCLK + + + + INS + INS + + + + PGUP + PGUP + + + + DEL + DEL + + + + PGDN + PGDN + + + + 1 + 1 + + + + 2 + 2 + + + + 3 + 3 + + + + 4 + 4 + + + + 5 + 5 + + + + 6 + 6 + + + + 7 + 7 + + + + 8 + 8 + + + + 9 + 9 + + + + 0 + 0 + + + + NUM +LK + NUM LK + + + + + * + * + + + + + + + + + + + E +N +T +E +R + E N T E R + + + + < + < + + + + : + : + + + + Super (L) + + + + + Menu + Menu + + + + Up + Cima + + + + Down + Baixo + + + + Left + Esquerda + + + + Right + Direita + + + + VirtualKeyboardMouseWidget + + + + Keyboard + Teclado + + + + + Mouse + Mouse + + + + Mouse Settings + Configurações do Mouse + + + + Left + Mouse + Esquerda + + + + Up + Mouse + Cima + + + + Left Button + Mouse + + + + + Middle Button + Mouse + + + + + Right Button + Mouse + + + + + Wheel Up + Mouse + Roda pra Cima + + + + Wheel Left + Mouse + Roda pra Esquerda + + + + Wheel Right + Mouse + Roda pra Direita + + + + Wheel Down + Mouse + Roda pra Baixo + + + + Down + Mouse + Baixo + + + + Right + Mouse + Direita + + + + Button 4 + Mouse + + + + + Mouse 8 + Mouse + + + + + Button 5 + Mouse + + + + + Mouse 9 + Mouse + + + + + NONE + NADA + + + + Applications + + + + + Browser Back + + + + + Browser Favorites + + + + + Browser Forward + + + + + Browser Home + + + + + Browser Refresh + + + + + Browser Search + + + + + Browser Stop + + + + + Calc + + + + + Email + + + + + Media + + + + + Media Next + + + + + Media Play + + + + + Media Previous + + + + + Media Stop + + + + + Search + + + + + Volume Down + + + + + Volume Mute + + + + + Volume Up + + + + + VirtualMousePushButton + + + INVALID + INVÁLIDO + + + + WinAppProfileTimerDialog + + + + Capture Application + + + + + After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. + + + + + Timer: + + + + + Seconds + + + + + Cancel + + + + + WinExtras + + + [NO KEY] + [SEM TECLA] + + + + AntiMicro Profile + + + + + X11Extras + + + ESC + ESC + + + + Tab + Tab + + + + Space + Espaço + + + + DEL + DEL + + + + Return + + + + + KP_Enter + KP_Enter + + + + Backspace + Retrocesso + + + + xinput extension was not found. No mouse acceleration changes will occur. + + + + + + xinput version must be at least 2.0. No mouse acceleration changes will occur. + + + + + Virtual pointer found with id=%1. + + + + + PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 + + + + + Changing mouse acceleration for device with id=%1 + + + + + XMLConfigReader + + + Could not write updated profile XML to file %1. + + + + + XMLConfigWriter + + + Could not write to profile at %1. + + + + diff --git a/share/antimicro/translations/antimicro_de.ts b/share/antimicro/translations/antimicro_de.ts new file mode 100644 index 0000000..68969f1 --- /dev/null +++ b/share/antimicro/translations/antimicro_de.ts @@ -0,0 +1,5966 @@ + + + + + AboutDialog + + + About + Über + + + + Version + Version + + + + Info + + + + + Changelog + + + + + Since December 30, 2012, I have been working on antimicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. + +The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. + +Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. + +Once the Steam controller is finally released to the public, the need for this program might not exist anymore. Just based on the concept of the controller alone, the Steam controller would have so many advantages over using a program like this to provide KB+M emulation. + + + + + Copyright: 2013 - 2015 + + + + + Credits + Mitwirkende + + + + antimicro + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Travis Nickles &lt;nickles.travis@gmail.com&gt;</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Contributors:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;"><br /></span>Zerro Alvein</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">aybe</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Jeff Backus &lt;jeff.backus@gmail.com&gt;</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Arthur Moore<br />Anton Tornqvist &lt;antont@inbox.lv&gt;</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Translators:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt; font-weight:600;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">zzpxyx - Chinese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">phob - German</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tou omiya - Japanese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">burunduk - Ukrainian</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Version 3, 29 June 2007</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Preamble</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">TERMS AND CONDITIONS</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">0. Definitions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">1. Source Code.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">2. Basic Permissions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">4. Conveying Verbatim Copies.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">5. Conveying Modified Source Versions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">6. Conveying Non-Source Forms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">7. Additional Terms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">8. Termination.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">11. Patents.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">14. Revised Versions of this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">15. Disclaimer of Warranty.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">16. Limitation of Liability.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> + + + + + About Development + Über die Entwicklung + + + + License + Lizenz + + + + Program Version %1 + Programmversion %1 + + + + Program Compiled on %1 at %2 + Programm kompiliert am %1 um %2 + + + + Built Against SDL %1 + Nutzt SDL %1 + + + + Running With SDL %1 + Läuft mit SDL %1 + + + + Using Qt %1 + Benutzt Qt %1 + + + + Using Event Handler: %1 + + + + + AddEditAutoProfileDialog + + + Auto Profile Dialog + Auto-Profil-Dialog + + + + Profile: + Profil: + + + + + Browse + Durchsuchen + + + + Window: + Fenster: + + + + + Select Window. Click on the appropriate application +window and the application file path will be populated +in the form. + Wählen Sie das Fenster. Klicken Sie auf das entsprechende +Anwendungs-Fenster und der Anwendungs-Dateipfad +wird in das Formular eingetragen. + + + + Detect Window Properties + Erkenne Fenstereigenschaften + + + + Class: + Klasse: + + + + Title: + Titel: + + + + Application: + Anwendung: + + + + Select + Wähle + + + + Devices: + Geräte: + + + + + Select this profile to be the default loaded for +the specified device. The selection will be used instead +of the all default profile option. + Wählen Sie dieses Profil als Standard für das jeweilige Gerät. Diese Auswahl wird anstatt jeder anderen Standardeinstellung genutzt. + + + + Set as Default for Controller + Setze als Standardcontroller + + + + + A different profile is already selected as the default for this device. + Ein anderes Profil ist bereits als Standard für dieses Gerät ausgewählt. + + + + Current (%1) + Aktuell (%1) + + + + Open Config + Konfiguration öffnen + + + + + Select Program + Wähle Anwendung + + + + Programs (*.exe) + Programme (*.exe) + + + + Please use the main default profile selection. + Bitte benutzen Sie die Standard-Profilauswahl. + + + + Please select a window by using the mouse. Press Escape if you want to cancel. + Bitte wählen Sie mit der Maus ein Fenster aus. Escape drücken um abzubrechen. + + + + Capture Application Window + Anwendungsfenster auswählen + + + + Could not obtain information for the selected window. + Konnte nicht Information für das ausgewählte Fenster gewinnen. + + + + Application Capture Failed + Anwendungsauswahl fehlgeschlagen + + + + Profile file path is invalid. + Profil-Dateipfad ist ungültig. + + + + No window matching property was specified. + Kein zugehöriges Fenster wurde spezifiziert. + + + + Program path is invalid or not executable. + Programmpfad ist ungültig oder nicht ausführbar. + + + + File is not an .exe file. + Datei ist keine .exe-Datei. + + + + No window matching property was selected. + Kein zugehöriges Fenster wurde ausgewählt. + + + + AdvanceButtonDialog + + + + Advanced + Erweitert + + + + Assignments + Zuweisungen + + + + Toggle + Umschalten + + + + Turbo + Turbo + + + + Set Selector + Wähle Set + + + + Blank or KB/M + Leer oder KB/M + + + + Hold + Halten + + + + Pause + Pause + + + + Cycle + Kreislauf + + + + Distance + Distanz + + + + Insert + Einfügen + + + + Delete + Entfernen + + + + Clear All + Leeren + + + + Time: + Zeit: + + + + 0.01s + 0.01s + + + + 0s + 0s + + + + Insert a pause that occurs in between key presses. + Fügt eine Pause zwischen den Tasten ein. + + + + Release + Freigeben + + + + + Insert a new blank slot. + Fügt eine neue leere Aktion hinzu. + + + + Delete a slot. + Löscht eine Aktion. + + + + Clear all currently assigned slots. + Löscht alle zugewiesenen Aktionen. + + + + Specify the duration of an inserted Pause or Hold slot. + Gibt die Dauer der hinzugefügten Pause- oder Haltenaktion an. + + + + 0m + 0m + + + + + Specify the range past an axis dead zone in which a sequence of actions will execute. + Gibt die Distanz der Achse zur "Dead Zone" an, in der die Sequenz an Aktionen ausgeführt wird. + + + + Distance: + Distanz: + + + + + % + % + + + + Mouse Mod + Maus Mod + + + + Press Time + Druckzeit + + + + Delay + Verzögerung + + + + Execute + + + + + Load + Laden + + + + Set Change + Wähle Änderung + + + + Text Entry + + + + + Placeholder + Platzhalter + + + + + 0 + 0 + + + + Mouse Speed Mod: + Maus Mod Geschwindigkeit: + + + + Set the percentage that mouse speeds will be modified by. + Stellen Sie den Prozentsatz ein um der die Mausgeschwindigkeit modifiziert werden soll. + + + + Auto Reset Cycle After + Zyklus automatisch neustarten nach + + + + seconds + Sekunden + + + + ... + + + + + + + Enabled + Aktiviert + + + + Mode: + Modus: + + + + <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> + <html><head/><body><p>Normal: Wiederholt mit der eingestellten Rate Taste drücken und loslassen.</p><p>Verlaufend: Ändere die Auslösen-/Loslassen-Verzögerung aufgrund wie weit die eine Achse bewegt wurde.</p><p>Pulsierend: Ändere wie häufig eine Taste pro Sekunde ausgelöst wurde. Die Verögerung bleibt gleich.</p></body></html> + + + + Normal + Normal + + + + Gradient + Verlaufend + + + + Pulse + Pulsierend + + + + Delay: + Verzögerung: + + + + 0.10s + 0.10s + + + + Rate: + Rate: + + + + 10.0/s + 10.0/s + + + + + Disabled + Deaktiviert + + + + Select Set 1 One Way + Wähle Set 1: einseitig + + + + Select Set 1 Two Way + Wähle Set 1: wechselseitig + + + + Select Set 1 While Held + Wähle Set 1: festgehalten + + + + Select Set 2 One Way + Wähle Set 2: einseitig + + + + Select Set 2 Two Way + Wähle Set 2: wechselseitig + + + + Select Set 2 While Held + Wähle Set 2: festgehalten + + + + Select Set 3 One Way + Wähle Set 3: einseitig + + + + Select Set 3 Two Way + Wähle Set 3: wechselseitig + + + + Select Set 3 While Held + Wähle Set 3: festgehalten + + + + Select Set 4 One Way + Wähle Set 4: einseitig + + + + Select Set 4 Two Way + Wähle Set 4: wechselseitig + + + + Select Set 4 While Held + Wähle Set 4: festgehalten + + + + Select Set 5 One Way + Wähle Set 5: einseitig + + + + Select Set 5 Two Way + Wähle Set 5: wechselseitig + + + + Select Set 5 While Held + Wähle Set 5: festgehalten + + + + Select Set 6 One Way + Wähle Set 6: einseitig + + + + Select Set 6 Two Way + Wähle Set 6: wechselseitig + + + + Select Set 6 While Held + Wähle Set 6: festgehalten + + + + Select Set 7 One Way + Wähle Set 7: einseitig + + + + Select Set 7 Two Way + Wähle Set 7: wechselseitig + + + + Select Set 7 While Held + Wähle Set 7: festgehalten + + + + Select Set 8 One Way + Wähle Set 8: einseitig + + + + Select Set 8 Two Way + Wähle Set 8: wechselseitig + + + + Select Set 8 While Held + Wähle Set 8: festgehalten + + + + sec. + Sek. + + + + /sec. + /Sek. + + + + Set %1 + Set %1 + + + + + Select Set %1 + Wähle Set %1 + + + + One Way + Einweg + + + + Two Way + Zweiwege + + + + While Held + Solang wie gehalten + + + + Choose Executable + + + + + Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. + + + + + Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. + + + + + Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. + + + + + Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. + + + + + Chose a profile to load when this slot is activated. + Wähle ein Profil zum Laden wenn dieser Slot aktiviert ist. + + + + Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. + + + + + Specify the time that keys past this slot should be held down. + + + + + Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. + + + + + Change to selected set once slot is activated. + Wechsle zu ausgewähltem Set wenn Slot aktiviert ist. + + + + Full string will be typed when a slot is activated. + + + + + Execute program when slot is activated. + + + + + + Choose Profile + Wähle Profil + + + + Config Files (*.amgp *.xml) + Konfigurationsdateien (*.amgp *.xml) + + + + AdvanceStickAssignmentDialog + + + Stick/Pad Assignment + Stick/Pad Zuweisung + + + + Sticks + Sticks + + + + DPads + DPads + + + + + %1 (Joystick %2) + %1 (Joystick %2) + + + + Stick 1 + Stick 1 + + + + + + Enabled + Aktiviert + + + + + + + + + Assign + Zuweisen + + + + + X Axis: + X Achse: + + + + + Y Axis: + Y Achse: + + + + Stick 2 + Stick 2 + + + + Number of Physical DPads: %1 + Nummer der physischen DPads: %1 + + + + Virtual DPad 1 + Virtueller DPad 1 + + + + Up: + Hoch: + + + + Down: + Runter: + + + + Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. + Hinweis: Dieses Fenster ist nur zur Rückwärtskompatibilität zu Profilen für antimicro vor 2.0 gedacht. Seit Version 2.0 wird das Spielecontroller-Zuweisungsfenster bevorzugt. + + + + Left: + Links: + + + + Right: + Rechts: + + + + + + + Axis %1 + Achse %1 + + + + + + + Axis %1 - + Achse %1 - + + + + + + + Axis %1 + + Achse %1 + + + + + + + + Button %1 + Button %1 + + + + Move stick 1 along the X axis + Bewege Stick 1 entlang der X Achse + + + + Move stick 1 along the Y axis + Bewege Stick 1 entlang der Y Achse + + + + Move stick 2 along the X axis + Bewege Stick 2 entlang der X Achse + + + + Move stick 2 along the Y axis + Bewege Stick 2 entlang der Y Achse + + + + + + + Press a button or move an axis + Drücke einen Button oder bewege eine Achse + + + + AxisEditDialog + + + Axis + Achse + + + + + Mouse (Horizontal) + Maus (Horizontal) + + + + + Mouse (Inverted Horizontal) + Maus (Invertiert Horizontal) + + + + + Mouse (Vertical) + Maus (Vertikal) + + + + + Mouse (Inverted Vertical) + Maus (Invertiert Vertikal) + + + + + Arrows: Up | Down + Pfeiltasten: Hoch | Runter + + + + + Arrows: Left | Right + Pfeiltasten: Links | Rechts + + + + + Keys: W | S + Tasten: W | S + + + + + Keys: A | D + Tasten: A | D + + + + + NumPad: KP_8 | KP_2 + Nummernblock: KP_8 | KP_2 + + + + + NumPad: KP_4 | KP_6 + Nummernblock: KP_4 | KP_6 + + + + + + None + Nichts + + + + + Set the value to use as the limit for an axis. Useful for a +worn out analog stick. + Setze einen Wert als Limitierung einer Achse. Nützlich +bei abgenutzten Analogsticks. + + + + Negative Half Throttle + Negative Halbbeschleunigung + + + + Positive Half Throttle + Positive Halbbeschleunigung + + + + Name: + Name: + + + + Specify the name of an axis. + Vergebe den Namen der Achse. + + + + Mouse Settings + Mauseinstellungen + + + + + Set the value of the dead zone for an axis. + Bestimmt den Wert der Dead Zone einer Achse. + + + + Presets: + Vorgaben: + + + + Dead Zone: + Dead Zone: + + + + Max Zone: + Max Zone: + + + + + [NO KEY] + [KEINE TASTE] + + + + Throttle setting that determines the behavior of how to +interpret an axis hold or release. + Beschleunigung gibt das Verhalten an wie das Halten +oder Loslassen einer Achse interpretiert wird. + + + + Negative Throttle + Negative Beschleunigung + + + + Normal + Normal + + + + Positive Throttle + Positive Beschleunigung + + + + Current Value: + Aktueller Wert: + + + + Set + Set + + + + Set %1 + Set %1 + + + + Left Mouse Button + Linke Maustaste + + + + Right Mouse Button + Rechte Maustaste + + + + ButtonEditDialog + + + Dialog + Dialog + + + + To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab + Um eine neue Zuweisung zu machen, drück eine Taste oder klick einen Button im Tastatur oder Mausreiter + + + + Placeholder + Platzhalter + + + + Toggle + Umschalten + + + + Enables a key press or release to only occur when a controller button is pressed. + Tasten werden erst, wenn der Button gedrückt wurde entweder festgehalten oder frei gelassen. + + + + Enables rapid key presses and releases. Turbo controller. + Aktiviert schnelles Tastendrücken oder Freigeben. Autofeuer. + + + + Turbo + Turbo + + + + Current: + Aktuell: + + + + Slots + Slots + + + + Na&me: + + + + + Specify the name of a button. + Vergebe den Namen des Buttons. + + + + Action: + Aktion: + + + + Specify the action that will be performed in game while +this button is being used. + Gibt die Aktion des Buttons an, die Ingame genutzt wird. + + + + Advanced + Advanced + + + + Set + Set + + + + Set %1 + Set %1 + + + + CapturedWindowInfoDialog + + + Captured Window Properties + Erkannte Fenstereigenschaften + + + + Information About Window + Fensterinformationen + + + + Class: + Klasse: + + + + + + TextLabel + + + + + Title: + Titel: + + + + Path: + Pfad: + + + + Match By Properties + + + + + Class + Klasse + + + + Title + Titel + + + + Path + Pfad + + + + Full Path + vollständiger Pfad + + + + File Name + Dateinmae + + + + CommandLineUtility + + + + Profile location %1 is not an XML file. + Profilort %1 ist keine XML Datei. + + + + + Profile location %1 does not exist. + Profilort %1 existiert nicht. + + + + An invalid set number '%1' was specified. + + + + + Controller identifier '%s'' is not a valid value. + + + + + No display string was specified. + + + + + + + Controller identifier is not a valid value. + Controllernummer ist keine gültige Ziffer. + + + + No set number was specified. + Kein Set gewählt. + + + + No controller was specified. + Kein Controller wurde spezifiert. + + + + An invalid event generator was specified. + Ein ungültiger Ereignisgenerator wurde angegeben. + + + + No event generator string was specified. + Kein Ereignesgenerator String wurde angegeben. + + + + Qt style flag was detected but no style was specified. + Qt style Parameter erkannt, aber kein Style spezifiziert. + + + + No log level specified. + Kein Log-Level angegeben. + + + + + + + antimicro version + antimicro Version + + + + + Usage: antimicro [options...] [profile] + + + + + + Options + Optionen + + + + + Print help text. + diese Hilfe ausgeben. + + + + + Print version information. + Programmversion ausgeben. + + + + + Launch program in system tray only. + Nur im Systemtray starten. + + + + + Launch program with the tray menu disabled. + Starten mit deaktiviertem Systemtray. + + + + + Launch program without the main window + displayed. + Starten mit verstecktem Hauptfenster. + + + + + Launch program with the configuration file + selected as the default for selected + controllers. Defaults to all controllers. + Programm mit ausgewählter Konfigurations- + datei als Standard für alle Controller + starten. + + + + + Apply configuration file to a specific + controller. Value can be a + controller index, name, or GUID. + Übernehme Konfigurationsdatei zu dem + angegebenen Controller. Wert + kann Controllerindex, Name + oder GUID sein. + + + + + Unload currently enabled profile(s). + Value can be a controller index, name, or GUID. + Aktuell aktiviertes Profil entladen. Wert + kann Controllerindex, Name + oder GUID sein. + + + + + Start joysticks on a specific set. + Value can be a controller index, name, or GUID. + Starte Joysticks beim angegebenen Set. Wert + kann Controllerindex, Name + oder GUID sein. + + + + + Advance profile loading set options. + + + + + + Launch program as a daemon. + Starte Programm als Dienst. + + + + + Enable logging. + Aktiviere Logging. + + + + + Use specified display for X11 calls. + Useful for ssh. + Nutze angegebenes Display für X11. + Nützlich für ssh. + + + + + Choose between using XTest support and uinput + support for event generation. Default: xtest. + Wähle zwischen XTest Unterstützung und uinput + Unterstützung zur Ereignisgenerierung. Standard: xtest. + + + + + Choose between using SendInput and vmulti + support for event generation. Default: sendinput. + Wähle zwischen der Nutzung von SendInput und vmulti + support zur Ereignisgenerierung. Standard: sendinput. + + + + + Print information about joysticks detected by + SDL. + Zeige Informationen über Joysticks die + von SDL erkannt wurden. + + + + + Open game controller mapping window of selected + controller. Value can be a controller index or + GUID. + Öffne Gamecontrollerzuweisungs-Fenster für + den ausgewählten Controller. Wert kann ein + Controller Index oder GUID sein. + + + + DPadContextMenu + + + Mouse (Normal) + Maus (Normal) + + + + Mouse (Inverted Horizontal) + Maus (Invertiert Horizontal) + + + + Mouse (Inverted Vertical) + Maus (Invertiert Vertikal) + + + + Mouse (Inverted Horizontal + Vertical) + Maus (Invertiert Horizontal + Vertikal) + + + + Arrows + Pfeiltasten + + + + Keys: W | A | S | D + Tasten: W | A | S | D + + + + NumPad + Nummerntastatur + + + + None + Nichts + + + + Standard + Standard + + + + Eight Way + 8-Weg + + + + 4 Way Cardinal + 4-Wege kardinal + + + + 4 Way Diagonal + 4-Wege diagonal + + + + Mouse Settings + Mauseinstellungen + + + + DPadEditDialog + + + Dialog + Dialog + + + + Presets: + Vorgaben: + + + + Mouse (Normal) + Maus (Normal) + + + + Mouse (Inverted Horizontal) + Maus (Invertiert Horizontal) + + + + Mouse (Inverted Vertical) + Maus (Invertiert Vertikal) + + + + Mouse (Inverted Horizontal + Vertical) + Maus (Invertiert Horizontal + Vertikal) + + + + Arrows + Pfeiltasten + + + + Keys: W | A | S | D + Tasten: W | A | S | D + + + + NumPad + Nummerntastatur + + + + None + Nichts + + + + Dpad Mode: + DPad Modus: + + + + &Name: + + + + + 4 Way Cardinal + 4-Wege kardinal + + + + 4 Way Diagonal + 4-Wege diagonal + + + + DPad Delay: + DPad-Verzögerung: + + + + + Time lapsed before a direction change is taken into effect. + Zeit abgelaufen bevor eine Richtungsänderung vollzogen wird. + + + + s + + + + + Specify the name of a dpad. + Vergebe den Namen des DPads. + + + + Mouse Settings + Mauseinstellungen + + + + Standard + Standard + + + + Standard: 8 region dpad with two direction buttons active +when the dpad is in a diagonal region. + +Eight Way: 8 region dpad with each direction having its +own dedicated button. Only one button is ever active at +at time. Useful for rougelike games. + +4 Way Cardinal: 4 region dpad with regions corresponding to +the cardinal directions of the dpad. Useful for menus. + +4 Way Diagonal: 4 region dpad with each region corresponding +to a diagonal zone. + + + + + Eight Way + 8-Wege + + + + Set + Set + + + + Set %1 + Set %1 + + + + EditAllDefaultAutoProfileDialog + + + Default Profile + Standardprofil + + + + Profile: + Profil: + + + + Browse + Durchsuchen + + + + Open Config + Konfiguration öffnen + + + + Profile file path is invalid. + Profil-Dateipfad ist ungültig. + + + + ExtraProfileSettingsDialog + + + Extra Profile Settings + Weitere Profileinstellungen + + + + Key Press Time: + Tastendruckzeit: + + + + 0.00 ms + 0.00 ms + + + + Profile Name: + Profilname: + + + + + + s + s + + + + GameController + + + Game Controller + Gamecontroller + + + + GameControllerDPad + + + + + DPad + DPad + + + + GameControllerMappingDialog + + + Game Controller Mapping + Game Controller Zuweisung + + + + <html><head/><body><p>antimicro makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicro will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> + + + + + A + A + + + + B + B + + + + X + X + + + + Y + Y + + + + Back + Zurück + + + + Start + Start + + + + Guide + Guide + + + + Left Shoulder + linker Schulterbutton + + + + Right Shoulder + rechter Schulterbutton + + + + Left Stick Click + linker Stick Klick + + + + Right Stick Click + rechter Stick Klick + + + + Left Stick X + linker Stick X + + + + Left Stick Y + linker Stick Y + + + + Right Stick X + rechter Stick X + + + + Right Stick Y + rechter Stick Y + + + + Left Trigger + linker Trigger + + + + Right Trigger + rechter Trigger + + + + DPad Up + DPad Hoch + + + + DPad Left + DPad Links + + + + DPad Down + DPad Runter + + + + DPad Right + DPad Rechts + + + + Mapping + Zuweisung + + + + SDL 2 Game Controller Mapping String + SDL 2 Game Controller Zuweisungsstring + + + + Last Axis Event: + Letztes Achsenereignis: + + + + Current Axis Detection Dead Zone: + Aktuelle Achsenerkennungs Totzone: + + + + 5000 + 5000 + + + + 10000 + 10000 + + + + 15000 + 15000 + + + + 20000 + 20000 + + + + 25000 + 25000 + + + + 30000 + 30000 + + + + 32000 + 32000 + + + + Game Controller Mapping (%1) (#%2) + Spielecontroller Zuweisung (%1) (#%2) + + + + Discard Controller Mapping? + Controller Zuweisung verwerfen? + + + + Discard mapping for this controller? + +If discarded, the controller will be reverted to a joystick once you refresh all joysticks. + Zuweisung für diesen Controller verwerfen? + +Wenn verworfen, kehrt der Controller zu einem Joystick zurück wenn alle +Joysticks aktualisiert werden. + + + + GameControllerSet + + + Back + Zurück + + + + Guide + Handbuch + + + + Start + Start + + + + LS Click + LS Klick + + + + RS Click + RS Klick + + + + L Shoulder + L Schulter + + + + R Shoulder + R Schulter + + + + L Trigger + L Trigger + + + + R Trigger + R Trigger + + + + GameControllerTrigger + + + + + Trigger + Trigger + + + + JoyAxis + + + + + Axis + Achse + + + + JoyAxisButton + + + Negative + Negativ + + + + Positive + Positiv + + + + Unknown + Unbekannt + + + + + + Button + Button + + + + JoyAxisContextMenu + + + Mouse (Horizontal) + Maus (Horizontal) + + + + Mouse (Inverted Horizontal) + Maus (Invertiert Horizontal) + + + + Mouse (Vertical) + Maus (Vertikal) + + + + Mouse (Inverted Vertical) + Maus (Invertiert Vertikal) + + + + Arrows: Up | Down + Pfeiltasten: Hoch | Runter + + + + Arrows: Left | Right + Pfeiltasten: Links | Rechts + + + + Keys: W | S + Tasten: W | S + + + + Keys: A | D + Tasten: A | D + + + + NumPad: KP_8 | KP_2 + Nummernblock: KP_8 | KP_2 + + + + NumPad: KP_4 | KP_6 + Nummernblock: KP_4 | KP_6 + + + + + None + Nichts + + + + + Mouse Settings + Mauseinstellungen + + + + Left Mouse Button + Linke Maustaste + + + + Right Mouse Button + Rechte Maustaste + + + + JoyButton + + + Processing turbo for #%1 - %2 + + + + + Finishing turbo for button #%1 - %2 + + + + + Processing press for button #%1 - %2 + + + + + Processing release for button #%1 - %2 + + + + + Distance change for button #%1 - %2 + + + + + + + Button + Button + + + + + + + [NO KEY] + [KEINE TASTE] + + + + [Set %1 1W] + + + + + [Set %1 2W] + + + + + [Set %1 WH] + + + + + JoyButtonContextMenu + + + Toggle + Umschalten + + + + Turbo + Turbo + + + + Clear + Leeren + + + + Set Select + Set-Auswahl + + + + Disabled + Deaktiviert + + + + Set %1 + Set %1 + + + + Set %1 1W + Set %1 1W + + + + Set %1 2W + Set %1 2W + + + + Set %1 WH + + + + + JoyButtonSlot + + + + Mouse + Maus + + + + Up + Hoch + + + + Down + Runter + + + + Left + Links + + + + Right + Rechts + + + + LB + LB + + + + MB + MB + + + + RB + RB + + + + B4 + B4 + + + + B5 + B5 + + + + Pause + Pause + + + + Hold + Halten + + + + Cycle + Kreislauf + + + + Distance + Distanz + + + + Release + Freigeben + + + + Mouse Mod + Maus Mod + + + + Press Time + Druckzeit + + + + Delay + Verzögerung + + + + Load %1 + Lade %1 + + + + Set Change %1 + + + + + [Text] %1 + + + + + [Exec] %1 + + + + + [NO KEY] + [KEINE TASTE] + + + + JoyControlStick + + + + + Stick + Stick + + + + JoyControlStickButton + + + + + Up + Hoch + + + + + + Down + Runter + + + + + + Left + Links + + + + + + Right + Rechts + + + + + + Button + Button + + + + JoyControlStickContextMenu + + + Mouse (Normal) + Maus (Normal) + + + + Mouse (Inverted Horizontal) + Maus (Invertiert Horizontal) + + + + Mouse (Inverted Vertical) + Maus (Invertiert Vertikal) + + + + Mouse (Inverted Horizontal + Vertical) + Maus (Invertiert Horizontal + Vertikal) + + + + Arrows + Pfeiltasten + + + + Keys: W | A | S | D + Tasten: W | A | S | D + + + + NumPad + Nummerntastatur + + + + None + Nichts + + + + Standard + Standard + + + + Eight Way + 8-Wege + + + + 4 Way Cardinal + 4-Wege kardinal + + + + 4 Way Diagonal + 4-Wege diagonal + + + + Mouse Settings + Mauseinstellungen + + + + JoyControlStickEditDialog + + + Dialog + Dialog + + + + X: + X: + + + + + + + + 0 + 0 + + + + Y: + Y: + + + + Distance: + Distanz: + + + + Presets: + Vorgaben: + + + + Mouse (Normal) + Maus (Normal) + + + + Mouse (Inverted Horizontal) + Maus (Invertiert Horizontal) + + + + Mouse (Inverted Vertical) + Maus (Invertiert Vertikal) + + + + Mouse (Inverted Horizontal + Vertical) + Maus (Invertiert Horizontal + Vertikal) + + + + Arrows + Pfeiltasten + + + + Keys: W | A | S | D + Tasten: W | A | S | D + + + + NumPad + Nummerntastatur + + + + None + Nichts + + + + Stick Mode: + Stickmodus: + + + + Standard: 8 region stick with two direction buttons active +when the stick is in a diagonal region. + +Eight Way: 8 region stick with each direction having its +own dedicated button. Only one button is ever active at +at time. Useful for rougelike games. + +4 Way Cardinal: 4 region stick with regions corresponding to +the cardinal directions of the stick. Useful for menus. + +4 Way Diagonal: 4 region stick with each region corresponding +to a diagonal zone of the stick. + Standard: 8-Wege-Stick mit zwei Richtungstasten aktiv +wenn der Stick in diagonaler Richtung ist. + +8-Wege: 8-Wege-Stick mit jedem Weg einer eigenen Taste +entsprechend. Nur eine Taste ist gleichzeitig aktiv. +Nützlich für "rougelike" Spiele. + +4-Wege Kardinal: 4-Regionen-Stick, wobei jede Region einer +Kardinal-/Himmelsrichtung des Sticks entspricht. Nützlich für Menüs. + +4-Wege Diagonal: 4-Regionen-Stick, wobei jede Region einer +Diagonal-Zone des Sticks entspricht. + + + + 4 Way Cardinal + 4-Wege kardinal + + + + 4 Way Diagonal + 4-Wege diagonal + + + + + Dead zone value to use for an analog stick. + Totzonenwert für Analogsticks. + + + + + Value when an analog stick is considered moved 100%. + Wert für den ein Analogstick als 100% ausgelenkt betrachtet wird. + + + + + The area (in degrees) that each diagonal region occupies. + Den Bereich (in Grad) die jede diagonale Region einnimmt. + + + + Square Stick: + + + + + + Percentage to modify a square stick coordinates to confine values to a circle + + + + + % + % + + + + Stick Delay: + Stick Verzögerung: + + + + + Time lapsed before a direction change is taken into effect. + Abgelaufene Zeit bis eine Richtungsänderung wirksam wird. + + + + s + + + + + Modifier: + Modifikator: + + + + Edit button that is active while the stick is active. + +This button is useful for assigning zones with +modifier keys that can be used to assign walk/run +functionality to an analog stick. + + + + + PushButton + + + + + Name: + Name: + + + + Specify the name of an analog stick. + Vergebe den Namen eines Analogsticks. + + + + Mouse Settings + Mauseinstellungen + + + + Standard + Standard + + + + Bearing: + + + + + % Safe Zone: + + + + + Eight Way + 8-Wege + + + + Dead Zone: + Dead Zone: + + + + Max Zone: + Max Zone: + + + + Diagonal Range: + diagonale Reichweite: + + + + Set + Set + + + + Set %1 + Set %1 + + + + JoyControlStickModifierButton + + + + + Modifier + Modifikator + + + + JoyDPad + + + + + DPad + DPad + + + + JoyDPadButton + + + + + Up + Hoch + + + + + + Down + Runter + + + + + + Left + Links + + + + + + Right + Rechts + + + + + + Button + Button + + + + JoyTabWidget + + + + + + + + <New> + <Neu> + + + + + Remove + Entfernen + + + + + Remove configuration from recent list. + Entferne Konfiguration aus den letzten Einträgen. + + + + + Load + Laden + + + + + Load configuration file. + Lade Konfigurationsdatei. + + + + + Save + Speichern + + + + + Save changes to configuration file. + Änderungen in Konfigurationsdatei speichern. + + + + + Save As + Speichern unter + + + + + Save changes to a new configuration file. + Änderungen in neue Konfigurationsdatei speichern. + + + + + Sets + Sets + + + + Copy from Set + + + + + Settings + Einstellungen + + + + + Set 1 + Set 1 + + + + + Set 2 + Set 2 + + + + + Set 3 + Set 3 + + + + + Set 4 + Set 4 + + + + + Set 5 + Set 5 + + + + + Set 6 + Set 6 + + + + + Set 7 + Set 7 + + + + + Set 8 + Set 8 + + + + + Stick/Pad Assign + Stick/Pad Zuweisung + + + + + Controller Mapping + Controllerzuweisung + + + + + Quick Set + Schnellkonfiguration + + + + + Names + Namen + + + + + Toggle button name displaying. + Buttonnamendarstellung wechseln. + + + + + Pref + Einst + + + + + Change global profile settings. + Globale Profileinstellungen ändern. + + + + + + Reset + Reset + + + + + Revert changes to the configuration. Reload configuration file. + Änderungen der Konfiguration zurücksetzen. Neuladen der Konfiguration. + + + + Open Config + Konfiguration öffnen + + + + Config Files (*.amgp *.xml) + Konfigurationsdateien (*.amgp *.xml) + + + + + + Config File (*.%1.amgp) + Konfigurationsdatei (*.%1.amgp) + + + + + Save Profile Changes? + Profiländerungen speichern? + + + + + Changes to the new profile have not been saved. Would you like to save or discard the current profile? + Änderungen am neuen Profil wurden nicht gespeichert. Möchten Sie das aktuelle Profil speichern oder verwerfen? + + + + + Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? + Änderungen am neuen Profil %1 wurden nicht gespeichert. Möchten Sie das aktuelle Profil speichern oder verwerfen? + + + + Sticks + Sticks + + + + + DPads + DPads + + + + No buttons have been assigned. Please use Quick Set to assign keys +to buttons or disable hiding empty buttons. + Es wurden keine Tasten zugewiesen. Bitte verwenden Sie den Schnellkonfiguration um Tasten zuzuweisen +oder deaktivieren Sie das Ausblenden leerer Tasten. + + + + + Set %1: %2 + Set %1: %2 + + + + + Set %1 + Set %1 + + + + Copy Set Assignments + Kopiere Set-Zuweisungen + + + + Are you sure you want to copy the assignments and device properties from %1? + Sind Sie sicher, dass Sie die Aufgaben-und Geräteeigenschaften von%1 kopieren möchten? + + + + + + Save Config + Konfiguration speichern + + + + + Set + Set + + + + Joystick + + + Joystick + Joystick + + + + JoystickStatusWindow + + + Properties + Eigenschaften + + + + Details + Details + + + + Name: + Name: + + + + + + + + + + %1 + %1 + + + + Number: + Nummer: + + + + Axes: + Achsen: + + + + Buttons: + Buttons: + + + + Hats: + Hats: + + + + GUID: + GUID: + + + + Game Controller: + Gamecontroller: + + + + Axes + Achsen + + + + Buttons + Buttons + + + + Hats + Hats + + + + %1 (#%2) Properties + %1 (#%2) Eigenschaften + + + + Axis %1 + Achse %1 + + + + Hat %1 + Hat %1 + + + + No + Nein + + + + Yes + Ja + + + + MainSettingsDialog + + + Edit Settings + Einstellungen ändern + + + + General + Allgemein + + + + Controller Mappings + Controllerzuweisungen + + + + Language + Sprache + + + + Auto Profile + Autoprofil + + + + Mouse + Maus + + + + <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> + <html><head/><body><p>Geben Sie das Standardverzeichnis an, dass das Programm im Dateidialog verwenden soll beim Laden oder Speichern eines Profils.</p></body></html> + + + + Recent Profile Count: + Einträge an Profilen merken: + + + + <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> + <html><head/><body><p>Anzahl der Profile, die in den letzten Profilen-Liste platziert werden können. 0 = keine Begrenzung.</p></body></html> + + + + Gamepad Poll Rate: + + + + + Change the poll rate that the program uses to discover new +events from gamepads. Defaults to 10 ms. + +Reducing the poll rate value could cause the application to +use more CPU power so please test the setting that you use +before using antimicro unattended. + + + + + Hide main window when the main window close button is +clicked instead of quitting the program. + Verstecke Hauptfenster anstatt es zu schließen, wenn die "Schließen"-Schaltfläche gedrückt wurde. + + + + Close To Tray + Schließen im Tray + + + + Have Windows start antimicro at system startup. + Lade antimicro beim Systemstart. + + + + Launch At Windows Startup + Beim Windows-Start starten + + + + Display recent profiles for all controllers +as a single list in the tray menu. Defaults +to using sub-menus. + Zeige die zuletzt benutzten Profile aller +Controller als eine Liste anstatt als Untermenüs. + + + + Single Profile List in Tray + Einzelprofil-Menü im Tray + + + + Have the program minimize to the taskbar. +By default, the program minimizes to the system +tray if available. + Minimiere das Programm in die Taskleiste. Standardmäßig wird AntiMicro, falls möglich, in das System-Tray minimiert. + + + + Minimize to Taskbar + In die Taskleiste minimieren + + + + This option will cause the program to hide all +buttons that have no slots assigned to them. +The Quick Set dialog window will have to be used +to bring up the edit dialog for gamepad buttons. + Diese Option versteckt alle Tasten denen keine +Aktion zugeordnet wird. Der Schnelleinstellungs-Dialog +muss benutzt werden um die Editier-Einstellungen aufzurufen. + + + + Hide Empty Buttons + Verstecke leere Schaltflächen + + + + When the program is launched, open the last +known profile that was opened during the +previous session. + Wenn das Programm gestartet wurde, +öffne das zuletzt benutzte Profil. + + + + Auto Load Last Opened Profile + Zuletzt geöffnetes Profil automatisch öffnen + + + + Only show the system tray icon when the program +first launches. + Zeige das System-Tray-Icon nur, +wenn das Programm zum ersten Mal startet. + + + + Launch in Tray + Starten im Tray + + + + Associate .amgp files with antimicro in Windows Explorer. + Assoziiere .amgp-Dateien mit antimicro im Windows Explorer. + + + + Associate Profiles + Assoziiere Profile + + + + Key Repeat + Tastenanschlag + + + + Active keys will be repeatedly pressed when this +option is enabled. + Dauerhaft gedrückte Tasten werden wiederholt gedrückt, +wenn diese Option aktiviert ist. + + + + + Enable + Aktivieren + + + + Specifies how much time should elapse before key repeating +begins. + Bestimmt die Zeit die abläuft bis das Wiederholen des +Tastenanschlags beginnt. + + + + Specifies how many times key presses will be performed +per seconds. + Bestimmt wie oft Tastenanschläge pro Sekunde +durchgeführt werden. + + + + <html><head/><body><p>antimicro has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make antimicro load a different translation depending on the language that you choose from the list below.</p></body></html> + <html><head/><body><p>antimicro wurde durch Mitwirkende in viele verschiedene Sprachen übersetzt. Standardmäßig wählt das Programm ein die entsprechende Übersetzung anhand der Einstellung Ihres Systems. Jedoch können Sie antimicro eine andere Übersetzung anhand der Sprache von der Liste hierunter wählen.</p></body></html> + + + + French + Französisch + + + + Japanese + + + + + Russian + Russisch + + + + Serbian + Serbisch + + + + Simplified Chinese + + + + + Ukrainian + Ukrainisch + + + + Class + Klasse + + + + Title + Titel + + + + Program + Programm + + + + Disable the "Enhanced Pointer Precision" Windows setting +while antimicro is running. Disabling "Enhanced Pointer Precision" +will allow mouse movement within antimicro to be more +precise. + Deaktiviere die "Zeigerbeschleunigung verbessern" Windowseinstellung +während antimicro läuft. Dies erlaubt präzisere Mausbewegungen in +antimicro. + + + + Disable Enhance Pointer Precision + Deaktiviere "Zeigerbeschleunigung verbessern" + + + + Smoothing + Glättung + + + + Histor&y Size: + + + + + Weight &Modifier: + + + + + Refresh Rate: + Wiederholrate: + + + + The refresh rate is the amount of time that will elapse +in between mouse events. Please be cautious when +editing this setting as it will cause the program to use +more CPU power. Setting this value too low can cause +system instability. Please test the setting before using +it unattended. + + + + + Spring + Quelle + + + + Screen: + Bildschirm: + + + + Utilize the specified screen for spring mode. On Linux, the +default is to use the primary screen. On Windows, the default +is to use all available screens. + + + + + Accel Numerator: + + + + + + + 0 + 0 + + + + Accel Denominator: + + + + + Accel Threshold: + + + + + If the acceleration values for the virtual mouse have been +changed by a different process, particularly when quitting +an older game, then you might want to reset the acceleration +values used by the virtual mouse. + + + + + Reset Acceleration + + + + + Delay: + Verzögerung: + + + + Profi&le Directory: + + + + + ms + ms + + + + Rate: + Rate: + + + + times/s + mal/s + + + + Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. + +Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. + Unten finden Sie eine Liste der benutzerdefinierten Zuordnungen, die gespeichert werden können. Sie können die folgende Tabelle verwenden, um Zuordnungen zu löschen bzw. Zuordnungen vorübergehend zu deaktivieren. Sie können auch Abbildungendeaktivieren, die in SDL enthalten sind, nur eine neue Zeile einfügen mit dem entsprechenden Joystick-GUID und prüfen deaktivieren. + +Die Einstellungen werden nicht wirksam werden, bis Sie entweder alle Joysticks aktualisieren oder diesen bestimmten Joystick trennen. + + + + GUID + GUID + + + + Mapping String + Zuweisungsstring + + + + Disable? + Deaktivieren? + + + + + Delete + Löschen + + + + Insert + Einfügen + + + + + Default + Standard + + + + Brazilian Portuguese + Brasilianisches Portugiesisch + + + + English + Englisch + + + + German + Deutsch + + + + + Active + Aktiv + + + + Devices: + Geräte: + + + + + All + Alles + + + + Device + Gerät + + + + Profile + Profil + + + + Default? + Standard? + + + + Add + Hinzufügen + + + + Edit + Editieren + + + + Also, Windows users who want to use a low value should also check the +"Disable Enhance Pointer Precision" checkbox if you haven't disabled +the option in Windows. + Außerdem, Windows-Nutzer die einen geringen Wert nutzen möchten, sollten +auch das "Deaktiviere 'Zeigerbeschleunigung verbessern'" Kontrollkästchen +aktivieren, wenn die Option nicht in Windows deaktiviert ist. + + + + Select Default Profile Directory + Wähle das Standard-Profil-Verzeichnis + + + + Are you sure you want to delete the profile? + Sind Sie sicher, dass Sie das Profil löschen möchten? + + + + MainWindow + + + No Joysticks have been found. + Please plug in a joystick and then choose the "Update Joysticks" option in the main menu + Keine Joysticks gefunden. + Stecken Sie eine Joystick ein und wählen Sie dann die Option "Joysticks aktualisieren" im Hauptmenü aus + + + + &App + &Anwendung + + + + Stick/Pad Assign + Stick/Pad Zuweisung + + + + &Options + &Optionen + + + + antimicro + + + + + If events are not seen by a game, please click here to run this application as the Adminstrator. + Wenn die Ereignisse nicht erkannt werden, klicken Sie hier um als Administrator neuzustarten. + + + + &Help + &Hilfe + + + + + &Quit + B&eenden + + + + Ctrl+Q + Strg+Q + + + + + &Update Joysticks + &Joysticks aktualisieren + + + + Ctrl+U + Strg+U + + + + + &Hide + &Verstecken + + + + Ctrl+H + Strg+H + + + + &About + Ü&ber + + + + Ctrl+A + Strg+A + + + + About Qt + Über Qt + + + + Properties + Eigenschaften + + + + Key Checker + Tastenkontrolle + + + + Home Page + Webseite + + + + GitHub Page + GitHub-Webseite + + + + Game Controller Mapping + Gamecontroller-Zuweisung + + + + Settings + Einstellungen + + + + Wiki + + + + + Could not find a proper controller identifier. Exiting. + + + + + + + + + + + (%1) + (%1) + + + + + Open File + Datei öffnen + + + + &Restore + &Wiederherstellen + + + + Run as Administrator? + Als Administrator ausführen? + + + + Are you sure that you want to run this program as Adminstrator? + +Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. + Sind Sie sicher, dass Sie das Programm als Administrator ausführen wollen? + +Manche Spiele laufen als Administrator, weshalb manche Ereignisse durch antimicro nicht von diesen Spielen erkannt werden, wenn antimicro nicht auch als Administrator ausgeführt wird. Dies geschieht auf Grund von Erlaubnisproblemen durch Benutzerkontensteuerung (UAC) Einstellungen in Windows Vista und neuer. + + + + Failed to elevate program + Berechtigungserhöhung fehlgeschlagen + + + + Failed to restart this program as the Administrator + Neustart als Administrator ist fehlgeschlagen + + + + Could not find controller. Exiting. + + + + + MouseAxisSettingsDialog + + + Mouse Settings - + Mauseinstellungen - + + + + Set %1 + Set %1 + + + + MouseButtonSettingsDialog + + + Mouse Settings - + Mauseinstellungen - + + + + Set %1 + Set %1 + + + + MouseControlStickSettingsDialog + + + Mouse Settings + Mauseinstellungen + + + + Set %1 + Set %1 + + + + MouseDPadSettingsDialog + + + Mouse Settings + Mauseinstellungen + + + + Set %1 + Set %1 + + + + MouseSettingsDialog + + + Mouse Settings + Mauseinstellungen + + + + Mouse Mode: + Mausmodus: + + + + Cursor mode is used to move the mouse cursor +around the screen relative to its current position +depending on how much you move an axis +or if a button is pressed. + +Spring mode is used to move the mouse cursor +from the center of the screen depending on how +much you move an axis. The mouse cursor will +be returned to the center of the screen when the +axis is moved back to the dead zone. + Der Zeigermodus wird verwendet, um den Mauszeiger relativ zu +der aktuellen Position auf dem Bildschirm zu bewegen +je nachdem, wie viel Sie eine Achse bewegen +oder wenn eine Taste gedrückt wird. + +Der Sprungmodus bewegt den Mauspfeil vom +Mittelpunkt des Bildschirms je nach Bewegung +einer Achse. Der Mauspfeil wandert zu seinem +Mittelpunkt, wenn eine Achse zur Dead +Zone zurück kehrt. + + + + Cursor + Zeiger + + + + Spring + Sprung + + + + Acceleration: + Beschleunigung: + + + + Enhanced Precision + Verbesserte Präzision + + + + + Linear + linear + + + + Quadratic + quadratisch + + + + Cubic + kubisch + + + + Quadratic Extreme + extrem quadratisch + + + + Power Function + Power Funktion + + + + Easing Quadratic + + + + + Easing Cubic + + + + + Mouse Speed Settings + Einstellungen der Mausgeschwindigkeit + + + + Enable to change the horizontal and vertical speed +boxes at the same time. + Aktivieren, um die horizontale und vertikale +Geschwindigkeitseinstellungen zur gleichen Zeit +zu ändern. + + + + Change Together + Zusammen ändern + + + + Horizontal +Speed: + Geschw. +horizontal: + + + + + 1 = 20 pps + 1 = 20 pps + + + + Vertical +Speed: + Geschw. +vertikal: + + + + Wheel Hori. +Speed: + Rad-Gesch. +horizontal: + + + + Set the speed used for horizontal mouse wheel movement +according to number of simulated notches per second. + Stellen Sie die Geschwindigkeit für die horizontale Mausrad-Bewegung +entsprechend der Anzahl der simulierten Raster pro Sekunde ein. + + + + Set the speed used for vertical mouse wheel movement +according to number of simulated notches per second. + Stellen Sie die Geschwindigkeit für die vertikale Mausrad-Bewegung +entsprechend der Anzahl der simulierten Raster pro Sekunde ein. + + + + For Power Function acceleration curve. Specifies +the factor to use for curve sensitivity. When the value +is above 1.0, the mouse movement will be accelerated +faster at the low end of an axis. + + + + + Easing Duration: + + + + + + s + + + + + Extra Acceleration + Zusätzliche Beschleunigung + + + + Multiplier: + Multiplikator: + + + + Highest value to accelerate mouse movement by + + + + + x + + + + + Start %: + + + + + Acceleration begins at this percentage of the base multiplier + + + + + Min +Threshold: + + + + + Minimum amount of axis travel required for acceleration to begin + + + + + Max +Threshold: + + + + + Maximum axis travel before acceleration has reached the multiplier value + + + + + Curve: + + + + + Ease Out Sine + + + + + Ease Out Quad + + + + + Ease Out Cubic + + + + + Release Radius: + + + + + Specifies that the spring area will be relative to the +mouse position set by a non-relative spring. + Wenn aktiviert, + Besagt, dass das Ursprungs-arreal + durch ein nicht-relativen Ursprung relativ zur Mausposition sein wird. + + + + Relative + Relativ + + + + Mouse Status + + + + + X: + X: + + + + + 0 (0 pps) + + + + + Y: + Y: + + + + + 1 = 1 notch(es)/s + 1 = 1 Raste + + + + Enhanced: Three tier curve that makes the mouse move +slow on the low end of an axis and fast on the high end. + +Linear: Mouse moves proportionally to axis. + +Quadratic: Mouse accelerates slowly on low end. + +Cubic: Mouse accelerates slower than Quadratic. + +Quadratic Extreme: Raises mouse speed 1.5 times once +95% axis travel has been reached. + +Power Function: Allows for a more custom curve option. + +Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. + +Easing Cubic: Axis high end is gradually accelerated over +a period of time using a Cubic curve. + + + + + Wheel Vert. +Speed: + Rad-Gesch +vertikal: + + + + Sensitivity: + Empfindlichkeit: + + + + Specifies the amount of time (in seconds) that will +be required before the mouse is fully accelerated +after reaching the high end of an axis. + + + + + Options for adding extra acceleration to the mouse +movement beyond what the acceleration curve would +produce. This is meant to help work around some of +the issues of the very limited input range available using +typical gamepad analog sticks. + + + + + + + + % + + + + + Extra Duration: + + + + + Extend the time that extra acceleration is applied. Axis travel +will be taken into account. A slower flick will decrease the +actual time that extra acceleration will be applied. + + + + + Spring Settings + Sprungeinstellungen + + + + Spring Width: + Sprungweite: + + + + Changes the width of the region that the cursor +can move in spring mode. 0 will use the entire width +of your screen. + Ändert die Breite der Region, die der Mauszeiger +im Sprungmodus zurück legt. 0 wird die gesamte Breite +auf Ihrem Bildschirm nutzen. + + + + Spring Height: + Sprunghöhe: + + + + Changes the height of the region that the cursor +can move in spring mode. 0 will use the entire height +of your screen. + Ändert die Höhe der Region, die der Mauszeiger +im Sprungmodus zurück legt. 0 wird die gesamte Höhe +auf Ihrem Bildschirm nutzen. + + + + + %n notch(es)/s + + %n notch/s + %n notches/s + + + + + QKeyDisplayDialog + + + Key Checker + Tastenkontrolle + + + + <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by antimicro.</p><p>The antimicro key value and the Qt key value will usually be the same. antimicro tries to use the key values defined in Qt when possible. Check the page <a href="http://qt-project.org/doc/qt-4.8/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://qt-project.org/doc/qt-4.8/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to antimicro's <a href="https://github.com/Ryochan7/antimicro"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> + + + + + Event Handler: + + + + + Native Key Value: + Nativer Tastenwert: + + + + + + 0x00000000 + 0x00000000 + + + + Qt Key Value: + Qt-Tastenwert: + + + + antimicro Key Value: + + + + + QObject + + + Super + Super + + + + Menu + Menü + + + + Mute + Stummschalten + + + + Vol+ + + + + + Vol- + + + + + Play/Pause + Wiedergabe/Pause + + + + Play + Wiedergabe + + + + Pause + + + + + Prev + Zurück + + + + Next + Vor + + + + Mail + EMail + + + + Home + Pos1 + + + + Media + + + + + Search + Suche + + + + Daemon launched + Dienst gestartet + + + + Failed to launch daemon + Dienst konnte nicht gestartet werden + + + + Launching daemon + Starte Dienst + + + + + Display string "%1" is not valid. + + + + + Failed to set a signature id for the daemon + Signatur-ID konnte für den Dienst nicht gesetzt werden + + + + Failed to change working directory to / + Arbeitsverzeichnis konnte nicht gesetzt werden zu / + + + + Quitting Program + Beende Programm + + + + # of joysticks found: %1 + # an Joysticks gefunden: %1 + + + + List Joysticks: + + + + + --------------- + + + + + Joystick %1: + + + + + Index: %1 + + + + + GUID: %1 + + + + + Name: %1 + + + + + Yes + Ja + + + + No + Nein + + + + Game Controller: %1 + + + + + # of Axes: %1 + # der Achsen: %1 + + + + # of Buttons: %1 + # der Knöpfe: %1 + + + + # of Hats: %1 + # der Hats: %1 + + + + Attempting to use fallback option %1 for event generation. + Versuche Fallback-Option %1 zur Ereignisgenerierung. + + + + Failed to open event generator. Exiting. + Öffnen des Ereignisgenerators fehlgeschlagen. Breche ab. + + + + Using %1 as the event generator. + Nutze %1 als Ereignisgenerator. + + + + Could not raise process priority. + Konnte Prozesspriorität nicht erhöhen. + + + + QuickSetDialog + + + Quick Set + Schnellkonfiguration + + + + <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> + <html><head/><body><p>Bitte drücken Sie eine Taste oder bewegen Sie eine Achse auf %1 (<span style=" font-weight:600;">%2</span>).<br/>Dann erscheint ein Dialogfenter, dass Ihnen <br>erlaubt eine Zuordnung zu machen.</p></body></html> + + + + Quick Set %1 + Schnellkonfiguration %1 + + + + SetAxisThrottleDialog + + + Throttle Change + Schubänderung + + + + The throttle setting for Axis %1 has been changed. + +Would you like to distribute this throttle change to all sets? + Auf Achse %1 wurde der Schub verändert. + +Möchten Sie die Änderungen an alle Sets übertragen? + + + + SetJoystick + + + Set %1: %2 + Set %1: %2 + + + + Set %1 + Set %1 + + + + SetNamesDialog + + + Set Name Settings + Setnameneinstellungen + + + + Set 1 + Set 1 + + + + Set 2 + Set 2 + + + + Set 3 + Set 3 + + + + Set 4 + Set 4 + + + + Set 5 + Set 5 + + + + Set 6 + Set 6 + + + + Set 7 + Set 7 + + + + Set 8 + Set 8 + + + + Name + Name + + + + SimpleKeyGrabberButton + + + Mouse + Maus + + + + SpringModeRegionPreview + + + Spring Mode Preview + Sprungmodus-Vorschau + + + + UInputEventHandler + + + Could not find a valid uinput device file. +Please check that you have the uinput module loaded. +lsmod | grep uinput + Konnte keine gültiges uinput Gerätedatei finden. +Bitte überprüfen Sie, ob das uinput Modul geladen ist. +lsmod | grep uinput + + + + Could not open uinput device file +Please check that you have permission to write to the device + Konnte nicht uinput Gerätedatei öffnen +Bitte überprüfen Sie ob Sie die Berechtigung haben auf dieses Gerät zu schreiben + + + + Using uinput device file %1 + Nutze uinput Gerätedatei %1 + + + + UInputHelper + + + a + + + + + b + + + + + c + + + + + d + + + + + e + + + + + f + + + + + g + + + + + h + + + + + i + + + + + j + + + + + k + + + + + l + + + + + m + + + + + n + + + + + o + + + + + p + + + + + q + + + + + r + + + + + s + + + + + t + + + + + u + + + + + v + + + + + w + + + + + x + + + + + y + + + + + z + + + + + Esc + + + + + F1 + + + + + F2 + + + + + F3 + + + + + F4 + + + + + F5 + + + + + F6 + + + + + F7 + + + + + F8 + + + + + F9 + + + + + F10 + + + + + F11 + + + + + F12 + + + + + ` + + + + + 1 + 1 + + + + 2 + 2 + + + + 3 + 3 + + + + 4 + 4 + + + + 5 + 5 + + + + 6 + 6 + + + + 7 + 7 + + + + 8 + 8 + + + + 9 + 9 + + + + 0 + 0 + + + + + - + + + + + = + + + + + BackSpace + Rücktaste + + + + Tab + Tabulator + + + + [ + + + + + ] + + + + + \ + + + + + CapsLock + Feststell + + + + ; + + + + + ' + + + + + Enter + Eingabe + + + + Shift_L + Umschalt_L + + + + , + + + + + + . + + + + + + / + + + + + Ctrl_L + Strg_L + + + + + Super_L + Super_L + + + + Alt_L + Alt_L + + + + Space + Leertaste + + + + Alt_R + Alt_R + + + + Menu + Menü + + + + Ctrl_R + Strg_R + + + + Shift_R + Umschalt_R + + + + Up + Hoch + + + + Left + Links + + + + Down + Runter + + + + Right + Rechts + + + + PrtSc + Druck + + + + Ins + Einfg + + + + Del + Entf + + + + Home + Pos1 + + + + End + Ende + + + + PgUp + Bild ↑ + + + + PgDn + Bild ↓ + + + + NumLock + + + + + * + + + + + + + + + + + KP_Enter + + + + + KP_1 + + + + + KP_2 + + + + + KP_3 + + + + + KP_4 + + + + + KP_5 + + + + + KP_6 + + + + + KP_7 + + + + + KP_8 + + + + + KP_9 + + + + + KP_0 + + + + + SCLK + Rol ↓ + + + + Pause + Pause + + + + Super_R + + + + + Mute + Stumm + + + + VolDn + Vol- + + + + VolUp + Vol+ + + + + Play + Wiedergabe + + + + Stop + + + + + Prev + Zurück + + + + Next + Vor + + + + [NO KEY] + [KEINE TASTE] + + + + UnixWindowInfoDialog + + + Captured Window Properties + Erkannte Fenstereigenschaften + + + + Information About Window + Informationen über das Fenster + + + + Class: + Klasse: + + + + + + TextLabel + + + + + Title: + Titel: + + + + Path: + Pfad: + + + + Match By Properties + + + + + Class + Klasse + + + + Title + Titel + + + + Path + Pfad + + + + VDPad + + + + + VDPad + VDPad + + + + VirtualKeyPushButton + + + Space + Leertaste + + + + Tab + + + + + Shift (L) + Umschalt (L) + + + + Shift (R) + Umschalt (R) + + + + Ctrl (L) + Strg (L) + + + + Ctrl (R) + Strg (R) + + + + Alt (L) + Alt (L) + + + + + Alt (R) + Alt (R) + + + + ` + + + + + ~ + + + + + + - + + + + + = + + + + + [ + + + + + ] + + + + + \ + + + + + Caps + Feststell + + + + ; + + + + + ' + + + + + , + + + + + + . + + + + + + / + + + + + ESC + + + + + PRTSC + Drucken + + + + SCLK + Rollen + + + + INS + Einfg + + + + PGUP + Bild ↑ + + + + DEL + Entf + + + + PGDN + Bild ↓ + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + 9 + + + + + 0 + + + + + NUM +LK + NUM +LOCK + + + + + * + + + + + + + + + + + E +N +T +E +R + E +I +N +G +A +B +E + + + + < + + + + + : + + + + + Super (L) + + + + + Menu + Menü + + + + Up + Hoch + + + + Down + Runter + + + + Left + Links + + + + Right + Rechts + + + + VirtualKeyboardMouseWidget + + + + Keyboard + Tastatur + + + + + Mouse + Maus + + + + Mouse Settings + Mauseinstellungen + + + + Left + Mouse + Links + + + + Up + Mouse + Hoch + + + + Left Button + Mouse + Linke Taste + + + + Middle Button + Mouse + Mittlere Taste + + + + Right Button + Mouse + Rechte Taste + + + + Wheel Up + Mouse + Mausrad hoch + + + + Wheel Left + Mouse + Mausrad links + + + + Wheel Right + Mouse + Mausrad rechts + + + + Wheel Down + Mouse + Mausrad runter + + + + Down + Mouse + Runter + + + + Right + Mouse + Rechts + + + + Button 4 + Mouse + Taste 4 + + + + Mouse 8 + Mouse + Taste 8 + + + + Button 5 + Mouse + Taste 5 + + + + Mouse 9 + Mouse + Taste 9 + + + + NONE + KEINE + + + + Applications + + + + + Browser Back + + + + + Browser Favorites + + + + + Browser Forward + + + + + Browser Home + + + + + Browser Refresh + + + + + Browser Search + + + + + Browser Stop + + + + + Calc + + + + + Email + + + + + Media + + + + + Media Next + + + + + Media Play + + + + + Media Previous + + + + + Media Stop + + + + + Search + Suche + + + + Volume Down + + + + + Volume Mute + + + + + Volume Up + + + + + VirtualMousePushButton + + + INVALID + UNGÜLTIG + + + + WinAppProfileTimerDialog + + + + Capture Application + Wähle Applikation + + + + After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. + Wählen Sie das Fenster aus mit dem Sie das Profil assozieren möchten, nachdem Sie auf den "Wähle Applikation" Button geklickt haben. Die aktive Applikation wird nach der angegebenen Zahl an Sekunden ausgewählt. + + + + Timer: + + + + + Seconds + Sekunden + + + + Cancel + Abbrechen + + + + WinExtras + + + [NO KEY] + [KEINE TASTE] + + + + AntiMicro Profile + + + + + X11Extras + + + ESC + + + + + Tab + Tabulator + + + + Space + Leertaste + + + + DEL + Entf + + + + Return + Eingabe + + + + KP_Enter + + + + + Backspace + Rücktaste + + + + xinput extension was not found. No mouse acceleration changes will occur. + xinput Erweiterung wurde nicht gefunden. Es wird keine Mausbeschleunigungsänderungen geben. + + + + + xinput version must be at least 2.0. No mouse acceleration changes will occur. + xinput Version muss mindestens 2.0 sein. Es wird keine Mausbeschleunigungsänderungen geben. + + + + Virtual pointer found with id=%1. + Virtueller Mauszeiger mit id=%1 gefunden. + + + + PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 + PtrFeedbackCalls wurde nicht für den virtuellen Mauszeiger gefunden. Es wird keine Mausbeschleunigungsänderungen für das Gerät mit id=%1 geben + + + + Changing mouse acceleration for device with id=%1 + Ändere Mausbeschleunigung für Gerät der id=%1 + + + + XMLConfigReader + + + Could not write updated profile XML to file %1. + Konnte aktuelles Profil nicht als XML in Datei %1 schreiben. + + + + XMLConfigWriter + + + Could not write to profile at %1. + Konnte Profil nicht schreiben in %1. + + + diff --git a/share/antimicro/translations/antimicro_en.ts b/share/antimicro/translations/antimicro_en.ts new file mode 100644 index 0000000..9a864a0 --- /dev/null +++ b/share/antimicro/translations/antimicro_en.ts @@ -0,0 +1,5880 @@ + + + + + AboutDialog + + + About + + + + + Version + + + + + Info + + + + + Changelog + + + + + Since December 30, 2012, I have been working on antimicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. + +The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. + +Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. + +Once the Steam controller is finally released to the public, the need for this program might not exist anymore. Just based on the concept of the controller alone, the Steam controller would have so many advantages over using a program like this to provide KB+M emulation. + + + + + Copyright: 2013 - 2015 + + + + + Credits + + + + + antimicro + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Travis Nickles &lt;nickles.travis@gmail.com&gt;</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Contributors:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;"><br /></span>Zerro Alvein</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">aybe</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Jeff Backus &lt;jeff.backus@gmail.com&gt;</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Arthur Moore<br />Anton Tornqvist &lt;antont@inbox.lv&gt;</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Translators:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt; font-weight:600;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">zzpxyx - Chinese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">phob - German</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tou omiya - Japanese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">burunduk - Ukrainian</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Version 3, 29 June 2007</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Preamble</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">TERMS AND CONDITIONS</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">0. Definitions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">1. Source Code.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">2. Basic Permissions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">4. Conveying Verbatim Copies.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">5. Conveying Modified Source Versions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">6. Conveying Non-Source Forms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">7. Additional Terms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">8. Termination.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">11. Patents.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">14. Revised Versions of this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">15. Disclaimer of Warranty.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">16. Limitation of Liability.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> + + + + + About Development + + + + + License + + + + + Program Version %1 + + + + + Program Compiled on %1 at %2 + + + + + Built Against SDL %1 + + + + + Running With SDL %1 + + + + + Using Qt %1 + + + + + Using Event Handler: %1 + + + + + AddEditAutoProfileDialog + + + Auto Profile Dialog + + + + + Profile: + + + + + + Browse + + + + + Window: + + + + + + Select Window. Click on the appropriate application +window and the application file path will be populated +in the form. + + + + + Detect Window Properties + + + + + Class: + + + + + Title: + + + + + Application: + + + + + Select + + + + + Devices: + + + + + + Select this profile to be the default loaded for +the specified device. The selection will be used instead +of the all default profile option. + + + + + Set as Default for Controller + + + + + + A different profile is already selected as the default for this device. + + + + + Current (%1) + + + + + Open Config + + + + + + Select Program + + + + + Programs (*.exe) + + + + + Please use the main default profile selection. + + + + + Please select a window by using the mouse. Press Escape if you want to cancel. + + + + + Capture Application Window + + + + + Could not obtain information for the selected window. + + + + + Application Capture Failed + + + + + Profile file path is invalid. + + + + + No window matching property was specified. + + + + + Program path is invalid or not executable. + + + + + File is not an .exe file. + + + + + No window matching property was selected. + + + + + AdvanceButtonDialog + + + + Advanced + + + + + Assignments + + + + + Toggle + + + + + Turbo + + + + + Set Selector + + + + + Blank or KB/M + + + + + Hold + + + + + Pause + + + + + Cycle + + + + + Distance + + + + + Insert + + + + + Delete + + + + + Clear All + + + + + Time: + + + + + 0.01s + + + + + 0s + + + + + Insert a pause that occurs in between key presses. + + + + + Release + + + + + + Insert a new blank slot. + + + + + Delete a slot. + + + + + Clear all currently assigned slots. + + + + + Specify the duration of an inserted Pause or Hold slot. + + + + + 0m + + + + + + Specify the range past an axis dead zone in which a sequence of actions will execute. + + + + + Distance: + + + + + + % + + + + + Mouse Mod + + + + + Press Time + + + + + Delay + + + + + Execute + + + + + Load + + + + + Set Change + + + + + Text Entry + + + + + Placeholder + + + + + + 0 + + + + + Mouse Speed Mod: + + + + + Set the percentage that mouse speeds will be modified by. + + + + + Auto Reset Cycle After + + + + + seconds + + + + + ... + + + + + + + Enabled + + + + + Mode: + + + + + <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> + + + + + Normal + + + + + Gradient + + + + + Pulse + + + + + Delay: + + + + + 0.10s + + + + + Rate: + + + + + 10.0/s + + + + + + Disabled + + + + + Select Set 1 One Way + + + + + Select Set 1 Two Way + + + + + Select Set 1 While Held + + + + + Select Set 2 One Way + + + + + Select Set 2 Two Way + + + + + Select Set 2 While Held + + + + + Select Set 3 One Way + + + + + Select Set 3 Two Way + + + + + Select Set 3 While Held + + + + + Select Set 4 One Way + + + + + Select Set 4 Two Way + + + + + Select Set 4 While Held + + + + + Select Set 5 One Way + + + + + Select Set 5 Two Way + + + + + Select Set 5 While Held + + + + + Select Set 6 One Way + + + + + Select Set 6 Two Way + + + + + Select Set 6 While Held + + + + + Select Set 7 One Way + + + + + Select Set 7 Two Way + + + + + Select Set 7 While Held + + + + + Select Set 8 One Way + + + + + Select Set 8 Two Way + + + + + Select Set 8 While Held + + + + + sec. + + + + + /sec. + + + + + Set %1 + + + + + + Select Set %1 + + + + + One Way + + + + + Two Way + + + + + While Held + + + + + Choose Executable + + + + + Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. + + + + + Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. + + + + + Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. + + + + + Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. + + + + + Chose a profile to load when this slot is activated. + + + + + Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. + + + + + Specify the time that keys past this slot should be held down. + + + + + Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. + + + + + Change to selected set once slot is activated. + + + + + Full string will be typed when a slot is activated. + + + + + Execute program when slot is activated. + + + + + + Choose Profile + + + + + Config Files (*.amgp *.xml) + + + + + AdvanceStickAssignmentDialog + + + Stick/Pad Assignment + + + + + Sticks + + + + + DPads + + + + + + %1 (Joystick %2) + + + + + Stick 1 + + + + + + + Enabled + + + + + + + + + + Assign + + + + + + X Axis: + + + + + + Y Axis: + + + + + Stick 2 + + + + + Number of Physical DPads: %1 + + + + + Virtual DPad 1 + + + + + Up: + + + + + Down: + + + + + Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. + + + + + Left: + + + + + Right: + + + + + + + + Axis %1 + + + + + + + + Axis %1 - + + + + + + + + Axis %1 + + + + + + + + + Button %1 + + + + + Move stick 1 along the X axis + + + + + Move stick 1 along the Y axis + + + + + Move stick 2 along the X axis + + + + + Move stick 2 along the Y axis + + + + + + + + Press a button or move an axis + + + + + AxisEditDialog + + + Axis + + + + + + Mouse (Horizontal) + + + + + + Mouse (Inverted Horizontal) + + + + + + Mouse (Vertical) + + + + + + Mouse (Inverted Vertical) + + + + + + Arrows: Up | Down + + + + + + Arrows: Left | Right + + + + + + Keys: W | S + + + + + + Keys: A | D + + + + + + NumPad: KP_8 | KP_2 + + + + + + NumPad: KP_4 | KP_6 + + + + + + + None + + + + + + Set the value to use as the limit for an axis. Useful for a +worn out analog stick. + + + + + Negative Half Throttle + + + + + Positive Half Throttle + + + + + Name: + + + + + Specify the name of an axis. + + + + + Mouse Settings + + + + + + Set the value of the dead zone for an axis. + + + + + Presets: + + + + + Dead Zone: + + + + + Max Zone: + + + + + + [NO KEY] + + + + + Throttle setting that determines the behavior of how to +interpret an axis hold or release. + + + + + Negative Throttle + + + + + Normal + + + + + Positive Throttle + + + + + Current Value: + + + + + Set + + + + + Set %1 + + + + + Left Mouse Button + + + + + Right Mouse Button + + + + + ButtonEditDialog + + + Dialog + + + + + To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab + + + + + Placeholder + + + + + Toggle + + + + + Enables a key press or release to only occur when a controller button is pressed. + + + + + Enables rapid key presses and releases. Turbo controller. + + + + + Turbo + + + + + Current: + + + + + Slots + + + + + Na&me: + + + + + Specify the name of a button. + + + + + Action: + + + + + Specify the action that will be performed in game while +this button is being used. + + + + + Advanced + + + + + Set + + + + + Set %1 + + + + + CapturedWindowInfoDialog + + + Captured Window Properties + + + + + Information About Window + + + + + Class: + + + + + + + TextLabel + + + + + Title: + + + + + Path: + + + + + Match By Properties + + + + + Class + + + + + Title + + + + + Path + + + + + Full Path + + + + + File Name + + + + + CommandLineUtility + + + + Profile location %1 is not an XML file. + + + + + + Profile location %1 does not exist. + + + + + An invalid set number '%1' was specified. + + + + + Controller identifier '%s'' is not a valid value. + + + + + No display string was specified. + + + + + + + Controller identifier is not a valid value. + + + + + No set number was specified. + + + + + No controller was specified. + + + + + An invalid event generator was specified. + + + + + No event generator string was specified. + + + + + Qt style flag was detected but no style was specified. + + + + + No log level specified. + + + + + + + + antimicro version + + + + + + Usage: antimicro [options...] [profile] + + + + + + Options + + + + + + Print help text. + + + + + + Print version information. + + + + + + Launch program in system tray only. + + + + + + Launch program with the tray menu disabled. + + + + + + Launch program without the main window + displayed. + + + + + + Launch program with the configuration file + selected as the default for selected + controllers. Defaults to all controllers. + + + + + + Apply configuration file to a specific + controller. Value can be a + controller index, name, or GUID. + + + + + + Unload currently enabled profile(s). + Value can be a controller index, name, or GUID. + + + + + + Start joysticks on a specific set. + Value can be a controller index, name, or GUID. + + + + + + Advance profile loading set options. + + + + + + Launch program as a daemon. + + + + + + Enable logging. + + + + + + Use specified display for X11 calls. + Useful for ssh. + + + + + + Choose between using XTest support and uinput + support for event generation. Default: xtest. + + + + + + Choose between using SendInput and vmulti + support for event generation. Default: sendinput. + + + + + + Print information about joysticks detected by + SDL. + + + + + + Open game controller mapping window of selected + controller. Value can be a controller index or + GUID. + + + + + DPadContextMenu + + + Mouse (Normal) + + + + + Mouse (Inverted Horizontal) + + + + + Mouse (Inverted Vertical) + + + + + Mouse (Inverted Horizontal + Vertical) + + + + + Arrows + + + + + Keys: W | A | S | D + + + + + NumPad + + + + + None + + + + + Standard + + + + + Eight Way + + + + + 4 Way Cardinal + + + + + 4 Way Diagonal + + + + + Mouse Settings + + + + + DPadEditDialog + + + Dialog + + + + + Presets: + + + + + Mouse (Normal) + + + + + Mouse (Inverted Horizontal) + + + + + Mouse (Inverted Vertical) + + + + + Mouse (Inverted Horizontal + Vertical) + + + + + Arrows + + + + + Keys: W | A | S | D + + + + + NumPad + + + + + None + + + + + Dpad Mode: + + + + + &Name: + + + + + 4 Way Cardinal + + + + + 4 Way Diagonal + + + + + DPad Delay: + + + + + + Time lapsed before a direction change is taken into effect. + + + + + s + + + + + Specify the name of a dpad. + + + + + Mouse Settings + + + + + Standard + + + + + Standard: 8 region dpad with two direction buttons active +when the dpad is in a diagonal region. + +Eight Way: 8 region dpad with each direction having its +own dedicated button. Only one button is ever active at +at time. Useful for rougelike games. + +4 Way Cardinal: 4 region dpad with regions corresponding to +the cardinal directions of the dpad. Useful for menus. + +4 Way Diagonal: 4 region dpad with each region corresponding +to a diagonal zone. + + + + + Eight Way + + + + + Set + + + + + Set %1 + + + + + EditAllDefaultAutoProfileDialog + + + Default Profile + + + + + Profile: + + + + + Browse + + + + + Open Config + + + + + Profile file path is invalid. + + + + + ExtraProfileSettingsDialog + + + Extra Profile Settings + + + + + Key Press Time: + + + + + 0.00 ms + + + + + Profile Name: + + + + + + + s + + + + + GameController + + + Game Controller + + + + + GameControllerDPad + + + + + DPad + + + + + GameControllerMappingDialog + + + Game Controller Mapping + + + + + <html><head/><body><p>antimicro makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicro will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> + + + + + A + + + + + B + + + + + X + + + + + Y + + + + + Back + + + + + Start + + + + + Guide + + + + + Left Shoulder + + + + + Right Shoulder + + + + + Left Stick Click + + + + + Right Stick Click + + + + + Left Stick X + + + + + Left Stick Y + + + + + Right Stick X + + + + + Right Stick Y + + + + + Left Trigger + + + + + Right Trigger + + + + + DPad Up + + + + + DPad Left + + + + + DPad Down + + + + + DPad Right + + + + + Mapping + + + + + SDL 2 Game Controller Mapping String + + + + + Last Axis Event: + + + + + Current Axis Detection Dead Zone: + + + + + 5000 + + + + + 10000 + + + + + 15000 + + + + + 20000 + + + + + 25000 + + + + + 30000 + + + + + 32000 + + + + + Game Controller Mapping (%1) (#%2) + + + + + Discard Controller Mapping? + + + + + Discard mapping for this controller? + +If discarded, the controller will be reverted to a joystick once you refresh all joysticks. + + + + + GameControllerSet + + + Back + + + + + Guide + + + + + Start + + + + + LS Click + + + + + RS Click + + + + + L Shoulder + + + + + R Shoulder + + + + + L Trigger + + + + + R Trigger + + + + + GameControllerTrigger + + + + + Trigger + + + + + JoyAxis + + + + + Axis + + + + + JoyAxisButton + + + Negative + + + + + Positive + + + + + Unknown + + + + + + + Button + + + + + JoyAxisContextMenu + + + Mouse (Horizontal) + + + + + Mouse (Inverted Horizontal) + + + + + Mouse (Vertical) + + + + + Mouse (Inverted Vertical) + + + + + Arrows: Up | Down + + + + + Arrows: Left | Right + + + + + Keys: W | S + + + + + Keys: A | D + + + + + NumPad: KP_8 | KP_2 + + + + + NumPad: KP_4 | KP_6 + + + + + + None + + + + + + Mouse Settings + + + + + Left Mouse Button + + + + + Right Mouse Button + + + + + JoyButton + + + Processing turbo for #%1 - %2 + + + + + Finishing turbo for button #%1 - %2 + + + + + Processing press for button #%1 - %2 + + + + + Processing release for button #%1 - %2 + + + + + Distance change for button #%1 - %2 + + + + + + + Button + + + + + + + + [NO KEY] + + + + + [Set %1 1W] + + + + + [Set %1 2W] + + + + + [Set %1 WH] + + + + + JoyButtonContextMenu + + + Toggle + + + + + Turbo + + + + + Clear + + + + + Set Select + + + + + Disabled + + + + + Set %1 + + + + + Set %1 1W + + + + + Set %1 2W + + + + + Set %1 WH + + + + + JoyButtonSlot + + + + Mouse + + + + + Up + + + + + Down + + + + + Left + + + + + Right + + + + + LB + + + + + MB + + + + + RB + + + + + B4 + + + + + B5 + + + + + Pause + + + + + Hold + + + + + Cycle + + + + + Distance + + + + + Release + + + + + Mouse Mod + + + + + Press Time + + + + + Delay + + + + + Load %1 + + + + + Set Change %1 + + + + + [Text] %1 + + + + + [Exec] %1 + + + + + [NO KEY] + + + + + JoyControlStick + + + + + Stick + + + + + JoyControlStickButton + + + + + Up + + + + + + + Down + + + + + + + Left + + + + + + + Right + + + + + + + Button + + + + + JoyControlStickContextMenu + + + Mouse (Normal) + + + + + Mouse (Inverted Horizontal) + + + + + Mouse (Inverted Vertical) + + + + + Mouse (Inverted Horizontal + Vertical) + + + + + Arrows + + + + + Keys: W | A | S | D + + + + + NumPad + + + + + None + + + + + Standard + + + + + Eight Way + + + + + 4 Way Cardinal + + + + + 4 Way Diagonal + + + + + Mouse Settings + + + + + JoyControlStickEditDialog + + + Dialog + + + + + X: + + + + + + + + + 0 + + + + + Y: + + + + + Distance: + + + + + Presets: + + + + + Mouse (Normal) + + + + + Mouse (Inverted Horizontal) + + + + + Mouse (Inverted Vertical) + + + + + Mouse (Inverted Horizontal + Vertical) + + + + + Arrows + + + + + Keys: W | A | S | D + + + + + NumPad + + + + + None + + + + + Stick Mode: + + + + + Standard: 8 region stick with two direction buttons active +when the stick is in a diagonal region. + +Eight Way: 8 region stick with each direction having its +own dedicated button. Only one button is ever active at +at time. Useful for rougelike games. + +4 Way Cardinal: 4 region stick with regions corresponding to +the cardinal directions of the stick. Useful for menus. + +4 Way Diagonal: 4 region stick with each region corresponding +to a diagonal zone of the stick. + + + + + 4 Way Cardinal + + + + + 4 Way Diagonal + + + + + + Dead zone value to use for an analog stick. + + + + + + Value when an analog stick is considered moved 100%. + + + + + + The area (in degrees) that each diagonal region occupies. + + + + + Square Stick: + + + + + + Percentage to modify a square stick coordinates to confine values to a circle + + + + + % + + + + + Stick Delay: + + + + + + Time lapsed before a direction change is taken into effect. + + + + + s + + + + + Modifier: + + + + + Edit button that is active while the stick is active. + +This button is useful for assigning zones with +modifier keys that can be used to assign walk/run +functionality to an analog stick. + + + + + PushButton + + + + + Name: + + + + + Specify the name of an analog stick. + + + + + Mouse Settings + + + + + Standard + + + + + Bearing: + + + + + % Safe Zone: + + + + + Eight Way + + + + + Dead Zone: + + + + + Max Zone: + + + + + Diagonal Range: + + + + + Set + + + + + Set %1 + + + + + JoyControlStickModifierButton + + + + + Modifier + + + + + JoyDPad + + + + + DPad + + + + + JoyDPadButton + + + + + Up + + + + + + + Down + + + + + + + Left + + + + + + + Right + + + + + + + Button + + + + + JoyTabWidget + + + + + + + + <New> + + + + + + Remove + + + + + + Remove configuration from recent list. + + + + + + Load + + + + + + Load configuration file. + + + + + + Save + + + + + + Save changes to configuration file. + + + + + + Save As + + + + + + Save changes to a new configuration file. + + + + + + Sets + + + + + Copy from Set + + + + + Settings + + + + + + Set 1 + + + + + + Set 2 + + + + + + Set 3 + + + + + + Set 4 + + + + + + Set 5 + + + + + + Set 6 + + + + + + Set 7 + + + + + + Set 8 + + + + + + Stick/Pad Assign + + + + + + Controller Mapping + + + + + + Quick Set + + + + + + Names + + + + + + Toggle button name displaying. + + + + + + Pref + + + + + + Change global profile settings. + + + + + + + Reset + + + + + + Revert changes to the configuration. Reload configuration file. + + + + + Open Config + + + + + Config Files (*.amgp *.xml) + + + + + + + Config File (*.%1.amgp) + + + + + + Save Profile Changes? + + + + + + Changes to the new profile have not been saved. Would you like to save or discard the current profile? + + + + + + Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? + + + + + Sticks + + + + + + DPads + + + + + No buttons have been assigned. Please use Quick Set to assign keys +to buttons or disable hiding empty buttons. + + + + + + Set %1: %2 + + + + + + Set %1 + + + + + Copy Set Assignments + + + + + Are you sure you want to copy the assignments and device properties from %1? + + + + + + + Save Config + + + + + + Set + + + + + Joystick + + + Joystick + + + + + JoystickStatusWindow + + + Properties + + + + + Details + + + + + Name: + + + + + + + + + + + %1 + + + + + Number: + + + + + Axes: + + + + + Buttons: + + + + + Hats: + + + + + GUID: + + + + + Game Controller: + + + + + Axes + + + + + Buttons + + + + + Hats + + + + + %1 (#%2) Properties + + + + + Axis %1 + + + + + Hat %1 + + + + + No + + + + + Yes + + + + + MainSettingsDialog + + + Edit Settings + + + + + General + + + + + Controller Mappings + + + + + Language + + + + + Auto Profile + + + + + Mouse + + + + + <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> + + + + + Recent Profile Count: + + + + + <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> + + + + + Gamepad Poll Rate: + + + + + Change the poll rate that the program uses to discover new +events from gamepads. Defaults to 10 ms. + +Reducing the poll rate value could cause the application to +use more CPU power so please test the setting that you use +before using antimicro unattended. + + + + + Hide main window when the main window close button is +clicked instead of quitting the program. + + + + + Close To Tray + + + + + Have Windows start antimicro at system startup. + + + + + Launch At Windows Startup + + + + + Display recent profiles for all controllers +as a single list in the tray menu. Defaults +to using sub-menus. + + + + + Single Profile List in Tray + + + + + Have the program minimize to the taskbar. +By default, the program minimizes to the system +tray if available. + + + + + Minimize to Taskbar + + + + + This option will cause the program to hide all +buttons that have no slots assigned to them. +The Quick Set dialog window will have to be used +to bring up the edit dialog for gamepad buttons. + + + + + Hide Empty Buttons + + + + + When the program is launched, open the last +known profile that was opened during the +previous session. + + + + + Auto Load Last Opened Profile + + + + + Only show the system tray icon when the program +first launches. + + + + + Launch in Tray + + + + + Associate .amgp files with antimicro in Windows Explorer. + + + + + Associate Profiles + + + + + Key Repeat + + + + + Active keys will be repeatedly pressed when this +option is enabled. + + + + + + Enable + + + + + Specifies how much time should elapse before key repeating +begins. + + + + + Specifies how many times key presses will be performed +per seconds. + + + + + <html><head/><body><p>antimicro has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make antimicro load a different translation depending on the language that you choose from the list below.</p></body></html> + + + + + French + + + + + Japanese + + + + + Russian + + + + + Serbian + + + + + Simplified Chinese + + + + + Ukrainian + + + + + Class + + + + + Title + + + + + Program + + + + + Disable the "Enhanced Pointer Precision" Windows setting +while antimicro is running. Disabling "Enhanced Pointer Precision" +will allow mouse movement within antimicro to be more +precise. + + + + + Disable Enhance Pointer Precision + + + + + Smoothing + + + + + Histor&y Size: + + + + + Weight &Modifier: + + + + + Refresh Rate: + + + + + The refresh rate is the amount of time that will elapse +in between mouse events. Please be cautious when +editing this setting as it will cause the program to use +more CPU power. Setting this value too low can cause +system instability. Please test the setting before using +it unattended. + + + + + Spring + + + + + Screen: + + + + + Utilize the specified screen for spring mode. On Linux, the +default is to use the primary screen. On Windows, the default +is to use all available screens. + + + + + Accel Numerator: + + + + + + + 0 + + + + + Accel Denominator: + + + + + Accel Threshold: + + + + + If the acceleration values for the virtual mouse have been +changed by a different process, particularly when quitting +an older game, then you might want to reset the acceleration +values used by the virtual mouse. + + + + + Reset Acceleration + + + + + Delay: + + + + + Profi&le Directory: + + + + + ms + + + + + Rate: + + + + + times/s + + + + + Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. + +Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. + + + + + GUID + + + + + Mapping String + + + + + Disable? + + + + + + Delete + + + + + Insert + + + + + + Default + + + + + Brazilian Portuguese + + + + + English + + + + + German + + + + + + Active + + + + + Devices: + + + + + + All + + + + + Device + + + + + Profile + + + + + Default? + + + + + Add + + + + + Edit + + + + + Also, Windows users who want to use a low value should also check the +"Disable Enhance Pointer Precision" checkbox if you haven't disabled +the option in Windows. + + + + + Select Default Profile Directory + + + + + Are you sure you want to delete the profile? + + + + + MainWindow + + + antimicro + + + + + No Joysticks have been found. + Please plug in a joystick and then choose the "Update Joysticks" option in the main menu + + + + + If events are not seen by a game, please click here to run this application as the Adminstrator. + + + + + &App + + + + + &Options + + + + + &Help + + + + + + &Quit + + + + + Ctrl+Q + + + + + + &Update Joysticks + + + + + Ctrl+U + + + + + + &Hide + + + + + Ctrl+H + + + + + &About + + + + + Ctrl+A + + + + + About Qt + + + + + Properties + + + + + Key Checker + + + + + Home Page + + + + + GitHub Page + + + + + Game Controller Mapping + + + + + Settings + + + + + Stick/Pad Assign + + + + + Wiki + + + + + Could not find a proper controller identifier. Exiting. + + + + + + + + + + + (%1) + + + + + + Open File + + + + + &Restore + + + + + Run as Administrator? + + + + + Are you sure that you want to run this program as Adminstrator? + +Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. + + + + + Failed to elevate program + + + + + Failed to restart this program as the Administrator + + + + + Could not find controller. Exiting. + + + + + MouseAxisSettingsDialog + + + Mouse Settings - + + + + + Set %1 + + + + + MouseButtonSettingsDialog + + + Mouse Settings - + + + + + Set %1 + + + + + MouseControlStickSettingsDialog + + + Mouse Settings + + + + + Set %1 + + + + + MouseDPadSettingsDialog + + + Mouse Settings + + + + + Set %1 + + + + + MouseSettingsDialog + + + Mouse Settings + + + + + Mouse Mode: + + + + + Cursor mode is used to move the mouse cursor +around the screen relative to its current position +depending on how much you move an axis +or if a button is pressed. + +Spring mode is used to move the mouse cursor +from the center of the screen depending on how +much you move an axis. The mouse cursor will +be returned to the center of the screen when the +axis is moved back to the dead zone. + + + + + Cursor + + + + + Spring + + + + + Acceleration: + + + + + Enhanced Precision + + + + + + Linear + + + + + Quadratic + + + + + Cubic + + + + + Quadratic Extreme + + + + + Power Function + + + + + Easing Quadratic + + + + + Easing Cubic + + + + + Mouse Speed Settings + + + + + Enable to change the horizontal and vertical speed +boxes at the same time. + + + + + Change Together + + + + + Horizontal +Speed: + + + + + + 1 = 20 pps + + + + + Vertical +Speed: + + + + + Wheel Hori. +Speed: + + + + + Set the speed used for horizontal mouse wheel movement +according to number of simulated notches per second. + + + + + Set the speed used for vertical mouse wheel movement +according to number of simulated notches per second. + + + + + For Power Function acceleration curve. Specifies +the factor to use for curve sensitivity. When the value +is above 1.0, the mouse movement will be accelerated +faster at the low end of an axis. + + + + + Easing Duration: + + + + + + s + + + + + Extra Acceleration + + + + + Multiplier: + + + + + Highest value to accelerate mouse movement by + + + + + x + + + + + Start %: + + + + + Acceleration begins at this percentage of the base multiplier + + + + + Min +Threshold: + + + + + Minimum amount of axis travel required for acceleration to begin + + + + + Max +Threshold: + + + + + Maximum axis travel before acceleration has reached the multiplier value + + + + + Curve: + + + + + Ease Out Sine + + + + + Ease Out Quad + + + + + Ease Out Cubic + + + + + Release Radius: + + + + + Specifies that the spring area will be relative to the +mouse position set by a non-relative spring. + + + + + Relative + + + + + Mouse Status + + + + + X: + + + + + + 0 (0 pps) + + + + + Y: + + + + + + 1 = 1 notch(es)/s + + + + + Enhanced: Three tier curve that makes the mouse move +slow on the low end of an axis and fast on the high end. + +Linear: Mouse moves proportionally to axis. + +Quadratic: Mouse accelerates slowly on low end. + +Cubic: Mouse accelerates slower than Quadratic. + +Quadratic Extreme: Raises mouse speed 1.5 times once +95% axis travel has been reached. + +Power Function: Allows for a more custom curve option. + +Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. + +Easing Cubic: Axis high end is gradually accelerated over +a period of time using a Cubic curve. + + + + + Wheel Vert. +Speed: + + + + + Sensitivity: + + + + + Specifies the amount of time (in seconds) that will +be required before the mouse is fully accelerated +after reaching the high end of an axis. + + + + + Options for adding extra acceleration to the mouse +movement beyond what the acceleration curve would +produce. This is meant to help work around some of +the issues of the very limited input range available using +typical gamepad analog sticks. + + + + + + + + % + + + + + Extra Duration: + + + + + Extend the time that extra acceleration is applied. Axis travel +will be taken into account. A slower flick will decrease the +actual time that extra acceleration will be applied. + + + + + Spring Settings + + + + + Spring Width: + + + + + Changes the width of the region that the cursor +can move in spring mode. 0 will use the entire width +of your screen. + + + + + Spring Height: + + + + + Changes the height of the region that the cursor +can move in spring mode. 0 will use the entire height +of your screen. + + + + + + %n notch(es)/s + + %n notch/s + %n notches/s + + + + + QKeyDisplayDialog + + + Key Checker + + + + + <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by antimicro.</p><p>The antimicro key value and the Qt key value will usually be the same. antimicro tries to use the key values defined in Qt when possible. Check the page <a href="http://qt-project.org/doc/qt-4.8/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://qt-project.org/doc/qt-4.8/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to antimicro's <a href="https://github.com/Ryochan7/antimicro"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> + + + + + Event Handler: + + + + + Native Key Value: + + + + + + + 0x00000000 + + + + + Qt Key Value: + + + + + antimicro Key Value: + + + + + QObject + + + Super + + + + + Menu + + + + + Mute + + + + + Vol+ + + + + + Vol- + + + + + Play/Pause + + + + + Play + + + + + Pause + + + + + Prev + + + + + Next + + + + + Mail + + + + + Home + + + + + Media + + + + + Search + + + + + Daemon launched + + + + + Failed to launch daemon + + + + + Launching daemon + + + + + + Display string "%1" is not valid. + + + + + Failed to set a signature id for the daemon + + + + + Failed to change working directory to / + + + + + Quitting Program + + + + + # of joysticks found: %1 + + + + + List Joysticks: + + + + + --------------- + + + + + Joystick %1: + + + + + Index: %1 + + + + + GUID: %1 + + + + + Name: %1 + + + + + Yes + + + + + No + + + + + Game Controller: %1 + + + + + # of Axes: %1 + + + + + # of Buttons: %1 + + + + + # of Hats: %1 + + + + + Attempting to use fallback option %1 for event generation. + + + + + Failed to open event generator. Exiting. + + + + + Using %1 as the event generator. + + + + + Could not raise process priority. + + + + + QuickSetDialog + + + Quick Set + + + + + <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> + + + + + Quick Set %1 + + + + + SetAxisThrottleDialog + + + Throttle Change + + + + + The throttle setting for Axis %1 has been changed. + +Would you like to distribute this throttle change to all sets? + + + + + SetJoystick + + + Set %1: %2 + + + + + Set %1 + + + + + SetNamesDialog + + + Set Name Settings + + + + + Set 1 + + + + + Set 2 + + + + + Set 3 + + + + + Set 4 + + + + + Set 5 + + + + + Set 6 + + + + + Set 7 + + + + + Set 8 + + + + + Name + + + + + SimpleKeyGrabberButton + + + Mouse + + + + + SpringModeRegionPreview + + + Spring Mode Preview + + + + + UInputEventHandler + + + Could not find a valid uinput device file. +Please check that you have the uinput module loaded. +lsmod | grep uinput + + + + + Could not open uinput device file +Please check that you have permission to write to the device + + + + + Using uinput device file %1 + + + + + UInputHelper + + + a + + + + + b + + + + + c + + + + + d + + + + + e + + + + + f + + + + + g + + + + + h + + + + + i + + + + + j + + + + + k + + + + + l + + + + + m + + + + + n + + + + + o + + + + + p + + + + + q + + + + + r + + + + + s + + + + + t + + + + + u + + + + + v + + + + + w + + + + + x + + + + + y + + + + + z + + + + + Esc + + + + + F1 + + + + + F2 + + + + + F3 + + + + + F4 + + + + + F5 + + + + + F6 + + + + + F7 + + + + + F8 + + + + + F9 + + + + + F10 + + + + + F11 + + + + + F12 + + + + + ` + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + 9 + + + + + 0 + + + + + + - + + + + + = + + + + + BackSpace + + + + + Tab + + + + + [ + + + + + ] + + + + + \ + + + + + CapsLock + + + + + ; + + + + + ' + + + + + Enter + + + + + Shift_L + + + + + , + + + + + + . + + + + + + / + + + + + Ctrl_L + + + + + + Super_L + + + + + Alt_L + + + + + Space + + + + + Alt_R + + + + + Menu + + + + + Ctrl_R + + + + + Shift_R + + + + + Up + + + + + Left + + + + + Down + + + + + Right + + + + + PrtSc + + + + + Ins + + + + + Del + + + + + Home + + + + + End + + + + + PgUp + + + + + PgDn + + + + + NumLock + + + + + * + + + + + + + + + + + KP_Enter + + + + + KP_1 + + + + + KP_2 + + + + + KP_3 + + + + + KP_4 + + + + + KP_5 + + + + + KP_6 + + + + + KP_7 + + + + + KP_8 + + + + + KP_9 + + + + + KP_0 + + + + + SCLK + + + + + Pause + + + + + Super_R + + + + + Mute + + + + + VolDn + + + + + VolUp + + + + + Play + + + + + Stop + + + + + Prev + + + + + Next + + + + + [NO KEY] + + + + + UnixWindowInfoDialog + + + Captured Window Properties + + + + + Information About Window + + + + + Class: + + + + + + + TextLabel + + + + + Title: + + + + + Path: + + + + + Match By Properties + + + + + Class + + + + + Title + + + + + Path + + + + + VDPad + + + + + VDPad + + + + + VirtualKeyPushButton + + + Space + + + + + Tab + + + + + Shift (L) + + + + + Shift (R) + + + + + Ctrl (L) + + + + + Ctrl (R) + + + + + Alt (L) + + + + + + Alt (R) + + + + + ` + + + + + ~ + + + + + + - + + + + + = + + + + + [ + + + + + ] + + + + + \ + + + + + Caps + + + + + ; + + + + + ' + + + + + , + + + + + + . + + + + + + / + + + + + ESC + + + + + PRTSC + + + + + SCLK + + + + + INS + + + + + PGUP + + + + + DEL + + + + + PGDN + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + 9 + + + + + 0 + + + + + NUM +LK + + + + + + * + + + + + + + + + + + E +N +T +E +R + + + + + < + + + + + : + + + + + Super (L) + + + + + Menu + + + + + Up + + + + + Down + + + + + Left + + + + + Right + + + + + VirtualKeyboardMouseWidget + + + + Keyboard + + + + + + Mouse + + + + + Mouse Settings + + + + + Left + Mouse + + + + + Up + Mouse + + + + + Left Button + Mouse + + + + + Middle Button + Mouse + + + + + Right Button + Mouse + + + + + Wheel Up + Mouse + + + + + Wheel Left + Mouse + + + + + Wheel Right + Mouse + + + + + Wheel Down + Mouse + + + + + Down + Mouse + + + + + Right + Mouse + + + + + Button 4 + Mouse + + + + + Mouse 8 + Mouse + + + + + Button 5 + Mouse + + + + + Mouse 9 + Mouse + + + + + NONE + + + + + Applications + + + + + Browser Back + + + + + Browser Favorites + + + + + Browser Forward + + + + + Browser Home + + + + + Browser Refresh + + + + + Browser Search + + + + + Browser Stop + + + + + Calc + + + + + Email + + + + + Media + + + + + Media Next + + + + + Media Play + + + + + Media Previous + + + + + Media Stop + + + + + Search + + + + + Volume Down + + + + + Volume Mute + + + + + Volume Up + + + + + VirtualMousePushButton + + + INVALID + + + + + WinAppProfileTimerDialog + + + + Capture Application + + + + + After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. + + + + + Timer: + + + + + Seconds + + + + + Cancel + + + + + WinExtras + + + [NO KEY] + + + + + AntiMicro Profile + + + + + X11Extras + + + ESC + + + + + Tab + + + + + Space + + + + + DEL + + + + + Return + + + + + KP_Enter + + + + + Backspace + + + + + xinput extension was not found. No mouse acceleration changes will occur. + + + + + + xinput version must be at least 2.0. No mouse acceleration changes will occur. + + + + + Virtual pointer found with id=%1. + + + + + PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 + + + + + Changing mouse acceleration for device with id=%1 + + + + + XMLConfigReader + + + Could not write updated profile XML to file %1. + + + + + XMLConfigWriter + + + Could not write to profile at %1. + + + + diff --git a/share/antimicro/translations/antimicro_fr.ts b/share/antimicro/translations/antimicro_fr.ts new file mode 100644 index 0000000..cdc4109 --- /dev/null +++ b/share/antimicro/translations/antimicro_fr.ts @@ -0,0 +1,5920 @@ + + + + + AboutDialog + + + About + À propos + + + + Version + + + + + Info + + + + + Changelog + + + + + Since December 30, 2012, I have been working on antimicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. + +The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. + +Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. + +Once the Steam controller is finally released to the public, the need for this program might not exist anymore. Just based on the concept of the controller alone, the Steam controller would have so many advantages over using a program like this to provide KB+M emulation. + + + + + Copyright: 2013 - 2015 + + + + + Credits + Crédits + + + + antimicro + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Travis Nickles &lt;nickles.travis@gmail.com&gt;</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Contributors:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;"><br /></span>Zerro Alvein</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">aybe</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Jeff Backus &lt;jeff.backus@gmail.com&gt;</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Arthur Moore<br />Anton Tornqvist &lt;antont@inbox.lv&gt;</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Translators:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt; font-weight:600;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">zzpxyx - Chinese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">phob - German</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tou omiya - Japanese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">burunduk - Ukrainian</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Version 3, 29 June 2007</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Preamble</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">TERMS AND CONDITIONS</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">0. Definitions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">1. Source Code.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">2. Basic Permissions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">4. Conveying Verbatim Copies.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">5. Conveying Modified Source Versions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">6. Conveying Non-Source Forms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">7. Additional Terms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">8. Termination.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">11. Patents.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">14. Revised Versions of this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">15. Disclaimer of Warranty.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">16. Limitation of Liability.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> + + + + + About Development + + + + + License + License + + + + Program Version %1 + + + + + Program Compiled on %1 at %2 + + + + + Built Against SDL %1 + + + + + Running With SDL %1 + + + + + Using Qt %1 + + + + + Using Event Handler: %1 + + + + + AddEditAutoProfileDialog + + + Auto Profile Dialog + + + + + Profile: + + + + + + Browse + + + + + Window: + + + + + + Select Window. Click on the appropriate application +window and the application file path will be populated +in the form. + + + + + Detect Window Properties + + + + + Class: + + + + + Title: + + + + + Application: + + + + + Select + + + + + Devices: + + + + + + Select this profile to be the default loaded for +the specified device. The selection will be used instead +of the all default profile option. + + + + + Set as Default for Controller + + + + + + A different profile is already selected as the default for this device. + + + + + Current (%1) + + + + + Open Config + Charger un fichier de configuration + + + + + Select Program + + + + + Programs (*.exe) + + + + + Please use the main default profile selection. + + + + + Please select a window by using the mouse. Press Escape if you want to cancel. + + + + + Capture Application Window + + + + + Could not obtain information for the selected window. + + + + + Application Capture Failed + + + + + Profile file path is invalid. + + + + + No window matching property was specified. + + + + + Program path is invalid or not executable. + + + + + File is not an .exe file. + + + + + No window matching property was selected. + + + + + AdvanceButtonDialog + + + + Advanced + Avancé + + + + Assignments + Assignements + + + + Toggle + Maintient de la pression + + + + Turbo + Turbo + + + + Set Selector + Séléction de réglage + + + + Blank or KB/M + + + + + Hold + Maintenir + + + + Pause + Pause + + + + Cycle + Cycle + + + + Distance + Distance + + + + Insert + Insérer + + + + Delete + Supprimer + + + + Clear All + Nettoyer + + + + Time: + Temps : + + + + 0.01s + 0,01s + + + + 0s + 0s + + + + Insert a pause that occurs in between key presses. + Insére une pause de la durée indiquée entre la pression des touches. + + + + Release + Relâchement + + + + + Insert a new blank slot. + Insere un nouvel emplacement vide. + + + + Delete a slot. + Supprime un emplacement. + + + + Clear all currently assigned slots. + Supprime tous les emplacements assignés. + + + + Specify the duration of an inserted Pause or Hold slot. + Spécifie la durée de Pause ou de Maintien. + + + + 0m + 0m + + + + + Specify the range past an axis dead zone in which a sequence of actions will execute. + Spécifie la distance par rapport à la zone morte pour exécuter la suite des actions. + + + + Distance: + Distance : + + + + + % + % + + + + Mouse Mod + Mode de la Souris + + + + Press Time + + + + + Delay + + + + + Execute + + + + + Load + Charger + + + + Set Change + + + + + Text Entry + + + + + Placeholder + Espace réservé + + + + + 0 + 0 + + + + Mouse Speed Mod: + Vitesse du Mode de la Souris : + + + + Set the percentage that mouse speeds will be modified by. + Régler toutes les vitesses de la souris avec le pourcentage spécifié. + + + + Auto Reset Cycle After + + + + + seconds + + + + + ... + + + + + + + Enabled + Activé + + + + Mode: + + + + + <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> + + + + + Normal + Normal + + + + Gradient + + + + + Pulse + + + + + Delay: + Intervalle : + + + + 0.10s + 0,10s + + + + Rate: + Taux : + + + + 10.0/s + 10,0/s + + + + + Disabled + Désactivé + + + + Select Set 1 One Way + Séléction du réglage N°1 : Aller + + + + Select Set 1 Two Way + Séléction du réglage N°1 : Aller-Retour + + + + Select Set 1 While Held + Séléction du réglage N°1 : Pendant la pression + + + + Select Set 2 One Way + Séléction du réglage N°2 : Aller + + + + Select Set 2 Two Way + Séléction du réglage N°2 : Aller-Retour + + + + Select Set 2 While Held + Séléction du réglage N°2 : Pendant la pression + + + + Select Set 3 One Way + Séléction du réglage N°3 : Aller + + + + Select Set 3 Two Way + Séléction du réglage N°3 : Aller-Retour + + + + Select Set 3 While Held + Séléction du réglage N°3 : Pendant la pression + + + + Select Set 4 One Way + Séléction du réglage N°4 : Aller + + + + Select Set 4 Two Way + Séléction du réglage N°4 : Aller-Retour + + + + Select Set 4 While Held + Séléction du réglage N°4 : Pendant la pression + + + + Select Set 5 One Way + Séléction du réglage N°5 : Aller + + + + Select Set 5 Two Way + Séléction du réglage N°5 : Aller-Retour + + + + Select Set 5 While Held + Séléction du réglage N°5 : Pendant la pression + + + + Select Set 6 One Way + Séléction du réglage N°6 : Aller + + + + Select Set 6 Two Way + Séléction du réglage N°6 : Aller-Retour + + + + Select Set 6 While Held + Séléction du réglage N°6 : Pendant la pression + + + + Select Set 7 One Way + Séléction du réglage N°7 : Aller + + + + Select Set 7 Two Way + Séléction du réglage N°7 : Aller-Retour + + + + Select Set 7 While Held + Séléction du réglage N°7 : Pendant la pression + + + + Select Set 8 One Way + Séléction du réglage N°8 : Aller + + + + Select Set 8 Two Way + Séléction du réglage N°8 : Aller-Retour + + + + Select Set 8 While Held + Séléction du réglage N°8 : Pendant la pression + + + + sec. + + + + + /sec. + + + + + Set %1 + + + + + + Select Set %1 + + + + + One Way + + + + + Two Way + + + + + While Held + + + + + Choose Executable + + + + + Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. + + + + + Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. + + + + + Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. + + + + + Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. + + + + + Chose a profile to load when this slot is activated. + + + + + Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. + + + + + Specify the time that keys past this slot should be held down. + + + + + Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. + + + + + Change to selected set once slot is activated. + + + + + Full string will be typed when a slot is activated. + + + + + Execute program when slot is activated. + + + + + + Choose Profile + + + + + Config Files (*.amgp *.xml) + + + + + AdvanceStickAssignmentDialog + + + Stick/Pad Assignment + Assignement du Stick/Pad + + + + Sticks + Sticks + + + + DPads + DPads + + + + + %1 (Joystick %2) + %1 (Manette %2) + + + + Stick 1 + Stick 1 + + + + + + Enabled + Activé + + + + + + + + + Assign + Assigner + + + + + X Axis: + Axe X : + + + + + Y Axis: + Axe Y : + + + + Stick 2 + Stick 2 + + + + Number of Physical DPads: %1 + Numéro du DPads Physique : %1 + + + + Virtual DPad 1 + DPad Virtuel 1 + + + + Up: + Haut : + + + + Down: + Bas : + + + + Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. + + + + + Left: + Gauche : + + + + Right: + Droite : + + + + + + + Axis %1 + Axe %1 + + + + + + + Axis %1 - + Axe %1 - + + + + + + + Axis %1 + + Axe %1 + + + + + + + + Button %1 + Bouton %1 + + + + Move stick 1 along the X axis + Déplacer le stick 1 selon l'axe X + + + + Move stick 1 along the Y axis + Déplacer le stick 1 selon l'axe Y + + + + Move stick 2 along the X axis + Déplacer le stick 2 selon l'axe X + + + + Move stick 2 along the Y axis + Déplacer le stick 1 selon l'axe Y + + + + + + + Press a button or move an axis + Presser un bouton ou bouger un axe + + + + AxisEditDialog + + + Axis + Axe + + + + + Mouse (Horizontal) + Souris (Horizontal) + + + + + Mouse (Inverted Horizontal) + Souris (Horizontal Inversé) + + + + + Mouse (Vertical) + Souris (Vertical) + + + + + Mouse (Inverted Vertical) + Souris (Vertical Inversé) + + + + + Arrows: Up | Down + Flèches : Haut | Bas + + + + + Arrows: Left | Right + Flèches : Gauche | Droite + + + + + Keys: W | S + Touches : W | S + + + + + Keys: A | D + Touches : A | D + + + + + NumPad: KP_8 | KP_2 + Pavé Numérique : KP_8 | KP_2 + + + + + NumPad: KP_4 | KP_6 + Pavé Numérique : KP_4 | KP_6 + + + + + + None + Aucun + + + + + Set the value to use as the limit for an axis. Useful for a +worn out analog stick. + + + + + Negative Half Throttle + Demie accélération négative + + + + Positive Half Throttle + Demie accélération positive + + + + Name: + Nom : + + + + Specify the name of an axis. + Indiquer le nom d'un axe. + + + + Mouse Settings + Configurations de la Souris + + + + + Set the value of the dead zone for an axis. + Régler la valeur de la zone morte pour un axe. + + + + Presets: + Pré-réglages : + + + + Dead Zone: + Zone morte : + + + + Max Zone: + Zone maximale : + + + + + [NO KEY] + [AUCUNE TOUCHE] + + + + Throttle setting that determines the behavior of how to +interpret an axis hold or release. + Configure l’accélération qui détermine le comportement +de maintien ou de relâchement d'un axe. + + + + Negative Throttle + Accélération négative + + + + Normal + Normal + + + + Positive Throttle + Accélération positive + + + + Current Value: + Valeur actuelle : + + + + Set + Configuration + + + + Set %1 + + + + + Left Mouse Button + + + + + Right Mouse Button + + + + + ButtonEditDialog + + + Dialog + Dialogue + + + + To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab + Pour assigner une touche à ce bouton, presser celle-ci ou cliquer sur son équivalent graphique dans les onglets clavier et souris + + + + Placeholder + Espace réservé + + + + Toggle + Pression continue + + + + Enables a key press or release to only occur when a controller button is pressed. + Permet d'appuyer ou de relâcher une touche uniquement lorsqu'un bouton est pressé. + + + + Enables rapid key presses and releases. Turbo controller. + Permet d'appuyer et de relâcher très rapidement une touche en maintenant pressé un bouton. Contrôle du Turbo. + + + + Turbo + Turbo + + + + Current: + Actuellement : + + + + Slots + Emplacements + + + + Na&me: + + + + + Specify the name of a button. + Indiquer le nom d'un bouton. + + + + Action: + Action : + + + + Specify the action that will be performed in game while +this button is being used. + Indiquer l'action qui sera exécutée pendnt le jeu +lorsque que ce bouton est utilisé. + + + + Advanced + Avancé + + + + Set + Configuration + + + + Set %1 + + + + + CapturedWindowInfoDialog + + + Captured Window Properties + + + + + Information About Window + + + + + Class: + + + + + + + TextLabel + + + + + Title: + + + + + Path: + + + + + Match By Properties + + + + + Class + + + + + Title + + + + + Path + + + + + Full Path + + + + + File Name + + + + + CommandLineUtility + + + + Profile location %1 is not an XML file. + Le fichier profile %1 n'est pas un fichier XML. + + + + + Profile location %1 does not exist. + Le fichier profile %1 n'existe pas. + + + + An invalid set number '%1' was specified. + + + + + Controller identifier '%s'' is not a valid value. + + + + + No display string was specified. + + + + + + + Controller identifier is not a valid value. + L'identifiant du contrôleur n'est pas une valeur valide. + + + + No set number was specified. + + + + + No controller was specified. + + + + + An invalid event generator was specified. + + + + + No event generator string was specified. + + + + + Qt style flag was detected but no style was specified. + + + + + No log level specified. + + + + + + + + antimicro version + + + + + + Usage: antimicro [options...] [profile] + + + + + + Options + Options + + + + + Print help text. + Affiche le texte d'aide. + + + + + Print version information. + Affiche des informations sur la version. + + + + + Launch program in system tray only. + Lance le logiciel directement dans la zone de notification. + + + + + Launch program with the tray menu disabled. + Lance le logiciel avec le menu de la zone de notification désactivé. + + + + + Launch program without the main window + displayed. + Lance le logiciel sans afficher la fenêtre + principale. + + + + + Launch program with the configuration file + selected as the default for selected + controllers. Defaults to all controllers. + Lance le programme avec le fichier de configuration + séléctionné par défaut pour le contrôleur + choisi. Par défaut, tous les contrôleurs. + + + + + Apply configuration file to a specific + controller. Value can be a + controller index, name, or GUID. + Appliquer le fichier de configuration à un contrôleur + specifique. La valeur peut être un index, + un nom ou le GUID d'un controleur. + + + + + Unload currently enabled profile(s). + Value can be a controller index, name, or GUID. + Déchargé le(s) profil(s) actuellement activés. + La valeur peut être un index, un nom ou le GUID d'un controleur. + + + + + Start joysticks on a specific set. + Value can be a controller index, name, or GUID. + + + + + + Advance profile loading set options. + + + + + + Launch program as a daemon. + + + + + + Enable logging. + + + + + + Use specified display for X11 calls. + Useful for ssh. + + + + + + Choose between using XTest support and uinput + support for event generation. Default: xtest. + + + + + + Choose between using SendInput and vmulti + support for event generation. Default: sendinput. + + + + + + Print information about joysticks detected by + SDL. + + + + + + Open game controller mapping window of selected + controller. Value can be a controller index or + GUID. + + + + + DPadContextMenu + + + Mouse (Normal) + Souris (Normal) + + + + Mouse (Inverted Horizontal) + Souris (Horizontal Inversé) + + + + Mouse (Inverted Vertical) + Souris (Vertical Inversé) + + + + Mouse (Inverted Horizontal + Vertical) + Souris (Vertical et Horizontal Inversés) + + + + Arrows + Flèches + + + + Keys: W | A | S | D + Touches :W | A | S | D + + + + NumPad + + + + + None + + + + + Standard + Standard + + + + Eight Way + Eight Way + + + + 4 Way Cardinal + + + + + 4 Way Diagonal + + + + + Mouse Settings + Configurations de la Souris + + + + DPadEditDialog + + + Dialog + Dialogue + + + + Presets: + Pré-réglages : + + + + Mouse (Normal) + Souris (Normal) + + + + Mouse (Inverted Horizontal) + Souris (Horizontal Inversé) + + + + Mouse (Inverted Vertical) + Souris (Vertical Inversé) + + + + Mouse (Inverted Horizontal + Vertical) + Souris (Vertical et Horizontal Inversés) + + + + Arrows + Flèches + + + + Keys: W | A | S | D + Touches :W | A | S | D + + + + NumPad + Pavé Numérique + + + + None + Aucun + + + + Dpad Mode: + Mode Dpad : + + + + &Name: + + + + + 4 Way Cardinal + + + + + 4 Way Diagonal + + + + + DPad Delay: + + + + + + Time lapsed before a direction change is taken into effect. + + + + + s + + + + + Specify the name of a dpad. + Indiquer le nom d'un dpad. + + + + Mouse Settings + Configurations de la Souris + + + + Standard + Standard + + + + Standard: 8 region dpad with two direction buttons active +when the dpad is in a diagonal region. + +Eight Way: 8 region dpad with each direction having its +own dedicated button. Only one button is ever active at +at time. Useful for rougelike games. + +4 Way Cardinal: 4 region dpad with regions corresponding to +the cardinal directions of the dpad. Useful for menus. + +4 Way Diagonal: 4 region dpad with each region corresponding +to a diagonal zone. + + + + + Eight Way + Eight Way + + + + Set + Configuration + + + + Set %1 + + + + + EditAllDefaultAutoProfileDialog + + + Default Profile + + + + + Profile: + + + + + Browse + + + + + Open Config + Charger un fichier de configuration + + + + Profile file path is invalid. + + + + + ExtraProfileSettingsDialog + + + Extra Profile Settings + + + + + Key Press Time: + + + + + 0.00 ms + + + + + Profile Name: + + + + + + + s + + + + + GameController + + + Game Controller + + + + + GameControllerDPad + + + + + DPad + + + + + GameControllerMappingDialog + + + Game Controller Mapping + Cartographie de contrôleur de jeu + + + + <html><head/><body><p>antimicro makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicro will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> + + + + + A + + + + + B + + + + + X + + + + + Y + + + + + Back + Retour + + + + Start + + + + + Guide + + + + + Left Shoulder + Latéral gauche + + + + Right Shoulder + Latéral droit + + + + Left Stick Click + Clic Stick Gauche + + + + Right Stick Click + Clic Stick Droite + + + + Left Stick X + Stick Gauche X + + + + Left Stick Y + Stick Gauche Y + + + + Right Stick X + Stick Droit X + + + + Right Stick Y + Stick Droit Y + + + + Left Trigger + Gachette gauche + + + + Right Trigger + Gachette droite + + + + DPad Up + DPad Haut + + + + DPad Left + DPad Gauche + + + + DPad Down + DPad Bas + + + + DPad Right + DPad Droit + + + + Mapping + Cartographie + + + + SDL 2 Game Controller Mapping String + + + + + Last Axis Event: + + + + + Current Axis Detection Dead Zone: + + + + + 5000 + 5000 + + + + 10000 + 10000 + + + + 15000 + 15000 + + + + 20000 + 20000 + + + + 25000 + 25000 + + + + 30000 + 30000 + + + + 32000 + 32000 + + + + Game Controller Mapping (%1) (#%2) + + + + + Discard Controller Mapping? + Désactivé la cartographie de contrôleur de jeu ? + + + + Discard mapping for this controller? + +If discarded, the controller will be reverted to a joystick once you refresh all joysticks. + Eliminer la cartographie pour ce contrôleur ? + +S'il est éliminé, le contrôleur redeviendra un joystick une fois tous les joysticks mis à jour. + + + + GameControllerSet + + + Back + Retour + + + + Guide + + + + + Start + + + + + LS Click + + + + + RS Click + + + + + L Shoulder + + + + + R Shoulder + + + + + L Trigger + + + + + R Trigger + + + + + GameControllerTrigger + + + + + Trigger + Gachette + + + + JoyAxis + + + + + Axis + Axe + + + + JoyAxisButton + + + Negative + Négatif + + + + Positive + Positif + + + + Unknown + Inconnu + + + + + + Button + Bouton + + + + JoyAxisContextMenu + + + Mouse (Horizontal) + Souris (Horizontal) + + + + Mouse (Inverted Horizontal) + Souris (Horizontal Inversé) + + + + Mouse (Vertical) + Souris (Vertical) + + + + Mouse (Inverted Vertical) + Souris (Vertical Inversé) + + + + Arrows: Up | Down + Flèches : Haut | Bas + + + + Arrows: Left | Right + Flèches : Gauche | Droite + + + + Keys: W | S + Touches : W | S + + + + Keys: A | D + Touches : A | D + + + + NumPad: KP_8 | KP_2 + Pavé Numérique : KP_8 | KP_2 + + + + NumPad: KP_4 | KP_6 + Pavé Numérique : KP_4 | KP_6 + + + + + None + + + + + + Mouse Settings + Configurations de la Souris + + + + Left Mouse Button + + + + + Right Mouse Button + + + + + JoyButton + + + Processing turbo for #%1 - %2 + + + + + Finishing turbo for button #%1 - %2 + + + + + Processing press for button #%1 - %2 + + + + + Processing release for button #%1 - %2 + + + + + Distance change for button #%1 - %2 + + + + + + + Button + Bouton + + + + + + + [NO KEY] + [AUCUNE TOUCHE] + + + + [Set %1 1W] + + + + + [Set %1 2W] + + + + + [Set %1 WH] + + + + + JoyButtonContextMenu + + + Toggle + + + + + Turbo + Turbo + + + + Clear + + + + + Set Select + + + + + Disabled + Désactivé + + + + Set %1 + + + + + Set %1 1W + + + + + Set %1 2W + + + + + Set %1 WH + + + + + JoyButtonSlot + + + + Mouse + Souris + + + + Up + Haut + + + + Down + Bas + + + + Left + Gauche + + + + Right + Droite + + + + LB + BG + + + + MB + BC + + + + RB + BD + + + + B4 + B4 + + + + B5 + B5 + + + + Pause + Pause + + + + Hold + Maintenir + + + + Cycle + Cycle + + + + Distance + Distance + + + + Release + Relâchement + + + + Mouse Mod + Mode de la Souris + + + + Press Time + + + + + Delay + + + + + Load %1 + + + + + Set Change %1 + + + + + [Text] %1 + + + + + [Exec] %1 + + + + + [NO KEY] + [AUCUNE TOUCHE] + + + + JoyControlStick + + + + + Stick + + + + + JoyControlStickButton + + + + + Up + Haut + + + + + + Down + Bas + + + + + + Left + Gauche + + + + + + Right + Droite + + + + + + Button + Bouton + + + + JoyControlStickContextMenu + + + Mouse (Normal) + Souris (Normal) + + + + Mouse (Inverted Horizontal) + Souris (Horizontal Inversé) + + + + Mouse (Inverted Vertical) + Souris (Vertical Inversé) + + + + Mouse (Inverted Horizontal + Vertical) + Souris (Vertical et Horizontal Inversés) + + + + Arrows + Flèches + + + + Keys: W | A | S | D + Touches :W | A | S | D + + + + NumPad + + + + + None + + + + + Standard + Standard + + + + Eight Way + Eight Way + + + + 4 Way Cardinal + + + + + 4 Way Diagonal + + + + + Mouse Settings + Configurations de la Souris + + + + JoyControlStickEditDialog + + + Dialog + Dialogue + + + + X: + X : + + + + + + + + 0 + 0 + + + + Y: + Y : + + + + Distance: + Distance : + + + + Presets: + Pré-réglages : + + + + Mouse (Normal) + Souris (Normal) + + + + Mouse (Inverted Horizontal) + Souris (Horizontal Inversé) + + + + Mouse (Inverted Vertical) + Souris (Vertical Inversé) + + + + Mouse (Inverted Horizontal + Vertical) + Souris (Vertical et Horizontal Inversés) + + + + Arrows + Flèches + + + + Keys: W | A | S | D + Touches :W | A | S | D + + + + NumPad + NumPad + + + + None + Aucub + + + + Stick Mode: + Mode du Stick : + + + + Standard: 8 region stick with two direction buttons active +when the stick is in a diagonal region. + +Eight Way: 8 region stick with each direction having its +own dedicated button. Only one button is ever active at +at time. Useful for rougelike games. + +4 Way Cardinal: 4 region stick with regions corresponding to +the cardinal directions of the stick. Useful for menus. + +4 Way Diagonal: 4 region stick with each region corresponding +to a diagonal zone of the stick. + + + + + 4 Way Cardinal + + + + + 4 Way Diagonal + + + + + + Dead zone value to use for an analog stick. + + + + + + Value when an analog stick is considered moved 100%. + + + + + + The area (in degrees) that each diagonal region occupies. + + + + + Square Stick: + + + + + + Percentage to modify a square stick coordinates to confine values to a circle + + + + + % + % + + + + Stick Delay: + + + + + + Time lapsed before a direction change is taken into effect. + + + + + s + + + + + Modifier: + + + + + Edit button that is active while the stick is active. + +This button is useful for assigning zones with +modifier keys that can be used to assign walk/run +functionality to an analog stick. + + + + + PushButton + + + + + Name: + Nom : + + + + Specify the name of an analog stick. + Indiquer le nom d'un stick analogue. + + + + Mouse Settings + Configurations de la Souris + + + + Standard + Standard + + + + Bearing: + + + + + % Safe Zone: + + + + + Eight Way + Eight Way + + + + Dead Zone: + Zone morte : + + + + Max Zone: + Zone maximale : + + + + Diagonal Range: + Valleur de diagonale : + + + + Set + Configuration + + + + Set %1 + + + + + JoyControlStickModifierButton + + + + + Modifier + + + + + JoyDPad + + + + + DPad + + + + + JoyDPadButton + + + + + Up + Haut + + + + + + Down + Bas + + + + + + Left + Gauche + + + + + + Right + Droite + + + + + + Button + Bouton + + + + JoyTabWidget + + + + + + + + <New> + <Nouveau> + + + + + Remove + Supprimer + + + + + Remove configuration from recent list. + Supprimer la configuration depuis la liste des recents. + + + + + Load + Charger + + + + + Load configuration file. + Charger un fichier de configuration. + + + + + Save + Enregistrer + + + + + Save changes to configuration file. + Enregistrer les modifications dans le fichier de configuration. + + + + + Save As + Enregistrer Sous + + + + + Save changes to a new configuration file. + Enregistrer les modifications dans un nouveau fichier de configuration. + + + + + Sets + + + + + Copy from Set + + + + + Settings + + + + + + Set 1 + + + + + + Set 2 + + + + + + Set 3 + + + + + + Set 4 + + + + + + Set 5 + + + + + + Set 6 + + + + + + Set 7 + + + + + + Set 8 + + + + + + Stick/Pad Assign + Assignement du Stick/Pad + + + + + Controller Mapping + + + + + + Quick Set + Configuration Rapide + + + + + Names + Noms + + + + + Toggle button name displaying. + Alterner nom du bouton d'affichage. + + + + + Pref + + + + + + Change global profile settings. + + + + + + + Reset + Réinitialiser + + + + + Revert changes to the configuration. Reload configuration file. + Annuler les changements de configuration. Recharger le fichier de configuration. + + + + Open Config + Charger un fichier de configuration + + + + Config Files (*.amgp *.xml) + + + + + + + Config File (*.%1.amgp) + + + + + + Save Profile Changes? + + + + + + Changes to the new profile have not been saved. Would you like to save or discard the current profile? + + + + + + Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? + + + + + Sticks + Sticks + + + + + DPads + DPads + + + + No buttons have been assigned. Please use Quick Set to assign keys +to buttons or disable hiding empty buttons. + + + + + + Set %1: %2 + + + + + + Set %1 + + + + + Copy Set Assignments + + + + + Are you sure you want to copy the assignments and device properties from %1? + + + + + + + Save Config + Enregistrer le fichier de configuration + + + + + Set + Configuration + + + + Joystick + + + Joystick + Manette + + + + JoystickStatusWindow + + + Properties + Propriétés + + + + Details + Détails + + + + Name: + Nom : + + + + + + + + + + %1 + %1 + + + + Number: + Nombre : + + + + Axes: + Axes : + + + + Buttons: + Boutons : + + + + Hats: + Hats : + + + + GUID: + GUID : + + + + Game Controller: + + + + + Axes + Axes + + + + Buttons + Boutons + + + + Hats + Hats + + + + %1 (#%2) Properties + %1 (#%2) Propriétés + + + + Axis %1 + Axe %1 + + + + Hat %1 + Hat %1 + + + + No + + + + + Yes + + + + + MainSettingsDialog + + + Edit Settings + Modifier les paramètres + + + + General + + + + + Controller Mappings + Cartographie de contrôleur + + + + Language + + + + + Auto Profile + + + + + Mouse + Souris + + + + <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> + + + + + Recent Profile Count: + + + + + <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> + + + + + Gamepad Poll Rate: + + + + + Change the poll rate that the program uses to discover new +events from gamepads. Defaults to 10 ms. + +Reducing the poll rate value could cause the application to +use more CPU power so please test the setting that you use +before using antimicro unattended. + + + + + Hide main window when the main window close button is +clicked instead of quitting the program. + + + + + Close To Tray + + + + + Have Windows start antimicro at system startup. + + + + + Launch At Windows Startup + + + + + Display recent profiles for all controllers +as a single list in the tray menu. Defaults +to using sub-menus. + + + + + Single Profile List in Tray + + + + + Have the program minimize to the taskbar. +By default, the program minimizes to the system +tray if available. + + + + + Minimize to Taskbar + + + + + This option will cause the program to hide all +buttons that have no slots assigned to them. +The Quick Set dialog window will have to be used +to bring up the edit dialog for gamepad buttons. + + + + + Hide Empty Buttons + + + + + When the program is launched, open the last +known profile that was opened during the +previous session. + + + + + Auto Load Last Opened Profile + + + + + Only show the system tray icon when the program +first launches. + + + + + Launch in Tray + + + + + Associate .amgp files with antimicro in Windows Explorer. + + + + + Associate Profiles + + + + + Key Repeat + + + + + Active keys will be repeatedly pressed when this +option is enabled. + + + + + + Enable + + + + + Specifies how much time should elapse before key repeating +begins. + + + + + Specifies how many times key presses will be performed +per seconds. + + + + + <html><head/><body><p>antimicro has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make antimicro load a different translation depending on the language that you choose from the list below.</p></body></html> + + + + + French + + + + + Japanese + + + + + Russian + + + + + Serbian + + + + + Simplified Chinese + + + + + Ukrainian + + + + + Class + + + + + Title + + + + + Program + + + + + Disable the "Enhanced Pointer Precision" Windows setting +while antimicro is running. Disabling "Enhanced Pointer Precision" +will allow mouse movement within antimicro to be more +precise. + + + + + Disable Enhance Pointer Precision + + + + + Smoothing + + + + + Histor&y Size: + + + + + Weight &Modifier: + + + + + Refresh Rate: + + + + + The refresh rate is the amount of time that will elapse +in between mouse events. Please be cautious when +editing this setting as it will cause the program to use +more CPU power. Setting this value too low can cause +system instability. Please test the setting before using +it unattended. + + + + + Spring + Ressort + + + + Screen: + + + + + Utilize the specified screen for spring mode. On Linux, the +default is to use the primary screen. On Windows, the default +is to use all available screens. + + + + + Accel Numerator: + + + + + + + 0 + 0 + + + + Accel Denominator: + + + + + Accel Threshold: + + + + + If the acceleration values for the virtual mouse have been +changed by a different process, particularly when quitting +an older game, then you might want to reset the acceleration +values used by the virtual mouse. + + + + + Reset Acceleration + + + + + Delay: + Intervalle : + + + + Profi&le Directory: + + + + + ms + + + + + Rate: + Taux : + + + + times/s + + + + + Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. + +Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. + Voici une liste des cartographies personnalisées qui ont été enregistrées. Utiliser le tableau suivant pour supprimer les cartographies ou désactiver temporairement une cartographie. Il est également possible de désactiver les cartographies qui sont inclus avec SDL, il suffit d'insérer une nouvelle ligne avec le GUID du manette approprié et cocher la case désactiver. + +Les paramètres ne prennent effet que lors de la prochaine réactualisation des joysticks ou en débranchant la manette spécifique. + + + + GUID + + + + + Mapping String + Chaîne de cartographie + + + + Disable? + Désactiver ? + + + + + Delete + Supprimer + + + + Insert + Insérer + + + + + Default + + + + + Brazilian Portuguese + + + + + English + + + + + German + + + + + + Active + + + + + Devices: + + + + + + All + + + + + Device + + + + + Profile + + + + + Default? + + + + + Add + + + + + Edit + + + + + Also, Windows users who want to use a low value should also check the +"Disable Enhance Pointer Precision" checkbox if you haven't disabled +the option in Windows. + + + + + Select Default Profile Directory + + + + + Are you sure you want to delete the profile? + + + + + MainWindow + + + No Joysticks have been found. + Please plug in a joystick and then choose the "Update Joysticks" option in the main menu + Aucune manette n'a été détéctée. + Merci de brancher une manette et de choisir l'option "Mettre à jour les manettes" du menu principal + + + + &App + + + + + Stick/Pad Assign + Assignement du Stick/Pad + + + + &Options + &Options + + + + antimicro + + + + + If events are not seen by a game, please click here to run this application as the Adminstrator. + + + + + &Help + &Aide + + + + + &Quit + &Quitter + + + + Ctrl+Q + Ctrl+Q + + + + + &Update Joysticks + &Mettre à jour les manettes + + + + Ctrl+U + Ctrl+U + + + + + &Hide + &Masquer + + + + Ctrl+H + Ctrl+H + + + + &About + &À propos + + + + Ctrl+A + Ctrl+A + + + + About Qt + À propos de Qt + + + + Properties + Propriétés + + + + Key Checker + Vérificateur de clé + + + + Home Page + Page d'accueil + + + + GitHub Page + Page GitHub + + + + Game Controller Mapping + Cartographie de contrôleur de jeu + + + + Settings + + + + + Wiki + + + + + Could not find a proper controller identifier. Exiting. + + + + + + + + + + + (%1) + + + + + + Open File + Ouvrir fichier + + + + &Restore + &Restaurer + + + + Run as Administrator? + + + + + Are you sure that you want to run this program as Adminstrator? + +Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. + + + + + Failed to elevate program + + + + + Failed to restart this program as the Administrator + + + + + Could not find controller. Exiting. + + + + + MouseAxisSettingsDialog + + + Mouse Settings - + Configurations de la Souris - + + + + Set %1 + + + + + MouseButtonSettingsDialog + + + Mouse Settings - + Configurations de la Souris - + + + + Set %1 + + + + + MouseControlStickSettingsDialog + + + Mouse Settings + Configurations de la Souris + + + + Set %1 + + + + + MouseDPadSettingsDialog + + + Mouse Settings + Configurations de la Souris + + + + Set %1 + + + + + MouseSettingsDialog + + + Mouse Settings + Configurations de la Souris + + + + Mouse Mode: + Mode de la Souris : + + + + Cursor mode is used to move the mouse cursor +around the screen relative to its current position +depending on how much you move an axis +or if a button is pressed. + +Spring mode is used to move the mouse cursor +from the center of the screen depending on how +much you move an axis. The mouse cursor will +be returned to the center of the screen when the +axis is moved back to the dead zone. + Le mode "curseur" est utilisé pour déplacer le +curseur de la souris autour de l'écran par rapport +à sa position actuelle en fonction de la pression +d'un axe ou d'un bouton. + +Le mode "ressort" est utilisé pour déplacer la +souris depuis le centre de l'écran en fonction +de la pression d'un axe. Le curseur de la souris +retourne au centre de l'écran quand l'axe +est déplacé vers la zone morte. + + + + Cursor + Curseur + + + + Spring + Ressort + + + + Acceleration: + Accélération : + + + + Enhanced Precision + + + + + + Linear + Linéair + + + + Quadratic + Quadratique + + + + Cubic + Cubique + + + + Quadratic Extreme + Quadratique Extreme + + + + Power Function + Fonction Énergie + + + + Easing Quadratic + + + + + Easing Cubic + + + + + Mouse Speed Settings + Configurations de la Vitesse de la Souris + + + + Enable to change the horizontal and vertical speed +boxes at the same time. + Activer la modification simultanée des boîtes +de vitesse horizontale et verticale. + + + + Change Together + Modifier en même temps + + + + Horizontal +Speed: + Vitesse +horizontale : + + + + + 1 = 20 pps + 1 = 20 pps + + + + Vertical +Speed: + Vitesse +verticale : + + + + Wheel Hori. +Speed: + Molette Hori. +Vitesse : + + + + Set the speed used for horizontal mouse wheel movement +according to number of simulated notches per second. + + + + + Set the speed used for vertical mouse wheel movement +according to number of simulated notches per second. + + + + + For Power Function acceleration curve. Specifies +the factor to use for curve sensitivity. When the value +is above 1.0, the mouse movement will be accelerated +faster at the low end of an axis. + + + + + Easing Duration: + + + + + + s + + + + + Extra Acceleration + + + + + Multiplier: + + + + + Highest value to accelerate mouse movement by + + + + + x + + + + + Start %: + + + + + Acceleration begins at this percentage of the base multiplier + + + + + Min +Threshold: + + + + + Minimum amount of axis travel required for acceleration to begin + + + + + Max +Threshold: + + + + + Maximum axis travel before acceleration has reached the multiplier value + + + + + Curve: + + + + + Ease Out Sine + + + + + Ease Out Quad + + + + + Ease Out Cubic + + + + + Release Radius: + + + + + Specifies that the spring area will be relative to the +mouse position set by a non-relative spring. + + + + + Relative + + + + + Mouse Status + + + + + X: + X : + + + + + 0 (0 pps) + + + + + Y: + Y : + + + + + 1 = 1 notch(es)/s + 1 = 1 cran(s)/s + + + + Enhanced: Three tier curve that makes the mouse move +slow on the low end of an axis and fast on the high end. + +Linear: Mouse moves proportionally to axis. + +Quadratic: Mouse accelerates slowly on low end. + +Cubic: Mouse accelerates slower than Quadratic. + +Quadratic Extreme: Raises mouse speed 1.5 times once +95% axis travel has been reached. + +Power Function: Allows for a more custom curve option. + +Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. + +Easing Cubic: Axis high end is gradually accelerated over +a period of time using a Cubic curve. + + + + + Wheel Vert. +Speed: + Molette Vert. +Vitesse : + + + + Sensitivity: + Sensibilité : + + + + Specifies the amount of time (in seconds) that will +be required before the mouse is fully accelerated +after reaching the high end of an axis. + + + + + Options for adding extra acceleration to the mouse +movement beyond what the acceleration curve would +produce. This is meant to help work around some of +the issues of the very limited input range available using +typical gamepad analog sticks. + + + + + + + + % + % + + + + Extra Duration: + + + + + Extend the time that extra acceleration is applied. Axis travel +will be taken into account. A slower flick will decrease the +actual time that extra acceleration will be applied. + + + + + Spring Settings + Configuration du Ressort + + + + Spring Width: + Largeur du Ressort : + + + + Changes the width of the region that the cursor +can move in spring mode. 0 will use the entire width +of your screen. + Modifie la largeur de la région dans laquelle +le curseur peut se déplacer en mode "ressort". +0 utilise toute la largeur de l'écran. + + + + Spring Height: + Hauteur du Ressort : + + + + Changes the height of the region that the cursor +can move in spring mode. 0 will use the entire height +of your screen. + Modifie la hauteur de la région dans laquelle +le curseur peut se déplacer en mode "ressort". +0 utilise toute la hauteur de l'écran. + + + + + %n notch(es)/s + + %n cran/s + %n crans/s + + + + + QKeyDisplayDialog + + + Key Checker + Vérificateur de touche + + + + <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by antimicro.</p><p>The antimicro key value and the Qt key value will usually be the same. antimicro tries to use the key values defined in Qt when possible. Check the page <a href="http://qt-project.org/doc/qt-4.8/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://qt-project.org/doc/qt-4.8/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to antimicro's <a href="https://github.com/Ryochan7/antimicro"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> + + + + + Event Handler: + + + + + Native Key Value: + Valeur native de la touche : + + + + + + 0x00000000 + + + + + Qt Key Value: + Valeur de la touche Qt : + + + + antimicro Key Value: + + + + + QObject + + + Super + Super + + + + Menu + + + + + Mute + + + + + Vol+ + + + + + Vol- + + + + + Play/Pause + + + + + Play + + + + + Pause + Pause + + + + Prev + + + + + Next + Suivant + + + + Mail + + + + + Home + Début + + + + Media + + + + + Search + + + + + Daemon launched + + + + + Failed to launch daemon + + + + + Launching daemon + + + + + + Display string "%1" is not valid. + + + + + Failed to set a signature id for the daemon + + + + + Failed to change working directory to / + + + + + Quitting Program + + + + + # of joysticks found: %1 + + + + + List Joysticks: + + + + + --------------- + + + + + Joystick %1: + + + + + Index: %1 + + + + + GUID: %1 + + + + + Name: %1 + + + + + Yes + + + + + No + + + + + Game Controller: %1 + + + + + # of Axes: %1 + + + + + # of Buttons: %1 + + + + + # of Hats: %1 + + + + + Attempting to use fallback option %1 for event generation. + + + + + Failed to open event generator. Exiting. + + + + + Using %1 as the event generator. + + + + + Could not raise process priority. + + + + + QuickSetDialog + + + Quick Set + Configuration Rapide + + + + <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> + <html><head/><body><p>Merci de presser un bouton ou de bouger un axe de %1 (<span style=" font-weight:600;">%2</span>).<br/>Une fenêtre de dialogue va apparaître<br/>pour permettre de faire une assignation.</p></body></html> + + + + Quick Set %1 + Configuration Rapide %1 + + + + SetAxisThrottleDialog + + + Throttle Change + Modifier l'accélération + + + + The throttle setting for Axis %1 has been changed. + +Would you like to distribute this throttle change to all sets? + axes ou axe dans ce cas ? + La configuration de l'accélération de l'axe %1 a été modifié. + +Faut-il appliquer cette valeur d'accélération à tous les réglages ? + + + + SetJoystick + + + Set %1: %2 + + + + + Set %1 + + + + + SetNamesDialog + + + Set Name Settings + + + + + Set 1 + + + + + Set 2 + + + + + Set 3 + + + + + Set 4 + + + + + Set 5 + + + + + Set 6 + + + + + Set 7 + + + + + Set 8 + + + + + Name + + + + + SimpleKeyGrabberButton + + + Mouse + Souris + + + + SpringModeRegionPreview + + + Spring Mode Preview + Aperçu du mode ressort + + + + UInputEventHandler + + + Could not find a valid uinput device file. +Please check that you have the uinput module loaded. +lsmod | grep uinput + + + + + Could not open uinput device file +Please check that you have permission to write to the device + + + + + Using uinput device file %1 + + + + + UInputHelper + + + a + q + + + + b + + + + + c + + + + + d + + + + + e + + + + + f + + + + + g + + + + + h + + + + + i + + + + + j + + + + + k + + + + + l + + + + + m + , + + + + n + + + + + o + + + + + p + + + + + q + a + + + + r + + + + + s + + + + + t + + + + + u + + + + + v + + + + + w + z + + + + x + + + + + y + + + + + z + w + + + + Esc + + + + + F1 + + + + + F2 + + + + + F3 + + + + + F4 + + + + + F5 + + + + + F6 + + + + + F7 + + + + + F8 + + + + + F9 + + + + + F10 + + + + + F11 + + + + + F12 + + + + + ` + + + + + 1 + 1 + + + + 2 + 2 + + + + 3 + 3 + + + + 4 + 4 + + + + 5 + 5 + + + + 6 + 6 + + + + 7 + 7 + + + + 8 + 8 + + + + 9 + 9 + + + + 0 + 0 + + + + + - + + + + + = + + + + + BackSpace + Retour Arrière + + + + Tab + Tab + + + + [ + + + + + ] + + + + + \ + + + + + CapsLock + + + + + ; + + + + + ' + + + + + Enter + + + + + Shift_L + Maj_G + + + + , + + + + + + . + + + + + + / + + + + + Ctrl_L + + + + + + Super_L + Super_L + + + + Alt_L + Alt_L + + + + Space + Espace + + + + Alt_R + Alt_R + + + + Menu + Menu + + + + Ctrl_R + + + + + Shift_R + Maj_D + + + + Up + Haut + + + + Left + Gauche + + + + Down + Bas + + + + Right + Droite + + + + PrtSc + + + + + Ins + + + + + Del + + + + + Home + Début + + + + End + End + + + + PgUp + + + + + PgDn + + + + + NumLock + + + + + * + + + + + + + + + + + KP_Enter + KP_Entrée + + + + KP_1 + + + + + KP_2 + + + + + KP_3 + + + + + KP_4 + + + + + KP_5 + + + + + KP_6 + + + + + KP_7 + + + + + KP_8 + + + + + KP_9 + + + + + KP_0 + + + + + SCLK + Arrêt Defil + + + + Pause + Pause + + + + Super_R + + + + + Mute + + + + + VolDn + + + + + VolUp + + + + + Play + + + + + Stop + + + + + Prev + + + + + Next + Suivant + + + + [NO KEY] + [AUCUNE TOUCHE] + + + + UnixWindowInfoDialog + + + Captured Window Properties + + + + + Information About Window + + + + + Class: + + + + + + + TextLabel + + + + + Title: + + + + + Path: + + + + + Match By Properties + + + + + Class + + + + + Title + + + + + Path + + + + + VDPad + + + + + VDPad + + + + + VirtualKeyPushButton + + + Space + Espace + + + + Tab + Tab + + + + Shift (L) + Maj (G) + + + + Shift (R) + Maj (D) + + + + Ctrl (L) + Ctrl (G) + + + + Ctrl (R) + Ctrl (D) + + + + Alt (L) + Alt (G) + + + + + Alt (R) + Alt (D) + + + + ` + + + + + ~ + + + + + + - + + + + + = + + + + + [ + + + + + ] + + + + + \ + + + + + Caps + Verr Maj + + + + ; + + + + + ' + + + + + , + + + + + + . + + + + + + / + + + + + ESC + ECHAP + + + + PRTSC + Impr Ecran + + + + SCLK + Arrêt Defil + + + + INS + INSER + + + + PGUP + PGUP + + + + DEL + SUPPR + + + + PGDN + PGDN + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + 9 + + + + + 0 + + + + + NUM +LK + VERR +NUM + + + + + * + + + + + + + + + + + E +N +T +E +R + E +N +T +R +É +E + + + + < + + + + + : + + + + + Super (L) + Super (G) + + + + Menu + + + + + Up + Haut + + + + Down + Bas + + + + Left + Gauche + + + + Right + Droite + + + + VirtualKeyboardMouseWidget + + + + Keyboard + Clavier + + + + + Mouse + Souris + + + + Mouse Settings + Configurations de la Souris + + + + Left + Mouse + Gauche + + + + Up + Mouse + Haut + + + + Left Button + Mouse + + + + + Middle Button + Mouse + + + + + Right Button + Mouse + + + + + Wheel Up + Mouse + Molette bas + + + + Wheel Left + Mouse + Molette gauche + + + + Wheel Right + Mouse + Molette droite + + + + Wheel Down + Mouse + Molette bas + + + + Down + Mouse + Bas + + + + Right + Mouse + Droite + + + + Button 4 + Mouse + Bouton 4 + + + + Mouse 8 + Mouse + Souris 8 + + + + Button 5 + Mouse + Bouton 5 + + + + Mouse 9 + Mouse + Souris 9 + + + + NONE + AUCUNE + + + + Applications + + + + + Browser Back + + + + + Browser Favorites + + + + + Browser Forward + + + + + Browser Home + + + + + Browser Refresh + + + + + Browser Search + + + + + Browser Stop + + + + + Calc + + + + + Email + + + + + Media + + + + + Media Next + + + + + Media Play + + + + + Media Previous + + + + + Media Stop + + + + + Search + + + + + Volume Down + + + + + Volume Mute + + + + + Volume Up + + + + + VirtualMousePushButton + + + INVALID + INVALIDE + + + + WinAppProfileTimerDialog + + + + Capture Application + + + + + After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. + + + + + Timer: + + + + + Seconds + + + + + Cancel + + + + + WinExtras + + + [NO KEY] + [AUCUNE TOUCHE] + + + + AntiMicro Profile + + + + + X11Extras + + + ESC + ECHAP + + + + Tab + Tab + + + + Space + Espace + + + + DEL + SUPPR + + + + Return + + + + + KP_Enter + KP_Entrée + + + + Backspace + Retour arrière + + + + xinput extension was not found. No mouse acceleration changes will occur. + + + + + + xinput version must be at least 2.0. No mouse acceleration changes will occur. + + + + + Virtual pointer found with id=%1. + + + + + PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 + + + + + Changing mouse acceleration for device with id=%1 + + + + + XMLConfigReader + + + Could not write updated profile XML to file %1. + Impossible de mettre à jour le profil XML du fichier %1. + + + + XMLConfigWriter + + + Could not write to profile at %1. + Impossible d'écrire le profil %1. + + + diff --git a/share/antimicro/translations/antimicro_ja.ts b/share/antimicro/translations/antimicro_ja.ts new file mode 100644 index 0000000..b89eaab --- /dev/null +++ b/share/antimicro/translations/antimicro_ja.ts @@ -0,0 +1,5880 @@ + + + + + AboutDialog + + + About + + + + + Version + バージョン + + + + Info + 情報 + + + + Changelog + + + + + Since December 30, 2012, I have been working on antimicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. + +The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. + +Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. + +Once the Steam controller is finally released to the public, the need for this program might not exist anymore. Just based on the concept of the controller alone, the Steam controller would have so many advantages over using a program like this to provide KB+M emulation. + + + + + Copyright: 2013 - 2015 + + + + + Credits + + + + + antimicro + antimicro + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Travis Nickles &lt;nickles.travis@gmail.com&gt;</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Contributors:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;"><br /></span>Zerro Alvein</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">aybe</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Jeff Backus &lt;jeff.backus@gmail.com&gt;</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Arthur Moore<br />Anton Tornqvist &lt;antont@inbox.lv&gt;</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Translators:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt; font-weight:600;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">zzpxyx - Chinese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">phob - German</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tou omiya - Japanese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">burunduk - Ukrainian</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Version 3, 29 June 2007</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Preamble</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">TERMS AND CONDITIONS</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">0. Definitions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">1. Source Code.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">2. Basic Permissions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">4. Conveying Verbatim Copies.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">5. Conveying Modified Source Versions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">6. Conveying Non-Source Forms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">7. Additional Terms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">8. Termination.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">11. Patents.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">14. Revised Versions of this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">15. Disclaimer of Warranty.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">16. Limitation of Liability.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> + + + + + About Development + + + + + License + ライセンス + + + + Program Version %1 + + + + + Program Compiled on %1 at %2 + + + + + Built Against SDL %1 + + + + + Running With SDL %1 + + + + + Using Qt %1 + + + + + Using Event Handler: %1 + + + + + AddEditAutoProfileDialog + + + Auto Profile Dialog + + + + + Profile: + プロファイル: + + + + + Browse + + + + + Window: + ウィンドウ: + + + + + Select Window. Click on the appropriate application +window and the application file path will be populated +in the form. + + + + + Detect Window Properties + + + + + Class: + + + + + Title: + タイトル: + + + + Application: + アプリケーション: + + + + Select + + + + + Devices: + デバイス: + + + + + Select this profile to be the default loaded for +the specified device. The selection will be used instead +of the all default profile option. + + + + + Set as Default for Controller + + + + + + A different profile is already selected as the default for this device. + + + + + Current (%1) + + + + + Open Config + + + + + + Select Program + + + + + Programs (*.exe) + + + + + Please use the main default profile selection. + + + + + Please select a window by using the mouse. Press Escape if you want to cancel. + + + + + Capture Application Window + + + + + Could not obtain information for the selected window. + + + + + Application Capture Failed + + + + + Profile file path is invalid. + + + + + No window matching property was specified. + + + + + Program path is invalid or not executable. + + + + + File is not an .exe file. + + + + + No window matching property was selected. + + + + + AdvanceButtonDialog + + + + Advanced + 詳細設定 + + + + Assignments + 割り当て + + + + Toggle + トグル + + + + Turbo + 連射 + + + + Set Selector + + + + + Blank or KB/M + + + + + Hold + + + + + Pause + Pause + + + + Cycle + + + + + Distance + + + + + Insert + + + + + Delete + 削除 + + + + Clear All + + + + + Time: + + + + + 0.01s + 0.01 秒 + + + + 0s + 0 秒 + + + + Insert a pause that occurs in between key presses. + + + + + Release + + + + + + Insert a new blank slot. + + + + + Delete a slot. + + + + + Clear all currently assigned slots. + + + + + Specify the duration of an inserted Pause or Hold slot. + + + + + 0m + 0 分 + + + + + Specify the range past an axis dead zone in which a sequence of actions will execute. + + + + + Distance: + + + + + + % + % + + + + Mouse Mod + + + + + Press Time + + + + + Delay + + + + + Execute + + + + + Load + 読み込み + + + + Set Change + + + + + Text Entry + + + + + Placeholder + + + + + + 0 + 0 + + + + Mouse Speed Mod: + + + + + Set the percentage that mouse speeds will be modified by. + + + + + Auto Reset Cycle After + + + + + seconds + + + + + ... + + + + + + + Enabled + 有効 + + + + Mode: + + + + + <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> + + + + + Normal + + + + + Gradient + + + + + Pulse + + + + + Delay: + + + + + 0.10s + 0.10 秒 + + + + Rate: + + + + + 10.0/s + + + + + + Disabled + + + + + Select Set 1 One Way + + + + + Select Set 1 Two Way + + + + + Select Set 1 While Held + + + + + Select Set 2 One Way + + + + + Select Set 2 Two Way + + + + + Select Set 2 While Held + + + + + Select Set 3 One Way + + + + + Select Set 3 Two Way + + + + + Select Set 3 While Held + + + + + Select Set 4 One Way + + + + + Select Set 4 Two Way + + + + + Select Set 4 While Held + + + + + Select Set 5 One Way + + + + + Select Set 5 Two Way + + + + + Select Set 5 While Held + + + + + Select Set 6 One Way + + + + + Select Set 6 Two Way + + + + + Select Set 6 While Held + + + + + Select Set 7 One Way + + + + + Select Set 7 Two Way + + + + + Select Set 7 While Held + + + + + Select Set 8 One Way + + + + + Select Set 8 Two Way + + + + + Select Set 8 While Held + + + + + sec. + + + + + /sec. + + + + + Set %1 + セット %1 + + + + + Select Set %1 + + + + + One Way + + + + + Two Way + + + + + While Held + + + + + Choose Executable + + + + + Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. + + + + + Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. + + + + + Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. + + + + + Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. + + + + + Chose a profile to load when this slot is activated. + + + + + Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. + + + + + Specify the time that keys past this slot should be held down. + + + + + Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. + + + + + Change to selected set once slot is activated. + + + + + Full string will be typed when a slot is activated. + + + + + Execute program when slot is activated. + + + + + + Choose Profile + + + + + Config Files (*.amgp *.xml) + 構成ファイル (*.amgp *.xml) + + + + AdvanceStickAssignmentDialog + + + Stick/Pad Assignment + + + + + Sticks + スティック + + + + DPads + 十字キー + + + + + %1 (Joystick %2) + %1 (ジョイスティック %2) + + + + Stick 1 + スティック 1 + + + + + + Enabled + 有効 + + + + + + + + + Assign + 割り当て + + + + + X Axis: + X 軸: + + + + + Y Axis: + Y 軸: + + + + Stick 2 + スティック 2 + + + + Number of Physical DPads: %1 + 物理方向キーの数: %1 + + + + Virtual DPad 1 + 仮想方向キー 1 + + + + Up: + 上: + + + + Down: + 下: + + + + Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. + 注: このウィンドウは、バージョン 2.0 より前の antimicro で作成したプロファイルとの後方互換性を確保するために使用します。バージョン 2.0 以降では「ゲームコントローラーマッピング」ウィンドウの使用を推奨します。 + + + + Left: + 左: + + + + Right: + 右: + + + + + + + Axis %1 + 軸 %1 + + + + + + + Axis %1 - + 軸 %1 - + + + + + + + Axis %1 + + 軸 %1 + + + + + + + + Button %1 + ボタン %1 + + + + Move stick 1 along the X axis + + + + + Move stick 1 along the Y axis + + + + + Move stick 2 along the X axis + + + + + Move stick 2 along the Y axis + + + + + + + + Press a button or move an axis + + + + + AxisEditDialog + + + Axis + + + + + + Mouse (Horizontal) + + + + + + Mouse (Inverted Horizontal) + + + + + + Mouse (Vertical) + + + + + + Mouse (Inverted Vertical) + + + + + + Arrows: Up | Down + + + + + + Arrows: Left | Right + + + + + + Keys: W | S + + + + + + Keys: A | D + + + + + + NumPad: KP_8 | KP_2 + + + + + + NumPad: KP_4 | KP_6 + + + + + + + None + + + + + + Set the value to use as the limit for an axis. Useful for a +worn out analog stick. + + + + + Negative Half Throttle + + + + + Positive Half Throttle + + + + + Name: + 名前: + + + + Specify the name of an axis. + + + + + Mouse Settings + マウスの設定 + + + + + Set the value of the dead zone for an axis. + + + + + Presets: + プリセット: + + + + Dead Zone: + + + + + Max Zone: + + + + + + [NO KEY] + [割り当てなし] + + + + Throttle setting that determines the behavior of how to +interpret an axis hold or release. + + + + + Negative Throttle + + + + + Normal + + + + + Positive Throttle + + + + + Current Value: + + + + + Set + セット + + + + Set %1 + セット %1 + + + + Left Mouse Button + 左マウスボタン + + + + Right Mouse Button + 右マウスボタン + + + + ButtonEditDialog + + + Dialog + + + + + To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab + 割り当てを新規作成するには、キーボードのキーを押すか、「キーボード」あるいは「マウス」タブのいずれかのボタンをクリックしてください + + + + Placeholder + + + + + Toggle + トグル + + + + Enables a key press or release to only occur when a controller button is pressed. + + + + + Enables rapid key presses and releases. Turbo controller. + + + + + Turbo + 連射 + + + + Current: + 現在の割り当て: + + + + Slots + + + + + Na&me: + 名前(&M): + + + + Specify the name of a button. + + + + + Action: + アクション: + + + + Specify the action that will be performed in game while +this button is being used. + + + + + Advanced + 詳細設定 + + + + Set + セット + + + + Set %1 + セット %1 + + + + CapturedWindowInfoDialog + + + Captured Window Properties + + + + + Information About Window + + + + + Class: + + + + + + + TextLabel + + + + + Title: + タイトル: + + + + Path: + + + + + Match By Properties + + + + + Class + + + + + Title + タイトル + + + + Path + + + + + Full Path + + + + + File Name + + + + + CommandLineUtility + + + + Profile location %1 is not an XML file. + + + + + + Profile location %1 does not exist. + + + + + An invalid set number '%1' was specified. + + + + + Controller identifier '%s'' is not a valid value. + + + + + No display string was specified. + + + + + + + Controller identifier is not a valid value. + + + + + No set number was specified. + + + + + No controller was specified. + + + + + An invalid event generator was specified. + + + + + No event generator string was specified. + + + + + Qt style flag was detected but no style was specified. + + + + + No log level specified. + + + + + + + + antimicro version + + + + + + Usage: antimicro [options...] [profile] + + + + + + Options + オプション + + + + + Print help text. + + + + + + Print version information. + + + + + + Launch program in system tray only. + + + + + + Launch program with the tray menu disabled. + + + + + + Launch program without the main window + displayed. + + + + + + Launch program with the configuration file + selected as the default for selected + controllers. Defaults to all controllers. + + + + + + Apply configuration file to a specific + controller. Value can be a + controller index, name, or GUID. + + + + + + Unload currently enabled profile(s). + Value can be a controller index, name, or GUID. + + + + + + Start joysticks on a specific set. + Value can be a controller index, name, or GUID. + + + + + + Advance profile loading set options. + + + + + + Launch program as a daemon. + + + + + + Enable logging. + + + + + + Use specified display for X11 calls. + Useful for ssh. + + + + + + Choose between using XTest support and uinput + support for event generation. Default: xtest. + + + + + + Choose between using SendInput and vmulti + support for event generation. Default: sendinput. + + + + + + Print information about joysticks detected by + SDL. + + + + + + Open game controller mapping window of selected + controller. Value can be a controller index or + GUID. + + + + + DPadContextMenu + + + Mouse (Normal) + + + + + Mouse (Inverted Horizontal) + + + + + Mouse (Inverted Vertical) + + + + + Mouse (Inverted Horizontal + Vertical) + + + + + Arrows + + + + + Keys: W | A | S | D + + + + + NumPad + + + + + None + + + + + Standard + + + + + Eight Way + + + + + 4 Way Cardinal + + + + + 4 Way Diagonal + + + + + Mouse Settings + マウスの設定 + + + + DPadEditDialog + + + Dialog + + + + + Presets: + プリセット: + + + + Mouse (Normal) + + + + + Mouse (Inverted Horizontal) + + + + + Mouse (Inverted Vertical) + + + + + Mouse (Inverted Horizontal + Vertical) + + + + + Arrows + + + + + Keys: W | A | S | D + + + + + NumPad + + + + + None + + + + + Dpad Mode: + + + + + &Name: + + + + + 4 Way Cardinal + + + + + 4 Way Diagonal + + + + + DPad Delay: + + + + + + Time lapsed before a direction change is taken into effect. + + + + + s + + + + + Specify the name of a dpad. + + + + + Mouse Settings + マウスの設定 + + + + Standard + + + + + Standard: 8 region dpad with two direction buttons active +when the dpad is in a diagonal region. + +Eight Way: 8 region dpad with each direction having its +own dedicated button. Only one button is ever active at +at time. Useful for rougelike games. + +4 Way Cardinal: 4 region dpad with regions corresponding to +the cardinal directions of the dpad. Useful for menus. + +4 Way Diagonal: 4 region dpad with each region corresponding +to a diagonal zone. + + + + + Eight Way + + + + + Set + セット + + + + Set %1 + セット %1 + + + + EditAllDefaultAutoProfileDialog + + + Default Profile + + + + + Profile: + プロファイル: + + + + Browse + + + + + Open Config + + + + + Profile file path is invalid. + + + + + ExtraProfileSettingsDialog + + + Extra Profile Settings + + + + + Key Press Time: + + + + + 0.00 ms + + + + + Profile Name: + プロファイル名: + + + + + + s + s + + + + GameController + + + Game Controller + ゲームコントローラー + + + + GameControllerDPad + + + + + DPad + 十字キー + + + + GameControllerMappingDialog + + + Game Controller Mapping + + + + + <html><head/><body><p>antimicro makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicro will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> + + + + + A + A + + + + B + B + + + + X + X + + + + Y + Y + + + + Back + + + + + Start + + + + + Guide + + + + + Left Shoulder + + + + + Right Shoulder + + + + + Left Stick Click + + + + + Right Stick Click + + + + + Left Stick X + 左スティック X + + + + Left Stick Y + 左スティック Y + + + + Right Stick X + 右スティック X + + + + Right Stick Y + 右スティック Y + + + + Left Trigger + 左トリガー + + + + Right Trigger + 右トリガー + + + + DPad Up + 十字キー↑ + + + + DPad Left + 十字キー← + + + + DPad Down + 十字キー↓ + + + + DPad Right + 十字キー→ + + + + Mapping + + + + + SDL 2 Game Controller Mapping String + + + + + Last Axis Event: + + + + + Current Axis Detection Dead Zone: + + + + + 5000 + 5000 + + + + 10000 + 10000 + + + + 15000 + 15000 + + + + 20000 + 20000 + + + + 25000 + 25000 + + + + 30000 + 30000 + + + + 32000 + 32000 + + + + Game Controller Mapping (%1) (#%2) + + + + + Discard Controller Mapping? + + + + + Discard mapping for this controller? + +If discarded, the controller will be reverted to a joystick once you refresh all joysticks. + + + + + GameControllerSet + + + Back + + + + + Guide + + + + + Start + + + + + LS Click + + + + + RS Click + + + + + L Shoulder + + + + + R Shoulder + + + + + L Trigger + 左トリガー + + + + R Trigger + 右トリガー + + + + GameControllerTrigger + + + + + Trigger + トリガー + + + + JoyAxis + + + + + Axis + + + + + JoyAxisButton + + + Negative + + + + + Positive + + + + + Unknown + 不明 + + + + + + Button + ボタン + + + + JoyAxisContextMenu + + + Mouse (Horizontal) + + + + + Mouse (Inverted Horizontal) + + + + + Mouse (Vertical) + + + + + Mouse (Inverted Vertical) + + + + + Arrows: Up | Down + + + + + Arrows: Left | Right + + + + + Keys: W | S + + + + + Keys: A | D + + + + + NumPad: KP_8 | KP_2 + + + + + NumPad: KP_4 | KP_6 + + + + + + None + + + + + + Mouse Settings + マウスの設定 + + + + Left Mouse Button + 左マウスボタン + + + + Right Mouse Button + 右マウスボタン + + + + JoyButton + + + Processing turbo for #%1 - %2 + + + + + Finishing turbo for button #%1 - %2 + + + + + Processing press for button #%1 - %2 + + + + + Processing release for button #%1 - %2 + + + + + Distance change for button #%1 - %2 + + + + + + + Button + ボタン + + + + + + + [NO KEY] + [割り当てなし] + + + + [Set %1 1W] + + + + + [Set %1 2W] + + + + + [Set %1 WH] + + + + + JoyButtonContextMenu + + + Toggle + + + + + Turbo + + + + + Clear + + + + + Set Select + + + + + Disabled + + + + + Set %1 + セット %1 + + + + Set %1 1W + セット %1 1W + + + + Set %1 2W + セット %1 2W + + + + Set %1 WH + + + + + JoyButtonSlot + + + + Mouse + マウス + + + + Up + + + + + Down + + + + + Left + + + + + Right + + + + + LB + + + + + MB + + + + + RB + + + + + B4 + + + + + B5 + + + + + Pause + Pause + + + + Hold + + + + + Cycle + + + + + Distance + + + + + Release + + + + + Mouse Mod + + + + + Press Time + + + + + Delay + + + + + Load %1 + + + + + Set Change %1 + + + + + [Text] %1 + + + + + [Exec] %1 + + + + + [NO KEY] + [割り当てなし] + + + + JoyControlStick + + + + + Stick + スティック + + + + JoyControlStickButton + + + + + Up + + + + + + + Down + + + + + + + Left + + + + + + + Right + + + + + + + Button + ボタン + + + + JoyControlStickContextMenu + + + Mouse (Normal) + + + + + Mouse (Inverted Horizontal) + + + + + Mouse (Inverted Vertical) + + + + + Mouse (Inverted Horizontal + Vertical) + + + + + Arrows + + + + + Keys: W | A | S | D + + + + + NumPad + + + + + None + + + + + Standard + + + + + Eight Way + + + + + 4 Way Cardinal + + + + + 4 Way Diagonal + + + + + Mouse Settings + マウスの設定 + + + + JoyControlStickEditDialog + + + Dialog + + + + + X: + X: + + + + + + + + 0 + 0 + + + + Y: + Y: + + + + Distance: + + + + + Presets: + プリセット: + + + + Mouse (Normal) + + + + + Mouse (Inverted Horizontal) + + + + + Mouse (Inverted Vertical) + + + + + Mouse (Inverted Horizontal + Vertical) + + + + + Arrows + + + + + Keys: W | A | S | D + + + + + NumPad + + + + + None + + + + + Stick Mode: + + + + + Standard: 8 region stick with two direction buttons active +when the stick is in a diagonal region. + +Eight Way: 8 region stick with each direction having its +own dedicated button. Only one button is ever active at +at time. Useful for rougelike games. + +4 Way Cardinal: 4 region stick with regions corresponding to +the cardinal directions of the stick. Useful for menus. + +4 Way Diagonal: 4 region stick with each region corresponding +to a diagonal zone of the stick. + + + + + 4 Way Cardinal + + + + + 4 Way Diagonal + + + + + + Dead zone value to use for an analog stick. + + + + + + Value when an analog stick is considered moved 100%. + + + + + + The area (in degrees) that each diagonal region occupies. + + + + + Square Stick: + + + + + + Percentage to modify a square stick coordinates to confine values to a circle + + + + + % + % + + + + Stick Delay: + + + + + + Time lapsed before a direction change is taken into effect. + + + + + s + + + + + Modifier: + + + + + Edit button that is active while the stick is active. + +This button is useful for assigning zones with +modifier keys that can be used to assign walk/run +functionality to an analog stick. + + + + + PushButton + + + + + Name: + + + + + Specify the name of an analog stick. + + + + + Mouse Settings + マウスの設定 + + + + Standard + + + + + Bearing: + + + + + % Safe Zone: + + + + + Eight Way + + + + + Dead Zone: + + + + + Max Zone: + + + + + Diagonal Range: + + + + + Set + セット + + + + Set %1 + セット %1 + + + + JoyControlStickModifierButton + + + + + Modifier + + + + + JoyDPad + + + + + DPad + 十字キー + + + + JoyDPadButton + + + + + Up + + + + + + + Down + + + + + + + Left + + + + + + + Right + + + + + + + Button + ボタン + + + + JoyTabWidget + + + + + + + + <New> + <新規> + + + + + Remove + 削除 + + + + + Remove configuration from recent list. + + + + + + Load + 読み込み + + + + + Load configuration file. + + + + + + Save + 保存 + + + + + Save changes to configuration file. + + + + + + Save As + 別名保存 + + + + + Save changes to a new configuration file. + + + + + + Sets + セット + + + + Copy from Set + セットからコピー + + + + Settings + 設定 + + + + + Set 1 + セット 1 + + + + + Set 2 + セット 2 + + + + + Set 3 + セット 3 + + + + + Set 4 + セット 4 + + + + + Set 5 + セット 5 + + + + + Set 6 + セット 6 + + + + + Set 7 + セット 7 + + + + + Set 8 + セット 8 + + + + + Stick/Pad Assign + + + + + + Controller Mapping + + + + + + Quick Set + クイックセット + + + + + Names + + + + + + Toggle button name displaying. + + + + + + Pref + + + + + + Change global profile settings. + + + + + + + Reset + リセット + + + + + Revert changes to the configuration. Reload configuration file. + + + + + Open Config + + + + + Config Files (*.amgp *.xml) + 構成ファイル (*.amgp *.xml) + + + + + + Config File (*.%1.amgp) + 構成ファイル (*.%1.amgp) + + + + + Save Profile Changes? + + + + + + Changes to the new profile have not been saved. Would you like to save or discard the current profile? + + + + + + Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? + + + + + Sticks + スティック + + + + + DPads + 十字キー + + + + No buttons have been assigned. Please use Quick Set to assign keys +to buttons or disable hiding empty buttons. + + + + + + Set %1: %2 + セット %1: %2 + + + + + Set %1 + セット %1 + + + + Copy Set Assignments + + + + + Are you sure you want to copy the assignments and device properties from %1? + + + + + + + Save Config + + + + + + Set + セット + + + + Joystick + + + Joystick + ジョイスティック + + + + JoystickStatusWindow + + + Properties + プロパティ + + + + Details + + + + + Name: + 名前: + + + + + + + + + + %1 + %1 + + + + Number: + + + + + Axes: + 軸: + + + + Buttons: + ボタン: + + + + Hats: + + + + + GUID: + GUID: + + + + Game Controller: + ゲームコントローラー: + + + + Axes + + + + + Buttons + ボタン + + + + Hats + + + + + %1 (#%2) Properties + + + + + Axis %1 + 軸 %1 + + + + Hat %1 + + + + + No + いいえ + + + + Yes + はい + + + + MainSettingsDialog + + + Edit Settings + + + + + General + 全般 + + + + Controller Mappings + + + + + Language + 言語 + + + + Auto Profile + + + + + Mouse + マウス + + + + <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> + + + + + Recent Profile Count: + + + + + <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> + + + + + Gamepad Poll Rate: + + + + + Change the poll rate that the program uses to discover new +events from gamepads. Defaults to 10 ms. + +Reducing the poll rate value could cause the application to +use more CPU power so please test the setting that you use +before using antimicro unattended. + + + + + Hide main window when the main window close button is +clicked instead of quitting the program. + + + + + Close To Tray + + + + + Have Windows start antimicro at system startup. + + + + + Launch At Windows Startup + Windows の起動と同時に開始 + + + + Display recent profiles for all controllers +as a single list in the tray menu. Defaults +to using sub-menus. + + + + + Single Profile List in Tray + + + + + Have the program minimize to the taskbar. +By default, the program minimizes to the system +tray if available. + + + + + Minimize to Taskbar + タスクバーに入れる + + + + This option will cause the program to hide all +buttons that have no slots assigned to them. +The Quick Set dialog window will have to be used +to bring up the edit dialog for gamepad buttons. + + + + + Hide Empty Buttons + + + + + When the program is launched, open the last +known profile that was opened during the +previous session. + + + + + Auto Load Last Opened Profile + + + + + Only show the system tray icon when the program +first launches. + + + + + Launch in Tray + + + + + Associate .amgp files with antimicro in Windows Explorer. + + + + + Associate Profiles + プロファイルを関連付け + + + + Key Repeat + + + + + Active keys will be repeatedly pressed when this +option is enabled. + + + + + + Enable + 有効 + + + + Specifies how much time should elapse before key repeating +begins. + + + + + Specifies how many times key presses will be performed +per seconds. + + + + + <html><head/><body><p>antimicro has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make antimicro load a different translation depending on the language that you choose from the list below.</p></body></html> + + + + + French + フランス語 + + + + Japanese + + + + + Russian + ロシア語 + + + + Serbian + セルビア語 + + + + Simplified Chinese + 中国語 (簡体字) + + + + Ukrainian + ウクライナ語 + + + + Class + + + + + Title + タイトル + + + + Program + + + + + Disable the "Enhanced Pointer Precision" Windows setting +while antimicro is running. Disabling "Enhanced Pointer Precision" +will allow mouse movement within antimicro to be more +precise. + + + + + Disable Enhance Pointer Precision + + + + + Smoothing + + + + + Histor&y Size: + + + + + Weight &Modifier: + + + + + Refresh Rate: + + + + + The refresh rate is the amount of time that will elapse +in between mouse events. Please be cautious when +editing this setting as it will cause the program to use +more CPU power. Setting this value too low can cause +system instability. Please test the setting before using +it unattended. + + + + + Spring + + + + + Screen: + スクリーン: + + + + Utilize the specified screen for spring mode. On Linux, the +default is to use the primary screen. On Windows, the default +is to use all available screens. + + + + + Accel Numerator: + + + + + + + 0 + 0 + + + + Accel Denominator: + + + + + Accel Threshold: + + + + + If the acceleration values for the virtual mouse have been +changed by a different process, particularly when quitting +an older game, then you might want to reset the acceleration +values used by the virtual mouse. + + + + + Reset Acceleration + + + + + Delay: + + + + + Profi&le Directory: + + + + + ms + + + + + Rate: + + + + + times/s + + + + + Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. + +Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. + + + + + GUID + GUID + + + + Mapping String + + + + + Disable? + + + + + + Delete + 削除 + + + + Insert + + + + + + Default + デフォルト + + + + Brazilian Portuguese + ポルトガル語 (ブラジル) + + + + English + 英語 + + + + German + ドイツ語 + + + + + Active + + + + + Devices: + デバイス: + + + + + All + + + + + Device + デバイス + + + + Profile + プロファイル + + + + Default? + + + + + Add + 追加 + + + + Edit + 編集 + + + + Also, Windows users who want to use a low value should also check the +"Disable Enhance Pointer Precision" checkbox if you haven't disabled +the option in Windows. + + + + + Select Default Profile Directory + + + + + Are you sure you want to delete the profile? + + + + + MainWindow + + + antimicro + antimicro + + + + No Joysticks have been found. + Please plug in a joystick and then choose the "Update Joysticks" option in the main menu + ジョイスティックが見つかりません。 +ジョイスティックを接続し、メインメニューの「ジョイスティックを更新」を選択してください + + + + If events are not seen by a game, please click here to run this application as the Adminstrator. + + + + + &App + + + + + &Options + オプション(&O) + + + + &Help + ヘルプ(&H) + + + + + &Quit + 終了(&Q) + + + + Ctrl+Q + Ctrl+Q + + + + + &Update Joysticks + ジョイスティックを更新(&U) + + + + Ctrl+U + Ctrl+U + + + + + &Hide + 隠す(&H) + + + + Ctrl+H + Ctrl+H + + + + &About + AntiMicro について(&A) + + + + Ctrl+A + Ctrl+A + + + + About Qt + Qt について + + + + Properties + プロパティ + + + + Key Checker + キーチェッカー + + + + Home Page + ホームページ + + + + GitHub Page + GitHub ページ + + + + Game Controller Mapping + + + + + Settings + 設定 + + + + Stick/Pad Assign + + + + + Wiki + + + + + Could not find a proper controller identifier. Exiting. + + + + + + + + + + + (%1) + (%1) + + + + + Open File + + + + + &Restore + + + + + Run as Administrator? + + + + + Are you sure that you want to run this program as Adminstrator? + +Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. + + + + + Failed to elevate program + + + + + Failed to restart this program as the Administrator + + + + + Could not find controller. Exiting. + + + + + MouseAxisSettingsDialog + + + Mouse Settings - + + + + + Set %1 + セット %1 + + + + MouseButtonSettingsDialog + + + Mouse Settings - + + + + + Set %1 + セット %1 + + + + MouseControlStickSettingsDialog + + + Mouse Settings + マウスの設定 + + + + Set %1 + セット %1 + + + + MouseDPadSettingsDialog + + + Mouse Settings + マウスの設定 + + + + Set %1 + セット %1 + + + + MouseSettingsDialog + + + Mouse Settings + マウスの設定 + + + + Mouse Mode: + マウスモード: + + + + Cursor mode is used to move the mouse cursor +around the screen relative to its current position +depending on how much you move an axis +or if a button is pressed. + +Spring mode is used to move the mouse cursor +from the center of the screen depending on how +much you move an axis. The mouse cursor will +be returned to the center of the screen when the +axis is moved back to the dead zone. + + + + + Cursor + カーソル + + + + Spring + + + + + Acceleration: + 加速: + + + + Enhanced Precision + + + + + + Linear + + + + + Quadratic + + + + + Cubic + + + + + Quadratic Extreme + + + + + Power Function + + + + + Easing Quadratic + + + + + Easing Cubic + + + + + Mouse Speed Settings + + + + + Enable to change the horizontal and vertical speed +boxes at the same time. + + + + + Change Together + + + + + Horizontal +Speed: + 水平速度: + + + + + 1 = 20 pps + + + + + Vertical +Speed: + 垂直速度: + + + + Wheel Hori. +Speed: + + + + + Set the speed used for horizontal mouse wheel movement +according to number of simulated notches per second. + + + + + Set the speed used for vertical mouse wheel movement +according to number of simulated notches per second. + + + + + For Power Function acceleration curve. Specifies +the factor to use for curve sensitivity. When the value +is above 1.0, the mouse movement will be accelerated +faster at the low end of an axis. + + + + + Easing Duration: + + + + + + s + + + + + Extra Acceleration + + + + + Multiplier: + + + + + Highest value to accelerate mouse movement by + + + + + x + + + + + Start %: + + + + + Acceleration begins at this percentage of the base multiplier + + + + + Min +Threshold: + + + + + Minimum amount of axis travel required for acceleration to begin + + + + + Max +Threshold: + + + + + Maximum axis travel before acceleration has reached the multiplier value + + + + + Curve: + + + + + Ease Out Sine + + + + + Ease Out Quad + + + + + Ease Out Cubic + + + + + Release Radius: + + + + + Specifies that the spring area will be relative to the +mouse position set by a non-relative spring. + + + + + Relative + + + + + Mouse Status + + + + + X: + X: + + + + + 0 (0 pps) + + + + + Y: + Y: + + + + + 1 = 1 notch(es)/s + 1 = 1 ノッチ/秒 + + + + Enhanced: Three tier curve that makes the mouse move +slow on the low end of an axis and fast on the high end. + +Linear: Mouse moves proportionally to axis. + +Quadratic: Mouse accelerates slowly on low end. + +Cubic: Mouse accelerates slower than Quadratic. + +Quadratic Extreme: Raises mouse speed 1.5 times once +95% axis travel has been reached. + +Power Function: Allows for a more custom curve option. + +Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. + +Easing Cubic: Axis high end is gradually accelerated over +a period of time using a Cubic curve. + + + + + Wheel Vert. +Speed: + + + + + Sensitivity: + 感度: + + + + Specifies the amount of time (in seconds) that will +be required before the mouse is fully accelerated +after reaching the high end of an axis. + + + + + Options for adding extra acceleration to the mouse +movement beyond what the acceleration curve would +produce. This is meant to help work around some of +the issues of the very limited input range available using +typical gamepad analog sticks. + + + + + + + + % + % + + + + Extra Duration: + + + + + Extend the time that extra acceleration is applied. Axis travel +will be taken into account. A slower flick will decrease the +actual time that extra acceleration will be applied. + + + + + Spring Settings + + + + + Spring Width: + + + + + Changes the width of the region that the cursor +can move in spring mode. 0 will use the entire width +of your screen. + + + + + Spring Height: + + + + + Changes the height of the region that the cursor +can move in spring mode. 0 will use the entire height +of your screen. + + + + + + %n notch(es)/s + + %n ノッチ/秒 + + + + + QKeyDisplayDialog + + + Key Checker + キーチェッカー + + + + <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by antimicro.</p><p>The antimicro key value and the Qt key value will usually be the same. antimicro tries to use the key values defined in Qt when possible. Check the page <a href="http://qt-project.org/doc/qt-4.8/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://qt-project.org/doc/qt-4.8/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to antimicro's <a href="https://github.com/Ryochan7/antimicro"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> + + + + + Event Handler: + イベントハンドラ: + + + + Native Key Value: + ネイティブキー値: + + + + + + 0x00000000 + 0x00000000 + + + + Qt Key Value: + Qt キー値: + + + + antimicro Key Value: + antimicro キー値: + + + + QObject + + + Super + + + + + Menu + + + + + Mute + + + + + Vol+ + + + + + Vol- + + + + + Play/Pause + + + + + Play + + + + + Pause + Pause + + + + Prev + + + + + Next + + + + + Mail + + + + + Home + Home + + + + Media + + + + + Search + + + + + Daemon launched + + + + + Failed to launch daemon + + + + + Launching daemon + + + + + + Display string "%1" is not valid. + + + + + Failed to set a signature id for the daemon + + + + + Failed to change working directory to / + + + + + Quitting Program + + + + + # of joysticks found: %1 + + + + + List Joysticks: + + + + + --------------- + + + + + Joystick %1: + ジョイスティック %1: + + + + Index: %1 + + + + + GUID: %1 + GUID: %1 + + + + Name: %1 + 名前: %1 + + + + Yes + はい + + + + No + いいえ + + + + Game Controller: %1 + ゲームコントローラー: %1 + + + + # of Axes: %1 + + + + + # of Buttons: %1 + + + + + # of Hats: %1 + + + + + Attempting to use fallback option %1 for event generation. + + + + + Failed to open event generator. Exiting. + + + + + Using %1 as the event generator. + + + + + Could not raise process priority. + + + + + QuickSetDialog + + + Quick Set + クイックセット + + + + <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> + + + + + Quick Set %1 + クイックセット %1 + + + + SetAxisThrottleDialog + + + Throttle Change + + + + + The throttle setting for Axis %1 has been changed. + +Would you like to distribute this throttle change to all sets? + + + + + SetJoystick + + + Set %1: %2 + セット %1: %2 + + + + Set %1 + セット %1 + + + + SetNamesDialog + + + Set Name Settings + + + + + Set 1 + セット 1 + + + + Set 2 + セット 2 + + + + Set 3 + セット 3 + + + + Set 4 + セット 4 + + + + Set 5 + セット 5 + + + + Set 6 + セット 6 + + + + Set 7 + セット 7 + + + + Set 8 + セット 8 + + + + Name + + + + + SimpleKeyGrabberButton + + + Mouse + マウス + + + + SpringModeRegionPreview + + + Spring Mode Preview + + + + + UInputEventHandler + + + Could not find a valid uinput device file. +Please check that you have the uinput module loaded. +lsmod | grep uinput + + + + + Could not open uinput device file +Please check that you have permission to write to the device + + + + + Using uinput device file %1 + + + + + UInputHelper + + + a + a + + + + b + b + + + + c + c + + + + d + d + + + + e + e + + + + f + f + + + + g + g + + + + h + h + + + + i + i + + + + j + j + + + + k + k + + + + l + l + + + + m + m + + + + n + n + + + + o + o + + + + p + p + + + + q + q + + + + r + r + + + + s + s + + + + t + t + + + + u + u + + + + v + v + + + + w + w + + + + x + x + + + + y + y + + + + z + z + + + + Esc + Esc + + + + F1 + F1 + + + + F2 + F2 + + + + F3 + F3 + + + + F4 + F4 + + + + F5 + F5 + + + + F6 + F6 + + + + F7 + F7 + + + + F8 + F8 + + + + F9 + F9 + + + + F10 + F10 + + + + F11 + F11 + + + + F12 + F12 + + + + ` + ` + + + + 1 + 1 + + + + 2 + 2 + + + + 3 + 3 + + + + 4 + 4 + + + + 5 + 5 + + + + 6 + 6 + + + + 7 + 7 + + + + 8 + 8 + + + + 9 + 9 + + + + 0 + 0 + + + + + - + - + + + + = + = + + + + BackSpace + BackSpace + + + + Tab + Tab + + + + [ + [ + + + + ] + ] + + + + \ + \ + + + + CapsLock + CapsLock + + + + ; + ; + + + + ' + ' + + + + Enter + Enter + + + + Shift_L + + + + + , + , + + + + + . + . + + + + + / + / + + + + Ctrl_L + + + + + + Super_L + + + + + Alt_L + + + + + Space + + + + + Alt_R + + + + + Menu + + + + + Ctrl_R + + + + + Shift_R + + + + + Up + + + + + Left + + + + + Down + + + + + Right + + + + + PrtSc + PrtSc + + + + Ins + + + + + Del + Del + + + + Home + Home + + + + End + End + + + + PgUp + PgUp + + + + PgDn + PgDn + + + + NumLock + NumLock + + + + * + * + + + + + + + + + + + KP_Enter + + + + + KP_1 + + + + + KP_2 + + + + + KP_3 + + + + + KP_4 + + + + + KP_5 + + + + + KP_6 + + + + + KP_7 + + + + + KP_8 + + + + + KP_9 + + + + + KP_0 + + + + + SCLK + + + + + Pause + Pause + + + + Super_R + + + + + Mute + + + + + VolDn + + + + + VolUp + + + + + Play + + + + + Stop + + + + + Prev + + + + + Next + + + + + [NO KEY] + [割り当てなし] + + + + UnixWindowInfoDialog + + + Captured Window Properties + + + + + Information About Window + + + + + Class: + + + + + + + TextLabel + + + + + Title: + タイトル: + + + + Path: + + + + + Match By Properties + + + + + Class + + + + + Title + タイトル + + + + Path + + + + + VDPad + + + + + VDPad + + + + + VirtualKeyPushButton + + + Space + スペース + + + + Tab + Tab + + + + Shift (L) + Shift (左) + + + + Shift (R) + Shift (右) + + + + Ctrl (L) + Ctrl (左) + + + + Ctrl (R) + Ctrl (右) + + + + Alt (L) + Alt (左) + + + + + Alt (R) + Alt (右) + + + + ` + ` + + + + ~ + ~ + + + + + - + - + + + + = + = + + + + [ + [ + + + + ] + ] + + + + \ + \ + + + + Caps + Caps + + + + ; + ; + + + + ' + ' + + + + , + , + + + + + . + . + + + + + / + / + + + + ESC + + + + + PRTSC + + + + + SCLK + + + + + INS + + + + + PGUP + + + + + DEL + + + + + PGDN + + + + + 1 + 1 + + + + 2 + 2 + + + + 3 + 3 + + + + 4 + 4 + + + + 5 + 5 + + + + 6 + 6 + + + + 7 + 7 + + + + 8 + 8 + + + + 9 + 9 + + + + 0 + 0 + + + + NUM +LK + + + + + + * + * + + + + + + + + + + + E +N +T +E +R + + + + + < + < + + + + : + : + + + + Super (L) + + + + + Menu + + + + + Up + + + + + Down + + + + + Left + + + + + Right + + + + + VirtualKeyboardMouseWidget + + + + Keyboard + キーボード + + + + + Mouse + マウス + + + + Mouse Settings + マウスの設定 + + + + Left + Mouse + + + + + Up + Mouse + + + + + Left Button + Mouse + 左ボタン + + + + Middle Button + Mouse + 中ボタン + + + + Right Button + Mouse + 右ボタン + + + + Wheel Up + Mouse + + + + + Wheel Left + Mouse + + + + + Wheel Right + Mouse + + + + + Wheel Down + Mouse + + + + + Down + Mouse + + + + + Right + Mouse + + + + + Button 4 + Mouse + ボタン 4 + + + + Mouse 8 + Mouse + マウス 8 + + + + Button 5 + Mouse + ボタン 5 + + + + Mouse 9 + Mouse + マウス 9 + + + + NONE + 割り当てなし + + + + Applications + アプリケーション + + + + Browser Back + ブラウザ: 戻る + + + + Browser Favorites + ブラウザ: お気に入り + + + + Browser Forward + ブラウザ: 進む + + + + Browser Home + ブラウザ: ホーム + + + + Browser Refresh + ブラウザ: 更新 + + + + Browser Search + ブラウザ: 検索 + + + + Browser Stop + + + + + Calc + + + + + Email + Eメール + + + + Media + メディア + + + + Media Next + メディア: 次へ + + + + Media Play + メディア: 再生 + + + + Media Previous + メディア: 前へ + + + + Media Stop + メディア: 停止 + + + + Search + 検索 + + + + Volume Down + 音量: 下げる + + + + Volume Mute + 音量: ミュート + + + + Volume Up + 音量: 上げる + + + + VirtualMousePushButton + + + INVALID + + + + + WinAppProfileTimerDialog + + + + Capture Application + + + + + After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. + + + + + Timer: + タイマー: + + + + Seconds + + + + + Cancel + キャンセル + + + + WinExtras + + + [NO KEY] + [割り当てなし] + + + + AntiMicro Profile + AntiMicro プロファイル + + + + X11Extras + + + ESC + + + + + Tab + Tab + + + + Space + スペース + + + + DEL + + + + + Return + + + + + KP_Enter + + + + + Backspace + Backspace + + + + xinput extension was not found. No mouse acceleration changes will occur. + + + + + + xinput version must be at least 2.0. No mouse acceleration changes will occur. + + + + + Virtual pointer found with id=%1. + + + + + PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 + + + + + Changing mouse acceleration for device with id=%1 + + + + + XMLConfigReader + + + Could not write updated profile XML to file %1. + + + + + XMLConfigWriter + + + Could not write to profile at %1. + + + + diff --git a/share/antimicro/translations/antimicro_ru.ts b/share/antimicro/translations/antimicro_ru.ts new file mode 100644 index 0000000..eb1cacd --- /dev/null +++ b/share/antimicro/translations/antimicro_ru.ts @@ -0,0 +1,5911 @@ + + + + + AboutDialog + + + About + О программе + + + + Version + Версия + + + + Info + Информация + + + + Changelog + + + + + Since December 30, 2012, I have been working on antimicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. + +The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. + +Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. + +Once the Steam controller is finally released to the public, the need for this program might not exist anymore. Just based on the concept of the controller alone, the Steam controller would have so many advantages over using a program like this to provide KB+M emulation. + + + + + Copyright: 2013 - 2015 + + + + + Credits + Авторы + + + + antimicro + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Travis Nickles &lt;nickles.travis@gmail.com&gt;</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Contributors:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;"><br /></span>Zerro Alvein</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">aybe</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Jeff Backus &lt;jeff.backus@gmail.com&gt;</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Arthur Moore<br />Anton Tornqvist &lt;antont@inbox.lv&gt;</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Translators:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt; font-weight:600;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">zzpxyx - Chinese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">phob - German</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tou omiya - Japanese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">burunduk - Ukrainian</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Version 3, 29 June 2007</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Preamble</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">TERMS AND CONDITIONS</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">0. Definitions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">1. Source Code.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">2. Basic Permissions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">4. Conveying Verbatim Copies.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">5. Conveying Modified Source Versions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">6. Conveying Non-Source Forms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">7. Additional Terms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">8. Termination.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">11. Patents.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">14. Revised Versions of this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">15. Disclaimer of Warranty.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">16. Limitation of Liability.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> + + + + + About Development + + + + + License + Лицензия + + + + Program Version %1 + Версия программы %1 + + + + Program Compiled on %1 at %2 + Программа скомпилирована %1 в %2 + + + + Built Against SDL %1 + Собрана на SDL %1 + + + + Running With SDL %1 + Запускается на SDL %1 + + + + Using Qt %1 + Версия Qt %1 + + + + Using Event Handler: %1 + + + + + AddEditAutoProfileDialog + + + Auto Profile Dialog + Окно Авто Профиля + + + + Profile: + Профиль: + + + + + Browse + Обзор + + + + Window: + + + + + + Select Window. Click on the appropriate application +window and the application file path will be populated +in the form. + Кликните по нужному окну приложения чтобы автоматически добавить путь до него в форму. + + + + Detect Window Properties + + + + + Class: + + + + + Title: + + + + + Application: + + + + + Select + Выбор + + + + Devices: + Устройства: + + + + + Select this profile to be the default loaded for +the specified device. The selection will be used instead +of the all default profile option. + Выберите профиль, который будет автоматически загружаться для выбранного устройства. Выбранный профиль загрузится даже если выбран профиль по-умолчанию. + + + + Set as Default for Controller + Установить по-умолчанию для этого контроллера + + + + + A different profile is already selected as the default for this device. + Для этого контроллера уже назначен профиль по-умолчанию. + + + + Current (%1) + Текущий (%1) + + + + Open Config + Открыть Конфигурацию + + + + + Select Program + Выбрать Программу + + + + Programs (*.exe) + + + + + Please use the main default profile selection. + Пожалуйста, используйте основной профиль по-умолчанию. + + + + Please select a window by using the mouse. Press Escape if you want to cancel. + + + + + Capture Application Window + + + + + Could not obtain information for the selected window. + + + + + Application Capture Failed + + + + + Profile file path is invalid. + Неверный путь до профиля. + + + + No window matching property was specified. + + + + + Program path is invalid or not executable. + Путь до программы содержит ошибку или не может быть выполнен. + + + + File is not an .exe file. + + + + + No window matching property was selected. + + + + + AdvanceButtonDialog + + + + Advanced + Продвинутые настройки + + + + Assignments + Назначения + + + + Toggle + Переключатель + + + + Turbo + Турбо + + + + Set Selector + Установить Селектор + + + + Blank or KB/M + + + + + Hold + Удерживать + + + + Pause + Пауза + + + + Cycle + Цикл + + + + Distance + Дистанция + + + + Insert + Вставить + + + + Delete + Удалить + + + + Clear All + Очистить Все + + + + Time: + Время: + + + + 0.01s + 0,01 сек + + + + 0s + 0 сек + + + + Insert a pause that occurs in between key presses. + Вставить паузу между нажатиями на кнопку. + + + + Release + Отпускание + + + + + Insert a new blank slot. + Вставить новый пустой слот. + + + + Delete a slot. + Удалить слот. + + + + Clear all currently assigned slots. + Очистить все заполненные слоты. + + + + Specify the duration of an inserted Pause or Hold slot. + Определяет продолжительность для слотов Пауза и Удерживание. + + + + 0m + 0 мин + + + + + Specify the range past an axis dead zone in which a sequence of actions will execute. + Определяет диапазон оси для мертвой зоны в котором следует выполнять действия. + + + + Distance: + Дистанция: + + + + + % + % + + + + Mouse Mod + Скорость Мыши + + + + Press Time + Время Нажатия + + + + Delay + Задержка + + + + Execute + + + + + Load + Загрузить + + + + Set Change + + + + + Text Entry + + + + + Placeholder + Заполнитель + + + + + 0 + 0 + + + + Mouse Speed Mod: + Модификатор Скорости Мыши: + + + + Set the percentage that mouse speeds will be modified by. + Определяет в процентах на сколько должна быть изменена скорость мыши. + + + + Auto Reset Cycle After + Автоматически сбросить цикл после + + + + seconds + секунд + + + + ... + + + + + + + Enabled + Включено + + + + Mode: + + + + + <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> + + + + + Normal + Нормально + + + + Gradient + + + + + Pulse + + + + + Delay: + Задержка: + + + + 0.10s + 0,10 сек + + + + Rate: + Частота: + + + + 10.0/s + 10,0/сек + + + + + Disabled + Отключено + + + + Select Set 1 One Way + Установить Набор 1 Односторонним + + + + Select Set 1 Two Way + Установить Набор 1 Двусторонним + + + + Select Set 1 While Held + Установить Набор 1 Пока Нажато + + + + Select Set 2 One Way + Установить Набор 2 Односторонним + + + + Select Set 2 Two Way + Установить Набор 2 Двусторонним + + + + Select Set 2 While Held + Установить Набор 2 Пока Нажато + + + + Select Set 3 One Way + Установить Набор 3 Односторонним + + + + Select Set 3 Two Way + Установить Набор 3 Двусторонним + + + + Select Set 3 While Held + Установить Набор 3 Пока Нажато + + + + Select Set 4 One Way + Установить Набор 4 Односторонним + + + + Select Set 4 Two Way + Установить Набор 4 Двусторонним + + + + Select Set 4 While Held + Установить Набор 4 Пока Нажато + + + + Select Set 5 One Way + Установить Набор 5 Односторонним + + + + Select Set 5 Two Way + Установить Набор 5 Двусторонним + + + + Select Set 5 While Held + Установить Набор 5 Пока Нажато + + + + Select Set 6 One Way + Установить Набор 6 Односторонним + + + + Select Set 6 Two Way + Установить Набор 6 Двусторонним + + + + Select Set 6 While Held + Установить Набор 6 Пока Нажато + + + + Select Set 7 One Way + Установить Набор 7 Односторонним + + + + Select Set 7 Two Way + Установить Набор 7 Двусторонним + + + + Select Set 7 While Held + Установить Набор 7 Пока Нажато + + + + Select Set 8 One Way + Установить Набор 8 Односторонним + + + + Select Set 8 Two Way + Установить Набор 8 Двусторонним + + + + Select Set 8 While Held + Установить Набор 8 Пока Нажато + + + + sec. + сек. + + + + /sec. + /сек. + + + + Set %1 + Набор %1 + + + + + Select Set %1 + Установить Набор %1 + + + + One Way + Односторонним + + + + Two Way + Двусторонним + + + + While Held + Пока Нажато + + + + Choose Executable + + + + + Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. + + + + + Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. + + + + + Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. + + + + + Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. + + + + + Chose a profile to load when this slot is activated. + + + + + Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. + + + + + Specify the time that keys past this slot should be held down. + + + + + Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. + + + + + Change to selected set once slot is activated. + + + + + Full string will be typed when a slot is activated. + + + + + Execute program when slot is activated. + + + + + + Choose Profile + + + + + Config Files (*.amgp *.xml) + + + + + AdvanceStickAssignmentDialog + + + Stick/Pad Assignment + Настройки Стиков / Крестовин + + + + Sticks + Стики + + + + DPads + Крестовины + + + + + %1 (Joystick %2) + %1 (Геймпад %2) + + + + Stick 1 + Стик 1 + + + + + + Enabled + Включено + + + + + + + + + Assign + Назначить + + + + + X Axis: + Ось X: + + + + + Y Axis: + Ось Y: + + + + Stick 2 + Стик 2 + + + + Number of Physical DPads: %1 + Количество физических крестовин: %1 + + + + Virtual DPad 1 + Виртуальная Крестовина 1 + + + + Up: + Вверх: + + + + Down: + Вниз: + + + + Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. + + + + + Left: + Влево: + + + + Right: + Вправо: + + + + + + + Axis %1 + Ось %1 + + + + + + + Axis %1 - + Ось %1 - + + + + + + + Axis %1 + + Ось %1 + + + + + + + + Button %1 + Кнопка %1 + + + + Move stick 1 along the X axis + Переместите Cтик 1 по оси X + + + + Move stick 1 along the Y axis + Переместите Cтик 1 по оси Y + + + + Move stick 2 along the X axis + Переместите Cтик 2 по оси X + + + + Move stick 2 along the Y axis + Переместите Cтик 2 по оси Y + + + + + + + Press a button or move an axis + Нажмите кнопку или подвигайте стик + + + + AxisEditDialog + + + Axis + Ось + + + + + Mouse (Horizontal) + Мышь (горизонталь) + + + + + Mouse (Inverted Horizontal) + Мышь (инвертированная горизонталь) + + + + + Mouse (Vertical) + Мышь (вертикаль) + + + + + Mouse (Inverted Vertical) + Мышь (инвертированная вертикаль) + + + + + Arrows: Up | Down + Стрелки: Вверх | Вниз + + + + + Arrows: Left | Right + Стрелки: Влево | Вправо + + + + + Keys: W | S + Клавиши: W | S + + + + + Keys: A | D + Клавиши: A | D + + + + + NumPad: KP_8 | KP_2 + NumPad: 8 | 2 + + + + + NumPad: KP_4 | KP_6 + NumPad: 4 | 6 + + + + + + None + Отсутствует + + + + + Set the value to use as the limit for an axis. Useful for a +worn out analog stick. + + + + + Negative Half Throttle + Отрицательная Полутяга + + + + Positive Half Throttle + Положительная Полутяга + + + + Name: + Имя: + + + + Specify the name of an axis. + Укажите имя для оси. + + + + Mouse Settings + Настройки Мыши + + + + + Set the value of the dead zone for an axis. + Устанавливает значение мертвой зоны для оси. + + + + Presets: + Пресет: + + + + Dead Zone: + Мертвая Зона: + + + + Max Zone: + Лимит: + + + + + [NO KEY] + [ПУСТО] + + + + Throttle setting that determines the behavior of how to +interpret an axis hold or release. + Настройки тяги определяют как программа будет расценивать удерживание или отпускание оси. + + + + Negative Throttle + Отрицательная Тяга + + + + Normal + Нормально + + + + Positive Throttle + Положительная Тяга + + + + Current Value: + Текущее значение: + + + + Set + Установки для + + + + Set %1 + Набор %1 + + + + Left Mouse Button + + + + + Right Mouse Button + + + + + ButtonEditDialog + + + Dialog + Окно + + + + To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab + <center>Чтобы назначить новое действие нажмите на соответствующую кнопку во вкладках "Клавиатура" или "Мышь"</center> + + + + Placeholder + Заполнитель + + + + Toggle + Переключатель + + + + Enables a key press or release to only occur when a controller button is pressed. + Добавляет возможность производить действие только в случае нажатия или отпускания кнопки. + + + + Enables rapid key presses and releases. Turbo controller. + Добавляет возможность быстрого нажатия кнопок (как в турбо контроллере). + + + + Turbo + Турбо + + + + Current: + Текущая: + + + + Slots + Слоты + + + + Na&me: + + + + + Specify the name of a button. + Укажите название кнопки. + + + + Action: + Действие: + + + + Specify the action that will be performed in game while +this button is being used. + Укажите какое действие будет производится при нажатии данной кнопки. + + + + Advanced + Дополнительно + + + + Set + Установки для + + + + Set %1 + Набор %1 + + + + CapturedWindowInfoDialog + + + Captured Window Properties + + + + + Information About Window + + + + + Class: + + + + + + + TextLabel + + + + + Title: + + + + + Path: + + + + + Match By Properties + + + + + Class + + + + + Title + + + + + Path + + + + + Full Path + + + + + File Name + + + + + CommandLineUtility + + + + Profile location %1 is not an XML file. + Профиль, находящийся в %1 не является XML файлом. + + + + + Profile location %1 does not exist. + Профиль, находящийся в %1 не существует. + + + + An invalid set number '%1' was specified. + + + + + Controller identifier '%s'' is not a valid value. + + + + + No display string was specified. + Не указана строка для отображения. + + + + + + Controller identifier is not a valid value. + Идентификатор контроллера имеет недопустимое значение. + + + + No set number was specified. + Не указан набор значений. + + + + No controller was specified. + + + + + An invalid event generator was specified. + + + + + No event generator string was specified. + + + + + Qt style flag was detected but no style was specified. + + + + + No log level specified. + + + + + + + + antimicro version + + + + + + Usage: antimicro [options...] [profile] + + + + + + Options + Опции + + + + + Print help text. + Показать текст помощи. + + + + + Print version information. + Показать информацию о версии. + + + + + Launch program in system tray only. + Запускать программу только в системном трее. + + + + + Launch program with the tray menu disabled. + Запустить программу с отключенным меню трея. + + + + + Launch program without the main window + displayed. + Запускать программу без отображения + главного окна. + + + + + Launch program with the configuration file + selected as the default for selected + controllers. Defaults to all controllers. + Запускать программу с конфигурационным файлом, + назначенным по-умолчанию для выбранных контроллеров. + Настройки контроллеров будут выставлены по-умолчанию. + + + + + Apply configuration file to a specific + controller. Value can be a + controller index, name, or GUID. + Применить файл конфигурации для определенных контроллеров. + Значениями могут быть индекс + контроллера, имя или GUID. + + + + + Unload currently enabled profile(s). + Value can be a controller index, name, or GUID. + Загрузить текущие активные профили. + Значениями могут быть индекс контроллера, имя или GUID. + + + + + Start joysticks on a specific set. + Value can be a controller index, name, or GUID. + Запускать геймпады на определнном наборе. + Значениями могут быть индекс контроллера, имя или GUID. + + + + + Advance profile loading set options. + + + + + + Launch program as a daemon. + Запускать программу в качестве демона. + + + + + Enable logging. + + + + + + Use specified display for X11 calls. + Useful for ssh. + + + + + + Choose between using XTest support and uinput + support for event generation. Default: xtest. + + + + + + Choose between using SendInput and vmulti + support for event generation. Default: sendinput. + + + + + + Print information about joysticks detected by + SDL. + + + + + + Open game controller mapping window of selected + controller. Value can be a controller index or + GUID. + + + + + DPadContextMenu + + + Mouse (Normal) + Мышь (Нормально) + + + + Mouse (Inverted Horizontal) + + + + + Mouse (Inverted Vertical) + + + + + Mouse (Inverted Horizontal + Vertical) + + + + + Arrows + Стрелки + + + + Keys: W | A | S | D + Клавиши: W | A | S | D + + + + NumPad + NumPad + + + + None + Отсутствует + + + + Standard + Стандартный + + + + Eight Way + 8-ми сторонний + + + + 4 Way Cardinal + 4-х сторонний основной + + + + 4 Way Diagonal + 4-х сторонний диагональный + + + + Mouse Settings + + + + + DPadEditDialog + + + Dialog + Окно + + + + Presets: + Пресет: + + + + Mouse (Normal) + Мышь (Нормально) + + + + Mouse (Inverted Horizontal) + Мышь (Инвертированная Горизонталь) + + + + Mouse (Inverted Vertical) + Мышь (Инвертированная Вертикаль) + + + + Mouse (Inverted Horizontal + Vertical) + Мышь (Инвертированная Горизонталь + Вертикаль) + + + + Arrows + Стрелки + + + + Keys: W | A | S | D + Клавиши: W | A | S | D + + + + NumPad + NumPad + + + + None + Отсутствует + + + + Dpad Mode: + Режим Крестовины: + + + + &Name: + + + + + 4 Way Cardinal + 4-х сторонний основной + + + + 4 Way Diagonal + 4-х сторонний диагональный + + + + DPad Delay: + + + + + + Time lapsed before a direction change is taken into effect. + + + + + s + + + + + Specify the name of a dpad. + Укажите имя для крестовины. + + + + Mouse Settings + Настройки Мыши + + + + Standard + Стандартный + + + + Standard: 8 region dpad with two direction buttons active +when the dpad is in a diagonal region. + +Eight Way: 8 region dpad with each direction having its +own dedicated button. Only one button is ever active at +at time. Useful for rougelike games. + +4 Way Cardinal: 4 region dpad with regions corresponding to +the cardinal directions of the dpad. Useful for menus. + +4 Way Diagonal: 4 region dpad with each region corresponding +to a diagonal zone. + + + + + Eight Way + 8-ми сторонний + + + + Set + Установки для + + + + Set %1 + Набор %1 + + + + EditAllDefaultAutoProfileDialog + + + Default Profile + Профиль По-Умолчанию + + + + Profile: + Профиль: + + + + Browse + Обзор + + + + Open Config + Открыть Конфигурацию + + + + Profile file path is invalid. + Путь до профиля неверен. + + + + ExtraProfileSettingsDialog + + + Extra Profile Settings + Дополнительные настройки профиля + + + + Key Press Time: + Отклик Клавиш: + + + + 0.00 ms + 0,00 мс + + + + Profile Name: + Имя Профиля: + + + + + + s + сек + + + + GameController + + + Game Controller + Геймпад + + + + GameControllerDPad + + + + + DPad + Крестовина + + + + GameControllerMappingDialog + + + Game Controller Mapping + Настройка Игрового Контроллера + + + + <html><head/><body><p>antimicro makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicro will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> + + + + + A + A + + + + B + B + + + + X + X + + + + Y + Y + + + + Back + Back + + + + Start + Start + + + + Guide + Guide + + + + Left Shoulder + Левый Бампер + + + + Right Shoulder + Правый Бампер + + + + Left Stick Click + Кнопка Левого Стика + + + + Right Stick Click + Кнопка Правого Стика + + + + Left Stick X + Ось X Левого Стика + + + + Left Stick Y + Ось Y Левого Стика + + + + Right Stick X + Ось X Правого Стика + + + + Right Stick Y + Ось Y Правого Стика + + + + Left Trigger + Левый Триггер + + + + Right Trigger + Правый Триггер + + + + DPad Up + Крестовина Вверх + + + + DPad Left + Крестовина Влево + + + + DPad Down + Крестовина Вниз + + + + DPad Right + Крестовина Вправо + + + + Mapping + Настройка + + + + SDL 2 Game Controller Mapping String + Вывод настройщика контроллеров SDL 2 + + + + Last Axis Event: + + + + + Current Axis Detection Dead Zone: + + + + + 5000 + 5000 + + + + 10000 + 10000 + + + + 15000 + 15000 + + + + 20000 + 20000 + + + + 25000 + 25000 + + + + 30000 + 30000 + + + + 32000 + 32000 + + + + Game Controller Mapping (%1) (#%2) + + + + + Discard Controller Mapping? + Сбросить настройки контроллера? + + + + Discard mapping for this controller? + +If discarded, the controller will be reverted to a joystick once you refresh all joysticks. + Сбросить настройки для этого контроллера? + +Если сбросить настройки, контроллер вернется к своему изначальному состоянию после обновления всех геймпадов. + + + + GameControllerSet + + + Back + Back + + + + Guide + Guide + + + + Start + Start + + + + LS Click + + + + + RS Click + + + + + L Shoulder + + + + + R Shoulder + + + + + L Trigger + + + + + R Trigger + + + + + GameControllerTrigger + + + + + Trigger + Триггер + + + + JoyAxis + + + + + Axis + Ось + + + + JoyAxisButton + + + Negative + Отрицательно + + + + Positive + Положительно + + + + Unknown + Неизвестно + + + + + + Button + Кнопка + + + + JoyAxisContextMenu + + + Mouse (Horizontal) + Мышь (горизонталь) + + + + Mouse (Inverted Horizontal) + + + + + Mouse (Vertical) + Мышь (вертикаль) + + + + Mouse (Inverted Vertical) + + + + + Arrows: Up | Down + Стрелки: Вверх | Вниз + + + + Arrows: Left | Right + Стрелки: Влево | Вправо + + + + Keys: W | S + Клавиши: W | S + + + + Keys: A | D + Клавиши: A | D + + + + NumPad: KP_8 | KP_2 + NumPad: 8 | 2 + + + + NumPad: KP_4 | KP_6 + NumPad: 4 | 6 + + + + + None + Отсутствует + + + + + Mouse Settings + + + + + Left Mouse Button + + + + + Right Mouse Button + + + + + JoyButton + + + Processing turbo for #%1 - %2 + + + + + Finishing turbo for button #%1 - %2 + + + + + Processing press for button #%1 - %2 + + + + + Processing release for button #%1 - %2 + + + + + Distance change for button #%1 - %2 + + + + + + + Button + Кнопка + + + + + + + [NO KEY] + [ПУСТО] + + + + [Set %1 1W] + + + + + [Set %1 2W] + + + + + [Set %1 WH] + + + + + JoyButtonContextMenu + + + Toggle + Переключатель + + + + Turbo + Турбо + + + + Clear + + + + + Set Select + + + + + Disabled + Отключено + + + + Set %1 + + + + + Set %1 1W + Набор %1 1W + + + + Set %1 2W + Набор %1 2W + + + + Set %1 WH + + + + + JoyButtonSlot + + + + Mouse + Мышь + + + + Up + Вверх + + + + Down + Вниз + + + + Left + Влево + + + + Right + Вправо + + + + LB + LB + + + + MB + MB + + + + RB + RB + + + + B4 + B4 + + + + B5 + B5 + + + + Pause + Пауза + + + + Hold + Удерживание + + + + Cycle + Цикл + + + + Distance + Дистанция + + + + Release + Отпускание + + + + Mouse Mod + Скорость Мыши + + + + Press Time + Время Нажатия + + + + Delay + Задержка + + + + Load %1 + + + + + Set Change %1 + + + + + [Text] %1 + + + + + [Exec] %1 + + + + + [NO KEY] + [ПУСТО] + + + + JoyControlStick + + + + + Stick + Стик + + + + JoyControlStickButton + + + + + Up + Вверх + + + + + + Down + Вниз + + + + + + Left + Влево + + + + + + Right + Вправо + + + + + + Button + Кнопка + + + + JoyControlStickContextMenu + + + Mouse (Normal) + Мышь (Нормально) + + + + Mouse (Inverted Horizontal) + + + + + Mouse (Inverted Vertical) + + + + + Mouse (Inverted Horizontal + Vertical) + + + + + Arrows + Стрелки + + + + Keys: W | A | S | D + Клавиши: W | A | S | D + + + + NumPad + NumPad + + + + None + Отсутствует + + + + Standard + Стандартный + + + + Eight Way + 8-ми сторонний + + + + 4 Way Cardinal + 4-х сторонний основной + + + + 4 Way Diagonal + 4-х сторонний диагональный + + + + Mouse Settings + + + + + JoyControlStickEditDialog + + + Dialog + Окно + + + + X: + Х: + + + + + + + + 0 + 0 + + + + Y: + Y: + + + + Distance: + Дистанция: + + + + Presets: + Пресет: + + + + Mouse (Normal) + Мышь (Нормально) + + + + Mouse (Inverted Horizontal) + Мышь (инвертированная горизонталь) + + + + Mouse (Inverted Vertical) + Мышь (инвертированная вертикаль) + + + + Mouse (Inverted Horizontal + Vertical) + Мышь (инвертированная горизонталь + вертикаль) + + + + Arrows + Стрелки + + + + Keys: W | A | S | D + Клавиши: W | A | S | D + + + + NumPad + NumPad + + + + None + Отсутствует + + + + Stick Mode: + Режим Стика: + + + + Standard: 8 region stick with two direction buttons active +when the stick is in a diagonal region. + +Eight Way: 8 region stick with each direction having its +own dedicated button. Only one button is ever active at +at time. Useful for rougelike games. + +4 Way Cardinal: 4 region stick with regions corresponding to +the cardinal directions of the stick. Useful for menus. + +4 Way Diagonal: 4 region stick with each region corresponding +to a diagonal zone of the stick. + + + + + 4 Way Cardinal + 4-х сторонний основной + + + + 4 Way Diagonal + 4-х сторонний диагональный + + + + + Dead zone value to use for an analog stick. + + + + + + Value when an analog stick is considered moved 100%. + + + + + + The area (in degrees) that each diagonal region occupies. + + + + + Square Stick: + + + + + + Percentage to modify a square stick coordinates to confine values to a circle + + + + + % + % + + + + Stick Delay: + + + + + + Time lapsed before a direction change is taken into effect. + + + + + s + + + + + Modifier: + + + + + Edit button that is active while the stick is active. + +This button is useful for assigning zones with +modifier keys that can be used to assign walk/run +functionality to an analog stick. + + + + + PushButton + + + + + Name: + Имя: + + + + Specify the name of an analog stick. + Укажите имя для аналогового стика. + + + + Mouse Settings + Настройки Мыши + + + + Standard + Стандартный + + + + Bearing: + Точка Опоры: + + + + % Safe Zone: + % ограничения: + + + + Eight Way + 8-ми сторонний + + + + Dead Zone: + Мертвая Зона: + + + + Max Zone: + Лимит: + + + + Diagonal Range: + Диагональный диапазон: + + + + Set + Установки для + + + + Set %1 + Установки для %1 + + + + JoyControlStickModifierButton + + + + + Modifier + + + + + JoyDPad + + + + + DPad + Крестовина + + + + JoyDPadButton + + + + + Up + Вверх + + + + + + Down + Вниз + + + + + + Left + Влево + + + + + + Right + Вправо + + + + + + Button + Кнопка + + + + JoyTabWidget + + + + + + + + <New> + <Новый> + + + + + Remove + Удалить + + + + + Remove configuration from recent list. + Удалить конфигурацию из списка недавно использованных файлов. + + + + + Load + Загрузить + + + + + Load configuration file. + Загрузить файл конфигурации. + + + + + Save + Сохранить + + + + + Save changes to configuration file. + Сохранить изменения в файл конфигурации. + + + + + Save As + Сохранить Как + + + + + Save changes to a new configuration file. + Сохранить изменения в новый файл конфигурации. + + + + + Sets + Наборы + + + + Copy from Set + + + + + Settings + Настройки + + + + + Set 1 + Набор 1 + + + + + Set 2 + Набор 2 + + + + + Set 3 + Набор 3 + + + + + Set 4 + Набор 4 + + + + + Set 5 + Набор 5 + + + + + Set 6 + Набор 6 + + + + + Set 7 + Набор 7 + + + + + Set 8 + Набор 8 + + + + + Stick/Pad Assign + Настройка Стиков/Крестровин + + + + + Controller Mapping + Настройка Контроллера + + + + + Quick Set + Быстрая Настройка + + + + + Names + Бирки + + + + + Toggle button name displaying. + Вкл. / Выкл. отображение названий команд на кнопках. + + + + + Pref + Настройки Профиля + + + + + Change global profile settings. + Изменить общие настройки профиля. + + + + + + Reset + Сброс + + + + + Revert changes to the configuration. Reload configuration file. + Отменяет изменения конфигурации. Перезагружает конфигурационный файл. + + + + Open Config + Открыть Конфигурацию + + + + Config Files (*.amgp *.xml) + + + + + + + Config File (*.%1.amgp) + + + + + + Save Profile Changes? + Сохранить изменения в профиле? + + + + + Changes to the new profile have not been saved. Would you like to save or discard the current profile? + Изменения в новом профиле не были сохранены. Сохранить или отменить изменения в текущем профиле? + + + + + Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? + Изменения в профиле "%1" не были сохранены. Сохранить или отменить изменения в текущем профиле? + + + + Sticks + Стики + + + + + DPads + Крестовины + + + + No buttons have been assigned. Please use Quick Set to assign keys +to buttons or disable hiding empty buttons. + <center>Не было назначено ни одной кнопки. Воспользуйтесь "Быстрой Настройкой" <br>для назначения кнопок или отключите сокрытие пустых кнопок.</center> + + + + + Set %1: %2 + Набор %1: %2 + + + + + Set %1 + Набор %1 + + + + Copy Set Assignments + Скопировать Набор Настроек + + + + Are you sure you want to copy the assignments and device properties from %1? + Вы уверены что хотите скопировать настройки и параметры устройства из %1? + + + + + + Save Config + Сохранить Конфигурацию + + + + + Set + Набор + + + + Joystick + + + Joystick + Геймпад + + + + JoystickStatusWindow + + + Properties + Свойства + + + + Details + Детали + + + + Name: + Имя: + + + + + + + + + + %1 + %1 + + + + Number: + Номер: + + + + Axes: + Осей: + + + + Buttons: + Кнопок: + + + + Hats: + Мини-джойстиков: + + + + GUID: + GUID: + + + + Game Controller: + + + + + Axes + Оси + + + + Buttons + Кнопки + + + + Hats + Мини-джойстики + + + + %1 (#%2) Properties + %1 (#%2) Свойства + + + + Axis %1 + Ось %1 + + + + Hat %1 + Мини-джойстик %1 + + + + No + + + + + Yes + + + + + MainSettingsDialog + + + Edit Settings + Редактировать настройки + + + + General + Общие + + + + Controller Mappings + Настройки Контроллера + + + + Language + Язык + + + + Auto Profile + АвтоПрофиль + + + + Mouse + Мышь + + + + <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> + <html><head/><body><p>Укажите путь до директории, которую программа будет использовать для хранения профилей.</p></body></html> + + + + Recent Profile Count: + Количество недавних профилей: + + + + <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> + <html><head/><body><p>Количество профилей, которые будут хранится в списке недавних. Если выставить "0" то программа не будет ограничивать количество отображаемых профилей.</p></body></html> + + + + Gamepad Poll Rate: + + + + + Change the poll rate that the program uses to discover new +events from gamepads. Defaults to 10 ms. + +Reducing the poll rate value could cause the application to +use more CPU power so please test the setting that you use +before using antimicro unattended. + + + + + Hide main window when the main window close button is +clicked instead of quitting the program. + Прятать главное окно программы по нажатию на кнопку выхода вместо того чтобы закрывать программу. + + + + Close To Tray + Сворачивать в трей + + + + Have Windows start antimicro at system startup. + + + + + Launch At Windows Startup + Загружать вместе с Windows + + + + Display recent profiles for all controllers +as a single list in the tray menu. Defaults +to using sub-menus. + Отображает недавно открытые профили для всех контроллеров в виде единого списка под иконкой в трее. По-умолчанию использует подменю. + + + + Single Profile List in Tray + Единый лист профилей в трее + + + + Have the program minimize to the taskbar. +By default, the program minimizes to the system +tray if available. + Заставляет программу сворачиватся в панель задач. По-умолчанию программа сворачивается в системный трей. + + + + Minimize to Taskbar + Сворачивать в панель задач + + + + This option will cause the program to hide all +buttons that have no slots assigned to them. +The Quick Set dialog window will have to be used +to bring up the edit dialog for gamepad buttons. + Эта опция заставит программу скрывать все кнопки, к которым не привязаны слоты с командами. Воспользуйтесь окном "Быстрой Настройки" для отображения скрытых кнопок. + + + + Hide Empty Buttons + Скрыть пустые кнопки + + + + When the program is launched, open the last +known profile that was opened during the +previous session. + Когда программа запустится, будет открыт последний профиль, использованный в предыдущей сессии. + + + + Auto Load Last Opened Profile + Автоматически загружать последний открытый профиль + + + + Only show the system tray icon when the program +first launches. + При запуске программы появится лишь значок в системном трее. + + + + Launch in Tray + Запускаться в свернутом виде + + + + Associate .amgp files with antimicro in Windows Explorer. + + + + + Associate Profiles + + + + + Key Repeat + Повтор клавиш + + + + Active keys will be repeatedly pressed when this +option is enabled. + Если активировать данную опцию то активные клавиши будут нажиматься автоматически. + + + + + Enable + + + + + Specifies how much time should elapse before key repeating +begins. + + + + + Specifies how many times key presses will be performed +per seconds. + + + + + <html><head/><body><p>antimicro has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make antimicro load a different translation depending on the language that you choose from the list below.</p></body></html> + + + + + French + + + + + Japanese + + + + + Russian + + + + + Serbian + + + + + Simplified Chinese + + + + + Ukrainian + + + + + Class + + + + + Title + + + + + Program + + + + + Disable the "Enhanced Pointer Precision" Windows setting +while antimicro is running. Disabling "Enhanced Pointer Precision" +will allow mouse movement within antimicro to be more +precise. + + + + + Disable Enhance Pointer Precision + + + + + Smoothing + + + + + Histor&y Size: + + + + + Weight &Modifier: + + + + + Refresh Rate: + + + + + The refresh rate is the amount of time that will elapse +in between mouse events. Please be cautious when +editing this setting as it will cause the program to use +more CPU power. Setting this value too low can cause +system instability. Please test the setting before using +it unattended. + + + + + Spring + Пружина + + + + Screen: + + + + + Utilize the specified screen for spring mode. On Linux, the +default is to use the primary screen. On Windows, the default +is to use all available screens. + + + + + Accel Numerator: + + + + + + + 0 + 0 + + + + Accel Denominator: + + + + + Accel Threshold: + + + + + If the acceleration values for the virtual mouse have been +changed by a different process, particularly when quitting +an older game, then you might want to reset the acceleration +values used by the virtual mouse. + + + + + Reset Acceleration + + + + + Delay: + Задержка: + + + + Profi&le Directory: + + + + + ms + мс + + + + Rate: + Частота: + + + + times/s + раз/сек + + + + Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. + +Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. + Ниже приведен сохраненный список из пользовательских настроек. Вы можете использовать эту таблицу, чтобы удалять настройки или же временно их отключать. Также Вы можете отключить настройки, входящие в SDL - просто добавьте новую строку с соответствующим GUID геймпада и активируйте чекбокс "Отключить" + +Изменения не вступят в силу пока вы не обновите или переподключите все геймпады. + + + + GUID + GUID + + + + Mapping String + Строка Настроек + + + + Disable? + Отключить? + + + + + Delete + Удалить + + + + Insert + Вставить + + + + + Default + По-умолчанию + + + + Brazilian Portuguese + Бразильский / Португальский + + + + English + Английский + + + + German + Немецкий + + + + + Active + Активировать + + + + Devices: + Устройства: + + + + + All + Все + + + + Device + Устройство + + + + Profile + Профиль + + + + Default? + По-умолчанию? + + + + Add + Добавить + + + + Edit + Редактировать + + + + Also, Windows users who want to use a low value should also check the +"Disable Enhance Pointer Precision" checkbox if you haven't disabled +the option in Windows. + + + + + Select Default Profile Directory + Выбрать как профиль по-умолчанию + + + + Are you sure you want to delete the profile? + Вы уверены что хотите удалить этот профиль? + + + + MainWindow + + + antimicro + + + + + No Joysticks have been found. + Please plug in a joystick and then choose the "Update Joysticks" option in the main menu + Геймпады не обнаружены. Пожалуйста, подключите геймпад к компьютеру и выберете опцию "Обновить Геймпады" из главного меню. + + + + If events are not seen by a game, please click here to run this application as the Adminstrator. + + + + + &App + &Приложение + + + + &Options + &Опции + + + + &Help + &Помощь + + + + + &Quit + &Выход + + + + Ctrl+Q + Ctrl+Q + + + + + &Update Joysticks + &Обновить Геймпады + + + + Ctrl+U + Ctrl+U + + + + + &Hide + &Скрыть + + + + Ctrl+H + Ctrl+H + + + + &About + &О программе + + + + Ctrl+A + Ctrl+A + + + + About Qt + О Qt + + + + Properties + Свойства + + + + Key Checker + Проверка Клавиш + + + + Home Page + Домашняя страница + + + + GitHub Page + Страница на GitHub + + + + Game Controller Mapping + Настройки Игрового Контроллера + + + + Settings + Настройки + + + + Stick/Pad Assign + Настройки Стиков / Крестовин + + + + Wiki + + + + + Could not find a proper controller identifier. Exiting. + + + + + + + + + + + (%1) + (%1) + + + + + Open File + Открыть файл + + + + &Restore + &Восстановить + + + + Run as Administrator? + + + + + Are you sure that you want to run this program as Adminstrator? + +Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. + + + + + Failed to elevate program + + + + + Failed to restart this program as the Administrator + + + + + Could not find controller. Exiting. + + + + + MouseAxisSettingsDialog + + + Mouse Settings - + Настройки Мыши - + + + + Set %1 + Установки для %1 + + + + MouseButtonSettingsDialog + + + Mouse Settings - + Настройки Мыши - + + + + Set %1 + Установки для %1 + + + + MouseControlStickSettingsDialog + + + Mouse Settings + Настройки Мыши + + + + Set %1 + Установки для %1 + + + + MouseDPadSettingsDialog + + + Mouse Settings + Настройки Мыши + + + + Set %1 + Установки для %1 + + + + MouseSettingsDialog + + + Mouse Settings + Настройки Мыши + + + + Mouse Mode: + Режим Мыши: + + + + Cursor mode is used to move the mouse cursor +around the screen relative to its current position +depending on how much you move an axis +or if a button is pressed. + +Spring mode is used to move the mouse cursor +from the center of the screen depending on how +much you move an axis. The mouse cursor will +be returned to the center of the screen when the +axis is moved back to the dead zone. + Режим Курсора используется для перемещения курсора мыши +по экрану по отношению к текущей позиции +в зависимости от того, насколько вы переместили ось, +или при нажатии кнопки. + +Режим Пружины используется для перемещения курсора мыши +от центра экрана в зависимости от того, насколько +вы переместили ось. Курсор мыши будет +возвращен в центр экрана, когда +ось переместится обратно к мертвой зоне. + + + + Cursor + Курсор + + + + Spring + Пружина + + + + Acceleration: + Усиление: + + + + Enhanced Precision + Улучшенная Точность + + + + + Linear + Линейное + + + + Quadratic + Квадратное + + + + Cubic + Кубическое + + + + Quadratic Extreme + Экстримально Кубическое + + + + Power Function + Степенная Функция + + + + Easing Quadratic + + + + + Easing Cubic + + + + + Mouse Speed Settings + Настройки скорости мыши + + + + Enable to change the horizontal and vertical speed +boxes at the same time. + Позволяет увеличивать скорость мыши по горизонтали и вертикали одновременно. + + + + Change Together + Изменять совместно + + + + Horizontal +Speed: + Скорость по +горизонтали: + + + + + 1 = 20 pps + 1 = 20 pps + + + + Vertical +Speed: + Скорость по +вертикали: + + + + Wheel Hori. +Speed: + Скорость колесика +по горизонтали: + + + + Set the speed used for horizontal mouse wheel movement +according to number of simulated notches per second. + Устанавливает скорость движения колесика мыши по горизонтали. + + + + Set the speed used for vertical mouse wheel movement +according to number of simulated notches per second. + Устанавливает скорость движения колесика мыши по вертикали. + + + + For Power Function acceleration curve. Specifies +the factor to use for curve sensitivity. When the value +is above 1.0, the mouse movement will be accelerated +faster at the low end of an axis. + + + + + Easing Duration: + + + + + + s + + + + + Extra Acceleration + + + + + Multiplier: + + + + + Highest value to accelerate mouse movement by + + + + + x + x + + + + Start %: + + + + + Acceleration begins at this percentage of the base multiplier + + + + + Min +Threshold: + + + + + Minimum amount of axis travel required for acceleration to begin + + + + + Max +Threshold: + + + + + Maximum axis travel before acceleration has reached the multiplier value + + + + + Curve: + + + + + Ease Out Sine + + + + + Ease Out Quad + + + + + Ease Out Cubic + + + + + Release Radius: + + + + + Specifies that the spring area will be relative to the +mouse position set by a non-relative spring. + Привязывает пружину к позиции мыши. + + + + Relative + Привязка + + + + Mouse Status + + + + + X: + Х: + + + + + 0 (0 pps) + + + + + Y: + Y: + + + + + 1 = 1 notch(es)/s + 1 = 1 шаг(ов)/сек + + + + Enhanced: Three tier curve that makes the mouse move +slow on the low end of an axis and fast on the high end. + +Linear: Mouse moves proportionally to axis. + +Quadratic: Mouse accelerates slowly on low end. + +Cubic: Mouse accelerates slower than Quadratic. + +Quadratic Extreme: Raises mouse speed 1.5 times once +95% axis travel has been reached. + +Power Function: Allows for a more custom curve option. + +Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. + +Easing Cubic: Axis high end is gradually accelerated over +a period of time using a Cubic curve. + + + + + Wheel Vert. +Speed: + Скорость колесика +по вертикали: + + + + Sensitivity: + Чувствительность: + + + + Specifies the amount of time (in seconds) that will +be required before the mouse is fully accelerated +after reaching the high end of an axis. + + + + + Options for adding extra acceleration to the mouse +movement beyond what the acceleration curve would +produce. This is meant to help work around some of +the issues of the very limited input range available using +typical gamepad analog sticks. + + + + + + + + % + % + + + + Extra Duration: + + + + + Extend the time that extra acceleration is applied. Axis travel +will be taken into account. A slower flick will decrease the +actual time that extra acceleration will be applied. + + + + + Spring Settings + Настройки Пружины + + + + Spring Width: + Ширина Пружины: + + + + Changes the width of the region that the cursor +can move in spring mode. 0 will use the entire width +of your screen. + Изменяет ширину области, по которой будет двигаться курсор в режиме Пружины. Если выставить "0" будет использоваться вся ширина экрана. + + + + Spring Height: + Высота Пружины: + + + + Changes the height of the region that the cursor +can move in spring mode. 0 will use the entire height +of your screen. + Изменяет высоту области, по которой будет двигаться курсор в режиме Пружины. Если выставить "0" будет использоваться вся высота экрана. + + + + + %n notch(es)/s + + %n шаг/сек + %n шагов/сек + %n шаг(ов)/сек + + + + + QKeyDisplayDialog + + + Key Checker + Проверка Клавиш + + + + <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by antimicro.</p><p>The antimicro key value and the Qt key value will usually be the same. antimicro tries to use the key values defined in Qt when possible. Check the page <a href="http://qt-project.org/doc/qt-4.8/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://qt-project.org/doc/qt-4.8/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to antimicro's <a href="https://github.com/Ryochan7/antimicro"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> + + + + + Event Handler: + + + + + Native Key Value: + Родное Значение Клавиши: + + + + + + 0x00000000 + 0x00000000 + + + + Qt Key Value: + Значение Клавиши в Qt: + + + + antimicro Key Value: + + + + + QObject + + + Super + Super + + + + Menu + Меню + + + + Mute + + + + + Vol+ + + + + + Vol- + + + + + Play/Pause + + + + + Play + + + + + Pause + Пауза + + + + Prev + + + + + Next + Next + + + + Mail + + + + + Home + Home + + + + Media + + + + + Search + + + + + Daemon launched + Демон запущен + + + + Failed to launch daemon + Не удалось запустить демон + + + + Launching daemon + Демон запускается + + + + + Display string "%1" is not valid. + + + + + Failed to set a signature id for the daemon + Не удалось подписать демон + + + + Failed to change working directory to / + Не удалось менить рабочую директорию на "/" + + + + Quitting Program + + + + + # of joysticks found: %1 + + + + + List Joysticks: + + + + + --------------- + + + + + Joystick %1: + + + + + Index: %1 + + + + + GUID: %1 + + + + + Name: %1 + + + + + Yes + + + + + No + + + + + Game Controller: %1 + + + + + # of Axes: %1 + + + + + # of Buttons: %1 + + + + + # of Hats: %1 + + + + + Attempting to use fallback option %1 for event generation. + + + + + Failed to open event generator. Exiting. + + + + + Using %1 as the event generator. + + + + + Could not raise process priority. + + + + + QuickSetDialog + + + Quick Set + Быстрая настройка + + + + <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> + <html><head/><body><p>Пожалуйста, нажмите кнопку или подвигайте стик на %1 (<span style=" font-weight:600;">%2</span>).<br/>Появится окно, которое позволит вам назначить кнопку.</p></body></html> + + + + Quick Set %1 + Быстрая Настройка %1 + + + + SetAxisThrottleDialog + + + Throttle Change + Смена Тяги + + + + The throttle setting for Axis %1 has been changed. + +Would you like to distribute this throttle change to all sets? + Настройки профиля для Оси %1 были изменены. + +Желаете применить эти настройки ко всем наборам? + + + + SetJoystick + + + Set %1: %2 + Набор %1: %2 + + + + Set %1 + Набор %1 + + + + SetNamesDialog + + + Set Name Settings + Установить имена для наборов + + + + Set 1 + Набор 1 + + + + Set 2 + Набор 2 + + + + Set 3 + Набор 3 + + + + Set 4 + Набор 4 + + + + Set 5 + Набор 5 + + + + Set 6 + Набор 6 + + + + Set 7 + Набор 7 + + + + Set 8 + Набор 8 + + + + Name + Имя + + + + SimpleKeyGrabberButton + + + Mouse + Мышь + + + + SpringModeRegionPreview + + + Spring Mode Preview + Предпросмотр Режима Пружины + + + + UInputEventHandler + + + Could not find a valid uinput device file. +Please check that you have the uinput module loaded. +lsmod | grep uinput + + + + + Could not open uinput device file +Please check that you have permission to write to the device + + + + + Using uinput device file %1 + + + + + UInputHelper + + + a + a + + + + b + b + + + + c + c + + + + d + d + + + + e + e + + + + f + f + + + + g + g + + + + h + h + + + + i + i + + + + j + j + + + + k + k + + + + l + l + + + + m + m + + + + n + n + + + + o + o + + + + p + p + + + + q + q + + + + r + r + + + + s + сек + + + + t + t + + + + u + u + + + + v + v + + + + w + w + + + + x + x + + + + y + y + + + + z + z + + + + Esc + + + + + F1 + F1 + + + + F2 + F2 + + + + F3 + F3 + + + + F4 + F4 + + + + F5 + F5 + + + + F6 + F6 + + + + F7 + F7 + + + + F8 + F8 + + + + F9 + F9 + + + + F10 + F10 + + + + F11 + F11 + + + + F12 + F12 + + + + ` + ` + + + + 1 + 1 + + + + 2 + 2 + + + + 3 + 3 + + + + 4 + 4 + + + + 5 + 5 + + + + 6 + 6 + + + + 7 + 7 + + + + 8 + 8 + + + + 9 + 9 + + + + 0 + 0 + + + + + - + - + + + + = + = + + + + BackSpace + BackSpace + + + + Tab + Tab + + + + [ + [ + + + + ] + ] + + + + \ + \ + + + + CapsLock + + + + + ; + ; + + + + ' + ' + + + + Enter + + + + + Shift_L + Shift_L + + + + , + , + + + + + . + . + + + + + / + / + + + + Ctrl_L + + + + + + Super_L + Super_L + + + + Alt_L + Alt_L + + + + Space + Пробел + + + + Alt_R + Alt_R + + + + Menu + Меню + + + + Ctrl_R + + + + + Shift_R + Shift_R + + + + Up + + + + + Left + + + + + Down + + + + + Right + + + + + PrtSc + + + + + Ins + + + + + Del + + + + + Home + Home + + + + End + End + + + + PgUp + + + + + PgDn + + + + + NumLock + + + + + * + * + + + + + + + + + + + KP_Enter + KP_Enter + + + + KP_1 + KP_1 + + + + KP_2 + KP_2 + + + + KP_3 + KP_3 + + + + KP_4 + KP_4 + + + + KP_5 + KP_5 + + + + KP_6 + KP_6 + + + + KP_7 + KP_7 + + + + KP_8 + KP_8 + + + + KP_9 + KP_9 + + + + KP_0 + KP_0 + + + + SCLK + SCLK + + + + Pause + Пауза + + + + Super_R + + + + + Mute + + + + + VolDn + + + + + VolUp + + + + + Play + + + + + Stop + + + + + Prev + + + + + Next + Next + + + + [NO KEY] + [ПУСТО] + + + + UnixWindowInfoDialog + + + Captured Window Properties + + + + + Information About Window + + + + + Class: + + + + + + + TextLabel + + + + + Title: + + + + + Path: + + + + + Match By Properties + + + + + Class + + + + + Title + + + + + Path + + + + + VDPad + + + + + VDPad + Виртуальная Крестовина + + + + VirtualKeyPushButton + + + Space + Пробел + + + + Tab + Tab + + + + Shift (L) + Shift (Л) + + + + Shift (R) + Shift (П) + + + + Ctrl (L) + Ctrl (Л) + + + + Ctrl (R) + Ctrl (П) + + + + Alt (L) + Alt (Л) + + + + + Alt (R) + Alt (П) + + + + ` + ` + + + + ~ + ~ + + + + + - + - + + + + = + = + + + + [ + [ + + + + ] + ] + + + + \ + \ + + + + Caps + Caps + + + + ; + ; + + + + ' + ' + + + + , + , + + + + + . + . + + + + + / + / + + + + ESC + ESC + + + + PRTSC + PRTSC + + + + SCLK + SCLK + + + + INS + INS + + + + PGUP + PGUP + + + + DEL + DEL + + + + PGDN + PGDN + + + + 1 + 1 + + + + 2 + 2 + + + + 3 + 3 + + + + 4 + 4 + + + + 5 + 5 + + + + 6 + 6 + + + + 7 + 7 + + + + 8 + 8 + + + + 9 + 9 + + + + 0 + 0 + + + + NUM +LK + NUM + + + + + * + * + + + + + + + + + + + E +N +T +E +R + E +N +T +E +R + + + + < + < + + + + : + : + + + + Super (L) + Super + + + + Menu + Меню + + + + Up + Вверх + + + + Down + Вниз + + + + Left + Влево + + + + Right + Вправо + + + + VirtualKeyboardMouseWidget + + + + Keyboard + Клавиатура + + + + + Mouse + Мышь + + + + Mouse Settings + Наcтройка Мыши + + + + Left + Mouse + Left + + + + Up + Mouse + Up + + + + Left Button + Mouse + Left Button + + + + Middle Button + Mouse + Middle Button + + + + Right Button + Mouse + Right Button + + + + Wheel Up + Mouse + Wheel Up + + + + Wheel Left + Mouse + Wheel Left + + + + Wheel Right + Mouse + Wheel Right + + + + Wheel Down + Mouse + Wheel Down + + + + Down + Mouse + Down + + + + Right + Mouse + Right + + + + Button 4 + Mouse + Button 4 + + + + Mouse 8 + Mouse + Mouse 8 + + + + Button 5 + Mouse + Button 5 + + + + Mouse 9 + Mouse + Mouse 9 + + + + NONE + ПУСТО + + + + Applications + + + + + Browser Back + + + + + Browser Favorites + + + + + Browser Forward + + + + + Browser Home + + + + + Browser Refresh + + + + + Browser Search + + + + + Browser Stop + + + + + Calc + + + + + Email + + + + + Media + + + + + Media Next + + + + + Media Play + + + + + Media Previous + + + + + Media Stop + + + + + Search + + + + + Volume Down + + + + + Volume Mute + + + + + Volume Up + + + + + VirtualMousePushButton + + + INVALID + ОШИБКА + + + + WinAppProfileTimerDialog + + + + Capture Application + Звхватить Приложение + + + + After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. + После нажатия на кнопку "Захватить Приложение" кликните по приложению с которым хотите ассоциировать данный профиль. Активное приложение будет захвачено после выбранного количества секунд. + + + + Timer: + Таймер: + + + + Seconds + Секунды + + + + Cancel + Отмена + + + + WinExtras + + + [NO KEY] + [ПУСТО] + + + + AntiMicro Profile + + + + + X11Extras + + + ESC + ESC + + + + Tab + Tab + + + + Space + Пробел + + + + DEL + DEL + + + + Return + Return + + + + KP_Enter + KP_Enter + + + + Backspace + Backspace + + + + xinput extension was not found. No mouse acceleration changes will occur. + + + + + + xinput version must be at least 2.0. No mouse acceleration changes will occur. + + + + + Virtual pointer found with id=%1. + + + + + PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 + + + + + Changing mouse acceleration for device with id=%1 + + + + + XMLConfigReader + + + Could not write updated profile XML to file %1. + + + + + XMLConfigWriter + + + Could not write to profile at %1. + + + + diff --git a/share/antimicro/translations/antimicro_sr.ts b/share/antimicro/translations/antimicro_sr.ts new file mode 100644 index 0000000..9d6eca7 --- /dev/null +++ b/share/antimicro/translations/antimicro_sr.ts @@ -0,0 +1,6032 @@ + + + + + AboutDialog + + + About + О програму + + + + Version + Издање + + + + Info + Подаци + + + + Changelog + Дневник измена + + + + Since December 30, 2012, I have been working on antimicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. + +The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. + +Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. + +Once the Steam controller is finally released to the public, the need for this program might not exist anymore. Just based on the concept of the controller alone, the Steam controller would have so many advantages over using a program like this to provide KB+M emulation. + Од 30. децембра 2012. године, стварао сам Анти-микро у своје слободно време. Оно што је првобитно започето као верзија програма КЈу-Џој-Пед (енг. „QJoyPad“) и начин да се научи правилно програмирање управљано догађајима, претворило се у нешто много веће од оне моје првобитна намере. Иако сам провео доста времена учећи нове технике, сазнавајући више о симулацији тастатуре и миша, те проводећи петак увече разбијајући главу о моју тастатуру, било је забавно ово радити свеукупно обогаћујући сопствено искуство. + +Програм сам створио јер није било природне подршке за контролере код неких игара као код сличних програма на Виндоузу. Иако су постојали слични програми на Гну/Линуксу, није било оних који би, по мени, били довољно добри у смислу функционалности или у играма које сам желео да играм са употребљавајући симулацију тастатуре и миша. КЈу-Џој-Пед је био основни програм који сам користио раније, али он се предуго није развијао и није пружао неке основне функционалности за које сам веровао да су од суштинског значаја. Како се КЈу-Џој-Пед није развијао већ неколико година одлучио сам да направим свој. + +Од тада, покушавао сам да откријем оно што други програми раде ваљано и да то онда унапредим и побољшам. Успут, открио сам неке лепе фазоне и научио више него што сам икада желео да знам о унутрашњим контролама гејмпеда и њиховој изведби у неким играма. Иако се у неким областима овај програм и даље може унапређивати, сматрам да нуди најбоље искуство у-контролама игара код играње старијих, а неки новијих игара које саме не обезбеђују природну подршку за контролер. + +Овај се програм, највероватније, неће даље развијати, када се званично појави програм Стим-контролер. Управо заснован на идеји самог контролера, Стим-контролер ће имати толико предности у односу на друге програме који обезбеђују симулацију тастатуре и миша. + + + + Copyright: 2013 - 2015 + Ауторска права: 2013 - 2015. + + + + Credits + Заслуге + + + + antimicro + Анти-микро + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Travis Nickles &lt;nickles.travis@gmail.com&gt;</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Contributors:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;"><br /></span>Zerro Alvein</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">aybe</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Jeff Backus &lt;jeff.backus@gmail.com&gt;</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Arthur Moore<br />Anton Tornqvist &lt;antont@inbox.lv&gt;</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Translators:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt; font-weight:600;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">zzpxyx - Chinese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">phob - German</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tou omiya - Japanese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">burunduk - Ukrainian</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Version 3, 29 June 2007</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Preamble</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">TERMS AND CONDITIONS</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">0. Definitions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">1. Source Code.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">2. Basic Permissions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">4. Conveying Verbatim Copies.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">5. Conveying Modified Source Versions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">6. Conveying Non-Source Forms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">7. Additional Terms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">8. Termination.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">11. Patents.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">14. Revised Versions of this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">15. Disclaimer of Warranty.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">16. Limitation of Liability.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> + + + + + About Development + О развоју програма + + + + License + Лиценца + + + + Program Version %1 + Издање програма %1 + + + + Program Compiled on %1 at %2 + Програмски код је превођен дана %1 у %2 + + + + Built Against SDL %1 + Изграђен помоћу СДЛ %1 + + + + Running With SDL %1 + Употребљава СДЛ %1 + + + + Using Qt %1 + Уз КјуТ-библиотеке %1 + + + + Using Event Handler: %1 + Употребљава руковаоца догађајима („Event Handler“) : %1 + + + + AddEditAutoProfileDialog + + + Auto Profile Dialog + Самостално профилисање + + + + Profile: + Профил: + + + + + Browse + Разгледај + + + + Window: + Прозор: + + + + + Select Window. Click on the appropriate application +window and the application file path will be populated +in the form. + Одабир прозора — Притиском на одговарајући прозор +програма у обрасцу се попуњава путања до датотеке +програма. + + + + Detect Window Properties + Сам откриј особине прозора + + + + Class: + Класа: + + + + Title: + Наслов: + + + + Application: + Програм: + + + + Select + Одабери + + + + Devices: + Уређаји: + + + + + Select this profile to be the default loaded for +the specified device. The selection will be used instead +of the all default profile option. + Подразумевано поставља овај профил за +дати уређај. Овај избор ће се користити +уместо свеопштих опција профила. + + + + Set as Default for Controller + Постави као подразумевано за контролер + + + + + A different profile is already selected as the default for this device. + За овај уређај је већ одабран други подразумевани профил. + + + + Current (%1) + Текући (%1) + + + + Open Config + Отвори подешавања + + + + + Select Program + Одабери програм + + + + Programs (*.exe) + Програми (*.exe) + + + + Please use the main default profile selection. + Користите главни избор подразумеваног профила. + + + + Please select a window by using the mouse. Press Escape if you want to cancel. + Одабирајте прозор употребом миша, а поништите одабир тастером <Esc>. + + + + Capture Application Window + Разоткривање графичког сучеља програма + + + + Could not obtain information for the selected window. + Не могу да добавим податке о одабраном прозору. + + + + Application Capture Failed + Није успело разоткривање програма + + + + Profile file path is invalid. + Путања до датотеке профила није ваљана. + + + + No window matching property was specified. + Није била одређена одговарајућа особина прозора. + + + + Program path is invalid or not executable. + Путања до програма није ваљана или није извршна. + + + + File is not an .exe file. + Ово није извршна датотека. + + + + No window matching property was selected. + Није била одабрана одговарајућа особина прозора. + + + + AdvanceButtonDialog + + + + Advanced + Напредно + + + + Assignments + Придруживања + + + + Toggle + Преклопник + + + + Turbo + Набуџи + + + + Set Selector + Изборник скупа + + + + Blank or KB/M + Празно или „Таст./Миш“ + + + + Hold + Држи + + + + Pause + Пауза + + + + Cycle + Врти + + + + Distance + Раздаљина + + + + Insert + Уметни + + + + Delete + Уклони + + + + Clear All + Уклони све + + + + Time: + Време: + + + + 0.01s + 0,01 сек + + + + 0s + 0 сек + + + + Insert a pause that occurs in between key presses. + Време између притиска два притиска дугмета. + + + + Release + Пусти + + + + + Insert a new blank slot. + Унеси нов, празан слот. + + + + Delete a slot. + Уклони слот. + + + + Clear all currently assigned slots. + Уклони све већ придружене слотове. + + + + Specify the duration of an inserted Pause or Hold slot. + Одређивање трајања за већ унет Пауза/Држи слот. + + + + 0m + 0 мин + + + + + Specify the range past an axis dead zone in which a sequence of actions will execute. + Поставите област изван мртве области правца, у којој ће се извршити низ радњи. + + + + Distance: + Раздаљина: + + + + + % + % + + + + Mouse Mod + Мишар + + + + Press Time + Трајање притиска + + + + Delay + Кашњење + + + + Execute + Изврши + + + + Load + Учитај + + + + Set Change + Измени скуп + + + + Text Entry + Унос текста + + + + Placeholder + Препознавач положаја + + + + + 0 + 0 + + + + Mouse Speed Mod: + Брзина Мишара: + + + + Set the percentage that mouse speeds will be modified by. + Поставите промену брзине померања миша у процентима. + + + + Auto Reset Cycle After + Самопоништавање „вртње“ након + + + + seconds + секунди + + + + ... + ... + + + + + + Enabled + Омогућено + + + + Mode: + Режим: + + + + <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> + <html><head/><body><p>Обично: Узастопно притискање-пуштање дугмета одабраном брзином.</p><p>Постепено: Измена кашњења код притиска-пуштања дугмета засновано на померају осног растојањ. Брзина остаје неизмењена.</p><p>Импулсно: Измена броја притисака-пуштања дугмета по секунди. Кашњење остаје неизмењено.</p></body></html> + + + + Normal + Обично + + + + Gradient + Постепено + + + + Pulse + Импулсно + + + + Delay: + Кашњење: + + + + 0.10s + 0,10 сек + + + + Rate: + Брзина: + + + + 10.0/s + 10,0/сек + + + + + Disabled + Онемогућено + + + + Select Set 1 One Way + Изабери 1. скуп, једносмерно + + + + Select Set 1 Two Way + Изабери 1. скуп, двосмерно + + + + Select Set 1 While Held + Изабери 1. скуп, док држим + + + + Select Set 2 One Way + Изабери 2. скуп, једносмерно + + + + Select Set 2 Two Way + Изабери 2. скуп, двосмерно + + + + Select Set 2 While Held + Изабери 2. скуп, док држим + + + + Select Set 3 One Way + Изабери 3. скуп, једносмерно + + + + Select Set 3 Two Way + Изабери 3. скуп, двосмерно + + + + Select Set 3 While Held + Изабери 3. скуп, док држим + + + + Select Set 4 One Way + Изабери 4. скуп, једносмерно + + + + Select Set 4 Two Way + Изабери 4. скуп, двосмерно + + + + Select Set 4 While Held + Изабери 4. скуп, док држим + + + + Select Set 5 One Way + Изабери 5. скуп, једносмерно + + + + Select Set 5 Two Way + Изабери 5. скуп, двосмерно + + + + Select Set 5 While Held + Изабери 5. скуп, док држим + + + + Select Set 6 One Way + Изабери 6. скуп, једносмерно + + + + Select Set 6 Two Way + Изабери 6. скуп, двосмерно + + + + Select Set 6 While Held + Изабери 6. скуп, док држим + + + + Select Set 7 One Way + Изабери 7. скуп, једносмерно + + + + Select Set 7 Two Way + Изабери 7. скуп, двосмерно + + + + Select Set 7 While Held + Изабери 7. скуп, док држим + + + + Select Set 8 One Way + Изабери 8. скуп, једносмерно + + + + Select Set 8 Two Way + Изабери 8. скуп, двосмерно + + + + Select Set 8 While Held + Изабери 8. скуп, док држим + + + + sec. + сек. + + + + /sec. + /сек. + + + + Set %1 + Скуп %1 + + + + + Select Set %1 + Одабери %1. скуп + + + + One Way + Једносмерно + + + + Two Way + Двосмерно + + + + While Held + Док држим + + + + Choose Executable + Избор извршне датотеке + + + + Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. + Слотови изван „вртње“ ће се извршити по наредном притиску тастера. Вишеструке „вртње“ се могу додавати код стварање делова једног низа. + + + + Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. + Покретање наредног слота биће одложено за наведено време.Слотови покренути пре овог одлагања ће остати покренути и по његовом истеку. + + + + Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. + Овом се радњом одређује да накнадни слотови могу да се изврше само када се нека оса помери за одређени опсег изван дате мртве области. + + + + Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. + Уметање задржавања. Слотови након дате радње ће да се изврше само ако се тастер задржи ван наведеног периода. + + + + Chose a profile to load when this slot is activated. + Одабир профила који ће се учитати по укључењу овог слота. + + + + Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. + Радња за управљањем начином рада миша ће изменити све поставке брзине миша за одређен проценат,а док је радња у току. Ово може бити корисно за успоравање миша при нишањењу. + + + + Specify the time that keys past this slot should be held down. + Одређује колико ће дуго бити задржани у доњем положају (притиснути) тастери ван овог слота. + + + + Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. + Уметање отпуштања. Слотови након дате радње ће да се изврше само по отпуштању тастера ако је он задржан ван наведеног периода. + + + + Change to selected set once slot is activated. + Промени на одабрани скуп по отпочињању слота. + + + + Full string will be typed when a slot is activated. + Уписује пуну ниску знакова по отпочињању слота. + + + + Execute program when slot is activated. + Извршава програм по отпочињању слота. + + + + + Choose Profile + Одабир профила + + + + Config Files (*.amgp *.xml) + Датотеке подешавања (*.amgp *.xml) + + + + AdvanceStickAssignmentDialog + + + Stick/Pad Assignment + Придружвање Управљача/Тастера + + + + Sticks + Управљачи + + + + DPads + Тастери правца или смера (дирекционални) + Д-тастери + + + + + %1 (Joystick %2) + %1 (Џојстик %2) + + + + Stick 1 + Управљач 1 + + + + + + Enabled + Омогућен + + + + + + + + + Assign + Придружи + + + + + X Axis: + »X« правац: + + + + + Y Axis: + »Y« правац: + + + + Stick 2 + Управљач 2 + + + + Number of Physical DPads: %1 + Број стварних Д-тастера: %1 + + + + Virtual DPad 1 + Патворено = Виртуелно + Патворен Д-тастатер 1 + + + + Up: + Горе: + + + + Down: + Доле: + + + + Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. + Обавештење: Ово прозорче још увек постоји само због усаглашености са ранијим издањима програма (пре издања 2.0). Придруживач тастера контролера се препоручује од издања 2.0. + + + + Left: + Лево: + + + + Right: + Десно: + + + + + + + Axis %1 + Правац %1 + + + + + + + Axis %1 - + Правац %1 - + + + + + + + Axis %1 + + Правац %1 + + + + + + + + Button %1 + Дугме %1 + + + + Move stick 1 along the X axis + Померајте по »Х-оси« 1. управљач + + + + Move stick 1 along the Y axis + Померајте по »У-оси« 1. управљач + + + + Move stick 2 along the X axis + Померајте по »Х-оси« 2. управљач + + + + Move stick 2 along the Y axis + Померајте по »У-оси« 2. управљач + + + + + + + Press a button or move an axis + Притисните тастер или померите управљач + + + + AxisEditDialog + + + Axis + Правац + + + + + Mouse (Horizontal) + Миш (водоравно) + + + + + Mouse (Inverted Horizontal) + Миш (обрнуто водоравно) + + + + + Mouse (Vertical) + Миш (усправно) + + + + + Mouse (Inverted Vertical) + Миш (обрнуто усправно) + + + + + Arrows: Up | Down + Стрелице: Горе | Доле + + + + + Arrows: Left | Right + Стрелице: Лево | Десно + + + + + Keys: W | S + Тастери: Њ | С + + + + + Keys: A | D + Тастери: А | Д + + + + + NumPad: KP_8 | KP_2 + Број.Тастатура: КП_8 | КП_2 + + + + + NumPad: KP_4 | KP_6 + Број.Тастатура: КП_4 | КП_6 + + + + + + None + Ништа + + + + + Set the value to use as the limit for an axis. Useful for a +worn out analog stick. + Постави ову вредност као граничну за правац. Употребљиво +у раду са истрошеним аналогним управљачем. + + + + Negative Half Throttle + Полу-регулатор умањења + + + + Positive Half Throttle + Полу-регулатор увећавања + + + + Name: + Назив: + + + + Specify the name of an axis. + Одредите Назив осе(правца). + + + + Mouse Settings + Поставке миша + + + + + Set the value of the dead zone for an axis. + Подеси вредност мртве области за правaц. + + + + Presets: + Поставке: + + + + Dead Zone: + Мртва област: + + + + Max Zone: + Највиша област: + + + + + [NO KEY] + [Без тастера] + + + + Throttle setting that determines the behavior of how to +interpret an axis hold or release. + Поставке регулатора које одређују понашање при +тумачењу држи („hold“) или пусти („release“) за правац. + + + + Negative Throttle + Регулатор умањења + + + + Normal + Нормално + + + + Positive Throttle + Регулатор увећавања + + + + Current Value: + Текућа вредност: + + + + Set + Постави + + + + Set %1 + Скуп %1 + + + + Left Mouse Button + Леви тастер миша + + + + Right Mouse Button + Десни тастер миша + + + + ButtonEditDialog + + + Dialog + Прозорче + + + + To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab + Да би сте створили ново придруживање, притисните неко од дугмади тастатуре +или кликните мишем на неко дугме у неком од језичака „Тастатура“ или „Миш“ + + + + Placeholder + Препознавач положаја + + + + Toggle + Преклопник + + + + Enables a key press or release to only occur when a controller button is pressed. + Омогућава да се догоди дугме „притисни“ или „пусти“, +и то, само ако је дугме контролера притиснуто. + + + + Enables rapid key presses and releases. Turbo controller. + Омогућава хитрије дугме „притисни“ или +дугме „пусти“. Контролер набуџивања. + + + + Turbo + Набуџи + + + + Current: + Тренутно стање: + + + + Slots + Слотови + + + + Na&me: + + + + + Specify the name of a button. + Унесите назив за дугме. + + + + Action: + Радња: + + + + Specify the action that will be performed in game while +this button is being used. + Одредите радњу која ће се извршавати при +употреби овог дугмета. + + + + Advanced + Напредно + + + + Set + Подеси + + + + Set %1 + Скуп %1 + + + + CapturedWindowInfoDialog + + + Captured Window Properties + Особине откривеног прозора + + + + Information About Window + Подаци о прозору + + + + Class: + Класа: + + + + + + TextLabel + Текст-натпис + + + + Title: + Наслов: + + + + Path: + Путања: + + + + Match By Properties + Прилагоди по + + + + Class + класи + + + + Title + наслову + + + + Path + путањи + + + + Full Path + Пуна путања + + + + File Name + Назив датотеке + + + + CommandLineUtility + + + + Profile location %1 is not an XML file. + Путања до профила „%1“ није ИксМЛ датотека. + + + + + Profile location %1 does not exist. + Путања до профила „%1“ не постоји. + + + + An invalid set number '%1' was specified. + + + + + Controller identifier '%s'' is not a valid value. + + + + + No display string was specified. + Није постављено »Display string«. + + + + + + Controller identifier is not a valid value. + Означивач контролера нема ваљану вредност. + + + + No set number was specified. + Није одређен број скупа. + + + + No controller was specified. + Није одређен контролер. + + + + An invalid event generator was specified. + Одређен је неважећи стваралац догађаја. + + + + No event generator string was specified. + Није одређен назив ствараоца догађаја. + + + + Qt style flag was detected but no style was specified. + Откривен је белег Кјут-стила али сам стил није одређен. + + + + No log level specified. + Није одређен ниво извештавања. + + + + + + + antimicro version + Издање програма + + + + + Usage: antimicro [options...] [profile] + + + + + + Options + Опције + + + + + Print help text. + Исписује овај текст помоћи. + + + + + Print version information. + Исписује податке о издању. + + + + + Launch program in system tray only. + Покреће програм само у обавештајној зони. + + + + + Launch program with the tray menu disabled. + Покреће програм не користећи обавештајну зону. + + + + + Launch program without the main window + displayed. + Покреће програм без приказивања + главног произора. + + + + + Launch program with the configuration file + selected as the default for selected + controllers. Defaults to all controllers. + Покреће програм учитавајући датотеку са + подешавањима обележену као + подразумевана за одабрани контролер. + Подразумевано је, примена на све контролере. + + + + + + Apply configuration file to a specific + controller. Value can be a + controller index, name, or GUID. + Примени датотеку са подешавањима на одређени + контролер, чија вредност се може представити + као индекс контролера, назив, или ЈИБГ. + + + + + Unload currently enabled profile(s). + Value can be a controller index, name, or GUID. + Одбаци текући, укључени профил(е). + Вредност се може представити као индекс контролера, назив, или ЈИБГ. + + + + + Start joysticks on a specific set. + Value can be a controller index, name, or GUID. + Покрени џојстик употребом одређеног скупа. + Вредност се може представити као индекс контролера, назив, или ЈИБГ. + + + + + Advance profile loading set options. + + + + + + Launch program as a daemon. + Покрени програм као позадински процес. + + + + + Enable logging. + Укључује извештавање. + + + + + Use specified display for X11 calls. + Useful for ssh. + Употребљава дати екран за Икс-11 позиве. + Употребљиво за „ssh“. + + + + + Choose between using XTest support and uinput + support for event generation. Default: xtest. + Одабир између Икс-тест и „uinput“ подршке + за стварање догађаја. Подразумевано: „xtest“. + + + + + Choose between using SendInput and vmulti + support for event generation. Default: sendinput. + Одабир између „SendInput“ и „vmulti“ подршке + за стварање догађаја. Подразумевано: „sendinput“. + + + + + Print information about joysticks detected by + SDL. + Приказује податке о џојсицима које је + открио СДЛ. + + + + + Open game controller mapping window of selected + controller. Value can be a controller index or + GUID. + Отвори прозор придруживача тастера контролера + за одабран контролер. Вредност може бити индекс + контролера или ЈИБГ (енг. „GUID“). + + + + DPadContextMenu + + + Mouse (Normal) + Миш (обично) + + + + Mouse (Inverted Horizontal) + Миш (обрнуто водоравно) + + + + Mouse (Inverted Vertical) + Миш (обрнуто усправно) + + + + Mouse (Inverted Horizontal + Vertical) + Миш (обрнуто водоравно и усправно) + + + + Arrows + Стрелице + + + + Keys: W | A | S | D + Тастери: Њ | А | С | Д + + + + NumPad + Број.тастатура + + + + None + Ништа + + + + Standard + Уобичајено + + + + Eight Way + Осмосмерно + + + + 4 Way Cardinal + Уобичајено четворосмерно + + + + 4 Way Diagonal + Четворосмерно-дијагонално + + + + Mouse Settings + Поставке миша + + + + DPadEditDialog + + + Dialog + Прозорче + + + + Presets: + Поставке: + + + + Mouse (Normal) + Миш (нормално) + + + + Mouse (Inverted Horizontal) + Миш (обрнуто водоравно) + + + + Mouse (Inverted Vertical) + Миш (обрнуто усправно) + + + + Mouse (Inverted Horizontal + Vertical) + Миш (обрнуто водоравно и усправно) + + + + Arrows + Стрелице + + + + Keys: W | A | S | D + Тастери: Њ | А | С | Д + + + + NumPad + Бројчана тастатура + + + + None + Ништа + + + + Dpad Mode: + Употреба Д-тастера: + + + + &Name: + + + + + 4 Way Cardinal + Уобичајено четворосмерно + + + + 4 Way Diagonal + Четворосмерно-дијагонално + + + + DPad Delay: + Д-тастери — кашњење: + + + + + Time lapsed before a direction change is taken into effect. + Кашњење пре но промена смера приметно наступи. + + + + s + с + + + + Specify the name of a dpad. + Унесите назив за Д-тастер. + + + + Mouse Settings + Поставке миша + + + + Standard + Уобичајено + + + + Standard: 8 region dpad with two direction buttons active +when the dpad is in a diagonal region. + +Eight Way: 8 region dpad with each direction having its +own dedicated button. Only one button is ever active at +at time. Useful for rougelike games. + +4 Way Cardinal: 4 region dpad with regions corresponding to +the cardinal directions of the dpad. Useful for menus. + +4 Way Diagonal: 4 region dpad with each region corresponding +to a diagonal zone. + + + + + Eight Way + Осмосмерно + + + + Set + Подеси + + + + Set %1 + Скуп %1 + + + + EditAllDefaultAutoProfileDialog + + + Default Profile + Подразумеван профил + + + + Profile: + Профил: + + + + Browse + Разгледај + + + + Open Config + Отвори подешавања + + + + Profile file path is invalid. + Путања до датотеке профила није ваљана. + + + + ExtraProfileSettingsDialog + + + Extra Profile Settings + Додатна подешавања профила + + + + Key Press Time: + Време притиска тастера: + + + + 0.00 ms + 0.00 мс + + + + Profile Name: + Назив профила: + + + + + + s + сек. + + + + GameController + + + Game Controller + Контролер програма + + + + GameControllerDPad + + + + + DPad + Д-тастер + + + + GameControllerMappingDialog + + + Game Controller Mapping + Придруживач тастера контролера + + + + <html><head/><body><p>antimicro makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicro will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> + <html><head/><body><p>Да би се у већини програма различити контролери (гејмпедови) употребљавали на јединствен начин програм Анти-микро употребљава програмско сучеље дефинисано у пројекту СДЛ издања2, а названо „Гејм-контролер АПИ“ (енг. <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">„Game Controller API“</span></a>). За придруживање тастера одаберите поље за придруживање у реду одговарајућег тастера, а након тога притисните неки тастер на гејмпеду или померите ручицу управљача правца на њему. У пољу за придруживање ће се појавити подаци стварног (физичког) тастера или ручице управљача који ће се употребљавати.</p><p>Анти-микро ће да употреби ова придруживања за чување знаковних ниски придруживања које се могу учитавати помоћу СДЛ програма.</p></body></html> + + + + A + 3 + + + + B + 2 + + + + X + 4 + + + + Y + 1 + + + + Back + Назад + + + + Start + Почни + + + + Guide + Водич + + + + Left Shoulder + Леви окидач 1 + + + + Right Shoulder + Десни окидач 1 + + + + Left Stick Click + Притисак на леви управљач + + + + Right Stick Click + Притисак на десни управљач + + + + Left Stick X + Леви управљач — водоравно + + + + Left Stick Y + Леви управљач — усправно + + + + Right Stick X + Десни управљач — водоравно + + + + Right Stick Y + Десни управљач — усправно + + + + Left Trigger + Леви окидач 2 + + + + Right Trigger + Десни окидач 2 + + + + DPad Up + Д-тастер — Горе + + + + DPad Left + Д-тастер — Лево + + + + DPad Down + Д-тастер — Доле + + + + DPad Right + Д-тастер — Десно + + + + Mapping + Придруживања + + + + SDL 2 Game Controller Mapping String + СДЛ-2 ниска придруживања тастера контролера + + + + Last Axis Event: + Задњи догађај на правцу: + + + + Current Axis Detection Dead Zone: + Откривање мртве области текућег правца: + + + + 5000 + 5000 + + + + 10000 + 10000 + + + + 15000 + 15000 + + + + 20000 + 20000 + + + + 25000 + 25000 + + + + 30000 + 30000 + + + + 32000 + 32000 + + + + Game Controller Mapping (%1) (#%2) + Придруживач тастера контролера (%1) (#%2) + + + + Discard Controller Mapping? + Поништавање придруживања контролера? + + + + Discard mapping for this controller? + +If discarded, the controller will be reverted to a joystick once you refresh all joysticks. + Да ли да поништим придруживања за овај контролер? + +If discarded, the controller will be reverted to a joystick once you refresh all joysticks. + + + + GameControllerSet + + + Back + Назад + + + + Guide + Водич + + + + Start + Почни + + + + LS Click + Притисак 1. левог окидача + + + + RS Click + Притисак 1. десног окидача + + + + L Shoulder + 1. леви окидач + + + + R Shoulder + 1. десни окидач + + + + L Trigger + 2. леви окидач + + + + R Trigger + 2. десни окидач + + + + GameControllerTrigger + + + + + Trigger + Окидач + + + + JoyAxis + + + + + Axis + Правац + + + + JoyAxisButton + + + Negative + Умањи + + + + Positive + Увећај + + + + Unknown + Непознато + + + + + + Button + Дугме + + + + JoyAxisContextMenu + + + Mouse (Horizontal) + Миш (водоравно) + + + + Mouse (Inverted Horizontal) + Миш (обрнуто водоравно) + + + + Mouse (Vertical) + Миш (усправно) + + + + Mouse (Inverted Vertical) + Миш (обрнуто усправно) + + + + Arrows: Up | Down + Стрелице: Горе | Доле + + + + Arrows: Left | Right + Стрелице: Лево | Десно + + + + Keys: W | S + Тастери: Њ | С + + + + Keys: A | D + Тастери: А | Д + + + + NumPad: KP_8 | KP_2 + Број.Тастатура: КП_8 | КП_2 + + + + NumPad: KP_4 | KP_6 + Број.Тастатура: КП_4 | КП_6 + + + + + None + Ништа + + + + + Mouse Settings + Поставке миша + + + + Left Mouse Button + Леви тастер миша + + + + Right Mouse Button + Десни тастер миша + + + + JoyButton + + + Processing turbo for #%1 - %2 + Буџим за #%1 - %2 + + + + Finishing turbo for button #%1 - %2 + Завршено набуџивање тастера #%1 - %2 + + + + Processing press for button #%1 - %2 + Притискам за тастер #%1 - %2 + + + + Processing release for button #%1 - %2 + Отпуштам за тастер #%1 - %2 + + + + Distance change for button #%1 - %2 + Промена раздаљине за тастер #%1 - %2 + + + + + + Button + Тастер + + + + + + + [NO KEY] + [Без тастера] + + + + [Set %1 1W] + [Скуп %1 1-смерно] + + + + [Set %1 2W] + [Скуп %1 2-смерно] + + + + [Set %1 WH] + [Скуп %1 WH] + + + + JoyButtonContextMenu + + + Toggle + Преклопи + + + + Turbo + Набуџи + + + + Clear + Очисти + + + + Set Select + Одабир скупа + + + + Disabled + Онемогућено + + + + Set %1 + Скуп %1 + + + + Set %1 1W + Скуп %1 1-смерно + + + + Set %1 2W + Скуп %1 2-смерно + + + + Set %1 WH + Скуп %1 WH + + + + JoyButtonSlot + + + + Mouse + Миш + + + + Up + Напред + + + + Down + Назад + + + + Left + Лево + + + + Right + Десно + + + + LB + Л.дугме + + + + MB + С.дугме + + + + RB + Д.дугме + + + + B4 + Дугме 4 + + + + B5 + Дугме 5 + + + + Pause + Пауза + + + + Hold + Држи + + + + Cycle + Врти + + + + Distance + Раздаљина + + + + Release + Пусти + + + + Mouse Mod + Мишар + + + + Press Time + Трајање притиска + + + + Delay + Кашњење + + + + Load %1 + Учитај %1 + + + + Set Change %1 + Измена скупа %1 + + + + [Text] %1 + [Текст] %1 + + + + [Exec] %1 + [Извршавам] %1 + + + + [NO KEY] + [Без тастера] + + + + JoyControlStick + + + + + Stick + Управљач + + + + JoyControlStickButton + + + + + Up + Напред + + + + + + Down + Назад + + + + + + Left + Лево + + + + + + Right + Десно + + + + + + Button + Дугме + + + + JoyControlStickContextMenu + + + Mouse (Normal) + Миш (обично) + + + + Mouse (Inverted Horizontal) + Миш (обрнуто водоравно) + + + + Mouse (Inverted Vertical) + Миш (обрнуто усправно) + + + + Mouse (Inverted Horizontal + Vertical) + Миш (обрнуто водоравно и усправно) + + + + Arrows + Стрелице + + + + Keys: W | A | S | D + Тастери: Њ | А | С | Д + + + + NumPad + Број.тастатура + + + + None + Ништа + + + + Standard + Уобичајено + + + + Eight Way + Осмосмерно + + + + 4 Way Cardinal + Уобичајено четворосмерно + + + + 4 Way Diagonal + Четворосмерно-дијагонално + + + + Mouse Settings + Поставке миша + + + + JoyControlStickEditDialog + + + Dialog + Прозорче + + + + X: + X: + + + + + + + + 0 + 0 + + + + Y: + Y: + + + + Distance: + Раздаљина: + + + + Presets: + Поставке: + + + + Mouse (Normal) + Миш (обично) + + + + Mouse (Inverted Horizontal) + Миш (обрнуто водоравно) + + + + Mouse (Inverted Vertical) + Миш (обрнуто усправно) + + + + Mouse (Inverted Horizontal + Vertical) + Миш (обрнуто водоравно и усправно) + + + + Arrows + Стрелице + + + + Keys: W | A | S | D + Тастери: Њ | А | С | Д + + + + NumPad + Бројчана тастатура + + + + None + Ништа + + + + Stick Mode: + Начин рада управљача: + + + + Standard: 8 region stick with two direction buttons active +when the stick is in a diagonal region. + +Eight Way: 8 region stick with each direction having its +own dedicated button. Only one button is ever active at +at time. Useful for rougelike games. + +4 Way Cardinal: 4 region stick with regions corresponding to +the cardinal directions of the stick. Useful for menus. + +4 Way Diagonal: 4 region stick with each region corresponding +to a diagonal zone of the stick. + Уобичајено: 8-смерни управљач са два притиснута +тастера за померање по дијагонали. + +Осмосмерно: 8-смерни управљач са сопственим тастерима +за сваки смер. У једном тренутку, радни је само један +тастер. Употребљиво за роголике (енг. „rougelike“) игре. + +Уобичајено 4-смерно: 4-смерни управљач за померање у +4 смера (померена за 90°). Употребљиво за изборнике. + +4-смерно дијагонално: 4-смерни управљач где свака +област одговара дијагоналној области датог управљача. + + + + 4 Way Cardinal + Уобичајено четворосмерно + + + + 4 Way Diagonal + Четворосмерно-дијагонално + + + + + Dead zone value to use for an analog stick. + Вредност мртве области код аналогних управљача. + + + + + Value when an analog stick is considered moved 100%. + Вредност у којој је аналогни управљач у крајњем положају. + + + + + The area (in degrees) that each diagonal region occupies. + Област (у степенима) коју свака област на дијагонали заузима. + + + + Square Stick: + Четвртаст управљач: + + + + + Percentage to modify a square stick coordinates to confine values to a circle + Постотак промене квадратних координата управљача за ограничавање вредности у кружници + + + + % + % + + + + Stick Delay: + Кашњење управљача: + + + + + Time lapsed before a direction change is taken into effect. + Кашњење пре но промена смера приметно наступи. + + + + s + с + + + + Modifier: + Измењивач: + + + + Edit button that is active while the stick is active. + +This button is useful for assigning zones with +modifier keys that can be used to assign walk/run +functionality to an analog stick. + Дугме за уређивање који је радно док управљач ради. + +Употребљиво за доделе области тастерима-измењивачима +који могу да се употребе за додавање могућности +ходај-трчи аналогним управљачима. + + + + PushButton + Дугме + + + + Name: + Назив: + + + + Specify the name of an analog stick. + Унесите назив за аналогни управљач. + + + + Mouse Settings + Поставке миша + + + + Standard + Уобичајено + + + + Bearing: + Азимут: + + + + % Safe Zone: + % Безбедна област: + + + + Eight Way + Осмосмерно + + + + Dead Zone: + Мртва област: + + + + Max Zone: + Највиша област: + + + + Diagonal Range: + Дијагонални опсег: + + + + Set + Постави + + + + Set %1 + Скуп %1 + + + + JoyControlStickModifierButton + + + + + Modifier + Измењивач + + + + JoyDPad + + + + + DPad + Д-тастер + + + + JoyDPadButton + + + + + Up + Горе + + + + + + Down + Доле + + + + + + Left + Лево + + + + + + Right + Десно + + + + + + Button + Дугме + + + + JoyTabWidget + + + + + + + + <New> + <Ново> + + + + + Remove + Уклони + + + + + Remove configuration from recent list. + Уклони подешавање са текуће листе. + + + + + Load + Учитај + + + + + Load configuration file. + Учитај датотеку са подешавањима. + + + + + Save + Сачувај + + + + + Save changes to configuration file. + Сачувај измене у датотеку подешавања. + + + + + Save As + Сачувај као + + + + + Save changes to a new configuration file. + Сачувај измене у новој датотеци подешавања. + + + + + Sets + Скупови + + + + Copy from Set + Умножи из ... + + + + Settings + Постави називе + + + + + Set 1 + 1. скупа + + + + + Set 2 + 2. скупа + + + + + Set 3 + 3. скупа + + + + + Set 4 + 4. скупа + + + + + Set 5 + 5. скупа + + + + + Set 6 + 6. скупа + + + + + Set 7 + 7. скупа + + + + + Set 8 + 8. скупа + + + + + Stick/Pad Assign + Придружи Управљач/Тастатуру + + + + + Controller Mapping + Придруживач тастера контролера + + + + + Quick Set + Брзе поставке + + + + + Names + Називи + + + + + Toggle button name displaying. + Приказивање назива преклопника. + + + + + Pref + Опште поставке + + + + + Change global profile settings. + Измените опште поставке профила. + + + + + + Reset + Поништи + + + + + Revert changes to the configuration. Reload configuration file. + Поништи измене и учитај опет датотеку са подешавањем. + + + + Open Config + Отвори подешавања + + + + Config Files (*.amgp *.xml) + Датотеке подешавања (*.amgp *.xml) + + + + + + Config File (*.%1.amgp) + Датотека подешавања (*.%1.amgp) + + + + + Save Profile Changes? + Да ли да сачувам измене профила? + + + + + Changes to the new profile have not been saved. Would you like to save or discard the current profile? + Имате несачуваних промена новог профила. Да ли желите да их сачувам или да их поништим? + + + + + Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? + Имате несачуваних промена у профилу "%1" . Да ли желите да их сачувам или да их поништим? + + + + Sticks + Управљачи + + + + + DPads + Д-тастери + + + + No buttons have been assigned. Please use Quick Set to assign keys +to buttons or disable hiding empty buttons. + Нема придруживања за дугмад. Можете да употребите „Брзе поставке“ +за придруживања дугмадима или да искључите скривање „празних“ дугмади. + + + + + Set %1: %2 + Скуп %1: %2 + + + + + Set %1 + Скуп %1 + + + + Copy Set Assignments + Умножи придруживања из скупа + + + + Are you sure you want to copy the assignments and device properties from %1? + Да ли заиста желите да умножите придруживања и особине уређаја из %1? + + + + + + Save Config + Сачувај подешавања + + + + + Set + Постави + + + + Joystick + + + Joystick + Џојстик + + + + JoystickStatusWindow + + + Properties + Особине + + + + Details + Детаљи + + + + Name: + Назив: + + + + + + + + + + %1 + %1 + + + + Number: + Број: + + + + Axes: + Праваца: + + + + Buttons: + Дугмад: + + + + Hats: + Капице: + + + + GUID: + ЈИБГ: + + + + Game Controller: + Контролер за игре: + + + + Axes + Правци + + + + Buttons + Дугмад + + + + Hats + Капице + + + + %1 (#%2) Properties + %1 (#%2) Особине + + + + Axis %1 + Правац %1 + + + + Hat %1 + Хат %1 + + + + No + Не + + + + Yes + Да + + + + MainSettingsDialog + + + Edit Settings + Уређивање поставки + + + + General + Опште поставке + + + + Controller Mappings + Придруживања контролера + + + + Language + Језик + + + + Auto Profile + Ауто-профил + + + + Mouse + Миш + + + + <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> + <html><head/><body><p>Постављање уобичајеног директоријума за учитавање постојећих или чување нових профила.</p></body></html> + + + + Recent Profile Count: + Број скорашњих профила: + + + + <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> + <html><head/><body><p>Број профила који се може сместити у листу недавно употребљаваних профила. Број 0 означава приказ свих употребљаваних профила.</p></body></html> + + + + Gamepad Poll Rate: + Провера порука џојстика након: + + + + Change the poll rate that the program uses to discover new +events from gamepads. Defaults to 10 ms. + +Reducing the poll rate value could cause the application to +use more CPU power so please test the setting that you use +before using antimicro unattended. + Измените време након кога ће програм да провери да ли је гејмпед +производио догађаје (поруке). Уобичајена вредност је 10 мс. + +Ниже вредности ове опције могу да доведу до веће употребе +ЦПЈ (процесора), Проверите ову поставку пре озбиљније употребе. + + + + Hide main window when the main window close button is +clicked instead of quitting the program. + Притиском на дугме затварања главног прозора, он се +затвара али програм остаје покренут у обавештајној зони. + + + + Close To Tray + Смести у обавештајну зону + + + + Have Windows start antimicro at system startup. + Покрени програм са покретањем система. + + + + Launch At Windows Startup + Покрени по покретању система + + + + Display recent profiles for all controllers +as a single list in the tray menu. Defaults +to using sub-menus. + Приказаће се скорашњи профили за све контролере +као јединствен списак профила у обавештајној зони. +Уобичајено је употреба под-изборника. + + + + Single Profile List in Tray + Јединствен списак профила у обавештајној зони + + + + Have the program minimize to the taskbar. +By default, the program minimizes to the system +tray if available. + Програм ће се сместити у траку покренутих задатака. +Подразумевано смештање програма је у обавештајној +зони ако је она доступна. + + + + Minimize to Taskbar + Смести у траку покренутих задатака + + + + This option will cause the program to hide all +buttons that have no slots assigned to them. +The Quick Set dialog window will have to be used +to bring up the edit dialog for gamepad buttons. + Ако је укључена ова опција, програм ће скрити +дугмад која немају придружених слотова. +У прозору „Брзе поставке“ моћи ћете да +подесите придруживања тастера гејмпеда. + + + + Hide Empty Buttons + Сакриј „празну“ дугмад + + + + When the program is launched, open the last +known profile that was opened during the +previous session. + Ово омогућава да се по покретању програма +учита познат, последње учитаван профил у +претходној сесији. + + + + Auto Load Last Opened Profile + Отвори сам последњи употребљени профил + + + + Only show the system tray icon when the program +first launches. + Приказује само икону у обавештајној зони +по првом покретању програма. + + + + Launch in Tray + Покрени у обавештајној зони + + + + Associate .amgp files with antimicro in Windows Explorer. + Придружуј „.amgp“-датотеке програму Анти-микро (виндоуз експлорер). + + + + Associate Profiles + Придружени профили + + + + Key Repeat + Вишеструки притисци тастера + + + + Active keys will be repeatedly pressed when this +option is enabled. + Ако је укључено омогућени су вишеструки, +узастопни притисци тастера. + + + + + Enable + Омогућено + + + + Specifies how much time should elapse before key repeating +begins. + Кашњење пре започињања вишеструког, узастопног +притискања тастера. + + + + Specifies how many times key presses will be performed +per seconds. + Одређује број притисака тастера у секунди код вишеструког, +узастопног притискања тастера. + + + + <html><head/><body><p>antimicro has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make antimicro load a different translation depending on the language that you choose from the list below.</p></body></html> + <html><head/><body><p>Сарадници аутора су локализовали програм за разне језике. Уобичајено, програм ће употребљавати језичке поставке самог система за приказ, али, уколико то желите, можете употребљавати програм и на језику који одаберете на листи испод.</p></body></html> + + + + French + француски + + + + Japanese + + + + + Russian + руски + + + + Serbian + српски + + + + Simplified Chinese + + + + + Ukrainian + украјински + + + + Class + класи + + + + Title + наслову + + + + Program + Програм + + + + Disable the "Enhanced Pointer Precision" Windows setting +while antimicro is running. Disabling "Enhanced Pointer Precision" +will allow mouse movement within antimicro to be more +precise. + Искључи виндоуз-поставку за „побољшање прецизности показивача“ +док програм ради. Онемогућавањем ове виндоуз-поставке +повећава се прецисност померања показивача (миша) у самом +програму. + + + + Disable Enhance Pointer Precision + Искључи побољшања прецизности показивача + + + + Smoothing + Углађеност + + + + Histor&y Size: + + + + + Weight &Modifier: + + + + + Refresh Rate: + Брзина освежавања: + + + + The refresh rate is the amount of time that will elapse +in between mouse events. Please be cautious when +editing this setting as it will cause the program to use +more CPU power. Setting this value too low can cause +system instability. Please test the setting before using +it unattended. + Брзина освежавања представља протекло време +између догађаја миша. Будите врло опрезни +при уређивању ове поставке јер се може повећати употреба +ЦПЈ (процесора), а при премалим вредностима ове поставке +систем може да пређе у нестабилно стање. Проверите ову +поставку пре озбиљније употребе. + + + + Spring + Скоковито + + + + Screen: + Екран: + + + + Utilize the specified screen for spring mode. On Linux, the +default is to use the primary screen. On Windows, the default +is to use all available screens. + Употребљава наведени екран за „скоковит“ режим. +Уобичајено, На ГНУ-Линуксу је употреба основног екрана, +а на Виндоузу свих расположивих екрана. + + + + Accel Numerator: + Бројилац убрзања: + + + + + + 0 + 0 + + + + Accel Denominator: + Именилац убрзања: + + + + Accel Threshold: + Праг убрзања: + + + + If the acceleration values for the virtual mouse have been +changed by a different process, particularly when quitting +an older game, then you might want to reset the acceleration +values used by the virtual mouse. + Када су вредности убрзања патвореног миша измењене +од стране различитих процеса, посебно при изласку из +старијих игара, можете пожелети да вратите ове +вредности убрзања патвореног миша на оне претходне. + + + + Reset Acceleration + Поврати убрзање + + + + Delay: + Кашњење: + + + + Profi&le Directory: + + + + + ms + мс + + + + Rate: + Брзина: + + + + times/s + пута/сек. + + + + Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. + +Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. + Испод је листа сачуваних, прилагођених мапирања. Можете да употребите следећу табелу да бисте избрисали мапирања или да их привремено онемогућите. Можете да онемогућите мапирања која су укључена у СДЛ; само уметните нови ред са одговарајућим ЈИБГ-џојстика и означите онемогући. + +Подешавања се неће узети у обзир док се не освежи листа доступних џојстика или док не искључите дати, конкретан џојстик. + + + + GUID + ЈИБГ + + + + Mapping String + Ниска придруживања + + + + Disable? + Искључи? + + + + + Delete + Уклони + + + + Insert + Уметни + + + + + Default + подразумевано + + + + Brazilian Portuguese + португалски (Бразил) + + + + English + енглески + + + + German + немачки + + + + + Active + Омогућен + + + + Devices: + Уређаји: + + + + + All + Сви + + + + Device + Уређај + + + + Profile + Профил + + + + Default? + Подразумевано? + + + + Add + Додај + + + + Edit + Уреди + + + + Also, Windows users who want to use a low value should also check the +"Disable Enhance Pointer Precision" checkbox if you haven't disabled +the option in Windows. + Такође, Виндоуз корисници који желе да употребе нижу вредност, +нека провере и „Искључи побољшања прецизности показивача“, ако +нису онемогућили ову опцију у самом систему. + + + + Select Default Profile Directory + Одабир уобичајеног директоријум профила + + + + Are you sure you want to delete the profile? + Да ли заиста желите да уклоните овај профил? + + + + MainWindow + + + No Joysticks have been found. + Please plug in a joystick and then choose the "Update Joysticks" option in the main menu + Нисам пронашао џојстик. + Када га прикључите покрените „Поставке > Пронађи џојстике“ из главног менија + + + + &App + &Датотека + + + + Stick/Pad Assign + Придружи Управљач/Тастатуру + + + + &Options + П&оставке + + + + antimicro + Анти-микро + + + + If events are not seen by a game, please click here to run this application as the Adminstrator. + Ако догађаје игра не „види“, притисните ово дугме за покретање овог програма као администратор. + + + + &Help + &Помоћ + + + + + &Quit + &Затвори + + + + Ctrl+Q + Ctrl+Q + + + + + &Update Joysticks + Про&нађи џојстике + + + + Ctrl+U + Ctrl+U + + + + + &Hide + &Сакриј + + + + Ctrl+H + Ctrl+H + + + + &About + О прогр&аму + + + + Ctrl+A + Ctrl+A + + + + About Qt + О КјуТ + + + + Properties + Особине + + + + Key Checker + Провера тастера тастатуре + + + + Home Page + Матична страна + + + + GitHub Page + Гит-хаб страна + + + + Game Controller Mapping + Придруживач тастера контролера + + + + Settings + Постави називе + + + + Wiki + Вики-стране + + + + Could not find a proper controller identifier. Exiting. + + + + + + + + + + + (%1) + (%1) + + + + + Open File + Отвори датотеку + + + + &Restore + В&рати + + + + Run as Administrator? + Покрени као администратор? + + + + Are you sure that you want to run this program as Adminstrator? + +Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. + Да ли заиста желите да покренете програм уз администраторске дозволе? + +Неки програми покренути уз администраторске дозволе могу да доведу до тога да радње које захтева Анти-микро не буду ваљано препознате све док се и сам Анти-микро не покрене уз исте дозволе. Код Видоуз-Виста или новијих виндоуза ово је изазвано проблемима са дозволама које ствара опција за управљање корисничким налозима (енг. скр. „UAC“). + + + + Failed to elevate program + Не могу да покренем програм + + + + Failed to restart this program as the Administrator + Неуспело покретање програма са админ. дозволама + + + + Could not find controller. Exiting. + + + + + MouseAxisSettingsDialog + + + Mouse Settings - + Поставке миша - + + + + Set %1 + Скуп %1 + + + + MouseButtonSettingsDialog + + + Mouse Settings - + Поставке миша - + + + + Set %1 + Скуп %1 + + + + MouseControlStickSettingsDialog + + + Mouse Settings + Поставке миша + + + + Set %1 + Скуп %1 + + + + MouseDPadSettingsDialog + + + Mouse Settings + Поставке миша + + + + Set %1 + Скуп %1 + + + + MouseSettingsDialog + + + Mouse Settings + Поставке миша + + + + Mouse Mode: + Мишар: + + + + Cursor mode is used to move the mouse cursor +around the screen relative to its current position +depending on how much you move an axis +or if a button is pressed. + +Spring mode is used to move the mouse cursor +from the center of the screen depending on how +much you move an axis. The mouse cursor will +be returned to the center of the screen when the +axis is moved back to the dead zone. + У начину „показивач“, омогућава се релативно +померање показивача миша у односу на његову +текућу позицију. + +У „скоковитом“ начину померање показивача миша +је од средишта екрана у свим смеровима, +а када се показивач миша нађе у мртвој области +програм га враћа на средину екрана. + + + + Cursor + Показивач + + + + Spring + Скоковито + + + + Acceleration: + Убрзавање: + + + + Enhanced Precision + Побољшана прецизност + + + + + Linear + Линеарно + + + + Quadratic + Квадратно + + + + Cubic + Кубно + + + + Quadratic Extreme + Набуџено квадратно + + + + Power Function + Нај-функција + + + + Easing Quadratic + Квадратно попуштање + + + + Easing Cubic + Кубно попуштање + + + + Mouse Speed Settings + Брзина померања + + + + Enable to change the horizontal and vertical speed +boxes at the same time. + Омогућује истовремену промену брзине у оба правца. + + + + Change Together + Измењуј повезано + + + + Horizontal +Speed: + Лево→Десно: + + + + + 1 = 20 pps + 1 = 20 тачака/сек. + + + + Vertical +Speed: + Горе→Доле: + + + + Wheel Hori. +Speed: + Tочкић +водоравно: + + + + Set the speed used for horizontal mouse wheel movement +according to number of simulated notches per second. + Постављање брзине водоравног померања миша према +одговарајућем, симулираном броју зареза по секунди. + + + + Set the speed used for vertical mouse wheel movement +according to number of simulated notches per second. + Постављање брзине усправног померања миша према +одговарајућем, симулираном броју зареза по секунди. + + + + For Power Function acceleration curve. Specifies +the factor to use for curve sensitivity. When the value +is above 1.0, the mouse movement will be accelerated +faster at the low end of an axis. + За кривуљу убрзавања Нај-функције. Одређује +чинилац код постављања осетљивости кривуље. За +вредност изнад 1.0, покрети миша ће се више +убрзавати у крајњем доњем положају осе. + + + + Easing Duration: + Трајање попуштањa: + + + + + s + с + + + + Extra Acceleration + Додатно убрзање + + + + Multiplier: + Чинилац: + + + + Highest value to accelerate mouse movement by + Највиша вредност за убрзање померања миша + + + + x + x + + + + Start %: + Почетак %: + + + + Acceleration begins at this percentage of the base multiplier + Убрзање почиње након оволико процената од основног чиниоца + + + + Min +Threshold: + Најмањи +праг: + + + + Minimum amount of axis travel required for acceleration to begin + Најмања количина осног померања неопходна за отпочињање убрзања + + + + Max +Threshold: + Највећи +праг: + + + + Maximum axis travel before acceleration has reached the multiplier value + Највиша количина осног померања пре но се достигне вредност датог чиниоца + + + + Curve: + + + + + Ease Out Sine + + + + + Ease Out Quad + + + + + Ease Out Cubic + + + + + Release Radius: + Пречник пуштања: + + + + Specifies that the spring area will be relative to the +mouse position set by a non-relative spring. + Одређује да ће „скоковито“ подручје бити +релативно у односу на положај миша постављен +не-релативним скоком. + + + + Relative + Релативно + + + + Mouse Status + Стање миша + + + + X: + X: + + + + + 0 (0 pps) + 0 (0 тачака/сек) + + + + Y: + Y: + + + + + 1 = 1 notch(es)/s + 1 = 1 зарез(а)/сек. + + + + Enhanced: Three tier curve that makes the mouse move +slow on the low end of an axis and fast on the high end. + +Linear: Mouse moves proportionally to axis. + +Quadratic: Mouse accelerates slowly on low end. + +Cubic: Mouse accelerates slower than Quadratic. + +Quadratic Extreme: Raises mouse speed 1.5 times once +95% axis travel has been reached. + +Power Function: Allows for a more custom curve option. + +Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. + +Easing Cubic: Axis high end is gradually accelerated over +a period of time using a Cubic curve. + Подиже брзину померања миша 1,5 пута по достизању 95% осног пута + Побољшана прецизност: Трослојна кривуља која чини да померање миша +буде споро на доњем крају осе и брзо на њеном горњем крају. + +Линеарно: Померања миша је сразмерно по оси. + +Квадратно: Померања миша се лагано убрзавају на доњем крају. + +Кубно: Спорије убрзавање миша од „Квадратног“. + +Набуџено квадратно: Подиже брзину померања миша 1,5 пута +по достизању 95% од могућег осног померања. + +Нај-функција: Дозвољава потпуније прилагођавање кривуље убрзавања. + +Квадратно попуштање: У горњем крају осе, постепено убрзање током времена +употребљавајући квадратну кривуљу. + +Кубно попуштање: У горњем крају осе, постепено убрзање током времена +употребљавајући кубну кривуљу. + + + + Wheel Vert. +Speed: + Tочкић +усправно: + + + + Sensitivity: + Осетљивост: + + + + Specifies the amount of time (in seconds) that will +be required before the mouse is fully accelerated +after reaching the high end of an axis. + Одређује количину времена (у секундама) +неопходну за потпуно убрзање миша, а +након достизања горњег краја осе. + + + + Options for adding extra acceleration to the mouse +movement beyond what the acceleration curve would +produce. This is meant to help work around some of +the issues of the very limited input range available using +typical gamepad analog sticks. + + + + + + + + % + % + + + + Extra Duration: + Додатно трајање: + + + + Extend the time that extra acceleration is applied. Axis travel +will be taken into account. A slower flick will decrease the +actual time that extra acceleration will be applied. + Продужује време за које ће се применити додатно убрзање. У +обзир ће се узети осно померање. Спорији „флик“ смањује +стварно време након кога ће се примењивати додатно убрзање. + + + + Spring Settings + Скоковито померање + + + + Spring Width: + По ширини: + + + + Changes the width of the region that the cursor +can move in spring mode. 0 will use the entire width +of your screen. + Мењање ширине области за померање показивача +у скоковитом начину. „0“ означава искоришћавање +укупне ширине Вашег екрана. + + + + Spring Height: + По висини: + + + + Changes the height of the region that the cursor +can move in spring mode. 0 will use the entire height +of your screen. + Мењање висине области за померање показивача +у скоковитом начину. „0“ означава искоришћавање +укупне висине Вашег екрана. + + + + + %n notch(es)/s + + %n зарез/сек. + %n зареза/сек. + %n зареза/сек. + + + + + QKeyDisplayDialog + + + Key Checker + Провера тастера тастатуре + + + + <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by antimicro.</p><p>The antimicro key value and the Qt key value will usually be the same. antimicro tries to use the key values defined in Qt when possible. Check the page <a href="http://qt-project.org/doc/qt-4.8/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://qt-project.org/doc/qt-4.8/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to antimicro's <a href="https://github.com/Ryochan7/antimicro"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> + <html><head/><body><p>Притисните тастер на тастатури да бисте видели како је овај програм открио одговарајућу вредност. У прозору ће се приказати вредност руковаоца догађаја, вредност у КјуТ-библиотекама (по потреби), као и прилагођена вредност у Анти-микро програму.</p><p>Вредности које су откривене програмима Анти-микро и КјуТ ће обично бити идентичне. јер Анти-микро употребљава вредности КјуТ-библиотека када је то могуће. Погледајте страницу на мрежи <a href="http://qt-project.org/doc/qt-4.8/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://qt-project.org/doc/qt-4.8/qt.html#Key-enum (енг.)</span></a> за вредности одређене за употребу КјуТ-програмима. Ако откријете неке неподржане вредности за тастере у овом програму, известите о том проблему на <a href="https://github.com/Ryochan7/antimicro"><span style=" text-decoration: underline; color:#0057ae;">Анти-микро гит-странама</span></a>, а у циљу исправљања уочених недостатака. Како год, додат је предложак за непознате вредности да би се програм могао употребљавати, али остаје главни проблем који се односи на преносивост профила.</p></body></html> + + + + Event Handler: + Руковалац догађајем: + + + + Native Key Value: + Очитана вредност: + + + + + + 0x00000000 + 0x00000000 + + + + Qt Key Value: + КјуТ вредност: + + + + antimicro Key Value: + Анти-микро вредност: + + + + QObject + + + Super + Супер + + + + Menu + Изборник + + + + Mute + Мук + + + + Vol+ + Гласније + + + + Vol- + Тише + + + + Play/Pause + Пусти/Пауза + + + + Play + Пусти + + + + Pause + Пауза + + + + Prev + Претходно + + + + Next + Наредно + + + + Mail + Е-пошта + + + + Home + Почетно + + + + Media + Медији + + + + Search + Нађи + + + + Daemon launched + Покренут је позадински процес + + + + Failed to launch daemon + Није успело покретање позадинског процеса + + + + Launching daemon + Покрећем позадински процес + + + + + Display string "%1" is not valid. + Није ваљана »Display string „%1“«. + + + + Failed to set a signature id for the daemon + Није успело постављање ИБ-потписа за позадински процес + + + + Failed to change working directory to / + Не могу да поставим „/“ као радни директоријум + + + + Quitting Program + Излазак из програма + + + + # of joysticks found: %1 + # џојстика пронађено: %1 + + + + List Joysticks: + Списак џојстика: + + + + --------------- + --------------- + + + + Joystick %1: + Џојстик %1: + + + + Index: %1 + Индекс: %1 + + + + GUID: %1 + ЈИБГ: %1 + + + + Name: %1 + Назив: %1 + + + + Yes + Да + + + + No + Не + + + + Game Controller: %1 + Контролер програма: %1 + + + + # of Axes: %1 + # праваца: %1 + + + + # of Buttons: %1 + # тастера: %1 + + + + # of Hats: %1 + # капица: %1 + + + + Attempting to use fallback option %1 for event generation. + Покушавам да користим резервну опцију %1 у стварању догађаја. + + + + Failed to open event generator. Exiting. + Не могу да отворим ствараоца догађаја. Излазим. + + + + Using %1 as the event generator. + Употребљавам %1 као ствараоца догађаја. + + + + Could not raise process priority. + Не могу да повисим приоритет процеса. + + + + QuickSetDialog + + + Quick Set + Брзе поставке + + + + <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> + <html><head/><body><p>Притисните неки тастер или померите управљач на уређају <br/>„%1“ (<span style=" font-weight:600;">%2</span>). Након тога, појавиће се прозорче <br/>у којем ћете моћи да придружите том тастеру-управљачу <br/>одговарајући тастер тастатуре, догађај и сл.</p></body></html> + + + + Quick Set %1 + Брзе поставке — %1 + + + + SetAxisThrottleDialog + + + Throttle Change + Промена регулатора + + + + The throttle setting for Axis %1 has been changed. + +Would you like to distribute this throttle change to all sets? + Поставке регулатора за правац %1 су се промениле. + +Желите ли да ове промене регулатора буду доступне у свим групама? + + + + SetJoystick + + + Set %1: %2 + Скуп %1: %2 + + + + Set %1 + Скуп %1 + + + + SetNamesDialog + + + Set Name Settings + Поставке назива скупова + + + + Set 1 + 1. скуп + + + + Set 2 + 2. скуп + + + + Set 3 + 3. скуп + + + + Set 4 + 4. скуп + + + + Set 5 + 5. скуп + + + + Set 6 + 6. скуп + + + + Set 7 + 7. скуп + + + + Set 8 + 8. скуп + + + + Name + Назив + + + + SimpleKeyGrabberButton + + + Mouse + Миш + + + + SpringModeRegionPreview + + + Spring Mode Preview + Преглед за начин „Скоковито“ + + + + UInputEventHandler + + + Could not find a valid uinput device file. +Please check that you have the uinput module loaded. +lsmod | grep uinput + Не могу да нађем ваљану „uinput“-датотеку уређаја. +Проверите да ли је „uinput“-модул учитан. +lsmod | grep uinput + + + + Could not open uinput device file +Please check that you have permission to write to the device + Не могу да отворим „uinput“-датотеку уређаја +Проверите да ли имате дозволу за уписивање на уређај + + + + Using uinput device file %1 + Употребљавам „uinput“-датотеку уређаја %1 + + + + UInputHelper + + + a + а + + + + b + б + + + + c + ц + + + + d + д + + + + e + е + + + + f + ф + + + + g + г + + + + h + х + + + + i + и + + + + j + ј + + + + k + к + + + + l + л + + + + m + м + + + + n + н + + + + o + о + + + + p + п + + + + q + љ + + + + r + р + + + + s + с + + + + t + т + + + + u + у + + + + v + в + + + + w + њ + + + + x + џ + + + + y + ж + + + + z + з + + + + Esc + Врати („Esc“) + + + + F1 + Ф1 + + + + F2 + Ф2 + + + + F3 + Ф3 + + + + F4 + Ф4 + + + + F5 + Ф5 + + + + F6 + Ф6 + + + + F7 + Ф7 + + + + F8 + Ф8 + + + + F9 + Ф9 + + + + F10 + Ф10 + + + + F11 + Ф11 + + + + F12 + Ф12 + + + + ` + ` + + + + 1 + 1 + + + + 2 + 2 + + + + 3 + 3 + + + + 4 + 4 + + + + 5 + 5 + + + + 6 + 6 + + + + 7 + 7 + + + + 8 + 8 + + + + 9 + 9 + + + + 0 + 0 + + + + + - + - + + + + = + = + + + + BackSpace + Уназад + + + + Tab + Таб + + + + [ + [ + + + + ] + ] + + + + \ + \ + + + + CapsLock + В.слова + + + + ; + ; + + + + ' + ' + + + + Enter + Унеси + + + + Shift_L + л.Мењач + + + + , + , + + + + + . + . + + + + + / + / + + + + Ctrl_L + л.Ктрл + + + + + Super_L + л.Супер + + + + Alt_L + л.Алт + + + + Space + Размакница + + + + Alt_R + д.Алт + + + + Menu + Изборник + + + + Ctrl_R + д.Ктрл + + + + Shift_R + д.Мењач + + + + Up + Горе + + + + Left + Лево + + + + Down + Доле + + + + Right + Десно + + + + PrtSc + Сликај + + + + Ins + Уметни + + + + Del + Бриши + + + + Home + Почетак + + + + End + Крај + + + + PgUp + Страна +изнад + + + + PgDn + Страна +испод + + + + NumLock + УКЉ/ +ИСКЉ + + + + * + * + + + + + + + + + + + KP_Enter + КП_Унеси + + + + KP_1 + КП_1 + + + + KP_2 + КП_2 + + + + KP_3 + КП_3 + + + + KP_4 + КП_4 + + + + KP_5 + КП_5 + + + + KP_6 + КП_6 + + + + KP_7 + КП_7 + + + + KP_8 + КП_8 + + + + KP_9 + КП_9 + + + + KP_0 + КП_0 + + + + SCLK + SCLK + + + + Pause + Пауза + + + + Super_R + д.Супер + + + + Mute + Мук + + + + VolDn + Тише + + + + VolUp + Гласније + + + + Play + Пусти + + + + Stop + Заустави + + + + Prev + Претходно + + + + Next + Наредно + + + + [NO KEY] + [Без тастера] + + + + UnixWindowInfoDialog + + + Captured Window Properties + Особине откривеног прозора + + + + Information About Window + Подаци о прозору + + + + Class: + Класа: + + + + + + TextLabel + Текст-натпис + + + + Title: + Наслов: + + + + Path: + Путања: + + + + Match By Properties + Прилагоди по + + + + Class + класи + + + + Title + наслову + + + + Path + путањи + + + + VDPad + + + + + VDPad + Патворен Д-тастер + + + + VirtualKeyPushButton + + + Space + Размакница + + + + Tab + Таб + + + + Shift (L) + л. Мењач + + + + Shift (R) + д. Мењач + + + + Ctrl (L) + л. Ктрл + + + + Ctrl (R) + д. Ктрл + + + + Alt (L) + л. Алт + + + + + Alt (R) + д. Алт + + + + ` + ` + + + + ~ + ~ + + + + + - + - + + + + = + = + + + + [ + [ + + + + ] + ] + + + + \ + \ + + + + Caps + В.слова + + + + ; + ; + + + + ' + ' + + + + , + , + + + + + . + . + + + + + / + / + + + + ESC + Врати + + + + PRTSC + Сликај + + + + SCLK + SCLK + + + + INS + Уметни + + + + PGUP + Страна +изнад + + + + DEL + Бриши + + + + PGDN + Страна +испод + + + + 1 + 1 + + + + 2 + 2 + + + + 3 + 3 + + + + 4 + 4 + + + + 5 + 5 + + + + 6 + 6 + + + + 7 + 7 + + + + 8 + 8 + + + + 9 + 9 + + + + 0 + 0 + + + + NUM +LK + УКЉ/ +ИСКЉ + + + + + * + * + + + + + + + + + + + E +N +T +E +R + У +Н +Е +С +И + + + + < + < + + + + : + : + + + + Super (L) + л.Супер + + + + Menu + Избор + + + + Up + Горе + + + + Down + Доле + + + + Left + Лево + + + + Right + Десно + + + + VirtualKeyboardMouseWidget + + + + Keyboard + Тастатура + + + + + Mouse + Миш + + + + Mouse Settings + Поставке миша + + + + Left + Mouse + Лево + + + + Up + Mouse + Горе + + + + Left Button + Mouse + Леви тастер + + + + Middle Button + Mouse + Средњи тастер + + + + Right Button + Mouse + Десни тастер + + + + Wheel Up + Mouse + Точкић унапред + + + + Wheel Left + Mouse + Точкић улево + + + + Wheel Right + Mouse + Точкић удесно + + + + Wheel Down + Mouse + Точкић уназад + + + + Down + Mouse + Доле + + + + Right + Mouse + Десно + + + + Button 4 + Mouse + Тастер 4 + + + + Mouse 8 + Mouse + Миш 8 + + + + Button 5 + Mouse + Тастер 5 + + + + Mouse 9 + Mouse + Миш 9 + + + + NONE + НИШТА + + + + Applications + Програми + + + + Browser Back + Претходно (веб прегледник) + + + + Browser Favorites + Обележивачи (веб прегледник) + + + + Browser Forward + Наредно (веб прегледник) + + + + Browser Home + Почетна страна (веб прегледник) + + + + Browser Refresh + Освежи (веб прегледник) + + + + Browser Search + Претрага (веб прегледник) + + + + Browser Stop + Заустави учитавање (веб прегледник) + + + + Calc + Калкулатор + + + + Email + Е-пошта + + + + Media + Медији + + + + Media Next + Медији — Наредно + + + + Media Play + Медији — Пусти + + + + Media Previous + Медији — Претходно + + + + Media Stop + Медији — Заустави + + + + Search + Нађи + + + + Volume Down + Тише + + + + Volume Mute + Мук + + + + Volume Up + Гласније + + + + VirtualMousePushButton + + + INVALID + ОШТЕЋЕНО + + + + WinAppProfileTimerDialog + + + + Capture Application + Разоткриј прозор + + + + After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. + По притиску дугмета „Разоткриј прозор“, одаберите прозор програма који желите да повежете са профилом. Разоткривање тог прозора отпочеће након истека доле задатог времена. + + + + Timer: + Након: + + + + Seconds + секунди(е,а) + + + + Cancel + Поништи + + + + WinExtras + + + [NO KEY] + [Без тастера] + + + + AntiMicro Profile + Профил за Анти-микро + + + + X11Extras + + + ESC + Врати + + + + Tab + Таб + + + + Space + Размакница + + + + DEL + Бриши + + + + Return + Унеси +(„Return“) +(„Enter“) + + + + KP_Enter + КП_Унеси + + + + Backspace + Уназад + + + + xinput extension was not found. No mouse acceleration changes will occur. + Није нађено проширење „xinput“. Нису могуће измене брзина при руковању мишем. + + + + + xinput version must be at least 2.0. No mouse acceleration changes will occur. + Издање проширење „xinput“ је старије од издања 2.0. Нису могуће измене брзина при руковању мишем. + + + + Virtual pointer found with id=%1. + Нађен је патворени показивач са ИБ=%1. + + + + PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 + Није нађено „НPtrFeedbackClass“ за патворени показивач. Нису могуће измене брзина при руковању мишем за уређај чији је ИБ=%1 + + + + Changing mouse acceleration for device with id=%1 + Измена убрзања при употреби миша за уређај чији је ИБ=%1 + + + + XMLConfigReader + + + Could not write updated profile XML to file %1. + Не могу да упишем зановљен ИксМЛ-профил у датотеку %1. + + + + XMLConfigWriter + + + Could not write to profile at %1. + Не могу да уписујем у профил у %1. + + + diff --git a/share/antimicro/translations/antimicro_uk.ts b/share/antimicro/translations/antimicro_uk.ts new file mode 100644 index 0000000..c8e3c42 --- /dev/null +++ b/share/antimicro/translations/antimicro_uk.ts @@ -0,0 +1,5919 @@ + + + + + AboutDialog + + + About + Про програму + + + + Version + Версія + + + + Credits + Розробники + + + + Changelog + + + + + Since December 30, 2012, I have been working on antimicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. + +The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. + +Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. + +Once the Steam controller is finally released to the public, the need for this program might not exist anymore. Just based on the concept of the controller alone, the Steam controller would have so many advantages over using a program like this to provide KB+M emulation. + + + + + Copyright: 2013 - 2015 + + + + + Info + Інформація + + + + antimicro + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Travis Nickles &lt;nickles.travis@gmail.com&gt;</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Contributors:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;"><br /></span>Zerro Alvein</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">aybe</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Jeff Backus &lt;jeff.backus@gmail.com&gt;</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Arthur Moore<br />Anton Tornqvist &lt;antont@inbox.lv&gt;</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Translators:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt; font-weight:600;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">zzpxyx - Chinese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">phob - German</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tou omiya - Japanese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">burunduk - Ukrainian</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Version 3, 29 June 2007</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Preamble</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">TERMS AND CONDITIONS</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">0. Definitions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">1. Source Code.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">2. Basic Permissions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">4. Conveying Verbatim Copies.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">5. Conveying Modified Source Versions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">6. Conveying Non-Source Forms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">7. Additional Terms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">8. Termination.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">11. Patents.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">14. Revised Versions of this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">15. Disclaimer of Warranty.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">16. Limitation of Liability.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> + + + + + About Development + + + + + License + Ліцензія + + + + Program Version %1 + Версія програми %1 + + + + Program Compiled on %1 at %2 + Програму скомпільовано %1 о %2 + + + + Built Against SDL %1 + Зібрано на SDL %1 + + + + Running With SDL %1 + Запущено з SDL %1 + + + + Using Qt %1 + Використано Qt %1 + + + + Using Event Handler: %1 + Обробник подій: %1 + + + + AddEditAutoProfileDialog + + + Auto Profile Dialog + Вікно автоматичного профілю + + + + Profile: + Профіль: + + + + + Browse + Оглянути + + + + Window: + + + + + + Select Window. Click on the appropriate application +window and the application file path will be populated +in the form. + Оберіть вікно. Натисніть на вікно необхідного додатку, +і шлях до нього автоматично заповниться +в поле вводу. + + + + Detect Window Properties + + + + + Class: + + + + + Title: + + + + + Application: + + + + + Select + Обрати + + + + Devices: + Пристрої: + + + + + Select this profile to be the default loaded for +the specified device. The selection will be used instead +of the all default profile option. + Оберіть цей профіль як типовий для вказаного +пристрою. Обраний профіль перекриватиме загальні +налаштування типового профілю. + + + + Set as Default for Controller + Встановити типовим для контролера + + + + + A different profile is already selected as the default for this device. + Інший профіль вже встановлено типовим для вказаного пристрою. + + + + Current (%1) + Поточний (%1) + + + + Open Config + Відкрити конфігурацію + + + + + Select Program + Обрати програму + + + + Programs (*.exe) + + + + + Please use the main default profile selection. + Використовуйте основний типовий профіль. + + + + Please select a window by using the mouse. Press Escape if you want to cancel. + Оберіть мишкою вікно. Аби скасувати вибір натисніть Escape. + + + + Capture Application Window + Захоплення вікна програми + + + + Could not obtain information for the selected window. + Не отримано інформації для обраного вікна. + + + + Application Capture Failed + Захоплення програми зазнало невдачі + + + + Profile file path is invalid. + Шлях до профілю хибний. + + + + No window matching property was specified. + + + + + Program path is invalid or not executable. + Шлях до програми хибний, або вона не має прав на виконання. + + + + File is not an .exe file. + + + + + No window matching property was selected. + + + + + AdvanceButtonDialog + + + + Advanced + Розширені параметри + + + + Assignments + Призначення + + + + Toggle + Перемикач + + + + Turbo + Турбо + + + + Set Selector + Встановити селектор + + + + Press Time + Час натиску + + + + Insert a pause that occurs in between key presses. + Вставте паузу між натисканнями клавіш. + + + + Pause + Пауза + + + + Hold + Утримання + + + + Mouse Mod + Мод. мишки + + + + Cycle + Цикл + + + + Distance + Дистанція + + + + Release + Віджати + + + + Blank or KB/M + + + + + Delay + Затримка + + + + Execute + + + + + Load + Завантажити + + + + Set Change + + + + + Text Entry + + + + + + Insert a new blank slot. + Вставити новий пустий слот. + + + + Insert + Вставити + + + + Delete a slot. + Вилучити слот. + + + + Delete + Вилучити + + + + Clear all currently assigned slots. + Очистити всі поточні слоти. + + + + Clear All + Очистити все + + + + Placeholder + Заповнювач + + + + Specify the duration of an inserted Pause or Hold slot. + Встановити тривалість слотів Пауза чи Утримання. + + + + Time: + Час: + + + + 0.01s + 0.01с + + + + 0m + 0хв + + + + + 0 + 0 + + + + 0s + + + + + Mouse Speed Mod: + Зміна швидкості мишки: + + + + Set the percentage that mouse speeds will be modified by. + Встановіть зміну швидкості миші у відсотковому співвідношенні. + + + + + % + % + + + + + Specify the range past an axis dead zone in which a sequence of actions will execute. + + + + + Distance: + Дистанція: + + + + Auto Reset Cycle After + Автоматично скидати цикл опісля + + + + seconds + секунд + + + + ... + + + + + + + Enabled + Включити + + + + Mode: + Режим: + + + + <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> + + + + + Normal + Звичайний + + + + Gradient + Наростаючий + + + + Pulse + Пульсуючий + + + + Delay: + Затримка: + + + + 0.10s + 0.10с + + + + Rate: + Частота: + + + + 10.0/s + 10.0/с + + + + + Disabled + Вимкнено + + + + Select Set 1 One Way + Встановити набір 1 одностороннім + + + + Select Set 1 Two Way + Встановити набір 1 двостороннім + + + + Select Set 1 While Held + Встановити набір 1 доки натиснуто + + + + Select Set 2 One Way + Встановити набір 2 одностороннім + + + + Select Set 2 Two Way + Встановити набір 2 двостороннім + + + + Select Set 2 While Held + Встановити набір 2 доки натиснуто + + + + Select Set 3 One Way + Встановити набір 3 одностороннім + + + + Select Set 3 Two Way + Встановити набір 3 двостороннім + + + + Select Set 3 While Held + Встановити набір 3 доки натиснуто + + + + Select Set 4 One Way + Встановити набір 4 одностороннім + + + + Select Set 4 Two Way + Встановити набір 4 двостороннім + + + + Select Set 4 While Held + Встановити набір 4 доки натиснуто + + + + Select Set 5 One Way + Встановити набір 5 одностороннім + + + + Select Set 5 Two Way + Встановити набір 5 двостороннім + + + + Select Set 5 While Held + Встановити набір 5 доки натиснуто + + + + Select Set 6 One Way + Встановити набір 6 одностороннім + + + + Select Set 6 Two Way + Встановити набір 6 двостороннім + + + + Select Set 6 While Held + Встановити набір 6 доки натиснуто + + + + Select Set 7 One Way + Встановити набір 7 одностороннім + + + + Select Set 7 Two Way + Встановити набір 7 двостороннім + + + + Select Set 7 While Held + Встановити набір 7 доки натиснуто + + + + Select Set 8 One Way + Встановити набір 8 одностороннім + + + + Select Set 8 Two Way + Встановити набір 8 двостороннім + + + + Select Set 8 While Held + Встановити набір 8 доки натиснуто + + + + sec. + сек. + + + + /sec. + /сек. + + + + Set %1 + Набір %1 + + + + + Select Set %1 + Обрати набір %1 + + + + One Way + Односторонній + + + + Two Way + Двосторонній + + + + While Held + Доки натиснуто + + + + Choose Executable + + + + + Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. + + + + + Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. + + + + + Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. + + + + + Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. + + + + + Chose a profile to load when this slot is activated. + + + + + Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. + + + + + Specify the time that keys past this slot should be held down. + + + + + Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. + + + + + Change to selected set once slot is activated. + + + + + Full string will be typed when a slot is activated. + + + + + Execute program when slot is activated. + + + + + + Choose Profile + + + + + Config Files (*.amgp *.xml) + + + + + AdvanceStickAssignmentDialog + + + Stick/Pad Assignment + Призначення стіків/хрестовин + + + + Sticks + Стіки + + + + DPads + DPad'и + + + + Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. + + + + + + %1 (Joystick %2) + %1 (джойстик %2) + + + + Stick 1 + Стік 1 + + + + + + Enabled + Активний + + + + + + + + + Assign + Призначити + + + + + X Axis: + Вісь X: + + + + + Y Axis: + Вісь Y: + + + + Stick 2 + Стік 2 + + + + Number of Physical DPads: %1 + Кількість фізичних DPad'ів: %1 + + + + Virtual DPad 1 + Віртуальний DPad 1 + + + + Down: + Вниз: + + + + Left: + Вліво: + + + + Right: + Вправо: + + + + Up: + Вверх: + + + + + + + Axis %1 + Вісь %1 + + + + + + + Axis %1 - + Вісь %1 - + + + + + + + Axis %1 + + Вісь %1 + + + + + + + + Button %1 + Кнопка %1 + + + + Move stick 1 along the X axis + Рухайте стік 1 по вісі X + + + + Move stick 1 along the Y axis + Рухайте стік 1 по вісі Y + + + + Move stick 2 along the X axis + Рухайте стік 2 по вісі X + + + + Move stick 2 along the Y axis + Рухайте стік 2 по вісі Y + + + + + + + Press a button or move an axis + Натисніть кнопки чи змістіть вісь + + + + AxisEditDialog + + + Axis + Вісь + + + + Presets: + Типовий набір: + + + + + Mouse (Horizontal) + Мишка (Горизонтально) + + + + + Mouse (Inverted Horizontal) + Мишка (Горизонтально інвертовано) + + + + + Mouse (Vertical) + Мишка (Вертикально) + + + + + Mouse (Inverted Vertical) + Мишка (Вертикально інвертовано) + + + + + Arrows: Up | Down + Стрілки: Вверх | Вниз + + + + + Arrows: Left | Right + Стрілки: Вліво | Вправо + + + + + Keys: W | S + Клавіші: W | S + + + + + Keys: A | D + Клавіші: A | D + + + + + NumPad: KP_8 | KP_2 + NumPad: KP_8 | KP_2 + + + + + NumPad: KP_4 | KP_6 + NumPad: KP_4 | KP_6 + + + + + + None + Відсутній + + + + + Set the value to use as the limit for an axis. Useful for a +worn out analog stick. + + + + + Dead Zone: + Сліпа зона: + + + + + Set the value of the dead zone for an axis. + Встановіть значення сліпої зони для вісі. + + + + Max Zone: + Максимальна зона: + + + + + [NO KEY] + [НЕМАЄ КНОПКИ] + + + + Throttle setting that determines the behavior of how to +interpret an axis hold or release. + Параметри тяги визначають, як програма має реагувати +на утримання та натискання вісі. + + + + Negative Half Throttle + Зворотня напівтяга + + + + Negative Throttle + Зворотня тяга + + + + Normal + Звичайний + + + + Positive Throttle + Пряма тяга + + + + Positive Half Throttle + Пряма напівтяга + + + + Current Value: + Поточне значення: + + + + Name: + Ім'я: + + + + Specify the name of an axis. + Назначте ім'я для вісі. + + + + Mouse Settings + Параметри мишки + + + + Set + Набір + + + + Set %1 + Набір %1 + + + + Left Mouse Button + + + + + Right Mouse Button + + + + + ButtonEditDialog + + + Dialog + Діалог + + + + To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab + Аби зробити нове призначення, натисніть клавішу на клавіатурі, чи клацніть по кнопці розташованій на вкладках «Клавіатура» чи «Мишка» + + + + Placeholder + Заповнювач + + + + Enables a key press or release to only occur when a controller button is pressed. + Дозволяє виконувати дію тільки при натисканні чи відпусканні клавіші. + + + + Toggle + Перемикач + + + + Enables rapid key presses and releases. Turbo controller. + Дозволити прискорене натискання клавіш. Турбо контролер. + + + + Turbo + Турбо + + + + Current: + Поточний: + + + + Slots + Слоти + + + + Na&me: + + + + + Specify the name of a button. + Назначте ім'я для кнопки. + + + + Action: + Дія: + + + + Specify the action that will be performed in game while +this button is being used. + + + + + Advanced + Розширені параметри + + + + Set + Набір + + + + Set %1 + Набір %1 + + + + CapturedWindowInfoDialog + + + Captured Window Properties + + + + + Information About Window + + + + + Class: + + + + + + + TextLabel + + + + + Title: + + + + + Path: + + + + + Match By Properties + + + + + Class + + + + + Title + + + + + Path + + + + + Full Path + + + + + File Name + + + + + CommandLineUtility + + + + Profile location %1 is not an XML file. + Профіль %1 не є XML файлом. + + + + + Profile location %1 does not exist. + Профіль %1 не існує. + + + + + + Controller identifier is not a valid value. + Контролер має хибне значення ідентифікатора. + + + + No set number was specified. + Не вказаний набір значень. + + + + No controller was specified. + Жодного контролеру не було вказано. + + + + No display string was specified. + Жодного рядка для показу не було вказано. + + + + An invalid event generator was specified. + + + + + No event generator string was specified. + + + + + Qt style flag was detected but no style was specified. + + + + + No log level specified. + + + + + + + + antimicro version + + + + + An invalid set number '%1' was specified. + + + + + Controller identifier '%s'' is not a valid value. + + + + + + Usage: antimicro [options...] [profile] + + + + + + Options + Параметри + + + + + Print help text. + Вивести довідку. + + + + + Print version information. + Вивести версію програми. + + + + + Launch program in system tray only. + Запустити програму згорнутою у системний лоток. + + + + + Launch program with the tray menu disabled. + Запустити програму із заблокованим меню в лотку. + + + + + Launch program without the main window + displayed. + Запустити програму без показу + головного вікна. + + + + + Launch program with the configuration file + selected as the default for selected + controllers. Defaults to all controllers. + + + + + + Apply configuration file to a specific + controller. Value can be a + controller index, name, or GUID. + + + + + + Unload currently enabled profile(s). + Value can be a controller index, name, or GUID. + + + + + + Start joysticks on a specific set. + Value can be a controller index, name, or GUID. + + + + + + Advance profile loading set options. + + + + + + Launch program as a daemon. + Запустити програму в режимі демона. + + + + + Enable logging. + + + + + + Use specified display for X11 calls. + Useful for ssh. + + + + + + Choose between using XTest support and uinput + support for event generation. Default: xtest. + + + + + + Choose between using SendInput and vmulti + support for event generation. Default: sendinput. + + + + + + Print information about joysticks detected by + SDL. + + + + + + Open game controller mapping window of selected + controller. Value can be a controller index or + GUID. + + + + + DPadContextMenu + + + Mouse (Normal) + Мишка (стандарт) + + + + Mouse (Inverted Horizontal) + Мишка (Горизонтально інвертовано) + + + + Mouse (Inverted Vertical) + Мишка (Вертикально інвертовано) + + + + Mouse (Inverted Horizontal + Vertical) + Мишка (Інвертовано гор.+верт.) + + + + Arrows + Стрілки + + + + Keys: W | A | S | D + Клавіші: W | A | S | D + + + + NumPad + NumPad + + + + None + Відсутній + + + + Standard + Стандарт + + + + Eight Way + Вісім сторін + + + + 4 Way Cardinal + 4 основні сторони + + + + 4 Way Diagonal + 4 діагональні сторони + + + + Mouse Settings + Параметри мишки + + + + DPadEditDialog + + + Dialog + Діалог + + + + Presets: + Типовий набір: + + + + Mouse (Normal) + Мишка (стандарт) + + + + Mouse (Inverted Horizontal) + Мишка (Горизонтально інвертовано) + + + + Mouse (Inverted Vertical) + Мишка (Вертикально інвертовано) + + + + Mouse (Inverted Horizontal + Vertical) + Мишка (Інвертовано гор.+верт.) + + + + Arrows + Стрілки + + + + Keys: W | A | S | D + Клавіші: W | A | S | D + + + + NumPad + NumPad + + + + None + Відсутній + + + + Dpad Mode: + Режим DPad: + + + + Standard: 8 region dpad with two direction buttons active +when the dpad is in a diagonal region. + +Eight Way: 8 region dpad with each direction having its +own dedicated button. Only one button is ever active at +at time. Useful for rougelike games. + +4 Way Cardinal: 4 region dpad with regions corresponding to +the cardinal directions of the dpad. Useful for menus. + +4 Way Diagonal: 4 region dpad with each region corresponding +to a diagonal zone. + + + + + &Name: + + + + + Standard + Стандарт + + + + Eight Way + Вісім сторін + + + + 4 Way Cardinal + 4 основні сторони + + + + 4 Way Diagonal + 4 діагональні сторони + + + + DPad Delay: + Затримка DPad'а: + + + + + Time lapsed before a direction change is taken into effect. + Час затримки, через який зміна напрямку набуде чинності. + + + + s + с + + + + Specify the name of a dpad. + Назначте ім'я для DPad. + + + + Mouse Settings + Параметри мишки + + + + Set + Набір + + + + Set %1 + Набір %1 + + + + EditAllDefaultAutoProfileDialog + + + Default Profile + Типовий профіль + + + + Profile: + Профіль: + + + + Browse + Оглянути + + + + Open Config + Відкрити конфігурацію + + + + Profile file path is invalid. + Шлях до профілю некоректний. + + + + ExtraProfileSettingsDialog + + + Extra Profile Settings + Розширені параметри профілю + + + + Key Press Time: + Час натиску клавіші: + + + + 0.00 ms + 0.00 мс + + + + Profile Name: + Ім'я профілю: + + + + + + s + с + + + + GameController + + + Game Controller + Ігровий контролер + + + + GameControllerDPad + + + + + DPad + DPad + + + + GameControllerMappingDialog + + + Game Controller Mapping + Відображення ігрового контролеру + + + + <html><head/><body><p>antimicro makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicro will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> + + + + + A + A + + + + B + B + + + + X + X + + + + Y + Y + + + + Back + Назад + + + + Start + Старт + + + + Guide + Guide + + + + Left Shoulder + Ліве плече + + + + Right Shoulder + Праве плече + + + + Left Stick Click + Клік лівого стіку + + + + Right Stick Click + Клік правого стіку + + + + Left Stick X + Лівий стік X + + + + Left Stick Y + Лівий стік Y + + + + Right Stick X + Правий стік X + + + + Right Stick Y + Правий стік Y + + + + Left Trigger + Лівий триґер + + + + Right Trigger + Правий триґер + + + + DPad Up + DPad Верх + + + + DPad Left + DPad Ліво + + + + DPad Down + DPad Низ + + + + DPad Right + DPad Право + + + + Mapping + Відображення + + + + SDL 2 Game Controller Mapping String + Рядок відображення контролеру від SDL 2 + + + + Last Axis Event: + + + + + Current Axis Detection Dead Zone: + + + + + 5000 + 5000 + + + + 10000 + 10000 + + + + 15000 + 15000 + + + + 20000 + 20000 + + + + 25000 + 25000 + + + + 30000 + 30000 + + + + 32000 + 32000 + + + + Game Controller Mapping (%1) (#%2) + Відображення ігрового контролеру (%1) (#%2) + + + + Discard Controller Mapping? + Скинути відображення контролеру? + + + + Discard mapping for this controller? + +If discarded, the controller will be reverted to a joystick once you refresh all joysticks. + + + + + GameControllerSet + + + Back + Назад + + + + Guide + Guide + + + + Start + Старт + + + + LS Click + Клік ЛС + + + + RS Click + Клік ПС + + + + L Shoulder + Л плече + + + + R Shoulder + П плече + + + + L Trigger + Л триґер + + + + R Trigger + П триґер + + + + GameControllerTrigger + + + + + Trigger + Триґер + + + + JoyAxis + + + + + Axis + Вісь + + + + JoyAxisButton + + + + + Button + Кнопка + + + + Negative + Зворотній + + + + Positive + Прямий + + + + Unknown + Невідомо + + + + JoyAxisContextMenu + + + Mouse (Horizontal) + Мишка (Горизонтально) + + + + Mouse (Inverted Horizontal) + Мишка (Горизонтально інвертовано) + + + + Mouse (Vertical) + Мишка (Вертикально) + + + + Mouse (Inverted Vertical) + Мишка (Вертикально інвертовано) + + + + Arrows: Up | Down + Стрілки: Вверх | Вниз + + + + Arrows: Left | Right + Стрілки: Вліво | Вправо + + + + Keys: W | S + Клавіші: W | S + + + + Keys: A | D + Клавіші: A | D + + + + NumPad: KP_8 | KP_2 + NumPad: KP_8 | KP_2 + + + + NumPad: KP_4 | KP_6 + NumPad: KP_4 | KP_6 + + + + + None + Відсутній + + + + + Mouse Settings + Параметри мишки + + + + Left Mouse Button + + + + + Right Mouse Button + + + + + JoyButton + + + Processing turbo for #%1 - %2 + + + + + Finishing turbo for button #%1 - %2 + + + + + Processing press for button #%1 - %2 + + + + + Processing release for button #%1 - %2 + + + + + Distance change for button #%1 - %2 + + + + + + + Button + Кнопка + + + + + + + [NO KEY] + [НЕМАЄ КНОПКИ] + + + + [Set %1 1W] + [Набір %1 1W] + + + + [Set %1 2W] + [Набір %1 2W] + + + + [Set %1 WH] + [Набір %1 WH] + + + + JoyButtonContextMenu + + + Toggle + Перемкнути + + + + Turbo + Турбо + + + + Clear + Очистити + + + + Set Select + Встановити вибір + + + + Disabled + Вимкнено + + + + Set %1 + Набір %1 + + + + Set %1 1W + Набір %1 1W + + + + Set %1 2W + Набір %1 2W + + + + Set %1 WH + Набір %1 WH + + + + JoyButtonSlot + + + + Mouse + Мишка + + + + Up + Вверх + + + + Down + Вниз + + + + Left + Вліво + + + + Right + Вправо + + + + LB + ЛК + + + + MB + СК + + + + RB + ПК + + + + B4 + К4 + + + + B5 + К5 + + + + Pause + Пауза + + + + Hold + Утримання + + + + Cycle + Цикл + + + + Distance + Дистанція + + + + Release + Віджати + + + + Mouse Mod + Мод. мишки + + + + Press Time + Час натиску + + + + Delay + Затримка + + + + Load %1 + + + + + Set Change %1 + + + + + [Text] %1 + + + + + [Exec] %1 + + + + + [NO KEY] + [НЕМАЄ КНОПКИ] + + + + JoyControlStick + + + + + Stick + Стік + + + + JoyControlStickButton + + + + + Up + Верх + + + + + + Down + Низ + + + + + + Left + Ліво + + + + + + Right + Право + + + + + + Button + Кнопка + + + + JoyControlStickContextMenu + + + Mouse (Normal) + Мишка (Стандарт) + + + + Mouse (Inverted Horizontal) + Мишка (Горизонтально інвертовано) + + + + Mouse (Inverted Vertical) + Мишка (Вертикально інвертовано) + + + + Mouse (Inverted Horizontal + Vertical) + Мишка (Інвертовано гор.+верт.) + + + + Arrows + Стрілки + + + + Keys: W | A | S | D + Клавіші: W | A | S | D + + + + NumPad + NumPad + + + + None + Відсутній + + + + Standard + Стандарт + + + + Eight Way + Вісім сторін + + + + 4 Way Cardinal + 4 основні сторони + + + + 4 Way Diagonal + 4 діагональні сторони + + + + Mouse Settings + Параметри мишки + + + + JoyControlStickEditDialog + + + Dialog + Діалог + + + + X: + X: + + + + + + + + 0 + 0 + + + + Y: + Y: + + + + Distance: + Дистанція: + + + + Bearing: + Напрям: + + + + % Safe Zone: + % Безпечна зона: + + + + Presets: + Типовий набір: + + + + Mouse (Normal) + Мишка (стандарт) + + + + Mouse (Inverted Horizontal) + Мишка (Горизонтально інвертовано) + + + + Mouse (Inverted Vertical) + Мишка (Вертикально інвертовано) + + + + Mouse (Inverted Horizontal + Vertical) + Мишка (Інвертовано гор.+верт.) + + + + Arrows + Стрілки + + + + Keys: W | A | S | D + Клавіші: W | A | S | D + + + + NumPad + NumPad + + + + None + Відсутній + + + + Stick Mode: + Режим стіка: + + + + Standard: 8 region stick with two direction buttons active +when the stick is in a diagonal region. + +Eight Way: 8 region stick with each direction having its +own dedicated button. Only one button is ever active at +at time. Useful for rougelike games. + +4 Way Cardinal: 4 region stick with regions corresponding to +the cardinal directions of the stick. Useful for menus. + +4 Way Diagonal: 4 region stick with each region corresponding +to a diagonal zone of the stick. + + + + + Standard + Стандарт + + + + Eight Way + Вісім сторін + + + + 4 Way Cardinal + 4 основні сторони + + + + 4 Way Diagonal + 4 діагональні сторони + + + + Dead Zone: + Сліпа зона: + + + + + Dead zone value to use for an analog stick. + + + + + Max Zone: + Максимальна зона: + + + + + Value when an analog stick is considered moved 100%. + + + + + Diagonal Range: + Діагональний діапазон: + + + + + The area (in degrees) that each diagonal region occupies. + + + + + Square Stick: + Квадратність стіку: + + + + + Percentage to modify a square stick coordinates to confine values to a circle + + + + + % + % + + + + Stick Delay: + Затримка стіка: + + + + + Time lapsed before a direction change is taken into effect. + Час затримки, через який зміна напрямку набуде чинності. + + + + s + с + + + + Modifier: + + + + + Edit button that is active while the stick is active. + +This button is useful for assigning zones with +modifier keys that can be used to assign walk/run +functionality to an analog stick. + + + + + PushButton + + + + + Name: + Ім'я: + + + + Specify the name of an analog stick. + Назначте ім'я для аналогового стіка. + + + + Mouse Settings + Параметри мишки + + + + Set + Набір + + + + Set %1 + Набір %1 + + + + JoyControlStickModifierButton + + + + + Modifier + + + + + JoyDPad + + + + + DPad + DPad + + + + JoyDPadButton + + + + + Up + Верх + + + + + + Down + Низ + + + + + + Left + Ліво + + + + + + Right + Право + + + + + + Button + Кнопка + + + + JoyTabWidget + + + + + + + + <New> + <Новий> + + + + + Remove + Вилучити + + + + + Remove configuration from recent list. + Вилучити конфігурацію з переліку частого користування. + + + + + Load + Завантажити + + + + + Load configuration file. + Завантажити файл конфігурації. + + + + + Save + Зберегти + + + + + Save changes to configuration file. + Зберегти зміни до файлу конфігурації. + + + + + Save As + Зберегти як + + + + + Save changes to a new configuration file. + Зберегти зміни в новий файл конфігурації. + + + + + Sets + Набори + + + + Copy from Set + Копіювати з набору + + + + Settings + Параметри + + + + + Set 1 + Набір 1 + + + + + Set 2 + Набір 2 + + + + + Set 3 + Набір 3 + + + + + Set 4 + Набір 4 + + + + + Set 5 + Набір 5 + + + + + Set 6 + Набір 6 + + + + + Set 7 + Набір 7 + + + + + Set 8 + Набір 8 + + + + + Stick/Pad Assign + Призначення стіків/DPad + + + + + Controller Mapping + Відображення контролеру + + + + + Quick Set + Швидкий набір + + + + + Names + Імена + + + + + Toggle button name displaying. + Перемкнути показ команд на кнопках. + + + + + Pref + Параметри + + + + + Change global profile settings. + Змінити глобальні параметри профілю. + + + + + + Reset + Скинути + + + + + Revert changes to the configuration. Reload configuration file. + Відновити зміни. Перезавантажити файл конфігурації. + + + + Open Config + Відкрити конфігурацію + + + + Config Files (*.amgp *.xml) + + + + + + + Save Config + Зберегти конфігурацію + + + + + + Config File (*.%1.amgp) + + + + + + Set + Набір + + + + + Save Profile Changes? + Зберегти зміни профілю? + + + + + Changes to the new profile have not been saved. Would you like to save or discard the current profile? + Зміни до нового профілю не збережені. Зберегти їх до поточного профілю? + + + + + Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? + Зміни до профілю "%1" не збережені. Зберегти їх до поточного профілю? + + + + Sticks + Стіки + + + + + DPads + DPad'и + + + + No buttons have been assigned. Please use Quick Set to assign keys +to buttons or disable hiding empty buttons. + Жодної кнопки не назначено. Використовуйте «Швидкий набір» для +призначення клавіш, або ж вимкніть приховування пустих кнопок. + + + + + Set %1: %2 + Набір %1: %2 + + + + + Set %1 + Набір %1 + + + + Copy Set Assignments + Скопіювати набір значень + + + + Are you sure you want to copy the assignments and device properties from %1? + Дійсно бажаєте скопіювати значення і властивості пристрою з %1? + + + + Joystick + + + Joystick + Джойстик + + + + JoystickStatusWindow + + + Properties + Властивості + + + + Details + Деталі + + + + Name: + Ім'я: + + + + + + + + + + %1 + %1 + + + + Number: + Кількість: + + + + Axes: + Вісь: + + + + Buttons: + Кнопок: + + + + Hats: + Міні джойстиків: + + + + GUID: + GUID: + + + + Game Controller: + Ігровий контролер: + + + + Axes + Вісь + + + + Buttons + Кнопки + + + + Hats + Міні джойстики + + + + %1 (#%2) Properties + Властивості %1 (#%2) + + + + Axis %1 + Вісь %1 + + + + Hat %1 + Міні джойстик %1 + + + + No + Ні + + + + Yes + Так + + + + MainSettingsDialog + + + Edit Settings + Змінити параметри + + + + General + Основні + + + + Controller Mappings + Відображення контролеру + + + + Language + Мова + + + + Auto Profile + Авто-профіль + + + + Mouse + Мишка + + + + <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> + <html><head/><body><p>Вкажіть типову теку, яку програма використовуватиме для збереження профілів.</p></body></html> + + + + Recent Profile Count: + Кількість швидких профілів: + + + + <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> + <html><head/><body><p>Кількість профілів, які будуть показані в переліку часто уживаних. Значення 0 трактується програмою, як необмежена кількість профілів для показу.</p></body></html> + + + + Gamepad Poll Rate: + + + + + Change the poll rate that the program uses to discover new +events from gamepads. Defaults to 10 ms. + +Reducing the poll rate value could cause the application to +use more CPU power so please test the setting that you use +before using antimicro unattended. + + + + + Hide main window when the main window close button is +clicked instead of quitting the program. + Приховувати головне вікно кнопкою закриття +замість виходу з програми. + + + + Close To Tray + Закривати до лотку + + + + Have Windows start antimicro at system startup. + + + + + Launch At Windows Startup + Запускати разом із Windows + + + + Display recent profiles for all controllers +as a single list in the tray menu. Defaults +to using sub-menus. + Виводить часто уживані профілі до всіх контролерів +єдиним переліком в меню лотку. +Типово використовується підменю. + + + + Single Profile List in Tray + Один перелік профілів в лотку + + + + Have the program minimize to the taskbar. +By default, the program minimizes to the system +tray if available. + Вказує програмі згортатись до панелі завдань. +Зазвичай, програма згортається до системного +лотку, якщо є можливість. + + + + Minimize to Taskbar + Згортати до панелі завдань + + + + This option will cause the program to hide all +buttons that have no slots assigned to them. +The Quick Set dialog window will have to be used +to bring up the edit dialog for gamepad buttons. + Параметр вказує програмі приховувати всі +кнопки, якім не назначено жодного слоту. +Використовуйте діалог «Швидкий набір» аби +повернути діалог редагування кнопок +ігрового контролера. + + + + Hide Empty Buttons + Приховати пусті кнопки + + + + When the program is launched, open the last +known profile that was opened during the +previous session. + Під час запуску програми, відкривається +останній відомий профіль, який був відкритий +у попередній сесії. + + + + Auto Load Last Opened Profile + Автоматично завантажувати останній відкритий профіль + + + + Only show the system tray icon when the program +first launches. + Показувати лише піктограму в системному лотку +під час першого запуску. + + + + Launch in Tray + Запускати в лотку + + + + Associate .amgp files with antimicro in Windows Explorer. + + + + + Associate Profiles + Прив'язати профілі + + + + Key Repeat + Повтор клавіш + + + + Active keys will be repeatedly pressed when this +option is enabled. + Активні клавіші повторно натискатимуться +коли цей параметр активний. + + + + + Enable + + + + + Specifies how much time should elapse before key repeating +begins. + + + + + Specifies how many times key presses will be performed +per seconds. + + + + + <html><head/><body><p>antimicro has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make antimicro load a different translation depending on the language that you choose from the list below.</p></body></html> + + + + + French + + + + + Japanese + + + + + Russian + + + + + Serbian + + + + + Simplified Chinese + + + + + Ukrainian + + + + + Class + + + + + Title + + + + + Program + + + + + Disable the "Enhanced Pointer Precision" Windows setting +while antimicro is running. Disabling "Enhanced Pointer Precision" +will allow mouse movement within antimicro to be more +precise. + + + + + Disable Enhance Pointer Precision + + + + + Smoothing + + + + + Histor&y Size: + + + + + Weight &Modifier: + + + + + Refresh Rate: + + + + + The refresh rate is the amount of time that will elapse +in between mouse events. Please be cautious when +editing this setting as it will cause the program to use +more CPU power. Setting this value too low can cause +system instability. Please test the setting before using +it unattended. + + + + + Spring + Пружинний + + + + Screen: + + + + + Utilize the specified screen for spring mode. On Linux, the +default is to use the primary screen. On Windows, the default +is to use all available screens. + + + + + Accel Numerator: + + + + + + + 0 + 0 + + + + Accel Denominator: + + + + + Accel Threshold: + + + + + If the acceleration values for the virtual mouse have been +changed by a different process, particularly when quitting +an older game, then you might want to reset the acceleration +values used by the virtual mouse. + + + + + Reset Acceleration + + + + + Delay: + Затримка: + + + + Profi&le Directory: + + + + + ms + мс + + + + Rate: + Частота: + + + + times/s + разів/с + + + + Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. + +Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. + + + + + GUID + GUID + + + + Mapping String + Рядок відображення + + + + Disable? + Вимкнути? + + + + + Delete + Вилучити + + + + Insert + Вставити + + + + + Default + Типова + + + + Brazilian Portuguese + Brazilian Portuguese + + + + English + English + + + + German + German + + + + + Active + Активний + + + + Devices: + Пристрої: + + + + + All + Всі + + + + Device + Пристрій + + + + Profile + Профіль + + + + Default? + Типовий? + + + + Add + Додати + + + + Edit + Змінити + + + + Also, Windows users who want to use a low value should also check the +"Disable Enhance Pointer Precision" checkbox if you haven't disabled +the option in Windows. + + + + + Select Default Profile Directory + Обрати типову теку профілю + + + + Are you sure you want to delete the profile? + Дійсно вилучити профіль? + + + + MainWindow + + + antimicro + + + + + No Joysticks have been found. + Please plug in a joystick and then choose the "Update Joysticks" option in the main menu + Не знайдено жодного джойстика. +Будь ласка, під'єднайте джойстик, і натисніть пункт «Оновити джойстики» в головному меню + + + + If events are not seen by a game, please click here to run this application as the Adminstrator. + Якщо події в грі не спостерігаються, натисніть тут, аби запустити програму з правами Адміністратора. + + + + &App + Прогр&ама + + + + &Options + &Параметри + + + + &Help + &Допомога + + + + + &Quit + &Вихід + + + + Ctrl+Q + Ctrl+Q + + + + + &Update Joysticks + &Оновити джойстики + + + + Ctrl+U + Ctrl+U + + + + + &Hide + &Згорнути + + + + Ctrl+H + Ctrl+H + + + + &About + Пр&о програму + + + + Ctrl+A + Ctrl+A + + + + About Qt + Про Qt + + + + Properties + Властивості + + + + Key Checker + Перевірка клавіш + + + + Home Page + Домашня сторінка + + + + GitHub Page + Сторінка на GitHub + + + + Game Controller Mapping + Відображення ігрового контролеру + + + + Settings + Параметри + + + + Stick/Pad Assign + Призначення стіків/DPad + + + + Wiki + Wiki + + + + Could not find a proper controller identifier. Exiting. + + + + + + + + + + + (%1) + (%1) + + + + + Open File + Відкрити файл + + + + &Restore + &Відновити + + + + Run as Administrator? + Запустити із правами Адміністратора? + + + + Are you sure that you want to run this program as Adminstrator? + +Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. + + + + + Failed to elevate program + Не вдалося підняти права програмі + + + + Failed to restart this program as the Administrator + Не вдалось перезапустити програму із правами Адміністратора + + + + Could not find controller. Exiting. + + + + + MouseAxisSettingsDialog + + + Mouse Settings - + Параметри мишки - + + + + Set %1 + Набір %1 + + + + MouseButtonSettingsDialog + + + Mouse Settings - + Параметри мишки - + + + + Set %1 + Набір %1 + + + + MouseControlStickSettingsDialog + + + Mouse Settings + Параметри мишки + + + + Set %1 + Набір %1 + + + + MouseDPadSettingsDialog + + + Mouse Settings + Параметри мишки + + + + Set %1 + Набір %1 + + + + MouseSettingsDialog + + + Mouse Settings + Параметри мишки + + + + Mouse Mode: + Режим мишки: + + + + Cursor mode is used to move the mouse cursor +around the screen relative to its current position +depending on how much you move an axis +or if a button is pressed. + +Spring mode is used to move the mouse cursor +from the center of the screen depending on how +much you move an axis. The mouse cursor will +be returned to the center of the screen when the +axis is moved back to the dead zone. + + + + + Cursor + Курсор + + + + Spring + Пружинний + + + + Acceleration: + Прискорення: + + + + Enhanced Precision + Покращена точність + + + + + Linear + Лінійне + + + + Quadratic + Квадратичне + + + + Cubic + Кубічне + + + + Quadratic Extreme + Екстремально квадратичне + + + + Power Function + По степеневій функції + + + + Easing Quadratic + Просте квадратичне + + + + Easing Cubic + Просте кубічне + + + + Mouse Speed Settings + Параметри швидкості мишки + + + + Enable to change the horizontal and vertical speed +boxes at the same time. + Змінювати значення гоизонтальної +та вертикальної швидкості разом. + + + + Change Together + Змінювати разом + + + + Horizontal +Speed: + Горизонтальна +швидкість: + + + + + 1 = 20 pps + 1 = 20 pps + + + + Vertical +Speed: + Вертикальна +швидкість: + + + + Wheel Hori. +Speed: + Коліщатко +горизонт.: + + + + Set the speed used for horizontal mouse wheel movement +according to number of simulated notches per second. + Встановіть швидкість для горизонтальної прокрутки коліщатка +миші відносно від числа симуляції кроків за секунду. + + + + + 1 = 1 notch(es)/s + 1 = 1 крок(ів)/с + + + + Wheel Vert. +Speed: + Коліщатко +вертикаль.: + + + + Set the speed used for vertical mouse wheel movement +according to number of simulated notches per second. + Встановіть швидкість для вертикальної прокрутки коліщатка +миші відносно від числа симуляції кроків за секунду. + + + + Sensitivity: + Чутливість: + + + + For Power Function acceleration curve. Specifies +the factor to use for curve sensitivity. When the value +is above 1.0, the mouse movement will be accelerated +faster at the low end of an axis. + + + + + Easing Duration: + + + + + Options for adding extra acceleration to the mouse +movement beyond what the acceleration curve would +produce. This is meant to help work around some of +the issues of the very limited input range available using +typical gamepad analog sticks. + + + + + + + + % + % + + + + Enhanced: Three tier curve that makes the mouse move +slow on the low end of an axis and fast on the high end. + +Linear: Mouse moves proportionally to axis. + +Quadratic: Mouse accelerates slowly on low end. + +Cubic: Mouse accelerates slower than Quadratic. + +Quadratic Extreme: Raises mouse speed 1.5 times once +95% axis travel has been reached. + +Power Function: Allows for a more custom curve option. + +Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. + +Easing Cubic: Axis high end is gradually accelerated over +a period of time using a Cubic curve. + + + + + Specifies the amount of time (in seconds) that will +be required before the mouse is fully accelerated +after reaching the high end of an axis. + + + + + + s + с + + + + Extra Acceleration + + + + + Multiplier: + + + + + Highest value to accelerate mouse movement by + + + + + x + x + + + + Start %: + + + + + Acceleration begins at this percentage of the base multiplier + + + + + Min +Threshold: + + + + + Minimum amount of axis travel required for acceleration to begin + + + + + Max +Threshold: + + + + + Maximum axis travel before acceleration has reached the multiplier value + + + + + Extra Duration: + + + + + Extend the time that extra acceleration is applied. Axis travel +will be taken into account. A slower flick will decrease the +actual time that extra acceleration will be applied. + + + + + Curve: + + + + + Ease Out Sine + + + + + Ease Out Quad + + + + + Ease Out Cubic + + + + + Spring Settings + Параметри пружини + + + + Spring Width: + Ширина пружини: + + + + Changes the width of the region that the cursor +can move in spring mode. 0 will use the entire width +of your screen. + + + + + Spring Height: + Висота пружини: + + + + Changes the height of the region that the cursor +can move in spring mode. 0 will use the entire height +of your screen. + + + + + Release Radius: + + + + + Specifies that the spring area will be relative to the +mouse position set by a non-relative spring. + + + + + Relative + Відносний + + + + Mouse Status + Стан мишки + + + + X: + X: + + + + + 0 (0 pps) + 0 (0 pps) + + + + Y: + Y: + + + + + %n notch(es)/s + + %n крок/с + %n кроки/с + %n кроків/с + + + + + QKeyDisplayDialog + + + Key Checker + Перевірка клавіш + + + + <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by antimicro.</p><p>The antimicro key value and the Qt key value will usually be the same. antimicro tries to use the key values defined in Qt when possible. Check the page <a href="http://qt-project.org/doc/qt-4.8/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://qt-project.org/doc/qt-4.8/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to antimicro's <a href="https://github.com/Ryochan7/antimicro"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> + + + + + Event Handler: + Обробник подій: + + + + Native Key Value: + Нативне значення клавіші: + + + + + + 0x00000000 + 0x00000000 + + + + Qt Key Value: + Значення клавіші Qt: + + + + antimicro Key Value: + + + + + QObject + + + Daemon launched + Демон завантажений + + + + Failed to launch daemon + Помилка під час завантаження демону + + + + Launching daemon + Запуск демона + + + + + Display string "%1" is not valid. + Виведений рядок «%1» не є вірним. + + + + Failed to set a signature id for the daemon + + + + + Failed to change working directory to / + Не вдалось змінити робочу теку на / + + + + Quitting Program + + + + + # of joysticks found: %1 + # джойстиків знайдено: %1 + + + + List Joysticks: + Перелік джойстиків: + + + + --------------- + --------------- + + + + Joystick %1: + Джойстик %1: + + + + Index: %1 + Індекс: %1 + + + + GUID: %1 + GUID: %1 + + + + Name: %1 + Ім'я: %1 + + + + Yes + Так + + + + No + Ні + + + + Game Controller: %1 + Ігровий контролер: %1 + + + + # of Axes: %1 + # Вісі: %1 + + + + # of Buttons: %1 + # Кнопок: %1 + + + + # of Hats: %1 + # Міні-падів: %1 + + + + Attempting to use fallback option %1 for event generation. + + + + + Failed to open event generator. Exiting. + + + + + Using %1 as the event generator. + + + + + Could not raise process priority. + + + + + Super + Super + + + + Menu + Меню + + + + Mute + Mute + + + + Vol+ + Vol+ + + + + Vol- + Vol- + + + + Play/Pause + Play/Pause + + + + Play + Play + + + + Pause + Pause + + + + Prev + Prev + + + + Next + Next + + + + Mail + Пошта + + + + Home + Home + + + + Media + Media + + + + Search + Пошук + + + + QuickSetDialog + + + Quick Set + Швидкий набір + + + + <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> + <html><head/><body><p>Натисніть кнопку, чи змістіть вісь по %1 (<span style=" font-weight:600;">%2</span>).<br/>З'явиться діалогове вікно<br/>в якому зможете зробити переназначення.</p></body></html> + + + + Quick Set %1 + Швидкий набір %1 + + + + SetAxisThrottleDialog + + + Throttle Change + Зміна тяги + + + + The throttle setting for Axis %1 has been changed. + +Would you like to distribute this throttle change to all sets? + Параметри тяги були змінені для вісі %1. + +Застосувати ці зміни до всіх наборів? + + + + SetJoystick + + + Set %1: %2 + Набір %1: %2 + + + + Set %1 + Набір %1 + + + + SetNamesDialog + + + Set Name Settings + Параметри наборів + + + + Set 1 + Набір 1 + + + + Set 2 + Набір 2 + + + + Set 3 + Набір 3 + + + + Set 4 + Набір 4 + + + + Set 5 + Набір 5 + + + + Set 6 + Набір 6 + + + + Set 7 + Набір 7 + + + + Set 8 + Набір 8 + + + + Name + Ім'я + + + + SimpleKeyGrabberButton + + + Mouse + Мишка + + + + SpringModeRegionPreview + + + Spring Mode Preview + Перегляд пружинного режиму + + + + UInputEventHandler + + + Could not find a valid uinput device file. +Please check that you have the uinput module loaded. +lsmod | grep uinput + Не можливо знайти прийнятний файл пристрою uinput. +Перевірте, чи завантажений модуль uinput. +lsmod | grep uinput + + + + Could not open uinput device file +Please check that you have permission to write to the device + Неможливо відкрити uinput файл пристрою +Перевірте, чи маєте ви права на запис до пристрою + + + + Using uinput device file %1 + + + + + UInputHelper + + + a + a + + + + b + b + + + + c + c + + + + d + d + + + + e + e + + + + f + f + + + + g + g + + + + h + h + + + + i + i + + + + j + j + + + + k + k + + + + l + l + + + + m + m + + + + n + n + + + + o + o + + + + p + p + + + + q + q + + + + r + r + + + + s + s + + + + t + t + + + + u + u + + + + v + v + + + + w + w + + + + x + x + + + + y + y + + + + z + z + + + + Esc + Esc + + + + F1 + F1 + + + + F2 + F2 + + + + F3 + F3 + + + + F4 + F4 + + + + F5 + F5 + + + + F6 + F6 + + + + F7 + F7 + + + + F8 + F8 + + + + F9 + F9 + + + + F10 + F10 + + + + F11 + F11 + + + + F12 + F12 + + + + ` + ` + + + + 1 + 1 + + + + 2 + 2 + + + + 3 + 3 + + + + 4 + 4 + + + + 5 + 5 + + + + 6 + 6 + + + + 7 + 7 + + + + 8 + 8 + + + + 9 + 9 + + + + 0 + 0 + + + + + - + - + + + + = + = + + + + BackSpace + BackSpace + + + + Tab + Tab + + + + [ + [ + + + + ] + ] + + + + \ + \ + + + + CapsLock + CapsLock + + + + ; + ; + + + + ' + ' + + + + Enter + Enter + + + + Shift_L + Shift_Л + + + + , + , + + + + + . + . + + + + + / + / + + + + Ctrl_L + Ctrl_Л + + + + + Super_L + Super_Л + + + + Alt_L + Alt_Л + + + + Space + Пробіл + + + + Alt_R + Alt_П + + + + Menu + Меню + + + + Ctrl_R + Ctrl_П + + + + Shift_R + Shift_П + + + + Up + Вверх + + + + Left + Вліво + + + + Down + Вниз + + + + Right + Вправо + + + + PrtSc + PrtSc + + + + Ins + Ins + + + + Del + Del + + + + Home + Home + + + + End + End + + + + PgUp + PgUp + + + + PgDn + PgDn + + + + NumLock + NumLock + + + + * + * + + + + + + + + + + + KP_Enter + KP_Enter + + + + KP_1 + KP_1 + + + + KP_2 + KP_2 + + + + KP_3 + KP_3 + + + + KP_4 + KP_4 + + + + KP_5 + KP_5 + + + + KP_6 + KP_6 + + + + KP_7 + KP_7 + + + + KP_8 + KP_8 + + + + KP_9 + KP_9 + + + + KP_0 + KP_0 + + + + SCLK + SCLK + + + + Pause + Pause + + + + Super_R + Super_П + + + + Mute + Mute + + + + VolDn + VolDn + + + + VolUp + VolUp + + + + Play + Play + + + + Stop + Stop + + + + Prev + Prev + + + + Next + Next + + + + [NO KEY] + [НЕМАЄ КНОПКИ] + + + + UnixWindowInfoDialog + + + Captured Window Properties + + + + + Information About Window + + + + + Class: + + + + + + + TextLabel + + + + + Title: + + + + + Path: + + + + + Match By Properties + + + + + Class + + + + + Title + + + + + Path + + + + + VDPad + + + + + VDPad + VDPad + + + + VirtualKeyPushButton + + + Space + Пробіл + + + + Tab + Tab + + + + Shift (L) + Shift (Л) + + + + Shift (R) + Shift (П) + + + + Ctrl (L) + Ctrl (Л) + + + + Ctrl (R) + Ctrl (П) + + + + Alt (L) + Alt (Л) + + + + + Alt (R) + Alt (П) + + + + ` + ` + + + + ~ + ~ + + + + + - + - + + + + = + = + + + + [ + [ + + + + ] + ] + + + + \ + \ + + + + Caps + Caps + + + + ; + ; + + + + ' + ' + + + + , + , + + + + + . + . + + + + + / + / + + + + ESC + ESC + + + + PRTSC + PRTSC + + + + SCLK + SCLK + + + + INS + INS + + + + PGUP + PGUP + + + + DEL + DEL + + + + PGDN + PGDN + + + + 1 + 1 + + + + 2 + 2 + + + + 3 + 3 + + + + 4 + 4 + + + + 5 + 5 + + + + 6 + 6 + + + + 7 + 7 + + + + 8 + 8 + + + + 9 + 9 + + + + 0 + 0 + + + + NUM +LK + NUM +LK + + + + + * + * + + + + + + + + + + + E +N +T +E +R + E +N +T +E +R + + + + < + < + + + + : + : + + + + Super (L) + Super (Л) + + + + Menu + Меню + + + + Up + Вверх + + + + Down + Вниз + + + + Left + Вліво + + + + Right + Вправо + + + + VirtualKeyboardMouseWidget + + + + Keyboard + Клавіатура + + + + + Mouse + Мишка + + + + Left + Mouse + Вліво + + + + Up + Mouse + Вверх + + + + Left Button + Mouse + Ліва кнопка + + + + Middle Button + Mouse + Середня кнопка + + + + Right Button + Mouse + Права кнопка + + + + Wheel Up + Mouse + Коліщатко вверх + + + + Wheel Left + Mouse + Коліщатко вліво + + + + Wheel Right + Mouse + Коліщатко вправо + + + + Wheel Down + Mouse + Коліщатко вниз + + + + Down + Mouse + Вниз + + + + Right + Mouse + Вправо + + + + Button 4 + Mouse + Кнопка 4 + + + + Mouse 8 + Mouse + Мишка 8 + + + + Button 5 + Mouse + Кнопка 5 + + + + Mouse 9 + Mouse + Мишка 9 + + + + Mouse Settings + Параметри мишки + + + + NONE + Відсутній + + + + Applications + + + + + Browser Back + + + + + Browser Favorites + + + + + Browser Forward + + + + + Browser Home + + + + + Browser Refresh + + + + + Browser Search + + + + + Browser Stop + + + + + Calc + + + + + Email + + + + + Media + Media + + + + Media Next + + + + + Media Play + + + + + Media Previous + + + + + Media Stop + + + + + Search + Пошук + + + + Volume Down + + + + + Volume Mute + + + + + Volume Up + + + + + VirtualMousePushButton + + + INVALID + ХИБНИЙ + + + + WinAppProfileTimerDialog + + + + Capture Application + Захопити програму + + + + After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. + Після натискання «Захопити програму», зробіть активним вікно програм, яку ви хочете прив'язати до поточного профілю. Активне вікно буде захоплено через вказаний проміжок часу. + + + + Timer: + Таймер: + + + + Seconds + Секунд + + + + Cancel + Скасувати + + + + WinExtras + + + [NO KEY] + [НЕМАЄ КНОПКИ] + + + + AntiMicro Profile + AntiMicro профіль + + + + X11Extras + + + ESC + ESC + + + + Tab + Tab + + + + Space + Пробіл + + + + DEL + DEL + + + + Return + Return + + + + KP_Enter + KP_Enter + + + + Backspace + Backspace + + + + xinput extension was not found. No mouse acceleration changes will occur. + Розширення xinput не знайдено. Зміна швидкості миші не використовується. + + + + + xinput version must be at least 2.0. No mouse acceleration changes will occur. + Версія xinput має бути вище 2.0. Зміна швидкості миші не використовується. + + + + Virtual pointer found with id=%1. + Віртуальний вказівник знайдено із id=%1. + + + + PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 + Не знайдено PtrFeedbackClass для віртуального вказівника. Зміна швидкості миші не використовується для пристрою із id=%1 + + + + Changing mouse acceleration for device with id=%1 + Зміна прискорення мишки для пристрою із id=%1 + + + + XMLConfigReader + + + Could not write updated profile XML to file %1. + Неможливо записати оновлений профіль до файлу %1. + + + + XMLConfigWriter + + + Could not write to profile at %1. + Неможливо записати профіль як %1. + + + diff --git a/share/antimicro/translations/antimicro_zh_CN.ts b/share/antimicro/translations/antimicro_zh_CN.ts new file mode 100644 index 0000000..afdb6b9 --- /dev/null +++ b/share/antimicro/translations/antimicro_zh_CN.ts @@ -0,0 +1,6078 @@ + + + + + AboutDialog + + + About + 关于 + + + + antimicro + antimicro + + + + Version + 版本 + + + + Info + 信息 + + + + Changelog + 更新日志 + + + + Since December 30, 2012, I have been working on antimicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. + +The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. + +Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. + +Once the Steam controller is finally released to the public, the need for this program might not exist anymore. Just based on the concept of the controller alone, the Steam controller would have so many advantages over using a program like this to provide KB+M emulation. + 自2012年12月30日以来,我利用业余时间编写 antimicro。这个项目本来是 QJoyPad 的派生,用来学习事件驱动编程,没想到规模变得如此之大。尽管我花了很多时间去学习新的技巧、探索键鼠模拟的领域、每周五晚上用头撞键盘,我仍然觉得这是一段有趣并且充实的经历。 + +对这个程序的需求来源于我想在 Windows 上使用类似的程序玩一些原生不支持手柄的游戏。虽然 Linux 上有其它替代品,但是我并没有找到在功能上或者游戏内控制足够好,以至于我可以使用键鼠模拟来享受游戏的工具。QJoyPad 是我过去主要使用的工具,尽管它非常古老而且不提供一些我认为非常关键的功能。那个项目已经停止开发很多年,所以我决定编写一个我自己的工具。 + +从那时起,我不断寻找其它程序的长处,然后在它们的基础上继续开发。在此期间,我还发现了一些不错的小技巧,并且学到了很多关于游戏如何实现原生支持手柄的知识。这些知识远远广于我之前想学的范围。尽管 antimicro 还有很多可以改进的地方,我还是认为它提供了最好的游戏内控制体验,不管是针对老一些还是新一些的原生不支持手柄的游戏。 + +等到 Steam 手柄向公众发布的时候,对这个程序的需求可能就消失了。相对于使用这个程序进行键鼠模拟而言,Steam 手柄单单在概念上就有如此之多的优势。 + + + + Copyright: 2013 - 2015 + 版权:2013 - 2015 + + + + Credits + 致谢 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Travis Nickles &lt;nickles.travis@gmail.com&gt;</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Contributors:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;"><br /></span>Zerro Alvein</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">aybe</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Jeff Backus &lt;jeff.backus@gmail.com&gt;</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Arthur Moore<br />Anton Tornqvist &lt;antont@inbox.lv&gt;</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Translators:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt; font-weight:600;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">zzpxyx - Chinese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">phob - German</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tou omiya - Japanese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">burunduk - Ukrainian</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Travis Nickles &lt;nickles.travis@gmail.com&gt;</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">贡献者:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;"><br /></span>Zerro Alvein</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">aybe</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Jeff Backus &lt;jeff.backus@gmail.com&gt;</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Arthur Moore<br />Anton Tornqvist &lt;antont@inbox.lv&gt;</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">翻译:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt; font-weight:600;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - 巴西葡萄牙语</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">zzpxyx - 简体中文</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Belleguic Terence &lt;hizo@free.fr&gt; - 法语</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - 德语</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">phob - 德语</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tou omiya - 日语</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - 俄语</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - 塞尔维亚语</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">burunduk - 乌克兰语</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Version 3, 29 June 2007</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Preamble</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">TERMS AND CONDITIONS</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">0. Definitions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">1. Source Code.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">2. Basic Permissions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">4. Conveying Verbatim Copies.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">5. Conveying Modified Source Versions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">6. Conveying Non-Source Forms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">7. Additional Terms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">8. Termination.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">11. Patents.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">14. Revised Versions of this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">15. Disclaimer of Warranty.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">16. Limitation of Liability.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Version 3, 29 June 2007</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Preamble</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">TERMS AND CONDITIONS</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">0. Definitions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">1. Source Code.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">2. Basic Permissions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">4. Conveying Verbatim Copies.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">5. Conveying Modified Source Versions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">6. Conveying Non-Source Forms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">7. Additional Terms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">8. Termination.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">11. Patents.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">14. Revised Versions of this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">15. Disclaimer of Warranty.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">16. Limitation of Liability.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> + + + + About Development + 关于开发 + + + + License + 许可 + + + + Program Version %1 + 程序版本 %1 + + + + Program Compiled on %1 at %2 + 编译时间 %1 %2 + + + + Built Against SDL %1 + 使用 SDL %1 构建 + + + + Running With SDL %1 + 使用 SDL %1 运行 + + + + Using Qt %1 + 使用 Qt %1 + + + + Using Event Handler: %1 + 使用事件处理程序:%1 + + + + AddEditAutoProfileDialog + + + Auto Profile Dialog + 自动配置文件对话框 + + + + Profile: + 配置文件: + + + + + Browse + 浏览 + + + + Window: + 窗口: + + + + + Select Window. Click on the appropriate application +window and the application file path will be populated +in the form. + 选择窗口。 +单击应用程序的窗口,程序文件路径将被自动填入表格。 + + + + Detect Window Properties + 检测窗口属性 + + + + Class: + 类: + + + + Title: + 标题: + + + + Application: + 应用程序: + + + + Select + 选择 + + + + Devices: + 设备: + + + + + Select this profile to be the default loaded for +the specified device. The selection will be used instead +of the all default profile option. + 将这个配置文件设定为上述设备的默认配置文件。 +这个配置文件将取代全局默认配置文件选项。 + + + + Set as Default for Controller + 设为上述设备的默认配置文件 + + + + + A different profile is already selected as the default for this device. + 这个设备已被指定了另一个不同的默认配置文件。 + + + + Current (%1) + 当前 (%1) + + + + Open Config + 打开配置文件 + + + + + Select Program + 选择程序 + + + + Programs (*.exe) + 程序 (*.exe) + + + + Please use the main default profile selection. + 请使用全局默认配置文件选项。 + + + + Please select a window by using the mouse. Press Escape if you want to cancel. + 请使用鼠标选择窗口。按 Esc 键取消。 + + + + Capture Application Window + 捕捉应用程序窗口 + + + + Could not obtain information for the selected window. + 无法获得所选窗口的信息。 + + + + Application Capture Failed + 应用程序捕捉失败 + + + + Profile file path is invalid. + 配置文件路径无效。 + + + + No window matching property was specified. + 未指定窗口匹配属性。 + + + + Program path is invalid or not executable. + 程序路径无效或非可执行文件。 + + + + File is not an .exe file. + 文件不是 .exe 文件。 + + + + No window matching property was selected. + 未选择窗口匹配属性。 + + + + AdvanceButtonDialog + + + + Advanced + 高级选项 + + + + Assignments + 分配 + + + + Toggle + 开关 + + + + Turbo + 连发 + + + + Set Selector + 设置选择器 + + + + Blank or KB/M + 空白或键鼠 + + + + Hold + 按下 + + + + Pause + 暂停 + + + + Cycle + 周期 + + + + Distance + 距离 + + + + Insert + 插入 + + + + Delete + 删除 + + + + Clear All + 清除所有 + + + + Time: + 时间: + + + + 0.01s + 0.01秒 + + + + 0s + 0秒 + + + + Insert a pause that occurs in between key presses. + 在按键间插入暂停。 + + + + Release + 释放 + + + + + Insert a new blank slot. + 插入新动作。 + + + + Delete a slot. + 删除所选动作。 + + + + Clear all currently assigned slots. + 清除所有动作。 + + + + Specify the duration of an inserted Pause or Hold slot. + 为“暂停”或“按下”动作指定所需时长。 + + + + 0m + 0分 + + + + &Mouse Speed Mod: + 鼠标速度更改 (&M): + + + + + Specify the range past an axis dead zone in which a sequence of actions will execute. + 为“距离”动作指定所需的超过不灵敏区的距离。 + + + + Distance: + 距离: + + + + + % + % + + + + Mouse Mod + 鼠标变速 + + + + Press Time + 按下时间 + + + + Delay + 延迟 + + + + Execute + 运行 + + + + Load + 载入 + + + + Set Change + 设置改变 + + + + Text Entry + 文本键入 + + + + Placeholder + 占位符 + + + + + 0 + 0 + + + + Set the percentage that mouse speeds will be modified by. + 设置鼠标移动速度百分比。 + + + + Auto Reset Cycle After + 在此时间之后取消未完成的“周期”动作 + + + + seconds + + + + + Executable: + 可执行文件: + + + + ... + ... + + + + Arguments: + 参数: + + + + + + Enabled + 启用 + + + + Mode: + 模式: + + + + <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> + <html><head/><body><p>正常:以所选频率重复按下并释放按键。</p><p>梯度:根据轴移动幅度调整按钮被按下和释放的延迟。频率保持不变。</p><p>脉冲:调整每秒按钮被按下和释放的次数。按钮延迟保持不变。</p></body></html> + + + + Normal + 正常 + + + + Gradient + 梯度 + + + + Pulse + 脉冲 + + + + Delay: + 延迟: + + + + 0.10s + 0.10秒 + + + + Rate: + 频率: + + + + 10.0/s + 10.0/秒 + + + + + Disabled + 禁用 + + + + Select Set 1 One Way + 单向选择设置1 + + + + Select Set 1 Two Way + 双向选择设置1 + + + + Select Set 1 While Held + 按下时选择设置1 + + + + Select Set 2 One Way + 单向选择设置2 + + + + Select Set 2 Two Way + 双向选择设置2 + + + + Select Set 2 While Held + 按下时选择设置2 + + + + Select Set 3 One Way + 单向选择设置3 + + + + Select Set 3 Two Way + 双向选择设置3 + + + + Select Set 3 While Held + 按下时选择设置3 + + + + Select Set 4 One Way + 单向选择设置4 + + + + Select Set 4 Two Way + 双向选择设置4 + + + + Select Set 4 While Held + 按下时选择设置4 + + + + Select Set 5 One Way + 单向选择设置5 + + + + Select Set 5 Two Way + 双向选择设置5 + + + + Select Set 5 While Held + 按下时选择设置5 + + + + Select Set 6 One Way + 单向选择设置6 + + + + Select Set 6 Two Way + 双向选择设置6 + + + + Select Set 6 While Held + 按下时选择设置6 + + + + Select Set 7 One Way + 单向选择设置7 + + + + Select Set 7 Two Way + 双向选择设置7 + + + + Select Set 7 While Held + 按下时选择设置7 + + + + Select Set 8 One Way + 单向选择设置8 + + + + Select Set 8 Two Way + 双向选择设置8 + + + + Select Set 8 While Held + 按下时选择设置8 + + + + sec. + 秒。 + + + + /sec. + /秒。 + + + + Set %1 + 设置%1 + + + + + Select Set %1 + 选择设置%1 + + + + One Way + 单向 + + + + Two Way + 双向 + + + + While Held + 按下时 + + + + Choose Executable + 选择可执行文件 + + + + Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. + “周期”动作之后的动作将在下一次按下相同按钮的时候被执行。可以添加多个“周期”动作来创建一个按键序列中不同的子序列。 + + + + Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. + 根据指定时长延迟下个动作开始执行的时间。延迟之前处于活动状态的动作将在延迟结束后保持活动状态。 + + + + Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. + “距离”动作之后的动作只有在轴移出不灵敏区并超过指定距离之后才会被执行。 + + + + Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. + 插入一个“按下”动作。“按下”动作之后的动作只有在按钮被按下超过指定的时长之后才会被执行。 + + + + Chose a profile to load when this slot is activated. + 当该动作被执行时,载入所选配置文件。 + + + + Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. + “鼠标变速”动作被处理时,将根据指定的百分比改变所有鼠标速度。这可以用在狙击时减缓鼠标速度。 + + + + Specify the time that keys past this slot should be held down. + 按钮被按下超过指定的时长将保持被按下的状态。 + + + + Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. + 插入一个“释放”动作。“释放”动作之后的动作只有在按钮被按下超过指定时长并被释放之后才会被执行。 + + + + Change to selected set once slot is activated. + 该动作被执行时,切换到所选的设置。 + + + + Full string will be typed when a slot is activated. + 当该动作被执行时,整个字符串将被键入。 + + + + Execute program when slot is activated. + 当该动作被执行时,运行一个程序。 + + + + + Choose Profile + 选择配置文件 + + + + Config Files (*.amgp *.xml) + 配置文件 (*.amgp *.xml) + + + + AdvanceStickAssignmentDialog + + + Stick/Pad Assignment + 摇杆/十字键分配 + + + + Sticks + 摇杆 + + + + DPads + 十字键 + + + + + %1 (Joystick %2) + %1(手柄%2) + + + + Stick 1 + 手柄1 + + + + + + Enabled + 启用 + + + + + + + + + Assign + 分配 + + + + + X Axis: + X轴: + + + + + Y Axis: + Y轴: + + + + Stick 2 + 手柄2 + + + + Number of Physical DPads: %1 + 物理十字键数:%1 + + + + Virtual DPad 1 + 虚拟十字键1 + + + + Up: + 上: + + + + Down: + 下: + + + + Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. + 注意:这个窗口是为了兼容 antimicro 2.0 版之前创建的配置文件。自 antimicro 2.0 起,推荐使用游戏控制器映射窗口。 + + + + Left: + 左: + + + + Right: + 右: + + + + + + + Axis %1 + 轴%1 + + + + + + + Axis %1 - + 轴%1 - + + + + + + + Axis %1 + + 轴%1 + + + + + + + + Button %1 + 按钮%1 + + + + Move stick 1 along the X axis + 沿X轴移动摇杆1 + + + + Move stick 1 along the Y axis + 沿Y轴移动摇杆1 + + + + Move stick 2 along the X axis + 沿X轴移动摇杆2 + + + + Move stick 2 along the Y axis + 沿Y轴移动摇杆2 + + + + + + + Press a button or move an axis + 按任意键或移动任意轴 + + + + AxisEditDialog + + + Axis + + + + + + Mouse (Horizontal) + 鼠标(水平) + + + + + Mouse (Inverted Horizontal) + 鼠标(水平翻转) + + + + + Mouse (Vertical) + 鼠标(垂直) + + + + + Mouse (Inverted Vertical) + 鼠标(垂直翻转) + + + + + Arrows: Up | Down + 方向键:上|下 + + + + + Arrows: Left | Right + 方向键:左|右 + + + + + Keys: W | S + 按键:W | S + + + + + Keys: A | D + 按键:A | D + + + + + NumPad: KP_8 | KP_2 + 数字键盘:8 | 2 + + + + + NumPad: KP_4 | KP_6 + 数字键盘:4 | 6 + + + + + + None + + + + + + Set the value to use as the limit for an axis. Useful for a +worn out analog stick. + 设置轴的最大值。 +对老旧磨损的模拟摇杆尤其有帮助。 + + + + Negative Half Throttle + 负半阀 + + + + Positive Half Throttle + 正半阀 + + + + Name: + 名称: + + + + Specify the name of an axis. + 指定轴的名称。 + + + + Mouse Settings + 鼠标设置 + + + + + Set the value of the dead zone for an axis. + 设置轴的不灵敏区。 + + + + Presets: + 预设: + + + + Dead Zone: + 不灵敏区: + + + + Max Zone: + 最大区: + + + + + [NO KEY] + [无按键] + + + + Throttle setting that determines the behavior of how to +interpret an axis hold or release. + 阀设置决定如何判断一个轴的按下和释放。 + + + + Negative Throttle + 负阀 + + + + Normal + 正常 + + + + Positive Throttle + 正阀 + + + + Current Value: + 当前值: + + + + Set + 设置 + + + + Set %1 + 设置%1 + + + + Left Mouse Button + 鼠标左键 + + + + Right Mouse Button + 鼠标右键 + + + + ButtonEditDialog + + + Dialog + 对话框 + + + + To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab + 若想分配按键,请按键盘上任意键或在键盘、鼠标页上点击按钮 + + + + Placeholder + 占位符 + + + + Toggle + 开关 + + + + Enables a key press or release to only occur when a controller button is pressed. + 当游戏控制器按钮被按下时,按下或释放某个按键,并一直保持此状态。 + + + + Enables rapid key presses and releases. Turbo controller. + 快速按下和释放某个键。 +连发游戏控制器。 + + + + Turbo + 连发 + + + + Current: + 当前: + + + + Slots + 动作 + + + + Na&me: + 名称 (&m): + + + + Specify the name of a button. + 指定按钮的名称。 + + + + Action: + 动作: + + + + Specify the action that will be performed in game while +this button is being used. + 指定游戏中这个按钮被按下时的动作。 + + + + Advanced + 高级选项 + + + + Set + 设置 + + + + Set %1 + 设置%1 + + + + CapturedWindowInfoDialog + + + Captured Window Properties + 捕获的窗口属性 + + + + Information About Window + 窗口信息 + + + + Class: + 类: + + + + + + TextLabel + 文本标签 + + + + Title: + 标题: + + + + Path: + 路径: + + + + Match By Properties + 根据属性匹配 + + + + Class + + + + + Title + 标题 + + + + Path + 路径 + + + + Full Path + 全路径 + + + + File Name + 文件名 + + + + CommandLineUtility + + + + Profile location %1 is not an XML file. + 配置文件 %1 不是一个 XML 文件。 + + + + + Profile location %1 does not exist. + 配置文件 %1 不存在。 + + + + An invalid set number '%1' was specified. + 指定的设置编号 "%1" 无效。 + + + + Controller identifier '%s'' is not a valid value. + 游戏控制器标识符 "%s" 无效。 + + + + No display string was specified. + 未指定显示字符串。 + + + + + + Controller identifier is not a valid value. + 游戏控制器标识符无效。 + + + + No set number was specified. + 未指定设置编号。 + + + + No controller was specified. + 未指定游戏控制器。 + + + + An invalid event generator was specified. + 指定的事件发生器无效。 + + + + No event generator string was specified. + 未指定事件发生器字符串。 + + + + Qt style flag was detected but no style was specified. + 检测到 Qt 样式标识,但未指定样式。 + + + + No log level specified. + 未指定日志级别。 + + + + + + + antimicro version + antimicro 版本 + + + + + Usage: antimicro [options...] [profile] + 用法:antimicro [选项] [配置文件] + + + + + Options + 选项 + + + + + Print help text. + 打印帮助文本。 + + + + + Print version information. + 打印版本信息。 + + + + + Launch program in system tray only. + 启动后最小化到系统托盘。 + + + + + Launch program with the tray menu disabled. + 启动后禁用系统托盘菜单。 + + + + + Launch program without the main window + displayed. + 启动后不显示主窗口。 + + + + + Launch program with the configuration file + selected as the default for selected + controllers. Defaults to all controllers. + 启动后将指定的配置文件作为默认配置文件。默认应用到所有游戏控制器。 + + + + + Apply configuration file to a specific + controller. Value can be a + controller index, name, or GUID. + 应用配置文件到指定的游戏控制器。值可以是编号、名称或全局唯一标识符。 + + + + + Unload currently enabled profile(s). + Value can be a controller index, name, or GUID. + 卸载当前生效的配置文件。值可以是控制器编号、名称或全局唯一标识符。 + + + + + Start joysticks on a specific set. + Value can be a controller index, name, or GUID. + 为摇杆指定设置编号。值可以是控制器编号、名称或全局唯一标识符。 + + + + + Advance profile loading set options. + 切换到下一个配置文件载入选项。 + + + + + Launch program as a daemon. + 以后台服务方式启动程序。 + + + + + Enable logging. + 开启日志。 + + + + + Use specified display for X11 calls. + Useful for ssh. + 为 X11 调用指定显示设备。对 ssh 尤其有用。 + + + + + Choose between using XTest support and uinput + support for event generation. Default: xtest. + 为事件发生器选择 XTest 支持或 uinput 支持。默认:XTest。 + + + + + Choose between using SendInput and vmulti + support for event generation. Default: sendinput. + 为事件发生器选择使用 SendInput 或 vmulti 支持。默认:SendInput。 + + + + + Print information about joysticks detected by + SDL. + 打印 SDL 检测到的摇杆。 + + + + + Open game controller mapping window of selected + controller. Value can be a controller index or + GUID. + 为所选的游戏控制器打开游戏控制器映射窗口。值可以是控制器编号或全局唯一标识符。 + + + + DPadContextMenu + + + Mouse (Normal) + 鼠标(正常) + + + + Mouse (Inverted Horizontal) + 鼠标(水平翻转) + + + + Mouse (Inverted Vertical) + 鼠标(垂直翻转) + + + + Mouse (Inverted Horizontal + Vertical) + 鼠标(水平翻转 + 垂直翻转) + + + + Arrows + 方向键 + + + + Keys: W | A | S | D + 按键:W | A | S | D + + + + NumPad + 数字键盘 + + + + None + + + + + Standard + 标准 + + + + Eight Way + 八向 + + + + 4 Way Cardinal + 正四向 + + + + 4 Way Diagonal + 斜四向 + + + + Mouse Settings + 鼠标设置 + + + + DPadEditDialog + + + Dialog + 对话框 + + + + Presets: + 预设: + + + + Mouse (Normal) + 鼠标(正常) + + + + Mouse (Inverted Horizontal) + 鼠标(水平翻转) + + + + Mouse (Inverted Vertical) + 鼠标(垂直翻转) + + + + Mouse (Inverted Horizontal + Vertical) + 鼠标(水平翻转 + 垂直翻转) + + + + Arrows + 方向键 + + + + Keys: W | A | S | D + 按键:W | A | S | D + + + + NumPad + 数字键盘 + + + + None + + + + + Dpad Mode: + 十字键模式: + + + + &Name: + 名称 (&N): + + + + 4 Way Cardinal + 正四向 + + + + 4 Way Diagonal + 斜四向 + + + + DPad Delay: + 十字键延迟: + + + + + Time lapsed before a direction change is taken into effect. + 方向改变生效前的延迟。 + + + + s + + + + + Specify the name of a dpad. + 指定十字键的名称。 + + + + Mouse Settings + 鼠标设置 + + + + Standard + 标准 + + + + Standard: 8 region dpad with two direction buttons active +when the dpad is in a diagonal region. + +Eight Way: 8 region dpad with each direction having its +own dedicated button. Only one button is ever active at +at time. Useful for rougelike games. + +4 Way Cardinal: 4 region dpad with regions corresponding to +the cardinal directions of the dpad. Useful for menus. + +4 Way Diagonal: 4 region dpad with each region corresponding +to a diagonal zone. + 标准:十字键有八个区域。当十字键处于对角线区域时,两个方向的按键同时被激活。 +八向:十字键有八个区域。每个区域有自己的方向按键。同一时间仅有一个方向按键被激活。尤其适用于类 Rouge 游戏。 +正四向:十字键有四个区域,分别对应上下左右四个方向。尤其适用于菜单选择。 +斜四向:十字键有四个区域,分别对应对角线的四个方向。 + + + + Eight Way + 八向 + + + + Set + 设置 + + + + Set %1 + 设置%1 + + + + EditAllDefaultAutoProfileDialog + + + Default Profile + 默认配置文件 + + + + Profile: + 配置文件: + + + + Browse + 浏览 + + + + Open Config + 打开配置文件 + + + + Profile file path is invalid. + 配置文件路径无效。 + + + + ExtraProfileSettingsDialog + + + Extra Profile Settings + 附加配置文件设置 + + + + Key Press Time: + 按键按下时间: + + + + 0.00 ms + 0.00毫秒 + + + + Profile Name: + 配置文件名称: + + + + + + s + + + + + GameController + + + Game Controller + 游戏控制器 + + + + GameControllerDPad + + + + + DPad + 十字键 + + + + GameControllerMappingDialog + + + Game Controller Mapping + 游戏控制器映射 + + + + <html><head/><body><p>antimicro makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicro will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> + <html><head/><body><p>antimicro 使用 SDL 2 的<a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">游戏控制器应用程序接口</span></a>把各式各样的手柄进行抽象,使它们适用于统一的标准。若要进行按钮分配,请选择下面相应的按钮映射单元格。之后您可以按一个按钮或者移动手柄上的一个轴,映射单元格将更新以匹配这个物理按键或轴。</p><p>antimicro 将把您指定的映射保存为一个字符串,而这个字符串将被加载到 SDL 中。</p></body></html> + + + + A + A键 + + + + B + B键 + + + + X + X键 + + + + Y + Y键 + + + + Back + 后退键 + + + + Start + 开始键 + + + + Guide + 导航键 + + + + Left Shoulder + 左肩键 + + + + Right Shoulder + 右肩键 + + + + Left Stick Click + 左摇杆点击 + + + + Right Stick Click + 右摇杆点击 + + + + Left Stick X + 左摇杆X轴 + + + + Left Stick Y + 左摇杆Y轴 + + + + Right Stick X + 右摇杆X轴 + + + + Right Stick Y + 右摇杆Y轴 + + + + Left Trigger + 左扳机 + + + + Right Trigger + 右扳机 + + + + DPad Up + 十字键上 + + + + DPad Left + 十字键左 + + + + DPad Down + 十字键下 + + + + DPad Right + 十字键右 + + + + Mapping + 映射 + + + + SDL 2 Game Controller Mapping String + SDL 游戏控制器映射字符串 + + + + Last Axis Event: + 最近轴事件: + + + + Current Axis Detection Dead Zone: + 当前轴不灵敏区: + + + + 5000 + 5000 + + + + 10000 + 10000 + + + + 15000 + 15000 + + + + 20000 + 20000 + + + + 25000 + 25000 + + + + 30000 + 30000 + + + + 32000 + 32000 + + + + Game Controller Mapping (%1) (#%2) + 游戏控制器映射 (%1) (#%2) + + + + Discard Controller Mapping? + 放弃修改游戏控制器映射? + + + + Discard mapping for this controller? + +If discarded, the controller will be reverted to a joystick once you refresh all joysticks. + 放弃修改这个游戏控制器的映射? + +如果放弃,这个游戏控制器将在您刷新所有摇杆时被重新识别为一个摇杆。 + + + + GameControllerSet + + + Back + 后退键 + + + + Guide + 导航键 + + + + Start + 开始键 + + + + LS Click + 左摇杆点击 + + + + RS Click + 右摇杆点击 + + + + L Shoulder + 左肩键 + + + + R Shoulder + 右肩键 + + + + L Trigger + 左扳机 + + + + R Trigger + 右扳机 + + + + GameControllerTrigger + + + + + Trigger + 扳机 + + + + JoyAxis + + + + + Axis + + + + + JoyAxisButton + + + Negative + + + + + Positive + + + + + Unknown + 未知 + + + + + + Button + 按钮 + + + + JoyAxisContextMenu + + + Mouse (Horizontal) + 鼠标(水平) + + + + Mouse (Inverted Horizontal) + 鼠标(水平翻转) + + + + Mouse (Vertical) + 鼠标(垂直) + + + + Mouse (Inverted Vertical) + 鼠标(垂直翻转) + + + + Arrows: Up | Down + 方向键:上|下 + + + + Arrows: Left | Right + 方向键:左|右 + + + + Keys: W | S + 按键:W | S + + + + Keys: A | D + 按键:A | D + + + + NumPad: KP_8 | KP_2 + 数字键盘:8 | 2 + + + + NumPad: KP_4 | KP_6 + 数字键盘:4 | 6 + + + + + None + + + + + + Mouse Settings + 鼠标设置 + + + + Left Mouse Button + 鼠标左键 + + + + Right Mouse Button + 鼠标右键 + + + + JoyButton + + + Processing turbo for #%1 - %2 + 正在处理按钮#%1-%2的连发 + + + + Finishing turbo for button #%1 - %2 + 正在完成按钮#%1-%2的连发 + + + + Processing press for button #%1 - %2 + 正在处理按下按钮#%1-%2 + + + + Processing release for button #%1 - %2 + 正在处理释放按钮#%1-%2 + + + + Distance change for button #%1 - %2 + 按钮#%1-%2距离改变 + + + + + + Button + 按钮 + + + + + + + [NO KEY] + [无按键] + + + + [Set %1 1W] + [单向选择设置%1] + + + + [Set %1 2W] + [双向选择设置%1] + + + + [Set %1 WH] + [按下时选择设置%1] + + + + JoyButtonContextMenu + + + Toggle + 开关 + + + + Turbo + 连发 + + + + Clear + 清除 + + + + Set Select + 选择设置 + + + + Disabled + 禁用 + + + + Set %1 + 设置%1 + + + + Set %1 1W + 单向选择设置%1 + + + + Set %1 2W + 双向选择设置%1 + + + + Set %1 WH + 按下时选择设置%1 + + + + JoyButtonSlot + + + + Mouse + 鼠标 + + + + Up + + + + + Down + + + + + Left + + + + + Right + + + + + LB + 鼠标左键 + + + + MB + 鼠标中键 + + + + RB + 鼠标右键 + + + + B4 + 按钮4 + + + + B5 + 按钮5 + + + + Pause + 暂停 + + + + Hold + 按下 + + + + Cycle + 周期 + + + + Distance + 距离 + + + + Release + 释放 + + + + Mouse Mod + 鼠标变速 + + + + Press Time + 按下时间 + + + + Delay + 延迟 + + + + Load %1 + 载入%1 + + + + Set Change %1 + 设置改变%1 + + + + [Text] %1 + [文本]%1 + + + + [Exec] %1 + [运行]%1 + + + + [NO KEY] + [无按键] + + + + JoyControlStick + + + + + Stick + 摇杆 + + + + JoyControlStickButton + + + + + Up + + + + + + + Down + + + + + + + Left + + + + + + + Right + + + + + + + Button + 按钮 + + + + JoyControlStickContextMenu + + + Mouse (Normal) + 鼠标(正常) + + + + Mouse (Inverted Horizontal) + 鼠标(水平翻转) + + + + Mouse (Inverted Vertical) + 鼠标(垂直翻转) + + + + Mouse (Inverted Horizontal + Vertical) + 鼠标(水平翻转 + 垂直翻转) + + + + Arrows + 方向键 + + + + Keys: W | A | S | D + 按键:W | A | S | D + + + + NumPad + 数字键盘 + + + + None + + + + + Standard + 标准 + + + + Eight Way + 八向 + + + + 4 Way Cardinal + 正四向 + + + + 4 Way Diagonal + 斜四向 + + + + Mouse Settings + 鼠标设置 + + + + JoyControlStickEditDialog + + + Dialog + 对话框 + + + + X: + X轴: + + + + + + + + 0 + 0 + + + + Y: + Y轴: + + + + Distance: + 距离: + + + + Presets: + 预设: + + + + Mouse (Normal) + 鼠标(正常) + + + + Mouse (Inverted Horizontal) + 鼠标(水平翻转) + + + + Mouse (Inverted Vertical) + 鼠标(垂直翻转) + + + + Mouse (Inverted Horizontal + Vertical) + 鼠标(水平翻转 + 垂直翻转) + + + + Arrows + 方向键 + + + + Keys: W | A | S | D + 按键:W | A | S | D + + + + NumPad + 数字键盘 + + + + None + + + + + Stick Mode: + 摇杆模式: + + + + Standard: 8 region stick with two direction buttons active +when the stick is in a diagonal region. + +Eight Way: 8 region stick with each direction having its +own dedicated button. Only one button is ever active at +at time. Useful for rougelike games. + +4 Way Cardinal: 4 region stick with regions corresponding to +the cardinal directions of the stick. Useful for menus. + +4 Way Diagonal: 4 region stick with each region corresponding +to a diagonal zone of the stick. + 标准:摇杆有八个区域。当摇杆处于对角线区域时,两个方向的按键同时被激活。 +八向:摇杆有八个区域。每个区域有自己的方向按键。同一时间仅有一个方向按键被激活。尤其适用于类 Rouge 游戏。 +正四向:摇杆有四个区域,分别对应上下左右四个方向。尤其适用于菜单选择。 +斜四向:摇杆有四个区域,分别对应对角线的四个方向。 + + + + 4 Way Cardinal + 正四向 + + + + 4 Way Diagonal + 斜四向 + + + + + Dead zone value to use for an analog stick. + 设置模拟摇杆的不灵敏区。 + + + + + Value when an analog stick is considered moved 100%. + 设置模拟摇杆的最大值。当达到这个值时,模拟摇杆被认为移动到了100%的位置。 + + + + + The area (in degrees) that each diagonal region occupies. + 每个对角线区域的角度数。 + + + + Square Stick: + 方形摇杆: + + + + + Percentage to modify a square stick coordinates to confine values to a circle + 这个百分比用来调整方形摇杆的坐标值使其被限制在一个圆里 + + + + % + % + + + + Stick Delay: + 摇杆延迟: + + + + + Time lapsed before a direction change is taken into effect. + 方向改变生效前的延迟。 + + + + s + + + + + Modifier: + 修饰键: + + + + Edit button that is active while the stick is active. + +This button is useful for assigning zones with +modifier keys that can be used to assign walk/run +functionality to an analog stick. + 编辑当摇杆被激活时同时激活的按钮。 +这个按钮尤其适用于分配带有修饰键的区域,例如在模拟摇杆上分配行走/跑步的功能。 + + + + PushButton + 按钮 + + + + Name: + 名称: + + + + Specify the name of an analog stick. + 指定模拟摇杆的名称。 + + + + Mouse Settings + 鼠标设置 + + + + Standard + 标准 + + + + Bearing: + 方向: + + + + % Safe Zone: + 安全区(%): + + + + Eight Way + 八向 + + + + Dead Zone: + 不灵敏区: + + + + Max Zone: + 最大区: + + + + Diagonal Range: + 对角线区域范围: + + + + Set + 设置 + + + + Set %1 + 设置%1 + + + + JoyControlStickModifierButton + + + + + Modifier + 修饰 + + + + JoyDPad + + + + + DPad + 十字键 + + + + JoyDPadButton + + + + + Up + + + + + + + Down + + + + + + + Left + + + + + + + Right + + + + + + + Button + 按钮 + + + + JoyTabWidget + + + + + + + + <New> + <新> + + + + + Remove + 移除 + + + + + Remove configuration from recent list. + 从最近使用列表中移除配置。 + + + + + Load + 载入 + + + + + Load configuration file. + 载入配置文件。 + + + + + Save + 保存 + + + + + Save changes to configuration file. + 保存更改到配置文件。 + + + + + Save As + 另存为 + + + + + Save changes to a new configuration file. + 保存更改到新的配置文件。 + + + + + Sets + 设置 + + + + Copy from Set + 从设置复制 + + + + Settings + 设置 + + + + + Set 1 + 设置1 + + + + + Set 2 + 设置2 + + + + + Set 3 + 设置3 + + + + + Set 4 + 设置4 + + + + + Set 5 + 设置5 + + + + + Set 6 + 设置6 + + + + + Set 7 + 设置7 + + + + + Set 8 + 设置8 + + + + + Stick/Pad Assign + 摇杆/十字键分配 + + + + + Controller Mapping + 游戏控制器映射 + + + + + Quick Set + 快速设置 + + + + + Names + 名称 + + + + + Toggle button name displaying. + 开关按钮名称显示。 + + + + + Pref + 偏好设置 + + + + + Change global profile settings. + 改变全局配置文件设置。 + + + + + + Reset + 重置 + + + + + Revert changes to the configuration. Reload configuration file. + 还原设置的更改。重新加载配置文件。 + + + + Open Config + 打开配置文件 + + + + Config Files (*.amgp *.xml) + 配置文件 (*.amgp *.xml) + + + + + + Config File (*.%1.amgp) + 配置文件 (*.%1.amgp) + + + + + Save Profile Changes? + 保存配置文件更改? + + + + + Changes to the new profile have not been saved. Would you like to save or discard the current profile? + 新配置文件的更改尚未保存。您想保存还是放弃修改当前的配置文件? + + + + + Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? + 配置文件“%1”的更改尚未保存。您想保存还是放弃修改此配置文件? + + + + Sticks + 摇杆 + + + + + DPads + 十字键 + + + + No buttons have been assigned. Please use Quick Set to assign keys +to buttons or disable hiding empty buttons. + 按钮未被分配。请使用“快速设置”来将按键分配到按钮,或取消隐藏空白按钮。 + + + + + Set %1: %2 + 设置%1:%2 + + + + + Set %1 + 设置%1 + + + + Copy Set Assignments + 复制设置分配信息 + + + + Are you sure you want to copy the assignments and device properties from %1? + 您确定要从 %1 复制分配信息和设备属性吗? + + + + + + Save Config + 保存配置文件 + + + + + Set + 设置 + + + + Joystick + + + Joystick + 摇杆 + + + + JoystickStatusWindow + + + Properties + 属性 + + + + Details + 详细信息 + + + + Name: + 名称: + + + + + + + + + + %1 + %1 + + + + Number: + 编号: + + + + Axes: + 轴数: + + + + Buttons: + 按钮数: + + + + Hats: + 帽子开关数: + + + + GUID: + 全局唯一标识符: + + + + Game Controller: + 是否为手柄: + + + + Axes + + + + + Buttons + 按钮 + + + + Hats + 帽子开关 + + + + %1 (#%2) Properties + %1 (#%2) 属性 + + + + Axis %1 + 轴%1 + + + + Hat %1 + 帽子开关%1 + + + + No + + + + + Yes + + + + + MainSettingsDialog + + + Edit Settings + 编辑设置 + + + + General + 常规 + + + + Controller Mappings + 游戏控制器映射 + + + + Language + 语言 + + + + Auto Profile + 自动配置文件 + + + + Mouse + 鼠标 + + + + <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> + <html><head/><body><p>指定本程序在加载或保存一个配置文件时,文件对话框中默认使用的路径。</p></body></html> + + + + Recent Profile Count: + 最近使用的配置文件数: + + + + <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> + <html><head/><body><p>最近使用的配置文件列表中配置文件的数量。设为0将显示所有最近使用的配置文件。</p></body></html> + + + + Gamepad Poll Rate: + 手柄轮询速率: + + + + Change the poll rate that the program uses to discover new +events from gamepads. Defaults to 10 ms. + +Reducing the poll rate value could cause the application to +use more CPU power so please test the setting that you use +before using antimicro unattended. + 改变轮询速率来发现新的手柄事件。默认10毫秒。 +降低轮询速率可能会导致本程序使用更多的处理器资源。请在以无人值守方式使用前测试此选项。 + + + + Hide main window when the main window close button is +clicked instead of quitting the program. + 点击关闭按钮时,最小化主窗口到系统托盘而不是退出程序。 + + + + Close To Tray + 关闭时最小化到系统托盘 + + + + Launch At Windows Startup + Windows 开机自启动 + + + + Display recent profiles for all controllers +as a single list in the tray menu. Defaults +to using sub-menus. + 在系统托盘菜单中以单一列表显示所有游戏控制器的最近使用的配置文件。 +默认是使用子菜单。 + + + + Single Profile List in Tray + 系统托盘菜单中使用单一配置文件列表 + + + + Have the program minimize to the taskbar. +By default, the program minimizes to the system +tray if available. + 使本程序最小化到任务栏。 +如果可能,默认情况下本程序将最小化到系统托盘。 + + + + Minimize to Taskbar + 最小化到任务栏 + + + + This option will cause the program to hide all +buttons that have no slots assigned to them. +The Quick Set dialog window will have to be used +to bring up the edit dialog for gamepad buttons. + 此选项将使本程序隐藏所有未分配槽的按钮。 +您需要使用“快速设置”对话框来打开手柄按钮的编辑对话框。 + + + + Hide Empty Buttons + 隐藏空白按钮 + + + + When the program is launched, open the last +known profile that was opened during the +previous session. + 本程序启动时,打开上次使用的配置文件。 + + + + Auto Load Last Opened Profile + 自动加载上次打开的配置文件 + + + + Only show the system tray icon when the program +first launches. + 首次启动本程序时只显示系统托盘。 + + + + Launch in Tray + 启动时最小化到系统托盘 + + + + Associate Profiles + 关联配置文件 + + + + Key Repeat + 键重复 + + + + Active keys will be repeatedly pressed when this +option is enabled. + 此选项启用后,处于活动状态的按键将一直被重复按下。 + + + + + Enable + 启用 + + + + Simplified Chinese + 简体中文 + + + + Class + + + + + Title + 标题 + + + + Program + 程序 + + + + Disable the "Enhanced Pointer Precision" Windows setting +while antimicro is running. Disabling "Enhanced Pointer Precision" +will allow mouse movement within antimicro to be more +precise. + 在 antimicro 运行时禁用 Windows 的“提高指针精确度”选项。 +禁用“提高指针精确度”可使鼠标在开启 antimicro 的情况下更精准地移动。 + + + + Disable Enhance Pointer Precision + 禁用提高指针精确度 + + + + Smoothing + 平滑 + + + + Refresh Rate: + 刷新率: + + + + The refresh rate is the amount of time that will elapse +in between mouse events. Please be cautious when +editing this setting as it will cause the program to use +more CPU power. Setting this value too low can cause +system instability. Please test the setting before using +it unattended. + 刷新率是鼠标事件之间间隔的时间。 +请小心修改此选项,因为它可能会导致本程序使用更多的处理器资源。 +此选项的值过低可能会导致系统不稳定。 +请在以无人值守方式使用前测试此选项。 + + + + Accel Numerator: + 加速度分子: + + + + + + 0 + 0 + + + + Accel Denominator: + 加速度分母: + + + + Accel Threshold: + 加速度阈值: + + + + If the acceleration values for the virtual mouse have been +changed by a different process, particularly when quitting +an older game, then you might want to reset the acceleration +values used by the virtual mouse. + 如果虚拟鼠标的加速度值被另一个进程改变,尤其是在退出老游戏的时候,您可能需要重置虚拟鼠标使用的加速度值。 + + + + Reset Acceleration + 重置加速度 + + + + Delay: + 延迟: + + + + Profi&le Directory: + 配置文件目录 (&l): + + + + Have Windows start antimicro at system startup. + 在 Windows 启动时运行本程序。 + + + + Associate .amgp files with antimicro in Windows Explorer. + 在 Windows 资源管理器中将 .amgp 文件关联到 antimicro。 + + + + Specifies how much time should elapse before key repeating +begins. + 指定开始键重复之前的延迟时间。 + + + + ms + 毫秒 + + + + Rate: + 频率: + + + + Specifies how many times key presses will be performed +per seconds. + 指定每秒按键多少次。 + + + + times/s + 次/秒 + + + + Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. + +Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. + 下面是已保存的自定义映射。您可以使用下表删除或临时禁用一个映射。您还可以禁用 SDL 中包含的映射。您只需要插入新的一行,指定摇杆的全局统一标识符,然后勾选禁用。 + +设置仅在您刷新所有摇杆或者拔出那个被禁用的摇杆之后生效。 + + + + GUID + 全局唯一标识符 + + + + Mapping String + 映射字符串 + + + + Disable? + 禁用? + + + + + Delete + 删除 + + + + Insert + 插入 + + + + <html><head/><body><p>antimicro has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make antimicro load a different translation depending on the language that you choose from the list below.</p></body></html> + <html><head/><body><p>antimicro 已被贡献者翻译为多种语言。默认情况下,本程序将根据您系统的区域设置选择相应的语言。然而,您也可以让 antimicro 加载以下列表中的任意语言。</p></body></html> + + + + + Default + 默认 + + + + Brazilian Portuguese + 巴西葡萄牙语 + + + + English + 英语 + + + + French + 法语 + + + + German + 德语 + + + + Japanese + 日语 + + + + Russian + 俄语 + + + + Serbian + 塞尔维亚语 + + + + Ukrainian + 乌克兰语 + + + + + Active + 启用 + + + + Devices: + 设备: + + + + + All + 所有 + + + + Device + 设备 + + + + Profile + 配置文件 + + + + Default? + 默认? + + + + Add + 添加 + + + + Edit + 编辑 + + + + Histor&y Size: + 历史缓冲大小 (&y): + + + + Weight &Modifier: + 权重修饰因数 (&M): + + + + Spring + 弹簧 + + + + Screen: + 屏幕: + + + + Utilize the specified screen for spring mode. On Linux, the +default is to use the primary screen. On Windows, the default +is to use all available screens. + 在弹簧模式中使用指定的屏幕。 +在 Linux 系统上,默认使用主屏幕。 +在 Windows 系统上,默认使用所有可用屏幕。 + + + + Also, Windows users who want to use a low value should also check the +"Disable Enhance Pointer Precision" checkbox if you haven't disabled +the option in Windows. + 另外,对于希望使用较低值的 Windows 用户,如果您未禁用 Windows 的“提高指针精确度”选项,请勾选本程序中的“禁用提高指针精确度”复选框。 + + + + Select Default Profile Directory + 选择默认配置文件目录 + + + + Are you sure you want to delete the profile? + 您确认要删除这个配置文件吗? + + + + MainWindow + + + antimicro + antimicro + + + + No Joysticks have been found. + Please plug in a joystick and then choose the "Update Joysticks" option in the main menu + 未找到摇杆。 +请插入一个摇杆然后选择“选项”菜单下的“更新摇杆” + + + + If events are not seen by a game, please click here to run this application as the Adminstrator. + 如果游戏无法识别事件,请点击这里以管理员权限运行本程序。 + + + + &App + 程序 (&A) + + + + &Options + 选项 (&O) + + + + &Help + 帮助 (&H) + + + + + &Quit + 退出 (&Q) + + + + Ctrl+Q + Ctrl+Q + + + + + &Update Joysticks + 更新摇杆 (&U) + + + + Ctrl+U + Ctrl+U + + + + + &Hide + 隐藏 (&H) + + + + Ctrl+H + Ctrl+H + + + + &About + 关于 (&A) + + + + Ctrl+A + Ctrl+A + + + + About Qt + 关于 Qt + + + + Properties + 属性 + + + + Key Checker + 按键检查器 + + + + Home Page + 主页 + + + + GitHub Page + GitHub 页面 + + + + Game Controller Mapping + 游戏控制器映射 + + + + Settings + 设置 + + + + Stick/Pad Assign + 摇杆/十字键分配 + + + + Wiki + 维基页面 + + + + Could not find a proper controller identifier. Exiting. + 无法找到合适的游戏控制器标识符。正在退出。 + + + + + + + + + + (%1) + (%1) + + + + + Open File + 打开文件 + + + + &Restore + 还原 (&R) + + + + Run as Administrator? + 以管理员权限运行? + + + + Are you sure that you want to run this program as Adminstrator? + +Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. + 您确定要使用管理员权限运行本程序吗? +有些以管理员权限运行的游戏无法识别 antimicro 生成的事件,除非 antimicro 也使用管理员权限运行。这是由于 Windows Vista 及以后系统中用户帐户控制 (UAC) 导致的权限问题。 + + + + Failed to elevate program + 无法提升本程序权限 + + + + Failed to restart this program as the Administrator + 无法以管理员权限重新运行本程序 + + + + Could not find controller. Exiting. + 无法找到游戏控制器。正在退出。 + + + + MouseAxisSettingsDialog + + + Mouse Settings - + 鼠标设置 - + + + + Set %1 + 设置%1 + + + + MouseButtonSettingsDialog + + + Mouse Settings - + 鼠标设置 - + + + + Set %1 + 设置%1 + + + + MouseControlStickSettingsDialog + + + Mouse Settings + 鼠标设置 + + + + Set %1 + 设置%1 + + + + MouseDPadSettingsDialog + + + Mouse Settings + 鼠标设置 + + + + Set %1 + 设置%1 + + + + MouseSettingsDialog + + + Mouse Settings + 鼠标设置 + + + + Mouse Mode: + 鼠标模式: + + + + Cursor mode is used to move the mouse cursor +around the screen relative to its current position +depending on how much you move an axis +or if a button is pressed. + +Spring mode is used to move the mouse cursor +from the center of the screen depending on how +much you move an axis. The mouse cursor will +be returned to the center of the screen when the +axis is moved back to the dead zone. + 光标:移动时,鼠标光标以当前位置为基准,移动距离取决于您移动轴或按下按钮的幅度。 +弹簧:移动时,鼠标光标以屏幕中心为基准,移动距离取决于您移动轴的幅度。轴移回不灵敏区之后,鼠标光标将回到屏幕中心。 + + + + Cursor + 光标 + + + + Spring + 弹簧 + + + + Acceleration: + 加速模式: + + + + Enhanced: Three tier curve that makes the mouse move +slow on the low end of an axis and fast on the high end. + +Linear: Mouse moves proportionally to axis. + +Quadratic: Mouse accelerates slowly on low end. + +Cubic: Mouse accelerates slower than Quadratic. + +Quadratic Extreme: Raises mouse speed 1.5 times once +95% axis travel has been reached. + +Power Function: Allows for a more custom curve option. + +Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. + +Easing Cubic: Axis high end is gradually accelerated over +a period of time using a Cubic curve. + 增强精度:三级曲线使得鼠标光标在轴移动幅度较小时移动慢,轴移动幅度较大时移动快。 +线性:鼠标移动速度和轴移动幅度成比例。 +平方:鼠标光标在轴移动幅度较小时缓慢加速。 +立方:鼠标加速度比平方模式慢。 +极限平方:轴移动距离达到95%后提升1.5倍鼠标速度。 +指数函数:允许更多自定义曲线选项。 +平方缓动:轴移动幅度较大时,鼠标速度随时间以平方曲线增加。 +立方缓动:轴移动幅度较大时,鼠标速度随时间以立方曲线增加。 + + + + Enhanced Precision + 增强精度 + + + + + Linear + 线性 + + + + Quadratic + 平方 + + + + Cubic + 立方 + + + + Quadratic Extreme + 极限平方 + + + + Power Function + 指数函数 + + + + Easing Quadratic + 平方缓动 + + + + Easing Cubic + 立方缓动 + + + + Mouse Speed Settings + 鼠标速度设置 + + + + Enable to change the horizontal and vertical speed +boxes at the same time. + 同时改变水平和垂直速度。 + + + + Change Together + 同时更改 + + + + Horizontal +Speed: + 水平速度: + + + + + 1 = 20 pps + 1级=20像素/秒 + + + + Vertical +Speed: + 垂直速度: + + + + Wheel Hori. +Speed: + 滚轮水平速度: + + + + Set the speed used for horizontal mouse wheel movement +according to number of simulated notches per second. + 根据每秒模拟滚动凹槽数设置鼠标滚轮水平滚动速度。 + + + + Set the speed used for vertical mouse wheel movement +according to number of simulated notches per second. + 根据每秒模拟滚动凹槽数设置鼠标滚轮垂直滚动速度。 + + + + For Power Function acceleration curve. Specifies +the factor to use for curve sensitivity. When the value +is above 1.0, the mouse movement will be accelerated +faster at the low end of an axis. + 仅用于指数函数加速曲线。 +指定曲线敏感度系数。当该值大于1.0时,增大轴移动幅度较小时的鼠标加速度。 + + + + Easing Duration: + 缓动时长: + + + + Specifies the amount of time (in seconds) that will +be required before the mouse is fully accelerated +after reaching the high end of an axis. + 轴移动幅度达到最大后,鼠标在此时长(以秒为单位)内加速到最大速度。 + + + + + s + + + + + Extra Acceleration + 额外加速 + + + + Multiplier: + 倍数: + + + + Highest value to accelerate mouse movement by + 鼠标速度的最大加速值 + + + + x + x + + + + Start %: + 起始百分比: + + + + Acceleration begins at this percentage of the base multiplier + 加速以基础倍数的此百分比速率开始 + + + + + + + % + % + + + + Min +Threshold: + 最小阈值: + + + + Minimum amount of axis travel required for acceleration to begin + 轴的移动幅度大于此最小阈值之后加速才开始 + + + + Max +Threshold: + 最大阈值: + + + + Maximum axis travel before acceleration has reached the multiplier value + 轴的移动幅度达到此最大阈值时加速达到上述倍数值 + + + + Extra Duration: + 额外加速时长: + + + + Extend the time that extra acceleration is applied. Axis travel +will be taken into account. A slower flick will decrease the +actual time that extra acceleration will be applied. + 此期间内额外加速生效。 +轴的移动幅度考虑在内。缓慢的轴移动将减小实际的额外加速生效时间。 + + + + Curve: + 曲线: + + + + Ease Out Sine + 正弦滑出缓动 + + + + Ease Out Quad + 平方滑出缓动 + + + + Ease Out Cubic + 立方滑出缓动 + + + + Release Radius: + 释放半径: + + + + Specifies that the spring area will be relative to the +mouse position set by a non-relative spring. + 弹簧区域将相对于鼠标指针的位置。鼠标指针的位置可由其它非弹簧模式指定。 + + + + Relative + 相对 + + + + Mouse Status + 鼠标状态 + + + + X: + X轴: + + + + + 0 (0 pps) + 0(0像素/秒) + + + + Y: + Y轴: + + + + + 1 = 1 notch(es)/s + 1级=1凹槽/秒 + + + + Wheel Vert. +Speed: + 滚轮垂直速度: + + + + Sensitivity: + 灵敏度: + + + + Options for adding extra acceleration to the mouse +movement beyond what the acceleration curve would +produce. This is meant to help work around some of +the issues of the very limited input range available using +typical gamepad analog sticks. + 在加速曲线之上为鼠标移动增添额外加速。 +这些选项是为了绕过某些由于手柄模拟摇杆的输入范围有限所带来的问题。 + + + + Spring Settings + 弹簧设置 + + + + Spring Width: + 弹簧区域宽度: + + + + Changes the width of the region that the cursor +can move in spring mode. 0 will use the entire width +of your screen. + 设置鼠标以弹簧模式移动的区域的宽度。设为0时将使用您整个屏幕的宽度。 + + + + Spring Height: + 弹簧区域高度: + + + + Changes the height of the region that the cursor +can move in spring mode. 0 will use the entire height +of your screen. + 设置鼠标以弹簧模式移动的区域的高度。设为0时将使用您整个屏幕的高度。 + + + + + %n notch(es)/s + + %n凹槽/秒 + + + + + QKeyDisplayDialog + + + Key Checker + 按键检查器 + + + + <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by antimicro.</p><p>The antimicro key value and the Qt key value will usually be the same. antimicro tries to use the key values defined in Qt when possible. Check the page <a href="http://qt-project.org/doc/qt-4.8/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://qt-project.org/doc/qt-4.8/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to antimicro's <a href="https://github.com/Ryochan7/antimicro"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> + <html><head/><body><p>按下您键盘上的一个键来观察本程序如何检测按键。本窗口将显示系统原生键值、Qt 原始键值(如果可用)和 antimicro 使用的自定义键值。</p><p>antimicro 键值和 Qt 键值通常是一样的。如果可能,antimicro 将优先使用 Qt 中已定义的键值。如果想了解 Qt 中已定义的键值列表,请查看页面 <a href="http://qt-project.org/doc/qt-4.8/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://qt-project.org/doc/qt-4.8/qt.html#Key-enum</span></a>。如果您发现某个键没有被本程序原生支持,请将问题报告至 antimicro 的 <a href="https://github.com/Ryochan7/antimicro"><span style=" text-decoration: underline; color:#0057ae;">GitHub 页面</span></a>,以便我们修改程序后直接支持这个键。如您所见,未知的键值将被附加一个自定义前缀。这样一来,它们就能被使用了,不过最大的问题是含有这个键的配置文件将无法在其它地方使用。</p></body></html> + + + + Event Handler: + 事件处理程序: + + + + Native Key Value: + 系统原生键值: + + + + + + 0x00000000 + 0x00000000 + + + + Qt Key Value: + Qt 原始键值: + + + + antimicro Key Value: + antimicro 自定义键值: + + + + QObject + + + Super + Super + + + + Menu + Menu + + + + Mute + Mute + + + + Vol+ + Vol+ + + + + Vol- + Vol- + + + + Play/Pause + Play/Pause + + + + Play + Play + + + + Pause + Pause + + + + Prev + Prev + + + + Next + Next + + + + Mail + Mail + + + + Home + Home + + + + Media + Media + + + + Search + Search + + + + Daemon launched + 后台服务已启动 + + + + Failed to launch daemon + 无法启动后台服务 + + + + Launching daemon + 正在启动后台服务 + + + + + Display string "%1" is not valid. + 显示字符串“%1”无效。 + + + + Failed to set a signature id for the daemon + 无法为后台服务设置签名ID + + + + Failed to change working directory to / + 无法切换工作路径到根目录 + + + + Quitting Program + 正在退出程序 + + + + # of joysticks found: %1 + 已发现摇杆数:%1 + + + + List Joysticks: + 摇杆列表: + + + + --------------- + --------------- + + + + Joystick %1: + 摇杆%1: + + + + Index: %1 + 编号:%1 + + + + GUID: %1 + 全局唯一标识符:%1 + + + + Name: %1 + 名称:%1 + + + + Yes + + + + + No + + + + + Game Controller: %1 + 游戏控制器:%1 + + + + # of Axes: %1 + 轴数:%1 + + + + # of Buttons: %1 + 按钮数:%1 + + + + # of Hats: %1 + 帽子开关数:%1 + + + + Attempting to use fallback option %1 for event generation. + 尝试为事件生成使用后备选项 %1。 + + + + Failed to open event generator. Exiting. + 无法打开事件发生器。正在退出。 + + + + Using %1 as the event generator. + 使用 %1 作为事件发生器。 + + + + Could not raise process priority. + 无法提升进程优先级。 + + + + QuickSetDialog + + + Quick Set + 快速设置 + + + + <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> + <html><head/><body><p>请在 %1(<span style=" font-weight:600;">%2</span>)上按任意键或移动任意轴。<br/>之后一个对话框会弹出并允许您设置按键分配。</p></body></html> + + + + Quick Set %1 + 快速设置 %1 + + + + SetAxisThrottleDialog + + + Throttle Change + 阀设置改变 + + + + The throttle setting for Axis %1 has been changed. + +Would you like to distribute this throttle change to all sets? + 轴%1的阀设置已改变。 +您想将这个阀设置的改变应用到所有设置吗? + + + + SetJoystick + + + Set %1: %2 + 设置%1:%2 + + + + Set %1 + 设置%1 + + + + SetNamesDialog + + + Set Name Settings + 指定设置名称 + + + + Set 1 + 设置1 + + + + Set 2 + 设置2 + + + + Set 3 + 设置3 + + + + Set 4 + 设置4 + + + + Set 5 + 设置5 + + + + Set 6 + 设置6 + + + + Set 7 + 设置7 + + + + Set 8 + 设置8 + + + + Name + 名称 + + + + SimpleKeyGrabberButton + + + Mouse + 鼠标 + + + + SpringModeRegionPreview + + + Spring Mode Preview + 弹簧模式预览 + + + + UInputEventHandler + + + Could not find a valid uinput device file. +Please check that you have the uinput module loaded. +lsmod | grep uinput + 无法找到任何有效的 uinput 设备文件。 +请确认您加载了 uinput 模块: +lsmod | grep uinput + + + + Could not open uinput device file +Please check that you have permission to write to the device + 无法打开 uinput 设备文件 +请确认您有写入该设备的权限 + + + + Using uinput device file %1 + 使用 uinput 设备文件%1 + + + + UInputHelper + + + a + a + + + + b + b + + + + c + c + + + + d + d + + + + e + e + + + + f + f + + + + g + g + + + + h + h + + + + i + i + + + + j + j + + + + k + k + + + + l + l + + + + m + m + + + + n + n + + + + o + o + + + + p + p + + + + q + q + + + + r + r + + + + s + s + + + + t + t + + + + u + u + + + + v + v + + + + w + w + + + + x + x + + + + y + y + + + + z + z + + + + Esc + Esc + + + + F1 + F1 + + + + F2 + F2 + + + + F3 + F3 + + + + F4 + F4 + + + + F5 + F5 + + + + F6 + F6 + + + + F7 + F7 + + + + F8 + F8 + + + + F9 + F9 + + + + F10 + F10 + + + + F11 + F11 + + + + F12 + F12 + + + + ` + ` + + + + 1 + 1 + + + + 2 + 2 + + + + 3 + 3 + + + + 4 + 4 + + + + 5 + 5 + + + + 6 + 6 + + + + 7 + 7 + + + + 8 + 8 + + + + 9 + 9 + + + + 0 + 0 + + + + + - + - + + + + = + = + + + + BackSpace + BackSpace + + + + Tab + Tab + + + + [ + [ + + + + ] + ] + + + + \ + \ + + + + CapsLock + CapsLock + + + + ; + ; + + + + ' + ' + + + + Enter + Enter + + + + Shift_L + Shift_L + + + + , + , + + + + + . + . + + + + + / + / + + + + Ctrl_L + Ctrl_L + + + + + Super_L + Super_L + + + + Alt_L + Alt_L + + + + Space + Space + + + + Alt_R + Alt_R + + + + Menu + Menu + + + + Ctrl_R + Ctrl_R + + + + Shift_R + Shift_R + + + + Up + Up + + + + Left + Left + + + + Down + Down + + + + Right + Right + + + + PrtSc + PrtSc + + + + Ins + Ins + + + + Del + Del + + + + Home + Home + + + + End + End + + + + PgUp + PgUp + + + + PgDn + PgDn + + + + NumLock + NumLock + + + + * + * + + + + + + + + + + + KP_Enter + KP_Enter + + + + KP_1 + KP_1 + + + + KP_2 + KP_2 + + + + KP_3 + KP_3 + + + + KP_4 + KP_4 + + + + KP_5 + KP_5 + + + + KP_6 + KP_6 + + + + KP_7 + KP_7 + + + + KP_8 + KP_8 + + + + KP_9 + KP_9 + + + + KP_0 + KP_0 + + + + SCLK + SCLK + + + + Pause + Pause + + + + Super_R + Super_R + + + + Mute + Mute + + + + VolDn + VolDn + + + + VolUp + VolUp + + + + Play + Play + + + + Stop + Stop + + + + Prev + Prev + + + + Next + Next + + + + [NO KEY] + [NO KEY] + + + + UnixWindowInfoDialog + + + Captured Window Properties + 捕获的窗口属性 + + + + Information About Window + 窗口信息 + + + + Class: + 类: + + + + + + TextLabel + 文本标签 + + + + Title: + 标题: + + + + Path: + 路径: + + + + Match By Properties + 根据属性匹配 + + + + Class + + + + + Title + 标题 + + + + Path + 路径 + + + + VDPad + + + + + VDPad + 虚拟十字键 + + + + VirtualKeyPushButton + + + Space + Space + + + + Tab + Tab + + + + Shift (L) + Shift (L) + + + + Shift (R) + Shift (R) + + + + Ctrl (L) + Ctrl (L) + + + + Ctrl (R) + Ctrl (R) + + + + Alt (L) + Alt (L) + + + + + Alt (R) + Alt (R) + + + + ` + ` + + + + ~ + ~ + + + + + - + - + + + + = + = + + + + [ + [ + + + + ] + ] + + + + \ + \ + + + + Caps + Caps + + + + ; + ; + + + + ' + ' + + + + , + , + + + + + . + . + + + + + / + / + + + + ESC + ESC + + + + PRTSC + PRTSC + + + + SCLK + SCLK + + + + INS + INS + + + + PGUP + PGUP + + + + DEL + DEL + + + + PGDN + PGDN + + + + 1 + 1 + + + + 2 + 2 + + + + 3 + 3 + + + + 4 + 4 + + + + 5 + 5 + + + + 6 + 6 + + + + 7 + 7 + + + + 8 + 8 + + + + 9 + 9 + + + + 0 + 0 + + + + NUM +LK + NUM +LK + + + + + * + * + + + + + + + + + + + E +N +T +E +R + E +N +T +E +R + + + + < + < + + + + : + : + + + + Super (L) + Super (L) + + + + Menu + Menu + + + + Up + Up + + + + Down + Down + + + + Left + Left + + + + Right + Right + + + + VirtualKeyboardMouseWidget + + + + Keyboard + 键盘 + + + + + Mouse + 鼠标 + + + + Mouse Settings + 鼠标设置 + + + + Left + Mouse + + + + + Up + Mouse + + + + + Left Button + Mouse + 左键 + + + + Middle Button + Mouse + 中键 + + + + Right Button + Mouse + 右键 + + + + Wheel Up + Mouse + 滚轮向上 + + + + Wheel Left + Mouse + 滚轮向左 + + + + Wheel Right + Mouse + 滚轮向右 + + + + Wheel Down + Mouse + 滚轮向下 + + + + Down + Mouse + + + + + Right + Mouse + + + + + Button 4 + Mouse + 按钮4 + + + + Mouse 8 + Mouse + 按钮8 + + + + Button 5 + Mouse + 按钮5 + + + + Mouse 9 + Mouse + 按钮9 + + + + NONE + + + + + Applications + 应用程序 + + + + Browser Back + 浏览器后退 + + + + Browser Favorites + 浏览器收藏 + + + + Browser Forward + 浏览器前进 + + + + Browser Home + 浏览器主页 + + + + Browser Refresh + 浏览器刷新 + + + + Browser Search + 浏览器搜索 + + + + Browser Stop + 浏览器停止 + + + + Calc + 计算器 + + + + Email + 邮件 + + + + Media + 多媒体 + + + + Media Next + 多媒体下一首 + + + + Media Play + 多媒体播放 + + + + Media Previous + 多媒体上一首 + + + + Media Stop + 多媒体停止 + + + + Search + 搜索 + + + + Volume Down + 音量减小 + + + + Volume Mute + 静音 + + + + Volume Up + 音量增加 + + + + VirtualMousePushButton + + + INVALID + 无效 + + + + WinAppProfileTimerDialog + + + + Capture Application + 捕捉应用程序 + + + + After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. + 按下“捕捉应用程序”按钮之后,请选择您想要关联配置文件的应用程序窗口。活动的应用程序将在指定的秒数之后被捕捉。 + + + + Timer: + 计时器: + + + + Seconds + + + + + Cancel + 取消 + + + + WinExtras + + + [NO KEY] + [无按键] + + + + AntiMicro Profile + antimicro 配置文件 + + + + X11Extras + + + ESC + ESC + + + + Tab + Tab + + + + Space + Space + + + + DEL + DEL + + + + Return + Return + + + + KP_Enter + KP_Enter + + + + Backspace + Backspace + + + + xinput extension was not found. No mouse acceleration changes will occur. + 未找到 XInput 扩展。鼠标加速选项将无效。 + + + + + xinput version must be at least 2.0. No mouse acceleration changes will occur. + XInput 版本必需至少为2.0。鼠标加速选项将无效。 + + + + Virtual pointer found with id=%1. + 发现虚拟指针 ID=%1。 + + + + PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 + 未找到虚拟指针的 PtrFeedbackClass。鼠标加速选项在 ID=%1 的设备上将无效 + + + + Changing mouse acceleration for device with id=%1 + 正在改变 ID=%1 的设备上的鼠标加速选项 + + + + XMLConfigReader + + + Could not write updated profile XML to file %1. + 无法将更新后的配置 XML 写入文件 %1。 + + + + XMLConfigWriter + + + Could not write to profile at %1. + 无法写入配置文件 %1。 + + + diff --git a/share/blank.txt b/share/blank.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/aboutdialog.cpp b/src/aboutdialog.cpp new file mode 100644 index 0000000..dc0da14 --- /dev/null +++ b/src/aboutdialog.cpp @@ -0,0 +1,115 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#ifdef USE_SDL_2 +#include +#else +#include +#endif + +#include "aboutdialog.h" +#include "ui_aboutdialog.h" +#include "common.h" + +#include "eventhandlerfactory.h" + +AboutDialog::AboutDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::AboutDialog) +{ + ui->setupUi(this); + + ui->versionLabel->setText(PadderCommon::programVersion); + fillInfoTextBrowser(); +} + +AboutDialog::~AboutDialog() +{ + delete ui; +} + +void AboutDialog::fillInfoTextBrowser() +{ + QStringList finalInfoText; + + finalInfoText.append(tr("Program Version %1").arg(PadderCommon::programVersion)); + finalInfoText.append(tr("Program Compiled on %1 at %2").arg(__DATE__).arg(__TIME__)); + + QString sdlCompiledVersionNumber("%1.%2.%3"); + QString sdlLinkedVersionNumber("%1.%2.%3"); + + SDL_version compiledver; + SDL_version linkedver; + SDL_VERSION(&compiledver); +#ifdef USE_SDL_2 + SDL_GetVersion(&linkedver); +#else + linkedver = *(SDL_Linked_Version()); +#endif + + sdlCompiledVersionNumber = sdlCompiledVersionNumber.arg(compiledver.major).arg(compiledver.minor).arg(compiledver.patch); + finalInfoText.append(tr("Built Against SDL %1").arg(sdlCompiledVersionNumber)); + + sdlLinkedVersionNumber = sdlLinkedVersionNumber.arg(linkedver.major).arg(linkedver.minor).arg(linkedver.patch); + finalInfoText.append(tr("Running With SDL %1").arg(sdlLinkedVersionNumber)); + + finalInfoText.append(tr("Using Qt %1").arg(qVersion())); + + BaseEventHandler *handler = 0; + EventHandlerFactory *factory = EventHandlerFactory::getInstance(); + if (factory) + { + handler = factory->handler(); + } + + if (handler) + { + finalInfoText.append(tr("Using Event Handler: %1").arg(handler->getName())); + } + + ui->infoTextBrowser->setText(finalInfoText.join("\n")); + + // Read Changelog text from resource and put text in text box. + QResource changelogFile(":/Changelog"); + QFile temp(changelogFile.absoluteFilePath()); + temp.open(QIODevice::Text | QIODevice::ReadOnly); + QTextStream changelogStream(&temp); + QString changelogText = changelogStream.readAll(); + temp.close(); + ui->changelogPlainTextEdit->setPlainText(changelogText); +} + +void AboutDialog::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + { + retranslateUi(); + } + + QDialog::changeEvent(event); +} + +void AboutDialog::retranslateUi() +{ + ui->retranslateUi(this); + + ui->versionLabel->setText(PadderCommon::programVersion); +} diff --git a/src/aboutdialog.h b/src/aboutdialog.h new file mode 100644 index 0000000..2eab965 --- /dev/null +++ b/src/aboutdialog.h @@ -0,0 +1,44 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef ABOUTDIALOG_H +#define ABOUTDIALOG_H + +#include + +namespace Ui { +class AboutDialog; +} + +class AboutDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AboutDialog(QWidget *parent = 0); + ~AboutDialog(); + +private: + Ui::AboutDialog *ui; + +protected: + void fillInfoTextBrowser(); + virtual void changeEvent(QEvent *event); + void retranslateUi(); +}; + +#endif // ABOUTDIALOG_H diff --git a/src/aboutdialog.ui b/src/aboutdialog.ui new file mode 100644 index 0000000..02dda7c --- /dev/null +++ b/src/aboutdialog.ui @@ -0,0 +1,445 @@ + + + AboutDialog + + + + 0 + 0 + 640 + 480 + + + + + 640 + 480 + + + + About + + + + 10 + + + + + 6 + + + 50 + + + 110 + + + + + + 0 + 0 + + + + + 64 + 64 + + + + + + + :/images/antimicro.png + + + + + + + + 0 + 0 + + + + + 14 + 75 + true + + + + antimicro + + + Qt::AlignHCenter|Qt::AlignTop + + + 0 + + + -1 + + + + + + + + + + 0 + 0 + + + + + 11 + + + + Version + + + Qt::AlignCenter + + + + + + + 0 + + + false + + + + Credits + + + + + + + 0 + 0 + + + + IBeamCursor + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Travis Nickles &lt;nickles.travis@gmail.com&gt;</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Contributors:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;"><br /></span>Zerro Alvein</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">aybe</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Jeff Backus &lt;jeff.backus@gmail.com&gt;</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Arthur Moore<br />Anton Tornqvist &lt;antont@inbox.lv&gt;</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Translators:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt; font-weight:600;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">zzpxyx - Chinese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">phob - German</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tou omiya - Japanese</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">burunduk - Ukrainian</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + true + + + + + + + + Info + + + + + + + + + + License + + + + + + + 0 + 0 + + + + IBeamCursor + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Version 3, 29 June 2007</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Preamble</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">TERMS AND CONDITIONS</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">0. Definitions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">1. Source Code.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">2. Basic Permissions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">4. Conveying Verbatim Copies.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">5. Conveying Modified Source Versions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">6. Conveying Non-Source Forms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">7. Additional Terms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">8. Termination.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">11. Patents.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">14. Revised Versions of this License.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">15. Disclaimer of Warranty.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">16. Limitation of Liability.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> + + + false + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + true + + + + + + + + Changelog + + + + + + true + + + + + + + + About Development + + + + + + 30 + + + + + Since December 30, 2012, I have been working on antimicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. + +The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. + +Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. + +Once the Steam controller is finally released to the public, the need for this program might not exist anymore. Just based on the concept of the controller alone, the Steam controller would have so many advantages over using a program like this to provide KB+M emulation. + + + + + + + + + + + + + Copyright: 2013 - 2016 + + + Qt::AlignBottom|Qt::AlignRight|Qt::AlignTrailing + + + -1 + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QDialogButtonBox::Close + + + + + + + versionLabel + copyrightLabel + tabWidget + + + + + + + buttonBox + accepted() + AboutDialog + accept() + + + 63 + 473 + + + 319 + 239 + + + + + buttonBox + rejected() + AboutDialog + reject() + + + 478 + 462 + + + 319 + 239 + + + + + diff --git a/src/addeditautoprofiledialog.cpp b/src/addeditautoprofiledialog.cpp new file mode 100644 index 0000000..5d656ba --- /dev/null +++ b/src/addeditautoprofiledialog.cpp @@ -0,0 +1,569 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +//#include +#include +#include +#include +#include +#include +#include + +#include "addeditautoprofiledialog.h" +#include "ui_addeditautoprofiledialog.h" + +#if defined(Q_OS_UNIX) + + #ifdef WITH_X11 +#include "unixcapturewindowutility.h" +#include "capturedwindowinfodialog.h" +#include "x11extras.h" + + #endif + + #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) +#include + #endif + +#elif defined(Q_OS_WIN) +#include "winappprofiletimerdialog.h" +#include "capturedwindowinfodialog.h" +#include "winextras.h" + +#endif + +#include "common.h" + +AddEditAutoProfileDialog::AddEditAutoProfileDialog(AutoProfileInfo *info, AntiMicroSettings *settings, + QList *devices, + QList &reservedGUIDS, bool edit, QWidget *parent) : + QDialog(parent), + ui(new Ui::AddEditAutoProfileDialog) +{ + ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + + this->info = info; + this->settings = settings; + this->editForm = edit; + this->devices = devices; + this->originalGUID = info->getGUID(); + this->originalExe = info->getExe(); + this->originalWindowClass = info->getWindowClass(); + this->originalWindowName = info->getWindowName(); + + QListIterator iterGUIDs(reservedGUIDS); + while (iterGUIDs.hasNext()) + { + QString guid = iterGUIDs.next(); + if (!this->reservedGUIDs.contains(guid)) + { + this->reservedGUIDs.append(guid); + } + } + + bool allowDefault = false; + if (info->getGUID() != "all" && + info->getGUID() != "" && + !this->reservedGUIDs.contains(info->getGUID())) + { + allowDefault = true; + } + + if (allowDefault && info->getExe().isEmpty()) + { + ui->asDefaultCheckBox->setEnabled(true); + if (info->isCurrentDefault()) + { + ui->asDefaultCheckBox->setChecked(true); + } + } + else + { + ui->asDefaultCheckBox->setToolTip(tr("A different profile is already selected as the default for this device.")); + } + + //if (!edit) + //{ + + ui->devicesComboBox->addItem("all"); + QListIterator iter(*devices); + int found = -1; + int numItems = 1; + while (iter.hasNext()) + { + InputDevice *device = iter.next(); + ui->devicesComboBox->addItem(device->getSDLName(), QVariant::fromValue(device)); + if (device->getGUIDString() == info->getGUID()) + { + found = numItems; + } + numItems++; + } + + if (!info->getGUID().isEmpty() && info->getGUID() != "all") + { + if (found >= 0) + { + ui->devicesComboBox->setCurrentIndex(found); + } + else + { + ui->devicesComboBox->addItem(tr("Current (%1)").arg(info->getDeviceName())); + ui->devicesComboBox->setCurrentIndex(ui->devicesComboBox->count()-1); + } + } + //} + + ui->profileLineEdit->setText(info->getProfileLocation()); + ui->applicationLineEdit->setText(info->getExe()); + ui->winClassLineEdit->setText(info->getWindowClass()); + ui->winNameLineEdit->setText(info->getWindowName()); + +#ifdef Q_OS_UNIX + ui->selectWindowPushButton->setVisible(false); + +#elif defined(Q_OS_WIN) + ui->detectWinPropsSelectWindowPushButton->setVisible(false); + + ui->winClassLineEdit->setVisible(false); + ui->winClassLabel->setVisible(false); + + //ui->winNameLineEdit->setVisible(false); + //ui->winNameLabel->setVisible(false); +#endif + + connect(ui->profileBrowsePushButton, SIGNAL(clicked()), this, SLOT(openProfileBrowseDialog())); + connect(ui->applicationPushButton, SIGNAL(clicked()), this, SLOT(openApplicationBrowseDialog())); + connect(ui->devicesComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(checkForReservedGUIDs(int))); + connect(ui->applicationLineEdit, SIGNAL(textChanged(QString)), this, SLOT(checkForDefaultStatus())); + connect(ui->winClassLineEdit, SIGNAL(textChanged(QString)), this, SLOT(checkForDefaultStatus())); + connect(ui->winNameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(checkForDefaultStatus())); + +#if defined(Q_OS_UNIX) + connect(ui->detectWinPropsSelectWindowPushButton, SIGNAL(clicked()), this, SLOT(showCaptureHelpWindow())); +#elif defined(Q_OS_WIN) + connect(ui->selectWindowPushButton, SIGNAL(clicked()), this, SLOT(openWinAppProfileDialog())); +#endif + + connect(this, SIGNAL(accepted()), this, SLOT(saveAutoProfileInformation())); +} + +AddEditAutoProfileDialog::~AddEditAutoProfileDialog() +{ + delete ui; +} + +void AddEditAutoProfileDialog::openProfileBrowseDialog() +{ + QString lookupDir = PadderCommon::preferredProfileDir(settings); + QString filename = QFileDialog::getOpenFileName(this, tr("Open Config"), lookupDir, QString("Config Files (*.amgp *.xml)")); + if (!filename.isNull() && !filename.isEmpty()) + { + ui->profileLineEdit->setText(QDir::toNativeSeparators(filename)); + } +} + +void AddEditAutoProfileDialog::openApplicationBrowseDialog() +{ + /*QString filename; + QFileDialog dialog(this, tr("Select Program"), QDir::homePath()); + dialog.setFilter(QDir::Files | QDir::Executable); + if (dialog.exec()) + { + filename = dialog.selectedFiles().first(); + }*/ +#ifdef Q_OS_WIN + QString filename = QFileDialog::getOpenFileName(this, tr("Select Program"), QDir::homePath(), tr("Programs (*.exe)")); +#else + QString filename = QFileDialog::getOpenFileName(this, tr("Select Program"), QDir::homePath(), QString()); +#endif + if (!filename.isNull() && !filename.isEmpty()) + { + QFileInfo exe(filename); + if (exe.exists() && exe.isExecutable()) + { + ui->applicationLineEdit->setText(filename); + } + } +} + +AutoProfileInfo* AddEditAutoProfileDialog::getAutoProfile() +{ + return info; +} + +void AddEditAutoProfileDialog::saveAutoProfileInformation() +{ + info->setProfileLocation(ui->profileLineEdit->text()); + int deviceIndex = ui->devicesComboBox->currentIndex(); + if (deviceIndex > 0) + { + QVariant temp = ui->devicesComboBox->itemData(deviceIndex, Qt::UserRole); + // Assume that if the following is not true, the GUID should + // not be changed. + if (!temp.isNull()) + { + InputDevice *device = ui->devicesComboBox->itemData(deviceIndex, Qt::UserRole).value(); + info->setGUID(device->getGUIDString()); + info->setDeviceName(device->getSDLName()); + } + } + else + { + info->setGUID("all"); + info->setDeviceName(""); + } + + info->setExe(ui->applicationLineEdit->text()); + info->setWindowClass(ui->winClassLineEdit->text()); + info->setWindowName(ui->winNameLineEdit->text()); + info->setDefaultState(ui->asDefaultCheckBox->isChecked()); + //info->setActive(true); +} + +void AddEditAutoProfileDialog::checkForReservedGUIDs(int index) +{ + QVariant data = ui->devicesComboBox->itemData(index); + if (index == 0) + { + ui->asDefaultCheckBox->setChecked(false); + ui->asDefaultCheckBox->setEnabled(false); + ui->asDefaultCheckBox->setToolTip(tr("Please use the main default profile selection.")); + } + else if (!data.isNull()) + { + InputDevice *device = data.value(); + if (reservedGUIDs.contains(device->getGUIDString())) + { + ui->asDefaultCheckBox->setChecked(false); + ui->asDefaultCheckBox->setEnabled(false); + ui->asDefaultCheckBox->setToolTip(tr("A different profile is already selected as the default for this device.")); + } + else + { + ui->asDefaultCheckBox->setEnabled(true); + ui->asDefaultCheckBox->setToolTip(tr("Select this profile to be the default loaded for\nthe specified device. The selection will be used instead\nof the all default profile option.")); + } + } +} + +QString AddEditAutoProfileDialog::getOriginalGUID() +{ + return originalGUID; +} + +QString AddEditAutoProfileDialog::getOriginalExe() +{ + return originalExe; +} + +QString AddEditAutoProfileDialog::getOriginalWindowClass() +{ + return originalWindowClass; +} + +QString AddEditAutoProfileDialog::getOriginalWindowName() +{ + return originalWindowName; +} + +#ifdef Q_OS_UNIX +/** + * @brief Display a simple message box and attempt to capture a window using the mouse + */ +void AddEditAutoProfileDialog::showCaptureHelpWindow() +{ + #ifdef WITH_X11 + #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + if (QApplication::platformName() == QStringLiteral("xcb")) + { + #endif + QMessageBox *box = new QMessageBox(this); + box->setText(tr("Please select a window by using the mouse. Press Escape if you want to cancel.")); + box->setWindowTitle(tr("Capture Application Window")); + box->setStandardButtons(QMessageBox::NoButton); + box->setModal(true); + box->show(); + + UnixCaptureWindowUtility *util = new UnixCaptureWindowUtility(); + QThread *thread = new QThread(this); + util->moveToThread(thread); + + connect(thread, SIGNAL(started()), util, SLOT(attemptWindowCapture())); + connect(util, SIGNAL(captureFinished()), thread, SLOT(quit())); + connect(util, SIGNAL(captureFinished()), box, SLOT(hide())); + connect(util, SIGNAL(captureFinished()), this, SLOT(checkForGrabbedWindow()), Qt::QueuedConnection); + + connect(thread, SIGNAL(finished()), box, SLOT(deleteLater())); + connect(util, SIGNAL(destroyed()), thread, SLOT(deleteLater())); + thread->start(); + #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + } + #endif + #endif +} + +/** + * @brief Check if there is a program path saved in an UnixCaptureWindowUtility + * object + */ +void AddEditAutoProfileDialog::checkForGrabbedWindow() +{ + #ifdef WITH_X11 + #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + if (QApplication::platformName() == QStringLiteral("xcb")) + { + #endif + UnixCaptureWindowUtility *util = static_cast(sender()); + unsigned long targetWindow = util->getTargetWindow(); + bool escaped = !util->hasFailed(); + bool failed = false; + QString path; + + if (targetWindow != None) + { + // Attempt to find the appropriate window below the root window + // that was clicked. + //qDebug() << "ORIGINAL: " << QString::number(targetWindow, 16); + unsigned long tempWindow = X11Extras::getInstance()->findClientWindow(targetWindow); + if (tempWindow > 0) + { + targetWindow = tempWindow; + } + //qDebug() << "ADJUSTED: " << QString::number(targetWindow, 16); + } + + if (targetWindow != None) + { + CapturedWindowInfoDialog *dialog = new CapturedWindowInfoDialog(targetWindow, this); + connect(dialog, SIGNAL(accepted()), this, SLOT(windowPropAssignment())); + dialog->show(); + + /*QString ham = X11Info::getInstance()->getWindowTitle(targetWindow); + int pid = X11Info::getInstance()->getApplicationPid(targetWindow); + if (pid > 0) + { + //qDebug() << "THIS ID: " << pid; + QString exepath = X11Info::getInstance()->getApplicationLocation(pid); + + if (!exepath.isEmpty()) + { + path = exepath; + } + else if (!failed) + { + failed = true; + } + } + else if (!failed) + { + failed = true; + }*/ + } + else if (!escaped) + { + failed = true; + } + + /*if (!path.isEmpty()) + { + ui->applicationLineEdit->setText(path); + }*/ + // Ensure that the operation was not cancelled (Escape wasn't pressed). + if (failed) + { + QMessageBox box; + box.setText(tr("Could not obtain information for the selected window.")); + box.setWindowTitle(tr("Application Capture Failed")); + box.setStandardButtons(QMessageBox::Close); + box.raise(); + box.exec(); + } + + util->deleteLater(); + #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + } + #endif + #endif +} + +#endif + +void AddEditAutoProfileDialog::windowPropAssignment() +{ + disconnect(ui->applicationLineEdit, SIGNAL(textChanged(QString)), this, SLOT(checkForDefaultStatus())); + disconnect(ui->winClassLineEdit, SIGNAL(textChanged(QString)), this, SLOT(checkForDefaultStatus())); + disconnect(ui->winNameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(checkForDefaultStatus())); + + CapturedWindowInfoDialog *dialog = static_cast(sender()); + if (dialog->getSelectedOptions() & CapturedWindowInfoDialog::WindowPath) + { + if (dialog->useFullWindowPath()) + { + ui->applicationLineEdit->setText(dialog->getWindowPath()); + } + else + { + QString temp; + temp = QFileInfo(dialog->getWindowPath()).fileName(); + ui->applicationLineEdit->setText(temp); + } + } + else + { + ui->applicationLineEdit->clear(); + } + + if (dialog->getSelectedOptions() & CapturedWindowInfoDialog::WindowClass) + { + ui->winClassLineEdit->setText(dialog->getWindowClass()); + } + else + { + ui->winClassLineEdit->clear(); + } + + if (dialog->getSelectedOptions() & CapturedWindowInfoDialog::WindowName) + { + ui->winNameLineEdit->setText(dialog->getWindowName()); + } + else + { + ui->winNameLineEdit->clear(); + } + + checkForDefaultStatus(); + + connect(ui->applicationLineEdit, SIGNAL(textChanged(QString)), this, SLOT(checkForDefaultStatus())); + connect(ui->winClassLineEdit, SIGNAL(textChanged(QString)), this, SLOT(checkForDefaultStatus())); + connect(ui->winNameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(checkForDefaultStatus())); +} + + +void AddEditAutoProfileDialog::checkForDefaultStatus() +{ + bool status = ui->applicationLineEdit->text().length() > 0; + status = status ? status : ui->winClassLineEdit->text().length() > 0; + status = status ? status : ui->winNameLineEdit->text().length() > 0; + + if (status) + { + ui->asDefaultCheckBox->setChecked(false); + ui->asDefaultCheckBox->setEnabled(false); + } + else + { + ui->asDefaultCheckBox->setEnabled(true); + } +} + +/** + * @brief Validate the form that is contained in this window + */ +void AddEditAutoProfileDialog::accept() +{ + bool validForm = true; + bool propertyFound = false; + + QString errorString; + if (ui->profileLineEdit->text().length() > 0) + { + QString profileFilename = ui->profileLineEdit->text(); + QFileInfo info(profileFilename); + if (!info.exists()) + { + validForm = false; + errorString = tr("Profile file path is invalid."); + } + } + + if (validForm && + (ui->applicationLineEdit->text().isEmpty() && + ui->winClassLineEdit->text().isEmpty() && + ui->winNameLineEdit->text().isEmpty())) + { + validForm = false; + errorString = tr("No window matching property was specified."); + } + else + { + propertyFound = true; + } + + if (validForm && !ui->applicationLineEdit->text().isEmpty()) + { + QString exeFileName = ui->applicationLineEdit->text(); + QFileInfo info(exeFileName); + if (info.isAbsolute() && (!info.exists() || !info.isExecutable())) + { + validForm = false; + errorString = tr("Program path is invalid or not executable."); + } +#ifdef Q_OS_WIN + else if (!info.isAbsolute() && + (info.fileName() != exeFileName || + info.suffix() != "exe")) + { + validForm = false; + errorString = tr("File is not an .exe file."); + } +#endif + } + + if (validForm && !propertyFound && !ui->asDefaultCheckBox->isChecked()) + { + validForm = false; + errorString = tr("No window matching property was selected."); + } + + if (validForm) + { + QDialog::accept(); + } + else + { + QMessageBox msgBox; + msgBox.setText(errorString); + msgBox.setStandardButtons(QMessageBox::Close); + msgBox.exec(); + } +} + +#ifdef Q_OS_WIN +void AddEditAutoProfileDialog::openWinAppProfileDialog() +{ + WinAppProfileTimerDialog *dialog = new WinAppProfileTimerDialog(this); + connect(dialog, SIGNAL(accepted()), this, SLOT(captureWindowsApplicationPath())); + dialog->show(); +} + +void AddEditAutoProfileDialog::captureWindowsApplicationPath() +{ + CapturedWindowInfoDialog *dialog = new CapturedWindowInfoDialog(this); + connect(dialog, SIGNAL(accepted()), this, SLOT(windowPropAssignment())); + dialog->show(); + + /*QString temp = WinExtras::getForegroundWindowExePath(); + if (!temp.isEmpty()) + { + ui->applicationLineEdit->setText(temp); + } + */ +} + +#endif diff --git a/src/addeditautoprofiledialog.h b/src/addeditautoprofiledialog.h new file mode 100644 index 0000000..4cd60f8 --- /dev/null +++ b/src/addeditautoprofiledialog.h @@ -0,0 +1,84 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef ADDEDITAUTOPROFILEDIALOG_H +#define ADDEDITAUTOPROFILEDIALOG_H + +#include + +#include "autoprofileinfo.h" +#include "inputdevice.h" +#include "antimicrosettings.h" + +namespace Ui { +class AddEditAutoProfileDialog; +} + +class AddEditAutoProfileDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AddEditAutoProfileDialog(AutoProfileInfo *info, AntiMicroSettings *settings, QList *devices, + QList &reservedGUIDS, + bool edit=false, QWidget *parent = 0); + ~AddEditAutoProfileDialog(); + + AutoProfileInfo* getAutoProfile(); + QString getOriginalGUID(); + QString getOriginalExe(); + QString getOriginalWindowClass(); + QString getOriginalWindowName(); + +protected: + virtual void accept(); + + AutoProfileInfo *info; + QList *devices; + AntiMicroSettings *settings; + bool editForm; + bool defaultInfo; + QList reservedGUIDs; + QString originalGUID; + QString originalExe; + QString originalWindowClass; + QString originalWindowName; + +private: + Ui::AddEditAutoProfileDialog *ui; + +signals: + void captureFinished(); + +private slots: + void openProfileBrowseDialog(); + void openApplicationBrowseDialog(); + void saveAutoProfileInformation(); + void checkForReservedGUIDs(int index); + void checkForDefaultStatus(); + void windowPropAssignment(); + +#ifdef Q_OS_WIN + void openWinAppProfileDialog(); + void captureWindowsApplicationPath(); +#else + void showCaptureHelpWindow(); + void checkForGrabbedWindow(); +#endif +}; + +#endif // ADDEDITAUTOPROFILEDIALOG_H diff --git a/src/addeditautoprofiledialog.ui b/src/addeditautoprofiledialog.ui new file mode 100644 index 0000000..5a767c7 --- /dev/null +++ b/src/addeditautoprofiledialog.ui @@ -0,0 +1,237 @@ + + + AddEditAutoProfileDialog + + + + 0 + 0 + 478 + 327 + + + + Auto Profile Dialog + + + true + + + + + + + + Profile: + + + profileLineEdit + + + + + + + + + + + + Browse + + + + + + + + + + + Window: + + + false + + + false + + + + 6 + + + 4 + + + + + Select Window. Click on the appropriate application +window and the application file path will be populated +in the form. + + + Detect Window Properties + + + + + + + + + Class: + + + applicationLineEdit + + + + + + + + + + + + + + Title: + + + applicationLineEdit + + + + + + + + + + + + + + Application: + + + applicationLineEdit + + + + + + + + + + Browse + + + + + + + Select Window. Click on the appropriate application +window and the application file path will be populated +in the form. + + + Select + + + + + + + + + + + + + + Devices: + + + devicesComboBox + + + + + + + + + + false + + + Select this profile to be the default loaded for +the specified device. The selection will be used instead +of the all default profile option. + + + Set as Default for Controller + + + + + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + AddEditAutoProfileDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + AddEditAutoProfileDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/advancebuttondialog.cpp b/src/advancebuttondialog.cpp new file mode 100644 index 0000000..0be7fec --- /dev/null +++ b/src/advancebuttondialog.cpp @@ -0,0 +1,1554 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +//#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "advancebuttondialog.h" +#include "ui_advancebuttondialog.h" +#include "event.h" +#include "inputdevice.h" +//#include "logger.h" + +const int AdvanceButtonDialog::MINIMUMTURBO = 2; + +AdvanceButtonDialog::AdvanceButtonDialog(JoyButton *button, QWidget *parent) : + QDialog(parent, Qt::Window), + ui(new Ui::AdvanceButtonDialog), + helper(button) +{ + ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + + PadderCommon::inputDaemonMutex.lock(); + + this->button = button; + oldRow = 0; + + helper.moveToThread(button->thread()); + + if (this->button->getToggleState()) + { + ui->toggleCheckbox->setChecked(true); + } + + if (this->button->isUsingTurbo()) + { + ui->turboCheckbox->setChecked(true); + ui->turboSlider->setEnabled(true); + } + + int interval = this->button->getTurboInterval() / 10; + if (interval < MINIMUMTURBO) + { + interval = JoyButton::ENABLEDTURBODEFAULT / 10; + } + ui->turboSlider->setValue(interval); + this->changeTurboText(interval); + + QListIterator iter(*(this->button->getAssignedSlots())); + while (iter.hasNext()) + { + JoyButtonSlot *buttonslot = iter.next(); + SimpleKeyGrabberButton *existingCode = new SimpleKeyGrabberButton(this); + existingCode->setText(buttonslot->getSlotString()); + if (buttonslot->getSlotMode() == JoyButtonSlot::JoyLoadProfile) + { + if (!buttonslot->getTextData().isEmpty()) + { + existingCode->setValue(buttonslot->getTextData(), JoyButtonSlot::JoyLoadProfile); + existingCode->setToolTip(buttonslot->getTextData()); + } + } + else if (buttonslot->getSlotMode() == JoyButtonSlot::JoyTextEntry) + { + if (!buttonslot->getTextData().isEmpty()) + { + existingCode->setValue(buttonslot->getTextData(), JoyButtonSlot::JoyTextEntry); + existingCode->setToolTip(buttonslot->getTextData()); + } + } + else if (buttonslot->getSlotMode() == JoyButtonSlot::JoyExecute) + { + if (!buttonslot->getTextData().isEmpty()) + { + existingCode->setValue(buttonslot->getTextData(), JoyButtonSlot::JoyExecute); + existingCode->setToolTip(buttonslot->getTextData()); + + if (buttonslot->getExtraData().canConvert()) + { + QString argumentsTemp = buttonslot->getExtraData().toString(); + existingCode->getValue()->setExtraData(argumentsTemp); + } + } + } + else + { + existingCode->setValue(buttonslot->getSlotCode(), + buttonslot->getSlotCodeAlias(), + buttonslot->getSlotMode()); + } + + QListWidgetItem *item = new QListWidgetItem(ui->slotListWidget); + item->setData(Qt::UserRole, QVariant::fromValue(existingCode)); + QHBoxLayout *layout= new QHBoxLayout(); + layout->setContentsMargins(10, 0, 10, 0); + layout->addWidget(existingCode); + QWidget *widget = new QWidget(); + widget->setLayout(layout); + item->setSizeHint(widget->sizeHint()); + + ui->slotListWidget->setItemWidget(item, widget); + connectButtonEvents(existingCode); + } + + appendBlankKeyGrabber(); + populateSetSelectionComboBox(); + populateSlotSetSelectionComboBox(); + + if (this->button->getSetSelection() > -1 && + this->button->getChangeSetCondition() != JoyButton::SetChangeDisabled) + { + int selectIndex = (int)this->button->getChangeSetCondition(); + selectIndex += this->button->getSetSelection() * 3; + if (this->button->getOriginSet() < this->button->getSetSelection()) + { + selectIndex -= 3; + } + + ui->setSelectionComboBox->setCurrentIndex(selectIndex); + } + + fillTimeComboBoxes(); + ui->actionTenthsComboBox->setCurrentIndex(1); + + updateActionTimeLabel(); + changeTurboForSequences(); + + if (button->isCycleResetActive()) + { + ui->autoResetCycleCheckBox->setEnabled(true); + ui->autoResetCycleCheckBox->setChecked(true); + checkCycleResetWidgetStatus(true); + } + + if (button->getCycleResetTime() != 0) + { + populateAutoResetInterval(); + } + + updateWindowTitleButtonName(); + + if (this->button->isPartRealAxis() && this->button->isUsingTurbo()) + { + ui->turboModeComboBox->setEnabled(true); + } + + findTurboModeComboIndex(); + + // Don't show Set Selector page for modifier buttons + if (this->button->isModifierButton()) + { + delete ui->listWidget->item(3); + } + + //performStatsWidgetRefresh(ui->slotListWidget->currentItem()); + changeSlotHelpText(ui->slotTypeComboBox->currentIndex()); + + PadderCommon::inputDaemonMutex.unlock(); + + ui->resetCycleDoubleSpinBox->setMaximum(static_cast(JoyButton::MAXCYCLERESETTIME * 0.001)); + + connect(ui->turboCheckbox, SIGNAL(clicked(bool)), ui->turboSlider, SLOT(setEnabled(bool))); + connect(ui->turboSlider, SIGNAL(valueChanged(int)), this, SLOT(checkTurboIntervalValue(int))); + + connect(ui->insertSlotButton, SIGNAL(clicked()), this, SLOT(insertSlot())); + connect(ui->deleteSlotButton, SIGNAL(clicked()), this, SLOT(deleteSlot())); + connect(ui->clearAllPushButton, SIGNAL(clicked()), this, SLOT(clearAllSlots())); + + connect(ui->slotTypeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeSlotTypeDisplay(int))); + connect(ui->slotTypeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeSlotHelpText(int))); + + connect(ui->actionHundredthsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateActionTimeLabel())); + connect(ui->actionSecondsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateActionTimeLabel())); + connect(ui->actionMinutesComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateActionTimeLabel())); + connect(ui->actionTenthsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateActionTimeLabel())); + + connect(ui->toggleCheckbox, SIGNAL(clicked(bool)), button, SLOT(setToggle(bool))); + connect(ui->turboCheckbox, SIGNAL(clicked(bool)), this, SLOT(checkTurboSetting(bool))); + + connect(ui->setSelectionComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSetSelection())); + + connect(ui->slotListWidget, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(performStatsWidgetRefresh(QListWidgetItem*))); + + connect(ui->actionHundredthsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(checkSlotTimeUpdate())); + connect(ui->actionTenthsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(checkSlotTimeUpdate())); + connect(ui->actionSecondsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(checkSlotTimeUpdate())); + connect(ui->actionMinutesComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(checkSlotTimeUpdate())); + connect(ui->slotSetChangeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(checkSlotSetChangeUpdate())); + + connect(ui->distanceSpinBox, SIGNAL(valueChanged(int)), this, SLOT(checkSlotDistanceUpdate())); + connect(ui->mouseSpeedModSpinBox, SIGNAL(valueChanged(int)), this, SLOT(checkSlotMouseModUpdate())); + + connect(ui->autoResetCycleCheckBox, SIGNAL(clicked(bool)), this, SLOT(checkCycleResetWidgetStatus(bool))); + connect(ui->autoResetCycleCheckBox, SIGNAL(clicked(bool)), this, SLOT(setButtonCycleReset(bool))); + connect(ui->resetCycleDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(setButtonCycleResetInterval(double))); + + connect(button, SIGNAL(toggleChanged(bool)), ui->toggleCheckbox, SLOT(setChecked(bool))); + connect(button, SIGNAL(turboChanged(bool)), this, SLOT(checkTurboSetting(bool))); + connect(ui->turboModeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setButtonTurboMode(int))); + connect(ui->loadProfilePushButton, SIGNAL(clicked()), this, SLOT(showSelectProfileWindow())); + connect(ui->execToolButton, SIGNAL(clicked(bool)), this, SLOT(showFindExecutableWindow(bool))); +} + +AdvanceButtonDialog::~AdvanceButtonDialog() +{ + delete ui; +} + +void AdvanceButtonDialog::changeTurboText(int value) +{ + if (value >= MINIMUMTURBO) + { + double delay = value / 100.0; + double clicks = 100.0 / (double)value; + QString delaytext = QString::number(delay, 'g', 3).append(" ").append(tr("sec.")); + QString labeltext = QString::number(clicks, 'g', 2).append(" ").append(tr("/sec.")); + + ui->delayValueLabel->setText(delaytext); + ui->rateValueLabel->setText(labeltext); + } +} + +void AdvanceButtonDialog::updateSlotsScrollArea(int value) +{ + int index = ui->slotListWidget->currentRow(); + int itemcount = ui->slotListWidget->count(); + + if (index == (itemcount - 1) && value >= 0) + { + // New slot added on the old blank button. Append + // new blank button to the end of the list. + appendBlankKeyGrabber(); + } + + // Go through all grabber buttons in list and possibly resize widgets. + for (int i = 0; i < ui->slotListWidget->count(); i++) + { + QListWidgetItem *item = ui->slotListWidget->item(i); + QWidget *widget = ui->slotListWidget->itemWidget(item); + item->setSizeHint(widget->sizeHint()); + } + + // Alter interface if turbo cannot be used. + changeTurboForSequences(); + + emit slotsChanged(); +} + +void AdvanceButtonDialog::connectButtonEvents(SimpleKeyGrabberButton *button) +{ + connect(button, SIGNAL(clicked()), this, SLOT(changeSelectedSlot())); + connect(button, SIGNAL(buttonCodeChanged(int)), this, SLOT(updateSelectedSlot(int))); + //connect(button, SIGNAL(buttonCodeChanged(int)), this, SLOT(updateSlotsScrollArea(int))); +} + +void AdvanceButtonDialog::updateSelectedSlot(int value) +{ + SimpleKeyGrabberButton *grabbutton = static_cast(sender()); + JoyButtonSlot *tempbuttonslot = grabbutton->getValue(); + int index = ui->slotListWidget->currentRow(); + + QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, + Q_ARG(int, tempbuttonslot->getSlotCode()), + Q_ARG(unsigned int, tempbuttonslot->getSlotCodeAlias()), + Q_ARG(int, index), + Q_ARG(JoyButtonSlot::JoySlotInputAction, tempbuttonslot->getSlotMode())); + + updateSlotsScrollArea(value); +} + +void AdvanceButtonDialog::deleteSlot() +{ + int index = ui->slotListWidget->currentRow(); + int itemcount = ui->slotListWidget->count(); + + QListWidgetItem *item = ui->slotListWidget->takeItem(index); + delete item; + item = 0; + + // Deleted last button. Replace with new blank button + if (index == itemcount - 1) + { + appendBlankKeyGrabber(); + } + + changeTurboForSequences(); + + QMetaObject::invokeMethod(&helper, "removeAssignedSlot", Qt::BlockingQueuedConnection, + Q_ARG(int, index)); + + index = qMax(0, index-1); + performStatsWidgetRefresh(ui->slotListWidget->item(index)); + + emit slotsChanged(); +} + +void AdvanceButtonDialog::changeSelectedSlot() +{ + SimpleKeyGrabberButton *button = static_cast(sender()); + + bool leave = false; + for (int i = 0; i < ui->slotListWidget->count() && !leave; i++) + { + QListWidgetItem *item = ui->slotListWidget->item(i); + SimpleKeyGrabberButton *tempbutton = item->data(Qt::UserRole) + .value(); + + if (button == tempbutton) + { + ui->slotListWidget->setCurrentRow(i); + leave = true; + oldRow = i; + } + } +} + +void AdvanceButtonDialog::appendBlankKeyGrabber() +{ + SimpleKeyGrabberButton *blankButton = new SimpleKeyGrabberButton(this); + QListWidgetItem *item = new QListWidgetItem(ui->slotListWidget); + item->setData(Qt::UserRole, + QVariant::fromValue(blankButton)); + + QHBoxLayout *layout= new QHBoxLayout(); + layout->setContentsMargins(10, 0, 10, 0); + layout->addWidget(blankButton); + QWidget *widget = new QWidget(); + widget->setLayout(layout); + item->setSizeHint(widget->sizeHint()); + + ui->slotListWidget->setItemWidget(item, widget); + ui->slotListWidget->setCurrentItem(item); + connectButtonEvents(blankButton); + ui->slotTypeComboBox->setCurrentIndex(KBMouseSlot); +} + +void AdvanceButtonDialog::insertSlot() +{ + int current = ui->slotListWidget->currentRow(); + int count = ui->slotListWidget->count(); + int slotTypeIndex = ui->slotTypeComboBox->currentIndex(); + + if (slotTypeIndex == KBMouseSlot) + { + if (current != (count - 1)) + { + SimpleKeyGrabberButton *blankButton = new SimpleKeyGrabberButton(this); + QListWidgetItem *item = new QListWidgetItem(); + ui->slotListWidget->insertItem(current, item); + item->setData(Qt::UserRole, + QVariant::fromValue(blankButton)); + + QHBoxLayout *layout= new QHBoxLayout(); + layout->addWidget(blankButton); + QWidget *widget = new QWidget(); + widget->setLayout(layout); + item->setSizeHint(widget->sizeHint()); + ui->slotListWidget->setItemWidget(item, widget); + ui->slotListWidget->setCurrentItem(item); + connectButtonEvents(blankButton); + blankButton->refreshButtonLabel(); + + QMetaObject::invokeMethod(&helper, "insertAssignedSlot", Qt::BlockingQueuedConnection, + Q_ARG(int, 0), Q_ARG(uint, 0), + Q_ARG(int, current)); + + updateSlotsScrollArea(0); + } + } + else if (slotTypeIndex == CycleSlot) + { + insertCycleSlot(); + } + else if (slotTypeIndex == DelaySlot) + { + insertDelaySlot(); + } + else if (slotTypeIndex == DistanceSlot) + { + insertDistanceSlot(); + } + else if (slotTypeIndex == HoldSlot) + { + insertHoldSlot(); + } + else if (slotTypeIndex == LoadSlot) + { + showSelectProfileWindow(); + } + else if (slotTypeIndex == MouseModSlot) + { + insertMouseSpeedModSlot(); + } + else if (slotTypeIndex == PauseSlot) + { + insertPauseSlot(); + } + else if (slotTypeIndex == PressTimeSlot) + { + insertKeyPressSlot(); + } + else if (slotTypeIndex == ReleaseSlot) + { + insertReleaseSlot(); + } + else if (slotTypeIndex == SetChangeSlot) + { + insertSetChangeSlot(); + } + else if (slotTypeIndex == TextEntry) + { + insertTextEntrySlot(); + } + else if (slotTypeIndex == ExecuteSlot) + { + insertExecuteSlot(); + } +} + +void AdvanceButtonDialog::insertPauseSlot() +{ + int index = ui->slotListWidget->currentRow(); + SimpleKeyGrabberButton *tempbutton = ui->slotListWidget->currentItem() + ->data(Qt::UserRole).value(); + int actionTime = actionTimeConvert(); + if (actionTime >= 0) + { + tempbutton->setValue(actionTime, JoyButtonSlot::JoyPause); + QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, + Q_ARG(int, actionTime), + Q_ARG(unsigned int, 0), + Q_ARG(int, index), + Q_ARG(JoyButtonSlot::JoySlotInputAction, JoyButtonSlot::JoyPause)); + + updateSlotsScrollArea(actionTime); + } +} + +void AdvanceButtonDialog::insertReleaseSlot() +{ + int index = ui->slotListWidget->currentRow(); + SimpleKeyGrabberButton *tempbutton = ui->slotListWidget->currentItem() + ->data(Qt::UserRole).value(); + int actionTime = actionTimeConvert(); + if (actionTime >= 0) + { + tempbutton->setValue(actionTime, JoyButtonSlot::JoyRelease); + + QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, + Q_ARG(int, actionTime), + Q_ARG(unsigned int, 0), + Q_ARG(int, index), + Q_ARG(JoyButtonSlot::JoySlotInputAction, JoyButtonSlot::JoyRelease)); + + updateSlotsScrollArea(actionTime); + } +} + +void AdvanceButtonDialog::insertHoldSlot() +{ + int index = ui->slotListWidget->currentRow(); + SimpleKeyGrabberButton *tempbutton = ui->slotListWidget->currentItem() + ->data(Qt::UserRole).value(); + int actionTime = actionTimeConvert(); + if (actionTime > 0) + { + tempbutton->setValue(actionTime, JoyButtonSlot::JoyHold); + + QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, + Q_ARG(int, actionTime), + Q_ARG(unsigned int, 0), + Q_ARG(int, index), + Q_ARG(JoyButtonSlot::JoySlotInputAction, JoyButtonSlot::JoyHold)); + + updateSlotsScrollArea(actionTime); + } +} + +void AdvanceButtonDialog::insertSetChangeSlot() +{ + int index = ui->slotListWidget->currentRow(); + SimpleKeyGrabberButton *tempbutton = ui->slotListWidget->currentItem() + ->data(Qt::UserRole).value(); + + int currentIndex = ui->slotSetChangeComboBox->currentIndex(); + unsigned int setIndex = ui->slotSetChangeComboBox->itemData(currentIndex).toInt(); + if (setIndex >= 0) + { + tempbutton->setValue(setIndex, JoyButtonSlot::JoySetChange); + + QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, + Q_ARG(int, setIndex), + Q_ARG(unsigned int, 0), + Q_ARG(int, index), + Q_ARG(JoyButtonSlot::JoySlotInputAction, JoyButtonSlot::JoySetChange)); + + updateSlotsScrollArea(setIndex); + } +} + +int AdvanceButtonDialog::actionTimeConvert() +{ + int minutesIndex = ui->actionMinutesComboBox->currentIndex(); + int secondsIndex = ui->actionSecondsComboBox->currentIndex(); + int hundredthsIndex = ui->actionHundredthsComboBox->currentIndex(); + int tenthsIndex = ui->actionTenthsComboBox->currentIndex(); + + int tempMilliSeconds = minutesIndex * 1000 * 60; + tempMilliSeconds += secondsIndex * 1000; + tempMilliSeconds += tenthsIndex * 100; + tempMilliSeconds += hundredthsIndex * 10; + return tempMilliSeconds; +} + +void AdvanceButtonDialog::refreshTimeComboBoxes(JoyButtonSlot *slot) +{ + disconnectTimeBoxesEvents(); + + int slottime = slot->getSlotCode(); + int tempMinutes = slottime / 1000 / 60; + int tempSeconds = slottime / 1000 % 60; + int tempTenthsSeconds = (slottime % 1000) / 100; + int tempHundredthsSeconds = (slottime % 1000 % 100) / 10; + + ui->actionMinutesComboBox->setCurrentIndex(tempMinutes); + ui->actionSecondsComboBox->setCurrentIndex(tempSeconds); + ui->actionTenthsComboBox->setCurrentIndex(tempTenthsSeconds); + ui->actionHundredthsComboBox->setCurrentIndex(tempHundredthsSeconds); + updateActionTimeLabel(); + + connectTimeBoxesEvents(); +} + +void AdvanceButtonDialog::updateActionTimeLabel() +{ + int actionTime = actionTimeConvert(); + int minutes = actionTime / 1000 / 60; + double hundredths = actionTime % 1000 / 1000.0; + double seconds = (actionTime / 1000 % 60) + hundredths; + QString temp; + temp.append(QString::number(minutes)).append("m "); + temp.append(QString::number(seconds, 'f', 2)).append("s"); + ui->actionTimeLabel->setText(temp); +} + +void AdvanceButtonDialog::clearAllSlots() +{ + ui->slotListWidget->clear(); + appendBlankKeyGrabber(); + changeTurboForSequences(); + + QMetaObject::invokeMethod(button, "clearSlotsEventReset", Qt::BlockingQueuedConnection); + performStatsWidgetRefresh(ui->slotListWidget->currentItem()); + + emit slotsChanged(); +} + +void AdvanceButtonDialog::changeTurboForSequences() +{ + bool containsSequences = false; + for (int i = 0; i < ui->slotListWidget->count() && !containsSequences; i++) + { + SimpleKeyGrabberButton *button = ui->slotListWidget->item(i) + ->data(Qt::UserRole).value(); + JoyButtonSlot *tempbuttonslot = button->getValue(); + if (tempbuttonslot->getSlotCode() > 0 && + (tempbuttonslot->getSlotMode() == JoyButtonSlot::JoyPause || + tempbuttonslot->getSlotMode() == JoyButtonSlot::JoyHold || + tempbuttonslot->getSlotMode() == JoyButtonSlot::JoyDistance + ) + ) + { + containsSequences = true; + } + } + + if (containsSequences) + { + if (ui->turboCheckbox->isChecked()) + { + ui->turboCheckbox->setChecked(false); + this->button->setUseTurbo(false); + emit turboChanged(false); + } + + if (ui->turboCheckbox->isEnabled()) + { + ui->turboCheckbox->setEnabled(false); + emit turboButtonEnabledChange(false); + } + } + else + { + if (!ui->turboCheckbox->isEnabled()) + { + ui->turboCheckbox->setEnabled(true); + emit turboButtonEnabledChange(true); + } + } +} + +void AdvanceButtonDialog::insertCycleSlot() +{ + int index = ui->slotListWidget->currentRow(); + SimpleKeyGrabberButton *tempbutton = ui->slotListWidget->currentItem() + ->data(Qt::UserRole).value(); + tempbutton->setValue(1, JoyButtonSlot::JoyCycle); + + QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, + Q_ARG(int, 1), + Q_ARG(unsigned int, 0), + Q_ARG(int, index), + Q_ARG(JoyButtonSlot::JoySlotInputAction, JoyButtonSlot::JoyCycle)); + + updateSlotsScrollArea(1); +} + +void AdvanceButtonDialog::insertDistanceSlot() +{ + int index = ui->slotListWidget->currentRow(); + SimpleKeyGrabberButton *tempbutton = ui->slotListWidget->currentItem() + ->data(Qt::UserRole).value(); + + int tempDistance = 0; + for (int i = 0; i < ui->slotListWidget->count(); i++) + { + SimpleKeyGrabberButton *button = ui->slotListWidget->item(i) + ->data(Qt::UserRole).value(); + JoyButtonSlot *tempbuttonslot = button->getValue(); + if (tempbuttonslot->getSlotMode() == JoyButtonSlot::JoyDistance) + { + tempDistance += tempbuttonslot->getSlotCode(); + } + else if (tempbuttonslot->getSlotMode() == JoyButtonSlot::JoyCycle) + { + tempDistance = 0; + } + } + + int testDistance = ui->distanceSpinBox->value(); + if (testDistance + tempDistance <= 100) + { + tempbutton->setValue(testDistance, JoyButtonSlot::JoyDistance); + + QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, + Q_ARG(int, testDistance), + Q_ARG(unsigned int, 0), + Q_ARG(int, index), + Q_ARG(JoyButtonSlot::JoySlotInputAction, JoyButtonSlot::JoyDistance)); + + updateSlotsScrollArea(testDistance); + } +} + +void AdvanceButtonDialog::placeNewSlot(JoyButtonSlot *slot) +{ + int index = ui->slotListWidget->currentRow(); + SimpleKeyGrabberButton *tempbutton = ui->slotListWidget->currentItem() + ->data(Qt::UserRole).value(); + tempbutton->setValue(slot->getSlotCode(), slot->getSlotCodeAlias(), slot->getSlotMode()); + + QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, + Q_ARG(int, slot->getSlotCode()), + Q_ARG(unsigned int, slot->getSlotCodeAlias()), + Q_ARG(int, index), + Q_ARG(JoyButtonSlot::JoySlotInputAction, slot->getSlotMode())); + + updateSlotsScrollArea(slot->getSlotCode()); + + slot->deleteLater(); +} + +void AdvanceButtonDialog::updateTurboIntervalValue(int value) +{ + if (value >= MINIMUMTURBO) + { + button->setTurboInterval(value * 10); + } +} + +void AdvanceButtonDialog::checkTurboSetting(bool state) +{ + ui->turboCheckbox->setChecked(state); + ui->turboSlider->setEnabled(state); + + if (this->button->isPartRealAxis()) + { + ui->turboModeComboBox->setEnabled(state); + } + + changeTurboForSequences(); + button->setUseTurbo(state); + if (button->getTurboInterval() / 10 >= MINIMUMTURBO) + { + ui->turboSlider->setValue(button->getTurboInterval() / 10); + } +} + +void AdvanceButtonDialog::updateSetSelection() +{ + PadderCommon::inputDaemonMutex.lock(); + + int condition_choice = 0; + int chosen_set = -1; + JoyButton::SetChangeCondition set_selection_condition = JoyButton::SetChangeDisabled; + + if (ui->setSelectionComboBox->currentIndex() > 0) + { + condition_choice = (ui->setSelectionComboBox->currentIndex() + 2) % 3; + chosen_set = (ui->setSelectionComboBox->currentIndex() - 1) / 3; + + // Above removed rows + if (button->getOriginSet() > chosen_set) + { + chosen_set = (ui->setSelectionComboBox->currentIndex() - 1) / 3; + } + // Below removed rows + else + { + chosen_set = (ui->setSelectionComboBox->currentIndex() + 2) / 3; + } + + //qDebug() << "CONDITION: " << QString::number(condition_choice) << endl; + if (condition_choice == 0) + { + set_selection_condition = JoyButton::SetChangeOneWay; + } + else if (condition_choice == 1) + { + set_selection_condition = JoyButton::SetChangeTwoWay; + } + else if (condition_choice == 2) + { + set_selection_condition = JoyButton::SetChangeWhileHeld; + } + //qDebug() << "CHOSEN SET: " << chosen_set << endl; + } + else + { + chosen_set = -1; + set_selection_condition = JoyButton::SetChangeDisabled; + } + + if (chosen_set > -1 && set_selection_condition != JoyButton::SetChangeDisabled) + { + // First, remove old condition for the button in both sets. + // After that, make the new assignment. + button->setChangeSetCondition(JoyButton::SetChangeDisabled); + + button->setChangeSetSelection(chosen_set); + button->setChangeSetCondition(set_selection_condition); + } + else + { + button->setChangeSetCondition(JoyButton::SetChangeDisabled); + } + + PadderCommon::inputDaemonMutex.unlock(); +} + +void AdvanceButtonDialog::checkTurboIntervalValue(int value) +{ + if (value >= MINIMUMTURBO) + { + changeTurboText(value); + updateTurboIntervalValue(value); + } + else + { + ui->turboSlider->setValue(MINIMUMTURBO); + } +} + +void AdvanceButtonDialog::fillTimeComboBoxes() +{ + ui->actionMinutesComboBox->clear(); + ui->actionSecondsComboBox->clear(); + ui->actionHundredthsComboBox->clear(); + ui->actionTenthsComboBox->clear(); + + for (double i=0; i <= 10; i++) + { + QString temp = QString::number(i, 'g', 2).append("m"); + ui->actionMinutesComboBox->addItem(temp); + } + + for (double i=0; i <= 59; i++) + { + QString temp = QString::number(i, 'g', 2); + ui->actionSecondsComboBox->addItem(temp); + } + + for (int i=0; i < 10; i++) + { + QString temp = QString(".%1").arg(i, 1, 10, QChar('0')); + ui->actionTenthsComboBox->addItem(temp); + } + + for (int i=0; i < 10; i++) + { + QString temp = QString("%1s").arg(i, 1, 10, QChar('0')); + ui->actionHundredthsComboBox->addItem(temp); + } +} + +void AdvanceButtonDialog::insertMouseSpeedModSlot() +{ + int index = ui->slotListWidget->currentRow(); + SimpleKeyGrabberButton *tempbutton = ui->slotListWidget->currentItem() + ->data(Qt::UserRole).value(); + int tempMouseMod = ui->mouseSpeedModSpinBox->value(); + if (tempMouseMod > 0) + { + tempbutton->setValue(tempMouseMod, JoyButtonSlot::JoyMouseSpeedMod); + + QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, + Q_ARG(int, tempMouseMod), + Q_ARG(unsigned int, 0), + Q_ARG(int, index), + Q_ARG(JoyButtonSlot::JoySlotInputAction, JoyButtonSlot::JoyMouseSpeedMod)); + + updateSlotsScrollArea(tempMouseMod); + } +} + +void AdvanceButtonDialog::insertKeyPressSlot() +{ + int index = ui->slotListWidget->currentRow(); + SimpleKeyGrabberButton *tempbutton = ui->slotListWidget->currentItem() + ->data(Qt::UserRole).value(); + int actionTime = actionTimeConvert(); + if (actionTime > 0) + { + tempbutton->setValue(actionTime, JoyButtonSlot::JoyKeyPress); + + QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, + Q_ARG(int, actionTime), + Q_ARG(unsigned int, 0), + Q_ARG(int, index), + Q_ARG(JoyButtonSlot::JoySlotInputAction, JoyButtonSlot::JoyKeyPress)); + + updateSlotsScrollArea(actionTime); + } +} + +void AdvanceButtonDialog::insertDelaySlot() +{ + //PadderCommon::lockInputDevices(); + + int index = ui->slotListWidget->currentRow(); + SimpleKeyGrabberButton *tempbutton = ui->slotListWidget->currentItem() + ->data(Qt::UserRole).value(); + int actionTime = actionTimeConvert(); + if (actionTime > 0) + { + tempbutton->setValue(actionTime, JoyButtonSlot::JoyDelay); + + QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, + Q_ARG(int, actionTime), + Q_ARG(unsigned int, 0), + Q_ARG(int, index), + Q_ARG(JoyButtonSlot::JoySlotInputAction, JoyButtonSlot::JoyDelay)); + + updateSlotsScrollArea(actionTime); + } +} + +void AdvanceButtonDialog::insertTextEntrySlot() +{ + int index = ui->slotListWidget->currentRow(); + SimpleKeyGrabberButton *tempbutton = ui->slotListWidget->currentItem() + ->data(Qt::UserRole).value(); + QString temp = ui->textEntryLineEdit->text(); + if (!temp.isEmpty()) + { + tempbutton->setValue(temp, JoyButtonSlot::JoyTextEntry); + + QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, + Q_ARG(JoyButtonSlot*, tempbutton->getValue()), + Q_ARG(int, index)); + tempbutton->setToolTip(temp); + updateSlotsScrollArea(0); + } +} + +void AdvanceButtonDialog::insertExecuteSlot() +{ + int index = ui->slotListWidget->currentRow(); + SimpleKeyGrabberButton *tempbutton = ui->slotListWidget->currentItem() + ->data(Qt::UserRole).value(); + QString temp = ui->execLineEdit->text(); + QString argumentsTemp = ui->execArgumentsLineEdit->text(); + if (!temp.isEmpty()) + { + QFileInfo tempFileInfo(temp); + if (tempFileInfo.exists() && tempFileInfo.isExecutable()) + { + tempbutton->setValue(temp, JoyButtonSlot::JoyExecute); + if (!argumentsTemp.isEmpty()) + { + tempbutton->getValue()->setExtraData(QVariant(argumentsTemp)); + } + + QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, + Q_ARG(JoyButtonSlot*, tempbutton->getValue()), + Q_ARG(int, index)); + + tempbutton->setToolTip(temp); + updateSlotsScrollArea(0); + } + } +} + +void AdvanceButtonDialog::performStatsWidgetRefresh(QListWidgetItem *item) +{ + SimpleKeyGrabberButton *tempbutton = item->data(Qt::UserRole).value(); + JoyButtonSlot *slot = tempbutton->getValue(); + + if (slot->getSlotMode() == JoyButtonSlot::JoyKeyboard && slot->getSlotCode() != 0) + { + ui->slotTypeComboBox->setCurrentIndex(KBMouseSlot); + } + else if (slot->getSlotMode() == JoyButtonSlot::JoyMouseButton || + slot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) + { + ui->slotTypeComboBox->setCurrentIndex(KBMouseSlot); + } + else if (slot->getSlotMode() == JoyButtonSlot::JoyCycle) + { + ui->slotTypeComboBox->setCurrentIndex(CycleSlot); + } + else if (slot->getSlotMode() == JoyButtonSlot::JoyDelay) + { + ui->slotTypeComboBox->setCurrentIndex(DelaySlot); + //changeSlotTypeDisplay(DelaySlot); + refreshTimeComboBoxes(slot); + } + else if (slot->getSlotMode() == JoyButtonSlot::JoyDistance) + { + ui->slotTypeComboBox->setCurrentIndex(DistanceSlot); + + disconnect(ui->distanceSpinBox, SIGNAL(valueChanged(int)), + this, SLOT(checkSlotDistanceUpdate())); + ui->distanceSpinBox->setValue(slot->getSlotCode()); + connect(ui->distanceSpinBox, SIGNAL(valueChanged(int)), + this, SLOT(checkSlotDistanceUpdate())); + } + else if (slot->getSlotMode() == JoyButtonSlot::JoyHold) + { + ui->slotTypeComboBox->setCurrentIndex(HoldSlot); + refreshTimeComboBoxes(slot); + } + else if (slot->getSlotMode() == JoyButtonSlot::JoyLoadProfile) + { + ui->slotTypeComboBox->setCurrentIndex(LoadSlot); + } + else if (slot->getSlotMode() == JoyButtonSlot::JoyMouseSpeedMod) + { + ui->slotTypeComboBox->setCurrentIndex(MouseModSlot); + disconnect(ui->mouseSpeedModSpinBox, SIGNAL(valueChanged(int)), + this, SLOT(checkSlotMouseModUpdate())); + ui->mouseSpeedModSpinBox->setValue(slot->getSlotCode()); + connect(ui->mouseSpeedModSpinBox, SIGNAL(valueChanged(int)), + this, SLOT(checkSlotMouseModUpdate())); + } + else if (slot->getSlotMode() == JoyButtonSlot::JoyPause) + { + ui->slotTypeComboBox->setCurrentIndex(PauseSlot); + refreshTimeComboBoxes(slot); + } + else if (slot->getSlotMode() == JoyButtonSlot::JoyKeyPress) + { + ui->slotTypeComboBox->setCurrentIndex(PressTimeSlot); + refreshTimeComboBoxes(slot); + } + else if (slot->getSlotMode() == JoyButtonSlot::JoyRelease) + { + ui->slotTypeComboBox->setCurrentIndex(ReleaseSlot); + refreshTimeComboBoxes(slot); + } + else if (slot->getSlotMode() == JoyButtonSlot::JoySetChange) + { + disconnect(ui->slotSetChangeComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(checkSlotSetChangeUpdate())); + + ui->slotTypeComboBox->setCurrentIndex(SetChangeSlot); + unsigned int chooseIndex = slot->getSlotCode(); + + int foundIndex = ui->slotSetChangeComboBox->findData(QVariant(chooseIndex)); + if (foundIndex >= 0) + { + ui->slotSetChangeComboBox->setCurrentIndex(foundIndex); + } + + connect(ui->slotSetChangeComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(checkSlotSetChangeUpdate())); + } + else if (slot->getSlotMode() == JoyButtonSlot::JoyTextEntry) + { + ui->slotTypeComboBox->setCurrentIndex(TextEntry); + ui->textEntryLineEdit->setText(slot->getTextData()); + } + else if (slot->getSlotMode() == JoyButtonSlot::JoyExecute) + { + ui->slotTypeComboBox->setCurrentIndex(ExecuteSlot); + ui->execLineEdit->setText(slot->getTextData()); + ui->execArgumentsLineEdit->setText(slot->getExtraData().toString()); + } + /*else + { + ui->slotTypeComboBox->setCurrentIndex(KBMouseSlot); + } + */ +} + +void AdvanceButtonDialog::checkSlotTimeUpdate() +{ + int index = ui->slotListWidget->currentRow(); + SimpleKeyGrabberButton *tempbutton = ui->slotListWidget->currentItem() + ->data(Qt::UserRole).value(); + JoyButtonSlot *tempbuttonslot = tempbutton->getValue(); + if (tempbuttonslot->getSlotMode() == JoyButtonSlot::JoyPause || + tempbuttonslot->getSlotMode() == JoyButtonSlot::JoyHold || + tempbuttonslot->getSlotMode() == JoyButtonSlot::JoyRelease || + tempbuttonslot->getSlotMode() == JoyButtonSlot::JoyKeyPress || + tempbuttonslot->getSlotMode() == JoyButtonSlot::JoyDelay) + { + int actionTime = actionTimeConvert(); + if (actionTime > 0) + { + tempbutton->setValue(actionTime, tempbuttonslot->getSlotMode()); + + QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, + Q_ARG(int, actionTime), + Q_ARG(unsigned int, 0), + Q_ARG(int, index), + Q_ARG(JoyButtonSlot::JoySlotInputAction, tempbuttonslot->getSlotMode())); + + updateSlotsScrollArea(actionTime); + } + } +} + +void AdvanceButtonDialog::checkSlotMouseModUpdate() +{ + int index = ui->slotListWidget->currentRow(); + SimpleKeyGrabberButton *tempbutton = ui->slotListWidget->currentItem() + ->data(Qt::UserRole).value(); + JoyButtonSlot *tempbuttonslot = tempbutton->getValue(); + + int tempMouseMod = ui->mouseSpeedModSpinBox->value(); + if (tempbuttonslot->getSlotMode() == JoyButtonSlot::JoyMouseSpeedMod && + tempMouseMod > 0) + { + tempbutton->setValue(tempMouseMod, tempbuttonslot->getSlotMode()); + + QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, + Q_ARG(int, tempMouseMod), + Q_ARG(unsigned int, 0), + Q_ARG(int, index), + Q_ARG(JoyButtonSlot::JoySlotInputAction, tempbuttonslot->getSlotMode())); + + updateSlotsScrollArea(tempMouseMod); + } +} + +void AdvanceButtonDialog::checkSlotSetChangeUpdate() +{ + int index = ui->slotListWidget->currentRow(); + SimpleKeyGrabberButton *tempbutton = ui->slotListWidget->currentItem() + ->data(Qt::UserRole).value(); + JoyButtonSlot *buttonslot = tempbutton->getValue(); + if (buttonslot->getSlotMode() == JoyButtonSlot::JoySetChange) + { + int comboIndex = ui->slotSetChangeComboBox->currentIndex(); + int setIndex = ui->slotSetChangeComboBox->itemData(comboIndex).toInt(); + + if (setIndex >= 0) + { + tempbutton->setValue(setIndex, buttonslot->getSlotMode()); + + QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, + Q_ARG(int, setIndex), + Q_ARG(unsigned int, 0), + Q_ARG(int, index), + Q_ARG(JoyButtonSlot::JoySlotInputAction, buttonslot->getSlotMode())); + + updateSlotsScrollArea(setIndex); + } + } +} + +void AdvanceButtonDialog::checkSlotDistanceUpdate() +{ + int index = ui->slotListWidget->currentRow(); + SimpleKeyGrabberButton *tempbutton = ui->slotListWidget->currentItem() + ->data(Qt::UserRole).value(); + JoyButtonSlot *buttonslot = tempbutton->getValue(); + int tempDistance = 0; + + if (buttonslot->getSlotMode() == JoyButtonSlot::JoyDistance) + { + for (int i = 0; i < ui->slotListWidget->count(); i++) + { + SimpleKeyGrabberButton *button = ui->slotListWidget->item(i) + ->data(Qt::UserRole).value(); + JoyButtonSlot *tempbuttonslot = button->getValue(); + if (tempbuttonslot->getSlotMode() == JoyButtonSlot::JoyDistance) + { + tempDistance += tempbuttonslot->getSlotCode(); + } + else if (tempbuttonslot->getSlotMode() == JoyButtonSlot::JoyCycle) + { + tempDistance = 0; + } + } + + int testDistance = ui->distanceSpinBox->value(); + tempDistance += testDistance - buttonslot->getSlotCode(); + if (tempDistance <= 100) + { + tempbutton->setValue(testDistance, buttonslot->getSlotMode()); + + QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, + Q_ARG(int, testDistance), + Q_ARG(unsigned int, 0), + Q_ARG(int, index), + Q_ARG(JoyButtonSlot::JoySlotInputAction, buttonslot->getSlotMode())); + + updateSlotsScrollArea(testDistance); + } + } +} + +void AdvanceButtonDialog::updateWindowTitleButtonName() +{ + QString temp; + temp.append(tr("Advanced").append(": ")).append(button->getPartialName(false, true)); + + if (button->getParentSet()->getIndex() != 0) + { + unsigned int setIndex = button->getParentSet()->getRealIndex(); + temp.append(" [").append(tr("Set %1").arg(setIndex)); + + QString setName = button->getParentSet()->getName(); + if (!setName.isEmpty()) + { + temp.append(": ").append(setName); + } + + temp.append("]"); + } + + setWindowTitle(temp); +} + +void AdvanceButtonDialog::checkCycleResetWidgetStatus(bool enabled) +{ + if (enabled) + { + ui->resetCycleDoubleSpinBox->setEnabled(true); + } + else + { + ui->resetCycleDoubleSpinBox->setEnabled(false); + } +} + +void AdvanceButtonDialog::setButtonCycleResetInterval(double value) +{ + unsigned int milliseconds = ((int)value * 1000) + (fmod(value, 1.0) * 1000); + button->setCycleResetTime(milliseconds); +} + +void AdvanceButtonDialog::populateAutoResetInterval() +{ + double seconds = button->getCycleResetTime() / 1000.0; + ui->resetCycleDoubleSpinBox->setValue(seconds); +} + +void AdvanceButtonDialog::setButtonCycleReset(bool enabled) +{ + if (enabled) + { + button->setCycleResetStatus(true); + if (button->getCycleResetTime() == 0 && ui->resetCycleDoubleSpinBox->value() > 0.0) + { + double current = ui->resetCycleDoubleSpinBox->value(); + setButtonCycleResetInterval(current); + } + } + else + { + button->setCycleResetStatus(false); + } +} + +void AdvanceButtonDialog::resetTimeBoxes() +{ + disconnectTimeBoxesEvents(); + + ui->actionMinutesComboBox->setCurrentIndex(0); + ui->actionSecondsComboBox->setCurrentIndex(0); + ui->actionTenthsComboBox->setCurrentIndex(1); + ui->actionHundredthsComboBox->setCurrentIndex(0); + + updateActionTimeLabel(); + connectTimeBoxesEvents(); +} + +void AdvanceButtonDialog::disconnectTimeBoxesEvents() +{ + disconnect(ui->actionSecondsComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(updateActionTimeLabel())); + disconnect(ui->actionHundredthsComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(updateActionTimeLabel())); + disconnect(ui->actionMinutesComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(updateActionTimeLabel())); + disconnect(ui->actionTenthsComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(updateActionTimeLabel())); + + disconnect(ui->actionHundredthsComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(checkSlotTimeUpdate())); + disconnect(ui->actionSecondsComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(checkSlotTimeUpdate())); + disconnect(ui->actionMinutesComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(checkSlotTimeUpdate())); + disconnect(ui->actionTenthsComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(checkSlotTimeUpdate())); +} + +void AdvanceButtonDialog::connectTimeBoxesEvents() +{ + connect(ui->actionSecondsComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(updateActionTimeLabel())); + connect(ui->actionHundredthsComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(updateActionTimeLabel())); + connect(ui->actionMinutesComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(updateActionTimeLabel())); + connect(ui->actionTenthsComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(updateActionTimeLabel())); + + connect(ui->actionHundredthsComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(checkSlotTimeUpdate())); + connect(ui->actionSecondsComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(checkSlotTimeUpdate())); + connect(ui->actionMinutesComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(checkSlotTimeUpdate())); + connect(ui->actionTenthsComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(checkSlotTimeUpdate())); +} + +void AdvanceButtonDialog::populateSetSelectionComboBox() +{ + ui->setSelectionComboBox->clear(); + ui->setSelectionComboBox->insertItem(0, tr("Disabled")); + + int currentIndex = 1; + for (int i=0; i < InputDevice::NUMBER_JOYSETS; i++) + { + if (this->button->getOriginSet() != i) + { + QString temp; + temp.append(tr("Select Set %1").arg(i+1)); + + InputDevice *tempdevice = button->getParentSet()->getInputDevice(); + SetJoystick *tempset = tempdevice->getSetJoystick(i); + if (tempset) + { + QString setName = tempset->getName(); + if (!setName.isEmpty()) + { + temp.append(" ").append("["); + temp.append(setName).append("]").append(" "); + } + } + + QString oneWayText; + oneWayText.append(temp).append(" ").append(tr("One Way")); + + QString twoWayText; + twoWayText.append(temp).append(" ").append(tr("Two Way")); + + QString whileHeldText; + whileHeldText.append(temp).append(" ").append(tr("While Held")); + + QStringList setChoices; + setChoices.append(oneWayText); + setChoices.append(twoWayText); + setChoices.append(whileHeldText); + + ui->setSelectionComboBox->insertItems(currentIndex, setChoices); + currentIndex += 3; + } + } +} + +void AdvanceButtonDialog::populateSlotSetSelectionComboBox() +{ + ui->slotSetChangeComboBox->clear(); + + unsigned int currentIndex = 0; + for (int i=0; i < InputDevice::NUMBER_JOYSETS; i++) + { + if (this->button->getOriginSet() != i) + { + QString temp; + temp.append(tr("Select Set %1").arg(i+1)); + + InputDevice *tempdevice = button->getParentSet()->getInputDevice(); + SetJoystick *tempset = tempdevice->getSetJoystick(i); + if (tempset) + { + QString setName = tempset->getName(); + if (!setName.isEmpty()) + { + temp.append(" ").append("["); + temp.append(setName).append("]").append(" "); + } + } + + ui->slotSetChangeComboBox->insertItem(currentIndex, temp, QVariant(i)); + currentIndex++; + } + } +} + +void AdvanceButtonDialog::findTurboModeComboIndex() +{ + JoyButton::TurboMode currentTurboMode = this->button->getTurboMode(); + if (currentTurboMode == JoyButton::NormalTurbo) + { + ui->turboModeComboBox->setCurrentIndex(0); + } + else if (currentTurboMode == JoyButton::GradientTurbo) + { + ui->turboModeComboBox->setCurrentIndex(1); + } + else if (currentTurboMode == JoyButton::PulseTurbo) + { + ui->turboModeComboBox->setCurrentIndex(2); + } +} + +void AdvanceButtonDialog::setButtonTurboMode(int value) +{ + if (value == 0) + { + this->button->setTurboMode(JoyButton::NormalTurbo); + } + else if (value == 1) + { + this->button->setTurboMode(JoyButton::GradientTurbo); + } + else if (value == 2) + { + this->button->setTurboMode(JoyButton::PulseTurbo); + } +} + +void AdvanceButtonDialog::showSelectProfileWindow() +{ + AntiMicroSettings *settings = this->button->getParentSet()->getInputDevice()->getSettings(); + + QString lookupDir = PadderCommon::preferredProfileDir(settings); + QString filename = QFileDialog::getOpenFileName(this, tr("Choose Profile"), + lookupDir, tr("Config Files (*.amgp *.xml)")); + if (!filename.isEmpty()) + { + int index = ui->slotListWidget->currentRow(); + SimpleKeyGrabberButton *tempbutton = ui->slotListWidget->currentItem() + ->data(Qt::UserRole).value(); + tempbutton->setValue(filename, JoyButtonSlot::JoyLoadProfile); + + QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, + Q_ARG(JoyButtonSlot*, tempbutton->getValue()), + Q_ARG(int, index)); + + tempbutton->setToolTip(filename); + updateSlotsScrollArea(0); + } +} + +void AdvanceButtonDialog::showFindExecutableWindow(bool) +{ + QString temp = ui->execLineEdit->text(); + QString lookupDir = QDir::homePath(); + if (!temp.isEmpty()) + { + QFileInfo tempFileInfo(temp); + if (tempFileInfo.absoluteDir().exists()) + { + lookupDir = tempFileInfo.absoluteDir().absolutePath(); + } + } + + QString filepath = QFileDialog::getOpenFileName(this, tr("Choose Executable"), lookupDir); + if (!filepath.isEmpty()) + { + QFileInfo tempFileInfo(filepath); + if (tempFileInfo.exists() && tempFileInfo.isExecutable()) + { + ui->execLineEdit->setText(filepath); + } + } +} + +void AdvanceButtonDialog::changeSlotTypeDisplay(int index) +{ + if (index == KBMouseSlot) + { + ui->slotControlsStackedWidget->setCurrentIndex(0); + } + else if (index == CycleSlot) + { + ui->slotControlsStackedWidget->setCurrentIndex(3); + } + else if (index == DelaySlot) + { + ui->slotControlsStackedWidget->setCurrentIndex(0); + } + else if (index == DistanceSlot) + { + ui->slotControlsStackedWidget->setCurrentIndex(2); + } + else if (index == HoldSlot) + { + ui->slotControlsStackedWidget->setCurrentIndex(0); + } + else if (index == LoadSlot) + { + ui->slotControlsStackedWidget->setCurrentIndex(4); + } + else if (index == MouseModSlot) + { + ui->slotControlsStackedWidget->setCurrentIndex(1); + } + else if (index == PauseSlot) + { + ui->slotControlsStackedWidget->setCurrentIndex(0); + } + else if (index == PressTimeSlot) + { + ui->slotControlsStackedWidget->setCurrentIndex(0); + } + else if (index == ReleaseSlot) + { + ui->slotControlsStackedWidget->setCurrentIndex(0); + } + else if (index == SetChangeSlot) + { + ui->slotControlsStackedWidget->setCurrentIndex(5); + } + else if (index == TextEntry) + { + ui->slotControlsStackedWidget->setCurrentIndex(6); + } + else if (index == ExecuteSlot) + { + ui->slotControlsStackedWidget->setCurrentIndex(7); + } +} + +void AdvanceButtonDialog::changeSlotHelpText(int index) +{ + if (index == KBMouseSlot) + { + ui->slotTypeHelpLabel->setText(tr("Insert a new blank slot.")); + } + else if (index == CycleSlot) + { + ui->slotTypeHelpLabel->setText(tr("Slots past a Cycle action will be executed " + "on the next button press. Multiple cycles can be added " + "in order to create partitions in a sequence.")); + } + else if (index == DelaySlot) + { + ui->slotTypeHelpLabel->setText(tr("Delays the time that the next slot is activated " + "by the time specified. Slots activated before the " + "delay will remain active after the delay time " + "has passed.")); + } + else if (index == DistanceSlot) + { + ui->slotTypeHelpLabel->setText(tr("Distance action specifies that the slots afterwards " + "will only be executed when an axis is moved " + "a certain range past the designated dead zone.")); + } + else if (index == HoldSlot) + { + ui->slotTypeHelpLabel->setText(tr("Insert a hold action. Slots after the action will only be " + "executed if the button is held past the interval specified.")); + } + else if (index == LoadSlot) + { + ui->slotTypeHelpLabel->setText(tr("Chose a profile to load when this slot is activated.")); + } + else if (index == MouseModSlot) + { + ui->slotTypeHelpLabel->setText(tr("Mouse mod action will modify all mouse speed settings " + "by a specified percentage while the action is being processed. " + "This can be useful for slowing down the mouse while " + "sniping.")); + } + else if (index == PauseSlot) + { + ui->slotTypeHelpLabel->setText(tr("Insert a pause that occurs in between key presses.")); + } + else if (index == PressTimeSlot) + { + ui->slotTypeHelpLabel->setText(tr("Specify the time that keys past this slot should be " + "held down.")); + } + else if (index == ReleaseSlot) + { + ui->slotTypeHelpLabel->setText(tr("Insert a release action. Slots after the action will only be " + "executed after a button release if the button was held " + "past the interval specified.")); + } + else if (index == SetChangeSlot) + { + ui->slotTypeHelpLabel->setText(tr("Change to selected set once slot is activated.")); + } + else if (index == TextEntry) + { + ui->slotTypeHelpLabel->setText(tr("Full string will be typed when a " + "slot is activated.")); + } + else if (index == ExecuteSlot) + { + ui->slotTypeHelpLabel->setText(tr("Execute program when slot is activated.")); + } +} diff --git a/src/advancebuttondialog.h b/src/advancebuttondialog.h new file mode 100644 index 0000000..f7eb9c0 --- /dev/null +++ b/src/advancebuttondialog.h @@ -0,0 +1,124 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef ADVANCEBUTTONDIALOG_H +#define ADVANCEBUTTONDIALOG_H + +#include +#include + +#include "joybutton.h" +#include "simplekeygrabberbutton.h" +#include "uihelpers/advancebuttondialoghelper.h" + +namespace Ui { +class AdvanceButtonDialog; +} + +class AdvanceButtonDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AdvanceButtonDialog(JoyButton *button, QWidget *parent=0); + ~AdvanceButtonDialog(); + +private: + Ui::AdvanceButtonDialog *ui; + + enum SlotTypeComboIndex { + KBMouseSlot = 0, CycleSlot, DelaySlot, DistanceSlot, ExecuteSlot, + HoldSlot, LoadSlot, MouseModSlot, PauseSlot, PressTimeSlot, + ReleaseSlot, SetChangeSlot, TextEntry, + }; + +protected: + void connectButtonEvents(SimpleKeyGrabberButton *button); + void appendBlankKeyGrabber(); + int actionTimeConvert(); + void changeTurboForSequences(); + void fillTimeComboBoxes(); + void refreshTimeComboBoxes(JoyButtonSlot *slot); + void updateWindowTitleButtonName(); + void populateAutoResetInterval(); + void disconnectTimeBoxesEvents(); + void connectTimeBoxesEvents(); + void resetTimeBoxes(); + void populateSetSelectionComboBox(); + void populateSlotSetSelectionComboBox(); + void findTurboModeComboIndex(); + + int oldRow; + JoyButton *button; + AdvanceButtonDialogHelper helper; + static const int MINIMUMTURBO; + +signals: + void toggleChanged(bool state); + void turboChanged(bool state); + void slotsChanged(); + void turboButtonEnabledChange(bool state); + +public slots: + void placeNewSlot(JoyButtonSlot *slot); + void clearAllSlots(); + +private slots: + void changeTurboText(int value); + void updateTurboIntervalValue(int value); + void checkTurboSetting(bool state); + + void updateSlotsScrollArea(int value); + void deleteSlot(); + void changeSelectedSlot(); + void insertSlot(); + void updateSelectedSlot(int value); + + void insertPauseSlot(); + void insertHoldSlot(); + void insertCycleSlot(); + void insertDistanceSlot(); + void insertReleaseSlot(); + void insertMouseSpeedModSlot(); + void insertKeyPressSlot(); + void insertDelaySlot(); + void insertSetChangeSlot(); + void insertTextEntrySlot(); + void insertExecuteSlot(); + + void updateActionTimeLabel(); + void updateSetSelection(); + void checkTurboIntervalValue(int value); + void performStatsWidgetRefresh(QListWidgetItem *item); + + void checkSlotTimeUpdate(); + void checkSlotMouseModUpdate(); + void checkSlotDistanceUpdate(); + void checkSlotSetChangeUpdate(); + + void checkCycleResetWidgetStatus(bool enabled); + void setButtonCycleResetInterval(double value); + void setButtonCycleReset(bool enabled); + void setButtonTurboMode(int value); + void showSelectProfileWindow(); + void showFindExecutableWindow(bool); + + void changeSlotTypeDisplay(int index); + void changeSlotHelpText(int index); +}; + +#endif // ADVANCEBUTTONDIALOG_H diff --git a/src/advancebuttondialog.ui b/src/advancebuttondialog.ui new file mode 100644 index 0000000..9a850dd --- /dev/null +++ b/src/advancebuttondialog.ui @@ -0,0 +1,1280 @@ + + + AdvanceButtonDialog + + + Qt::NonModal + + + + 0 + 0 + 750 + 439 + + + + + 0 + 0 + + + + + 750 + 430 + + + + Advanced + + + + + + false + + + + 6 + + + 4 + + + + + 0 + + + + + true + + + + 0 + 0 + + + + + 200 + 16777215 + + + + 0 + + + + Assignments + + + + + Toggle + + + + + Turbo + + + + + Set Selector + + + + + + + + + 0 + 0 + + + + 0 + + + + + + + + 0 + 0 + + + + + 0 + 100 + + + + + 16777215 + 100 + + + + false + + + QFrame::StyledPanel + + + QFrame::Sunken + + + 1 + + + 0 + + + Qt::ScrollBarAlwaysOff + + + QListView::LeftToRight + + + 0 + + + QListView::ListMode + + + false + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 10 + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 50 + 20 + + + + + + + + + Blank or KB/M + + + + + Cycle + + + + + Delay + + + + + Distance + + + + + Execute + + + + + Hold + + + + + Load + + + + + Mouse Mod + + + + + Pause + + + + + Press Time + + + + + Release + + + + + Set Change + + + + + Text Entry + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 50 + 20 + + + + + + + + + + Insert a new blank slot. + + + Insert + + + + + + + + + + + + Delete a slot. + + + Delete + + + + + + + + + + + + Clear all currently assigned slots. + + + Clear All + + + + + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + Placeholder + + + true + + + + + + + 0 + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + 40 + + + + + + + + 0 + 0 + + + + + 75 + true + + + + Specify the duration of an inserted Pause or Hold slot. + + + Time: + + + + + + + + 50 + false + + + + 0.01s + + + + + + + + + 10 + + + + + + 0m + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + 11 + + + + 0 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + 0 + + + + 0 + + + + + + + + + 0s + + + + + + + + + + + + + + + + + + + 75 + true + + + + + + + &Mouse Speed Mod: + + + mouseSpeedModSpinBox + + + + + + + + 81 + 0 + + + + Set the percentage that mouse speeds will be modified by. + + + % + + + 1 + + + 400 + + + 1 + + + 100 + + + + + + + + + + + + + 20 + + + + + + 75 + true + + + + Specify the range past an axis dead zone in which a sequence of actions will execute. + + + Distance: + + + distanceSpinBox + + + + + + + + 81 + 0 + + + + Specify the range past an axis dead zone in which a sequence of actions will execute. + + + % + + + 1 + + + 100 + + + 1 + + + + + + + + + + + + + 10 + + + + + true + + + + 75 + true + + + + Auto Reset Cycle After + + + + + + + false + + + 60.000000000000000 + + + 0.500000000000000 + + + 1.000000000000000 + + + + + + + true + + + + 75 + true + + + + seconds + + + + + + + + + + + + + Choose Profile + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Executable: + + + + + + + + + + ... + + + + + + + + + + + Arguments: + + + + + + + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 10 + + + + + + verticalSpacer_5 + slotListWidget + + verticalSpacer_6 + slotControlsStackedWidget + slotTypeHelpLabel + verticalSpacer_2 + + + + + + + 20 + + + + + Enabled + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 302 + + + + + + + + + + + + + + + + + 0 + 0 + + + + Enabled + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + Mode: + + + + + + + false + + + <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> + + + + Normal + + + + + Gradient + + + + + Pulse + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + 6 + + + 0 + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 20 + + + + Delay: + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 20 + + + + 0.10s + + + + + + + + + false + + + + 0 + 0 + + + + 0 + + + 400 + + + 10 + + + 10 + + + true + + + Qt::Horizontal + + + false + + + false + + + QSlider::TicksBelow + + + 10 + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + + Rate: + + + + + + + 10.0/s + + + + + + + turboSlider + + verticalSpacer + + verticalSpacer_4 + + + + + + + 30 + + + + + Enabled + + + + + + + 0 + + + 30 + + + + Disabled + + + + + Select Set 1 One Way + + + + + Select Set 1 Two Way + + + + + Select Set 1 While Held + + + + + Select Set 2 One Way + + + + + Select Set 2 Two Way + + + + + Select Set 2 While Held + + + + + Select Set 3 One Way + + + + + Select Set 3 Two Way + + + + + Select Set 3 While Held + + + + + Select Set 4 One Way + + + + + Select Set 4 Two Way + + + + + Select Set 4 While Held + + + + + Select Set 5 One Way + + + + + Select Set 5 Two Way + + + + + Select Set 5 While Held + + + + + Select Set 6 One Way + + + + + Select Set 6 Two Way + + + + + Select Set 6 While Held + + + + + Select Set 7 One Way + + + + + Select Set 7 Two Way + + + + + Select Set 7 While Held + + + + + Select Set 8 One Way + + + + + Select Set 8 Two Way + + + + + Select Set 8 While Held + + + + + + + + + + Qt::Vertical + + + + 20 + 289 + + + + + + + + + + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + buttonBox + line + + + + + SlotItemListWidget + QListWidget +

    slotitemlistwidget.h
    + + + + + + buttonBox + accepted() + AdvanceButtonDialog + accept() + + + 222 + 406 + + + 157 + 274 + + + + + buttonBox + rejected() + AdvanceButtonDialog + reject() + + + 290 + 412 + + + 286 + 274 + + + + + listWidget + currentRowChanged(int) + stackedWidget + setCurrentIndex(int) + + + 119 + 90 + + + 573 + 14 + + + + + diff --git a/src/advancestickassignmentdialog.cpp b/src/advancestickassignmentdialog.cpp new file mode 100644 index 0000000..ca0d2f7 --- /dev/null +++ b/src/advancestickassignmentdialog.cpp @@ -0,0 +1,1364 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include +#include +#include + +#include "advancestickassignmentdialog.h" +#include "ui_advancestickassignmentdialog.h" +#include "joycontrolstick.h" + +AdvanceStickAssignmentDialog::AdvanceStickAssignmentDialog(Joystick *joystick, QWidget *parent) : + QDialog(parent, Qt::Window), + ui(new Ui::AdvanceStickAssignmentDialog) +{ + ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + + this->joystick = joystick; + joystick->getActiveSetJoystick()->setIgnoreEventState(true); + joystick->getActiveSetJoystick()->release(); + joystick->resetButtonDownCount(); + + QString tempHeaderLabel = ui->joystickNumberLabel->text(); + tempHeaderLabel = tempHeaderLabel.arg(joystick->getSDLName()).arg(joystick->getRealJoyNumber()); + ui->joystickNumberLabel->setText(tempHeaderLabel); + ui->joystickNumberLabel2->setText(tempHeaderLabel); + + tempHeaderLabel = ui->hatNumberLabel->text(); + tempHeaderLabel = tempHeaderLabel.arg(joystick->getNumberHats()); + ui->hatNumberLabel->setText(tempHeaderLabel); + + ui->xAxisOneComboBox->addItem("", QVariant(0)); + ui->yAxisOneComboBox->addItem("", QVariant(0)); + + ui->xAxisTwoComboBox->addItem("", QVariant(0)); + ui->yAxisTwoComboBox->addItem("", QVariant(0)); + + for (int i=0; i < joystick->getNumberAxes(); i++) + { + ui->xAxisOneComboBox->addItem(tr("Axis %1").arg(i+1), QVariant(i)); + ui->yAxisOneComboBox->addItem(tr("Axis %1").arg(i+1), QVariant(i)); + + ui->xAxisTwoComboBox->addItem(tr("Axis %1").arg(i+1), QVariant(i)); + ui->yAxisTwoComboBox->addItem(tr("Axis %1").arg(i+1), QVariant(i)); + } + + refreshStickConfiguration(); + + populateDPadComboBoxes(); + refreshVDPadConfiguration(); + +#ifndef USE_SDL_2 + ui->versionTwoMessageLabel->setVisible(false); +#endif + + connect(ui->enableOneCheckBox, SIGNAL(clicked(bool)), this, SLOT(changeStateStickOneWidgets(bool))); + connect(ui->enableTwoCheckBox, SIGNAL(clicked(bool)), this, SLOT(changeStateStickTwoWidgets(bool))); + + connect(ui->vdpadEnableCheckBox, SIGNAL(clicked(bool)), this, SLOT(changeStateVDPadWidgets(bool))); + + connect(ui->xAxisOneComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(checkForAxisAssignmentStickOne())); + connect(ui->yAxisOneComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(checkForAxisAssignmentStickOne())); + + connect(ui->xAxisTwoComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(checkForAxisAssignmentStickTwo())); + connect(ui->yAxisTwoComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(checkForAxisAssignmentStickTwo())); + + connect(ui->quickAssignStick1PushButton, SIGNAL(clicked()), this, SLOT(openQuickAssignDialogStick1())); + connect(ui->quickAssignStick2PushButton, SIGNAL(clicked()), this, SLOT(openQuickAssignDialogStick2())); + + enableVDPadComboBoxes(); + + connect(this, SIGNAL(stickConfigurationChanged()), this, SLOT(disableVDPadComboBoxes())); + connect(this, SIGNAL(stickConfigurationChanged()), this, SLOT(populateDPadComboBoxes())); + connect(this, SIGNAL(stickConfigurationChanged()), this, SLOT(refreshVDPadConfiguration())); + connect(this, SIGNAL(stickConfigurationChanged()), this, SLOT(enableVDPadComboBoxes())); + + connect(ui->vdpadUpPushButton, SIGNAL(clicked()), this, SLOT(openAssignVDPadUp())); + connect(ui->vdpadDownPushButton, SIGNAL(clicked()), this, SLOT(openAssignVDPadDown())); + connect(ui->vdpadLeftPushButton, SIGNAL(clicked()), this, SLOT(openAssignVDPadLeft())); + connect(ui->vdpadRightPushButton, SIGNAL(clicked()), this, SLOT(openAssignVDPadRight())); + + connect(this, SIGNAL(finished(int)), this, SLOT(reenableButtonEvents())); +} + +AdvanceStickAssignmentDialog::~AdvanceStickAssignmentDialog() +{ + delete ui; +} + +void AdvanceStickAssignmentDialog::checkForAxisAssignmentStickOne() +{ + if (ui->xAxisOneComboBox->currentIndex() > 0 && ui->yAxisOneComboBox->currentIndex() > 0) + { + if (ui->xAxisOneComboBox->currentIndex() != ui->yAxisOneComboBox->currentIndex()) + { + for (int i=0; i < joystick->NUMBER_JOYSETS; i++) + { + SetJoystick *currentset = joystick->getSetJoystick(i); + JoyAxis *axis1 = currentset->getJoyAxis(ui->xAxisOneComboBox->currentIndex()-1); + JoyAxis *axis2 = currentset->getJoyAxis(ui->yAxisOneComboBox->currentIndex()-1); + if (axis1 && axis2) + { + JoyControlStick *controlstick = currentset->getJoyStick(0); + if (controlstick) + { + controlstick->replaceAxes(axis1, axis2); + } + else + { + JoyControlStick *controlstick = new JoyControlStick(axis1, axis2, 0, i, currentset); + currentset->addControlStick(0, controlstick); + } + } + } + + refreshStickConfiguration(); + emit stickConfigurationChanged(); + } + else + { + if (sender() == ui->xAxisOneComboBox) + { + ui->yAxisOneComboBox->setCurrentIndex(0); + } + else if (sender() == ui->yAxisOneComboBox) + { + ui->xAxisOneComboBox->setCurrentIndex(0); + } + } + } +} + +void AdvanceStickAssignmentDialog::checkForAxisAssignmentStickTwo() +{ + if (ui->xAxisTwoComboBox->currentIndex() > 0 && ui->yAxisTwoComboBox->currentIndex() > 0) + { + if (ui->xAxisTwoComboBox->currentIndex() != ui->yAxisTwoComboBox->currentIndex()) + { + for (int i=0; i < joystick->NUMBER_JOYSETS; i++) + { + SetJoystick *currentset = joystick->getSetJoystick(i); + JoyAxis *axis1 = currentset->getJoyAxis(ui->xAxisTwoComboBox->currentIndex()-1); + JoyAxis *axis2 = currentset->getJoyAxis(ui->yAxisTwoComboBox->currentIndex()-1); + if (axis1 && axis2) + { + JoyControlStick *controlstick = currentset->getJoyStick(1); + if (controlstick) + { + controlstick->replaceXAxis(axis1); + controlstick->replaceYAxis(axis2); + } + else + { + JoyControlStick *controlstick = new JoyControlStick(axis1, axis2, 1, i, currentset); + currentset->addControlStick(1, controlstick); + } + } + } + + refreshStickConfiguration(); + emit stickConfigurationChanged(); + } + else + { + if (sender() == ui->xAxisTwoComboBox) + { + ui->yAxisTwoComboBox->setCurrentIndex(0); + } + else if (sender() == ui->yAxisTwoComboBox) + { + ui->xAxisTwoComboBox->setCurrentIndex(0); + } + } + } +} + +void AdvanceStickAssignmentDialog::changeStateVDPadWidgets(bool enabled) +{ + if (enabled) + { + ui->vdpadUpComboBox->setEnabled(true); + ui->vdpadDownComboBox->setEnabled(true); + ui->vdpadLeftComboBox->setEnabled(true); + ui->vdpadRightComboBox->setEnabled(true); + + ui->vdpadUpPushButton->setEnabled(true); + ui->vdpadDownPushButton->setEnabled(true); + ui->vdpadLeftPushButton->setEnabled(true); + ui->vdpadRightPushButton->setEnabled(true); + + for (int i=0; i < joystick->NUMBER_JOYSETS; i++) + { + SetJoystick *currentset = joystick->getSetJoystick(i); + if (!currentset->getVDPad(0)) + { + VDPad *vdpad = new VDPad(0, i, currentset, currentset); + currentset->addVDPad(0, vdpad); + } + } + } + else + { + ui->vdpadUpComboBox->setEnabled(false); + ui->vdpadDownComboBox->setEnabled(false); + ui->vdpadLeftComboBox->setEnabled(false); + ui->vdpadRightComboBox->setEnabled(false); + + ui->vdpadUpPushButton->setEnabled(false); + ui->vdpadDownPushButton->setEnabled(false); + ui->vdpadLeftPushButton->setEnabled(false); + ui->vdpadRightPushButton->setEnabled(false); + + for (int i=0; i < joystick->NUMBER_JOYSETS; i++) + { + SetJoystick *currentset = joystick->getSetJoystick(i); + if (currentset->getVDPad(0)) + { + currentset->removeVDPad(0); + } + } + } +} + +void AdvanceStickAssignmentDialog::changeStateStickOneWidgets(bool enabled) +{ + if (enabled) + { + ui->xAxisOneComboBox->setEnabled(true); + ui->yAxisOneComboBox->setEnabled(true); + ui->enableTwoCheckBox->setEnabled(true); + ui->quickAssignStick1PushButton->setEnabled(true); + } + else + { + ui->xAxisOneComboBox->setEnabled(false); + ui->xAxisOneComboBox->setCurrentIndex(0); + ui->yAxisOneComboBox->setEnabled(false); + ui->yAxisOneComboBox->setCurrentIndex(0); + + ui->xAxisTwoComboBox->setEnabled(false); + ui->yAxisTwoComboBox->setEnabled(false); + ui->xAxisTwoComboBox->setCurrentIndex(0); + ui->yAxisTwoComboBox->setCurrentIndex(0); + ui->enableTwoCheckBox->setEnabled(false); + ui->enableTwoCheckBox->setChecked(false); + ui->quickAssignStick1PushButton->setEnabled(false); + + JoyControlStick *controlstick = joystick->getActiveSetJoystick()->getJoyStick(0); + JoyControlStick *controlstick2 = joystick->getActiveSetJoystick()->getJoyStick(1); + + if (controlstick2) + { + joystick->removeControlStick(1); + } + + if (controlstick) + { + joystick->removeControlStick(0); + } + } +} + +void AdvanceStickAssignmentDialog::changeStateStickTwoWidgets(bool enabled) +{ + if (enabled) + { + ui->xAxisTwoComboBox->setEnabled(true); + ui->yAxisTwoComboBox->setEnabled(true); + ui->quickAssignStick2PushButton->setEnabled(true); + } + else + { + ui->xAxisTwoComboBox->setEnabled(false); + ui->xAxisTwoComboBox->setCurrentIndex(0); + ui->yAxisTwoComboBox->setEnabled(false); + ui->yAxisTwoComboBox->setCurrentIndex(0); + ui->quickAssignStick2PushButton->setEnabled(false); + + JoyControlStick *controlstick = joystick->getActiveSetJoystick()->getJoyStick(1); + if (controlstick) + { + for (int i=0; i < joystick->NUMBER_JOYSETS; i++) + { + SetJoystick *currentset = joystick->getSetJoystick(i); + currentset->removeControlStick(1); + } + } + } +} + +void AdvanceStickAssignmentDialog::refreshStickConfiguration() +{ + JoyControlStick *stick1 = joystick->getActiveSetJoystick()->getJoyStick(0); + JoyControlStick *stick2 = joystick->getActiveSetJoystick()->getJoyStick(1); + if (stick1) + { + JoyAxis *axisX = stick1->getAxisX(); + JoyAxis *axisY = stick1->getAxisY(); + if (axisX && axisY) + { + ui->xAxisOneComboBox->setCurrentIndex(axisX->getRealJoyIndex()); + ui->yAxisOneComboBox->setCurrentIndex(axisY->getRealJoyIndex()); + ui->xAxisOneComboBox->setEnabled(true); + ui->yAxisOneComboBox->setEnabled(true); + ui->enableOneCheckBox->setEnabled(true); + ui->enableOneCheckBox->setChecked(true); + ui->enableTwoCheckBox->setEnabled(true); + ui->quickAssignStick1PushButton->setEnabled(true); + } + } + else + { + ui->xAxisOneComboBox->setCurrentIndex(0); + ui->xAxisOneComboBox->setEnabled(false); + ui->yAxisOneComboBox->setCurrentIndex(0); + ui->yAxisOneComboBox->setEnabled(false); + ui->enableOneCheckBox->setChecked(false); + ui->enableTwoCheckBox->setEnabled(false); + ui->quickAssignStick1PushButton->setEnabled(false); + } + + if (stick2) + { + JoyAxis *axisX = stick2->getAxisX(); + JoyAxis *axisY = stick2->getAxisY(); + if (axisX && axisY) + { + ui->xAxisTwoComboBox->setCurrentIndex(axisX->getRealJoyIndex()); + ui->yAxisTwoComboBox->setCurrentIndex(axisY->getRealJoyIndex()); + ui->xAxisTwoComboBox->setEnabled(true); + ui->yAxisTwoComboBox->setEnabled(true); + ui->enableTwoCheckBox->setEnabled(true); + ui->enableTwoCheckBox->setChecked(true); + ui->quickAssignStick2PushButton->setEnabled(true); + } + } + else + { + ui->xAxisTwoComboBox->setCurrentIndex(0); + ui->xAxisTwoComboBox->setEnabled(false); + ui->yAxisTwoComboBox->setCurrentIndex(0); + ui->yAxisTwoComboBox->setEnabled(false); + ui->enableTwoCheckBox->setChecked(false); + ui->quickAssignStick2PushButton->setEnabled(false); + } +} + +void AdvanceStickAssignmentDialog::refreshVDPadConfiguration() +{ + VDPad *vdpad = joystick->getActiveSetJoystick()->getVDPad(0); + if (vdpad) + { + ui->vdpadEnableCheckBox->setChecked(true); + ui->vdpadUpComboBox->setEnabled(true); + ui->vdpadDownComboBox->setEnabled(true); + ui->vdpadLeftComboBox->setEnabled(true); + ui->vdpadRightComboBox->setEnabled(true); + + ui->vdpadUpPushButton->setEnabled(true); + ui->vdpadDownPushButton->setEnabled(true); + ui->vdpadLeftPushButton->setEnabled(true); + ui->vdpadRightPushButton->setEnabled(true); + + JoyButton *upButton = vdpad->getVButton(JoyDPadButton::DpadUp); + if (upButton) + { + int buttonindex = 0; + if (typeid(*upButton) == typeid(JoyAxisButton)) + { + JoyAxisButton *axisbutton = static_cast(upButton); + JoyAxis *axis = axisbutton->getAxis(); + QList templist; + templist.append(QVariant(axis->getRealJoyIndex())); + templist.append(QVariant(axisbutton->getJoyNumber())); + buttonindex = ui->vdpadUpComboBox->findData(templist); + } + else + { + QList templist; + templist.append(QVariant(0)); + templist.append(QVariant(upButton->getRealJoyNumber())); + buttonindex = ui->vdpadUpComboBox->findData(templist); + } + + if (buttonindex == -1) + { + vdpad->removeVButton(upButton); + } + else + { + ui->vdpadUpComboBox->setCurrentIndex(buttonindex); + } + } + + JoyButton *downButton = vdpad->getVButton(JoyDPadButton::DpadDown); + if (downButton) + { + int buttonindex = 0; + if (typeid(*downButton) == typeid(JoyAxisButton)) + { + JoyAxisButton *axisbutton = static_cast(downButton); + JoyAxis *axis = axisbutton->getAxis(); + QList templist; + templist.append(QVariant(axis->getRealJoyIndex())); + templist.append(QVariant(axisbutton->getJoyNumber())); + buttonindex = ui->vdpadDownComboBox->findData(templist); + } + else + { + QList templist; + templist.append(QVariant(0)); + templist.append(QVariant(downButton->getRealJoyNumber())); + buttonindex = ui->vdpadDownComboBox->findData(templist); + } + + if (buttonindex == -1) + { + vdpad->removeVButton(downButton); + } + else + { + ui->vdpadDownComboBox->setCurrentIndex(buttonindex); + } + } + + JoyButton *leftButton = vdpad->getVButton(JoyDPadButton::DpadLeft); + if (leftButton) + { + int buttonindex = 0; + if (typeid(*leftButton) == typeid(JoyAxisButton)) + { + JoyAxisButton *axisbutton = static_cast(leftButton); + JoyAxis *axis = axisbutton->getAxis(); + QList templist; + templist.append(QVariant(axis->getRealJoyIndex())); + templist.append(QVariant(axisbutton->getJoyNumber())); + buttonindex = ui->vdpadLeftComboBox->findData(templist); + } + else + { + QList templist; + templist.append(QVariant(0)); + templist.append(QVariant(leftButton->getRealJoyNumber())); + buttonindex = ui->vdpadLeftComboBox->findData(templist); + } + + if (buttonindex == -1) + { + vdpad->removeVButton(leftButton); + } + else + { + ui->vdpadLeftComboBox->setCurrentIndex(buttonindex); + } + } + + JoyButton *rightButton = vdpad->getVButton(JoyDPadButton::DpadRight); + if (rightButton) + { + int buttonindex = 0; + if (typeid(*rightButton) == typeid(JoyAxisButton)) + { + JoyAxisButton *axisbutton = static_cast(rightButton); + JoyAxis *axis = axisbutton->getAxis(); + QList templist; + templist.append(QVariant(axis->getRealJoyIndex())); + templist.append(QVariant(axisbutton->getJoyNumber())); + buttonindex = ui->vdpadRightComboBox->findData(templist); + } + else + { + QList templist; + templist.append(QVariant(0)); + templist.append(QVariant(rightButton->getRealJoyNumber())); + buttonindex = ui->vdpadRightComboBox->findData(templist); + } + + if (buttonindex == -1) + { + vdpad->removeVButton(rightButton); + } + else + { + ui->vdpadRightComboBox->setCurrentIndex(buttonindex); + } + } + } + else + { + ui->vdpadEnableCheckBox->setChecked(false); + + ui->vdpadUpComboBox->setCurrentIndex(0); + ui->vdpadUpComboBox->setEnabled(false); + + ui->vdpadDownComboBox->setCurrentIndex(0); + ui->vdpadDownComboBox->setEnabled(false); + + ui->vdpadLeftComboBox->setCurrentIndex(0); + ui->vdpadLeftComboBox->setEnabled(false); + + ui->vdpadRightComboBox->setCurrentIndex(0); + ui->vdpadRightComboBox->setEnabled(false); + + ui->vdpadUpPushButton->setEnabled(false); + ui->vdpadDownPushButton->setEnabled(false); + ui->vdpadLeftPushButton->setEnabled(false); + ui->vdpadRightPushButton->setEnabled(false); + } +} + +void AdvanceStickAssignmentDialog::populateDPadComboBoxes() +{ + ui->vdpadUpComboBox->clear(); + ui->vdpadDownComboBox->clear(); + ui->vdpadLeftComboBox->clear(); + ui->vdpadRightComboBox->clear(); + + ui->vdpadUpComboBox->addItem("", QVariant(0)); + ui->vdpadDownComboBox->addItem("", QVariant(0)); + ui->vdpadLeftComboBox->addItem("", QVariant(0)); + ui->vdpadRightComboBox->addItem("", QVariant(0)); + + for (int i = 0; i < joystick->getNumberAxes(); i++) + { + JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); + if (!axis->isPartControlStick()) + { + QList templist; + templist.append(QVariant(i+1)); + templist.append(QVariant(0)); + + ui->vdpadUpComboBox->addItem(tr("Axis %1 -").arg(QString::number(i+1)), templist); + ui->vdpadDownComboBox->addItem(tr("Axis %1 -").arg(QString::number(i+1)), templist); + ui->vdpadLeftComboBox->addItem(tr("Axis %1 -").arg(QString::number(i+1)), templist); + ui->vdpadRightComboBox->addItem(tr("Axis %1 -").arg(QString::number(i+1)), templist); + + templist.clear(); + templist.append(QVariant(i+1)); + templist.append(QVariant(1)); + ui->vdpadUpComboBox->addItem(tr("Axis %1 +").arg(QString::number(i+1)), templist); + ui->vdpadDownComboBox->addItem(tr("Axis %1 +").arg(QString::number(i+1)), templist); + ui->vdpadLeftComboBox->addItem(tr("Axis %1 +").arg(QString::number(i+1)), templist); + ui->vdpadRightComboBox->addItem(tr("Axis %1 +").arg(QString::number(i+1)), templist); + } + } + + for (int i = 0; i < joystick->getNumberButtons(); i++) + { + QList templist; + templist.append(QVariant(0)); + templist.append(QVariant(i+1)); + + ui->vdpadUpComboBox->addItem(tr("Button %1").arg(QString::number(i+1)), templist); + ui->vdpadDownComboBox->addItem(tr("Button %1").arg(QString::number(i+1)), templist); + ui->vdpadLeftComboBox->addItem(tr("Button %1").arg(QString::number(i+1)), templist); + ui->vdpadRightComboBox->addItem(tr("Button %1").arg(QString::number(i+1)), templist); + } +} + +void AdvanceStickAssignmentDialog::changeVDPadUpButton(int index) +{ + if (index > 0) + { + if (ui->vdpadDownComboBox->currentIndex() == index) + { + ui->vdpadDownComboBox->setCurrentIndex(0); + } + else if (ui->vdpadLeftComboBox->currentIndex() == index) + { + ui->vdpadLeftComboBox->setCurrentIndex(0); + } + else if (ui->vdpadRightComboBox->currentIndex() == index) + { + ui->vdpadRightComboBox->setCurrentIndex(0); + } + + QVariant temp = ui->vdpadUpComboBox->itemData(index); + QList templist = temp.toList(); + if (templist.size() == 2) + { + int axis = templist.at(0).toInt(); + int button = templist.at(1).toInt(); + if (axis > 0 && button >= 0) + { + for (int i=0; i < joystick->NUMBER_JOYSETS; i++) + { + SetJoystick *currentset = joystick->getSetJoystick(i); + VDPad *vdpad = currentset->getVDPad(0); + JoyAxis *currentaxis = currentset->getJoyAxis(axis-1); + JoyButton *currentbutton = 0; + if (button == 0) + { + currentbutton = currentaxis->getNAxisButton(); + } + else if (button == 1) + { + currentbutton = currentaxis->getPAxisButton(); + } + + vdpad->addVButton(JoyDPadButton::DpadUp, currentbutton); + } + } + else if (button > 0) + { + for (int i=0; i < joystick->NUMBER_JOYSETS; i++) + { + SetJoystick *currentset = joystick->getSetJoystick(i); + VDPad *vdpad = currentset->getVDPad(0); + JoyButton *currentbutton = currentset->getJoyButton(button-1); + if (currentbutton) + { + vdpad->addVButton(JoyDPadButton::DpadUp, currentbutton); + } + } + } + } + } + else + { + for (int i=0; i < joystick->NUMBER_JOYSETS; i++) + { + SetJoystick *currentset = joystick->getSetJoystick(i); + VDPad *vdpad = currentset->getVDPad(0); + if (vdpad && vdpad->getVButton(JoyDPadButton::DpadUp)) + { + vdpad->removeVButton(JoyDPadButton::DpadUp); + } + } + } +} + +void AdvanceStickAssignmentDialog::changeVDPadDownButton(int index) +{ + if (index > 0) + { + if (ui->vdpadUpComboBox->currentIndex() == index) + { + ui->vdpadUpComboBox->setCurrentIndex(0); + } + else if (ui->vdpadLeftComboBox->currentIndex() == index) + { + ui->vdpadLeftComboBox->setCurrentIndex(0); + } + else if (ui->vdpadRightComboBox->currentIndex() == index) + { + ui->vdpadRightComboBox->setCurrentIndex(0); + } + + QVariant temp = ui->vdpadDownComboBox->itemData(index); + QList templist = temp.toList(); + if (templist.size() == 2) + { + int axis = templist.at(0).toInt(); + int button = templist.at(1).toInt(); + if (axis > 0 && button >= 0) + { + for (int i=0; i < joystick->NUMBER_JOYSETS; i++) + { + SetJoystick *currentset = joystick->getSetJoystick(i); + VDPad *vdpad = currentset->getVDPad(0); + JoyAxis *currentaxis = currentset->getJoyAxis(axis-1); + JoyButton *currentbutton = 0; + if (button == 0) + { + currentbutton = currentaxis->getNAxisButton(); + } + else if (button == 1) + { + currentbutton = currentaxis->getPAxisButton(); + } + + vdpad->addVButton(JoyDPadButton::DpadDown, currentbutton); + } + } + else if (button > 0) + { + for (int i=0; i < joystick->NUMBER_JOYSETS; i++) + { + SetJoystick *currentset = joystick->getSetJoystick(i); + VDPad *vdpad = currentset->getVDPad(0); + JoyButton *currentbutton = currentset->getJoyButton(button-1); + if (currentbutton) + { + vdpad->addVButton(JoyDPadButton::DpadDown, currentbutton); + } + } + } + } + } + else + { + for (int i=0; i < joystick->NUMBER_JOYSETS; i++) + { + SetJoystick *currentset = joystick->getSetJoystick(i); + VDPad *vdpad = currentset->getVDPad(0); + if (vdpad && vdpad->getVButton(JoyDPadButton::DpadDown)) + { + vdpad->removeVButton(JoyDPadButton::DpadDown); + } + } + } +} + +void AdvanceStickAssignmentDialog::changeVDPadLeftButton(int index) +{ + if (index > 0) + { + if (ui->vdpadUpComboBox->currentIndex() == index) + { + ui->vdpadUpComboBox->setCurrentIndex(0); + } + else if (ui->vdpadDownComboBox->currentIndex() == index) + { + ui->vdpadDownComboBox->setCurrentIndex(0); + } + else if (ui->vdpadRightComboBox->currentIndex() == index) + { + ui->vdpadRightComboBox->setCurrentIndex(0); + } + + QVariant temp = ui->vdpadLeftComboBox->itemData(index); + QList templist = temp.toList(); + if (templist.size() == 2) + { + int axis = templist.at(0).toInt(); + int button = templist.at(1).toInt(); + if (axis > 0 && button >= 0) + { + for (int i=0; i < joystick->NUMBER_JOYSETS; i++) + { + SetJoystick *currentset = joystick->getSetJoystick(i); + VDPad *vdpad = currentset->getVDPad(0); + JoyAxis *currentaxis = currentset->getJoyAxis(axis-1); + JoyButton *currentbutton = 0; + if (button == 0) + { + currentbutton = currentaxis->getNAxisButton(); + } + else if (button == 1) + { + currentbutton = currentaxis->getPAxisButton(); + } + + vdpad->addVButton(JoyDPadButton::DpadLeft, currentbutton); + } + } + else if (button > 0) + { + for (int i=0; i < joystick->NUMBER_JOYSETS; i++) + { + SetJoystick *currentset = joystick->getSetJoystick(i); + VDPad *vdpad = currentset->getVDPad(0); + JoyButton *currentbutton = currentset->getJoyButton(button-1); + if (currentbutton) + { + vdpad->addVButton(JoyDPadButton::DpadLeft, currentbutton); + } + } + } + } + } + else + { + for (int i=0; i < joystick->NUMBER_JOYSETS; i++) + { + SetJoystick *currentset = joystick->getSetJoystick(i); + VDPad *vdpad = currentset->getVDPad(0); + if (vdpad && vdpad->getVButton(JoyDPadButton::DpadLeft)) + { + vdpad->removeVButton(JoyDPadButton::DpadLeft); + } + } + } +} + +void AdvanceStickAssignmentDialog::changeVDPadRightButton(int index) +{ + if (index > 0) + { + if (ui->vdpadUpComboBox->currentIndex() == index) + { + ui->vdpadUpComboBox->setCurrentIndex(0); + } + else if (ui->vdpadDownComboBox->currentIndex() == index) + { + ui->vdpadDownComboBox->setCurrentIndex(0); + } + else if (ui->vdpadLeftComboBox->currentIndex() == index) + { + ui->vdpadLeftComboBox->setCurrentIndex(0); + } + + QVariant temp = ui->vdpadRightComboBox->itemData(index); + QList templist = temp.toList(); + if (templist.size() == 2) + { + int axis = templist.at(0).toInt(); + int button = templist.at(1).toInt(); + if (axis > 0 && button >= 0) + { + for (int i=0; i < joystick->NUMBER_JOYSETS; i++) + { + SetJoystick *currentset = joystick->getSetJoystick(i); + VDPad *vdpad = currentset->getVDPad(0); + JoyAxis *currentaxis = currentset->getJoyAxis(axis-1); + JoyButton *currentbutton = 0; + if (button == 0) + { + currentbutton = currentaxis->getNAxisButton(); + } + else if (button == 1) + { + currentbutton = currentaxis->getPAxisButton(); + } + + vdpad->addVButton(JoyDPadButton::DpadRight, currentbutton); + } + } + else if (button > 0) + { + for (int i=0; i < joystick->NUMBER_JOYSETS; i++) + { + SetJoystick *currentset = joystick->getSetJoystick(i); + VDPad *vdpad = currentset->getVDPad(0); + JoyButton *currentbutton = currentset->getJoyButton(button-1); + if (currentbutton) + { + vdpad->addVButton(JoyDPadButton::DpadRight, currentbutton); + } + } + } + } + } + else + { + for (int i=0; i < joystick->NUMBER_JOYSETS; i++) + { + SetJoystick *currentset = joystick->getSetJoystick(i); + VDPad *vdpad = currentset->getVDPad(0); + if (vdpad && vdpad->getVButton(JoyDPadButton::DpadRight)) + { + vdpad->removeVButton(JoyDPadButton::DpadRight); + } + } + } +} + +void AdvanceStickAssignmentDialog::enableVDPadComboBoxes() +{ + connect(ui->vdpadUpComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeVDPadUpButton(int))); + connect(ui->vdpadDownComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeVDPadDownButton(int))); + connect(ui->vdpadLeftComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeVDPadLeftButton(int))); + connect(ui->vdpadRightComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeVDPadRightButton(int))); +} + +void AdvanceStickAssignmentDialog::disableVDPadComboBoxes() +{ + disconnect(ui->vdpadUpComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeVDPadUpButton(int))); + disconnect(ui->vdpadDownComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeVDPadDownButton(int))); + disconnect(ui->vdpadLeftComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeVDPadLeftButton(int))); + disconnect(ui->vdpadRightComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeVDPadRightButton(int))); +} + +void AdvanceStickAssignmentDialog::openQuickAssignDialogStick1() +{ + QMessageBox msgBox; + msgBox.setText(tr("Move stick 1 along the X axis")); + msgBox.setStandardButtons(QMessageBox::Close); + for (int i=0; i < joystick->getNumberAxes(); i++) + { + JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); + if (axis) + { + connect(axis, SIGNAL(active(int)), &msgBox, SLOT(close())); + connect(axis, SIGNAL(active(int)), this, SLOT(quickAssignStick1Axis1())); + } + } + + msgBox.exec(); + + msgBox.setText(tr("Move stick 1 along the Y axis")); + for (int i=0; i < joystick->getNumberAxes(); i++) + { + JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); + if (axis) + { + disconnect(axis, SIGNAL(active(int)), &msgBox, SLOT(close())); + disconnect(axis, SIGNAL(active(int)), this, SLOT(quickAssignStick1Axis1())); + + connect(axis, SIGNAL(active(int)), &msgBox, SLOT(close())); + connect(axis, SIGNAL(active(int)), this, SLOT(quickAssignStick1Axis2())); + } + } + + msgBox.exec(); + for (int i=0; i < joystick->getNumberAxes(); i++) + { + JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); + if (axis) + { + disconnect(axis, SIGNAL(active(int)), &msgBox, SLOT(close())); + disconnect(axis, SIGNAL(active(int)), this, SLOT(quickAssignStick1Axis2())); + } + } +} + +void AdvanceStickAssignmentDialog::openQuickAssignDialogStick2() +{ + QMessageBox msgBox; + msgBox.setText(tr("Move stick 2 along the X axis")); + msgBox.setStandardButtons(QMessageBox::Close); + for (int i=0; i < joystick->getNumberAxes(); i++) + { + JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); + if (axis) + { + connect(axis, SIGNAL(active(int)), &msgBox, SLOT(close())); + connect(axis, SIGNAL(active(int)), this, SLOT(quickAssignStick2Axis1())); + } + } + + msgBox.exec(); + + + msgBox.setText(tr("Move stick 2 along the Y axis")); + for (int i=0; i < joystick->getNumberAxes(); i++) + { + JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); + if (axis) + { + disconnect(axis, SIGNAL(active(int)), &msgBox, SLOT(close())); + disconnect(axis, SIGNAL(active(int)), this, SLOT(quickAssignStick2Axis1())); + + connect(axis, SIGNAL(active(int)), &msgBox, SLOT(close())); + connect(axis, SIGNAL(active(int)), this, SLOT(quickAssignStick2Axis2())); + } + } + + msgBox.exec(); + for (int i=0; i < joystick->getNumberAxes(); i++) + { + JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); + if (axis) + { + disconnect(axis, SIGNAL(active(int)), &msgBox, SLOT(close())); + disconnect(axis, SIGNAL(active(int)), this, SLOT(quickAssignStick2Axis2())); + } + } +} + +void AdvanceStickAssignmentDialog::quickAssignStick1Axis1() +{ + JoyAxis *axis = static_cast(sender()); + ui->xAxisOneComboBox->setCurrentIndex(axis->getRealJoyIndex()); +} + +void AdvanceStickAssignmentDialog::quickAssignStick1Axis2() +{ + JoyAxis *axis = static_cast(sender()); + ui->yAxisOneComboBox->setCurrentIndex(axis->getRealJoyIndex()); +} + +void AdvanceStickAssignmentDialog::quickAssignStick2Axis1() +{ + JoyAxis *axis = static_cast(sender()); + ui->xAxisTwoComboBox->setCurrentIndex(axis->getRealJoyIndex()); +} + +void AdvanceStickAssignmentDialog::quickAssignStick2Axis2() +{ + JoyAxis *axis = static_cast(sender()); + ui->yAxisTwoComboBox->setCurrentIndex(axis->getRealJoyIndex()); +} + +void AdvanceStickAssignmentDialog::reenableButtonEvents() +{ + joystick->getActiveSetJoystick()->setIgnoreEventState(false); + joystick->getActiveSetJoystick()->release(); +} + +void AdvanceStickAssignmentDialog::openAssignVDPadUp() +{ + QMessageBox msgBox; + msgBox.setText(tr("Press a button or move an axis")); + msgBox.setStandardButtons(QMessageBox::Close); + for (int i=0; i < joystick->getNumberAxes(); i++) + { + JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); + if (axis && !axis->isPartControlStick()) + { + connect(axis->getNAxisButton(), SIGNAL(clicked(int)), &msgBox, SLOT(close())); + connect(axis->getNAxisButton(), SIGNAL(clicked(int)), this, SLOT(quickAssignVDPadUp())); + + connect(axis->getPAxisButton(), SIGNAL(clicked(int)), &msgBox, SLOT(close())); + connect(axis->getPAxisButton(), SIGNAL(clicked(int)), this, SLOT(quickAssignVDPadUp())); + } + } + + for (int i=0; i < joystick->getNumberButtons(); i++) + { + JoyButton *button = joystick->getActiveSetJoystick()->getJoyButton(i); + if (button) + { + connect(button, SIGNAL(clicked(int)), &msgBox, SLOT(close())); + connect(button, SIGNAL(clicked(int)), this, SLOT(quickAssignVDPadUp())); + } + } + + msgBox.exec(); + + for (int i=0; i < joystick->getNumberAxes(); i++) + { + JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); + if (axis && !axis->isPartControlStick()) + { + disconnect(axis->getNAxisButton(), SIGNAL(clicked(int)), &msgBox, SLOT(close())); + disconnect(axis->getNAxisButton(), SIGNAL(clicked(int)), this, SLOT(quickAssignVDPadUp())); + + disconnect(axis->getPAxisButton(), SIGNAL(clicked(int)), &msgBox, SLOT(close())); + disconnect(axis->getPAxisButton(), SIGNAL(clicked(int)), this, SLOT(quickAssignVDPadUp())); + } + } + + for (int i=0; i < joystick->getNumberButtons(); i++) + { + JoyButton *button = joystick->getActiveSetJoystick()->getJoyButton(i); + if (button) + { + disconnect(button, SIGNAL(clicked(int)), &msgBox, SLOT(close())); + disconnect(button, SIGNAL(clicked(int)), this, SLOT(quickAssignVDPadUp())); + } + } +} + +void AdvanceStickAssignmentDialog::openAssignVDPadDown() +{ + QMessageBox msgBox; + msgBox.setText(tr("Press a button or move an axis")); + msgBox.setStandardButtons(QMessageBox::Close); + for (int i=0; i < joystick->getNumberAxes(); i++) + { + JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); + if (axis && !axis->isPartControlStick()) + { + connect(axis->getNAxisButton(), SIGNAL(clicked(int)), &msgBox, SLOT(close())); + connect(axis->getNAxisButton(), SIGNAL(clicked(int)), this, SLOT(quickAssignVDPadDown())); + + connect(axis->getPAxisButton(), SIGNAL(clicked(int)), &msgBox, SLOT(close())); + connect(axis->getPAxisButton(), SIGNAL(clicked(int)), this, SLOT(quickAssignVDPadDown())); + } + } + + for (int i=0; i < joystick->getNumberButtons(); i++) + { + JoyButton *button = joystick->getActiveSetJoystick()->getJoyButton(i); + if (button) + { + connect(button, SIGNAL(clicked(int)), &msgBox, SLOT(close())); + connect(button, SIGNAL(clicked(int)), this, SLOT(quickAssignVDPadDown())); + } + } + + msgBox.exec(); + + for (int i=0; i < joystick->getNumberAxes(); i++) + { + JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); + if (axis && !axis->isPartControlStick()) + { + disconnect(axis->getNAxisButton(), SIGNAL(clicked(int)), &msgBox, SLOT(close())); + disconnect(axis->getNAxisButton(), SIGNAL(clicked(int)), this, SLOT(quickAssignVDPadDown())); + + disconnect(axis->getPAxisButton(), SIGNAL(clicked(int)), &msgBox, SLOT(close())); + disconnect(axis->getPAxisButton(), SIGNAL(clicked(int)), this, SLOT(quickAssignVDPadDown())); + } + } + + for (int i=0; i < joystick->getNumberButtons(); i++) + { + JoyButton *button = joystick->getActiveSetJoystick()->getJoyButton(i); + if (button) + { + disconnect(button, SIGNAL(clicked(int)), &msgBox, SLOT(close())); + disconnect(button, SIGNAL(clicked(int)), this, SLOT(quickAssignVDPadDown())); + } + } +} + +void AdvanceStickAssignmentDialog::openAssignVDPadLeft() +{ + QMessageBox msgBox; + msgBox.setText(tr("Press a button or move an axis")); + msgBox.setStandardButtons(QMessageBox::Close); + for (int i=0; i < joystick->getNumberAxes(); i++) + { + JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); + if (axis && !axis->isPartControlStick()) + { + connect(axis->getNAxisButton(), SIGNAL(clicked(int)), &msgBox, SLOT(close())); + connect(axis->getNAxisButton(), SIGNAL(clicked(int)), this, SLOT(quickAssignVDPadLeft())); + + connect(axis->getPAxisButton(), SIGNAL(clicked(int)), &msgBox, SLOT(close())); + connect(axis->getPAxisButton(), SIGNAL(clicked(int)), this, SLOT(quickAssignVDPadLeft())); + } + } + + for (int i=0; i < joystick->getNumberButtons(); i++) + { + JoyButton *button = joystick->getActiveSetJoystick()->getJoyButton(i); + if (button) + { + connect(button, SIGNAL(clicked(int)), &msgBox, SLOT(close())); + connect(button, SIGNAL(clicked(int)), this, SLOT(quickAssignVDPadLeft())); + } + } + + msgBox.exec(); + + for (int i=0; i < joystick->getNumberAxes(); i++) + { + JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); + if (axis && !axis->isPartControlStick()) + { + disconnect(axis->getNAxisButton(), SIGNAL(clicked(int)), &msgBox, SLOT(close())); + disconnect(axis->getNAxisButton(), SIGNAL(clicked(int)), this, SLOT(quickAssignVDPadLeft())); + + disconnect(axis->getPAxisButton(), SIGNAL(clicked(int)), &msgBox, SLOT(close())); + disconnect(axis->getPAxisButton(), SIGNAL(clicked(int)), this, SLOT(quickAssignVDPadLeft())); + } + } + + for (int i=0; i < joystick->getNumberButtons(); i++) + { + JoyButton *button = joystick->getActiveSetJoystick()->getJoyButton(i); + if (button) + { + disconnect(button, SIGNAL(clicked(int)), &msgBox, SLOT(close())); + disconnect(button, SIGNAL(clicked(int)), this, SLOT(quickAssignVDPadLeft())); + } + } +} + +void AdvanceStickAssignmentDialog::openAssignVDPadRight() +{ + QMessageBox msgBox; + msgBox.setText(tr("Press a button or move an axis")); + msgBox.setStandardButtons(QMessageBox::Close); + for (int i=0; i < joystick->getNumberAxes(); i++) + { + JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); + if (axis && !axis->isPartControlStick()) + { + connect(axis->getNAxisButton(), SIGNAL(clicked(int)), &msgBox, SLOT(close())); + connect(axis->getNAxisButton(), SIGNAL(clicked(int)), this, SLOT(quickAssignVDPadRight())); + + connect(axis->getPAxisButton(), SIGNAL(clicked(int)), &msgBox, SLOT(close())); + connect(axis->getPAxisButton(), SIGNAL(clicked(int)), this, SLOT(quickAssignVDPadRight())); + } + } + + for (int i=0; i < joystick->getNumberButtons(); i++) + { + JoyButton *button = joystick->getActiveSetJoystick()->getJoyButton(i); + if (button) + { + connect(button, SIGNAL(clicked(int)), &msgBox, SLOT(close())); + connect(button, SIGNAL(clicked(int)), this, SLOT(quickAssignVDPadRight())); + } + } + + msgBox.exec(); + + for (int i=0; i < joystick->getNumberAxes(); i++) + { + JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); + if (axis && !axis->isPartControlStick()) + { + disconnect(axis->getNAxisButton(), SIGNAL(clicked(int)), &msgBox, SLOT(close())); + disconnect(axis->getNAxisButton(), SIGNAL(clicked(int)), this, SLOT(quickAssignVDPadRight())); + + disconnect(axis->getPAxisButton(), SIGNAL(clicked(int)), &msgBox, SLOT(close())); + disconnect(axis->getPAxisButton(), SIGNAL(clicked(int)), this, SLOT(quickAssignVDPadRight())); + } + } + + for (int i=0; i < joystick->getNumberButtons(); i++) + { + JoyButton *button = joystick->getActiveSetJoystick()->getJoyButton(i); + if (button) + { + disconnect(button, SIGNAL(clicked(int)), &msgBox, SLOT(close())); + disconnect(button, SIGNAL(clicked(int)), this, SLOT(quickAssignVDPadRight())); + } + } +} + +void AdvanceStickAssignmentDialog::quickAssignVDPadUp() +{ + if (qobject_cast(sender()) != 0) + { + JoyAxisButton *axisButton = static_cast(sender()); + + QList templist; + templist.append(QVariant(axisButton->getAxis()->getRealJoyIndex())); + if (axisButton->getAxis()->getNAxisButton() == axisButton) + { + templist.append(QVariant(0)); + } + else + { + templist.append(QVariant(1)); + } + + int index = ui->vdpadUpComboBox->findData(templist); + if (index > 0) + { + ui->vdpadUpComboBox->setCurrentIndex(index); + } + } + else + { + JoyButton *button = static_cast(sender()); + QList templist; + templist.append(QVariant(0)); + templist.append(QVariant(button->getJoyNumber()+1)); + + int index = ui->vdpadUpComboBox->findData(templist); + if (index > 0) + { + ui->vdpadUpComboBox->setCurrentIndex(index); + } + } +} + +void AdvanceStickAssignmentDialog::quickAssignVDPadDown() +{ + if (qobject_cast(sender()) != 0) + { + JoyAxisButton *axisButton = static_cast(sender()); + + QList templist; + templist.append(QVariant(axisButton->getAxis()->getRealJoyIndex())); + if (axisButton->getAxis()->getNAxisButton() == axisButton) + { + templist.append(QVariant(0)); + } + else + { + templist.append(QVariant(1)); + } + + int index = ui->vdpadDownComboBox->findData(templist); + if (index > 0) + { + ui->vdpadDownComboBox->setCurrentIndex(index); + } + } + else + { + JoyButton *button = static_cast(sender()); + QList templist; + templist.append(QVariant(0)); + templist.append(QVariant(button->getJoyNumber()+1)); + + int index = ui->vdpadDownComboBox->findData(templist); + if (index > 0) + { + ui->vdpadDownComboBox->setCurrentIndex(index); + } + } +} + +void AdvanceStickAssignmentDialog::quickAssignVDPadLeft() +{ + if (qobject_cast(sender()) != 0) + { + JoyAxisButton *axisButton = static_cast(sender()); + + QList templist; + templist.append(QVariant(axisButton->getAxis()->getRealJoyIndex())); + if (axisButton->getAxis()->getNAxisButton() == axisButton) + { + templist.append(QVariant(0)); + } + else + { + templist.append(QVariant(1)); + } + + int index = ui->vdpadLeftComboBox->findData(templist); + if (index > 0) + { + ui->vdpadLeftComboBox->setCurrentIndex(index); + } + } + else + { + JoyButton *button = static_cast(sender()); + QList templist; + templist.append(QVariant(0)); + templist.append(QVariant(button->getJoyNumber()+1)); + + int index = ui->vdpadLeftComboBox->findData(templist); + if (index > 0) + { + ui->vdpadLeftComboBox->setCurrentIndex(index); + } + } +} + +void AdvanceStickAssignmentDialog::quickAssignVDPadRight() +{ + if (qobject_cast(sender()) != 0) + { + JoyAxisButton *axisButton = static_cast(sender()); + + QList templist; + templist.append(QVariant(axisButton->getAxis()->getRealJoyIndex())); + if (axisButton->getAxis()->getNAxisButton() == axisButton) + { + templist.append(QVariant(0)); + } + else + { + templist.append(QVariant(1)); + } + + int index = ui->vdpadRightComboBox->findData(templist); + if (index > 0) + { + ui->vdpadRightComboBox->setCurrentIndex(index); + } + } + else + { + JoyButton *button = static_cast(sender()); + QList templist; + templist.append(QVariant(0)); + templist.append(QVariant(button->getJoyNumber()+1)); + + int index = ui->vdpadRightComboBox->findData(templist); + if (index > 0) + { + ui->vdpadRightComboBox->setCurrentIndex(index); + } + } +} diff --git a/src/advancestickassignmentdialog.h b/src/advancestickassignmentdialog.h new file mode 100644 index 0000000..e334fe7 --- /dev/null +++ b/src/advancestickassignmentdialog.h @@ -0,0 +1,90 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef ADVANCESTICKASSIGNMENTDIALOG_H +#define ADVANCESTICKASSIGNMENTDIALOG_H + +#include + +#include "joystick.h" + +namespace Ui { +class AdvanceStickAssignmentDialog; +} + +class AdvanceStickAssignmentDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AdvanceStickAssignmentDialog(Joystick *joystick, QWidget *parent = 0); + ~AdvanceStickAssignmentDialog(); + +protected: + Joystick *joystick; + +signals: + void stickConfigurationChanged(); + void vdpadConfigurationChanged(); + +private: + Ui::AdvanceStickAssignmentDialog *ui; + +private slots: + void refreshStickConfiguration(); + void refreshVDPadConfiguration(); + + void checkForAxisAssignmentStickOne(); + void checkForAxisAssignmentStickTwo(); + + void changeStateStickOneWidgets(bool enabled); + void changeStateStickTwoWidgets(bool enabled); + void changeStateVDPadWidgets(bool enabled); + + void populateDPadComboBoxes(); + + void changeVDPadUpButton(int index); + void changeVDPadDownButton(int index); + void changeVDPadLeftButton(int index); + void changeVDPadRightButton(int index); + + void disableVDPadComboBoxes(); + void enableVDPadComboBoxes(); + + void openQuickAssignDialogStick1(); + void openQuickAssignDialogStick2(); + + void quickAssignStick1Axis1(); + void quickAssignStick1Axis2(); + + void quickAssignStick2Axis1(); + void quickAssignStick2Axis2(); + + void openAssignVDPadUp(); + void openAssignVDPadDown(); + void openAssignVDPadLeft(); + void openAssignVDPadRight(); + + void quickAssignVDPadUp(); + void quickAssignVDPadDown(); + void quickAssignVDPadLeft(); + void quickAssignVDPadRight(); + + void reenableButtonEvents(); +}; + +#endif // ADVANCESTICKASSIGNMENTDIALOG_H diff --git a/src/advancestickassignmentdialog.ui b/src/advancestickassignmentdialog.ui new file mode 100644 index 0000000..ec46807 --- /dev/null +++ b/src/advancestickassignmentdialog.ui @@ -0,0 +1,645 @@ + + + AdvanceStickAssignmentDialog + + + + 0 + 0 + 770 + 440 + + + + + 0 + 0 + + + + Stick/Pad Assignment + + + true + + + + + + + + + 0 + 0 + + + + 0 + + + + Sticks + + + + + DPads + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + 0 + + + + + + + + + + 50 + false + + + + Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. + + + true + + + + + + + + 75 + true + + + + %1 (Joystick %2) + + + + + + + -1 + + + + + -1 + + + + + + 75 + true + + + + Stick 1 + + + + + + + true + + + Enabled + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + Assign + + + + + + + + + + + X Axis: + + + + + + + false + + + + + + + + + + + Y Axis: + + + + + + + false + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 40 + 10 + + + + + + + + + + + 75 + true + + + + Stick 2 + + + + + + + false + + + Enabled + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + Assign + + + + + + + + + + + X Axis: + + + + + + + false + + + + + + + + + + + Y Axis: + + + + + + + false + + + + + + + + + + + + + + + + + + + + 75 + true + + + + %1 (Joystick %2) + + + + + + + + 75 + true + + + + Number of Physical DPads: %1 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + -1 + + + + + + 75 + true + + + + Virtual DPad 1 + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 11 + + + + + + + + Enabled + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + 41 + + + 20 + + + + + false + + + + + + + Down: + + + + + + + false + + + + + + + Left: + + + + + + + false + + + + + + + Right: + + + + + + + Up: + + + + + + + false + + + + + + + false + + + Assign + + + + + + + false + + + Assign + + + + + + + false + + + Assign + + + + + + + false + + + Assign + + + + + + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + + + + buttonBox + accepted() + AdvanceStickAssignmentDialog + accept() + + + 252 + 369 + + + 157 + 274 + + + + + buttonBox + rejected() + AdvanceStickAssignmentDialog + reject() + + + 320 + 369 + + + 286 + 274 + + + + + listWidget + currentRowChanged(int) + stackedWidget + setCurrentIndex(int) + + + 91 + 116 + + + 291 + 105 + + + + + diff --git a/src/antimicro.exe.manifest b/src/antimicro.exe.manifest new file mode 100644 index 0000000..cf5facc --- /dev/null +++ b/src/antimicro.exe.manifest @@ -0,0 +1,17 @@ + + + + antimicro + + + + + + + + + + diff --git a/src/antimicro.exe.uiaccess.manifest b/src/antimicro.exe.uiaccess.manifest new file mode 100644 index 0000000..cab4268 --- /dev/null +++ b/src/antimicro.exe.uiaccess.manifest @@ -0,0 +1,17 @@ + + + + antimicro + + + + + + + + + + diff --git a/src/antimicro.rc b/src/antimicro.rc new file mode 100644 index 0000000..a89e4be --- /dev/null +++ b/src/antimicro.rc @@ -0,0 +1,8 @@ +#include "winuser.h" + + IDI_ICON1 ICON DISCARDABLE "images/antimicro.ico" +#ifndef PERFORM_SIGNING + CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "antimicro.exe.manifest" +#else + CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "antimicro.exe.uiaccess.manifest" +#endif diff --git a/src/antimicrosettings.cpp b/src/antimicrosettings.cpp new file mode 100644 index 0000000..98e99b3 --- /dev/null +++ b/src/antimicrosettings.cpp @@ -0,0 +1,78 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "antimicrosettings.h" + +const bool AntiMicroSettings::defaultDisabledWinEnhanced = false; +const bool AntiMicroSettings::defaultAssociateProfiles = true; +const int AntiMicroSettings::defaultSpringScreen = -1; +const unsigned int AntiMicroSettings::defaultSDLGamepadPollRate = 10; + +AntiMicroSettings::AntiMicroSettings(const QString &fileName, Format format, QObject *parent) : + QSettings(fileName, format, parent) +{ +} + +/** + * @brief Get the currently used value such as an setting overridden + * with a command line argument. + * @param Setting key + * @param Default value to use if key does not exist + * @return Stored value or the default value passed + */ +QVariant AntiMicroSettings::runtimeValue(const QString &key, const QVariant &defaultValue) const +{ + QVariant settingValue; + QString inGroup = group(); + QString fullKey = QString(inGroup).append("/").append(key); + if (cmdSettings.contains(fullKey)) + { + settingValue = cmdSettings.value(fullKey, defaultValue); + } + else + { + settingValue = value(key, defaultValue); + } + + return settingValue; +} + +/** + * @brief Import relevant options given on the command line into a QSettings + * instance. Used to override any options that might be present in the + * main settings file. Keys will have to be changed to the appropriate + * config key. + * @param Interpreted options set on the command line. + */ +void AntiMicroSettings::importFromCommandLine(CommandLineUtility &cmdutility) +{ + cmdSettings.clear(); + + if (cmdutility.isLaunchInTrayEnabled()) + { + cmdSettings.setValue("LaunchInTray", 1); + } + if (cmdutility.shouldMapController()) + { + cmdSettings.setValue("DisplaySDLMapping", 1); + } +} + +QMutex* AntiMicroSettings::getLock() +{ + return &lock; +} diff --git a/src/antimicrosettings.h b/src/antimicrosettings.h new file mode 100644 index 0000000..e749649 --- /dev/null +++ b/src/antimicrosettings.h @@ -0,0 +1,51 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef ANTIMICROSETTINGS_H +#define ANTIMICROSETTINGS_H + +#include +#include + +#include "commandlineutility.h" + +class AntiMicroSettings : public QSettings +{ + Q_OBJECT +public: + explicit AntiMicroSettings(const QString &fileName, Format format, QObject *parent = 0); + + QVariant runtimeValue(const QString &key, const QVariant &defaultValue = QVariant()) const; + void importFromCommandLine(CommandLineUtility &cmdutility); + QMutex* getLock(); + + static const bool defaultDisabledWinEnhanced; + static const bool defaultAssociateProfiles; + static const int defaultSpringScreen; + static const unsigned int defaultSDLGamepadPollRate; + +protected: + QSettings cmdSettings; + QMutex lock; + +signals: + +public slots: + +}; + +#endif // ANTIMICROSETTINGS_H diff --git a/src/antkeymapper.cpp b/src/antkeymapper.cpp new file mode 100644 index 0000000..39d4e73 --- /dev/null +++ b/src/antkeymapper.cpp @@ -0,0 +1,144 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +//#include +#include +#include + +#include "antkeymapper.h" +#include "eventhandlerfactory.h" + +AntKeyMapper* AntKeyMapper::_instance = 0; + +static QStringList buildEventGeneratorList() +{ + QStringList temp; + +#ifdef Q_OS_WIN + temp.append("sendinput"); + #ifdef WITH_VMULTI + temp.append("vmulti"); + #endif + +#else + #ifdef WITH_XTEST + temp.append("xtest"); + #endif + #ifdef WITH_UINPUT + temp.append("uinput"); + #endif + +#endif + return temp; +} + +AntKeyMapper::AntKeyMapper(QString handler, QObject *parent) : + QObject(parent) +{ + internalMapper = 0; + +#ifdef Q_OS_WIN + #ifdef WITH_VMULTI + if (handler == "vmulti") + { + internalMapper = &vmultiMapper; + nativeKeyMapper = &winMapper; + } + #endif + + BACKEND_ELSE_IF (handler == "sendinput") + { + internalMapper = &winMapper; + nativeKeyMapper = 0; + } + +#else + #ifdef WITH_XTEST + if (handler == "xtest") + { + internalMapper = &x11Mapper; + nativeKeyMapper = 0; + } + #endif + + #ifdef WITH_UINPUT + if (handler == "uinput") + { + internalMapper = &uinputMapper; +#ifdef WITH_XTEST + nativeKeyMapper = &x11Mapper; +#else + nativeKeyMapper = 0; +#endif + } + #endif + +#endif +} + +AntKeyMapper* AntKeyMapper::getInstance(QString handler) +{ + if (!_instance) + { + Q_ASSERT(!handler.isEmpty()); + QStringList temp = buildEventGeneratorList(); + Q_ASSERT(temp.contains(handler)); + _instance = new AntKeyMapper(handler); + } + + return _instance; +} + +void AntKeyMapper::deleteInstance() +{ + if (_instance) + { + delete _instance; + _instance = 0; + } +} + +unsigned int AntKeyMapper::returnQtKey(unsigned int key, unsigned int scancode) +{ + return internalMapper->returnQtKey(key, scancode); +} + +unsigned int AntKeyMapper::returnVirtualKey(unsigned int qkey) +{ + return internalMapper->returnVirtualKey(qkey); +} + +bool AntKeyMapper::isModifierKey(unsigned int qkey) +{ + return internalMapper->isModifier(qkey); +} + +QtKeyMapperBase* AntKeyMapper::getNativeKeyMapper() +{ + return nativeKeyMapper; +} + +QtKeyMapperBase* AntKeyMapper::getKeyMapper() +{ + return internalMapper; +} + +bool AntKeyMapper::hasNativeKeyMapper() +{ + bool result = nativeKeyMapper != 0; + return result; +} diff --git a/src/antkeymapper.h b/src/antkeymapper.h new file mode 100644 index 0000000..c27bb7b --- /dev/null +++ b/src/antkeymapper.h @@ -0,0 +1,85 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef ANTKEYMAPPER_H +#define ANTKEYMAPPER_H + +#include + +#ifdef Q_OS_WIN + #include "qtwinkeymapper.h" + + #ifdef WITH_VMULTI + #include "qtvmultikeymapper.h" + #endif +#else + + #if defined(WITH_XTEST) + #include "qtx11keymapper.h" + #endif + + #if defined(WITH_UINPUT) + #include "qtuinputkeymapper.h" + #endif +#endif + +class AntKeyMapper : public QObject +{ + Q_OBJECT +public: + static AntKeyMapper* getInstance(QString handler = ""); + void deleteInstance(); + + unsigned int returnVirtualKey(unsigned int qkey); + unsigned int returnQtKey(unsigned int key, unsigned int scancode=0); + bool isModifierKey(unsigned int qkey); + QtKeyMapperBase* getNativeKeyMapper(); + QtKeyMapperBase* getKeyMapper(); + bool hasNativeKeyMapper(); + +protected: + explicit AntKeyMapper(QString handler = "", QObject *parent = 0); + + static AntKeyMapper *_instance; + QtKeyMapperBase *internalMapper; + QtKeyMapperBase *nativeKeyMapper; + +#ifdef Q_OS_WIN + QtWinKeyMapper winMapper; + + #ifdef WITH_VMULTI + QtVMultiKeyMapper vmultiMapper; + #endif + +#else + #if defined(WITH_XTEST) + QtX11KeyMapper x11Mapper; + #endif + + #if defined(WITH_UINPUT) + QtUInputKeyMapper uinputMapper; + #endif + +#endif + +signals: + +public slots: + +}; + +#endif // ANTKEYMAPPER_H diff --git a/src/applaunchhelper.cpp b/src/applaunchhelper.cpp new file mode 100644 index 0000000..4caa96d --- /dev/null +++ b/src/applaunchhelper.cpp @@ -0,0 +1,181 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include "applaunchhelper.h" + +#ifdef Q_OS_WIN +#include +#endif + +AppLaunchHelper::AppLaunchHelper(AntiMicroSettings *settings, bool graphical, + QObject *parent) : + QObject(parent) +{ + this->settings = settings; + this->graphical = graphical; +} + +void AppLaunchHelper::initRunMethods() +{ + if (graphical) + { + establishMouseTimerConnections(); + enablePossibleMouseSmoothing(); + changeMouseRefreshRate(); + changeSpringModeScreen(); + changeGamepadPollRate(); + +#ifdef Q_OS_WIN + checkPointerPrecision(); +#endif + } +} + +void AppLaunchHelper::enablePossibleMouseSmoothing() +{ + bool smoothingEnabled = settings->value("Mouse/Smoothing", false).toBool(); + if (smoothingEnabled) + { + int historySize = settings->value("Mouse/HistorySize", 0).toInt(); + if (historySize > 0) + { + JoyButton::setMouseHistorySize(historySize); + } + + double weightModifier = settings->value("Mouse/WeightModifier", 0.0).toDouble(); + if (weightModifier > 0.0) + { + JoyButton::setWeightModifier(weightModifier); + } + } +} + +void AppLaunchHelper::changeMouseRefreshRate() +{ + int refreshRate = settings->value("Mouse/RefreshRate", 0).toInt(); + if (refreshRate > 0) + { + JoyButton::setMouseRefreshRate(refreshRate); + } +} + +void AppLaunchHelper::changeGamepadPollRate() +{ + unsigned int pollRate = settings->value("GamepadPollRate", + AntiMicroSettings::defaultSDLGamepadPollRate).toUInt(); + if (pollRate > 0) + { + JoyButton::setGamepadRefreshRate(pollRate); + } +} + +void AppLaunchHelper::printControllerList(QMap *joysticks) +{ + QTextStream outstream(stdout); + + outstream << QObject::tr("# of joysticks found: %1").arg(joysticks->size()) << endl; + outstream << endl; + outstream << QObject::tr("List Joysticks:") << endl; + outstream << QObject::tr("---------------") << endl; + QMapIterator iter(*joysticks); + unsigned int indexNumber = 1; + while (iter.hasNext()) + { + InputDevice *tempdevice = iter.next().value(); + outstream << QObject::tr("Joystick %1:").arg(indexNumber) << endl; + outstream << " " << QObject::tr("Index: %1").arg(tempdevice->getRealJoyNumber()) << endl; +#ifdef USE_SDL_2 + outstream << " " << QObject::tr("GUID: %1").arg(tempdevice->getGUIDString()) << endl; +#endif + outstream << " " << QObject::tr("Name: %1").arg(tempdevice->getSDLName()) << endl; +#ifdef USE_SDL_2 + QString gameControllerStatus = tempdevice->isGameController() ? + QObject::tr("Yes") : QObject::tr("No"); + outstream << " " << QObject::tr("Game Controller: %1").arg(gameControllerStatus) << endl; +#endif + + outstream << " " << QObject::tr("# of Axes: %1").arg(tempdevice->getNumberRawAxes()) << endl; + outstream << " " << QObject::tr("# of Buttons: %1").arg(tempdevice->getNumberRawButtons()) << endl; + outstream << " " << QObject::tr("# of Hats: %1").arg(tempdevice->getNumberHats()) << endl; + + if (iter.hasNext()) + { + outstream << endl; + indexNumber++; + } + } +} + +void AppLaunchHelper::changeSpringModeScreen() +{ + QDesktopWidget deskWid; + int springScreen = settings->value("Mouse/SpringScreen", + AntiMicroSettings::defaultSpringScreen).toInt(); + + if (springScreen >= deskWid.screenCount()) + { + springScreen = -1; + settings->setValue("Mouse/SpringScreen", + AntiMicroSettings::defaultSpringScreen); + settings->sync(); + } + + JoyButton::setSpringModeScreen(springScreen); +} + +#ifdef Q_OS_WIN +void AppLaunchHelper::checkPointerPrecision() +{ + WinExtras::grabCurrentPointerPrecision(); + bool disableEnhandedPoint = settings->value("Mouse/DisableWinEnhancedPointer", + AntiMicroSettings::defaultDisabledWinEnhanced).toBool(); + if (disableEnhandedPoint) + { + WinExtras::disablePointerPrecision(); + } +} + +void AppLaunchHelper::appQuitPointerPrecision() +{ + bool disableEnhancedPoint = settings->value("Mouse/DisableWinEnhancedPointer", + AntiMicroSettings::defaultDisabledWinEnhanced).toBool(); + if (disableEnhancedPoint && !WinExtras::isUsingEnhancedPointerPrecision()) + { + WinExtras::enablePointerPrecision(); + } +} + +#endif + +void AppLaunchHelper::revertMouseThread() +{ + JoyButton::indirectStaticMouseThread(QThread::currentThread()); +} + +void AppLaunchHelper::changeMouseThread(QThread *thread) +{ + JoyButton::setStaticMouseThread(thread); +} + +void AppLaunchHelper::establishMouseTimerConnections() +{ + JoyButton::establishMouseTimerConnections(); +} diff --git a/src/applaunchhelper.h b/src/applaunchhelper.h new file mode 100644 index 0000000..fe080e2 --- /dev/null +++ b/src/applaunchhelper.h @@ -0,0 +1,63 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef APPLAUNCHHELPER_H +#define APPLAUNCHHELPER_H + +#include +#include +#include + +#include "inputdevice.h" +#include "joybutton.h" +#include "antimicrosettings.h" + +class AppLaunchHelper : public QObject +{ + Q_OBJECT +public: + explicit AppLaunchHelper(AntiMicroSettings *settings, bool graphical=false, + QObject *parent=0); + + void printControllerList(QMap *joysticks); + +protected: + void enablePossibleMouseSmoothing(); + void establishMouseTimerConnections(); + void changeMouseRefreshRate(); + void changeSpringModeScreen(); + void changeGamepadPollRate(); +#ifdef Q_OS_WIN + void checkPointerPrecision(); +#endif + + AntiMicroSettings *settings; + bool graphical; + +signals: + +public slots: +#ifdef Q_OS_WIN + void appQuitPointerPrecision(); +#endif + + void initRunMethods(); + void revertMouseThread(); + void changeMouseThread(QThread *thread); +}; + +#endif // APPLAUNCHHELPER_H diff --git a/src/autoprofileinfo.cpp b/src/autoprofileinfo.cpp new file mode 100644 index 0000000..7f380fd --- /dev/null +++ b/src/autoprofileinfo.cpp @@ -0,0 +1,158 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "autoprofileinfo.h" + +AutoProfileInfo::AutoProfileInfo(QString guid, QString profileLocation, + QString exe, bool active, QObject *parent) : + QObject(parent) +{ + setGUID(guid); + setProfileLocation(profileLocation); + setExe(exe); + setActive(active); + setDefaultState(false); +} + +AutoProfileInfo::AutoProfileInfo(QString guid, QString profileLocation, + bool active, QObject *parent) : + QObject(parent) +{ + setGUID(guid); + setProfileLocation(profileLocation); + setActive(active); + setDefaultState(false); +} + +AutoProfileInfo::AutoProfileInfo(QObject *parent) : + QObject(parent) +{ + setActive(true); + setDefaultState(false); +} + +AutoProfileInfo::~AutoProfileInfo() +{ +} + +void AutoProfileInfo::setGUID(QString guid) +{ + this->guid = guid; +} + +QString AutoProfileInfo::getGUID() +{ + return guid; +} + +void AutoProfileInfo::setProfileLocation(QString profileLocation) +{ + QFileInfo info(profileLocation); + if (profileLocation != this->profileLocation && + info.exists() && info.isReadable()) + { + this->profileLocation = profileLocation; + } + else if (profileLocation.isEmpty()) + { + this->profileLocation = ""; + } +} + +QString AutoProfileInfo::getProfileLocation() +{ + return profileLocation; +} + +void AutoProfileInfo::setExe(QString exe) +{ + if (!exe.isEmpty()) + { + QFileInfo info(exe); + if (exe != this->exe && info.exists() && info.isExecutable()) + { + this->exe = exe; + } +#ifdef Q_OS_WIN + else if (exe != this->exe && info.suffix() == "exe") + { + this->exe = exe; + } +#endif + } + else + { + this->exe = exe; + } +} + +QString AutoProfileInfo::getExe() +{ + return exe; +} + +void AutoProfileInfo::setWindowClass(QString windowClass) +{ + this->windowClass = windowClass; +} + +QString AutoProfileInfo::getWindowClass() +{ + return windowClass; +} + +void AutoProfileInfo::setWindowName(QString winName) +{ + this->windowName = winName; +} + +QString AutoProfileInfo::getWindowName() +{ + return windowName; +} + +void AutoProfileInfo::setActive(bool active) +{ + this->active = active; +} + +bool AutoProfileInfo::isActive() +{ + return active; +} + +void AutoProfileInfo::setDefaultState(bool value) +{ + this->defaultState = value; +} + +bool AutoProfileInfo::isCurrentDefault() +{ + return defaultState; +} + +void AutoProfileInfo::setDeviceName(QString name) +{ + this->deviceName = name; +} + +QString AutoProfileInfo::getDeviceName() +{ + return deviceName; +} diff --git a/src/autoprofileinfo.h b/src/autoprofileinfo.h new file mode 100644 index 0000000..9101b50 --- /dev/null +++ b/src/autoprofileinfo.h @@ -0,0 +1,77 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef AUTOPROFILEINFO_H +#define AUTOPROFILEINFO_H + +#include +#include + +class AutoProfileInfo : public QObject +{ + Q_OBJECT +public: + explicit AutoProfileInfo(QString guid, QString profileLocation, + bool active, QObject *parent = 0); + explicit AutoProfileInfo(QString guid, QString profileLocation, + QString exe, bool active, QObject *parent = 0); + explicit AutoProfileInfo(QObject *parent=0); + ~AutoProfileInfo(); + + void setGUID(QString guid); + QString getGUID(); + + void setProfileLocation(QString profileLocation); + QString getProfileLocation(); + + void setExe(QString exe); + QString getExe(); + + void setWindowClass(QString windowClass); + QString getWindowClass(); + + void setWindowName(QString winName); + QString getWindowName(); + + void setActive(bool active); + bool isActive(); + + void setDeviceName(QString name); + QString getDeviceName(); + + void setDefaultState(bool value); + bool isCurrentDefault(); + +protected: + QString guid; + QString profileLocation; + QString exe; + QString deviceName; + QString windowClass; + QString windowName; + bool active; + bool defaultState; + +signals: + +public slots: + +}; + +Q_DECLARE_METATYPE(AutoProfileInfo*) + +#endif // AUTOPROFILEINFO_H diff --git a/src/autoprofilewatcher.cpp b/src/autoprofilewatcher.cpp new file mode 100644 index 0000000..fd7f8d4 --- /dev/null +++ b/src/autoprofilewatcher.cpp @@ -0,0 +1,484 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +//#include +#include +#include +#include +#include +#include +#include +#include + +#include "autoprofilewatcher.h" + +#if defined(Q_OS_UNIX) && defined(WITH_X11) +#include "x11extras.h" + +#elif defined(Q_OS_WIN) +#include "winextras.h" + +#endif + +AutoProfileWatcher::AutoProfileWatcher(AntiMicroSettings *settings, QObject *parent) : + QObject(parent) +{ + this->settings = settings; + allDefaultInfo = 0; + currentApplication = ""; + + syncProfileAssignment(); + + connect(&appTimer, SIGNAL(timeout()), this, SLOT(runAppCheck())); +} + +void AutoProfileWatcher::startTimer() +{ + appTimer.start(CHECKTIME); +} + +void AutoProfileWatcher::stopTimer() +{ + appTimer.stop(); +} + +void AutoProfileWatcher::runAppCheck() +{ + //qDebug() << qApp->applicationFilePath(); + QString appLocation; + QString baseAppFileName; + guidSet.clear(); + + // Check whether program path needs to be parsed. Removes processing time + // and need to run Linux specific code searching /proc. +#ifdef Q_OS_LINUX + if (!appProfileAssignments.isEmpty()) + { + appLocation = findAppLocation(); + } +#else + // In Windows, get program location no matter what. + appLocation = findAppLocation(); + if (!appLocation.isEmpty()) + { + baseAppFileName = QFileInfo(appLocation).fileName(); + } +#endif + + // More portable check for whether antimicro is the current application + // with focus. + QWidget *focusedWidget = qApp->activeWindow(); + + QString nowWindow; + QString nowWindowClass; + QString nowWindowName; + +#ifdef Q_OS_WIN + nowWindowName = WinExtras::getCurrentWindowText(); +#else + unsigned long currentWindow = X11Extras::getInstance()->getWindowInFocus(); + if (currentWindow > 0) + { + unsigned long tempWindow = X11Extras::getInstance()->findParentClient(currentWindow); + if (tempWindow > 0) + { + currentWindow = tempWindow; + } + nowWindow = QString::number(currentWindow); + nowWindowClass = X11Extras::getInstance()->getWindowClass(currentWindow); + nowWindowName = X11Extras::getInstance()->getWindowTitle(currentWindow); + //qDebug() << nowWindowClass; + //qDebug() << nowWindowName; + } +#endif + + bool checkForTitleChange = windowNameProfileAssignments.size() > 0; + +#ifdef Q_OS_WIN + if (!focusedWidget && ((!appLocation.isEmpty() && appLocation != currentApplication) || + (checkForTitleChange && nowWindowName != currentAppWindowTitle))) + +#else + if (!focusedWidget && ((!nowWindow.isEmpty() && nowWindow != currentApplication) || + (checkForTitleChange && nowWindowName != currentAppWindowTitle))) + +#endif + { + +#ifdef Q_OS_WIN + currentApplication = appLocation; +#else + currentApplication = nowWindow; +#endif + + currentAppWindowTitle = nowWindowName; + //currentApplication = appLocation; + + QSet fullSet; + + if (!appLocation.isEmpty() && appProfileAssignments.contains(appLocation)) + { + QSet tempSet; + tempSet = appProfileAssignments.value(appLocation).toSet(); + fullSet.unite(tempSet); + } + else if (!baseAppFileName.isEmpty() && appProfileAssignments.contains(baseAppFileName)) + { + QSet tempSet; + tempSet = appProfileAssignments.value(baseAppFileName).toSet(); + fullSet.unite(tempSet); + } + + if (!nowWindowClass.isEmpty() && windowClassProfileAssignments.contains(nowWindowClass)) + { + QSet tempSet; + tempSet = windowClassProfileAssignments.value(nowWindowClass).toSet(); + fullSet.unite(tempSet); + } + + if (!nowWindowName.isEmpty() && windowNameProfileAssignments.contains(nowWindowName)) + { + QSet tempSet; + tempSet = windowNameProfileAssignments.value(nowWindowName).toSet(); + fullSet = fullSet.unite(tempSet); + } + + QHash highestMatchCount; + QHash highestMatches; + + QSetIterator fullSetIter(fullSet); + while (fullSetIter.hasNext()) + { + AutoProfileInfo *info = fullSetIter.next(); + if (info->isActive()) + { + int numProps = 0; + numProps += !info->getExe().isEmpty() ? 1 : 0; + numProps += !info->getWindowClass().isEmpty() ? 1 : 0; + numProps += !info->getWindowName().isEmpty() ? 1 : 0; + + int numMatched = 0; + numMatched += (!info->getExe().isEmpty() && + info->getExe() == appLocation) ? 1 : 0; + numMatched += (!info->getWindowClass().isEmpty() && + info->getWindowClass() == nowWindowClass) ? 1 : 0; + numMatched += (!info->getWindowName().isEmpty() && + info->getWindowName() == nowWindowName) ? 1 : 0; + + if (numProps == numMatched) + { + if (highestMatchCount.contains(info->getGUID())) + { + int currentHigh = highestMatchCount.value(info->getGUID()); + if (numMatched > currentHigh) + { + highestMatchCount.insert(info->getGUID(), numMatched); + highestMatches.insert(info->getGUID(), info); + } + } + else + { + highestMatchCount.insert(info->getGUID(), numMatched); + highestMatches.insert(info->getGUID(), info); + } + } + } + } + + QHashIterator highIter(highestMatches); + while (highIter.hasNext()) + { + AutoProfileInfo *info = highIter.next().value(); + guidSet.insert(info->getGUID()); + emit foundApplicableProfile(info); + } + + if ((!defaultProfileAssignments.isEmpty() || allDefaultInfo) && !focusedWidget) + //antiProgramLocation != appLocation) + { + if (allDefaultInfo) + { + if (allDefaultInfo->isActive() && !guidSet.contains("all")) + { + emit foundApplicableProfile(allDefaultInfo); + } + } + + QHashIterator iter(defaultProfileAssignments); + while (iter.hasNext()) + { + iter.next(); + AutoProfileInfo *info = iter.value(); + if (info->isActive() && !guidSet.contains(info->getGUID())) + { + emit foundApplicableProfile(info); + } + } + } + } +} + +void AutoProfileWatcher::syncProfileAssignment() +{ + clearProfileAssignments(); + + currentApplication = ""; + + //QStringList assignments = settings->allKeys(); + //QStringListIterator iter(assignments); + + settings->getLock()->lock(); + settings->beginGroup("DefaultAutoProfiles"); + QString exe; + QString guid; + QString profile; + QString active; + QString windowClass; + QString windowName; + + QStringList registeredGUIDs = settings->value("GUIDs", QStringList()).toStringList(); + //QStringList defaultkeys = settings->allKeys(); + settings->endGroup(); + + QString allProfile = settings->value(QString("DefaultAutoProfileAll/Profile"), "").toString(); + QString allActive = settings->value(QString("DefaultAutoProfileAll/Active"), "0").toString(); + + // Handle overall Default profile assignment + bool defaultActive = allActive == "1" ? true : false; + if (defaultActive) + { + allDefaultInfo = new AutoProfileInfo("all", allProfile, defaultActive, this); + allDefaultInfo->setDefaultState(true); + } + + // Handle device specific Default profile assignments + QStringListIterator iter(registeredGUIDs); + while (iter.hasNext()) + { + QString tempkey = iter.next(); + QString guid = QString(tempkey).replace("GUID", ""); + + QString profile = settings->value(QString("DefaultAutoProfile-%1/Profile").arg(guid), "").toString(); + QString active = settings->value(QString("DefaultAutoProfile-%1/Active").arg(guid), "").toString(); + + if (!guid.isEmpty() && !profile.isEmpty()) + { + bool profileActive = active == "1" ? true : false; + if (profileActive && guid != "all") + { + AutoProfileInfo *info = new AutoProfileInfo(guid, profile, profileActive, this); + info->setDefaultState(true); + defaultProfileAssignments.insert(guid, info); + } + } + } + + settings->beginGroup("AutoProfiles"); + bool quitSearch = false; + + //QHash > tempAssociation; + for (int i = 1; !quitSearch; i++) + { + exe = settings->value(QString("AutoProfile%1Exe").arg(i), "").toString(); + exe = QDir::toNativeSeparators(exe); + guid = settings->value(QString("AutoProfile%1GUID").arg(i), "").toString(); + profile = settings->value(QString("AutoProfile%1Profile").arg(i), "").toString(); + active = settings->value(QString("AutoProfile%1Active").arg(i), 0).toString(); + windowName = settings->value(QString("AutoProfile%1WindowName").arg(i), "").toString(); +#ifdef Q_OS_UNIX + windowClass = settings->value(QString("AutoProfile%1WindowClass").arg(i), "").toString(); +#else + windowClass.clear(); +#endif + + // Check if all required elements exist. If not, assume that the end of the + // list has been reached. + if ((!exe.isEmpty() || !windowClass.isEmpty() || !windowName.isEmpty()) && + !guid.isEmpty()) + { + bool profileActive = active == "1" ? true : false; + if (profileActive) + { + AutoProfileInfo *info = new AutoProfileInfo(guid, profile, profileActive, this); + + if (!windowClass.isEmpty()) + { + info->setWindowClass(windowClass); + + QList templist; + if (windowClassProfileAssignments.contains(windowClass)) + { + templist = windowClassProfileAssignments.value(windowClass); + } + templist.append(info); + windowClassProfileAssignments.insert(windowClass, templist); + } + + if (!windowName.isEmpty()) + { + info->setWindowName(windowName); + + QList templist; + if (windowNameProfileAssignments.contains(windowName)) + { + templist = windowNameProfileAssignments.value(windowName); + } + templist.append(info); + windowNameProfileAssignments.insert(windowName, templist); + } + + if (!exe.isEmpty()) + { + info->setExe(exe); + + QList templist; + if (appProfileAssignments.contains(exe)) + { + templist = appProfileAssignments.value(exe); + } + templist.append(info); + appProfileAssignments.insert(exe, templist); + + QString baseExe = QFileInfo(exe).fileName(); + if (!baseExe.isEmpty() && baseExe != exe) + { + QList templist; + if (appProfileAssignments.contains(baseExe)) + { + templist = appProfileAssignments.value(baseExe); + } + templist.append(info); + appProfileAssignments.insert(baseExe, templist); + } + } + } + } + else + { + quitSearch = true; + } + } + + settings->endGroup(); + settings->getLock()->unlock(); +} + +void AutoProfileWatcher::clearProfileAssignments() +{ + QSet terminateProfiles; + + QListIterator > iterDelete(appProfileAssignments.values()); + while (iterDelete.hasNext()) + { + QList templist = iterDelete.next(); + terminateProfiles.unite(templist.toSet()); + } + appProfileAssignments.clear(); + + QListIterator > iterClassDelete(windowClassProfileAssignments.values()); + while (iterClassDelete.hasNext()) + { + QList templist = iterClassDelete.next(); + terminateProfiles.unite(templist.toSet()); + } + windowClassProfileAssignments.clear(); + + QListIterator > iterNameDelete(windowNameProfileAssignments.values()); + while (iterNameDelete.hasNext()) + { + QList templist = iterNameDelete.next(); + terminateProfiles.unite(templist.toSet()); + } + windowNameProfileAssignments.clear(); + + QSetIterator iterTerminate(terminateProfiles); + while (iterTerminate.hasNext()) + { + AutoProfileInfo *info = iterTerminate.next(); + if (info) + { + delete info; + info = 0; + } + } + + QListIterator iterDefaultsDelete(defaultProfileAssignments.values()); + while (iterDefaultsDelete.hasNext()) + { + AutoProfileInfo *info = iterDefaultsDelete.next(); + if (info) + { + delete info; + info = 0; + } + } + defaultProfileAssignments.clear(); + + allDefaultInfo = 0; + guidSet.clear(); +} + +QString AutoProfileWatcher::findAppLocation() +{ + QString exepath; + +#if defined(Q_OS_LINUX) + #ifdef WITH_X11 + Window currentWindow = 0; + int pid = 0; + + currentWindow = X11Extras::getInstance()->getWindowInFocus(); + if (currentWindow) + { + pid = X11Extras::getInstance()->getApplicationPid(currentWindow); + } + + if (pid > 0) + { + exepath = X11Extras::getInstance()->getApplicationLocation(pid); + } + #endif + +#elif defined(Q_OS_WIN) + exepath = WinExtras::getForegroundWindowExePath(); + //qDebug() << exepath; +#endif + + return exepath; +} + +QList* AutoProfileWatcher::getCustomDefaults() +{ + QList *temp = new QList(); + QHashIterator iter(defaultProfileAssignments); + while (iter.hasNext()) + { + iter.next(); + temp->append(iter.value()); + } + return temp; +} + +AutoProfileInfo* AutoProfileWatcher::getDefaultAllProfile() +{ + return allDefaultInfo; +} + +bool AutoProfileWatcher::isGUIDLocked(QString guid) +{ + return guidSet.contains(guid); +} diff --git a/src/autoprofilewatcher.h b/src/autoprofilewatcher.h new file mode 100644 index 0000000..d24d8a7 --- /dev/null +++ b/src/autoprofilewatcher.h @@ -0,0 +1,74 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef AUTOPROFILEWATCHER_H +#define AUTOPROFILEWATCHER_H + +#include +#include +#include +#include +#include + +#include "autoprofileinfo.h" +#include "antimicrosettings.h" + + +class AutoProfileWatcher : public QObject +{ + Q_OBJECT +public: + explicit AutoProfileWatcher(AntiMicroSettings *settings, QObject *parent = 0); + void startTimer(); + void stopTimer(); + QList* getCustomDefaults(); + AutoProfileInfo* getDefaultAllProfile(); + bool isGUIDLocked(QString guid); + + static const int CHECKTIME = 1000; // time in ms + +protected: + QString findAppLocation(); + void clearProfileAssignments(); + + QTimer appTimer; + AntiMicroSettings *settings; + // Path, QList + QHash > appProfileAssignments; + // WM_CLASS, QList + QHash > windowClassProfileAssignments; + // WM_NAME, QList + QHash > windowNameProfileAssignments; + // GUID, AutoProfileInfo* + QHash defaultProfileAssignments; + //QList *customDefaults; + AutoProfileInfo *allDefaultInfo; + QString currentApplication; + QString currentAppWindowTitle; + QSet guidSet; + +signals: + void foundApplicableProfile(AutoProfileInfo *info); + +public slots: + void syncProfileAssignment(); + +private slots: + void runAppCheck(); +}; + +#endif // AUTOPROFILEWATCHER_H diff --git a/src/axiseditdialog.cpp b/src/axiseditdialog.cpp new file mode 100644 index 0000000..69dade5 --- /dev/null +++ b/src/axiseditdialog.cpp @@ -0,0 +1,653 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +//#include +#include + +#include "axiseditdialog.h" +#include "ui_axiseditdialog.h" +#include "buttoneditdialog.h" +#include "mousedialog/mouseaxissettingsdialog.h" +#include "event.h" +#include "antkeymapper.h" +#include "setjoystick.h" +#include "inputdevice.h" +#include "common.h" + +AxisEditDialog::AxisEditDialog(JoyAxis *axis, QWidget *parent) : + QDialog(parent, Qt::Window), + ui(new Ui::AxisEditDialog) +{ + ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + + setAxisThrottleConfirm = new SetAxisThrottleDialog(axis, this); + + this->axis = axis; + + updateWindowTitleAxisName(); + + initialThrottleState = axis->getThrottle(); + bool actAsTrigger = false; + if (initialThrottleState == JoyAxis::PositiveThrottle || + initialThrottleState == JoyAxis::PositiveHalfThrottle) + { + actAsTrigger = true; + } + + if (actAsTrigger) + { + buildTriggerPresetsMenu(); + } + + ui->horizontalSlider->setValue(axis->getDeadZone()); + ui->lineEdit->setText(QString::number(axis->getDeadZone())); + + ui->horizontalSlider_2->setValue(axis->getMaxZoneValue()); + ui->lineEdit_2->setText(QString::number(axis->getMaxZoneValue())); + + JoyAxisButton *nButton = axis->getNAxisButton(); + + if (!nButton->getActionName().isEmpty()) + { + ui->nPushButton->setText(nButton->getActionName()); + } + else + { + ui->nPushButton->setText(nButton->getSlotsSummary()); + } + + JoyAxisButton *pButton = axis->getPAxisButton(); + + if (!pButton->getActionName().isEmpty()) + { + ui->pPushButton->setText(pButton->getActionName()); + } + else + { + ui->pPushButton->setText(pButton->getSlotsSummary()); + } + + int currentThrottle = axis->getThrottle(); + //ui->comboBox_2->setCurrentIndex(currentThrottle+1); + if (currentThrottle == JoyAxis::NegativeThrottle || currentThrottle == JoyAxis::NegativeHalfThrottle) + { + int tempindex = currentThrottle == JoyAxis::NegativeHalfThrottle ? 0 : 1; + ui->comboBox_2->setCurrentIndex(tempindex); + ui->nPushButton->setEnabled(true); + ui->pPushButton->setEnabled(false); + } + else if (currentThrottle == JoyAxis::PositiveThrottle || currentThrottle == JoyAxis::PositiveHalfThrottle) + { + int tempindex = currentThrottle == JoyAxis::PositiveThrottle ? 3 : 4; + ui->comboBox_2->setCurrentIndex(tempindex); + ui->pPushButton->setEnabled(true); + ui->nPushButton->setEnabled(false); + } + + ui->axisstatusBox->setDeadZone(axis->getDeadZone()); + ui->axisstatusBox->setMaxZone(axis->getMaxZoneValue()); + ui->axisstatusBox->setThrottle(axis->getThrottle()); + + ui->joyValueLabel->setText(QString::number(axis->getCurrentRawValue())); + ui->axisstatusBox->setValue(axis->getCurrentRawValue()); + + if (!actAsTrigger) + { + selectAxisCurrentPreset(); + } + else + { + selectTriggerPreset(); + } + + ui->axisNameLineEdit->setText(axis->getAxisName()); + + connect(ui->presetsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(implementPresets(int))); + + connect(ui->horizontalSlider, SIGNAL(valueChanged(int)), this, SLOT(updateDeadZoneBox(int))); + connect(ui->horizontalSlider, SIGNAL(valueChanged(int)), ui->axisstatusBox, SLOT(setDeadZone(int))); + connect(ui->horizontalSlider, SIGNAL(valueChanged(int)), axis, SLOT(setDeadZone(int))); + + connect(ui->horizontalSlider_2, SIGNAL(valueChanged(int)), this, SLOT(updateMaxZoneBox(int))); + connect(ui->horizontalSlider_2, SIGNAL(valueChanged(int)), ui->axisstatusBox, SLOT(setMaxZone(int))); + connect(ui->horizontalSlider_2, SIGNAL(valueChanged(int)), axis, SLOT(setMaxZoneValue(int))); + + connect(ui->comboBox_2, SIGNAL(currentIndexChanged(int)), this, SLOT(updateThrottleUi(int))); + connect(ui->comboBox_2, SIGNAL(currentIndexChanged(int)), this, SLOT(presetForThrottleChange(int))); + + connect(axis, SIGNAL(moved(int)), ui->axisstatusBox, SLOT(setValue(int))); + connect(axis, SIGNAL(moved(int)), this, SLOT(updateJoyValue(int))); + + connect(ui->lineEdit, SIGNAL(textEdited(QString)), this, SLOT(updateDeadZoneSlider(QString))); + connect(ui->lineEdit_2, SIGNAL(textEdited(QString)), this, SLOT(updateMaxZoneSlider(QString))); + + connect(ui->nPushButton, SIGNAL(clicked()), this, SLOT(openAdvancedNDialog())); + connect(ui->pPushButton, SIGNAL(clicked()), this, SLOT(openAdvancedPDialog())); + + connect(ui->mouseSettingsPushButton, SIGNAL(clicked()), this, SLOT(openMouseSettingsDialog())); + connect(ui->axisNameLineEdit, SIGNAL(textEdited(QString)), axis, SLOT(setAxisName(QString))); + + connect(axis, SIGNAL(axisNameChanged()), this, SLOT(updateWindowTitleAxisName())); + connect(this, SIGNAL(finished(int)), this, SLOT(checkFinalSettings())); +} + +AxisEditDialog::~AxisEditDialog() +{ + delete ui; +} + +void AxisEditDialog::implementPresets(int index) +{ + bool actAsTrigger = false; + int currentThrottle = axis->getThrottle(); + if (currentThrottle == JoyAxis::PositiveThrottle || + currentThrottle == JoyAxis::PositiveHalfThrottle) + { + actAsTrigger = true; + } + + if (actAsTrigger) + { + implementTriggerPresets(index); + } + else + { + implementAxisPresets(index); + } +} + +void AxisEditDialog::implementAxisPresets(int index) +{ + JoyButtonSlot *nbuttonslot = 0; + JoyButtonSlot *pbuttonslot = 0; + + PadderCommon::lockInputDevices(); + InputDevice *tempDevice = axis->getParentSet()->getInputDevice(); + QMetaObject::invokeMethod(tempDevice, "haltServices", Qt::BlockingQueuedConnection); + + if (index == 1) + { + nbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); + pbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); + } + else if (index == 2) + { + nbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); + pbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); + } + else if (index == 3) + { + nbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); + pbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); + } + else if (index == 4) + { + nbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); + pbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); + } + else if (index == 5) + { + nbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Up), Qt::Key_Up, JoyButtonSlot::JoyKeyboard, this); + pbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Down), Qt::Key_Down, JoyButtonSlot::JoyKeyboard, this); + } + else if (index == 6) + { + nbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Left), Qt::Key_Left, JoyButtonSlot::JoyKeyboard, this); + pbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Right), Qt::Key_Right, JoyButtonSlot::JoyKeyboard, this); + } + else if (index == 7) + { + nbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_W), Qt::Key_W, JoyButtonSlot::JoyKeyboard, this); + pbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_S), Qt::Key_S, JoyButtonSlot::JoyKeyboard, this); + } + else if (index == 8) + { + nbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_A), Qt::Key_A, JoyButtonSlot::JoyKeyboard, this); + pbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_D), Qt::Key_D, JoyButtonSlot::JoyKeyboard, this); + } + else if (index == 9) + { + nbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8), QtKeyMapperBase::AntKey_KP_8, JoyButtonSlot::JoyKeyboard, this); + pbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2), QtKeyMapperBase::AntKey_KP_2, JoyButtonSlot::JoyKeyboard, this); + } + else if (index == 10) + { + nbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4), QtKeyMapperBase::AntKey_KP_4, JoyButtonSlot::JoyKeyboard, this); + pbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6), QtKeyMapperBase::AntKey_KP_6, JoyButtonSlot::JoyKeyboard, this); + } + else if (index == 11) + { + JoyAxisButton *nbutton = axis->getNAxisButton(); + JoyAxisButton *pbutton = axis->getPAxisButton(); + + QMetaObject::invokeMethod(nbutton, "clearSlotsEventReset"); + QMetaObject::invokeMethod(pbutton, "clearSlotsEventReset", Qt::BlockingQueuedConnection); + + refreshNButtonLabel(); + refreshPButtonLabel(); + } + + if (nbuttonslot) + { + JoyAxisButton *button = axis->getNAxisButton(); + QMetaObject::invokeMethod(button, "clearSlotsEventReset", + Q_ARG(bool, false)); + + QMetaObject::invokeMethod(button, "setAssignedSlot", Qt::BlockingQueuedConnection, + Q_ARG(int, nbuttonslot->getSlotCode()), + Q_ARG(unsigned int, nbuttonslot->getSlotCodeAlias()), + Q_ARG(JoyButtonSlot::JoySlotInputAction, nbuttonslot->getSlotMode())); + + refreshNButtonLabel(); + nbuttonslot->deleteLater(); + } + + if (pbuttonslot) + { + JoyAxisButton *button = axis->getPAxisButton(); + QMetaObject::invokeMethod(button, "clearSlotsEventReset", Q_ARG(bool, false)); + + QMetaObject::invokeMethod(button, "setAssignedSlot", Qt::BlockingQueuedConnection, + Q_ARG(int, pbuttonslot->getSlotCode()), + Q_ARG(unsigned int, pbuttonslot->getSlotCodeAlias()), + Q_ARG(JoyButtonSlot::JoySlotInputAction, pbuttonslot->getSlotMode())); + + refreshPButtonLabel(); + pbuttonslot->deleteLater(); + } + + PadderCommon::unlockInputDevices(); +} + +void AxisEditDialog::updateDeadZoneBox(int value) +{ + ui->lineEdit->setText(QString::number(value)); +} + +void AxisEditDialog::updateMaxZoneBox(int value) +{ + ui->lineEdit_2->setText(QString::number(value)); +} + +void AxisEditDialog::updateThrottleUi(int index) +{ + int tempthrottle = 0; + if (index == 0 || index == 1) + { + ui->nPushButton->setEnabled(true); + ui->pPushButton->setEnabled(false); + tempthrottle = index == 0 ? JoyAxis::NegativeHalfThrottle : JoyAxis::NegativeThrottle; + } + else if (index == 2) + { + ui->nPushButton->setEnabled(true); + ui->pPushButton->setEnabled(true); + tempthrottle = JoyAxis::NormalThrottle; + } + else if (index == 3 || index == 4) + { + ui->pPushButton->setEnabled(true); + ui->nPushButton->setEnabled(false); + tempthrottle = index == 3 ? JoyAxis::PositiveThrottle : JoyAxis::PositiveHalfThrottle; + } + + axis->setThrottle(tempthrottle); + ui->axisstatusBox->setThrottle(tempthrottle); +} + +void AxisEditDialog::updateJoyValue(int value) +{ + ui->joyValueLabel->setText(QString::number(value)); +} + +void AxisEditDialog::updateDeadZoneSlider(QString value) +{ + int temp = value.toInt(); + if (temp >= JoyAxis::AXISMIN && temp <= JoyAxis::AXISMAX) + { + ui->horizontalSlider->setValue(temp); + } +} + +void AxisEditDialog::updateMaxZoneSlider(QString value) +{ + int temp = value.toInt(); + if (temp >= JoyAxis::AXISMIN && temp <= JoyAxis::AXISMAX) + { + ui->horizontalSlider_2->setValue(temp); + } +} + +void AxisEditDialog::openAdvancedPDialog() +{ + ButtonEditDialog *dialog = new ButtonEditDialog(axis->getPAxisButton(), this); + dialog->show(); + + connect(dialog, SIGNAL(finished(int)), this, SLOT(refreshPButtonLabel())); + connect(dialog, SIGNAL(finished(int)), this, SLOT(refreshPreset())); +} + +void AxisEditDialog::openAdvancedNDialog() +{ + ButtonEditDialog *dialog = new ButtonEditDialog(axis->getNAxisButton(), this); + dialog->show(); + + connect(dialog, SIGNAL(finished(int)), this, SLOT(refreshNButtonLabel())); + connect(dialog, SIGNAL(finished(int)), this, SLOT(refreshPreset())); +} + +void AxisEditDialog::refreshNButtonLabel() +{ + /*if (!axis->getNAxisButton()->getActionName().isEmpty()) + { + ui->nPushButton->setText(axis->getNAxisButton()->getActionName()); + } + else + { + ui->nPushButton->setText(axis->getNAxisButton()->getSlotsSummary()); + }*/ + ui->nPushButton->setText(axis->getNAxisButton()->getSlotsSummary()); +} + +void AxisEditDialog::refreshPButtonLabel() +{ + /*if (!axis->getPAxisButton()->getActionName().isEmpty()) + { + ui->pPushButton->setText(axis->getPAxisButton()->getActionName()); + } + else + { + ui->pPushButton->setText(axis->getPAxisButton()->getSlotsSummary()); + }*/ + ui->pPushButton->setText(axis->getPAxisButton()->getSlotsSummary()); + +} + +void AxisEditDialog::checkFinalSettings() +{ + if (axis->getThrottle() != initialThrottleState) + { + setAxisThrottleConfirm->exec(); + } +} + +void AxisEditDialog::selectAxisCurrentPreset() +{ + JoyAxisButton *naxisbutton = axis->getNAxisButton(); + QList *naxisslots = naxisbutton->getAssignedSlots(); + JoyAxisButton *paxisbutton = axis->getPAxisButton(); + QList *paxisslots = paxisbutton->getAssignedSlots(); + + if (naxisslots->length() == 1 && paxisslots->length() == 1) + { + JoyButtonSlot *nslot = naxisslots->at(0); + JoyButtonSlot *pslot = paxisslots->at(0); + if (nslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && nslot->getSlotCode() == JoyButtonSlot::MouseLeft && + pslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && pslot->getSlotCode() == JoyButtonSlot::MouseRight) + { + ui->presetsComboBox->setCurrentIndex(1); + } + else if (nslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && nslot->getSlotCode() == JoyButtonSlot::MouseRight && + pslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && pslot->getSlotCode() == JoyButtonSlot::MouseLeft) + { + ui->presetsComboBox->setCurrentIndex(2); + } + else if (nslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && nslot->getSlotCode() == JoyButtonSlot::MouseUp && + pslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && pslot->getSlotCode() == JoyButtonSlot::MouseDown) + { + ui->presetsComboBox->setCurrentIndex(3); + } + else if (nslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && nslot->getSlotCode() == JoyButtonSlot::MouseDown && + pslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && pslot->getSlotCode() == JoyButtonSlot::MouseUp) + { + ui->presetsComboBox->setCurrentIndex(4); + } + else if (nslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && (unsigned int)nslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Up) && + pslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && (unsigned int)pslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Down)) + { + ui->presetsComboBox->setCurrentIndex(5); + } + else if (nslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && (unsigned int)nslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Left) && + pslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && (unsigned int)pslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Right)) + { + ui->presetsComboBox->setCurrentIndex(6); + } + else if (nslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && (unsigned int)nslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_W) && + pslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && (unsigned int)pslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_S)) + { + ui->presetsComboBox->setCurrentIndex(7); + } + else if (nslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && (unsigned int)nslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_A) && + pslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && (unsigned int)pslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_D)) + { + ui->presetsComboBox->setCurrentIndex(8); + } + else if (nslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && (unsigned int)nslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8) && + pslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && (unsigned int)pslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2)) + { + ui->presetsComboBox->setCurrentIndex(9); + } + else if (nslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && (unsigned int)nslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4) && + pslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && (unsigned int)pslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6)) + { + ui->presetsComboBox->setCurrentIndex(10); + } + else + { + ui->presetsComboBox->setCurrentIndex(0); + } + } + else if (naxisslots->length() == 0 && paxisslots->length() == 0) + { + ui->presetsComboBox->setCurrentIndex(11); + } + else + { + ui->presetsComboBox->setCurrentIndex(0); + } +} + +void AxisEditDialog::selectTriggerPreset() +{ + JoyAxisButton *paxisbutton = axis->getPAxisButton(); + QList *paxisslots = paxisbutton->getAssignedSlots(); + + if (paxisslots->length() == 1) + { + JoyButtonSlot *pslot = paxisslots->at(0); + if (pslot->getSlotMode() == JoyButtonSlot::JoyMouseButton && pslot->getSlotCode() == JoyButtonSlot::MouseLB) + { + ui->presetsComboBox->setCurrentIndex(1); + } + else if (pslot->getSlotMode() == JoyButtonSlot::JoyMouseButton && pslot->getSlotCode() == JoyButtonSlot::MouseRB) + { + ui->presetsComboBox->setCurrentIndex(2); + } + else + { + ui->presetsComboBox->setCurrentIndex(0); + } + } + else if (paxisslots->length() == 0) + { + ui->presetsComboBox->setCurrentIndex(3); + } + else + { + ui->presetsComboBox->setCurrentIndex(0); + } +} + +void AxisEditDialog::implementTriggerPresets(int index) +{ + JoyButtonSlot *pbuttonslot = 0; + + if (index == 1) + { + pbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseLB, JoyButtonSlot::JoyMouseButton, this); + } + else if (index == 2) + { + pbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseRB, JoyButtonSlot::JoyMouseButton, this); + } + else if (index == 3) + { + JoyAxisButton *nbutton = axis->getNAxisButton(); + JoyAxisButton *pbutton = axis->getPAxisButton(); + + QMetaObject::invokeMethod(nbutton, "clearSlotsEventReset"); + QMetaObject::invokeMethod(pbutton, "clearSlotsEventReset", Qt::BlockingQueuedConnection); + + refreshNButtonLabel(); + refreshPButtonLabel(); + } + + if (pbuttonslot) + { + + JoyAxisButton *nbutton = axis->getNAxisButton(); + JoyAxisButton *pbutton = axis->getPAxisButton(); + if (nbutton->getAssignedSlots()->length() > 0) + { + QMetaObject::invokeMethod(nbutton, "clearSlotsEventReset", Qt::BlockingQueuedConnection, + Q_ARG(bool, false)); + refreshNButtonLabel(); + } + + QMetaObject::invokeMethod(pbutton, "clearSlotsEventReset", + Q_ARG(bool, false)); + + QMetaObject::invokeMethod(pbutton, "setAssignedSlot", Qt::BlockingQueuedConnection, + Q_ARG(int, pbuttonslot->getSlotCode()), + Q_ARG(unsigned int, pbuttonslot->getSlotCodeAlias()), + Q_ARG(JoyButtonSlot::JoySlotInputAction, pbuttonslot->getSlotMode())); + + refreshPButtonLabel(); + pbuttonslot->deleteLater(); + } +} + +void AxisEditDialog::refreshPreset() +{ + // Disconnect event associated with presetsComboBox so a change in the index does not + // alter the axis buttons + disconnect(ui->presetsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(implementPresets(int))); + selectAxisCurrentPreset(); + // Reconnect the event + connect(ui->presetsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(implementPresets(int))); +} + +void AxisEditDialog::openMouseSettingsDialog() +{ + ui->mouseSettingsPushButton->setEnabled(false); + + MouseAxisSettingsDialog *dialog = new MouseAxisSettingsDialog(this->axis, this); + dialog->show(); + connect(this, SIGNAL(finished(int)), dialog, SLOT(close())); + connect(dialog, SIGNAL(finished(int)), this, SLOT(enableMouseSettingButton())); +} + +void AxisEditDialog::enableMouseSettingButton() +{ + ui->mouseSettingsPushButton->setEnabled(true); +} + +void AxisEditDialog::updateWindowTitleAxisName() +{ + QString temp = QString(tr("Set")).append(" "); + + if (!axis->getAxisName().isEmpty()) + { + temp.append(axis->getPartialName(false, true)); + } + else + { + temp.append(axis->getPartialName()); + } + + if (axis->getParentSet()->getIndex() != 0) + { + unsigned int setIndex = axis->getParentSet()->getRealIndex(); + temp.append(" [").append(tr("Set %1").arg(setIndex)); + + QString setName = axis->getParentSet()->getName(); + if (!setName.isEmpty()) + { + temp.append(": ").append(setName); + } + + temp.append("]"); + } + + setWindowTitle(temp); +} + +void AxisEditDialog::buildAxisPresetsMenu() +{ + ui->presetsComboBox->clear(); + + ui->presetsComboBox->addItem(tr("")); + ui->presetsComboBox->addItem(tr("Mouse (Horizontal)")); + ui->presetsComboBox->addItem(tr("Mouse (Inverted Horizontal)")); + ui->presetsComboBox->addItem(tr("Mouse (Vertical)")); + ui->presetsComboBox->addItem(tr("Mouse (Inverted Vertical)")); + ui->presetsComboBox->addItem(tr("Arrows: Up | Down")); + ui->presetsComboBox->addItem(tr("Arrows: Left | Right")); + ui->presetsComboBox->addItem(tr("Keys: W | S")); + ui->presetsComboBox->addItem(tr("Keys: A | D")); + ui->presetsComboBox->addItem(tr("NumPad: KP_8 | KP_2")); + ui->presetsComboBox->addItem(tr("NumPad: KP_4 | KP_6")); + ui->presetsComboBox->addItem(tr("None")); +} + +void AxisEditDialog::buildTriggerPresetsMenu() +{ + ui->presetsComboBox->clear(); + + ui->presetsComboBox->addItem(tr("")); + ui->presetsComboBox->addItem(tr("Left Mouse Button")); + ui->presetsComboBox->addItem(tr("Right Mouse Button")); + ui->presetsComboBox->addItem(tr("None")); +} + +void AxisEditDialog::presetForThrottleChange(int index) +{ + Q_UNUSED(index); + + bool actAsTrigger = false; + int currentThrottle = axis->getThrottle(); + if (currentThrottle == JoyAxis::PositiveThrottle || + currentThrottle == JoyAxis::PositiveHalfThrottle) + { + actAsTrigger = true; + } + + disconnect(ui->presetsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(implementPresets(int))); + if (actAsTrigger) + { + buildTriggerPresetsMenu(); + selectTriggerPreset(); + } + else + { + buildAxisPresetsMenu(); + selectAxisCurrentPreset(); + } + + connect(ui->presetsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(implementPresets(int))); +} diff --git a/src/axiseditdialog.h b/src/axiseditdialog.h new file mode 100644 index 0000000..acbc684 --- /dev/null +++ b/src/axiseditdialog.h @@ -0,0 +1,78 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef AXISEDITDIALOG_H +#define AXISEDITDIALOG_H + +#include + +#include "joyaxis.h" +#include "axisvaluebox.h" +#include "setaxisthrottledialog.h" + +namespace Ui { +class AxisEditDialog; +} + +class AxisEditDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AxisEditDialog(JoyAxis *axis, QWidget *parent=0); + ~AxisEditDialog(); + +protected: + void selectAxisCurrentPreset(); + void selectTriggerPreset(); + + void buildTriggerPresetsMenu(); + void buildAxisPresetsMenu(); + + JoyAxis *axis; + SetAxisThrottleDialog *setAxisThrottleConfirm; + int initialThrottleState; + +private: + Ui::AxisEditDialog *ui; + +private slots: + void implementAxisPresets(int index); + void implementTriggerPresets(int index); + void implementPresets(int index); + void presetForThrottleChange(int index); + + void updateDeadZoneBox(int value); + void updateMaxZoneBox(int value); + void updateThrottleUi(int index); + void updateJoyValue(int value); + void updateDeadZoneSlider(QString value); + void updateMaxZoneSlider(QString value); + void openAdvancedPDialog(); + void openAdvancedNDialog(); + + void refreshPButtonLabel(); + void refreshNButtonLabel(); + void refreshPreset(); + + void checkFinalSettings(); + void openMouseSettingsDialog(); + void enableMouseSettingButton(); + void updateWindowTitleAxisName(); +}; + +#endif // AXISEDITDIALOG_H diff --git a/src/axiseditdialog.ui b/src/axiseditdialog.ui new file mode 100644 index 0000000..9c2e9e5 --- /dev/null +++ b/src/axiseditdialog.ui @@ -0,0 +1,575 @@ + + + AxisEditDialog + + + + 0 + 0 + 511 + 369 + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Axis + + + false + + + true + + + + + + 10 + + + + + 1 + + + Presets: + + + + + + + false + + + false + + + 12 + + + 12 + + + + + + + + + Mouse (Horizontal) + + + + + Mouse (Inverted Horizontal) + + + + + Mouse (Vertical) + + + + + Mouse (Inverted Vertical) + + + + + Arrows: Up | Down + + + + + Arrows: Left | Right + + + + + Keys: W | S + + + + + Keys: A | D + + + + + NumPad: KP_8 | KP_2 + + + + + NumPad: KP_4 | KP_6 + + + + + None + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + 10 + + + 10 + + + 10 + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + false + + + false + + + Set the value to use as the limit for an axis. Useful for a +worn out analog stick. + + + + + + + + + 5 + + + false + + + + + + + Dead Zone: + + + + + + + Set the value of the dead zone for an axis. + + + 0 + + + 32737 + + + 100 + + + 1000 + + + 5000 + + + 5000 + + + true + + + Qt::Horizontal + + + false + + + false + + + QSlider::NoTicks + + + 1000 + + + + + + + true + + + + 0 + 0 + + + + + 100 + 16777215 + + + + false + + + false + + + Set the value of the dead zone for an axis. + + + + + + + + + 5 + + + true + + + false + + + + + + + Set the value to use as the limit for an axis. Useful for a +worn out analog stick. + + + 0 + + + 32737 + + + 100 + + + 1000 + + + 32000 + + + Qt::Horizontal + + + QSlider::NoTicks + + + 1000 + + + + + + + Max Zone: + + + + + + + + + + + [NO KEY] + + + + + + + Throttle setting that determines the behavior of how to +interpret an axis hold or release. + + + 2 + + + 5 + + + 5 + + + + Negative Half Throttle + + + + + Negative Throttle + + + + + Normal + + + + + Positive Throttle + + + + + Positive Half Throttle + + + + + + + + [NO KEY] + + + + + + + + + + 0 + 0 + + + + + 0 + 25 + + + + + 16777215 + 25 + + + + + + + + 10 + + + + + + 0 + 0 + + + + Current Value: + + + 0 + + + 4 + + + + + + + + 0 + 0 + + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + + Name: + + + axisNameLineEdit + + + + + + + Specify the name of an axis. + + + + + + + + + Mouse Settings + + + + + + + + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + false + + + + + buttonBox + line + + axisstatusBox + verticalSpacer + mouseSettingsPushButton + verticalSpacer_2 + + + + AxisValueBox + QWidget +
    axisvaluebox.h
    + 1 +
    +
    + + + + buttonBox + accepted() + AxisEditDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + AxisEditDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +
    diff --git a/src/axisvaluebox.cpp b/src/axisvaluebox.cpp new file mode 100644 index 0000000..dd3561d --- /dev/null +++ b/src/axisvaluebox.cpp @@ -0,0 +1,208 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "axisvaluebox.h" +#include "joyaxis.h" + +AxisValueBox::AxisValueBox(QWidget *parent) : + QWidget(parent) +{ + deadZone = 0; + maxZone = 0; + joyValue = 0; + throttle = 0; + lboxstart = 0; + lboxend = 0; + rboxstart = 0; + rboxend = 0; +} + +void AxisValueBox::setThrottle(int throttle) +{ + if (throttle <= JoyAxis::PositiveHalfThrottle && throttle >= JoyAxis::NegativeHalfThrottle) + { + this->throttle = throttle; + setValue(joyValue); + } + update(); +} + +void AxisValueBox::setValue(int value) +{ + if (value >= JoyAxis::AXISMIN && value <= JoyAxis::AXISMAX) + { + if (throttle == JoyAxis::NormalThrottle) + { + this->joyValue = value; + } + else if (throttle == JoyAxis::NegativeThrottle) + { + this->joyValue = (value + JoyAxis::AXISMIN) / 2; + } + else if (throttle == JoyAxis::PositiveThrottle) + { + this->joyValue = (value + JoyAxis::AXISMAX) / 2; + } + else if (throttle == JoyAxis::NegativeHalfThrottle) + { + this->joyValue = value <= 0 ? value : -value; + } + else if (throttle == JoyAxis::PositiveHalfThrottle) + { + this->joyValue = value >= 0 ? value : -value; + } + } + update(); +} + +void AxisValueBox::setDeadZone(int deadZone) +{ + if (deadZone >= JoyAxis::AXISMIN && deadZone <= JoyAxis::AXISMAX) + { + this->deadZone = deadZone; + } + update(); +} + +int AxisValueBox::getDeadZone() +{ + return deadZone; +} + +void AxisValueBox::setMaxZone(int maxZone) +{ + if (maxZone >= JoyAxis::AXISMIN && maxZone <= JoyAxis::AXISMAX) + { + this->maxZone = maxZone; + } + update(); +} + +int AxisValueBox::getMaxZone() +{ + return maxZone; +} + +int AxisValueBox::getJoyValue() +{ + return joyValue; +} + +int AxisValueBox::getThrottle() +{ + return throttle; +} + +void AxisValueBox::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event); + + boxwidth = (this->width() / 2) - 5; + boxheight = this->height() - 4; + + lboxstart = 0; + lboxend = lboxstart + boxwidth; + + rboxstart = lboxend + 10; + rboxend = rboxstart + boxwidth; + + singlewidth = this->width(); + singleend = lboxstart + singlewidth; +} + +void AxisValueBox::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + + QPainter paint (this); + + paint.setPen(palette().base().color()); + paint.setBrush(palette().base().color()); + QBrush brush(palette().light().color()); + + if (throttle == 0) + { + qDrawShadeRect(&paint, lboxstart, 0, lboxend, height(), palette(), true, 2, 0, &brush); + qDrawShadeRect(&paint, rboxstart, 0, rboxend, height(), palette(), true, 2, 0, &brush); + } + else + { + qDrawShadeRect(&paint, lboxstart, 0, singlewidth, height(), palette(), true, 2, 0, &brush); + } + + QColor innerColor; + if (abs(joyValue) <= deadZone) + { + innerColor = Qt::gray; + } + else if (abs(joyValue) >= maxZone) + { + innerColor = Qt::red; + } + else + { + innerColor = Qt::blue; + } + paint.setPen(innerColor); + paint.setBrush(innerColor); + + int barwidth = (throttle == 0) ? boxwidth : singlewidth; + int barlength = abs((barwidth - 2) * joyValue) / JoyAxis::AXISMAX; + + if (joyValue > 0) + { + paint.drawRect(((throttle == 0) ? rboxstart : lboxstart) + 2, 2, barlength, boxheight); + } + else if (joyValue < 0) + { + paint.drawRect(lboxstart + barwidth - 2 - barlength, 2, barlength, boxheight); + } + + // Draw marker for deadZone + int deadLine = abs((barwidth - 2) * deadZone) / JoyAxis::AXISMAX; + int maxLine = abs((barwidth - 2) * maxZone) / JoyAxis::AXISMAX; + + paint.setPen(Qt::blue); + brush.setColor(Qt::blue); + QBrush maxBrush(Qt::red); + + if (throttle == JoyAxis::NormalThrottle) + { + qDrawPlainRect(&paint, rboxstart + 2 + deadLine, 2, 4, boxheight + 2, Qt::black, 1, &brush); + qDrawPlainRect(&paint, lboxend - deadLine - 2, 2, 4, boxheight + 2, Qt::black, 1, &brush); + + paint.setPen(Qt::red); + qDrawPlainRect(&paint, rboxstart + 2 + maxLine, 2, 4, boxheight + 2, Qt::black, 1, &maxBrush); + qDrawPlainRect(&paint, lboxend - maxLine - 2, 2, 4, boxheight + 2, Qt::black, 1, &maxBrush); + } + else if (throttle == JoyAxis::PositiveThrottle || JoyAxis::PositiveHalfThrottle) + { + qDrawPlainRect(&paint, lboxstart + deadLine - 2, 2, 4, boxheight + 2, Qt::black, 1, &brush); + paint.setPen(Qt::red); + qDrawPlainRect(&paint, lboxstart + maxLine, 2, 4, boxheight + 2, Qt::black, 1, &maxBrush); + } + + else if (throttle == JoyAxis::NegativeThrottle || throttle == JoyAxis::NegativeHalfThrottle) + { + qDrawPlainRect(&paint, singleend - deadLine - 2, 2, 4, boxheight + 2, Qt::black, 1, &brush); + paint.setPen(Qt::red); + qDrawPlainRect(&paint, singleend - maxLine, 2, 4, boxheight + 2, Qt::black, 1, &maxBrush); + } +} diff --git a/src/axisvaluebox.h b/src/axisvaluebox.h new file mode 100644 index 0000000..ab92e27 --- /dev/null +++ b/src/axisvaluebox.h @@ -0,0 +1,61 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef AXISVALUEBOX_H +#define AXISVALUEBOX_H + +#include + +class AxisValueBox : public QWidget +{ + Q_OBJECT +public: + explicit AxisValueBox(QWidget *parent = 0); + + int getDeadZone(); + int getMaxZone(); + int getJoyValue(); + int getThrottle(); + +protected: + virtual void resizeEvent(QResizeEvent *event); + virtual void paintEvent(QPaintEvent *event); + + int deadZone; + int maxZone; + int joyValue; + int throttle; + int boxwidth; + int boxheight; + int lboxstart; + int lboxend; + int rboxstart; + int rboxend; + int singlewidth; + int singleend; + +signals: + +public slots: + void setThrottle(int throttle); + void setValue(int value); + void setDeadZone(int deadZone); + void setMaxZone(int maxZone); + +}; + +#endif // AXISVALUEBOX_H diff --git a/src/buttoneditdialog.cpp b/src/buttoneditdialog.cpp new file mode 100644 index 0000000..6f60b29 --- /dev/null +++ b/src/buttoneditdialog.cpp @@ -0,0 +1,450 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +//#include +#include + +#ifdef Q_OS_WIN +#include +#include "winextras.h" + +#else + + #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) +#include + #endif +#endif + +#include "buttoneditdialog.h" +#include "ui_buttoneditdialog.h" + +#include "event.h" +#include "antkeymapper.h" +#include "eventhandlerfactory.h" +#include "setjoystick.h" +#include "inputdevice.h" +#include "common.h" + +ButtonEditDialog::ButtonEditDialog(JoyButton *button, QWidget *parent) : + QDialog(parent, Qt::Window), + ui(new Ui::ButtonEditDialog), + helper(button) +{ + ui->setupUi(this); + +#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + setMinimumHeight(460); +#endif + + setAttribute(Qt::WA_DeleteOnClose); + setWindowModality(Qt::WindowModal); + + ignoreRelease = false; + + helper.moveToThread(button->thread()); + + PadderCommon::inputDaemonMutex.lock(); + + this->button = button; + ui->virtualKeyMouseTabWidget->hide(); + ui->virtualKeyMouseTabWidget->deleteLater(); + ui->virtualKeyMouseTabWidget = new VirtualKeyboardMouseWidget(button, this); + + ui->verticalLayout->insertWidget(1, ui->virtualKeyMouseTabWidget); + //ui->virtualKeyMouseTabWidget->setFocus(); + + ui->slotSummaryLabel->setText(button->getSlotsString()); + updateWindowTitleButtonName(); + + ui->toggleCheckBox->setChecked(button->getToggleState()); + ui->turboCheckBox->setChecked(button->isUsingTurbo()); + + if (!button->getActionName().isEmpty()) + { + ui->actionNameLineEdit->setText(button->getActionName()); + } + + if (!button->getButtonName().isEmpty()) + { + ui->buttonNameLineEdit->setText(button->getButtonName()); + } + + PadderCommon::inputDaemonMutex.unlock(); + + connect(qApp, SIGNAL(focusChanged(QWidget*,QWidget*)), this, SLOT(checkForKeyboardWidgetFocus(QWidget*,QWidget*))); + + connect(ui->virtualKeyMouseTabWidget, SIGNAL(selectionCleared()), this, SLOT(refreshSlotSummaryLabel())); + connect(ui->virtualKeyMouseTabWidget, SIGNAL(selectionFinished()), this, SLOT(close())); + + connect(this, SIGNAL(keyGrabbed(JoyButtonSlot*)), this, SLOT(processSlotAssignment(JoyButtonSlot*))); + connect(this, SIGNAL(selectionCleared()), this, SLOT(clearButtonSlots())); + connect(this, SIGNAL(selectionCleared()), this, SLOT(sendSelectionFinished())); + connect(this, SIGNAL(selectionFinished()), this, SLOT(close())); + + connect(ui->toggleCheckBox, SIGNAL(clicked()), this, SLOT(changeToggleSetting())); + connect(ui->turboCheckBox, SIGNAL(clicked()), this, SLOT(changeTurboSetting())); + connect(ui->advancedPushButton, SIGNAL(clicked()), this, SLOT(openAdvancedDialog())); + connect(this, SIGNAL(advancedDialogOpened()), ui->virtualKeyMouseTabWidget, SLOT(establishVirtualKeyboardAdvancedSignalConnections())); + connect(this, SIGNAL(advancedDialogOpened()), ui->virtualKeyMouseTabWidget, SLOT(establishVirtualMouseAdvancedSignalConnections())); + //connect(ui->virtualKeyMouseTabWidget, SIGNAL(selectionMade(int)), this, SLOT(createTempSlot(int))); + + connect(ui->actionNameLineEdit, SIGNAL(textEdited(QString)), button, SLOT(setActionName(QString))); + connect(ui->buttonNameLineEdit, SIGNAL(textEdited(QString)), button, SLOT(setButtonName(QString))); + + connect(button, SIGNAL(toggleChanged(bool)), ui->toggleCheckBox, SLOT(setChecked(bool))); + connect(button, SIGNAL(turboChanged(bool)), this, SLOT(checkTurboSetting(bool))); + connect(button, SIGNAL(slotsChanged()), this, SLOT(refreshSlotSummaryLabel())); + connect(button, SIGNAL(buttonNameChanged()), this, SLOT(updateWindowTitleButtonName())); +} + +void ButtonEditDialog::checkForKeyboardWidgetFocus(QWidget *old, QWidget *now) +{ + Q_UNUSED(old); + Q_UNUSED(now); + + if (ui->virtualKeyMouseTabWidget->hasFocus() && + ui->virtualKeyMouseTabWidget->isKeyboardTabVisible()) + { + grabKeyboard(); + } + else + { + releaseKeyboard(); + } +} + +ButtonEditDialog::~ButtonEditDialog() +{ + delete ui; +} + +void ButtonEditDialog::keyPressEvent(QKeyEvent *event) +{ + bool ignore = false; + // Ignore the following keys that might + // trigger an event in QDialog::keyPressEvent + switch(event->key()) + { + case Qt::Key_Escape: + case Qt::Key_Right: + case Qt::Key_Enter: + case Qt::Key_Return: + { + ignore = true; + break; + } + } + + if (!ignore) + { + QDialog::keyPressEvent(event); + } +} + +void ButtonEditDialog::keyReleaseEvent(QKeyEvent *event) +{ + if (ui->actionNameLineEdit->hasFocus() || ui->buttonNameLineEdit->hasFocus()) + { + QDialog::keyReleaseEvent(event); + } + else if (ui->virtualKeyMouseTabWidget->isKeyboardTabVisible()) + { + int controlcode = event->nativeScanCode(); + int virtualactual = event->nativeVirtualKey(); + + BaseEventHandler *handler = EventHandlerFactory::getInstance()->handler(); + +#ifdef Q_OS_WIN + int finalvirtual = 0; + int checkalias = 0; + + #ifdef WITH_VMULTI + if (handler->getIdentifier() == "vmulti") + { + finalvirtual = WinExtras::correctVirtualKey(controlcode, virtualactual); + checkalias = AntKeyMapper::getInstance()->returnQtKey(finalvirtual); + + //unsigned int tempQtKey = nativeWinKeyMapper.returnQtKey(finalvirtual); + QtKeyMapperBase *nativeWinKeyMapper = AntKeyMapper::getInstance()->getNativeKeyMapper(); + unsigned int tempQtKey = 0; + if (nativeWinKeyMapper) + { + tempQtKey = nativeWinKeyMapper->returnQtKey(finalvirtual); + } + + if (tempQtKey > 0) + { + finalvirtual = AntKeyMapper::getInstance()->returnVirtualKey(tempQtKey); + checkalias = AntKeyMapper::getInstance()->returnQtKey(finalvirtual); + } + else + { + finalvirtual = AntKeyMapper::getInstance()->returnVirtualKey(event->key()); + } + } + + #endif + + BACKEND_ELSE_IF (handler->getIdentifier() == "sendinput") + { + // Find more specific virtual key (VK_SHIFT -> VK_LSHIFT) + // by checking for extended bit in scan code. + finalvirtual = WinExtras::correctVirtualKey(controlcode, virtualactual); + checkalias = AntKeyMapper::getInstance()->returnQtKey(finalvirtual, controlcode); + } + +#else + + #if defined(WITH_X11) + int finalvirtual = 0; + int checkalias = 0; + + #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + if (QApplication::platformName() == QStringLiteral("xcb")) + { + #endif + // Obtain group 1 X11 keysym. Removes effects from modifiers. + finalvirtual = X11KeyCodeToX11KeySym(controlcode); + + #ifdef WITH_UINPUT + if (handler->getIdentifier() == "uinput") + { + // Find Qt Key corresponding to X11 KeySym. + //checkalias = x11KeyMapper.returnQtKey(finalvirtual); + Q_ASSERT(AntKeyMapper::getInstance()->hasNativeKeyMapper()); + QtKeyMapperBase *x11KeyMapper = AntKeyMapper::getInstance()->getNativeKeyMapper(); + Q_ASSERT(x11KeyMapper != NULL); + checkalias = x11KeyMapper->returnQtKey(finalvirtual); + // Find corresponding Linux input key for the Qt key. + finalvirtual = AntKeyMapper::getInstance()->returnVirtualKey(checkalias); + } + #endif + + #ifdef WITH_XTEST + BACKEND_ELSE_IF (handler->getIdentifier() == "xtest") + { + // Check for alias against group 1 keysym. + checkalias = AntKeyMapper::getInstance()->returnQtKey(finalvirtual); + } + + #endif + + #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + } + else + { + // Not running on xcb platform. + finalvirtual = controlcode; + checkalias = AntKeyMapper::getInstance()->returnQtKey(finalvirtual); + } + #endif + + #else + int finalvirtual = 0; + int checkalias = 0; + #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + if (QApplication::platformName() == QStringLiteral("xcb")) + { + #endif + finalvirtual = AntKeyMapper::getInstance()->returnVirtualKey(event->key()); + checkalias = AntKeyMapper::getInstance()->returnQtKey(finalvirtual); + #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + } + else + { + // Not running on xcb platform. + finalvirtual = controlcode; + checkalias = AntKeyMapper::getInstance()->returnQtKey(finalvirtual); + } + #endif + + #endif + +#endif + + if (!ignoreRelease) + { + if ((event->modifiers() & Qt::ControlModifier) && event->key() == Qt::Key_X) + { + controlcode = 0; + ignoreRelease = true; + emit selectionCleared(); + } + else if (controlcode <= 0) + { + controlcode = 0; + } + } + else + { + controlcode = 0; + ignoreRelease = false; + } + + + if (controlcode > 0) + { + if (checkalias > 0 && finalvirtual > 0) + { + JoyButtonSlot *tempslot = new JoyButtonSlot(finalvirtual, checkalias, JoyButtonSlot::JoyKeyboard, this); + emit keyGrabbed(tempslot); + } + else if (virtualactual > 0) + { + JoyButtonSlot *tempslot = new JoyButtonSlot(virtualactual, JoyButtonSlot::JoyKeyboard, this); + emit keyGrabbed(tempslot); + } + else + { + QDialog::keyReleaseEvent(event); + } + } + else + { + QDialog::keyReleaseEvent(event); + } + } + else + { + QDialog::keyReleaseEvent(event); + } +} + +void ButtonEditDialog::refreshSlotSummaryLabel() +{ + ui->slotSummaryLabel->setText(button->getSlotsString().replace("&", "&&")); +} + +void ButtonEditDialog::changeToggleSetting() +{ + button->setToggle(ui->toggleCheckBox->isChecked()); +} + +void ButtonEditDialog::changeTurboSetting() +{ + button->setUseTurbo(ui->turboCheckBox->isChecked()); +} + +void ButtonEditDialog::openAdvancedDialog() +{ + ui->advancedPushButton->setEnabled(false); + + AdvanceButtonDialog *dialog = new AdvanceButtonDialog(button, this); + dialog->show(); + + // Disconnect event to allow for placing slot to AdvanceButtonDialog + disconnect(this, SIGNAL(keyGrabbed(JoyButtonSlot*)), 0, 0); + disconnect(this, SIGNAL(selectionCleared()), 0, 0); + disconnect(this, SIGNAL(selectionFinished()), 0, 0); + + connect(dialog, SIGNAL(finished(int)), ui->virtualKeyMouseTabWidget, SLOT(establishVirtualKeyboardSingleSignalConnections())); + connect(dialog, SIGNAL(finished(int)), ui->virtualKeyMouseTabWidget, SLOT(establishVirtualMouseSignalConnections())); + connect(dialog, SIGNAL(finished(int)), this, SLOT(closedAdvancedDialog())); + connect(dialog, SIGNAL(turboButtonEnabledChange(bool)), this, SLOT(setTurboButtonEnabled(bool))); + + connect(this, SIGNAL(sendTempSlotToAdvanced(JoyButtonSlot*)), dialog, SLOT(placeNewSlot(JoyButtonSlot*))); + connect(this, SIGNAL(keyGrabbed(JoyButtonSlot*)), dialog, SLOT(placeNewSlot(JoyButtonSlot*))); + connect(this, SIGNAL(selectionCleared()), dialog, SLOT(clearAllSlots())); + connect(ui->virtualKeyMouseTabWidget, SIGNAL(selectionMade(JoyButtonSlot*)), dialog, SLOT(placeNewSlot(JoyButtonSlot*))); + connect(ui->virtualKeyMouseTabWidget, SIGNAL(selectionMade(int, unsigned int)), this, SLOT(createTempSlot(int, unsigned int))); + connect(ui->virtualKeyMouseTabWidget, SIGNAL(selectionCleared()), dialog, SLOT(clearAllSlots())); + + connect(this, SIGNAL(finished(int)), dialog, SLOT(close())); + emit advancedDialogOpened(); +} + +void ButtonEditDialog::createTempSlot(int keycode, unsigned int alias) +{ + JoyButtonSlot *slot = new JoyButtonSlot(keycode, alias, + JoyButtonSlot::JoyKeyboard, this); + emit sendTempSlotToAdvanced(slot); +} + +void ButtonEditDialog::checkTurboSetting(bool state) +{ + if (button->containsSequence()) + { + ui->turboCheckBox->setChecked(false); + ui->turboCheckBox->setEnabled(false); + } + else + { + ui->turboCheckBox->setChecked(state); + ui->turboCheckBox->setEnabled(true); + } + + helper.setUseTurbo(state); +} + +void ButtonEditDialog::setTurboButtonEnabled(bool state) +{ + ui->turboCheckBox->setEnabled(state); +} + +void ButtonEditDialog::closedAdvancedDialog() +{ + ui->advancedPushButton->setEnabled(true); + + disconnect(ui->virtualKeyMouseTabWidget, SIGNAL(selectionMade(int, unsigned int)), this, 0); + + // Re-connect previously disconnected event + connect(this, SIGNAL(keyGrabbed(JoyButtonSlot*)), this, SLOT(processSlotAssignment(JoyButtonSlot*))); + connect(this, SIGNAL(selectionCleared()), this, SLOT(clearButtonSlots())); + connect(this, SIGNAL(selectionCleared()), this, SLOT(sendSelectionFinished())); + connect(this, SIGNAL(selectionFinished()), this, SLOT(close())); +} + +void ButtonEditDialog::processSlotAssignment(JoyButtonSlot *tempslot) +{ + QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, + Q_ARG(int, tempslot->getSlotCode()), + Q_ARG(unsigned int, tempslot->getSlotCodeAlias()), + Q_ARG(JoyButtonSlot::JoySlotInputAction, tempslot->getSlotMode())); + + this->close(); + tempslot->deleteLater(); +} + +void ButtonEditDialog::clearButtonSlots() +{ + QMetaObject::invokeMethod(button, "clearSlotsEventReset", Q_ARG(bool, false)); +} + +void ButtonEditDialog::sendSelectionFinished() +{ + emit selectionFinished(); +} + +void ButtonEditDialog::updateWindowTitleButtonName() +{ + QString temp = QString(tr("Set")).append(" ").append(button->getPartialName(false, true)); + + if (button->getParentSet()->getIndex() != 0) + { + unsigned int setIndex = button->getParentSet()->getRealIndex(); + temp.append(" [").append(tr("Set %1").arg(setIndex)); + QString setName = button->getParentSet()->getName(); + if (!setName.isEmpty()) + { + temp.append(": ").append(setName); + } + + temp.append("]"); + } + + setWindowTitle(temp); +} diff --git a/src/buttoneditdialog.h b/src/buttoneditdialog.h new file mode 100644 index 0000000..b87495e --- /dev/null +++ b/src/buttoneditdialog.h @@ -0,0 +1,76 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef BUTTONEDITDIALOGTWO_H +#define BUTTONEDITDIALOGTWO_H + +#include + +#include "joybutton.h" +#include "keyboard/virtualkeyboardmousewidget.h" +#include "advancebuttondialog.h" +#include "uihelpers/buttoneditdialoghelper.h" + + +namespace Ui { +class ButtonEditDialog; +} + +class ButtonEditDialog : public QDialog +{ + Q_OBJECT + +public: + explicit ButtonEditDialog(JoyButton *button, QWidget *parent = 0); + ~ButtonEditDialog(); + +protected: + JoyButton *button; + bool ignoreRelease; + ButtonEditDialogHelper helper; + + virtual void keyReleaseEvent(QKeyEvent *event); + virtual void keyPressEvent(QKeyEvent *event); + +private: + Ui::ButtonEditDialog *ui; + +signals: + void advancedDialogOpened(); + void sendTempSlotToAdvanced(JoyButtonSlot *tempslot); + void keyGrabbed(JoyButtonSlot *tempslot); + void selectionCleared(); + void selectionFinished(); + +private slots: + void refreshSlotSummaryLabel(); + void changeToggleSetting(); + void changeTurboSetting(); + void openAdvancedDialog(); + void closedAdvancedDialog(); + void createTempSlot(int keycode, unsigned int alias); + + void checkTurboSetting(bool state); + void setTurboButtonEnabled(bool state); + void processSlotAssignment(JoyButtonSlot *tempslot); + void clearButtonSlots(); + void sendSelectionFinished(); + void updateWindowTitleButtonName(); + void checkForKeyboardWidgetFocus(QWidget *old, QWidget *now); +}; + +#endif // BUTTONEDITDIALOGTWO_H diff --git a/src/buttoneditdialog.ui b/src/buttoneditdialog.ui new file mode 100644 index 0000000..08642d9 --- /dev/null +++ b/src/buttoneditdialog.ui @@ -0,0 +1,327 @@ + + + ButtonEditDialog + + + Qt::WindowModal + + + + 0 + 0 + 800 + 430 + + + + + 800 + 430 + + + + Dialog + + + false + + + false + + + + + + + 0 + 0 + + + + 1 + + + To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab + + + false + + + Qt::AlignCenter + + + true + + + + + + + QTabWidget::South + + + 0 + + + false + + + + Placeholder + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 4 + + + + + + + + + + Enables a key press or release to only occur when a controller button is pressed. + + + Toggle + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + + Enables rapid key presses and releases. Turbo controller. + + + Turbo + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 20 + 20 + + + + + + + + + + + + + 75 + true + + + + Current: + + + + + + + Slots + + + false + + + + + + + + + + + 30 + + + 6 + + + 6 + + + + + 4 + + + + + Na&me: + + + buttonNameLineEdit + + + + + + + Specify the name of a button. + + + 20 + + + + + + + + + 4 + + + + + Action: + + + actionNameLineEdit + + + + + + + Specify the action that will be performed in game while +this button is being used. + + + 50 + + + + + + + + + + + Qt::Horizontal + + + + + + + 4 + + + + + Advanced + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + + + + + VirtualKeyboardMouseWidget + QTabWidget +
    keyboard/virtualkeyboardmousewidget.h
    + 1 +
    +
    + + + + buttonBox + accepted() + ButtonEditDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + ButtonEditDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +
    diff --git a/src/capturedwindowinfodialog.cpp b/src/capturedwindowinfodialog.cpp new file mode 100644 index 0000000..f2ca3a7 --- /dev/null +++ b/src/capturedwindowinfodialog.cpp @@ -0,0 +1,200 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "capturedwindowinfodialog.h" +#include "ui_capturedwindowinfodialog.h" + +#ifdef Q_OS_WIN +#include "winextras.h" +#else +#include "x11extras.h" +#endif + +#ifdef Q_OS_WIN +CapturedWindowInfoDialog::CapturedWindowInfoDialog(QWidget *parent) : +#else +CapturedWindowInfoDialog::CapturedWindowInfoDialog(unsigned long window, QWidget *parent) : +#endif + QDialog(parent), + ui(new Ui::CapturedWindowInfoDialog) +{ + ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + + selectedMatch = WindowNone; + +#ifdef Q_OS_UNIX + X11Extras *info = X11Extras::getInstance(); + ui->winPathChoiceComboBox->setVisible(false); +#endif + + bool setRadioDefault = false; + fullWinPath = false; + +#ifdef Q_OS_WIN + ui->winClassCheckBox->setVisible(false); + ui->winClassLabel->setVisible(false); + ui->winClassHeadLabel->setVisible(false); +#else + winClass = info->getWindowClass(window); + ui->winClassLabel->setText(winClass); + if (winClass.isEmpty()) + { + ui->winClassCheckBox->setEnabled(false); + ui->winClassCheckBox->setChecked(false); + } + else + { + ui->winClassCheckBox->setChecked(true); + setRadioDefault = true; + } + + ui->winPathChoiceComboBox->setVisible(false); + +#endif + +#ifdef Q_OS_WIN + winName = WinExtras::getCurrentWindowText(); +#else + winName = info->getWindowTitle(window); +#endif + + ui->winTitleLabel->setText(winName); + if (winName.isEmpty()) + { + ui->winTitleCheckBox->setEnabled(false); + ui->winTitleCheckBox->setChecked(false); + } + else if (!setRadioDefault) + { + ui->winTitleCheckBox->setChecked(true); + setRadioDefault = true; + } + + ui->winPathLabel->clear(); +#ifdef Q_OS_WIN + winPath = WinExtras::getForegroundWindowExePath(); + ui->winPathLabel->setText(winPath); + + if (winPath.isEmpty()) + { + ui->winPathCheckBox->setEnabled(false); + ui->winPathCheckBox->setChecked(false); + } + else + { + ui->winPathCheckBox->setChecked(true); + ui->winTitleCheckBox->setChecked(false); + setRadioDefault = true; + } + +#elif defined(Q_OS_LINUX) + int pid = info->getApplicationPid(window); + if (pid > 0) + { + QString exepath = X11Extras::getInstance()->getApplicationLocation(pid); + if (!exepath.isEmpty()) + { + ui->winPathLabel->setText(exepath); + winPath = exepath; + if (!setRadioDefault) + { + ui->winTitleCheckBox->setChecked(true); + setRadioDefault = true; + } + } + else + { + ui->winPathCheckBox->setEnabled(false); + ui->winPathCheckBox->setChecked(false); + } + } + else + { + ui->winPathCheckBox->setEnabled(false); + ui->winPathCheckBox->setChecked(false); + } +#endif + + if (winClass.isEmpty() && winName.isEmpty() && + winPath.isEmpty()) + { + QPushButton *button = ui->buttonBox->button(QDialogButtonBox::Ok); + button->setEnabled(false); + } + + connect(this, SIGNAL(accepted()), this, SLOT(populateOption())); +} + +CapturedWindowInfoDialog::~CapturedWindowInfoDialog() +{ + delete ui; +} + +void CapturedWindowInfoDialog::populateOption() +{ + if (ui->winClassCheckBox->isChecked()) + { + selectedMatch = selectedMatch | WindowClass; + } + + if (ui->winTitleCheckBox->isChecked()) + { + selectedMatch = selectedMatch | WindowName; + } + + if (ui->winPathCheckBox->isChecked()) + { + selectedMatch = selectedMatch | WindowPath; + + if (ui->winPathChoiceComboBox->currentIndex() == 0) + { + fullWinPath = true; + } + else + { + fullWinPath = false; + } + } +} + +CapturedWindowInfoDialog::CapturedWindowOption CapturedWindowInfoDialog::getSelectedOptions() +{ + return selectedMatch; +} + +QString CapturedWindowInfoDialog::getWindowClass() +{ + return winClass; +} + +QString CapturedWindowInfoDialog::getWindowName() +{ + return winName; +} + +QString CapturedWindowInfoDialog::getWindowPath() +{ + return winPath; +} + +bool CapturedWindowInfoDialog::useFullWindowPath() +{ + return fullWinPath; +} diff --git a/src/capturedwindowinfodialog.h b/src/capturedwindowinfodialog.h new file mode 100644 index 0000000..b15eb70 --- /dev/null +++ b/src/capturedwindowinfodialog.h @@ -0,0 +1,71 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef UNIXWINDOWINFODIALOG_H +#define UNIXWINDOWINFODIALOG_H + +#include +#include + +namespace Ui { +class CapturedWindowInfoDialog; +} + +class CapturedWindowInfoDialog : public QDialog +{ + Q_OBJECT + +public: + +#ifdef Q_OS_WIN + explicit CapturedWindowInfoDialog(QWidget *parent = 0); +#else + explicit CapturedWindowInfoDialog(unsigned long window, QWidget *parent = 0); +#endif + + ~CapturedWindowInfoDialog(); + + enum { + WindowNone = 0, + WindowClass = (1 << 0), + WindowName = (1 << 1), + WindowPath = (1 << 2), + }; + typedef unsigned int CapturedWindowOption; + + QString getWindowClass(); + QString getWindowName(); + QString getWindowPath(); + bool useFullWindowPath(); + CapturedWindowOption getSelectedOptions(); + +private: + Ui::CapturedWindowInfoDialog *ui; + +protected: + CapturedWindowOption selectedMatch; + + QString winClass; + QString winName; + QString winPath; + bool fullWinPath; + +private slots: + void populateOption(); +}; + +#endif // UNIXWINDOWINFODIALOG_H diff --git a/src/capturedwindowinfodialog.ui b/src/capturedwindowinfodialog.ui new file mode 100644 index 0000000..cbbe982 --- /dev/null +++ b/src/capturedwindowinfodialog.ui @@ -0,0 +1,230 @@ + + + CapturedWindowInfoDialog + + + + 0 + 0 + 533 + 363 + + + + Captured Window Properties + + + + 20 + + + + + + 50 + false + + + + Information About Window + + + true + + + + + + 20 + + + + + Class: + + + + + + + + true + + + + TextLabel + + + + + + + Title: + + + + + + + + true + + + + TextLabel + + + + + + + Path: + + + + + + + + true + + + + TextLabel + + + + + + + + + + + + + Match By Properties + + + true + + + false + + + false + + + + + + Class + + + + + + + Title + + + + + + + + + Path + + + + + + + true + + + + Full Path + + + + + File Name + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + CapturedWindowInfoDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + CapturedWindowInfoDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/commandlineutility.cpp b/src/commandlineutility.cpp new file mode 100644 index 0000000..2bee108 --- /dev/null +++ b/src/commandlineutility.cpp @@ -0,0 +1,779 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +//#include +#include +#include +#include + +#ifdef Q_OS_UNIX + #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) +#include + #endif +#endif + +#include "commandlineutility.h" +#include "common.h" + +#include "eventhandlerfactory.h" + +QRegExp CommandLineUtility::trayRegexp = QRegExp("--tray"); +QRegExp CommandLineUtility::helpRegexp = QRegExp("(-h|--help)"); +QRegExp CommandLineUtility::versionRegexp = QRegExp("(-v|--version)"); +QRegExp CommandLineUtility::noTrayRegexp = QRegExp("--no-tray"); +QRegExp CommandLineUtility::loadProfileRegexp = QRegExp("--profile"); +QRegExp CommandLineUtility::loadProfileForControllerRegexp = QRegExp("--profile-controller"); +QRegExp CommandLineUtility::hiddenRegexp = QRegExp("--hidden"); +QRegExp CommandLineUtility::unloadRegexp = QRegExp("--unload"); +QRegExp CommandLineUtility::startSetRegexp = QRegExp("--startSet"); +QRegExp CommandLineUtility::gamepadListRegexp = QRegExp("(-l|--list)"); +QRegExp CommandLineUtility::mappingRegexp = QRegExp("--map"); +QRegExp CommandLineUtility::qtStyleRegexp = QRegExp("-style"); +QRegExp CommandLineUtility::logLevelRegexp = QRegExp("--log-level"); +QRegExp CommandLineUtility::eventgenRegexp = QRegExp("--eventgen"); +QRegExp CommandLineUtility::nextRegexp = QRegExp("--next"); + +#ifdef Q_OS_UNIX +QRegExp CommandLineUtility::daemonRegexp = QRegExp("--daemon|-d"); + + #ifdef WITH_X11 + QRegExp CommandLineUtility::displayRegexp = QRegExp("--display"); + #endif +#endif + +QStringList CommandLineUtility::eventGeneratorsList = EventHandlerFactory::buildEventGeneratorList(); + +CommandLineUtility::CommandLineUtility(QObject *parent) : + QObject(parent) +{ + launchInTray = false; + helpRequest = false; + versionRequest = false; + hideTrayIcon = false; + profileLocation = ""; + controllerNumber = 0; + encounteredError = false; + hiddenRequest = false; + unloadProfile = false; + startSetNumber = 0; + daemonMode = false; + displayString = ""; + listControllers = false; + mappingController = false; + currentLogLevel = Logger::LOG_INFO; + + currentListsIndex = 0; + ControllerOptionsInfo tempInfo; + controllerOptionsList.append(tempInfo); + + eventGenerator = EventHandlerFactory::fallBackIdentifier(); +} + +void CommandLineUtility::parseArguments(QStringList &arguments) +{ + QStringListIterator iter(arguments); + while (iter.hasNext() && !encounteredError) + { + QString temp = iter.next(); + if (helpRegexp.exactMatch(temp)) + { + helpRequest = true; + } + else if (versionRegexp.exactMatch(temp)) + { + versionRequest = true; + } + else if (trayRegexp.exactMatch(temp)) + { + launchInTray = true; + hideTrayIcon = false; + } + else if (noTrayRegexp.exactMatch(temp)) + { + hideTrayIcon = true; + launchInTray = false; + } + else if (loadProfileRegexp.exactMatch(temp)) + { + if (iter.hasNext()) + { + temp = iter.next(); + QFileInfo fileInfo(temp); + if (fileInfo.exists()) + { + if (fileInfo.suffix() != "amgp" && fileInfo.suffix() != "xml") + { + setErrorMessage(tr("Profile location %1 is not an XML file.").arg(temp)); + } + else + { + QString tempProfileLocation = fileInfo.absoluteFilePath(); + ControllerOptionsInfo tempInfo = controllerOptionsList.at(currentListsIndex); + tempInfo.setProfileLocation(tempProfileLocation); + controllerOptionsList.replace(currentListsIndex, tempInfo); + } + } + else + { + setErrorMessage(tr("Profile location %1 does not exist.").arg(temp)); + } + } + } + else if (loadProfileForControllerRegexp.exactMatch(temp)) + { + if (iter.hasNext()) + { + temp = iter.next(); + + bool validNumber = false; + int tempNumber = temp.toInt(&validNumber); + if (validNumber) + { + if (controllerNumber == 0) + { + controllerNumber = tempNumber; + } + + ControllerOptionsInfo tempInfo = controllerOptionsList.at(currentListsIndex); + tempInfo.setControllerNumber(tempNumber); + controllerOptionsList.replace(currentListsIndex, tempInfo); + } + else if (!temp.isEmpty()) + { + if (controllerIDString.isEmpty()) + { + controllerIDString = temp; + } + + ControllerOptionsInfo tempInfo = controllerOptionsList.at(currentListsIndex); + tempInfo.setControllerID(temp); + controllerOptionsList.replace(currentListsIndex, tempInfo); + } + else + { + setErrorMessage(tr("Controller identifier is not a valid value.")); + } + } + } + else if (hiddenRegexp.exactMatch(temp)) + { + hiddenRequest = true; + } + else if (unloadRegexp.exactMatch(temp)) + { + ControllerOptionsInfo tempInfo = controllerOptionsList.at(currentListsIndex); + tempInfo.setProfileLocation(""); + tempInfo.setUnloadRequest(true); + controllerOptionsList.replace(currentListsIndex, tempInfo); + + if (iter.hasNext()) + { + temp = iter.next(); + + if (!isPossibleCommand(temp)) + { + // A value has been passed. Attempt + // to validate the value. + bool validNumber = false; + int tempNumber = temp.toInt(&validNumber); + if (validNumber) + { + controllerNumber = tempNumber; + tempInfo = controllerOptionsList.at(currentListsIndex); + tempInfo.setControllerNumber(controllerNumber); + controllerOptionsList.replace(currentListsIndex, tempInfo); + } + else if (!temp.isEmpty()) + { + controllerIDString = temp; + tempInfo = controllerOptionsList.at(currentListsIndex); + tempInfo.setControllerID(controllerIDString); + controllerOptionsList.replace(currentListsIndex, tempInfo); + } + else + { + setErrorMessage(tr("Controller identifier is not a valid value.")); + } + } + else + { + // Grabbed a possible command-line option. + // Move iterator back to previous item. + iter.previous(); + } + } + else + { + unloadProfile = true; + profileLocation = ""; + } + } + else if (startSetRegexp.exactMatch(temp)) + { + if (iter.hasNext()) + { + temp = iter.next(); + + bool validNumber = false; + int tempNumber = temp.toInt(&validNumber); + if (validNumber && tempNumber >= 1 && tempNumber <= 8) + { + startSetNumber = tempNumber; + ControllerOptionsInfo tempInfo = controllerOptionsList.at(currentListsIndex); + tempInfo.setStartSetNumber(startSetNumber); + controllerOptionsList.replace(currentListsIndex, tempInfo); + } + else if (validNumber) + { + setErrorMessage(tr("An invalid set number '%1' was specified.").arg(tempNumber)); + } + + if (iter.hasNext()) + { + temp = iter.next(); + + if (!isPossibleCommand(temp)) + { + if (validNumber) + { + controllerNumber = tempNumber; + ControllerOptionsInfo tempInfo = controllerOptionsList.at(currentListsIndex); + tempInfo.setControllerNumber(controllerNumber); + controllerOptionsList.replace(currentListsIndex, tempInfo); + } + else if (!temp.isEmpty()) + { + controllerIDString = temp; + ControllerOptionsInfo tempInfo = controllerOptionsList.at(currentListsIndex); + tempInfo.setControllerID(controllerIDString); + controllerOptionsList.replace(currentListsIndex, tempInfo); + } + else + { + setErrorMessage(tr("Controller identifier '%s'' is not a valid value.").arg(temp)); + } + } + else + { + // Grabbed a possible command-line option. + // Move iterator back to previous item. + iter.previous(); + } + } + } + else + { + setErrorMessage(tr("No set number was specified.")); + } + } + else if (nextRegexp.exactMatch(temp)) + { + currentListsIndex++; + + ControllerOptionsInfo tempInfo; + controllerOptionsList.append(tempInfo); + } + +#ifdef USE_SDL_2 + else if (gamepadListRegexp.exactMatch(temp)) + { + listControllers = true; + } + else if (mappingRegexp.exactMatch(temp)) + { + if (iter.hasNext()) + { + temp = iter.next(); + + bool validNumber = false; + int tempNumber = temp.toInt(&validNumber); + if (validNumber) + { + controllerNumber = tempNumber; + mappingController = true; + } + else if (!temp.isEmpty()) + { + controllerIDString = temp; + mappingController = true; + } + else + { + setErrorMessage(tr("Controller identifier is not a valid value.")); + } + } + else + { + setErrorMessage(tr("No controller was specified.")); + } + } +#endif + +#ifdef Q_OS_UNIX + else if (daemonRegexp.exactMatch(temp)) + { + daemonMode = true; + } + #ifdef WITH_X11 + else if (displayRegexp.exactMatch(temp)) + { + if (iter.hasNext()) + { + displayString = iter.next(); + } + else + { + setErrorMessage(tr("No display string was specified.")); + //errorsteam << tr("No display string was specified.") << endl; + //encounteredError = true; + } + } + #endif +#endif + +#if (defined (Q_OS_UNIX) && defined(WITH_UINPUT) && defined(WITH_XTEST)) \ + || (defined(Q_OS_WIN) && defined(WITH_VMULTI)) + else if (eventgenRegexp.exactMatch(temp)) + { + if (iter.hasNext()) + { + QString temp = iter.next(); + + if (!eventGeneratorsList.contains(temp)) + { + eventGenerator = ""; + setErrorMessage(tr("An invalid event generator was specified.")); + //errorsteam << tr("An invalid event generator was specified.") << endl; + //encounteredError = true; + } + else + { + eventGenerator = temp; + } + } + else + { + setErrorMessage(tr("No event generator string was specified.")); + //errorsteam << tr("No event generator string was specified.") << endl; + //encounteredError = true; + } + } +#endif + + else if (qtStyleRegexp.exactMatch(temp)) + { + if (iter.hasNext()) + { + // Skip over argument + iter.next(); + } + else + { + setErrorMessage(tr("Qt style flag was detected but no style was specified.")); + //errorsteam << tr("Qt style flag was detected but no style was specified.") << endl; + //encounteredError = true; + } + } + else if (logLevelRegexp.exactMatch(temp)) + { + if (iter.hasNext()) + { + QString temp = iter.next(); + if (temp == "debug") + { + currentLogLevel = Logger::LOG_DEBUG; + } + else if (temp == "info") + { + currentLogLevel = Logger::LOG_INFO; + } + /*else if (temp == "warn") + { + currentLogLevel = Logger::LOG_WARNING; + } + else if (temp == "error") + { + currentLogLevel = Logger::LOG_ERROR; + } + */ + } + else + { + setErrorMessage(tr("No log level specified.")); + //errorsteam << tr("No log level specified.") << endl; + //encounteredError = true; + } + + } + else if (isPossibleCommand(temp)) + { + // Flag is unrecognized. Assume that it is a Qt option. + if (iter.hasNext()) + { + // Check next argument + QString nextarg = iter.next(); + if (isPossibleCommand(nextarg)) + { + // Flag likely didn't take an argument. Move iterator + // back. + iter.previous(); + } + } + } + // Check if this is the last argument. If it is and no command line flag + // is active, the final argument is likely a profile that has + // been specified. + else if (!temp.isEmpty() && !iter.hasNext()) + { + // If the file exists and it is an xml file, assume that it is a + // profile. + QFileInfo fileInfo(temp); + if (fileInfo.exists()) + { + if (fileInfo.suffix() != "amgp" && fileInfo.suffix() != "xml") + { + setErrorMessage(tr("Profile location %1 is not an XML file.").arg(temp)); + } + else + { + profileLocation = fileInfo.absoluteFilePath(); + // Only use properties if no other OptionsInfo lines have + // been defined. + if (currentListsIndex > 0) + { + controllerNumber = 0; + controllerIDString.clear(); + } + } + } + else + { + setErrorMessage(tr("Profile location %1 does not exist.").arg(temp)); + } + } + } +} + +bool CommandLineUtility::isLaunchInTrayEnabled() +{ + return launchInTray; +} + +void CommandLineUtility::printHelp() +{ + QTextStream out(stdout); + out << tr("antimicro version") << " " << PadderCommon::programVersion << endl; + out << tr("Usage: antimicro [options...] [profile]") << endl; + out << endl; + out << tr("Options") << ":" << endl; + out << "-h, --help " << " " << tr("Print help text.") << endl; + out << "-v, --version " << " " << tr("Print version information.") << endl; + out << "--tray " << " " << tr("Launch program in system tray only.") << endl; + out << "--no-tray " << " " << tr("Launch program with the tray menu disabled.") << endl; + out << "--hidden " << " " << tr("Launch program without the main window\n displayed.") << endl; + out << "--profile " << " " << + tr("Launch program with the configuration file\n selected as the default for selected\n controllers. Defaults to all controllers.") + << endl; + out << "--profile-controller " << " " + << tr("Apply configuration file to a specific\n controller. Value can be a\n controller index, name, or GUID.") + << endl; + out << "--unload [] " << " " << tr("Unload currently enabled profile(s). \n Value can be a controller index, name, or GUID.") + << endl; + out << "--startSet [] " << " " << tr("Start joysticks on a specific set. \n Value can be a controller index, name, or GUID.") + << endl; + out << "--next " << " " << tr("Advance profile loading set options.") + << endl; + +#ifdef Q_OS_UNIX + out << "-d, --daemon " << " " + << tr("Launch program as a daemon.") << endl; + out << "--log-level {debug,info} " << " " << tr("Enable logging.") << endl; + + #ifdef WITH_X11 + #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + if (QApplication::platformName() == QStringLiteral("xcb")) + { + #endif + out << "--display " << " " + << tr("Use specified display for X11 calls.\n" + " Useful for ssh.") + << endl; + #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + } + #endif + #endif +#endif + +#if defined(Q_OS_UNIX) && defined(WITH_UINPUT) && defined(WITH_XTEST) + out << "--eventgen {xtest,uinput} " << " " + << tr("Choose between using XTest support and uinput\n" + " support for event generation. Default: xtest.") + << endl; +#elif defined(Q_OS_WIN) && defined(WITH_VMULTI) + out << "--eventgen {sendinput,vmulti} " << " " + << tr("Choose between using SendInput and vmulti\n" + " support for event generation. Default: sendinput.") + << endl; +#endif + +#ifdef USE_SDL_2 + out << "-l, --list " << " " + << tr("Print information about joysticks detected by \n" + " SDL.") << endl; + out << "--map " << " " + << tr("Open game controller mapping window of selected\n" + " controller. Value can be a controller index or\n" + " GUID.") + << endl; +#endif + +} + +QString CommandLineUtility::generateHelpString() +{ + QString temp; + QTextStream out(&temp); + out << tr("antimicro version") << " " << PadderCommon::programVersion << endl; + out << tr("Usage: antimicro [options...] [profile]") << endl; + out << endl; + out << tr("Options") << ":" << endl; + out << "-h, --help " << " " << tr("Print help text.") << endl; + out << "-v, --version " << " " << tr("Print version information.") << endl; + out << "--tray " << " " << tr("Launch program in system tray only.") << endl; + out << "--no-tray " << " " << tr("Launch program with the tray menu disabled.") << endl; + out << "--hidden " << " " << tr("Launch program without the main window\n displayed.") << endl; + out << "--profile " << " " << + tr("Launch program with the configuration file\n selected as the default for selected\n controllers. Defaults to all controllers.") + << endl; + out << "--profile-controller " << " " + << tr("Apply configuration file to a specific\n controller. Value can be a\n controller index, name, or GUID.") + << endl; + out << "--unload [] " << " " << tr("Unload currently enabled profile(s). \n Value can be a controller index, name, or GUID.") + << endl; + out << "--startSet [] " << " " << tr("Start joysticks on a specific set. \n Value can be a controller index, name, or GUID.") + << endl; + out << "--next " << " " << tr("Advance profile loading set options.") + << endl; + +#ifdef Q_OS_UNIX + out << "-d, --daemon " << " " + << tr("Launch program as a daemon.") << endl; + out << "--log-level {debug,info} " << " " << tr("Enable logging.") << endl; + #ifdef WITH_X11 + #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + if (QApplication::platformName() == QStringLiteral("xcb")) + { + #endif + out << "--display " << " " + << tr("Use specified display for X11 calls.\n" + " Useful for ssh.") + << endl; + #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + } + #endif + #endif +#endif + +#if defined(Q_OS_UNIX) && defined(WITH_UINPUT) && defined(WITH_XTEST) + out << "--eventgen {xtest,uinput} " << " " + << tr("Choose between using XTest support and uinput\n" + " support for event generation. Default: xtest.") + << endl; +#elif defined(Q_OS_WIN) && defined(WITH_VMULTI) + out << "--eventgen {sendinput,vmulti} " << " " + << tr("Choose between using SendInput and vmulti\n" + " support for event generation. Default: sendinput.") + << endl; +#endif + +#ifdef USE_SDL_2 + out << "-l, --list " << " " + << tr("Print information about joysticks detected by \n" + " SDL.") << endl; + out << "--map " << " " + << tr("Open game controller mapping window of selected\n" + " controller. Value can be a controller index or\n" + " GUID.") + << endl; +#endif + + return temp; +} + +bool CommandLineUtility::isHelpRequested() +{ + return helpRequest; +} + +bool CommandLineUtility::isVersionRequested() +{ + return versionRequest; +} + +void CommandLineUtility::printVersionString() +{ + QTextStream out(stdout); + out << tr("antimicro version") << " " << PadderCommon::programVersion << endl; +} + +QString CommandLineUtility::generateVersionString() +{ + QString temp; + QTextStream out(&temp); + out << tr("antimicro version") << " " << PadderCommon::programVersion; + + return temp; +} + +bool CommandLineUtility::isTrayHidden() +{ + return hideTrayIcon; +} + +bool CommandLineUtility::hasProfile() +{ + return !profileLocation.isEmpty(); +} + +bool CommandLineUtility::hasControllerNumber() +{ + return (controllerNumber > 0); +} + +QString CommandLineUtility::getProfileLocation() +{ + return profileLocation; +} + +unsigned int CommandLineUtility::getControllerNumber() +{ + return controllerNumber; +} + +bool CommandLineUtility::hasError() +{ + return encounteredError; +} + +bool CommandLineUtility::isHiddenRequested() +{ + return hiddenRequest; +} + +bool CommandLineUtility::hasControllerID() +{ + return !controllerIDString.isEmpty(); +} + +QString CommandLineUtility::getControllerID() +{ + return controllerIDString; +} + +bool CommandLineUtility::isUnloadRequested() +{ + return unloadProfile; +} + +unsigned int CommandLineUtility::getStartSetNumber() +{ + return startSetNumber; +} + +unsigned int CommandLineUtility::getJoyStartSetNumber() +{ + return startSetNumber - 1; +} + +bool CommandLineUtility::isPossibleCommand(QString temp) +{ + bool result = false; + + if (temp.startsWith("--") || temp.startsWith("-")) + { + result = true; + } + + return result; +} + +bool CommandLineUtility::shouldListControllers() +{ + return listControllers; +} + +bool CommandLineUtility::shouldMapController() +{ + return mappingController; +} + +QString CommandLineUtility::getEventGenerator() +{ + return eventGenerator; +} + +#ifdef Q_OS_UNIX +bool CommandLineUtility::launchAsDaemon() +{ + return daemonMode; +} + +QString CommandLineUtility::getDisplayString() +{ + return displayString; +} + +#endif + +Logger::LogLevel CommandLineUtility::getCurrentLogLevel() +{ + return currentLogLevel; +} + +QString CommandLineUtility::getErrorText() +{ + return errorText; +} + +void CommandLineUtility::setErrorMessage(QString temp) +{ + errorText = temp; + encounteredError = true; +} + +QList* CommandLineUtility::getControllerOptionsList() +{ + return &controllerOptionsList; +} + +bool CommandLineUtility::hasProfileInOptions() +{ + bool result = false; + + QListIterator iter(controllerOptionsList); + while (iter.hasNext()) + { + ControllerOptionsInfo temp = iter.next(); + if (temp.hasProfile()) + { + result = true; + iter.toBack(); + } + } + + return result; +} diff --git a/src/commandlineutility.h b/src/commandlineutility.h new file mode 100644 index 0000000..5bdb510 --- /dev/null +++ b/src/commandlineutility.h @@ -0,0 +1,225 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef COMMANDLINEPARSER_H +#define COMMANDLINEPARSER_H + +#include +#include +#include +#include + +#include "logger.h" + +class ControllerOptionsInfo { +public: + ControllerOptionsInfo() + { + controllerNumber = 0; + startSetNumber = 0; + unloadProfile = false; + } + + bool hasProfile() + { + return !profileLocation.isEmpty(); + } + + QString getProfileLocation() + { + return profileLocation; + } + + void setProfileLocation(QString location) + { + profileLocation = location; + } + + bool hasControllerNumber() + { + return (controllerNumber > 0); + } + + unsigned int getControllerNumber() + { + return controllerNumber; + } + + void setControllerNumber(unsigned int temp) + { + controllerNumber = temp; + } + + bool hasControllerID() + { + return !controllerIDString.isEmpty(); + } + + QString getControllerID() + { + return controllerIDString; + } + + void setControllerID(QString temp) + { + controllerIDString = temp; + } + + bool isUnloadRequested() + { + return unloadProfile; + } + + void setUnloadRequest(bool status) + { + unloadProfile = status; + } + + unsigned int getStartSetNumber() + { + return startSetNumber; + } + + unsigned int getJoyStartSetNumber() + { + return startSetNumber - 1; + } + + void setStartSetNumber(unsigned int temp) + { + if (temp >= 1 && temp <= 8) + { + startSetNumber = temp; + } + } + +protected: + QString profileLocation; + unsigned int controllerNumber; + QString controllerIDString; + unsigned int startSetNumber; + bool unloadProfile; +}; + +class CommandLineUtility : public QObject +{ + Q_OBJECT +public: + explicit CommandLineUtility(QObject *parent = 0); + + void parseArguments(QStringList &arguments); + bool isLaunchInTrayEnabled(); + bool isHelpRequested(); + bool isVersionRequested(); + bool isTrayHidden(); + bool hasProfile(); + bool hasControllerNumber(); + bool hasControllerID(); + + QString getProfileLocation(); + + unsigned int getControllerNumber(); + + QString getControllerID(); + + bool isHiddenRequested(); + bool isUnloadRequested(); + bool shouldListControllers(); + bool shouldMapController(); + + unsigned int getStartSetNumber(); + unsigned int getJoyStartSetNumber(); + QList* getJoyStartSetNumberList(); + + QList* getControllerOptionsList(); + bool hasProfileInOptions(); + + QString getEventGenerator(); + +#ifdef Q_OS_UNIX + bool launchAsDaemon(); + QString getDisplayString(); +#endif + + void printHelp(); + void printVersionString(); + + QString generateHelpString(); + QString generateVersionString(); + + bool hasError(); + Logger::LogLevel getCurrentLogLevel(); + QString getErrorText(); + +protected: + bool isPossibleCommand(QString temp); + void setErrorMessage(QString temp); + + bool launchInTray; + bool helpRequest; + bool versionRequest; + bool hideTrayIcon; + + QString profileLocation; + unsigned int controllerNumber; + QString controllerIDString; + + bool encounteredError; + bool hiddenRequest; + bool unloadProfile; + + unsigned int startSetNumber; + + bool daemonMode; + QString displayString; + bool listControllers; + bool mappingController; + QString eventGenerator; + QString errorText; + Logger::LogLevel currentLogLevel; + unsigned int currentListsIndex; + QList controllerOptionsList; + + static QRegExp trayRegexp; + static QRegExp helpRegexp; + static QRegExp versionRegexp; + static QRegExp noTrayRegexp; + static QRegExp loadProfileRegexp; + static QRegExp loadProfileForControllerRegexp; + static QRegExp hiddenRegexp; + static QRegExp unloadRegexp; + static QRegExp startSetRegexp; + static QRegExp gamepadListRegexp; + static QRegExp mappingRegexp; + static QRegExp qtStyleRegexp; + static QRegExp logLevelRegexp; + static QRegExp eventgenRegexp; + static QRegExp nextRegexp; + static QStringList eventGeneratorsList; + +#ifdef Q_OS_UNIX + static QRegExp daemonRegexp; + static QRegExp displayRegexp; +#endif + +signals: + +public slots: + +}; + +#endif // COMMANDLINEPARSER_H diff --git a/src/common.cpp b/src/common.cpp new file mode 100644 index 0000000..33c3b59 --- /dev/null +++ b/src/common.cpp @@ -0,0 +1,185 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#ifdef Q_OS_WIN +#include +#endif + +#include "common.h" + +namespace PadderCommon +{ + QString preferredProfileDir(AntiMicroSettings *settings) + { + QString lastProfileDir = settings->value("LastProfileDir", "").toString(); + QString defaultProfileDir = settings->value("DefaultProfileDir", "").toString(); + QString lookupDir; + + if (!defaultProfileDir.isEmpty()) + { + QFileInfo dirinfo(defaultProfileDir); + if (dirinfo.isDir() && dirinfo.isReadable()) + { + lookupDir = defaultProfileDir; + } + } + + if (lookupDir.isEmpty() && !lastProfileDir.isEmpty()) + { + QFileInfo dirinfo(lastProfileDir); + if (dirinfo.isDir() && dirinfo.isReadable()) + { + lookupDir = lastProfileDir; + } + } + + if (lookupDir.isEmpty()) + { +#ifdef Q_OS_WIN + #ifdef WIN_PORTABLE_PACKAGE + QString portableProDir = QDir::currentPath().append("/profiles"); + QFileInfo portableProDirInfo(portableProDir); + if (portableProDirInfo.isDir() && portableProDirInfo.isReadable()) + { + lookupDir = portableProDir; + } + else + { + lookupDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); + } + #else + lookupDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); + #endif +#else + lookupDir = QDir::homePath(); +#endif + } + + return lookupDir; + } + + QStringList arguments(int &argc, char **argv) + { + QStringList list; + + for (int a = 0; a < argc; ++a) { + list << QString::fromLocal8Bit(argv[a]); + } + + return list; + } + + QStringList parseArgumentsString(QString tempString) + { + bool inside = (!tempString.isEmpty() && tempString.at(0) == QChar('"')); + QStringList tempList = tempString.split(QRegExp("\""), QString::SkipEmptyParts); + QStringList finalList; + QStringListIterator iter(tempList); + while (iter.hasNext()) + { + QString temp = iter.next(); + if (inside) + { + finalList.append(temp); + } + else + { + finalList.append(temp.split(QRegExp("\\s+"), QString::SkipEmptyParts)); + } + + inside = !inside; + } + + return finalList; + } + + /** + * @brief Reload main application and base Qt translation files. + * @param Based Qt translator + * @param Application translator + * @param Language code + */ + void reloadTranslations(QTranslator *translator, + QTranslator *appTranslator, + QString language) + { + // Remove application specific translation strings + qApp->removeTranslator(translator); + + // Remove old Qt translation strings + qApp->removeTranslator(appTranslator); + + // Load new Qt translation strings + #if defined(Q_OS_UNIX) + translator->load(QString("qt_").append(language), QLibraryInfo::location(QLibraryInfo::TranslationsPath)); + #elif defined(Q_OS_WIN) + #ifdef QT_DEBUG + translator->load(QString("qt_").append(language), QLibraryInfo::location(QLibraryInfo::TranslationsPath)); + #else + translator->load(QString("qt_").append(language), + QApplication::applicationDirPath().append("\\share\\qt\\translations")); + #endif + #endif + + qApp->installTranslator(appTranslator); + + // Load application specific translation strings + #if defined(Q_OS_UNIX) + translator->load("antimicro_" + language, QApplication::applicationDirPath().append("/../share/antimicro/translations")); + #elif defined(Q_OS_WIN) + translator->load("antimicro_" + language, QApplication::applicationDirPath().append("\\share\\antimicro\\translations")); + #endif + qApp->installTranslator(translator); + } + + void lockInputDevices() + { + sdlWaitMutex.lock(); + /*editingLock.lockForWrite(); + editingBindings = true; + editingLock.unlock(); + + waitMutex.lock(); + //editingBindings = true; + waitThisOut.wait(&waitMutex); + */ + } + + void unlockInputDevices() + { + sdlWaitMutex.unlock(); + /*editingLock.lockForWrite(); + editingBindings = false; + editingLock.unlock(); + + waitMutex.unlock(); + */ + } + + QWaitCondition waitThisOut; + QMutex sdlWaitMutex; + QMutex inputDaemonMutex; + QReadWriteLock editingLock; + bool editingBindings = false; + MouseHelper mouseHelperObj; + + QString mouseDeviceName("antimicro Mouse Emulation"); + QString keyboardDeviceName("antimicro Keyboard Emulation"); + QString springMouseDeviceName("antimicro Abs Mouse Emulation"); +} diff --git a/src/common.h b/src/common.h new file mode 100644 index 0000000..c82641a --- /dev/null +++ b/src/common.h @@ -0,0 +1,152 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef COMMON_H +#define COMMON_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "antimicrosettings.h" +#include "mousehelper.h" + +#ifdef Q_OS_WIN + +static QString findWinSystemConfigPath() +{ + QString temp; + temp = (!qgetenv("LocalAppData").isEmpty()) ? + QString::fromUtf8(qgetenv("LocalAppData")) + "/antimicro" : + QDir::homePath() + "/.antimicro"; + return temp; +} + +static QString findWinLocalConfigPath() +{ + QString temp = QDir::currentPath(); + return temp; +} + +static QString findWinDefaultConfigPath() +{ + QString temp = findWinLocalConfigPath(); + QFileInfo dirInfo(temp); + if (!dirInfo.isWritable()) + { + temp = findWinSystemConfigPath(); + } + + return temp; +} + +static QString findWinConfigPath(QString configFileName) +{ + QString temp; + QFileInfo localConfigInfo(findWinLocalConfigPath().append("/").append(configFileName)); + QFileInfo systemConfigInfo(findWinSystemConfigPath().append("/").append(configFileName)); + if (localConfigInfo.exists() && localConfigInfo.isWritable()) + { + temp = localConfigInfo.absoluteFilePath(); + } + else if (systemConfigInfo.exists() && systemConfigInfo.isWritable()) + { + temp = systemConfigInfo.absoluteFilePath(); + } + else + { + temp = findWinDefaultConfigPath().append("/").append(configFileName); + } + + return temp; +} + +#endif + + +namespace PadderCommon +{ +#if defined(Q_OS_WIN) && defined(WIN_PORTABLE_PACKAGE) + const QString configPath = findWinLocalConfigPath(); +#elif defined(Q_OS_WIN) + const QString configPath = findWinSystemConfigPath(); +#else + const QString configPath = (!qgetenv("XDG_CONFIG_HOME").isEmpty()) ? + QString::fromUtf8(qgetenv("XDG_CONFIG_HOME")) + "/antimicro" : + QDir::homePath() + "/.config/antimicro"; + +#endif + + const QString configFileName = "antimicro_settings.ini"; +#if defined(Q_OS_WIN) && defined(WIN_PORTABLE_PACKAGE) + const QString configFilePath = QString(configPath).append("/").append(configFileName); +#elif defined(Q_OS_WIN) + const QString configFilePath = QString(configPath).append("/").append(configFileName); +#else + const QString configFilePath = QString(configPath).append("/").append(configFileName); +#endif + + const int LATESTCONFIGFILEVERSION = 19; + // Specify the last known profile version that requires a migration + // to be performed in order to be compatible with the latest version. + const int LATESTCONFIGMIGRATIONVERSION = 5; + const QString localSocketKey = "antimicroSignalListener"; + const QString githubProjectPage = "https://github.com/Ryochan7/antimicro"; + const QString wikiPage = QString("%1/wiki").arg(githubProjectPage); + + extern QString mouseDeviceName; + extern QString keyboardDeviceName; + extern QString springMouseDeviceName; + + const int ANTIMICRO_MAJOR_VERSION = PROJECT_MAJOR_VERSION; + const int ANTIMICRO_MINOR_VERSION = PROJECT_MINOR_VERSION; + const int ANTIMICRO_PATCH_VERSION = PROJECT_PATCH_VERSION; + + const QString programVersion = (ANTIMICRO_PATCH_VERSION > 0) ? + QString("%1.%2.%3").arg(ANTIMICRO_MAJOR_VERSION) + .arg(ANTIMICRO_MINOR_VERSION).arg(ANTIMICRO_PATCH_VERSION) : + QString("%1.%2").arg(ANTIMICRO_MAJOR_VERSION) + .arg(ANTIMICRO_MINOR_VERSION); + + extern QWaitCondition waitThisOut; + extern QMutex sdlWaitMutex; + extern QMutex inputDaemonMutex; + extern bool editingBindings; + extern QReadWriteLock editingLock; + extern MouseHelper mouseHelperObj; + + QString preferredProfileDir(AntiMicroSettings *settings); + QStringList arguments(int &argc, char **argv); + QStringList parseArgumentsString(QString tempString); + void reloadTranslations(QTranslator *translator, + QTranslator *appTranslator, + QString language); + void lockInputDevices(); + void unlockInputDevices(); +} + +Q_DECLARE_METATYPE(QThread*) + +#endif // COMMON_H diff --git a/src/config.h.in b/src/config.h.in new file mode 100644 index 0000000..3192cf2 --- /dev/null +++ b/src/config.h.in @@ -0,0 +1,8 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#define PROJECT_MAJOR_VERSION @ANTIMICRO_MAJOR_VERSION@ +#define PROJECT_MINOR_VERSION @ANTIMICRO_MINOR_VERSION@ +#define PROJECT_PATCH_VERSION @ANTIMICRO_PATCH_VERSION@ + +#endif // CONFIG_H diff --git a/src/dpadcontextmenu.cpp b/src/dpadcontextmenu.cpp new file mode 100644 index 0000000..e302564 --- /dev/null +++ b/src/dpadcontextmenu.cpp @@ -0,0 +1,406 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "dpadcontextmenu.h" +#include "mousedialog/mousedpadsettingsdialog.h" +#include "antkeymapper.h" +#include "inputdevice.h" +#include "common.h" + +DPadContextMenu::DPadContextMenu(JoyDPad *dpad, QWidget *parent) : + QMenu(parent), + helper(dpad) +{ + this->dpad = dpad; + helper.moveToThread(dpad->thread()); + + connect(this, SIGNAL(aboutToHide()), this, SLOT(deleteLater())); +} + +/** + * @brief Generate the context menu that will be shown to a user when the person + * right clicks on the DPad settings button. + */ +void DPadContextMenu::buildMenu() +{ + QAction *action = 0; + + QActionGroup *presetGroup = new QActionGroup(this); + int presetMode = 0; + int currentPreset = getPresetIndex(); + + action = this->addAction(tr("Mouse (Normal)")); + action->setCheckable(true); + action->setChecked(currentPreset == presetMode+1); + action->setData(QVariant(presetMode)); + connect(action, SIGNAL(triggered()), this, SLOT(setDPadPreset())); + presetGroup->addAction(action); + + presetMode++; + action = this->addAction(tr("Mouse (Inverted Horizontal)")); + action->setCheckable(true); + action->setChecked(currentPreset == presetMode+1); + action->setData(QVariant(presetMode)); + connect(action, SIGNAL(triggered()), this, SLOT(setDPadPreset())); + presetGroup->addAction(action); + + presetMode++; + action = this->addAction(tr("Mouse (Inverted Vertical)")); + action->setCheckable(true); + action->setChecked(currentPreset == presetMode+1); + action->setData(QVariant(presetMode)); + connect(action, SIGNAL(triggered()), this, SLOT(setDPadPreset())); + presetGroup->addAction(action); + + presetMode++; + action = this->addAction(tr("Mouse (Inverted Horizontal + Vertical)")); + action->setCheckable(true); + action->setChecked(currentPreset == presetMode+1); + action->setData(QVariant(presetMode)); + connect(action, SIGNAL(triggered()), this, SLOT(setDPadPreset())); + presetGroup->addAction(action); + + presetMode++; + action = this->addAction(tr("Arrows")); + action->setCheckable(true); + action->setChecked(currentPreset == presetMode+1); + action->setData(QVariant(presetMode)); + connect(action, SIGNAL(triggered()), this, SLOT(setDPadPreset())); + presetGroup->addAction(action); + + presetMode++; + action = this->addAction(tr("Keys: W | A | S | D")); + action->setCheckable(true); + action->setChecked(currentPreset == presetMode+1); + action->setData(QVariant(presetMode)); + connect(action, SIGNAL(triggered()), this, SLOT(setDPadPreset())); + presetGroup->addAction(action); + + presetMode++; + action = this->addAction(tr("NumPad")); + action->setCheckable(true); + action->setChecked(currentPreset == presetMode+1); + action->setData(QVariant(presetMode)); + connect(action, SIGNAL(triggered()), this, SLOT(setDPadPreset())); + presetGroup->addAction(action); + + presetMode++; + action = this->addAction(tr("None")); + action->setCheckable(true); + action->setChecked(currentPreset == presetMode+1); + action->setData(QVariant(presetMode)); + connect(action, SIGNAL(triggered()), this, SLOT(setDPadPreset())); + presetGroup->addAction(action); + + this->addSeparator(); + + QActionGroup *modesGroup = new QActionGroup(this); + int mode = (int)JoyDPad::StandardMode; + + action = this->addAction(tr("Standard")); + action->setCheckable(true); + action->setChecked(dpad->getJoyMode() == JoyDPad::StandardMode); + action->setData(QVariant(mode)); + connect(action, SIGNAL(triggered()), this, SLOT(setDPadMode())); + modesGroup->addAction(action); + + action = this->addAction(tr("Eight Way")); + action->setCheckable(true); + action->setChecked(dpad->getJoyMode() == JoyDPad::EightWayMode); + mode = (int)JoyDPad::EightWayMode; + action->setData(QVariant(mode)); + connect(action, SIGNAL(triggered()), this, SLOT(setDPadMode())); + modesGroup->addAction(action); + + action = this->addAction(tr("4 Way Cardinal")); + action->setCheckable(true); + action->setChecked(dpad->getJoyMode() == JoyDPad::FourWayCardinal); + mode = (int)JoyDPad::FourWayCardinal; + action->setData(QVariant(mode)); + connect(action, SIGNAL(triggered()), this, SLOT(setDPadMode())); + modesGroup->addAction(action); + + action = this->addAction(tr("4 Way Diagonal")); + action->setCheckable(true); + action->setChecked(dpad->getJoyMode() == JoyDPad::FourWayDiagonal); + mode = (int)JoyDPad::FourWayDiagonal; + action->setData(QVariant(mode)); + connect(action, SIGNAL(triggered()), this, SLOT(setDPadMode())); + modesGroup->addAction(action); + + this->addSeparator(); + + action = this->addAction(tr("Mouse Settings")); + action->setCheckable(false); + connect(action, SIGNAL(triggered()), this, SLOT(openMouseSettingsDialog())); +} + +/** + * @brief Set the appropriate mode for a DPad based on the item chosen. + */ +void DPadContextMenu::setDPadMode() +{ + QAction *action = static_cast(sender()); + int item = action->data().toInt(); + dpad->setJoyMode((JoyDPad::JoyMode)item); +} + +/** + * @brief Assign the appropriate slots to DPad buttons based on the preset item + * that was chosen. + */ +void DPadContextMenu::setDPadPreset() +{ + QAction *action = static_cast(sender()); + int item = action->data().toInt(); + + JoyButtonSlot *upButtonSlot = 0; + JoyButtonSlot *downButtonSlot = 0; + JoyButtonSlot *leftButtonSlot = 0; + JoyButtonSlot *rightButtonSlot = 0; + JoyButtonSlot *upLeftButtonSlot = 0; + JoyButtonSlot *upRightButtonSlot = 0; + JoyButtonSlot *downLeftButtonSlot = 0; + JoyButtonSlot *downRightButtonSlot = 0; + + if (item == 0) + { + PadderCommon::inputDaemonMutex.lock(); + + upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); + downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); + leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); + rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); + dpad->setJoyMode(JoyDPad::StandardMode); + + PadderCommon::inputDaemonMutex.unlock(); + } + else if (item == 1) + { + PadderCommon::inputDaemonMutex.lock(); + + upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); + downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); + leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); + rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); + dpad->setJoyMode(JoyDPad::StandardMode); + + PadderCommon::inputDaemonMutex.unlock(); + } + else if (item == 2) + { + PadderCommon::inputDaemonMutex.lock(); + + upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); + downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); + leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); + rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); + dpad->setJoyMode(JoyDPad::StandardMode); + + PadderCommon::inputDaemonMutex.unlock(); + } + else if (item == 3) + { + PadderCommon::inputDaemonMutex.lock(); + + upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); + downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); + leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); + rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); + dpad->setJoyMode(JoyDPad::StandardMode); + + PadderCommon::inputDaemonMutex.unlock(); + } + else if (item == 4) + { + PadderCommon::inputDaemonMutex.lock(); + + upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Up), Qt::Key_Up, JoyButtonSlot::JoyKeyboard, this); + downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Down), Qt::Key_Down, JoyButtonSlot::JoyKeyboard, this); + leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Left), Qt::Key_Left, JoyButtonSlot::JoyKeyboard, this); + rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Right), Qt::Key_Right, JoyButtonSlot::JoyKeyboard, this); + dpad->setJoyMode(JoyDPad::StandardMode); + + PadderCommon::inputDaemonMutex.unlock(); + } + else if (item == 5) + { + PadderCommon::inputDaemonMutex.lock(); + + upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_W), Qt::Key_W, JoyButtonSlot::JoyKeyboard, this); + downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_S), Qt::Key_S, JoyButtonSlot::JoyKeyboard, this); + leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_A), Qt::Key_A, JoyButtonSlot::JoyKeyboard, this); + rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_D), Qt::Key_D, JoyButtonSlot::JoyKeyboard, this); + dpad->setJoyMode(JoyDPad::StandardMode); + + PadderCommon::inputDaemonMutex.unlock(); + } + else if (item == 6) + { + PadderCommon::inputDaemonMutex.lock(); + + if (dpad->getJoyMode() == JoyDPad::StandardMode || + dpad->getJoyMode() == JoyDPad::FourWayCardinal) + { + upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8), QtKeyMapperBase::AntKey_KP_8, JoyButtonSlot::JoyKeyboard, this); + downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2), QtKeyMapperBase::AntKey_KP_2, JoyButtonSlot::JoyKeyboard, this); + leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4), QtKeyMapperBase::AntKey_KP_4, JoyButtonSlot::JoyKeyboard, this); + rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6), QtKeyMapperBase::AntKey_KP_6, JoyButtonSlot::JoyKeyboard, this); + } + else if (dpad->getJoyMode() == JoyDPad::EightWayMode) + { + upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8), QtKeyMapperBase::AntKey_KP_8, JoyButtonSlot::JoyKeyboard, this); + downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2), QtKeyMapperBase::AntKey_KP_2, JoyButtonSlot::JoyKeyboard, this); + leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4), QtKeyMapperBase::AntKey_KP_4, JoyButtonSlot::JoyKeyboard, this); + rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6), QtKeyMapperBase::AntKey_KP_6, JoyButtonSlot::JoyKeyboard, this); + + upLeftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_7), QtKeyMapperBase::AntKey_KP_7, JoyButtonSlot::JoyKeyboard, this); + upRightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_9), QtKeyMapperBase::AntKey_KP_9, JoyButtonSlot::JoyKeyboard, this); + downLeftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_1), QtKeyMapperBase::AntKey_KP_1, JoyButtonSlot::JoyKeyboard, this); + downRightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_3), QtKeyMapperBase::AntKey_KP_3, JoyButtonSlot::JoyKeyboard, this); + } + else if (dpad->getJoyMode() == JoyDPad::FourWayDiagonal) + { + upLeftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_7), QtKeyMapperBase::AntKey_KP_7, JoyButtonSlot::JoyKeyboard, this); + upRightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_9), QtKeyMapperBase::AntKey_KP_9, JoyButtonSlot::JoyKeyboard, this); + downLeftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_1), QtKeyMapperBase::AntKey_KP_1, JoyButtonSlot::JoyKeyboard, this); + downRightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_3), QtKeyMapperBase::AntKey_KP_3, JoyButtonSlot::JoyKeyboard, this); + } + + PadderCommon::inputDaemonMutex.unlock(); + } + else if (item == 7) + { + QMetaObject::invokeMethod(&helper, "clearButtonsSlotsEventReset", Qt::BlockingQueuedConnection); + } + + QHash tempHash; + tempHash.insert(JoyDPadButton::DpadUp, upButtonSlot); + tempHash.insert(JoyDPadButton::DpadDown, downButtonSlot); + tempHash.insert(JoyDPadButton::DpadLeft, leftButtonSlot); + tempHash.insert(JoyDPadButton::DpadRight, rightButtonSlot); + tempHash.insert(JoyDPadButton::DpadLeftUp, upLeftButtonSlot); + tempHash.insert(JoyDPadButton::DpadRightUp, upRightButtonSlot); + tempHash.insert(JoyDPadButton::DpadLeftDown, downLeftButtonSlot); + tempHash.insert(JoyDPadButton::DpadRightDown, downRightButtonSlot); + + helper.setPendingSlots(&tempHash); + QMetaObject::invokeMethod(&helper, "setFromPendingSlots", Qt::BlockingQueuedConnection); +} + +/** + * @brief Find the appropriate menu item index for the currently assigned + * slots that are assigned to a DPad. + * @return Menu index that corresponds to the currently assigned preset choice. + * 0 means that no matching preset was found. + */ +int DPadContextMenu::getPresetIndex() +{ + int result = 0; + + PadderCommon::inputDaemonMutex.lock(); + + JoyDPadButton *upButton = dpad->getJoyButton(JoyDPadButton::DpadUp); + QList *upslots = upButton->getAssignedSlots(); + + JoyDPadButton *downButton = dpad->getJoyButton(JoyDPadButton::DpadDown); + QList *downslots = downButton->getAssignedSlots(); + + JoyDPadButton *leftButton = dpad->getJoyButton(JoyDPadButton::DpadLeft); + QList *leftslots = leftButton->getAssignedSlots(); + + JoyDPadButton *rightButton = dpad->getJoyButton(JoyDPadButton::DpadRight); + QList *rightslots = rightButton->getAssignedSlots(); + + if (upslots->length() == 1 && downslots->length() == 1 && leftslots->length() == 1 && rightslots->length() == 1) + { + JoyButtonSlot *upslot = upslots->at(0); + JoyButtonSlot *downslot = downslots->at(0); + JoyButtonSlot *leftslot = leftslots->at(0); + JoyButtonSlot *rightslot = rightslots->at(0); + + if (upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && upslot->getSlotCode() == JoyButtonSlot::MouseUp && + downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && downslot->getSlotCode() == JoyButtonSlot::MouseDown && + leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && leftslot->getSlotCode() == JoyButtonSlot::MouseLeft && + rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && rightslot->getSlotCode() == JoyButtonSlot::MouseRight) + { + result = 1; + } + else if (upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && upslot->getSlotCode() == JoyButtonSlot::MouseUp && + downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && downslot->getSlotCode() == JoyButtonSlot::MouseDown && + leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && leftslot->getSlotCode() == JoyButtonSlot::MouseRight && + rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && rightslot->getSlotCode() == JoyButtonSlot::MouseLeft) + { + result = 2; + } + else if (upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && upslot->getSlotCode() == JoyButtonSlot::MouseDown && + downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && downslot->getSlotCode() == JoyButtonSlot::MouseUp && + leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && leftslot->getSlotCode() == JoyButtonSlot::MouseLeft && + rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && rightslot->getSlotCode() == JoyButtonSlot::MouseRight) + { + result = 3; + } + else if (upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && upslot->getSlotCode() == JoyButtonSlot::MouseDown && + downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && downslot->getSlotCode() == JoyButtonSlot::MouseUp && + leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && leftslot->getSlotCode() == JoyButtonSlot::MouseRight && + rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && rightslot->getSlotCode() == JoyButtonSlot::MouseLeft) + { + result = 4; + } + else if (upslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && static_cast(upslot->getSlotCode()) == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Up) && + downslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && static_cast(downslot->getSlotCode()) == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Down) && + leftslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && static_cast(leftslot->getSlotCode()) == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Left) && + rightslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && static_cast(rightslot->getSlotCode()) == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Right)) + { + result = 5; + } + else if (upslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && static_cast(upslot->getSlotCode()) == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_W) && + downslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && static_cast(downslot->getSlotCode()) == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_S) && + leftslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && static_cast(leftslot->getSlotCode()) == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_A) && + rightslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && static_cast(rightslot->getSlotCode()) == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_D)) + { + result = 6; + } + else if (upslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && static_cast(upslot->getSlotCode()) == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8) && + downslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && static_cast(downslot->getSlotCode()) == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2) && + leftslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && static_cast(leftslot->getSlotCode()) == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4) && + rightslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && static_cast(rightslot->getSlotCode()) == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6)) + { + result = 7; + } + } + else if (upslots->length() == 0 && downslots->length() == 0 && leftslots->length() == 0 && rightslots->length() == 0) + { + result = 8; + } + + PadderCommon::inputDaemonMutex.unlock(); + + return result; +} + +/** + * @brief Open a mouse settings dialog for changing the mouse speed settings + * for all DPad buttons. + */ +void DPadContextMenu::openMouseSettingsDialog() +{ + MouseDPadSettingsDialog *dialog = new MouseDPadSettingsDialog(dpad, parentWidget()); + dialog->show(); +} diff --git a/src/dpadcontextmenu.h b/src/dpadcontextmenu.h new file mode 100644 index 0000000..2024057 --- /dev/null +++ b/src/dpadcontextmenu.h @@ -0,0 +1,50 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef DPADCONTEXTMENU_H +#define DPADCONTEXTMENU_H + +#include + +#include "joydpad.h" + +#include "uihelpers/dpadcontextmenuhelper.h" + +class DPadContextMenu : public QMenu +{ + Q_OBJECT +public: + explicit DPadContextMenu(JoyDPad *dpad, QWidget *parent = 0); + void buildMenu(); + +protected: + int getPresetIndex(); + + JoyDPad *dpad; + DPadContextMenuHelper helper; + +signals: + +public slots: + +private slots: + void setDPadPreset(); + void setDPadMode(); + void openMouseSettingsDialog(); +}; + +#endif // DPADCONTEXTMENU_H diff --git a/src/dpadeditdialog.cpp b/src/dpadeditdialog.cpp new file mode 100644 index 0000000..0f1811a --- /dev/null +++ b/src/dpadeditdialog.cpp @@ -0,0 +1,400 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +//#include +#include +#include + +#include "dpadeditdialog.h" +#include "ui_dpadeditdialog.h" +#include "mousedialog/mousedpadsettingsdialog.h" +#include "event.h" +#include "antkeymapper.h" +#include "setjoystick.h" +#include "inputdevice.h" +#include "common.h" + +DPadEditDialog::DPadEditDialog(JoyDPad *dpad, QWidget *parent) : + QDialog(parent, Qt::Window), + ui(new Ui::DPadEditDialog), + helper(dpad) +{ + ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + + this->dpad = dpad; + helper.moveToThread(dpad->thread()); + + PadderCommon::inputDaemonMutex.lock(); + + updateWindowTitleDPadName(); + + if (dpad->getJoyMode() == JoyDPad::StandardMode) + { + ui->joyModeComboBox->setCurrentIndex(0); + } + else if (dpad->getJoyMode() == JoyDPad::EightWayMode) + { + ui->joyModeComboBox->setCurrentIndex(1); + } + else if (dpad->getJoyMode() == JoyDPad::FourWayCardinal) + { + ui->joyModeComboBox->setCurrentIndex(2); + } + else if (dpad->getJoyMode() == JoyDPad::FourWayDiagonal) + { + ui->joyModeComboBox->setCurrentIndex(3); + } + + selectCurrentPreset(); + + ui->dpadNameLineEdit->setText(dpad->getDpadName()); + + unsigned int dpadDelay = dpad->getDPadDelay(); + ui->dpadDelaySlider->setValue(dpadDelay * .1); + ui->dpadDelayDoubleSpinBox->setValue(dpadDelay * .001); + + PadderCommon::inputDaemonMutex.unlock(); + + connect(ui->presetsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(implementPresets(int))); + connect(ui->joyModeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(implementModes(int))); + connect(ui->mouseSettingsPushButton, SIGNAL(clicked()), this, SLOT(openMouseSettingsDialog())); + connect(ui->dpadNameLineEdit, SIGNAL(textEdited(QString)), dpad, SLOT(setDPadName(QString))); + + connect(ui->dpadDelaySlider, SIGNAL(valueChanged(int)), &helper, SLOT(updateJoyDPadDelay(int))); + connect(dpad, SIGNAL(dpadDelayChanged(int)), this, SLOT(updateDPadDelaySpinBox(int))); + connect(ui->dpadDelayDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(updateDPadDelaySlider(double))); + + connect(dpad, SIGNAL(dpadNameChanged()), this, SLOT(updateWindowTitleDPadName())); +} + +DPadEditDialog::~DPadEditDialog() +{ + delete ui; +} + +void DPadEditDialog::implementPresets(int index) +{ + JoyButtonSlot *upButtonSlot = 0; + JoyButtonSlot *downButtonSlot = 0; + JoyButtonSlot *leftButtonSlot = 0; + JoyButtonSlot *rightButtonSlot = 0; + JoyButtonSlot *upLeftButtonSlot = 0; + JoyButtonSlot *upRightButtonSlot = 0; + JoyButtonSlot *downLeftButtonSlot = 0; + JoyButtonSlot *downRightButtonSlot = 0; + + if (index == 1) + { + PadderCommon::inputDaemonMutex.lock(); + + upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); + downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); + leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); + rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); + + PadderCommon::inputDaemonMutex.unlock(); + + ui->joyModeComboBox->setCurrentIndex(0); + } + else if (index == 2) + { + PadderCommon::inputDaemonMutex.lock(); + + upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); + downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); + leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); + rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); + + PadderCommon::inputDaemonMutex.unlock(); + + ui->joyModeComboBox->setCurrentIndex(0); + } + else if (index == 3) + { + PadderCommon::inputDaemonMutex.lock(); + + upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); + downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); + leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); + rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); + + PadderCommon::inputDaemonMutex.unlock(); + + ui->joyModeComboBox->setCurrentIndex(0); + } + else if (index == 4) + { + PadderCommon::inputDaemonMutex.lock(); + + upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); + downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); + leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); + rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); + + PadderCommon::inputDaemonMutex.unlock(); + + ui->joyModeComboBox->setCurrentIndex(0); + } + else if (index == 5) + { + PadderCommon::inputDaemonMutex.lock(); + + upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Up), Qt::Key_Up, JoyButtonSlot::JoyKeyboard, this); + downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Down), Qt::Key_Down, JoyButtonSlot::JoyKeyboard, this); + leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Left), Qt::Key_Left, JoyButtonSlot::JoyKeyboard, this); + rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Right), Qt::Key_Right, JoyButtonSlot::JoyKeyboard, this); + + PadderCommon::inputDaemonMutex.unlock(); + + ui->joyModeComboBox->setCurrentIndex(0); + } + else if (index == 6) + { + PadderCommon::inputDaemonMutex.lock(); + + upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_W), Qt::Key_W, JoyButtonSlot::JoyKeyboard, this); + downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_S), Qt::Key_S, JoyButtonSlot::JoyKeyboard, this); + leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_A), Qt::Key_A, JoyButtonSlot::JoyKeyboard, this); + rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_D), Qt::Key_D, JoyButtonSlot::JoyKeyboard, this); + + PadderCommon::inputDaemonMutex.unlock(); + + ui->joyModeComboBox->setCurrentIndex(0); + } + else if (index == 7) + { + PadderCommon::inputDaemonMutex.lock(); + + if (ui->joyModeComboBox->currentIndex() == 0 || + ui->joyModeComboBox->currentIndex() == 2) + { + upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8), QtKeyMapperBase::AntKey_KP_8, JoyButtonSlot::JoyKeyboard, this); + downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2), QtKeyMapperBase::AntKey_KP_2, JoyButtonSlot::JoyKeyboard, this); + leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4), QtKeyMapperBase::AntKey_KP_4, JoyButtonSlot::JoyKeyboard, this); + rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6), QtKeyMapperBase::AntKey_KP_6, JoyButtonSlot::JoyKeyboard, this); + } + else if (ui->joyModeComboBox->currentIndex() == 1) + { + upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8), QtKeyMapperBase::AntKey_KP_8, JoyButtonSlot::JoyKeyboard, this); + downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2), QtKeyMapperBase::AntKey_KP_2, JoyButtonSlot::JoyKeyboard, this); + leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4), QtKeyMapperBase::AntKey_KP_4, JoyButtonSlot::JoyKeyboard, this); + rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6), QtKeyMapperBase::AntKey_KP_6, JoyButtonSlot::JoyKeyboard, this); + + upLeftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_7), QtKeyMapperBase::AntKey_KP_7, JoyButtonSlot::JoyKeyboard, this); + upRightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_9), QtKeyMapperBase::AntKey_KP_9, JoyButtonSlot::JoyKeyboard, this); + downLeftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_1), QtKeyMapperBase::AntKey_KP_1, JoyButtonSlot::JoyKeyboard, this); + downRightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_3), QtKeyMapperBase::AntKey_KP_3, JoyButtonSlot::JoyKeyboard, this); + } + else if (ui->joyModeComboBox->currentIndex() == 3) + { + upLeftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_7), QtKeyMapperBase::AntKey_KP_7, JoyButtonSlot::JoyKeyboard, this); + upRightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_9), QtKeyMapperBase::AntKey_KP_9, JoyButtonSlot::JoyKeyboard, this); + downLeftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_1), QtKeyMapperBase::AntKey_KP_1, JoyButtonSlot::JoyKeyboard, this); + downRightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_3), QtKeyMapperBase::AntKey_KP_3, JoyButtonSlot::JoyKeyboard, this); + } + + PadderCommon::inputDaemonMutex.unlock(); + } + else if (index == 8) + { + QMetaObject::invokeMethod(&helper, "clearButtonsSlotsEventReset", Qt::BlockingQueuedConnection); + } + + + QHash tempHash; + tempHash.insert(JoyDPadButton::DpadUp, upButtonSlot); + tempHash.insert(JoyDPadButton::DpadDown, downButtonSlot); + tempHash.insert(JoyDPadButton::DpadLeft, leftButtonSlot); + tempHash.insert(JoyDPadButton::DpadRight, rightButtonSlot); + tempHash.insert(JoyDPadButton::DpadLeftUp, upLeftButtonSlot); + tempHash.insert(JoyDPadButton::DpadRightUp, upRightButtonSlot); + tempHash.insert(JoyDPadButton::DpadLeftDown, downLeftButtonSlot); + tempHash.insert(JoyDPadButton::DpadRightDown, downRightButtonSlot); + + helper.setPendingSlots(&tempHash); + QMetaObject::invokeMethod(&helper, "setFromPendingSlots", Qt::BlockingQueuedConnection); +} + +void DPadEditDialog::implementModes(int index) +{ + PadderCommon::inputDaemonMutex.lock(); + + dpad->releaseButtonEvents(); + + if (index == 0) + { + dpad->setJoyMode(JoyDPad::StandardMode); + } + else if (index == 1) + { + dpad->setJoyMode(JoyDPad::EightWayMode); + } + else if (index == 2) + { + dpad->setJoyMode(JoyDPad::FourWayCardinal); + } + else if (index == 3) + { + dpad->setJoyMode(JoyDPad::FourWayDiagonal); + } + + PadderCommon::inputDaemonMutex.unlock(); +} + +void DPadEditDialog::selectCurrentPreset() +{ + JoyDPadButton *upButton = dpad->getJoyButton(JoyDPadButton::DpadUp); + QList *upslots = upButton->getAssignedSlots(); + JoyDPadButton *downButton = dpad->getJoyButton(JoyDPadButton::DpadDown); + QList *downslots = downButton->getAssignedSlots(); + JoyDPadButton *leftButton = dpad->getJoyButton(JoyDPadButton::DpadLeft); + QList *leftslots = leftButton->getAssignedSlots(); + JoyDPadButton *rightButton = dpad->getJoyButton(JoyDPadButton::DpadRight); + QList *rightslots = rightButton->getAssignedSlots(); + + if (upslots->length() == 1 && downslots->length() == 1 && leftslots->length() == 1 && rightslots->length() == 1) + { + JoyButtonSlot *upslot = upslots->at(0); + JoyButtonSlot *downslot = downslots->at(0); + JoyButtonSlot *leftslot = leftslots->at(0); + JoyButtonSlot *rightslot = rightslots->at(0); + + if (upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && upslot->getSlotCode() == JoyButtonSlot::MouseUp && + downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && downslot->getSlotCode() == JoyButtonSlot::MouseDown && + leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && leftslot->getSlotCode() == JoyButtonSlot::MouseLeft && + rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && rightslot->getSlotCode() == JoyButtonSlot::MouseRight) + { + ui->presetsComboBox->setCurrentIndex(1); + } + else if (upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && upslot->getSlotCode() == JoyButtonSlot::MouseUp && + downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && downslot->getSlotCode() == JoyButtonSlot::MouseDown && + leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && leftslot->getSlotCode() == JoyButtonSlot::MouseRight && + rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && rightslot->getSlotCode() == JoyButtonSlot::MouseLeft) + { + ui->presetsComboBox->setCurrentIndex(2); + } + else if (upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && upslot->getSlotCode() == JoyButtonSlot::MouseDown && + downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && downslot->getSlotCode() == JoyButtonSlot::MouseUp && + leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && leftslot->getSlotCode() == JoyButtonSlot::MouseLeft && + rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && rightslot->getSlotCode() == JoyButtonSlot::MouseRight) + { + ui->presetsComboBox->setCurrentIndex(3); + } + else if (upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && upslot->getSlotCode() == JoyButtonSlot::MouseDown && + downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && downslot->getSlotCode() == JoyButtonSlot::MouseUp && + leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && leftslot->getSlotCode() == JoyButtonSlot::MouseRight && + rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement && rightslot->getSlotCode() == JoyButtonSlot::MouseLeft) + { + ui->presetsComboBox->setCurrentIndex(4); + } + else if (upslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && static_cast(upslot->getSlotCode()) == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Up) && + downslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && static_cast(downslot->getSlotCode()) == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Down) && + leftslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && static_cast(leftslot->getSlotCode()) == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Left) && + rightslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && static_cast(rightslot->getSlotCode()) == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Right)) + { + ui->presetsComboBox->setCurrentIndex(5); + } + else if (upslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && static_cast(upslot->getSlotCode()) == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_W) && + downslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && static_cast(downslot->getSlotCode()) == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_S) && + leftslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && static_cast(leftslot->getSlotCode()) == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_A) && + rightslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && static_cast(rightslot->getSlotCode()) == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_D)) + { + ui->presetsComboBox->setCurrentIndex(6); + } + else if (upslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && static_cast(upslot->getSlotCode()) == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8) && + downslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && static_cast(downslot->getSlotCode()) == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2) && + leftslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && static_cast(leftslot->getSlotCode()) == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4) && + rightslot->getSlotMode() == JoyButtonSlot::JoyKeyboard && static_cast(rightslot->getSlotCode()) == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6)) + { + ui->presetsComboBox->setCurrentIndex(7); + } + } + else if (upslots->length() == 0 && downslots->length() == 0 && + leftslots->length() == 0 && rightslots->length() == 0) + { + ui->presetsComboBox->setCurrentIndex(8); + } +} + +void DPadEditDialog::openMouseSettingsDialog() +{ + ui->mouseSettingsPushButton->setEnabled(false); + + MouseDPadSettingsDialog *dialog = new MouseDPadSettingsDialog(this->dpad, this); + dialog->show(); + connect(this, SIGNAL(finished(int)), dialog, SLOT(close())); + connect(dialog, SIGNAL(finished(int)), this, SLOT(enableMouseSettingButton())); +} + +void DPadEditDialog::enableMouseSettingButton() +{ + ui->mouseSettingsPushButton->setEnabled(true); +} + +/** + * @brief Update QDoubleSpinBox value based on updated dpad delay value. + * @param Delay value obtained from JoyDPad. + */ +void DPadEditDialog::updateDPadDelaySpinBox(int value) +{ + double temp = static_cast(value * 0.001); + ui->dpadDelayDoubleSpinBox->setValue(temp); +} + +/** + * @brief Update QSlider value based on value from QDoubleSpinBox. + * @param Value from QDoubleSpinBox. + */ +void DPadEditDialog::updateDPadDelaySlider(double value) +{ + int temp = static_cast(value * 100); + if (ui->dpadDelaySlider->value() != temp) + { + ui->dpadDelaySlider->setValue(temp); + } +} + +void DPadEditDialog::updateWindowTitleDPadName() +{ + QString temp = QString(tr("Set")).append(" "); + + if (!dpad->getDpadName().isEmpty()) + { + temp.append(dpad->getName(false, true)); + } + else + { + temp.append(dpad->getName()); + } + + if (dpad->getParentSet()->getIndex() != 0) + { + unsigned int setIndex = dpad->getParentSet()->getRealIndex(); + temp.append(" [").append(tr("Set %1").arg(setIndex)); + + QString setName = dpad->getParentSet()->getName(); + if (!setName.isEmpty()) + { + temp.append(": ").append(setName); + } + + temp.append("]"); + } + + setWindowTitle(temp); +} diff --git a/src/dpadeditdialog.h b/src/dpadeditdialog.h new file mode 100644 index 0000000..136fb9f --- /dev/null +++ b/src/dpadeditdialog.h @@ -0,0 +1,57 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef DPADEDITDIALOG_H +#define DPADEDITDIALOG_H + +#include + +#include "joydpad.h" +#include "uihelpers/dpadeditdialoghelper.h" + +namespace Ui { +class DPadEditDialog; +} + +class DPadEditDialog : public QDialog +{ + Q_OBJECT + +public: + explicit DPadEditDialog(JoyDPad *dpad, QWidget *parent = 0); + ~DPadEditDialog(); + +protected: + void selectCurrentPreset(); + + JoyDPad *dpad; + DPadEditDialogHelper helper; + +private: + Ui::DPadEditDialog *ui; + +private slots: + void implementPresets(int index); + void implementModes(int index); + void openMouseSettingsDialog(); + void enableMouseSettingButton(); + void updateWindowTitleDPadName(); + void updateDPadDelaySpinBox(int value); + void updateDPadDelaySlider(double value); +}; + +#endif // DPADEDITDIALOG_H diff --git a/src/dpadeditdialog.ui b/src/dpadeditdialog.ui new file mode 100644 index 0000000..b57223f --- /dev/null +++ b/src/dpadeditdialog.ui @@ -0,0 +1,337 @@ + + + DPadEditDialog + + + Qt::WindowModal + + + + 0 + 0 + 528 + 334 + + + + Dialog + + + + + + + + + + Presets: + + + + + + + + 282 + 0 + + + + + + + + + + Mouse (Normal) + + + + + Mouse (Inverted Horizontal) + + + + + Mouse (Inverted Vertical) + + + + + Mouse (Inverted Horizontal + Vertical) + + + + + Arrows + + + + + Keys: W | A | S | D + + + + + NumPad + + + + + None + + + + + + + + + + + + Dpad Mode: + + + + + + + + 282 + 0 + + + + Standard: 8 region dpad with two direction buttons active +when the dpad is in a diagonal region. + +Eight Way: 8 region dpad with each direction having its +own dedicated button. Only one button is ever active at +at time. Useful for rougelike games. + +4 Way Cardinal: 4 region dpad with regions corresponding to +the cardinal directions of the dpad. Useful for menus. + +4 Way Diagonal: 4 region dpad with each region corresponding +to a diagonal zone. + + + + Standard + + + + + Eight Way + + + + + 4 Way Cardinal + + + + + 4 Way Diagonal + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + + DPad Delay: + + + + + + + Time lapsed before a direction change is taken into effect. + + + 0 + + + 100 + + + 1 + + + 10 + + + 0 + + + 0 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 0 + + + + + + + Time lapsed before a direction change is taken into effect. + + + false + + + s + + + 2 + + + 1.000000000000000 + + + 0.010000000000000 + + + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 20 + 36 + + + + + + + + 10 + + + 6 + + + + + &Name: + + + dpadNameLineEdit + + + + + + + Specify the name of a dpad. + + + + + + + + + Mouse Settings + + + + + + + + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + + + + buttonBox + accepted() + DPadEditDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + DPadEditDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/dpadpushbutton.cpp b/src/dpadpushbutton.cpp new file mode 100644 index 0000000..e78a1d7 --- /dev/null +++ b/src/dpadpushbutton.cpp @@ -0,0 +1,84 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "dpadpushbutton.h" +#include "dpadcontextmenu.h" + +DPadPushButton::DPadPushButton(JoyDPad *dpad, bool displayNames, QWidget *parent) : + FlashButtonWidget(displayNames, parent) +{ + this->dpad = dpad; + + refreshLabel(); + enableFlashes(); + + tryFlash(); + + this->setContextMenuPolicy(Qt::CustomContextMenu); + connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showContextMenu(const QPoint&))); + + connect(dpad, SIGNAL(dpadNameChanged()), this, SLOT(refreshLabel())); +} + +JoyDPad* DPadPushButton::getDPad() +{ + return dpad; +} + +QString DPadPushButton::generateLabel() +{ + QString temp; + if (!dpad->getDpadName().isEmpty()) + { + temp.append(dpad->getName(false, displayNames)); + } + else + { + temp.append(dpad->getName()); + } + + return temp; +} + +void DPadPushButton::disableFlashes() +{ + disconnect(dpad, SIGNAL(active(int)), this, SLOT(flash())); + disconnect(dpad, SIGNAL(released(int)), this, SLOT(unflash())); + this->unflash(); +} + +void DPadPushButton::enableFlashes() +{ + connect(dpad, SIGNAL(active(int)), this, SLOT(flash()), Qt::QueuedConnection); + connect(dpad, SIGNAL(released(int)), this, SLOT(unflash()), Qt::QueuedConnection); +} + +void DPadPushButton::showContextMenu(const QPoint &point) +{ + QPoint globalPos = this->mapToGlobal(point); + DPadContextMenu *contextMenu = new DPadContextMenu(dpad, this); + contextMenu->buildMenu(); + contextMenu->popup(globalPos); +} + +void DPadPushButton::tryFlash() +{ + if (dpad->getCurrentDirection() != static_cast(JoyDPadButton::DpadCentered)) + { + flash(); + } +} diff --git a/src/dpadpushbutton.h b/src/dpadpushbutton.h new file mode 100644 index 0000000..e3c9f7e --- /dev/null +++ b/src/dpadpushbutton.h @@ -0,0 +1,51 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef DPADPUSHBUTTON_H +#define DPADPUSHBUTTON_H + +#include + +#include "flashbuttonwidget.h" +#include "joydpad.h" + +class DPadPushButton : public FlashButtonWidget +{ + Q_OBJECT + +public: + explicit DPadPushButton(JoyDPad *dpad, bool displayNames, QWidget *parent = 0); + + JoyDPad* getDPad(); + void tryFlash(); + +protected: + QString generateLabel(); + + JoyDPad *dpad; + +signals: + +public slots: + void disableFlashes(); + void enableFlashes(); + +private slots: + void showContextMenu(const QPoint &point); +}; + +#endif // DPADPUSHBUTTON_H diff --git a/src/dpadpushbuttongroup.cpp b/src/dpadpushbuttongroup.cpp new file mode 100644 index 0000000..acad5e2 --- /dev/null +++ b/src/dpadpushbuttongroup.cpp @@ -0,0 +1,204 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "dpadpushbuttongroup.h" +#include "buttoneditdialog.h" +#include "dpadeditdialog.h" + +DPadPushButtonGroup::DPadPushButtonGroup(JoyDPad *dpad, bool displayNames, QWidget *parent) : + QGridLayout(parent) +{ + this->dpad = dpad; + this->displayNames = displayNames; + + generateButtons(); + changeButtonLayout(); + + connect(dpad, SIGNAL(joyModeChanged()), this, SLOT(changeButtonLayout())); +} + +void DPadPushButtonGroup::generateButtons() +{ + QHash *buttons = dpad->getJoyButtons(); + + JoyDPadButton *button = 0; + JoyDPadButtonWidget *pushbutton = 0; + + button = buttons->value(JoyDPadButton::DpadLeftUp); + upLeftButton = new JoyDPadButtonWidget(button, displayNames, parentWidget()); + pushbutton = upLeftButton; + connect(pushbutton, SIGNAL(clicked()), this, SLOT(openDPadButtonDialog())); + + button->establishPropertyUpdatedConnections(); + + connect(button, SIGNAL(slotsChanged()), this, SLOT(propogateSlotsChanged())); + + addWidget(pushbutton, 0, 0); + + + button = buttons->value(JoyDPadButton::DpadUp); + upButton = new JoyDPadButtonWidget(button, displayNames, parentWidget()); + pushbutton = upButton; + connect(pushbutton, SIGNAL(clicked()), this, SLOT(openDPadButtonDialog())); + button->establishPropertyUpdatedConnections(); + + connect(button, SIGNAL(slotsChanged()), this, SLOT(propogateSlotsChanged())); + + addWidget(pushbutton, 0, 1); + + button = buttons->value(JoyDPadButton::DpadRightUp); + upRightButton = new JoyDPadButtonWidget(button, displayNames, parentWidget()); + pushbutton = upRightButton; + connect(pushbutton, SIGNAL(clicked()), this, SLOT(openDPadButtonDialog())); + button->establishPropertyUpdatedConnections(); + + connect(button, SIGNAL(slotsChanged()), this, SLOT(propogateSlotsChanged())); + + addWidget(pushbutton, 0, 2); + + button = buttons->value(JoyDPadButton::DpadLeft); + leftButton = new JoyDPadButtonWidget(button, displayNames, parentWidget()); + pushbutton = leftButton; + connect(pushbutton, SIGNAL(clicked()), this, SLOT(openDPadButtonDialog())); + button->establishPropertyUpdatedConnections(); + + connect(button, SIGNAL(slotsChanged()), this, SLOT(propogateSlotsChanged())); + + addWidget(pushbutton, 1, 0); + + dpadWidget = new DPadPushButton(dpad, displayNames, parentWidget()); + dpadWidget->setIcon(QIcon::fromTheme(QString::fromUtf8("games-config-options"))); + connect(dpadWidget, SIGNAL(clicked()), this, SLOT(showDPadDialog())); + addWidget(dpadWidget, 1, 1); + + button = buttons->value(JoyDPadButton::DpadRight); + rightButton = new JoyDPadButtonWidget(button, displayNames, parentWidget()); + pushbutton = rightButton; + connect(pushbutton, SIGNAL(clicked()), this, SLOT(openDPadButtonDialog())); + button->establishPropertyUpdatedConnections(); + + connect(button, SIGNAL(slotsChanged()), this, SLOT(propogateSlotsChanged())); + + addWidget(pushbutton, 1, 2); + + button = buttons->value(JoyDPadButton::DpadLeftDown); + downLeftButton = new JoyDPadButtonWidget(button, displayNames, parentWidget()); + pushbutton = downLeftButton; + connect(pushbutton, SIGNAL(clicked()), this, SLOT(openDPadButtonDialog())); + button->establishPropertyUpdatedConnections(); + connect(button, SIGNAL(slotsChanged()), this, SLOT(propogateSlotsChanged())); + + addWidget(pushbutton, 2, 0); + + button = buttons->value(JoyDPadButton::DpadDown); + downButton = new JoyDPadButtonWidget(button, displayNames, parentWidget()); + pushbutton = downButton; + connect(pushbutton, SIGNAL(clicked()), this, SLOT(openDPadButtonDialog())); + button->establishPropertyUpdatedConnections(); + connect(button, SIGNAL(slotsChanged()), this, SLOT(propogateSlotsChanged())); + + addWidget(pushbutton, 2, 1); + + button = buttons->value(JoyDPadButton::DpadRightDown); + downRightButton = new JoyDPadButtonWidget(button, displayNames, parentWidget()); + pushbutton = downRightButton; + connect(pushbutton, SIGNAL(clicked()), this, SLOT(openDPadButtonDialog())); + button->establishPropertyUpdatedConnections(); + connect(button, SIGNAL(slotsChanged()), this, SLOT(propogateSlotsChanged())); + + addWidget(pushbutton, 2, 2); +} + +void DPadPushButtonGroup::changeButtonLayout() +{ + if (dpad->getJoyMode() == JoyDPad::StandardMode || + dpad->getJoyMode() == JoyDPad::EightWayMode || + dpad->getJoyMode() == JoyDPad::FourWayCardinal) + { + upButton->setVisible(true); + downButton->setVisible(true); + leftButton->setVisible(true); + rightButton->setVisible(true); + } + else + { + upButton->setVisible(false); + downButton->setVisible(false); + leftButton->setVisible(false); + rightButton->setVisible(false); + } + + if (dpad->getJoyMode() == JoyDPad::EightWayMode || + dpad->getJoyMode() == JoyDPad::FourWayDiagonal) + { + upLeftButton->setVisible(true); + upRightButton->setVisible(true); + downLeftButton->setVisible(true); + downRightButton->setVisible(true); + } + else + { + upLeftButton->setVisible(false); + upRightButton->setVisible(false); + downLeftButton->setVisible(false); + downRightButton->setVisible(false); + } +} + +void DPadPushButtonGroup::propogateSlotsChanged() +{ + emit buttonSlotChanged(); +} + +JoyDPad* DPadPushButtonGroup::getDPad() +{ + return dpad; +} + +void DPadPushButtonGroup::openDPadButtonDialog() +{ + JoyButtonWidget *buttonWidget = static_cast(sender()); + JoyButton *button = buttonWidget->getJoyButton(); + + ButtonEditDialog *dialog = new ButtonEditDialog(button, parentWidget()); + dialog->show(); +} + +void DPadPushButtonGroup::showDPadDialog() +{ + DPadEditDialog *dialog = new DPadEditDialog(dpad, parentWidget()); + dialog->show(); +} + +void DPadPushButtonGroup::toggleNameDisplay() +{ + displayNames = !displayNames; + + upButton->toggleNameDisplay(); + downButton->toggleNameDisplay(); + leftButton->toggleNameDisplay(); + rightButton->toggleNameDisplay(); + + upLeftButton->toggleNameDisplay(); + upRightButton->toggleNameDisplay(); + downLeftButton->toggleNameDisplay(); + downRightButton->toggleNameDisplay(); + + dpadWidget->toggleNameDisplay(); +} diff --git a/src/dpadpushbuttongroup.h b/src/dpadpushbuttongroup.h new file mode 100644 index 0000000..8f667dd --- /dev/null +++ b/src/dpadpushbuttongroup.h @@ -0,0 +1,66 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef DPADPUSHBUTTONGROUP_H +#define DPADPUSHBUTTONGROUP_H + +#include + +#include "joydpad.h" +#include "joydpadbuttonwidget.h" +#include "dpadpushbutton.h" + +class DPadPushButtonGroup : public QGridLayout +{ + Q_OBJECT +public: + explicit DPadPushButtonGroup(JoyDPad *dpad, bool displayNames = false, QWidget *parent = 0); + + JoyDPad *getDPad(); + +protected: + void generateButtons(); + + JoyDPad *dpad; + bool displayNames; + + JoyDPadButtonWidget *upButton; + JoyDPadButtonWidget *downButton; + JoyDPadButtonWidget *leftButton; + JoyDPadButtonWidget *rightButton; + + JoyDPadButtonWidget *upLeftButton; + JoyDPadButtonWidget *upRightButton; + JoyDPadButtonWidget *downLeftButton; + JoyDPadButtonWidget *downRightButton; + + DPadPushButton *dpadWidget; + +signals: + void buttonSlotChanged(); + +public slots: + void changeButtonLayout(); + void toggleNameDisplay(); + +private slots: + void propogateSlotsChanged(); + void openDPadButtonDialog(); + void showDPadDialog(); +}; + +#endif // DPADPUSHBUTTONGROUP_H diff --git a/src/editalldefaultautoprofiledialog.cpp b/src/editalldefaultautoprofiledialog.cpp new file mode 100644 index 0000000..257cc0e --- /dev/null +++ b/src/editalldefaultautoprofiledialog.cpp @@ -0,0 +1,99 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include "editalldefaultautoprofiledialog.h" +#include "ui_editalldefaultautoprofiledialog.h" +#include "common.h" + +EditAllDefaultAutoProfileDialog::EditAllDefaultAutoProfileDialog(AutoProfileInfo *info, AntiMicroSettings *settings, + QWidget *parent) : + QDialog(parent), + ui(new Ui::EditAllDefaultAutoProfileDialog) +{ + ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + + this->info = info; + this->settings = settings; + + if (!info->getProfileLocation().isEmpty()) + { + ui->profileLineEdit->setText(info->getProfileLocation()); + } + + connect(ui->profileBrowsePushButton, SIGNAL(clicked()), this, SLOT(openProfileBrowseDialog())); + connect(this, SIGNAL(accepted()), this, SLOT(saveAutoProfileInformation())); +} + +EditAllDefaultAutoProfileDialog::~EditAllDefaultAutoProfileDialog() +{ + delete ui; +} + +void EditAllDefaultAutoProfileDialog::openProfileBrowseDialog() +{ + QString lookupDir = PadderCommon::preferredProfileDir(settings); + QString filename = QFileDialog::getOpenFileName(this, tr("Open Config"), lookupDir, QString("Config Files (*.amgp *.xml)")); + if (!filename.isNull() && !filename.isEmpty()) + { + ui->profileLineEdit->setText(filename); + } +} + +void EditAllDefaultAutoProfileDialog::saveAutoProfileInformation() +{ + info->setGUID("all"); + info->setProfileLocation(ui->profileLineEdit->text()); + info->setActive(true); +} + +AutoProfileInfo* EditAllDefaultAutoProfileDialog::getAutoProfile() +{ + return info; +} + +void EditAllDefaultAutoProfileDialog::accept() +{ + bool validForm = true; + QString errorString; + if (ui->profileLineEdit->text().length() > 0) + { + QString profileFilename = ui->profileLineEdit->text(); + QFileInfo info(profileFilename); + if (!info.exists()) + { + validForm = false; + errorString = tr("Profile file path is invalid."); + } + } + + if (validForm) + { + QDialog::accept(); + } + else + { + QMessageBox msgBox; + msgBox.setText(errorString); + msgBox.setStandardButtons(QMessageBox::Close); + msgBox.exec(); + } +} diff --git a/src/editalldefaultautoprofiledialog.h b/src/editalldefaultautoprofiledialog.h new file mode 100644 index 0000000..77c46f3 --- /dev/null +++ b/src/editalldefaultautoprofiledialog.h @@ -0,0 +1,55 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef EDITALLDEFAULTAUTOPROFILEDIALOG_H +#define EDITALLDEFAULTAUTOPROFILEDIALOG_H + +#include + +#include "autoprofileinfo.h" +#include "antimicrosettings.h" + +namespace Ui { +class EditAllDefaultAutoProfileDialog; +} + +class EditAllDefaultAutoProfileDialog : public QDialog +{ + Q_OBJECT + +public: + explicit EditAllDefaultAutoProfileDialog(AutoProfileInfo *info, AntiMicroSettings *settings, + QWidget *parent = 0); + ~EditAllDefaultAutoProfileDialog(); + + AutoProfileInfo* getAutoProfile(); + +protected: + virtual void accept(); + + AutoProfileInfo *info; + AntiMicroSettings *settings; + +private: + Ui::EditAllDefaultAutoProfileDialog *ui; + +private slots: + void openProfileBrowseDialog(); + void saveAutoProfileInformation(); +}; + +#endif // EDITALLDEFAULTAUTOPROFILEDIALOG_H diff --git a/src/editalldefaultautoprofiledialog.ui b/src/editalldefaultautoprofiledialog.ui new file mode 100644 index 0000000..8c114f7 --- /dev/null +++ b/src/editalldefaultautoprofiledialog.ui @@ -0,0 +1,107 @@ + + + EditAllDefaultAutoProfileDialog + + + + 0 + 0 + 384 + 114 + + + + Default Profile + + + true + + + + + + Profile: + + + profileLineEdit + + + + + + + + + + + + Browse + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 10 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + EditAllDefaultAutoProfileDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + EditAllDefaultAutoProfileDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/event.cpp b/src/event.cpp new file mode 100644 index 0000000..8465276 --- /dev/null +++ b/src/event.cpp @@ -0,0 +1,640 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "event.h" +#include "eventhandlerfactory.h" +#include "joybutton.h" + +#if defined(Q_OS_UNIX) + + #if defined(WITH_X11) + +#include +#include +#include +#include "x11extras.h" + + #ifdef WITH_XTEST +#include + #endif + #endif + + #if defined(WITH_UINPUT) +#include "uinputhelper.h" + #endif + +#elif defined (Q_OS_WIN) +#include +#include "winextras.h" + +#endif + + +// Create the event used by the operating system. +void sendevent(JoyButtonSlot *slot, bool pressed) +{ + //int code = slot->getSlotCode(); + JoyButtonSlot::JoySlotInputAction device = slot->getSlotMode(); + + if (device == JoyButtonSlot::JoyKeyboard) + { + EventHandlerFactory::getInstance()->handler()->sendKeyboardEvent(slot, pressed); + } + else if (device == JoyButtonSlot::JoyMouseButton) + { + EventHandlerFactory::getInstance()->handler()->sendMouseButtonEvent(slot, pressed); + } + else if (device == JoyButtonSlot::JoyTextEntry && pressed && !slot->getTextData().isEmpty()) + { + EventHandlerFactory::getInstance()->handler()->sendTextEntryEvent(slot->getTextData()); + } + else if (device == JoyButtonSlot::JoyExecute && pressed && !slot->getTextData().isEmpty()) + { + QString execString = slot->getTextData(); + if (slot->getExtraData().canConvert()) + { + QString argumentsString = slot->getExtraData().toString(); + QStringList argumentsTempList(PadderCommon::parseArgumentsString(argumentsString)); + QProcess::startDetached(execString, argumentsTempList); + } + else + { + QProcess::startDetached(execString); + } + } +} + +void sendevent(int code1, int code2) +{ + EventHandlerFactory::getInstance()->handler()->sendMouseEvent(code1, code2); +} + +// TODO: Change to only use this routine when using a relative mouse +// pointer to fake absolute mouse moves. Otherwise, don't worry about +// current position of the mouse and just send an absolute mouse pointer +// event. +void sendSpringEvent(PadderCommon::springModeInfo *fullSpring, + PadderCommon::springModeInfo *relativeSpring, + int* const mousePosX, int* const mousePosY) +{ + PadderCommon::mouseHelperObj.mouseTimer.stop(); + + if ((fullSpring->displacementX >= -2.0 && fullSpring->displacementX <= 1.0 && + fullSpring->displacementY >= -2.0 && fullSpring->displacementY <= 1.0) || + (relativeSpring && (relativeSpring->displacementX >= -2.0 && relativeSpring->displacementX <= 1.0 && + relativeSpring->displacementY >= -2.0 && relativeSpring->displacementY <= 1.0))) + { + int xmovecoor = 0; + int ymovecoor = 0; + int width = 0; + int height = 0; + int midwidth = 0; + int midheight = 0; + int destSpringWidth = 0; + int destSpringHeight = 0; + int destMidWidth = 0; + int destMidHeight = 0; + int currentMouseX = 0; + int currentMouseY = 0; + + //QDesktopWidget deskWid; + if (fullSpring->screen >= PadderCommon::mouseHelperObj.getDesktopWidget()->screenCount()) + { + fullSpring->screen = -1; + } + + QRect deskRect = PadderCommon::mouseHelperObj.getDesktopWidget()->screenGeometry(fullSpring->screen); + width = deskRect.width(); + height = deskRect.height(); +#if defined(Q_OS_UNIX) && defined(WITH_X11) + QPoint currentPoint; + #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + if (QApplication::platformName() == QStringLiteral("xcb")) + { + #endif + currentPoint = X11Extras::getInstance()->getPos(); + #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + } + else + { + currentPoint = QCursor::pos(); + } + #endif +#else + QPoint currentPoint = QCursor::pos(); +#endif + currentMouseX = currentPoint.x(); + currentMouseY = currentPoint.y(); + + midwidth = width / 2; + midheight = height / 2; + + int springWidth = fullSpring->width; + int springHeight = fullSpring->height; + + if (springWidth >= 2 && springHeight >= 2) + { + destSpringWidth = qMin(springWidth, width); + destSpringHeight = qMin(springHeight, height); + } + else + { + destSpringWidth = width; + destSpringHeight = height; + } + + destMidWidth = destSpringWidth / 2; + destMidHeight = destSpringHeight / 2; + + unsigned int pivotX = currentMouseX; + unsigned int pivotY = currentMouseY; + if (relativeSpring) + { + if (PadderCommon::mouseHelperObj.pivotPoint[0] != -1) + { + pivotX = PadderCommon::mouseHelperObj.pivotPoint[0]; + } + else + { + pivotX = currentMouseX; + } + + if (PadderCommon::mouseHelperObj.pivotPoint[1] != -1) + { + pivotY = PadderCommon::mouseHelperObj.pivotPoint[1]; + } + else + { + pivotY = currentMouseY; + } + } + + xmovecoor = (fullSpring->displacementX >= -1.0) ? (midwidth + (fullSpring->displacementX * destMidWidth) + deskRect.x()): pivotX; + ymovecoor = (fullSpring->displacementY >= -1.0) ? (midheight + (fullSpring->displacementY * destMidHeight) + deskRect.y()) : pivotY; + + unsigned int fullSpringDestX = xmovecoor; + unsigned int fullSpringDestY = ymovecoor; + + unsigned int destRelativeWidth = 0; + unsigned int destRelativeHeight = 0; + if (relativeSpring && relativeSpring->width >= 2 && relativeSpring->height >= 2) + { + destRelativeWidth = relativeSpring->width; + destRelativeHeight = relativeSpring->height; + + int xRelativeMoovCoor = 0; + if (relativeSpring->displacementX >= -1.0) + { + xRelativeMoovCoor = (relativeSpring->displacementX * destRelativeWidth) / 2; + } + + int yRelativeMoovCoor = 0; + if (relativeSpring->displacementY >= -1.0) + { + yRelativeMoovCoor = (relativeSpring->displacementY * destRelativeHeight) / 2; + } + + xmovecoor += xRelativeMoovCoor; + ymovecoor += yRelativeMoovCoor; + } + + + if (mousePosX) + { + *mousePosX = xmovecoor; + } + + if (mousePosY) + { + *mousePosY = ymovecoor; + } + + if (xmovecoor != currentMouseX || ymovecoor != currentMouseY) + { + double diffx = abs(currentMouseX - xmovecoor); + double diffy = abs(currentMouseY - ymovecoor); + + // If either position is set to center, force update. + if (xmovecoor == (deskRect.x() + midwidth) || ymovecoor == (deskRect.y() + midheight)) + { +#if defined(Q_OS_UNIX) + BaseEventHandler *handler = EventHandlerFactory::getInstance()->handler(); + if (fullSpring->screen <= -1) + { + if (handler->getIdentifier() == "xtest") + { + EventHandlerFactory::getInstance()->handler()->sendMouseAbsEvent(xmovecoor, + ymovecoor); + } + else if (handler->getIdentifier() == "uinput") + { + EventHandlerFactory::getInstance()->handler() + ->sendMouseSpringEvent(xmovecoor, ymovecoor, width, height); + } + } + else + { + EventHandlerFactory::getInstance()->handler()->sendMouseEvent(xmovecoor - currentMouseX, + ymovecoor - currentMouseY); + } + +#elif defined(Q_OS_WIN) + if (fullSpring->screen <= -1) + { + EventHandlerFactory::getInstance()->handler() + ->sendMouseSpringEvent(xmovecoor, ymovecoor, width, height); + } + else + { + sendevent(xmovecoor - currentMouseX, ymovecoor - currentMouseY); + } +#endif + + } + else if (!PadderCommon::mouseHelperObj.springMouseMoving && relativeSpring && + (relativeSpring->displacementX >= -1.0 || relativeSpring->displacementY >= -1.0) && + (diffx >= destRelativeWidth*.013 || diffy >= destRelativeHeight*.013)) + { + PadderCommon::mouseHelperObj.springMouseMoving = true; +#if defined(Q_OS_UNIX) + BaseEventHandler *handler = EventHandlerFactory::getInstance()->handler(); + if (fullSpring->screen <= -1) + { + if (handler->getIdentifier() == "xtest") + { + EventHandlerFactory::getInstance()->handler()->sendMouseAbsEvent(xmovecoor, + ymovecoor); + } + else if (handler->getIdentifier() == "uinput") + { + EventHandlerFactory::getInstance()->handler() + ->sendMouseSpringEvent(xmovecoor, ymovecoor, width, height); + } + } + else + { + EventHandlerFactory::getInstance()->handler()->sendMouseEvent(xmovecoor - currentMouseX, + ymovecoor - currentMouseY); + } + +#elif defined(Q_OS_WIN) + if (fullSpring->screen <= -1) + { + EventHandlerFactory::getInstance()->handler() + ->sendMouseSpringEvent(xmovecoor, ymovecoor, width, height); + } + else + { + sendevent(xmovecoor - currentMouseX, ymovecoor - currentMouseY); + } +#endif + PadderCommon::mouseHelperObj.mouseTimer.start( + qMax(JoyButton::getMouseRefreshRate(), + JoyButton::getGamepadRefreshRate()) + 1); + } + else if (!PadderCommon::mouseHelperObj.springMouseMoving && (diffx >= destSpringWidth*.013 || diffy >= destSpringHeight*.013)) + { + PadderCommon::mouseHelperObj.springMouseMoving = true; +#if defined(Q_OS_UNIX) + + BaseEventHandler *handler = EventHandlerFactory::getInstance()->handler(); + if (fullSpring->screen <= -1) + { + if (handler->getIdentifier() == "xtest") + { + EventHandlerFactory::getInstance()->handler()->sendMouseAbsEvent(xmovecoor, + ymovecoor); + } + else if (handler->getIdentifier() == "uinput") + { + EventHandlerFactory::getInstance()->handler() + ->sendMouseSpringEvent(xmovecoor, ymovecoor, width, height); + } + } + else + { + EventHandlerFactory::getInstance()->handler()->sendMouseEvent(xmovecoor - currentMouseX, + ymovecoor - currentMouseY); + } + + +#elif defined(Q_OS_WIN) + if (fullSpring->screen <= -1) + { + EventHandlerFactory::getInstance()->handler() + ->sendMouseSpringEvent(xmovecoor, ymovecoor, width, height); + } + else + { + sendevent(xmovecoor - currentMouseX, ymovecoor - currentMouseY); + } +#endif + + PadderCommon::mouseHelperObj.mouseTimer.start( + qMax(JoyButton::getMouseRefreshRate(), + JoyButton::getGamepadRefreshRate()) + 1); + } + + else if (PadderCommon::mouseHelperObj.springMouseMoving && (diffx < 2 && diffy < 2)) + { + PadderCommon::mouseHelperObj.springMouseMoving = false; + } + + else if (PadderCommon::mouseHelperObj.springMouseMoving) + { +#if defined(Q_OS_UNIX) + BaseEventHandler *handler = EventHandlerFactory::getInstance()->handler(); + if (fullSpring->screen <= -1) + { + if (handler->getIdentifier() == "xtest") + { + EventHandlerFactory::getInstance()->handler()->sendMouseAbsEvent(xmovecoor, + ymovecoor); + } + else if (handler->getIdentifier() == "uinput") + { + EventHandlerFactory::getInstance()->handler() + ->sendMouseSpringEvent(xmovecoor, ymovecoor, width, height); + } + } + else + { + EventHandlerFactory::getInstance()->handler()->sendMouseEvent(xmovecoor - currentMouseX, + ymovecoor - currentMouseY); + } + +#elif defined(Q_OS_WIN) + if (fullSpring->screen <= -1) + { + EventHandlerFactory::getInstance()->handler() + ->sendMouseSpringEvent(xmovecoor, ymovecoor, width, height); + } + else + { + sendevent(xmovecoor - currentMouseX, ymovecoor - currentMouseY); + } +#endif + + PadderCommon::mouseHelperObj.mouseTimer.start( + qMax(JoyButton::getMouseRefreshRate(), + JoyButton::getGamepadRefreshRate()) + 1); + } + + + PadderCommon::mouseHelperObj.previousCursorLocation[0] = currentMouseX; + PadderCommon::mouseHelperObj.previousCursorLocation[1] = currentMouseY; + PadderCommon::mouseHelperObj.pivotPoint[0] = fullSpringDestX; + PadderCommon::mouseHelperObj.pivotPoint[1] = fullSpringDestY; + } + else if (PadderCommon::mouseHelperObj.previousCursorLocation[0] == xmovecoor && + PadderCommon::mouseHelperObj.previousCursorLocation[1] == ymovecoor) + { + PadderCommon::mouseHelperObj.springMouseMoving = false; + } + else + { + PadderCommon::mouseHelperObj.previousCursorLocation[0] = currentMouseX; + PadderCommon::mouseHelperObj.previousCursorLocation[1] = currentMouseY; + PadderCommon::mouseHelperObj.pivotPoint[0] = fullSpringDestX; + PadderCommon::mouseHelperObj.pivotPoint[1] = fullSpringDestY; + + PadderCommon::mouseHelperObj.mouseTimer.start( + qMax(JoyButton::getMouseRefreshRate(), + JoyButton::getGamepadRefreshRate()) + 1); + } + } + else + { + PadderCommon::mouseHelperObj.springMouseMoving = false; + PadderCommon::mouseHelperObj.pivotPoint[0] = -1; + PadderCommon::mouseHelperObj.pivotPoint[1] = -1; + } +} + +int X11KeySymToKeycode(QString key) +{ + int tempcode = 0; +#if defined (Q_OS_UNIX) + + BaseEventHandler *handler = EventHandlerFactory::getInstance()->handler(); + + if (key.length() > 0) + { +#ifdef WITH_XTEST + if (handler->getIdentifier() == "xtest") + { + Display* display = X11Extras::getInstance()->display(); + tempcode = XKeysymToKeycode(display, XStringToKeysym(key.toUtf8().data())); + } +#endif + +#ifdef WITH_UINPUT + if (handler->getIdentifier() == "uinput") + { + tempcode = UInputHelper::getInstance()->getVirtualKey(key); + } +#endif + } + +#elif defined (Q_OS_WIN) + if (key.length() > 0) + { + tempcode = WinExtras::getVirtualKey(key); + if (tempcode <= 0 && key.length() == 1) + { + //qDebug() << "KEY: " << key; + //int oridnal = key.toUtf8().constData()[0]; + int ordinal = QVariant(key.toUtf8().constData()[0]).toInt(); + tempcode = VkKeyScan(ordinal); + int modifiers = tempcode >> 8; + tempcode = tempcode & 0xff; + if ((modifiers & 1) != 0) tempcode |= VK_SHIFT; + if ((modifiers & 2) != 0) tempcode |= VK_CONTROL; + if ((modifiers & 4) != 0) tempcode |= VK_MENU; + //tempcode = VkKeyScan(QVariant(key.constData()).toInt()); + //tempcode = OemKeyScan(key.toUtf8().toInt()); + //tempcode = OemKeyScan(ordinal); + } + } + +#endif + + return tempcode; +} + +QString keycodeToKeyString(int keycode, unsigned int alias) +{ + QString newkey; + +#if defined (Q_OS_UNIX) + Q_UNUSED(alias); + + if (keycode <= 0) + { + newkey = "[NO KEY]"; + } + else + { + BaseEventHandler *handler = EventHandlerFactory::getInstance()->handler(); + +#ifdef WITH_XTEST + if (handler->getIdentifier() == "xtest") + { + Display* display = X11Extras::getInstance()->display(); + newkey = QString("0x%1").arg(keycode, 0, 16); + QString tempkey = XKeysymToString(XkbKeycodeToKeysym(display, keycode, 0, 0)); + QString tempalias = X11Extras::getInstance()->getDisplayString(tempkey); + if (!tempalias.isEmpty()) + { + newkey = tempalias; + } + else + { + XKeyPressedEvent tempevent; + tempevent.keycode = keycode; + tempevent.type = KeyPress; + tempevent.display = display; + tempevent.state = 0; + + char tempstring[256]; + memset(tempstring, 0, sizeof(tempstring)); + int bitestoreturn = sizeof(tempstring) - 1; + int numchars = XLookupString(&tempevent, tempstring, bitestoreturn, NULL, NULL); + if (numchars > 0) + { + tempstring[numchars] = '\0'; + newkey = QString::fromUtf8(tempstring); + //qDebug() << "NEWKEY:" << newkey << endl; + //qDebug() << "NEWKEY LEGNTH:" << numchars << endl; + } + else + { + newkey = tempkey; + } + } + } +#endif + +#ifdef WITH_UINPUT + if (handler->getIdentifier() == "uinput") + { + QString tempalias = UInputHelper::getInstance()->getDisplayString(keycode); + if (!tempalias.isEmpty()) + { + newkey = tempalias; + } + else + { + newkey = QString("0x%1").arg(keycode, 0, 16); + } + } +#endif + } + +#elif defined (Q_OS_WIN) + wchar_t buffer[50] = {0}; + + QString tempalias = WinExtras::getDisplayString(keycode); + if (!tempalias.isEmpty()) + { + newkey = tempalias; + } + else + { + int scancode = WinExtras::scancodeFromVirtualKey(keycode, alias); + + if (keycode >= VK_BROWSER_BACK && keycode <= VK_LAUNCH_APP2) + { + newkey.append(QString("0x%1").arg(keycode, 0, 16)); + } + else + { + int length = GetKeyNameTextW(scancode << 16, buffer, sizeof(buffer)); + if (length > 0) + { + newkey = QString::fromWCharArray(buffer); + } + else + { + newkey.append(QString("0x%1").arg(keycode, 0, 16)); + } + } + } + +#endif + + return newkey; +} + +unsigned int X11KeyCodeToX11KeySym(unsigned int keycode) +{ +#ifdef Q_OS_WIN + Q_UNUSED(keycode); + return 0; +#else + #ifdef WITH_X11 + Display* display = X11Extras::getInstance()->display(); + unsigned int tempcode = XkbKeycodeToKeysym(display, keycode, 0, 0); + return tempcode; + #else + + Q_UNUSED(keycode); + return 0; + #endif +#endif +} + +QString keysymToKeyString(int keysym, unsigned int alias) +{ + QString newkey; + +#if defined (Q_OS_UNIX) + Q_UNUSED(alias); + + BaseEventHandler *handler = EventHandlerFactory::getInstance()->handler(); + + if (handler->getIdentifier() == "xtest") + { + Display* display = X11Extras::getInstance()->display(); + unsigned int keycode = 0; + if (keysym > 0) + { + keycode = XKeysymToKeycode(display, keysym); + } + newkey = keycodeToKeyString(keycode); + } + else if (handler->getIdentifier() == "uinput") + { + newkey = keycodeToKeyString(keysym); + } + +#else + newkey = keycodeToKeyString(keysym, alias); +#endif + return newkey; +} diff --git a/src/event.h b/src/event.h new file mode 100644 index 0000000..e4edcb4 --- /dev/null +++ b/src/event.h @@ -0,0 +1,37 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef EVENT_H +#define EVENT_H + +#include + +#include "joybuttonslot.h" +//#include "mousehelper.h" +#include "springmousemoveinfo.h" +#include "common.h" + +void sendevent (JoyButtonSlot *slot, bool pressed=true); +void sendevent(int code1, int code2); +void sendSpringEvent(PadderCommon::springModeInfo *fullSpring, PadderCommon::springModeInfo *relativeSpring=0, int* const mousePosX=0, int* const mousePos=0); +//void sendSpringEvent(double xcoor, double ycoor, int springWidth=0, int springHeight=0); +int X11KeySymToKeycode(QString key); +QString keycodeToKeyString(int keycode, unsigned int alias=0); +unsigned int X11KeyCodeToX11KeySym(unsigned int keycode); +QString keysymToKeyString(int keysym, unsigned int alias=0); + +#endif // EVENT_H diff --git a/src/eventhandlerfactory.cpp b/src/eventhandlerfactory.cpp new file mode 100644 index 0000000..b0232be --- /dev/null +++ b/src/eventhandlerfactory.cpp @@ -0,0 +1,156 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "eventhandlerfactory.h" + +static QHash buildDisplayNames() +{ + QHash temp; +#ifdef Q_OS_WIN + temp.insert("sendinput", "SendInput"); + #ifdef WITH_VMULTI + temp.insert("vmulti", "Vmulti"); + #endif +#else + temp.insert("xtest", "Xtest"); + temp.insert("uinput", "uinput"); +#endif + return temp; +} + +QHash handlerDisplayNames = buildDisplayNames(); + +EventHandlerFactory* EventHandlerFactory::instance = 0; + +EventHandlerFactory::EventHandlerFactory(QString handler, QObject *parent) : + QObject(parent) +{ +#ifdef Q_OS_UNIX + #ifdef WITH_UINPUT + if (handler == "uinput") + { + eventHandler = new UInputEventHandler(this); + } + #endif + + #ifdef WITH_XTEST + if (handler == "xtest") + { + eventHandler = new XTestEventHandler(this); + } + #endif +#elif defined(Q_OS_WIN) + if (handler == "sendinput") + { + eventHandler = new WinSendInputEventHandler(this); + } + #ifdef WITH_VMULTI + else if (handler == "vmulti") + { + eventHandler = new WinVMultiEventHandler(this); + } + #endif +#endif +} + +EventHandlerFactory::~EventHandlerFactory() +{ + if (eventHandler) + { + delete eventHandler; + eventHandler = 0; + } +} + +EventHandlerFactory* EventHandlerFactory::getInstance(QString handler) +{ + if (!instance) + { + QStringList temp = buildEventGeneratorList(); + if (!handler.isEmpty() && temp.contains(handler)) + { + instance = new EventHandlerFactory(handler); + } + else + { + instance = new EventHandlerFactory(fallBackIdentifier()); + } + } + + return instance; +} + +void EventHandlerFactory::deleteInstance() +{ + if (instance) + { + delete instance; + instance = 0; + } +} + +BaseEventHandler* EventHandlerFactory::handler() +{ + return eventHandler; +} + +QString EventHandlerFactory::fallBackIdentifier() +{ + QString temp; +#ifdef Q_OS_UNIX + #if defined(WITH_XTEST) + temp = "xtest"; + #elif defined(WITH_UINPUT) + temp = "uinput"; + #else + temp = "xtest"; + #endif +#elif defined(Q_OS_WIN) + temp = "sendinput"; +#endif + + return temp; +} + +QStringList EventHandlerFactory::buildEventGeneratorList() +{ + QStringList temp; + +#ifdef Q_OS_WIN + temp.append("sendinput"); + #ifdef WITH_VMULTI + temp.append("vmulti"); + #endif +#else + temp.append("xtest"); + temp.append("uinput"); +#endif + return temp; +} + +QString EventHandlerFactory::handlerDisplayName(QString handler) +{ + QString temp; + if (handlerDisplayNames.contains(handler)) + { + temp = handlerDisplayNames.value(handler); + } + + return temp; +} diff --git a/src/eventhandlerfactory.h b/src/eventhandlerfactory.h new file mode 100644 index 0000000..69f7a07 --- /dev/null +++ b/src/eventhandlerfactory.h @@ -0,0 +1,95 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef EVENTHANDLERFACTORY_H +#define EVENTHANDLERFACTORY_H + +#include +#include + +#ifdef Q_OS_UNIX + #ifdef WITH_UINPUT + #include "eventhandlers/uinputeventhandler.h" + #endif + + #ifdef WITH_XTEST + #include "eventhandlers/xtesteventhandler.h" + #endif +#elif defined(Q_OS_WIN) + #include "eventhandlers/winsendinputeventhandler.h" + + #ifdef WITH_VMULTI + #include "eventhandlers/winvmultieventhandler.h" + #endif +#endif + +#ifdef Q_OS_WIN + #define ADD_SENDINPUT 1 + #ifdef WITH_VMULTI + #define ADD_VMULTI 1 + #else + #define ADD_VMULTI 0 + #endif + + #define NUM_BACKENDS (ADD_SENDINPUT + ADD_VMULTI) +#else + #ifdef WITH_XTEST + #define ADD_XTEST 1 + #else + #define ADD_XTEST 0 + #endif + + #ifdef WITH_UINPUT + #define ADD_UINPUT 1 + #else + #define ADD_UINPUT 0 + #endif + + #define NUM_BACKENDS (ADD_XTEST + ADD_UINPUT) +#endif + +#if (NUM_BACKENDS > 1) + #define BACKEND_ELSE_IF else if +#else + #define BACKEND_ELSE_IF if +#endif + +class EventHandlerFactory : public QObject +{ + Q_OBJECT +public: + static EventHandlerFactory* getInstance(QString handler = ""); + void deleteInstance(); + BaseEventHandler* handler(); + static QString fallBackIdentifier(); + static QStringList buildEventGeneratorList(); + static QString handlerDisplayName(QString handler); + +protected: + explicit EventHandlerFactory(QString handler, QObject *parent = 0); + ~EventHandlerFactory(); + + BaseEventHandler *eventHandler; + static EventHandlerFactory *instance; + +signals: + +public slots: + +}; + +#endif // EVENTHANDLERFACTORY_H diff --git a/src/eventhandlers/baseeventhandler.cpp b/src/eventhandlers/baseeventhandler.cpp new file mode 100644 index 0000000..a028ebb --- /dev/null +++ b/src/eventhandlers/baseeventhandler.cpp @@ -0,0 +1,68 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "baseeventhandler.h" + +BaseEventHandler::BaseEventHandler(QObject *parent) : + QObject(parent) +{ +} + +QString BaseEventHandler::getErrorString() +{ + return lastErrorString; +} + +/** + * @brief Do nothing by default. Allow child classes to specify text to output + * to a text stream. + */ +void BaseEventHandler::printPostMessages() +{ +} + +/** + * @brief Do nothing by default. Useful for child classes to define behavior. + * @param Displacement of X coordinate + * @param Displacement of Y coordinate + */ +void BaseEventHandler::sendMouseAbsEvent(int xDis, int yDis) +{ + Q_UNUSED(xDis); + Q_UNUSED(yDis); +} + +/** + * @brief Do nothing by default. Useful for child classes to define behavior. + * @param Displacement of X coordinate + * @param Displacement of Y coordinate + * @param Bounding box width + * @param Bounding box height + */ +void BaseEventHandler::sendMouseSpringEvent(unsigned int xDis, unsigned int yDis, + unsigned int width, unsigned int height) +{ + Q_UNUSED(xDis); + Q_UNUSED(yDis); + Q_UNUSED(width); + Q_UNUSED(height); +} + +void BaseEventHandler::sendTextEntryEvent(QString maintext) +{ + +} diff --git a/src/eventhandlers/baseeventhandler.h b/src/eventhandlers/baseeventhandler.h new file mode 100644 index 0000000..4f46a25 --- /dev/null +++ b/src/eventhandlers/baseeventhandler.h @@ -0,0 +1,56 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef BASEEVENTHANDLER_H +#define BASEEVENTHANDLER_H + +#include +#include + +#include +#include + +class BaseEventHandler : public QObject +{ + Q_OBJECT +public: + explicit BaseEventHandler(QObject *parent = 0); + + virtual bool init() = 0; + virtual bool cleanup() = 0; + virtual void sendKeyboardEvent(JoyButtonSlot *slot, bool pressed) = 0; + virtual void sendMouseButtonEvent(JoyButtonSlot *slot, bool pressed) = 0; + virtual void sendMouseEvent(int xDis, int yDis) = 0; + virtual QString getName() = 0; + virtual QString getIdentifier() = 0; + virtual void printPostMessages(); + QString getErrorString(); + virtual void sendMouseAbsEvent(int xDis, int yDis); + virtual void sendMouseSpringEvent(unsigned int xDis, unsigned int yDis, + unsigned int width, unsigned int height); + virtual void sendTextEntryEvent(QString maintext); + +protected: + QString lastErrorString; + +signals: + +public slots: + +}; + +#endif // BASEEVENTHANDLER_H diff --git a/src/eventhandlers/uinputeventhandler.cpp b/src/eventhandlers/uinputeventhandler.cpp new file mode 100644 index 0000000..86132e0 --- /dev/null +++ b/src/eventhandlers/uinputeventhandler.cpp @@ -0,0 +1,584 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include + +//#include +#include +#include +#include +#include +#include +#include +#include + +static const QString mouseDeviceName = PadderCommon::mouseDeviceName; +static const QString keyboardDeviceName = PadderCommon::keyboardDeviceName; +static const QString springMouseDeviceName = PadderCommon::springMouseDeviceName; + +#ifdef WITH_X11 + #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + #include + #endif + + #include +#endif + +#include "uinputeventhandler.h" + +UInputEventHandler::UInputEventHandler(QObject *parent) : + BaseEventHandler(parent) +{ + keyboardFileHandler = 0; + mouseFileHandler = 0; + springMouseFileHandler = 0; +} + +UInputEventHandler::~UInputEventHandler() +{ + cleanup(); +} + +/** + * @brief Initialize keyboard and mouse virtual devices. Each device will + * use its own file handle with various codes set to distinquish the two + * devices. + * @return + */ +bool UInputEventHandler::init() +{ + bool result = true; + + // Open file handle for keyboard emulation. + keyboardFileHandler = openUInputHandle(); + if (keyboardFileHandler > 0) + { + setKeyboardEvents(keyboardFileHandler); + populateKeyCodes(keyboardFileHandler); + createUInputKeyboardDevice(keyboardFileHandler); + } + else + { + result = false; + } + + if (result) + { + // Open mouse file handle to use for relative mouse emulation. + mouseFileHandler = openUInputHandle(); + if (mouseFileHandler > 0) + { + setRelMouseEvents(mouseFileHandler); + createUInputMouseDevice(mouseFileHandler); + } + else + { + result = false; + } + } + + if (result) + { + // Open mouse file handle to use for absolute mouse emulation. + springMouseFileHandler = openUInputHandle(); + if (springMouseFileHandler > 0) + { + setSpringMouseEvents(springMouseFileHandler); + createUInputSpringMouseDevice(springMouseFileHandler); + } + else + { + result = false; + } + } + +#ifdef WITH_X11 + if (result) + { + #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + + if (QApplication::platformName() == QStringLiteral("xcb")) + { + #endif + // Some time needs to elapse after device creation before changing + // pointer settings. Otherwise, settings will not take effect. + QTimer::singleShot(2000, this, SLOT(x11ResetMouseAccelerationChange())); + #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + } + #endif + } +#endif + + return result; +} + +#ifdef WITH_X11 +void UInputEventHandler::x11ResetMouseAccelerationChange() +{ + if (X11Extras::getInstance()) + { + X11Extras::getInstance()->x11ResetMouseAccelerationChange(); + } +} +#endif + +bool UInputEventHandler::cleanup() +{ + if (keyboardFileHandler > 0) + { + closeUInputDevice(keyboardFileHandler); + keyboardFileHandler = 0; + } + + if (mouseFileHandler > 0) + { + closeUInputDevice(mouseFileHandler); + mouseFileHandler = 0; + } + + if (springMouseFileHandler > 0) + { + closeUInputDevice(springMouseFileHandler); + springMouseFileHandler = 0; + } + + return true; +} + +void UInputEventHandler::sendKeyboardEvent(JoyButtonSlot *slot, bool pressed) +{ + JoyButtonSlot::JoySlotInputAction device = slot->getSlotMode(); + int code = slot->getSlotCode(); + + if (device == JoyButtonSlot::JoyKeyboard) + { + write_uinput_event(keyboardFileHandler, EV_KEY, code, pressed ? 1 : 0); + } +} + +void UInputEventHandler::sendMouseButtonEvent(JoyButtonSlot *slot, bool pressed) +{ + JoyButtonSlot::JoySlotInputAction device = slot->getSlotMode(); + int code = slot->getSlotCode(); + + if (device == JoyButtonSlot::JoyMouseButton) + { + if (code <= 3) + { + unsigned int tempcode = BTN_LEFT; + switch (code) + { + case 3: + { + tempcode = BTN_RIGHT; + break; + } + case 2: + { + tempcode = BTN_MIDDLE; + break; + } + case 1: + default: + { + tempcode = BTN_LEFT; + } + } + + write_uinput_event(mouseFileHandler, EV_KEY, tempcode, pressed ? 1 : 0); + } + else if (code == 4) + { + if (pressed) + { + write_uinput_event(mouseFileHandler, EV_REL, REL_WHEEL, 1); + } + + } + else if (code == 5) + { + if (pressed) + { + write_uinput_event(mouseFileHandler, EV_REL, REL_WHEEL, -1); + } + } + else if (code == 6) + { + if (pressed) + { + write_uinput_event(mouseFileHandler, EV_REL, REL_HWHEEL, 1); + } + } + else if (code == 7) + { + if (pressed) + { + write_uinput_event(mouseFileHandler, EV_REL, REL_HWHEEL, -1); + } + } + else if (code == 8) + { + write_uinput_event(mouseFileHandler, EV_KEY, BTN_SIDE, pressed ? 1 : 0); + } + else if (code == 9) + { + write_uinput_event(mouseFileHandler, EV_KEY, BTN_EXTRA, pressed ? 1 : 0); + } + } +} + +void UInputEventHandler::sendMouseEvent(int xDis, int yDis) +{ + write_uinput_event(mouseFileHandler, EV_REL, REL_X, xDis, false); + write_uinput_event(mouseFileHandler, EV_REL, REL_Y, yDis); +} + +void UInputEventHandler::sendMouseSpringEvent(unsigned int xDis, unsigned int yDis, + unsigned int width, unsigned int height) +{ + if (width > 0 && height > 0) + { + double midwidth = static_cast(width) / 2.0; + double midheight = static_cast(height) / 2.0; + + int fx = ceil(32767 * ((xDis - midwidth) / midwidth)); + int fy = ceil(32767 * ((yDis - midheight) / midheight)); + + write_uinput_event(springMouseFileHandler, EV_ABS, ABS_X, fx, false); + write_uinput_event(springMouseFileHandler, EV_ABS, ABS_Y, fy); + } +} + +int UInputEventHandler::openUInputHandle() +{ + int filehandle = -1; + + QStringList locations; + locations.append("/dev/input/uinput"); + locations.append("/dev/uinput"); + locations.append("/dev/misc/uinput"); + + QString possibleLocation; + QStringListIterator iter(locations); + while (iter.hasNext()) + { + QString temp = iter.next(); + QFileInfo tempFileInfo(temp); + if (tempFileInfo.exists()) + { + possibleLocation = temp; + iter.toBack(); + } + } + + if (possibleLocation.isEmpty()) + { + lastErrorString = tr("Could not find a valid uinput device file.\n" + "Please check that you have the uinput module loaded.\n" + "lsmod | grep uinput"); + } + else + { + QByteArray tempArray = possibleLocation.toUtf8(); + filehandle = open(tempArray.constData(), O_WRONLY | O_NONBLOCK); + if (filehandle < 0) + { + lastErrorString = tr("Could not open uinput device file\n" + "Please check that you have permission to write to the device"); + lastErrorString.append("\n").append(possibleLocation); + } + else + { + uinputDeviceLocation = possibleLocation; + } + } + + return filehandle; +} + + +void UInputEventHandler::setKeyboardEvents(int filehandle) +{ + int result = 0; + result = ioctl(filehandle, UI_SET_EVBIT, EV_KEY); + result = ioctl(filehandle, UI_SET_EVBIT, EV_SYN); +} + +void UInputEventHandler::setRelMouseEvents(int filehandle) +{ + int result = 0; + result = ioctl(filehandle, UI_SET_EVBIT, EV_KEY); + result = ioctl(filehandle, UI_SET_EVBIT, EV_SYN); + result = ioctl(filehandle, UI_SET_EVBIT, EV_REL); + + result = ioctl(filehandle, UI_SET_RELBIT, REL_X); + result = ioctl(filehandle, UI_SET_RELBIT, REL_Y); + result = ioctl(filehandle, UI_SET_RELBIT, REL_WHEEL); + result = ioctl(filehandle, UI_SET_RELBIT, REL_HWHEEL); + + result = ioctl(filehandle, UI_SET_KEYBIT, BTN_LEFT); + result = ioctl(filehandle, UI_SET_KEYBIT, BTN_RIGHT); + result = ioctl(filehandle, UI_SET_KEYBIT, BTN_MIDDLE); + result = ioctl(filehandle, UI_SET_KEYBIT, BTN_SIDE); + result = ioctl(filehandle, UI_SET_KEYBIT, BTN_EXTRA); +} + +void UInputEventHandler::setSpringMouseEvents(int filehandle) +{ + int result = 0; + result = ioctl(filehandle, UI_SET_EVBIT, EV_KEY); + result = ioctl(filehandle, UI_SET_EVBIT, EV_SYN); + + result = ioctl(filehandle, UI_SET_KEYBIT, BTN_LEFT); + result = ioctl(filehandle, UI_SET_KEYBIT, BTN_RIGHT); + result = ioctl(filehandle, UI_SET_KEYBIT, BTN_MIDDLE); + result = ioctl(filehandle, UI_SET_KEYBIT, BTN_SIDE); + result = ioctl(filehandle, UI_SET_KEYBIT, BTN_EXTRA); + + result = ioctl(filehandle, UI_SET_EVBIT, EV_ABS); + result = ioctl(filehandle, UI_SET_ABSBIT, ABS_X); + result = ioctl(filehandle, UI_SET_ABSBIT, ABS_Y); + result = ioctl(filehandle, UI_SET_KEYBIT, BTN_TOUCH); + // BTN_TOOL_PEN is required for the mouse to be seen as an + // absolute mouse as opposed to a relative mouse. + result = ioctl(filehandle, UI_SET_KEYBIT, BTN_TOOL_PEN); +} + +void UInputEventHandler::populateKeyCodes(int filehandle) +{ + int result = 0; + for (unsigned int i=KEY_ESC; i <= KEY_MICMUTE; i++) + { + result = ioctl(filehandle, UI_SET_KEYBIT, i); + } +} + +void UInputEventHandler::createUInputKeyboardDevice(int filehandle) +{ + struct uinput_user_dev uidev; + + memset(&uidev, 0, sizeof(uidev)); + QByteArray temp = keyboardDeviceName.toUtf8(); + strncpy(uidev.name, temp.constData(), UINPUT_MAX_NAME_SIZE); + uidev.id.bustype = BUS_USB; + uidev.id.vendor = 0x0; + uidev.id.product = 0x0; + uidev.id.version = 1; + + int result = 0; + result = write(filehandle, &uidev, sizeof(uidev)); + result = ioctl(filehandle, UI_DEV_CREATE); +} + +void UInputEventHandler::createUInputMouseDevice(int filehandle) +{ + struct uinput_user_dev uidev; + + memset(&uidev, 0, sizeof(uidev)); + QByteArray temp = mouseDeviceName.toUtf8(); + strncpy(uidev.name, temp.constData(), UINPUT_MAX_NAME_SIZE); + uidev.id.bustype = BUS_USB; + uidev.id.vendor = 0x0; + uidev.id.product = 0x0; + uidev.id.version = 1; + + int result = 0; + result = write(filehandle, &uidev, sizeof(uidev)); + result = ioctl(filehandle, UI_DEV_CREATE); +} + +void UInputEventHandler::createUInputSpringMouseDevice(int filehandle) +{ + struct uinput_user_dev uidev; + + memset(&uidev, 0, sizeof(uidev)); + QByteArray temp = springMouseDeviceName.toUtf8(); + strncpy(uidev.name, temp.constData(), UINPUT_MAX_NAME_SIZE); + uidev.id.bustype = BUS_USB; + uidev.id.vendor = 0x0; + uidev.id.product = 0x0; + uidev.id.version = 1; + + uidev.absmin[ABS_X] = -32767; + uidev.absmax[ABS_X] = 32767; + uidev.absflat[ABS_X] = 0; + + uidev.absmin[ABS_Y] = -32767; + uidev.absmax[ABS_Y] = 32767; + uidev.absflat[ABS_Y] = 0; + + int result = 0; + result = write(filehandle, &uidev, sizeof(uidev)); + result = ioctl(filehandle, UI_DEV_CREATE); +} + +void UInputEventHandler::closeUInputDevice(int filehandle) +{ + int result = 0; + result = ioctl(filehandle, UI_DEV_DESTROY); + result = close(filehandle); +} + + +void UInputEventHandler::write_uinput_event(int filehandle, unsigned int type, + unsigned int code, int value, bool syn) +{ + struct input_event ev; + struct input_event ev2; + + memset(&ev, 0, sizeof(struct input_event)); + gettimeofday(&ev.time, 0); + ev.type = type; + ev.code = code; + ev.value = value; + + int result = 0; + result = write(filehandle, &ev, sizeof(struct input_event)); + + if (syn) + { + memset(&ev2, 0, sizeof(struct input_event)); + gettimeofday(&ev2.time, 0); + ev2.type = EV_SYN; + ev2.code = SYN_REPORT; + ev2.value = 0; + + result = write(filehandle, &ev2, sizeof(struct input_event)); + } +} + +QString UInputEventHandler::getName() +{ + return QString("uinput"); +} + +QString UInputEventHandler::getIdentifier() +{ + return getName(); +} + +/** + * @brief Print extra help messages to stdout. + */ +void UInputEventHandler::printPostMessages() +{ + //QTextStream out(stdout); + + if (!lastErrorString.isEmpty()) + { + Logger::LogInfo(lastErrorString); + } + + if (!uinputDeviceLocation.isEmpty()) + { + Logger::LogInfo(tr("Using uinput device file %1").arg(uinputDeviceLocation)); + } +} + +void UInputEventHandler::sendTextEntryEvent(QString maintext) +{ + AntKeyMapper *mapper = AntKeyMapper::getInstance(); + + if (mapper && mapper->getKeyMapper()) + { + QtUInputKeyMapper *keymapper = static_cast(mapper->getKeyMapper()); + QtX11KeyMapper *nativeWinKeyMapper = 0; + if (mapper->getNativeKeyMapper()) + { + nativeWinKeyMapper = static_cast(mapper->getNativeKeyMapper()); + } + + QList tempList; + for (int i=0; i < maintext.size(); i++) + { + tempList.clear(); + + QtUInputKeyMapper::charKeyInformation temp; + temp.virtualkey = 0; + temp.modifiers = Qt::NoModifier; + + if (nativeWinKeyMapper) + { + QtX11KeyMapper::charKeyInformation tempX11 = nativeWinKeyMapper->getCharKeyInformation(maintext.at(i)); + tempX11.virtualkey = X11Extras::getInstance()->getGroup1KeySym(tempX11.virtualkey); + unsigned int tempQtKey = nativeWinKeyMapper->returnQtKey(tempX11.virtualkey); + if (tempQtKey > 0) + { + temp.virtualkey = keymapper->returnVirtualKey(tempQtKey); + temp.modifiers = tempX11.modifiers; + } + else + { + temp = keymapper->getCharKeyInformation(maintext.at(i)); + } + } + else + { + temp = keymapper->getCharKeyInformation(maintext.at(i)); + } + + if (temp.virtualkey > KEY_RESERVED) + { + if (temp.modifiers != Qt::NoModifier) + { + if (temp.modifiers.testFlag(Qt::ShiftModifier)) + { + tempList.append(KEY_LEFTSHIFT); + write_uinput_event(keyboardFileHandler, EV_KEY, KEY_LEFTSHIFT, 1, false); + } + + if (temp.modifiers.testFlag(Qt::ControlModifier)) + { + tempList.append(KEY_LEFTCTRL); + write_uinput_event(keyboardFileHandler, EV_KEY, KEY_LEFTCTRL, 1, false); + } + + if (temp.modifiers.testFlag(Qt::AltModifier)) + { + tempList.append(KEY_LEFTALT); + write_uinput_event(keyboardFileHandler, EV_KEY, KEY_LEFTALT, 1, false); + } + + if (temp.modifiers.testFlag(Qt::MetaModifier)) + { + tempList.append(KEY_LEFTMETA); + write_uinput_event(keyboardFileHandler, EV_KEY, KEY_LEFTMETA, 1, false); + } + } + + tempList.append(temp.virtualkey); + write_uinput_event(keyboardFileHandler, EV_KEY, temp.virtualkey, 1, true); + } + + if (tempList.size() > 0) + { + QListIterator tempiter(tempList); + tempiter.toBack(); + while (tempiter.hasPrevious()) + { + unsigned int currentcode = tempiter.previous(); + bool sync = !tempiter.hasPrevious() ? true : false; + write_uinput_event(keyboardFileHandler, EV_KEY, currentcode, 0, sync); + } + } + } + } +} diff --git a/src/eventhandlers/uinputeventhandler.h b/src/eventhandlers/uinputeventhandler.h new file mode 100644 index 0000000..61b9105 --- /dev/null +++ b/src/eventhandlers/uinputeventhandler.h @@ -0,0 +1,75 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef UINPUTEVENTHANDLER_H +#define UINPUTEVENTHANDLER_H + +#include "baseeventhandler.h" +#include "../qtx11keymapper.h" + +#include +#include + +class UInputEventHandler : public BaseEventHandler +{ + Q_OBJECT +public: + explicit UInputEventHandler(QObject *parent = 0); + ~UInputEventHandler(); + + virtual bool init(); + virtual bool cleanup(); + virtual void sendKeyboardEvent(JoyButtonSlot *slot, bool pressed); + virtual void sendMouseButtonEvent(JoyButtonSlot *slot, bool pressed); + virtual void sendMouseEvent(int xDis, int yDis); + virtual void sendMouseSpringEvent(unsigned int xDis, unsigned int yDis, + unsigned int width, unsigned int height); + virtual QString getName(); + virtual QString getIdentifier(); + virtual void printPostMessages(); + + virtual void sendTextEntryEvent(QString maintext); + +protected: + int openUInputHandle(); + void setKeyboardEvents(int filehandle); + void setRelMouseEvents(int filehandle); + void setSpringMouseEvents(int filehandle); + void populateKeyCodes(int filehandle); + void createUInputKeyboardDevice(int filehandle); + void createUInputMouseDevice(int filehandle); + void createUInputSpringMouseDevice(int filehandle); + void closeUInputDevice(int filehandle); + void write_uinput_event(int filehandle, unsigned int type, + unsigned int code, int value, bool syn=true); + + int keyboardFileHandler; + int mouseFileHandler; + int springMouseFileHandler; + QString uinputDeviceLocation; + +signals: + +public slots: + +private slots: +#ifdef WITH_X11 + void x11ResetMouseAccelerationChange(); +#endif +}; + +#endif // UINPUTEVENTHANDLER_H diff --git a/src/eventhandlers/winsendinputeventhandler.cpp b/src/eventhandlers/winsendinputeventhandler.cpp new file mode 100644 index 0000000..e9fce33 --- /dev/null +++ b/src/eventhandlers/winsendinputeventhandler.cpp @@ -0,0 +1,239 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "winsendinputeventhandler.h" +#include +#include + +WinSendInputEventHandler::WinSendInputEventHandler(QObject *parent) : + BaseEventHandler(parent) +{ +} + +bool WinSendInputEventHandler::init() +{ + return true; +} + +bool WinSendInputEventHandler::cleanup() +{ + return true; +} + +void WinSendInputEventHandler::sendKeyboardEvent(JoyButtonSlot *slot, bool pressed) +{ + int code = slot->getSlotCode(); + INPUT temp[1] = {}; + + unsigned int scancode = WinExtras::scancodeFromVirtualKey(code, slot->getSlotCodeAlias()); + int extended = (scancode & WinExtras::EXTENDED_FLAG) != 0; + int tempflags = extended ? KEYEVENTF_EXTENDEDKEY : 0; + + temp[0].type = INPUT_KEYBOARD; + //temp[0].ki.wScan = MapVirtualKey(code, MAPVK_VK_TO_VSC); + temp[0].ki.wScan = scancode; + temp[0].ki.time = 0; + temp[0].ki.dwExtraInfo = 0; + + temp[0].ki.wVk = code; + temp[0].ki.dwFlags = pressed ? tempflags : (tempflags | KEYEVENTF_KEYUP); // 0 for key press + SendInput(1, temp, sizeof(INPUT)); +} + +void WinSendInputEventHandler::sendMouseButtonEvent(JoyButtonSlot *slot, bool pressed) +{ + int code = slot->getSlotCode(); + INPUT temp[1] = {}; + + temp[0].type = INPUT_MOUSE; + if (code == 1) + { + temp[0].mi.dwFlags = pressed ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP; + } + else if (code == 2) + { + temp[0].mi.dwFlags = pressed ? MOUSEEVENTF_MIDDLEDOWN : MOUSEEVENTF_MIDDLEUP; + } + else if (code == 3) + { + temp[0].mi.dwFlags = pressed ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP; + } + else if (code == 4) + { + temp[0].mi.dwFlags = MOUSEEVENTF_WHEEL; + temp[0].mi.mouseData = pressed ? WHEEL_DELTA : 0; + } + else if (code == 5) + { + temp[0].mi.dwFlags = MOUSEEVENTF_WHEEL; + temp[0].mi.mouseData = pressed ? -WHEEL_DELTA : 0; + } + else if (code == 6) + { + temp[0].mi.dwFlags = 0x01000; + temp[0].mi.mouseData = pressed ? -WHEEL_DELTA : 0; + } + else if (code == 7) + { + temp[0].mi.dwFlags = 0x01000; + temp[0].mi.mouseData = pressed ? WHEEL_DELTA : 0; + } + else if (code == 8) + { + temp[0].mi.dwFlags = pressed ? MOUSEEVENTF_XDOWN : MOUSEEVENTF_XUP; + temp[0].mi.mouseData = XBUTTON1; + } + else if (code == 9) + { + temp[0].mi.dwFlags = pressed ? MOUSEEVENTF_XDOWN : MOUSEEVENTF_XUP; + temp[0].mi.mouseData = XBUTTON2; + } + + SendInput(1, temp, sizeof(INPUT)); +} + +void WinSendInputEventHandler::sendMouseEvent(int xDis, int yDis) +{ + INPUT temp[1] = {}; + temp[0].type = INPUT_MOUSE; + temp[0].mi.mouseData = 0; + temp[0].mi.dwFlags = MOUSEEVENTF_MOVE; + temp[0].mi.dx = xDis; + temp[0].mi.dy = yDis; + SendInput(1, temp, sizeof(INPUT)); +} + +QString WinSendInputEventHandler::getName() +{ + return QString("SendInput"); +} + +QString WinSendInputEventHandler::getIdentifier() +{ + return QString("sendinput"); +} + +void WinSendInputEventHandler::sendMouseSpringEvent(unsigned int xDis, unsigned int yDis, + unsigned int width, unsigned int height) +{ + if (width > 0 && height > 0) + { + INPUT temp[1] = {}; + temp[0].type = INPUT_MOUSE; + temp[0].mi.mouseData = 0; + temp[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; + + int fx = ceil(xDis * (65535.0/static_cast(width))); + int fy = ceil(yDis * (65535.0/static_cast(height))); + temp[0].mi.dx = fx; + temp[0].mi.dy = fy; + SendInput(1, temp, sizeof(INPUT)); + } +} + +void WinSendInputEventHandler::sendTextEntryEvent(QString maintext) +{ + AntKeyMapper *mapper = AntKeyMapper::getInstance(); + + if (mapper && mapper->getKeyMapper()) + { + QtWinKeyMapper *keymapper = static_cast(mapper->getKeyMapper()); + + for (int i=0; i < maintext.size(); i++) + { + QtWinKeyMapper::charKeyInformation temp = keymapper->getCharKeyInformation(maintext.at(i)); + QList tempList; + + if (temp.modifiers != Qt::NoModifier) + { + if (temp.modifiers.testFlag(Qt::ShiftModifier)) + { + tempList.append(VK_LSHIFT); + } + + if (temp.modifiers.testFlag(Qt::ControlModifier)) + { + tempList.append(VK_LCONTROL); + } + + if (temp.modifiers.testFlag(Qt::AltModifier)) + { + tempList.append(VK_LMENU); + } + + if (temp.modifiers.testFlag(Qt::MetaModifier)) + { + tempList.append(VK_LWIN); + } + } + + tempList.append(temp.virtualkey); + + if (tempList.size() > 0) + { + INPUT tempBuffer[tempList.size()] = {0}; + + QListIterator tempiter(tempList); + unsigned int j = 0; + while (tempiter.hasNext()) + { + unsigned int tempcode = tempiter.next(); + unsigned int scancode = WinExtras::scancodeFromVirtualKey(tempcode); + int extended = (scancode & WinExtras::EXTENDED_FLAG) != 0; + int tempflags = extended ? KEYEVENTF_EXTENDEDKEY : 0; + + tempBuffer[j].type = INPUT_KEYBOARD; + tempBuffer[j].ki.wScan = scancode; + tempBuffer[j].ki.time = 0; + tempBuffer[j].ki.dwExtraInfo = 0; + + tempBuffer[j].ki.wVk = tempcode; + tempBuffer[j].ki.dwFlags = tempflags; + j++; + } + + SendInput(j, tempBuffer, sizeof(INPUT)); + + tempiter.toBack(); + j = 0; + memset(tempBuffer, 0, sizeof(tempBuffer)); + //INPUT tempBuffer2[tempList.size()] = {0}; + while (tempiter.hasPrevious()) + { + unsigned int tempcode = tempiter.previous(); + unsigned int scancode = WinExtras::scancodeFromVirtualKey(tempcode); + int extended = (scancode & WinExtras::EXTENDED_FLAG) != 0; + int tempflags = extended ? KEYEVENTF_EXTENDEDKEY : 0; + + tempBuffer[j].type = INPUT_KEYBOARD; + tempBuffer[j].ki.wScan = scancode; + tempBuffer[j].ki.time = 0; + tempBuffer[j].ki.dwExtraInfo = 0; + + tempBuffer[j].ki.wVk = tempcode; + tempBuffer[j].ki.dwFlags = tempflags | KEYEVENTF_KEYUP; + j++; + } + + SendInput(j, tempBuffer, sizeof(INPUT)); + } + } + } +} diff --git a/src/eventhandlers/winsendinputeventhandler.h b/src/eventhandlers/winsendinputeventhandler.h new file mode 100644 index 0000000..0a6c8e9 --- /dev/null +++ b/src/eventhandlers/winsendinputeventhandler.h @@ -0,0 +1,51 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef WINSENDINPUTEVENTHANDLER_H +#define WINSENDINPUTEVENTHANDLER_H + +#include + +#include "baseeventhandler.h" + +#include + + +class WinSendInputEventHandler : public BaseEventHandler +{ + Q_OBJECT +public: + explicit WinSendInputEventHandler(QObject *parent = 0); + + virtual bool init(); + virtual bool cleanup(); + virtual void sendKeyboardEvent(JoyButtonSlot *slot, bool pressed); + virtual void sendMouseButtonEvent(JoyButtonSlot *slot, bool pressed); + virtual void sendMouseEvent(int xDis, int yDis); + virtual QString getName(); + virtual QString getIdentifier(); + virtual void sendMouseSpringEvent(unsigned int xDis, unsigned int yDis, + unsigned int width, unsigned int height); + virtual void sendTextEntryEvent(QString maintext); + +signals: + +public slots: + +}; + +#endif // WINSENDINPUTEVENTHANDLER_H diff --git a/src/eventhandlers/winvmultieventhandler.cpp b/src/eventhandlers/winvmultieventhandler.cpp new file mode 100644 index 0000000..8924be0 --- /dev/null +++ b/src/eventhandlers/winvmultieventhandler.cpp @@ -0,0 +1,393 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +//#include +#include +#include +#include + +#include "winvmultieventhandler.h" + +#include + +WinVMultiEventHandler::WinVMultiEventHandler(QObject *parent) : + BaseEventHandler(parent), + sendInputHandler(this) +{ + vmulti = 0; + mouseButtons = 0; + shiftKeys = 0; + multiKeys = 0; + extraKeys = 0; + + keyboardKeys.resize(6); + keyboardKeys.fill(0); + + nativeKeyMapper = 0; +} + +WinVMultiEventHandler::~WinVMultiEventHandler() +{ + cleanup(); +} + +bool WinVMultiEventHandler::init() +{ + bool result = true; + + vmulti = vmulti_alloc(); + + if (vmulti == NULL) + { + result = false; + } + + if (vmulti && !vmulti_connect(vmulti)) + { + vmulti_free(vmulti); + vmulti = 0; + result = false; + } + + if (vmulti) + { + nativeKeyMapper = 0; + if (AntKeyMapper::getInstance("vmulti")->hasNativeKeyMapper()) + { + nativeKeyMapper = AntKeyMapper::getInstance("vmulti")->getNativeKeyMapper(); + } + } + + return result; +} + +bool WinVMultiEventHandler::cleanup() +{ + bool result = true; + + if (vmulti) + { + vmulti_disconnect(vmulti); + vmulti_free(vmulti); + + vmulti = 0; + } + + nativeKeyMapper = 0; + + return result; +} + +void WinVMultiEventHandler::sendKeyboardEvent(JoyButtonSlot *slot, bool pressed) +{ + int code = slot->getSlotCode(); + + BYTE pendingShift = 0x0; + BYTE pendingMultimedia = 0x0; + BYTE pendingExtra = 0x0; + BYTE pendingKey = 0x0; + + JoyButtonSlot tempSendInputSlot(slot); + bool useSendInput = false; + + bool exists = keyboardKeys.contains(code); + + if (code <= 0x65) + { + pendingKey = code; + } + else if (code >= 0xE0 && code <= 0xE7) + { + //pendingShift = 1 << (code - 0xE0); + if (nativeKeyMapper) + { + unsigned int nativeKey = nativeKeyMapper->returnVirtualKey(slot->getSlotCodeAlias()); + if (nativeKey > 0) + { + tempSendInputSlot.setSlotCode(nativeKey); + useSendInput = true; + } + } + } + else if (code > QtVMultiKeyMapper::consumerUsagePagePrefix) + { + if (nativeKeyMapper) + { + unsigned int nativeKey = nativeKeyMapper->returnVirtualKey(slot->getSlotCodeAlias()); + if (nativeKey > 0) + { + tempSendInputSlot.setSlotCode(nativeKey); + useSendInput = true; + } + } + + /*if (code == 0xB5 | QtVMultiKeyMapper::consumerUsagePagePrefix) + { + pendingMultimedia = 1 << 0; // (Scan Next Track) + } + else if (code == 0xB6 | QtVMultiKeyMapper::consumerUsagePagePrefix) + { + pendingMultimedia = 1 << 1; // (Scan Previous Track) + } + else if (code == 0xB1 | QtVMultiKeyMapper::consumerUsagePagePrefix) + { + pendingMultimedia = 1 << 3; // (Play / Pause) + } + else if (code == 0x189 | QtVMultiKeyMapper::consumerUsagePagePrefix) + { + pendingMultimedia = 1 << 6; // (WWW Home) + } + + else if (code == 0x194 | QtVMultiKeyMapper::consumerUsagePagePrefix) + { + pendingExtra = 1 << 0; // (My Computer) + } + else if (code == 0x192 | QtVMultiKeyMapper::consumerUsagePagePrefix) + { + pendingExtra = 1 << 1; // (Calculator) + } + else if (code == 0x22a | QtVMultiKeyMapper::consumerUsagePagePrefix) + { + pendingExtra = 1 << 2; // (WWW fav) + } + else if (code == 0x221 | QtVMultiKeyMapper::consumerUsagePagePrefix) + { + pendingExtra = 1 << 3; // (WWW search) + } + else if (code == 0xB7 | QtVMultiKeyMapper::consumerUsagePagePrefix) + { + pendingExtra = 1 << 3; // (WWW stop) + } + else if (code == 0x224 | QtVMultiKeyMapper::consumerUsagePagePrefix) + { + pendingExtra = 1 << 4; // (WWW back) + } + else if (code == 0x87 | QtVMultiKeyMapper::consumerUsagePagePrefix) + { + pendingExtra = 1 << 5; // (Media Select) + } + else if (code == 0x18a | QtVMultiKeyMapper::consumerUsagePagePrefix) + { + pendingExtra = 1 << 6; // (Mail) + } + */ + + } + else if (code > 0x65) + { + if (nativeKeyMapper) + { + unsigned int nativeKey = nativeKeyMapper->returnVirtualKey(slot->getSlotCodeAlias()); + if (nativeKey > 0) + { + tempSendInputSlot.setSlotCode(nativeKey); + //sendInputHandler.sendKeyboardEvent(tempslot, pressed); + useSendInput = true; + } + } + + /*if (code == 0x78) + { + pendingMultimedia = 1 << 2; // (Stop) + } + else if (code == 0x7F) + { + pendingMultimedia = 1 << 4; // (Mute) + } + else if (code == 0x81) + { + pendingMultimedia = 1 << 5; // (Volume Down) + } + else if (code == 0x80) + { + pendingMultimedia = 1 << 6; // (Volume Up) + } + */ + } + + if (!useSendInput) + { + if (pressed) + { + shiftKeys = shiftKeys | pendingShift; + multiKeys = multiKeys | pendingMultimedia; + extraKeys = extraKeys | pendingExtra; + + if (!exists) + { + // Check for an empty key value + int index = keyboardKeys.indexOf(0); + if (index != -1) + { + keyboardKeys.replace(index, pendingKey); + } + } + } + else + { + shiftKeys = shiftKeys ^ pendingShift; + multiKeys = multiKeys ^ pendingMultimedia; + extraKeys = extraKeys ^ pendingExtra; + + if (exists) + { + int index = keyboardKeys.indexOf(pendingKey); + if (index != -1) + { + keyboardKeys.replace(index, 0); + } + } + } + + BYTE *keykeyArray = keyboardKeys.data(); + /*QStringList trying; + for (int i=0; i < 6; i++) + { + BYTE current = keykeyArray[i]; + trying.append(QString("0x%1").arg(QString::number(current, 16))); + } + */ + + //qDebug() << "CURRENT: " << trying.join(","); + //qDebug() << keykeyArray; + + if (pendingKey > 0x0) + { + vmulti_update_keyboard(vmulti, shiftKeys, keykeyArray); + } + + if (pendingMultimedia > 0 || pendingExtra > 0) + { + //vmulti_update_keyboard_enhanced(vmulti, multiKeys, extraKeys); + } + } + else + { + sendInputHandler.sendKeyboardEvent(&tempSendInputSlot, pressed); + useSendInput = false; + } +} + +void WinVMultiEventHandler::sendMouseButtonEvent(JoyButtonSlot *slot, bool pressed) +{ + BYTE pendingButton = 0; + BYTE pendingWheel = 0; + BYTE pendingHWheel = 0; + + bool useSendInput = false; + + int code = slot->getSlotCode(); + if (code == 1) + { + pendingButton = 0x01; + } + else if (code == 2) + { + pendingButton = 0x04; + } + else if (code == 3) + { + pendingButton = 0x02; + } + else if (code == 4) + { + pendingWheel = pressed ? 1 : 0; + } + else if (code == 5) + { + pendingWheel = pressed ? -1 : 0; + } + else if (code >= 6 && code <= 9) + { + useSendInput = true; + } + /* + else if (code == 6) + { + pendingHWheel = pressed ? -1 : 0; + } + else if (code == 7) + { + pendingHWheel = pressed ? 1 : 0; + } + else if (code == 8) + { + pendingButton = 0x08; + } + else if (code == 9) + { + pendingButton = 0x10; + } + */ + + if (!useSendInput) + { + if (pressed) + { + mouseButtons = mouseButtons | pendingButton; + vmulti_update_relative_mouse(vmulti, mouseButtons, 0, 0, pendingWheel);//, pendingHWheel); + } + else + { + mouseButtons = mouseButtons ^ pendingButton; + vmulti_update_relative_mouse(vmulti, mouseButtons, 0, 0, pendingWheel);//, pendingHWheel); + } + } + else + { + sendInputHandler.sendMouseButtonEvent(slot, pressed); + } +} + +void WinVMultiEventHandler::sendMouseEvent(int xDis, int yDis) +{ + vmulti_update_relative_mouse(vmulti, mouseButtons, xDis, yDis, 0);//, 0); +} + +void WinVMultiEventHandler::sendMouseSpringEvent(unsigned int xDis, unsigned int yDis, + unsigned int width, unsigned int height) +{ + if (width > 0 && height > 0) + { + int fx = ceil(xDis * (32767.0/static_cast(width))); + int fy = ceil(yDis * (32767.0/static_cast(height))); + sendMouseAbsEvent(fx, fy); + } +} + +void WinVMultiEventHandler::sendMouseAbsEvent(int xDis, int yDis) +{ + vmulti_update_mouse(vmulti, mouseButtons, xDis, yDis, 0);//, 0); +} + +/* + * TODO: Implement text event using information from QtWinKeyMapper. + */ +void WinVMultiEventHandler::sendTextEntryEvent(QString maintext) +{ + sendInputHandler.sendTextEntryEvent(maintext); +} + +QString WinVMultiEventHandler::getName() +{ + return QString("Vmulti"); +} + +QString WinVMultiEventHandler::getIdentifier() +{ + return QString("vmulti"); +} diff --git a/src/eventhandlers/winvmultieventhandler.h b/src/eventhandlers/winvmultieventhandler.h new file mode 100644 index 0000000..f833352 --- /dev/null +++ b/src/eventhandlers/winvmultieventhandler.h @@ -0,0 +1,72 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef WINVMULTIEVENTHANDLER_H +#define WINVMULTIEVENTHANDLER_H + +#include +#include + +#include "baseeventhandler.h" + +#include + +#include + +#include +#include "winsendinputeventhandler.h" + + +class WinVMultiEventHandler : public BaseEventHandler +{ + Q_OBJECT +public: + explicit WinVMultiEventHandler(QObject *parent = 0); + ~WinVMultiEventHandler(); + + virtual bool init(); + virtual bool cleanup(); + virtual void sendKeyboardEvent(JoyButtonSlot *slot, bool pressed); + virtual void sendMouseButtonEvent(JoyButtonSlot *slot, bool pressed); + virtual void sendMouseEvent(int xDis, int yDis); + virtual void sendMouseAbsEvent(int xDis, int yDis); + virtual void sendMouseSpringEvent(unsigned int xDis, unsigned int yDis, + unsigned int width, unsigned int height); + + // TODO: Implement text event using information from QtWinKeyMapper. + virtual void sendTextEntryEvent(QString maintext); + virtual QString getName(); + virtual QString getIdentifier(); + +protected: + pvmulti_client vmulti; + BYTE mouseButtons; + BYTE shiftKeys; + BYTE multiKeys; + BYTE extraKeys; + QVector keyboardKeys; + WinSendInputEventHandler sendInputHandler; + QtKeyMapperBase *nativeKeyMapper; + + +signals: + +public slots: + +}; + +#endif // WINVMULTIEVENTHANDLER_H diff --git a/src/eventhandlers/xtesteventhandler.cpp b/src/eventhandlers/xtesteventhandler.cpp new file mode 100644 index 0000000..6d8d669 --- /dev/null +++ b/src/eventhandlers/xtesteventhandler.cpp @@ -0,0 +1,214 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "xtesteventhandler.h" + +#include + +#include +#include +#include +#include +#include +#include + +XTestEventHandler::XTestEventHandler(QObject *parent) : + BaseEventHandler(parent) +{ +} + +bool XTestEventHandler::init() +{ + X11Extras *instance = X11Extras::getInstance(); + if (instance) + { + instance->x11ResetMouseAccelerationChange(X11Extras::xtestMouseDeviceName); + } + + return true; +} + +bool XTestEventHandler::cleanup() +{ + return true; +} + +void XTestEventHandler::sendKeyboardEvent(JoyButtonSlot *slot, bool pressed) +{ + Display* display = X11Extras::getInstance()->display(); + JoyButtonSlot::JoySlotInputAction device = slot->getSlotMode(); + int code = slot->getSlotCode(); + + if (device == JoyButtonSlot::JoyKeyboard) + { + unsigned int tempcode = XKeysymToKeycode(display, code); + if (tempcode > 0) + { + XTestFakeKeyEvent(display, tempcode, pressed, 0); + XFlush(display); + } + } +} + +void XTestEventHandler::sendMouseButtonEvent(JoyButtonSlot *slot, bool pressed) +{ + Display* display = X11Extras::getInstance()->display(); + JoyButtonSlot::JoySlotInputAction device = slot->getSlotMode(); + int code = slot->getSlotCode(); + + if (device == JoyButtonSlot::JoyMouseButton) + { + XTestFakeButtonEvent(display, code, pressed, 0); + XFlush(display); + } +} + +void XTestEventHandler::sendMouseEvent(int xDis, int yDis) +{ + Display* display = X11Extras::getInstance()->display(); + XTestFakeRelativeMotionEvent(display, xDis, yDis, 0); + XFlush(display); +} + +void XTestEventHandler::sendMouseAbsEvent(int xDis, int yDis) +{ + Display* display = X11Extras::getInstance()->display(); + XTestFakeMotionEvent(display, -1, xDis, yDis, 0); + XFlush(display); +} + +QString XTestEventHandler::getName() +{ + return QString("XTest"); +} + +QString XTestEventHandler::getIdentifier() +{ + return QString("xtest"); +} + +void XTestEventHandler::sendTextEntryEvent(QString maintext) +{ + AntKeyMapper *mapper = AntKeyMapper::getInstance(); + + // Populated as needed. + unsigned int shiftcode = 0; + unsigned int controlcode = 0; + unsigned int metacode = 0; + unsigned int altcode = 0; + + if (mapper && mapper->getKeyMapper()) + { + //Qt::KeyboardModifiers originalModifiers = Qt::KeyboardModifiers(QApplication::keyboardModifiers()); + //Qt::KeyboardModifiers currentModifiers = Qt::KeyboardModifiers(QApplication::keyboardModifiers()); + Display* display = X11Extras::getInstance()->display(); + QtX11KeyMapper *keymapper = static_cast(mapper->getKeyMapper()); + + for (int i=0; i < maintext.size(); i++) + { + QtX11KeyMapper::charKeyInformation temp = keymapper->getCharKeyInformation(maintext.at(i)); + unsigned int tempcode = XKeysymToKeycode(display, temp.virtualkey); + if (tempcode > 0) + { + QList tempList; + + if (temp.modifiers != Qt::NoModifier) + { + if (temp.modifiers.testFlag(Qt::ShiftModifier)) + { + if (shiftcode == 0) + { + shiftcode = XKeysymToKeycode(display, XK_Shift_L); + } + + unsigned int modifiercode = shiftcode; + XTestFakeKeyEvent(display, modifiercode, 1, 0); + //currentModifiers |= Qt::ShiftModifier; + tempList.append(modifiercode); + } + + if (temp.modifiers.testFlag(Qt::ControlModifier)) + { + if (controlcode == 0) + { + controlcode = XKeysymToKeycode(display, XK_Control_L); + } + + unsigned int modifiercode = controlcode; + XTestFakeKeyEvent(display, modifiercode, 1, 0); + //currentModifiers |= Qt::ControlModifier; + tempList.append(modifiercode); + } + + if (temp.modifiers.testFlag(Qt::AltModifier)) + { + if (altcode == 0) + { + altcode = XKeysymToKeycode(display, XK_Alt_L); + } + + unsigned int modifiercode = altcode; + XTestFakeKeyEvent(display, modifiercode, 1, 0); + //currentModifiers |= Qt::AltModifier; + tempList.append(modifiercode); + } + + if (temp.modifiers.testFlag(Qt::MetaModifier)) + { + if (metacode == 0) + { + metacode = XKeysymToKeycode(display, XK_Meta_L); + } + + unsigned int modifiercode = metacode; + XTestFakeKeyEvent(display, modifiercode, 1, 0); + //currentModifiers |= Qt::MetaModifier; + tempList.append(modifiercode); + } + } + + XTestFakeKeyEvent(display, tempcode, 1, 0); + tempList.append(tempcode); + + XFlush(display); + + if (tempList.size() > 0) + { + QListIterator tempiter(tempList); + tempiter.toBack(); + while (tempiter.hasPrevious()) + { + unsigned int currentcode = tempiter.previous(); + XTestFakeKeyEvent(display, currentcode, 0, 0); + } + + XFlush(display); + } + } + } + + // Perform a flush at the end. + //XFlush(display); + + // Restore modifiers in place + /*if (originalModifiers != currentModifiers) + { + + } + */ + } +} diff --git a/src/eventhandlers/xtesteventhandler.h b/src/eventhandlers/xtesteventhandler.h new file mode 100644 index 0000000..161d13c --- /dev/null +++ b/src/eventhandlers/xtesteventhandler.h @@ -0,0 +1,48 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XTESTEVENTHANDLER_H +#define XTESTEVENTHANDLER_H + +#include "baseeventhandler.h" + +#include + +class XTestEventHandler : public BaseEventHandler +{ + Q_OBJECT +public: + explicit XTestEventHandler(QObject *parent = 0); + + virtual bool init(); + virtual bool cleanup(); + virtual void sendKeyboardEvent(JoyButtonSlot *slot, bool pressed); + virtual void sendMouseButtonEvent(JoyButtonSlot *slot, bool pressed); + virtual void sendMouseEvent(int xDis, int yDis); + virtual void sendMouseAbsEvent(int xDis, int yDis); + virtual QString getName(); + virtual QString getIdentifier(); + + virtual void sendTextEntryEvent(QString maintext); + +signals: + +public slots: + +}; + +#endif // XTESTEVENTHANDLER_H diff --git a/src/extraprofilesettingsdialog.cpp b/src/extraprofilesettingsdialog.cpp new file mode 100644 index 0000000..5806051 --- /dev/null +++ b/src/extraprofilesettingsdialog.cpp @@ -0,0 +1,59 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +//#include + +#include "extraprofilesettingsdialog.h" +#include "ui_extraprofilesettingsdialog.h" + +ExtraProfileSettingsDialog::ExtraProfileSettingsDialog(InputDevice *device, QWidget *parent) : + QDialog(parent), + ui(new Ui::ExtraProfileSettingsDialog) +{ + ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + + this->device = device; + + ui->pressValueLabel->setText(QString::number(0.10, 'g', 3).append("").append(tr("s"))); + if (device->getDeviceKeyPressTime() > 0) + { + int temppress = device->getDeviceKeyPressTime(); + ui->keyPressHorizontalSlider->setValue(device->getDeviceKeyPressTime() / 10); + ui->pressValueLabel->setText(QString::number(temppress / 1000.0, 'g', 3).append("").append(tr("s"))); + } + + if (!device->getProfileName().isEmpty()) + { + ui->profileNameLineEdit->setText(device->getProfileName()); + } + + connect(ui->keyPressHorizontalSlider, SIGNAL(valueChanged(int)), this, SLOT(changeDeviceKeyPress(int))); + connect(ui->profileNameLineEdit, SIGNAL(textChanged(QString)), device, SLOT(setProfileName(QString))); +} + +ExtraProfileSettingsDialog::~ExtraProfileSettingsDialog() +{ + delete ui; +} + +void ExtraProfileSettingsDialog::changeDeviceKeyPress(int value) +{ + int temppress = value * 10; + device->setDeviceKeyPressTime(temppress); + ui->pressValueLabel->setText(QString::number(temppress / 1000.0, 'g', 3).append("").append(tr("s"))); +} diff --git a/src/extraprofilesettingsdialog.h b/src/extraprofilesettingsdialog.h new file mode 100644 index 0000000..a8b9d86 --- /dev/null +++ b/src/extraprofilesettingsdialog.h @@ -0,0 +1,47 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef KEYDELAYDIALOG_H +#define KEYDELAYDIALOG_H + +#include + +#include "inputdevice.h" + +namespace Ui { +class ExtraProfileSettingsDialog; +} + +class ExtraProfileSettingsDialog : public QDialog +{ + Q_OBJECT + +public: + explicit ExtraProfileSettingsDialog(InputDevice *device, QWidget *parent = 0); + ~ExtraProfileSettingsDialog(); + +protected: + InputDevice *device; + +private: + Ui::ExtraProfileSettingsDialog *ui; + +private slots: + void changeDeviceKeyPress(int value); +}; + +#endif // KEYDELAYDIALOG_H diff --git a/src/extraprofilesettingsdialog.ui b/src/extraprofilesettingsdialog.ui new file mode 100644 index 0000000..92f092e --- /dev/null +++ b/src/extraprofilesettingsdialog.ui @@ -0,0 +1,160 @@ + + + ExtraProfileSettingsDialog + + + + 0 + 0 + 439 + 144 + + + + + 396 + 136 + + + + Extra Profile Settings + + + true + + + + + + 10 + + + 10 + + + + + 20 + + + 0 + + + + + Key Press Time: + + + + + + + 1 + + + 100 + + + 10 + + + Qt::Horizontal + + + + + + + + + 0.00 ms + + + + + + + + + 36 + + + + + Profile Name: + + + + + + + 50 + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 10 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + + + + buttonBox + accepted() + ExtraProfileSettingsDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + ExtraProfileSettingsDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/flashbuttonwidget.cpp b/src/flashbuttonwidget.cpp new file mode 100644 index 0000000..884ece6 --- /dev/null +++ b/src/flashbuttonwidget.cpp @@ -0,0 +1,132 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +//#include +#include +#include +#include + +#include "flashbuttonwidget.h" + +FlashButtonWidget::FlashButtonWidget(QWidget *parent) : + QPushButton(parent) +{ + isflashing = false; + displayNames = false; + leftAlignText = false; +} + +FlashButtonWidget::FlashButtonWidget(bool displayNames, QWidget *parent) : + QPushButton(parent) +{ + isflashing = false; + this->displayNames = displayNames; + leftAlignText = false; +} + +void FlashButtonWidget::flash() +{ + isflashing = true; + + this->style()->unpolish(this); + this->style()->polish(this); + + emit flashed(isflashing); +} + +void FlashButtonWidget::unflash() +{ + isflashing = false; + + this->style()->unpolish(this); + this->style()->polish(this); + + emit flashed(isflashing); +} + +void FlashButtonWidget::refreshLabel() +{ + setText(generateLabel()); +} + +bool FlashButtonWidget::isButtonFlashing() +{ + return isflashing; +} + +void FlashButtonWidget::toggleNameDisplay() +{ + displayNames = !displayNames; + refreshLabel(); +} + +void FlashButtonWidget::setDisplayNames(bool display) +{ + displayNames = display; +} + +bool FlashButtonWidget::isDisplayingNames() +{ + return displayNames; +} + +void FlashButtonWidget::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + + QFont tempScaledFont = painter.font(); + QFont temp; + tempScaledFont.setPointSize(temp.pointSize()); + QFontMetrics fm(tempScaledFont); + + bool reduce = false; + while ((this->width() < fm.width(text())) && tempScaledFont.pointSize() >= 7) + { + tempScaledFont.setPointSize(tempScaledFont.pointSize()-1); + painter.setFont(tempScaledFont); + fm = painter.fontMetrics(); + reduce = true; + } + + bool changeFontSize = this->font().pointSize() != tempScaledFont.pointSize(); + if (changeFontSize) + { + if (reduce && !leftAlignText) + { + leftAlignText = !leftAlignText; + setStyleSheet("text-align: left;"); + this->style()->unpolish(this); + this->style()->polish(this); + } + else if (!reduce && leftAlignText) + { + leftAlignText = !leftAlignText; + setStyleSheet("text-align: center;"); + this->style()->unpolish(this); + this->style()->polish(this); + } + + this->setFont(tempScaledFont); + } + + QPushButton::paintEvent(event); +} + +void FlashButtonWidget::retranslateUi() +{ + refreshLabel(); +} diff --git a/src/flashbuttonwidget.h b/src/flashbuttonwidget.h new file mode 100644 index 0000000..5ca2021 --- /dev/null +++ b/src/flashbuttonwidget.h @@ -0,0 +1,60 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef FLASHBUTTONWIDGET_H +#define FLASHBUTTONWIDGET_H + +#include +#include + +class FlashButtonWidget : public QPushButton +{ + Q_OBJECT + Q_PROPERTY(bool isflashing READ isButtonFlashing) + +public: + explicit FlashButtonWidget(QWidget *parent = 0); + explicit FlashButtonWidget(bool displayNames, QWidget *parent = 0); + + bool isButtonFlashing(); + void setDisplayNames(bool display); + bool isDisplayingNames(); + +protected: + virtual void paintEvent(QPaintEvent *event); + virtual QString generateLabel() = 0; + virtual void retranslateUi(); + + bool isflashing; + bool displayNames; + bool leftAlignText; + +signals: + void flashed(bool flashing); + +public slots: + void refreshLabel(); + void toggleNameDisplay(); + virtual void disableFlashes() = 0; + virtual void enableFlashes() = 0; + +protected slots: + void flash(); + void unflash(); +}; + +#endif // FLASHBUTTONWIDGET_H diff --git a/src/gamecontroller/gamecontroller.cpp b/src/gamecontroller/gamecontroller.cpp new file mode 100644 index 0000000..5b8af88 --- /dev/null +++ b/src/gamecontroller/gamecontroller.cpp @@ -0,0 +1,961 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +//#include +#include + +#include "gamecontroller.h" +//#include "logger.h" + +const QString GameController::xmlName = "gamecontroller"; + +GameController::GameController(SDL_GameController *controller, int deviceIndex, + AntiMicroSettings *settings, QObject *parent) : + InputDevice(deviceIndex, settings, parent) +{ + this->controller = controller; + SDL_Joystick *joyhandle = SDL_GameControllerGetJoystick(controller); + joystickID = SDL_JoystickInstanceID(joyhandle); + + for (int i=0; i < NUMBER_JOYSETS; i++) + { + GameControllerSet *controllerset = new GameControllerSet(this, i, this); + joystick_sets.insert(i, controllerset); + enableSetConnections(controllerset); + } +} + +QString GameController::getName() +{ + return QString(tr("Game Controller")).append(" ").append(QString::number(getRealJoyNumber())); +} + +QString GameController::getSDLName() +{ + QString temp; + if (controller) + { + temp = SDL_GameControllerName(controller); + } + + return temp; +} + +QString GameController::getGUIDString() +{ + QString temp = getRawGUIDString(); +#ifdef Q_OS_WIN + // On Windows, if device is seen as a game controller by SDL + // and the device has an empty GUID, assume that it is an XInput + // compatible device. Send back xinput as the GUID since SDL uses it + // internally anyway. + /*if (!temp.isEmpty() && temp.contains(emptyGUID)) + { + temp = "xinput"; + } + */ +#endif + + return temp; +} + +QString GameController::getRawGUIDString() +{ + QString temp; + if (controller) + { + SDL_Joystick *joyhandle = SDL_GameControllerGetJoystick(controller); + if (joyhandle) + { + SDL_JoystickGUID tempGUID = SDL_JoystickGetGUID(joyhandle); + char guidString[65] = {'0'}; + SDL_JoystickGetGUIDString(tempGUID, guidString, sizeof(guidString)); + temp = QString(guidString); + } + } + + return temp; +} + +QString GameController::getXmlName() +{ + return this->xmlName; +} + +void GameController::closeSDLDevice() +{ + if (controller && SDL_GameControllerGetAttached(controller)) + { + SDL_GameControllerClose(controller); + controller = 0; + } +} + +int GameController::getNumberRawButtons() +{ + return SDL_CONTROLLER_BUTTON_MAX; +} + +int GameController::getNumberRawAxes() +{ + return SDL_CONTROLLER_AXIS_MAX; +} + +int GameController::getNumberRawHats() +{ + return 0; +} + +void GameController::readJoystickConfig(QXmlStreamReader *xml) +{ + if (xml->isStartElement() && xml->name() == "joystick") + { + //reset(); + transferReset(); + + QHash buttons; + QHash axes; + QList hatButtons; + + for (int i=(int)SDL_CONTROLLER_BUTTON_A; i < (int)SDL_CONTROLLER_BUTTON_MAX; i++) + { + SDL_GameControllerButton currentButton = (SDL_GameControllerButton)i; + SDL_GameControllerButtonBind bound = SDL_GameControllerGetBindForButton(this->controller, currentButton); + if (bound.bindType == SDL_CONTROLLER_BINDTYPE_BUTTON) + { + buttons.insert(bound.value.button, currentButton); + } + else if (bound.bindType == SDL_CONTROLLER_BINDTYPE_HAT) + { + hatButtons.append(bound); + } + } + + for (int i=(int)SDL_CONTROLLER_AXIS_LEFTX; i < (int)SDL_CONTROLLER_AXIS_MAX; i++) + { + SDL_GameControllerAxis currentAxis = (SDL_GameControllerAxis)i; + SDL_GameControllerButtonBind bound = SDL_GameControllerGetBindForAxis(this->controller, currentAxis); + if (bound.bindType == SDL_CONTROLLER_BINDTYPE_AXIS) + { + axes.insert(bound.value.axis, currentAxis); + } + } + + xml->readNextStartElement(); + while (!xml->atEnd() && (!xml->isEndElement() && xml->name() != "joystick")) + { + if (xml->name() == "sets" && xml->isStartElement()) + { + xml->readNextStartElement(); + + while (!xml->atEnd() && (!xml->isEndElement() && xml->name() != "sets")) + { + if (xml->name() == "set" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + index = index - 1; + if (index >= 0 && index < joystick_sets.size()) + { + GameControllerSet *currentSet = static_cast(joystick_sets.value(index)); + currentSet->readJoystickConfig(xml, buttons, axes, hatButtons); + } + } + else + { + // If none of the above, skip the element + xml->skipCurrentElement(); + } + + xml->readNextStartElement(); + } + } + else if (xml->name() == "names" && xml->isStartElement()) + { + bool dpadNameExists = false; + bool vdpadNameExists = false; + + xml->readNextStartElement(); + while (!xml->atEnd() && (!xml->isEndElement() && xml->name() != "names")) + { + if (xml->name() == "buttonname" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + QString temp = xml->readElementText(); + index = index - 1; + if (index >= 0 && !temp.isEmpty()) + { + SDL_GameControllerButton current = buttons.value(index); + if (current) + { + setButtonName(current, temp); + } + } + } + else if (xml->name() == "axisbuttonname" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + int buttonIndex = xml->attributes().value("button").toString().toInt(); + QString temp = xml->readElementText(); + index = index - 1; + buttonIndex = buttonIndex - 1; + if (index >= 0 && !temp.isEmpty()) + { + SDL_GameControllerAxis current = axes.value(index); + if (current) + { + if (current == SDL_CONTROLLER_AXIS_LEFTX) + { + setStickButtonName(0, buttonIndex, temp); + } + else if (current == SDL_CONTROLLER_AXIS_LEFTY) + { + setStickButtonName(0, buttonIndex, temp); + } + else if (current == SDL_CONTROLLER_AXIS_RIGHTX) + { + setStickButtonName(1, buttonIndex, temp); + } + else if (current == SDL_CONTROLLER_AXIS_RIGHTY) + { + setStickButtonName(1, buttonIndex, temp); + } + else if (current == SDL_CONTROLLER_AXIS_TRIGGERLEFT) + { + setAxisName(current, temp); + } + else if (current == SDL_CONTROLLER_AXIS_TRIGGERRIGHT) + { + setAxisName(current, temp); + } + } + } + } + else if (xml->name() == "controlstickbuttonname" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + int buttonIndex = xml->attributes().value("button").toString().toInt(); + QString temp = xml->readElementText(); + index = index - 1; + if (index >= 0 && !temp.isEmpty()) + { + setStickButtonName(index, buttonIndex, temp); + } + } + else if (xml->name() == "dpadbuttonname" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + int buttonIndex = xml->attributes().value("button").toString().toInt(); + QString temp = xml->readElementText(); + index = index - 1; + if (index >= 0 && !temp.isEmpty()) + { + bool found = false; + QListIterator iter(hatButtons); + SDL_GameControllerButtonBind current; + while (iter.hasNext()) + { + current = iter.next(); + if (current.value.hat.hat == index) + { + found = true; + iter.toBack(); + } + } + + if (found) + { + VDPad *dpad = getActiveSetJoystick()->getVDPad(0); + if (dpad) + { + JoyDPadButton *dpadbutton = dpad->getJoyButton(buttonIndex); + if (dpad && dpadbutton->getActionName().isEmpty()) + { + setVDPadButtonName(index, buttonIndex, temp); + } + } + } + } + } + else if (xml->name() == "vdpadbuttonname" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + int buttonIndex = xml->attributes().value("button").toString().toInt(); + QString temp = xml->readElementText(); + index = index - 1; + if (index >= 0 && !temp.isEmpty()) + { + bool found = false; + QListIterator iter(hatButtons); + SDL_GameControllerButtonBind current; + while (iter.hasNext()) + { + current = iter.next(); + if (current.value.hat.hat == index) + { + found = true; + iter.toBack(); + } + } + + if (found) + { + VDPad *dpad = getActiveSetJoystick()->getVDPad(0); + if (dpad) + { + JoyDPadButton *dpadbutton = dpad->getJoyButton(buttonIndex); + if (dpad && dpadbutton->getActionName().isEmpty()) + { + setVDPadButtonName(index, buttonIndex, temp); + } + } + } + } + } + else if (xml->name() == "axisname" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + QString temp = xml->readElementText(); + index = index - 1; + if (index >= 0 && !temp.isEmpty()) + { + if (axes.contains(index)) + { + SDL_GameControllerAxis current = axes.value(index); + setAxisName((int)current, temp); + } + } + } + else if (xml->name() == "controlstickname" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + QString temp = xml->readElementText(); + index = index - 1; + if (index >= 0 && !temp.isEmpty()) + { + setStickName(index, temp); + } + } + else if (xml->name() == "dpadname" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + QString temp = xml->readElementText(); + index = index - 1; + if (index >= 0 && !temp.isEmpty() && !vdpadNameExists) + { + bool found = false; + QListIterator iter(hatButtons); + SDL_GameControllerButtonBind current; + while (iter.hasNext()) + { + current = iter.next(); + if (current.value.hat.hat == index) + { + found = true; + iter.toBack(); + } + } + + if (found) + { + dpadNameExists = true; + + VDPad *dpad = getActiveSetJoystick()->getVDPad(0); + if (dpad) + { + if (dpad->getDpadName().isEmpty()) + { + setVDPadName(index, temp); + } + } + } + } + } + else if (xml->name() == "vdpadname" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + QString temp = xml->readElementText(); + index = index - 1; + if (index >= 0 && !temp.isEmpty() && !dpadNameExists) + { + bool found = false; + QListIterator iter(hatButtons); + SDL_GameControllerButtonBind current; + while (iter.hasNext()) + { + current = iter.next(); + if (current.value.hat.hat == index) + { + found = true; + iter.toBack(); + } + } + + if (found) + { + vdpadNameExists = true; + + VDPad *dpad = getActiveSetJoystick()->getVDPad(0); + if (dpad) + { + if (dpad->getDpadName().isEmpty()) + { + setVDPadName(index, temp); + } + } + } + } + } + else + { + // If none of the above, skip the element + xml->skipCurrentElement(); + } + + xml->readNextStartElement(); + } + } + else if (xml->name() == "keyPressTime" && xml->isStartElement()) + { + QString temptext = xml->readElementText(); + int tempchoice = temptext.toInt(); + if (tempchoice >= 10) + { + this->setDeviceKeyPressTime(tempchoice); + } + } + else if (xml->name() == "profilename" && xml->isStartElement()) + { + QString temptext = xml->readElementText(); + this->setProfileName(temptext); + } + else + { + // If none of the above, skip the element + xml->skipCurrentElement(); + } + + xml->readNextStartElement(); + } + + reInitButtons(); + } +} + + +void GameController::readConfig(QXmlStreamReader *xml) +{ + if (xml->isStartElement() && xml->name() == getXmlName()) + { + //reset(); + transferReset(); + + xml->readNextStartElement(); + while (!xml->atEnd() && (!xml->isEndElement() && xml->name() != getXmlName())) + { + if (xml->name() == "sets" && xml->isStartElement()) + { + xml->readNextStartElement(); + + while (!xml->atEnd() && (!xml->isEndElement() && xml->name() != "sets")) + { + if (xml->name() == "set" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + index = index - 1; + if (index >= 0 && index < joystick_sets.size()) + { + joystick_sets.value(index)->readConfig(xml); + } + } + else + { + // If none of the above, skip the element + xml->skipCurrentElement(); + } + + xml->readNextStartElement(); + } + } + else if (xml->name() == "names" && xml->isStartElement()) + { + xml->readNextStartElement(); + while (!xml->atEnd() && (!xml->isEndElement() && xml->name() != "names")) + { + if (xml->name() == "buttonname" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + QString temp = xml->readElementText(); + index = index - 1; + if (index >= 0 && !temp.isEmpty()) + { + setButtonName(index, temp); + } + } + else if (xml->name() == "triggerbuttonname" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + int buttonIndex = xml->attributes().value("button").toString().toInt(); + QString temp = xml->readElementText(); + index = (index - 1) + SDL_CONTROLLER_AXIS_TRIGGERLEFT; + buttonIndex = buttonIndex - 1; + if ((index == SDL_CONTROLLER_AXIS_TRIGGERLEFT || + index == SDL_CONTROLLER_AXIS_TRIGGERRIGHT) && !temp.isEmpty()) + { + setAxisButtonName(index, buttonIndex, temp); + } + } + else if (xml->name() == "controlstickbuttonname" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + int buttonIndex = xml->attributes().value("button").toString().toInt(); + QString temp = xml->readElementText(); + index = index - 1; + if (index >= 0 && !temp.isEmpty()) + { + setStickButtonName(index, buttonIndex, temp); + } + } + else if (xml->name() == "dpadbuttonname" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + int buttonIndex = xml->attributes().value("button").toString().toInt(); + QString temp = xml->readElementText(); + index = index - 1; + if (index >= 0 && !temp.isEmpty()) + { + setVDPadButtonName(index, buttonIndex, temp); + } + } + else if (xml->name() == "triggername" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + QString temp = xml->readElementText(); + index = (index - 1) + SDL_CONTROLLER_AXIS_TRIGGERLEFT; + if ((index == SDL_CONTROLLER_AXIS_TRIGGERLEFT || + index == SDL_CONTROLLER_AXIS_TRIGGERRIGHT) && !temp.isEmpty()) + { + setAxisName(index, temp); + } + } + else if (xml->name() == "controlstickname" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + QString temp = xml->readElementText(); + index = index - 1; + if (index >= 0 && !temp.isEmpty()) + { + setStickName(index, temp); + } + } + else if (xml->name() == "dpadname" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + QString temp = xml->readElementText(); + index = index - 1; + if (index >= 0 && !temp.isEmpty()) + { + setVDPadName(index, temp); + } + } + else + { + // If none of the above, skip the element + xml->skipCurrentElement(); + } + + xml->readNextStartElement(); + } + } + else if (xml->name() == "keyPressTime" && xml->isStartElement()) + { + QString temptext = xml->readElementText(); + int tempchoice = temptext.toInt(); + if (tempchoice >= 10) + { + this->setDeviceKeyPressTime(tempchoice); + } + } + else if (xml->name() == "profilename" && xml->isStartElement()) + { + QString temptext = xml->readElementText(); + this->setProfileName(temptext); + } + else + { + // If none of the above, skip the element + xml->skipCurrentElement(); + } + + xml->readNextStartElement(); + } + + reInitButtons(); + } + else if (xml->isStartElement() && xml->name() == "joystick") + { + this->readJoystickConfig(xml); + } +} + +void GameController::writeConfig(QXmlStreamWriter *xml) +{ + xml->writeStartElement(getXmlName()); + xml->writeAttribute("configversion", QString::number(PadderCommon::LATESTCONFIGFILEVERSION)); + xml->writeAttribute("appversion", PadderCommon::programVersion); + + xml->writeComment("The SDL name for a joystick is included for informational purposes only."); + xml->writeTextElement("sdlname", getSDLName()); +#ifdef USE_SDL_2 + xml->writeComment("The GUID for a joystick is included for informational purposes only."); + xml->writeTextElement("guid", getGUIDString()); +#endif + + if (!profileName.isEmpty()) + { + xml->writeTextElement("profilename", profileName); + } + + xml->writeStartElement("names"); // + + SetJoystick *tempSet = getActiveSetJoystick(); + for (int i=0; i < getNumberButtons(); i++) + { + JoyButton *button = tempSet->getJoyButton(i); + if (button && !button->getButtonName().isEmpty()) + { + xml->writeStartElement("buttonname"); + xml->writeAttribute("index", QString::number(button->getRealJoyNumber())); + xml->writeCharacters(button->getButtonName()); + xml->writeEndElement(); + } + } + + for (int i=0; i < getNumberAxes(); i++) + { + JoyAxis *axis = tempSet->getJoyAxis(i); + if (axis) + { + if (!axis->getAxisName().isEmpty()) + { + xml->writeStartElement("axisname"); + xml->writeAttribute("index", QString::number(axis->getRealJoyIndex())); + xml->writeCharacters(axis->getAxisName()); + xml->writeEndElement(); + } + + JoyAxisButton *naxisbutton = axis->getNAxisButton(); + if (!naxisbutton->getButtonName().isEmpty()) + { + xml->writeStartElement("axisbuttonname"); + xml->writeAttribute("index", QString::number(axis->getRealJoyIndex())); + xml->writeAttribute("button", QString::number(naxisbutton->getRealJoyNumber())); + xml->writeCharacters(naxisbutton->getButtonName()); + xml->writeEndElement(); + } + + JoyAxisButton *paxisbutton = axis->getPAxisButton(); + if (!paxisbutton->getButtonName().isEmpty()) + { + xml->writeStartElement("axisbuttonname"); + xml->writeAttribute("index", QString::number(axis->getRealJoyIndex())); + xml->writeAttribute("button", QString::number(paxisbutton->getRealJoyNumber())); + xml->writeCharacters(paxisbutton->getButtonName()); + xml->writeEndElement(); + } + } + } + + for (int i=0; i < getNumberSticks(); i++) + { + JoyControlStick *stick = tempSet->getJoyStick(i); + if (stick) + { + if (!stick->getStickName().isEmpty()) + { + xml->writeStartElement("controlstickname"); + xml->writeAttribute("index", QString::number(stick->getRealJoyIndex())); + xml->writeCharacters(stick->getStickName()); + xml->writeEndElement(); + } + + QHash *buttons = stick->getButtons(); + QHashIterator iter(*buttons); + while (iter.hasNext()) + { + JoyControlStickButton *button = iter.next().value(); + if (button && !button->getButtonName().isEmpty()) + { + xml->writeStartElement("controlstickbuttonname"); + xml->writeAttribute("index", QString::number(stick->getRealJoyIndex())); + xml->writeAttribute("button", QString::number(button->getRealJoyNumber())); + xml->writeCharacters(button->getButtonName()); + xml->writeEndElement(); + } + } + } + } + + for (int i=0; i < getNumberVDPads(); i++) + { + VDPad *vdpad = getActiveSetJoystick()->getVDPad(i); + if (vdpad) + { + if (!vdpad->getDpadName().isEmpty()) + { + xml->writeStartElement("dpadname"); + xml->writeAttribute("index", QString::number(vdpad->getRealJoyNumber())); + xml->writeCharacters(vdpad->getDpadName()); + xml->writeEndElement(); + } + + QHash *temp = vdpad->getButtons(); + QHashIterator iter(*temp); + while (iter.hasNext()) + { + JoyDPadButton *button = iter.next().value(); + if (button && !button->getButtonName().isEmpty()) + { + xml->writeStartElement("dpadbutton"); + xml->writeAttribute("index", QString::number(vdpad->getRealJoyNumber())); + xml->writeAttribute("button", QString::number(button->getRealJoyNumber())); + xml->writeCharacters(button->getButtonName()); + xml->writeEndElement(); + } + } + } + } + xml->writeEndElement(); // + + if (keyPressTime > 0 && keyPressTime != DEFAULTKEYPRESSTIME) + { + xml->writeTextElement("keyPressTime", QString::number(keyPressTime)); + } + + xml->writeStartElement("sets"); + for (int i=0; i < joystick_sets.size(); i++) + { + joystick_sets.value(i)->writeConfig(xml); + } + xml->writeEndElement(); + + xml->writeEndElement(); +} + +QString GameController::getBindStringForAxis(int index, bool trueIndex) +{ + QString temp; + SDL_GameControllerButtonBind bind = + SDL_GameControllerGetBindForAxis(controller, + static_cast(index)); + if (bind.bindType != SDL_CONTROLLER_BINDTYPE_NONE) + { + int offset = trueIndex ? 0 : 1; + if (bind.bindType == SDL_CONTROLLER_BINDTYPE_BUTTON) + { + temp.append(QString("Button %1").arg(bind.value.button + offset)); + } + else if (bind.bindType == SDL_CONTROLLER_BINDTYPE_AXIS) + { + temp.append(QString("Axis %1").arg(bind.value.axis + offset)); + } + } + return temp; +} + +QString GameController::getBindStringForButton(int index, bool trueIndex) +{ + QString temp; + SDL_GameControllerButtonBind bind = + SDL_GameControllerGetBindForButton(controller, + static_cast(index)); + + if (bind.bindType != SDL_CONTROLLER_BINDTYPE_NONE) + { + int offset = trueIndex ? 0 : 1; + + if (bind.bindType == SDL_CONTROLLER_BINDTYPE_BUTTON) + { + temp.append(QString("Button %1").arg(bind.value.button + offset)); + } + else if (bind.bindType == SDL_CONTROLLER_BINDTYPE_AXIS) + { + temp.append(QString("Axis %1").arg(bind.value.axis + offset)); + } + else if (bind.bindType == SDL_CONTROLLER_BINDTYPE_HAT) + { + temp.append(QString("Hat %1.%2").arg(bind.value.hat.hat + offset) + .arg(bind.value.hat.hat_mask)); + } + } + return temp; +} + +SDL_GameControllerButtonBind GameController::getBindForAxis(int index) +{ + SDL_GameControllerButtonBind bind = SDL_GameControllerGetBindForAxis(controller, (SDL_GameControllerAxis)index); + return bind; +} + +SDL_GameControllerButtonBind GameController::getBindForButton(int index) +{ + SDL_GameControllerButtonBind bind = SDL_GameControllerGetBindForButton(controller, (SDL_GameControllerButton)index); + return bind; +} + +void GameController::buttonClickEvent(int buttonindex) +{ + SDL_GameControllerButtonBind bind = getBindForButton(static_cast(buttonindex)); + if (bind.bindType != SDL_CONTROLLER_BINDTYPE_NONE) + { + if (bind.bindType == SDL_CONTROLLER_BINDTYPE_AXIS) + { + //emit rawAxisButtonClick(bind.value.axis, 0); + //emit rawAxisActivated(bind.value.axis, JoyAxis::AXISMAX); + } + else if (bind.bindType == SDL_CONTROLLER_BINDTYPE_BUTTON) + { + //emit rawButtonClick(bind.value.button); + } + else if (bind.bindType == SDL_CONTROLLER_BINDTYPE_HAT) + { + //emit rawDPadButtonClick(bind.value.hat.hat, bind.value.hat.hat_mask); + } + } +} + +void GameController::buttonReleaseEvent(int buttonindex) +{ + SDL_GameControllerButtonBind bind = getBindForButton(static_cast(buttonindex)); + if (bind.bindType != SDL_CONTROLLER_BINDTYPE_NONE) + { + if (bind.bindType == SDL_CONTROLLER_BINDTYPE_AXIS) + { + //emit rawAxisButtonRelease(bind.value.axis, 0); + } + else if (bind.bindType == SDL_CONTROLLER_BINDTYPE_BUTTON) + { + //emit rawButtonRelease(bind.value.button); + } + else if (bind.bindType == SDL_CONTROLLER_BINDTYPE_HAT) + { + //emit rawDPadButtonRelease(bind.value.hat.hat, bind.value.hat.hat_mask); + } + } +} + +void GameController::axisActivatedEvent(int setindex, int axisindex, int value) +{ + Q_UNUSED(setindex); + + SDL_GameControllerButtonBind bind = getBindForAxis(static_cast(axisindex)); + if (bind.bindType != SDL_CONTROLLER_BINDTYPE_NONE) + { + if (bind.bindType == SDL_CONTROLLER_BINDTYPE_AXIS) + { + //emit rawAxisButtonClick(bind.value.axis, 0); + //emit rawAxisActivated(bind.value.axis, value); + } + else if (bind.bindType == SDL_CONTROLLER_BINDTYPE_BUTTON) + { + //emit rawButtonClick(bind.value.button); + } + else if (bind.bindType == SDL_CONTROLLER_BINDTYPE_HAT) + { + //emit rawDPadButtonClick(bind.value.hat.hat, bind.value.hat.hat_mask); + } + } +} + +SDL_JoystickID GameController::getSDLJoystickID() +{ + return joystickID; +} + +/** + * @brief Check if device is using the SDL Game Controller API + * @return Status showing if device is using the Game Controller API + */ +bool GameController::isGameController() +{ + return true; +} + +/** + * @brief Check if GUID passed matches the expected GUID for a device. + * Needed for xinput GUID abstraction. + * @param GUID string + * @return if GUID is considered a match. + */ +bool GameController::isRelevantGUID(QString tempGUID) +{ + bool result = false; + + if (InputDevice::isRelevantGUID(tempGUID))// || isEmptyGUID(tempGUID)) + { + result = true; + } + + return result; +} + +void GameController::rawButtonEvent(int index, bool pressed) +{ + bool knownbutton = rawbuttons.contains(index); + if (!knownbutton && pressed) + { + rawbuttons.insert(index, pressed); + emit rawButtonClick(index); + } + else if (knownbutton && !pressed) + { + rawbuttons.remove(index); + emit rawButtonRelease(index); + } +} + +void GameController::rawAxisEvent(int index, int value) +{ + bool knownaxis = axisvalues.contains(index); + + if (!knownaxis && fabs(value) > rawAxisDeadZone) + { + axisvalues.insert(index, value); + emit rawAxisActivated(index, value); + } + else if (knownaxis && fabs(value) < rawAxisDeadZone) + { + axisvalues.remove(index); + emit rawAxisReleased(index, value); + } + + emit rawAxisMoved(index, value); +} + +void GameController::rawDPadEvent(int index, int value) +{ + bool knowndpad = dpadvalues.contains(index); + if (!knowndpad && value != 0) + { + dpadvalues.insert(index, value); + emit rawDPadButtonClick(index, value); + } + else if (knowndpad && value == 0) + { + dpadvalues.remove(index); + emit rawDPadButtonRelease(index, value); + } +} diff --git a/src/gamecontroller/gamecontroller.h b/src/gamecontroller/gamecontroller.h new file mode 100644 index 0000000..5be50c7 --- /dev/null +++ b/src/gamecontroller/gamecontroller.h @@ -0,0 +1,87 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef GAMECONTROLLER_H +#define GAMECONTROLLER_H + +#include + +#include +#include + +#include +#include "gamecontrollerdpad.h" +#include "gamecontrollerset.h" + +class GameController : public InputDevice +{ + Q_OBJECT +public: + explicit GameController(SDL_GameController *controller, int deviceIndex, AntiMicroSettings *settings, QObject *parent = 0); + + virtual QString getName(); + virtual QString getSDLName(); + + // GUID available on SDL 2. + virtual QString getGUIDString(); + virtual QString getRawGUIDString(); + + virtual QString getXmlName(); + virtual bool isGameController(); + virtual void closeSDLDevice(); + virtual SDL_JoystickID getSDLJoystickID(); + + virtual int getNumberRawButtons(); + virtual int getNumberRawAxes(); + virtual int getNumberRawHats(); + + QString getBindStringForAxis(int index, bool trueIndex=true); + QString getBindStringForButton(int index, bool trueIndex=true); + + SDL_GameControllerButtonBind getBindForAxis(int index); + SDL_GameControllerButtonBind getBindForButton(int index); + + bool isRelevantGUID(QString tempGUID); + void rawButtonEvent(int index, bool pressed); + void rawAxisEvent(int index, int value); + void rawDPadEvent(int index, int value); + + QHash rawbuttons; + QHash axisvalues; + QHash dpadvalues; + + static const QString xmlName; + +protected: + void readJoystickConfig(QXmlStreamReader *xml); + + SDL_GameController *controller; + +signals: + + +public slots: + virtual void readConfig(QXmlStreamReader *xml); + virtual void writeConfig(QXmlStreamWriter *xml); + +protected slots: + virtual void axisActivatedEvent(int setindex, int axisindex, int value); + virtual void buttonClickEvent(int buttonindex); + virtual void buttonReleaseEvent(int buttonindex); +}; + +#endif // GAMECONTROLLER_H diff --git a/src/gamecontroller/gamecontrollerdpad.cpp b/src/gamecontroller/gamecontrollerdpad.cpp new file mode 100644 index 0000000..51d764d --- /dev/null +++ b/src/gamecontroller/gamecontrollerdpad.cpp @@ -0,0 +1,80 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "gamecontrollerdpad.h" + +const QString GameControllerDPad::xmlName = "dpad"; + +GameControllerDPad::GameControllerDPad(JoyButton *upButton, JoyButton *downButton, JoyButton *leftButton, JoyButton *rightButton, + int index, int originset, SetJoystick *parentSet, QObject *parent) : + VDPad(upButton, downButton, leftButton, rightButton, index, originset, parentSet, parent) +{ +} + +QString GameControllerDPad::getName(bool forceFullFormat, bool displayName) +{ + QString label; + + if (!dpadName.isEmpty() && displayName) + { + if (forceFullFormat) + { + label.append(tr("DPad")).append(" "); + } + + label.append(dpadName); + } + else if (!defaultDPadName.isEmpty()) + { + if (forceFullFormat) + { + label.append(tr("DPad")).append(" "); + } + + label.append(defaultDPadName); + } + else + { + label.append(tr("DPad")).append(" "); + label.append(QString::number(getRealJoyNumber())); + } + + return label; +} + +QString GameControllerDPad::getXmlName() +{ + return this->xmlName; +} + +void GameControllerDPad::readJoystickConfig(QXmlStreamReader *xml) +{ + if (xml->isStartElement() && xml->name() == VDPad::xmlName) + { + xml->readNextStartElement(); + while (!xml->atEnd() && (!xml->isEndElement() && xml->name() != VDPad::xmlName)) + { + bool found = readMainConfig(xml); + if (!found) + { + xml->skipCurrentElement(); + } + + xml->readNextStartElement(); + } + } +} diff --git a/src/gamecontroller/gamecontrollerdpad.h b/src/gamecontroller/gamecontrollerdpad.h new file mode 100644 index 0000000..8e12ab1 --- /dev/null +++ b/src/gamecontroller/gamecontrollerdpad.h @@ -0,0 +1,45 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef GAMECONTROLLERDPAD_H +#define GAMECONTROLLERDPAD_H + +#include + +#include "vdpad.h" + +class GameControllerDPad : public VDPad +{ + Q_OBJECT +public: + explicit GameControllerDPad(JoyButton *upButton, JoyButton *downButton, JoyButton *leftButton, JoyButton *rightButton, + int index, int originset, SetJoystick *parentSet, QObject *parent = 0); + + virtual QString getName(bool forceFullFormat, bool displayName); + virtual QString getXmlName(); + + void readJoystickConfig(QXmlStreamReader *xml); + + static const QString xmlName; + +signals: + +public slots: + +}; + +#endif // GAMECONTROLLERDPAD_H diff --git a/src/gamecontroller/gamecontrollerset.cpp b/src/gamecontroller/gamecontrollerset.cpp new file mode 100644 index 0000000..bdcd612 --- /dev/null +++ b/src/gamecontroller/gamecontrollerset.cpp @@ -0,0 +1,348 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +//#include + +#include "gamecontrollerset.h" +#include + +GameControllerSet::GameControllerSet(InputDevice *device, int index, QObject *parent) : + SetJoystick(device, index, false, parent) +{ + reset(); +} + +void GameControllerSet::reset() +{ + SetJoystick::reset(); + populateSticksDPad(); +} + +void GameControllerSet::populateSticksDPad() +{ + // Left Stick Assignment + JoyAxis *axisX = getJoyAxis(SDL_CONTROLLER_AXIS_LEFTX); + JoyAxis *axisY = getJoyAxis(SDL_CONTROLLER_AXIS_LEFTY); + JoyControlStick *stick1 = new JoyControlStick(axisX, axisY, 0, index, this); + //stick1->setStickDelay(10); + stick1->setDefaultStickName("L Stick"); + addControlStick(0, stick1); + + // Right Stick Assignment + axisX = getJoyAxis(SDL_CONTROLLER_AXIS_RIGHTX); + axisY = getJoyAxis(SDL_CONTROLLER_AXIS_RIGHTY); + JoyControlStick *stick2 = new JoyControlStick(axisX, axisY, 1, index, this); + stick2->setDefaultStickName("R Stick"); + addControlStick(1, stick2); + + // Assign DPad buttons as a virtual DPad. Allows rougelike controls + // to be assigned. + JoyButton *buttonUp = getJoyButton(SDL_CONTROLLER_BUTTON_DPAD_UP); + JoyButton *buttonDown = getJoyButton(SDL_CONTROLLER_BUTTON_DPAD_DOWN); + JoyButton *buttonLeft = getJoyButton(SDL_CONTROLLER_BUTTON_DPAD_LEFT); + JoyButton *buttonRight = getJoyButton(SDL_CONTROLLER_BUTTON_DPAD_RIGHT); + GameControllerDPad *controllerDPad = new GameControllerDPad(buttonUp, buttonDown, buttonLeft, buttonRight, 0, index, this, this); + controllerDPad->setDefaultDPadName("DPad"); + //controllerDPad->setDPadDelay(10); + addVDPad(0, controllerDPad); + + // Give default names to buttons + getJoyButton(SDL_CONTROLLER_BUTTON_A)->setDefaultButtonName("A"); + getJoyButton(SDL_CONTROLLER_BUTTON_B)->setDefaultButtonName("B"); + getJoyButton(SDL_CONTROLLER_BUTTON_X)->setDefaultButtonName("X"); + getJoyButton(SDL_CONTROLLER_BUTTON_Y)->setDefaultButtonName("Y"); + getJoyButton(SDL_CONTROLLER_BUTTON_BACK)->setDefaultButtonName(tr("Back")); + getJoyButton(SDL_CONTROLLER_BUTTON_GUIDE)->setDefaultButtonName(tr("Guide")); + getJoyButton(SDL_CONTROLLER_BUTTON_START)->setDefaultButtonName(tr("Start")); + getJoyButton(SDL_CONTROLLER_BUTTON_LEFTSTICK)->setDefaultButtonName(tr("LS Click")); + getJoyButton(SDL_CONTROLLER_BUTTON_RIGHTSTICK)->setDefaultButtonName(tr("RS Click")); + getJoyButton(SDL_CONTROLLER_BUTTON_LEFTSHOULDER)->setDefaultButtonName(tr("L Shoulder")); + getJoyButton(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER)->setDefaultButtonName(tr("R Shoulder")); + + // Give default names to triggers + getJoyAxis(SDL_CONTROLLER_AXIS_TRIGGERLEFT)->setDefaultAxisName(tr("L Trigger")); + getJoyAxis(SDL_CONTROLLER_AXIS_TRIGGERRIGHT)->setDefaultAxisName(tr("R Trigger")); +} + +void GameControllerSet::readJoystickConfig(QXmlStreamReader *xml, + QHash &buttons, + QHash &axes, + QList &hatButtons) +{ + if (xml->isStartElement() && xml->name() == "set") + { + xml->readNextStartElement(); + + while (!xml->atEnd() && (!xml->isEndElement() && xml->name() != "set")) + { + bool dpadExists = false; + bool vdpadExists = false; + + if (xml->name() == "button" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + JoyButton *button = 0; + if (buttons.contains(index-1)) + { + SDL_GameControllerButton current = buttons.value(index-1); + button = getJoyButton(current); + } + + if (button) + { + button->readConfig(xml); + } + else + { + xml->skipCurrentElement(); + } + } + else if (xml->name() == "axis" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + GameControllerTrigger *trigger = 0; + if (axes.contains(index-1)) + { + SDL_GameControllerAxis current = axes.value(index-1); + trigger = static_cast(getJoyAxis((int)current)); + } + + if (trigger) + { + trigger->readJoystickConfig(xml); + } + else + { + xml->skipCurrentElement(); + } + } + else if (xml->name() == "dpad" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + index = index - 1; + bool found = false; + QListIterator iter(hatButtons); + SDL_GameControllerButtonBind current; + while (iter.hasNext()) + { + current = iter.next(); + if (current.value.hat.hat == index) + { + found = true; + iter.toBack(); + } + } + + VDPad *dpad = 0; + if (found) + { + dpad = getVDPad(0); + } + + if (dpad && !vdpadExists) + { + dpadExists = true; + dpad->readConfig(xml); + } + else + { + xml->skipCurrentElement(); + } + } + else if (xml->name() == "stick" && xml->isStartElement()) + { + int stickIndex = xml->attributes().value("index").toString().toInt(); + + if (stickIndex > 0) + { + stickIndex -= 1; + JoyControlStick *stick = getJoyStick(stickIndex); + if (stick) + { + stick->readConfig(xml); + } + else + { + xml->skipCurrentElement(); + } + } + else + { + xml->skipCurrentElement(); + } + } + else if (xml->name() == "vdpad" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + index = index - 1; + bool found = false; + QListIterator iter(hatButtons); + SDL_GameControllerButtonBind current; + while (iter.hasNext()) + { + current = iter.next(); + if (current.value.hat.hat == index) + { + found = true; + iter.toBack(); + } + } + + VDPad *dpad = 0; + if (found) + { + dpad = getVDPad(0); + } + + if (dpad && !dpadExists) + { + vdpadExists = true; + + dpad->readConfig(xml); + } + else + { + xml->skipCurrentElement(); + } + } + else if (xml->name() == "name" && xml->isStartElement()) + { + QString temptext = xml->readElementText(); + if (!temptext.isEmpty()) + { + setName(temptext); + } + } + else + { + // If none of the above, skip the element + xml->skipCurrentElement(); + } + + xml->readNextStartElement(); + } + } +} + +void GameControllerSet::readConfig(QXmlStreamReader *xml) +{ + if (xml->isStartElement() && xml->name() == "set") + { + xml->readNextStartElement(); + while (!xml->atEnd() && (!xml->isEndElement() && xml->name() != "set")) + { + if (xml->name() == "button" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + JoyButton *button = getJoyButton(index-1); + if (button) + { + button->readConfig(xml); + } + else + { + xml->skipCurrentElement(); + } + } + else if (xml->name() == "trigger" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + GameControllerTrigger *axis = qobject_cast(getJoyAxis((index-1) + SDL_CONTROLLER_AXIS_TRIGGERLEFT)); + if (axis) + { + axis->readConfig(xml); + } + else + { + xml->skipCurrentElement(); + } + } + else if (xml->name() == "stick" && xml->isStartElement()) + { + int stickIndex = xml->attributes().value("index").toString().toInt(); + + if (stickIndex > 0) + { + stickIndex -= 1; + JoyControlStick *stick = getJoyStick(stickIndex); + if (stick) + { + stick->readConfig(xml); + } + else + { + xml->skipCurrentElement(); + } + } + else + { + xml->skipCurrentElement(); + } + } + else if (xml->name() == "dpad" && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + GameControllerDPad *vdpad = qobject_cast(getVDPad(index-1)); + if (vdpad) + { + vdpad->readConfig(xml); + } + else + { + xml->skipCurrentElement(); + } + } + else if (xml->name() == "name" && xml->isStartElement()) + { + QString temptext = xml->readElementText(); + if (!temptext.isEmpty()) + { + setName(temptext); + } + } + else + { + // If none of the above, skip the element + xml->skipCurrentElement(); + } + + xml->readNextStartElement(); + } + } +} + +void GameControllerSet::refreshAxes() +{ + deleteAxes(); + + for (int i=0; i < device->getNumberRawAxes(); i++) + { + if (i == SDL_CONTROLLER_AXIS_TRIGGERLEFT || + i == SDL_CONTROLLER_AXIS_TRIGGERRIGHT) + { + GameControllerTrigger *trigger = new GameControllerTrigger(i, index, this, this); + axes.insert(i, trigger); + enableAxisConnections(trigger); + } + else + { + JoyAxis *axis = new JoyAxis(i, index, this, this); + axes.insert(i, axis); + enableAxisConnections(axis); + } + } +} diff --git a/src/gamecontroller/gamecontrollerset.h b/src/gamecontroller/gamecontrollerset.h new file mode 100644 index 0000000..3ee6670 --- /dev/null +++ b/src/gamecontroller/gamecontrollerset.h @@ -0,0 +1,55 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef GAMECONTROLLERSET_H +#define GAMECONTROLLERSET_H + +#include +#include +#include +#include + +#include + +#include +#include "gamecontrollerdpad.h" +#include "gamecontrollertrigger.h" + +class GameControllerSet : public SetJoystick +{ + Q_OBJECT +public: + explicit GameControllerSet(InputDevice *device, int index, QObject *parent = 0); + + virtual void refreshAxes(); + + virtual void readConfig(QXmlStreamReader *xml); + virtual void readJoystickConfig(QXmlStreamReader *xml, + QHash &buttons, + QHash &axes, + QList &hatButtons); + +protected: + void populateSticksDPad(); + +signals: + +public slots: + virtual void reset(); +}; + +#endif // GAMECONTROLLERSET_H diff --git a/src/gamecontroller/gamecontrollertrigger.cpp b/src/gamecontroller/gamecontrollertrigger.cpp new file mode 100644 index 0000000..6b8104b --- /dev/null +++ b/src/gamecontroller/gamecontrollertrigger.cpp @@ -0,0 +1,199 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +//#include + +#include "gamecontrollertrigger.h" + +const int GameControllerTrigger::AXISDEADZONE = 2000; +const int GameControllerTrigger::AXISMAXZONE = 32000; +const GameControllerTrigger::ThrottleTypes GameControllerTrigger::DEFAULTTHROTTLE = GameControllerTrigger::PositiveHalfThrottle; + +const QString GameControllerTrigger::xmlName = "trigger"; + +GameControllerTrigger::GameControllerTrigger(int index, int originset, SetJoystick *parentSet, QObject *parent) : + JoyAxis(index, originset, parentSet, parent) +{ + naxisbutton = new GameControllerTriggerButton(this, 0, originset, parentSet, this); + paxisbutton = new GameControllerTriggerButton(this, 1, originset, parentSet, this); + reset(index); +} + +QString GameControllerTrigger::getXmlName() +{ + return this->xmlName; +} + +QString GameControllerTrigger::getPartialName(bool forceFullFormat, bool displayNames) +{ + QString label; + + if (!axisName.isEmpty() && displayNames) + { + label.append(axisName); + + if (forceFullFormat) + { + label.append(" ").append(tr("Trigger")); + } + } + else if (!defaultAxisName.isEmpty()) + { + label.append(defaultAxisName); + + if (forceFullFormat) + { + label.append(" ").append(tr("Trigger")); + } + } + else + { + label.append(tr("Trigger")).append(" "); + label.append(QString::number(getRealJoyIndex() - SDL_CONTROLLER_AXIS_TRIGGERLEFT)); + } + + return label; +} + +void GameControllerTrigger::readJoystickConfig(QXmlStreamReader *xml) +{ + if (xml->isStartElement() && xml->name() == JoyAxis::xmlName) + { + xml->readNextStartElement(); + while (!xml->atEnd() && (!xml->isEndElement() && xml->name() != JoyAxis::xmlName)) + { + bool found = readMainConfig(xml); + if (!found && xml->name() == JoyAxisButton::xmlName && xml->isStartElement()) + { + int index = xml->attributes().value("index").toString().toInt(); + if (index == 1) + { + found = true; + GameControllerTriggerButton *triggerButton = + static_cast(naxisbutton); + triggerButton->readJoystickConfig(xml); + } + else if (index == 2) + { + found = true; + GameControllerTriggerButton *triggerButton = + static_cast(paxisbutton); + triggerButton->readJoystickConfig(xml); + } + } + + if (!found) + { + xml->skipCurrentElement(); + } + + xml->readNextStartElement(); + } + } + + if (this->throttle != PositiveHalfThrottle) + { + this->setThrottle(PositiveHalfThrottle); + + setCurrentRawValue(currentThrottledDeadValue); + currentThrottledValue = calculateThrottledValue(currentRawValue); + } +} + +void GameControllerTrigger::correctJoystickThrottle() +{ + if (this->throttle != PositiveHalfThrottle) + { + this->setThrottle(PositiveHalfThrottle); + + setCurrentRawValue(currentThrottledDeadValue); + currentThrottledValue = calculateThrottledValue(currentRawValue); + } +} + +void GameControllerTrigger::writeConfig(QXmlStreamWriter *xml) +{ + bool currentlyDefault = isDefault(); + + xml->writeStartElement(getXmlName()); + xml->writeAttribute("index", QString::number((index+1)-SDL_CONTROLLER_AXIS_TRIGGERLEFT)); + + if (!currentlyDefault) + { + if (deadZone != AXISDEADZONE) + { + xml->writeTextElement("deadZone", QString::number(deadZone)); + } + + if (maxZoneValue != AXISMAXZONE) + { + xml->writeTextElement("maxZone", QString::number(maxZoneValue)); + } + } + + //if (throttle != DEFAULTTHROTTLE) + //{ + xml->writeStartElement("throttle"); + + if (throttle == JoyAxis::NegativeHalfThrottle) + { + xml->writeCharacters("negativehalf"); + } + else if (throttle == JoyAxis::NegativeThrottle) + { + xml->writeCharacters("negative"); + } + else if (throttle == JoyAxis::NormalThrottle) + { + xml->writeCharacters("normal"); + } + else if (throttle == JoyAxis::PositiveThrottle) + { + xml->writeCharacters("positive"); + } + else if (throttle == JoyAxis::PositiveHalfThrottle) + { + xml->writeCharacters("positivehalf"); + } + + xml->writeEndElement(); + //} + + if (!currentlyDefault) + { + naxisbutton->writeConfig(xml); + paxisbutton->writeConfig(xml); + } + + + xml->writeEndElement(); +} + +int GameControllerTrigger::getDefaultDeadZone() +{ + return this->AXISDEADZONE; +} + +int GameControllerTrigger::getDefaultMaxZone() +{ + return this->AXISMAXZONE; +} + +JoyAxis::ThrottleTypes GameControllerTrigger::getDefaultThrottle() +{ + return (ThrottleTypes)this->DEFAULTTHROTTLE; +} diff --git a/src/gamecontroller/gamecontrollertrigger.h b/src/gamecontroller/gamecontrollertrigger.h new file mode 100644 index 0000000..8663e4d --- /dev/null +++ b/src/gamecontroller/gamecontrollertrigger.h @@ -0,0 +1,63 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef GAMECONTROLLERTRIGGER_H +#define GAMECONTROLLERTRIGGER_H + +#include +#include +#include +#include + +#include + +#include "gamecontrollertriggerbutton.h" +#include + +class GameControllerTrigger : public JoyAxis +{ + Q_OBJECT +public: + explicit GameControllerTrigger(int index, int originset, SetJoystick *parentSet, QObject *parent = 0); + + virtual QString getXmlName(); + virtual QString getPartialName(bool forceFullFormat, bool displayNames); + + virtual int getDefaultDeadZone(); + virtual int getDefaultMaxZone(); + virtual ThrottleTypes getDefaultThrottle(); + + void readJoystickConfig(QXmlStreamReader *xml); + + virtual void writeConfig(QXmlStreamWriter *xml); + + static const int AXISDEADZONE; + static const int AXISMAXZONE; + static const ThrottleTypes DEFAULTTHROTTLE; + + static const QString xmlName; + +protected: + void correctJoystickThrottle(); + +signals: + +public slots: + +}; + +#endif // GAMECONTROLLERTRIGGER_H diff --git a/src/gamecontroller/gamecontrollertriggerbutton.cpp b/src/gamecontroller/gamecontrollertriggerbutton.cpp new file mode 100644 index 0000000..b40c1db --- /dev/null +++ b/src/gamecontroller/gamecontrollertriggerbutton.cpp @@ -0,0 +1,55 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "gamecontrollertriggerbutton.h" + +const QString GameControllerTriggerButton::xmlName = "triggerbutton"; + +GameControllerTriggerButton::GameControllerTriggerButton(JoyAxis *axis, int index, int originset, SetJoystick *parentSet, QObject *parent) : + JoyAxisButton(axis, index, originset, parentSet, parent) +{ +} + +QString GameControllerTriggerButton::getXmlName() +{ + return this->xmlName; +} + +void GameControllerTriggerButton::readJoystickConfig(QXmlStreamReader *xml) +{ + if (xml->isStartElement() && xml->name() == JoyAxisButton::xmlName) + { + disconnect(this, SIGNAL(slotsChanged()), parentSet->getInputDevice(), SLOT(profileEdited())); + + xml->readNextStartElement(); + while (!xml->atEnd() && (!xml->isEndElement() && xml->name() != JoyAxisButton::xmlName)) + { + bool found = readButtonConfig(xml); + if (!found) + { + xml->skipCurrentElement(); + } + + xml->readNextStartElement(); + } + + connect(this, SIGNAL(slotsChanged()), parentSet->getInputDevice(), SLOT(profileEdited())); + } +} diff --git a/src/gamecontroller/gamecontrollertriggerbutton.h b/src/gamecontroller/gamecontrollertriggerbutton.h new file mode 100644 index 0000000..6c617da --- /dev/null +++ b/src/gamecontroller/gamecontrollertriggerbutton.h @@ -0,0 +1,43 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef GAMECONTROLLERBUTTON_H +#define GAMECONTROLLERBUTTON_H + +#include +#include + +#include + +class GameControllerTriggerButton : public JoyAxisButton +{ + Q_OBJECT +public: + explicit GameControllerTriggerButton(JoyAxis *axis, int index, int originset, SetJoystick *parentSet, QObject *parent = 0); + + virtual QString getXmlName(); + void readJoystickConfig(QXmlStreamReader *xml); + + static const QString xmlName; + +signals: + +public slots: + +}; + +#endif // GAMECONTROLLERBUTTON_H diff --git a/src/gamecontrollerexample.cpp b/src/gamecontrollerexample.cpp new file mode 100644 index 0000000..ed5f232 --- /dev/null +++ b/src/gamecontrollerexample.cpp @@ -0,0 +1,104 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include "gamecontrollerexample.h" + +struct ButtonImagePlacement { + int x; + int y; + GameControllerExample::ButtonType buttontype; +}; + +static ButtonImagePlacement buttonLocations[] = { + {225, 98, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_A + {252, 77, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_B + {200, 77, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_X + {227, 59, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_Y + {102, 77, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_BACK + {169, 77, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_START + {137, 77, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_GUIDE + {45, 23, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_LEFTSHOULDER + {232, 21, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_RIGHTSHOULDER + {44, 90, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_LEFTSTICK + {179, 135, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_RIGHTSTICK + + {44, 90, GameControllerExample::AxisX}, // SDL_CONTROLLER_AXIS_LEFTX + {44, 90, GameControllerExample::AxisY}, // SDL_CONTROLLER_AXIS_LEFTY + {179, 135, GameControllerExample::AxisX}, // SDL_CONTROLLER_AXIS_RIGHTX + {179, 135, GameControllerExample::AxisY}, // SDL_CONTROLLER_AXIS_RIGHTY + + {53, 0, GameControllerExample::Button}, // SDL_CONTROLLER_AXIS_TRIGGERLEFT + {220, 0, GameControllerExample::Button}, // SDL_CONTROLLER_AXIS_TRIGGERRIGHT + + {90, 110, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_DPAD_UP + {68, 127, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_DPAD_DOWN + {90, 146, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_DPAD_LEFT + {109, 127, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_DPAD_RIGHT +}; + +GameControllerExample::GameControllerExample(QWidget *parent) : + QWidget(parent) +{ + controllerimage = QImage(":/images/controllermap.png"); + buttonimage = QImage(":/images/button.png"); + axisimage = QImage(":/images/axis.png"); + + QTransform myTransform; + myTransform.rotate(90); + rotatedaxisimage = axisimage.transformed(myTransform); + currentIndex = 0; + + connect(this, SIGNAL(indexUpdated(int)), this, SLOT(update())); +} + +void GameControllerExample::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + + QPainter paint(this); + paint.drawImage(controllerimage.rect(), controllerimage); + ButtonImagePlacement current = buttonLocations[currentIndex]; + + paint.setOpacity(0.85); + if (current.buttontype == Button) + { + paint.drawImage(QRect(current.x, current.y, buttonimage.width(), buttonimage.height()), buttonimage); + } + else if (current.buttontype == AxisX) + { + paint.drawImage(QRect(current.x, current.y, axisimage.width(), axisimage.height()), axisimage); + } + else if (current.buttontype == AxisY) + { + paint.drawImage(QRect(current.x, current.y, rotatedaxisimage.width(), rotatedaxisimage.height()), rotatedaxisimage); + } + + paint.setOpacity(1.0); +} + +void GameControllerExample::setActiveButton(int button) +{ + if (button >= 0 && button <= MAXBUTTONINDEX) + { + currentIndex = button; + emit indexUpdated(button); + } +} diff --git a/src/gamecontrollerexample.h b/src/gamecontrollerexample.h new file mode 100644 index 0000000..3a5a269 --- /dev/null +++ b/src/gamecontrollerexample.h @@ -0,0 +1,52 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef GAMECONTROLLEREXAMPLE_H +#define GAMECONTROLLEREXAMPLE_H + +#include +#include + +class GameControllerExample : public QWidget +{ + Q_OBJECT +public: + explicit GameControllerExample(QWidget *parent = 0); + + enum ButtonType { + Button, AxisX, AxisY, + }; + + static const unsigned int MAXBUTTONINDEX = 20; + +protected: + virtual void paintEvent(QPaintEvent *event); + + QImage controllerimage; + QImage buttonimage; + QImage axisimage; + QImage rotatedaxisimage; + int currentIndex; + +signals: + void indexUpdated(int index); + +public slots: + void setActiveButton(int button); +}; + +#endif // GAMECONTROLLEREXAMPLE_H diff --git a/src/gamecontrollermappingdialog.cpp b/src/gamecontrollermappingdialog.cpp new file mode 100644 index 0000000..dfd4126 --- /dev/null +++ b/src/gamecontrollermappingdialog.cpp @@ -0,0 +1,657 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gamecontrollermappingdialog.h" +#include "ui_gamecontrollermappingdialog.h" + +static QHash initAliases() +{ + QHash temp; + temp.insert(0, "a"); + temp.insert(1, "b"); + temp.insert(2, "x"); + temp.insert(3, "y"); + temp.insert(4, "back"); + temp.insert(5, "start"); + temp.insert(6, "guide"); + temp.insert(7, "leftshoulder"); + temp.insert(8, "rightshoulder"); + temp.insert(9, "leftstick"); + temp.insert(10, "rightstick"); + temp.insert(11, "leftx"); + temp.insert(12, "lefty"); + temp.insert(13, "rightx"); + temp.insert(14, "righty"); + temp.insert(15, "lefttrigger"); + temp.insert(16, "righttrigger"); + temp.insert(17, "dpup"); + temp.insert(18, "dpleft"); + temp.insert(19, "dpdown"); + temp.insert(20, "dpright"); + return temp; +} + +static QHash initButtonPlacement() +{ + QHash temp; + temp.insert(SDL_CONTROLLER_BUTTON_A, 0); + temp.insert(SDL_CONTROLLER_BUTTON_B, 1); + temp.insert(SDL_CONTROLLER_BUTTON_X, 2); + temp.insert(SDL_CONTROLLER_BUTTON_Y, 3); + temp.insert(SDL_CONTROLLER_BUTTON_BACK, 4); + temp.insert(SDL_CONTROLLER_BUTTON_START, 5); + temp.insert(SDL_CONTROLLER_BUTTON_GUIDE, 6); + temp.insert(SDL_CONTROLLER_BUTTON_LEFTSHOULDER, 7); + temp.insert(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, 8); + temp.insert(SDL_CONTROLLER_BUTTON_LEFTSTICK, 9); + temp.insert(SDL_CONTROLLER_BUTTON_RIGHTSTICK, 10); + temp.insert(SDL_CONTROLLER_BUTTON_DPAD_UP, 17); + temp.insert(SDL_CONTROLLER_BUTTON_DPAD_LEFT, 18); + temp.insert(SDL_CONTROLLER_BUTTON_DPAD_DOWN, 19); + temp.insert(SDL_CONTROLLER_BUTTON_DPAD_RIGHT, 20); + return temp; +} + +static QHash initAxisPlacement() +{ + QHash temp; + temp.insert(SDL_CONTROLLER_AXIS_LEFTX, 11); + temp.insert(SDL_CONTROLLER_AXIS_LEFTY, 12); + temp.insert(SDL_CONTROLLER_AXIS_RIGHTX, 13); + temp.insert(SDL_CONTROLLER_AXIS_RIGHTY, 14); + temp.insert(SDL_CONTROLLER_AXIS_TRIGGERLEFT, 15); + temp.insert(SDL_CONTROLLER_AXIS_TRIGGERRIGHT, 16); + return temp; +} + +QHash GameControllerMappingDialog::tempaliases = initAliases(); + +QHash GameControllerMappingDialog::buttonPlacement = initButtonPlacement(); +QHash GameControllerMappingDialog::axisPlacement = initAxisPlacement(); + +GameControllerMappingDialog::GameControllerMappingDialog(InputDevice *device, + AntiMicroSettings *settings, + QWidget *parent) : + QDialog(parent), + ui(new Ui::GameControllerMappingDialog), + helper(device) +{ + ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + + buttonGrabs = 0; + usingGameController = false; + + this->device = device; + this->settings = settings; + + helper.moveToThread(device->thread()); + + PadderCommon::lockInputDevices(); + + QMetaObject::invokeMethod(device, "haltServices"); + QMetaObject::invokeMethod(&helper, "setupDeadZones", Qt::BlockingQueuedConnection); + + GameController *controller = qobject_cast(device); + if (controller) + { + usingGameController = true; + populateGameControllerBindings(controller); + ui->mappingStringPlainTextEdit->document()->setPlainText(generateSDLMappingString()); + } + + QString tempWindowTitle = QString(tr("Game Controller Mapping (%1) (#%2)")).arg(device->getSDLName()) + .arg(device->getRealJoyNumber()); + setWindowTitle(tempWindowTitle); + + enableDeviceConnections(); + + ui->buttonMappingTableWidget->setCurrentCell(0, 0); + + ui->axisDeadZoneComboBox->clear(); + populateAxisDeadZoneComboBox(); + + currentDeadZoneValue = 20000; + int index = ui->axisDeadZoneComboBox->findData(currentDeadZoneValue); + if (index != -1) + { + ui->axisDeadZoneComboBox->setCurrentIndex(index); + } + + connect(device, SIGNAL(destroyed()), this, SLOT(obliterate())); + connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(saveChanges())); + connect(ui->buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(discardMapping(QAbstractButton*))); + connect(ui->buttonMappingTableWidget, SIGNAL(itemSelectionChanged()), this, SLOT(changeButtonDisplay())); + connect(ui->axisDeadZoneComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeAxisDeadZone(int))); + connect(this, SIGNAL(finished(int)), this, SLOT(enableButtonEvents(int))); + + PadderCommon::unlockInputDevices(); +} + +GameControllerMappingDialog::~GameControllerMappingDialog() +{ + delete ui; +} + +void GameControllerMappingDialog::buttonAssign(int buttonindex) +{ + // Only perform assignment if no other control is currently active. + if (ui->buttonMappingTableWidget->currentRow() > -1) + { + + QTableWidgetItem* item = ui->buttonMappingTableWidget->currentItem(); + int column = ui->buttonMappingTableWidget->currentColumn(); + int row = ui->buttonMappingTableWidget->currentRow(); + + if (!item) + { + item = new QTableWidgetItem(QString("Button %1").arg(buttonindex+1)); + ui->buttonMappingTableWidget->setItem(row, column, item); + } + + QList templist; + templist.append(QVariant(0)); + templist.append(QVariant(buttonindex)); + QAbstractItemModel *model = ui->buttonMappingTableWidget->model(); + QModelIndexList matchlist = model->match(model->index(0,0), Qt::UserRole, templist, 1, Qt::MatchExactly); + foreach (const QModelIndex &index, matchlist) { + QTableWidgetItem *existingItem = ui->buttonMappingTableWidget->item(index.row(), index.column()); + if (existingItem) + { + existingItem->setText(""); + existingItem->setData(Qt::UserRole, QVariant()); + } + } + + QList tempvalue; + tempvalue.append(QVariant(0)); + tempvalue.append(QVariant(buttonindex)); + + item->setData(Qt::UserRole, tempvalue); + item->setText(QString("Button %1").arg(buttonindex+1)); + + if (row < ui->buttonMappingTableWidget->rowCount()-1) + { + ui->buttonMappingTableWidget->setCurrentCell(row+1, column); + } + + ui->mappingStringPlainTextEdit->document()->setPlainText(generateSDLMappingString()); + } +} + +void GameControllerMappingDialog::axisAssign(int axis, int value) +{ + bool skip = false; + bool change = true; + + if (usingGameController) + { + if (eventTriggerAxes.contains(axis) && value < -currentDeadZoneValue) + { + skip = true; + eventTriggerAxes.removeAll(axis); + } + } + + if (!skip && ui->buttonMappingTableWidget->currentRow() > -1) + { + QTableWidgetItem* item = ui->buttonMappingTableWidget->currentItem(); + int column = ui->buttonMappingTableWidget->currentColumn(); + int row = ui->buttonMappingTableWidget->currentRow(); + + if (row < 17) + { + if (usingGameController) + { + bool considerTrigger = (row == 15 || row == 16); + if (considerTrigger && value > currentDeadZoneValue && !eventTriggerAxes.contains(axis)) + { + eventTriggerAxes.append(axis); + } + else if (considerTrigger && value < currentDeadZoneValue) + { + skip = true; + } + } + + if (!skip) + { + if (!item) + { + item = new QTableWidgetItem(QString("Axis %1").arg(axis+1)); + ui->buttonMappingTableWidget->setItem(row, column, item); + } + + QList templist; + templist.append(QVariant(axis+1)); + templist.append(QVariant(0)); + QAbstractItemModel *model = ui->buttonMappingTableWidget->model(); + QModelIndexList matchlist = model->match(model->index(0,0), Qt::UserRole, templist, 1, Qt::MatchExactly); + foreach (const QModelIndex &index, matchlist) { + QTableWidgetItem *existingItem = ui->buttonMappingTableWidget->item(index.row(), index.column()); + if (existingItem) + { + existingItem->setText(""); + existingItem->setData(Qt::UserRole, QVariant()); + } + } + + QList tempvalue; + tempvalue.append(QVariant(axis+1)); + tempvalue.append(QVariant(0)); + + item->setData(Qt::UserRole, tempvalue); + item->setText(QString("Axis %1").arg(axis+1)); + + if (row < ui->buttonMappingTableWidget->rowCount()-1) + { + ui->buttonMappingTableWidget->setCurrentCell(row+1, column); + } + + ui->mappingStringPlainTextEdit->document()->setPlainText(generateSDLMappingString()); + } + } + + else + { + change = false; + skip = true; + } + } +} + +void GameControllerMappingDialog::dpadAssign(int dpad, int buttonindex) +{ + if (ui->buttonMappingTableWidget->currentRow() > -1) + { + if (buttonindex == 1 || buttonindex == 2 || + buttonindex == 4 || buttonindex == 8) + { + QTableWidgetItem* item = ui->buttonMappingTableWidget->currentItem(); + int column = ui->buttonMappingTableWidget->currentColumn(); + int row = ui->buttonMappingTableWidget->currentRow(); + + if (row <= 10 || row >= 17) + { + if (!item) + { + item = new QTableWidgetItem(QString("Hat %1.%2").arg(dpad+1).arg(buttonindex)); + ui->buttonMappingTableWidget->setItem(row, column, item); + } + + QList templist; + templist.append(QVariant(-dpad-1)); + templist.append(QVariant(buttonindex)); + QAbstractItemModel *model = ui->buttonMappingTableWidget->model(); + QModelIndexList matchlist = model->match(model->index(0,0), Qt::UserRole, templist, 1, Qt::MatchExactly); + foreach (const QModelIndex &index, matchlist) { + QTableWidgetItem *existingItem = ui->buttonMappingTableWidget->item(index.row(), index.column()); + if (existingItem) + { + existingItem->setText(""); + existingItem->setData(Qt::UserRole, QVariant()); + } + } + + QList tempvalue; + tempvalue.append(QVariant(-dpad-1)); + tempvalue.append(QVariant(buttonindex)); + + item->setData(Qt::UserRole, tempvalue); + item->setText(QString("Hat %1.%2").arg(dpad+1).arg(buttonindex)); + } + + if (row < ui->buttonMappingTableWidget->rowCount()-1) + { + ui->buttonMappingTableWidget->setCurrentCell(row+1, column); + } + + ui->mappingStringPlainTextEdit->document()->setPlainText(generateSDLMappingString()); + } + } +} + +void GameControllerMappingDialog::saveChanges() +{ + QString mappingString = generateSDLMappingString(); + + settings->getLock()->lock(); + + settings->setValue(QString("Mappings/").append(device->getGUIDString()), mappingString); + settings->setValue(QString("Mappings/%1%2").arg(device->getGUIDString()).arg("Disable"), "0"); + settings->sync(); + + bool displayMapping = settings->runtimeValue("DisplaySDLMapping", false).toBool(); + settings->getLock()->unlock(); + + if (displayMapping) + { + QTextStream out(stdout); + out << generateSDLMappingString(); + } + + emit mappingUpdate(mappingString, device); +} + +void GameControllerMappingDialog::populateGameControllerBindings(GameController *controller) +{ + if (controller) + { + for (int i = 0; i < controller->getNumberButtons(); i++) + { + int associatedRow = buttonPlacement.value((SDL_GameControllerButton)i); + SDL_GameControllerButtonBind bind = controller->getBindForButton(i); + QString temptext = bindingString(bind); + if (!temptext.isEmpty()) + { + QList tempvariant = bindingValues(bind); + QTableWidgetItem* item = new QTableWidgetItem(); + ui->buttonMappingTableWidget->setItem(associatedRow, 0, item); + item->setText(temptext); + item->setData(Qt::UserRole, tempvariant); + } + } + + for (int i = 0; i < controller->getNumberAxes(); i++) + { + int associatedRow = axisPlacement.value((SDL_GameControllerAxis)i); + SDL_GameControllerButtonBind bind = controller->getBindForAxis(i); + QString temptext = bindingString(bind); + if (!temptext.isEmpty()) + { + QList tempvariant = bindingValues(bind); + QTableWidgetItem* item = new QTableWidgetItem(); + ui->buttonMappingTableWidget->setItem(associatedRow, 0, item); + item->setText(temptext); + item->setData(Qt::UserRole, tempvariant); + } + } + } +} + +QString GameControllerMappingDialog::bindingString(SDL_GameControllerButtonBind bind) +{ + QString temp; + + if (bind.bindType != SDL_CONTROLLER_BINDTYPE_NONE) + { + if (bind.bindType == SDL_CONTROLLER_BINDTYPE_BUTTON) + { + temp.append(QString("Button %1").arg(bind.value.button+1)); + } + else if (bind.bindType == SDL_CONTROLLER_BINDTYPE_AXIS) + { + temp.append(QString("Axis %1").arg(bind.value.axis+1)); + } + else if (bind.bindType == SDL_CONTROLLER_BINDTYPE_HAT) + { + temp.append(QString("Hat %1.%2").arg(bind.value.hat.hat+1) + .arg(bind.value.hat.hat_mask)); + } + } + + return temp; +} + +QList GameControllerMappingDialog::bindingValues(SDL_GameControllerButtonBind bind) +{ + QList temp; + + if (bind.bindType != SDL_CONTROLLER_BINDTYPE_NONE) + { + if (bind.bindType == SDL_CONTROLLER_BINDTYPE_BUTTON) + { + temp.append(QVariant(0)); + temp.append(QVariant(bind.value.button)); + } + else if (bind.bindType == SDL_CONTROLLER_BINDTYPE_AXIS) + { + temp.append(QVariant(bind.value.axis+1)); + temp.append(QVariant(0)); + } + else if (bind.bindType == SDL_CONTROLLER_BINDTYPE_HAT) + { + temp.append(QVariant(-bind.value.hat.hat-1)); + temp.append(QVariant(bind.value.hat.hat_mask)); + } + } + + return temp; +} + +void GameControllerMappingDialog::discardMapping(QAbstractButton *button) +{ + disableDeviceConnections(); + QDialogButtonBox::ButtonRole currentRole = ui->buttonBox->buttonRole(button); + if (currentRole == QDialogButtonBox::DestructiveRole) + { + QMessageBox msgBox; + msgBox.setWindowTitle(tr("Discard Controller Mapping?")); + msgBox.setText(tr("Discard mapping for this controller?\n\nIf discarded, the controller will be reverted to a joystick once you refresh all joysticks.")); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel); + + int status = msgBox.exec(); + if (status == QMessageBox::Yes) + { + removeControllerMapping(); + close(); + } + else + { + enableDeviceConnections(); + } + } +} + +void GameControllerMappingDialog::removeControllerMapping() +{ + settings->getLock()->lock(); + + settings->beginGroup("Mappings"); + settings->remove(device->getGUIDString()); + settings->remove(QString("%1Disable").arg(device->getGUIDString())); + settings->endGroup(); + settings->sync(); + + settings->getLock()->unlock(); +} + +void GameControllerMappingDialog::enableDeviceConnections() +{ + connect(device, SIGNAL(rawButtonClick(int)), this, SLOT(buttonAssign(int))); + connect(device, SIGNAL(rawButtonRelease(int)), this, SLOT(buttonRelease(int))); + connect(device, SIGNAL(rawAxisMoved(int,int)), this, SLOT(updateLastAxisLineEditRaw(int,int))); + connect(device, SIGNAL(rawAxisActivated(int,int)), this, SLOT(axisAssign(int,int))); + connect(device, SIGNAL(rawAxisReleased(int,int)), this, SLOT(axisRelease(int,int))); + connect(device, SIGNAL(rawDPadButtonClick(int,int)), this, SLOT(dpadAssign(int,int))); + connect(device, SIGNAL(rawDPadButtonRelease(int,int)), this, SLOT(dpadRelease(int,int))); +} + +void GameControllerMappingDialog::disableDeviceConnections() +{ + disconnect(device, SIGNAL(rawButtonClick(int)), this, 0); + disconnect(device, SIGNAL(rawButtonRelease(int)), this, 0); + disconnect(device, SIGNAL(rawAxisMoved(int,int)), this, 0); + disconnect(device, SIGNAL(rawAxisActivated(int,int)), this, 0); + disconnect(device, SIGNAL(rawAxisReleased(int,int)), this, 0); + disconnect(device, SIGNAL(rawDPadButtonClick(int,int)), this, 0); + disconnect(device, SIGNAL(rawDPadButtonRelease(int,int)), this, 0); +} + +void GameControllerMappingDialog::enableButtonEvents(int code) +{ + Q_UNUSED(code); + + QMetaObject::invokeMethod(&helper, "restoreDeviceDeadZones", Qt::BlockingQueuedConnection); +} + +QString GameControllerMappingDialog::generateSDLMappingString() +{ + QStringList templist; + templist.append(device->getGUIDString()); + templist.append(device->getSDLName()); + templist.append(QString("platform:").append(device->getSDLPlatform())); + + for (int i=0; i < ui->buttonMappingTableWidget->rowCount(); i++) + { + QTableWidgetItem *item = ui->buttonMappingTableWidget->item(i, 0); + if (item) + { + QString mapNative; + QList tempassociation = item->data(Qt::UserRole).toList(); + if (tempassociation.size() == 2) + { + int bindingType = tempassociation.value(0).toInt(); + if (bindingType == 0) + { + mapNative.append("b"); + mapNative.append(QString::number(tempassociation.value(1).toInt())); + } + else if (bindingType > 0) + { + mapNative.append("a"); + mapNative.append(QString::number(tempassociation.value(0).toInt()-1)); + } + else if (bindingType < 0) + { + mapNative.append("h"); + mapNative.append(QString::number(tempassociation.value(0).toInt()+1)); + mapNative.append(".").append(QString::number(tempassociation.value(1).toInt())); + } + } + + if (!mapNative.isEmpty()) + { + QString sdlButtonName = tempaliases.value(i); + QString temp = QString("%1:%2").arg(sdlButtonName).arg(mapNative); + templist.append(temp); + } + } + } + + return templist.join(",").append(","); +} + +void GameControllerMappingDialog::obliterate() +{ + this->done(QDialogButtonBox::DestructiveRole); +} + +void GameControllerMappingDialog::changeButtonDisplay() +{ + + ui->gameControllerDisplayWidget->setActiveButton(ui->buttonMappingTableWidget->currentRow()); +} + +/** + * @brief TODO: Possibly remove. This was used for decrementing a reference + * count. + * @param axis + * @param value + */ +void GameControllerMappingDialog::axisRelease(int axis, int value) +{ + Q_UNUSED(axis); + Q_UNUSED(value); +} + +/** + * @brief TODO: Possibly remove. This was used for decrementing a reference + * count. + * @param buttonindex + */ +void GameControllerMappingDialog::buttonRelease(int buttonindex) +{ + Q_UNUSED(buttonindex); +} + +/** + * @brief TODO: Possibly remove. This was used for decrementing a reference + * count. + * @param dpad + * @param buttonindex + */ +void GameControllerMappingDialog::dpadRelease(int dpad, int buttonindex) +{ + Q_UNUSED(dpad); + Q_UNUSED(buttonindex); +} + +void GameControllerMappingDialog::populateAxisDeadZoneComboBox() +{ + for (int i=0; i < 28; i++) + { + unsigned int temp = (i * 1000) + 5000; + ui->axisDeadZoneComboBox->addItem(QString::number(temp), temp); + } +} + +void GameControllerMappingDialog::changeAxisDeadZone(int index) +{ + unsigned int value = ui->axisDeadZoneComboBox->itemData(index).toInt(); + if (value >= 5000 && value <= 32000) + { + QMetaObject::invokeMethod(&helper, "raiseDeadZones", Qt::BlockingQueuedConnection, + Q_ARG(int, value)); + currentDeadZoneValue = value; + } +} + +void GameControllerMappingDialog::updateLastAxisLineEdit(int value) +{ + if (abs(value) >= 5000) + { + JoyAxis *tempAxis = static_cast(sender()); + QString temp; + if (device->isGameController()) + { + GameController *controller = static_cast(device); + temp = QString("%1: %2").arg(controller->getBindStringForAxis(tempAxis->getIndex(), false)) + .arg(value); + } + else + { + temp = QString("Axis %1: %2").arg(tempAxis->getRealJoyIndex()) + .arg(value); + } + + ui->lastAxisEventLineEdit->setText(temp); + } +} + +void GameControllerMappingDialog::updateLastAxisLineEditRaw(int index, int value) +{ + if (abs(value) >= 5000) + { + QString temp; + temp = QString("Axis %1: %2").arg(index) + .arg(value); + + ui->lastAxisEventLineEdit->setText(temp); + } +} diff --git a/src/gamecontrollermappingdialog.h b/src/gamecontrollermappingdialog.h new file mode 100644 index 0000000..1e0166d --- /dev/null +++ b/src/gamecontrollermappingdialog.h @@ -0,0 +1,90 @@ +/* antimicro Gamepad to KB+M event mapper + * Copyright (C) 2015 Travis Nickles + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef GAMECONTROLLERMAPPINGDIALOG_H +#define GAMECONTROLLERMAPPINGDIALOG_H + +#include +#include +#include +#include + +#include "uihelpers/gamecontrollermappingdialoghelper.h" +#include "inputdevice.h" +#include "gamecontroller/gamecontroller.h" +#include "antimicrosettings.h" + +namespace Ui { +class GameControllerMappingDialog; +} + +class GameControllerMappingDialog : public QDialog +{ + Q_OBJECT + +public: + explicit GameControllerMappingDialog(InputDevice *device, AntiMicroSettings *settings, QWidget *parent = 0); + ~GameControllerMappingDialog(); + + static QHash tempaliases; + static QHash buttonPlacement; + static QHash axisPlacement; + +protected: + void populateGameControllerBindings(GameController *controller); + void removeControllerMapping(); + void enableDeviceConnections(); + void disableDeviceConnections(); + QString generateSDLMappingString(); + void populateAxisDeadZoneComboBox(); + + QString bindingString(SDL_GameControllerButtonBind bind); + QList bindingValues(SDL_GameControllerButtonBind bind); + + InputDevice *device; + AntiMicroSettings *settings; + unsigned int buttonGrabs; + QList eventTriggerAxes; + QList originalAxesDeadZones; + GameControllerMappingDialogHelper helper; + int currentDeadZoneValue; + bool usingGameController; + +private: + Ui::GameControllerMappingDialog *ui; + +signals: + void mappingUpdate(QString mapping, InputDevice *device); + +private slots: + void buttonAssign(int buttonindex); + void axisAssign(int axis, int value); + void dpadAssign(int dpad, int buttonindex); + void buttonRelease(int buttonindex); + void axisRelease(int axis, int value); + void dpadRelease(int dpad, int buttonindex); + void saveChanges(); + void discardMapping(QAbstractButton *button); + void enableButtonEvents(int code); + void obliterate(); + void changeButtonDisplay(); + void changeAxisDeadZone(int index); + void updateLastAxisLineEdit(int value); + void updateLastAxisLineEditRaw(int index, int value); +}; + +#endif // GAMECONTROLLERMAPPINGDIALOG_H diff --git a/src/gamecontrollermappingdialog.ui b/src/gamecontrollermappingdialog.ui new file mode 100644 index 0000000..4617ed5 --- /dev/null +++ b/src/gamecontrollermappingdialog.ui @@ -0,0 +1,445 @@ + + + GameControllerMappingDialog + + + + 0 + 0 + 918 + 600 + + + + + 600 + 400 + + + + Game Controller Mapping + + + + + + 40 + + + + + 20 + + + + + <html><head/><body><p>antimicro makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicro will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> + + + true + + + true + + + + + + + QFrame::Sunken + + + 1 + + + true + + + QAbstractItemView::NoEditTriggers + + + false + + + false + + + false + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectItems + + + Qt::ElideRight + + + true + + + Qt::SolidLine + + + false + + + true + + + true + + + 21 + + + 1 + + + true + + + false + + + 100 + + + true + + + true + + + true + + + false + + + 30 + + + true + + + 20 + + + false + + + false + + + + A + + + + + B + + + + + X + + + + + Y + + + + + Back + + + + + Start + + + + + Guide + + + + + Left Shoulder + + + + + Right Shoulder + + + + + Left Stick Click + + + + + Right Stick Click + + + + + Left Stick X + + + + + Left Stick Y + + + + + Right Stick X + + + + + Right Stick Y + + + + + Left Trigger + + + + + Right Trigger + + + + + DPad Up + + + + + DPad Left + + + + + DPad Down + + + + + DPad Right + + + + + Mapping + + + + + + + + + 75 + true + + + + SDL 2 Game Controller Mapping String + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 100 + + + + true + + + + + + + + + 20 + + + + + + 300 + 200 + + + + + + + + + + Last Axis Event: + + + + + + + true + + + + + + + Current Axis Detection Dead Zone: + + + + + + + + 5000 + + + + + 10000 + + + + + 15000 + + + + + 20000 + + + + + 25000 + + + + + 30000 + + + + + 32000 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close|QDialogButtonBox::Discard|QDialogButtonBox::Save + + + + + + + + GameControllerExample + QWidget +
    gamecontrollerexample.h
    + 1 +
    +
    + + + + buttonBox + accepted() + GameControllerMappingDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + GameControllerMappingDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +
    diff --git a/src/icons/16x16/actions/application-exit.png b/src/icons/16x16/actions/application-exit.png new file mode 100644 index 0000000000000000000000000000000000000000..1c6ddf04bf39d3d8bb039ec190dcda0db7aa8e0a GIT binary patch literal 781 zcmV+o1M>WdP))iKj(3$_nv!0#;d|YkaR;OXo%KEVxvjZ zSV+;5@K;ck*mx|&#@Z{P2(jr(l#sURMiYsOc!Wv_rXB4teaty?@3j~++VV@z<|N#UkB3CrL(Vbe9D^mxle`bv?3tQ@5Mn`$q`8^= z#*K_GTS5FKOH1cwf`$f;&CYP>N1o3e2RJr9K3p@XQYfV=D>Vk$*~yDsjzYYGUsFpF z*(}bMDA_sUBnC(q5NNIOeIH{Cxm*sjb`34puhRd1jK`xzww^vk@lV~YwE&40Le%hm zzm7L=-V&HP+S*$Q!w4Y+d+*(@Q5JqqVV$K^Dph(Qgdmg2kk3zG%a*2{+weS%bq+T* zxwv_xX-YXRR}B*V;r+)uw|Z|L%>S4GU~q8YAJO7Tk_6B5&H?FfrMB***8^k200000 LNkvXXu0mjfgPvB< literal 0 HcmV?d00001 diff --git a/src/icons/16x16/actions/archive-insert.png b/src/icons/16x16/actions/archive-insert.png new file mode 100644 index 0000000000000000000000000000000000000000..193c25c0d0cebaee4c0f68d98f9fe567cf3b57ec GIT binary patch literal 433 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=f!eQwFr$;k>lq?4V+omX|mX$dS6{%PE2D<;ickfNXOv5~p6lPl4rDN&$