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/MainFrameResult.py

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 .. import qt
DEBUG_LEVEL = 99999
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)
debug(11, f"send message{item}")
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([qt.QKeySequence(x) for x in 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)