|
|
|
|
#-*- 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
|
|
|
|
|
import os
|
|
|
|
|
import time
|
|
|
|
|
import urllib.request as urllib2
|
|
|
|
|
import pwd
|
|
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
from calculate.consolegui import qt
|
|
|
|
|
# from calculate.core.client.function import create_obj
|
|
|
|
|
# from .utils import create_obj
|
|
|
|
|
from . import utils
|
|
|
|
|
from calculate.lib.utils.files import readLinesFile, listDirectory, readFile, \
|
|
|
|
|
getProgPath, process, STDOUT
|
|
|
|
|
from calculate.lib.utils.colortext.palette import (
|
|
|
|
|
GuiPalette as WorkPalette)
|
|
|
|
|
from calculate.lib.utils.tools import Locker
|
|
|
|
|
|
|
|
|
|
ParameterWindow = qt.QPalette.Window
|
|
|
|
|
|
|
|
|
|
def get_system_rgb(obj, pallete_type):
|
|
|
|
|
color = obj.palette().color(pallete_type).getRgb()
|
|
|
|
|
return "rgb%s"%str(color[0:3])
|
|
|
|
|
|
|
|
|
|
def dpivalue(size):
|
|
|
|
|
try:
|
|
|
|
|
return size * qt.QApplication.screens()[0].logicalDotsPerInch() / 96.0;
|
|
|
|
|
except BaseException as e:
|
|
|
|
|
print(str(e))
|
|
|
|
|
if isinstance(e, KeyboardInterrupt):
|
|
|
|
|
raise
|
|
|
|
|
return size
|
|
|
|
|
|
|
|
|
|
def alphed(rgbstr, value):
|
|
|
|
|
# return rgbstr.replace(")", ",%d)"%value)
|
|
|
|
|
return f"rgba({rgbstr[4:-1]}, {value})"
|
|
|
|
|
|
|
|
|
|
def get_icon(*images):
|
|
|
|
|
fimage = images[0]
|
|
|
|
|
if fimage.startswith("/") or fimage.endswith(".svg") or fimage.endswith(".png"):
|
|
|
|
|
icon = qt.QIcon(fimage)
|
|
|
|
|
images = images[1:]
|
|
|
|
|
if not icon.isNull():
|
|
|
|
|
return icon
|
|
|
|
|
else:
|
|
|
|
|
icon = qt.QIcon()
|
|
|
|
|
themeName = qt.QIcon.themeName()
|
|
|
|
|
for image in images:
|
|
|
|
|
for theme in (themeName, "Calculate", "Tango", "Adwaita"):
|
|
|
|
|
icon.setThemeName(theme)
|
|
|
|
|
icon = icon.fromTheme(image)
|
|
|
|
|
if not icon.isNull():
|
|
|
|
|
return icon
|
|
|
|
|
return qt.QIcon()
|
|
|
|
|
|
|
|
|
|
def get_pixmap(*images, **kw):
|
|
|
|
|
pixmap = None
|
|
|
|
|
fallback_icon = kw.get('fallback_icon', None)
|
|
|
|
|
_size = kw.get('size', 32)
|
|
|
|
|
qsize = kw.get('size', qt.QSize(_size,_size))
|
|
|
|
|
for image in images:
|
|
|
|
|
icon = get_icon(image)
|
|
|
|
|
if not icon.isNull():
|
|
|
|
|
return icon.pixmap(_size)
|
|
|
|
|
elif os.path.isfile(image):
|
|
|
|
|
ir = qt.QImageReader(image)
|
|
|
|
|
ir.setScaledSize(qsize)
|
|
|
|
|
img = ir.read()
|
|
|
|
|
return qt.QPixmap().fromImage(img)
|
|
|
|
|
else:
|
|
|
|
|
if fallback_icon:
|
|
|
|
|
return get_icon('applications-system').pixmap(_size)
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# _('The user must not be root')
|
|
|
|
|
class TopMenu(qt.QPushButton):
|
|
|
|
|
def __init__(self, label, images, parent = None):
|
|
|
|
|
super().__init__(parent)
|
|
|
|
|
self.setStyleSheet("QPushButton{border: none; margin: 0px;}"
|
|
|
|
|
"QPushButton:hover{border: 1px solid #73D1FF;"
|
|
|
|
|
"border-radius: 3px; margin: 0px;}")
|
|
|
|
|
# self.setStyleSheet("QPushButton{border: none; margin: 0px 0px 0px 0px;}"
|
|
|
|
|
# ":hover {border: 1px solid #73D1FF;"
|
|
|
|
|
# "border-radius: 3px; margin: 0px 0px 0px 0px;}"
|
|
|
|
|
# ":pressed {border: 1px solid #63C1EF;"
|
|
|
|
|
# "border-radius: 3px; margin: 20px 0px 0px 0px;}")
|
|
|
|
|
self.layout = qt.QVBoxLayout(self)
|
|
|
|
|
|
|
|
|
|
self.image_lbl = qt.QLabel(self)
|
|
|
|
|
|
|
|
|
|
icon = get_icon(*images)
|
|
|
|
|
|
|
|
|
|
# icon.actualSize(qt.QSize(48,48))
|
|
|
|
|
pm1 = icon.pixmap(24)
|
|
|
|
|
|
|
|
|
|
# img = p.toImage()
|
|
|
|
|
# p.fromImage(img)
|
|
|
|
|
pm2 = pm1.scaled(qt.QSize(24, 24), qt.Qt.KeepAspectRatio,
|
|
|
|
|
qt.Qt.SmoothTransformation)
|
|
|
|
|
# pm2.scaled(24,24)
|
|
|
|
|
|
|
|
|
|
self.image_lbl.setPixmap(pm2)
|
|
|
|
|
# self.image_lbl.adjustSize()
|
|
|
|
|
#self.image_lbl.setFixedHeight(dpivalue(24))
|
|
|
|
|
self.image_lbl.setAlignment(qt.Qt.AlignCenter)
|
|
|
|
|
|
|
|
|
|
# add transparency
|
|
|
|
|
self.image_lbl.setAttribute(qt.Qt.WA_NoSystemBackground)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.layout.addWidget(self.image_lbl)
|
|
|
|
|
self.setFlat(True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.lbl = qt.QLabel(label, self)
|
|
|
|
|
self.lbl.setAlignment(qt.Qt.AlignCenter)
|
|
|
|
|
|
|
|
|
|
# add transparency
|
|
|
|
|
self.lbl.setAttribute(qt.Qt.WA_NoSystemBackground)
|
|
|
|
|
|
|
|
|
|
self.layout.addWidget(self.lbl)
|
|
|
|
|
self.layout.setContentsMargins(2,4,2,4)
|
|
|
|
|
self.layout.setSpacing(0)
|
|
|
|
|
|
|
|
|
|
# self.setFixedSize(48,40)
|
|
|
|
|
self.setFixedHeight(52)
|
|
|
|
|
if self.lbl.sizeHint().width() > 32:
|
|
|
|
|
self.setFixedWidth(self.lbl.sizeHint().width()+16)
|
|
|
|
|
else:
|
|
|
|
|
self.setFixedWidth(48)
|
|
|
|
|
self.updateGeometry()
|
|
|
|
|
self.setFocusPolicy(qt.Qt.NoFocus)
|
|
|
|
|
|
|
|
|
|
self.setAttribute(qt.Qt.WA_DeleteOnClose)
|
|
|
|
|
|
|
|
|
|
def mousePressEvent(self, event):
|
|
|
|
|
self.layout.setContentsMargins(2,5,2,4)
|
|
|
|
|
event.accept()
|
|
|
|
|
qt.QPushButton.mousePressEvent(self, event)
|
|
|
|
|
|
|
|
|
|
def mouseReleaseEvent(self, event):
|
|
|
|
|
self.layout.setContentsMargins(2,4,2,4)
|
|
|
|
|
event.accept()
|
|
|
|
|
qt.QPushButton.mouseReleaseEvent(self, event)
|
|
|
|
|
|
|
|
|
|
def text(self):
|
|
|
|
|
return self.lbl.text()
|
|
|
|
|
|
|
|
|
|
def setText(self, text):
|
|
|
|
|
self.lbl.setText(text)
|
|
|
|
|
self.setFixedHeight(52)
|
|
|
|
|
if self.lbl.sizeHint().width() > 48:
|
|
|
|
|
self.setFixedWidth(self.lbl.sizeHint().width()+16)
|
|
|
|
|
else:
|
|
|
|
|
self.setFixedWidth(48)
|
|
|
|
|
|
|
|
|
|
class HelpMenu(TopMenu):
|
|
|
|
|
def __init__(self, label, images, actions, parent):
|
|
|
|
|
TopMenu.__init__(self, label, images, parent)
|
|
|
|
|
self._parent = parent
|
|
|
|
|
self.actions = actions
|
|
|
|
|
|
|
|
|
|
def mousePressEvent(self, event):
|
|
|
|
|
if event.button() != qt.Qt.LeftButton:
|
|
|
|
|
event.ignore()
|
|
|
|
|
return 0
|
|
|
|
|
TopMenu.mousePressEvent(self, event)
|
|
|
|
|
menu = qt.QMenu(self)
|
|
|
|
|
|
|
|
|
|
About_icon = get_icon(
|
|
|
|
|
'/usr/share/pixmaps/calculate-console-online.svg',
|
|
|
|
|
'help-about', 'help-browser')
|
|
|
|
|
|
|
|
|
|
about = qt.QAction(About_icon, _("About"), self,
|
|
|
|
|
triggered=self.actions.help)
|
|
|
|
|
menu.addAction(about)
|
|
|
|
|
|
|
|
|
|
menu.addSeparator()
|
|
|
|
|
handbook_icon = get_icon('help-contents','system-help','help-browser')
|
|
|
|
|
|
|
|
|
|
handbook = qt.QAction(handbook_icon,_("Info"),\
|
|
|
|
|
self, triggered=self.actions.hand_book)
|
|
|
|
|
menu.addAction(handbook)
|
|
|
|
|
|
|
|
|
|
menu.addSeparator()
|
|
|
|
|
bug_icon = get_icon('tools-report-bug','system-help','help-browser')
|
|
|
|
|
|
|
|
|
|
bug = qt.QAction(bug_icon, _("Report a Bug"), \
|
|
|
|
|
self, triggered=self.actions.bug_report)
|
|
|
|
|
menu.addAction(bug)
|
|
|
|
|
# menu.addSeparator()
|
|
|
|
|
x = self._parent.pos().x() + self.pos().x()
|
|
|
|
|
y = self._parent.pos().y() + self.pos().y() + 2*self.size().height()
|
|
|
|
|
menu.exec_(qt.QPoint(x, y))
|
|
|
|
|
TopMenu.mouseReleaseEvent(self, event)
|
|
|
|
|
|
|
|
|
|
class ButtonMenu(qt.QPushButton):
|
|
|
|
|
def __init__(self, name, label, images, parent):
|
|
|
|
|
super().__init__(parent)
|
|
|
|
|
self.layout = qt.QVBoxLayout(self)
|
|
|
|
|
self.layout.setAlignment(qt.Qt.AlignHCenter | qt.Qt.AlignTop)
|
|
|
|
|
|
|
|
|
|
self.image_lbl = qt.QLabel(self)
|
|
|
|
|
if not images:
|
|
|
|
|
images = ''
|
|
|
|
|
|
|
|
|
|
pm2 = get_pixmap(*images.split(','),
|
|
|
|
|
fallback_icon='applications-system',
|
|
|
|
|
size=32)
|
|
|
|
|
|
|
|
|
|
if pm2:
|
|
|
|
|
pm2 = pm2.scaled(qt.QSize(32,32), qt.Qt.IgnoreAspectRatio,
|
|
|
|
|
qt.Qt.SmoothTransformation)
|
|
|
|
|
|
|
|
|
|
self.image_lbl.setPixmap(pm2)
|
|
|
|
|
self.image_lbl.setMinimumHeight(32)
|
|
|
|
|
self.image_lbl.setAlignment(qt.Qt.AlignHCenter)
|
|
|
|
|
|
|
|
|
|
# add transparency
|
|
|
|
|
self.image_lbl.setAttribute(qt.Qt.WA_NoSystemBackground)
|
|
|
|
|
|
|
|
|
|
self.layout.addWidget(self.image_lbl)
|
|
|
|
|
self.setFlat(True)
|
|
|
|
|
|
|
|
|
|
if not label:
|
|
|
|
|
label = name
|
|
|
|
|
self.lbl = LabelWordWrap(label, self)
|
|
|
|
|
self.lbl.setFixedHeight(dpivalue(52) - 22)
|
|
|
|
|
self.lbl.setAlignment(qt.Qt.AlignHCenter | qt.Qt.AlignTop)
|
|
|
|
|
self.lbl.resize(self.lbl.sizeHint())
|
|
|
|
|
self.lbl.setStyleSheet("QLabel {border: None;}")
|
|
|
|
|
# add transparency
|
|
|
|
|
self.lbl.setAttribute(qt.Qt.WA_NoSystemBackground)
|
|
|
|
|
|
|
|
|
|
self.layout.addWidget(self.lbl)
|
|
|
|
|
self.layout.setContentsMargins(0,8,0,0)
|
|
|
|
|
# self.layout.setSpacing(28)
|
|
|
|
|
|
|
|
|
|
self.setFixedSize(20 + dpivalue(90),54 + dpivalue(30))
|
|
|
|
|
self.setObjectName(name)
|
|
|
|
|
|
|
|
|
|
# rgb(218,218,218)
|
|
|
|
|
# rgb(230,230,230)
|
|
|
|
|
self.updateColors()
|
|
|
|
|
self.updateGeometry()
|
|
|
|
|
|
|
|
|
|
def updateColors(self):
|
|
|
|
|
self.setStyleSheet(
|
|
|
|
|
"QPushButton:flat {border: None;}"
|
|
|
|
|
"QPushButton:hover:pressed {border: none;"
|
|
|
|
|
"background-color: %s;"
|
|
|
|
|
"border-radius: 7px;}"
|
|
|
|
|
"QPushButton:hover:!pressed {background-color: "
|
|
|
|
|
"%s; border-radius: 7px;}" %
|
|
|
|
|
(alphed(get_system_rgb(self, qt.QPalette.Highlight),255),
|
|
|
|
|
alphed(get_system_rgb(self, qt.QPalette.Highlight),100)))
|
|
|
|
|
|
|
|
|
|
#def mousePressEvent(self, *args, **kwargs):
|
|
|
|
|
# self.lbl.setStyleSheet("QLabel {border: None; color: %s;}"%
|
|
|
|
|
# get_system_rgb(self, qt.QPalette.Base))
|
|
|
|
|
# return super(ButtonMenu, self).mousePressEvent(*args, **kwargs)
|
|
|
|
|
|
|
|
|
|
#def enterEvent(self, *args, **kwargs):
|
|
|
|
|
# self.lbl.setStyleSheet("QLabel {border: None; color: %s;}"%
|
|
|
|
|
# get_system_rgb(self, qt.QPalette.Text))
|
|
|
|
|
# return super(ButtonMenu, self).enterEvent(*args, **kwargs)
|
|
|
|
|
|
|
|
|
|
#def leaveEvent(self, *args, **kwargs):
|
|
|
|
|
# self.lbl.setStyleSheet("QLabel {border: None; color: %s;}"%
|
|
|
|
|
# get_system_rgb(self, qt.QPalette.Text))
|
|
|
|
|
# return super(ButtonMenu, self).leaveEvent(*args, **kwargs)
|
|
|
|
|
|
|
|
|
|
def text(self):
|
|
|
|
|
return self.lbl.text()
|
|
|
|
|
|
|
|
|
|
class ErrorLabel (qt.QWidget):
|
|
|
|
|
def __init__(self, parent, text = None):
|
|
|
|
|
super().__init__(parent)
|
|
|
|
|
self._parent = parent
|
|
|
|
|
layout = qt.QHBoxLayout(self)
|
|
|
|
|
|
|
|
|
|
self.image_lbl = qt.QLabel(self)
|
|
|
|
|
|
|
|
|
|
pm1 = get_pixmap("dialog-warning", size=16)
|
|
|
|
|
if pm1:
|
|
|
|
|
pm2 = pm1.scaled(qt.QSize(16, 16),
|
|
|
|
|
qt.Qt.KeepAspectRatio,
|
|
|
|
|
qt.Qt.SmoothTransformation)
|
|
|
|
|
self.image_lbl.setPixmap(pm2)
|
|
|
|
|
self.image_lbl.setAlignment(qt.Qt.AlignCenter)
|
|
|
|
|
|
|
|
|
|
# add transparency
|
|
|
|
|
self.image_lbl.setAttribute(qt.Qt.WA_NoSystemBackground)
|
|
|
|
|
self.image_lbl.setAlignment(qt.Qt.AlignVCenter)
|
|
|
|
|
|
|
|
|
|
layout.addWidget(self.image_lbl)
|
|
|
|
|
|
|
|
|
|
self.text_lbl = qt.QLabel()
|
|
|
|
|
self.text_lbl.setWordWrap(True)
|
|
|
|
|
self.text_lbl.setAlignment(qt.Qt.AlignVCenter)
|
|
|
|
|
self.text_lbl.setTextInteractionFlags (self.text_lbl.\
|
|
|
|
|
textInteractionFlags() | qt.Qt.TextSelectableByMouse)
|
|
|
|
|
|
|
|
|
|
maximum = qt.QSizePolicy.Maximum
|
|
|
|
|
exp = qt.QSizePolicy.Expanding
|
|
|
|
|
self.text_lbl.setSizePolicy(exp, maximum)
|
|
|
|
|
|
|
|
|
|
layout.addWidget(self.text_lbl)
|
|
|
|
|
layout.setAlignment(qt.Qt.AlignLeft)
|
|
|
|
|
layout.setContentsMargins (0,0,0,0)
|
|
|
|
|
|
|
|
|
|
if text:
|
|
|
|
|
self.setText(text)
|
|
|
|
|
self.hide()
|
|
|
|
|
|
|
|
|
|
# for clear memory after closed this window
|
|
|
|
|
self.setAttribute(qt.Qt.WA_DeleteOnClose)
|
|
|
|
|
|
|
|
|
|
def mousePressEvent(self, event):
|
|
|
|
|
if event.button() == qt.Qt.RightButton:
|
|
|
|
|
if hasattr(self, 'menu'):
|
|
|
|
|
self.menu.move(qt.QCursor.pos())
|
|
|
|
|
self.menu.show()
|
|
|
|
|
event.accept()
|
|
|
|
|
|
|
|
|
|
def setText(self, txt):
|
|
|
|
|
txt.replace('\n',' ')
|
|
|
|
|
self.text_lbl.setText(txt)
|
|
|
|
|
|
|
|
|
|
if not hasattr(self, 'menu'):
|
|
|
|
|
self.menu = qt.QMenu(self)
|
|
|
|
|
|
|
|
|
|
bug_icon = get_icon('tools-report-bug','system-help','help-browser')
|
|
|
|
|
bug = qt.QAction(bug_icon, _("Report a Bug"), self, \
|
|
|
|
|
triggered=self.bug_report)
|
|
|
|
|
self.menu.addAction(bug)
|
|
|
|
|
|
|
|
|
|
def bug_report(self):
|
|
|
|
|
self._parent.ClientObj.MainWidget.bug_report()
|
|
|
|
|
self._parent.ClientObj.MainWidget.bugWidget.set_message_text\
|
|
|
|
|
(self.text_lbl.text())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ERROR_ICON_SIZE = 16
|
|
|
|
|
|
|
|
|
|
class ErrorWgt(qt.QWidget):
|
|
|
|
|
def __init__(self, text='', parent=None):
|
|
|
|
|
super().__init__()
|
|
|
|
|
self._parent = parent
|
|
|
|
|
layout = qt.QHBoxLayout(self)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.text = LabelWordWrap(text, self)
|
|
|
|
|
self.text.setTextInteractionFlags (self.text.textInteractionFlags() \
|
|
|
|
|
| qt.Qt.TextSelectableByMouse)
|
|
|
|
|
layout.addWidget(self.text)
|
|
|
|
|
|
|
|
|
|
layout.setContentsMargins(0,0,0,0)
|
|
|
|
|
layout.setSpacing(4)
|
|
|
|
|
layout.setAlignment(qt.Qt.AlignTop)
|
|
|
|
|
self.set_status = False
|
|
|
|
|
self.add_menu()
|
|
|
|
|
self.resize(self.sizeHint())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def set_warning(self):
|
|
|
|
|
self.text.setStyleSheet("color:blue;")
|
|
|
|
|
|
|
|
|
|
def set_error(self):
|
|
|
|
|
self.text.setStyleSheet("font-weight:bold;color:red;")
|
|
|
|
|
|
|
|
|
|
def add_menu(self):
|
|
|
|
|
if not hasattr(self, 'menu'):
|
|
|
|
|
self.menu = qt.QMenu(self)
|
|
|
|
|
|
|
|
|
|
bug_icon = get_icon('tools-report-bug','system-help','help-browser')
|
|
|
|
|
bug = qt.QAction(bug_icon, _("Report a Bug"), self, \
|
|
|
|
|
triggered=self.bug_report)
|
|
|
|
|
# bug.setDisabled(True)
|
|
|
|
|
self.menu.addAction(bug)
|
|
|
|
|
|
|
|
|
|
def bug_report(self):
|
|
|
|
|
self._parent._parent.bug_report()
|
|
|
|
|
self._parent._parent.bugWidget.set_message_text\
|
|
|
|
|
(self.text.text())
|
|
|
|
|
|
|
|
|
|
def mousePressEvent(self, event):
|
|
|
|
|
if event.button() == qt.Qt.RightButton:
|
|
|
|
|
if hasattr(self, 'menu'):
|
|
|
|
|
self.menu.move(qt.QCursor.pos())
|
|
|
|
|
self.menu.show()
|
|
|
|
|
event.accept()
|
|
|
|
|
|
|
|
|
|
def resizeEvent(self, resize_var):
|
|
|
|
|
self.setFixedHeight(self.text.height())
|
|
|
|
|
# self.setFixedHeight(self.text.height() + 24)
|
|
|
|
|
|
|
|
|
|
class LabelWordWrap(qt.QLabel):
|
|
|
|
|
def __init__(self, name, parent = None, mono=False, margin_top=0):
|
|
|
|
|
if not name:
|
|
|
|
|
name = ''
|
|
|
|
|
try:
|
|
|
|
|
# name = name.decode('utf-8')
|
|
|
|
|
name = name
|
|
|
|
|
if not mono:
|
|
|
|
|
name = name.replace(" "," ")
|
|
|
|
|
else:
|
|
|
|
|
name = name.replace("	", " "*8)
|
|
|
|
|
leftMargin = len(name)-len(name.lstrip(' '))
|
|
|
|
|
name = name[leftMargin:]
|
|
|
|
|
except (UnicodeDecodeError, UnicodeEncodeError):
|
|
|
|
|
pass
|
|
|
|
|
super().__init__(name, parent)
|
|
|
|
|
WorkPalette.defaultBackground = get_system_rgb(
|
|
|
|
|
self, qt.QPalette.Window)
|
|
|
|
|
WorkPalette.defaultColor[0] = get_system_rgb(
|
|
|
|
|
self, qt.QPalette.Text)
|
|
|
|
|
if mono:
|
|
|
|
|
self.setStyleSheet(
|
|
|
|
|
'font-family: Liberation Mono;color:{color};'
|
|
|
|
|
'background-color:{background};'.format(
|
|
|
|
|
color=WorkPalette.defaultColor[0],
|
|
|
|
|
background=WorkPalette.defaultBackground
|
|
|
|
|
))
|
|
|
|
|
else:
|
|
|
|
|
self.setStyleSheet('margin-left:%dpx;margin-top:%d;'%(
|
|
|
|
|
leftMargin*5, margin_top))
|
|
|
|
|
|
|
|
|
|
minimum = qt.QSizePolicy.Minimum
|
|
|
|
|
exp = qt.QSizePolicy.Expanding
|
|
|
|
|
self.setSizePolicy(exp, minimum)
|
|
|
|
|
|
|
|
|
|
self.setWordWrap(True)
|
|
|
|
|
|
|
|
|
|
# for clear memory after closed this window
|
|
|
|
|
self.setAttribute(qt.Qt.WA_DeleteOnClose)
|
|
|
|
|
|
|
|
|
|
class ClearLineEdit(qt.QLineEdit):
|
|
|
|
|
def __init__(self, text = None, parent=None):
|
|
|
|
|
super().__init__(text, parent)
|
|
|
|
|
self.def_text = text
|
|
|
|
|
self.button=qt.QToolButton(self)
|
|
|
|
|
self.button.setCursor(qt.Qt.ArrowCursor)
|
|
|
|
|
self.button.hide()
|
|
|
|
|
self.button.setFocusPolicy(qt.Qt.NoFocus)
|
|
|
|
|
icon = get_icon("edit-clear")
|
|
|
|
|
if not icon.isNull():
|
|
|
|
|
self.button.setIcon(icon)
|
|
|
|
|
else:
|
|
|
|
|
self.button.setText('clear')
|
|
|
|
|
self.button.setStyleSheet("border: none;")
|
|
|
|
|
self.textChanged.connect(self.changed)
|
|
|
|
|
self.button.clicked.connect(self.clear)
|
|
|
|
|
|
|
|
|
|
# for clear memory after closed this window
|
|
|
|
|
self.setAttribute(qt.Qt.WA_DeleteOnClose)
|
|
|
|
|
|
|
|
|
|
layout=qt.QVBoxLayout(self)
|
|
|
|
|
layout.addWidget(self.button,0,qt.Qt.AlignRight)
|
|
|
|
|
layout.setSpacing(0)
|
|
|
|
|
|
|
|
|
|
def changed(self,text):
|
|
|
|
|
if len(text)==0: self.button.hide()
|
|
|
|
|
else: self.button.show()
|
|
|
|
|
|
|
|
|
|
def focusInEvent(self, FocusEvent):
|
|
|
|
|
if self.text() == self.def_text:
|
|
|
|
|
self.clear()
|
|
|
|
|
|
|
|
|
|
def focusOutEvent(self, FocusEvent):
|
|
|
|
|
if self.text() == '':
|
|
|
|
|
self.setText(self.def_text)
|
|
|
|
|
|
|
|
|
|
class FileOpenWgt(qt.QWidget):
|
|
|
|
|
textChanged = qt.Signal()
|
|
|
|
|
def __init__(self, parent, type, caption=None, directory=None):
|
|
|
|
|
super().__init__(parent)
|
|
|
|
|
self.type = type
|
|
|
|
|
self.caption = caption
|
|
|
|
|
self.dir = directory
|
|
|
|
|
|
|
|
|
|
self.data = None
|
|
|
|
|
|
|
|
|
|
self.hlayout = qt.QHBoxLayout(self)
|
|
|
|
|
|
|
|
|
|
self.lineEdit = qt.QLineEdit(self)
|
|
|
|
|
self.lineEdit.textChanged.connect(self.textChanged)
|
|
|
|
|
|
|
|
|
|
self.button=qt.QToolButton(self)
|
|
|
|
|
self.button.setCursor(qt.Qt.ArrowCursor)
|
|
|
|
|
self.button.setFocusPolicy(qt.Qt.NoFocus)
|
|
|
|
|
icon = get_icon("document-open")
|
|
|
|
|
if not icon.isNull():
|
|
|
|
|
self.button.setIcon(icon)
|
|
|
|
|
else:
|
|
|
|
|
self.button.setText(_('Open'))
|
|
|
|
|
self.button.setStyleSheet("border: none;")
|
|
|
|
|
self.button.clicked.connect(self.file_dialog)
|
|
|
|
|
|
|
|
|
|
# for clear memory after closed this window
|
|
|
|
|
self.setAttribute(qt.Qt.WA_DeleteOnClose)
|
|
|
|
|
|
|
|
|
|
self.hlayout.addWidget(self.lineEdit)
|
|
|
|
|
self.hlayout.addWidget(self.button)
|
|
|
|
|
self.hlayout.setSpacing(0)
|
|
|
|
|
|
|
|
|
|
if self.type == 'files':
|
|
|
|
|
self.lineEdit.setReadOnly(True)
|
|
|
|
|
|
|
|
|
|
def file_dialog(self):
|
|
|
|
|
self.fd = qt.QFileDialog(self, self.caption, self.dir)
|
|
|
|
|
|
|
|
|
|
self.fd.setWindowModality(qt.Qt.WindowModal)
|
|
|
|
|
if self.type == 'dir':
|
|
|
|
|
data = self.fd.getExistingDirectory()
|
|
|
|
|
if self.type == 'file':
|
|
|
|
|
data = self.fd.getOpenFileName()
|
|
|
|
|
data = data[0]
|
|
|
|
|
if self.type == 'files':
|
|
|
|
|
data = self.fd.getOpenFileNames()
|
|
|
|
|
data = data[0]
|
|
|
|
|
if data:
|
|
|
|
|
self.data = data
|
|
|
|
|
self.set_label()
|
|
|
|
|
|
|
|
|
|
def set_label(self):
|
|
|
|
|
if type(self.data) in [str]:
|
|
|
|
|
self.lineEdit.setText(self.data)
|
|
|
|
|
elif type(self.data) == list:
|
|
|
|
|
lbl = ', '.join(self.data)
|
|
|
|
|
self.lineEdit.setText(lbl)
|
|
|
|
|
|
|
|
|
|
def text(self):
|
|
|
|
|
return self.lineEdit.text()
|
|
|
|
|
|
|
|
|
|
def setText(self, text):
|
|
|
|
|
return self.lineEdit.setText(text)
|
|
|
|
|
|
|
|
|
|
class ComboFileWgt(qt.QLabel):
|
|
|
|
|
# textChanged = qt.Signal()
|
|
|
|
|
def __init__(self, parent, type, choice = None, caption=None, \
|
|
|
|
|
value=None, comments = None):
|
|
|
|
|
super().__init__(parent)
|
|
|
|
|
self.type = type
|
|
|
|
|
self.caption = caption
|
|
|
|
|
self.value = value
|
|
|
|
|
|
|
|
|
|
if hasattr (comments, 'string'):
|
|
|
|
|
self.comments = comments.string
|
|
|
|
|
else:
|
|
|
|
|
self.comments = None
|
|
|
|
|
|
|
|
|
|
self.data = None
|
|
|
|
|
|
|
|
|
|
if not choice:
|
|
|
|
|
choice = []
|
|
|
|
|
if not value in choice and value:
|
|
|
|
|
choice.append(value)
|
|
|
|
|
if self.comments:
|
|
|
|
|
self.comments.append(value)
|
|
|
|
|
|
|
|
|
|
self.layout = qt.QHBoxLayout(self)
|
|
|
|
|
self.layout.setContentsMargins(0,0,0,0)
|
|
|
|
|
self.ComboBox = qt.QComboBox()
|
|
|
|
|
self.setContentsMargins(0,0,0,0)
|
|
|
|
|
self.ComboBox.currentIndexChanged.connect(self.setCursorPos)
|
|
|
|
|
self.ComboBox.setEditable(True)
|
|
|
|
|
self.lineEdit = self.ComboBox.lineEdit()
|
|
|
|
|
self.setFixedHeight(self.ComboBox.sizeHint().height()+2)
|
|
|
|
|
self.layout.addWidget(self.ComboBox)
|
|
|
|
|
|
|
|
|
|
self.view_value = []
|
|
|
|
|
if choice:
|
|
|
|
|
if not self.comments:
|
|
|
|
|
for item in choice:
|
|
|
|
|
self.ComboBox.addItem(item)
|
|
|
|
|
if value == item:
|
|
|
|
|
self.ComboBox.setCurrentIndex(self.ComboBox.count()-1)
|
|
|
|
|
else:
|
|
|
|
|
for item in range (len(self.comments)):
|
|
|
|
|
try:
|
|
|
|
|
self.ComboBox.addItem(self.comments[item])
|
|
|
|
|
self.view_value.append(self.comments[item])
|
|
|
|
|
except IndexError:
|
|
|
|
|
self.ComboBox.addItem(choice[item])
|
|
|
|
|
self.view_value.append(choice[item])
|
|
|
|
|
self.ComboBox.setItemData(item,choice[item])
|
|
|
|
|
|
|
|
|
|
if value == choice[item]:
|
|
|
|
|
self.ComboBox.setCurrentIndex(self.ComboBox.count()-1)
|
|
|
|
|
self.ComboBox.setSizeAdjustPolicy(
|
|
|
|
|
qt.QComboBox.AdjustToMinimumContentsLengthWithIcon)
|
|
|
|
|
|
|
|
|
|
self.button = qt.QToolButton(self)
|
|
|
|
|
self.button.setCursor(qt.Qt.ArrowCursor)
|
|
|
|
|
self.button.setFocusPolicy(qt.Qt.NoFocus)
|
|
|
|
|
|
|
|
|
|
icon = get_icon("document-open")
|
|
|
|
|
if not icon.isNull():
|
|
|
|
|
self.button.setIcon(icon)
|
|
|
|
|
else:
|
|
|
|
|
self.button.setText(_('Open'))
|
|
|
|
|
self.button.clicked.connect(self.file_dialog)
|
|
|
|
|
|
|
|
|
|
self.layout.addWidget(self.button)
|
|
|
|
|
self.unsetErrorBorder()
|
|
|
|
|
|
|
|
|
|
def setCursorPos(self, num = None):
|
|
|
|
|
self.lineEdit.setCursorPosition(0)
|
|
|
|
|
|
|
|
|
|
def file_dialog(self):
|
|
|
|
|
self.fd = qt.QFileDialog(self, self.caption)
|
|
|
|
|
|
|
|
|
|
self.fd.setWindowModality(qt.Qt.WindowModal)
|
|
|
|
|
if self.type == 'dir':
|
|
|
|
|
data = self.fd.getExistingDirectory()
|
|
|
|
|
if self.type == 'file':
|
|
|
|
|
data = self.fd.getOpenFileName()
|
|
|
|
|
data = data[0]
|
|
|
|
|
if self.type == 'files':
|
|
|
|
|
data = self.fd.getOpenFileNames()
|
|
|
|
|
data = data[0]
|
|
|
|
|
if data:
|
|
|
|
|
self.data = data
|
|
|
|
|
self.set_label()
|
|
|
|
|
|
|
|
|
|
def set_label(self):
|
|
|
|
|
if type(self.data) in [str]:
|
|
|
|
|
lbl = self.data
|
|
|
|
|
self.ComboBox.addItem(lbl)
|
|
|
|
|
|
|
|
|
|
elif type(self.data) == list:
|
|
|
|
|
lbl = ', '.join(self.data)
|
|
|
|
|
self.ComboBox.addItem(lbl)
|
|
|
|
|
|
|
|
|
|
if self.comments:
|
|
|
|
|
self.ComboBox.setItemData(self.ComboBox.count()-1, lbl)
|
|
|
|
|
self.ComboBox.setCurrentIndex(self.ComboBox.count()-1)
|
|
|
|
|
|
|
|
|
|
def text(self):
|
|
|
|
|
if self.comments:
|
|
|
|
|
if self.ComboBox.currentText() in self.view_value:
|
|
|
|
|
return self.ComboBox.itemData(self.ComboBox.currentIndex())
|
|
|
|
|
return self.ComboBox.currentText()
|
|
|
|
|
|
|
|
|
|
def setText(self, text):
|
|
|
|
|
self.ComboBox.addItem(text)
|
|
|
|
|
if self.comments:
|
|
|
|
|
self.ComboBox.setItemData(self.ComboBox.count()-1, text)
|
|
|
|
|
self.ComboBox.setCurrentIndex(self.ComboBox.count()-1)
|
|
|
|
|
|
|
|
|
|
def setErrorBorder(self):
|
|
|
|
|
style = ".ComboFileWgt {border: 1px solid red; margin: 0px;}"
|
|
|
|
|
self.setStyleSheet(style)
|
|
|
|
|
|
|
|
|
|
def unsetErrorBorder(self):
|
|
|
|
|
style = ".ComboFileWgt {border: 1px solid transparent; margin: 0px;}"
|
|
|
|
|
self.setStyleSheet(style)
|
|
|
|
|
|
|
|
|
|
class ReadonlyCheckBox(qt.QCheckBox):
|
|
|
|
|
def __init__(self, parent):
|
|
|
|
|
super().__init__(parent)
|
|
|
|
|
self.setFocusPolicy(qt.Qt.NoFocus)
|
|
|
|
|
self.disabled = False
|
|
|
|
|
|
|
|
|
|
def mousePressEvent(self, event):
|
|
|
|
|
cur_state = self.checkState()
|
|
|
|
|
event.accept()
|
|
|
|
|
qt.QCheckBox.click(self)
|
|
|
|
|
if self.disabled:
|
|
|
|
|
self.setCheckState(cur_state)
|
|
|
|
|
|
|
|
|
|
class CentralCheckBox (qt.QWidget):
|
|
|
|
|
def __init__(self, parent, tristate, text = None, ind_col = False):
|
|
|
|
|
super().__init__(parent)
|
|
|
|
|
self.lay = qt.QHBoxLayout(self)
|
|
|
|
|
self.pCheckB = ReadonlyCheckBox(self)
|
|
|
|
|
self.lay.addWidget(self.pCheckB)
|
|
|
|
|
self.lay.setAlignment(qt.Qt.AlignHCenter)
|
|
|
|
|
self.lay.setContentsMargins(3,3,3,3)
|
|
|
|
|
self.setLayout(self.lay)
|
|
|
|
|
if tristate:
|
|
|
|
|
self.pCheckB.setTristate(True)
|
|
|
|
|
self.pCheckB.setCheckState(qt.Qt.PartiallyChecked)
|
|
|
|
|
if not ind_col:
|
|
|
|
|
self.pCheckB.clicked.connect(self.change_label)
|
|
|
|
|
self.change_label()
|
|
|
|
|
self.setStyleSheet('padding: 0px; margin-left: 2px;')
|
|
|
|
|
self.setFocusPolicy(qt.Qt.NoFocus)
|
|
|
|
|
self.setAttribute(qt.Qt.WA_DeleteOnClose)
|
|
|
|
|
|
|
|
|
|
def setChecked(self, check = True):
|
|
|
|
|
self.pCheckB.setChecked(check)
|
|
|
|
|
self.change_label()
|
|
|
|
|
|
|
|
|
|
def isChecked(self):
|
|
|
|
|
return self.pCheckB.isChecked()
|
|
|
|
|
|
|
|
|
|
def set_label(self, text):
|
|
|
|
|
self.pCheckB.setText(text)
|
|
|
|
|
|
|
|
|
|
def change_label(self):
|
|
|
|
|
if self.pCheckB.disabled:
|
|
|
|
|
return
|
|
|
|
|
elif self.pCheckB.checkState() == \
|
|
|
|
|
qt.Qt.PartiallyChecked:
|
|
|
|
|
self.set_label(_('Auto'))
|
|
|
|
|
elif self.pCheckB.checkState() == qt.Qt.Checked:
|
|
|
|
|
self.set_label(_('Yes'))
|
|
|
|
|
else:
|
|
|
|
|
self.set_label(_('No'))
|
|
|
|
|
|
|
|
|
|
def setCheckState(self, CheckState):
|
|
|
|
|
self.pCheckB.setCheckState(CheckState)
|
|
|
|
|
self.change_label()
|
|
|
|
|
|
|
|
|
|
def getState(self):
|
|
|
|
|
if self.pCheckB.isTristate():
|
|
|
|
|
if self.pCheckB.checkState() == \
|
|
|
|
|
qt.Qt.PartiallyChecked:
|
|
|
|
|
return ''
|
|
|
|
|
elif self.pCheckB.checkState() == qt.Qt.Checked:
|
|
|
|
|
return 'on'
|
|
|
|
|
else:
|
|
|
|
|
return 'off'
|
|
|
|
|
else:
|
|
|
|
|
if self.pCheckB.isChecked():
|
|
|
|
|
return 'on'
|
|
|
|
|
else:
|
|
|
|
|
return 'off'
|
|
|
|
|
|
|
|
|
|
def setState(self, text):
|
|
|
|
|
if text.lower() in ['yes', 'on']:
|
|
|
|
|
self.pCheckB.setCheckState(qt.Qt.Checked)
|
|
|
|
|
elif text.lower() in ['no', 'off']:
|
|
|
|
|
self.pCheckB.setCheckState(qt.Qt.Unchecked)
|
|
|
|
|
else:
|
|
|
|
|
self.pCheckB.setCheckState(qt.Qt.PartiallyChecked)
|
|
|
|
|
self.change_label()
|
|
|
|
|
|
|
|
|
|
def setCheckable(self, set_bool):
|
|
|
|
|
self.pCheckB.setCheckable(set_bool)
|
|
|
|
|
|
|
|
|
|
def _setDisabled(self):
|
|
|
|
|
self.pCheckB.disabled = True
|
|
|
|
|
|
|
|
|
|
class QComboWgt(qt.QLabel):
|
|
|
|
|
currentIndexChanged = qt.Signal(int)
|
|
|
|
|
def __init__(self, parent = None):
|
|
|
|
|
super().__init__(parent)
|
|
|
|
|
self.layout = qt.QVBoxLayout(self)
|
|
|
|
|
self.layout.setContentsMargins(0,0,0,0)
|
|
|
|
|
self.ComboBox = qt.QComboBox()
|
|
|
|
|
self.setContentsMargins(0,0,0,0)
|
|
|
|
|
self.ComboBox.currentIndexChanged.connect(self.currentIndexChanged)
|
|
|
|
|
self.setFixedHeight(self.ComboBox.sizeHint().height()+2)
|
|
|
|
|
self.layout.addWidget(self.ComboBox)
|
|
|
|
|
self.unsetErrorBorder()
|
|
|
|
|
|
|
|
|
|
def insertSeparator(self, separator):
|
|
|
|
|
self.ComboBox.insertSeparator(separator)
|
|
|
|
|
def addItem(self, item):
|
|
|
|
|
self.ComboBox.addItem(item)
|
|
|
|
|
def insertItem(self, pos, item):
|
|
|
|
|
self.ComboBox.insertItem(pos, item)
|
|
|
|
|
def setItemData(self, pos, item):
|
|
|
|
|
self.ComboBox.setItemData(pos, item)
|
|
|
|
|
def setCurrentIndex(self, ind):
|
|
|
|
|
self.ComboBox.setCurrentIndex(ind)
|
|
|
|
|
def currentIndex(self):
|
|
|
|
|
return self.ComboBox.currentIndex()
|
|
|
|
|
def currentText(self):
|
|
|
|
|
return self.ComboBox.currentText()
|
|
|
|
|
def itemData(self, ind):
|
|
|
|
|
return self.ComboBox.itemData(ind)
|
|
|
|
|
def unsetErrorBorder(self):
|
|
|
|
|
style = ".QComboWgt {border: 1px solid transparent; margin: 0px;}"
|
|
|
|
|
self.setStyleSheet(style)
|
|
|
|
|
def setErrorBorder(self):
|
|
|
|
|
style = ".QComboWgt {border: 1px solid red; margin: 0px;}"
|
|
|
|
|
self.setStyleSheet(style)
|
|
|
|
|
def setDuplicatesEnabled(self, boolean = True):
|
|
|
|
|
self.ComboBox.setDuplicatesEnabled(boolean)
|
|
|
|
|
def setEditable(self, boolean = True):
|
|
|
|
|
self.ComboBox.setEditable(boolean)
|
|
|
|
|
def setLineEdit(self, lineEdit):
|
|
|
|
|
self.ComboBox.setLineEdit(lineEdit)
|
|
|
|
|
def lineEdit(self):
|
|
|
|
|
return self.ComboBox.lineEdit()
|
|
|
|
|
|
|
|
|
|
class ListWidget (qt.QListWidget):
|
|
|
|
|
def __init__(self, parent):
|
|
|
|
|
super().__init__(parent)
|
|
|
|
|
self.setDragEnabled(True)
|
|
|
|
|
self.setAcceptDrops(True)
|
|
|
|
|
self.setDropIndicatorShown(True)
|
|
|
|
|
|
|
|
|
|
def dropEvent(self, event):
|
|
|
|
|
temp_item = event.source().takeItem(event.source().currentRow())
|
|
|
|
|
self.addItem(temp_item)
|
|
|
|
|
event.accept()
|
|
|
|
|
|
|
|
|
|
class MultipleChoiceDialog (qt.QWidget):
|
|
|
|
|
""" Widget opens a dialog multiple select """
|
|
|
|
|
def __init__(self, parent, Available_dict, Available_list, Selected_list, \
|
|
|
|
|
add_ability):
|
|
|
|
|
super().__init__()
|
|
|
|
|
self._parent = parent
|
|
|
|
|
self.layout = qt.QGridLayout(self)
|
|
|
|
|
self.layout.setColumnStretch(0,5)
|
|
|
|
|
self.layout.setColumnStretch(1,5)
|
|
|
|
|
self.layout.setColumnStretch(2,0)
|
|
|
|
|
self.layout.setColumnStretch(3,5)
|
|
|
|
|
self.layout.setColumnStretch(4,5)
|
|
|
|
|
|
|
|
|
|
self.Available_dict = Available_dict
|
|
|
|
|
|
|
|
|
|
minimum = qt.QSizePolicy.Maximum
|
|
|
|
|
exp = qt.QSizePolicy.Expanding
|
|
|
|
|
# if there is a possibility of adding
|
|
|
|
|
if add_ability:
|
|
|
|
|
add_line_wgt = qt.QWidget(self)
|
|
|
|
|
add_line_layout = qt.QHBoxLayout(add_line_wgt)
|
|
|
|
|
# add "input new items" LineEdit
|
|
|
|
|
self.add_LineEdit = qt.QLineEdit(self)
|
|
|
|
|
self.add_LineEdit.setSizePolicy(exp, minimum)
|
|
|
|
|
add_line_layout.addWidget(self.add_LineEdit)
|
|
|
|
|
|
|
|
|
|
# add "add new items" PushButton
|
|
|
|
|
self.add_Button = qt.QPushButton(self)
|
|
|
|
|
self.add_Button.setFixedWidth(32)
|
|
|
|
|
icon = get_icon("list-add")
|
|
|
|
|
if not icon.isNull():
|
|
|
|
|
self.add_Button.setIcon(icon)
|
|
|
|
|
else:
|
|
|
|
|
self.add_Button.setText('Add Item')
|
|
|
|
|
self.add_Button.setShortcut \
|
|
|
|
|
(qt.QKeySequence(qt.Qt.Key_Return))
|
|
|
|
|
self.add_Button.clicked.connect(self.add_new_item)
|
|
|
|
|
self.add_Button.setSizePolicy(exp, minimum)
|
|
|
|
|
add_line_layout.addWidget(self.add_Button)
|
|
|
|
|
|
|
|
|
|
self.layout.addWidget(add_line_wgt, 0,0,1,5)
|
|
|
|
|
|
|
|
|
|
# add 2 labels
|
|
|
|
|
self.available_label = qt.QLabel('Available values', self)
|
|
|
|
|
self.available_label.setSizePolicy(exp, minimum)
|
|
|
|
|
self.layout.addWidget(self.available_label, 1,0,1,2)
|
|
|
|
|
|
|
|
|
|
self.selected_label = qt.QLabel('Selected values', self)
|
|
|
|
|
self.selected_label.setSizePolicy(exp, minimum)
|
|
|
|
|
self.layout.addWidget(self.selected_label, 1,3,1,2)
|
|
|
|
|
|
|
|
|
|
#add left list
|
|
|
|
|
self.left_ListWidget = ListWidget(self)
|
|
|
|
|
self.left_ListWidget.itemDoubleClicked.connect(self.plus_item)
|
|
|
|
|
self.layout.addWidget(self.left_ListWidget, 2,0,2,2)
|
|
|
|
|
|
|
|
|
|
p_m_wgt = qt.QWidget(self)
|
|
|
|
|
p_m_layout = qt.QVBoxLayout(p_m_wgt)
|
|
|
|
|
|
|
|
|
|
# add '++' button
|
|
|
|
|
self.plus_all_Button = qt.QPushButton(self)
|
|
|
|
|
icon_next = get_icon('go-last-view', 'go-last')
|
|
|
|
|
if not icon_next.isNull():
|
|
|
|
|
self.plus_all_Button.setIcon(icon_next)
|
|
|
|
|
else:
|
|
|
|
|
self.plus_all_Button.setText('->\n->')
|
|
|
|
|
self.plus_all_Button.clicked.connect(self.plus_all_items)
|
|
|
|
|
p_m_layout.addWidget(self.plus_all_Button)
|
|
|
|
|
|
|
|
|
|
# add '+' button
|
|
|
|
|
self.plus_Button = qt.QPushButton(self)
|
|
|
|
|
icon_plus = get_icon('go-next-view', 'go-next')
|
|
|
|
|
if not icon_plus.isNull():
|
|
|
|
|
self.plus_Button.setIcon(icon_plus)
|
|
|
|
|
else:
|
|
|
|
|
self.plus_Button.setText('->')
|
|
|
|
|
self.plus_Button.clicked.connect(self.plus_item)
|
|
|
|
|
p_m_layout.addWidget(self.plus_Button)
|
|
|
|
|
|
|
|
|
|
# add '-' button
|
|
|
|
|
self.minus_Button = qt.QPushButton(self)
|
|
|
|
|
icon_minus = get_icon('go-previous-view', 'go-previous')
|
|
|
|
|
if not icon_minus.isNull():
|
|
|
|
|
self.minus_Button.setIcon(icon_minus)
|
|
|
|
|
else:
|
|
|
|
|
self.minus_Button.setText('<-')
|
|
|
|
|
self.minus_Button.clicked.connect(self.minus_item)
|
|
|
|
|
p_m_layout.addWidget(self.minus_Button)
|
|
|
|
|
|
|
|
|
|
self.layout.addWidget(p_m_wgt, 2, 2, 2, 1)
|
|
|
|
|
|
|
|
|
|
# add '--' button
|
|
|
|
|
self.minus_all_Button = qt.QPushButton(self)
|
|
|
|
|
icon_all_minus = get_icon('go-first-view', 'go-first')
|
|
|
|
|
if not icon_all_minus.isNull():
|
|
|
|
|
self.minus_all_Button.setIcon(icon_all_minus)
|
|
|
|
|
else:
|
|
|
|
|
self.minus_all_Button.setText('<-\n<-')
|
|
|
|
|
self.minus_all_Button.clicked.connect(self.minus_all_items)
|
|
|
|
|
p_m_layout.addWidget(self.minus_all_Button)
|
|
|
|
|
|
|
|
|
|
#add right list
|
|
|
|
|
self.right_ListWidget = ListWidget(self)
|
|
|
|
|
self.right_ListWidget.itemDoubleClicked.connect(self.minus_item)
|
|
|
|
|
self.layout.addWidget(self.right_ListWidget, 2,3,2,2)
|
|
|
|
|
|
|
|
|
|
buttons_wgt = qt.QWidget(self)
|
|
|
|
|
buttons_layout = qt.QHBoxLayout(buttons_wgt)
|
|
|
|
|
# add OK button
|
|
|
|
|
self.Ok_Button = qt.QPushButton('Ok', self)
|
|
|
|
|
self.Ok_Button.clicked.connect(self.ok_pressed)
|
|
|
|
|
self.Ok_Button.setFixedWidth(100)
|
|
|
|
|
buttons_layout.addWidget(self.Ok_Button)
|
|
|
|
|
|
|
|
|
|
# add Cancel button
|
|
|
|
|
self.Cancel_Button = qt.QPushButton(_('Cancel'), self)
|
|
|
|
|
self.Cancel_Button.clicked.connect(self.close)
|
|
|
|
|
self.Cancel_Button.setFixedWidth(100)
|
|
|
|
|
buttons_layout.addWidget(self.Cancel_Button)
|
|
|
|
|
|
|
|
|
|
self.layout.addWidget(buttons_wgt, 4,3,1,2, qt.Qt.AlignRight)
|
|
|
|
|
|
|
|
|
|
#add Items in list
|
|
|
|
|
self.left_ListWidget.addItems(map(lambda x: Available_dict[x],
|
|
|
|
|
filter (lambda x: x not in Selected_list,
|
|
|
|
|
Available_list)))
|
|
|
|
|
self.right_ListWidget.addItems(map(lambda x: Available_dict[x],
|
|
|
|
|
filter (lambda x: x in Available_dict.keys(),
|
|
|
|
|
Selected_list)))
|
|
|
|
|
|
|
|
|
|
self.layout.setRowStretch(0,0)
|
|
|
|
|
self.layout.setRowStretch(1,0)
|
|
|
|
|
self.layout.setRowStretch(2,1)
|
|
|
|
|
self.layout.setRowStretch(3,1)
|
|
|
|
|
self.layout.setRowStretch(4,0)
|
|
|
|
|
self.setLayout(self.layout)
|
|
|
|
|
|
|
|
|
|
def add_new_item(self):
|
|
|
|
|
# Slot click event add_Button
|
|
|
|
|
if self.add_LineEdit.text() not in [None, '']:
|
|
|
|
|
self.right_ListWidget.addItem(self.add_LineEdit.text())
|
|
|
|
|
self.add_LineEdit.setText('')
|
|
|
|
|
self.add_LineEdit.setFocus()
|
|
|
|
|
|
|
|
|
|
def plus_all_items(self):
|
|
|
|
|
# get item in left_ListWidget and set this item in right_ListWidget
|
|
|
|
|
while True:
|
|
|
|
|
temp_item = self.left_ListWidget.takeItem(0)
|
|
|
|
|
if not temp_item:
|
|
|
|
|
return
|
|
|
|
|
self.right_ListWidget.addItem(temp_item)
|
|
|
|
|
|
|
|
|
|
def plus_item(self):
|
|
|
|
|
# get item in left_ListWidget and set this item in right_ListWidget
|
|
|
|
|
temp_item = self.left_ListWidget.takeItem \
|
|
|
|
|
(self.left_ListWidget.currentRow())
|
|
|
|
|
self.right_ListWidget.addItem(temp_item)
|
|
|
|
|
|
|
|
|
|
def minus_item(self):
|
|
|
|
|
# get item in right_ListWidget and set this item in left_ListWidget
|
|
|
|
|
temp_item = self.right_ListWidget.takeItem \
|
|
|
|
|
(self.right_ListWidget.currentRow())
|
|
|
|
|
self.left_ListWidget.addItem(temp_item)
|
|
|
|
|
|
|
|
|
|
def minus_all_items(self):
|
|
|
|
|
# get item in left_ListWidget and set this item in right_ListWidget
|
|
|
|
|
while True:
|
|
|
|
|
temp_item = self.right_ListWidget.takeItem(0)
|
|
|
|
|
if not temp_item:
|
|
|
|
|
return
|
|
|
|
|
self.left_ListWidget.addItem(temp_item)
|
|
|
|
|
|
|
|
|
|
def ok_pressed(self):
|
|
|
|
|
# save all lists and close this widget
|
|
|
|
|
self._parent.Selected = []
|
|
|
|
|
revertDict = {y:x for x,y in self.Available_dict.items()}
|
|
|
|
|
for i in range(self.right_ListWidget.count()):
|
|
|
|
|
text = self.right_ListWidget.takeItem(0).text()
|
|
|
|
|
if text in revertDict:
|
|
|
|
|
self._parent.Selected.append(revertDict[text])
|
|
|
|
|
else:
|
|
|
|
|
self._parent.Selected.append(text)
|
|
|
|
|
|
|
|
|
|
self._parent.avail = []
|
|
|
|
|
for i in range(self.left_ListWidget.count()):
|
|
|
|
|
text = self.left_ListWidget.takeItem(0).text()
|
|
|
|
|
if text in revertDict:
|
|
|
|
|
self._parent.avail.append(revertDict[text])
|
|
|
|
|
else:
|
|
|
|
|
self._parent.avail.append(text)
|
|
|
|
|
|
|
|
|
|
# self._parent.Selected = ','.join(self._parent.select)
|
|
|
|
|
self._parent.change_value()
|
|
|
|
|
self.close()
|
|
|
|
|
|
|
|
|
|
def keyPressEvent(self, key):
|
|
|
|
|
if key.key() in [qt.Qt.Key_Enter, qt.Qt.Key_Return]:
|
|
|
|
|
if hasattr (self, 'add_Button'):
|
|
|
|
|
self.add_new_item()
|
|
|
|
|
|
|
|
|
|
class MultipleButton(qt.QPushButton):
|
|
|
|
|
def __init__(self, text, parent):
|
|
|
|
|
super().__init__(text, parent)
|
|
|
|
|
self.setStyleSheet("text-align: left; padding: 3px;")
|
|
|
|
|
self.setFocusPolicy(qt.Qt.NoFocus)
|
|
|
|
|
|
|
|
|
|
def mousePressEvent(self, button = None):
|
|
|
|
|
self.parent().mousePressEvent()
|
|
|
|
|
|
|
|
|
|
class MultipleChoice (qt.QWidget):
|
|
|
|
|
Changed = qt.Signal()
|
|
|
|
|
# multiple-choice widget displayed in the table
|
|
|
|
|
def __init__(self, parent, Available_list, Selected, comments, \
|
|
|
|
|
add_ability = False, expert = False):
|
|
|
|
|
super().__init__(parent)
|
|
|
|
|
''' Available_list is string list, Selected_list is string,
|
|
|
|
|
add_ability is boolean'''
|
|
|
|
|
self.avail = Available_list
|
|
|
|
|
self.Selected = Selected if Selected else []
|
|
|
|
|
if hasattr(comments, 'string'):
|
|
|
|
|
self.Comments = comments.string
|
|
|
|
|
else:
|
|
|
|
|
self.Comments = []
|
|
|
|
|
# self.select = Selected if Selected else []
|
|
|
|
|
self.ability = add_ability
|
|
|
|
|
|
|
|
|
|
self.value_dict = None
|
|
|
|
|
self.value_dict = {}
|
|
|
|
|
for i in range (len(self.avail)):
|
|
|
|
|
if len(self.Comments) > i:
|
|
|
|
|
self.value_dict[self.avail[i]] = self.Comments[i]
|
|
|
|
|
else:
|
|
|
|
|
self.value_dict[self.avail[i]] = self.avail[i]
|
|
|
|
|
|
|
|
|
|
layout = qt.QHBoxLayout(self)
|
|
|
|
|
layout.setSpacing(0)
|
|
|
|
|
layout.setContentsMargins(0, 0, 0, 0)
|
|
|
|
|
|
|
|
|
|
self.label_text = ','.join(map (lambda x: self.value_dict[x], \
|
|
|
|
|
filter (lambda x: x in self.value_dict.keys(),
|
|
|
|
|
self.Selected)))
|
|
|
|
|
self.lbl = MultipleButton(self.label_text, self)
|
|
|
|
|
|
|
|
|
|
self.lbl.setMaximumWidth(450)
|
|
|
|
|
maximum = qt.QSizePolicy.Maximum
|
|
|
|
|
exp = qt.QSizePolicy.Expanding
|
|
|
|
|
self.lbl.setSizePolicy(exp, maximum)
|
|
|
|
|
layout.addWidget(self.lbl)
|
|
|
|
|
|
|
|
|
|
self.button=qt.QToolButton(self)
|
|
|
|
|
# self.button.hide()
|
|
|
|
|
self.button.setFocusPolicy(qt.Qt.NoFocus)
|
|
|
|
|
icon = get_icon("list-add")
|
|
|
|
|
if not icon.isNull():
|
|
|
|
|
self.button.setIcon(icon)
|
|
|
|
|
else:
|
|
|
|
|
self.button.setText('+')
|
|
|
|
|
self.button.setStyleSheet("border: none;")
|
|
|
|
|
self.button.setFixedWidth(24)
|
|
|
|
|
self.button.clicked.connect(self.mousePressEvent)
|
|
|
|
|
layout.addWidget(self.button, qt.Qt.AlignRight)
|
|
|
|
|
|
|
|
|
|
if expert:
|
|
|
|
|
self.clear_button = qt.QPushButton(self)
|
|
|
|
|
self.clear_button.setFocusPolicy(qt.Qt.NoFocus)
|
|
|
|
|
icon = get_icon('edit-clear')
|
|
|
|
|
if not icon.isNull():
|
|
|
|
|
self.clear_button.setIcon(icon)
|
|
|
|
|
else:
|
|
|
|
|
self.clear_button.setText('C')
|
|
|
|
|
self.clear_button.setToolTip(_('Clear the table'))
|
|
|
|
|
self.clear_button.setStyleSheet("border: none;")
|
|
|
|
|
self.clear_button.setFixedWidth(24)
|
|
|
|
|
self.clear_button.clicked.connect(self.default_value)
|
|
|
|
|
layout.addWidget(self.clear_button, qt.Qt.AlignRight)
|
|
|
|
|
|
|
|
|
|
self.setAttribute(qt.Qt.WA_DeleteOnClose)
|
|
|
|
|
|
|
|
|
|
self.setLayout(layout)
|
|
|
|
|
|
|
|
|
|
def mousePressEvent(self, button = None):
|
|
|
|
|
# call widget MultipleChoiceDialog in new window
|
|
|
|
|
self.MCD = MultipleChoiceDialog(self, self.value_dict, self.avail, \
|
|
|
|
|
self.Selected, self.ability)
|
|
|
|
|
self.MCD.setWindowModality(qt.Qt.WindowModal)
|
|
|
|
|
self.MCD.move(qt.QCursor.pos ())
|
|
|
|
|
self.MCD.show()
|
|
|
|
|
|
|
|
|
|
def change_value(self):
|
|
|
|
|
# show values in label
|
|
|
|
|
# self.select = self.Selected.split(',') if self.Selected else []
|
|
|
|
|
self.label_text = ','.join(
|
|
|
|
|
self.value_dict.get(x, x) for x in self.Selected)
|
|
|
|
|
self.lbl.setText(self.label_text)
|
|
|
|
|
self.Changed.emit()
|
|
|
|
|
|
|
|
|
|
def text(self):
|
|
|
|
|
return self.lbl.text()
|
|
|
|
|
|
|
|
|
|
def values(self):
|
|
|
|
|
res_dict = {}
|
|
|
|
|
for key in self.value_dict:
|
|
|
|
|
res_dict[self.value_dict[key]] = key
|
|
|
|
|
|
|
|
|
|
res = map(lambda x: res_dict[x],
|
|
|
|
|
filter (lambda x: x in res_dict, self.Selected))
|
|
|
|
|
res += filter (lambda x: not x in res_dict, self.Selected)
|
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
def default_value(self):
|
|
|
|
|
self.label_text = ''
|
|
|
|
|
self.lbl.setText(self.label_text)
|
|
|
|
|
|
|
|
|
|
class AddLineWidget (qt.QWidget):
|
|
|
|
|
def __init__(self, parent, text):
|
|
|
|
|
super().__init__()
|
|
|
|
|
layout = qt.QHBoxLayout(self)
|
|
|
|
|
self.add_line = qt.QLineEdit(self)
|
|
|
|
|
self.add_line.setFixedWidth(100)
|
|
|
|
|
add_button = qt.QPushButton(text, self)
|
|
|
|
|
close_button = qt.QPushButton(_("Cancel"), self)
|
|
|
|
|
|
|
|
|
|
layout.addWidget(self.add_line)
|
|
|
|
|
layout.addWidget(add_button)
|
|
|
|
|
layout.addWidget(close_button)
|
|
|
|
|
|
|
|
|
|
add_button.clicked.connect(parent.add_line)
|
|
|
|
|
close_button.clicked.connect(self.close)
|
|
|
|
|
self.setWindowTitle(text)
|
|
|
|
|
self.move(qt.QCursor.pos())
|
|
|
|
|
self.show()
|
|
|
|
|
|
|
|
|
|
class MultipleCheckBox(qt.QCheckBox):
|
|
|
|
|
def __init__(self, parent):
|
|
|
|
|
super().__init__(parent)
|
|
|
|
|
|
|
|
|
|
class SelectTable(qt.QWidget):
|
|
|
|
|
Changed = qt.Signal()
|
|
|
|
|
# multiple-choice table
|
|
|
|
|
def __init__(self, parent, Available_list, Selected, comments, \
|
|
|
|
|
add_ability = False, expert = False, default = None):
|
|
|
|
|
super().__init__(parent)
|
|
|
|
|
self._parent = parent
|
|
|
|
|
|
|
|
|
|
self.Available_list = Available_list
|
|
|
|
|
self.Selected = Selected
|
|
|
|
|
self.items_dict = {}
|
|
|
|
|
self.comments = []
|
|
|
|
|
self.expert = expert
|
|
|
|
|
self.set_auto = expert if default else False
|
|
|
|
|
self.default = default
|
|
|
|
|
|
|
|
|
|
if hasattr(comments, 'string'):
|
|
|
|
|
comments = comments.string
|
|
|
|
|
else:
|
|
|
|
|
comments = None
|
|
|
|
|
|
|
|
|
|
self.grid = qt.QGridLayout(self)
|
|
|
|
|
self.grid.setContentsMargins(0, 0, 0, 0)
|
|
|
|
|
self.grid.setSpacing(0)
|
|
|
|
|
self.grid.setAlignment(qt.Qt.AlignTop)
|
|
|
|
|
|
|
|
|
|
unit_layout = qt.QHBoxLayout()
|
|
|
|
|
unit_layout.setContentsMargins(0, 0, 0, 0)
|
|
|
|
|
unit_layout.setSpacing(0)
|
|
|
|
|
|
|
|
|
|
if add_ability:
|
|
|
|
|
plus_but = qt.QPushButton(self)
|
|
|
|
|
icon = get_icon('list-add')
|
|
|
|
|
if not icon.isNull():
|
|
|
|
|
plus_but.setIcon(icon)
|
|
|
|
|
else:
|
|
|
|
|
plus_but.setText('+')
|
|
|
|
|
|
|
|
|
|
plus_but.setToolTip(_('Add a row'))
|
|
|
|
|
plus_but.setFixedSize(30, 30)
|
|
|
|
|
plus_but.clicked.connect(self.line_add)
|
|
|
|
|
unit_layout.addWidget(plus_but)
|
|
|
|
|
|
|
|
|
|
self.recover_but = qt.QPushButton(self)
|
|
|
|
|
icon = get_icon('edit-clear')
|
|
|
|
|
if not icon.isNull():
|
|
|
|
|
self.recover_but.setIcon(icon)
|
|
|
|
|
else:
|
|
|
|
|
self.recover_but.setText('R')
|
|
|
|
|
|
|
|
|
|
self.recover_but.setToolTip(_('Recover the table'))
|
|
|
|
|
self.recover_but.setFixedSize(30, 30)
|
|
|
|
|
|
|
|
|
|
self.recover_but.clicked.connect(self.recover_table)
|
|
|
|
|
|
|
|
|
|
unit_layout.addWidget(self.recover_but)
|
|
|
|
|
|
|
|
|
|
unit_layout.setAlignment(qt.Qt.AlignLeft)
|
|
|
|
|
self.grid.addLayout(unit_layout, 0,0)
|
|
|
|
|
|
|
|
|
|
self.table = qt.QTableWidget(self)
|
|
|
|
|
|
|
|
|
|
self.row_count = len(Available_list)
|
|
|
|
|
for num in range(self.row_count):
|
|
|
|
|
try:
|
|
|
|
|
if not comments:
|
|
|
|
|
comment = Available_list[num]
|
|
|
|
|
else:
|
|
|
|
|
comment = comments[num]
|
|
|
|
|
if not comment:
|
|
|
|
|
comment = Available_list[num]
|
|
|
|
|
except IndexError:
|
|
|
|
|
comment = Available_list[num]
|
|
|
|
|
self.items_dict[comment] = Available_list[num]
|
|
|
|
|
self.comments.append(comment)
|
|
|
|
|
|
|
|
|
|
self.create_table()
|
|
|
|
|
|
|
|
|
|
self.table.itemClicked.connect(self.row_activate)
|
|
|
|
|
|
|
|
|
|
self.grid.addWidget(self.table, 1, 0, 1, 2)
|
|
|
|
|
self.resize(self.sizeHint())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def create_table(self, hard_auto = False):
|
|
|
|
|
self.table.setColumnCount(2)
|
|
|
|
|
self.table.setRowCount(self.row_count + 1)
|
|
|
|
|
|
|
|
|
|
for i in range (2):
|
|
|
|
|
tablewidgetitem = qt.QTableWidgetItem('')
|
|
|
|
|
tablewidgetitem.setBackground(qt.QBrush(qt.QColor \
|
|
|
|
|
('#dddddd')))
|
|
|
|
|
self.table.setItem(0, i, tablewidgetitem)
|
|
|
|
|
|
|
|
|
|
all_check = qt.QCheckBox()
|
|
|
|
|
all_check.setToolTip(_('Check all'))
|
|
|
|
|
all_check.clicked.connect(self.select_all)
|
|
|
|
|
self.table.setCellWidget(0, 0, all_check)
|
|
|
|
|
|
|
|
|
|
self.add_select_check(hard_auto)
|
|
|
|
|
for row in range(self.row_count):
|
|
|
|
|
tablewidgetitem = qt.QTableWidgetItem(self.comments[row])
|
|
|
|
|
self.table.setItem(row + 1, 1, tablewidgetitem)
|
|
|
|
|
if not self.expert or not self.default:
|
|
|
|
|
if self.items_dict[self.comments[row]] in self.Selected:
|
|
|
|
|
if not hard_auto:
|
|
|
|
|
self.table.cellWidget(row + 1 ,0).setChecked(True)
|
|
|
|
|
|
|
|
|
|
# if not add_ability:
|
|
|
|
|
self.table.setEditTriggers(qt.QAbstractItemView.NoEditTriggers)
|
|
|
|
|
|
|
|
|
|
self.table.setSelectionMode(qt.QAbstractItemView.NoSelection)
|
|
|
|
|
|
|
|
|
|
self.table.horizontalHeader().setStretchLastSection(True)
|
|
|
|
|
|
|
|
|
|
self.table.horizontalScrollBar().hide()
|
|
|
|
|
self.table.setColumnWidth(0, 24)
|
|
|
|
|
|
|
|
|
|
self.table.verticalHeader().hide()
|
|
|
|
|
self.table.horizontalHeader().hide()
|
|
|
|
|
self.resize_table()
|
|
|
|
|
|
|
|
|
|
def select_all(self):
|
|
|
|
|
self.Changed.emit()
|
|
|
|
|
if self.table.cellWidget(0,0).isChecked():
|
|
|
|
|
check = qt.Qt.Checked
|
|
|
|
|
else:
|
|
|
|
|
check = qt.Qt.Unchecked
|
|
|
|
|
for i in range(1, self.table.rowCount()):
|
|
|
|
|
self.table.cellWidget(i,0).setTristate(False)
|
|
|
|
|
for i in range(1, self.table.rowCount()):
|
|
|
|
|
self.table.cellWidget(i,0).setCheckState(check)
|
|
|
|
|
|
|
|
|
|
def row_activate(self, item):
|
|
|
|
|
self.table.cellWidget(item.row(),0).click()
|
|
|
|
|
|
|
|
|
|
def selected_row(self):
|
|
|
|
|
self.Changed.emit()
|
|
|
|
|
if self.set_auto:
|
|
|
|
|
for i in range(1, self.table.rowCount()):
|
|
|
|
|
if self.table.cellWidget(i,0).checkState() == \
|
|
|
|
|
qt.Qt.PartiallyChecked:
|
|
|
|
|
self.table.cellWidget(i,0).setChecked(False)
|
|
|
|
|
|
|
|
|
|
self.table.cellWidget(i,0).setTristate(False)
|
|
|
|
|
self.set_auto = False
|
|
|
|
|
|
|
|
|
|
def add_select_check(self, hard_auto):
|
|
|
|
|
# add row Selected
|
|
|
|
|
for row in range (1, self.table.rowCount()):
|
|
|
|
|
cb = MultipleCheckBox(self.table)
|
|
|
|
|
if self.expert and self.default:
|
|
|
|
|
cb.setCheckState(qt.Qt.PartiallyChecked)
|
|
|
|
|
if hard_auto:
|
|
|
|
|
cb.setCheckState(qt.Qt.PartiallyChecked)
|
|
|
|
|
# cb.setToolTip(_('Delete the row'))
|
|
|
|
|
cb.clicked.connect(self.selected_row)
|
|
|
|
|
self.table.setCellWidget(row, 0, cb)
|
|
|
|
|
|
|
|
|
|
def add_line(self):
|
|
|
|
|
self.Changed.emit()
|
|
|
|
|
if self.set_auto:
|
|
|
|
|
for i in range(1, self.table.rowCount()):
|
|
|
|
|
self.table.cellWidget(i,0).setTristate(False)
|
|
|
|
|
self.table.cellWidget(i,0).setChecked(False)
|
|
|
|
|
self.set_auto = False
|
|
|
|
|
text = self.addLineWgt.add_line.text()
|
|
|
|
|
self.addLineWgt.close()
|
|
|
|
|
row_number = self.table.rowCount()
|
|
|
|
|
self.table.insertRow(row_number)
|
|
|
|
|
cb = MultipleCheckBox(self.table)
|
|
|
|
|
cb.clicked.connect(self.selected_row)
|
|
|
|
|
self.table.setCellWidget(row_number, 0, cb)
|
|
|
|
|
twi = qt.QTableWidgetItem(text)
|
|
|
|
|
self.table.setItem(row_number, 1, twi)
|
|
|
|
|
self.resize_table()
|
|
|
|
|
|
|
|
|
|
def line_add(self):
|
|
|
|
|
self.addLineWgt = AddLineWidget(self, _('Add a row'))
|
|
|
|
|
|
|
|
|
|
def resize_table(self):
|
|
|
|
|
# Resize table
|
|
|
|
|
h = 2 * self.table.frameWidth()
|
|
|
|
|
for row_in_table in range (self.table.rowCount()):
|
|
|
|
|
h += self.table.rowHeight(row_in_table)
|
|
|
|
|
self.table.setFixedHeight(h)
|
|
|
|
|
|
|
|
|
|
def recover_table(self):
|
|
|
|
|
hard_auto = False
|
|
|
|
|
if self.expert:
|
|
|
|
|
self.set_auto = True
|
|
|
|
|
hard_auto = True
|
|
|
|
|
self.create_table(hard_auto = hard_auto)
|
|
|
|
|
|
|
|
|
|
def values(self):
|
|
|
|
|
result = []
|
|
|
|
|
for row in range(1, self.table.rowCount()):
|
|
|
|
|
if self.table.cellWidget(row, 0).checkState() == \
|
|
|
|
|
qt.Qt.PartiallyChecked:
|
|
|
|
|
return []
|
|
|
|
|
if self.table.cellWidget(row, 0).checkState() == \
|
|
|
|
|
qt.Qt.Checked:
|
|
|
|
|
value = self.table.item(row, 1).text()
|
|
|
|
|
if value in self.items_dict.keys():
|
|
|
|
|
result.append(self.items_dict[value])
|
|
|
|
|
else:
|
|
|
|
|
result.append(value)
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
class SelectList(qt.QGroupBox):
|
|
|
|
|
Changed = qt.Signal()
|
|
|
|
|
def __init__(self, parent, label, Available_list, Selected, comments, \
|
|
|
|
|
add_ability = False, expert = False, default = None):
|
|
|
|
|
super().__init__(label, parent)
|
|
|
|
|
self._parent = parent
|
|
|
|
|
self.Available_list = Available_list
|
|
|
|
|
self.Selected = Selected
|
|
|
|
|
self.items_dict = {}
|
|
|
|
|
self.comments = []
|
|
|
|
|
self.expert = expert
|
|
|
|
|
self.set_auto = expert if default else False
|
|
|
|
|
self.default = default
|
|
|
|
|
|
|
|
|
|
if hasattr(comments, 'string'):
|
|
|
|
|
comments = comments.string
|
|
|
|
|
else:
|
|
|
|
|
comments = None
|
|
|
|
|
|
|
|
|
|
self.grid = qt.QGridLayout(self)
|
|
|
|
|
self.grid.setContentsMargins(0,0,0,0)
|
|
|
|
|
self.grid.setSpacing(4)
|
|
|
|
|
self.grid.setAlignment(qt.Qt.AlignTop | qt.Qt.AlignLeft)
|
|
|
|
|
|
|
|
|
|
buttons_layout = qt.QHBoxLayout()
|
|
|
|
|
buttons_layout.setAlignment(qt.Qt.AlignLeft)
|
|
|
|
|
buttons_layout.setContentsMargins(0,0,0,0)
|
|
|
|
|
if add_ability:
|
|
|
|
|
self.plus_but = qt.QPushButton(self)
|
|
|
|
|
self.plus_but.setFocusPolicy(qt.Qt.NoFocus)
|
|
|
|
|
self.plus_but.setFixedSize(30, 30)
|
|
|
|
|
icon = get_icon('list-add')
|
|
|
|
|
if not icon.isNull():
|
|
|
|
|
self.plus_but.setIcon(icon)
|
|
|
|
|
else:
|
|
|
|
|
self.plus_but.setText('+')
|
|
|
|
|
self.plus_but.setToolTip(_('Add a row'))
|
|
|
|
|
self.plus_but.clicked.connect(self.line_add)
|
|
|
|
|
self.plus_but.setDisabled(True)
|
|
|
|
|
buttons_layout.addWidget(self.plus_but)
|
|
|
|
|
|
|
|
|
|
self.recover_but = qt.QPushButton(self)
|
|
|
|
|
self.recover_but.setFocusPolicy(qt.Qt.NoFocus)
|
|
|
|
|
self.recover_but.setFixedSize(30, 30)
|
|
|
|
|
icon = get_icon('edit-undo')
|
|
|
|
|
if not icon.isNull():
|
|
|
|
|
self.recover_but.setIcon(icon)
|
|
|
|
|
else:
|
|
|
|
|
self.recover_but.setText('R')
|
|
|
|
|
|
|
|
|
|
self.recover_but.setToolTip(_('Reset'))
|
|
|
|
|
self.recover_but.clicked.connect(self.recover_list)
|
|
|
|
|
if default:
|
|
|
|
|
self.recover_but.setDisabled(True)
|
|
|
|
|
|
|
|
|
|
buttons_layout.addWidget(self.recover_but)
|
|
|
|
|
self.grid.addLayout(buttons_layout, 0, 0)
|
|
|
|
|
|
|
|
|
|
self.row_count = len(Available_list)
|
|
|
|
|
for num in range(self.row_count):
|
|
|
|
|
try:
|
|
|
|
|
if not comments:
|
|
|
|
|
comment = Available_list[num]
|
|
|
|
|
else:
|
|
|
|
|
comment = comments[num]
|
|
|
|
|
if not comment:
|
|
|
|
|
comment = Available_list[num]
|
|
|
|
|
except IndexError:
|
|
|
|
|
comment = Available_list[num]
|
|
|
|
|
self.items_dict[comment] = Available_list[num]
|
|
|
|
|
self.comments.append(comment)
|
|
|
|
|
|
|
|
|
|
self.CheckBoxList = []
|
|
|
|
|
for row in range(self.row_count):
|
|
|
|
|
item = qt.QCheckBox(self.comments[row])
|
|
|
|
|
item.setFocusPolicy(qt.Qt.NoFocus)
|
|
|
|
|
item.setStyleSheet("QCheckBox {margin: 2px;}"
|
|
|
|
|
"QCheckBox:hover { margin: 2px;"
|
|
|
|
|
"background-color: transparent;}")
|
|
|
|
|
if self.expert:
|
|
|
|
|
item.setTristate(True)
|
|
|
|
|
if self.expert and self.default:
|
|
|
|
|
item.setCheckState(qt.Qt.PartiallyChecked)
|
|
|
|
|
|
|
|
|
|
item.clicked.connect(self.selected_row)
|
|
|
|
|
self.grid.addWidget(item, row + 1, 0, 1, 3)
|
|
|
|
|
if not self.expert or not self.default:
|
|
|
|
|
if self.items_dict[self.comments[row]] in self.Selected:
|
|
|
|
|
item.setChecked(True)
|
|
|
|
|
if not self.set_auto:
|
|
|
|
|
item.setTristate(False)
|
|
|
|
|
self.CheckBoxList.append(item)
|
|
|
|
|
self.resize(self.sizeHint())
|
|
|
|
|
self.setStyleSheet("QGroupBox {"
|
|
|
|
|
'padding-top: 8px; padding-bottom: 0px;'
|
|
|
|
|
'padding-left: 5px; padding-right: 5px;'
|
|
|
|
|
'border: 1px solid gray;'
|
|
|
|
|
'border-left-color: qlineargradient( x1: 0, y1: 0, x2: 0, y2: 1,'
|
|
|
|
|
'stop: 0 gray, stop: 1 transparent);'
|
|
|
|
|
'border-top-color: qlineargradient( x1: 0, y1: 0, x2: 1, y2: 0,'
|
|
|
|
|
'stop: 0 gray, stop: 1 transparent);'
|
|
|
|
|
'border-right: 0px; border-bottom: 0px;'
|
|
|
|
|
'border-top-left-radius: 2px;'
|
|
|
|
|
|
|
|
|
|
'background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1,'
|
|
|
|
|
'stop: 0 rgba(200, 200, 200, 75), stop: 0.5 transparent,'
|
|
|
|
|
'stop: 1 transparent);}'
|
|
|
|
|
|
|
|
|
|
'QGroupBox::title {'
|
|
|
|
|
'background-color: transparent;'
|
|
|
|
|
'subcontrol-position: top center;'
|
|
|
|
|
'margin-top: 6px;}')
|
|
|
|
|
|
|
|
|
|
def selected_row(self):
|
|
|
|
|
self.Changed.emit()
|
|
|
|
|
if hasattr (self, 'plus_but'):
|
|
|
|
|
self.plus_but.setEnabled(True)
|
|
|
|
|
self.recover_but.setEnabled(True)
|
|
|
|
|
if self.set_auto:
|
|
|
|
|
for i in range(self.row_count):
|
|
|
|
|
if self.CheckBoxList[i].checkState() == \
|
|
|
|
|
qt.Qt.PartiallyChecked:
|
|
|
|
|
self.CheckBoxList[i].setChecked(False)
|
|
|
|
|
self.CheckBoxList[i].setTristate(False)
|
|
|
|
|
self.set_auto = False
|
|
|
|
|
|
|
|
|
|
def add_line(self):
|
|
|
|
|
self.Changed.emit()
|
|
|
|
|
if hasattr (self, 'plus_but'):
|
|
|
|
|
self.plus_but.setEnabled(True)
|
|
|
|
|
self.recover_but.setEnabled(True)
|
|
|
|
|
if self.set_auto:
|
|
|
|
|
for i in range(self.row_count):
|
|
|
|
|
self.CheckBoxList[i].setTristate(False)
|
|
|
|
|
self.CheckBoxList[i].setChecked(False)
|
|
|
|
|
self.set_auto = False
|
|
|
|
|
text = self.addLineWgt.add_line.text()
|
|
|
|
|
self.addLineWgt.close()
|
|
|
|
|
|
|
|
|
|
item = qt.QCheckBox(text)
|
|
|
|
|
item.setFocusPolicy(qt.Qt.NoFocus)
|
|
|
|
|
item.setStyleSheet("QCheckBox {margin: 2px;}"
|
|
|
|
|
"QCheckBox:hover { margin: 2px;"
|
|
|
|
|
"background-color: transparent;}")
|
|
|
|
|
self.CheckBoxList.append(item)
|
|
|
|
|
self.grid.addWidget(item, self.row_count + 1, 0, 1, 3)
|
|
|
|
|
self.row_count += 1
|
|
|
|
|
item.clicked.connect(self.selected_row)
|
|
|
|
|
|
|
|
|
|
def line_add(self):
|
|
|
|
|
self.addLineWgt = AddLineWidget(self, _('Add a row'))
|
|
|
|
|
|
|
|
|
|
def recover_list(self):
|
|
|
|
|
if hasattr (self, 'plus_but'):
|
|
|
|
|
self.plus_but.setDisabled(True)
|
|
|
|
|
self.recover_but.setDisabled(True)
|
|
|
|
|
for i in range(len(self.CheckBoxList)):
|
|
|
|
|
item = self.CheckBoxList.pop()
|
|
|
|
|
item.hide()
|
|
|
|
|
self.grid.removeWidget(item)
|
|
|
|
|
del item
|
|
|
|
|
|
|
|
|
|
hard_auto = False
|
|
|
|
|
if self.expert:
|
|
|
|
|
self.set_auto = True
|
|
|
|
|
hard_auto = True
|
|
|
|
|
|
|
|
|
|
self.CheckBoxList = []
|
|
|
|
|
self.row_count = len(self.Available_list)
|
|
|
|
|
for row in range(self.row_count):
|
|
|
|
|
item = qt.QCheckBox(self.comments[row])
|
|
|
|
|
item.setStyleSheet("QCheckBox {margin: 2px;}"
|
|
|
|
|
"QCheckBox:hover {margin: 2px;"
|
|
|
|
|
"background-color: transparent;}")
|
|
|
|
|
if self.expert:
|
|
|
|
|
item.setTristate(True)
|
|
|
|
|
if self.expert and self.default:
|
|
|
|
|
item.setCheckState(qt.Qt.PartiallyChecked)
|
|
|
|
|
if hard_auto:
|
|
|
|
|
item.setCheckState(qt.Qt.PartiallyChecked)
|
|
|
|
|
|
|
|
|
|
item.clicked.connect(self.selected_row)
|
|
|
|
|
self.grid.addWidget(item, row + 1, 0, 1, 3)
|
|
|
|
|
if not self.expert or not self.default:
|
|
|
|
|
if self.items_dict[self.comments[row]] in self.Selected:
|
|
|
|
|
if not hard_auto:
|
|
|
|
|
item.setChecked(True)
|
|
|
|
|
self.CheckBoxList.append(item)
|
|
|
|
|
self.resize(self.sizeHint())
|
|
|
|
|
|
|
|
|
|
def values(self):
|
|
|
|
|
result = []
|
|
|
|
|
for row in range(self.row_count):
|
|
|
|
|
if self.CheckBoxList[row].checkState() == \
|
|
|
|
|
qt.Qt.PartiallyChecked:
|
|
|
|
|
return []
|
|
|
|
|
if self.CheckBoxList[row].checkState() == \
|
|
|
|
|
qt.Qt.Checked:
|
|
|
|
|
value = self.CheckBoxList[row].text()
|
|
|
|
|
if value in self.items_dict.keys():
|
|
|
|
|
result.append(self.items_dict[value])
|
|
|
|
|
else:
|
|
|
|
|
result.append(value)
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
class ExpertWidget (qt.QPushButton):
|
|
|
|
|
# multiple-choice widget displayed in the table
|
|
|
|
|
def __init__(self, label, parent):
|
|
|
|
|
super().__init__()
|
|
|
|
|
self.setStyleSheet('''QPushButton:pressed {border: none;}
|
|
|
|
|
QPushButton::hover {border: none;}''')
|
|
|
|
|
layout = qt.QHBoxLayout(self)
|
|
|
|
|
|
|
|
|
|
layout.setContentsMargins(0,8,0,0)
|
|
|
|
|
layout.setSpacing(5)
|
|
|
|
|
|
|
|
|
|
self.image_lbl = qt.QLabel(self)
|
|
|
|
|
self.images = ['draw-triangle2', 'media-playback-start']
|
|
|
|
|
layout.addWidget(self.image_lbl)
|
|
|
|
|
|
|
|
|
|
self.text_lbl = qt.QLabel(label, self)
|
|
|
|
|
self.setFocusPolicy(qt.Qt.NoFocus)
|
|
|
|
|
layout.addWidget(self.text_lbl)
|
|
|
|
|
layout.setAlignment(qt.Qt.AlignLeft | qt.Qt.AlignVCenter)
|
|
|
|
|
|
|
|
|
|
def set_close(self):
|
|
|
|
|
self.icon = get_icon(*self.images)
|
|
|
|
|
|
|
|
|
|
pm = self.icon.pixmap(16)
|
|
|
|
|
pm = pm.scaled(qt.QSize(16, 16), qt.Qt.KeepAspectRatio, \
|
|
|
|
|
qt.Qt.SmoothTransformation)
|
|
|
|
|
|
|
|
|
|
self.image_lbl.setPixmap(pm)
|
|
|
|
|
self.image_lbl.setAlignment(qt.Qt.AlignLeft)
|
|
|
|
|
|
|
|
|
|
# add transparency
|
|
|
|
|
self.image_lbl.setAttribute(qt.Qt.WA_NoSystemBackground)
|
|
|
|
|
|
|
|
|
|
def set_open(self):
|
|
|
|
|
self.icon = get_icon(*self.images)
|
|
|
|
|
|
|
|
|
|
pm = self.icon.pixmap(16)
|
|
|
|
|
|
|
|
|
|
pm = pm.scaled(qt.QSize(16, 16), qt.Qt.KeepAspectRatio, \
|
|
|
|
|
qt.Qt.SmoothTransformation)
|
|
|
|
|
|
|
|
|
|
pm = pm.transformed(qt.QTransform().rotate(90))
|
|
|
|
|
self.image_lbl.setPixmap(pm)
|
|
|
|
|
self.image_lbl.setAlignment(qt.Qt.AlignCenter)
|
|
|
|
|
|
|
|
|
|
# add transparency
|
|
|
|
|
self.image_lbl.setAttribute(qt.Qt.WA_NoSystemBackground)
|
|
|
|
|
|
|
|
|
|
class FlowLayout(qt.QLayout):
|
|
|
|
|
def __init__(self, parent=None, margin=0, spacing=-1):
|
|
|
|
|
super().__init__(parent)
|
|
|
|
|
self.setSpacing(spacing)
|
|
|
|
|
self.itemList = []
|
|
|
|
|
|
|
|
|
|
def __del__(self):
|
|
|
|
|
item = self.takeAt(0)
|
|
|
|
|
while item:
|
|
|
|
|
item = self.takeAt(0)
|
|
|
|
|
|
|
|
|
|
def addItem(self, item):
|
|
|
|
|
self.itemList.append(item)
|
|
|
|
|
|
|
|
|
|
def count(self):
|
|
|
|
|
return len(self.itemList)
|
|
|
|
|
|
|
|
|
|
def itemAt(self, index):
|
|
|
|
|
if index >= 0 and index < len(self.itemList):
|
|
|
|
|
return self.itemList[index]
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
def takeAt(self, index):
|
|
|
|
|
if index >= 0 and index < len(self.itemList):
|
|
|
|
|
return self.itemList.pop(index)
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
def expandingDirections(self):
|
|
|
|
|
return qt.Qt.Orientations(qt.Qt.Orientation(0))
|
|
|
|
|
|
|
|
|
|
def hasHeightForWidth(self):
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def heightForWidth(self, width):
|
|
|
|
|
height = self.doLayout(qt.QRect(0, 0, width, 0), True)
|
|
|
|
|
return height
|
|
|
|
|
|
|
|
|
|
def setGeometry(self, rect):
|
|
|
|
|
super(FlowLayout, self).setGeometry(rect)
|
|
|
|
|
self.doLayout(rect, False)
|
|
|
|
|
|
|
|
|
|
def sizeHint(self):
|
|
|
|
|
return self.minimumSize()
|
|
|
|
|
|
|
|
|
|
def minimumSize(self):
|
|
|
|
|
size = qt.QSize()
|
|
|
|
|
for item in self.itemList:
|
|
|
|
|
size = size.expandedTo(item.minimumSize())
|
|
|
|
|
return size
|
|
|
|
|
|
|
|
|
|
def doLayout(self, rect, testOnly):
|
|
|
|
|
x = rect.x()
|
|
|
|
|
y = rect.y()
|
|
|
|
|
lineHeight = 0
|
|
|
|
|
|
|
|
|
|
for item in self.itemList:
|
|
|
|
|
wid = item.widget()
|
|
|
|
|
spaceX = self.spacing() + wid.style().layoutSpacing \
|
|
|
|
|
(qt.QSizePolicy.PushButton, \
|
|
|
|
|
qt.QSizePolicy.PushButton, qt.Qt.Horizontal)
|
|
|
|
|
spaceY = self.spacing() + wid.style().layoutSpacing \
|
|
|
|
|
(qt.QSizePolicy.PushButton, \
|
|
|
|
|
qt.QSizePolicy.PushButton, qt.Qt.Vertical)
|
|
|
|
|
nextX = x + item.sizeHint().width() + spaceX
|
|
|
|
|
if nextX - spaceX > rect.right() and lineHeight > 0:
|
|
|
|
|
x = rect.x()
|
|
|
|
|
y = y + lineHeight + spaceY
|
|
|
|
|
nextX = x + item.sizeHint().width() + spaceX
|
|
|
|
|
lineHeight = 0
|
|
|
|
|
|
|
|
|
|
if not testOnly:
|
|
|
|
|
item.setGeometry(qt.QRect(qt.QPoint(x, y), \
|
|
|
|
|
item.sizeHint()))
|
|
|
|
|
|
|
|
|
|
x = nextX
|
|
|
|
|
lineHeight = max(lineHeight, item.sizeHint().height())
|
|
|
|
|
return y + lineHeight - rect.y()
|
|
|
|
|
|
|
|
|
|
class PlusRow (qt.QWidget):
|
|
|
|
|
""" Widget opens a dialog multiple select """
|
|
|
|
|
def __init__(self, parent, table, field, changed = False, num_row = None):
|
|
|
|
|
super().__init__()
|
|
|
|
|
self.grid = qt.QGridLayout(self)
|
|
|
|
|
self.grid.setContentsMargins(24,8,24,8)
|
|
|
|
|
self.grid.setSpacing(6)
|
|
|
|
|
self.field = field
|
|
|
|
|
self.table = table
|
|
|
|
|
self._parent = parent
|
|
|
|
|
self.changed = changed
|
|
|
|
|
self.num_row = num_row
|
|
|
|
|
x = 0
|
|
|
|
|
y = 0
|
|
|
|
|
self.widget_dict = {}
|
|
|
|
|
if hasattr(field,"label"):
|
|
|
|
|
self.setWindowTitle(field.label or field.name)
|
|
|
|
|
|
|
|
|
|
for i in range (len(field.tablevalue.values.ChoiceValue)):
|
|
|
|
|
col = i+1
|
|
|
|
|
element = field.tablevalue.values.ChoiceValue[i].typefield
|
|
|
|
|
name = field.tablevalue.head.string[i]
|
|
|
|
|
# add element in frame
|
|
|
|
|
if element == 'input':
|
|
|
|
|
#add label
|
|
|
|
|
lbl = qt.QLabel(name, self)
|
|
|
|
|
lbl.setAlignment(qt.Qt.AlignRight| qt.Qt.AlignVCenter)
|
|
|
|
|
self.grid.addWidget(lbl, x, y)
|
|
|
|
|
|
|
|
|
|
self.widget_dict[str(i)] = qt.QLineEdit(self)
|
|
|
|
|
if field.value:
|
|
|
|
|
self.widget_dict[str(i)].setText(field.value)
|
|
|
|
|
if field.type == 'int':
|
|
|
|
|
self.rx = qt.QRegExp ("^[\d]{1,50}$")
|
|
|
|
|
self.validator = qt.QRegExpValidator(self.rx, self)
|
|
|
|
|
self.widget_dict[str(i)].setValidator(self.validator)
|
|
|
|
|
elif field.type == 'float':
|
|
|
|
|
self.rx = qt.QRegExp ("^[\d]{1,50}[.][\d]{1,50}$")
|
|
|
|
|
self.validator = qt.QRegExpValidator(self.rx, self)
|
|
|
|
|
self.widget_dict[str(i)].setValidator(self.validator)
|
|
|
|
|
if changed:
|
|
|
|
|
text = self.table.item(num_row, col).text()
|
|
|
|
|
self.widget_dict[str(i)].setText(text)
|
|
|
|
|
self.grid.addWidget(self.widget_dict[str(i)], x, y+1)
|
|
|
|
|
x += 1
|
|
|
|
|
|
|
|
|
|
elif element in ['check', 'check_tristate']:
|
|
|
|
|
lbl = qt.QLabel(name, self)
|
|
|
|
|
lbl.setAlignment(qt.Qt.AlignRight| qt.Qt.AlignVCenter)
|
|
|
|
|
self.grid.addWidget(lbl, x, y)
|
|
|
|
|
if element == 'check_tristate':
|
|
|
|
|
self.widget_dict[str(i)] = CentralCheckBox(self, True)
|
|
|
|
|
else:
|
|
|
|
|
self.widget_dict[str(i)] = CentralCheckBox(self, False)
|
|
|
|
|
if changed:
|
|
|
|
|
text = self.table.item(num_row, col).data(1)
|
|
|
|
|
self.widget_dict[str(i)].setState(text)
|
|
|
|
|
|
|
|
|
|
self.grid.addWidget(self.widget_dict[str(i)], x, y+1, \
|
|
|
|
|
qt.Qt.AlignLeft)
|
|
|
|
|
x += 1
|
|
|
|
|
|
|
|
|
|
elif element == 'combo':
|
|
|
|
|
ChoiceValue = field.tablevalue.values.ChoiceValue[i]
|
|
|
|
|
if ChoiceValue.comments and \
|
|
|
|
|
hasattr (ChoiceValue.comments, 'string'):
|
|
|
|
|
choice = ChoiceValue.comments.string
|
|
|
|
|
values = ChoiceValue.values.string
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
if ChoiceValue.values and \
|
|
|
|
|
hasattr (ChoiceValue.values, 'string'):
|
|
|
|
|
choice = ChoiceValue.values.string
|
|
|
|
|
else:
|
|
|
|
|
choice = []
|
|
|
|
|
values = choice
|
|
|
|
|
|
|
|
|
|
#add label
|
|
|
|
|
lbl = qt.QLabel(name, self)
|
|
|
|
|
lbl.setAlignment(qt.Qt.AlignRight| qt.Qt.AlignVCenter)
|
|
|
|
|
self.grid.addWidget(lbl, x, y)
|
|
|
|
|
self.ComboBox = qt.QComboBox(self)
|
|
|
|
|
text = ''
|
|
|
|
|
if changed:
|
|
|
|
|
text = self.table.item(num_row, col).text()
|
|
|
|
|
if text in choice:
|
|
|
|
|
ind = choice.index(text)
|
|
|
|
|
text = values[ind]
|
|
|
|
|
for ch in range(len(values)):
|
|
|
|
|
if len(choice) > ch:
|
|
|
|
|
if choice[ch]:
|
|
|
|
|
self.ComboBox.addItem(choice[ch])
|
|
|
|
|
else:
|
|
|
|
|
self.ComboBox.addItem(values[ch])
|
|
|
|
|
else:
|
|
|
|
|
self.ComboBox.addItem(values[ch])
|
|
|
|
|
self.ComboBox.setItemData(ch, values[ch])
|
|
|
|
|
if text and text == values[ch]:
|
|
|
|
|
self.ComboBox.setCurrentIndex(self.ComboBox.count()-1)
|
|
|
|
|
|
|
|
|
|
self.widget_dict[str(i)] = self.ComboBox
|
|
|
|
|
self.grid.addWidget(self.widget_dict[str(i)], x, y+1)
|
|
|
|
|
x += 1
|
|
|
|
|
|
|
|
|
|
elif element == 'comboEdit':
|
|
|
|
|
ChoiceValue = field.tablevalue.values.ChoiceValue[i]
|
|
|
|
|
if ChoiceValue.comments and \
|
|
|
|
|
hasattr (ChoiceValue.comments, 'string'):
|
|
|
|
|
choice = ChoiceValue.comments.string
|
|
|
|
|
values = ChoiceValue.values.string
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
if ChoiceValue.values and \
|
|
|
|
|
hasattr (ChoiceValue.values, 'string'):
|
|
|
|
|
choice = ChoiceValue.values.string
|
|
|
|
|
else:
|
|
|
|
|
choice = []
|
|
|
|
|
values = choice
|
|
|
|
|
|
|
|
|
|
#add label
|
|
|
|
|
lbl = qt.QLabel(name, self)
|
|
|
|
|
lbl.setAlignment(qt.Qt.AlignRight| qt.Qt.AlignVCenter)
|
|
|
|
|
self.grid.addWidget(lbl, x, y)
|
|
|
|
|
self.ComboBox = qt.QComboBox(self)
|
|
|
|
|
self.ComboBox.setDuplicatesEnabled(False)
|
|
|
|
|
self.ComboBox.setEditable(True)
|
|
|
|
|
le = qt.QLineEdit(self)
|
|
|
|
|
# le.setStyleSheet('QLineEdit {background:white;margin: 1px;}')
|
|
|
|
|
self.ComboBox.setLineEdit(le)
|
|
|
|
|
text = None
|
|
|
|
|
if changed:
|
|
|
|
|
text = self.table.item(num_row, col).text()
|
|
|
|
|
for ch in range(len(values)):
|
|
|
|
|
if len(choice) > ch:
|
|
|
|
|
if choice[ch]:
|
|
|
|
|
self.ComboBox.addItem(choice[ch])
|
|
|
|
|
else:
|
|
|
|
|
self.ComboBox.addItem(values[ch])
|
|
|
|
|
else:
|
|
|
|
|
self.ComboBox.addItem(values[ch])
|
|
|
|
|
self.ComboBox.setItemData(ch, values[ch])
|
|
|
|
|
if text and text == values[ch]:
|
|
|
|
|
self.ComboBox.setCurrentIndex(self.ComboBox.count()-1)
|
|
|
|
|
|
|
|
|
|
if not text in values and text != None:
|
|
|
|
|
self.ComboBox.addItem(text)
|
|
|
|
|
self.ComboBox.setItemData(self.ComboBox.count(), text)
|
|
|
|
|
self.ComboBox.setCurrentIndex(self.ComboBox.count()-1)
|
|
|
|
|
|
|
|
|
|
self.widget_dict[str(i)] = self.ComboBox
|
|
|
|
|
|
|
|
|
|
self.grid.addWidget(self.widget_dict[str(i)], x, y+1)
|
|
|
|
|
x += 1
|
|
|
|
|
|
|
|
|
|
elif element in ['multichoice', 'multichoice_add']:
|
|
|
|
|
if field.element == 'multichoice_add':
|
|
|
|
|
add_ability = True
|
|
|
|
|
else:
|
|
|
|
|
add_ability = False
|
|
|
|
|
choice = field.tablevalue.values.ChoiceValue[i].values.string
|
|
|
|
|
comments = field.tablevalue.values.ChoiceValue[i].comments
|
|
|
|
|
default = []
|
|
|
|
|
if changed:
|
|
|
|
|
text = self.table.item(num_row, col).text()
|
|
|
|
|
default = text.split(',')
|
|
|
|
|
def_res = []
|
|
|
|
|
|
|
|
|
|
if comments and hasattr (comments, 'string'):
|
|
|
|
|
comm = comments.string
|
|
|
|
|
else: comm = []
|
|
|
|
|
for item in default:
|
|
|
|
|
if item in comm:
|
|
|
|
|
ind = comm.index(item)
|
|
|
|
|
def_res.append(choice[ind])
|
|
|
|
|
else: def_res.append(item)
|
|
|
|
|
|
|
|
|
|
self.widget_dict[str(i)] = \
|
|
|
|
|
MultipleChoice(self, choice, def_res, comments, add_ability)
|
|
|
|
|
#add label
|
|
|
|
|
lbl = qt.QLabel(name, self)
|
|
|
|
|
lbl.setAlignment(qt.Qt.AlignRight| qt.Qt.AlignVCenter)
|
|
|
|
|
self.grid.addWidget(lbl, x, y)
|
|
|
|
|
self.grid.addWidget(self.widget_dict[str(i)], x, y+1)
|
|
|
|
|
x += 1
|
|
|
|
|
|
|
|
|
|
elif element == 'password':
|
|
|
|
|
if not name or name.lower() == 'password':
|
|
|
|
|
name = _('Password')
|
|
|
|
|
lbl1 = LabelWordWrap(name, self)
|
|
|
|
|
lbl1.setAlignment(qt.Qt.AlignRight| qt.Qt.AlignVCenter)
|
|
|
|
|
lbl2 = LabelWordWrap(_('Repeat'), self)
|
|
|
|
|
lbl2.setAlignment(qt.Qt.AlignRight| qt.Qt.AlignVCenter)
|
|
|
|
|
|
|
|
|
|
layout = qt.QVBoxLayout()
|
|
|
|
|
layout.setContentsMargins(0,0,0,0)
|
|
|
|
|
layout.setSpacing(0)
|
|
|
|
|
|
|
|
|
|
layout.addWidget(lbl1)
|
|
|
|
|
layout.addWidget(lbl2)
|
|
|
|
|
|
|
|
|
|
self.grid.addLayout(layout, x, y, 2, 1)
|
|
|
|
|
|
|
|
|
|
self.widget_dict[str(i)] = SimplePasswordWidget \
|
|
|
|
|
(self, lbl1, lbl2)
|
|
|
|
|
self.grid.addWidget(self.widget_dict[str(i)], x, y+1, 2, 1)
|
|
|
|
|
x += 2
|
|
|
|
|
|
|
|
|
|
elif element == 'readonly' and field.type == 'writable':
|
|
|
|
|
self.widget_dict[str(i)] = ''
|
|
|
|
|
if '0' not in self.widget_dict:
|
|
|
|
|
continue
|
|
|
|
|
index_widget = self.widget_dict['0']
|
|
|
|
|
|
|
|
|
|
ChoiceValue = field.tablevalue.values.ChoiceValue[i]
|
|
|
|
|
values = ChoiceValue.values.string
|
|
|
|
|
comments = ChoiceValue.comments.string
|
|
|
|
|
index_comment = []
|
|
|
|
|
index_values = []
|
|
|
|
|
if hasattr (field.tablevalue.values.ChoiceValue[0].comments, \
|
|
|
|
|
'string') and hasattr (field.tablevalue. \
|
|
|
|
|
values.ChoiceValue[0].values, 'string'):
|
|
|
|
|
index_comment = field.tablevalue.values.ChoiceValue[0].\
|
|
|
|
|
comments.string
|
|
|
|
|
index_values = field.tablevalue.values.ChoiceValue[0].\
|
|
|
|
|
values.string
|
|
|
|
|
|
|
|
|
|
find_flag = False
|
|
|
|
|
text = self.widget_dict['0'].currentText()
|
|
|
|
|
if text in index_comment:
|
|
|
|
|
com_ind = index_comment.index(text)
|
|
|
|
|
val = index_values[com_ind]
|
|
|
|
|
if val in values:
|
|
|
|
|
find_flag = True
|
|
|
|
|
val_ind = values.index(val)
|
|
|
|
|
self.widget_dict[str(i)] = str(comments[val_ind])
|
|
|
|
|
if text in values:
|
|
|
|
|
find_flag = True
|
|
|
|
|
ind = values.index(text)
|
|
|
|
|
self.widget_dict[str(i)] = str(comments[ind])
|
|
|
|
|
|
|
|
|
|
if not find_flag:
|
|
|
|
|
self.widget_dict[str(i)] = ''
|
|
|
|
|
|
|
|
|
|
if type(index_widget) in [qt.QComboBox]:
|
|
|
|
|
index_widget.editTextChanged.connect(self.change_readonly \
|
|
|
|
|
(i, values, comments, index_comment, index_values))
|
|
|
|
|
if type(index_widget) in [qt.QLineEdit]:
|
|
|
|
|
index_widget.textChanged.connect(self.change_readonly \
|
|
|
|
|
(i, values, comments, index_comment, index_values))
|
|
|
|
|
|
|
|
|
|
# add OK button
|
|
|
|
|
self.button_layout = qt.QHBoxLayout()
|
|
|
|
|
self.Ok_Button = qt.QPushButton('Ok', self)
|
|
|
|
|
self.Ok_Button.setFixedWidth(128)
|
|
|
|
|
self.Ok_Button.setShortcut(qt.QKeySequence(qt.Qt.Key_Return))
|
|
|
|
|
self.Ok_Button.clicked.connect(self.ok_pressed)
|
|
|
|
|
self.button_layout.addWidget(self.Ok_Button)
|
|
|
|
|
|
|
|
|
|
# add Cancel button
|
|
|
|
|
self.Cancel_Button = qt.QPushButton('Cancel', self)
|
|
|
|
|
self.Cancel_Button.setFixedWidth(128)
|
|
|
|
|
self.Ok_Button.setShortcut(qt.QKeySequence(qt.Qt.Key_Escape))
|
|
|
|
|
self.Cancel_Button.clicked.connect(self.close)
|
|
|
|
|
self.button_layout.addWidget(self.Cancel_Button)
|
|
|
|
|
self.button_layout.setAlignment(qt.Qt.AlignRight)
|
|
|
|
|
self.grid.addLayout(self.button_layout,x,y,1,2,qt.Qt.AlignRight)
|
|
|
|
|
|
|
|
|
|
self.grid.setColumnStretch(0,0)
|
|
|
|
|
self.grid.setColumnStretch(1,5)
|
|
|
|
|
|
|
|
|
|
self.resize(self.sizeHint().width(), self.sizeHint().height())
|
|
|
|
|
self.setFixedHeight(self.sizeHint().height())
|
|
|
|
|
|
|
|
|
|
move_x = parent.window().x() + parent.window().width() - \
|
|
|
|
|
parent.width() + parent.width()/2 - self.size().width()/2
|
|
|
|
|
|
|
|
|
|
self.move(move_x, parent.window().y() + parent.window().height()/2 - \
|
|
|
|
|
self.size().height()/2)
|
|
|
|
|
|
|
|
|
|
def change_readonly(self, i, values, comments, index_comment,index_values):
|
|
|
|
|
def wrapper(index):
|
|
|
|
|
find_flag = False
|
|
|
|
|
text = self.widget_dict['0'].currentText()
|
|
|
|
|
if text in index_comment:
|
|
|
|
|
com_ind = index_comment.index(text)
|
|
|
|
|
val = index_values[com_ind]
|
|
|
|
|
if val in values:
|
|
|
|
|
find_flag = True
|
|
|
|
|
val_ind = values.index(val)
|
|
|
|
|
self.widget_dict[str(i)] = str(comments[val_ind])
|
|
|
|
|
if text in values:
|
|
|
|
|
find_flag = True
|
|
|
|
|
ind = values.index(text)
|
|
|
|
|
self.widget_dict[str(i)] = str(comments[ind])
|
|
|
|
|
if not find_flag:
|
|
|
|
|
self.widget_dict[str(i)] = ''
|
|
|
|
|
return wrapper
|
|
|
|
|
|
|
|
|
|
def ok_pressed(self):
|
|
|
|
|
items = filter(lambda x: type(self.widget_dict[str(x)]) == \
|
|
|
|
|
SimplePasswordWidget, self.widget_dict.keys())
|
|
|
|
|
if filter(lambda x: not self.widget_dict[str(x)].status(), items):
|
|
|
|
|
return 1
|
|
|
|
|
|
|
|
|
|
if self.changed:
|
|
|
|
|
row = self.num_row
|
|
|
|
|
else:
|
|
|
|
|
row = self.table.rowCount()
|
|
|
|
|
self.table.setRowCount(row + 1)
|
|
|
|
|
# add widgets in table
|
|
|
|
|
for i in range (len(self.field.tablevalue.values.ChoiceValue)):
|
|
|
|
|
col = i + 1
|
|
|
|
|
val = ''
|
|
|
|
|
if str(i) not in self.widget_dict:
|
|
|
|
|
continue
|
|
|
|
|
if type(self.widget_dict[str(i)]) == CentralCheckBox:
|
|
|
|
|
state = self.widget_dict[str(i)].getState()
|
|
|
|
|
if state == 'on':
|
|
|
|
|
val = _('Yes')
|
|
|
|
|
elif state == 'off':
|
|
|
|
|
val = _('No')
|
|
|
|
|
elif not state:
|
|
|
|
|
val = _('Auto')
|
|
|
|
|
|
|
|
|
|
elif type(self.widget_dict[str(i)]) == qt.QComboBox:
|
|
|
|
|
val = self.widget_dict[str(i)].currentText()
|
|
|
|
|
|
|
|
|
|
elif type(self.widget_dict[str(i)]) == str:
|
|
|
|
|
if self.widget_dict[str(i)]:
|
|
|
|
|
val = self.widget_dict[str(i)]
|
|
|
|
|
|
|
|
|
|
elif type(self.widget_dict[str(i)]) in [MultipleChoice,
|
|
|
|
|
qt.QLineEdit]:
|
|
|
|
|
val = self.widget_dict[str(i)].text()
|
|
|
|
|
|
|
|
|
|
elif type(self.widget_dict[str(i)]) == SimplePasswordWidget:
|
|
|
|
|
if self.widget_dict[str(i)].status():
|
|
|
|
|
passwd = self.widget_dict[str(i)].get_password()
|
|
|
|
|
val = '***' if passwd else ''
|
|
|
|
|
else:
|
|
|
|
|
return 1
|
|
|
|
|
|
|
|
|
|
tablewidgetitem = qt.QTableWidgetItem(val)
|
|
|
|
|
if type(self.widget_dict[str(i)]) == CentralCheckBox:
|
|
|
|
|
tablewidgetitem.setData(1, self.widget_dict[str(i)].getState())
|
|
|
|
|
if type(self.widget_dict[str(i)]) == SimplePasswordWidget:
|
|
|
|
|
tablewidgetitem.setData(1, passwd)
|
|
|
|
|
self.table.setItem(row, col, tablewidgetitem)
|
|
|
|
|
|
|
|
|
|
self.table.item(row, col).setFlags(qt.Qt.ItemIsEditable)
|
|
|
|
|
brush = qt.QBrush(
|
|
|
|
|
self.palette().color(qt.QPalette.Text))
|
|
|
|
|
self.table.item(row, col).setForeground(brush)
|
|
|
|
|
|
|
|
|
|
# adding in table 'readonly' values
|
|
|
|
|
diff = self.table.columnCount() - \
|
|
|
|
|
len(self.field.tablevalue.values.ChoiceValue) - 1
|
|
|
|
|
for j in range (diff):
|
|
|
|
|
column = len(self.field.tablevalue.values.ChoiceValue) + j + 1
|
|
|
|
|
tablewidgetitem = qt.QTableWidgetItem()
|
|
|
|
|
self.table.setItem(row, column, tablewidgetitem)
|
|
|
|
|
|
|
|
|
|
self.table.item(row, column).setFlags(qt.Qt.ItemIsEditable)
|
|
|
|
|
font = self.table.item(row, column).font()
|
|
|
|
|
font.setWeight(qt.QFont.Black)
|
|
|
|
|
self.table.item(row, column).setFont(font)
|
|
|
|
|
|
|
|
|
|
if self.field.type == 'writable':
|
|
|
|
|
self._parent.add_select_check(self.table)
|
|
|
|
|
|
|
|
|
|
# Resize table
|
|
|
|
|
if self.table.bFixedHeight:
|
|
|
|
|
h = self.table.horizontalHeader().height() + \
|
|
|
|
|
2 * self.table.frameWidth()
|
|
|
|
|
h += self.table.horizontalScrollBar().height()
|
|
|
|
|
for row_in_table in range (self.table.rowCount()):
|
|
|
|
|
h += self.table.rowHeight(row_in_table)
|
|
|
|
|
self.table.setFixedHeight(h)
|
|
|
|
|
|
|
|
|
|
if self.table.rowCount() == 1:
|
|
|
|
|
self.table.horizontalHeader().resizeSections(
|
|
|
|
|
qt.QHeaderView.ResizeToContents)
|
|
|
|
|
self.table.setColor()
|
|
|
|
|
self.close()
|
|
|
|
|
|
|
|
|
|
class PasswordWgt(qt.QWidget):
|
|
|
|
|
# answer to the server question
|
|
|
|
|
def __init__(self, parent, text):
|
|
|
|
|
super().__init__()
|
|
|
|
|
self._parent = parent
|
|
|
|
|
self.text = text
|
|
|
|
|
if parent.label:
|
|
|
|
|
self.setWindowTitle(parent.label)
|
|
|
|
|
|
|
|
|
|
self.layout = qt.QGridLayout(self)
|
|
|
|
|
|
|
|
|
|
self.pass_edit = qt.QLineEdit(self)
|
|
|
|
|
self.pass_edit.setEchoMode(self.pass_edit.Password)
|
|
|
|
|
|
|
|
|
|
self.layout.addWidget(LabelWordWrap(_('Password')),0,0)
|
|
|
|
|
self.layout.addWidget(self.pass_edit,0,1)
|
|
|
|
|
|
|
|
|
|
self.pass_edit2 = qt.QLineEdit(self)
|
|
|
|
|
self.pass_edit2.setEchoMode(self.pass_edit2.Password)
|
|
|
|
|
|
|
|
|
|
if self.text:
|
|
|
|
|
self.pass_edit.setText('***')
|
|
|
|
|
self.pass_edit2.setText('***')
|
|
|
|
|
|
|
|
|
|
self.layout.addWidget(LabelWordWrap(_('Repeat'), self), 1, 0)
|
|
|
|
|
self.layout.addWidget(self.pass_edit2, 1, 1)
|
|
|
|
|
self.pass_edit.textChanged.connect(self.check_passwd)
|
|
|
|
|
self.pass_edit2.textChanged.connect(self.check_passwd)
|
|
|
|
|
|
|
|
|
|
self.ok_button = qt.QPushButton(_('Ok'), self)
|
|
|
|
|
self.ok_button.setShortcut(qt.QKeySequence(qt.Qt.Key_Return))
|
|
|
|
|
self.ok_button.clicked.connect(self.send_password)
|
|
|
|
|
self.ok_button.setDisabled(True)
|
|
|
|
|
self.layout.addWidget(self.ok_button,2,0)
|
|
|
|
|
|
|
|
|
|
self.cancel_button = qt.QPushButton(_('Cancel'), self)
|
|
|
|
|
self.cancel_button.setShortcut(qt.QKeySequence \
|
|
|
|
|
(qt.Qt.Key_Escape))
|
|
|
|
|
self.cancel_button.clicked.connect(self.close)
|
|
|
|
|
self.layout.addWidget(self.cancel_button,2,1)
|
|
|
|
|
self.resize(self.sizeHint() + qt.QSize(40,0))
|
|
|
|
|
self.setFixedHeight(self.sizeHint().height())
|
|
|
|
|
self.move(qt.QCursor.pos())
|
|
|
|
|
|
|
|
|
|
def send_password(self):
|
|
|
|
|
password = self.pass_edit.text()
|
|
|
|
|
if password == self.pass_edit2.text() and password != '***':
|
|
|
|
|
self.text = password
|
|
|
|
|
self._parent.set_text(password)
|
|
|
|
|
self.close()
|
|
|
|
|
else:
|
|
|
|
|
self.ok_button.setDisabled(True)
|
|
|
|
|
|
|
|
|
|
def check_passwd(self):
|
|
|
|
|
if self.pass_edit.text() != self.pass_edit2.text():
|
|
|
|
|
self.ok_button.setDisabled(True)
|
|
|
|
|
else:
|
|
|
|
|
self.ok_button.setEnabled(True)
|
|
|
|
|
|
|
|
|
|
class PasswordWidget(qt.QLineEdit):
|
|
|
|
|
def __init__(self, parent, text = '', label = ''):
|
|
|
|
|
super().__init__()
|
|
|
|
|
self.text = text
|
|
|
|
|
self.label = label
|
|
|
|
|
self.setEchoMode(self.Password)
|
|
|
|
|
|
|
|
|
|
self.set_text(text)
|
|
|
|
|
self.setReadOnly(True)
|
|
|
|
|
|
|
|
|
|
def mousePressEvent(self, button = None):
|
|
|
|
|
self.passwgt = PasswordWgt(self, self.text)
|
|
|
|
|
self.passwgt.setWindowModality(qt.Qt.WindowModal)
|
|
|
|
|
self.passwgt.show()
|
|
|
|
|
|
|
|
|
|
def set_text(self, text):
|
|
|
|
|
self.text = text
|
|
|
|
|
if text:
|
|
|
|
|
self.setText('***')
|
|
|
|
|
else:
|
|
|
|
|
self.setText('')
|
|
|
|
|
|
|
|
|
|
def get_text(self):
|
|
|
|
|
if not self.text:
|
|
|
|
|
self.text = ''
|
|
|
|
|
return self.text
|
|
|
|
|
|
|
|
|
|
class SimplePasswordWidget(qt.QWidget):
|
|
|
|
|
def __init__(self, parent, lbl1, lbl2):
|
|
|
|
|
super().__init__()
|
|
|
|
|
self.layout = qt.QVBoxLayout(self)
|
|
|
|
|
self.layout.setContentsMargins(0,0,0,0)
|
|
|
|
|
self.layout.setSpacing(4)
|
|
|
|
|
|
|
|
|
|
self.lbl1 = lbl1
|
|
|
|
|
self.lbl2 = lbl2
|
|
|
|
|
self._status = True
|
|
|
|
|
|
|
|
|
|
self.pass_edit = qt.QLineEdit(self)
|
|
|
|
|
self.pass_edit.setEchoMode(self.pass_edit.Password)
|
|
|
|
|
|
|
|
|
|
self.layout.addWidget(self.pass_edit)
|
|
|
|
|
|
|
|
|
|
self.pass_edit2 = qt.QLineEdit(self)
|
|
|
|
|
self.pass_edit2.setEchoMode(self.pass_edit2.Password)
|
|
|
|
|
|
|
|
|
|
self.layout.addWidget(self.pass_edit2)
|
|
|
|
|
self.pass_edit.textChanged.connect(self.check_passwd)
|
|
|
|
|
self.pass_edit2.textChanged.connect(self.check_passwd)
|
|
|
|
|
|
|
|
|
|
def check_passwd(self):
|
|
|
|
|
if self.pass_edit.text() != self.pass_edit2.text():
|
|
|
|
|
self._status = False
|
|
|
|
|
self.set_error()
|
|
|
|
|
else:
|
|
|
|
|
self._status = True
|
|
|
|
|
self.set_normal()
|
|
|
|
|
|
|
|
|
|
def status(self):
|
|
|
|
|
return self._status
|
|
|
|
|
|
|
|
|
|
def set_error(self):
|
|
|
|
|
self.lbl1.setStyleSheet("QLabel { color : red; }")
|
|
|
|
|
self.lbl2.setStyleSheet("QLabel { color : red; }")
|
|
|
|
|
|
|
|
|
|
def set_normal(self):
|
|
|
|
|
self.lbl1.setStyleSheet("QLabel { color : black; }")
|
|
|
|
|
self.lbl2.setStyleSheet("QLabel { color : black; }")
|
|
|
|
|
|
|
|
|
|
def get_password(self):
|
|
|
|
|
if self.status():
|
|
|
|
|
return self.pass_edit.text()
|
|
|
|
|
else:
|
|
|
|
|
raise Exception
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ResultLayout(qt.QVBoxLayout):
|
|
|
|
|
"""
|
|
|
|
|
Слой с результатами работы задачи
|
|
|
|
|
"""
|
|
|
|
|
def __init__(self, parent):
|
|
|
|
|
super().__init__(parent)
|
|
|
|
|
self.setAlignment(qt.Qt.AlignTop)
|
|
|
|
|
self.setContentsMargins(28, 28, 28, 10)
|
|
|
|
|
self.setSpacing(2)
|
|
|
|
|
self.content = qt.QVBoxLayout()
|
|
|
|
|
self.content.setAlignment(qt.Qt.AlignTop)
|
|
|
|
|
self.addLayout(self.content)
|
|
|
|
|
|
|
|
|
|
self.kill_process_button = self._create_button(_('Break the process'))
|
|
|
|
|
self.kill_process_button.setFixedHeight(dpivalue(32))
|
|
|
|
|
parent._parent.control_button.set_break_button(self.kill_process_button)
|
|
|
|
|
|
|
|
|
|
def _addWidget(self, widget):
|
|
|
|
|
self.content.addWidget(widget)
|
|
|
|
|
|
|
|
|
|
def _create_button(self, label, width=144):
|
|
|
|
|
button = qt.QPushButton(label)
|
|
|
|
|
button.setFixedWidth(dpivalue(width))
|
|
|
|
|
button.setContentsMargins(0, 10, 0, 0)
|
|
|
|
|
button.setFixedHeight(dpivalue(32))
|
|
|
|
|
#button.setMinimumHeight(
|
|
|
|
|
# button.minimumSizeHint().height())
|
|
|
|
|
#button.setMaximumHeight(
|
|
|
|
|
# button.minimumSizeHint().height())
|
|
|
|
|
return button
|
|
|
|
|
|
|
|
|
|
def hide_kill_button(self):
|
|
|
|
|
#self.removeWidget(self.kill_process_button)
|
|
|
|
|
self.kill_process_button.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class LabelTaskWgt(qt.QLabel):
|
|
|
|
|
def __init__(self, name, parent=None):
|
|
|
|
|
super().__init__(name, parent)
|
|
|
|
|
self.setStyleSheet("color: #B3ABA7;")
|
|
|
|
|
|
|
|
|
|
def sizeHint(self):
|
|
|
|
|
self.br_ = qt.QFontMetrics(self.font()).boundingRect('')
|
|
|
|
|
return self.br_.size()
|
|
|
|
|
|
|
|
|
|
def paintEvent(self, e):
|
|
|
|
|
p = qt.QPainter(self)
|
|
|
|
|
fm = p.fontMetrics()
|
|
|
|
|
y = (self.sizeHint().height() - self.br_.height()) / 2 + fm.ascent()
|
|
|
|
|
|
|
|
|
|
dot_w = fm.width('. ')
|
|
|
|
|
for x in range (0, self.width(), dot_w):
|
|
|
|
|
p.drawText(x, y, '. ')
|
|
|
|
|
|
|
|
|
|
class TaskWidget(qt.QWidget):
|
|
|
|
|
console_ok = '/usr/share/icons/Calculate/16x16/client-gui/console_ok'
|
|
|
|
|
console_cancel = ('/usr/share/icons/Calculate/16x16/client-gui/'
|
|
|
|
|
'console_cancel')
|
|
|
|
|
console_skip = "object-select-symbolic"
|
|
|
|
|
|
|
|
|
|
def __init__(self, text='', parent=None, clean_text=None):
|
|
|
|
|
super().__init__(parent)
|
|
|
|
|
self._layout = qt.QHBoxLayout(self)
|
|
|
|
|
|
|
|
|
|
if clean_text is None:
|
|
|
|
|
clean_text = text
|
|
|
|
|
self.text = qt.QLabel(text, self)
|
|
|
|
|
fm = qt.QFontMetrics(self.text.font())
|
|
|
|
|
d_w = fm.width(clean_text)
|
|
|
|
|
pref = qt.QSizePolicy.Preferred
|
|
|
|
|
exp = qt.QSizePolicy.Expanding
|
|
|
|
|
self.text.setSizePolicy(exp, pref)
|
|
|
|
|
self.text.setMinimumHeight(self.text.sizeHint().height())
|
|
|
|
|
self.text.setMinimumWidth(d_w)
|
|
|
|
|
self._layout.addWidget(self.text)
|
|
|
|
|
self._layout.setContentsMargins(0, 0, 0, 0)
|
|
|
|
|
self._layout.setSpacing(8)
|
|
|
|
|
self.status = False
|
|
|
|
|
|
|
|
|
|
def set_status(self, message=None, color=None):
|
|
|
|
|
if not self.status:
|
|
|
|
|
point_lbl = LabelTaskWgt('', self)
|
|
|
|
|
self._layout.addWidget(point_lbl)
|
|
|
|
|
|
|
|
|
|
self.image_lbl = qt.QLabel(self)
|
|
|
|
|
self.image_lbl.setFixedHeight(16)
|
|
|
|
|
self._layout.addWidget(self.image_lbl)
|
|
|
|
|
self._layout.setStretch(1, 5)
|
|
|
|
|
|
|
|
|
|
#self.image_lbl.setPixmap(icon.pixmap(16))
|
|
|
|
|
self.image_lbl.setStyleSheet('color:%s;'%color)
|
|
|
|
|
self.image_lbl.setText("%s"%message.upper())
|
|
|
|
|
self.status = True
|
|
|
|
|
|
|
|
|
|
def set_ok(self):
|
|
|
|
|
self.set_status("ok",color="green")
|
|
|
|
|
|
|
|
|
|
def set_error(self):
|
|
|
|
|
self.set_status("failed", color="red")
|
|
|
|
|
|
|
|
|
|
def set_skip(self):
|
|
|
|
|
self.set_status("skip", color="gold")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ButtonsWidget(qt.QWidget):
|
|
|
|
|
def __init__(self, parent = None):
|
|
|
|
|
super().__init__(parent)
|
|
|
|
|
self.layout = qt.QHBoxLayout(self)
|
|
|
|
|
|
|
|
|
|
self.layout.setContentsMargins(0,0,0,0)
|
|
|
|
|
self.layout.setSpacing(0)
|
|
|
|
|
self.layout.setAlignment(qt.Qt.AlignRight)
|
|
|
|
|
|
|
|
|
|
def add_button(self, button):
|
|
|
|
|
self.layout.addWidget(button)
|
|
|
|
|
|
|
|
|
|
def _print (*args):
|
|
|
|
|
# print(" ".join(map(lambda x:unicode(x).encode('utf-8'),args)))
|
|
|
|
|
print(" ".join(map(lambda x:str(x),args)))
|
|
|
|
|
|
|
|
|
|
def show_msg(text, title = None, parent = None):
|
|
|
|
|
msgBox = qt.QMessageBox(parent)
|
|
|
|
|
#DEBUG: want traceback? force error there.
|
|
|
|
|
# raise Exception
|
|
|
|
|
if title:
|
|
|
|
|
msgBox.setWindowTitle(title)
|
|
|
|
|
else:
|
|
|
|
|
msgBox.setWindowTitle("Calculate Console")
|
|
|
|
|
if not text:
|
|
|
|
|
return 1
|
|
|
|
|
if not type(text) in [str]:
|
|
|
|
|
|
|
|
|
|
if hasattr(text, '__iter__'):
|
|
|
|
|
#print(f'{text} is iterable')
|
|
|
|
|
temp = ''
|
|
|
|
|
for i in text:
|
|
|
|
|
try:
|
|
|
|
|
# temp += str(i).decode('utf-8')+' '
|
|
|
|
|
temp += str(i) + ' '
|
|
|
|
|
except (UnicodeEncodeError, UnicodeDecodeError):
|
|
|
|
|
temp += str(i) + ' '
|
|
|
|
|
text = temp
|
|
|
|
|
else:
|
|
|
|
|
text = str(text)
|
|
|
|
|
msgBox.setText(text)
|
|
|
|
|
msgBox.setStandardButtons(qt.QMessageBox.Ok)
|
|
|
|
|
#TODO this is broken
|
|
|
|
|
msgBox.setWindowIcon(get_icon('calculate-install.svg'))
|
|
|
|
|
msgBox.exec_()
|
|
|
|
|
|
|
|
|
|
def show_question(parent, text, informative_text = None, cursor_pos = False,
|
|
|
|
|
not_move = False, title = None):
|
|
|
|
|
msgBox = qt.QMessageBox()
|
|
|
|
|
msgBox.setText(text)
|
|
|
|
|
msgBox.setInformativeText(informative_text)
|
|
|
|
|
msgBox.setStandardButtons(qt.QMessageBox.Yes | qt.QMessageBox.No)
|
|
|
|
|
msgBox.setDefaultButton(qt.QMessageBox.No)
|
|
|
|
|
if title:
|
|
|
|
|
msgBox.setWindowTitle(title)
|
|
|
|
|
# translate
|
|
|
|
|
msgBox.button(msgBox.Yes).setText(_('Yes'))
|
|
|
|
|
msgBox.button(msgBox.No).setText(_('No'))
|
|
|
|
|
|
|
|
|
|
if not_move:
|
|
|
|
|
reply = msgBox.exec_()
|
|
|
|
|
return reply
|
|
|
|
|
if cursor_pos:
|
|
|
|
|
msgBox.move(qt.QCursor.pos())
|
|
|
|
|
else:
|
|
|
|
|
msgBox.move(parent.frameGeometry().x()+parent.size().width()/2 - 150,\
|
|
|
|
|
parent.frameGeometry().y() + parent.size().height()/2 - 100)
|
|
|
|
|
|
|
|
|
|
reply = msgBox.exec_()
|
|
|
|
|
return reply
|
|
|
|
|
|
|
|
|
|
#def uniq(seq):
|
|
|
|
|
# seen = set()
|
|
|
|
|
# seen_add = seen.add
|
|
|
|
|
# return [ x for x in seq if x not in seen and not seen_add(x)]
|
|
|
|
|
|
|
|
|
|
def uniq(seq):
|
|
|
|
|
seen = set()
|
|
|
|
|
return [ x for x in seq if x not in seen and not seen.add(x)]
|
|
|
|
|
|
|
|
|
|
class VerifyError(Exception):
|
|
|
|
|
def __init__(self, value):
|
|
|
|
|
self.value = value
|
|
|
|
|
def __str__(self):
|
|
|
|
|
return repr(self.value)
|
|
|
|
|
|
|
|
|
|
def client_post_auth(client):
|
|
|
|
|
""" authorization client or post request """
|
|
|
|
|
try:
|
|
|
|
|
if not os.path.exists(client.CERT_FILE):
|
|
|
|
|
show_msg (_('You do not have a certificate. Please generate a '
|
|
|
|
|
'new request and get the new certificate from the server.'))
|
|
|
|
|
return 1
|
|
|
|
|
except VerifyError as e:
|
|
|
|
|
show_msg (e.value)
|
|
|
|
|
return 1
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
class ClientSignal(qt.QThread):
|
|
|
|
|
sid_sig = qt.Signal(int, int)
|
|
|
|
|
connect_count = qt.Signal(str, int, int)
|
|
|
|
|
def __init__(self, ClientObj):
|
|
|
|
|
super().__init__()
|
|
|
|
|
self.ClientObj = ClientObj
|
|
|
|
|
self.connect_count.connect(ClientObj._parent.connect_count_changed)
|
|
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
|
self.exit_flag = False
|
|
|
|
|
self.ClientObj.has_connect = None
|
|
|
|
|
try:
|
|
|
|
|
client_active = self.ClientObj.VarsApi.Get \
|
|
|
|
|
('core.cl_core_client_active_period')
|
|
|
|
|
except:
|
|
|
|
|
show_msg('Write cl_core_client_active_period Error!')
|
|
|
|
|
client_active = 15
|
|
|
|
|
sid = get_sid(self.ClientObj.client)
|
|
|
|
|
client = self.ClientObj.client
|
|
|
|
|
while not self.exit_flag:
|
|
|
|
|
reply = 2
|
|
|
|
|
try:
|
|
|
|
|
reply = client.service.active_client(sid)
|
|
|
|
|
except urllib2.URLError:
|
|
|
|
|
reply = 2
|
|
|
|
|
except Exception as e:
|
|
|
|
|
show_msg (e.message, 'no connection to server!')
|
|
|
|
|
if reply == 0:
|
|
|
|
|
#if not self.ClientObj.has_connect:
|
|
|
|
|
self.connect_count.emit(self.ClientObj.host_name,
|
|
|
|
|
self.ClientObj.port, 1)
|
|
|
|
|
#self.ClientObj.has_connect = 1
|
|
|
|
|
else:
|
|
|
|
|
#if self.ClientObj.has_connect:
|
|
|
|
|
self.connect_count.emit(self.ClientObj.host_name,
|
|
|
|
|
self.ClientObj.port, 0)
|
|
|
|
|
#self.ClientObj.has_connect = 0
|
|
|
|
|
self.sid_sig.emit(sid, reply)
|
|
|
|
|
for i in range (5):
|
|
|
|
|
time.sleep(float(client_active)/15.0)
|
|
|
|
|
if self.exit_flag:
|
|
|
|
|
self.connect_count.emit(self.ClientObj.host_name,
|
|
|
|
|
self.ClientObj.port, 0)
|
|
|
|
|
return
|
|
|
|
|
self.connect_count.emit(self.ClientObj.host_name,self.ClientObj.port,0)
|
|
|
|
|
|
|
|
|
|
def close(self):
|
|
|
|
|
self.exit_flag = True
|
|
|
|
|
|
|
|
|
|
def post_connect_action(client, ClientObj):
|
|
|
|
|
if client_post_auth(client):
|
|
|
|
|
# Exit with closing session
|
|
|
|
|
client_del_sid(ClientObj.client)
|
|
|
|
|
ClientObj.client = None
|
|
|
|
|
|
|
|
|
|
ClientObj.MainWidget.process_dict = {}
|
|
|
|
|
from .ConnectionTabs import SelectedMethodWgt
|
|
|
|
|
if type (ClientObj._parent) == SelectedMethodWgt:
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
return 1
|
|
|
|
|
|
|
|
|
|
ClientObj.signaling = ClientSignal(ClientObj)
|
|
|
|
|
|
|
|
|
|
ClientObj.signaling.sid_sig.connect(ClientObj.MainWidget.signaling_slot)
|
|
|
|
|
ClientObj.signaling.start()
|
|
|
|
|
|
|
|
|
|
ClientObj.sid = get_sid(ClientObj.client)
|
|
|
|
|
# Add Icons in MainMenu
|
|
|
|
|
icon_visible(ClientObj.MainWidget, 'Disconnect', True)
|
|
|
|
|
icon_visible(ClientObj.MainWidget, 'Processes', True)
|
|
|
|
|
icon_visible(ClientObj.MainWidget, 'Session', True)
|
|
|
|
|
icon_visible(ClientObj.MainWidget, 'Connect', False)
|
|
|
|
|
icon_visible(ClientObj.MainWidget, 'Certificates', False)
|
|
|
|
|
|
|
|
|
|
ClientObj.methods_list = client_list_methods(ClientObj.sid, client)
|
|
|
|
|
if ClientObj.methods_list == 1:
|
|
|
|
|
show_msg (_('No methods available!'), parent = ClientObj.MainWidget)
|
|
|
|
|
ClientObj.MainWidget.disconnect(True)
|
|
|
|
|
return 1
|
|
|
|
|
ClientObj.MainWidget.display_methods()
|
|
|
|
|
|
|
|
|
|
def icon_visible (mainwgt, name, action):
|
|
|
|
|
# show/hide Icon in MainMenu
|
|
|
|
|
if hasattr (mainwgt.topmenu, name):
|
|
|
|
|
getattr (mainwgt.topmenu, name).setVisible(action)
|
|
|
|
|
|
|
|
|
|
from calculate.lib.utils import ip as ip_mod
|
|
|
|
|
|
|
|
|
|
def get_ip_mac():
|
|
|
|
|
for Interfaces in ip_mod.getInterfaces():
|
|
|
|
|
try:
|
|
|
|
|
ip, mac, client_type = utils.get_ip_mac_type('gui')
|
|
|
|
|
return (ip, mac)
|
|
|
|
|
except:
|
|
|
|
|
pass
|
|
|
|
|
return ('no_ip','no_mac')
|
|
|
|
|
|
|
|
|
|
def client_del_sid(client):
|
|
|
|
|
""" delete this session """
|
|
|
|
|
sid = get_sid(client)
|
|
|
|
|
try:
|
|
|
|
|
s = client.service.del_sid(sid)
|
|
|
|
|
fd = open(client.SID_FILE, 'w')
|
|
|
|
|
fd.close()
|
|
|
|
|
|
|
|
|
|
if s[0][0] == "-1":
|
|
|
|
|
_print (_("No access to the file!"))
|
|
|
|
|
return -1
|
|
|
|
|
if s[0][0] == "1":
|
|
|
|
|
_print (_("Failed to obtain certificate data!"))
|
|
|
|
|
return -2
|
|
|
|
|
if s[0][0] == "Permission denied":
|
|
|
|
|
_print (_("%s: Permission denied") % s[1][1])
|
|
|
|
|
return -3
|
|
|
|
|
if s[0][0] == '0':
|
|
|
|
|
pass
|
|
|
|
|
# _print (_("SID deleted!"))
|
|
|
|
|
except urllib2.URLError as e:
|
|
|
|
|
if e.__str__() == '<urlopen error The read operation timed out>':
|
|
|
|
|
_print ('Closing process...')
|
|
|
|
|
# _print (_("SID deleted!"))
|
|
|
|
|
return 0
|
|
|
|
|
except Exception as e:
|
|
|
|
|
_print (_("Error removing the session from the server"), e)
|
|
|
|
|
return 1
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
def client_list_methods(sid, client):
|
|
|
|
|
""" get & show all available methods for this certificate """
|
|
|
|
|
DAT = 0 # Access to data soap structure
|
|
|
|
|
RES = 0 # Access to result
|
|
|
|
|
COM = 0 # Getting command group
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
results = client.service.get_methods(sid, 'gui')
|
|
|
|
|
except urllib2.URLError as e:
|
|
|
|
|
_print ('client.service.get_methods in client_list_methods Exception')
|
|
|
|
|
return 1
|
|
|
|
|
if not results:
|
|
|
|
|
return 1
|
|
|
|
|
try:
|
|
|
|
|
if results[DAT][RES][RES][COM] == '0':
|
|
|
|
|
return 1
|
|
|
|
|
except:
|
|
|
|
|
pass
|
|
|
|
|
return results[DAT]
|
|
|
|
|
|
|
|
|
|
# get session id
|
|
|
|
|
def get_sid (client):
|
|
|
|
|
SID_FILE = client.SID_FILE
|
|
|
|
|
with Locker(fn=client.SID_LOCK):
|
|
|
|
|
server_host_name = client.server_host_name
|
|
|
|
|
if not os.path.exists(SID_FILE):
|
|
|
|
|
fs = open(SID_FILE, 'w')
|
|
|
|
|
fs.write('%s 0\n' %server_host_name)
|
|
|
|
|
fs.close()
|
|
|
|
|
else:
|
|
|
|
|
fs = open(SID_FILE, 'r')
|
|
|
|
|
lines = fs.readlines()
|
|
|
|
|
fs.close()
|
|
|
|
|
for line in lines:
|
|
|
|
|
word = line.split()
|
|
|
|
|
if word:
|
|
|
|
|
if word[0] == server_host_name:
|
|
|
|
|
sid = int (word[1])
|
|
|
|
|
return sid
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
class ClientServiceThread(qt.QThread):
|
|
|
|
|
signal = qt.Signal(object)
|
|
|
|
|
signal_extended = qt.Signal(object, object)
|
|
|
|
|
def __init__(self, ClientObj, method_name, *args, **kwargs):
|
|
|
|
|
super().__init__()
|
|
|
|
|
self.ClientObj = ClientObj
|
|
|
|
|
self.method_name = method_name
|
|
|
|
|
self.args = args
|
|
|
|
|
# установка kwargs с провркой на лишние
|
|
|
|
|
self.return_except, self.sleeptime, self.through_object = \
|
|
|
|
|
(lambda return_except=False,sleeptime=None,
|
|
|
|
|
through_object=None:
|
|
|
|
|
(return_except,sleeptime,through_object))(**kwargs)
|
|
|
|
|
self.close_flag = False
|
|
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
|
client = self.ClientObj.client
|
|
|
|
|
if self.sleeptime:
|
|
|
|
|
try:
|
|
|
|
|
for i in range(10):
|
|
|
|
|
time.sleep(self.sleeptime / 10.0)
|
|
|
|
|
if self.close_flag:
|
|
|
|
|
return
|
|
|
|
|
except TypeError:
|
|
|
|
|
_print ('TypeError Exception in class ClientServiceThread')
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
print(f"method name : {self.method_name}")
|
|
|
|
|
# print(client.service[0])
|
|
|
|
|
result = client.service[0][self.method_name](*self.args)
|
|
|
|
|
except Exception as e:
|
|
|
|
|
if self.return_except:
|
|
|
|
|
_print ("EMIT EXCEPTION!")
|
|
|
|
|
if self.close_flag:
|
|
|
|
|
return
|
|
|
|
|
if self.through_object:
|
|
|
|
|
self.signal_extended.emit(Exception(e), \
|
|
|
|
|
self.through_object)
|
|
|
|
|
else:
|
|
|
|
|
self.signal.emit(Exception(e))
|
|
|
|
|
return
|
|
|
|
|
else:
|
|
|
|
|
_print ("EXCEPTION!", e)
|
|
|
|
|
return
|
|
|
|
|
if self.close_flag:
|
|
|
|
|
return
|
|
|
|
|
if self.through_object:
|
|
|
|
|
self.signal_extended.emit(result, self.through_object)
|
|
|
|
|
else:
|
|
|
|
|
self.signal.emit(result)
|
|
|
|
|
|
|
|
|
|
def close(self):
|
|
|
|
|
self.close_flag = True
|
|
|
|
|
|
|
|
|
|
class ImageLabel(qt.QLabel):
|
|
|
|
|
def __init__(self, image, height_image, parent):
|
|
|
|
|
super().__init__()
|
|
|
|
|
# self._parent = parent
|
|
|
|
|
save_path = os.path.join('/tmp', 'calculate-' + \
|
|
|
|
|
pwd.getpwuid(os.getuid()).pw_name)
|
|
|
|
|
if not os.path.isdir(save_path):
|
|
|
|
|
os.mkdir(save_path)
|
|
|
|
|
repeat = None
|
|
|
|
|
|
|
|
|
|
image_path, filename = image.rsplit('/',1)
|
|
|
|
|
image_conf = os.path.join(image_path, 'conf')
|
|
|
|
|
|
|
|
|
|
repeat_dict = {'no' : 'no-repeat', 'x' : 'repeat-x'}
|
|
|
|
|
for line in readLinesFile(image_conf):
|
|
|
|
|
list_data = line.split()
|
|
|
|
|
if len (list_data) < 2:
|
|
|
|
|
return False
|
|
|
|
|
if list_data[0] == filename:
|
|
|
|
|
if not list_data[1] in repeat_dict.keys():
|
|
|
|
|
return False
|
|
|
|
|
repeat = list_data[1]
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
style = ''
|
|
|
|
|
|
|
|
|
|
def resize_image(source_path, height, output_path):
|
|
|
|
|
convert_cmd = getProgPath('/usr/bin/convert')
|
|
|
|
|
identify_cmd = getProgPath('/usr/bin/identify')
|
|
|
|
|
|
|
|
|
|
def convert_image(source, res, target):
|
|
|
|
|
command = [convert_cmd, "-quality", "100",
|
|
|
|
|
source, "-resize", "%s" % res,
|
|
|
|
|
"-strip",
|
|
|
|
|
target]
|
|
|
|
|
#"-strip", "-gravity", "center",
|
|
|
|
|
#"-crop", "%s+0+0" % res, target]
|
|
|
|
|
|
|
|
|
|
convert = process(*command, stderr=STDOUT)
|
|
|
|
|
if convert.success():
|
|
|
|
|
return True
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def get_image_resolution(source):
|
|
|
|
|
identify = process(identify_cmd, "-format", "%w %h", source)
|
|
|
|
|
if identify.success():
|
|
|
|
|
swidth, _sep, sheight = identify.read().strip().partition(" ")
|
|
|
|
|
if swidth.isdigit() and sheight.isdigit():
|
|
|
|
|
return int(swidth), int(sheight)
|
|
|
|
|
return None, None
|
|
|
|
|
return None, None
|
|
|
|
|
|
|
|
|
|
cx, cy = get_image_resolution(source_path)
|
|
|
|
|
|
|
|
|
|
if cx and cy:
|
|
|
|
|
if convert_image(source_path, "{}x{}".format(cx, height),
|
|
|
|
|
output_path):
|
|
|
|
|
|
|
|
|
|
return get_image_resolution(output_path)
|
|
|
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
if len(list_data) == 3:
|
|
|
|
|
fix_image_path = os.path.join(image_path, list_data[2])
|
|
|
|
|
if os.path.isfile(fix_image_path):
|
|
|
|
|
layout = qt.QHBoxLayout(self)
|
|
|
|
|
fix_image = qt.QLabel(self)
|
|
|
|
|
temp_file = os.path.join(save_path, '%s_fix' %filename)
|
|
|
|
|
sizes = resize_image(fix_image_path, height_image, temp_file)
|
|
|
|
|
if sizes:
|
|
|
|
|
os.chmod(temp_file, 0o666)
|
|
|
|
|
fix_image.setFixedWidth(sizes[0])
|
|
|
|
|
fix_image.setStyleSheet("background-image: url(%s); " \
|
|
|
|
|
%temp_file)
|
|
|
|
|
layout.addWidget(fix_image)
|
|
|
|
|
layout.setContentsMargins(0,0,0,0)
|
|
|
|
|
layout.setAlignment(qt.Qt.AlignLeft)
|
|
|
|
|
|
|
|
|
|
elif len(list_data) > 3:
|
|
|
|
|
color1, color2 = list_data[-2:]
|
|
|
|
|
style = "background-color: qlineargradient(x1: 0, y1: 0, " + \
|
|
|
|
|
"x2: 0, y2: 1, stop: 0 %s, stop: 1 %s);" %(color1, color2)
|
|
|
|
|
|
|
|
|
|
temp_file = os.path.join(save_path, '%s_temp' %filename)
|
|
|
|
|
sizes = resize_image(image, height_image, temp_file)
|
|
|
|
|
if sizes:
|
|
|
|
|
os.chmod(temp_file, 0o666)
|
|
|
|
|
style += "background-image: url(%s); " %temp_file
|
|
|
|
|
style += "background-attachment: fixed; "
|
|
|
|
|
style += "background-repeat: %s; " %repeat_dict[repeat.lower()]
|
|
|
|
|
style += "border-bottom: 1px solid #B8B3B0;"
|
|
|
|
|
self.setStyleSheet(style)
|
|
|
|
|
self.setFixedHeight(sizes[1])
|
|
|
|
|
|
|
|
|
|
def get_view_params(client, method, step = None, expert = None, brief = None):
|
|
|
|
|
view_params = utils.create_obj(client, method)
|
|
|
|
|
view_params.step = step
|
|
|
|
|
view_params.expert = expert
|
|
|
|
|
view_params.brief = brief
|
|
|
|
|
if hasattr(view_params,"clienttype"):
|
|
|
|
|
view_params.clienttype = "gui"
|
|
|
|
|
return view_params
|
|
|
|
|
|
|
|
|
|
def owner(pid):
|
|
|
|
|
UID = 1
|
|
|
|
|
for ln in open('/proc/%s/status' %pid):
|
|
|
|
|
if ln.startswith('Uid:'):
|
|
|
|
|
uid = int(ln.split()[UID])
|
|
|
|
|
return pwd.getpwuid(uid).pw_name
|
|
|
|
|
|
|
|
|
|
def getRunProc():
|
|
|
|
|
"""List run program"""
|
|
|
|
|
def getCmd(procNum):
|
|
|
|
|
cmdLineFile = '/proc/%s/cmdline'%procNum
|
|
|
|
|
try:
|
|
|
|
|
if os.path.exists(cmdLineFile):
|
|
|
|
|
return [readFile(cmdLineFile).strip(), procNum]
|
|
|
|
|
except:
|
|
|
|
|
pass
|
|
|
|
|
return ["", procNum]
|
|
|
|
|
if not os.access('/proc',os.R_OK):
|
|
|
|
|
return []
|
|
|
|
|
return map(getCmd,
|
|
|
|
|
filter(lambda x:x.isdigit(),
|
|
|
|
|
listDirectory('/proc')))
|