#-*- coding: utf-8 -*- # Copyright 2010-2016 Mir Calculate. http://www.calculate-linux.org # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import dbus import dbus.service import dbus.mainloop.glib from .. import qt import time, sys import calculate.contrib from suds import MethodNotFound import os, pwd, shutil # import ConfigParser import calculate.lib.configparser as ConfigParser from .TrayIcon import TrayIcon from .more import get_sid, get_view_params, _print, get_icon, get_system_rgb, \ dpivalue from .MainClass import ApiClient from ..datavars import DataVarsGui from .pid_information import client_pid_info #from calculate.lib.cl_lang import setLocalTranslate #setLocalTranslate('console_gui',sys.modules[__name__]) import gettext _ = gettext.gettext class SelectedMethodWgt(qt.QWidget): def __init__(self, app, args): super().__init__() self.args = args self.user_changed_flag = False self.lang = args.lang self.method = args.method self.skip_options = args.skip_options # Initialization GUI variables self.VarsGui = DataVarsGui() self.VarsGui.importGui() self.VarsGui.flIniFile() self.ClientObj = ApiClient(app, self) self.port = args.port or self.VarsGui.GetInteger('core.cl_core_port') self.MethodWidget = self.ClientObj.MainWidget self.MethodWidget.topmenu.hide() layout = qt.QHBoxLayout(self) layout.setContentsMargins(0,0,0,0) layout.setSpacing(0) layout.addWidget(self.MethodWidget) icon = get_icon('console-gui-%s'%self.method.replace("_","-"), 'calculate-%s'%self.method.replace("_","-")) self.setWindowIcon(icon) qt.QApplication.setWindowIcon(icon) conf_path = self.VarsGui.Get('cl_gui_config_path') homePath = self.VarsGui.Get('ur_home_path') self.user_config = conf_path.replace("~",homePath) if self.connect(): sys.exit(1) if not self.get_size(): # definition of screen resolution prim_screen = app.desktop().primaryScreen() d_size = app.desktop().screenGeometry(prim_screen).size() # resize main widget if d_size.height() < 768: self.resize(900,560) else: self.resize(900, 726) self.setMinimumHeight(100) self.setMinimumWidth(500) self.show() def connect(self): self.MethodWidget.connect_to_localhost(self.args.host, self.port) if not self.ClientObj.client: return 1 self.ClientObj.sid = get_sid(self.ClientObj.client) try: view_params = get_view_params(self.ClientObj.client, \ self.args.method + '_view', step = 0) view = self.ClientObj.client.service[0][self.args.method + \ '_view'](int(self.ClientObj.sid), view_params) except MethodNotFound: _print('Method not found: ', self.args.method + '_view') self.close() sys.exit(1) if self.args.method in self.ClientObj.method_names: view_method = self.ClientObj.method_names[self.args.method] else: view_method = self.args.method self.setWindowTitle(view_method + ' - ' + \ self.ClientObj._parent.windowTitle()) #self.MethodWidget.MainFrameWgt.call_server_method(False) #self.MethodWidget.main_frame_view(view, self.args.method, # skip_options=not self.args.skip_options) self.MethodWidget.main_frame_view(view, self.args.method, skip_options=self.args.skip_options) return 0 def translate(self, lang = None): return 0 def connect_count_changed(self, host, port, count): pass def has_update(self, update): print("Update", update) def get_size(self): self.config = ConfigParser.ConfigParser() self.config.read(self.user_config) try: size = self.config.get('gui', 'size') except (ConfigParser.NoOptionError, ConfigParser.NoSectionError): return False tup_size = [int(x) for x in size.split(',')] self.resize(tup_size[0], tup_size[1]) return True def set_size(self): self.config = ConfigParser.ConfigParser() self.config.read(self.user_config) try: selfsize = self.size() self.config.set('gui', 'size', "{},{}".format(selfsize.width(), selfsize.height())) with open(self.user_config, 'w') as f: self.config.write(f) except (ConfigParser.NoOptionError, ConfigParser.NoSectionError): return False def closeEvent(self, event): close_event = self._closeEvent() # event.ignore() if close_event: self.set_size() save_path = os.path.join('/tmp', 'calculate-' + \ pwd.getpwuid(os.getuid()).pw_name) if os.path.isdir(save_path): shutil.rmtree(save_path) event.accept() else: event.ignore() def _closeEvent(self): if not self.isVisible(): if self.ClientObj.signaling.isRunning(): self.ClientObj.signaling.close() self.ClientObj.signaling.wait() return 1 if not self.user_changed_flag: reply = qt.QMessageBox.Yes else: reply = self.show_close_messagebox() from .mainframe import MainFrame if reply == qt.QMessageBox.Yes: if hasattr (self, 'con_lost_lbl'): self.con_lost_lbl.hide() self.con_lost_lbl.close() # Exit with closing session if self.ClientObj.signaling.isRunning(): self.ClientObj.signaling.close() self.ClientObj.signaling.wait() if type (self.MethodWidget.MainFrameWgt) == MainFrame: return 1 else: pid = int(self.MethodWidget.MainFrameWgt.cur_pid) self.MethodWidget.MainFrameWgt.close() self.ClientObj.client.service.pid_kill(pid, self.ClientObj.sid) while True: client_pid_info(self.ClientObj, self.ClientObj.client, 0) if 'status' not in self.ClientObj.process_dict[str(pid)]: return 1 if self.ClientObj.process_dict[str(pid)]['status'] != '1': return 1 time.sleep(1) elif reply == qt.QMessageBox.No: return 0 def user_changed(self): self.user_changed_flag = True def show_close_messagebox(self): msgBox = qt.QMessageBox(self) if self.method in self.ClientObj.method_names: method_name = self.ClientObj.method_names[self.method] else: method_name = self.method msgBox.setText(_("Close") +' "%s"?' %method_name) msgBox.setStandardButtons(qt.QMessageBox.Yes | qt.QMessageBox.No) # translate msgBox.button(msgBox.Yes).setText(_('Yes')) msgBox.button(msgBox.No).setText(_('No')) icon = get_icon('dialog-close') if not icon.isNull(): msgBox.button(msgBox.No).setIcon(icon) msgBox.setDefaultButton(qt.QMessageBox.No) msgBox.setWindowIcon(get_icon("application-exit")) reply = msgBox.exec_() return reply def parse(): import gettext import locale try: # set_lang = gettext.locale.getdefaultlocale()[0][:2] set_lang = locale.getdefaultlocale()[0][:2] lang = gettext.translation('cl_consolegui3', languages=[set_lang],fallback=True) try: lang.install() # lang.install(unicode=True) except UnboundLocalError: pass except (IOError, TypeError): pass _ = gettext.gettext import argparse parser = argparse.ArgumentParser(add_help=False) parser.add_argument( '-h', '--help', action='store_true', default=False, dest='help', help=_("show this help message and exit")) parser.add_argument( '-l', '--lang', type=str, dest='lang', help=_("translation language")) parser.add_argument( '--method', type=str, dest='method', help=_('call method')) parser.add_argument( '--skip-options', action='store_true', dest='skip_options', default=False, help=_('run the method without options')) parser.add_argument( '-p', '--port', type=int, dest='port', help=_('port number')) parser.add_argument( '--host', type=str, default = 'localhost', dest='host', help=_('destination host')) return parser class MyTabBar(qt.QTabBar): def __init__(self, _parent): super().__init__() self._parent = _parent def wheelEvent(self, event): event.ignore() def mousePressEvent(self, event): if event.button() == qt.Qt.LeftButton: self.setCurrentIndex(self.tabAt(event.pos())) event.accept() if event.button() == qt.Qt.MiddleButton: self._parent.close_tab(self.tabAt(event.pos())) class ToolTabWidget(qt.QTabWidget): def __init__(self, app, args = None, host = None, port = None): super().__init__() self.app = app if args: if args.lang: self.lang = args.lang self.current_icon = None self.setContentsMargins(0,0,0,0) self.init_variables() # Initialization GUI variables self.VarsGui = DataVarsGui() self.VarsGui.importGui() self.VarsGui.flIniFile() ClientObj = ApiClient(app, self) self.FirstWidget = ClientObj.MainWidget self.PlusWidget = qt.QWidget(self) self.tabbar = MyTabBar(self) self.setTabBar(self.tabbar) self.gui_icon = get_icon("video-display") self.other_icon = get_icon("list-add", "preferences-desktop") self.addTab(self.FirstWidget, self.gui_icon , self.new_con_txt) self.addTab(self.PlusWidget, self.other_icon, '') self.last_close_index = -1 self.tabCloseRequested.connect(self.close_tab) self.currentChanged.connect(self.add_tab) self.currentChanged.connect(self.changeWindowTitle) self.setTabsClosable(True) self.tabbar.tabButton(1, qt.QTabBar.RightSide).hide() if not self.get_size(): # definition of screen resolution prim_screen = self.app.desktop().primaryScreen() d_size = self.app.desktop().screenGeometry(prim_screen).size() # resize main widget if d_size.height() < 768: self.resize(900,560) else: self.resize(dpivalue(900), dpivalue(700)) self.setMinimumHeight(100) self.setMinimumWidth(500) self.setWindowTitle(self.Name) hbg = get_system_rgb(self, qt.QPalette.Base) bg = "transparent" leftpadding = 8 width = 24 #self.setStyleSheet(''' #QTabBar::tab:last { #background: %s; #margin: 2px 2px 3px 0px; #width: %s; #padding: 0px 0px 0px %spx;} #QTabBar::tab:last::hover { # background: %s;}''' % (bg, width, leftpadding, hbg)) self.set_offline_icon() self.show() self.app.processEvents() self.connect_dict = {} self.connect_count = 0 if not host or host == 'localhost': self.host = '127.0.0.1' else: self.host = host if not port: self.port = self.VarsGui.GetInteger('core.cl_core_port') else: self.port = port self.setEnabled(False) qt.QTimer.singleShot(200, self.connect_after_init) self.create_tray() if self.FirstWidget.ClientObj.client: self.tray.set_icon(True) def connect_after_init(self): self.FirstWidget.connect_to_localhost(self.host, self.port) self.setEnabled(True) if self.FirstWidget.ClientObj.client: self.FirstWidget.updateColors() if self.host in ['127.0.0.1', 'localhost']: self.localhost_ClientObj = self.FirstWidget.ClientObj if not self.host in self.connect_dict: self.connect_dict[self.host] = [self.port] else: if self.port: if not self.port in self.connect_dict[self.host]: self.connect_dict[self.host].append(self.port) def set_offline_icon(self): if self.current_icon != "offline": self.current_icon = "offline" self.setWindowIcon(get_icon( '/usr/share/pixmaps/calculate-console-offline.svg')) def set_online_icon(self): if self.current_icon != "online": self.current_icon = "online" self.setWindowIcon(get_icon( '/usr/share/pixmaps/calculate-console-online.svg')) def connect_count_changed(self, host, port, count): if count: if not host in self.connect_dict: self.connect_dict[host] = [port] else: if port: if not port in self.connect_dict[host]: self.connect_dict[host].append(port) else: if host in self.connect_dict: if port in self.connect_dict[host]: self.connect_dict[host].remove(port) if not self.connect_dict[host]: self.connect_dict.pop(host) if self.connect_dict: self.set_online_icon() if hasattr(self, 'tray'): self.tray.set_icon(True) else: self.set_offline_icon() if hasattr(self, 'tray'): self.tray.set_icon(False) def init_variables(self): try: self.Version = self.VarsGui.Get('cl_ver') except: self.Version = '' #try: # self.Name = self.VarsGui.Get('cl_name') #except: self.Name = 'Calculate Console' self.new_con_txt = _('New connection') self.sys_update_pid = None def close_tab(self, cur_num = None, hard = False): exit_flag = 0 if cur_num == None: cur_num = self.currentIndex() if cur_num != self.count() - 1: # for delete widget self.setCurrentIndex(cur_num) wgt = self.currentWidget() if wgt == self.FirstWidget and not hard: return exit_flag if wgt._closeEvent(): wgt.close() self.last_close_index = cur_num if cur_num: self.setCurrentIndex(cur_num - 1) else: self.setCurrentIndex(0) self.removeTab(cur_num) exit_flag = 1 if self.count() < 2: self.add_tab() return exit_flag def add_tab(self): if self.currentIndex() == self.count() - 1: # not add if exists clean tab for tab_num in range(self.count() - 1): self.setCurrentIndex(tab_num) if not self.currentWidget().ClientObj.client: return 0 ClientObj = ApiClient(self.app, self) widget = ClientObj.MainWidget widget.cur_window_title = self.Name self.insertTab(self.count() - 1, widget, self.gui_icon , \ self.new_con_txt) self.setCurrentIndex(self.count() - 2) if self.currentWidget().ClientObj.client: self.tabbar.setTabEnabled(self.count() - 1, True) else: self.tabbar.setTabEnabled(self.count() - 1, False) def rename_tab(self, text = None, ind = None): if not text: text = self.new_con_txt if not ind: ind = self.currentIndex() self.setTabText(ind, text) def changeWindowTitle(self, tab_num): try: text = self.currentWidget().cur_window_title self.setWindowTitle(text) except AttributeError: pass def setWindowTitle(self, title): self.currentWidget().cur_window_title = title super(ToolTabWidget, self).setWindowTitle(title) def create_tray(self): self.tray = TrayIcon(self) self.tray.setVisible(True) self.app.processEvents() def translate(self, lang = None): self.new_con_txt = _('New connection') # self.new_con_txt = self.new_con_txt.decode('utf-8') current = self.currentIndex() # not add if exists clean tab for tab_num in range(self.count() - 1): self.setCurrentIndex(tab_num) if not self.currentWidget().ClientObj.client: self.setTabText(tab_num, self.new_con_txt) self.setCurrentIndex(current) if hasattr(self, 'tray'): self.tray.translate() def set_localhost(self, ClientObj): self.localhost_ClientObj = ClientObj # if ClientObj: # self.connect_dict[ClientObj.host_name] = \ # [ClientObj, self.currentIndex()] # self.tabbar.tabButton(self.currentIndex(), \ # qt.QTabBar.RightSide).hide() def find_host(self, host_name, port): ind = self.currentIndex() for i in range (self.count() - 1): self.setCurrentIndex(i) wgt = self.currentWidget() if hasattr (wgt, 'ClientObj'): ClientObj = wgt.ClientObj if host_name == ClientObj.host_name and \ port == ClientObj.port and ClientObj.client: self.removeTab(ind) return 1 self.setCurrentIndex(ind) return 0 def closeEvent(self, event): self.cur_pos = self.pos() self.hide() from os import environ if environ.get("XSESSION","").lower() == "plasma": event.accept() else: event.ignore() def _closeEvent(self): for tab_num in range(self.count()): if not self.close_tab(0, True): return 1 self.set_size() save_path = os.path.join('/tmp', 'calculate-' + \ pwd.getpwuid(os.getuid()).pw_name) if os.path.isdir(save_path): shutil.rmtree(save_path) self.app.exit() def get_size(self): conf_path = self.VarsGui.Get('cl_gui_config_path') homePath = self.VarsGui.Get('ur_home_path') self.user_config = conf_path.replace("~",homePath) self.config = ConfigParser.ConfigParser() self.config.read(self.user_config) try: size = self.config.get('gui', 'size') except (ConfigParser.NoOptionError, ConfigParser.NoSectionError): return False tup_size = [int(x) for x in size.split(',')] self.resize(tup_size[0], tup_size[1]) return True def set_size(self): self.config = ConfigParser.ConfigParser() self.config.read(self.user_config) try: selfsize = self.size() self.config.set('gui', 'size', "{},{}".format(selfsize.width(), selfsize.height())) with open(self.user_config, 'w') as f: self.config.write(f) except (ConfigParser.NoOptionError, ConfigParser.NoSectionError): return False def keyPressEvent(self, e): if e.key() == qt.Qt.Key_Return: self.currentWidget().keyPressEvent(e) else: qt.QTabWidget.keyPressEvent(self, e)