class Titlebar(QWidget): # 默认基础样式参数 TITLE_TEXT_COLOR = "white" BGD_COLOR = "#28AAAA" TITLEBAR_HEIGHT = 30 ICON_SIZE = QSize(20, 20) MIN_BUTT_SIZE = QSize(27, 22) RET_BUTT_SIZE = QSize(27, 22) CLOSE_BUTT_SIZE = QSize(27, 22) TITLE_LABEL_NAME = "Titlebar_titleLabel" BACKGROUND_LABEL_NAME = "Titlebar_backgroundLabel" MIN_BUTT_NAME = "Titlebar_minimizeButton" RET_BUTT_NAME = "Titlebar_maximizeButton" CLOSE_BUTT_NAME = "Titlebar_closeButton" THEME_IMG_DIR = 'default' def __init__(self, parent, icon_name): super(Titlebar, self).__init__(parent) self.parentwidget = parent self.setFixedHeight(Titlebar.TITLEBAR_HEIGHT) self.icon_name = icon_name self.m_pBackgroundLabel = QLabel(self) self.m_pIconLabel = QLabel(self) self.m_pTitleLabel = QLabel(self) self.m_pMinimizeButton = QPushButton(self) self.m_pReturnButton = QPushButton(self) self.m_pCloseButton = QPushButton(self) self.m_pIconLabel.setFixedSize(Titlebar.ICON_SIZE) self.m_pIconLabel.setScaledContents(True) self.m_pTitleLabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.m_pBackgroundLabel.setObjectName(Titlebar.BACKGROUND_LABEL_NAME) # 三大金刚按钮大小 self.m_pReturnButton.setFixedSize(Titlebar.RET_BUTT_SIZE) self.m_pMinimizeButton.setFixedSize(Titlebar.MIN_BUTT_SIZE) self.m_pCloseButton.setFixedSize(Titlebar.CLOSE_BUTT_SIZE) # 统一设置ObjName self.m_pTitleLabel.setObjectName(Titlebar.TITLE_LABEL_NAME) self.m_pBackgroundLabel.resize(self.parentwidget.width(), Titlebar.TITLEBAR_HEIGHT) self.m_pReturnButton.setObjectName(Titlebar.RET_BUTT_NAME) self.m_pMinimizeButton.setObjectName(Titlebar.MIN_BUTT_NAME) self.m_pCloseButton.setObjectName(Titlebar.CLOSE_BUTT_NAME) # 布局 pLayout = QHBoxLayout(self) pLayout.addWidget(self.m_pIconLabel) pLayout.addSpacing(5) pLayout.addWidget(self.m_pTitleLabel) pLayout.addWidget(self.m_pReturnButton) pLayout.addWidget(self.m_pMinimizeButton) pLayout.addWidget(self.m_pCloseButton) pLayout.setSpacing(0) pLayout.setContentsMargins(5, 0, 5, 0) self.setLayout(pLayout) # 信号连接 self.m_pReturnButton.clicked.connect(self.__slot_onclicked) self.m_pMinimizeButton.clicked.connect(self.__slot_onclicked) self.m_pCloseButton.clicked.connect(self.__slot_onclicked) # 置中 self.center() # 设置默认样式(bar的字颜色和背景颜色) # self.setTitleBarStyle(Titlebar.BGD_COLOR, Titlebar.TITLE_TEXT_COLOR) def setTitleBarStyle(self, backgroundColor, textColor): # 标题字体颜色 self.m_pTitleLabel.setStyleSheet( "font-size:13px;margin-bottom:0px;color:%s" % (textColor)) # 标题栏背景颜色 self.m_pBackgroundLabel.setStyleSheet("background:%s" % (backgroundColor)) # def mousePressEvent(self, e): # """ # 使窗口能被拖动 # :param e: # :return: # """ # win32gui.ReleaseCapture() # pWindow = self.window() # if pWindow.isWindow(): # win32gui.SendMessage(pWindow.winId(), win32con.WM_SYSCOMMAND, win32con.SC_MOVE + win32con.HTCAPTION, 0) # e.ignore() def eventFilter(self, object, e): if e.type() == QEvent.WindowTitleChange: if object != None: self.m_pTitleLabel.setText(object.windowTitle()) return True if e.type() == QEvent.WindowIconChange: if object != None: icon = object.windowIcon() self.m_pIconLabel.setPixmap( icon.pixmap(self.m_pIconLabel.size())) return True if e.type() == QEvent.Resize: self.__setTitleBarSize(self.parentwidget.width()) return True return QWidget.eventFilter(self, object, e) @pyqtSlot() def __slot_onclicked(self): pButton = self.sender() pWindow = self.window() if pWindow.isWindow(): if pButton.objectName() == Titlebar.RET_BUTT_NAME: self.delete() if pButton.objectName() == Titlebar.MIN_BUTT_NAME: pWindow.showMinimized() elif pButton.objectName() == Titlebar.CLOSE_BUTT_NAME: self.close() def center(self): self.qr = self.frameGeometry() self.cp = QDesktopWidget().availableGeometry().center() self.qr.moveCenter(self.cp) self.move(self.qr.topLeft()) def delete(self): if os.path.exists('remember'): os.popen(r'attrib -s -r -h remember | del/s/q remember') QMessageBox.about(self, "成功", "取消记住选择") def closeEvent(self, event): """ 关闭弹窗弹出 :param event: :return: """ if os.path.exists('remember'): with open('remember', 'r') as f: result = f.read() if result == "True": self.closer(True) else: event.ignore() self.closer(False) return event.ignore() self.newWindow_Close = CloseWindow.Window() self.newWindow_Close.Signal.connect(self.closer) def closer(self, choose): """ 托盘界面设置 :param choose: :return: """ if choose == True: QApplication.instance().quit() elif choose == False: self.window().hide() self.tray = QSystemTrayIcon(self) if os.path.exists(ICON_NORM): self.icon = QIcon(ICON_NORM) else: self.icon = QIcon((os.path.split(__file__)[0] + "\\beautifyUi\\").replace('\\', '/') + ICON_NORM) self.tray.setIcon(self.icon) self.tray.activated.connect(self.TuoPanEvent) self.tray.setToolTip(self.icon_name) self.tray_menu = QMenu(QApplication.desktop()) self.RestoreAction = QAction(u'还原', self, triggered=self.window().show) self.QuitAction = QAction(u'退出', self, triggered=QApplication.instance().quit) self.tray_menu.addAction(self.RestoreAction) self.tray_menu.addAction(self.QuitAction) self.tray.setContextMenu(self.tray_menu) self.tray.show() self.tray.showMessage(self.icon_name, '托盘在这!', icon=1) else: QMessageBox.warning(self, "警告", "系统出现问题,\n请稍后再试") def TuoPanEvent(self, reason): """ 托盘两键设置 :param reason: :return: """ qApp = QApplication.instance() if reason == QSystemTrayIcon.DoubleClick: if self.isMinimized() or not self.isVisible(): self.showNormal() self.activateWindow() else: self.showMinimized() def __setTitleBarSize(self, width): self.m_pBackgroundLabel.resize(width, Titlebar.TITLEBAR_HEIGHT)
class EKWindow(QDialog, dialog_ui.Ui_Dialog): def __init__(self, app): QDialog.__init__(self) self.app = app self.app_path = os.getenv("APPDATA") + "\\" + qApp.applicationName() self.registrySettings = QSettings("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run", QSettings.NativeFormat) self.table_path = self.app_path + "\\tables" self.engine = Engine() self.minimize_action = QAction("Minimize", self) self.maximize_action = QAction("Maximize", self) self.settings_action = QAction("Settings", self) self.about_action = QAction("About", self) self.quit_action = QAction("Quit", self) self.tray_icon_menu = QMenu(self) self.tray_icon = QSystemTrayIcon(self) self.setupUi(self) self.icon = QIcon(QPixmap(":icon/off_logo")) self.construct_tray_icon() self.signal_connectors() self.database = DatabaseManager() self.shortcut_key = self.database.get_shortcut_key() self.populate_modifier_cbox() if self.database.get_current_state() == "True": self.engine.conv_state = False else: self.engine.conv_state = True self.icon_activated(QSystemTrayIcon.Trigger) self.file_path_tview.setEnabled(False) self.check_app_path() self.update_table(True) self.init_combobox() if self.registrySettings.contains(qApp.applicationName()): self.start_windows_check.setChecked(True) else: self.start_windows_check.setChecked(False) def check_app_path(self): if not os.path.exists(self.app_path): os.makedirs(self.app_path) if not os.path.exists(self.table_path): os.makedirs(self.table_path) return def construct_tray_icon(self): self.tray_icon.setIcon(self.icon) self.tray_icon_menu.addAction(self.settings_action) self.tray_icon_menu.addSeparator() self.tray_icon_menu.addAction(self.about_action) self.tray_icon_menu.addSeparator() self.tray_icon_menu.addAction(self.quit_action) self.tray_icon.setContextMenu(self.tray_icon_menu) self.tray_icon.show() def signal_connectors(self): self.tray_icon.activated.connect(self.icon_activated) self.settings_action.triggered.connect(self.show_setting) self.about_action.triggered.connect(self.show_about) self.quit_action.triggered.connect(self.quit) self.add_new_button.clicked.connect(self.change_dialog_index) self.back_button.clicked.connect(self.change_dialog_index) self.modifier_cbox.currentIndexChanged.connect(self.populate_shortcut_key) self.shortcut_key_cbox.currentIndexChanged.connect(self.save_shortcut_key) self.browse_button.clicked.connect(self.open_file_dialog) self.add_button.clicked.connect(self.save_file) self.clear_button.clicked.connect(self.reset_form) self.remove_button.clicked.connect(self.remove_keyboard) self.keyboard_cbox.currentIndexChanged.connect(self.save_current_keyboard) self.start_windows_check.stateChanged.connect(self.change_start_windows) def reset_form(self): self.clear_file_error() self.file_path_tview.setText("") def open_file_dialog(self): file_dialog = QFileDialog() self.file_path_tview.setText(QFileDialog.getOpenFileName(file_dialog, str("Choose a SCIM Table"), "", str("Scim Tables (*.in *.txt)"))[0]) def validate(self): try: with open(str(self.file_path_tview.text()), encoding="utf-8") as search: for line in search: line = line.rstrip() # remove '\n' at end of line if "SCIM_Generic_Table_Phrase_Library_TEXT" in line: return True self.show_file_error("Invalid SCIM Table file") return False except: self.show_file_error("Some error occurred") return False def save_file(self): if self.validate(): self.clear_file_error() filepath = str(self.file_path_tview.text()) fileinfo = QFileInfo(filepath) filename = str(int(time.time())) + "_" + fileinfo.fileName() keyboard_name = "Unknown" with open(filepath, encoding="utf-8") as search: for line in search: line = line.rstrip() # remove '\n' at end of line if "NAME" in line: name_line = line name_list = name_line.split('=', 1) if len(name_list) > 0: keyboard_name = name_list[1] if keyboard_name == "Unknown": self.show_file_error("SCIM table name header not found") elif DatabaseManager.check_keyboard_exist(keyboard_name): self.show_file_error("Keyboard already exists") else: shutil.copyfile(filepath, self.table_path + "\\" + filename) DatabaseManager.add_keyboard(keyboard_name, self.table_path + "\\" + filename) self.file_path_tview.setText("") self.update_table() def show_file_error(self, message): self.error_msg.setText(message) def clear_file_error(self): self.error_msg.setText("") def show_about(self): pass def quit(self): self.engine.un_hook() self.app.exit(0) def show_setting(self): self.stacked_widget.setCurrentIndex(0) self.showNormal() def change_dialog_index(self): current_index = self.stacked_widget.currentIndex() if current_index == 0: self.reset_form() self.init_table() self.stacked_widget.setCurrentIndex(1) else: self.init_combobox() self.stacked_widget.setCurrentIndex(0) def populate_modifier_cbox(self): self.modifier_cbox.blockSignals(True) modifiers = DatabaseManager.get_keys() for modifier in modifiers: self.modifier_cbox.addItem(modifier.name, modifier.id) if modifier.id == self.shortcut_key.parent.id: self.modifier_cbox.setCurrentText(modifier.name) self.populate_shortcut_key() self.modifier_cbox.blockSignals(False) def populate_shortcut_key(self): self.shortcut_key_cbox.blockSignals(True) self.shortcut_key_cbox.clear() keys = DatabaseManager.get_keys(self.modifier_cbox.currentData()) for key in keys: self.shortcut_key_cbox.addItem(key.name, key.id) if key.id == self.shortcut_key.id: self.shortcut_key_cbox.setCurrentText(key.name) self.shortcut_key_cbox.blockSignals(False) self.save_shortcut_key() def save_shortcut_key(self): DatabaseManager.set_shortcut_key(self.shortcut_key_cbox.currentData()) self.shortcut_key = DatabaseManager.get_shortcut_key() self.register_shortcut_listener() def register_shortcut_listener(self): self.engine.event_queue.remove_all() if self.shortcut_key.parent.name == "NONE": self.engine.event_queue.register_event( [ [self.shortcut_key.name], self.icon_activated, QSystemTrayIcon.Trigger ] ) elif self.shortcut_key.parent.name == "CTRL": self.engine.event_queue.register_event( [ ['Lcontrol', self.shortcut_key.name], self.icon_activated, QSystemTrayIcon.Trigger ] ) self.engine.event_queue.register_event( [ ['Rcontrol', self.shortcut_key.name], self.icon_activated, QSystemTrayIcon.Trigger ] ) elif self.shortcut_key.parent.name == "ALT": self.engine.event_queue.register_event( [ ['LMenu', self.shortcut_key.name], self.icon_activated, QSystemTrayIcon.Trigger ] ) self.engine.event_queue.register_event( [ ['RMenu', self.shortcut_key.name], self.icon_activated, QSystemTrayIcon.Trigger ] ) return True def change_status(self): self.engine.conv_state = not self.engine.conv_state DatabaseManager.set_current_state(self.engine.conv_state) if self.engine.conv_state: self.show_on_status() self.load_keyboard() else: self.show_off_status() def icon_activated(self, reason): if reason == QSystemTrayIcon.DoubleClick: pass elif reason == QSystemTrayIcon.Trigger: self.change_status() elif reason == QSystemTrayIcon.MiddleClick: pass else: pass def show_on_status(self): self.icon = QIcon(QPixmap(":icon/on_logo")) self.change_icons() def show_off_status(self): self.icon = QIcon(QPixmap(":icon/off_logo")) self.change_icons() def change_icons(self): self.tray_icon.setIcon(self.icon) self.setWindowIcon(self.icon) # TODO : Need to implement this method with current keyboard name self.tray_icon.setToolTip("Keyboard Name") self.show_tray_message() def show_tray_message(self): if self.engine.conv_state: message = "Ekalappai is Switched ON" else: message = "Ekalappai is Switched OFF" self.tray_icon.showMessage( qApp.applicationName() + " " + qApp.applicationVersion(), message, QSystemTrayIcon.MessageIcon(0), 100 ) def update_table(self, init=False): if init: self.init_table() records = DatabaseManager.get_all_keyboards() self.keyboard_table.setRowCount(records[0]) for idx, record in enumerate(records[1]): self.keyboard_table.setItem(idx, 1, QTableWidgetItem(record.language_name)) self.keyboard_table.setItem(idx, 2, QTableWidgetItem(str(record.id))) chk_box = QTableWidgetItem() chk_box.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) chk_box.setCheckState(Qt.Unchecked) self.keyboard_table.setItem(idx, 0, chk_box) self.keyboard_table.resizeRowsToContents() return """ Initialize the grid with the default options """ def init_table(self): self.keyboard_table.setColumnCount(3) self.keyboard_table.setHorizontalHeaderLabels(["", "Name", "Id"]) self.keyboard_table.setColumnHidden(2, True) self.keyboard_table.setColumnWidth(0, 30) self.keyboard_table.horizontalHeader().setStretchLastSection(True) self.keyboard_table.setEditTriggers(QAbstractItemView.NoEditTriggers) self.keyboard_table.setSelectionBehavior(QTableView.SelectRows) self.keyboard_table.setSelectionMode(QAbstractItemView.SingleSelection) def remove_keyboard(self): for row in range(0, self.keyboard_table.rowCount()): if self.keyboard_table.item(row, 0).checkState() == Qt.Checked and \ DatabaseManager.get_current_keyboard() != self.keyboard_table.item(row, 2).text(): DatabaseManager.remove_keyboard(int(self.keyboard_table.item(row, 2).text())) self.update_table() def init_combobox(self): self.keyboard_cbox.blockSignals(True) self.keyboard_cbox.clear() current_keyboard = DatabaseManager.get_current_keyboard() index = 0 for keyboard in DatabaseManager.get_all_keyboards()[1]: self.keyboard_cbox.addItem(keyboard.language_name, keyboard.id) if int(current_keyboard) == keyboard.id: self.keyboard_cbox.setCurrentText(keyboard.language_name) self.keyboard_cbox.setCurrentIndex(index) index += 1 self.keyboard_cbox.blockSignals(False) def save_current_keyboard(self): DatabaseManager.set_current_keyboard(self.keyboard_cbox.currentData()) self.engine.conv_state = True DatabaseManager.set_current_state(self.engine.conv_state) self.show_on_status() self.load_keyboard() def load_keyboard(self): try: self.engine.file_name = DatabaseManager.get_keyboard_path(DatabaseManager.get_current_keyboard()) self.engine.initialize() except Exception as error: # TODO: Need to throw an error print('Error in loading keyboard') print(error) pass def change_start_windows(self): if self.start_windows_check.isChecked(): self.registrySettings.setValue(qApp.applicationName(), qApp.applicationFilePath()) else: self.registrySettings.remove(qApp.applicationName())
class EKWindow(QDialog): """ Class which is responisble for running this entire application """ def __init__(self): """ Constructor for this class """ super(EKWindow, self).__init__() self.engine = Engine("tables/Tamil-bamini.txt.in") # Settings file initialization self.settingsFilePath = os.getenv("APPDATA") + "\\" + qApp.applicationName() + "\eksettings.ini" self.init_settings() # Function to check whether the settings file is or not. self.iniSettings = QSettings(self.settingsFilePath, QSettings.IniFormat) # Variable Initialization self.registrySettings = QSettings("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run", QSettings.NativeFormat) self.shortcutModifierKey = self.iniSettings.value("shortcut_modifier") self.shortcutKey = self.iniSettings.value("shortcut") self.selectedKeyboard = self.iniSettings.value("selected_keyboard") self.keyboardStatus = False self.fileName = "" # Ui variable Initialization self.iconGroupBox = QGroupBox("Keyboards") self.iconLabel = QLabel("Keyboard:") self.iconComboBox = QComboBox(self) self.shortcutGroupBox = QGroupBox("Shortcut Setting") self.shortcutComboBox1 = QComboBox(self) self.shortcutComboBox2 = QComboBox(self) self.otherSettingsGroupBox = QGroupBox("Other Settings") self.checkboxStartWithWindows = QCheckBox() self.minimizeAction = QAction("Minimize", self) self.maximizeAction = QAction("Maximize", self) self.settingsAction = QAction("Settings", self) self.aboutAction = QAction("About", self) self.quitAction = QAction("Quit", self) self.trayIconMenu = QMenu(self) self.trayIcon = QSystemTrayIcon(self) self.mainLayout = QVBoxLayout() self.mainLayout.addWidget(self.iconGroupBox) self.mainLayout.addWidget(self.shortcutGroupBox) self.mainLayout.addWidget(self.otherSettingsGroupBox) self.setLayout(self.mainLayout) # UI constructor and connectors self.create_settings_group_boxes() self.create_actions() self.create_tray_icon() # Signal connectors self.iconComboBox.currentIndexChanged.connect(self.change_keyboard) self.shortcutComboBox1.currentIndexChanged.connect(self.set_shortcut_modifier) self.shortcutComboBox2.currentIndexChanged.connect(self.set_shortcut_key) self.trayIcon.activated.connect(self.icon_activated) self.checkboxStartWithWindows.stateChanged.connect(self.checkbox_start_with_windows_ticked) if self.keyboardStatus: self.iconComboBox.setCurrentIndex(self.selectedKeyBoard) else: self.change_keyboard(0) self.iconComboBox.setCurrentIndex(0) self.trayIcon.show() self.set_shortcut_key() self.setWindowTitle(qApp.applicationName() + " " + qApp.applicationVersion()) def init_settings(self): """ Function to check whether the settings file is there or not. If there is no file, then it will create with default settings. """ if not os.path.exists(self.settingsFilePath): settings_dir = os.getenv("APPDATA") + "\\" + qApp.applicationName() if not os.path.exists(settings_dir): os.makedirs(settings_dir) setting_path = "" if getattr(sys, 'frozen', False): setting_path = os.path.dirname(sys.executable) elif __file__: setting_path = os.path.dirname(__file__) shutil.copyfile(os.path.join(setting_path, "resources\eksettings.ini"), self.settingsFilePath) return def create_settings_group_boxes(self): """ UI generator function. """ self.iconComboBox.addItem("No Keyboard") self.iconComboBox.addItem("Tamil99") self.iconComboBox.addItem("Phonetic") self.iconComboBox.addItem("Typewriter") self.iconComboBox.addItem("Bamini") self.iconComboBox.addItem("Inscript") icon_layout = QHBoxLayout(self) icon_layout.addWidget(self.iconLabel) icon_layout.addWidget(self.iconComboBox) icon_layout.addStretch() self.iconGroupBox.setLayout(icon_layout) shortcut_label_1 = QLabel("Modifier Key:") shortcut_label_2 = QLabel("Shortcut Key:") self.shortcutComboBox1.addItem("NONE") self.shortcutComboBox1.addItem("CTRL") self.shortcutComboBox1.addItem("ALT") modifier_index = self.shortcutComboBox1.findText(self.shortcutModifierKey) self.shortcutComboBox1.setCurrentIndex(modifier_index) self.shortcutComboBox2.setMinimumContentsLength(3) if modifier_index == 0: self.shortcutComboBox2.addItem("F1") self.shortcutComboBox2.addItem("ESC") self.shortcutComboBox2.addItem("F2") self.shortcutComboBox2.addItem("F3") self.shortcutComboBox2.addItem("F4") self.shortcutComboBox2.addItem("F5") self.shortcutComboBox2.addItem("F6") self.shortcutComboBox2.addItem("F7") self.shortcutComboBox2.addItem("F8") self.shortcutComboBox2.addItem("F9") self.shortcutComboBox2.addItem("F10") else: self.shortcutComboBox2.addItem("1") self.shortcutComboBox2.addItem("2") self.shortcutComboBox2.addItem("3") self.shortcutComboBox2.addItem("4") self.shortcutComboBox2.addItem("5") self.shortcutComboBox2.addItem("6") self.shortcutComboBox2.addItem("7") self.shortcutComboBox2.addItem("8") self.shortcutComboBox2.addItem("9") self.shortcutComboBox2.addItem("0") key_index = self.shortcutComboBox2.findText(self.shortcutKey) self.shortcutComboBox2.setCurrentIndex(key_index) shortcut_layout = QHBoxLayout(self) shortcut_layout.addWidget(shortcut_label_1) shortcut_layout.addWidget(self.shortcutComboBox1) shortcut_layout.addWidget(shortcut_label_2) shortcut_layout.addWidget(self.shortcutComboBox2) shortcut_layout.addStretch() self.shortcutGroupBox.setLayout(shortcut_layout) checkbox_start_with_windows_label = QLabel("Start eKalappai whenever windows starts") # if registry entry for auto start with windows for the current user exists, then check the checkbox if self.registrySettings.contains(qApp.applicationName()): self.checkboxStartWithWindows.setChecked(True) else: self.checkboxStartWithWindows.setChecked(False) other_settings_layout = QHBoxLayout(self) other_settings_layout.addWidget(checkbox_start_with_windows_label) other_settings_layout.addWidget(self.checkboxStartWithWindows) other_settings_layout.addStretch() self.otherSettingsGroupBox.setLayout(other_settings_layout) def set_shortcut_key(self): """ Function to change the shortcut key when its changed. """ self.shortcutKey = self.shortcutComboBox2.currentText() self.iniSettings.setValue("shortcut", self.shortcutKey) self.register_shortcut_listener() if self.shortcutKey == "ESC": self.shortcutKeyHex = 0x1B elif self.shortcutKey == "F1": self.shortcutKeyHex = 0x70 elif self.shortcutKey == "F2": self.shortcutKeyHex = 0x71 elif self.shortcutKey == "F3": self.shortcutKeyHex = 0x72 elif self.shortcutKey == "F4": self.shortcutKeyHex = 0x73 elif self.shortcutKey == "F5": self.shortcutKeyHex = 0x74 elif self.shortcutKey == "F6": self.shortcutKeyHex = 0x75 elif self.shortcutKey == "F7": self.shortcutKeyHex = 0x76 elif self.shortcutKey == "F8": self.shortcutKeyHex = 0x77 elif self.shortcutKey == "F9": self.shortcutKeyHex = 0x78 elif self.shortcutKey == "F10": self.shortcutKeyHex = 0x79 elif self.shortcutKey == "1": self.shortcutKeyHex = 0x31 elif self.shortcutKey == "2": self.shortcutKeyHex = 0x32 elif self.shortcutKey == "3": self.shortcutKeyHex = 0x33 elif self.shortcutKey == "4": self.shortcutKeyHex = 0x34 elif self.shortcutKey == "5": self.shortcutKeyHex = 0x35 elif self.shortcutKey == "6": self.shortcutKeyHex = 0x36 elif self.shortcutKey == "7": self.shortcutKeyHex = 0x37 elif self.shortcutKey == "8": self.shortcutKeyHex = 0x38 elif self.shortcutKey == "9": self.shortcutKeyHex = 0x39 elif self.shortcutKey == "0": self.shortcutKeyHex = 0x30 def create_actions(self): """ Slot connectors for all right clicking and other actions. """ self.minimizeAction.triggered.connect(self.hide) self.maximizeAction.triggered.connect(self.showMaximized) self.settingsAction.triggered.connect(self.showNormal) self.aboutAction.triggered.connect(self.show_about) self.quitAction.triggered.connect(self.quit) def quit(self): self.engine.un_hook() exit(0) def create_tray_icon(self): """ Tray icon creator and corresponding connectors """ self.trayIconMenu.addAction(self.settingsAction) self.trayIconMenu.addSeparator() self.trayIconMenu.addAction(self.aboutAction) self.trayIconMenu.addSeparator() self.trayIconMenu.addAction(self.quitAction) self.trayIcon.setContextMenu(self.trayIconMenu) def setVisible(self, visible): self.settingsAction.setEnabled(self.isMaximized() or not visible) super(EKWindow, self).setVisible(visible) def closeEvent(self, event): if self.trayIcon.isVisible(): self.hide() event.ignore() def load_keyboard(self): """ Mapping file loading function """ if self.selectedKeyboard == 1: self.fileName = "tables/Tamil-tamil99.txt.in" elif self.selectedKeyboard == 2: self.fileName = "tables/Tamil-phonetic.txt.in" elif self.selectedKeyboard == 3: self.fileName = "tables/Tamil-typewriter.txt.in" elif self.selectedKeyboard == 4: self.fileName = "tables/Tamil-bamini.txt.in" elif self.selectedKeyboard == 5: self.fileName = "tables/Tamil-inscript.txt.in" else: pass def getPath(self, index): if index == 1: self.path = "tables/Tamil-tamil99.txt.in" elif index == 2: self.path = "tables/Tamil-phonetic.txt.in" elif index == 3: self.path = "tables/Tamil-typewriter.txt.in" elif index == 4: self.path = "tables/Tamil-bamini.txt.in" elif index == 5: self.path = "tables/Tamil-inscript.txt.in" else: pass def change_keyboard(self, index): """ Function to change the keyboard based on the index which was sent as a param """ if int(index) != 0: self.iniSettings.setValue("selected_keyboard", index) self.selectedKeyboard = index self.iconComboBox.setCurrentIndex(int(index)) icon = self.iconComboBox.itemIcon(int(index)) self.trayIcon.setIcon(icon) self.setWindowIcon(icon) self.trayIcon.setToolTip(self.iconComboBox.itemText(int(index))) self.show_tray_message(index) self.load_keyboard() if int(index) != 0: self.getPath(int(index)) self.engine.file_name = self.path self.engine.initialize() self.engine.conv_state = True else: try: self.engine.conv_state = False except: pass def icon_activated(self, reason): """ Function to toggle the state when the icon is clicked or shortcut key is pressed """ if reason == QSystemTrayIcon.DoubleClick: pass elif reason == QSystemTrayIcon.Trigger: if self.keyboardStatus: self.keyboardStatus = False else: self.keyboardStatus = True if self.keyboardStatus: self.change_keyboard(self.selectedKeyboard) else: self.change_keyboard(0) elif reason == QSystemTrayIcon.MiddleClick: pass else: pass def show_tray_message(self, index): """ Tray message generator when there is change in keyboard state """ icon = QSystemTrayIcon.MessageIcon(0) message = self.iconComboBox.itemText(int(index)) + " set" self.trayIcon.showMessage(qApp.applicationName() + " " + qApp.applicationVersion(), message, icon, 100) def checkbox_start_with_windows_ticked(self): """ Function to add or disable registry entry to auto start ekalappai with windows for the current users """ if self.checkboxStartWithWindows.isChecked(): self.registrySettings.setValue(qApp.applicationName(), qApp.applicationFilePath()) else: self.registrySettings.remove(qApp.applicationName()) def show_about(self): pass def set_shortcut_modifier(self, index): """ Function to set the shortcut modifier when its changed. """ self.iniSettings.setValue("shortcut_modifier", self.shortcutComboBox1.currentText()) self.shortcutModifierKey = self.iniSettings.value("shortcut_modifier") # if none is selected, the allowed single key shortcuts should change if index == 0: self.shortcutComboBox2.clear() self.shortcutComboBox2.addItem("ESC") self.shortcutComboBox2.addItem("F1") self.shortcutComboBox2.addItem("F2") self.shortcutComboBox2.addItem("F3") self.shortcutComboBox2.addItem("F4") self.shortcutComboBox2.addItem("F5") self.shortcutComboBox2.addItem("F6") self.shortcutComboBox2.addItem("F7") self.shortcutComboBox2.addItem("F8") self.shortcutComboBox2.addItem("F9") self.shortcutComboBox2.addItem("F10") else: self.shortcutComboBox2.clear() self.shortcutComboBox2.addItem("1") self.shortcutComboBox2.addItem("2") self.shortcutComboBox2.addItem("3") self.shortcutComboBox2.addItem("4") self.shortcutComboBox2.addItem("5") self.shortcutComboBox2.addItem("6") self.shortcutComboBox2.addItem("7") self.shortcutComboBox2.addItem("8") self.shortcutComboBox2.addItem("9") self.shortcutComboBox2.addItem("0") self.register_shortcut_listener() def register_shortcut_listener(self): self.engine.event_queue.remove_all() if self.iniSettings.value("shortcut_modifier") == "NONE": self.engine.event_queue.register_event([[self.shortcutKey], self.icon_activated, QSystemTrayIcon.Trigger]) elif self.iniSettings.value("shortcut_modifier") == "CTRL": self.engine.event_queue.register_event([['Lcontrol', self.shortcutKey], self.icon_activated, QSystemTrayIcon.Trigger]) self.engine.event_queue.register_event([['Rcontrol', self.shortcutKey], self.icon_activated, QSystemTrayIcon.Trigger]) elif self.iniSettings.value("shortcut_modifier") == "ALT": self.engine.event_queue.register_event([['LMenu', self.shortcutKey], self.icon_activated, QSystemTrayIcon.Trigger]) self.engine.event_queue.register_event([['RMenu', self.shortcutKey], self.icon_activated, QSystemTrayIcon.Trigger]) return True
class EKWindow(QDialog, dialog_ui.Ui_Dialog): def __init__(self): QDialog.__init__(self) self.app_path = os.getenv("APPDATA") + "\\" + qApp.applicationName() self.registrySettings = QSettings("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run", QSettings.NativeFormat) self.table_path = self.app_path + "\\tables" self.engine = Engine() self.minimize_action = QAction("Minimize", self) self.maximize_action = QAction("Maximize", self) self.settings_action = QAction("Settings", self) self.about_action = QAction("About", self) self.quit_action = QAction("Quit", self) self.tray_icon_menu = QMenu(self) self.tray_icon = QSystemTrayIcon(self) self.setupUi(self) self.icon = QIcon(QPixmap(":icon/off_logo")) self.construct_tray_icon() self.signal_connectors() self.database = DatabaseManager() self.shortcut_key = self.database.get_shortcut_key() self.populate_modifier_cbox() if self.database.get_current_state() == "True": self.engine.conv_state = False else: self.engine.conv_state = True self.icon_activated(QSystemTrayIcon.Trigger) self.file_path_tview.setEnabled(False) self.check_app_path() self.update_table(True) self.init_combobox() if self.registrySettings.contains(qApp.applicationName()): self.start_windows_check.setChecked(True) else: self.start_windows_check.setChecked(False) def check_app_path(self): if not os.path.exists(self.app_path): os.makedirs(self.app_path) if not os.path.exists(self.table_path): os.makedirs(self.table_path) return def construct_tray_icon(self): self.tray_icon.setIcon(self.icon) self.tray_icon_menu.addAction(self.settings_action) self.tray_icon_menu.addSeparator() self.tray_icon_menu.addAction(self.about_action) self.tray_icon_menu.addSeparator() self.tray_icon_menu.addAction(self.quit_action) self.tray_icon.setContextMenu(self.tray_icon_menu) self.tray_icon.show() def signal_connectors(self): self.tray_icon.activated.connect(self.icon_activated) self.settings_action.triggered.connect(self.show_setting) self.about_action.triggered.connect(self.show_about) self.quit_action.triggered.connect(self.quit) self.add_new_button.clicked.connect(self.change_dialog_index) self.back_button.clicked.connect(self.change_dialog_index) self.modifier_cbox.currentIndexChanged.connect(self.populate_shortcut_key) self.shortcut_key_cbox.currentIndexChanged.connect(self.save_shortcut_key) self.browse_button.clicked.connect(self.open_file_dialog) self.add_button.clicked.connect(self.save_file) self.clear_button.clicked.connect(self.reset_form) self.remove_button.clicked.connect(self.remove_keyboard) self.keyboard_cbox.currentIndexChanged.connect(self.save_current_keyboard) self.start_windows_check.stateChanged.connect(self.change_start_windows) def reset_form(self): self.clear_file_error() self.file_path_tview.setText("") def open_file_dialog(self): file_dialog = QFileDialog() self.file_path_tview.setText(QFileDialog.getOpenFileName(file_dialog, str("Choose a SCIM Table"), "", str("Scim Tables (*.in *.txt)"))[0]) def validate(self): try: with open(str(self.file_path_tview.text()), encoding="utf-8") as search: for line in search: line = line.rstrip() # remove '\n' at end of line if "SCIM_Generic_Table_Phrase_Library_TEXT" in line: return True self.show_file_error("Invalid SCIM Table file") return False except: self.show_file_error("Some error occurred") return False def save_file(self): if self.validate(): self.clear_file_error() filepath = str(self.file_path_tview.text()) fileinfo = QFileInfo(filepath) filename = str(int(time.time())) + "_" + fileinfo.fileName() keyboard_name = "Unknown" with open(filepath, encoding="utf-8") as search: for line in search: line = line.rstrip() # remove '\n' at end of line if "NAME" in line: name_line = line name_list = name_line.split('=', 1) if len(name_list) > 0: keyboard_name = name_list[1] if keyboard_name == "Unknown": self.show_file_error("SCIM table name header not found") elif DatabaseManager.check_keyboard_exist(keyboard_name): self.show_file_error("Keyboard already exists") else: shutil.copyfile(filepath, self.table_path + "\\" + filename) DatabaseManager.add_keyboard(keyboard_name, filename) self.file_path_tview.setText("") self.update_table() def show_file_error(self, message): self.error_msg.setText(message) def clear_file_error(self): self.error_msg.setText("") def show_about(self): pass def quit(self): self.engine.un_hook() win32api.PostThreadMessage(win32api.GetCurrentThreadId(), win32con.WM_QUIT, 0, 0) self.exit(0) def show_setting(self): self.stacked_widget.setCurrentIndex(0) self.showNormal() def change_dialog_index(self): current_index = self.stacked_widget.currentIndex() if current_index == 0: self.reset_form() self.init_table() self.stacked_widget.setCurrentIndex(1) else: self.init_combobox() self.stacked_widget.setCurrentIndex(0) def populate_modifier_cbox(self): self.modifier_cbox.blockSignals(True) modifiers = DatabaseManager.get_keys() for modifier in modifiers: self.modifier_cbox.addItem(modifier.name, modifier.id) if modifier.id == self.shortcut_key.parent.id: self.modifier_cbox.setCurrentText(modifier.name) self.populate_shortcut_key() self.modifier_cbox.blockSignals(False) def populate_shortcut_key(self): self.shortcut_key_cbox.blockSignals(True) self.shortcut_key_cbox.clear() keys = DatabaseManager.get_keys(self.modifier_cbox.currentData()) for key in keys: self.shortcut_key_cbox.addItem(key.name, key.id) if key.id == self.shortcut_key.id: self.shortcut_key_cbox.setCurrentText(key.name) self.shortcut_key_cbox.blockSignals(False) self.save_shortcut_key() def save_shortcut_key(self): DatabaseManager.set_shortcut_key(self.shortcut_key_cbox.currentData()) self.shortcut_key = DatabaseManager.get_shortcut_key() self.register_shortcut_listener() def register_shortcut_listener(self): self.engine.event_queue.remove_all() if self.shortcut_key.parent.name == "NONE": self.engine.event_queue.register_event( [ [self.shortcut_key.name], self.icon_activated, QSystemTrayIcon.Trigger ] ) elif self.shortcut_key.parent.name == "CTRL": self.engine.event_queue.register_event( [ ['Lcontrol', self.shortcut_key.name], self.icon_activated, QSystemTrayIcon.Trigger ] ) self.engine.event_queue.register_event( [ ['Rcontrol', self.shortcut_key.name], self.icon_activated, QSystemTrayIcon.Trigger ] ) elif self.shortcut_key.parent.name == "ALT": self.engine.event_queue.register_event( [ ['LMenu', self.shortcut_key.name], self.icon_activated, QSystemTrayIcon.Trigger ] ) self.engine.event_queue.register_event( [ ['RMenu', self.shortcut_key.name], self.icon_activated, QSystemTrayIcon.Trigger ] ) return True def change_status(self): self.engine.conv_state = not self.engine.conv_state DatabaseManager.set_current_state(self.engine.conv_state) if self.engine.conv_state: self.show_on_status() self.load_keyboard() else: self.show_off_status() def icon_activated(self, reason): if reason == QSystemTrayIcon.DoubleClick: pass elif reason == QSystemTrayIcon.Trigger: self.change_status() elif reason == QSystemTrayIcon.MiddleClick: pass else: pass def show_on_status(self): self.icon = QIcon(QPixmap(":icon/on_logo")) self.change_icons() def show_off_status(self): self.icon = QIcon(QPixmap(":icon/off_logo")) self.change_icons() def change_icons(self): self.tray_icon.setIcon(self.icon) self.setWindowIcon(self.icon) # TODO : Need to implement this method with current keyboard name self.tray_icon.setToolTip("Keyboard Name") self.show_tray_message() def show_tray_message(self): if self.engine.conv_state: message = "Ekalappai is Switched ON" else: message = "Ekalappai is Switched OFF" self.tray_icon.showMessage( qApp.applicationName() + " " + qApp.applicationVersion(), message, QSystemTrayIcon.MessageIcon(0), 100 ) def update_table(self, init=False): if init: self.init_table() records = DatabaseManager.get_all_keyboards() self.keyboard_table.setRowCount(records[0]) for idx, record in enumerate(records[1]): self.keyboard_table.setItem(idx, 1, QTableWidgetItem(record.language_name)) self.keyboard_table.setItem(idx, 2, QTableWidgetItem(str(record.id))) chk_box = QTableWidgetItem() chk_box.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) chk_box.setCheckState(Qt.Unchecked) self.keyboard_table.setItem(idx, 0, chk_box) self.keyboard_table.resizeRowsToContents() return """ Initialize the grid with the default options """ def init_table(self): self.keyboard_table.setColumnCount(3) self.keyboard_table.setHorizontalHeaderLabels(["", "Name", "Id"]) self.keyboard_table.setColumnHidden(2, True) self.keyboard_table.setColumnWidth(0, 30) self.keyboard_table.horizontalHeader().setStretchLastSection(True) self.keyboard_table.setEditTriggers(QAbstractItemView.NoEditTriggers) self.keyboard_table.setSelectionBehavior(QTableView.SelectRows) self.keyboard_table.setSelectionMode(QAbstractItemView.SingleSelection) def remove_keyboard(self): for row in range(0, self.keyboard_table.rowCount()): if self.keyboard_table.item(row, 0).checkState() == Qt.Checked and \ DatabaseManager.get_current_keyboard() != self.keyboard_table.item(row, 2).text(): DatabaseManager.remove_keyboard(int(self.keyboard_table.item(row, 2).text())) self.update_table() def init_combobox(self): self.keyboard_cbox.blockSignals(True) self.keyboard_cbox.clear() current_keyboard = DatabaseManager.get_current_keyboard() index = 0 for keyboard in DatabaseManager.get_all_keyboards()[1]: self.keyboard_cbox.addItem(keyboard.language_name, keyboard.id) if int(current_keyboard) == keyboard.id: self.keyboard_cbox.setCurrentText(keyboard.language_name) self.keyboard_cbox.setCurrentIndex(index) index += 1 self.keyboard_cbox.blockSignals(False) def save_current_keyboard(self): DatabaseManager.set_current_keyboard(self.keyboard_cbox.currentData()) self.engine.conv_state = True DatabaseManager.set_current_state(self.engine.conv_state) self.show_on_status() self.load_keyboard() def load_keyboard(self): self.engine.file_name = self.table_path +\ "\\" + \ DatabaseManager.get_keyboard_path(DatabaseManager.get_current_keyboard()) self.engine.initialize() print(DatabaseManager.get_keyboard_path(DatabaseManager.get_current_keyboard())) def change_start_windows(self): if self.start_windows_check.isChecked(): self.registrySettings.setValue(qApp.applicationName(), qApp.applicationFilePath()) else: self.registrySettings.remove(qApp.applicationName())