def test_add_spy_host(self):
        """Add Spy Host from Problems QWidget"""

        data_manager.update_database('host', [])
        data_manager.update_database('service', [])

        under_test = ProblemsQWidget()
        spy_widget_test = SpyQWidget()
        spy_widget_test.initialize()
        under_test.initialize(spy_widget_test)

        # Update view with problems
        under_test.problems_table.update_view({'problems': [self.host_list[8]]})

        # Make this QStandardItem as current index
        index_test = under_test.problems_table.model().index(0, 0)
        under_test.problems_table.selectionModel().setCurrentIndex(
            index_test,
            QItemSelectionModel.SelectCurrent
        )

        self.assertFalse(under_test.spy_widget.spy_list_widget.spied_hosts)

        under_test.add_spied_host()

        # Assert host has been spied
        self.assertTrue(under_test.spy_widget.spy_list_widget.spied_hosts)
        # "_id8" is inside "spied_hosts"
        self.assertTrue(
            self.host_list[8].item_id in under_test.spy_widget.spy_list_widget.spied_hosts
        )
    def test_filter_hosts(self):
        """Filter Hosts in Problems View"""

        under_test = ProblemsQWidget()
        spy_widget_test = SpyQWidget()
        spy_widget_test.initialize()
        under_test.initialize(spy_widget_test)

        # Add problems
        data_manager.database['problems'] = []
        for item in self.host_list:
            data_manager.database['problems'].append(item)
        for item in self.service_list:
            data_manager.database['problems'].append(item)

        # Update and filter Hosts
        under_test.filter_hosts_btn.update_btn_state(True)
        under_test.update_problems_data('host')

        # Assert service filter button is False
        self.assertFalse(under_test.filter_services_btn.is_checked())
        # Collect items
        items_test = [
            under_test.problems_table.model().data(
                under_test.problems_table.model().index(row, 0), Qt.UserRole
            )
            for row in range(under_test.problems_table.model().rowCount())
        ]

        self.assertEqual(10, len(items_test))
        for item in items_test:
            self.assertIsInstance(item, Host)
    def test_filter_hosts(self):
        """Filter Hosts in Problems View"""

        under_test = ProblemsQWidget()
        spy_widget_test = SpyQWidget()
        spy_widget_test.initialize()
        under_test.initialize(spy_widget_test)

        # Add problems
        data_manager.database['problems'] = []
        for item in self.host_list:
            data_manager.database['problems'].append(item)
        for item in self.service_list:
            data_manager.database['problems'].append(item)

        # Update and filter Hosts
        under_test.filter_hosts_btn.update_btn_state(True)
        under_test.update_problems_data('host')

        # Assert service filter button is False
        self.assertFalse(under_test.filter_services_btn.is_checked())
        # Collect items
        items_test = [
            under_test.problems_table.model().data(
                under_test.problems_table.model().index(row, 0), Qt.UserRole)
            for row in range(under_test.problems_table.model().rowCount())
        ]

        self.assertEqual(10, len(items_test))
        for item in items_test:
            self.assertIsInstance(item, Host)
    def test_add_spy_host(self):
        """Add Spy Host from Problems QWidget"""

        data_manager.update_database('host', [])
        data_manager.update_database('service', [])

        under_test = ProblemsQWidget()
        spy_widget_test = SpyQWidget()
        spy_widget_test.initialize()
        under_test.initialize(spy_widget_test)

        # Update view with problems
        under_test.problems_table.update_view(
            {'problems': [self.host_list[8]]})

        # Make this QStandardItem as current index
        index_test = under_test.problems_table.model().index(0, 0)
        under_test.problems_table.selectionModel().setCurrentIndex(
            index_test, QItemSelectionModel.SelectCurrent)

        self.assertFalse(under_test.spy_widget.spy_list_widget.spied_hosts)

        under_test.add_spied_host()

        # Assert host has been spied
        self.assertTrue(under_test.spy_widget.spy_list_widget.spied_hosts)
        # "_id8" is inside "spied_hosts"
        self.assertTrue(self.host_list[8].item_id in
                        under_test.spy_widget.spy_list_widget.spied_hosts)
    def test_filter_services(self):
        """Filter Services in Problems View"""

        under_test = ProblemsQWidget()
        spy_widget_test = SpyQWidget()
        spy_widget_test.initialize()
        under_test.initialize(spy_widget_test)

        # Update and filter Services
        under_test.filter_services_btn.update_btn_state(True)
        under_test.update_problems_data('service')

        # Assert host filter button is False
        self.assertFalse(under_test.filter_hosts_btn.is_checked())
        # Collect items
        items_test = [
            under_test.problems_table.model().data(
                under_test.problems_table.model().index(row, 0), Qt.UserRole
            )
            for row in range(under_test.problems_table.model().rowCount())
        ]

        self.assertEqual(10, len(items_test))
        for item in items_test:
            self.assertIsInstance(item, Service)
    def test_initialize(self):
        """Initialize SpyQWidget"""

        under_test = SpyQWidget()

        self.assertIsNotNone(under_test.spy_list_widget)
        self.assertIsInstance(under_test.spy_list_widget, SpyQListWidget)
        self.assertIsNone(under_test.spy_list_widget.item(0))

        under_test.initialize()

        self.assertIsNotNone(under_test.spy_list_widget)
        self.assertIsInstance(under_test.spy_list_widget, SpyQListWidget)
        self.assertIsNotNone(under_test.spy_list_widget.item(0))
    def test_update_problems_data_keep_linesearch_text(self):
        """Update Problems Data Keep LineSearch Text"""

        under_test = ProblemsQWidget()
        spy_widget_test = SpyQWidget()
        spy_widget_test.initialize()
        under_test.initialize(None)

        self.assertFalse(under_test.line_search.text())

        # Set text of QLineEdit
        under_test.line_search.setText('research')

        under_test.update_problems_data()

        # After update, text is keeped
        self.assertEqual('research', under_test.line_search.text())
    def test_update_problems_data_keep_linesearch_text(self):
        """Update Problems Data Keep LineSearch Text"""

        under_test = ProblemsQWidget()
        spy_widget_test = SpyQWidget()
        spy_widget_test.initialize()
        under_test.initialize(None)

        self.assertFalse(under_test.line_search.text())

        # Set text of QLineEdit
        under_test.line_search.setText('research')

        under_test.update_problems_data()

        # After update, text is keeped
        self.assertEqual('research', under_test.line_search.text())
    def test_remove_event(self):
        """Remove Spy Event Item"""

        under_test = SpyQWidget()
        under_test.initialize()

        spy_item_test = EventItem()
        spy_item_test.initialize('OK', 'Message', host='_id_1')

        # Fill database
        host_test = Host()
        host_test.create(
            '_id_1', {
                '_id': '_id_1',
                'ls_downtimed': False,
                'ls_acknowledged': False,
                'active_checks_enabled': True,
                'passive_checks_enabled': True,
                '_overall_state_id': 4,
                'ls_state': 'DOWN'
            }, 'hostname')
        data_manager.update_database('host', [host_test])

        # No item spy, so item is None
        self.assertIsNone(under_test.spy_list_widget.item(1))
        self.assertFalse(under_test.spy_list_widget.spied_hosts)

        # Spy host
        under_test.spy_list_widget.add_spy_host(host_test.item_id)

        # Assert EventItem have same host "_id" that the one added
        self.assertEqual(spy_item_test.host,
                         under_test.spy_list_widget.item(0).host)
        self.assertEqual(['_id_1'], under_test.spy_list_widget.spied_hosts)

        # Set this item to current one and add it to spy list
        under_test.spy_list_widget.setCurrentRow(0)
        under_test.spy_list_widget.setCurrentItem(
            under_test.spy_list_widget.item(0))

        under_test.remove_event()

        # Event is no more here
        self.assertNotEqual(spy_item_test.host,
                            under_test.spy_list_widget.item(0).host)
        self.assertFalse(under_test.spy_list_widget.spied_hosts)
    def test_send_spy_events(self):
        """Send Spy Events"""

        init_event_widget()
        under_test = SpyQWidget()
        under_test.initialize()

        # Hint item is here
        self.assertEqual(1, under_test.spy_list_widget.count())

        # Filling database
        host_test = Host()
        host_test.create(
            'spy1', {
                '_id': 'spy1',
                'ls_downtimed': False,
                'ls_acknowledged': False,
                'active_checks_enabled': True,
                'passive_checks_enabled': True,
                '_overall_state_id': 4,
                'ls_state': 'DOWN'
            }, 'hostname')
        host_test_2 = Host()
        host_test_2.create(
            'spy2', {
                '_id': 'spy2',
                'ls_downtimed': False,
                'ls_acknowledged': False,
                'active_checks_enabled': True,
                'passive_checks_enabled': True,
                '_overall_state_id': 4,
                'ls_state': 'DOWN'
            }, 'hostname')
        data_manager.update_database('host', [host_test, host_test_2])

        under_test.spy_list_widget.add_spy_host('spy1')
        under_test.spy_list_widget.add_spy_host('spy2')

        # Item hint have been removed, host spied added
        self.assertEqual(2, under_test.spy_list_widget.count())

        under_test.send_spy_events()

        # Sending events does not modify spy list widget count
        self.assertEqual(2, under_test.spy_list_widget.count())
    def test_update_problems_data(self):
        """Update Problems Data"""

        # Reset Problems
        data_manager.database['problems'] = []

        # Initialize QWidget
        under_test = ProblemsQWidget()
        spy_widget_test = SpyQWidget()
        spy_widget_test.initialize()
        under_test.initialize(spy_widget_test)

        model_test = under_test.problems_table.model()
        select_model_test = under_test.problems_table.selectionModel()

        under_test.update_problems_data()

        # Assert Table models have changed
        self.assertNotEqual(model_test, under_test.problems_table.model())
        self.assertNotEqual(select_model_test,
                            under_test.problems_table.selectionModel())

        # Add problems
        for item in self.host_list:
            data_manager.database['problems'].append(item)
        for item in self.service_list:
            data_manager.database['problems'].append(item)

        # Assert filter buttons are False
        self.assertFalse(under_test.filter_hosts_btn.is_checked())
        self.assertFalse(under_test.filter_services_btn.is_checked())

        # Even if a filter is given,
        # the view does not filter by item type if filter buttons are False
        under_test.update_problems_data('service')

        # Collect items
        items_test = [
            under_test.problems_table.model().data(
                under_test.problems_table.model().index(row, 0), Qt.UserRole)
            for row in range(under_test.problems_table.model().rowCount())
        ]

        self.assertEqual(20, len(items_test))
    def test_update_problems_data(self):
        """Update Problems Data"""

        # Reset Problems
        data_manager.database['problems'] = []

        # Initialize QWidget
        under_test = ProblemsQWidget()
        spy_widget_test = SpyQWidget()
        spy_widget_test.initialize()
        under_test.initialize(spy_widget_test)

        model_test = under_test.problems_table.model()
        select_model_test = under_test.problems_table.selectionModel()

        under_test.update_problems_data()

        # Assert Table models have changed
        self.assertNotEqual(model_test, under_test.problems_table.model())
        self.assertNotEqual(select_model_test, under_test.problems_table.selectionModel())

        # Add problems
        for item in self.host_list:
            data_manager.database['problems'].append(item)
        for item in self.service_list:
            data_manager.database['problems'].append(item)

        # Assert filter buttons are False
        self.assertFalse(under_test.filter_hosts_btn.is_checked())
        self.assertFalse(under_test.filter_services_btn.is_checked())

        # Even if a filter is given,
        # the view does not filter by item type if filter buttons are False
        under_test.update_problems_data('service')

        # Collect items
        items_test = [
            under_test.problems_table.model().data(
                under_test.problems_table.model().index(row, 0), Qt.UserRole
            )
            for row in range(under_test.problems_table.model().rowCount())
        ]

        self.assertEqual(20, len(items_test))
    def test_manage_host_events_with_wrong_row(self):
        """Manage Host Events With Wrong Row"""

        under_test = SpyQWidget()
        under_test.initialize()

        # Hint item in spy list widget, 0 item in host list widget
        self.assertEqual(1, under_test.spy_list_widget.count())
        self.assertEqual(0, under_test.host_list_widget.count())

        # Filling database
        host_test = Host()
        host_test.create(
            'spy1', {
                '_id': 'spy1',
                'ls_downtimed': False,
                'ls_acknowledged': False,
                'active_checks_enabled': True,
                'passive_checks_enabled': True,
                '_overall_state_id': 4,
                'ls_state': 'DOWN'
            }, 'hostname')
        data_manager.update_database('host', [host_test])

        # Spy this host
        under_test.spy_list_widget.add_spy_host(host_test.item_id)

        # Host have been added in list widget, 0 item in host list widget
        self.assertEqual(1, under_test.spy_list_widget.count())
        self.assertEqual(host_test.item_id,
                         under_test.spy_list_widget.item(0).host)
        self.assertEqual(0, under_test.host_list_widget.count())

        # Manage problems
        under_test.manage_host_events(-1)

        # Host list equal to 0 with row equal to -1
        self.assertEqual(0, under_test.host_list_widget.count())
    def test_filter_services(self):
        """Filter Services in Problems View"""

        under_test = ProblemsQWidget()
        spy_widget_test = SpyQWidget()
        spy_widget_test.initialize()
        under_test.initialize(spy_widget_test)

        # Update and filter Services
        under_test.filter_services_btn.update_btn_state(True)
        under_test.update_problems_data('service')

        # Assert host filter button is False
        self.assertFalse(under_test.filter_hosts_btn.is_checked())
        # Collect items
        items_test = [
            under_test.problems_table.model().data(
                under_test.problems_table.model().index(row, 0), Qt.UserRole)
            for row in range(under_test.problems_table.model().rowCount())
        ]

        self.assertEqual(10, len(items_test))
        for item in items_test:
            self.assertIsInstance(item, Service)
