def initialize(self, title, text):
        """
        Initialize QDialog for UserNotesQDialog

        :param title: title of the QDialog
        :type title: str
        :param text: text to edit
        :type text: str
        """

        self.old_text = text
        center_widget(self)

        # Main status_layout
        main_layout = QVBoxLayout(self)
        main_layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(main_layout)

        main_layout.addWidget(get_logo_widget(self, title))

        text_title = QLabel(_("Edit your text:"))
        text_title.setObjectName('subtitle')
        main_layout.addWidget(text_title)
        main_layout.setAlignment(text_title, Qt.AlignCenter)

        main_layout.addWidget(self.get_text_widget())
    def initialize(self, title, text):
        """
        Initialize QDialog for UserNotesQDialog

        :param title: title of the QDialog
        :type title: str
        :param text: text to edit
        :type text: str
        """

        self.old_text = text
        center_widget(self)

        # Main status_layout
        main_layout = QVBoxLayout(self)
        main_layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(main_layout)

        main_layout.addWidget(get_logo_widget(self, title))

        text_title = QLabel(_("Edit your text:"))
        text_title.setObjectName('subtitle')
        main_layout.addWidget(text_title)
        main_layout.setAlignment(text_title, Qt.AlignCenter)

        main_layout.addWidget(self.get_text_widget())
Example #3
0
    def _setup_ui(self):
        self.setFixedWidth(300)

        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setAlignment(Qt.AlignTop)

        layout.addWidget(ImageInfo())
        layout.addWidget(ProcessList())

        self.setLayout(layout)
    def initialize_synthesis(self):
        """
        Initialize Synthesis QWidget

        """

        synthesis_layout = QVBoxLayout()
        synthesis_layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(synthesis_layout)

        # Search widget
        search_widget = self.get_search_widget()
        synthesis_layout.addWidget(search_widget)

        # Host widget
        self.host_widget.initialize()
        self.host_widget.setMaximumHeight(self.width() * 0.5)
        synthesis_layout.addWidget(self.host_widget)

        # Hint Widget
        hint_text = _(
            '<h4>Dahsboard</h4>'
            '<ul><li>At the top of App, '
            'you have a dashboard that summarizes the number of items per state.</li></ul>'
            '<h4>Tabs</h4>'
            '<ul><li><h4>Host Synthesis</h4></li>'
            'Tap in the search bar to view a host and its services.'
            '<li><h4>Problems</h4></li>'
            'The "Problems" tab will show you all problems detected in your backend.'
            '<li><h4>Spy Hosts</h4></li>'
            'A "Spy Host" will keep you regularly informed of his condition. '
            'You will also see problems detected for this host, in the "Spy Hosts" panel.</ul>'
            '<h4>Alignak</h4>'
            '<ul><li>You can see your backend status and daemons if available, '
            'as well as your profile.</li></ul>'
            '<h4>Livestate</h4>'
            '<ul><li>In the livestate, you can see global state of your monitored items.</li></ul>'
            '<h4>Events</h4>'
            '<ul><li>Events will show you informative messages your actions inside App.</li></ul>'
        )
        hint_layout = QVBoxLayout(self.hint_widget)
        hint_label = QLabel(hint_text)
        hint_label.setObjectName('subtitle')
        hint_layout.addWidget(hint_label)
        synthesis_layout.addWidget(self.hint_widget)

        # Services widget
        self.services_widget.initialize()
        synthesis_layout.addWidget(self.services_widget)

        # Align all widgets to Top
        synthesis_layout.setAlignment(Qt.AlignTop)
    def initialize_synthesis(self):
        """
        Initialize Synthesis QWidget

        """

        synthesis_layout = QVBoxLayout()
        synthesis_layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(synthesis_layout)

        # Search widget
        search_widget = self.get_search_widget()
        synthesis_layout.addWidget(search_widget)

        # Host widget
        self.host_widget.initialize()
        self.host_widget.setMaximumHeight(self.width() * 0.5)
        synthesis_layout.addWidget(self.host_widget)

        # Hint Widget
        hint_text = _(
            '<h4>Dahsboard</h4>'
            '<ul><li>At the top of App, '
            'you have a dashboard that summarizes the number of items per state.</li></ul>'
            '<h4>Tabs</h4>'
            '<ul><li><h4>Host Synthesis</h4></li>'
            'Tap in the search bar to view a host and its services.'
            '<li><h4>Problems</h4></li>'
            'The "Problems" tab will show you all problems detected in your backend.'
            '<li><h4>Spy Hosts</h4></li>'
            'A "Spy Host" will keep you regularly informed of his condition. '
            'You will also see problems detected for this host, in the "Spy Hosts" panel.</ul>'
            '<h4>Alignak</h4>'
            '<ul><li>You can see your backend status and daemons if available, '
            'as well as your profile.</li></ul>'
            '<h4>Livestate</h4>'
            '<ul><li>In the livestate, you can see global state of your monitored items.</li></ul>'
            '<h4>Events</h4>'
            '<ul><li>Events will show you informative messages your actions inside App.</li></ul>'
        )
        hint_layout = QVBoxLayout(self.hint_widget)
        hint_label = QLabel(hint_text)
        hint_label.setObjectName('subtitle')
        hint_layout.addWidget(hint_label)
        synthesis_layout.addWidget(self.hint_widget)

        # Services widget
        self.services_widget.initialize()
        synthesis_layout.addWidget(self.services_widget)

        # Align all widgets to Top
        synthesis_layout.setAlignment(Qt.AlignTop)
Example #6
0
    def initialize(self):
        """
        Initialize QDialog for PasswordDialog

        """

        center_widget(self)

        # Main status_layout
        main_layout = QVBoxLayout(self)
        main_layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(main_layout)

        main_layout.addWidget(get_logo_widget(self, _('Edit Password')))

        pass_title = QLabel(_("Please type a new PASSWORD:"******"Your password must contain at least 5 characters."))
        self.help_label.setWordWrap(True)
        pass_layout.addWidget(self.help_label)

        # Accept button
        accept_btn = QPushButton('Confirm', self)
        accept_btn.clicked.connect(self.handle_confirm)
        accept_btn.setObjectName('valid')
        accept_btn.setMinimumHeight(30)
        pass_layout.addWidget(accept_btn)

        main_layout.addWidget(pass_widget)
Example #7
0
    def initialize(self):
        """
        Initialize the QWidget

        """

        layout = QVBoxLayout(self)
        layout.setSpacing(0)

        title_lbl = QLabel('%s - %s' % (__application__, __version__))
        title_lbl.setAlignment(Qt.AlignCenter)
        title_lbl.setObjectName('start')
        title_lbl.setFixedHeight(30)
        layout.addWidget(title_lbl)

        self.progress_bar.setFixedHeight(30)
        layout.addWidget(self.progress_bar)

        layout.setAlignment(Qt.AlignCenter)
    def get_actions_widget(self):
        """
        Return QWidget with actions buttons

        :return: widget with buttons
        :rtype: QWidget
        """

        widget = QWidget()
        layout = QVBoxLayout()
        widget.setLayout(layout)

        action_title = QLabel(_('Actions:'))
        action_title.setObjectName('title')
        layout.addWidget(action_title)

        self.actions_widget.initialize(self.service_item)
        layout.addWidget(self.actions_widget)

        layout.setAlignment(Qt.AlignCenter)

        return widget
    def get_message_widget(self, dialog, title, text):
        """
        Return colored message QWidget

        :param dialog: type of dialog ('text' or 'error')
        :type dialog: str
        :param title: title of text to display
        :type title: str
        :param text: text to display
        :type text: str
        :return: message QWidget
        :rtype: QWidget
        """

        # Token QWidget
        token_widget = QWidget()
        token_widget.setObjectName('dialog')
        token_layout = QVBoxLayout()
        token_widget.setLayout(token_layout)

        token_title = QLabel(title)
        token_title.setObjectName('itemtitle')
        token_layout.addWidget(token_title)
        token_layout.setAlignment(token_title, Qt.AlignCenter)

        token_label = QLabel(text)
        token_label.setObjectName(dialog)
        token_label.setTextInteractionFlags(Qt.TextSelectableByMouse)
        token_label.setWordWrap(True)
        token_layout.addWidget(token_label)

        # Login button
        accept_btn = QPushButton('OK', self)
        accept_btn.clicked.connect(self.accept)
        accept_btn.setObjectName('ok')
        accept_btn.setMinimumHeight(30)
        token_layout.addWidget(accept_btn)

        return token_widget
    def get_actions_widget(self):
        """
        Return QWidget with actions buttons

        :return: widget with buttons
        :rtype: QWidget
        """

        widget = QWidget()
        layout = QVBoxLayout()
        widget.setLayout(layout)

        action_title = QLabel(_('Actions:'))
        action_title.setObjectName('title')
        layout.addWidget(action_title)

        self.actions_widget.initialize(self.service_item)
        layout.addWidget(self.actions_widget)

        layout.setAlignment(Qt.AlignCenter)

        return widget
    def get_message_widget(self, dialog, title, text):
        """
        Return colored message QWidget

        :param dialog: type of dialog ('text' or 'error')
        :type dialog: str
        :param title: title of text to display
        :type title: str
        :param text: text to display
        :type text: str
        :return: message QWidget
        :rtype: QWidget
        """

        # Token QWidget
        token_widget = QWidget()
        token_widget.setObjectName('dialog')
        token_layout = QVBoxLayout()
        token_widget.setLayout(token_layout)

        token_title = QLabel(title)
        token_title.setObjectName('itemtitle')
        token_layout.addWidget(token_title)
        token_layout.setAlignment(token_title, Qt.AlignCenter)

        token_label = QLabel(text)
        token_label.setObjectName(dialog)
        token_label.setTextInteractionFlags(Qt.TextSelectableByMouse)
        token_label.setWordWrap(True)
        token_layout.addWidget(token_label)

        # Login button
        accept_btn = QPushButton('OK', self)
        accept_btn.clicked.connect(self.accept)
        accept_btn.setObjectName('ok')
        accept_btn.setMinimumHeight(30)
        token_layout.addWidget(accept_btn)

        return token_widget
    def get_service_icon_widget(self):
        """
        Return QWidget with its icon and name

        :return: widget with icon and name
        :rtype: QWidget
        """

        widget = QWidget()
        layout = QVBoxLayout()
        widget.setLayout(layout)

        # Host Icon
        layout.addWidget(self.labels['service_icon'])
        layout.setAlignment(self.labels['service_icon'], Qt.AlignCenter)

        # Host Name
        self.labels['service_name'].setObjectName('itemname')
        self.labels['service_name'].setWordWrap(True)
        layout.addWidget(self.labels['service_name'])
        layout.setAlignment(self.labels['service_name'], Qt.AlignCenter)

        return widget
    def get_service_icon_widget(self):
        """
        Return QWidget with its icon and name

        :return: widget with icon and name
        :rtype: QWidget
        """

        widget = QWidget()
        layout = QVBoxLayout()
        widget.setLayout(layout)

        # Host Icon
        layout.addWidget(self.labels['service_icon'])
        layout.setAlignment(self.labels['service_icon'], Qt.AlignCenter)

        # Host Name
        self.labels['service_name'].setObjectName('itemname')
        self.labels['service_name'].setWordWrap(True)
        layout.addWidget(self.labels['service_name'])
        layout.setAlignment(self.labels['service_name'], Qt.AlignCenter)

        return widget
Example #14
0
    def get_item_type_widget(self, item_type, problem_nb, total_nb):
        """
        Create and return QWidget with backend data

        :param item_type: type of item: host, service, problem
        :type item_type: str
        :param problem_nb: number of problems for item type
        :type problem_nb: int
        :param total_nb: total number of item type
        :type total_nb: int
        :return: widget with its data
        :rtype: QWidget
        """

        layout = QVBoxLayout()
        widget = QWidget()
        widget.setLayout(layout)

        problem_label = QLabel('%d' % problem_nb)
        problem_label.setObjectName('ok')
        problem_label.setToolTip(
            _('Number of unhandled %s problems') % (
                item_type if 'problem' not in item_type else ''
            )
        )
        layout.addWidget(problem_label)
        layout.setAlignment(problem_label, Qt.AlignCenter)

        icon_label = QLabel()
        icon_label.setFixedSize(64, 64)
        icon_label.setScaledContents(True)
        layout.addWidget(icon_label)
        layout.setAlignment(icon_label, Qt.AlignCenter)

        total_label = QLabel('%d' % total_nb)
        total_label.setObjectName('total')
        total_label.setToolTip(
            _('Number of monitored %s') % (
                item_type if 'problem' not in item_type else 'items'
            )
        )
        layout.addWidget(total_label)
        layout.setAlignment(total_label, Qt.AlignCenter)

        self.labels[item_type] = {
            'problem': problem_label,
            'icon': icon_label,
            'total': total_label
        }

        return widget
    def get_host_icon_widget(self):
        """
        Return QWidget with overall icon state and host name

        :return: widget with host name and icon
        :rtype: QWidget
        """

        widget = QWidget()
        layout = QVBoxLayout()
        widget.setLayout(layout)

        # Host Icon
        layout.addWidget(self.labels['host_icon'])
        layout.setAlignment(self.labels['host_icon'], Qt.AlignCenter)

        # Host Name
        self.labels['host_name'].setObjectName('itemname')
        self.labels['host_name'].setWordWrap(True)
        layout.addWidget(self.labels['host_name'])
        layout.setAlignment(self.labels['host_name'], Qt.AlignCenter)

        # Customs button
        customs_lbl = QLabel(_('Configuration:'))
        customs_lbl.setObjectName('subtitle')
        layout.addWidget(customs_lbl)
        layout.setAlignment(customs_lbl, Qt.AlignBottom)
        self.customs_btn.setIcon(QIcon(settings.get_image('settings')))
        self.customs_btn.setFixedSize(80, 20)
        self.customs_btn.clicked.connect(self.show_customs)
        layout.addWidget(self.customs_btn)
        layout.setAlignment(self.customs_btn, Qt.AlignCenter)

        # Initialize Customs QWidget
        self.customs_widget.initialize()

        return widget
    def get_host_icon_widget(self):
        """
        Return QWidget with overall icon state and host name

        :return: widget with host name and icon
        :rtype: QWidget
        """

        widget = QWidget()
        layout = QVBoxLayout()
        widget.setLayout(layout)

        # Host Icon
        layout.addWidget(self.labels['host_icon'])
        layout.setAlignment(self.labels['host_icon'], Qt.AlignCenter)

        # Host Name
        self.labels['host_name'].setObjectName('itemname')
        self.labels['host_name'].setWordWrap(True)
        layout.addWidget(self.labels['host_name'])
        layout.setAlignment(self.labels['host_name'], Qt.AlignCenter)

        # Customs button
        customs_lbl = QLabel(_('Configuration:'))
        customs_lbl.setObjectName('subtitle')
        layout.addWidget(customs_lbl)
        layout.setAlignment(customs_lbl, Qt.AlignBottom)
        self.customs_btn.setIcon(QIcon(settings.get_image('settings')))
        self.customs_btn.setFixedSize(80, 20)
        self.customs_btn.clicked.connect(self.show_customs)
        layout.addWidget(self.customs_btn)
        layout.setAlignment(self.customs_btn, Qt.AlignCenter)

        # Initialize Customs QWidget
        self.customs_widget.initialize()

        return widget
    def get_proxy_widget(self):
        """
        Return the proxy QWidget

        :return: proxy QWidget
        :rtype: QWidget
        """

        proxy_widget = QWidget()
        proxy_widget.setObjectName('dialog')
        proxy_layout = QVBoxLayout(proxy_widget)

        # Title
        title_lbl = QLabel(_('Proxy Settings'))
        title_lbl.setObjectName('itemtitle')
        proxy_layout.addWidget(title_lbl)
        proxy_layout.setAlignment(title_lbl, Qt.AlignTop)

        # Description
        desc_label = QLabel(
            _('Here you can define your proxy. Be sure to enter a valid address.')
        )
        desc_label.setWordWrap(True)
        proxy_layout.addWidget(desc_label)

        # Proxy Settings
        proxy_lbl = QLabel(_('Proxy Address with Port'))
        proxy_layout.addWidget(proxy_lbl)

        proxy = settings.get_config('Alignak', 'proxy')
        self.proxy_address.setText(proxy)
        self.proxy_address.setPlaceholderText(_('proxy adress:port...'))
        self.proxy_address.setFixedHeight(25)
        proxy_layout.addWidget(self.proxy_address)

        # Proxy User
        proxy_user_lbl = QLabel(_('Proxy User (Optional)'))
        proxy_layout.addWidget(proxy_user_lbl)

        proxy_user = settings.get_config('Alignak', 'proxy_user')
        self.proxy_user.setText(proxy_user)
        self.proxy_user.setPlaceholderText(_('proxy user...'))
        self.proxy_user.setFixedHeight(25)
        proxy_layout.addWidget(self.proxy_user)

        # Proxy Password
        proxy_password_lbl = QLabel(_('Proxy Password (Optional)'))
        proxy_layout.addWidget(proxy_password_lbl)

        if settings.get_config('Alignak', 'proxy_password'):
            self.proxy_password.setText(settings.get_config('Alignak', 'proxy_password'))
        self.proxy_password.setPlaceholderText(_('proxy password...'))
        self.proxy_password.setFixedHeight(25)
        self.proxy_password.setEchoMode(QLineEdit.Password)
        proxy_layout.addWidget(self.proxy_password)

        # Valid Button
        valid_btn = QPushButton(_('Valid'))
        valid_btn.setObjectName('valid')
        valid_btn.setMinimumHeight(30)
        valid_btn.clicked.connect(self.accept_proxy)

        proxy_layout.addWidget(valid_btn)

        return proxy_widget
