class ProxyQDialog(QDialog):
    """
        Class who create a Proxy QDialog
    """

    def __init__(self, parent=None):
        super(ProxyQDialog, self).__init__(parent)
        self.setWindowTitle(_('Proxy Configuration'))
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setStyleSheet(settings.css_style)
        self.setWindowIcon(QIcon(settings.get_image('icon')))
        self.setObjectName('dialog')
        self.setFixedSize(320, 380)
        # Fields
        self.proxy_address = QLineEdit()
        self.proxy_user = QLineEdit()
        self.proxy_password = QLineEdit()
        self.offset = None

    def initialize_dialog(self):
        """
        Initialize Proxy QDialog

        """

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

        main_layout.addWidget(get_logo_widget(self, _('Proxy Settings')))

        main_layout.addWidget(self.get_proxy_widget())

        center_widget(self)

    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

    def accept_proxy(self):
        """
        Accept QDialog if proxy is valid

        """

        if self.proxy_address.text() or self.proxy_user.text() or self.proxy_password.text():
            try:
                _, _, _ = self.proxy_address.text().split(':')
                self.accept()
            except ValueError:
                self.proxy_error()
        else:
            self.accept()

    @staticmethod
    def proxy_error():  # pragma: no cover - not testable
        """
        Display a Message QDialog error

        """

        error_dialog = MessageQDialog()
        error_dialog.initialize(
            'Proxy Error', 'error', 'Wrong proxy setting !',
            'You must enter a valid address: "http://proxy:port"'
        )
        error_dialog.exec_()

    def mousePressEvent(self, event):  # pragma: no cover - not testable
        """ QWidget.mousePressEvent(QMouseEvent) """

        self.offset = event.pos()

    def mouseMoveEvent(self, event):  # pragma: no cover - not testable
        """ QWidget.mousePressEvent(QMouseEvent) """

        try:
            x = event.globalX()
            y = event.globalY()
            x_w = self.offset.x()
            y_w = self.offset.y()
            self.move(x - x_w, y - y_w)
        except AttributeError as e:
            logger.warning('Move Event %s: %s', self.objectName(), str(e))
示例#2
0
class ServerQDialog(QDialog):
    """
        Class who create Server QDialog.
    """
    def __init__(self, parent=None):
        super(ServerQDialog, self).__init__(parent)
        self.setWindowTitle(_('Alignak Settings'))
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setStyleSheet(settings.css_style)
        self.setWindowIcon(QIcon(settings.get_image('icon')))
        self.setObjectName('dialog')
        self.setFixedSize(340, 420)
        # Fields
        self.server_proc = QLineEdit()
        self.server_url = QLineEdit()
        self.server_port = QLineEdit()
        self.webservice_url = QLineEdit()
        self.proxy_address = QLineEdit()
        self.proxy_user = QLineEdit()
        self.proxy_password = QLineEdit()
        self.offset = None

    def initialize_dialog(self):
        """
        Initialize Server QDialog

        """

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

        main_layout.addWidget(get_logo_widget(self, _('Alignak Settings')))

        main_layout.addWidget(self.get_settings_widget())

        center_widget(self)

    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 mousePressEvent(self, event):  # pragma: no cover - not testable
        """ QWidget.mousePressEvent(QMouseEvent) """

        self.offset = event.pos()

    def mouseMoveEvent(self, event):  # pragma: no cover - not testable
        """ QWidget.mousePressEvent(QMouseEvent) """

        try:
            x = event.globalX()
            y = event.globalY()
            x_w = self.offset.x()
            y_w = self.offset.y()
            self.move(x - x_w, y - y_w)
        except AttributeError as e:
            logger.warning('Move Event %s: %s', self.objectName(), str(e))
