Exemplo n.º 1
0
class DeltaGenMenu(QMenu):
    def __init__(self, ui, menu_name: str = _('DeltaGen')):
        """ Setup the DeltaGen MainMenu setting KnechtSettings for DeltaGen communication

        :param modules.gui.main_ui.KnechtWindow ui:
        :param menu_name: name of the menu that will be displayed
        """
        super(DeltaGenMenu, self).__init__(menu_name, ui)
        self.ui = ui

        self.reset, self.freeze, self.check = None, None, None

        self.hidden_actions = QActionGroup(self)
        self.hidden_actions.setVisible(False)

        self.send_camera, self.display, self.display_overlay = None, None, None
        self.enable_material_dummy, self.validate_plmxml, self.change_port = None, None, None
        self.as_scene_menu = QMenu()

        self.setup_deltagen_menu()

        # Apply settings before showing
        self.aboutToShow.connect(self._menu_about_to_show)

    def setup_deltagen_menu(self):
        # ---- Reset On/Off ----
        self.reset = self._setup_checkable_action(_('Reset senden'), True,
                                                  self.toggle_reset)

        # ---- Freeze Viewer On/Off ----
        self.freeze = self._setup_checkable_action(_('Freeze Viewer'), True,
                                                   self.toggle_freeze_viewer)

        # ---- Variants State Check On/Off ----
        self.check = self._setup_checkable_action(
            _('Varianten State Check'), True, self.toggle_variants_state_check)

        # ---- Send Camera Data On/Off ----
        self.send_camera = self._setup_checkable_action(
            _('Kamera Daten übertragen'), True, self.toggle_camera_send)

        # ---- Display State Check On/Off ----
        self.display = self._setup_checkable_action(
            _('State Check im Baum anzeigen'), False,
            self.toggle_state_check_display)

        # ---- Display Overlay after Preset Send operation finished ----
        self.display_overlay = self._setup_checkable_action(
            _('Zuletzt gesendetes Preset als Overlay anzeigen'), False,
            self.toggle_display_finished_overlay)

        # ---- Assign Dummy Material before applying PlmXml Materials
        self.enable_material_dummy = self._setup_checkable_action(
            _('Dummy Material auf PlmXml Konfiguration anwenden'), False,
            self.toggle_plmxml_material_dummy)

        # ---- Validate DeltaGen Scene vs PlmXml before switching configurations
        self.validate_plmxml = self._setup_checkable_action(
            _('DeltaGen Szene vor dem konfigurieren mit PlmXml abgleichen.'),
            True, self.toggle_validate_plmxml, self.hidden_actions)

        # --- As Connector choose active scene menu ---
        self.as_scene_menu.deleteLater()
        self.as_scene_menu = AsSceneMenu(self.ui,
                                         _('AsConnector aktive Szene:'))
        self.addMenu(self.as_scene_menu)

        # --- Change DeltaGen Command Port
        self.change_port = QAction(IconRsc.get_icon('paperplane'),
                                   _('DeltaGen Port ändern'), self)
        self.change_port.triggered.connect(self.change_deltagen_port)
        self.addAction(self.change_port)

        self._apply_settings()

    def _setup_checkable_action(self,
                                name: str,
                                checked: bool,
                                target: object,
                                action_grp: QActionGroup = None):
        check_icon = IconRsc.get_icon('check_box_empty')
        check_icon.addPixmap(IconRsc.get_pixmap('check_box'), QIcon.Normal,
                             QIcon.On)

        if action_grp:
            action = QAction(check_icon, name, action_grp)
        else:
            action = QAction(check_icon, name, self)
        action.setCheckable(True)
        action.setChecked(checked)
        action.triggered.connect(target)
        self.addAction(action)

        return action

    def _menu_about_to_show(self):
        """ Setup method before menu is visible """
        # Hide hidden actions
        self.hidden_actions.setVisible(False)

        # Show hidden actions with Ctrl Key
        if QApplication.keyboardModifiers() & QtCore.Qt.ControlModifier:
            self.hidden_actions.setVisible(True)

        self._apply_settings()

    def _apply_settings(self):
        """ Apply saved settings """
        self.reset.setChecked(KnechtSettings.dg.get('reset'))
        self.freeze.setChecked(KnechtSettings.dg.get('freeze_viewer'))
        self.check.setChecked(KnechtSettings.dg.get('check_variants'))
        self.send_camera.setChecked(KnechtSettings.dg.get('send_camera_data'))
        self.display.setChecked(KnechtSettings.dg.get('display_variant_check'))
        self.display_overlay.setChecked(
            KnechtSettings.dg.get('display_send_finished_overlay'))
        self.enable_material_dummy.setChecked(
            KnechtSettings.dg.get('use_material_dummy'))
        self.validate_plmxml.setChecked(
            KnechtSettings.dg.get('validate_plmxml_scene'))

    @Slot(bool)
    def toggle_reset(self, checked: bool):
        LOGGER.debug('Received from: %s', self.sender().text())
        KnechtSettings.dg['reset'] = checked

    @Slot(bool)
    def toggle_freeze_viewer(self, checked: bool):
        KnechtSettings.dg['freeze_viewer'] = checked

    @Slot(bool)
    def toggle_variants_state_check(self, checked: bool):
        KnechtSettings.dg['check_variants'] = checked

    @Slot(bool)
    def toggle_state_check_display(self, checked: bool):
        KnechtSettings.dg['display_variant_check'] = checked

    @Slot(bool)
    def toggle_display_finished_overlay(self, checked: bool):
        KnechtSettings.dg['display_send_finished_overlay'] = checked

    @Slot(bool)
    def toggle_plmxml_material_dummy(self, checked: bool):
        KnechtSettings.dg['use_material_dummy'] = checked

    @Slot(bool)
    def toggle_validate_plmxml(self, checked: bool):
        KnechtSettings.dg['validate_plmxml_scene'] = checked

    @Slot(bool)
    def toggle_camera_send(self, checked: bool):
        KnechtSettings.dg['send_camera_data'] = checked

    def change_deltagen_port(self):
        box = QMessageBox(self)
        box.setText(
            _('Port zwischen 3000-3999 angeben. '
              'Muss mit DeltaGen>Preferences>Tools>External Commands übereinstimmen.'
              ))
        box.setWindowTitle(_('DeltaGen Kommando Port'))

        port = QSpinBox(box)
        port.setMinimum(3000)
        port.setMaximum(3999)
        port.setValue(KnechtSettings.dg.get('port', DG_TCP_PORT))
        box.layout().addWidget(port,
                               box.layout().rowCount() - 1, 0, 1,
                               box.layout().columnCount())
        box.layout().addWidget(
            box.layout().takeAt(box.layout().rowCount() - 1).widget(),
            box.layout().rowCount(), 0, 1,
            box.layout().columnCount())
        box.exec_()

        if 3000 <= port.value() <= 3999:
            KnechtSettings.dg['port'] = port.value()
            box = QMessageBox(self)
            box.setText(
                _('Anwendung neu starten um geänderten Port zu übernehmen.'))
            box.setWindowTitle(_('Neustart erforderlich'))
            box.exec_()

    def enable_menus(self, enabled: bool = True):
        for a in self.menu.actions():
            a.setEnabled(enabled)
