You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
calculate-utils-3-console-gui/pym/consolegui/application/ConnectionTabs.py

585 lines
20 KiB

#-*- 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 calculate.consolegui import qt
import time, sys
import calculate.contrib
from suds import MethodNotFound
import os, pwd, shutil
import 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 calculate.consolegui.datavars import DataVarsGui
from pid_information import client_pid_info
#from calculate.lib.cl_lang import setLocalTranslate
#setLocalTranslate('console_gui',sys.modules[__name__])
class SelectedMethodWgt(qt.QWidget):
def __init__(self, app, args):
qt.QWidget.__init__(self)
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.ClientObj.method_names.has_key(self.args.method):
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 = map(lambda x: int(x), 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 not self.ClientObj.process_dict[str(pid)].has_key \
('status'):
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.ClientObj.method_names.has_key(self.method):
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
try:
set_lang = gettext.locale.getdefaultlocale()[0][:2]
lang = gettext.translation('cl_consolegui3', languages=[set_lang],fallback=True)
try:
lang.install(unicode=True)
except UnboundLocalError:
pass
except (IOError, TypeError):
pass
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):
qt.QTabBar.__init__(self)
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):
qt.QTabWidget.__init__(self)
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 xrange (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 = map(lambda x: int(x), 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)