class ProblemsQWidget(QWidget):
    """
        Class who create Problems QWidget
    """
    def __init__(self, parent=None):
        super(ProblemsQWidget, self).__init__(parent)
        self.setWindowIcon(QIcon(settings.get_image('icon')))
        # Fields
        self.line_search = QLineEdit()
        self.problems_table = ProblemsQTableView()
        self.problems_title = QLabel()
        self.actions_widget = ActionsQWidget()
        self.spy_widget = None
        self.filter_hosts_btn = ToggleQWidgetButton()
        self.filter_services_btn = ToggleQWidgetButton()
        self.spy_btn = QPushButton()
        self.host_btn = QPushButton()
        self.refresh_timer = QTimer()

    def initialize(self, spy_widget):
        """
        Initialize QWidget and set SpyQWidget

        :param spy_widget: instance of SpyQWidget to manage spy events
        :type spy_widget: alignak_app.qobjects.events.spy.SpyQWidget
        """

        problem_layout = QVBoxLayout()
        problem_layout.setContentsMargins(5, 20, 5, 5)
        self.setLayout(problem_layout)

        self.spy_widget = spy_widget

        self.problems_title.setObjectName('title')
        problem_layout.addWidget(self.problems_title)

        problem_layout.addWidget(self.get_search_widget())

        problem_layout.addWidget(self.get_btn_widget())

        problem_layout.addWidget(self.problems_table)

        self.update_problems_data()

        update_problems = int(
            settings.get_config('Alignak-app', 'update_problems')) * 1000
        self.refresh_timer.setInterval(update_problems)
        self.refresh_timer.start()
        self.refresh_timer.timeout.connect(self.update_problems_data)

    def get_current_user_role_item(self):
        """
        Return current selected item by ``Qt.UserRole``

        :return: current selected item or None
        :rtype: alignak_app.items.item.Item
        """

        item = self.problems_table.model().data(
            self.problems_table.selectionModel().currentIndex(), Qt.UserRole)

        return item

    def update_action_buttons(self):
        """
        Update status of action buttons and set current item for ActionsQWidget

        """

        # Get item by UserRole
        item = self.get_current_user_role_item()

        if item:
            # If the elements had been ack or downtimed, they would not be present
            self.actions_widget.acknowledge_btn.setEnabled(True)
            self.actions_widget.downtime_btn.setEnabled(True)
            self.actions_widget.item = item

            if 'service' in item.item_type:
                host_id = item.data['host']
            else:
                host_id = item.item_id
            self.spy_btn.setEnabled(
                bool(host_id not in
                     self.spy_widget.spy_list_widget.spied_hosts))
            self.host_btn.setEnabled(True)
        else:
            self.actions_widget.acknowledge_btn.setEnabled(False)
            self.actions_widget.downtime_btn.setEnabled(False)
            self.host_btn.setEnabled(False)
            self.spy_btn.setEnabled(False)

    def get_search_widget(self):
        """
        Create and return the search QWidget

        :return: search QWidget
        :rtype: QWidget
        """

        widget = QWidget()
        layout = QHBoxLayout()
        layout.setSpacing(0)
        layout.setContentsMargins(5, 20, 5, 10)
        widget.setLayout(layout)

        # Search label
        search_lbl = QLabel(_('Search Problems'))
        search_lbl.setObjectName('bordertitle')
        search_lbl.setFixedHeight(25)
        search_lbl.setToolTip(_('Search Problems'))
        layout.addWidget(search_lbl)

        # QLineEdit
        self.line_search.setFixedHeight(search_lbl.height())
        self.line_search.setPlaceholderText(
            _('Type text to filter problems...'))
        layout.addWidget(self.line_search)

        # Refresh button
        refresh_btn = QPushButton(_('Refresh'))
        refresh_btn.setObjectName('ok')
        refresh_btn.setFixedSize(120, search_lbl.height())
        refresh_btn.setToolTip(_('Refresh problems'))
        refresh_btn.clicked.connect(self.update_problems_data)
        layout.addWidget(refresh_btn)

        return widget

    def get_btn_widget(self):
        """
        Return QWidget with spy and host synthesis QPushButtons

        :return: widget with spy and host button
        :rtype: QWidget
        """

        widget_btn = QWidget()
        layout_btn = QHBoxLayout()
        layout_btn.setContentsMargins(0, 0, 0, 5)
        widget_btn.setLayout(layout_btn)

        host_filter = QLabel(_('Filter hosts'))
        host_filter.setObjectName('subtitle')
        layout_btn.addWidget(host_filter)
        self.filter_hosts_btn.initialize()
        self.filter_hosts_btn.update_btn_state(False)
        self.filter_hosts_btn.toggle_btn.clicked.connect(
            lambda: self.update_problems_data('host'))
        layout_btn.addWidget(self.filter_hosts_btn)

        service_filter = QLabel(_('Filter services'))
        service_filter.setObjectName('subtitle')
        layout_btn.addWidget(service_filter)
        self.filter_services_btn.initialize()
        self.filter_services_btn.update_btn_state(False)
        self.filter_services_btn.toggle_btn.clicked.connect(
            lambda: self.update_problems_data('service'))
        layout_btn.addWidget(self.filter_services_btn)

        layout_btn.addStretch()

        self.host_btn.setIcon(QIcon(settings.get_image('host')))
        self.host_btn.setFixedSize(80, 20)
        self.host_btn.setEnabled(False)
        self.host_btn.setToolTip(_('See current item in synthesis view'))
        layout_btn.addWidget(self.host_btn)

        self.spy_btn.setIcon(QIcon(settings.get_image('spy')))
        self.spy_btn.setFixedSize(80, 20)
        self.spy_btn.setEnabled(False)
        self.spy_btn.setToolTip(_('Spy current host'))
        self.spy_btn.clicked.connect(self.add_spied_host)
        layout_btn.addWidget(self.spy_btn)

        self.actions_widget.initialize(None)
        self.actions_widget.acknowledge_btn.setEnabled(False)
        self.actions_widget.downtime_btn.setEnabled(False)
        layout_btn.addWidget(self.actions_widget)

        layout_btn.setAlignment(Qt.AlignCenter)

        return widget_btn

    def add_spied_host(self):
        """
        Add a host to spied hosts

        """

        # Get item by UserRole
        item = self.get_current_user_role_item()

        if item:
            if 'service' in item.item_type:
                item_id = item.data['host']
            else:
                item_id = item.item_id

            app_backend.query_services(item_id)
            self.spy_widget.spy_list_widget.add_spy_host(item_id)
            self.spy_widget.update_parent_spytab()

        self.update_action_buttons()

    def update_problems_data(self, item_type=''):
        """
        Update data of Problems QTableWidget and problems title

        :param item_type: type of item to filter
        :type item_type: str
        """

        problems_data = data_manager.get_problems()
        old_research = self.line_search.text()

        if self.parent():
            self.parent().parent().setTabText(
                self.parent().parent().indexOf(self),
                _("Problems (%d)") % len(problems_data['problems']))
            self.problems_title.setText(
                _('There are %d problems to manage (hosts: %d, services: %d)')
                % (len(problems_data['problems']), problems_data['hosts_nb'],
                   problems_data['services_nb']))

        if self.filter_hosts_btn.is_checked(
        ) and not self.filter_services_btn.is_checked():
            item_type = 'host'
        if self.filter_services_btn.is_checked(
        ) and not self.filter_hosts_btn.is_checked():
            item_type = 'service'
        if not self.filter_services_btn.is_checked(
        ) and not self.filter_hosts_btn.is_checked():
            item_type = ''

        if isinstance(item_type, str):
            if 'host' in item_type and self.filter_hosts_btn.is_checked():
                if self.filter_services_btn.is_checked():
                    self.filter_services_btn.update_btn_state(False)
            if 'service' in item_type and self.filter_services_btn.is_checked(
            ):
                if self.filter_hosts_btn.is_checked():
                    self.filter_hosts_btn.update_btn_state(False)
            problems_data['problems'] = [
                item for item in problems_data['problems']
                if item_type in item.item_type
            ]

        proxy_filter = self.problems_table.update_view(problems_data)
        if problems_data['problems']:
            self.line_search.textChanged.connect(proxy_filter.setFilterRegExp)
        else:
            self.problems_title.setText(
                _('If problems are found, they will be displayed here.'))

        self.problems_table.selectionModel().selectionChanged.connect(
            self.update_action_buttons)
        self.update_action_buttons()

        if old_research:
            self.line_search.setText(old_research)
            self.line_search.textChanged.emit(old_research)