Example #18
0
class Enlargement(QMdiSubWindow, form_Enlargement.Ui_frmEnlargement):

    # create "resized" as a signal that the window can emit
    # we respond to this signal with the form's resizeMe method below
    resized = pyqtSignal()

    class MyGraphicsView(QGraphicsView):
        def __init__(self):
            QGraphicsView.__init__(self)
            self.setRenderHints(QPainter.Antialiasing
                                | QPainter.SmoothPixmapTransform)
            self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
            self.setDragMode(QGraphicsView.ScrollHandDrag)
            self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
            self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
            self.mdiParent = ""

        def wheelEvent(self, event):
            adj = 1 + event.angleDelta().y() / 120 * 0.1
            self.scale(adj, adj)

        # we need a keepress event handler here in case the user clicks on the photo.
        # when user clicks on the photo, the keypress handler is this GraphicsView, not the Englargement class.
        def keyPressEvent(self, e):

            # F key is pressed. Re-display the currentEnlargement to fit the screen
            if e.key() == Qt.Key_F:
                self.mdiParent.fitEnlargement()

            # Backspace key is pressed, so show previous image as enlargement
            if e.key() == Qt.Key_Backspace:
                self.mdiParent.showPreviousPhoto()

            # Space bar is pressed, so show next image as enlargement
            if e.key() == Qt.Key_Space:
                self.mdiParent.showNextPhoto()

            # F7 is pressed, so toggle display of cursor
            if e.key() == Qt.Key_F7:
                self.mdiParent.toggleHideCursor()

            # F9 is pressed, so toggle display of camera details
            if e.key() == Qt.Key_F9:
                self.mdiParent.toggleCameraDetails()

            # F11 is pressed, so toggle display of camera details
            if e.key() == Qt.Key_F11:
                self.mdiParent.toggleFullScreen()

            # Esc is pressed, so exit full screen mode, if we're in it
            if e.key(
            ) == Qt.Key_Escape and self.mdiParent.mdiParent.mdiParent.statusBar.isVisible(
            ) is False:
                self.mdiParent.toggleFullScreen()

            # 1-5 pressed, so rate the photo
            if e.key() in [
                    Qt.Key_0, Qt.Key_1, Qt.Key_2, Qt.Key_3, Qt.Key_4, Qt.Key_5
            ]:
                self.mdiParent.ratePhoto(e.key())

            # Right is pressed: show next photo
            if e.key() == Qt.Key_Right or e.key() == Qt.Key_PageDown:
                self.mdiParent.showNextPhoto()

            # Left is pressed: show previous photo
            if e.key() == Qt.Key_Left or e.key() == Qt.Key_PageUp:
                self.mdiParent.showPreviousPhoto()

        def contextMenuEvent(self, event):

            QApplication.restoreOverrideCursor()

            menu = QMenu(self)
            menu.setStyleSheet("color:silver; background-color: #343333;")

            actionFitToWindow = menu.addAction("Fit to window (F)")
            menu.addSeparator()
            actionShowNextPhoto = menu.addAction("Next photo (Right arrow)")
            actionShowPreviousPhoto = menu.addAction(
                "Previous photo (Left arrow)")
            menu.addSeparator()

            if self.mdiParent.isMaximized() is True:
                if self.mdiParent.cursorIsVisible:
                    actionToggleHideCursor = menu.addAction("Hide cursor (F7)")
                else:
                    actionToggleHideCursor = menu.addAction("Show cursor (F7)")

            if self.mdiParent.detailsPane.isVisible():
                actionToggleCameraDetails = menu.addAction("Hide details (F9)")
            else:
                actionToggleCameraDetails = menu.addAction("Show details (F9)")

            if self.mdiParent.isMaximized(
            ) and self.mdiParent.mdiParent.mdiParent.isFullScreen():
                actionToggleFullScreen = menu.addAction(
                    "Exit full screen (F11)")
            else:
                actionToggleFullScreen = menu.addAction("Full screen (F11)")

            menu.addSeparator()
            actionDetachFile = menu.addAction("Detach photo from Yearbird")
            menu.addSeparator()
            actionDeleteFile = menu.addAction("Delete photo from file system")

            action = menu.exec_(self.mapToGlobal(event.pos()))

            if self.mdiParent.isMaximized() is True:
                if action == actionToggleHideCursor:
                    self.parent().toggleHideCursor()

            if action == actionFitToWindow:
                self.parent().fitEnlargement()

            if action == actionShowNextPhoto:
                self.parent().showNextPhoto()

            if action == actionShowPreviousPhoto:
                self.parent().showPreviousPhoto()

            if action == actionToggleCameraDetails:
                self.parent().toggleCameraDetails()

            if action == actionToggleFullScreen:
                self.parent().toggleFullScreen()

            if action == actionDeleteFile:
                self.parent().deleteFile()

            if action == actionDetachFile:
                self.parent().detachFile()

    def __init__(self):
        super(self.__class__, self).__init__()
        self.setupUi(self)
        self.setAttribute(Qt.WA_DeleteOnClose, True)
        self.resized.connect(self.resizeMe)
        self.mdiParent = ""
        self.photoList = []
        self.currentIndex = 0

        self.pixmapEnlargement = QPixmap()

        self.layout().setDirection(1)
        self.layout().setContentsMargins(0, 0, 0, 0)
        self.layout().setSpacing(0)
        self.setStyleSheet("color:silver; background-color: #343333")

        self.detailsPaneLayout = QVBoxLayout()
        self.detailsPaneLayout.setContentsMargins(0, 0, 0, 0)
        self.detailsPaneLayout.setSpacing(0)
        self.detailsPaneLayout.setAlignment(Qt.AlignCenter)

        self.detailsPane = QFrame()
        self.detailsPane.setLayout(self.detailsPaneLayout)
        self.detailsPane.setStyleSheet(
            "color:silver; background-color: #343333")

        self.layout().addWidget(self.detailsPane)

        # create label for species common name
        self.commonName = QLabel()
        self.commonName.setStyleSheet(
            "font:12pt; font-weight:bold; color:silver; background-color: #343333; padding: 3px"
        )
        self.detailsPaneLayout.addWidget(self.commonName)

        # create label for species scientific name
        self.scientificName = QLabel()
        self.scientificName.setStyleSheet(
            "font:12pt; font-style:italic; color:silver; background-color: #343333; padding: 3px"
        )
        self.detailsPaneLayout.addWidget(self.scientificName)

        # create label for camera details text
        self.cameraDetails = QLabel()
        self.cameraDetails.setStyleSheet(
            "color:silver; background-color: #343333; padding: 3px")
        self.detailsPane.setVisible(False)
        self.detailsPaneLayout.addWidget(self.cameraDetails)

        # create horizontal layout to show rating stars
        self.horizontalGroupBox = QGroupBox()
        self.horizontalGroupBox.setContentsMargins(0, 0, 0, 0)
        self.horizontalGroupBox.setStyleSheet(
            "background-color: #343333; padding: 3px")

        self.detailsPaneLayout.addWidget(self.horizontalGroupBox)

        ratingLayout = QHBoxLayout()
        ratingLayout.setContentsMargins(0, 0, 0, 0)
        ratingLayout.setSpacing(0)

        self.star1 = QPushButton()
        self.star2 = QPushButton()
        self.star3 = QPushButton()
        self.star4 = QPushButton()
        self.star5 = QPushButton()

        self.star1.setIconSize(QSize(40, 40))
        self.star2.setIconSize(QSize(40, 40))
        self.star3.setIconSize(QSize(40, 40))
        self.star4.setIconSize(QSize(40, 40))
        self.star5.setIconSize(QSize(40, 40))

        self.star1.setStyleSheet(
            "QPushButton:pressed{ background-color: #343333; }")
        self.star1.setStyleSheet(
            "QPushButton:hover{ background-color: #343333; }")
        self.star1.setStyleSheet(
            "QPushButton:flat{ background-color: #343333; }")
        self.star1.setStyleSheet(
            "QPushButton{ background-color: #343333; border:none }")
        self.star2.setStyleSheet(
            "QPushButton:pressed{ background-color: #343333; }")
        self.star2.setStyleSheet(
            "QPushButton:hover{ background-color: #343333; }")
        self.star2.setStyleSheet(
            "QPushButton:flat{ background-color: #343333; }")
        self.star2.setStyleSheet(
            "QPushButton{ background-color: #343333; border:none }")
        self.star3.setStyleSheet(
            "QPushButton:pressed{ background-color: #343333; }")
        self.star3.setStyleSheet(
            "QPushButton:hover{ background-color: #343333; }")
        self.star3.setStyleSheet(
            "QPushButton:flat{ background-color: #343333; }")
        self.star3.setStyleSheet(
            "QPushButton{ background-color: #343333; border:none }")
        self.star4.setStyleSheet(
            "QPushButton:pressed{ background-color: #343333; }")
        self.star4.setStyleSheet(
            "QPushButton:hover{ background-color: #343333; }")
        self.star4.setStyleSheet(
            "QPushButton:flat{ background-color: #343333; }")
        self.star4.setStyleSheet(
            "QPushButton{ background-color: #343333; border:none }")
        self.star5.setStyleSheet(
            "QPushButton:pressed{ background-color: #343333; }")
        self.star5.setStyleSheet(
            "QPushButton:hover{ background-color: #343333; }")
        self.star5.setStyleSheet(
            "QPushButton:flat{ background-color: #343333; }")
        self.star5.setStyleSheet(
            "QPushButton{ background-color: #343333; border:none }")

        self.star1.setIcon(QIcon(QPixmap(":/icon_star.png")))
        self.star2.setIcon(QIcon(QPixmap(":/icon_star.png")))
        self.star3.setIcon(QIcon(QPixmap(":/icon_star.png")))
        self.star4.setIcon(QIcon(QPixmap(":/icon_star.png")))
        self.star5.setIcon(QIcon(QPixmap(":/icon_star.png")))

        self.star1.clicked.connect(lambda: self.ratePhoto(Qt.Key_1, "Clicked"))
        self.star2.clicked.connect(lambda: self.ratePhoto(Qt.Key_2))
        self.star3.clicked.connect(lambda: self.ratePhoto(Qt.Key_3))
        self.star4.clicked.connect(lambda: self.ratePhoto(Qt.Key_4))
        self.star5.clicked.connect(lambda: self.ratePhoto(Qt.Key_5))

        ratingLayout.addWidget(self.star1)
        ratingLayout.addWidget(self.star2)
        ratingLayout.addWidget(self.star3)
        ratingLayout.addWidget(self.star4)
        ratingLayout.addWidget(self.star5)

        self.horizontalGroupBox.setLayout(ratingLayout)

        self.cursorIsVisible = True

    def resizeEvent(self, event):
        #routine to handle window resize event
        self.resized.emit()
        return super(self.__class__, self).resizeEvent(event)

    def resizeMe(self):

        QTimer.singleShot(5, self.fitEnlargement)

    def scaleMe(self):

        return

    def keyPressEvent(self, e):

        # F key is pressed. Re-display the currentEnlargement to fit the screen
        if e.key() == Qt.Key_F:
            self.fitEnlargement()

        # Backspace key is pressed, so show previous image as enlargement
        if e.key() == Qt.Key_Backspace:
            self.showPreviousPhoto()

        # Space bar is pressed, so show next image as enlargement
        if e.key() == Qt.Key_Space:
            self.showNextPhoto()

        # F7 is pressed, so toggle display of cursor
        if e.key() == Qt.Key_F7:
            self.toggleHideCursor()

        # F9 is pressed, so toggle display of camera details
        if e.key() == Qt.Key_F9:
            self.toggleCameraDetails()

        # F11 is pressed, so toggle display of camera details
        if e.key() == Qt.Key_F11:
            self.toggleFullScreen()

        # Esc is pressed, so exit full screen mode, if we're in it
        if e.key(
        ) == Qt.Key_Escape and self.mdiParent.mdiParent.statusBar.isVisible(
        ) is False:
            self.toggleFullScreen()

        # 1-5 pressed, so rate the photo
        if e.key() in [
                Qt.Key_0, Qt.Key_1, Qt.Key_2, Qt.Key_3, Qt.Key_4, Qt.Key_5
        ]:
            self.ratePhoto(e.key())

        # Right is pressed: show next photo
        if e.key() == Qt.Key_Right or e.key() == Qt.Key_PageDown:
            self.showNextPhoto()

        # Left is pressed: show previous photo
        if e.key() == Qt.Key_Left or e.key() == Qt.Key_PageUp:
            self.showPreviousPhoto()

    def ratePhoto(self, ratingKey, actionType=""):

        if ratingKey == Qt.Key_0:
            self.photoList[self.currentIndex][0]["rating"] = "0"
        if ratingKey == Qt.Key_1:
            if self.photoList[self.currentIndex][0][
                    "rating"] == "1" and actionType == "Clicked":
                self.photoList[self.currentIndex][0]["rating"] = "0"
            else:
                self.photoList[self.currentIndex][0]["rating"] = "1"
        if ratingKey == Qt.Key_2:
            self.photoList[self.currentIndex][0]["rating"] = "2"
        if ratingKey == Qt.Key_3:
            self.photoList[self.currentIndex][0]["rating"] = "3"
        if ratingKey == Qt.Key_4:
            self.photoList[self.currentIndex][0]["rating"] = "4"
        if ratingKey == Qt.Key_5:
            self.photoList[self.currentIndex][0]["rating"] = "5"

        self.setCameraDetails()
        self.detailsPane.setVisible(True)
        self.mdiParent.mdiParent.db.photosNeedSaving = True
        self.viewEnlargement.setFocus()

    def showPreviousPhoto(self):

        if self.currentIndex > 0:
            self.currentIndex = self.currentIndex - 1

        if self.currentIndex >= 0:
            self.changeEnlargement()

    def showNextPhoto(self):

        if self.currentIndex < len(self.photoList) - 1:
            self.currentIndex += 1
            self.changeEnlargement()

    def fillEnlargement(self):

        # routine uses self.currentIndex to fill the right photo
        self.pixmapEnlargement = QPixmap(
            self.photoList[self.currentIndex][0]["fileName"])

        self.sceneEnlargement = QGraphicsScene()
        # save the item ID of the pixmap so we can replace the pixmap photo easily later
        self.itemPixmap = self.sceneEnlargement.addPixmap(
            self.pixmapEnlargement)

        self.viewEnlargement = self.MyGraphicsView()
        self.viewEnlargement.mdiParent = self
        self.viewEnlargement.setScene(self.sceneEnlargement)
        self.viewEnlargement.setStyleSheet(
            "QWidget{ background-color: #343333;}")

        # add viewEnlargementto the default layout of the form
        self.layout().addWidget(self.viewEnlargement)

        self.setCameraDetails()

        self.setPhotoTitle()

        QTimer.singleShot(10, self.fitEnlargement)

    def changeEnlargement(self):

        self.pixmapEnlargement = QPixmap(
            self.photoList[self.currentIndex][0]["fileName"])

        self.itemPixmap.setPixmap(self.pixmapEnlargement)

        self.setCameraDetails()

        self.setPhotoTitle()

        QTimer.singleShot(20, self.fitEnlargement)

    def fitEnlargement(self):

        # scale the view to fit the photo, edge to edge
        self.viewEnlargement.setSceneRect(0, 0, self.pixmapEnlargement.width(),
                                          self.pixmapEnlargement.height())
        self.viewEnlargement.fitInView(self.viewEnlargement.sceneRect(),
                                       Qt.KeepAspectRatio)

    def setPhotoTitle(self):

        # display the file name in the window title bar
        basename = os.path.basename(
            self.photoList[self.currentIndex][0]["fileName"])
        self.setWindowTitle(basename)

    def toggleCameraDetails(self):

        # toggle visibility of cameraDetails
        if self.detailsPane.isVisible():
            self.detailsPane.setVisible(False)
        else:
            self.detailsPane.setVisible(True)

        QTimer.singleShot(10, self.fitEnlargement)

    def toggleHideCursor(self):

        # toggle visibility of the cursor

        # abort if we're not full screen (don't want to confuse user by hiding cursor)
        if not self.isMaximized():
            return ()

        # abort if we're not full screen (don't want to confuse user by hiding cursor)
        if not self.mdiParent.mdiParent.isFullScreen():
            return ()

        if self.cursorIsVisible is True:
            QApplication.setOverrideCursor(QCursor(Qt.BlankCursor))
            self.cursorIsVisible = False
        else:
            QApplication.restoreOverrideCursor()
            self.cursorIsVisible = True

    def detachFile(self):

        # remove photo from database, but don't delete it from file system
        msgText = "Detach \n\n" + self.photoList[
            self.currentIndex][0]["fileName"] + "\n\n from Yearbird?"
        msgText = msgText + "\n\n(File will NOT be deleted from file system)"

        msg = QMessageBox()
        msg.setText(msgText)
        msg.setWindowTitle("Detach photo?")
        msg.setStandardButtons(QMessageBox.No | QMessageBox.Yes)
        buttonClicked = msg.exec_()

        if buttonClicked == QMessageBox.Yes:

            # remove photo from database
            currentPhoto = self.photoList[self.currentIndex][0]["fileName"]
            photoCommonName = self.photoList[
                self.currentIndex][1]["commonName"]
            photoLocation = self.photoList[self.currentIndex][1]["location"]

            self.mdiParent.mdiParent.db.removePhotoFromDatabase(
                photoLocation, "", "", photoCommonName, currentPhoto)

            # remove photo from current window's photo list
            self.photoList.remove(self.photoList[self.currentIndex])

            # refresh display of parent photo list
            self.mdiParent.FillPhotos(self.mdiParent.filter)

            # advance display to next photo
            if len(self.photoList) == 0:
                self.close()

            if self.currentIndex < len(self.photoList):
                self.changeEnlargement()

            else:
                self.currentIndex -= 1
                self.changeEnlargement()

            # set flag for requiring photo file save
            self.mdiParent.mdiParent.db.photosNeedSaving = True

    def deleteFile(self):

        # remove photo from database, but don't delete it from file system
        msgText = "Permanently delete \n\n" + self.photoList[
            self.currentIndex][0][
                "fileName"] + "\n\n from Yearbird and the file system?"

        msg = QMessageBox()
        msg.setText(msgText)
        msg.setWindowTitle("Permanently delete photo?")
        msg.setStandardButtons(QMessageBox.No | QMessageBox.Yes)
        buttonClicked = msg.exec_()

        if buttonClicked == QMessageBox.Yes:

            # remove photo from database
            currentPhoto = self.photoList[self.currentIndex][0]["fileName"]
            photoCommonName = self.photoList[
                self.currentIndex][1]["commonName"]
            photoLocation = self.photoList[self.currentIndex][1]["location"]

            self.mdiParent.mdiParent.db.removePhotoFromDatabase(
                photoLocation, "", "", photoCommonName, currentPhoto)

            # remove photo from current window's photo list
            self.photoList.remove(self.photoList[self.currentIndex])

            # advance display to next photo
            if len(self.photoList) == 0:
                self.close()

            if self.currentIndex < len(self.photoList):
                self.changeEnlargement()

            else:
                self.currentIndex -= 1
                self.changeEnlargement()

            # set flag for requiring photo file save
            self.mdiParent.mdiParent.db.photosNeedSaving = True

            # delete file from file system
            if os.path.isfile(currentPhoto):
                try:
                    os.remove(currentPhoto)
                except:
                    pass

            # refresh display of parent photo list
            self.mdiParent.FillPhotos(self.mdiParent.filter)

    def toggleFullScreen(self):

        # toggle visibility of filter and menu bar
        if not self.mdiParent.mdiParent.isFullScreen() is True:

            self.mdiParent.mdiParent.dckFilter.setVisible(False)
            self.mdiParent.mdiParent.dckPhotoFilter.setVisible(False)
            self.mdiParent.mdiParent.menuBar.setVisible(False)
            self.mdiParent.mdiParent.toolBar.setVisible(False)
            self.mdiParent.mdiParent.statusBar.setVisible(False)
            self.setWindowFlags(Qt.FramelessWindowHint)
            self.mdiParent.mdiParent.showFullScreen()
            self.showMaximized()

        else:

            self.mdiParent.mdiParent.dckFilter.setVisible(True)
            self.mdiParent.mdiParent.dckPhotoFilter.setVisible(True)
            self.mdiParent.mdiParent.menuBar.setVisible(True)
            self.mdiParent.mdiParent.toolBar.setVisible(True)
            self.mdiParent.mdiParent.statusBar.setVisible(True)
            self.mdiParent.mdiParent.showNormal()
            self.mdiParent.mdiParent.showMaximized()
            self.setWindowFlags(Qt.SubWindow)
            self.showNormal()
            QApplication.restoreOverrideCursor()

        QTimer.singleShot(10, self.fitEnlargement)

    def setCameraDetails(self):

        currentPhoto = self.photoList[self.currentIndex][0]["fileName"]
        photoRating = self.photoList[self.currentIndex][0]["rating"]

        photoCommonName = self.photoList[self.currentIndex][1]["commonName"]
        photoScientificName = self.photoList[
            self.currentIndex][1]["scientificName"]
        photoLocation = self.photoList[self.currentIndex][1]["location"]

        # get EXIF data

        try:
            exif_dict = piexif.load(currentPhoto)
        except:
            exif_dict = ""

        # get photo date from EXIF
        try:
            photoDateTime = exif_dict["Exif"][
                piexif.ExifIFD.DateTimeOriginal].decode("utf-8")

            #parse EXIF data for date/time components
            photoExifDate = photoDateTime[0:4] + "-" + photoDateTime[
                5:7] + "-" + photoDateTime[8:10]
            photoExifTime = photoDateTime[11:13] + ":" + photoDateTime[14:16]

            photoWeekday = datetime.datetime(int(photoDateTime[0:4]),
                                             int(photoDateTime[5:7]),
                                             int(photoDateTime[8:10]))
            photoWeekday = photoWeekday.strftime("%A") + ", "

        except:
            photoExifDate = "Date unknown"
            photoExifTime = "Time unknown"
            photoWeekday = ""

        try:
            photoExifModel = exif_dict["0th"][piexif.ImageIFD.Model].decode(
                "utf-8")
        except:
            photoExifModel = ""
        try:
            photoExifLensModel = exif_dict["Exif"][
                piexif.ExifIFD.LensModel].decode("utf-8")
        except:
            photoExifLensModel = ""

        try:
            photoExifExposureTime = exif_dict["Exif"][
                piexif.ExifIFD.ExposureTime]
            photoExifExposureTime = "1/" + str(
                floor(photoExifExposureTime[1] /
                      photoExifExposureTime[0])) + " sec"
        except:
            photoExifExposureTime = ""

        try:
            photoExifAperture = exif_dict["Exif"][piexif.ExifIFD.FNumber]
            photoExifAperture = round(
                photoExifAperture[0] / photoExifAperture[1], 1)
        except:
            photoExifAperture = ""

        try:
            photoExifISO = exif_dict["Exif"][piexif.ExifIFD.ISOSpeedRatings]
        except:
            photoExifISO = ""

        try:
            photoExifFocalLength = exif_dict["Exif"][
                piexif.ExifIFD.FocalLength]
            photoExifFocalLength = floor(photoExifFocalLength[0] /
                                         photoExifFocalLength[1])
            photoExifFocalLength = str(photoExifFocalLength) + " mm"

        except:
            photoExifFocalLength = ""

        self.commonName.setText(photoCommonName)
        self.scientificName.setText(photoScientificName)

        #         detailsText = photoCommonName + "\n"
        #         detailsText = photoScientificName + "\n"
        detailsText = "\n\n" + photoLocation + "\n"
        detailsText = detailsText + photoWeekday + photoExifDate + "\n"
        detailsText = detailsText + photoExifTime + "\n"
        detailsText = detailsText + "\n"
        detailsText = detailsText + photoExifModel + "\n"
        detailsText = detailsText + photoExifLensModel + "\n"
        detailsText = detailsText + "Focal Length: " + str(
            photoExifFocalLength) + "\n"
        detailsText = detailsText + str(photoExifExposureTime) + "\n"
        detailsText = detailsText + "Aperture: " + str(
            photoExifAperture) + "\n"
        detailsText = detailsText + "ISO: " + str(photoExifISO)
        detailsText = detailsText + "\n\n" + ntpath.basename(currentPhoto)
        detailsText = detailsText + "\n\n\n"  #add space to separate rating stars from text

        if photoRating == "0":
            self.star1.setIcon(QIcon(QPixmap(":/icon_star_gray.png")))
            self.star2.setIcon(QIcon(QPixmap(":/icon_star_gray.png")))
            self.star3.setIcon(QIcon(QPixmap(":/icon_star_gray.png")))
            self.star4.setIcon(QIcon(QPixmap(":/icon_star_gray.png")))
            self.star5.setIcon(QIcon(QPixmap(":/icon_star_gray.png")))
        if photoRating == "1":
            self.star1.setIcon(QIcon(QPixmap(":/icon_star.png")))
            self.star2.setIcon(QIcon(QPixmap(":/icon_star_gray.png")))
            self.star3.setIcon(QIcon(QPixmap(":/icon_star_gray.png")))
            self.star4.setIcon(QIcon(QPixmap(":/icon_star_gray.png")))
            self.star5.setIcon(QIcon(QPixmap(":/icon_star_gray.png")))
        if photoRating == "2":
            self.star1.setIcon(QIcon(QPixmap(":/icon_star.png")))
            self.star2.setIcon(QIcon(QPixmap(":/icon_star.png")))
            self.star3.setIcon(QIcon(QPixmap(":/icon_star_gray.png")))
            self.star4.setIcon(QIcon(QPixmap(":/icon_star_gray.png")))
            self.star5.setIcon(QIcon(QPixmap(":/icon_star_gray.png")))
        if photoRating == "3":
            self.star1.setIcon(QIcon(QPixmap(":/icon_star.png")))
            self.star2.setIcon(QIcon(QPixmap(":/icon_star.png")))
            self.star3.setIcon(QIcon(QPixmap(":/icon_star.png")))
            self.star4.setIcon(QIcon(QPixmap(":/icon_star_gray.png")))
            self.star5.setIcon(QIcon(QPixmap(":/icon_star_gray.png")))
        if photoRating == "4":
            self.star1.setIcon(QIcon(QPixmap(":/icon_star.png")))
            self.star2.setIcon(QIcon(QPixmap(":/icon_star.png")))
            self.star3.setIcon(QIcon(QPixmap(":/icon_star.png")))
            self.star4.setIcon(QIcon(QPixmap(":/icon_star.png")))
            self.star5.setIcon(QIcon(QPixmap(":/icon_star_gray.png")))
        if photoRating == "5":
            self.star1.setIcon(QIcon(QPixmap(":/icon_star.png")))
            self.star2.setIcon(QIcon(QPixmap(":/icon_star.png")))
            self.star3.setIcon(QIcon(QPixmap(":/icon_star.png")))
            self.star4.setIcon(QIcon(QPixmap(":/icon_star.png")))
            self.star5.setIcon(QIcon(QPixmap(":/icon_star.png")))

        self.cameraDetails.setText(detailsText)