Exemplo n.º 2
0
class TreeContextMenu(QMenu):
    def __init__(self, view, ui, menu_name: str = _('Baum Kontextmenü')):
        """ Context menu of tree views

        :param modules.itemview.tree_view.KnechtTreeView view: tree view
        :param KnechtWindow ui: main window ui class
        :param str menu_name: name of the menu
        """
        super(TreeContextMenu, self).__init__(menu_name, view)
        self.view, self.ui, self.status_bar = view, ui, ui.statusBar()

        self.edit_menu = self.ui.main_menu.edit_menu
        self.create_menu = CreateMenu(self)
        self.tree_menu = TreeMenu(self, ui)

        self.send_dg_action = QAction(IconRsc.get_icon('paperplane'),
                                      _('Senden an DeltaGen'), self)
        dg_tip_1 = _(
            'Selektierte Bauminhalte als Variantenschaltung mit vorherigem Reset an DeltaGen senden.'
        )
        self.send_dg_action.setToolTip(dg_tip_1)
        self.send_dg_action.setStatusTip(dg_tip_1)
        self.send_dg_action.triggered.connect(self.send_to_deltagen)
        self.addAction(self.send_dg_action)
        self.addSeparator()

        self.send_ave_action = QAction(IconRsc.get_icon('paperplane'),
                                       _('Senden an AVE'), self)
        dg_tip_1 = _(
            'Selektierte Bauminhalte als Konfiguration an laufende AVE Instanz senden.'
        )
        self.send_ave_action.setToolTip(dg_tip_1)
        self.send_ave_action.setStatusTip(dg_tip_1)
        self.send_ave_action.triggered.connect(self.send_to_ave)
        self.addAction(self.send_ave_action)
        self.addSeparator()

        self.send_dg_short = QAction(IconRsc.get_icon('paperplane'),
                                     _('Ohne Reset an DeltaGen senden'), self)
        dg_tip_2 = _(
            'Selektierte Bauminhalte ohne einen Reset an DeltaGen senden.')
        self.send_dg_short.setToolTip(dg_tip_2)
        self.send_dg_short.setStatusTip(dg_tip_2)
        self.send_dg_short.triggered.connect(self.send_to_deltagen_wo_reset)
        self.addAction(self.send_dg_short)
        self.addSeparator()

        # -- PR-String Actions
        copy_pr = QAction(IconRsc.get_icon('options'),
                          _('PR String in Zwischenablage kopieren'), self)
        copy_pr.triggered.connect(self.copy_strings_to_clipboard)
        self.addAction(copy_pr)
        copy_li = QAction(IconRsc.get_icon('assignment'),
                          _('Linc String in Zwischenablage kopieren'), self)
        copy_li.triggered.connect(self.copy_linc_string_to_clipboard)
        self.addAction(copy_li)
        self.addSeparator()

        # -- PlmXml Actions
        self.show_plmxml_scn = QAction(IconRsc.get_icon('dog'),
                                       'PlmXml Schnuffi', self)
        self.show_plmxml_scn.triggered.connect(self.show_plmxml_scene)
        self.addAction(self.show_plmxml_scn)
        self.addSeparator()

        # ---- Create preset from selected actions ----
        self.addActions([
            self.create_menu.user_preset_from_selected,
            self.create_menu.render_preset_from_selected
        ])
        self.addSeparator()

        # ---- Prepare Context Menus & Actions ----
        # ---- Add main menu > edit -----
        self.addMenu(self.edit_menu)
        # ---- Add main menu > tree -----
        self.addMenu(self.tree_menu)
        # ---- Add main menu > create -----
        self.addMenu(self.create_menu)

        self.addSeparator()

        self.remove_row_action = QAction(
            IconRsc.get_icon('trash-a'),
            _('Selektierte Zeilen entfernen\tEntf'), self)
        self.remove_row_action.triggered.connect(
            self.edit_menu.remove_rows_action.trigger)
        self.addAction(self.remove_row_action)

        self.addSeparator()

        # ---- Developer Actions -----
        self.dev_actions = QActionGroup(self)
        cake = QAction(IconRsc.get_icon('layer'), '--- The cake was a lie ---',
                       self.dev_actions)

        show_id_action = QAction(IconRsc.get_icon('options'),
                                 'Show ID columns', self.dev_actions)
        show_id_action.triggered.connect(self.show_id_columns)

        hide_id_action = QAction(IconRsc.get_icon('options-neg'),
                                 _('Hide ID columns'), self.dev_actions)
        hide_id_action.triggered.connect(self.hide_id_columns)

        list_tab_widgets = QAction(IconRsc.get_icon('navicon'),
                                   'List Tab Widgets', self.dev_actions)
        list_tab_widgets.triggered.connect(self.list_tab_widgets)

        report_action = QAction('Report Item attributes to log',
                                self.dev_actions)
        report_action.setShortcut(QKeySequence('Ctrl+B'))
        report_action.triggered.connect(self.report_current)

        log_level = QAction(IconRsc.get_icon('sort'), 'Enable DEBUG log level',
                            self.dev_actions)
        log_level.triggered.connect(self.ui.app.set_debug_log_level)

        produce_exception = QAction(IconRsc.get_icon('warn'),
                                    'Produce Exception', self.dev_actions)
        produce_exception.triggered.connect(self.ui.app.produce_exception)

        open_dir = QAction(IconRsc.get_icon('folder'),
                           'Open Settings Directoy', self.dev_actions)
        open_dir.triggered.connect(self.open_settings_dir)

        notify = QAction(IconRsc.get_icon('eye-disabled'),
                         'Show tray notification', self.dev_actions)
        notify.triggered.connect(self.noclick_tray_notification)

        notify_click = QAction(IconRsc.get_icon('eye'),
                               'Show click tray notification',
                               self.dev_actions)
        notify_click.triggered.connect(self.click_tray_notification)

        overlay_btn_msg = QAction(IconRsc.get_icon('check_box'),
                                  'Show overlay confirm message',
                                  self.dev_actions)
        overlay_btn_msg.triggered.connect(self.overlay_confirm_message)

        overlay_msg = QAction(IconRsc.get_icon('check_box_empty'),
                              'Show regular overlay message', self.dev_actions)
        overlay_msg.triggered.connect(self.overlay_message)

        overlay_imm_msg = QAction(IconRsc.get_icon('reset'),
                                  'Show immediate overlay message',
                                  self.dev_actions)
        overlay_imm_msg.triggered.connect(self.overlay_message_immediate)

        restart = QAction(IconRsc.get_icon('reset'), 'Restart',
                          self.dev_actions)
        restart.triggered.connect(self.restart_app)

        reorder = QAction(IconRsc.get_icon('sort'),
                          'Rewrite item order whole tree', self.dev_actions)
        reorder.triggered.connect(self.reorder_tree)

        self.addActions(self.dev_actions.actions())
        self.dev_actions.setVisible(False)

        self.aboutToShow.connect(self.update_actions)

        # Install context menu event filter
        self.view.installEventFilter(self)

    def eventFilter(self, obj, event):
        if obj is not self.view:
            return False

        if event.type() == QtCore.QEvent.ContextMenu:
            self.dev_actions.setVisible(False)

            # Hold Control and Shift to display dev context
            if event.modifiers(
            ) == QtCore.Qt.ShiftModifier | QtCore.Qt.ControlModifier:
                self.dev_actions.setVisible(True)

            self.popup(event.globalPos())
            return True

        return False

    def send_to_deltagen(self):
        variants = self.view.editor.collect.collect_current_index()
        self.ui.app.send_dg.send_variants(variants, self.view)

    def send_to_ave(self):
        variants = self.view.editor.collect.collect_current_index()
        variants.ave = True
        self.ui.app.send_dg.send_variants(variants, self.view)

    def send_to_deltagen_wo_reset(self):
        variants = self.view.editor.collect.collect_current_index(
            collect_reset=False)
        self.ui.app.send_dg.send_variants(variants, self.view)

    def copy_strings_to_clipboard(self):
        variants = self.view.editor.collect.collect_current_index(
            collect_reset=False)

        pr_string = ''
        for variant in variants.variants:
            pr_string += f'{variant.name} {variant.value};'

        self.ui.app.clipboard().setText(pr_string)

    def copy_linc_string_to_clipboard(self):
        variants = self.view.editor.collect.collect_current_index(
            collect_reset=False)

        pr_string = ''
        for variant in variants.variants:
            pr_string += f'+{variant.name}'

        self.ui.app.clipboard().setText(pr_string)

    def _get_plmxml_item(self, variants: KnechtVariantList) -> Optional[Path]:
        if variants.plm_xml_path:
            return Path(variants.plm_xml_path)

        index, src_model = self.view.editor.get_current_selection()
        current_item = src_model.get_item(index)

        if current_item.userType != Kg.plmxml_item:
            return
        else:
            plmxml_file = Path(current_item.data(Kg.VALUE))
            if not path_exists(plmxml_file):
                return

        return plmxml_file

    def show_plmxml_scene(self):
        variants = self.view.editor.collect.collect_current_index()
        plmxml_file = self._get_plmxml_item(variants)
        if not plmxml_file:
            return
        plmxml_scene_page = KnechtPlmXmlScene(self.ui, plmxml_file, variants)

        GenericTabWidget(self.ui, plmxml_scene_page)

    def hide_id_columns(self):
        self.view.hideColumn(Kg.REF)
        self.view.hideColumn(Kg.ID)

    def show_id_columns(self):
        self.view.showColumn(Kg.REF)
        self.view.showColumn(Kg.ID)

    def list_tab_widgets(self):
        self.ui.view_mgr.log_tabs()

    def report_current(self):
        self.view.editor.report_current()

    def open_settings_dir(self):
        settings_dir = Path(get_settings_dir())

        if path_exists(settings_dir):
            q = QUrl.fromLocalFile(settings_dir.as_posix())
            QDesktopServices.openUrl(q)

    def noclick_tray_notification(self):
        self.ui.show_tray_notification(
            title='Test Notification',
            message='Clicking the message should hopefully emit nothing.')

    def click_tray_notification(self):
        def test_callback():
            LOGGER.info('Test notification click callback activated.')
            self.ui.msg('Message triggered by notification messageClicked.',
                        4000)

        self.ui.show_tray_notification(
            title='Test Notification',
            message='Clicking the message should trigger a overlay message.',
            clicked_callback=test_callback)

    def restart_app(self):
        restart_knecht_app(self.ui)

    def reorder_tree(self):
        for idx, _ in self.view.editor.iterator.iterate_view():
            self.view.editor.iterator.order_items(idx)

    def overlay_message(self):
        self.view.info_overlay.display(
            'Message in queue for a duration of 5000ms', 5000)

    def overlay_message_immediate(self):
        self.view.info_overlay.display(
            'Immediate message for a duration of 6000ms', 6000, True)

    def overlay_confirm_message(self):
        buttons = (('Buttontext 1', None), ('Buttontext 2', None))
        self.view.info_overlay.display_confirm(
            'Test Message to confirm something. '
            'Lenghty information ahead! This message ends '
            'with this sentence.', buttons)

    def update_actions(self):
        src_model = self.view.model().sourceModel()
        if src_model.id_mgr.has_recursive_items():
            self.send_dg_action.setEnabled(False)
            self.send_dg_short.setEnabled(False)
        else:
            self.send_dg_action.setEnabled(True)
            self.send_dg_short.setEnabled(True)

        self.create_menu.update_current_view()

        if self.view.is_render_view:
            self.send_dg_action.setEnabled(False)
            self.send_dg_short.setEnabled(False)

        self.show_plmxml_scn.setEnabled(False)
        index, src_model = self.view.editor.get_current_selection()
        current_item = src_model.get_item(index)
        if current_item.userType in (Kg.plmxml_item, Kg.preset):
            self.show_plmxml_scn.setEnabled(True)