class ServerQDialog(QDialog):
    """
        Class who create Server QDialog.
    """

    def __init__(self, parent=None):
        super(ServerQDialog, self).__init__(parent)
        self.setWindowTitle(_('Alignak Settings'))
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setStyleSheet(settings.css_style)
        self.setWindowIcon(QIcon(settings.get_image('icon')))
        self.setObjectName('dialog')
        self.setFixedSize(340, 420)
        # Fields
        self.server_proc = QLineEdit()
        self.server_url = QLineEdit()
        self.server_port = QLineEdit()
        self.webservice_url = QLineEdit()
        self.proxy_address = QLineEdit()
        self.proxy_user = QLineEdit()
        self.proxy_password = QLineEdit()
        self.offset = None

    def initialize_dialog(self):
        """
        Initialize Server QDialog

        """

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

        main_layout.addWidget(get_logo_widget(self, _('Alignak Settings')))

        main_layout.addWidget(self.get_settings_widget())

        center_widget(self)

    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 mousePressEvent(self, event):  # pragma: no cover - not testable
        """ QWidget.mousePressEvent(QMouseEvent) """

        self.offset = event.pos()

    def mouseMoveEvent(self, event):  # pragma: no cover - not testable
        """ QWidget.mousePressEvent(QMouseEvent) """

        try:
            x = event.globalX()
            y = event.globalY()
            x_w = self.offset.x()
            y_w = self.offset.y()
            self.move(x - x_w, y - y_w)
        except AttributeError as e:
            logger.warning('Move Event %s: %s', self.objectName(), str(e))
class SynthesisQWidget(QWidget):
    """
        Class who manage Synthesis view with Host and Services QWidgets
    """

    def __init__(self, parent=None):
        super(SynthesisQWidget, self).__init__(parent)
        # Fields
        self.host_widget = HostQWidget()
        self.services_widget = ServicesQWidget()
        self.line_search = QLineEdit()
        self.completer = QCompleter()
        self.hint_widget = QWidget()

    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 get_search_widget(self):
        """
        Create and return the search QWidget

        :return: search QWidget
        :rtype: QWidget
        """

        widget = QWidget()
        layout = QHBoxLayout()
        layout.setSpacing(0)
        widget.setLayout(layout)

        # Search label
        search_lbl = QLabel(_('Search Host'))
        search_lbl.setObjectName('bordertitle')
        search_lbl.setFixedHeight(25)
        search_lbl.setToolTip(_('Search Host'))
        layout.addWidget(search_lbl)

        # QLineEdit
        self.line_search.setFixedHeight(search_lbl.height())
        layout.addWidget(self.line_search)
        self.create_line_search([])

        return widget

    def create_line_search(self, hostnames_list):
        """
        Add all hosts to QLineEdit and set QCompleter

        :param hostnames_list: list of host names
        :type hostnames_list: list
        """

        # Get QStringListModel
        model = self.completer.model()
        if not model:
            model = QStringListModel()

        model.setStringList(hostnames_list)

        # Configure QCompleter from model
        self.completer.setFilterMode(Qt.MatchContains)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setModel(model)
        self.completer.popup().setObjectName('popup')

        # Add completer to QLineEdit
        self.line_search.setCompleter(self.completer)
        self.line_search.setPlaceholderText(_('Type a host name to display its data'))
        self.line_search.setToolTip(_('Type a host name to display its data'))

    def update_synthesis(self, host, services, not_spied):
        """
        Update Synthesis QWidget with given host and services

        :param host: host item
        :type host: alignak_app.items.host.Host
        :param services: list of services attached to host
        :type services: list
        :param not_spied: define if host is spied or not
        :type not_spied: bool
        """

        self.host_widget.spy_btn.setEnabled(not_spied)

        if host:
            logger.info('Display %s in synthesis view', host.name)
            # Update Qwidgets
            self.host_widget.update_host(host)
            self.services_widget.update_widget(services)
            self.hint_widget.hide()
            self.host_widget.show()
            self.services_widget.show()

            # If the service element does not have the same ID as the host, reset to None
            if self.services_widget.service_data_widget.service_item:
                if self.services_widget.service_data_widget.service_item.data['host'] != \
                        self.host_widget.host_item.item_id:
                    self.services_widget.service_data_widget.service_item = None

        else:
            self.host_widget.hide()
            self.services_widget.hide()
            self.hint_widget.show()