Example #19
0
    def get_settings_widget(self):
        """
        Return the alignak settings QWidget

        :return: settings QWidget
        :rtype: QWidget
        """

        server_widget = QWidget()
        server_widget.setObjectName('dialog')
        server_layout = QVBoxLayout(server_widget)

        # Title
        title_lbl = QLabel(_('Alignak Backend'))
        title_lbl.setObjectName('itemtitle')
        server_layout.addWidget(title_lbl)
        server_layout.setAlignment(title_lbl, Qt.AlignTop)

        # Description
        desc_label = QLabel(
            _('Here you can define alignak settings. Be sure to enter a valid address.'
              ))
        desc_label.setWordWrap(True)
        server_layout.addWidget(desc_label)

        # Server URL
        server_lbl = QLabel(_('Server'))
        server_layout.addWidget(server_lbl)

        self.server_url.setText(settings.get_config('Alignak', 'url'))
        self.server_url.setPlaceholderText(_('alignak backend url...'))
        self.server_url.setFixedHeight(25)
        server_layout.addWidget(self.server_url)

        # Server Port
        port_lbl = QLabel(_('Port'))
        server_layout.addWidget(port_lbl)

        cur_port = settings.get_config('Alignak', 'backend').split(':')[2]
        self.server_port.setText(cur_port)
        self.server_port.setPlaceholderText(_('alignak backend port...'))
        self.server_port.setFixedHeight(25)
        server_layout.addWidget(self.server_port)

        # Server Processes (displayed only for Unix platforms)
        if 'win32' not in sys.platform:
            process_lbl = QLabel(_('Processes'))
            server_layout.addWidget(process_lbl)

            cur_proc = settings.get_config('Alignak', 'processes')
            self.server_proc.setText(cur_proc)
            self.server_proc.setPlaceholderText(
                _('alignak backend processes...'))
            self.server_proc.setFixedHeight(25)
            server_layout.addWidget(self.server_proc)

        # Web Service description
        server_layout.addStretch(1)
        webservice_lbl = QLabel(_('Web Service'))
        webservice_lbl.setObjectName('itemtitle')
        server_layout.addWidget(webservice_lbl)
        ws_desc_lbl = QLabel(
            _('Here you can define your alignak web service url, with port if needed'
              ))
        ws_desc_lbl.setWordWrap(True)
        server_layout.addWidget(ws_desc_lbl)

        # Web Service URL
        self.webservice_url.setText(
            settings.get_config('Alignak', 'webservice'))
        self.webservice_url.setPlaceholderText(_('alignak webservice url...'))
        self.webservice_url.setFixedHeight(25)
        server_layout.addWidget(self.webservice_url)

        # Valid Button
        valid_btn = QPushButton(_('Valid'))
        valid_btn.setObjectName('valid')
        valid_btn.setMinimumHeight(30)
        valid_btn.clicked.connect(self.accept)

        server_layout.addWidget(valid_btn)

        return server_widget
