|
|
|
#!/usr/bin/python
|
|
|
|
#-*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
# Copyright 2012 Calculate Ltd. 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 PySide import QtGui, QtCore
|
|
|
|
import os, time, urllib2
|
|
|
|
from calculate.core.client.function import create_obj
|
|
|
|
from calculate.lib.utils.files import readLinesFile
|
|
|
|
import Image
|
|
|
|
import pwd, sys
|
|
|
|
from calculate.lib.utils.files import listDirectory
|
|
|
|
|
|
|
|
_('The user must not be root')
|
|
|
|
class TopMenu(QtGui.QPushButton):
|
|
|
|
def __init__(self, label, images, parent = None):
|
|
|
|
QtGui.QPushButton.__init__(self, parent)
|
|
|
|
self.setStyleSheet("QPushButton{border: none; margin: 1px;}"
|
|
|
|
"QPushButton:hover{border: 1px solid #73D1FF;"
|
|
|
|
"border-radius: 3px; margin: 1px;}")
|
|
|
|
# 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 = QtGui.QVBoxLayout(self)
|
|
|
|
|
|
|
|
self.image_lbl = QtGui.QLabel(self)
|
|
|
|
|
|
|
|
themeName = QtGui.QIcon.themeName()
|
|
|
|
icon = QtGui.QIcon()
|
|
|
|
for image in images:
|
|
|
|
icon.setThemeName(themeName)
|
|
|
|
icon = icon.fromTheme(image)
|
|
|
|
if not icon.isNull():
|
|
|
|
break
|
|
|
|
icon.setThemeName('Tango')
|
|
|
|
icon = icon.fromTheme(image)
|
|
|
|
if not icon.isNull():
|
|
|
|
break
|
|
|
|
|
|
|
|
# icon.actualSize(QtCore.QSize(48,48))
|
|
|
|
pm1 = icon.pixmap(24)
|
|
|
|
|
|
|
|
# img = p.toImage()
|
|
|
|
# p.fromImage(img)
|
|
|
|
pm2 = pm1.scaled(QtCore.QSize(24, 24), QtCore.Qt.KeepAspectRatio, \
|
|
|
|
QtCore.Qt.SmoothTransformation)
|
|
|
|
# pm2.scaled(24,24)
|
|
|
|
|
|
|
|
self.image_lbl.setPixmap(pm2)
|
|
|
|
# self.image_lbl.adjustSize()
|
|
|
|
self.image_lbl.setAlignment(QtCore.Qt.AlignCenter)
|
|
|
|
|
|
|
|
# add transparency
|
|
|
|
self.image_lbl.setAttribute(QtCore.Qt.WA_NoSystemBackground)
|
|
|
|
|
|
|
|
|
|
|
|
self.layout.addWidget(self.image_lbl)
|
|
|
|
self.setFlat(True)
|
|
|
|
|
|
|
|
|
|
|
|
self.lbl = QtGui.QLabel(label, self)
|
|
|
|
self.lbl.setAlignment(QtCore.Qt.AlignCenter)
|
|
|
|
|
|
|
|
# add transparency
|
|
|
|
self.lbl.setAttribute(QtCore.Qt.WA_NoSystemBackground)
|
|
|
|
|
|
|
|
self.layout.addWidget(self.lbl)
|
|
|
|
self.layout.setContentsMargins(2,4,2,2)
|
|
|
|
self.layout.setSpacing(0)
|
|
|
|
|
|
|
|
# self.setFixedSize(48,40)
|
|
|
|
self.setFixedHeight(48)
|
|
|
|
if self.lbl.sizeHint().width() > 32:
|
|
|
|
self.setFixedWidth(self.lbl.sizeHint().width()+16)
|
|
|
|
else:
|
|
|
|
self.setFixedWidth(48)
|
|
|
|
self.updateGeometry()
|
|
|
|
self.setFocusPolicy(QtCore.Qt.NoFocus)
|
|
|
|
|
|
|
|
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
|
|
|
|
|
|
|
|
def mousePressEvent(self, event):
|
|
|
|
self.layout.setContentsMargins(2,5,2,2)
|
|
|
|
event.accept()
|
|
|
|
QtGui.QPushButton.mousePressEvent(self, event)
|
|
|
|
|
|
|
|
def mouseReleaseEvent(self, event):
|
|
|
|
self.layout.setContentsMargins(2,4,2,2)
|
|
|
|
event.accept()
|
|
|
|
QtGui.QPushButton.mouseReleaseEvent(self, event)
|
|
|
|
|
|
|
|
def text(self):
|
|
|
|
return self.lbl.text()
|
|
|
|
|
|
|
|
def setText(self, text):
|
|
|
|
self.lbl.setText(text)
|
|
|
|
self.setFixedHeight(48)
|
|
|
|
if self.lbl.sizeHint().width() > 32:
|
|
|
|
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() != QtCore.Qt.MouseButton.LeftButton:
|
|
|
|
event.ignore()
|
|
|
|
return 0
|
|
|
|
TopMenu.mousePressEvent(self, event)
|
|
|
|
menu = QtGui.QMenu(self)
|
|
|
|
|
|
|
|
About_icon = (QtGui.QIcon \
|
|
|
|
('/usr/share/pixmaps/calculate-console-online.png'))
|
|
|
|
themeName = QtGui.QIcon.themeName()
|
|
|
|
if About_icon.isNull():
|
|
|
|
about_icons = ['help-about','help-browser']
|
|
|
|
About_icon = QtGui.QIcon()
|
|
|
|
for image in about_icons:
|
|
|
|
About_icon.setThemeName(themeName)
|
|
|
|
About_icon = About_icon.fromTheme(image)
|
|
|
|
if not About_icon.isNull():
|
|
|
|
break
|
|
|
|
About_icon.setThemeName('Tango')
|
|
|
|
About_icon = About_icon.fromTheme(image)
|
|
|
|
if not About_icon.isNull():
|
|
|
|
break
|
|
|
|
|
|
|
|
about = QtGui.QAction(About_icon, _("About"), self, \
|
|
|
|
triggered=self.actions.help)
|
|
|
|
menu.addAction(about)
|
|
|
|
|
|
|
|
menu.addSeparator()
|
|
|
|
handbook_icons = ['help-contents','system-help','help-browser']
|
|
|
|
handbook_icon = QtGui.QIcon()
|
|
|
|
for image in handbook_icons:
|
|
|
|
handbook_icon.setThemeName(themeName)
|
|
|
|
handbook_icon = handbook_icon.fromTheme(image)
|
|
|
|
if not handbook_icon.isNull():
|
|
|
|
break
|
|
|
|
handbook_icon.setThemeName('Tango')
|
|
|
|
handbook_icon = handbook_icon.fromTheme(image)
|
|
|
|
if not handbook_icon.isNull():
|
|
|
|
break
|
|
|
|
|
|
|
|
handbook = QtGui.QAction(handbook_icon,_("Info"),\
|
|
|
|
self, triggered=self.actions.hand_book)
|
|
|
|
menu.addAction(handbook)
|
|
|
|
|
|
|
|
menu.addSeparator()
|
|
|
|
bug_icons = ['tools-report-bug','system-help','help-browser']
|
|
|
|
bug_icon = QtGui.QIcon()
|
|
|
|
for image in bug_icons:
|
|
|
|
bug_icon.setThemeName(themeName)
|
|
|
|
bug_icon = bug_icon.fromTheme(image)
|
|
|
|
if not bug_icon.isNull():
|
|
|
|
break
|
|
|
|
bug_icon.setThemeName('Tango')
|
|
|
|
bug_icon = bug_icon.fromTheme(image)
|
|
|
|
if not bug_icon.isNull():
|
|
|
|
break
|
|
|
|
|
|
|
|
bug = QtGui.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_(QtCore.QPoint(x, y))
|
|
|
|
TopMenu.mouseReleaseEvent(self, event)
|
|
|
|
|
|
|
|
class ButtonMenu(QtGui.QPushButton):
|
|
|
|
def __init__(self, name, label, images, parent):
|
|
|
|
QtGui.QPushButton.__init__(self, parent)
|
|
|
|
self.layout = QtGui.QVBoxLayout(self)
|
|
|
|
self.layout.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop)
|
|
|
|
|
|
|
|
self.image_lbl = QtGui.QLabel(self)
|
|
|
|
if not images:
|
|
|
|
images = ''
|
|
|
|
|
|
|
|
images = images.split(',')
|
|
|
|
icon_flag = True
|
|
|
|
|
|
|
|
QtGui.QIcon.setThemeName('Calculate')
|
|
|
|
for image in images:
|
|
|
|
icon = QtGui.QIcon.fromTheme(image)
|
|
|
|
if not icon.isNull():
|
|
|
|
pm2 = icon.pixmap(128)
|
|
|
|
icon_flag = False
|
|
|
|
break
|
|
|
|
elif os.path.isfile(image):
|
|
|
|
ir = QtGui.QImageReader(image)
|
|
|
|
ir.setScaledSize(QtCore.QSize(32, 32))
|
|
|
|
img = ir.read()
|
|
|
|
pm2 = QtGui.QPixmap().fromImage(img)
|
|
|
|
|
|
|
|
icon_flag = False
|
|
|
|
break
|
|
|
|
if icon_flag:
|
|
|
|
icon = QtGui.QIcon.fromTheme('applications-system')
|
|
|
|
pm2 = icon.pixmap(32)
|
|
|
|
|
|
|
|
pm2 = pm2.scaled(QtCore.QSize(32,32), QtCore.Qt.IgnoreAspectRatio, \
|
|
|
|
QtCore.Qt.SmoothTransformation)
|
|
|
|
|
|
|
|
self.image_lbl.setPixmap(pm2)
|
|
|
|
self.image_lbl.setMinimumHeight(32)
|
|
|
|
self.image_lbl.setAlignment(QtCore.Qt.AlignHCenter)
|
|
|
|
|
|
|
|
# add transparency
|
|
|
|
self.image_lbl.setAttribute(QtCore.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(30)
|
|
|
|
self.lbl.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop)
|
|
|
|
self.lbl.resize(self.lbl.sizeHint())
|
|
|
|
self.lbl.setStyleSheet("QLabel {border: None;}")
|
|
|
|
# add transparency
|
|
|
|
self.lbl.setAttribute(QtCore.Qt.WA_NoSystemBackground)
|
|
|
|
|
|
|
|
self.layout.addWidget(self.lbl)
|
|
|
|
self.layout.setContentsMargins(0,8,0,0)
|
|
|
|
# self.layout.setSpacing(28)
|
|
|
|
|
|
|
|
self.setFixedSize(96,80)
|
|
|
|
self.setObjectName(name)
|
|
|
|
|
|
|
|
self.setStyleSheet("QPushButton:flat {border: None;}"
|
|
|
|
"QPushButton:hover:pressed {border: none;"
|
|
|
|
"background-color: rgb(218,218,218);"
|
|
|
|
"border-radius: 7px;}"
|
|
|
|
"QPushButton:hover:!pressed{background-color: "
|
|
|
|
"rgb(230,230,230); border-radius: 7px;}")
|
|
|
|
self.updateGeometry()
|
|
|
|
|
|
|
|
def text(self):
|
|
|
|
return self.lbl.text()
|
|
|
|
|
|
|
|
class ErrorLabel (QtGui.QWidget):
|
|
|
|
def __init__(self, parent, text = None):
|
|
|
|
QtGui.QWidget.__init__(self, parent)
|
|
|
|
self._parent = parent
|
|
|
|
layout = QtGui.QHBoxLayout(self)
|
|
|
|
|
|
|
|
self.image_lbl = QtGui.QLabel(self)
|
|
|
|
|
|
|
|
icon = QtGui.QIcon.fromTheme('dialog-warning')
|
|
|
|
pm1 = icon.pixmap(16)
|
|
|
|
|
|
|
|
pm2 = pm1.scaled(QtCore.QSize(16, 16), QtCore.Qt.KeepAspectRatio, \
|
|
|
|
QtCore.Qt.SmoothTransformation)
|
|
|
|
|
|
|
|
self.image_lbl.setPixmap(pm2)
|
|
|
|
self.image_lbl.setAlignment(QtCore.Qt.AlignCenter)
|
|
|
|
|
|
|
|
# add transparency
|
|
|
|
self.image_lbl.setAttribute(QtCore.Qt.WA_NoSystemBackground)
|
|
|
|
self.image_lbl.setAlignment(QtCore.Qt.AlignVCenter)
|
|
|
|
|
|
|
|
layout.addWidget(self.image_lbl)
|
|
|
|
|
|
|
|
self.text_lbl = QtGui.QLabel()
|
|
|
|
self.text_lbl.setWordWrap(True)
|
|
|
|
self.text_lbl.setAlignment(QtCore.Qt.AlignVCenter)
|
|
|
|
self.text_lbl.setTextInteractionFlags (self.text_lbl.\
|
|
|
|
textInteractionFlags() | QtCore.Qt.TextSelectableByMouse)
|
|
|
|
|
|
|
|
maximum = QtGui.QSizePolicy.Policy.Maximum
|
|
|
|
exp = QtGui.QSizePolicy.Policy.Expanding
|
|
|
|
self.text_lbl.setSizePolicy(exp, maximum)
|
|
|
|
|
|
|
|
layout.addWidget(self.text_lbl)
|
|
|
|
layout.setAlignment(QtCore.Qt.AlignLeft)
|
|
|
|
layout.setContentsMargins (0,0,0,0)
|
|
|
|
|
|
|
|
if text:
|
|
|
|
self.setText(text)
|
|
|
|
self.hide()
|
|
|
|
|
|
|
|
# for clear memory after closed this window
|
|
|
|
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
|
|
|
|
|
|
|
|
def mousePressEvent(self, event):
|
|
|
|
if event.button() == QtCore.Qt.MouseButton.RightButton:
|
|
|
|
if hasattr(self, 'menu'):
|
|
|
|
self.menu.move(QtGui.QCursor.pos())
|
|
|
|
self.menu.show()
|
|
|
|
event.accept()
|
|
|
|
|
|
|
|
def setText(self, txt):
|
|
|
|
txt.replace('\n',' ')
|
|
|
|
self.text_lbl.setText(txt)
|
|
|
|
|
|
|
|
if not hasattr(self, 'menu'):
|
|
|
|
themeName = QtGui.QIcon.themeName()
|
|
|
|
self.menu = QtGui.QMenu(self)
|
|
|
|
bug_icons = ['tools-report-bug','system-help','help-browser']
|
|
|
|
bug_icon = QtGui.QIcon()
|
|
|
|
for image in bug_icons:
|
|
|
|
bug_icon.setThemeName(themeName)
|
|
|
|
bug_icon = bug_icon.fromTheme(image)
|
|
|
|
if not bug_icon.isNull():
|
|
|
|
break
|
|
|
|
bug_icon.setThemeName('Tango')
|
|
|
|
bug_icon = bug_icon.fromTheme(image)
|
|
|
|
if not bug_icon.isNull():
|
|
|
|
break
|
|
|
|
|
|
|
|
bug = QtGui.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(QtGui.QWidget):
|
|
|
|
def __init__(self, text = '', parent = None):
|
|
|
|
QtGui.QWidget.__init__(self)
|
|
|
|
self._parent = parent
|
|
|
|
layout = QtGui.QHBoxLayout(self)
|
|
|
|
|
|
|
|
self.image_but = QtGui.QPushButton(self)
|
|
|
|
self.image_but.setFlat(True)
|
|
|
|
self.image_but.setFixedSize(ERROR_ICON_SIZE,ERROR_ICON_SIZE)
|
|
|
|
self.image_but.setStyleSheet('''QPushButton:pressed {border: none;}
|
|
|
|
QPushButton::hover {border: none;}''')
|
|
|
|
layout.addWidget(self.image_but, 0, QtCore.Qt.AlignmentFlag.AlignTop)
|
|
|
|
|
|
|
|
self.text = LabelWordWrap(text, self)
|
|
|
|
# self.text.setMinimumHeight(self.text.sizeHint().height())
|
|
|
|
self.text.setTextInteractionFlags (self.text.textInteractionFlags() \
|
|
|
|
| QtCore.Qt.TextSelectableByMouse)
|
|
|
|
layout.addWidget(self.text)
|
|
|
|
|
|
|
|
layout.setContentsMargins(0,0,0,0)
|
|
|
|
layout.setSpacing(4)
|
|
|
|
layout.setAlignment(QtCore.Qt.AlignTop)
|
|
|
|
self.set_status = False
|
|
|
|
self.add_menu()
|
|
|
|
self.resize(self.sizeHint())
|
|
|
|
|
|
|
|
def set_warning(self):
|
|
|
|
icon = QtGui.QIcon.fromTheme('dialog-warning')
|
|
|
|
icon.actualSize(QtCore.QSize(ERROR_ICON_SIZE,ERROR_ICON_SIZE))
|
|
|
|
self.image_but.setIcon(icon)
|
|
|
|
self.image_but.setIconSize(QtCore.QSize(ERROR_ICON_SIZE,ERROR_ICON_SIZE))
|
|
|
|
|
|
|
|
def set_error(self):
|
|
|
|
icon = QtGui.QIcon.fromTheme('dialog-error')
|
|
|
|
icon.actualSize(QtCore.QSize(ERROR_ICON_SIZE,ERROR_ICON_SIZE))
|
|
|
|
self.image_but.setIcon(icon)
|
|
|
|
self.image_but.setIconSize(QtCore.QSize(ERROR_ICON_SIZE,ERROR_ICON_SIZE))
|
|
|
|
|
|
|
|
def add_menu(self):
|
|
|
|
if not hasattr(self, 'menu'):
|
|
|
|
themeName = QtGui.QIcon.themeName()
|
|
|
|
self.menu = QtGui.QMenu(self)
|
|
|
|
bug_icons = ['tools-report-bug','system-help','help-browser']
|
|
|
|
bug_icon = QtGui.QIcon()
|
|
|
|
for image in bug_icons:
|
|
|
|
bug_icon.setThemeName(themeName)
|
|
|
|
bug_icon = bug_icon.fromTheme(image)
|
|
|
|
if not bug_icon.isNull():
|
|
|
|
break
|
|
|
|
bug_icon.setThemeName('Tango')
|
|
|
|
bug_icon = bug_icon.fromTheme(image)
|
|
|
|
if not bug_icon.isNull():
|
|
|
|
break
|
|
|
|
|
|
|
|
bug = QtGui.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() == QtCore.Qt.MouseButton.RightButton:
|
|
|
|
if hasattr(self, 'menu'):
|
|
|
|
self.menu.move(QtGui.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(QtGui.QLabel):
|
|
|
|
def __init__(self, name, parent = None, mono=False):
|
|
|
|
if not name:
|
|
|
|
name = ''
|
|
|
|
try:
|
|
|
|
name = name.decode('utf-8').replace(" "," ")
|
|
|
|
leftMargin = len(name)-len(name.lstrip(' '))
|
|
|
|
name = name[leftMargin:]
|
|
|
|
except (UnicodeDecodeError, UnicodeEncodeError):
|
|
|
|
pass
|
|
|
|
QtGui.QLabel.__init__(self, name, parent)
|
|
|
|
if mono:
|
|
|
|
self.setStyleSheet('font-family: Droid Sans Mono;'
|
|
|
|
'background-color:white;'
|
|
|
|
'margin:3px;')
|
|
|
|
else:
|
|
|
|
self.setStyleSheet('margin-left:%dpx;'%(leftMargin*5))
|
|
|
|
|
|
|
|
minimum = QtGui.QSizePolicy.Policy.Minimum
|
|
|
|
exp = QtGui.QSizePolicy.Policy.Expanding
|
|
|
|
self.setSizePolicy(exp, minimum)
|
|
|
|
|
|
|
|
self.setWordWrap(True)
|
|
|
|
|
|
|
|
# for clear memory after closed this window
|
|
|
|
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
|
|
|
|
|
|
|
|
class ClearLineEdit(QtGui.QLineEdit):
|
|
|
|
def __init__(self, text = None, parent=None):
|
|
|
|
QtGui.QLineEdit.__init__(self, text, parent)
|
|
|
|
self.def_text = text
|
|
|
|
self.button=QtGui.QToolButton(self)
|
|
|
|
self.button.setCursor(QtCore.Qt.ArrowCursor)
|
|
|
|
self.button.hide()
|
|
|
|
self.button.setFocusPolicy(QtCore.Qt.NoFocus)
|
|
|
|
try:
|
|
|
|
self.button.setIcon(QtGui.QIcon.fromTheme("edit-clear"))
|
|
|
|
except:
|
|
|
|
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(QtCore.Qt.WA_DeleteOnClose)
|
|
|
|
|
|
|
|
layout=QtGui.QVBoxLayout(self)
|
|
|
|
layout.addWidget(self.button,0,QtCore.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(QtGui.QWidget):
|
|
|
|
textChanged = QtCore.Signal()
|
|
|
|
def __init__(self, parent, type, caption=None, directory=None):
|
|
|
|
QtGui.QWidget.__init__(self,parent)
|
|
|
|
self.type = type
|
|
|
|
self.caption = caption
|
|
|
|
self.dir = directory
|
|
|
|
|
|
|
|
self.data = None
|
|
|
|
|
|
|
|
self.hlayout = QtGui.QHBoxLayout(self)
|
|
|
|
|
|
|
|
self.lineEdit = QtGui.QLineEdit(self)
|
|
|
|
self.lineEdit.textChanged.connect(self.textChanged)
|
|
|
|
|
|
|
|
self.button=QtGui.QToolButton(self)
|
|
|
|
self.button.setCursor(QtCore.Qt.ArrowCursor)
|
|
|
|
self.button.setFocusPolicy(QtCore.Qt.NoFocus)
|
|
|
|
try:
|
|
|
|
self.button.setIcon(QtGui.QIcon.fromTheme("document-open"))
|
|
|
|
except:
|
|
|
|
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(QtCore.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 = QtGui.QFileDialog(self, self.caption, self.dir)
|
|
|
|
|
|
|
|
self.fd.setWindowModality(QtCore.Qt.WindowModality.WindowModal)
|
|
|
|
if self.type == 'dir':
|
|
|
|
self.data = self.fd.getExistingDirectory()
|
|
|
|
if self.type == 'file':
|
|
|
|
data = self.fd.getOpenFileName()
|
|
|
|
self.data = data[0]
|
|
|
|
if self.type == 'files':
|
|
|
|
data = self.fd.getOpenFileNames()
|
|
|
|
self.data = data[0]
|
|
|
|
self.set_label()
|
|
|
|
|
|
|
|
def set_label(self):
|
|
|
|
if type(self.data) in [str, unicode]:
|
|
|
|
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(QtGui.QWidget):
|
|
|
|
# textChanged = QtCore.Signal()
|
|
|
|
def __init__(self, parent, type, choice = None, caption=None, \
|
|
|
|
value=None, comments = None):
|
|
|
|
QtGui.QWidget.__init__(self,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.hlayout = QtGui.QHBoxLayout(self)
|
|
|
|
|
|
|
|
self.ComboBox = QtGui.QComboBox(self)
|
|
|
|
self.ComboBox.setDuplicatesEnabled(False)
|
|
|
|
self.ComboBox.setEditable(True)
|
|
|
|
self.lineEdit = QtGui.QLineEdit(self)
|
|
|
|
self.ComboBox.setLineEdit(self.lineEdit)
|
|
|
|
self.ComboBox.currentIndexChanged.connect(self.setCursorPos)
|
|
|
|
# self.lineEdit.setStyleSheet("QLineEdit {border: none;}")
|
|
|
|
|
|
|
|
self.ComboWidget = QtGui.QLabel(self)
|
|
|
|
self.ComboWidget.setContentsMargins(0,0,0,0)
|
|
|
|
ComboLayout = QtGui.QVBoxLayout(self.ComboWidget)
|
|
|
|
ComboLayout.setContentsMargins(0,0,0,0)
|
|
|
|
ComboLayout.addWidget(self.ComboBox)
|
|
|
|
self.unsetErrorBorder()
|
|
|
|
|
|
|
|
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 \
|
|
|
|
(QtGui.QComboBox.SizeAdjustPolicy.\
|
|
|
|
AdjustToMinimumContentsLengthWithIcon)
|
|
|
|
|
|
|
|
self.button = QtGui.QToolButton(self)
|
|
|
|
self.button.setCursor(QtCore.Qt.ArrowCursor)
|
|
|
|
self.button.setFocusPolicy(QtCore.Qt.NoFocus)
|
|
|
|
try:
|
|
|
|
self.button.setIcon(QtGui.QIcon.fromTheme("document-open"))
|
|
|
|
except:
|
|
|
|
self.button.setText(_('Open'))
|
|
|
|
# self.button.setStyleSheet("QToolButton {border: none;}")
|
|
|
|
self.button.clicked.connect(self.file_dialog)
|
|
|
|
|
|
|
|
self.hlayout.addWidget(self.ComboWidget)
|
|
|
|
self.hlayout.addWidget(self.button)
|
|
|
|
self.hlayout.setSpacing(0)
|
|
|
|
|
|
|
|
def setCursorPos(self, num = None):
|
|
|
|
self.lineEdit.setCursorPosition(0)
|
|
|
|
|
|
|
|
def file_dialog(self):
|
|
|
|
self.fd = QtGui.QFileDialog(self, self.caption)
|
|
|
|
|
|
|
|
self.fd.setWindowModality(QtCore.Qt.WindowModality.WindowModal)
|
|
|
|
if self.type == 'dir':
|
|
|
|
self.data = self.fd.getExistingDirectory()
|
|
|
|
if self.type == 'file':
|
|
|
|
data = self.fd.getOpenFileName()
|
|
|
|
self.data = data[0]
|
|
|
|
if self.type == 'files':
|
|
|
|
data = self.fd.getOpenFileNames()
|
|
|
|
self.data = data[0]
|
|
|
|
self.set_label()
|
|
|
|
|
|
|
|
def set_label(self):
|
|
|
|
if type(self.data) in [str, unicode]:
|
|
|
|
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 = ".QLabel {border: 1px solid red; margin: 0px;}"
|
|
|
|
self.ComboWidget.setStyleSheet(style)
|
|
|
|
|
|
|
|
def unsetErrorBorder(self):
|
|
|
|
style = "QLabel {border: 1px solid transparent; margin: 0px;}"
|
|
|
|
self.ComboWidget.setStyleSheet(style)
|
|
|
|
|
|
|
|
class ReadonlyCheckBox(QtGui.QCheckBox):
|
|
|
|
def __init__(self, parent):
|
|
|
|
QtGui.QCheckBox.__init__(self, parent)
|
|
|
|
self.setFocusPolicy(QtCore.Qt.NoFocus)
|
|
|
|
self.disabled = False
|
|
|
|
|
|
|
|
def mousePressEvent(self, event):
|
|
|
|
cur_state = self.checkState()
|
|
|
|
event.accept()
|
|
|
|
QtGui.QCheckBox.click(self)
|
|
|
|
if self.disabled:
|
|
|
|
self.setCheckState(cur_state)
|
|
|
|
|
|
|
|
class CentralCheckBox (QtGui.QWidget):
|
|
|
|
def __init__(self, parent, tristate, text = None, ind_col = False):
|
|
|
|
super(CentralCheckBox, self).__init__(parent)
|
|
|
|
self.lay = QtGui.QHBoxLayout(self)
|
|
|
|
self.pCheckB = ReadonlyCheckBox(self)
|
|
|
|
self.lay.addWidget(self.pCheckB)
|
|
|
|
self.lay.setAlignment(QtCore.Qt.AlignmentFlag.AlignHCenter)
|
|
|
|
self.lay.setContentsMargins(3,3,3,3)
|
|
|
|
self.setLayout(self.lay)
|
|
|
|
if tristate:
|
|
|
|
self.pCheckB.setTristate(True)
|
|
|
|
self.pCheckB.setCheckState(QtCore.Qt.CheckState.PartiallyChecked)
|
|
|
|
if not ind_col:
|
|
|
|
self.pCheckB.clicked.connect(self.change_label)
|
|
|
|
self.change_label()
|
|
|
|
self.setStyleSheet('padding: 0px; margin-left: 2px;')
|
|
|
|
self.setFocusPolicy(QtCore.Qt.NoFocus)
|
|
|
|
self.setAttribute(QtCore.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() == \
|
|
|
|
QtCore.Qt.CheckState.PartiallyChecked:
|
|
|
|
self.set_label(_('Auto'))
|
|
|
|
elif self.pCheckB.checkState() == QtCore.Qt.CheckState.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() == \
|
|
|
|
QtCore.Qt.CheckState.PartiallyChecked:
|
|
|
|
return ''
|
|
|
|
elif self.pCheckB.checkState() == QtCore.Qt.CheckState.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(QtCore.Qt.CheckState.Checked)
|
|
|
|
elif text.lower() in ['no', 'off']:
|
|
|
|
self.pCheckB.setCheckState(QtCore.Qt.CheckState.Unchecked)
|
|
|
|
else:
|
|
|
|
self.pCheckB.setCheckState(QtCore.Qt.CheckState.PartiallyChecked)
|
|
|
|
self.change_label()
|
|
|
|
|
|
|
|
def setCheckable(self, set_bool):
|
|
|
|
self.pCheckB.setCheckable(set_bool)
|
|
|
|
|
|
|
|
def _setDisabled(self):
|
|
|
|
self.pCheckB.disabled = True
|
|
|
|
|
|
|
|
class QComboWgt(QtGui.QLabel):
|
|
|
|
currentIndexChanged = QtCore.Signal(int)
|
|
|
|
def __init__(self, parent = None):
|
|
|
|
QtGui.QLabel.__init__(self, parent)
|
|
|
|
self.layout = QtGui.QVBoxLayout(self)
|
|
|
|
self.layout.setContentsMargins(0,0,0,0)
|
|
|
|
self.ComboBox = QtGui.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 (QtGui.QListWidget):
|
|
|
|
def __init__(self, parent):
|
|
|
|
QtGui.QListWidget.__init__(self, 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 (QtGui.QWidget):
|
|
|
|
""" Widget opens a dialog multiple select """
|
|
|
|
def __init__(self, parent, Available_dict, Available_list, Selected_list, \
|
|
|
|
add_ability):
|
|
|
|
super(MultipleChoiceDialog, self).__init__()
|
|
|
|
self._parent = parent
|
|
|
|
self.layout = QtGui.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 = QtGui.QSizePolicy.Policy.Maximum
|
|
|
|
exp = QtGui.QSizePolicy.Policy.Expanding
|
|
|
|
# if there is a possibility of adding
|
|
|
|
if add_ability:
|
|
|
|
add_line_wgt = QtGui.QWidget(self)
|
|
|
|
add_line_layout = QtGui.QHBoxLayout(add_line_wgt)
|
|
|
|
# add "input new items" LineEdit
|
|
|
|
self.add_LineEdit = QtGui.QLineEdit(self)
|
|
|
|
self.add_LineEdit.setSizePolicy(exp, minimum)
|
|
|
|
add_line_layout.addWidget(self.add_LineEdit)
|
|
|
|
|
|
|
|
# add "add new items" PushButton
|
|
|
|
self.add_Button = QtGui.QPushButton(self)
|
|
|
|
self.add_Button.setFixedWidth(32)
|
|
|
|
try:
|
|
|
|
self.add_Button.setIcon(QtGui.QIcon.fromTheme("list-add"))
|
|
|
|
except:
|
|
|
|
self.add_Button.setText('Add Item')
|
|
|
|
self.add_Button.setShortcut \
|
|
|
|
(QtGui.QKeySequence(QtCore.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 = QtGui.QLabel('Available values', self)
|
|
|
|
self.available_label.setSizePolicy(exp, minimum)
|
|
|
|
self.layout.addWidget(self.available_label, 1,0,1,2)
|
|
|
|
|
|
|
|
self.selected_label = QtGui.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 = QtGui.QWidget(self)
|
|
|
|
p_m_layout = QtGui.QVBoxLayout(p_m_wgt)
|
|
|
|
|
|
|
|
# add '++' button
|
|
|
|
self.plus_all_Button = QtGui.QPushButton(self)
|
|
|
|
plus_all_icons = ['go-last-view', 'go-last']
|
|
|
|
for icon in plus_all_icons:
|
|
|
|
icon_next = QtGui.QIcon.fromTheme(icon)
|
|
|
|
if not icon_next.isNull():
|
|
|
|
self.plus_all_Button.setIcon(icon_next)
|
|
|
|
break
|
|
|
|
if icon_next.isNull():
|
|
|
|
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 = QtGui.QPushButton(self)
|
|
|
|
plus_icons = ['go-next-view','go-next']
|
|
|
|
for icon in plus_icons:
|
|
|
|
icon_next = QtGui.QIcon.fromTheme(icon)
|
|
|
|
if not icon_next.isNull():
|
|
|
|
self.plus_Button.setIcon(icon_next)
|
|
|
|
break
|
|
|
|
if icon_next.isNull():
|
|
|
|
self.plus_Button.setText('->')
|
|
|
|
self.plus_Button.clicked.connect(self.plus_item)
|
|
|
|
p_m_layout.addWidget(self.plus_Button)
|
|
|
|
|
|
|
|
# add '-' button
|
|
|
|
self.minus_Button = QtGui.QPushButton(self)
|
|
|
|
minus_icons = ['go-previous-view','go-previous']
|
|
|
|
for icon in minus_icons:
|
|
|
|
icon_prev = QtGui.QIcon.fromTheme(icon)
|
|
|
|
if not icon_prev.isNull():
|
|
|
|
self.minus_Button.setIcon(icon_prev)
|
|
|
|
break
|
|
|
|
if icon_prev.isNull():
|
|
|
|
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 = QtGui.QPushButton(self)
|
|
|
|
minus_all_icons = ['go-first-view', 'go-first']
|
|
|
|
for icon in minus_all_icons:
|
|
|
|
icon_next = QtGui.QIcon.fromTheme(icon)
|
|
|
|
if not icon_next.isNull():
|
|
|
|
self.minus_all_Button.setIcon(icon_next)
|
|
|
|
break
|
|
|
|
if icon_next.isNull():
|
|
|
|
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 = QtGui.QWidget(self)
|
|
|
|
buttons_layout = QtGui.QHBoxLayout(buttons_wgt)
|
|
|
|
# add OK button
|
|
|
|
self.Ok_Button = QtGui.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 = QtGui.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, QtCore.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 = []
|
|
|
|
for i in range(self.right_ListWidget.count()):
|
|
|
|
text = self.right_ListWidget.takeItem(0).text()
|
|
|
|
if text in self.Available_dict:
|
|
|
|
self._parent.Selected.append(self.Available_dict[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 self.Available_dict:
|
|
|
|
self._parent.avail.append(self.Available_dict[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 [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return]:
|
|
|
|
if hasattr (self, 'add_Button'):
|
|
|
|
self.add_new_item()
|
|
|
|
|
|
|
|
class MultipleButton(QtGui.QPushButton):
|
|
|
|
def __init__(self, text, parent):
|
|
|
|
QtGui.QPushButton.__init__(self, text, parent)
|
|
|
|
self.setStyleSheet("text-align: left; padding: 3px;")
|
|
|
|
self.setFocusPolicy(QtCore.Qt.NoFocus)
|
|
|
|
|
|
|
|
def mousePressEvent(self, button = None):
|
|
|
|
self.parent().mousePressEvent()
|
|
|
|
|
|
|
|
class MultipleChoice (QtGui.QWidget):
|
|
|
|
Changed = QtCore.Signal()
|
|
|
|
# multiple-choice widget displayed in the table
|
|
|
|
def __init__(self, parent, Available_list, Selected, comments, \
|
|
|
|
add_ability = False, expert = False):
|
|
|
|
super(MultipleChoice, self).__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 = QtGui.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 = QtGui.QSizePolicy.Policy.Maximum
|
|
|
|
exp = QtGui.QSizePolicy.Policy.Expanding
|
|
|
|
self.lbl.setSizePolicy(exp, maximum)
|
|
|
|
layout.addWidget(self.lbl)
|
|
|
|
|
|
|
|
self.button=QtGui.QToolButton(self)
|
|
|
|
# self.button.hide()
|
|
|
|
self.button.setFocusPolicy(QtCore.Qt.NoFocus)
|
|
|
|
try:
|
|
|
|
self.button.setIcon(QtGui.QIcon.fromTheme("list-add"))
|
|
|
|
except:
|
|
|
|
self.button.setText('+')
|
|
|
|
self.button.setStyleSheet("border: none;")
|
|
|
|
self.button.setFixedWidth(24)
|
|
|
|
self.button.clicked.connect(self.mousePressEvent)
|
|
|
|
layout.addWidget(self.button, QtCore.Qt.AlignRight)
|
|
|
|
|
|
|
|
if expert:
|
|
|
|
self.clear_button = QtGui.QPushButton(self)
|
|
|
|
self.clear_button.setFocusPolicy(QtCore.Qt.NoFocus)
|
|
|
|
try:
|
|
|
|
self.clear_button.setIcon(QtGui.QIcon.fromTheme('edit-clear'))
|
|
|
|
except:
|
|
|
|
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, QtCore.Qt.AlignRight)
|
|
|
|
|
|
|
|
self.setAttribute(QtCore.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.setAttribute(QtCore.Qt.WA_ShowModal)
|
|
|
|
self.MCD.move(QtGui.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.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 (QtGui.QWidget):
|
|
|
|
def __init__(self, parent, text):
|
|
|
|
QtGui.QWidget.__init__(self)
|
|
|
|
layout = QtGui.QHBoxLayout(self)
|
|
|
|
self.add_line = QtGui.QLineEdit(self)
|
|
|
|
self.add_line.setFixedWidth(100)
|
|
|
|
add_button = QtGui.QPushButton(text, self)
|
|
|
|
close_button = QtGui.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(QtGui.QCursor.pos())
|
|
|
|
self.show()
|
|
|
|
|
|
|
|
class MultipleCheckBox(QtGui.QCheckBox):
|
|
|
|
def __init__(self, parent):
|
|
|
|
QtGui.QCheckBox.__init__(self, parent)
|
|
|
|
|
|
|
|
class SelectTable(QtGui.QWidget):
|
|
|
|
Changed = QtCore.Signal()
|
|
|
|
# multiple-choice table
|
|
|
|
def __init__(self, parent, Available_list, Selected, comments, \
|
|
|
|
add_ability = False, expert = False, default = None):
|
|
|
|
QtGui.QWidget.__init__(self, 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 = QtGui.QGridLayout(self)
|
|
|
|
self.grid.setContentsMargins(0, 0, 0, 0)
|
|
|
|
self.grid.setSpacing(0)
|
|
|
|
self.grid.setAlignment(QtCore.Qt.AlignTop)
|
|
|
|
|
|
|
|
unit_layout = QtGui.QHBoxLayout()
|
|
|
|
unit_layout.setContentsMargins(0, 0, 0, 0)
|
|
|
|
unit_layout.setSpacing(0)
|
|
|
|
|
|
|
|
if add_ability:
|
|
|
|
plus_but = QtGui.QPushButton(self)
|
|
|
|
try:
|
|
|
|
plus_but.setIcon(QtGui.QIcon.fromTheme('list-add'))
|
|
|
|
except:
|
|
|
|
plus_but.setText('+')
|
|
|
|
|
|
|
|
plus_but.setToolTip(_('Add a row'))
|
|
|
|
plus_but.setFixedWidth(30)
|
|
|
|
plus_but.clicked.connect(self.line_add)
|
|
|
|
unit_layout.addWidget(plus_but)
|
|
|
|
|
|
|
|
self.recover_but = QtGui.QPushButton(self)
|
|
|
|
try:
|
|
|
|
self.recover_but.setIcon(QtGui.QIcon.fromTheme('edit-clear'))
|
|
|
|
except:
|
|
|
|
self.recover_but.setText('R')
|
|
|
|
|
|
|
|
self.recover_but.setToolTip(_('Recover the table'))
|
|
|
|
self.recover_but.setFixedWidth(30)
|
|
|
|
|
|
|
|
self.recover_but.clicked.connect(self.recover_table)
|
|
|
|
|
|
|
|
unit_layout.addWidget(self.recover_but)
|
|
|
|
|
|
|
|
unit_layout.setAlignment(QtCore.Qt.AlignLeft)
|
|
|
|
self.grid.addLayout(unit_layout, 0,0)
|
|
|
|
|
|
|
|
self.table = QtGui.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 = QtGui.QTableWidgetItem('')
|
|
|
|
tablewidgetitem.setBackground(QtGui.QBrush(QtGui.QColor \
|
|
|
|
('#dddddd')))
|
|
|
|
self.table.setItem(0, i, tablewidgetitem)
|
|
|
|
|
|
|
|
all_check = QtGui.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 = QtGui.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(QtGui.QAbstractItemView.NoEditTriggers)
|
|
|
|
|
|
|
|
self.table.setSelectionMode \
|
|
|
|
(QtGui.QAbstractItemView.SelectionMode.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 = QtCore.Qt.CheckState.Checked
|
|
|
|
else:
|
|
|
|
check = QtCore.Qt.CheckState.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() == \
|
|
|
|
QtCore.Qt.CheckState.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(QtCore.Qt.CheckState.PartiallyChecked)
|
|
|
|
if hard_auto:
|
|
|
|
cb.setCheckState(QtCore.Qt.CheckState.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 = QtGui.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() == \
|
|
|
|
QtCore.Qt.CheckState.PartiallyChecked:
|
|
|
|
return []
|
|
|
|
if self.table.cellWidget(row, 0).checkState() == \
|
|
|
|
QtCore.Qt.CheckState.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(QtGui.QGroupBox):
|
|
|
|
Changed = QtCore.Signal()
|
|
|
|
def __init__(self, parent, label, Available_list, Selected, comments, \
|
|
|
|
add_ability = False, expert = False, default = None):
|
|
|
|
QtGui.QGroupBox.__init__(self, 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 = QtGui.QGridLayout(self)
|
|
|
|
self.grid.setContentsMargins(0,0,0,0)
|
|
|
|
self.grid.setSpacing(4)
|
|
|
|
self.grid.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft)
|
|
|
|
|
|
|
|
buttons_layout = QtGui.QHBoxLayout()
|
|
|
|
buttons_layout.setAlignment(QtCore.Qt.AlignLeft)
|
|
|
|
buttons_layout.setContentsMargins(0,0,0,0)
|
|
|
|
if add_ability:
|
|
|
|
self.plus_but = QtGui.QPushButton(self)
|
|
|
|
self.plus_but.setFocusPolicy(QtCore.Qt.NoFocus)
|
|
|
|
self.plus_but.setFixedWidth(30)
|
|
|
|
try:
|
|
|
|
self.plus_but.setIcon(QtGui.QIcon.fromTheme('list-add'))
|
|
|
|
except:
|
|
|
|
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 = QtGui.QPushButton(self)
|
|
|
|
self.recover_but.setFocusPolicy(QtCore.Qt.NoFocus)
|
|
|
|
self.recover_but.setFixedWidth(30)
|
|
|
|
try:
|
|
|
|
self.recover_but.setIcon(QtGui.QIcon.fromTheme('edit-undo'))
|
|
|
|
except:
|
|
|
|
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 = QtGui.QCheckBox(self.comments[row])
|
|
|
|
item.setFocusPolicy(QtCore.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(QtCore.Qt.CheckState.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 transparent;'
|
|
|
|
'border-top-color: gray;'
|
|
|
|
'border-left-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,'
|
|
|
|
'stop: 0 gray, stop: 0.7 gray, stop: 1 transparent);'
|
|
|
|
|
|
|
|
'border-right-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,'
|
|
|
|
'stop: 0 gray, stop: 0.7 gray, stop: 1 transparent);'
|
|
|
|
|
|
|
|
'background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,'
|
|
|
|
'stop: 0 #eeeeee, stop: 0.8 transparent, stop: 1 transparent);'
|
|
|
|
'border-bottom: 0px;'
|
|
|
|
'border-top-left-radius: 4px;'
|
|
|
|
'border-top-right-radius: 4px;}'
|
|
|
|
|
|
|
|
'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() == \
|
|
|
|
QtCore.Qt.CheckState.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 = QtGui.QCheckBox(text)
|
|
|
|
item.setFocusPolicy(QtCore.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 = QtGui.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(QtCore.Qt.CheckState.PartiallyChecked)
|
|
|
|
if hard_auto:
|
|
|
|
item.setCheckState(QtCore.Qt.CheckState.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() == \
|
|
|
|
QtCore.Qt.CheckState.PartiallyChecked:
|
|
|
|
return []
|
|
|
|
if self.CheckBoxList[row].checkState() == \
|
|
|
|
QtCore.Qt.CheckState.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 (QtGui.QPushButton):
|
|
|
|
# multiple-choice widget displayed in the table
|
|
|
|
def __init__(self, label, parent):
|
|
|
|
QtGui.QPushButton.__init__(self)
|
|
|
|
self.setStyleSheet('''QPushButton:pressed {border: none;}
|
|
|
|
QPushButton::hover {border: none;}''')
|
|
|
|
layout = QtGui.QHBoxLayout(self)
|
|
|
|
|
|
|
|
layout.setContentsMargins(0,8,0,0)
|
|
|
|
layout.setSpacing(5)
|
|
|
|
|
|
|
|
self.image_lbl = QtGui.QLabel(self)
|
|
|
|
self.images = ['draw-triangle2', 'media-playback-start']
|
|
|
|
layout.addWidget(self.image_lbl)
|
|
|
|
|
|
|
|
self.text_lbl = QtGui.QLabel(label, self)
|
|
|
|
self.setFocusPolicy(QtCore.Qt.NoFocus)
|
|
|
|
layout.addWidget(self.text_lbl)
|
|
|
|
layout.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
|
|
|
|
|
|
|
|
def set_close(self):
|
|
|
|
themeName = QtGui.QIcon.themeName()
|
|
|
|
self.icon = QtGui.QIcon()
|
|
|
|
for image in self.images:
|
|
|
|
self.icon.setThemeName(themeName)
|
|
|
|
self.icon = self.icon.fromTheme(image)
|
|
|
|
if not self.icon.isNull():
|
|
|
|
break
|
|
|
|
self.icon.setThemeName('Tango')
|
|
|
|
self.icon = self.icon.fromTheme(image)
|
|
|
|
if not self.icon.isNull():
|
|
|
|
break
|
|
|
|
|
|
|
|
pm = self.icon.pixmap(16)
|
|
|
|
pm = pm.scaled(QtCore.QSize(16, 16), QtCore.Qt.KeepAspectRatio, \
|
|
|
|
QtCore.Qt.SmoothTransformation)
|
|
|
|
|
|
|
|
self.image_lbl.setPixmap(pm)
|
|
|
|
self.image_lbl.setAlignment(QtCore.Qt.AlignLeft)
|
|
|
|
|
|
|
|
# add transparency
|
|
|
|
self.image_lbl.setAttribute(QtCore.Qt.WA_NoSystemBackground)
|
|
|
|
|
|
|
|
def set_open(self):
|
|
|
|
themeName = QtGui.QIcon.themeName()
|
|
|
|
self.icon = QtGui.QIcon()
|
|
|
|
for image in self.images:
|
|
|
|
self.icon.setThemeName(themeName)
|
|
|
|
self.icon = self.icon.fromTheme(image)
|
|
|
|
if not self.icon.isNull():
|
|
|
|
break
|
|
|
|
self.icon.setThemeName('Tango')
|
|
|
|
self.icon = self.icon.fromTheme(image)
|
|
|
|
if not self.icon.isNull():
|
|
|
|
break
|
|
|
|
|
|
|
|
pm = self.icon.pixmap(16)
|
|
|
|
|
|
|
|
pm = pm.scaled(QtCore.QSize(16, 16), QtCore.Qt.KeepAspectRatio, \
|
|
|
|
QtCore.Qt.SmoothTransformation)
|
|
|
|
|
|
|
|
pm = pm.transformed(QtGui.QTransform().rotate(90))
|
|
|
|
self.image_lbl.setPixmap(pm)
|
|
|
|
self.image_lbl.setAlignment(QtCore.Qt.AlignCenter)
|
|
|
|
|
|
|
|
# add transparency
|
|
|
|
self.image_lbl.setAttribute(QtCore.Qt.WA_NoSystemBackground)
|
|
|
|
|
|
|
|
class FlowLayout(QtGui.QLayout):
|
|
|
|
def __init__(self, parent=None, margin=0, spacing=-1):
|
|
|
|
super(FlowLayout, self).__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 QtCore.Qt.Orientations(QtCore.Qt.Orientation(0))
|
|
|
|
|
|
|
|
def hasHeightForWidth(self):
|
|
|
|
return True
|
|
|
|
|
|
|
|
def heightForWidth(self, width):
|
|
|
|
height = self.doLayout(QtCore.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 = QtCore.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 \
|
|
|
|
(QtGui.QSizePolicy.PushButton, \
|
|
|
|
QtGui.QSizePolicy.PushButton, QtCore.Qt.Horizontal)
|
|
|
|
spaceY = self.spacing() + wid.style().layoutSpacing \
|
|
|
|
(QtGui.QSizePolicy.PushButton, \
|
|
|
|
QtGui.QSizePolicy.PushButton, QtCore.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(QtCore.QRect(QtCore.QPoint(x, y), \
|
|
|
|
item.sizeHint()))
|
|
|
|
|
|
|
|
x = nextX
|
|
|
|
lineHeight = max(lineHeight, item.sizeHint().height())
|
|
|
|
return y + lineHeight - rect.y()
|
|
|
|
|
|
|
|
class PlusRow (QtGui.QWidget):
|
|
|
|
""" Widget opens a dialog multiple select """
|
|
|
|
def __init__(self, parent, table, field, changed = False, num_row = None):
|
|
|
|
QtGui.QWidget.__init__(self)
|
|
|
|
|
|
|
|
self.grid = QtGui.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 = {}
|
|
|
|
|
|
|
|
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 = QtGui.QLabel(name, self)
|
|
|
|
lbl.setAlignment(QtCore.Qt.AlignRight| QtCore.Qt.AlignVCenter)
|
|
|
|
self.grid.addWidget(lbl, x, y)
|
|
|
|
|
|
|
|
self.widget_dict[str(i)] = QtGui.QLineEdit(self)
|
|
|
|
if field.value:
|
|
|
|
self.widget_dict[str(i)].setText(field.value)
|
|
|
|
if field.type == 'int':
|
|
|
|
self.rx = QtCore.QRegExp ("^[\d]{1,50}$")
|
|
|
|
self.validator = QtGui.QRegExpValidator(self.rx, self)
|
|
|
|
self.widget_dict[str(i)].setValidator(self.validator)
|
|
|
|
elif field.type == 'float':
|
|
|
|
self.rx = QtCore.QRegExp ("^[\d]{1,50}[.][\d]{1,50}$")
|
|
|
|
self.validator = QtGui.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 = QtGui.QLabel(name, self)
|
|
|
|
lbl.setAlignment(QtCore.Qt.AlignRight| QtCore.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, \
|
|
|
|
QtCore.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 = QtGui.QLabel(name, self)
|
|
|
|
lbl.setAlignment(QtCore.Qt.AlignRight| QtCore.Qt.AlignVCenter)
|
|
|
|
self.grid.addWidget(lbl, x, y)
|
|
|
|
self.ComboBox = QtGui.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 = QtGui.QLabel(name, self)
|
|
|
|
lbl.setAlignment(QtCore.Qt.AlignRight| QtCore.Qt.AlignVCenter)
|
|
|
|
self.grid.addWidget(lbl, x, y)
|
|
|
|
self.ComboBox = QtGui.QComboBox(self)
|
|
|
|
self.ComboBox.setDuplicatesEnabled(False)
|
|
|
|
self.ComboBox.setEditable(True)
|
|
|
|
self.ComboBox.setLineEdit(QtGui.QLineEdit(self))
|
|
|
|
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 = QtGui.QLabel(name, self)
|
|
|
|
lbl.setAlignment(QtCore.Qt.AlignRight| QtCore.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(QtCore.Qt.AlignRight| QtCore.Qt.AlignVCenter)
|
|
|
|
lbl2 = LabelWordWrap(_('Repeat'), self)
|
|
|
|
lbl2.setAlignment(QtCore.Qt.AlignRight| QtCore.Qt.AlignVCenter)
|
|
|
|
|
|
|
|
layout = QtGui.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 not self.widget_dict.has_key('0'):
|
|
|
|
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 [QtGui.QComboBox, QtGui.QLineEdit]:
|
|
|
|
index_widget.textChanged.connect(self.change_readonly \
|
|
|
|
(i, values, comments, index_comment, index_values))
|
|
|
|
|
|
|
|
# add OK button
|
|
|
|
self.button_layout = QtGui.QHBoxLayout()
|
|
|
|
self.Ok_Button = QtGui.QPushButton('Ok', self)
|
|
|
|
self.Ok_Button.setFixedWidth(128)
|
|
|
|
self.Ok_Button.setShortcut(QtGui.QKeySequence(QtCore.Qt.Key_Return))
|
|
|
|
self.Ok_Button.clicked.connect(self.ok_pressed)
|
|
|
|
self.button_layout.addWidget(self.Ok_Button)
|
|
|
|
|
|
|
|
# add Cancel button
|
|
|
|
self.Cancel_Button = QtGui.QPushButton('Cancel', self)
|
|
|
|
self.Cancel_Button.setFixedWidth(128)
|
|
|
|
self.Ok_Button.setShortcut(QtGui.QKeySequence(QtCore.Qt.Key_Escape))
|
|
|
|
self.Cancel_Button.clicked.connect(self.close)
|
|
|
|
self.button_layout.addWidget(self.Cancel_Button)
|
|
|
|
self.button_layout.setAlignment(QtCore.Qt.AlignRight)
|
|
|
|
self.grid.addLayout(self.button_layout,x,y,1,2,QtCore.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 not self.widget_dict.has_key(str(i)):
|
|
|
|
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)]) == QtGui.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, \
|
|
|
|
QtGui.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 = QtGui.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 \
|
|
|
|
(QtCore.Qt.ItemIsEditable)
|
|
|
|
brush = QtGui.QBrush(QtCore.Qt.black)
|
|
|
|
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 = QtGui.QTableWidgetItem()
|
|
|
|
self.table.setItem(row, column, tablewidgetitem)
|
|
|
|
|
|
|
|
self.table.item(row, column).setFlags(QtCore.Qt.ItemIsEditable)
|
|
|
|
font = self.table.item(row, column).font()
|
|
|
|
font.setWeight(QtGui.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\
|
|
|
|
(QtGui.QHeaderView.ResizeMode.ResizeToContents)
|
|
|
|
self.table.setColor()
|
|
|
|
self.close()
|
|
|
|
|
|
|
|
class PasswordWgt(QtGui.QWidget):
|
|
|
|
# answer to the server question
|
|
|
|
def __init__(self, parent, text):
|
|
|
|
super(PasswordWgt, self).__init__()
|
|
|
|
self._parent = parent
|
|
|
|
self.text = text
|
|
|
|
if parent.label:
|
|
|
|
self.setWindowTitle(parent.label)
|
|
|
|
|
|
|
|
self.layout = QtGui.QGridLayout(self)
|
|
|
|
|
|
|
|
self.pass_edit = QtGui.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 = QtGui.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 = QtGui.QPushButton(_('Ok'), self)
|
|
|
|
self.ok_button.setShortcut(QtGui.QKeySequence(QtCore.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 = QtGui.QPushButton(_('Cancel'), self)
|
|
|
|
self.cancel_button.setShortcut(QtGui.QKeySequence \
|
|
|
|
(QtCore.Qt.Key_Escape))
|
|
|
|
self.cancel_button.clicked.connect(self.close)
|
|
|
|
self.layout.addWidget(self.cancel_button,2,1)
|
|
|
|
self.resize(self.sizeHint() + QtCore.QSize(40,0))
|
|
|
|
self.setFixedHeight(self.sizeHint().height())
|
|
|
|
self.move(QtGui.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(QtGui.QLineEdit):
|
|
|
|
def __init__(self, parent, text = '', label = ''):
|
|
|
|
QtGui.QLineEdit.__init__(self)
|
|
|
|
|
|
|
|
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.setAttribute(QtCore.Qt.WA_ShowModal)
|
|
|
|
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(QtGui.QWidget):
|
|
|
|
def __init__(self, parent, lbl1, lbl2):
|
|
|
|
QtGui.QWidget.__init__(self)
|
|
|
|
self.layout = QtGui.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 = QtGui.QLineEdit(self)
|
|
|
|
self.pass_edit.setEchoMode(self.pass_edit.Password)
|
|
|
|
|
|
|
|
self.layout.addWidget(self.pass_edit)
|
|
|
|
|
|
|
|
self.pass_edit2 = QtGui.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(QtGui.QVBoxLayout):
|
|
|
|
def __init__(self, parent):
|
|
|
|
QtGui.QVBoxLayout.__init__(self, parent)
|
|
|
|
self.setAlignment(QtCore.Qt.AlignTop)
|
|
|
|
# self.setDirection(QtGui.QBoxLayout.TopToBottom)
|
|
|
|
self.setContentsMargins(28,28,28,10)
|
|
|
|
self.setSpacing(2)
|
|
|
|
|
|
|
|
self.kill_process_button = QtGui.QPushButton(_('Break the process'))
|
|
|
|
self.kill_process_button.setFixedWidth(144)
|
|
|
|
self.kill_process_button.setContentsMargins(0,10,0,0)
|
|
|
|
self.kill_process_button.setMinimumHeight(
|
|
|
|
self.kill_process_button.minimumSizeHint().height())
|
|
|
|
self.kill_process_button.setMaximumHeight(
|
|
|
|
self.kill_process_button.minimumSizeHint().height())
|
|
|
|
self.addWidget(self.kill_process_button)
|
|
|
|
|
|
|
|
def _addWidget(self, widget):
|
|
|
|
self.removeWidget(self.kill_process_button)
|
|
|
|
self.addWidget(widget)
|
|
|
|
self.addWidget(self.kill_process_button)
|
|
|
|
|
|
|
|
def hide_kill_button(self):
|
|
|
|
self.removeWidget(self.kill_process_button)
|
|
|
|
self.kill_process_button.close()
|
|
|
|
|
|
|
|
class LabelTaskWgt(QtGui.QLabel):
|
|
|
|
def __init__(self, name, parent = None):
|
|
|
|
QtGui.QLabel.__init__(self, name, parent)
|
|
|
|
self.setStyleSheet("color: #B3ABA7;")
|
|
|
|
|
|
|
|
def sizeHint(self):
|
|
|
|
self.br_ = QtGui.QFontMetrics(self.font()).boundingRect('')
|
|
|
|
return self.br_.size()
|
|
|
|
|
|
|
|
def paintEvent(self, e):
|
|
|
|
p = QtGui.QPainter(self)
|
|
|
|
fm = p.fontMetrics()
|
|
|
|
y = (self.sizeHint().height() - self.br_.height()) / 2 + fm.ascent()
|
|
|
|
|
|
|
|
dot_w = fm.width('. ')
|
|
|
|
for x in xrange (0, self.width(), dot_w):
|
|
|
|
p.drawText(x, y, '. ')
|
|
|
|
|
|
|
|
class TaskWidget(QtGui.QWidget):
|
|
|
|
def __init__(self, text = '', parent = None):
|
|
|
|
QtGui.QWidget.__init__(self)
|
|
|
|
self._layout = QtGui.QHBoxLayout(self)
|
|
|
|
|
|
|
|
self.text = QtGui.QLabel(text, self)
|
|
|
|
fm = QtGui.QFontMetrics(self.text.font())
|
|
|
|
d_w = fm.width(text)
|
|
|
|
pref = QtGui.QSizePolicy.Policy.Preferred
|
|
|
|
exp = QtGui.QSizePolicy.Policy.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,4,0,4)
|
|
|
|
self._layout.setSpacing(8)
|
|
|
|
self.set_status = False
|
|
|
|
|
|
|
|
def set_ok(self):
|
|
|
|
if not self.set_status:
|
|
|
|
point_lbl = LabelTaskWgt('', self)
|
|
|
|
self._layout.addWidget(point_lbl)
|
|
|
|
|
|
|
|
self.image_lbl = QtGui.QLabel(self)
|
|
|
|
self.image_lbl.setFixedSize(16,16)
|
|
|
|
|
|
|
|
self._layout.addWidget(self.image_lbl)
|
|
|
|
|
|
|
|
self._layout.setStretch(0,0)
|
|
|
|
self._layout.setStretch(1,5)
|
|
|
|
|
|
|
|
i_path = '/usr/share/icons/Calculate/16x16/client-gui/console_ok'
|
|
|
|
icon = QtGui.QIcon(i_path)
|
|
|
|
self.image_lbl.setPixmap(icon.pixmap(16))
|
|
|
|
self.set_status = True
|
|
|
|
|
|
|
|
def set_error(self):
|
|
|
|
if not self.set_status:
|
|
|
|
point_lbl = LabelTaskWgt('', self)
|
|
|
|
self._layout.addWidget(point_lbl)
|
|
|
|
|
|
|
|
self.image_lbl = QtGui.QLabel(self)
|
|
|
|
self.image_lbl.setFixedSize(16,16)
|
|
|
|
|
|
|
|
self._layout.addWidget(self.image_lbl)
|
|
|
|
self._layout.setStretch(0,0)
|
|
|
|
self._layout.setStretch(1,5)
|
|
|
|
|
|
|
|
i_path = '/usr/share/icons/Calculate/16x16/client-gui/' \
|
|
|
|
'console_cancel'
|
|
|
|
icon = QtGui.QIcon(i_path)
|
|
|
|
self.image_lbl.setPixmap(icon.pixmap(16))
|
|
|
|
self.set_status = True
|
|
|
|
|
|
|
|
class ButtonsWidget(QtGui.QWidget):
|
|
|
|
def __init__(self, parent = None):
|
|
|
|
QtGui.QWidget.__init__(self, parent)
|
|
|
|
self.layout = QtGui.QHBoxLayout(self)
|
|
|
|
|
|
|
|
self.layout.setContentsMargins(0,0,0,0)
|
|
|
|
self.layout.setSpacing(0)
|
|
|
|
self.layout.setAlignment(QtCore.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))
|
|
|
|
|
|
|
|
def show_msg(text, title = None, parent = None):
|
|
|
|
msgBox = QtGui.QMessageBox(parent)
|
|
|
|
if title:
|
|
|
|
msgBox.setWindowTitle(title)
|
|
|
|
if not text:
|
|
|
|
return 1
|
|
|
|
if not type(text) in [str,unicode]:
|
|
|
|
temp = ''
|
|
|
|
for i in text:
|
|
|
|
try:
|
|
|
|
temp += str(i).decode('utf-8')+' '
|
|
|
|
except (UnicodeEncodeError, UnicodeDecodeError):
|
|
|
|
temp += str(i)+' '
|
|
|
|
text = temp
|
|
|
|
msgBox.setText(text)
|
|
|
|
msgBox.setStandardButtons(QtGui.QMessageBox.Ok)
|
|
|
|
msgBox.setWindowIcon (QtGui.QIcon('calculate-install.png'))
|
|
|
|
msgBox.exec_()
|
|
|
|
|
|
|
|
def show_question(parent, text, informative_text = None, cursor_pos = False,
|
|
|
|
not_move = False, title = None):
|
|
|
|
msgBox = QtGui.QMessageBox()
|
|
|
|
msgBox.setText(text)
|
|
|
|
msgBox.setInformativeText(informative_text)
|
|
|
|
msgBox.setStandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
|
|
|
|
msgBox.setDefaultButton(QtGui.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(QtGui.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, e:
|
|
|
|
show_msg (e.value)
|
|
|
|
return 1
|
|
|
|
return 0
|
|
|
|
|
|
|
|
class ClientSignal(QtCore.QThread):
|
|
|
|
sid_sig = QtCore.Signal(int, int)
|
|
|
|
connect_count = QtCore.Signal(str, int, int)
|
|
|
|
def __init__(self, ClientObj):
|
|
|
|
QtCore.QThread.__init__(self)
|
|
|
|
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, 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 1
|
|
|
|
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.core.client.function import get_ip_mac_type
|
|
|
|
from calculate.lib.utils import ip as ip_mod
|
|
|
|
|
|
|
|
def get_ip_mac():
|
|
|
|
for Interfaces in ip_mod.getInterfaces():
|
|
|
|
try:
|
|
|
|
ip, mac, client_type = 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, 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, 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
|
|
|
|
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(QtCore.QThread):
|
|
|
|
signal = QtCore.Signal(object)
|
|
|
|
signal_extended = QtCore.Signal(object, object)
|
|
|
|
def __init__(self, ClientObj, method_name, parameters_object, \
|
|
|
|
second_params = None, third_params = None, \
|
|
|
|
return_except = False, sleeptime = None, \
|
|
|
|
through_object = None):
|
|
|
|
QtCore.QThread.__init__(self)
|
|
|
|
self.ClientObj = ClientObj
|
|
|
|
self.method_name = method_name
|
|
|
|
self.parameters_object = parameters_object
|
|
|
|
self.second_params = second_params
|
|
|
|
self.third_params = third_params
|
|
|
|
self.return_except = return_except
|
|
|
|
self.sleeptime = sleeptime
|
|
|
|
self.through_object = through_object
|
|
|
|
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:
|
|
|
|
if self.second_params == None:
|
|
|
|
result = client.service[0][self.method_name] \
|
|
|
|
(self.parameters_object)
|
|
|
|
elif self.third_params == None:
|
|
|
|
result = client.service[0][self.method_name] \
|
|
|
|
(self.parameters_object, self.second_params)
|
|
|
|
else:
|
|
|
|
result = client.service[0][self.method_name] \
|
|
|
|
(self.parameters_object, self.second_params, \
|
|
|
|
self.third_params)
|
|
|
|
|
|
|
|
except Exception, 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(QtGui.QLabel):
|
|
|
|
def __init__(self, image, height_image, parent):
|
|
|
|
QtGui.QLabel.__init__(self)
|
|
|
|
# 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 = ''
|
|
|
|
|
|
|
|
if len(list_data) == 3:
|
|
|
|
fix_image_path = os.path.join(image_path, list_data[2])
|
|
|
|
if os.path.isfile(fix_image_path):
|
|
|
|
layout = QtGui.QHBoxLayout(self)
|
|
|
|
fix_image = QtGui.QLabel(self)
|
|
|
|
img = Image.open(fix_image_path)
|
|
|
|
img.thumbnail((img.size[0],height_image), Image.ANTIALIAS)
|
|
|
|
temp_file = os.path.join(save_path, '%s_fix' %filename)
|
|
|
|
img.save(temp_file, "JPEG")
|
|
|
|
os.chmod(temp_file, 0666)
|
|
|
|
fix_image.setFixedWidth(img.size[0])
|
|
|
|
fix_image.setStyleSheet("background-image: url(%s); " \
|
|
|
|
%temp_file)
|
|
|
|
layout.addWidget(fix_image)
|
|
|
|
layout.setContentsMargins(0,0,0,0)
|
|
|
|
layout.setAlignment(QtCore.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)
|
|
|
|
|
|
|
|
im = Image.open(image)
|
|
|
|
im.thumbnail((im.size[0],height_image), Image.ANTIALIAS)
|
|
|
|
temp_file = os.path.join(save_path, '%s_temp' %filename)
|
|
|
|
im.save(temp_file, "JPEG")
|
|
|
|
os.chmod(temp_file, 0666)
|
|
|
|
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(im.size[1])
|
|
|
|
|
|
|
|
def get_view_params(client, method, step = None, expert = None, brief = None):
|
|
|
|
view_params = 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 [open(cmdLineFile,'r').read().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')))
|