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.
1203 lines
46 KiB
1203 lines
46 KiB
#-*- coding: utf-8 -*-
|
|
|
|
# Copyright 2012-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.
|
|
|
|
from __future__ import print_function
|
|
from __future__ import absolute_import
|
|
from calculate.consolegui import qt
|
|
|
|
DEBUG_LEVEL = 0
|
|
|
|
def debug(level, *args):
|
|
if level <= DEBUG_LEVEL:
|
|
for s in args:
|
|
print(s, end=' ')
|
|
print()
|
|
import calculate.contrib
|
|
from urllib.error import URLError
|
|
from suds import MethodNotFound
|
|
import re
|
|
|
|
|
|
from calculate.lib.utils.colortext.converter import XmlConverter
|
|
from calculate.lib.utils.colortext.output import SpanCssOutput
|
|
from calculate.lib.utils.tools import imap_regexp
|
|
from .utils import switch, create_obj
|
|
from .more import WorkPalette, ParameterWindow, get_system_rgb
|
|
|
|
from .more import get_sid, ClientServiceThread, show_msg, TaskWidget, ErrorWgt,\
|
|
ResultLayout, get_view_params, get_icon, dpivalue
|
|
from .more import LabelWordWrap as Label
|
|
from .SelectTable import SelectedTableWidget
|
|
|
|
class LabelWordWrap(Label):
|
|
def __init__(self, name, parent=None, mono=False, margin_top=0):
|
|
Label.__init__(self, name, parent, mono, margin_top)
|
|
# set text selectable
|
|
self.setTextInteractionFlags(self.textInteractionFlags() | \
|
|
qt.Qt.TextSelectableByMouse)
|
|
|
|
class PlusButton(qt.QPushButton):
|
|
def __init__(self, parent, ClientObj, method, disable_method=None):
|
|
super().__init__(parent)
|
|
icon = get_icon('list-add')
|
|
if not icon.isNull():
|
|
self.setIcon(icon)
|
|
else:
|
|
self.setText('+')
|
|
self._parent = parent
|
|
self.ClientObj = ClientObj
|
|
self.method = method
|
|
self.setFixedSize(30, 30)
|
|
if disable_method:
|
|
self.clicked.connect(disable_method)
|
|
self.clicked.connect(self.call_method)
|
|
|
|
def call_method(self):
|
|
# Call server method
|
|
if hasattr (self, 'get_Frame_thread'):
|
|
if self.get_Frame_thread.isRunning():
|
|
return 1
|
|
sid = int(self.ClientObj.sid)
|
|
view_params = get_view_params(self.ClientObj.client, \
|
|
self.method + '_view')
|
|
self.get_Frame_thread = ClientServiceThread(self.ClientObj,\
|
|
self.method + '_view', sid, view_params)
|
|
self.get_Frame_thread.signal.connect(self.after_call)
|
|
self.get_Frame_thread.start()
|
|
|
|
def after_call(self, view):
|
|
if self.method in self.ClientObj.method_names:
|
|
view_method = self._parent.ClientObj.method_names[self.method]
|
|
else:
|
|
view_method = self.method
|
|
self._parent.ClientObj._parent.setWindowTitle(view_method +
|
|
' - ' + self.ClientObj.Name)
|
|
self._parent._parent.main_frame_view(view, self.method)
|
|
|
|
class MainFrameRes(qt.QWidget):
|
|
valSignal = qt.Signal()
|
|
def __init__(self, parent, ClientObj, method_name, meth_result,
|
|
change_offset=False):
|
|
super().__init__(parent)
|
|
self._parent = parent
|
|
self.ClientObj = ClientObj
|
|
self.method_name = method_name
|
|
self.meth_result = meth_result
|
|
self.client = ClientObj.client
|
|
self.cur_pid = 0
|
|
self.change_offset = change_offset
|
|
self.show_last = True
|
|
self.max_val = None
|
|
self.buttons = []
|
|
|
|
if self.meth_result.type == "pid":
|
|
self.cur_pid = self.meth_result.message
|
|
|
|
self.work_layout = ResultLayout(self)
|
|
self.work_layout.kill_process_button.clicked.connect \
|
|
(self.kill_process(self.cur_pid))
|
|
|
|
self.progress_list = []
|
|
self.task_list = []
|
|
|
|
self._parent.methodname_wgt.show()
|
|
self._parent.control_button.show()
|
|
#DEBUG
|
|
# self._parent.control_button.del_button()
|
|
if self.method_name in self.ClientObj.method_names:
|
|
self._parent.methodname_wgt.setMethodName \
|
|
(self.ClientObj.method_names[self.method_name])
|
|
else:
|
|
self._parent.methodname_wgt.setMethodName(method_name)
|
|
parent.main_frame.viewport().setObjectName('main_frame')
|
|
#parent.main_frame.viewport().setStyleSheet("#main_frame "
|
|
# "{background-color: #FFFFFF;}")
|
|
# #"{background-color: #E4E1E0;}")
|
|
#self.setObjectName("Frame_Res")
|
|
#self.setStyleSheet("#Frame_Res {background-color: %s;}"% get_system_rgb(self, ParameterWindow))
|
|
#self.setStyleSheet("#Frame_Res {background-color: green;}")
|
|
# "QWidget {border: 1px solid red;}")
|
|
|
|
self.timer = qt.QTimer(self)
|
|
self.timer.timeout.connect(self.show_bottom)
|
|
self.timer.start(100)
|
|
self.valSignal.connect(self.show_bottom)
|
|
|
|
|
|
def initUI(self):
|
|
#self.setSizePolicy(qt.QSizePolicy.Minimum,qt.QSizePolicy.Minimum)
|
|
self.updateGeometry()
|
|
|
|
def show_bottom(self):
|
|
debug(20, "SHOW BOTTOM PAGE")
|
|
max_val = self._parent.main_frame.verticalScrollBar().maximum()
|
|
current_val = \
|
|
self._parent.main_frame.verticalScrollBar().sliderPosition()
|
|
|
|
if self.show_last:
|
|
if current_val != max_val:
|
|
if self.max_val != max_val:
|
|
self._parent.main_frame.verticalScrollBar(
|
|
).setSliderPosition(max_val)
|
|
else:
|
|
self.show_last = False
|
|
else:
|
|
if current_val == max_val:
|
|
self.show_last = True
|
|
self.max_val = max_val
|
|
|
|
################# API FUNCTION ###############################
|
|
def show_view(self, view):
|
|
pass
|
|
|
|
def show_table(self, table, item):
|
|
# method to display tables
|
|
add_offset_flag = False
|
|
|
|
if not table.body:
|
|
table.body = [[]]
|
|
self.show_normal(item)
|
|
self.mytable = None
|
|
|
|
if self.method_name in self.ClientObj.param_objects:
|
|
if len(table.body[0]) >= self.ClientObj.count_row_res_table or \
|
|
self.ClientObj.param_objects[self.method_name]['offset']:
|
|
|
|
if table.onClick and table.records != "0":
|
|
self.add_offset_buttons(len(table.body[0]),
|
|
table.addAction,
|
|
table.records)
|
|
add_offset_flag = True
|
|
|
|
if table.addAction and not add_offset_flag:
|
|
plus_but = PlusButton(self, self.ClientObj, table.addAction,
|
|
self.disable_buttons)
|
|
self.buttons.append(plus_but)
|
|
self.work_layout._addWidget(plus_but)
|
|
if table.onClick and table.body[0]:
|
|
self.mytable = SelectedTableWidget(len(table.body[0]), \
|
|
len(table.head[0]), self)
|
|
if not self.mytable:
|
|
if table.body:
|
|
len_body = len(table.body[0])
|
|
else:
|
|
len_body = 0
|
|
if table.head:
|
|
len_head = len(table.head[0])
|
|
else:
|
|
len_head = 1
|
|
if len_body:
|
|
self.mytable = SelectedTableWidget(len_body, len_head, self,
|
|
readonly=True)
|
|
if self.mytable:
|
|
list_head = table.head[0]
|
|
self.mytable.setHorizontalHeaderLabels(list_head)
|
|
for line in range(len(table.body[0])):
|
|
for i in range(len(table.body[0][line][0])):
|
|
tablewidgetitem = qt.QTableWidgetItem(
|
|
table.body[0][line][0][i])
|
|
self.mytable.setItem(line, i, tablewidgetitem)
|
|
# set writeonly
|
|
self.mytable.setEditTriggers(qt.QAbstractItemView.NoEditTriggers)
|
|
|
|
if table.onClick:
|
|
self.mytable.itemClicked.connect(self.row_activate(table))
|
|
|
|
self.mytable.setColor()
|
|
minimum = qt.QSizePolicy.Minimum
|
|
self.mytable.setSizePolicy(minimum, minimum)
|
|
self.mytable.horizontalHeader().resizeSections(
|
|
qt.QHeaderView.ResizeToContents)
|
|
self.work_layout._addWidget(self.mytable)
|
|
self.ClientObj.app.processEvents()
|
|
self.mytable.resizeRowsToContents()
|
|
self.mytable.resizeColumnsToContents()
|
|
|
|
self.initUI()
|
|
|
|
def row_activate(self, table):
|
|
def wrapper(item):
|
|
param_object = create_obj(self.client, table.onClick)
|
|
for field in table.fields.string:
|
|
if field:
|
|
if ":" in field:
|
|
field, op, value = field.partition(":")
|
|
else:
|
|
value = None
|
|
if hasattr (param_object, field):
|
|
if value:
|
|
param_object[field] = value
|
|
else:
|
|
param_object[field] = self.mytable.item(item.row(),0).\
|
|
text()
|
|
#print param_object, table.step
|
|
param_object.CheckOnly = True
|
|
# Calling method
|
|
sid = int(self.ClientObj.sid)
|
|
self.client.service[0][table.onClick](sid, param_object)
|
|
|
|
# Calling View
|
|
try:
|
|
self.client.service.clear_pid_cache(sid, self.cur_pid)
|
|
except:
|
|
pass
|
|
try:
|
|
view_params = get_view_params(self.client,
|
|
table.onClick + '_view', step = 0) #int(table.step) if table.step else 0)
|
|
view = self.client.service[0][table.onClick + '_view'](
|
|
sid, view_params)
|
|
except MethodNotFound as e:
|
|
_print(e)
|
|
return
|
|
if table.onClick in self._parent.ClientObj.method_names:
|
|
view_method = self._parent.ClientObj.method_names \
|
|
[table.onClick]
|
|
else:
|
|
view_method = table.onClick
|
|
self._parent.ClientObj._parent.setWindowTitle(view_method + \
|
|
' - ' + self.ClientObj.Name)
|
|
#self.ClientObj.param_objects[self.method_name]['offset'] = 0
|
|
self._parent.main_frame_view(
|
|
view, table.onClick,
|
|
new_step=table.step if table.step else None)
|
|
return wrapper
|
|
|
|
def disable_buttons(self):
|
|
debug(11, "DISABLE", self.buttons)
|
|
for button in self.buttons:
|
|
button.setDisabled(True)
|
|
self.timer.stop()
|
|
|
|
def add_offset_buttons(self, len_body, addAction, records):
|
|
offset_buttons = qt.QWidget()
|
|
layout = qt.QHBoxLayout(offset_buttons)
|
|
layout.setAlignment(qt.Qt.AlignLeft)
|
|
|
|
offset = self.ClientObj.param_objects[self.method_name]['offset']
|
|
count_records = int(self.ClientObj.count_row_res_table)
|
|
debug(15, "DATA:", records, offset, count_records)
|
|
records = int(records) or 0
|
|
if records:
|
|
if offset + count_records >= records:
|
|
last = True
|
|
else:
|
|
last = False
|
|
else:
|
|
if len_body < self.ClientObj.count_row_res_table:
|
|
last = True
|
|
else:
|
|
last = False
|
|
|
|
|
|
begin_offset = qt.QPushButton(offset_buttons)
|
|
begin_offset.setIcon(get_icon('go-first'))
|
|
begin_offset.setToolTip('First page')
|
|
begin_offset.clicked.connect(self.disable_buttons)
|
|
begin_offset.clicked.connect(self.call_method_with_offset(0, True))
|
|
begin_offset.setFixedSize(30, 30)
|
|
self.buttons.append(begin_offset)
|
|
|
|
layout.addWidget(begin_offset)
|
|
|
|
minus_offset = qt.QPushButton(offset_buttons)
|
|
minus_offset.setIcon(get_icon('go-previous'))
|
|
minus_offset.setToolTip('Previous page')
|
|
minus_offset.clicked.connect(self.disable_buttons)
|
|
minus_offset.clicked.connect(self.call_method_with_offset(
|
|
-count_records))
|
|
minus_offset.setFixedSize(30, 30)
|
|
layout.addWidget(minus_offset)
|
|
self.buttons.append(minus_offset)
|
|
|
|
if not offset:
|
|
minus_offset.setDisabled(True)
|
|
begin_offset.setDisabled(True)
|
|
|
|
|
|
plus_offset = qt.QPushButton(offset_buttons)
|
|
plus_offset.setIcon(get_icon('go-next'))
|
|
plus_offset.setToolTip('Next page')
|
|
plus_offset.clicked.connect(self.disable_buttons)
|
|
plus_offset.clicked.connect(self.call_method_with_offset(
|
|
count_records))
|
|
plus_offset.setFixedSize(30, 30)
|
|
layout.addWidget(plus_offset)
|
|
self.buttons.append(plus_offset)
|
|
|
|
last_offset = qt.QPushButton(offset_buttons)
|
|
last_offset.setIcon(get_icon('go-last'))
|
|
last_offset.setToolTip('Last page')
|
|
last_offset.clicked.connect(self.disable_buttons)
|
|
last_offset.clicked.connect(self.call_method_with_offset(
|
|
0, False, records - count_records))
|
|
last_offset.setFixedSize(30, 30)
|
|
layout.addWidget(last_offset)
|
|
self.buttons.append(last_offset)
|
|
|
|
if last or not records:
|
|
last_offset.setDisabled(True)
|
|
if last:
|
|
plus_offset.setDisabled(True)
|
|
|
|
if addAction:
|
|
plus_but = PlusButton(self, self.ClientObj, addAction,
|
|
self.disable_buttons)
|
|
self.buttons.append(plus_but)
|
|
layout.addWidget(plus_but)
|
|
|
|
self.work_layout._addWidget(offset_buttons)
|
|
|
|
def call_method_with_offset(self, offset, begin=False, reset=None):
|
|
def wrapper():
|
|
debug(10, "CHANGE OFFSET FOR %s to %d" % (
|
|
self.method_name, offset))
|
|
if begin:
|
|
self.ClientObj.param_objects[self.method_name]['offset'] = 0
|
|
elif reset is not None:
|
|
self.ClientObj.param_objects[self.method_name]['offset'] = \
|
|
reset
|
|
else:
|
|
self.ClientObj.param_objects[self.method_name]['offset'] += offset
|
|
if self.ClientObj.param_objects[self.method_name]['offset'] < 0:
|
|
self.ClientObj.param_objects[self.method_name]['offset'] = 0
|
|
|
|
# Calling View
|
|
debug(10, "CALL VIEW", self.method_name)
|
|
sid = int(self.ClientObj.sid)
|
|
try:
|
|
view_params = get_view_params(self.client,
|
|
self.method_name + '_view', step = None)
|
|
view = self.client.service[0][self.method_name + '_view'] \
|
|
(sid, view_params)
|
|
except MethodNotFound:
|
|
return
|
|
#if self._parent.ClientObj.method_names.has_key(self.method_name):
|
|
# view_method = self._parent.ClientObj.method_names \
|
|
# [self.method_name]
|
|
#else:
|
|
view_method = self.method_name
|
|
self._parent.ClientObj._parent.setWindowTitle(view_method + \
|
|
' - ' + self.ClientObj.Name)
|
|
self._parent.main_frame_view(view, view_method, change_offset=True)
|
|
return wrapper
|
|
|
|
def show_message(self, message, mono=False, space=0):
|
|
message = self.processTags(message)
|
|
# add normal message label
|
|
lbl_temp = LabelWordWrap(message, self, mono=mono, margin_top=space)
|
|
if mono:
|
|
lbl_temp.setMinimumHeight(lbl_temp.minimumSizeHint().height())
|
|
lbl_temp.setMaximumHeight(lbl_temp.sizeHint().height())
|
|
else:
|
|
lbl_temp.setMinimumHeight(lbl_temp.minimumSizeHint().height())
|
|
lbl_temp.setMaximumHeight(lbl_temp.sizeHint().height())
|
|
self.work_layout._addWidget(lbl_temp)
|
|
self.initUI()
|
|
return lbl_temp
|
|
#self._parent.main_frame.verticalScrollBar().setSliderPosition \
|
|
# (self._parent.main_frame.verticalScrollBar().maximum())
|
|
|
|
def show_normal(self, item, mono=False):
|
|
if not hasattr(item, 'message'):
|
|
return
|
|
if item.message:
|
|
self.show_message(item.message, mono)
|
|
if not mono:
|
|
if self.progress_list:
|
|
self.progress_list[-1].hide()
|
|
self.add_Progress()
|
|
|
|
def show_error(self, message):
|
|
# add error message label
|
|
self.set_result_task(True)
|
|
if self.progress_list:
|
|
self.progress_list[len(self.progress_list)-1].hide()
|
|
if message:
|
|
message = self.processTags(message)
|
|
lbl_temp = ErrorWgt(message, self)
|
|
lbl_temp.set_error()
|
|
lbl_temp.setMinimumHeight(lbl_temp.minimumSizeHint().height())
|
|
lbl_temp.setMaximumHeight(lbl_temp.minimumSizeHint().height())
|
|
#lbl_temp.setMinimumHeight(lbl_temp.sizeHint().height())
|
|
self.work_layout._addWidget(lbl_temp)
|
|
|
|
self.initUI()
|
|
|
|
def show_warning(self, item):
|
|
# add warning message label
|
|
if item.message:
|
|
item.message = self.processTags(item.message)
|
|
lbl_temp = ErrorWgt(item.message, self)
|
|
lbl_temp.set_warning()
|
|
lbl_temp.setMinimumHeight(lbl_temp.minimumSizeHint().height())
|
|
lbl_temp.setMaximumHeight(lbl_temp.minimumSizeHint().height())
|
|
self.work_layout._addWidget(lbl_temp)
|
|
self.initUI()
|
|
|
|
def show_group(self, item, *args):
|
|
pass
|
|
|
|
def show_result(self, result):
|
|
# add normal message label
|
|
lbl_temp = LabelWordWrap(result.message, self)
|
|
|
|
lbl_temp.setMinimumHeight(lbl_temp.sizeHint().height())
|
|
self.work_layout._addWidget(lbl_temp)
|
|
|
|
self.initUI()
|
|
|
|
def processTags(self, s):
|
|
xc = XmlConverter(SpanCssOutput(palette=WorkPalette()))
|
|
return xc.transform(s)
|
|
|
|
def cleanTags(self, s):
|
|
xc = XmlConverter()
|
|
return xc.transform(s)
|
|
|
|
def startTask(self, item):
|
|
if self.progress_list:
|
|
self.progress_list[-1].hide()
|
|
task_widget = TaskWidget(self.processTags(item.message),
|
|
self, clean_text=self.cleanTags(item.message))
|
|
|
|
self.task_list.append(task_widget)
|
|
self.work_layout._addWidget(task_widget)
|
|
self.add_Progress()
|
|
self.initUI()
|
|
|
|
def endTask(self, item, set_res = True):
|
|
if self.progress_list:
|
|
self.progress_list[-1].hide()
|
|
message = item.message if item.message else ''
|
|
if set_res:
|
|
if message == "skip":
|
|
self.set_result_task(skip=True)
|
|
elif hasattr(item,"result") and not item.result is None:
|
|
self.set_result_task(not item.result)
|
|
else:
|
|
self.set_result_task()
|
|
if message and message != "skip":
|
|
message = self.processTags(message)
|
|
lbl_temp = LabelWordWrap(message, self)
|
|
|
|
lbl_temp.setMinimumHeight(lbl_temp.sizeHint().height())
|
|
self.work_layout._addWidget(lbl_temp)
|
|
self.initUI()
|
|
|
|
def set_result_task(self, error=False, skip=False):
|
|
if not len(self.task_list):
|
|
return
|
|
if skip:
|
|
self.task_list[len(self.task_list) - 1].set_skip()
|
|
elif error:
|
|
self.task_list[len(self.task_list) - 1].set_error()
|
|
else:
|
|
self.task_list[len(self.task_list) - 1].set_ok()
|
|
|
|
def beginFrame(self, item):
|
|
pass
|
|
|
|
def endFrame(self, item):
|
|
if self.progress_list:
|
|
self.progress_list[len(self.progress_list)-1].hide()
|
|
self.endTask(item)
|
|
|
|
self.initUI()
|
|
self.work_layout.hide_kill_button()
|
|
self.closeDialogs()
|
|
self.close_all_thread()
|
|
|
|
if self.change_offset:
|
|
self._parent.delete_MainFrameWgt()
|
|
self._parent.MainFrameWgt = self
|
|
self._parent.main_frame.setWidget (self._parent.MainFrameWgt)
|
|
self._parent.main_frame.setWidgetResizable(True)
|
|
self._parent.methodname_wgt.show()
|
|
self._parent.control_button.show()
|
|
|
|
#if hasattr (self, "mytable"):
|
|
# if not self.mytable.readonly:
|
|
# self.initUI()
|
|
# return 0
|
|
|
|
#self._parent.control_button.add_clear_cache_button(self.cur_pid)
|
|
#self.initUI()
|
|
# TODO: возможно здесь не нужне return 1
|
|
self._parent.control_button.add_clear_cache_button(self.cur_pid)
|
|
self.initUI()
|
|
return 0
|
|
|
|
# def clear_pid_cache(self):
|
|
# self.clear_proc_cache_button.setDisabled(True)
|
|
# sid = int(self.ClientObj.sid)
|
|
# res = self.client.service.clear_pid_cache(sid, self.cur_pid)
|
|
# if res:
|
|
# _print (_('Error closing the process'))
|
|
# self._parent.back()
|
|
|
|
def startGroup(self, item):
|
|
if not hasattr(item, 'message'):
|
|
return
|
|
if item.message:
|
|
item.message = self.processTags(item.message)
|
|
# add normal message label
|
|
lbl_temp = LabelWordWrap("<b>%s</b>"%item.message, self)
|
|
lbl_temp.setMinimumHeight(lbl_temp.minimumSizeHint().height())
|
|
lbl_temp.setMaximumHeight(lbl_temp.sizeHint().height())
|
|
|
|
self.work_layout._addWidget(lbl_temp)
|
|
self.initUI()
|
|
#self._parent.main_frame.verticalScrollBar().setSliderPosition \
|
|
# (self._parent.main_frame.verticalScrollBar().maximum())
|
|
|
|
def endGroup(self, item):
|
|
pass
|
|
|
|
def kill_process(self, pid):
|
|
def wrapper():
|
|
sid = int(self.ClientObj.sid)
|
|
|
|
self.closeDialogs()
|
|
# Call server method
|
|
if hasattr (self, 'kill_process_thread'):
|
|
if self.kill_process_thread.isRunning():
|
|
return 1
|
|
self.kill_process_thread = ClientServiceThread(self.ClientObj,\
|
|
'pid_kill', pid, sid)
|
|
self.kill_process_thread.signal.connect(self.kill_process_after)
|
|
self.kill_process_thread.start()
|
|
return wrapper
|
|
|
|
def kill_process_after(self, result):
|
|
if result in [0,2]:
|
|
return 0
|
|
elif result == -1:
|
|
msg = _("Certificate not found in the server!")
|
|
elif result == -2:
|
|
msg = _("Session not matching your certificate!")
|
|
elif result == 1:
|
|
msg = _("Failed to kill the process!")
|
|
else:
|
|
msg = 'error'
|
|
|
|
show_msg(msg)
|
|
|
|
###############################################################################
|
|
|
|
def analysis(self, meth_result):
|
|
""" analysis of the bounced message method """
|
|
# for mess in meth_result:
|
|
self.ClientObj.app.processEvents()
|
|
mess = meth_result
|
|
if mess.type == 'pid':
|
|
self.get_messages(self.ClientObj.sid, mess.message)
|
|
if mess.type == 'error':
|
|
try:
|
|
self.show_error(self, mess.message)
|
|
except:
|
|
pass
|
|
if mess.type == 'warning':
|
|
try:
|
|
self.show_warning(self, mess)
|
|
except:
|
|
pass
|
|
|
|
def get_message(self, item, sid, pid):
|
|
try:
|
|
if item.type == "error" and item.message == "403 Forbidden":
|
|
return 0
|
|
if self.cur_pid != pid:
|
|
return 1
|
|
except:
|
|
return 1
|
|
""" get one message by its type """
|
|
if not hasattr(item,"type"):
|
|
return 1
|
|
for case in switch(item.type):
|
|
if case('normal'):
|
|
self.show_normal(item)
|
|
return 1
|
|
if case('pre'):
|
|
self.show_normal(item,mono=True)
|
|
return 1
|
|
if case('plain'):
|
|
self.show_normal(item)
|
|
return 1
|
|
if case('progress'):
|
|
self.get_Progress(sid, pid, item.id)
|
|
return 1
|
|
if case('error'):
|
|
# for i in range(20):
|
|
self.show_error(item.message)
|
|
if item.message == "403 Forbidden":
|
|
# show_msg(item.message, 'Access Denied')
|
|
return 0
|
|
return 1
|
|
if case('warning'):
|
|
self.show_warning(item)
|
|
return 1
|
|
if case('table'):
|
|
self.get_Table(sid, pid, item)
|
|
return 1
|
|
if case('group'):
|
|
self.show_group(item)
|
|
return 1
|
|
if case('question'):
|
|
self.send_Message(sid, pid, item)
|
|
return 1
|
|
if case('confirm'):
|
|
self.send_Confirm(sid, pid, item)
|
|
return 1
|
|
if case('choice'):
|
|
self.send_Choice(sid, pid, item)
|
|
return 1
|
|
if case('password'):
|
|
self.send_Password(sid, pid, item)
|
|
return 1
|
|
if case('startTask'):
|
|
self.startTask(item)
|
|
return 1
|
|
if case('taskNumber'):
|
|
# self.startTask(item)
|
|
return 1
|
|
if case('endTask'):
|
|
self.endTask(item)
|
|
return 1
|
|
if case('beginFrame'):
|
|
self.beginFrame(item)
|
|
return 1
|
|
if case('endFrame'):
|
|
self.endFrame(item)
|
|
self.resize(self.sizeHint())
|
|
return 0
|
|
if case('startGroup'):
|
|
self.startGroup(item)
|
|
return 1
|
|
if case('endGroup'):
|
|
self.endGroup(item)
|
|
return 1
|
|
if case(): # default, could also just omit condition or 'if True'
|
|
return 1
|
|
|
|
def get_messages(self, sid, pid):
|
|
""" get frame in a separate thread """
|
|
#import threading
|
|
#thread_messages = threading.Thread(target=self.get_Frame,\
|
|
# args = (sid, pid))
|
|
#thread_messages.start()
|
|
self.get_Frame(sid, pid)
|
|
|
|
def get_Frame(self, sid, pid, def_end_frame = 1):
|
|
""" get all messages, until type is not endFrame (or Error) """
|
|
self.not_end_frame = def_end_frame
|
|
|
|
if self.not_end_frame:
|
|
# Call server method
|
|
if hasattr (self, 'get_Frame_thread'):
|
|
if self.get_Frame_thread.isRunning():
|
|
self.get_Frame_thread.wait()
|
|
self.get_Frame_thread = ClientServiceThread(self.ClientObj,\
|
|
'get_frame', sid, pid, "gui", return_except = True, \
|
|
through_object = (sid, pid))
|
|
self.get_Frame_thread.signal_extended.connect(self.get_Frame_cycle)
|
|
self.get_Frame_thread.start()
|
|
|
|
def get_errno(self, exception):
|
|
"""
|
|
Exception container with URLError
|
|
"""
|
|
from socket import error as socket_error
|
|
try:
|
|
if (exception.args and type(exception.args[0]) == URLError and
|
|
exception.args[0].args and
|
|
type(exception.args[0].args[0]) == socket_error):
|
|
return exception.args[0].args[0].errno
|
|
if (exception.args[0].args and
|
|
type(exception.args[0].args[0]) == socket_error):
|
|
return exception.args[0].errno
|
|
except:
|
|
return None
|
|
return None
|
|
|
|
def get_Frame_cycle(self, current_frame, through_object):
|
|
if type(current_frame) == Exception:
|
|
_print (_("Failed to get a frame from the server."))
|
|
#show_msg(_("Failed to get a frame from the server.") +'\n'+ \
|
|
# _('Try resfeshing this page later.'),'get frame error')
|
|
sid, pid = through_object
|
|
if current_frame in [None, [], ""]:
|
|
try:
|
|
if self.cur_pid != pid:
|
|
return 1
|
|
except:
|
|
return 1
|
|
elif not isinstance(current_frame,Exception):
|
|
self.get_Frame_after(current_frame, sid, pid)
|
|
if self.not_end_frame:
|
|
# Call server method
|
|
if hasattr (self, 'get_Frame_thread'):
|
|
if self.get_Frame_thread.isRunning():
|
|
self.get_Frame_thread.wait()
|
|
if self.ClientObj.host_name in ('localhost','127.0.0.1'):
|
|
if self.get_errno(current_frame) == 111:
|
|
sleeptime = 5
|
|
else:
|
|
sleeptime = int(self.ClientObj.client.frame_period)
|
|
else:
|
|
sleeptime = int(self.ClientObj.client.frame_period)
|
|
self.get_Frame_thread = ClientServiceThread(self.ClientObj,
|
|
'get_frame', sid, pid, "gui",return_except = True,
|
|
sleeptime = sleeptime,
|
|
through_object = (sid, pid))
|
|
self.get_Frame_thread.signal_extended.connect(self.get_Frame_cycle)
|
|
self.get_Frame_thread.start()
|
|
|
|
def get_Frame_after(self, current_frame, sid, pid):
|
|
for item in range(len(current_frame[0])):
|
|
self.not_end_frame = self.get_message(current_frame[0][item],
|
|
sid, pid)
|
|
self.valSignal.emit()
|
|
try:
|
|
if self.cur_pid != pid:
|
|
return 1
|
|
except:
|
|
return 1
|
|
if len (current_frame[0]) > 3:
|
|
if not item % 10:
|
|
self.ClientObj.app.processEvents()
|
|
else:
|
|
self.ClientObj.app.processEvents()
|
|
self.valSignal.emit()
|
|
|
|
def get_entire_frame(self, pid = None):
|
|
""" get entire frame, from beginning (if client disconnected) """
|
|
self.ClientObj.app.processEvents()
|
|
sid = get_sid(self.ClientObj.client)
|
|
if not pid:
|
|
try:
|
|
list_pid = self.ClientObj.client.service.list_pid(sid = sid)
|
|
except URLError as e:
|
|
_print ('get_entire_frame in MainFrameResult Exception')
|
|
show_msg (e, _("Not connected!"))
|
|
return 1
|
|
else:
|
|
list_pid = {}
|
|
list_pid[0] = [pid]
|
|
|
|
if list_pid[0] == [0]:
|
|
return 0
|
|
pid = list_pid[0][0]
|
|
|
|
# Call server method
|
|
if hasattr (self, 'get_Frame_thread'):
|
|
if self.get_Frame_thread.isRunning():
|
|
self.get_Frame_thread.wait()
|
|
self.get_Frame_thread = ClientServiceThread(self.ClientObj,\
|
|
'get_entire_frame', sid, pid, return_except = True, \
|
|
through_object = (sid, pid))
|
|
self.get_Frame_thread.signal_extended.connect \
|
|
(self.get_entire_frame_after)
|
|
self.get_Frame_thread.start()
|
|
|
|
def get_entire_frame_after(self, current_frame, through_object):
|
|
if type(current_frame) == Exception:
|
|
_print (_('Failed to get the complete frame from the server.'))
|
|
# show_msg(_("Failed to get a frame from the server.") +'\n'+ \
|
|
# _('Try resfeshing this page later.'),'get frame error')
|
|
return 1
|
|
sid, pid = through_object
|
|
end_frame = 1
|
|
if not current_frame in [None, [], ""]:
|
|
# for i in range (10):
|
|
for item in range(len(current_frame[0])):
|
|
end_frame = self.get_message(current_frame[0][item], sid, pid)
|
|
self.valSignal.emit()
|
|
try:
|
|
if self.cur_pid != pid:
|
|
return 1
|
|
except:
|
|
return 1
|
|
if len (current_frame[0]) > 3:
|
|
if not item % 10:
|
|
self.ClientObj.app.processEvents()
|
|
else:
|
|
self.ClientObj.app.processEvents()
|
|
|
|
self.get_Frame(sid, pid, def_end_frame = end_frame)
|
|
|
|
def add_Progress(self):
|
|
progressBar = qt.QProgressBar()
|
|
progressBar.setMinimumHeight(progressBar.sizeHint().height())
|
|
progressBar.setTextVisible(True)
|
|
self.progress_list.append(progressBar)
|
|
self.work_layout._addWidget(progressBar)
|
|
|
|
progressBar.setMinimum(0)
|
|
progressBar.setMaximum(0)
|
|
self.initUI()
|
|
return progressBar
|
|
|
|
def get_Progress(self, sid, pid, id):
|
|
""" get progress for the current job """
|
|
#if self.progress_list and self.progress_list[-1].isVisible():
|
|
if self.progress_list:
|
|
progressBar = self.progress_list[-1]
|
|
else:
|
|
progressBar = self.add_Progress()
|
|
#else:
|
|
# progressBar = self.add_Progress()
|
|
#if self.progress_list:
|
|
# self.progress_list[-1].hide()
|
|
|
|
temp_progress = -1
|
|
# Call server method
|
|
if hasattr (self, 'get_Progress_thread'):
|
|
if self.get_Progress_thread.isRunning():
|
|
self.get_Progress_thread.wait()
|
|
self.get_Progress_thread = ClientServiceThread(self.ClientObj,\
|
|
'get_progress', sid, pid, id, return_except = True, \
|
|
through_object = (sid, pid, id, temp_progress, \
|
|
progressBar))
|
|
self.get_Progress_thread.signal_extended.connect \
|
|
(self.get_Progress_cycle)
|
|
self.get_Progress_thread.start()
|
|
|
|
def get_Progress_cycle(self, returnProgr, through_object):
|
|
sid, pid, id, temp_progress, progressBar = through_object
|
|
def nextProgress():
|
|
if hasattr (self, 'get_Progress_thread'):
|
|
if self.get_Progress_thread.isRunning():
|
|
self.get_Progress_thread.wait()
|
|
self.get_Progress_thread = ClientServiceThread(self.ClientObj,\
|
|
'get_progress', sid, pid, id, return_except = True,\
|
|
sleeptime = 1, through_object = \
|
|
(sid, pid, id, temp_progress, progressBar))
|
|
self.get_Progress_thread.signal_extended.connect \
|
|
(self.get_Progress_cycle)
|
|
self.get_Progress_thread.start()
|
|
|
|
if type(returnProgr) == Exception:
|
|
_print (_('Failed to get the progress status from the server'))
|
|
# show_msg(_('Failed to get the progress status from the server') + \
|
|
# '\n'+ \
|
|
# _('Try resfeshing this page later.'),'get progress error')
|
|
nextProgress()
|
|
return 1
|
|
########################################
|
|
try:
|
|
percent = returnProgr.percent
|
|
except AttributeError:
|
|
if type(returnProgr) in [str,unicode]:
|
|
_print ('Server return:', returnProgr)
|
|
percent = temp_progress
|
|
if percent <= 100 and percent >= 0 :
|
|
if temp_progress != percent:
|
|
if percent:
|
|
# progressBar.setProperty("value", 100)
|
|
progressBar.setMaximum(100)
|
|
# progressBar.setValue(percent)
|
|
self.set_progress_value(progressBar, returnProgr)
|
|
if percent == 100:
|
|
return 0
|
|
self.initUI()
|
|
temp_progress = percent
|
|
try:
|
|
if self.cur_pid != pid:
|
|
return 1
|
|
except:
|
|
return 1
|
|
|
|
# Call server method
|
|
nextProgress()
|
|
if percent < 0:
|
|
progressBar.setMaximum(100)
|
|
returnProgr.percent = 0 - percent
|
|
self.set_progress_value(progressBar, returnProgr)
|
|
self.ClientObj.app.processEvents()
|
|
self.initUI()
|
|
|
|
def set_progress_value(self, progressBar, returnProgr):
|
|
if returnProgr.long_message:
|
|
if progressBar.fontMetrics().width(returnProgr.long_message) + \
|
|
progressBar.fontMetrics().width(' 000%') \
|
|
< progressBar.width():
|
|
progressBar.setFormat('%s %d%%' %(returnProgr.long_message, \
|
|
returnProgr.percent))
|
|
progressBar.setValue(returnProgr.percent)
|
|
self.ClientObj.app.processEvents()
|
|
return 0
|
|
if returnProgr.short_message:
|
|
progressBar.setFormat('%s %d%%' %(returnProgr.short_message, \
|
|
returnProgr.percent))
|
|
progressBar.setValue(returnProgr.percent)
|
|
self.ClientObj.app.processEvents()
|
|
return 0
|
|
progressBar.setFormat('%d%%' %returnProgr.percent)
|
|
progressBar.setValue(returnProgr.percent)
|
|
self.ClientObj.app.processEvents()
|
|
|
|
def get_Table(self, sid, pid, item):
|
|
try:
|
|
table = self.ClientObj.client.service.get_table(sid, pid, item.id)
|
|
except URLError:
|
|
self.show_error('Error get table from server')
|
|
return 1
|
|
|
|
self.show_table(table, item)
|
|
self.ClientObj.app.processEvents()
|
|
# Resize table
|
|
if self.mytable:
|
|
h = self.mytable.horizontalHeader().height() + \
|
|
2 * self.mytable.frameWidth()
|
|
h += self.mytable.horizontalScrollBar().sizeHint().height()
|
|
for row_in_table in range(self.mytable.rowCount()):
|
|
h += self.mytable.rowHeight(row_in_table)
|
|
self.mytable.setFixedHeight(h)
|
|
|
|
def send_Confirm(self, sid, pid, item):
|
|
""" send answer to the question """
|
|
if self.progress_list:
|
|
self.progress_list[-1].hide()
|
|
self.message = ConfirmDialog(self, item, sid, pid)
|
|
self._parent.control_button.set_confirmation(self.message)
|
|
self.message.show()
|
|
|
|
def send_Choice(self, sid, pid, item):
|
|
""" send answer to the question """
|
|
if self.progress_list:
|
|
self.progress_list[-1].hide()
|
|
self.message = ChoiceDialog(self, item, sid, pid)
|
|
self._parent.control_button.set_confirmation(self.message)
|
|
self.message.show()
|
|
|
|
def send_Message(self, sid, pid, item):
|
|
""" send answer to the question """
|
|
self.message = MessageDialog(self, item, sid, pid)
|
|
self.message.show()
|
|
|
|
def send_Password(self, sid, pid, item):
|
|
""" send password """
|
|
self.passwd = MessageDialog(self, item, sid, pid, True)
|
|
self.passwd.show()
|
|
|
|
def close_all_thread(self):
|
|
if hasattr (self, 'get_Frame_thread'):
|
|
if self.get_Frame_thread.isRunning():
|
|
self.get_Frame_thread.close()
|
|
self.get_Frame_thread.wait()
|
|
|
|
if hasattr (self, 'get_Progress_thread'):
|
|
if self.get_Progress_thread.isRunning():
|
|
self.get_Progress_thread.close()
|
|
self.get_Progress_thread.wait()
|
|
|
|
if hasattr (self, 'send_password_thread'):
|
|
if self.send_password_thread.isRunning():
|
|
self.send_password_thread.close()
|
|
self.send_password_thread.wait()
|
|
|
|
def closeDialogs(self):
|
|
if hasattr(self, "message") and self.message:
|
|
self.message.close()
|
|
self.message = None
|
|
if hasattr(self, "passwd") and self.passwd:
|
|
self.passwd.close()
|
|
self.passwd = None
|
|
self._parent.control_button.close_confirmation()
|
|
self._parent.control_button.close_break_button()
|
|
|
|
def closeEvent(self, event):
|
|
self.timer.stop()
|
|
self.cur_pid = 'no'
|
|
self.close_all_thread()
|
|
self._parent.methodname_wgt._hide()
|
|
self._parent.control_button._hide()
|
|
self.closeDialogs()
|
|
event.accept()
|
|
|
|
|
|
class MessageDialog(qt.QWidget):
|
|
# answer to the server question
|
|
def __init__(self, parent, item, sid, pid, isPassword = False):
|
|
super().__init__()
|
|
self._parent = parent
|
|
# self.item = item
|
|
self.sid = sid
|
|
self.pid = pid
|
|
self.setWindowTitle(self._parent.ClientObj._parent.windowTitle())
|
|
self.layout = qt.QGridLayout(self)
|
|
|
|
self.label = LabelWordWrap(item.message, self)
|
|
|
|
self.pass_edit = qt.QLineEdit(self)
|
|
self.layout.addWidget(self.label,0,0)
|
|
self.layout.addWidget(self.pass_edit,0,1)
|
|
|
|
x = 1
|
|
if isPassword:
|
|
self.pass_edit.setEchoMode(self.pass_edit.Password)
|
|
if item.id == 2:
|
|
if hasattr(self,'pass_edit2'):
|
|
self.pass_edit2 = qt.QLineEdit(self)
|
|
self.pass_edit2.setEchoMode(self.pass_edit2.Password)
|
|
|
|
self.layout.addWidget(LabelWordWrap(_('Repeat'), self), x, 0)
|
|
self.layout.addWidget(self.pass_edit2, x, 1)
|
|
x += 1
|
|
self.pass_edit.textChanged.connect(self.check_passwd)
|
|
if hasattr(self,'pass_edit2'):
|
|
self.pass_edit2.textChanged.connect(self.check_passwd)
|
|
|
|
self.send_button = qt.QPushButton(_('Send'), self)
|
|
self.send_button.setShortcut(qt.QKeySequence(qt.Qt.Key_Return))
|
|
self.send_button.clicked.connect(self.send_password)
|
|
|
|
self.layout.addWidget(self.send_button,x,1)
|
|
|
|
self.move(parent.ClientObj._parent.geometry().x() + \
|
|
parent.ClientObj._parent.geometry().width() / 2 \
|
|
- self.sizeHint().width() / 2, \
|
|
parent.ClientObj._parent.geometry().y() + \
|
|
parent.ClientObj._parent.geometry().height() / 2 \
|
|
- self.sizeHint().height() / 2)
|
|
self.setWindowFlags (qt.Qt.WindowMinimizeButtonHint)
|
|
|
|
def send_password(self):
|
|
answer = self.pass_edit.text()
|
|
if not hasattr(self,"pass_edit2") or \
|
|
answer == self.pass_edit2.text():
|
|
|
|
# Call server method
|
|
if hasattr (self, 'send_password_thread'):
|
|
if self.send_password_thread.isRunning():
|
|
return 1
|
|
self.send_password_thread = ClientServiceThread(\
|
|
self._parent.ClientObj, 'send_message', self.sid, \
|
|
self.pid, answer, return_except = True)
|
|
self.send_password_thread.signal.connect(self.send_password_after)
|
|
self.send_password_thread.start()
|
|
else:
|
|
self.send_button.setDisabled(True)
|
|
|
|
def send_password_after(self, result):
|
|
if type(result) == Exception:
|
|
show_msg(_('Failed to send the message (password) to the server'))
|
|
self.close()
|
|
return 1
|
|
self._parent.show_result(result)
|
|
self.close()
|
|
|
|
def check_passwd(self):
|
|
if self.pass_edit.text() != self.pass_edit2.text():
|
|
self.send_button.setDisabled(True)
|
|
else:
|
|
self.send_button.setEnabled(True)
|
|
|
|
|
|
class ButtonDialog(qt.QWidget):
|
|
button_size = 144
|
|
|
|
def __init__(self, parent, item, sid, pid):
|
|
super().__init__()
|
|
self._parent = parent
|
|
self.sid = sid
|
|
self.pid = pid
|
|
self.layout = qt.QHBoxLayout(self)
|
|
self.layout.setContentsMargins(0, 0, 4, 0)
|
|
self.header_label = None
|
|
|
|
minimum = qt.QSizePolicy.Fixed
|
|
self.setSizePolicy(minimum, minimum)
|
|
self.setFixedHeight(dpivalue(32))
|
|
self.init(item)
|
|
|
|
def init(self, item):
|
|
pass
|
|
|
|
def createButton(self, label, answer, shortcut=None):
|
|
"""
|
|
Создать кнопку в диалоге
|
|
"""
|
|
button = qt.QPushButton(label, self)
|
|
if type(shortcut) in (list, tuple):
|
|
action = qt.QAction(self)
|
|
action.setShortcuts(map(qt.QKeySequence,
|
|
shortcut))
|
|
action.triggered.connect(button.animateClick)
|
|
button.addAction(action)
|
|
elif shortcut:
|
|
button.setShortcut(qt.QKeySequence(shortcut))
|
|
button.clicked.connect(self.send(answer, label))
|
|
button.setFixedWidth(self.button_size)
|
|
button.setFixedHeight(dpivalue(32))
|
|
self.layout.addWidget(button)
|
|
|
|
def send(self, answer, human_answer=None):
|
|
# Call server method
|
|
def wrapper():
|
|
self._parent._parent.control_button.close_confirmation()
|
|
if human_answer and self.header_label:
|
|
self.header_label.setText(
|
|
self.header_label.text() + " " +
|
|
human_answer)
|
|
if hasattr(self, 'send_password_thread'):
|
|
if self.send_password_thread.isRunning():
|
|
return 1
|
|
self.send_password_thread = ClientServiceThread( \
|
|
self._parent.ClientObj, 'send_message', self.sid, \
|
|
self.pid, answer, return_except=True)
|
|
self.send_password_thread.signal.connect(self.send_after)
|
|
self.send_password_thread.start()
|
|
|
|
return wrapper
|
|
|
|
def send_after(self, result):
|
|
if type(result) == Exception:
|
|
show_msg(_('Failed to send the message (password) to the server'))
|
|
self.close()
|
|
return 1
|
|
#self._parent.show_result(result)
|
|
self.close()
|
|
|
|
|
|
class ConfirmDialog(ButtonDialog):
|
|
"""
|
|
Диалог подтверждения действия
|
|
"""
|
|
def init(self, item):
|
|
self._parent._parent.control_button.set_confirm_question(
|
|
"<b>%s</b>" % item.message)
|
|
self.createButton(_("Yes"), "yes", [qt.Qt.Key_Enter,
|
|
qt.Qt.Key_Return])
|
|
self.createButton(_("No"), "no", qt.Qt.Key_Escape)
|
|
|
|
|
|
class ChoiceDialog(ButtonDialog):
|
|
"""
|
|
Диалог выбора ответа из нескольких
|
|
"""
|
|
def init(self, item):
|
|
message, answers = item.message.split('|')
|
|
|
|
self._parent._parent.control_button.set_confirm_question(
|
|
"<b>%s</b>" % message)
|
|
|
|
reAnswer = re.compile("^(.*)\((.*)\)$")
|
|
answers = imap_regexp(reAnswer, answers.split(','))
|
|
|
|
for answer, label in answers:
|
|
self.createButton(label, answer)
|