Example #20
0
    def FillPhotosByFilter(self, filter):

        # it's tempting to think that we could use the insertPhotoIntoTable routine,
        # but we can't here, because if we're filling photos by filter, we already know
        # each photo's meta data.  The insertPhotoIntoTable routine tries to guess the
        # location, time, species, etc. from the photo file's embedded meta data.

        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

        self.scaleMe()
        self.resizeMe()

        self.fillingCombos = True

        # save the filter settings passed to this routine to the form itself for future use
        self.filter = filter

        photoSightings = self.mdiParent.db.GetSightingsWithPhotos(filter)

        if len(photoSightings) == 0:
            return False

        row = 0

        # count photos for message display
        photoCount = 0
        for s in photoSightings:
            photoCount = photoCount + len(s["photos"])
        photoCount = str(photoCount)

        for s in photoSightings:
            for p in s["photos"]:

                self.mdiParent.lblStatusBarMessage.setVisible(True)
                self.mdiParent.lblStatusBarMessage.setText(
                    "Processing photo " + str(row + 1) + " of " + photoCount)

                # p is a filename. Use it to add the image to the label as a pixmap
                buttonPhoto = QPushButton()
                buttonPhoto.setMinimumHeight(281)
                buttonPhoto.setMinimumWidth(500)

                # get thumbnail from file to display
                pixMap = self.GetPixmapForThumbnail(p["fileName"])

                buttonPhoto.setIcon(QIcon(pixMap))

                # size to 500x281
                buttonPhoto.setIconSize(QSize(500, 281))
                buttonPhoto.setStyleSheet(
                    "QPushButton {background-color: #343333; border: 0px}")

                # display thumbnail to new row in grid
                self.gridPhotos.addWidget(buttonPhoto, row, 0)

                # set up layout in second column of row to house combo boxes
                # give each object a name according to the row so we can access them later
                container = QWidget()
                container.setObjectName("container" + str(row))
                detailsLayout = QVBoxLayout(container)
                detailsLayout.setObjectName("layout" + str(row))
                detailsLayout.setAlignment(Qt.AlignTop)
                self.gridPhotos.addWidget(container, row, 1)

                # create combo boxes for details
                # add connection for when user changes a combo box
                cboLocation = QComboBox()
                cboLocation.currentIndexChanged.connect(
                    partial(self.cboLocationChanged, row))

                cboDate = QComboBox()
                cboDate.currentIndexChanged.connect(
                    partial(self.cboDateChanged, row))

                cboTime = QComboBox()
                cboTime.currentIndexChanged.connect(
                    partial(self.cboTimeChanged, row))

                cboCommonName = QComboBox()
                cboCommonName.currentIndexChanged.connect(
                    partial(self.cboCommonNameChanged, row))

                cboRating = QComboBox()
                cboRating.addItems(["Not Rated", "1", "2", "3", "4", "5"])
                cboRating.currentIndexChanged.connect(
                    partial(self.cboRatingChanged, row))

                # set stylesheet for cmbo boxes
                for c in [
                        cboLocation, cboDate, cboTime, cboCommonName, cboRating
                ]:
                    self.removeHighlight(c)

                # fill location combo box with all locations in db
                locations = self.mdiParent.db.locationList
                cboLocation.addItems(locations)

                # set location combo box to the photo's location
                index = cboLocation.findText(s["location"])
                if index >= 0:
                    cboLocation.setCurrentIndex(index)

                # fill date combo box with all dates associated with selected location
                filterForThisPhoto = code_Filter.Filter()
                filterForThisPhoto.setLocationName(s["location"])
                filterForThisPhoto.setLocationType("Location")
                dates = self.mdiParent.db.GetDates(filterForThisPhoto)
                cboDate.addItems(dates)

                # set date  combo box to the photo's associated date
                index = cboDate.findText(s["date"])
                if index >= 0:
                    cboDate.setCurrentIndex(index)

                # fill time combo box with all times associated with selected location and date
                filterForThisPhoto.setStartDate(s["date"])
                filterForThisPhoto.setEndDate(s["date"])
                startTimes = self.mdiParent.db.GetStartTimes(
                    filterForThisPhoto)
                cboTime.addItems(startTimes)

                # set time combo box to the photo's associated checklist time
                index = cboTime.findText(s["time"])
                if index >= 0:
                    cboTime.setCurrentIndex(index)

                # get common names from checklist associated with photo
                filterForThisPhoto.setChecklistID(s["checklistID"])
                commonNames = self.mdiParent.db.GetSpecies(filterForThisPhoto)

                cboCommonName.addItem("**Detach Photo**")
                cboCommonName.addItems(commonNames)

                # set combo box to common name
                index = cboCommonName.findText(s["commonName"])
                if index >= 0:
                    cboCommonName.setCurrentIndex(index)

                # set combo box to rating value
                index = int(p["rating"])
                cboRating.setCurrentIndex(index)

                # assign names to combo boxes for future access
                cboLocation.setObjectName("cboLocation" + str(row))
                cboDate.setObjectName("cboDate" + str(row))
                cboTime.setObjectName("cboTime" + str(row))
                cboCommonName.setObjectName("cboCommonName" + str(row))
                cboRating.setObjectName("cboRating" + str(row))

                # add combo boxes to the layout in second column
                detailsLayout.addWidget(cboLocation)
                detailsLayout.addWidget(cboDate)
                detailsLayout.addWidget(cboTime)
                detailsLayout.addWidget(cboCommonName)
                detailsLayout.addWidget(cboRating)

                # create and add resent button
                btnReset = QPushButton()
                btnReset.setText("Reset")
                btnReset.clicked.connect(partial(self.btnResetClicked, row))
                detailsLayout.addWidget(btnReset)

                # save meta data for future use when user clicks cbo boxes
                thisPhotoMetaData = {}
                thisPhotoMetaData["photoFileName"] = p["fileName"]
                thisPhotoMetaData["location"] = s["location"]
                thisPhotoMetaData["date"] = s["date"]
                thisPhotoMetaData["time"] = s["time"]
                thisPhotoMetaData["commonName"] = s["commonName"]
                thisPhotoMetaData["photoData"] = p
                thisPhotoMetaData["rating"] = p["rating"]

                self.metaDataByRow[row] = thisPhotoMetaData

                # initialize the "new" data so that there are values there, even if they're not really new
                # user can change the cbo boxes later, which will also change the "new" data
                self.saveNewMetaData(row)

                row = row + 1

                qApp.processEvents()

        self.mdiParent.lblStatusBarMessage.setText("")
        self.mdiParent.lblStatusBarMessage.setVisible(False)

        QApplication.processEvents()

        icon = QIcon()
        icon.addPixmap(QPixmap(":/icon_camera.png"), QIcon.Normal, QIcon.Off)
        self.setWindowIcon(icon)
        self.setWindowTitle("Manage Photos")

        self.fillingCombos = False

        QApplication.restoreOverrideCursor()

        # tell MainWindow that we succeeded filling the list
        return (True)
Example #21
0
    def insertPhotoIntoTable(self, row, photoData, photoMatchData, pixMap):

        QApplication.processEvents()

        self.fillingCombos = True

        photoLocation = photoMatchData["photoLocation"]
        photoDate = photoMatchData["photoDate"]
        photoTime = photoMatchData["photoTime"]
        photoCommonName = photoMatchData["photoCommonName"]

        # p is a filename. Use it to add the image to the label as a pixmap
        buttonPhoto = QPushButton()
        buttonPhoto.setMinimumHeight(281)
        buttonPhoto.setMinimumWidth(500)

        buttonPhoto.setIcon(QIcon(pixMap))

        # size to 500x281
        buttonPhoto.setIconSize(QSize(500, 281))
        buttonPhoto.setStyleSheet(
            "QPushButton {background-color: #343333; border: 0px}")

        # display thumbnail to new row in grid
        self.gridPhotos.addWidget(buttonPhoto, row, 0)

        # set up layout in second column of row to house combo boxes
        # give each object a name according to the row so we can access them later
        container = QWidget()
        container.setObjectName("container" + str(row))
        detailsLayout = QVBoxLayout(container)
        detailsLayout.setObjectName("layout" + str(row))
        detailsLayout.setAlignment(Qt.AlignTop)

        self.gridPhotos.addWidget(container, row, 1)

        # create combo boxes for details
        # add connection for when user changes a combo box
        cboLocation = QComboBox()
        cboLocation.currentIndexChanged.connect(
            partial(self.cboLocationChanged, row))

        cboDate = QComboBox()
        cboDate.currentIndexChanged.connect(partial(self.cboDateChanged, row))

        cboTime = QComboBox()
        cboTime.currentIndexChanged.connect(partial(self.cboTimeChanged, row))

        cboCommonName = QComboBox()
        cboCommonName.currentIndexChanged.connect(
            partial(self.cboCommonNameChanged, row))

        cboRating = QComboBox()
        cboRating.addItems(["Not Rated", "1", "2", "3", "4", "5"])
        cboRating.currentIndexChanged.connect(
            partial(self.cboRatingChanged, row))

        # set stylesheet for cbo boxes
        for c in [cboLocation, cboDate, cboTime, cboCommonName, cboRating]:
            self.removeHighlight(c)

        # fill location combo box with all locations in db
        locations = self.mdiParent.db.locationList
        cboLocation.addItems(locations)

        # set location combo box to the photo's location
        if photoLocation != "":
            index = cboLocation.findText(photoLocation)
            if index >= 0:
                cboLocation.setCurrentIndex(index)

                # fill date combo box with all dates associated with selected location
                filterForThisPhoto = code_Filter.Filter()
                filterForThisPhoto.setLocationName(photoLocation)
                filterForThisPhoto.setLocationType("Location")
                dates = self.mdiParent.db.GetDates(filterForThisPhoto)
                cboDate.addItems(dates)

                # set date  combo box to the photo's associated date
                index = cboDate.findText(photoDate)
                if index >= 0:
                    cboDate.setCurrentIndex(index)

                # fill time combo box with all times associated with selected location and date
                filterForThisPhoto.setStartDate(photoDate)
                filterForThisPhoto.setEndDate(photoDate)
                startTimes = self.mdiParent.db.GetStartTimes(
                    filterForThisPhoto)
                cboTime.addItems(startTimes)

                # set time combo box to the photo's associated checklist time
                index = cboTime.findText(photoTime)
                if index >= 0:
                    cboTime.setCurrentIndex(index)

                # get common names from checklist associated with photo
                filterForThisPhoto.setTime(photoTime)
                commonNames = self.mdiParent.db.GetSpecies(filterForThisPhoto)

                cboCommonName.addItem("**Detach Photo**")
                cboCommonName.addItems(commonNames)

                # set combo box to common name
                index = cboCommonName.findText(photoCommonName)
                if index >= 0:
                    cboCommonName.setCurrentIndex(index)

        # assign names to combo boxes for future access
        cboLocation.setObjectName("cboLocation" + str(row))
        cboDate.setObjectName("cboDate" + str(row))
        cboTime.setObjectName("cboTime" + str(row))
        cboCommonName.setObjectName("cboCommonName" + str(row))
        cboRating.setObjectName("cboRating" + str(row))

        lblFileName = QLabel()
        lblFileName.setText("File: " + os.path.basename(photoData["fileName"]))

        lblFileDate = QLabel()
        lblFileDate.setText("Date: " + photoData["date"])

        lblFileTime = QLabel()
        lblFileTime.setText("Time: " + photoData["time"])

        # add combo boxes to the layout in second column
        detailsLayout.addWidget(lblFileName)
        detailsLayout.addWidget(lblFileDate)
        detailsLayout.addWidget(lblFileTime)
        detailsLayout.addWidget(cboLocation)
        detailsLayout.addWidget(cboDate)
        detailsLayout.addWidget(cboTime)
        detailsLayout.addWidget(cboCommonName)
        detailsLayout.addWidget(cboRating)

        # create and add resent button
        btnReset = QPushButton()
        btnReset.setText("Reset")
        btnReset.clicked.connect(partial(self.btnResetClicked, row))
        detailsLayout.addWidget(btnReset)

        # save meta data for future use when user clicks cbo boxes
        thisPhotoMetaData = {}
        thisPhotoMetaData["photoFileName"] = photoData["fileName"]
        thisPhotoMetaData["location"] = photoLocation
        thisPhotoMetaData["date"] = photoDate
        thisPhotoMetaData["time"] = cboTime.currentText()
        thisPhotoMetaData["commonName"] = photoCommonName
        thisPhotoMetaData["photoData"] = photoData
        thisPhotoMetaData["rating"] = thisPhotoMetaData["photoData"]["rating"]

        self.metaDataByRow[row] = thisPhotoMetaData

        # initialize the "new" data so that there are values there, even if they're not really new
        # user can change the cbo boxes later, which will also change the "new" data
        self.saveNewMetaData(row)

        self.fillingCombos = False