示例#6
0
class LoginQDialog(QDialog):
    """
        Class who create login QDialog.
    """
    def __init__(self, parent=None):
        super(LoginQDialog, self).__init__(parent)
        self.setWindowTitle('Login to Alignak')
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setStyleSheet(settings.css_style)
        self.setWindowIcon(QIcon(settings.get_image('icon')))
        self.setObjectName('dialog')
        self.setFixedSize(310, 360)
        # Fields
        self.username_line = QLineEdit()
        self.password_line = QLineEdit()
        self.proxies = {}
        self.offset = None

    def create_widget(self):
        """
        Create widget login

        """

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

        main_layout.addWidget(get_logo_widget(self, _('Login'), exitapp=True))

        # Login QWidget
        login_widget = QWidget(self)
        login_widget.setObjectName('dialog')
        login_layout = QGridLayout()
        login_widget.setLayout(login_layout)

        # _ = init_localization()
        title = QLabel(_('Welcome to Alignak-app'))
        title.setObjectName('itemtitle')
        title.setContentsMargins(1, 1, 1, 1)
        login_layout.addWidget(title, 0, 0, 1, 2)
        login_layout.setAlignment(title, Qt.AlignCenter)

        version = QLabel(_('Version %s') % __version__)
        version.setObjectName('subtitle')
        login_layout.addWidget(version, 1, 0, 1, 2)
        login_layout.setAlignment(version, Qt.AlignCenter | Qt.AlignTop)

        # Alignak server
        login_label = QLabel(_('Configure Alignak server'))
        login_layout.addWidget(login_label, 2, 0, 1, 1)
        login_layout.setAlignment(login_label, Qt.AlignRight)

        server_btn = QPushButton()
        server_btn.clicked.connect(self.handle_server)
        server_btn.setFixedSize(35, 35)
        server_btn.setIcon(QIcon(settings.get_image('server_settings')))
        server_btn.setToolTip(_('Configure Alignak Server'))
        login_layout.addWidget(server_btn, 2, 1, 1, 1)

        # Proxy settings
        proxy_lbl = QLabel(_('Configure Proxy'))
        login_layout.addWidget(proxy_lbl, 3, 0, 1, 1)
        login_layout.setAlignment(proxy_lbl, Qt.AlignRight)

        proxy_btn = QPushButton()
        proxy_btn.setIcon(QIcon(settings.get_image('password')))
        proxy_btn.setToolTip(_('Configure your Proxy'))
        proxy_btn.setFixedSize(35, 35)
        proxy_btn.clicked.connect(self.handle_proxy)
        login_layout.addWidget(proxy_btn, 3, 1, 1, 1)

        # Connection label
        connection_lbl = QLabel()
        connection_lbl.setText(_('<b>Log-in</b> to use the application'))
        connection_lbl.setWordWrap(True)
        login_layout.addWidget(connection_lbl, 4, 0, 1, 2)

        # Username field
        self.username_line.setFixedHeight(25)
        self.username_line.setPlaceholderText(_('username...'))
        login_layout.addWidget(self.username_line, 5, 0, 1, 2)

        # Password field
        self.password_line.setFixedHeight(25)
        self.password_line.setPlaceholderText(_('password...'))
        self.password_line.setEchoMode(QLineEdit.Password)
        login_layout.addWidget(self.password_line, 6, 0, 1, 2)

        # Login button
        login_button = QPushButton(_('LOGIN'), self)
        login_button.clicked.connect(self.accept_login)
        login_button.setObjectName('valid')
        login_button.setMinimumHeight(30)
        login_button.setDefault(True)
        login_layout.addWidget(login_button, 7, 0, 1, 2)

        main_layout.addWidget(login_widget)
        self.setLayout(main_layout)

        center_widget(self)

        if settings.get_config('Alignak', 'proxy_user'):
            self.handle_proxy()

    def accept_login(self):
        """
        Accept Login or not if backend is connected

        """

        username = str(self.username_line.text())
        password = str(self.password_line.text())

        # Set proxy only if in config
        if not self.proxies and settings.get_config('Alignak', 'proxy'):
            self.set_proxy_settings()

        if app_backend.login(username, password, proxies=self.proxies):
            self.accept()
        else:
            self.reject()

    def set_proxy_settings(self, proxy_password=None):
        """
        Set the proxy settings, with password if given

        :param proxy_password: the pasword of proxy
        :type proxy_password: str
        """

        if settings.get_config('Alignak', 'proxy_user'):
            # Model is: {'http': 'http://*****:*****@proxy:port'}
            protocol, address, port = settings.get_config('Alignak',
                                                          'proxy').split(':')
            proxy_user = settings.get_config('Alignak', 'proxy_user')
            address = address.replace('//', '')
            proxy = {
                protocol:
                '%s://%s:%s@%s:%s' %
                (protocol, proxy_user, proxy_password, address, port)
            }
            self.proxies = proxy
        elif settings.get_config('Alignak', 'proxy'):
            protocol = settings.get_config('Alignak', 'proxy').split(':')[0]
            self.proxies = {protocol: settings.get_config('Alignak', 'proxy')}
        else:
            self.proxies = {}

    def handle_proxy(self):  # pragma: no cover - not testable
        """
        Handle Proxy QDialog display and set proxies for login

        """

        proxy_dialog = ProxyQDialog()
        proxy_dialog.initialize_dialog()

        self.proxies = None

        if proxy_dialog.exec_() == ProxyQDialog.Accepted:
            proxy_address = proxy_dialog.proxy_address.text().rstrip()
            proxy_user = proxy_dialog.proxy_user.text().rstrip()
            proxy_password = proxy_dialog.proxy_password.text().rstrip()

            # Save proxy and user proxy for next login
            settings.set_config('Alignak', 'proxy', proxy_address)
            settings.set_config('Alignak', 'proxy_user', proxy_user)

            self.set_proxy_settings(proxy_password)

    @staticmethod
    def handle_server():  # pragma: no cover - not testable
        """
        Handle for Server QDialog and set alignak backend server settings

        """

        server_dialog = ServerQDialog()
        server_dialog.initialize_dialog()

        if server_dialog.exec_() == QDialog.Accepted:
            if server_dialog.server_port.text().rstrip():
                backend_url = '%(url)s:' + str(
                    server_dialog.server_port.text()).rstrip()
            else:
                backend_url = '%(url)s'
            settings.set_config('Alignak', 'backend', backend_url)
            settings.set_config('Alignak', 'url',
                                str(server_dialog.server_url.text()).rstrip())
            settings.set_config('Alignak', 'processes',
                                str(server_dialog.server_proc.text()).rstrip())
            settings.set_config(
                'Alignak', 'webservice',
                str(server_dialog.webservice_url.text()).rstrip())

    def showEvent(self, _):
        """ QDialog.showEvent(QShowEvent) """

        self.username_line.setFocus()

    def mousePressEvent(self, event):  # pragma: no cover - not testable
        """ QWidget.mousePressEvent(QMouseEvent) """

        self.offset = event.pos()

    def mouseMoveEvent(self, event):  # pragma: no cover - not testable
        """ QWidget.mousePressEvent(QMouseEvent) """

        try:
            x = event.globalX()
            y = event.globalY()
            x_w = self.offset.x()
            y_w = self.offset.y()
            self.move(x - x_w, y - y_w)
        except AttributeError as e:
            logger.warning('Move Event %s: %s', self.objectName(), str(e))
