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): """ 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 Ui_MainWindow(object): def setupUi(self, MainWindow): self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.gridLayout = QtWidgets.QGridLayout(self.centralwidget) self.gridLayout.setObjectName("gridLayout") self.localProxyEntry = QtWidgets.QPlainTextEdit(self.centralwidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.localProxyEntry.sizePolicy().hasHeightForWidth()) self.localProxyEntry.setSizePolicy(sizePolicy) self.localProxyEntry.setMaximumSize(QtCore.QSize(16777215, 40)) self.localProxyEntry.setObjectName("localProxyEntry") self.gridLayout.addWidget(self.localProxyEntry, 3, 1, 1, 1) self.serverAddr = QtWidgets.QLabel(self.centralwidget) self.serverAddr.setObjectName("serverAddr") self.gridLayout.addWidget(self.serverAddr, 0, 0, 1, 1) self.passwd = QtWidgets.QLabel(self.centralwidget) self.passwd.setObjectName("passwd") self.gridLayout.addWidget(self.passwd, 2, 0, 1, 1) self.serverEntry = QtWidgets.QPlainTextEdit(self.centralwidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(100) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.serverEntry.sizePolicy().hasHeightForWidth()) self.serverEntry.setSizePolicy(sizePolicy) self.serverEntry.setMaximumSize(QtCore.QSize(16777215, 40)) self.serverEntry.setObjectName("serverEntry") self.gridLayout.addWidget(self.serverEntry, 0, 1, 1, 1) self.localProxyPort = QtWidgets.QLabel(self.centralwidget) self.localProxyPort.setObjectName("localProxyPort") self.gridLayout.addWidget(self.localProxyPort, 3, 0, 1, 1) self.passwdEntry = QtWidgets.QPlainTextEdit(self.centralwidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.passwdEntry.sizePolicy().hasHeightForWidth()) self.passwdEntry.setSizePolicy(sizePolicy) self.passwdEntry.setMaximumSize(QtCore.QSize(16777215, 40)) self.passwdEntry.setObjectName("passwdEntry") self.gridLayout.addWidget(self.passwdEntry, 2, 1, 1, 1) self.usrName = QtWidgets.QLabel(self.centralwidget) self.usrName.setObjectName("usrName") self.gridLayout.addWidget(self.usrName, 1, 0, 1, 1) self.userEntry = QtWidgets.QPlainTextEdit(self.centralwidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.userEntry.sizePolicy().hasHeightForWidth()) self.userEntry.setSizePolicy(sizePolicy) self.userEntry.setMaximumSize(QtCore.QSize(16777215, 40)) self.userEntry.setObjectName("userEntry") self.gridLayout.addWidget(self.userEntry, 1, 1, 1, 1) self.gridLayout_2 = QtWidgets.QGridLayout() self.gridLayout_2.setObjectName("gridLayout_2") self.connect = QtWidgets.QPushButton(self.centralwidget) self.connect.setObjectName("connect") self.gridLayout_2.addWidget(self.connect, 0, 0, 1, 1) self.disconnect = QtWidgets.QPushButton(self.centralwidget) self.disconnect.setObjectName("disconnect") self.gridLayout_2.addWidget(self.disconnect, 0, 1, 1, 1) self.progressBar = QtWidgets.QProgressBar(self.centralwidget) self.progressBar.setProperty("value", 0) self.progressBar.setObjectName("progressBar") self.gridLayout_2.addWidget(self.progressBar, 1, 0, 1, 2) self.gridLayout.addLayout(self.gridLayout_2, 4, 0, 1, 2) MainWindow.setCentralWidget(self.centralwidget) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.menuBar = QtWidgets.QMenuBar(MainWindow) self.menuBar.setGeometry(QtCore.QRect(0, 0, 576, 26)) self.menuBar.setObjectName("menuBar") self.menuFile = QtWidgets.QMenu(self.menuBar) self.menuFile.setObjectName("menuFile") MainWindow.setMenuBar(self.menuBar) self.actionOpen_Config = QtWidgets.QAction(MainWindow) self.actionOpen_Config.setObjectName("actionOpen_Config") self.actionOpen_Config.setShortcut("Ctrl+O") self.actionSave_Config = QtWidgets.QAction(MainWindow) self.actionSave_Config.setObjectName("actionSave_Config") self.actionSave_Config.setShortcut("Ctrl+S") self.actionExit = QtWidgets.QAction(MainWindow) self.actionExit.setObjectName("actionExit") self.menuFile.addAction(self.actionOpen_Config) self.menuFile.addAction(self.actionSave_Config) self.menuFile.addAction(self.actionExit) self.menuBar.addAction(self.menuFile.menuAction()) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) # Connect all buttons with functions self.actionExit.triggered.connect(self.exitOnClick) self.actionSave_Config.triggered.connect(self.saveConfig) self.actionOpen_Config.triggered.connect(self.loadConfig) self.connect.clicked.connect(self.connectToNaive) self.disconnect.clicked.connect(self.disconnectFromNaive) self.CONNECTED = False # System tray self.trayIcon = QSystemTrayIcon(QIcon('icon.png'), parent=app) self.trayIcon.setToolTip("Naive Proxy") self.trayIcon.show() self.trayIcon.setContextMenu(self.menuFile) self.defaultConfig() def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "naiveProxy")) self.localProxyEntry.setPlainText(_translate("MainWindow", "1080")) self.serverAddr.setText(_translate("MainWindow", "Server Address")) self.passwd.setText(_translate("MainWindow", "Password")) self.serverEntry.setPlainText(_translate("MainWindow", "example.org")) self.localProxyPort.setText(_translate("MainWindow", "SOCKS Port")) self.passwdEntry.setPlainText(_translate("MainWindow", "password")) self.usrName.setText(_translate("MainWindow", "Username")) self.userEntry.setPlainText(_translate("MainWindow", "username")) self.connect.setText(_translate("MainWindow", "Connect")) self.disconnect.setText(_translate("MainWindow", "Disconnect")) self.menuFile.setTitle(_translate("MainWindow", "File")) self.actionOpen_Config.setText(_translate("MainWindow", "Open Config")) self.actionSave_Config.setText(_translate("MainWindow", "Save Config")) self.actionExit.setText(_translate("MainWindow", "Exit")) def overrideConfig(self): serverAddress = self.serverEntry.toPlainText() username = self.userEntry.toPlainText() password = self.passwdEntry.toPlainText() SOCKSPort = self.localProxyEntry.toPlainText() with open("config.json", 'w') as output: json.dump( { "listen": "socks://127.0.0.1:" + SOCKSPort, "proxy": "https://" + username + ":" + password + "@" + serverAddress, "padding": True }, output) def saveConfig(self): serverAddress = self.serverEntry.toPlainText() username = self.userEntry.toPlainText() password = self.passwdEntry.toPlainText() SOCKSPort = self.localProxyEntry.toPlainText() fileName, _ = QtWidgets.QFileDialog.getSaveFileName( None, "Save Naive Configuration", "", "Naive Configuration File (*.json)", "") if (fileName): with open(fileName, 'w') as output: json.dump( { "listen": "socks://127.0.0.1:" + SOCKSPort, "proxy": "https://" + username + ":" + password + "@" + serverAddress, "padding": True }, output) def defaultConfig(self): try: with open("config.json") as f: data = json.load(f) listen = data['listen'] proxy = data['proxy'][8:] self.serverEntry.setPlainText(proxy[proxy.rfind('@') + 1:]) self.userEntry.setPlainText(proxy[:proxy.find(':')]) self.passwdEntry.setPlainText( proxy[proxy.find(self.userEntry.toPlainText()) + len(self.userEntry.toPlainText()) + 1:proxy.rfind('@')]) self.localProxyEntry.setPlainText(listen[-4:]) except: msg = QMessageBox() msg.setIcon(QMessageBox.Critical) msg.setText("Please place in proper config.json") msg.setWindowTitle("Error") msg.exec_() quit() def loadConfig(self): fileName, _ = QtWidgets.QFileDialog.getOpenFileName( None, "Open Naive Configuration", "", "Naive Configuration File (*.json)", "") try: with open(fileName) as f: data = json.load(f) listen = data['listen'] proxy = data['proxy'][8:] self.serverEntry.setPlainText(proxy[proxy.rfind('@') + 1:]) self.userEntry.setPlainText(proxy[:proxy.find(':')]) self.passwdEntry.setPlainText( proxy[proxy.find(self.userEntry.toPlainText()) + len(self.userEntry.toPlainText()) + 1:proxy.rfind('@')]) self.localProxyEntry.setPlainText(listen[-4:]) except: msg = QMessageBox() msg.setIcon(QMessageBox.Critical) msg.setText("Not a valid configuration") msg.setWindowTitle("Error") msg.exec_() def testConnection(self): self.progressBar.setProperty("value", 50) try: proxyPort = int(self.localProxyEntry.toPlainText()) proxies = {'https': "socks5://localhost:" + str(proxyPort)} try: response = int( requests.get('https://skylantern.social/success', proxies=proxies).content.decode('utf-8')) self.progressBar.setProperty("value", 70) except: self.p.kill() msg = QMessageBox() msg.setIcon(QMessageBox.Critical) msg.setText("Credential Error") msg.setWindowTitle("Wrong username / password") msg.exec_() self.progressBar.setProperty("value", 0) return if (response): self.CONNECTED = True self.progressBar.setProperty("value", 100) msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText("Naive connected") msg.setWindowTitle("Connection Established") msg.exec_() else: self.p.kill() msg = QMessageBox() msg.setIcon(QMessageBox.Critical) msg.setText("Credential Error") msg.setWindowTitle("Wrong username / password") msg.exec_() self.progressBar.setProperty("value", 0) except: msg = QMessageBox() msg.setIcon(QMessageBox.Critical) msg.setText("Naive not connected") msg.setWindowTitle("No connection") msg.exec_() self.progressBar.setProperty("value", 0) def connectToNaive(self): if self.CONNECTED: msg = QMessageBox() msg.setText("Reconnect with current credentials?") msg.setStandardButtons(QMessageBox.Yes | QMessageBox.Cancel) msg = msg.exec() if msg == QMessageBox.Yes: self.progressBar.setProperty("value", 0) self.p.kill() pass else: return self.overrideConfig() CURRENT_OS = os.name if CURRENT_OS == "nt": args = ["naive.exe", "config.json"] self.p = Popen(["naive.exe", "config.json"], stderr=STDOUT, stdout=PIPE) self.testConnection() elif CURRENT_OS == "postfix": args = ["naive", "config.json"] self.p = Popen(["naive.exe", "config.json"], stderr=STDOUT, stdout=PIPE) self.testConnection() def disconnectFromNaive(self): if self.CONNECTED: self.p.kill() self.progressBar.setProperty("value", 0) self.CONNECTED = False msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText("Naive disconnected") msg.setWindowTitle("Connection Terminated") msg.exec_() else: msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText("Naive not connected") msg.setWindowTitle("No connection") msg.exec_() def exitOnClick(self): if (self.CONNECTED): self.p.kill() quit()
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, 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())
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle(WINDOW_TITLE) from pathlib import Path file_name = str(Path(__file__).resolve().parent / 'favicon.ico') icon = QIcon(file_name) self.setWindowIcon(icon) self.tray = QSystemTrayIcon(icon) self.tray.setToolTip(self.windowTitle()) self.tray.activated.connect(self._on_tray_activated) self.tray.show() self.logged_dict = dict() self.pb_refresh = QPushButton('REFRESH') self.pb_refresh.clicked.connect(self.refresh) self.cb_show_log = QCheckBox() self.cb_show_log.setChecked(True) self.log = QPlainTextEdit() self.log.setReadOnly(True) self.log.setWordWrapMode(QTextOption.NoWrap) log_font = self.log.font() log_font.setFamily('Courier New') self.log.setFont(log_font) self.cb_show_log.clicked.connect(self.log.setVisible) self.log.setVisible(self.cb_show_log.isChecked()) header_labels = ['DATE', 'TOTAL LOGGED TIME'] self.table_logged = QTableWidget() self.table_logged.setEditTriggers(QTableWidget.NoEditTriggers) self.table_logged.setSelectionBehavior(QTableWidget.SelectRows) self.table_logged.setSelectionMode(QTableWidget.SingleSelection) self.table_logged.setColumnCount(len(header_labels)) self.table_logged.setHorizontalHeaderLabels(header_labels) self.table_logged.horizontalHeader().setStretchLastSection(True) self.table_logged.itemClicked.connect( self._on_table_logged_item_clicked) header_labels = ['TIME', 'LOGGED', 'JIRA'] self.table_logged_info = QTableWidget() self.table_logged_info.setEditTriggers(QTableWidget.NoEditTriggers) self.table_logged_info.setSelectionBehavior(QTableWidget.SelectRows) self.table_logged_info.setSelectionMode(QTableWidget.SingleSelection) self.table_logged_info.setColumnCount(len(header_labels)) self.table_logged_info.setHorizontalHeaderLabels(header_labels) self.table_logged_info.horizontalHeader().setSectionResizeMode( 1, QHeaderView.ResizeToContents) self.table_logged_info.horizontalHeader().setStretchLastSection(True) self.table_logged_info.itemDoubleClicked.connect( self._on_table_logged_info_item_double_clicked) main_layout = QVBoxLayout() central_widget = QWidget() central_widget.setLayout(main_layout) self.setCentralWidget(central_widget) self.pb_refresh.setSizePolicy( QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)) h_layout = QHBoxLayout() h_layout.addWidget(self.pb_refresh) h_layout.addWidget(self.cb_show_log) layout_table_widget = QVBoxLayout() layout_table_widget.setContentsMargins(0, 0, 0, 0) layout_table_widget.addWidget(self.table_logged) layout_table_widget.addWidget(self.table_logged_info) table_widget = QWidget() table_widget.setLayout(layout_table_widget) splitter = QSplitter(Qt.Horizontal) splitter.addWidget(table_widget) splitter.addWidget(self.log) main_layout.addLayout(h_layout) main_layout.addWidget(splitter) def _fill_tables(self, xml_data: bytes): import io buffer_io = io.StringIO() from contextlib import redirect_stdout try: with redirect_stdout(buffer_io): print(len(xml_data), repr(xml_data[:50])) # Структура документа -- xml self.logged_dict = parse_logged_dict(xml_data) print(self.logged_dict) if not self.logged_dict: return import json print( json.dumps(self.logged_dict, indent=4, ensure_ascii=False)) print() logged_list = get_logged_list_by_now_utc_date(self.logged_dict) logged_total_seconds = get_logged_total_seconds(logged_list) logged_total_seconds_str = seconds_to_str(logged_total_seconds) print('entry_logged_list:', logged_list) print('today seconds:', logged_total_seconds) print('today time:', logged_total_seconds_str) print() # Для красоты выводим результат в табличном виде lines = [] # Удаление строк таблицы while self.table_logged.rowCount(): self.table_logged.removeRow(0) for i, (date_str, logged_list) in enumerate( get_sorted_logged(self.logged_dict)): total_seconds = get_logged_total_seconds(logged_list) total_seconds_str = seconds_to_str(total_seconds) row = date_str, total_seconds_str, total_seconds lines.append(row) self.table_logged.setRowCount( self.table_logged.rowCount() + 1) self.table_logged.setItem(i, 0, QTableWidgetItem(date_str)) item = QTableWidgetItem(total_seconds_str) item.setToolTip('Total seconds: {}'.format(total_seconds)) self.table_logged.setItem(i, 1, item) self.table_logged.setCurrentCell(0, 0) self.table_logged.setFocus() self._on_table_logged_item_clicked( self.table_logged.currentItem()) # Список строк станет списком столбцов, у каждого столбца подсчитается максимальная длина max_len_columns = [ max(map(len, map(str, col))) for col in zip(*lines) ] # Создание строки форматирования: [30, 14, 5] -> "{:<30} | {:<14} | {:<5}" my_table_format = ' | '.join('{:<%s}' % max_len for max_len in max_len_columns) for line in lines: print(my_table_format.format(*line)) finally: text = buffer_io.getvalue() self.log.setPlainText(text) print(text) def refresh(self): progress_dialog = QProgressDialog(self) thread = RunFuncThread(func=get_rss_jira_log) thread.run_finished.connect(self._fill_tables) thread.run_finished.connect(progress_dialog.close) thread.start() progress_dialog.setWindowTitle('Please wait...') progress_dialog.setLabelText(progress_dialog.windowTitle()) progress_dialog.setRange(0, 0) progress_dialog.exec() from datetime import datetime self.setWindowTitle(WINDOW_TITLE + ". Last refresh date: " + datetime.now().strftime('%d/%m/%Y %H:%M:%S')) def _on_table_logged_item_clicked(self, item: QTableWidgetItem): # Удаление строк таблицы while self.table_logged_info.rowCount(): self.table_logged_info.removeRow(0) row = item.row() date_str = self.table_logged.item(row, 0).text() logged_list = self.logged_dict[date_str] logged_list = reversed(logged_list) for i, logged in enumerate(logged_list): self.table_logged_info.setRowCount( self.table_logged_info.rowCount() + 1) self.table_logged_info.setItem(i, 0, QTableWidgetItem(logged['time'])) self.table_logged_info.setItem( i, 1, QTableWidgetItem(logged['logged_human_time'])) item = QTableWidgetItem(logged['jira_id']) item.setToolTip(logged['jira_title']) self.table_logged_info.setItem(i, 2, item) def _on_table_logged_info_item_double_clicked(self, item: QTableWidgetItem): row = item.row() jira_id = self.table_logged_info.item(row, 2).text() url = 'https://jira.compassplus.ru/browse/' + jira_id import webbrowser webbrowser.open(url) def _on_tray_activated(self, reason): self.setVisible(not self.isVisible()) if self.isVisible(): self.showNormal() self.activateWindow() def changeEvent(self, event: QEvent): if event.type() == QEvent.WindowStateChange: # Если окно свернули if self.isMinimized(): # Прячем окно с панели задач QTimer.singleShot(0, self.hide)