Example #22
0
class LibraryCodesTab(QWidget):
    def __init__(self, mygui, myguidb, mymainprefs, myparam_dict, myuiexit,
                 mysavedialoggeometry):
        super(LibraryCodesTab, self).__init__()
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.gui = mygui
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.guidb = myguidb
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.lib_path = self.gui.library_view.model().db.library_path
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.mytabprefs = mymainprefs
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.param_dict = myparam_dict
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.ui_exit = myuiexit
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.save_dialog_geometry = mysavedialoggeometry
        #-----------------------------------------------------
        #-----------------------------------------------------
        font = QFont()
        font.setBold(False)
        font.setPointSize(10)
        #-----------------------------------------------------
        self.layout_top = QVBoxLayout()
        self.layout_top.setSpacing(0)
        self.layout_top.setAlignment(Qt.AlignLeft)
        self.setLayout(self.layout_top)
        #-----------------------------------------------------
        self.scroll_area_frame = QScrollArea()
        self.scroll_area_frame.setAlignment(Qt.AlignLeft)
        self.scroll_area_frame.setWidgetResizable(True)
        self.scroll_area_frame.ensureVisible(400, 400)

        self.layout_top.addWidget(
            self.scroll_area_frame
        )  # the scroll area is now the child of the parent of self.layout_top

        # NOTE: the self.scroll_area_frame.setWidget(self.scroll_widget) is at the end of the init() AFTER all children have been created and assigned to a layout...

        #-----------------------------------------------------
        self.scroll_widget = QWidget()
        self.layout_top.addWidget(
            self.scroll_widget
        )  # causes automatic reparenting of QWidget to the parent of self.layout_top, which is:  self .
        #-----------------------------------------------------
        self.layout_frame = QVBoxLayout()
        self.layout_frame.setSpacing(0)
        self.layout_frame.setAlignment(Qt.AlignLeft)

        self.scroll_widget.setLayout(
            self.layout_frame
        )  # causes automatic reparenting of any widget later added to self.layout_frame to the parent of self.layout_frame, which is:  QWidget .

        #-----------------------------------------------------
        self.lc_groupbox = QGroupBox('Settings:')
        self.lc_groupbox.setMaximumWidth(400)
        self.lc_groupbox.setToolTip(
            "<p style='white-space:wrap'>The settings that control 'Library Codes'.  Using only ISBN or ISSN or Author/Title, Library Codes for selected books will be derived using the Current Settings."
        )
        self.layout_frame.addWidget(self.lc_groupbox)

        self.lc_layout = QGridLayout()
        self.lc_groupbox.setLayout(self.lc_layout)
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.spacing0 = QLabel()
        self.layout_frame.addWidget(self.spacing0)
        self.spacing0.setMaximumHeight(20)
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.button_box = QDialogButtonBox()
        self.button_box.setOrientation(Qt.Horizontal)
        self.button_box.setCenterButtons(True)

        self.layout_frame.addWidget(self.button_box)
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.push_button_save_only = QPushButton("Save")
        self.push_button_save_only.clicked.connect(self.save_settings)
        self.push_button_save_only.setDefault(True)
        self.push_button_save_only.setFont(font)
        self.push_button_save_only.setToolTip(
            "<p style='white-space:wrap'>Save all user settings.")
        self.button_box.addButton(self.push_button_save_only, 0)

        self.push_button_exit_only = QPushButton("Exit")
        self.push_button_exit_only.clicked.connect(self.exit_only)
        self.push_button_exit_only.setDefault(False)
        self.push_button_exit_only.setFont(font)
        self.push_button_exit_only.setToolTip(
            "<p style='white-space:wrap'>Exit immediately without saving anything."
        )
        self.button_box.addButton(self.push_button_exit_only, 0)
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------

        r = 4

        self.ddc_labelname = QLineEdit(self)
        self.ddc_labelname.setText(self.mytabprefs['DDC'])
        self.ddc_labelname.setFont(font)
        self.ddc_labelname.setToolTip(
            "<p style='white-space:wrap'>Custom Column Search/Lookup #name for DDC.<br><br>See:  https://www.oclc.org/dewey/features/summaries.en.html"
        )
        self.ddc_labelname.setMaximumWidth(100)
        self.lc_layout.addWidget(self.ddc_labelname, r, 0)

        self.ddc_activate_checkbox = QCheckBox(
            "Activate 'Dewey Decimal Code' Classification?")
        self.ddc_activate_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do you want to derive DDC?")
        r = r + 1
        self.lc_layout.addWidget(self.ddc_activate_checkbox, r, 0)
        if prefs['DDC_IS_ACTIVE'] == unicode_type(S_TRUE):
            self.ddc_activate_checkbox.setChecked(True)
        else:
            self.ddc_activate_checkbox.setChecked(False)
        #-----------------------------------------------------
        self.spacing1 = QLabel()
        r = r + 1
        self.lc_layout.addWidget(self.spacing1, r, 0)
        self.spacing1.setMaximumHeight(10)
        #-----------------------------------------------------
        self.lcc_labelname = QLineEdit(self)
        self.lcc_labelname.setText(self.mytabprefs['LCC'])
        self.lcc_labelname.setFont(font)
        self.lcc_labelname.setToolTip(
            "<p style='white-space:wrap'>Custom Column Search/Lookup #name for LCC.<br><br>See: http://www.loc.gov/catdir/cpso/lcco/ "
        )
        self.lcc_labelname.setMaximumWidth(100)
        r = r + 4
        self.lc_layout.addWidget(self.lcc_labelname, r, 0)

        self.lcc_activate_checkbox = QCheckBox(
            "Activate 'Library of Congress Code' Classification?")
        self.lcc_activate_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do you want to derive LCC?")
        r = r + 1
        self.lc_layout.addWidget(self.lcc_activate_checkbox, r, 0)
        if prefs['LCC_IS_ACTIVE'] == unicode_type(S_TRUE):
            self.lcc_activate_checkbox.setChecked(True)
        else:
            self.lcc_activate_checkbox.setChecked(False)
        #-----------------------------------------------------
        self.spacing2 = QLabel("")
        r = r + 1
        self.lc_layout.addWidget(self.spacing2, r, 0)
        self.spacing2.setMaximumHeight(10)
        #-----------------------------------------------------

        self.fast_labelname = QLineEdit(self)
        self.fast_labelname.setText(self.mytabprefs['FAST'])
        self.fast_labelname.setFont(font)
        self.fast_labelname.setToolTip(
            "<p style='white-space:wrap'>Custom Column Search/Lookup #name for FAST Tag Values. "
        )
        self.fast_labelname.setMinimumWidth(100)
        self.fast_labelname.setMaximumWidth(100)
        r = r + 4
        self.lc_layout.addWidget(self.fast_labelname, r, 0)

        self.fast_activate_checkbox = QCheckBox("Activate 'FAST' Tags?")
        self.fast_activate_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do you want to derive FAST Tags?\
                                                                                                                    <br><br>Text.  Behaves like Tags. Not Names.<br><br>"
        )
        r = r + 1
        self.lc_layout.addWidget(self.fast_activate_checkbox, r, 0)
        if prefs['FAST_IS_ACTIVE'] == unicode_type(S_TRUE):
            self.fast_activate_checkbox.setChecked(True)
        else:
            self.fast_activate_checkbox.setChecked(False)

        #-----------------------------------------------------
        self.spacing6 = QLabel("")
        r = r + 1
        self.lc_layout.addWidget(self.spacing6, r, 0)
        self.spacing6.setMaximumHeight(10)
        #-----------------------------------------------------

        self.oclc_labelname = QLineEdit(self)
        self.oclc_labelname.setText(self.mytabprefs['OCLC'])
        self.oclc_labelname.setFont(font)
        self.oclc_labelname.setToolTip(
            "<p style='white-space:wrap'>Custom Column Search/Lookup #name for OCLC-OWI.<br><br>See: #http://classify.oclc.org/classify2/   "
        )
        self.oclc_labelname.setMaximumWidth(100)
        r = r + 4
        self.lc_layout.addWidget(self.oclc_labelname, r, 0)

        self.oclc_activate_checkbox = QCheckBox(
            "Activate 'Online Computer Library Center' Work ID Code?")
        self.oclc_activate_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do you want to derive OCLC-OWI?")
        r = r + 1
        self.lc_layout.addWidget(self.oclc_activate_checkbox, r, 0)
        if self.mytabprefs['OCLC_IS_ACTIVE'] == unicode_type(S_TRUE):
            self.oclc_activate_checkbox.setChecked(True)
        else:
            self.oclc_activate_checkbox.setChecked(False)
        #-----------------------------------------------------
        self.spacing5 = QLabel("")
        r = r + 1
        self.lc_layout.addWidget(self.spacing5, r, 0)
        self.spacing5.setMaximumHeight(10)
        #-----------------------------------------------------
        self.lc_author_details_labelname = QLineEdit(self)
        self.lc_author_details_labelname.setText(
            self.mytabprefs['EXTRA_AUTHOR_DETAILS'])
        self.lc_author_details_labelname.setFont(font)
        self.lc_author_details_labelname.setToolTip(
            "<p style='white-space:wrap'>Custom Column Search/Lookup #name for 'LC Extra Author Details'.\
                                                                                                                              <br><br>Text.  Behaves like Tags. Not Names.<br><br>"
        )
        self.lc_author_details_labelname.setMaximumWidth(100)
        r = r + 4
        self.lc_layout.addWidget(self.lc_author_details_labelname, r, 0)

        self.lc_author_details_checkbox = QCheckBox(
            "Activate 'Library Codes Extra Author Details'?")
        self.lc_author_details_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do you want to add (never delete or replace) any available Tag-like values to this Custom Column if they are associated with the OCLC-OWI Identifier?"
        )
        r = r + 1
        self.lc_layout.addWidget(self.lc_author_details_checkbox, r, 0)
        if self.mytabprefs['EXTRA_AUTHOR_DETAILS_IS_ACTIVE'] == unicode_type(
                S_TRUE):
            self.lc_author_details_checkbox.setChecked(True)
        else:
            self.lc_author_details_checkbox.setChecked(False)
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.spacing4 = QLabel()
        r = r + 1
        self.lc_layout.addWidget(self.spacing4, r, 0)
        self.spacing4.setMaximumHeight(10)
        #-----------------------------------------------------
        font.setBold(False)
        font.setPointSize(7)
        #-----------------------------------------------------
        self.push_button_autoadd_custom_columns = QPushButton(
            "Automatically Add Activated Custom Columns?")
        self.push_button_autoadd_custom_columns.clicked.connect(
            self.autoadd_custom_columns)
        self.push_button_autoadd_custom_columns.setDefault(False)
        self.push_button_autoadd_custom_columns.setFont(font)
        self.push_button_autoadd_custom_columns.setToolTip(
            "<p style='white-space:wrap'>Do you want to automatically add the Custom Columns selected above?<br><br>If you have any issues, please add them manually."
        )
        r = r + 4
        self.lc_layout.addWidget(self.push_button_autoadd_custom_columns, r, 0)
        self.push_button_autoadd_custom_columns.setMaximumWidth(250)
        #-----------------------------------------------------
        self.lc_custom_columns_generation_label = QLabel()
        r = r + 1
        self.lc_layout.addWidget(self.lc_custom_columns_generation_label, r, 0)
        self.lc_custom_columns_generation_label.setText(
            "                                                              ")
        self.lc_custom_columns_generation_label.setMaximumHeight(10)
        self.lc_custom_columns_generation_label.setFont(font)

        self.oclc_identifier_only_checkbox = QCheckBox(
            "Always Create OCLC-OWI as an 'Identifier' (à la ISBN)?")
        self.oclc_identifier_only_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do you want to update Calibre's Identifiers for an Identifier of 'OCLC-OWI',\
                                                                                                                                 regardless of whether you want its own Custom Column updated?\
                                                                                                                                <br><br>REQUIRED to derive DDC/LCC using Author/Title."
        )
        r = r + 2
        self.lc_layout.addWidget(self.oclc_identifier_only_checkbox, r, 0)
        if prefs['OCLC_IDENTIFIER'] == unicode_type(S_TRUE):
            self.oclc_identifier_only_checkbox.setChecked(True)
        else:
            self.oclc_identifier_only_checkbox.setChecked(False)

        #-----------------------------------------------------
        self.spacing3 = QLabel("")
        r = r + 1
        self.lc_layout.addWidget(self.spacing3, r, 0)
        self.spacing3.setMaximumHeight(10)
        #-----------------------------------------------------
        font.setBold(False)
        font.setPointSize(10)
        #-----------------------------------------------------
        self.lc_genre_labelname = QLineEdit(self)
        self.lc_genre_labelname.setText(self.mytabprefs['GENRE'])
        self.lc_genre_labelname.setFont(font)
        self.lc_genre_labelname.setToolTip(
            "<p style='white-space:wrap'>Custom Column Search/Lookup #name for 'Genre'.\
                                                                                                                              <br><br>Text.  Behaves like Tags.<br><br>"
        )
        self.lc_genre_labelname.setMaximumWidth(100)
        r = r + 1
        self.lc_layout.addWidget(self.lc_genre_labelname, r, 0)

        self.lc_checkbox_buttongroup = QButtonGroup()
        self.lc_checkbox_buttongroup.setExclusive(True)

        self.lc_genre_ddc_checkbox = QCheckBox(
            "Update 'Genre' using DDC-to-Genre Mappings?")
        self.lc_genre_ddc_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do you want LC to update 'Genre' using the DDC-to-Genre mapping in Table _lc_genre_mapping?"
        )
        r = r + 1
        self.lc_layout.addWidget(self.lc_genre_ddc_checkbox, r, 0)

        self.lc_genre_lcc_checkbox = QCheckBox(
            "Update 'Genre' using LCC-to-Genre Mappings?")
        self.lc_genre_lcc_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do you want LC to update 'Genre' using the LCC-to-Genre mapping in Table _lc_genre_mapping?"
        )
        r = r + 1
        self.lc_layout.addWidget(self.lc_genre_lcc_checkbox, r, 0)

        self.lc_genre_inactive_checkbox = QCheckBox(
            "Do not update 'Genre' at all")
        self.lc_genre_inactive_checkbox.setToolTip(
            "<p style='white-space:wrap'>Do no 'Genre' processing at all?")
        r = r + 1
        self.lc_layout.addWidget(self.lc_genre_inactive_checkbox, r, 0)

        self.lc_checkbox_buttongroup.addButton(self.lc_genre_ddc_checkbox)
        self.lc_checkbox_buttongroup.addButton(self.lc_genre_lcc_checkbox)
        self.lc_checkbox_buttongroup.addButton(self.lc_genre_inactive_checkbox)

        if self.mytabprefs['GENRE_DDC_IS_ACTIVE'] == unicode_type(S_TRUE):
            self.lc_genre_ddc_checkbox.setChecked(True)
        elif self.mytabprefs['GENRE_LCC_IS_ACTIVE'] == unicode_type(S_TRUE):
            self.lc_genre_lcc_checkbox.setChecked(True)
        elif self.mytabprefs['GENRE_IS_INACTIVE'] == unicode_type(S_TRUE):
            self.lc_genre_inactive_checkbox.setChecked(True)

        self.lc_exact_match_checkbox = QCheckBox(
            "DDC: Require an 'Exact Match', not a 'Best Match'?")
        self.lc_exact_match_checkbox.setToolTip(
            "<p style='white-space:wrap'>Check this checkbox if you want an exact DDC match to be required in Table _lc_genre_mapping.  Otherwise, a 'best match' will be used via progressive shortening from right to left, but not past any decimal point.  If there is no decimal point in a book's DDC, then no progressive shortening will be performed at all."
        )
        r = r + 1
        self.lc_layout.addWidget(self.lc_exact_match_checkbox, r, 0)

        if self.mytabprefs['GENRE_EXACT_MATCH'] == unicode_type(S_TRUE):
            self.lc_exact_match_checkbox.setChecked(True)

        self.spin_lcc = QSpinBox(self)
        self.spin_lcc.setMinimum(1)
        self.spin_lcc.setMaximum(50)
        self.spin_lcc.setProperty('value', prefs['GENRE_LCC_MATCH_LENGTH'])
        self.spin_lcc.setMaximumWidth(250)
        self.spin_lcc.setSuffix("    LCC: Maximum Length to Match")
        self.spin_lcc.setToolTip(
            "<p style='white-space:nowrap'>Maximum number of characters in the LCC that should be used to map to the 'Genre', starting from the left.  A maximum of 1 guarantees a (broad) match.\
                                                                                                   <br><br>LCCs are structured with either 1 or 2 beginning letters, so 2-character LCCs have special matching logic.\
                                                                                                   <br><br>Example:   Assume maximum = 2 for a LCC of 'Q1':  Q1 would be attempted.  If it failed, because the 2nd digit is a number, 'Q' would be attempted.\
                                                                                                   <br><br>Example:   Assume maximum = 2 for a LCC of 'PN1969.C65':  PN would be attempted.  If it failed, nothing else would be attempted.\
                                                                                                   <br><br>Example:   Assume maximum = 4 for a LCC of 'PN1969.C65':  PN19 would be attempted.  If it failed, nothing else would be attempted.\
                                                                                                   <br><br>Example:   Assume maximum = 4 for a LCC of 'Q1':  Q1 would be attempted.  If it failed, because the 2nd digit is a number, 'Q' would be attempted.\
                                                                                                   <br><br>Example:   Assume maximum = 4 for a LCC of 'Q389':  Q389 would be attempted.  If it failed, nothing else would be attempted."
        )
        r = r + 2
        self.lc_layout.addWidget(self.spin_lcc, r, 0)

        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.scroll_widget.resize(self.sizeHint())
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.scroll_area_frame.setWidget(
            self.scroll_widget
        )  # now that all widgets have been created and assigned to a layout...
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.scroll_area_frame.resize(self.sizeHint())
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.resize(self.sizeHint())

    #-----------------------------------------------------------------------------------------
    def validate(self):
        return True

    #-----------------------------------------------------------------------------------------
    def autoadd_custom_columns(self):
        number_active = self.save_settings()
        if number_active == 0:
            return error_dialog(
                self.gui,
                _('Automatically Add Custom Columns'),
                _('No Activated Library Codes Custom Columns Found.  Nothing to Add.'
                  ),
                show=True)
        self.cli_param_list = self.create_cli_parameters()
        is_valid, restart_required = self.create_new_lc_custom_columns(
            self.cli_param_list)
        if is_valid:
            if restart_required:
                self.lc_custom_columns_generation_label.setText(
                    "Addition of Custom Columns Complete.  Restart Calibre Now."
                )
                self.repaint()
                info_dialog(
                    self.gui, 'Automatically Add Custom Columns',
                    'All Selected Custom Customs Were Added If They Did Not Already Exist.  Please Restart Calibre now.'
                ).show()
            else:
                self.lc_custom_columns_generation_label.setText(
                    "Selected Custom Columns Already Exist.  Nothing Done.")
                self.repaint()
        else:
            self.lc_custom_columns_generation_label.setText(
                "Not Completed.  Please Restart Calibre, then Add Manually.")
            self.repaint()
            msg = "Fatal error experienced in adding new Custom Columns."
            error_dialog(self.gui,
                         _('Automatically Add Custom Columns'),
                         _(msg),
                         show=True)

    #-----------------------------------------------------------------------------------------
    def create_cli_parameters(self):

        try:
            del self.cli_param_list
        except:
            pass

        self.cli_param_list = []
        temp_list = []
        cc_taglike_list = []
        cc_fast_name = ""

        if self.mytabprefs['DDC_IS_ACTIVE'] == unicode_type(S_TRUE):
            cc = self.mytabprefs['DDC']
            if cc > '#':
                cc = cc.replace('#', "").strip()
                cc = unicode_type(cc)
                temp_list.append(cc)
            else:
                error_dialog(self.gui,
                             _('Automatically Add Custom Columns'),
                             _('Illogical DDC Settings.  Please Correct.'),
                             show=True)
                return self.cli_param_list

        if self.mytabprefs['LCC_IS_ACTIVE'] == unicode_type(S_TRUE):
            cc = self.mytabprefs['LCC']
            if cc > '#':
                cc = cc.replace('#', "").strip()
                cc = unicode_type(cc)
                temp_list.append(cc)
            else:
                error_dialog(self.gui,
                             _('Automatically Add Custom Columns'),
                             _('Illogical LCC Settings.  Please Correct.'),
                             show=True)
                return self.cli_param_list

        if self.mytabprefs['FAST_IS_ACTIVE'] == unicode_type(S_TRUE):
            cc = self.mytabprefs['FAST']
            if cc > '#':
                cc = cc.replace('#', "").strip()
                cc = unicode_type(cc)
                temp_list.append(cc)
                cc_taglike_list.append(cc)
                cc_fast_name = cc
            else:
                error_dialog(self.gui,
                             _('Automatically Add Custom Columns'),
                             _('Illogical FAST Settings.  Please Correct.'),
                             show=True)
                return self.cli_param_list

        if self.mytabprefs['OCLC_IS_ACTIVE'] == unicode_type(S_TRUE):
            cc = self.mytabprefs['OCLC']
            if cc > '#':
                cc = cc.replace('#', "").strip()
                cc = unicode_type(cc)
                temp_list.append(cc)
            else:
                error_dialog(self.gui,
                             _('Automatically Add Custom Columns'),
                             _('Illogical OCLC Settings.  Please Correct.'),
                             show=True)
                return self.cli_param_list

        if self.mytabprefs['EXTRA_AUTHOR_DETAILS_IS_ACTIVE'] == unicode_type(
                S_TRUE):
            cc = self.mytabprefs['EXTRA_AUTHOR_DETAILS']
            if cc > '#':
                cc = cc.replace('#', "").strip()
                cc = unicode_type(cc)
                temp_list.append(cc)
                cc_taglike_list.append(cc)
            else:
                error_dialog(
                    self.gui,
                    _('Automatically Add Custom Columns'),
                    _('Illogical LC Extra Author Details Settings.  Please Correct.'
                      ),
                    show=True)
                return self.cli_param_list
        else:
            pass

        if len(temp_list) == 0:
            del temp_list
            error_dialog(self.gui,
                         _('Automatically Add Custom Columns'),
                         _('Nothing to do.  Please Review Settings.'),
                         show=True)
            return self.cli_param_list

        cc_to_add_list = []

        # for each cc currently set to active, create a parameter...but only if the cc does NOT already exist...
        my_db, my_cursor, is_valid = self.apsw_connect_to_library()
        if not is_valid:
            error_dialog(self.gui,
                         _('Automatically Add Custom Columns'),
                         _('Database Connection Error.  Restart Calibre.'),
                         show=True)
            return

        self.lc_custom_columns_generation_label.setText(
            "...Adding Custom Columns...")
        self.repaint()

        mysql = "SELECT label,name FROM custom_columns"
        my_cursor.execute(mysql)
        tmp_rows = my_cursor.fetchall()
        if not tmp_rows:
            for cc in temp_list:
                cc_to_add_list.append(cc)
            #END FOR
        else:
            if len(tmp_rows) == 0:
                for cc in temp_list:
                    cc_to_add_list.append(cc)
                #END FOR
            else:
                for cc in temp_list:
                    label_already_exists = False
                    for row in tmp_rows:
                        label, name = row
                        if unicode_type(label) == unicode_type(cc):
                            label_already_exists = True
                            break
                        else:
                            continue
                    #END FOR
                    if not label_already_exists:
                        cc_to_add_list.append(cc)
                #END FOR
                del tmp_rows
                del temp_list

        if len(cc_to_add_list) == 0:
            return self.cli_param_list

        cc_to_add_list.sort()

        for label in cc_to_add_list:
            label = unicodedata.normalize('NFKD',
                                          label).encode('ascii', 'ignore')
            label = unicode_type(label)
            label = label.lower()
            name = label.upper()
            datatype = 'text'
            if label in cc_taglike_list:
                is_multiple = "--is-multiple"
                if label == cc_fast_name:
                    name = "FAST Tags"
                else:
                    name = '"LC Extra Author Details"'
                param = is_multiple + '|||' + label + '|||' + name + '|||' + datatype
            else:
                param = label + '|||' + name + '|||' + datatype
            param = param.replace("[LIBRARY]", self.lib_path)
            self.cli_param_list.append(param)
        #END FOR

        del cc_to_add_list

        return self.cli_param_list

    #-----------------------------------------------------------------------------------------
    #-----------------------------------------------------------------------------------------
    def apsw_connect_to_library(self):

        my_db = self.gui.library_view.model().db

        self.lib_path = my_db.library_path
        self.lib_path = self.lib_path.replace(os.sep, '/')
        if isbytestring(self.lib_path):
            self.lib_path = self.lib_path.decode(filesystem_encoding)

        path = my_db.library_path
        if isbytestring(path):
            path = path.decode(filesystem_encoding)
        path = path.replace(os.sep, '/')
        path = os.path.join(path, 'metadata.db')
        path = path.replace(os.sep, '/')

        if isbytestring(path):
            path = path.decode(filesystem_encoding)

        if path.endswith("/"):
            path = path[0:-1]

        if path.count("metadata.db") == 0:
            path = path + "/metadata.db"

        try:
            my_db = apsw.Connection(path)
            is_valid = True
        except Exception as e:
            if DEBUG: print("path to metadata.db is: ", path)
            if DEBUG: print("error: ", as_unicode(e))
            is_valid = False
            return None, None, is_valid

        my_cursor = my_db.cursor()

        mysql = "PRAGMA main.busy_timeout = 5000;"  #PRAGMA busy_timeout = milliseconds;
        my_cursor.execute(mysql)

        return my_db, my_cursor, is_valid

    #-----------------------------------------------------------------------------------------
    def exit_only(self):
        self.save_dialog_geometry()  #  inherited from SizePersistedDialog
        self.ui_exit()

    #-----------------------------------------------------------------------------------------
    def save_settings(self):

        self.save_dialog_geometry()  #  inherited from SizePersistedDialog

        self.mytabprefs['DDC'] = self.ddc_labelname.text()
        self.mytabprefs['LCC'] = self.lcc_labelname.text()
        self.mytabprefs['FAST'] = self.fast_labelname.text()
        self.mytabprefs['OCLC'] = self.oclc_labelname.text()

        self.mytabprefs['DDC_IS_ACTIVE'] = unicode_type(
            self.ddc_activate_checkbox.isChecked())
        self.mytabprefs['LCC_IS_ACTIVE'] = unicode_type(
            self.lcc_activate_checkbox.isChecked())
        self.mytabprefs['FAST_IS_ACTIVE'] = unicode_type(
            self.fast_activate_checkbox.isChecked())
        self.mytabprefs['OCLC_IS_ACTIVE'] = unicode_type(
            self.oclc_activate_checkbox.isChecked())
        self.mytabprefs['OCLC_IDENTIFIER'] = unicode_type(
            self.oclc_identifier_only_checkbox.isChecked())

        label = self.mytabprefs['DDC']
        label = unicode_type(label)
        label = unicodedata.normalize('NFKD', label).encode('ascii', 'ignore')
        label = label.lower().strip()
        if not label.startswith("#"):
            label = "#" + label
        if label == "#":
            label = ""
            self.ddc_activate_checkbox.setChecked(False)
        self.mytabprefs['DDC'] = unicode_type(label)

        label = self.mytabprefs['LCC']
        label = unicode_type(label)
        label = unicodedata.normalize('NFKD', label).encode('ascii', 'ignore')
        label = label.lower().strip()
        if not label.startswith("#"):
            label = "#" + label
        if label == "#":
            label = ""
            self.lcc_activate_checkbox.setChecked(False)
        self.mytabprefs['LCC'] = unicode_type(label)

        label = self.mytabprefs['FAST']
        label = unicode_type(label)
        label = unicodedata.normalize('NFKD', label).encode('ascii', 'ignore')
        label = label.lower().strip()
        if not label.startswith("#"):
            label = "#" + label
        if label == "#":
            label = ""
            self.fast_activate_checkbox.setChecked(False)
        self.mytabprefs['FAST'] = unicode_type(label)

        label = self.mytabprefs['OCLC']
        label = unicode_type(label)
        label = unicodedata.normalize('NFKD', label).encode('ascii', 'ignore')
        label = label.lower().strip()
        if not label.startswith("#"):
            label = "#" + label
        if label == "#":
            label = ""
            self.oclc_activate_checkbox.setChecked(False)
        self.mytabprefs['OCLC'] = unicode_type(label)

        if self.mytabprefs['DDC'] == unicode_type(
                "") and self.mytabprefs['LCC'] == unicode_type(
                    "") and self.mytabprefs['FAST'] == unicode_type(
                        "") and self.mytabprefs['OCLC'] == unicode_type(""):
            self.mytabprefs['DDC'] = unicode_type("#ddc")
            self.mytabprefs['LCC'] = unicode_type("#lcc")
            self.mytabprefs['FAST'] = unicode_type("#fast")
            self.mytabprefs['OCLC'] = unicode_type("#oclc_owi")
        else:
            if self.mytabprefs['DDC'] == unicode_type(
                    "") and self.mytabprefs['LCC'] == unicode_type(""):
                self.oclc_identifier_only_checkbox.setChecked(False)
        #---------------------------------------

        s = unicode_type(self.lc_genre_labelname.text())
        s = s.strip()
        if s.startswith("#") and len(s) > 1:
            self.mytabprefs['GENRE'] = unicode_type(s)
            self.mytabprefs['GENRE_DDC_IS_ACTIVE'] = unicode_type(
                self.lc_genre_ddc_checkbox.isChecked())
            self.mytabprefs['GENRE_LCC_IS_ACTIVE'] = unicode_type(
                self.lc_genre_lcc_checkbox.isChecked())
            self.mytabprefs['GENRE_IS_INACTIVE'] = unicode_type(
                self.lc_genre_inactive_checkbox.isChecked())
            self.mytabprefs['GENRE_EXACT_MATCH'] = unicode_type(
                self.lc_exact_match_checkbox.isChecked())
            self.mytabprefs['GENRE_LCC_MATCH_LENGTH'] = self.spin_lcc.value()
        else:
            self.mytabprefs['GENRE'] = unicode_type("#genre")
            self.lc_genre_labelname.setText(unicode_type("#genre"))
            self.lc_genre_ddc_checkbox.setChecked(False)
            self.lc_genre_lcc_checkbox.setChecked(False)
            self.lc_genre_inactive_checkbox.setChecked(True)
            self.mytabprefs['GENRE_DDC_IS_ACTIVE'] = unicode_type(S_FALSE)
            self.mytabprefs['GENRE_LCC_IS_ACTIVE'] = unicode_type(S_FALSE)
            self.mytabprefs['GENRE_IS_INACTIVE'] = unicode_type(S_TRUE)
            self.mytabprefs['GENRE_EXACT_MATCH'] = unicode_type(S_TRUE)
            self.mytabprefs['GENRE_LCC_MATCH_LENGTH'] = 2
            self.repaint()
            sleep(2)

        #---------------------------------------
        #~ for k,v in self.mytabprefs.iteritems():
        for k, v in iteritems(self.mytabprefs):
            v = unicode_type(v)
            v = v.strip()
            prefs[k] = v
        #END FOR
        prefs

        #---------------------------------------

        self.ddc_labelname.setText(self.mytabprefs['DDC'])
        self.lcc_labelname.setText(self.mytabprefs['LCC'])
        self.fast_labelname.setText(self.mytabprefs['FAST'])
        self.oclc_labelname.setText(self.mytabprefs['OCLC'])
        self.repaint()
        sleep(0)

        #~ for k,v in self.mytabprefs.iteritems():
        for k, v in iteritems(self.mytabprefs):
            self.param_dict[k] = v
        #END FOR

        number_active = 0

        if self.mytabprefs['DDC_IS_ACTIVE'] == unicode_type(S_TRUE):
            number_active = number_active + 1
        if self.mytabprefs['LCC_IS_ACTIVE'] == unicode_type(S_TRUE):
            number_active = number_active + 1
        if self.mytabprefs['FAST_IS_ACTIVE'] == unicode_type(S_TRUE):
            number_active = number_active + 1
        if self.mytabprefs['OCLC_IS_ACTIVE'] == unicode_type(S_TRUE):
            number_active = number_active + 1

        self.ddc_name = self.mytabprefs['DDC'].replace("#", "").strip()
        self.lcc_name = self.mytabprefs['LCC'].replace("#", "").strip()
        self.fast_name = self.mytabprefs['FAST'].replace("#", "").strip()
        self.oclc_name = self.mytabprefs['OCLC'].replace("#", "").strip()

        if self.oclc_identifier_only_checkbox.isChecked():
            self.oclc_identifier_is_desired = True
        else:
            self.oclc_identifier_is_desired = False

        return number_active

    #-----------------------------------------------------------------------------------------
    #-----------------------------------------------------------------------------------------
    def create_new_lc_custom_columns(self, execution_param_list):

        if len(self.cli_param_list) == 0:
            return True, False  # successful since the labels already exist; no restart is required.

        dbpath = self.lib_path

        was_successful = True
        restart_required = True

        for param in execution_param_list:
            try:
                lc_cli_add_custom_column(self.guidb, param, dbpath)
            except Exception as e:
                if DEBUG: print("Exception: ", as_unicode(e))
                was_successful = False
                break
        #END FOR

        return was_successful, restart_required

    #-----------------------------------------------------------------------------------------
    #-----------------------------------------------------------------------------------------
    #-----------------------------------------------------------------------------------------
    #-----------------------------------------------------------------------------------------
    #-----------------------------------------------------------------------------------------
    #-----------------------------------------------------------------------------------------