class ValidatorQDialog(QDialog):
    """
        Class who create Validator QDialog to edit text in Alignak-app with regexp to validate
    """
    def __init__(self, parent=None):
        super(ValidatorQDialog, self).__init__(parent)
        self.setWindowTitle('Edit Dialog')
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setStyleSheet(settings.css_style)
        self.setWindowIcon(QIcon(settings.get_image('icon')))
        self.setObjectName('dialog')
        self.setFixedSize(250, 200)
        # Fields
        self.line_edit = QLineEdit()
        self.valid_text = QLabel()
        self.validator = QRegExpValidator()
        self.old_text = ''

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

        :param title: title of the QDialog
        :type title: str
        :param text: text to edit
        :type text: str
        :param regexp: regular expression to validate
        :type regexp: 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(regexp))

    def get_text_widget(self, regexp):
        """
        Return text QWidget with QTextEdit

        :return: text QWidget
        :rtype: QWidget
        """

        text_widget = QWidget()
        text_widget.setObjectName('dialog')
        text_layout = QVBoxLayout()
        text_widget.setLayout(text_layout)

        text_layout.addWidget(self.valid_text)

        qreg_exp = QRegExp(regexp)
        self.validator.setRegExp(qreg_exp)
        self.line_edit.setPlaceholderText(_('type your text...'))
        self.line_edit.setText(self.old_text)
        self.line_edit.setValidator(self.validator)
        self.line_edit.setFixedHeight(25)
        self.line_edit.textChanged.connect(self.check_text)
        text_layout.addWidget(self.line_edit)

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

        return text_widget

    def check_text(self):
        """
        Valid email with ``QRegExpValidator`` and inform user

        """

        state = self.validator.validate(self.line_edit.text(), 0)[0]
        if state == QRegExpValidator.Acceptable:
            text = 'Valid email'
            color = '#27ae60'  # green
        else:
            text = 'Invalid email !'
            color = '#e67e22'  # orange

        self.valid_text.setStyleSheet('QLabel { color: %s; }' % color)
        self.valid_text.setText(text)

    def accept_text(self):  # pragma: no cover
        """
        Set Edit QDialog to Rejected or Accepted (prevent to patch for nothing)

        """

        state = self.validator.validate(self.line_edit.text(), 0)[0]
        if self.old_text == self.line_edit.text():
            self.reject()
        elif not self.old_text or self.old_text.isspace():
            if not self.line_edit.text() or self.line_edit.text().isspace():
                self.reject()
            else:
                if state == QRegExpValidator.Acceptable:
                    self.accept()
                else:
                    self.reject()
        elif not self.line_edit.text() or self.line_edit.text().isspace():
            self.line_edit.setText('')
            self.accept()
        else:
            if state == QRegExpValidator.Acceptable:
                self.accept()
            else:
                self.reject()
class ValidatorQDialog(QDialog):
    """
        Class who create Validator QDialog to edit text in Alignak-app with regexp to validate
    """

    def __init__(self, parent=None):
        super(ValidatorQDialog, self).__init__(parent)
        self.setWindowTitle('Edit Dialog')
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setStyleSheet(settings.css_style)
        self.setWindowIcon(QIcon(settings.get_image('icon')))
        self.setObjectName('dialog')
        self.setFixedSize(250, 200)
        # Fields
        self.line_edit = QLineEdit()
        self.valid_text = QLabel()
        self.validator = QRegExpValidator()
        self.old_text = ''

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

        :param title: title of the QDialog
        :type title: str
        :param text: text to edit
        :type text: str
        :param regexp: regular expression to validate
        :type regexp: 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(regexp))

    def get_text_widget(self, regexp):
        """
        Return text QWidget with QTextEdit

        :return: text QWidget
        :rtype: QWidget
        """

        text_widget = QWidget()
        text_widget.setObjectName('dialog')
        text_layout = QVBoxLayout()
        text_widget.setLayout(text_layout)

        text_layout.addWidget(self.valid_text)

        qreg_exp = QRegExp(regexp)
        self.validator.setRegExp(qreg_exp)
        self.line_edit.setPlaceholderText(_('type your text...'))
        self.line_edit.setText(self.old_text)
        self.line_edit.setValidator(self.validator)
        self.line_edit.setFixedHeight(25)
        self.line_edit.textChanged.connect(self.check_text)
        text_layout.addWidget(self.line_edit)

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

        return text_widget

    def check_text(self):
        """
        Valid email with ``QRegExpValidator`` and inform user

        """

        state = self.validator.validate(self.line_edit.text(), 0)[0]
        if state == QRegExpValidator.Acceptable:
            text = 'Valid email'
            color = '#27ae60'  # green
        else:
            text = 'Invalid email !'
            color = '#e67e22'  # orange

        self.valid_text.setStyleSheet('QLabel { color: %s; }' % color)
        self.valid_text.setText(text)

    def accept_text(self):  # pragma: no cover
        """
        Set Edit QDialog to Rejected or Accepted (prevent to patch for nothing)

        """

        state = self.validator.validate(self.line_edit.text(), 0)[0]
        if self.old_text == self.line_edit.text():
            self.reject()
        elif not self.old_text or self.old_text.isspace():
            if not self.line_edit.text() or self.line_edit.text().isspace():
                self.reject()
            else:
                if state == QRegExpValidator.Acceptable:
                    self.accept()
                else:
                    self.reject()
        elif not self.line_edit.text() or self.line_edit.text().isspace():
            self.line_edit.setText('')
            self.accept()
        else:
            if state == QRegExpValidator.Acceptable:
                self.accept()
            else:
                self.reject()
