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

2776 lines
99 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#-*- 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.
import os
import time
import urllib.request as urllib2
import pwd
import sys
DEBUG_LEVEL = 99999
def debug(level, *args):
if level <= DEBUG_LEVEL:
for s in args:
print(s, end=' ')
print()
from .. 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 int(size * qt.QApplication.screens()[0].logicalDotsPerInch() / 96.0);
except BaseException as e:
print(str(e))
if isinstance(e, KeyboardInterrupt):
raise
return int(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("&nbsp;"," ")
else:
name = name.replace("&#9;", "&nbsp;"*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__()
debug(11, "Creating multiple choice dialog")
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([Available_dict[x] for x
in Available_list if x not in Selected_list])
self.right_ListWidget.addItems([Available_dict[x] for x
in Selected_list if x in Available_dict.keys()])
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)
# debug(11, "ADDED mouse press event")
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 ())
debug(11, "MultipleChoice mouse event")
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 = [res_dict[x] for x in self.Selected if x in res_dict]
res += [x for x in self.Selected if not x in res_dict]
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())
debug(11, "AddLineWidget init")
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().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 = (x for x in self.widget_dict.keys()
if type(self.widget_dict[str(x)]) == SimplePasswordWidget)
if [x for x in items if not self.widget_dict[str(x)].status()]:
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((str(x) for x in 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, '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():
tmp = identify.read()
if isinstance(tmp, bytes):
swidth, _sep, sheight = identify.read().decode(encoding="UTF-8").strip().partition(" ")
else:
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 [getCmd(x) for x in listDirectory('/proc') if x.isdigit()]