#END of library_codes_dialog.py
class ConfigWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        self.main_layout = QVBoxLayout()
        self.l = QFormLayout()
        self.l2 = QHBoxLayout()
        self.l3 = QHBoxLayout()

        self.group_box = QGroupBox('Ustawienia ogólne')
        self.group_box2 = QGroupBox('Pobieraj metadane')
        self.group_box3 = QGroupBox(
            'Pobieraj dodatkowe metadane i dołącz je do komentarza')

        # general settings
        self.max_results_label = QLabel('Maksymalna liczba wyników')
        self.max_results_label.setToolTip(
            'Maksymalna liczba pobieranych metadanych. Dla książek o nieunikalnych tytułach \
pierwszy wynik może być niepoprawny')
        self.max_results = QLineEdit(self)
        self.max_results.setValidator(QIntValidator())
        self.max_results.setText(str(PREFS['max_results']))
        self.max_results_label.setBuddy(self.max_results)
        self.l.addRow(self.max_results_label, self.max_results)

        self.authors_search_label = QLabel('Używaj autorów do wyszukiwań')
        self.authors_search_label.setToolTip(
            'Wyszukuj uwzględniając autorów. Może poprawić trafność wyników, ale błędni autorzy spowodują brak wyników'
        )
        self.authors_search = QCheckBox()
        self.authors_search.setChecked(PREFS['authors_search'])
        self.authors_search_label.setBuddy(self.authors_search)
        self.l.addRow(self.authors_search_label, self.authors_search)

        self.only_first_author_label = QLabel(
            'Używaj tylko pierwszego autora do wyszukiwania')
        self.only_first_author_label.setToolTip(
            'Używaj tylko pierwszego autora do wyszukiwań, obowiązuje tylko gdy wyszukiwanie z autorami jest aktywowane'
        )
        self.only_first_author = QCheckBox()
        self.only_first_author.setChecked(PREFS['only_first_author'])
        self.only_first_author_label.setBuddy(self.only_first_author)
        self.l.addRow(self.only_first_author_label, self.only_first_author)

        self.covers_label = QLabel('Pobieraj okładki')
        self.covers = QCheckBox()
        self.covers.setChecked(PREFS['covers'])
        self.covers_label.setBuddy(self.covers)
        self.l.addRow(self.covers_label, self.covers)

        self.max_covers_label = QLabel('Maksymalna liczba okładek')
        self.max_covers_label.setToolTip(
            'Maksymalna liczba pobieranych okładek')
        self.max_covers = QLineEdit(self)
        self.max_covers.setValidator(QIntValidator())
        self.max_covers.setText(str(PREFS['max_covers']))
        self.max_covers_label.setBuddy(self.max_covers)
        self.l.addRow(self.max_covers_label, self.max_covers)

        self.threads_label = QLabel('WielowÄ…tkowe przetwarzanie')
        self.threads_label.setToolTip(
            'Przyśpiesza pracę używając wielu wątków')
        self.threads = QCheckBox()
        self.threads.setChecked(PREFS['threads'])
        self.threads_label.setBuddy(self.threads)
        self.l.addRow(self.threads_label, self.threads)

        self.max_threads_label = QLabel('Maksymalna liczba wątków')
        self.max_threads = QLineEdit(self)
        self.max_threads.setValidator(QIntValidator())
        self.max_threads.setText(str(PREFS['max_threads']))
        self.max_threads_label.setBuddy(self.max_threads)
        self.l.addRow(self.max_threads_label, self.max_threads)

        self.thread_delay_label = QLabel('Opóźnienie wątku')
        self.thread_delay_label.setToolTip(
            'Czas oczekiwania na uruchomienie kolejnego wÄ…tku')
        self.thread_delay = QLineEdit(self)
        self.thread_delay.setValidator(QDoubleValidator())
        self.thread_delay.setText(str(PREFS['thread_delay']))
        self.thread_delay_label.setBuddy(self.thread_delay)
        self.l.addRow(self.thread_delay_label, self.thread_delay)

        # metadata settings
        if 'title' in PREFS.defaults:
            self.title = QCheckBox('Tytuł')
            self.title.setChecked(PREFS['title'])
            self.l2.addWidget(self.title)

        if 'authors' in PREFS.defaults:
            self.authors = QCheckBox('Autorzy')
            self.authors.setChecked(PREFS['authors'])
            self.l2.addWidget(self.authors)

        if 'pubdate' in PREFS.defaults:
            self.pubdate = QCheckBox('Data wydania')
            self.pubdate.setChecked(PREFS['pubdate'])
            self.l2.addWidget(self.pubdate)

        if 'publisher' in PREFS.defaults:
            self.publisher = QCheckBox('Wydawca')
            self.publisher.setChecked(PREFS['publisher'])
            self.l2.addWidget(self.publisher)

        if 'isbn' in PREFS.defaults:
            self.isbn = QCheckBox('ISBN')
            self.isbn.setChecked(PREFS['isbn'])
            self.l2.addWidget(self.isbn)

        if 'comments' in PREFS.defaults:
            self.comments = QCheckBox('Opis')
            self.comments.setChecked(PREFS['comments'])
            self.l2.addWidget(self.comments)

        if 'languages' in PREFS.defaults:
            self.languages = QCheckBox('Języki')
            self.languages.setChecked(PREFS['languages'])
            self.l2.addWidget(self.languages)

        if 'rating' in PREFS.defaults:
            self.rating = QCheckBox('Ocena')
            self.rating.setChecked(PREFS['rating'])
            self.l2.addWidget(self.rating)

        if 'tags' in PREFS.defaults:
            self.tags = QCheckBox('Etykiety (tagi)')
            self.tags.setChecked(PREFS['tags'])
            self.l2.addWidget(self.tags)

        if 'series' in PREFS.defaults:
            self.series = QCheckBox('Cykle')
            self.series.setChecked(PREFS['series'])
            self.l2.addWidget(self.series)

        if 'identifier' in PREFS.defaults:
            self.identifier = QCheckBox('Identyfikator')
            self.identifier.setChecked(PREFS['identifier'])
            self.l2.addWidget(self.identifier)

        # custom metadata
        if 'translators' in PREFS.defaults:
            self.translators = QCheckBox('TÅ‚umaczenie')
            self.translators.setChecked(PREFS['translators'])
            self.l3.addWidget(self.translators)

        if 'original_title' in PREFS.defaults:
            self.original_title = QCheckBox('Tytuł oryginału')
            self.original_title.setChecked(PREFS['original_title'])
            self.l3.addWidget(self.original_title)

        if 'categories' in PREFS.defaults:
            self.categories = QCheckBox('Kategorie')
            self.categories.setChecked(PREFS['categories'])
            self.l3.addWidget(self.categories)

        if 'genres' in PREFS.defaults:
            self.genres = QCheckBox('Gatunki')
            self.genres.setChecked(PREFS['genres'])
            self.l3.addWidget(self.genres)

        self.group_box.setLayout(self.l)
        self.group_box2.setLayout(self.l2)
        self.group_box3.setLayout(self.l3)
        self.main_layout.addWidget(self.group_box)
        self.main_layout.addWidget(self.group_box2)
        self.main_layout.addWidget(self.group_box3)
        self.main_layout.setAlignment(Qt.AlignTop)
        self.setLayout(self.main_layout)

    def save_settings(self):
        PREFS['max_results'] = int(self.max_results.text())
        PREFS['authors_search'] = self.authors_search.isChecked()
        PREFS['only_first_author'] = self.only_first_author.isChecked()
        PREFS['covers'] = self.covers.isChecked()
        PREFS['max_covers'] = int(self.max_covers.text())
        PREFS['threads'] = self.threads.isChecked()
        PREFS['max_threads'] = int(self.max_threads.text())
        PREFS['thread_delay'] = float(self.thread_delay.text().replace(
            ',', '.'))

        # metadata settings
        if 'title' in PREFS.defaults:
            PREFS['title'] = self.title.isChecked()
        if 'authors' in PREFS.defaults:
            PREFS['authors'] = self.authors.isChecked()
        if 'pubdate' in PREFS.defaults:
            PREFS['pubdate'] = self.pubdate.isChecked()
        if 'publisher' in PREFS.defaults:
            PREFS['publisher'] = self.publisher.isChecked()
        if 'isbn' in PREFS.defaults:
            PREFS['isbn'] = self.isbn.isChecked()
        if 'comments' in PREFS.defaults:
            PREFS['comments'] = self.comments.isChecked()
        if 'languages' in PREFS.defaults:
            PREFS['languages'] = self.languages.isChecked()
        if 'rating' in PREFS.defaults:
            PREFS['rating'] = self.rating.isChecked()
        if 'tags' in PREFS.defaults:
            PREFS['tags'] = self.tags.isChecked()
        if 'series' in PREFS.defaults:
            PREFS['series'] = self.series.isChecked()
        if 'identifier' in PREFS.defaults:
            PREFS['identifier'] = self.identifier.isChecked()

        # custom metadata settings
        if 'translators' in PREFS.defaults:
            PREFS['translators'] = self.translators.isChecked()
        if 'original_title' in PREFS.defaults:
            PREFS['original_title'] = self.original_title.isChecked()
        if 'categories' in PREFS.defaults:
            PREFS['categories'] = self.categories.isChecked()
        if 'genres' in PREFS.defaults:
            PREFS['genres'] = self.genres.isChecked()

        return PREFS
    def initialize(self):
        """
        Initialize QDialog

        """

        main_layout = QVBoxLayout()
        main_layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(main_layout)

        about_widget = QWidget()
        about_widget.setObjectName('about')
        about_layout = QVBoxLayout(about_widget)

        # QDialog Title
        about_title = QLabel(_('About'))
        about_title.setFixedHeight(40)
        about_title.setObjectName('aboutheader')
        main_layout.addWidget(about_title)

        # Main About
        about_text = "%s\nVersion %s\nCopyright: %s" % \
            (__application__, __version__, __copyright__)
        main_about = QLabel(about_text)
        main_about.setObjectName('aboutmain')
        main_about.setToolTip(__application__)
        about_layout.addWidget(main_about)
        about_layout.setAlignment(main_about, Qt.AlignCenter)

        # Release notes
        release_data = QLabel(__releasenotes__)
        release_data.setObjectName('about')
        release_data.setToolTip(_('Release notes'))
        release_data.setWordWrap(True)
        about_layout.addWidget(release_data)

        # Homepage
        home_title = QLabel(_('Home page:'))
        home_title.setObjectName('abouttitle')
        home_title.setToolTip(_('Home page'))
        about_layout.addWidget(home_title)
        about_layout.addWidget(self.get_external_link_label(__project_url__))

        # User Doc
        doc_title = QLabel(_('User documentation'))
        doc_title.setObjectName('abouttitle')
        doc_title.setToolTip(_('User documentation'))
        about_layout.addWidget(doc_title)
        about_layout.addWidget(self.get_external_link_label(__doc_url__))

        # Alignak
        alignak_title = QLabel(_('About Alignak solution:'))
        alignak_title.setObjectName('abouttitle')
        alignak_title.setToolTip(_('About Alignak solution'))
        about_layout.addWidget(alignak_title)
        about_layout.addWidget(self.get_external_link_label(__alignak_url__))

        # Powered
        powered_title = QLabel(_('Powered by:'))
        powered_title.setObjectName('abouttitle')
        powered_title.setToolTip(_('PyQt5'))
        about_layout.addWidget(powered_title)
        powered_data = self.get_external_link_label('https://www.riverbankcomputing.com/', 'PyQt5')
        about_layout.addWidget(powered_data)

        main_layout.addWidget(about_widget)