class PanelQWidget(QWidget):
    """
        Class who manage Panel with Host and Services QWidgets
    """

    def __init__(self, parent=None):
        super(PanelQWidget, self).__init__(parent)
        self.setAcceptDrops(True)
        # Fields
        self.tab_widget = QTabWidget()
        self.layout = QVBoxLayout()
        self.dashboard_widget = DashboardQWidget()
        self.synthesis_widget = SynthesisQWidget()
        self.problems_widget = ProblemsQWidget()
        self.spy_widget = SpyQWidget()
        self.hostnames_list = []

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

        """

        logger.info('Create Panel View...')
        self.setLayout(self.layout)

        # Dashboard widget
        self.dashboard_widget.initialize()
        self.layout.addWidget(self.dashboard_widget)

        self.tab_widget.setMovable(True)
        self.layout.addWidget(self.tab_widget)
        tab_order = self.get_tab_order()

        # Set hostnames
        self.hostnames_list = data_manager.get_all_hostnames()

        # Synthesis
        self.synthesis_widget.initialize_synthesis()
        self.synthesis_widget.host_widget.spy_btn.clicked.connect(self.spy_host)
        self.synthesis_widget.line_search.returnPressed.connect(self.display_host)
        self.synthesis_widget.line_search.cursorPositionChanged.connect(self.display_host)
        self.synthesis_widget.create_line_search(self.hostnames_list)
        self.tab_widget.insertTab(tab_order.index('h'), self.synthesis_widget, _('Host Synthesis'))
        self.tab_widget.setTabToolTip(
            self.tab_widget.indexOf(self.synthesis_widget), _('See a synthesis view of a host')
        )

        # Problems
        self.problems_widget.initialize(self.spy_widget)
        self.problems_widget.host_btn.clicked.connect(self.display_host)
        self.problems_widget.problems_table.doubleClicked.connect(self.set_host_from_problems)
        self.tab_widget.insertTab(
            tab_order.index('p'),
            self.problems_widget,
            _('Problems (%d)') % len(data_manager.get_problems()['problems'])
        )
        self.tab_widget.setTabToolTip(
            self.tab_widget.indexOf(self.problems_widget), _('See the problems found in backend')
        )

        # Spied hosts
        self.spy_widget.initialize()
        self.tab_widget.insertTab(tab_order.index('s'), self.spy_widget, _('Spy Hosts'))
        self.tab_widget.setTabToolTip(
            self.tab_widget.indexOf(self.spy_widget), _('See spy hosts by Alignak-app')
        )

        # Hide widget for first display
        self.dashboard_widget.show()
        self.synthesis_widget.host_widget.hide()
        self.synthesis_widget.services_widget.hide()

    @staticmethod
    def get_tab_order():
        """
        Return tab order defined by user, else default order

        :return: tab order of App
        :rtype: list
        """

        default_order = ['p', 'h', 's']
        tab_order = settings.get_config('Alignak-app', 'tab_order').split(',')

        try:
            assert len(tab_order) == len(default_order)
            for nb in default_order:
                assert nb in tab_order
        except AssertionError:
            logger.error('Wrong "tab_order" value in config file %s', tab_order)
            tab_order = default_order

        return tab_order

    def spy_host(self):
        """
        Spy host who is available in line_search QLineEdit

        """

        if self.synthesis_widget.line_search.text() in self.hostnames_list:
            # Spy host
            self.spy_widget.spy_list_widget.add_spy_host(
                self.synthesis_widget.host_widget.host_item.item_id
            )

            # Update QWidgets
            self.synthesis_widget.host_widget.spy_btn.setEnabled(False)
            self.tab_widget.setTabText(
                self.tab_widget.indexOf(self.spy_widget),
                _("Spied Hosts (%d)") % self.spy_widget.spy_list_widget.count()
            )

    def display_host(self):
        """
        Display and update HostQWidget

        """

        # Update and set "line_search" in case hosts have been added or deleted
        hostnames_list = data_manager.get_all_hostnames()
        if hostnames_list != self.hostnames_list:
            self.synthesis_widget.create_line_search(hostnames_list)

        # If sender is QPushButton from problems, set "line_search" text
        if isinstance(self.sender(), QPushButton):
            self.set_host_from_problems()

        # Display host if exists
        if self.synthesis_widget.line_search.text().rstrip() in self.hostnames_list:
            # Get Host Item and its services
            host = self.get_current_host()
            services = data_manager.get_host_services(host.item_id)

            if not services:
                app_backend.query_services(host.item_id)
                services = data_manager.get_host_services(host.item_id)

            # Update QWidgets
            self.tab_widget.setTabText(
                self.tab_widget.indexOf(self.synthesis_widget),
                _('Host "%s"') % host.get_display_name()
            )
            not_spied = bool(
                host.item_id not in self.spy_widget.spy_list_widget.spied_hosts
            )
            self.synthesis_widget.update_synthesis(host, services, not_spied)
            self.dashboard_widget.update_dashboard()
        else:
            self.synthesis_widget.update_synthesis(None, None, True)
            self.tab_widget.setTabText(
                self.tab_widget.indexOf(self.synthesis_widget),
                _('Host Synthesis')
            )

    def set_host_from_problems(self):
        """
        Set line search if ``sender()`` is instance of QPushButton from
        :class:`Problems <alignak_app.qobjects.alignak.problems.ProblemsQWidget>` QWidget

        """

        item = self.problems_widget.get_current_user_role_item()
        if item:
            if 'service' in item.item_type:
                hostname = data_manager.get_item('host', item.data['host']).name
            else:
                hostname = item.name

            if hostname in self.hostnames_list:
                self.synthesis_widget.line_search.setText(hostname)
                self.tab_widget.setCurrentIndex(self.tab_widget.indexOf(self.synthesis_widget))

    def get_current_host(self):
        """
        Return current Host item with name in QLineEdit

        :return: current host
        :rtype: alignak_app.items.host.Host
        """

        current_host = data_manager.get_item(
            'host',
            self.synthesis_widget.line_search.text().rstrip()
        )

        return current_host

    def dragMoveEvent(self, event):  # pragma: no cover
        """
        Override dragMoveEvent.
         Only accept EventItem() objects who have ``Qt.UserRole``

        :param event: event triggered when something move
        """

        if event.source().currentItem().data(Qt.UserRole):
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):  # pragma: no cover
        """
        Override dropEvent.
         Get dropped item data, create a new one, and delete the one who is in EventsQWidget

        :param event: event triggered when something is dropped
        """

        host = data_manager.get_item('host', '_id', event.source().currentItem().data(Qt.UserRole))

        logger.debug('Drag and drop host in Panel: %s', host.name)
        logger.debug('... with current item: %s', event.source().currentItem())

        self.synthesis_widget.line_search.setText(host.name)
        self.tab_widget.setCurrentIndex(self.tab_widget.indexOf(self.synthesis_widget))
        self.display_host()

    def dragEnterEvent(self, event):
        """
        Override dragEnterEvent.

        :param event: event triggered when something enter
        """

        event.accept()
        event.acceptProposedAction()
    def test_manage_host_events_with_valid_rows(self):
        """Manage Host Events With Valid Rows"""

        under_test = SpyQWidget()
        under_test.initialize()

        # Filling "host" database
        host_test = Host()
        host_test.create(
            'spy1', {
                '_id': 'spy1',
                'ls_downtimed': False,
                'ls_acknowledged': False,
                'active_checks_enabled': True,
                'passive_checks_enabled': True,
                '_overall_state_id': 4,
                'ls_state': 'DOWN'
            }, 'hostname')
        data_manager.update_database('host', [host_test])

        # Spy this host and set current row
        under_test.spy_list_widget.add_spy_host(host_test.item_id)
        under_test.spy_list_widget.setCurrentRow(0)

        # "(new !)" is added to new spy host
        self.assertEqual(
            'Host Hostname, current state: DOWN (new !)',
            under_test.spy_list_widget.item(0).data(Qt.DisplayRole))

        # Manage problems with a valid row
        under_test.manage_host_events(under_test.spy_list_widget.currentRow())

        # Host list equal to 1, No services are attached to host
        self.assertEqual(1, under_test.host_list_widget.count())
        self.assertEqual(
            'Hostname is DOWN. No services.',
            under_test.host_list_widget.item(0).data(Qt.DisplayRole))
        # "(new !)" is removed
        self.assertEqual(
            'Host Hostname, current state: DOWN ',
            under_test.spy_list_widget.item(0).data(Qt.DisplayRole))

        # Fill "services" database attached to host
        service = Service()
        service.create(
            '_id1', {
                'host': 'spy1',
                'ls_state': 'CRITICAL',
                'ls_acknowledged': False,
                'ls_downtimed': False,
                'ls_output': 'Output of service 1',
                'ls_last_check': 1234567890,
                'passive_checks_enabled': True,
                'active_checks_enabled': False
            }, 'service_name')
        service_2 = Service()
        service_2.create(
            '_id2', {
                'host': 'spy1',
                'ls_state': 'OK',
                'ls_acknowledged': False,
                'ls_downtimed': False,
                'ls_output': 'Output of service 2',
                'ls_last_check': 1234567890,
                'passive_checks_enabled': True,
                'active_checks_enabled': False
            }, 'service2_name')
        data_manager.update_database('service', [service, service_2])

        # Manage problems again
        under_test.manage_host_events(under_test.spy_list_widget.currentRow())

        # Host list equal to 1, cause one service is CRITICAL
        self.assertEqual(1, under_test.host_list_widget.count())
        self.assertEqual(
            'Service Service_Name is CRITICAL',
            under_test.host_list_widget.item(0).data(Qt.DisplayRole))

        # If CRITICAL service is removed, text change
        data_manager.remove_item('service', '_id1')

        # Manage problems again
        under_test.manage_host_events(under_test.spy_list_widget.currentRow())

        # Host list equal to 1, cause one service is CRITICAL
        self.assertEqual(1, under_test.host_list_widget.count())
        self.assertEqual(
            'Hostname is DOWN. Services of host seems managed.',
            under_test.host_list_widget.item(0).data(Qt.DisplayRole))
class PanelQWidget(QWidget):
    """
        Class who manage Panel with Host and Services QWidgets
    """
    def __init__(self, parent=None):
        super(PanelQWidget, self).__init__(parent)
        self.setAcceptDrops(True)
        # Fields
        self.tab_widget = QTabWidget()
        self.layout = QVBoxLayout()
        self.dashboard_widget = DashboardQWidget()
        self.synthesis_widget = SynthesisQWidget()
        self.problems_widget = ProblemsQWidget()
        self.spy_widget = SpyQWidget()
        self.hostnames_list = []

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

        """

        logger.info('Create Panel View...')
        self.setLayout(self.layout)

        # Dashboard widget
        self.dashboard_widget.initialize()
        self.layout.addWidget(self.dashboard_widget)

        self.tab_widget.setMovable(True)
        self.layout.addWidget(self.tab_widget)
        tab_order = self.get_tab_order()

        # Set hostnames
        self.hostnames_list = data_manager.get_all_hostnames()

        # Synthesis
        self.synthesis_widget.initialize_synthesis()
        self.synthesis_widget.host_widget.spy_btn.clicked.connect(
            self.spy_host)
        self.synthesis_widget.line_search.returnPressed.connect(
            self.display_host)
        self.synthesis_widget.line_search.cursorPositionChanged.connect(
            self.display_host)
        self.synthesis_widget.create_line_search(self.hostnames_list)
        self.tab_widget.insertTab(tab_order.index('h'), self.synthesis_widget,
                                  _('Host Synthesis'))
        self.tab_widget.setTabToolTip(
            self.tab_widget.indexOf(self.synthesis_widget),
            _('See a synthesis view of a host'))

        # Problems
        self.problems_widget.initialize(self.spy_widget)
        self.problems_widget.host_btn.clicked.connect(self.display_host)
        self.problems_widget.problems_table.doubleClicked.connect(
            self.set_host_from_problems)
        self.tab_widget.insertTab(
            tab_order.index('p'), self.problems_widget,
            _('Problems (%d)') % len(data_manager.get_problems()['problems']))
        self.tab_widget.setTabToolTip(
            self.tab_widget.indexOf(self.problems_widget),
            _('See the problems found in backend'))

        # Spied hosts
        self.spy_widget.initialize()
        self.tab_widget.insertTab(tab_order.index('s'), self.spy_widget,
                                  _('Spy Hosts'))
        self.tab_widget.setTabToolTip(self.tab_widget.indexOf(self.spy_widget),
                                      _('See spy hosts by Alignak-app'))

        # Hide widget for first display
        self.dashboard_widget.show()
        self.synthesis_widget.host_widget.hide()
        self.synthesis_widget.services_widget.hide()

    @staticmethod
    def get_tab_order():
        """
        Return tab order defined by user, else default order

        :return: tab order of App
        :rtype: list
        """

        default_order = ['p', 'h', 's']
        tab_order = settings.get_config('Alignak-app', 'tab_order').split(',')

        try:
            assert len(tab_order) == len(default_order)
            for nb in default_order:
                assert nb in tab_order
        except AssertionError:
            logger.error('Wrong "tab_order" value in config file %s',
                         tab_order)
            tab_order = default_order

        return tab_order

    def spy_host(self):
        """
        Spy host who is available in line_search QLineEdit

        """

        if self.synthesis_widget.line_search.text() in self.hostnames_list:
            # Spy host
            self.spy_widget.spy_list_widget.add_spy_host(
                self.synthesis_widget.host_widget.host_item.item_id)

            # Update QWidgets
            self.synthesis_widget.host_widget.spy_btn.setEnabled(False)
            self.tab_widget.setTabText(
                self.tab_widget.indexOf(self.spy_widget),
                _("Spied Hosts (%d)") %
                self.spy_widget.spy_list_widget.count())

    def display_host(self):
        """
        Display and update HostQWidget

        """

        # Update and set "line_search" in case hosts have been added or deleted
        hostnames_list = data_manager.get_all_hostnames()
        if hostnames_list != self.hostnames_list:
            self.synthesis_widget.create_line_search(hostnames_list)

        # If sender is QPushButton from problems, set "line_search" text
        if isinstance(self.sender(), QPushButton):
            self.set_host_from_problems()

        # Display host if exists
        if self.synthesis_widget.line_search.text().rstrip(
        ) in self.hostnames_list:
            # Get Host Item and its services
            host = self.get_current_host()
            services = data_manager.get_host_services(host.item_id)

            if not services:
                app_backend.query_services(host.item_id)
                services = data_manager.get_host_services(host.item_id)

            # Update QWidgets
            self.tab_widget.setTabText(
                self.tab_widget.indexOf(self.synthesis_widget),
                _('Host "%s"') % host.get_display_name())
            not_spied = bool(host.item_id not in
                             self.spy_widget.spy_list_widget.spied_hosts)
            self.synthesis_widget.update_synthesis(host, services, not_spied)
            self.dashboard_widget.update_dashboard()
        else:
            self.synthesis_widget.update_synthesis(None, None, True)
            self.tab_widget.setTabText(
                self.tab_widget.indexOf(self.synthesis_widget),
                _('Host Synthesis'))

    def set_host_from_problems(self):
        """
        Set line search if ``sender()`` is instance of QPushButton from
        :class:`Problems <alignak_app.qobjects.alignak.problems.ProblemsQWidget>` QWidget

        """

        item = self.problems_widget.get_current_user_role_item()
        if item:
            if 'service' in item.item_type:
                hostname = data_manager.get_item('host',
                                                 item.data['host']).name
            else:
                hostname = item.name

            if hostname in self.hostnames_list:
                self.synthesis_widget.line_search.setText(hostname)
                self.tab_widget.setCurrentIndex(
                    self.tab_widget.indexOf(self.synthesis_widget))

    def get_current_host(self):
        """
        Return current Host item with name in QLineEdit

        :return: current host
        :rtype: alignak_app.items.host.Host
        """

        current_host = data_manager.get_item(
            'host',
            self.synthesis_widget.line_search.text().rstrip())

        return current_host

    def dragMoveEvent(self, event):  # pragma: no cover
        """
        Override dragMoveEvent.
         Only accept EventItem() objects who have ``Qt.UserRole``

        :param event: event triggered when something move
        """

        if event.source().currentItem().data(Qt.UserRole):
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):  # pragma: no cover
        """
        Override dropEvent.
         Get dropped item data, create a new one, and delete the one who is in EventsQWidget

        :param event: event triggered when something is dropped
        """

        host = data_manager.get_item(
            'host', '_id',
            event.source().currentItem().data(Qt.UserRole))

        logger.debug('Drag and drop host in Panel: %s', host.name)
        logger.debug('... with current item: %s', event.source().currentItem())

        self.synthesis_widget.line_search.setText(host.name)
        self.tab_widget.setCurrentIndex(
            self.tab_widget.indexOf(self.synthesis_widget))
        self.display_host()

    def dragEnterEvent(self, event):
        """
        Override dragEnterEvent.

        :param event: event triggered when something enter
        """

        event.accept()
        event.acceptProposedAction()