class SynthesisQWidget(QWidget):
    """
        Class who manage Synthesis view with Host and Services QWidgets
    """
    def __init__(self, parent=None):
        super(SynthesisQWidget, self).__init__(parent)
        # Fields
        self.host_widget = HostQWidget()
        self.services_widget = ServicesQWidget()
        self.line_search = QLineEdit()
        self.completer = QCompleter()
        self.hint_widget = QWidget()

    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 get_search_widget(self):
        """
        Create and return the search QWidget

        :return: search QWidget
        :rtype: QWidget
        """

        widget = QWidget()
        layout = QHBoxLayout()
        layout.setSpacing(0)
        widget.setLayout(layout)

        # Search label
        search_lbl = QLabel(_('Search Host'))
        search_lbl.setObjectName('bordertitle')
        search_lbl.setFixedHeight(25)
        search_lbl.setToolTip(_('Search Host'))
        layout.addWidget(search_lbl)

        # QLineEdit
        self.line_search.setFixedHeight(search_lbl.height())
        layout.addWidget(self.line_search)
        self.create_line_search([])

        return widget

    def create_line_search(self, hostnames_list):
        """
        Add all hosts to QLineEdit and set QCompleter

        :param hostnames_list: list of host names
        :type hostnames_list: list
        """

        # Get QStringListModel
        model = self.completer.model()
        if not model:
            model = QStringListModel()

        model.setStringList(hostnames_list)

        # Configure QCompleter from model
        self.completer.setFilterMode(Qt.MatchContains)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setModel(model)
        self.completer.popup().setObjectName('popup')

        # Add completer to QLineEdit
        self.line_search.setCompleter(self.completer)
        self.line_search.setPlaceholderText(
            _('Type a host name to display its data'))
        self.line_search.setToolTip(_('Type a host name to display its data'))

    def update_synthesis(self, host, services, not_spied):
        """
        Update Synthesis QWidget with given host and services

        :param host: host item
        :type host: alignak_app.items.host.Host
        :param services: list of services attached to host
        :type services: list
        :param not_spied: define if host is spied or not
        :type not_spied: bool
        """

        self.host_widget.spy_btn.setEnabled(not_spied)

        if host:
            logger.info('Display %s in synthesis view', host.name)
            # Update Qwidgets
            self.host_widget.update_host(host)
            self.services_widget.update_widget(services)
            self.hint_widget.hide()
            self.host_widget.show()
            self.services_widget.show()

            # If the service element does not have the same ID as the host, reset to None
            if self.services_widget.service_data_widget.service_item:
                if self.services_widget.service_data_widget.service_item.data['host'] != \
                        self.host_widget.host_item.item_id:
                    self.services_widget.service_data_widget.service_item = None

        else:
            self.host_widget.hide()
            self.services_widget.hide()
            self.hint_widget.show()