Example #25
0
class LibraryCodesDialog(SizePersistedDialog):
    #-----------------------------------------------------------------------------------------
    def __init__(self, gui, icon, guidb, plugin_path, ui_exit, action_type):
        parent = gui
        unique_pref_name = 'library_codes:gui_parameters_dialog'
        SizePersistedDialog.__init__(self, parent, unique_pref_name)
        #-----------------------------------------------------
        self.gui = gui
        self.guidb = guidb
        #-----------------------------------------------------
        self.icon = icon
        #-----------------------------------------------------
        self.plugin_path = plugin_path
        #-----------------------------------------------------
        self.ui_exit = ui_exit
        #-----------------------------------------------------
        self.action_type = action_type
        #-----------------------------------------------------
        self.myparentprefs = collections.OrderedDict([])
        prefsdefaults = deepcopy(prefs.defaults)
        tmp_list = []
        #~ for k,v in prefs.iteritems():
        for k, v in iteritems(prefs):
            tmp_list.append(k)
        #END FOR
        #~ for k,v in prefsdefaults.iteritems():
        for k, v in iteritems(prefsdefaults):
            tmp_list.append(k)
        #END FOR
        tmp_set = set(tmp_list)
        tmp_list = list(tmp_set)  #no duplicates
        del tmp_set
        tmp_list.sort()
        for k in tmp_list:
            self.myparentprefs[k] = " "  # ordered by key
        #END FOR
        del tmp_list
        #~ for k,v in prefs.iteritems():
        for k, v in iteritems(prefs):
            self.myparentprefs[k] = v
        #END FOR
        #~ for k,v in prefsdefaults.iteritems():
        for k, v in iteritems(prefsdefaults):
            if not k in prefs:
                prefs[k] = v
            else:
                if not prefs[k] > " ":
                    prefs[k] = v
            if not k in self.myparentprefs:
                self.myparentprefs[k] = v
            else:
                if not self.myparentprefs[k] > " ":
                    self.myparentprefs[k] = v
        #END FOR
        #~ for k,v in self.myparentprefs.iteritems():
        for k, v in iteritems(self.myparentprefs):
            prefs[k] = v
        #END FOR
        prefs  #prefs now synched
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.param_dict = collections.OrderedDict([])
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.init_tooltips_for_parent()
        self.setToolTip(self.parent_tooltip)
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        # Tab 0: LibraryCodesTab
        #-----------------------------------------------------
        #-----------------------------------------------------
        from calibre_plugins.library_codes.library_codes_dialog import LibraryCodesTab
        self.LibraryCodesTab = LibraryCodesTab(self.gui, self.guidb,
                                               self.myparentprefs,
                                               self.param_dict, self.ui_exit,
                                               self.save_dialog_geometry)
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #    Parent             LibraryCodesDialog
        #-----------------------------------------------------
        font = QFont()
        font.setBold(False)
        font.setPointSize(10)

        tablabel_font = QFont()
        tablabel_font.setBold(False)
        tablabel_font.setPointSize(10)

        #-----------------------------------------------------
        self.setWindowTitle('Library Codes')
        self.setWindowIcon(icon)
        #-----------------------------------------------------
        self.layout_frame = QVBoxLayout()
        self.layout_frame.setAlignment(Qt.AlignLeft)
        self.setLayout(self.layout_frame)
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        n_width = 600

        self.LCtabWidget = QTabWidget()
        self.LCtabWidget.setMaximumWidth(n_width)
        self.LCtabWidget.setFont(tablabel_font)

        self.LCtabWidget.addTab(
            self.LibraryCodesTab,
            "Derivation from ISBN or ISSN or Author/Title")
        self.LibraryCodesTab.setToolTip(
            "<p style='white-space:wrap'>Derive Library Codes DDC and/or LCC and/or OCLC-OWI from ISBN or ISSN or Author/Title.  Visit: http://classify.oclc.org/classify2/ "
        )
        self.LibraryCodesTab.setMaximumWidth(n_width)

        #-----------------------------------------------------
        self.layout_frame.addWidget(self.LCtabWidget)
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        #-----------------------------------------------------
        self.resize_dialog()  # inherited from SizePersistedDialog
        #-----------------------------------------------------
        self.LCtabWidget.setCurrentIndex(0)

    #-----------------------------------------------------------------------------------------
    #-----------------------------------------------------------------------------------------

    #-----------------------------------------------------------------------------------------
    #-----------------------------------------------------------------------------------------
    # OTHER
    #-----------------------------------------------------------------------------------------
    #-----------------------------------------------------------------------------------------
    def init_tooltips_for_parent(self):
        self.setStyleSheet(
            "QToolTip { color: #ffffff; background-color: #2a82da; border: 1px solid white; }"
        )
        self.parent_tooltip = "<p style='white-space:wrap'>" + \
        '''
Example #26
0
    def addVignette (self, warrior):
        label_name = "label_vignette_left"
        if self.current_page == 0 : 
            widget_vignette = QWidget(self.vignettes_gauche)
        else:
            label_name = "label_vignette_right"
            widget_vignette = QWidget(self.vignettes_droite)        
        # widget_vignette.setObjectName("toto")
        # widget_vignette.setStyleSheet("#toto { background-color: rgb(170, 255, 0,0);}")
        layout_one_vignette = QVBoxLayout(widget_vignette)
        layout_one_vignette.setSpacing(0)
        layout_one_vignette.setContentsMargins(0, 0, 0, 0)
        if type(warrior)== Temple:
            warrior_button = TempleButton(self.model, warrior, widget_vignette)
        else:
            warrior_button = HerosButton(self.model, warrior, widget_vignette)
        warrior_button.connect()
        layout_one_vignette.setAlignment(QtCore.Qt.AlignCenter)
#         warrior_button.setStyleSheet("QPushButton { background-color: rgb(170, 255, 0);border-style: outset; border-width: 2px; border-color: beige;}")
        # warrior_button.setAttribute(QtCore.Qt.WA_TranslucentBackground,True)
        layout_one_vignette.addWidget(warrior_button)
        
        # label
        if (type(warrior)==Temple):
            warrior_label = TempleLabel(warrior, widget_vignette)
        else:
            warrior_label = HerosLabel(warrior, widget_vignette)
        warrior_label.connect()
        warrior_label.setObjectName(label_name)
        layout_one_vignette.addWidget(warrior_label)
        

#         warrior_button.setFixedSize(QSize(100,120))
        max_col = 3

#         groupe_name = warrior.groupe().name
#         if warrior.masterGroupe() != None : 
#             groupe_name = warrior.masterGroupe().name + "/" + groupe_name
        
 
        
        size_pic_height = warrior_button.size().height()
        size_pic_width = warrior_button.size().width()
        ratio_h = warrior.thumb.height() / size_pic_height
        ratio_v = warrior.thumb.width() / size_pic_width
        picture = warrior.thumb
        if ratio_h < ratio_v :
            if not warrior.thumb.isNull():
                picture = warrior.thumb.scaledToHeight(size_pic_height)
                diff = picture.width() - size_pic_width
                picture = picture.copy(diff / 2.0, 0, size_pic_width, size_pic_height)
        else:
            if not warrior.thumb.isNull():
                picture = warrior.thumb.scaledToWidth(size_pic_width)
                diff = picture.height() - size_pic_height
                picture = picture.copy(0, diff / 2.0, size_pic_width, size_pic_height)

        icon = QIcon(picture)
        warrior_button.setIcon(icon)
        warrior_button.setIconSize(QSize(picture.width() - 3, picture.height() - 3))

            

        if self.nb_col == 0:
            self.nb_row = self.nb_row + 1

        if self.current_page == 0 : 
            self.gridLayout.addWidget(widget_vignette, self.nb_row, self.nb_col)
        else:
            self.gridLayout_2.addWidget(widget_vignette, self.nb_row, self.nb_col)
        self.nb_col = (self.nb_col + 1) % max_col
Example #27
0
class _BuilderTab(QWidget):
    """Handles the creation of launchers."""
    def __init__(self):
        super().__init__()

        self._layout = QVBoxLayout()

        host_label = QLabel("Server host (where EvilOSX will connect to):")
        self._host_field = QLineEdit()

        self._layout.addWidget(host_label)
        self._layout.addWidget(self._host_field)

        port_label = QLabel("Server port:")
        self._port_field = QLineEdit()

        self._layout.addWidget(port_label)
        self._layout.addWidget(self._port_field)

        live_label = QLabel(
            "Where should EvilOSX live? (Leave empty for ~/Library/Containers/.<RANDOM>): "
        )
        self._live_field = QLineEdit()

        self._layout.addWidget(live_label)
        self._layout.addWidget(self._live_field)

        launcher_label = QLabel("Launcher name:")
        self._launcher_combobox = QComboBox()

        for launcher_name in launchers.get_names():
            self._launcher_combobox.addItem(launcher_name)

        self._layout.addWidget(launcher_label)
        self._layout.addWidget(self._launcher_combobox)

        loader_label = QLabel("Loader name:")
        loader_combobox = QComboBox()
        self._loader_layout = QVBoxLayout()

        for loader_name in loaders.get_names():
            loader_combobox.addItem(loader_name)

        self._layout.addWidget(loader_label)
        self._layout.addWidget(loader_combobox)
        loader_combobox.currentTextChanged.connect(self._set_on_loader_change)

        # Dynamically loaded loader layout
        self._layout.addLayout(self._loader_layout)
        self._set_on_loader_change(loader_combobox.currentText())

        self._layout.setContentsMargins(10, 10, 10, 0)
        self._layout.setAlignment(Qt.AlignTop)
        self.setLayout(self._layout)

    def _set_on_loader_change(self, new_text: str):
        """Handles the loader combobox change event."""
        while self._loader_layout.count():
            child = self._loader_layout.takeAt(0)

            if child.widget():
                child.widget().deleteLater()

        input_fields = []

        for message in loaders.get_option_messages(new_text):
            input_field = QLineEdit()

            self._loader_layout.addWidget(QLabel(message))
            self._loader_layout.addWidget(input_field)
            input_fields.append(input_field)

        create_button = QPushButton("Create launcher")
        create_button.setMaximumWidth(250)
        create_button.setMinimumHeight(30)
        create_button.pressed.connect(lambda: self._on_create_launcher(
            self._host_field.text(), self._port_field.text(),
            self._live_field.text(), new_text,
            self._launcher_combobox.currentText(), input_fields))

        self._loader_layout.addWidget(QLabel(""))
        self._loader_layout.addWidget(create_button)

    @staticmethod
    def display_error(text: str):
        """Displays an error message to the user."""
        message = QMessageBox()

        message.setIcon(QMessageBox.Critical)
        message.setWindowTitle("Error")
        message.setText(text)
        message.setStandardButtons(QMessageBox.Ok)
        message.exec_()

    @staticmethod
    def display_info(text: str):
        message = QMessageBox()

        message.setIcon(QMessageBox.Information)
        message.setWindowTitle("Information")
        message.setText(text)
        message.setStandardButtons(QMessageBox.Ok)
        message.exec_()

    def _on_create_launcher(self, server_host, server_port, program_directory,
                            loader_name: str, launcher_name: str,
                            input_fields: list):
        """Creates the launcher and outputs it to the builds directory."""
        if not self._host_field.text():
            self.display_error("Invalid host specified.")
        elif not str(self._port_field.text()).isdigit():
            self.display_error("Invalid port specified.")
        else:
            set_options = []

            for field in input_fields:
                set_options.append(field.text())

            loader_options = loaders.get_options(loader_name, set_options)
            loader_options["program_directory"] = program_directory

            stager = launchers.create_stager(server_host, server_port,
                                             loader_options)

            launcher_extension, launcher = launchers.generate(
                launcher_name, stager)
            launcher_path = path.realpath(
                path.join(
                    path.dirname(__file__), path.pardir, path.pardir, "data",
                    "builds", "Launcher-{}.{}".format(
                        str(uuid4())[:6], launcher_extension)))

            with open(launcher_path, "w") as output_file:
                output_file.write(launcher)

            self.display_info(
                "Launcher written to: \n{}".format(launcher_path))
    def get_actions_widget(self):
        """
        Return QWidget with actions buttons

        :return: widget with buttons
        :rtype: QWidget
        """

        widget = QWidget()
        layout = QVBoxLayout()
        widget.setLayout(layout)

        # Actions
        action_title = QLabel(_('Host actions'))
        action_title.setObjectName('itemtitle')
        action_title.setFixedHeight(25)
        layout.addWidget(action_title)

        ack_down_lbl = QLabel(_('Acknowledge / Downtime:'))
        ack_down_lbl.setObjectName('subtitle')
        layout.addWidget(ack_down_lbl)

        self.actions_widget.initialize(self.host_item)
        layout.addWidget(self.actions_widget)

        # Active Checks
        activecheck_lbl = QLabel(_('Active checks:'))
        activecheck_lbl.setObjectName('subtitle')
        layout.addWidget(activecheck_lbl)
        self.activecheck_btn.initialize()
        self.activecheck_btn.toggle_btn.clicked.connect(
            lambda: self.patch_host_checks('active_checks_enabled',
                                           self.activecheck_btn.is_checked()))
        layout.addWidget(self.activecheck_btn)

        # Passive Checks
        passivecheck_lbl = QLabel(_('Passive checks:'))
        passivecheck_lbl.setObjectName('subtitle')
        layout.addWidget(passivecheck_lbl)
        self.passivecheck_btn.initialize()
        self.passivecheck_btn.toggle_btn.clicked.connect(
            lambda: self.patch_host_checks('passive_checks_enabled',
                                           self.passivecheck_btn.is_checked()))
        layout.addWidget(self.passivecheck_btn)

        # History
        hist_lbl = QLabel(_('Timeline:'))
        hist_lbl.setObjectName('subtitle')
        layout.addWidget(hist_lbl)
        self.history_btn.setIcon(QIcon(settings.get_image('time')))
        self.history_btn.setFixedSize(80, 20)
        self.history_btn.clicked.connect(self.show_history)
        self.history_btn.setToolTip(_('See history of host'))
        layout.addWidget(self.history_btn)
        layout.setAlignment(self.history_btn, Qt.AlignCenter)

        self.history_widget.initialize()

        # Spy Button
        spy_lbl = QLabel(_('Spy Host:'))
        spy_lbl.setObjectName('subtitle')
        layout.addWidget(spy_lbl)
        self.spy_btn.setIcon(QIcon(settings.get_image('spy')))
        self.spy_btn.setFixedSize(80, 20)
        self.spy_btn.setToolTip(_('Spy current host'))
        layout.addWidget(self.spy_btn)
        layout.setAlignment(self.spy_btn, Qt.AlignCenter)

        layout.setAlignment(Qt.AlignCenter | Qt.AlignTop)

        return widget
    def get_actions_widget(self):
        """
        Return QWidget with actions buttons

        :return: widget with buttons
        :rtype: QWidget
        """

        widget = QWidget()
        layout = QVBoxLayout()
        widget.setLayout(layout)

        # Actions
        action_title = QLabel(_('Host actions'))
        action_title.setObjectName('itemtitle')
        action_title.setFixedHeight(25)
        layout.addWidget(action_title)

        ack_down_lbl = QLabel(_('Acknowledge / Downtime:'))
        ack_down_lbl.setObjectName('subtitle')
        layout.addWidget(ack_down_lbl)

        self.actions_widget.initialize(self.host_item)
        layout.addWidget(self.actions_widget)

        # Active Checks
        activecheck_lbl = QLabel(_('Active checks:'))
        activecheck_lbl.setObjectName('subtitle')
        layout.addWidget(activecheck_lbl)
        self.activecheck_btn.initialize()
        self.activecheck_btn.toggle_btn.clicked.connect(lambda: self.patch_host_checks(
            'active_checks_enabled', self.activecheck_btn.is_checked()
        ))
        layout.addWidget(self.activecheck_btn)

        # Passive Checks
        passivecheck_lbl = QLabel(_('Passive checks:'))
        passivecheck_lbl.setObjectName('subtitle')
        layout.addWidget(passivecheck_lbl)
        self.passivecheck_btn.initialize()
        self.passivecheck_btn.toggle_btn.clicked.connect(lambda: self.patch_host_checks(
            'passive_checks_enabled', self.passivecheck_btn.is_checked()
        ))
        layout.addWidget(self.passivecheck_btn)

        # History
        hist_lbl = QLabel(_('Timeline:'))
        hist_lbl.setObjectName('subtitle')
        layout.addWidget(hist_lbl)
        self.history_btn.setIcon(QIcon(settings.get_image('time')))
        self.history_btn.setFixedSize(80, 20)
        self.history_btn.clicked.connect(self.show_history)
        self.history_btn.setToolTip(_('See history of host'))
        layout.addWidget(self.history_btn)
        layout.setAlignment(self.history_btn, Qt.AlignCenter)

        self.history_widget.initialize()

        # Spy Button
        spy_lbl = QLabel(_('Spy Host:'))
        spy_lbl.setObjectName('subtitle')
        layout.addWidget(spy_lbl)
        self.spy_btn.setIcon(QIcon(settings.get_image('spy')))
        self.spy_btn.setFixedSize(80, 20)
        self.spy_btn.setToolTip(_('Spy current host'))
        layout.addWidget(self.spy_btn)
        layout.setAlignment(self.spy_btn, Qt.AlignCenter)

        layout.setAlignment(Qt.AlignCenter | Qt.AlignTop)

        return widget
    def get_settings_widget(self):
        """
        Return the alignak settings QWidget

        :return: settings QWidget
        :rtype: QWidget
        """

        server_widget = QWidget()
        server_widget.setObjectName('dialog')
        server_layout = QVBoxLayout(server_widget)

        # Title
        title_lbl = QLabel(_('Alignak Backend'))
        title_lbl.setObjectName('itemtitle')
        server_layout.addWidget(title_lbl)
        server_layout.setAlignment(title_lbl, Qt.AlignTop)

        # Description
        desc_label = QLabel(
            _('Here you can define alignak settings. Be sure to enter a valid address.')
        )
        desc_label.setWordWrap(True)
        server_layout.addWidget(desc_label)

        # Server URL
        server_lbl = QLabel(_('Server'))
        server_layout.addWidget(server_lbl)

        self.server_url.setText(settings.get_config('Alignak', 'url'))
        self.server_url.setPlaceholderText(_('alignak backend url...'))
        self.server_url.setFixedHeight(25)
        server_layout.addWidget(self.server_url)

        # Server Port
        port_lbl = QLabel(_('Port'))
        server_layout.addWidget(port_lbl)

        cur_port = settings.get_config('Alignak', 'backend').split(':')[2]
        self.server_port.setText(cur_port)
        self.server_port.setPlaceholderText(_('alignak backend port...'))
        self.server_port.setFixedHeight(25)
        server_layout.addWidget(self.server_port)

        # Server Processes (displayed only for Unix platforms)
        if 'win32' not in sys.platform:
            process_lbl = QLabel(_('Processes'))
            server_layout.addWidget(process_lbl)

            cur_proc = settings.get_config('Alignak', 'processes')
            self.server_proc.setText(cur_proc)
            self.server_proc.setPlaceholderText(_('alignak backend processes...'))
            self.server_proc.setFixedHeight(25)
            server_layout.addWidget(self.server_proc)

        # Web Service description
        server_layout.addStretch(1)
        webservice_lbl = QLabel(_('Web Service'))
        webservice_lbl.setObjectName('itemtitle')
        server_layout.addWidget(webservice_lbl)
        ws_desc_lbl = QLabel(
            _('Here you can define your alignak web service url, with port if needed')
        )
        ws_desc_lbl.setWordWrap(True)
        server_layout.addWidget(ws_desc_lbl)

        # Web Service URL
        self.webservice_url.setText(settings.get_config('Alignak', 'webservice'))
        self.webservice_url.setPlaceholderText(_('alignak webservice url...'))
        self.webservice_url.setFixedHeight(25)
        server_layout.addWidget(self.webservice_url)

        # Valid Button
        valid_btn = QPushButton(_('Valid'))
        valid_btn.setObjectName('valid')
        valid_btn.setMinimumHeight(30)
        valid_btn.clicked.connect(self.accept)

        server_layout.addWidget(valid_btn)

        return server_widget
    def setup_ui(self):
        layout = QVBoxLayout()
        self.setLayout(layout)
        columns_frame = QHBoxLayout()
        layout.addLayout(columns_frame)

        # How many columns of nine items each will it take to display
        # a text box for each tag in taglist?
        col_limit = 9
        num_cols = len(TAGLIST)/col_limit
        num_cols = int(math.ceil(num_cols))

        # If the column limit and the number of columns produces a single
        # orphan text entry widget, reduce the column limit accordingly.
        if num_cols > 1 and (len(TAGLIST) - ((num_cols - 1)*col_limit)) < 2:
            if num_cols >= 3:
                col_limit -= 1

        # Create an integer-indexed dictionary of QVBoxLayouts representing the number of
        # columns necessary. Added left to right in the parent QHBoxLayout.
        column = {}
        for i in xrange(1, num_cols+1):
            column[i] = QVBoxLayout()
            column[i].setAlignment(Qt.AlignLeft)
            columns_frame.addLayout(column[i])

        # Create a dictionary of QLineEdit widgets (indexed by tag name) and stack them
        # (top to bottom) and their labels in as many columns as it takes.
        curr_col = 1
        curr_item = 1
        tooltip = _('Comma separated list of html elements (no quotes, no angle "&lt;" brackets).')
        for tag in TAGLIST:
            # Column item limit surpassed - switch to next column.
            if curr_item > col_limit:
                column[curr_col].addStretch()
                curr_col += 1
                curr_item = 1
            # Add lable and QLineEdit widget to current column.
            label = QLabel(_('<b>Choices to change "{}" elements to:</b>').format(tag), self)
            label.setAlignment(Qt.AlignCenter)
            self.qlinedit_widgets[tag] = QLineEdit(', '.join(plugin_prefs['{}_changes'.format(tag)]), self)
            self.qlinedit_widgets[tag].setToolTip('<p>{}'.format(tooltip))
            column[curr_col].addWidget(label)
            column[curr_col].addWidget(self.qlinedit_widgets[tag])

            if not len(CHANGE_TO_MAP[tag]):
                self.qlinedit_widgets[tag].setDisabled(True)
            curr_item += 1
        column[curr_col].addStretch()

        layout.addSpacing(10)
        attrs_layout = QVBoxLayout()
        attrs_layout.setAlignment(Qt.AlignCenter)
        layout.addLayout(attrs_layout)
        label = QLabel(_('<b>HTML attributes available to search for:</b>'), self)
        label.setAlignment(Qt.AlignCenter)
        self.attrs_txtBox = QLineEdit(', '.join(plugin_prefs['attrs']), self)
        self.attrs_txtBox.setToolTip('<p>{}'.format(_('Comma separated list of html attribute names (no quotes).')))
        attrs_layout.addWidget(label)
        attrs_layout.addWidget(self.attrs_txtBox)

        layout.addSpacing(10)
        right_layout = QHBoxLayout()
        right_layout.setAlignment(Qt.AlignRight)
        layout.addLayout(right_layout)
        reset_button = QPushButton(_('Reset all defaults'), self)
        reset_button.setToolTip('<p>{}'.format(_('Reset all settings to original defaults.')))
        reset_button.clicked.connect(self.reset_defaults)
        right_layout.addWidget(reset_button)

        layout.addSpacing(10)
        button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        button_box.accepted.connect(self.save_settings)
        button_box.rejected.connect(self.reject)
        layout.addWidget(button_box)
    def initialize(self):
        """
        Initialize QDialog

        """

        main_layout = QVBoxLayout()
        main_layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(main_layout)

        about_widget = QWidget()
        about_widget.setObjectName('about')
        about_layout = QVBoxLayout(about_widget)

        # QDialog Title
        about_title = QLabel(_('About'))
        about_title.setFixedHeight(40)
        about_title.setObjectName('aboutheader')
        main_layout.addWidget(about_title)

        # Main About
        about_text = "%s\nVersion %s\nCopyright: %s" % \
            (__application__, __version__, __copyright__)
        main_about = QLabel(about_text)
        main_about.setObjectName('aboutmain')
        main_about.setToolTip(__application__)
        about_layout.addWidget(main_about)
        about_layout.setAlignment(main_about, Qt.AlignCenter)

        # Release notes
        release_data = QLabel(__releasenotes__)
        release_data.setObjectName('about')
        release_data.setToolTip(_('Release notes'))
        release_data.setWordWrap(True)
        about_layout.addWidget(release_data)

        # Homepage
        home_title = QLabel(_('Home page:'))
        home_title.setObjectName('abouttitle')
        home_title.setToolTip(_('Home page'))
        about_layout.addWidget(home_title)
        about_layout.addWidget(self.get_external_link_label(__project_url__))

        # User Doc
        doc_title = QLabel(_('User documentation'))
        doc_title.setObjectName('abouttitle')
        doc_title.setToolTip(_('User documentation'))
        about_layout.addWidget(doc_title)
        about_layout.addWidget(self.get_external_link_label(__doc_url__))

        # Alignak
        alignak_title = QLabel(_('About Alignak solution:'))
        alignak_title.setObjectName('abouttitle')
        alignak_title.setToolTip(_('About Alignak solution'))
        about_layout.addWidget(alignak_title)
        about_layout.addWidget(self.get_external_link_label(__alignak_url__))

        # Powered
        powered_title = QLabel(_('Powered by:'))
        powered_title.setObjectName('abouttitle')
        powered_title.setToolTip(_('PyQt5'))
        about_layout.addWidget(powered_title)
        powered_data = self.get_external_link_label(
            'https://www.riverbankcomputing.com/', 'PyQt5')
        about_layout.addWidget(powered_data)

        main_layout.addWidget(about_widget)