class ProblemsQWidget(QWidget):
    """
        Class who create Problems QWidget
    """

    def __init__(self, parent=None):
        super(ProblemsQWidget, self).__init__(parent)
        self.setWindowIcon(QIcon(settings.get_image('icon')))
        # Fields
        self.line_search = QLineEdit()
        self.problems_table = ProblemsQTableView()
        self.problems_title = QLabel()
        self.actions_widget = ActionsQWidget()
        self.spy_widget = None
        self.filter_hosts_btn = ToggleQWidgetButton()
        self.filter_services_btn = ToggleQWidgetButton()
        self.spy_btn = QPushButton()
        self.host_btn = QPushButton()
        self.refresh_timer = QTimer()

    def initialize(self, spy_widget):
        """
        Initialize QWidget and set SpyQWidget

        :param spy_widget: instance of SpyQWidget to manage spy events
        :type spy_widget: alignak_app.qobjects.events.spy.SpyQWidget
        """

        problem_layout = QVBoxLayout()
        problem_layout.setContentsMargins(5, 20, 5, 5)
        self.setLayout(problem_layout)

        self.spy_widget = spy_widget

        self.problems_title.setObjectName('title')
        problem_layout.addWidget(self.problems_title)

        problem_layout.addWidget(self.get_search_widget())

        problem_layout.addWidget(self.get_btn_widget())

        problem_layout.addWidget(self.problems_table)

        self.update_problems_data()

        update_problems = int(settings.get_config('Alignak-app', 'update_problems')) * 1000
        self.refresh_timer.setInterval(update_problems)
        self.refresh_timer.start()
        self.refresh_timer.timeout.connect(self.update_problems_data)

    def get_current_user_role_item(self):
        """
        Return current selected item by ``Qt.UserRole``

        :return: current selected item or None
        :rtype: alignak_app.items.item.Item
        """

        item = self.problems_table.model().data(
            self.problems_table.selectionModel().currentIndex(),
            Qt.UserRole
        )

        return item

    def update_action_buttons(self):
        """
        Update status of action buttons and set current item for ActionsQWidget

        """

        # Get item by UserRole
        item = self.get_current_user_role_item()

        if item:
            # If the elements had been ack or downtimed, they would not be present
            self.actions_widget.acknowledge_btn.setEnabled(True)
            self.actions_widget.downtime_btn.setEnabled(True)
            self.actions_widget.item = item

            if 'service' in item.item_type:
                host_id = item.data['host']
            else:
                host_id = item.item_id
            self.spy_btn.setEnabled(
                bool(host_id not in self.spy_widget.spy_list_widget.spied_hosts)
            )
            self.host_btn.setEnabled(True)
        else:
            self.actions_widget.acknowledge_btn.setEnabled(False)
            self.actions_widget.downtime_btn.setEnabled(False)
            self.host_btn.setEnabled(False)
            self.spy_btn.setEnabled(False)

    def get_search_widget(self):
        """
        Create and return the search QWidget

        :return: search QWidget
        :rtype: QWidget
        """

        widget = QWidget()
        layout = QHBoxLayout()
        layout.setSpacing(0)
        layout.setContentsMargins(5, 20, 5, 10)
        widget.setLayout(layout)

        # Search label
        search_lbl = QLabel(_('Search Problems'))
        search_lbl.setObjectName('bordertitle')
        search_lbl.setFixedHeight(25)
        search_lbl.setToolTip(_('Search Problems'))
        layout.addWidget(search_lbl)

        # QLineEdit
        self.line_search.setFixedHeight(search_lbl.height())
        self.line_search.setPlaceholderText(_('Type text to filter problems...'))
        layout.addWidget(self.line_search)

        # Refresh button
        refresh_btn = QPushButton(_('Refresh'))
        refresh_btn.setObjectName('ok')
        refresh_btn.setFixedSize(120, search_lbl.height())
        refresh_btn.setToolTip(_('Refresh problems'))
        refresh_btn.clicked.connect(self.update_problems_data)
        layout.addWidget(refresh_btn)

        return widget

    def get_btn_widget(self):
        """
        Return QWidget with spy and host synthesis QPushButtons

        :return: widget with spy and host button
        :rtype: QWidget
        """

        widget_btn = QWidget()
        layout_btn = QHBoxLayout()
        layout_btn.setContentsMargins(0, 0, 0, 5)
        widget_btn.setLayout(layout_btn)

        host_filter = QLabel(_('Filter hosts'))
        host_filter.setObjectName('subtitle')
        layout_btn.addWidget(host_filter)
        self.filter_hosts_btn.initialize()
        self.filter_hosts_btn.update_btn_state(False)
        self.filter_hosts_btn.toggle_btn.clicked.connect(lambda: self.update_problems_data('host'))
        layout_btn.addWidget(self.filter_hosts_btn)

        service_filter = QLabel(_('Filter services'))
        service_filter.setObjectName('subtitle')
        layout_btn.addWidget(service_filter)
        self.filter_services_btn.initialize()
        self.filter_services_btn.update_btn_state(False)
        self.filter_services_btn.toggle_btn.clicked.connect(
            lambda: self.update_problems_data('service')
        )
        layout_btn.addWidget(self.filter_services_btn)

        layout_btn.addStretch()

        self.host_btn.setIcon(QIcon(settings.get_image('host')))
        self.host_btn.setFixedSize(80, 20)
        self.host_btn.setEnabled(False)
        self.host_btn.setToolTip(_('See current item in synthesis view'))
        layout_btn.addWidget(self.host_btn)

        self.spy_btn.setIcon(QIcon(settings.get_image('spy')))
        self.spy_btn.setFixedSize(80, 20)
        self.spy_btn.setEnabled(False)
        self.spy_btn.setToolTip(_('Spy current host'))
        self.spy_btn.clicked.connect(self.add_spied_host)
        layout_btn.addWidget(self.spy_btn)

        self.actions_widget.initialize(None)
        self.actions_widget.acknowledge_btn.setEnabled(False)
        self.actions_widget.downtime_btn.setEnabled(False)
        layout_btn.addWidget(self.actions_widget)

        layout_btn.setAlignment(Qt.AlignCenter)

        return widget_btn

    def add_spied_host(self):
        """
        Add a host to spied hosts

        """

        # Get item by UserRole
        item = self.get_current_user_role_item()

        if item:
            if 'service' in item.item_type:
                item_id = item.data['host']
            else:
                item_id = item.item_id

            app_backend.query_services(item_id)
            self.spy_widget.spy_list_widget.add_spy_host(item_id)
            self.spy_widget.update_parent_spytab()

        self.update_action_buttons()

    def update_problems_data(self, item_type=''):
        """
        Update data of Problems QTableWidget and problems title

        :param item_type: type of item to filter
        :type item_type: str
        """

        problems_data = data_manager.get_problems()
        old_research = self.line_search.text()

        if self.parent():
            self.parent().parent().setTabText(
                self.parent().parent().indexOf(self),
                _("Problems (%d)") % len(problems_data['problems'])
            )
            self.problems_title.setText(
                _('There are %d problems to manage (hosts: %d, services: %d)') % (
                    len(problems_data['problems']),
                    problems_data['hosts_nb'],
                    problems_data['services_nb']
                )
            )

        if self.filter_hosts_btn.is_checked() and not self.filter_services_btn.is_checked():
            item_type = 'host'
        if self.filter_services_btn.is_checked() and not self.filter_hosts_btn.is_checked():
            item_type = 'service'
        if not self.filter_services_btn.is_checked() and not self.filter_hosts_btn.is_checked():
            item_type = ''

        if isinstance(item_type, str):
            if 'host' in item_type and self.filter_hosts_btn.is_checked():
                if self.filter_services_btn.is_checked():
                    self.filter_services_btn.update_btn_state(False)
            if 'service' in item_type and self.filter_services_btn.is_checked():
                if self.filter_hosts_btn.is_checked():
                    self.filter_hosts_btn.update_btn_state(False)
            problems_data['problems'] = [
                item for item in problems_data['problems'] if item_type in item.item_type
            ]

        proxy_filter = self.problems_table.update_view(problems_data)
        if problems_data['problems']:
            self.line_search.textChanged.connect(proxy_filter.setFilterRegExp)
        else:
            self.problems_title.setText(_('If problems are found, they will be displayed here.'))

        self.problems_table.selectionModel().selectionChanged.connect(self.update_action_buttons)
        self.update_action_buttons()

        if old_research:
            self.line_search.setText(old_research)
            self.line_search.textChanged.emit(old_research)
示例#11
0
class PasswordQDialog(QDialog):
    """
        Class who create PasswordDialog QDialog
    """

    def __init__(self, parent=None):
        super(PasswordQDialog, self).__init__(parent)
        self.setWindowTitle('User Password')
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setStyleSheet(settings.css_style)
        self.setWindowIcon(QIcon(settings.get_image('icon')))
        self.setObjectName('dialog')
        self.setFixedSize(300, 300)
        # Fields
        self.pass_edit = QLineEdit()
        self.confirm_edit = QLineEdit()
        self.help_label = QLabel()

    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)

    def handle_confirm(self):
        """
        Handle accept_btn for password

        """

        if bool(self.pass_edit.text() == self.confirm_edit.text()) and \
                len(self.pass_edit.text()) > 4 and len(self.confirm_edit.text()) > 4:
            self.accept()
        else:
            if bool(self.pass_edit.text() != self.confirm_edit.text()):
                self.help_label.setText(_("Passwords do not match !"))
                self.help_label.setStyleSheet("color: red;")
            if len(self.pass_edit.text()) < 5 or len(self.confirm_edit.text()) < 5:
                self.help_label.setText(_("Your password must contain at least 5 characters."))
                self.help_label.setStyleSheet("color: orange;")
示例#12
0
class Synthesis(QWidget):
    """
        Class who create the Synthesis QWidget.
    """

    first_display = True

    def __init__(self, parent=None):
        super(Synthesis, self).__init__(parent)
        self.setStyleSheet(get_css())
        # Fields
        self.line_search = QLineEdit()
        self.app_backend = None
        self.action_manager = None
        self.host_synthesis = None
        self.app_widget = AppQWidget()
        self.old_checkbox_states = {}

    def initialize(self, app_backend):
        """
        Create the QWidget with its items and layout.

        :param app_backend: app_backend of alignak.
        :type app_backend: alignak_app.core.backend.AppBackend
        """

        logger.info('Create Synthesis View...')

        # App_backend
        self.app_backend = app_backend
        self.action_manager = ActionManager(app_backend)

        layout = QGridLayout()
        self.setLayout(layout)

        # button
        button = QPushButton('Search / Refresh Host', self)
        button.setObjectName('search')
        button.setFixedHeight(22)
        button.setToolTip('Search Host')
        button.clicked.connect(self.display_host_synthesis)
        layout.addWidget(button, 0, 4, 1, 1)
        layout.setAlignment(button, Qt.AlignTop)

        self.line_search.setFixedHeight(button.height())
        self.line_search.returnPressed.connect(button.click)
        self.line_search.cursorPositionChanged.connect(button.click)
        layout.addWidget(self.line_search, 0, 0, 1, 4)
        layout.setAlignment(self.line_search, Qt.AlignTop)

        self.app_widget.initialize('Host Synthesis View')
        self.app_widget.add_widget(self)
        self.app_widget.setMinimumSize(1300, 750)

        refresh_interval = int(get_app_config('Alignak-App', 'item_interval'))
        if bool(refresh_interval) and refresh_interval > 0:
            logger.debug('Hosts synthesis will be refresh in %ss',
                         str(refresh_interval))
            refresh_interval *= 1000
        else:
            logger.error(
                '"item_interval" option must be greater than 0. Replace by default: 30s'
            )
            refresh_interval = 30000

        refresh_timer = QTimer(self)
        refresh_timer.start(refresh_interval)
        refresh_timer.timeout.connect(self.display_host_synthesis)

    def create_line_search(self):
        """
        Add all hosts to QLineEdit and set QCompleter

        """

        # Create list for QStringModel
        hosts_list = []
        params = {'where': json.dumps({'_is_template': False})}

        all_hosts = self.app_backend.get('host', params, ['name'])

        if all_hosts:
            for host in all_hosts['_items']:
                hosts_list.append(host['name'])

        model = QStringListModel()
        model.setStringList(hosts_list)

        # Create completer from model
        completer = QCompleter()
        completer.setFilterMode(Qt.MatchContains)
        completer.setCaseSensitivity(Qt.CaseInsensitive)
        completer.setModel(model)

        # Add completer to "line edit"
        self.line_search.setCompleter(completer)
        self.line_search.setPlaceholderText(
            'Type a host name to display its data')
        self.line_search.setToolTip('Type a host name to display its data')

    def display_host_synthesis(self):
        """
        Display Synthesis QWidget. Remove and delete HostSynthesis if exists

        """

        if self.isVisible() or self.first_display:
            # If first display, create line search from hosts list
            if self.first_display:
                self.create_line_search()
                self.first_display = False

            host_name = str(self.line_search.text()).rstrip()
            backend_data = None
            old_row = -1

            if host_name:
                backend_data = self.app_backend.get_host_with_services(
                    host_name)

            # Store old data, remove and delete host_synthesis
            if self.host_synthesis:
                # Store old data
                if self.host_synthesis.services_list:
                    old_row = self.host_synthesis.services_list.currentRow()
                if self.host_synthesis.check_boxes:
                    for key in self.host_synthesis.check_boxes:
                        self.old_checkbox_states[key] = \
                            self.host_synthesis.check_boxes[key].isChecked()

                # Remove and delete QWidget
                self.layout().removeWidget(self.host_synthesis)
                self.host_synthesis.deleteLater()
                self.host_synthesis = None

            # Create the new host_synthesis
            self.host_synthesis = HostSynthesis(self.action_manager)
            self.host_synthesis.initialize(backend_data)

            # Restore old data
            if old_row >= 0 and self.host_synthesis.services_list:
                self.host_synthesis.services_list.setCurrentRow(old_row)
            if self.old_checkbox_states and self.host_synthesis.check_boxes:
                for key, checked in self.old_checkbox_states.items():
                    try:
                        self.host_synthesis.check_boxes[key].setChecked(
                            checked)
                    except KeyError as e:
                        logger.warning('Can\'t reapply filter [%s]: %s', e,
                                       checked)

            self.layout().addWidget(self.host_synthesis, 1, 0, 1, 5)