Пример #1
0
 def testMenu(self):
     self._actionDestroyed = False
     w = QWidget()
     menu = QMenu(w)
     act = menu.addAction("MENU")
     _ref = weakref.ref(act, self.actionDestroyed)
     act = None
     self.assertFalse(self._actionDestroyed)
     menu.clear()
     self.assertTrue(self._actionDestroyed)
Пример #2
0
 def testMenu(self):
     self._actionDestroyed = False
     w = QWidget()
     menu = QMenu(w)
     act = menu.addAction("MENU")
     _ref = weakref.ref(act, self.actionDestroyed)
     act = None
     self.assertFalse(self._actionDestroyed)
     menu.clear()
     self.assertTrue(self._actionDestroyed)
Пример #3
0
class SystemTrayIcon(QSystemTrayIcon):
    def __init__(self, icon, parent=None):
        QSystemTrayIcon.__init__(self, icon, parent)
        self.setToolTip("usb-resetter 1.0 (Left\Right-Click)")
        self.parent = parent
        self.activated.connect(self.toggleP)
        menu = QMenu(parent)
        self.fmenu = QMenu("Fast reset", parent)
        self.fmenu.setToolTip("List of filtered devices to fast reset")
        aboutAction = QAction("About", self)
        aboutAction.triggered.connect(parent.show_about)
        quitAction = QAction("Exit", self)
        quitAction.triggered.connect(parent.exitEvent)
        menu.addMenu(self.fmenu)
        menu.addSeparator()
        menu.addAction(aboutAction)
        menu.addAction(quitAction)
        self.setContextMenu(menu)

    def toggleP(self, ar):
        actions = [QSystemTrayIcon.ActivationReason.Context,
                   QSystemTrayIcon.ActivationReason.Trigger]
        if ar in actions:
            self.set_Freset()
        else:
            if self.parent.Hidden:
                self.parent.show()
                self.parent.Hidden = None
            else:
                self.parent.hide()
                self.parent.Hidden = True

    def set_Freset(self):
        self.fmenu.clear()
        for l in self.parent.get_list():
            ac = QAction(l, self)

            def actdo(t):
                if resetit(t):
                    self.parent.statusbar.setStyleSheet(self.parent.s_norm)
                    self.parent.statusbar.showMessage(
                        "# Done: usb device got reset")
                    return True
                self.parent.statusbar.setStyleSheet(self.parent.s_error)
            ac.triggered.connect(partial(actdo, l))
            self.fmenu.addAction(ac)
Пример #4
0
class Indicator(QSystemTrayIcon):
    def __init__(self, *args, **kwargs):
        QSystemTrayIcon.__init__(self, *args, **kwargs)
        self.app = QApplication.instance()
        self.menu = QMenu()
        self.setContextMenu(self.menu)
        self.menu.aboutToShow.connect(self.update)
        self.opened_notes = {}
        self.activated.connect(self._activated)

    def _activated(self, reason):
        if reason == QSystemTrayIcon.Trigger:
            self.menu.popup(QCursor().pos())

    def _add_note(self, struct):
        note = Note.from_tuple(struct)
        title = note.title[:40].replace("&", "&&")
        self.menu.addAction(title, Slot()(partial(self.open, note=note)))

    @Slot()
    def update(self):
        self.menu.clear()
        try:
            version = self.app.provider.get_api_version()
        except (dbus.exceptions.UnknownMethodException, dbus.exceptions.DBusException):  # dbus raise some magic
            version = -1
        if version != API_VERSION:
            action = self.menu.addAction(self.tr("API version missmatch, please restart"))
            action.setEnabled(False)
            if version < API_VERSION:
                handler = self.app.provider.kill
            else:
                handler = partial(os.execlp, "everpad", "--replace")
            self.menu.addAction(self.tr("Restart everpad"), handler)
            return
        if get_auth_token():
            pin_notes = self.app.provider.find_notes(
                "", dbus.Array([], signature="i"), dbus.Array([], signature="i"), 0, 20, Note.ORDER_UPDATED_DESC, 1
            )
            notes = self.app.provider.find_notes(
                "",
                dbus.Array([], signature="i"),
                dbus.Array([], signature="i"),
                0,
                20 - len(pin_notes),
                Note.ORDER_UPDATED_DESC,
                0,
            )
            if len(notes) + len(pin_notes) or self.app.provider.is_first_synced():
                self.menu.addAction(self.tr("All Notes"), self.show_all_notes)
                self.menu.addSeparator()
                if len(pin_notes):
                    for struct in pin_notes:
                        self._add_note(struct)
                    self.menu.addSeparator()
                for struct in notes:
                    self._add_note(struct)
                self.menu.addSeparator()
                self.menu.addAction(self.tr("Create Note"), self.create)
                first_sync = False
            else:
                first_sync = True
            if self.app.provider.get_status() == STATUS_SYNC:
                action = self.menu.addAction(
                    self.tr("Wait, first sync in progress") if first_sync else self.tr("Sync in progress")
                )
                action.setEnabled(False)
            else:
                if first_sync:
                    label = self.tr("Please perform first sync")
                else:
                    last_sync = self.app.provider.get_last_sync()
                    delta_sync = (datetime.now() - datetime.strptime(last_sync, "%H:%M")).seconds // 60
                    if delta_sync == 0:
                        label = self.tr("Last Sync: Just now")
                    elif delta_sync == 1:
                        label = self.tr("Last Sync: %s min ago") % delta_sync
                    else:
                        label = self.tr("Last Sync: %s mins ago") % delta_sync
                self.menu.addAction(label, Slot()(self.app.provider.sync))
        self.menu.addAction(self.tr("Settings and Management"), self.show_management)
        self.menu.addSeparator()
        self.menu.addAction(self.tr("Exit"), self.exit)

    def open(self, note, search_term=""):
        old_note_window = self.opened_notes.get(note.id, None)
        if old_note_window and not getattr(old_note_window, "closed", True):
            editor = self.opened_notes[note.id]
            editor.activateWindow()
        else:
            editor = Editor(note)
            editor.show()
            self.opened_notes[note.id] = editor
        if search_term:
            editor.findbar.set_search_term(search_term)
            editor.findbar.show()
        return editor

    @Slot()
    def create(self, attach=None, notebook_id=NONE_ID):
        note_struct = Note(  # maybe replace NONE's to somthing better
            id=NONE_ID,
            title=self.tr("New note"),
            content=self.tr("New note content"),
            tags=dbus.Array([], signature="i"),
            notebook=notebook_id,
            created=NONE_VAL,
            updated=NONE_VAL,
            conflict_parent=NONE_VAL,
            conflict_items=dbus.Array([], signature="i"),
            place="",
        ).struct
        note = Note.from_tuple(self.app.provider.create_note(note_struct))
        editor = self.open(note)
        if attach:
            editor.resource_edit.add_attach(attach)

    @Slot()
    def show_all_notes(self):
        if not hasattr(self, "list") or getattr(self.list, "closed", True):
            self.list = List()
            self.list.show()
        else:
            self.list.activateWindow()

    @Slot()
    def show_management(self):
        if not hasattr(self, "management") or getattr(self.management, "closed", True):
            self.management = Management()
            self.management.show()
        else:
            self.management.activateWindow()

    @Slot()
    def exit(self):
        self.app.quit()
Пример #5
0
class Indicator(QSystemTrayIcon):
    def __init__(self, app, *args, **kwargs):
        QSystemTrayIcon.__init__(self, *args, **kwargs)
        self.app = app
        self.menu = QMenu()
        self.setContextMenu(self.menu)
        self.menu.aboutToShow.connect(self.update)
        self.opened_notes = {}
        self.management = None

    @Slot()
    def update(self):
        self.menu.clear()
        if get_auth_token():
            for note_struct in self.app.provider.find_notes(
                "", dbus.Array([], signature="i"), dbus.Array([], signature="i"), 0, 20, Note.ORDER_UPDATED_DESC
            ):
                note = Note.from_tuple(note_struct)
                self.menu.addAction(note.title[:40], Slot()(partial(self.open, note=note)))
            self.menu.addSeparator()
            self.menu.addAction(self.tr("Create Note"), self.create)
            if self.app.provider.get_status() == STATUS_SYNC:
                action = self.menu.addAction(self.tr("Sync in progress"))
                action.setEnabled(False)
            else:
                self.menu.addAction(
                    self.tr("Last sync: %s") % self.app.provider.get_last_sync(), Slot()(self.app.provider.sync)
                )
        self.menu.addAction(self.tr("Settings and Management"), self.show_management)
        self.menu.addSeparator()
        self.menu.addAction(self.tr("Exit"), self.exit)

    def open(self, note):
        old_note_window = self.opened_notes.get(note.id, None)
        if old_note_window and not getattr(old_note_window, "closed", True):
            editor = self.opened_notes[note.id]
            editor.activateWindow()
        else:
            editor = Editor(self.app, note)
            editor.show()
            self.opened_notes[note.id] = editor
        return editor

    @Slot()
    def create(self, attach=None):
        note_struct = Note(  # maybe replace NONE's to somthing better
            id=NONE_ID,
            title=self.tr("New note"),
            content=self.tr("New note content"),
            tags=dbus.Array([], signature="i"),
            notebook=NONE_ID,
            created=NONE_VAL,
            updated=NONE_VAL,
            place="",
        ).struct
        note = Note.from_tuple(self.app.provider.create_note(note_struct))
        editor = self.open(note)
        if attach:
            editor.resource_edit.add_attach(attach)

    @Slot()
    def show_management(self):
        if not self.management or getattr(self.management, "closed", True):
            self.management = Management(self.app)
            self.management.show()
        else:
            self.management.activateWindow()

    @Slot()
    def exit(self):
        sys.exit(0)
Пример #6
0
class Indicator(QSystemTrayIcon):
    def __init__(self, *args, **kwargs):
        QSystemTrayIcon.__init__(self, *args, **kwargs)
        self.app = QApplication.instance()
        self.menu = QMenu()
        self.setContextMenu(self.menu)
        self.menu.aboutToShow.connect(self.update)
        self.opened_notes = {}
        self.activated.connect(self._activated)
        self.settings = QSettings('everpad', 'everpad-pad')
        # Configure logger.
        self.logger = logging.getLogger('everpad-indicator')
        self.logger.setLevel(logging.DEBUG)
        fh = logging.FileHandler(
            os.path.expanduser('~/.everpad/logs/everpad.log'))
        fh.setLevel(logging.DEBUG)
        formatter = logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        fh.setFormatter(formatter)
        self.logger.addHandler(fh)

    def _activated(self, reason):
        if reason == QSystemTrayIcon.Trigger:
            self.menu.popup(QCursor().pos())

    def _add_note(self, menu, struct):
        note = Note.from_tuple(struct)
        title = note.title[:40].replace('&', '&&')
        menu.addAction(title, Slot()(partial(self.open, note=note)))

    @Slot()
    def update(self):
        self.menu.clear()
        try:
            version = self.app.provider.get_api_version()
        except (  # dbus raise some magic
                dbus.exceptions.UnknownMethodException,
                dbus.exceptions.DBusException,
        ):
            version = -1
        if version != API_VERSION:
            action = self.menu.addAction(
                self.tr('API version missmatch, please restart'), )
            action.setEnabled(False)
            if version < API_VERSION:
                handler = self.app.provider.kill
            else:
                handler = partial(os.execlp, 'everpad', '--replace')
            self.menu.addAction(
                self.tr('Restart everpad'),
                handler,
            )
            return
        if self.app.provider.is_authenticated():
            pin_notes = self.app.provider.find_notes(
                '',
                dbus.Array([], signature='i'),
                dbus.Array([], signature='i'),
                0,
                20,
                Note.ORDER_UPDATED_DESC,
                1,
            )
            sort_by_notebook = bool(
                int(
                    self.app.provider.get_settings_value('sort-by-notebook')
                    or 0))
            has_notes = False
            if not sort_by_notebook:
                notes = self.app.provider.find_notes(
                    '',
                    dbus.Array([], signature='i'),
                    dbus.Array([], signature='i'),
                    0,
                    20 - len(pin_notes),
                    Note.ORDER_UPDATED_DESC,
                    0,
                )
                has_notes = bool(notes)
            else:
                notebooks = self.app.provider.list_notebooks()
                notes = {}
                for notebook_struct in notebooks:
                    notebook = Notebook.from_tuple(notebook_struct)
                    _notes = self.app.provider.find_notes(
                        '',
                        [notebook.id],
                        dbus.Array([], signature='i'),
                        0,
                        20 - len(pin_notes),
                        Note.ORDER_UPDATED_DESC,
                        0,
                    )
                    notes[notebook] = _notes
                    if _notes:
                        has_notes = True
            first_sync = not (has_notes or len(pin_notes)
                              or self.app.provider.is_first_synced())

            # Rate Limit indication added
            # STATUS_RATE = -1  # Rate Limit status
            # STATUS_NONE = 0
            # STATUS_SYNC = 1
            # status_syncing = self.app.provider.get_status() == STATUS_SYNC
            status_syncing = self.app.provider.get_status()

            if status_syncing < 0:
                sync_label = self.tr('Rate Limit')
            elif status_syncing and first_sync:
                sync_label = self.tr('Wait, first sync in progress')
            elif status_syncing and not first_sync:
                sync_label = self.tr('Sync in progress')
            elif not status_syncing and first_sync:
                sync_label = self.tr('Please perform first sync')
            else:
                last_sync = self.app.provider.get_last_sync()
                delta_sync = (datetime.now() - datetime.strptime(
                    last_sync, '%H:%M')).seconds // 60
                if delta_sync == 0:
                    sync_label = self.tr('Last Sync: Just now')
                elif delta_sync == 1:
                    sync_label = self.tr('Last Sync: %s min ago') % delta_sync
                else:
                    sync_label = self.tr('Last Sync: %s mins ago') % delta_sync

            menu_items = {
                'create_note': [self.tr('Create Note'), self.create],
                'all_notes': [self.tr('All Notes'), self.show_all_notes],
                'sync': [sync_label,
                         Slot()(self.app.provider.sync)],
                'pin_notes': pin_notes,
                'notes': notes,
            }
            for item in self.app.settings.value('menu-order',
                                                DEFAULT_INDICATOR_LAYOUT):
                if item == 'pin_notes' or item == 'notes':
                    if not first_sync and len(menu_items[item]):
                        self.menu.addSeparator()
                        if item == 'notes' and sort_by_notebook:
                            for notebook in menu_items[item]:
                                sub_menu = self.menu.addMenu(notebook.name)
                                _notes = menu_items[item][notebook]
                                for struct in _notes:
                                    self._add_note(sub_menu, struct)
                        else:
                            for struct in menu_items[item]:
                                self._add_note(self.menu, struct)
                        self.menu.addSeparator()
                else:
                    action = self.menu.addAction(menu_items[item][0],
                                                 menu_items[item][1])
                    if status_syncing and item == 'sync':
                        action.setEnabled(False)
        self.menu.addSeparator()
        self.menu.addAction(self.tr('Settings and Management'),
                            self.show_management)
        self.menu.addAction(self.tr('Exit'), self.exit)

    def open(self, note, search_term=''):
        self.logger.debug('Opening note: "%s".' % note.title)
        old_note_window = self.opened_notes.get(note.id, None)
        if old_note_window and not getattr(old_note_window, 'closed', True):
            editor = self.opened_notes[note.id]
            # hide and show for bringing to front
            editor.hide()
            editor.show()
        else:
            editor = Editor(note)
            editor.show()
            self.opened_notes[note.id] = editor
        if search_term:
            editor.findbar.set_search_term(search_term)
            editor.findbar.show()
        editor.raise_()
        editor.activateWindow()
        return editor

    @Slot()
    def create(self, attach=None, notebook_id=NONE_ID):
        self.logger.debug('Creating new note.')
        note_struct = Note(  # maybe replace NONE's to somthing better
            id=NONE_ID,
            title=self.tr('New note'),
            content=self.tr("New note content"),
            tags=dbus.Array([], signature='i'),
            notebook=notebook_id,
            created=NONE_VAL,
            updated=NONE_VAL,
            conflict_parent=NONE_VAL,
            conflict_items=dbus.Array([], signature='i'),
            place='',
            share_date=NONE_VAL,
            share_url='',
        ).struct
        note = Note.from_tuple(self.app.provider.create_note(note_struct), )
        editor = self.open(note)
        if attach:
            editor.resource_edit.add_all_attach(attach)

    @Slot()
    def show_all_notes(self):
        if not hasattr(self, 'list') or getattr(self.list, 'closed', True):
            self.list = List()
            self.list.show()
        else:
            self.list.activateWindow()

    @Slot()
    def show_management(self):
        if not hasattr(self, 'management') or getattr(self.management,
                                                      'closed', True):
            self.management = Management()
            self.management.show()
        else:
            self.management.activateWindow()

    @Slot()
    def exit(self):
        self.app.quit()
Пример #7
0
class Indicator(QSystemTrayIcon):
    """Indicator applet class"""
    notes_get = Signal(list)

    def __init__(self, app, *args, **kwargs):
        """Init indicator

        Keyword Arguments:
        app -- QApplication

        Returns: None
        """
        QSystemTrayIcon.__init__(self, *args, **kwargs)
        self._action_threads = []
        self._cached_notes = {}
        self.menu = QMenu()
        self.setContextMenu(self.menu)
        self.app = app
        app.indicator = self
        self.menu.aboutToShow.connect(self.update)
        self.auth_dialog = AuthDialog(self.app)
        self._notes = []
        self.notes_get.connect(self.notes_getted)
        self.get_notes()

    @Slot(list)
    def notes_getted(self, notes):
        self._notes = notes

    def get_notes(self):
        self.app.sync_thread.action_receive.emit((
            self.app.provider.get_notes,
            ('', 10), {}, self.notes_get,
        ))

    @Slot()
    def update(self):
        """Set notes to menu"""
        self.menu.clear()
        self._open_slots = []
        if self.app.authenticated:
            for note in self._notes:
                slot = Slot()(partial(self.show_note, note[1]))
                self._open_slots.append(slot)
                self.menu.addAction(
                    note[2][:40],
                    slot,
                )
            self.menu.addSeparator()
            self.menu.addAction(
                self.tr('New note'),
                self.new_note,
            )
            self.menu.addAction(
                self.tr('Auth settings'),
                self.auth_settings,
            )
        else:
            self.menu.addAction(
                self.tr('Please authorise'),
                self.auth_settings,
            )
        self.menu.addAction(self.tr('Exit'), self.app.end)
        self.get_notes()


    @Slot()
    def new_note(self):
        """Create new note"""
        self.show_note(None, True)

    @Slot()
    def auth_settings(self):
        """Show auth settings dialog"""
        self.auth_dialog.show()

    def show_note(self, id, create=False):
        """Show note"""
        if create:
            note = None
        else:
            note = self.app.provider.get_note(id)
        prev = self.app.opened.get(id, None)
        if not prev or getattr(prev, 'closed', False):
            self.app.opened[id] = NoteWindow(self.app, note, create)
            self.app.opened[id].show()
Пример #8
0
class Indicator(QSystemTrayIcon):
    def __init__(self, *args, **kwargs):
        QSystemTrayIcon.__init__(self, *args, **kwargs)
        self.app = QApplication.instance()
        self.menu = QMenu()
        self.setContextMenu(self.menu)
        self.menu.aboutToShow.connect(self.update)
        self.opened_notes = {}
        self.activated.connect(self._activated)
        self.settings = QSettings('everpad', 'everpad-pad')

    def _activated(self, reason):
        if reason == QSystemTrayIcon.Trigger:
            self.menu.popup(QCursor().pos())

    def _add_note(self, menu, struct):
        note = Note.from_tuple(struct)
        title = note.title[:40].replace('&', '&&')
        menu.addAction(title, Slot()(
            partial(self.open, note=note)
        ))

    @Slot()
    def update(self):
        self.menu.clear()
        try:
            version = self.app.provider.get_api_version()
        except (  # dbus raise some magic
            dbus.exceptions.UnknownMethodException,
            dbus.exceptions.DBusException,
        ):
            version = -1
        if version != API_VERSION:
            action = self.menu.addAction(
                self.tr('API version missmatch, please restart'),
            )
            action.setEnabled(False)
            if version < API_VERSION:
                handler = self.app.provider.kill
            else:
                handler = partial(os.execlp, 'everpad', '--replace')
            self.menu.addAction(
                self.tr('Restart everpad'), handler,
            )
            return
        if self.app.provider.is_authenticated():
            pin_notes = self.app.provider.find_notes(
                '', dbus.Array([], signature='i'),
                dbus.Array([], signature='i'), 0,
                20, Note.ORDER_UPDATED_DESC, 1,
            )
            sort_by_notebook = bool(int(
                self.app.provider.get_settings_value('sort-by-notebook') or 0))
            has_notes = False
            if not sort_by_notebook:
                notes = self.app.provider.find_notes(
                    '', dbus.Array([], signature='i'),
                    dbus.Array([], signature='i'), 0,
                    20 - len(pin_notes), Note.ORDER_UPDATED_DESC, 0,
                )
                has_notes = bool(notes)
            else:
                notebooks = self.app.provider.list_notebooks()
                notes = {}
                for notebook_struct in notebooks:
                    notebook = Notebook.from_tuple(notebook_struct)
                    _notes = self.app.provider.find_notes('', [notebook.id],
                         dbus.Array([], signature='i'), 0,
                         20 - len(pin_notes), Note.ORDER_UPDATED_DESC, 0,
                    )
                    notes[notebook] = _notes
                    if _notes:
                        has_notes = True
            first_sync = not (
                has_notes or len(pin_notes) or self.app.provider.is_first_synced()
            )
            status_syncing = self.app.provider.get_status() == STATUS_SYNC
            if status_syncing and first_sync:
                sync_label = self.tr('Wait, first sync in progress')
            elif status_syncing and not first_sync:
                sync_label = self.tr('Sync in progress')
            elif not status_syncing and first_sync:
                sync_label = self.tr('Please perform first sync')
            else:
                last_sync = self.app.provider.get_last_sync()
                delta_sync = (
                    datetime.now() - datetime.strptime(last_sync, '%H:%M')
                ).seconds // 60
                if delta_sync == 0:
                    sync_label = self.tr('Last Sync: Just now')
                elif delta_sync == 1:
                    sync_label = self.tr('Last Sync: %s min ago') % delta_sync
                else:
                    sync_label = self.tr('Last Sync: %s mins ago') % delta_sync
            menu_items = {
                'create_note': [self.tr('Create Note'), self.create],
                'all_notes': [self.tr('All Notes'), self.show_all_notes],
                'sync': [sync_label, Slot()(self.app.provider.sync)],
                'pin_notes': pin_notes,
                'notes': notes,
            }
            for item in self.app.settings.value('menu-order', DEFAULT_INDICATOR_LAYOUT):
                if item == 'pin_notes' or item == 'notes':
                    if not first_sync and len(menu_items[item]):
                        self.menu.addSeparator()
                        if item == 'notes' and sort_by_notebook:
                            for notebook in menu_items[item]:
                                sub_menu = self.menu.addMenu(notebook.name)
                                _notes = menu_items[item][notebook]
                                for struct in _notes:
                                    self._add_note(sub_menu, struct)
                        else:
                            for struct in menu_items[item]:
                                self._add_note(self.menu, struct)
                        self.menu.addSeparator()
                else:
                    action = self.menu.addAction(menu_items[item][0], menu_items[item][1])
                    if status_syncing and item == 'sync':
                        action.setEnabled(False)
        self.menu.addSeparator()
        self.menu.addAction(self.tr('Settings and Management'), self.show_management)
        self.menu.addAction(self.tr('Exit'), self.exit)

    def open(self, note, search_term=''):
        old_note_window = self.opened_notes.get(note.id, None)
        if old_note_window and not getattr(old_note_window, 'closed', True):
            editor = self.opened_notes[note.id]
            # hide and show for bringing to front
            editor.hide()
            editor.show()
        else:
            editor = Editor(note)
            editor.show()
            self.opened_notes[note.id] = editor
        if search_term:
            editor.findbar.set_search_term(search_term)
            editor.findbar.show()
        editor.raise_()
        editor.activateWindow()
        return editor

    @Slot()
    def create(self, attach=None, notebook_id=NONE_ID):
        note_struct = Note(  # maybe replace NONE's to somthing better
            id=NONE_ID,
            title=self.tr('New note'),
            content=self.tr("New note content"),
            tags=dbus.Array([], signature='i'),
            notebook=notebook_id,
            created=NONE_VAL,
            updated=NONE_VAL,
            conflict_parent=NONE_VAL,
            conflict_items=dbus.Array([], signature='i'),
            place='',
            share_date=NONE_VAL,
            share_url='',
        ).struct
        note = Note.from_tuple(
            self.app.provider.create_note(note_struct),
        )
        editor = self.open(note)
        if attach:
            editor.resource_edit.add_all_attach(attach)

    @Slot()
    def show_all_notes(self):
        if not hasattr(self, 'list') or getattr(self.list, 'closed', True):
            self.list = List()
            self.list.show()
        else:
            self.list.activateWindow()

    @Slot()
    def show_management(self):
        if not hasattr(self, 'management') or getattr(self.management, 'closed', True):
            self.management = Management()
            self.management.show()
        else:
            self.management.activateWindow()

    @Slot()
    def exit(self):
        self.app.quit()
class MTTSettingsMenu(QMenu):

    def __init__(self, parent=None):
        super(MTTSettingsMenu, self).__init__(parent)

        self.view = parent
        self.is_master_cmd = False
        # power user state
        self.power_user = MTTSettings.value('powerUser')

        self.__create_actions()
        self.__populate_menu()

    def keyPressEvent(self, event):
        if event.modifiers() == Qt.ControlModifier:
            self.is_master_cmd = True

        super(MTTSettingsMenu, self).keyPressEvent(event)

    def keyReleaseEvent(self, event):
        self.is_master_cmd = False
        super(MTTSettingsMenu, self).keyReleaseEvent(event)

    def __create_actions(self):
        def add_action(lbl, tip, cmd, checkable=False, checked=False):
            a = QAction(lbl, self)
            a.setStatusTip(tip)
            a.triggered.connect(cmd)
            if checkable:
                a.setCheckable(True)
                a.setChecked(checked)

            return a

        self.help_a = add_action(
            'Help',
            'Opens the online Help page',
            self.on_settings_help)

        self.switch_edit_a = add_action(
            'Switch Edit/Source',
            'Replace "Edit" button by "Source" button',
            self.on_switch_source_edit_menu,
            True,
            MTTSettings.value('switchEdit'))

        self.heads_up_a = add_action(
            'HeadsUp Message',
            'Show HeadsUp Message in viewport',
            self.on_toggle_headsup,
            True,
            MTTSettings.value('showHeadsUp'))

        self.focus_filter_a = add_action(
            'Focus Filter Field at Startup',
            'Focus filter field at startup',
            self.on_toggle_focus,
            True,
            MTTSettings.value('filterFocus'))

        self.force_relative_path_a = add_action(
            'Force Relative Path',
            'Set a relative path when selecting a new file',
            self.on_force_relative_path,
            True,
            MTTSettings.value('forceRelativePath'))

        self.show_real_attr_value_a = add_action(
            'Show Real Attribute Value',
            'Show fullpath instead of filtering path as Attribute Editor',
            self.on_show_real_attribute_value,
            True,
            MTTSettings.value('showRealAttributeValue'))

        self.manage_quick_filter_a = add_action(
            'Manage Quick Filters',
            'Manage filters that popup with right clic in filter field',
            self.on_filter_manage_quick_filter)

        self.clear_completion_cache_a = add_action(
            'Clear Completion Cache',
            'Erase auto completion cache of filter field',
            self.on_filter_clear_completion_cache)

        self.override_panels_a = add_action(
            'Add CreateNode Button to Editors',
            ('Add "Create Node" to HyperShade and '
                'Node Editor for the current session'),
            self.on_override_panels)

        self.export_to_csv = add_action(
            'Export Texture List as CSV',
            'Export current textures into a csv file',
            self.view.model.export_as_csv)

        self.about = add_action(
            'About',
            'About',
            self.on_settings_about)

    def __populate_menu(self):
        self.addAction(self.help_a)

        self.addSeparator()

        self.addAction(self._get_menu_header('SETTINGS'))
        self.addAction(self.switch_edit_a)
        self.addAction(self.heads_up_a)
        self.addAction(self.focus_filter_a)
        self.addAction(self.force_relative_path_a)
        self.addAction(self.show_real_attr_value_a)
        self.addMenu(self._create_instance_menu())
        self.addMenu(self._create_theme_menu())

        self.addSeparator()

        self.addAction(self._get_menu_header('FILTER OPTIONS'))
        self.addAction(self.manage_quick_filter_a)
        self.addAction(self.clear_completion_cache_a)

        self.addSeparator()

        self.addAction(self._get_menu_header('MISC'))
        self.addAction(self.override_panels_a)
        self.addAction(self.export_to_csv)

        self.addSeparator()

        self.addAction(self._get_menu_header('DEBUG'))
        self.addMenu(self._create_debug_menu())

        self.addSeparator()

        self.addAction(self.about)

    def _get_menu_header(self, title):
        header = QAction(title, self)
        header.setEnabled(False)
        return header

    def _create_instance_menu(self):
        self.instance_menu = QMenu(self)
        self.instance_menu.setTitle('Prompt Instance Delay')
        self.instance_menu.aboutToShow.connect(
            self.on_show_prompt_instance_delay_menu)

        return self.instance_menu

    def _create_theme_menu(self):
        theme_menu = QMenu(self)
        theme_menu.setTitle('Buttons Theme')
        theme_menu.setTearOffEnabled(True)
        theme_menu.setWindowTitle(TAG)
        theme_actions = QActionGroup(self)
        theme_actions.setExclusive(True)
        # create ordered theme list
        custom_order_theme = sorted(THEMES.iterkeys())
        custom_order_theme.remove('Maya Theme')
        custom_order_theme.insert(0, 'Maya Theme')
        default_item = True
        for theme in custom_order_theme:
            current_theme_action = QAction(theme, theme_actions)
            current_theme_action.setCheckable(True)
            current_theme_action.setChecked(
                MTTSettings.value('theme', 'Maya Theme') == theme)
            current_theme_action.triggered.connect(self.on_change_theme)
            theme_menu.addAction(current_theme_action)

            if default_item:
                theme_menu.addSeparator()
                default_item = False

        return theme_menu

    def _create_debug_menu(self):
        self.debug_menu = QMenu(self)
        self.debug_menu.setTitle('Debug Menu')
        self.debug_menu.aboutToShow.connect(self.on_show_debug_menu)

        return self.debug_menu

    def on_change_theme(self):
        self.view.on_choose_theme(self.sender().text())

    def on_show_debug_menu(self):
        self.debug_menu.clear()

        if self.is_master_cmd or self.power_user:
            power_user_mode = QAction('Power User Mode', self)
            power_user_mode.setCheckable(True)
            power_user_mode.setChecked(MTTSettings.value('powerUser'))
            power_user_mode.triggered.connect(self.__on_toggle_power_user)
            self.debug_menu.addAction(power_user_mode)
            self.is_master_cmd = False

            self.debug_menu.addSeparator()

        open_pref_folder_action = QAction('Open Preferences Folder', self)
        open_pref_folder_action.setStatusTip('Open MTT preference folder')
        open_pref_folder_action.triggered.connect(self.on_open_preference_folder)
        self.debug_menu.addAction(open_pref_folder_action)

        self.debug_menu.addSeparator()

        database_dump_csv = QAction('Dump Database as CSV', self)
        database_dump_csv.triggered.connect(self.view.model.database_dump_csv)
        self.debug_menu.addAction(database_dump_csv)

        database_dump_sql = QAction('Dump Database as SQL', self)
        database_dump_sql.triggered.connect(self.view.model.database_dump_sql)
        self.debug_menu.addAction(database_dump_sql)

        self.debug_menu.addSeparator()

        support_info = QMenu(self)
        support_info.setTitle('Supported Node Type')
        support_info.aboutToShow.connect(self.on_show_supported_type)
        self.debug_menu.addMenu(support_info)

    def on_filter_clear_completion_cache(self):
        """ Clear filter auto completion cache """
        self.view.on_filter_set_text('')
        MTTSettings.remove('filterCompletionWildcard')
        MTTSettings.remove('filterCompletionRegExp')
        self.view.completion_model.setStringList([])

    def on_switch_source_edit_menu(self):
        state = MTTSettings.value('switchEdit')
        MTTSettings.set_value('switchEdit', not state)
        self.view.on_set_source_edit_menu(not state)

    def on_show_real_attribute_value(self):
        self.view.model.layoutAboutToBeChanged.emit()
        show_real_attribute_state = MTTSettings.value('showRealAttributeValue')
        MTTSettings.set_value(
            'showRealAttributeValue', not show_real_attribute_state)
        self.view._layout_changed()

    def on_filter_manage_quick_filter(self):
        """ Open Quick Filter words manager and save its content """
        manager = MTTQuickFilterManager(self)
        if manager.exec_():
            lists = manager.get_lists()
            # save list in settings
            MTTSettings.set_value('filterQuickWordsWildcard', ';;'.join(lists[0]))
            MTTSettings.set_value('filterQuickWordsRegExp', ';;'.join(lists[1]))
            # set current list
            self.view.quick_filter_words = lists[MTTSettings.value('filterRE')]
        manager.deleteLater()

    @staticmethod
    def on_toggle_headsup():
        state = MTTSettings.value('showHeadsUp')
        MTTSettings.set_value('showHeadsUp', not state)

    @staticmethod
    def on_toggle_focus():
        state = MTTSettings.value('filterFocus')
        MTTSettings.set_value('filterFocus', not state)

    @staticmethod
    def on_force_relative_path():
        state = MTTSettings.value('forceRelativePath')
        MTTSettings.set_value('forceRelativePath', not state)

    def on_show_supported_type(self):
        node_types = sorted(
            [n_type for (n_type, nice, attr) in
             MTTSettings.SUPPORTED_TYPE] + MTTSettings.UNSUPPORTED_TYPE)
        support_info = self.sender()
        support_info.clear()

        for node_type in node_types:
            current = QAction(node_type, self)
            current.setEnabled(False)
            current.setCheckable(True)
            current.setChecked(node_type not in MTTSettings.UNSUPPORTED_TYPE)
            support_info.addAction(current)

    def __on_toggle_power_user(self):
        state = MTTSettings.value('powerUser')
        MTTSettings.set_value('powerUser', not state)
        self.power_user = not state

    @staticmethod
    def on_open_preference_folder():
        """ Open preference folder """
        folder_path = os.path.dirname(MTTSettings.filename())
        cmds.launchImageEditor(viewImageFile=folder_path)

    @staticmethod
    def on_override_panels():
        """ Override HyperShade and NodeEditor creation callback"""
        override_info_box = QMessageBox()
        override_info_box.setWindowTitle(WINDOW_TITLE)
        override_info_box.setIcon(QMessageBox.Information)
        override_info_box.setText(
            'Buttons will be added to HyperShade toolbar and Node Editor toolbar.<br/>'
            'Changes will exists during this session.'
        )
        override_info_box.setInformativeText('<i>Read Help to set this settings permanent</i>')
        override_info_box.setStandardButtons(QMessageBox.Ok)
        override_info_box.setDefaultButton(QMessageBox.Ok)
        override_info_box.exec_()

        mttOverridePanels.override_panels()

    def on_settings_about(self):

        special_list = map(lambda x: x.replace(' ', '&nbsp;'), sorted([
            u'Beno\xeet Stordeur', u'Fran\xe7ois Jumel',
            'Jonathan Lorber', 'Norbert Cretinon',
            'Gilles Hoff'
        ]))
        QMessageBox.about(
            self.parent(),
            WINDOW_TITLE,
            '<b>Maya Texture Toolkit v{:.02f}</b>'
            u'<p>{} - \xa9 2014 - 2016'
            '</p>'
            '<p>Special thanks to :<br/>'
            '<i>{}</i>'
            '</p>'.format(__version__, __author__, ', '.join(special_list))
        )

    @staticmethod
    def on_settings_help():
        help_wiki = 'https://github.com/Bioeden/dbMayaTextureToolkit/wiki'
        webbrowser.open(help_wiki)

    def on_show_prompt_instance_delay_menu(self):
        prompt_instance_state = cmds.optionVar(query='MTT_prompt_instance_state')

        if prompt_instance_state == PROMPT_INSTANCE_WAIT:
            elapsed_time = time() - cmds.optionVar(query='MTT_prompt_instance_suspend')
            if elapsed_time > PROMPT_INSTANCE_WAIT_DURATION:
                prompt_instance_state = PROMPT_INSTANCE_ASK
                cmds.optionVar(iv=['MTT_prompt_instance_state', prompt_instance_state])
            else:
                mtt_log('Remaining %.2fs' % (PROMPT_INSTANCE_WAIT_DURATION - elapsed_time))
        elif prompt_instance_state == PROMPT_INSTANCE_SESSION:
            if 'mtt_prompt_session' not in __main__.__dict__:
                prompt_instance_state = PROMPT_INSTANCE_ASK
                cmds.optionVar(iv=['MTT_prompt_instance_state', prompt_instance_state])

        self.instance_menu.clear()

        prompt_delay = QActionGroup(self)
        prompt_delay.setExclusive(True)
        for i in range(len(PROMPT_INSTANCE_STATE.keys())):
            current_delay_action = QAction(PROMPT_INSTANCE_STATE[i], prompt_delay)
            current_delay_action.setCheckable(True)
            current_delay_action.setChecked(prompt_instance_state == i)
            current_delay_action.triggered.connect(
                partial(self.view.on_choose_instance_delay, i, prompt=i != 0))
            self.instance_menu.addAction(current_delay_action)
Пример #10
0
class Indicator(QSystemTrayIcon):
    def __init__(self, app, *args, **kwargs):
        QSystemTrayIcon.__init__(self, *args, **kwargs)
        self.app = app
        self.menu = QMenu()
        self.setContextMenu(self.menu)
        self.menu.aboutToShow.connect(self.update)
        self.opened_notes = {}
        self.activated.connect(self._activated)

    def _activated(self, reason):
        if reason == QSystemTrayIcon.Trigger:
            self.menu.popup(QCursor().pos())

    def _add_note(self, struct):
        note = Note.from_tuple(struct)
        title = note.title[:40].replace('&', '&&')
        self.menu.addAction(title, Slot()(partial(self.open, note=note)))

    @Slot()
    def kill_all(self):
        try:
            self.app.provider.kill()
        except dbus.exceptions.DBusException:
            pass
        os.system('everpad --replace')

    @Slot()
    def update(self):
        self.menu.clear()
        try:
            version = self.app.provider.get_api_version()
        except (  # dbus raise some magic
                dbus.exceptions.UnknownMethodException,
                dbus.exceptions.DBusException,
        ):
            version = -1
        if version != API_VERSION:
            action = self.menu.addAction(
                self.tr('API version missmatch, please restart'), )
            action.setEnabled(False)
            self.menu.addAction(
                self.tr('Restart everpad'),
                self.kill_all,
            )
            return
        if get_auth_token():
            pin_notes = self.app.provider.find_notes(
                '',
                dbus.Array([], signature='i'),
                dbus.Array([], signature='i'),
                0,
                20,
                Note.ORDER_UPDATED_DESC,
                1,
            )
            notes = self.app.provider.find_notes(
                '',
                dbus.Array([], signature='i'),
                dbus.Array([], signature='i'),
                0,
                20 - len(pin_notes),
                Note.ORDER_UPDATED_DESC,
                0,
            )
            if len(notes) + len(
                    pin_notes) or self.app.provider.is_first_synced():
                self.menu.addAction(self.tr('All Notes'), self.show_all_notes)
                self.menu.addSeparator()
                if len(pin_notes):
                    for struct in pin_notes:
                        self._add_note(struct)
                    self.menu.addSeparator()
                for struct in notes:
                    self._add_note(struct)
                self.menu.addSeparator()
                self.menu.addAction(self.tr('Create Note'), self.create)
                first_sync = False
            else:
                first_sync = True
            if self.app.provider.get_status() == STATUS_SYNC:
                action = self.menu.addAction(
                    self.tr('Wait, first sync in progress'
                            ) if first_sync else self.tr('Sync in progress'))
                action.setEnabled(False)
            else:
                if first_sync:
                    label = self.tr('Please perform first sync')
                else:
                    label = self.tr(
                        'Last sync: %s') % self.app.provider.get_last_sync()
                self.menu.addAction(label, Slot()(self.app.provider.sync))
        self.menu.addAction(self.tr('Settings and Management'),
                            self.show_management)
        self.menu.addSeparator()
        self.menu.addAction(self.tr('Exit'), self.exit)

    def open(self, note, search_term=''):
        old_note_window = self.opened_notes.get(note.id, None)
        if old_note_window and not getattr(old_note_window, 'closed', True):
            editor = self.opened_notes[note.id]
            editor.activateWindow()
        else:
            editor = Editor(self.app, note)
            editor.show()
            self.opened_notes[note.id] = editor
        if search_term:
            editor.findbar.set_search_term(search_term)
            editor.findbar.show()
        return editor

    @Slot()
    def create(self, attach=None, notebook_id=NONE_ID):
        note_struct = Note(  # maybe replace NONE's to somthing better
            id=NONE_ID,
            title=self.tr('New note'),
            content=self.tr("New note content"),
            tags=dbus.Array([], signature='i'),
            notebook=notebook_id,
            created=NONE_VAL,
            updated=NONE_VAL,
            place='',
        ).struct
        note = Note.from_tuple(self.app.provider.create_note(note_struct), )
        editor = self.open(note)
        if attach:
            editor.resource_edit.add_attach(attach)

    @Slot()
    def show_all_notes(self):
        if not hasattr(self, 'list') or getattr(self.list, 'closed', True):
            self.list = List(self.app)
            self.list.show()
        else:
            self.list.activateWindow()

    @Slot()
    def show_management(self):
        if not hasattr(self, 'management') or getattr(self.management,
                                                      'closed', True):
            self.management = Management(self.app)
            self.management.show()
        else:
            self.management.activateWindow()

    @Slot()
    def exit(self):
        sys.exit(0)
Пример #11
0
 def fill_submenu(window: QtGui.QMainWindow, menu: QtGui.QMenu, method):
     menu.clear()
     for menu_action in method():
         menu_action.create(window, menu)
Пример #12
0
class Indicator(QSystemTrayIcon):
    def __init__(self, app, *args, **kwargs):
        QSystemTrayIcon.__init__(self, *args, **kwargs)
        self.app = app
        self.menu = QMenu()
        self.setContextMenu(self.menu)
        self.menu.aboutToShow.connect(self.update)
        self.opened_notes = {}
        self.activated.connect(self._activated)

    def _activated(self, reason):
        if reason == QSystemTrayIcon.Trigger:
            self.menu.popup(QCursor().pos())

    def _add_note(self, struct):
        note = Note.from_tuple(struct)
        title = note.title[:40].replace('&', '&&')
        self.menu.addAction(title, Slot()(
            partial(self.open, note=note)
        ))

    @Slot()
    def kill_all(self):
        try:
            self.app.provider.kill()
        except dbus.exceptions.DBusException:
            pass
        os.system('everpad --replace')

    @Slot()
    def update(self):
        self.menu.clear()
        try:
            version = self.app.provider.get_api_version()
        except (  # dbus raise some magic
            dbus.exceptions.UnknownMethodException,
            dbus.exceptions.DBusException,
        ):
            version = -1
        if version != API_VERSION:
            action = self.menu.addAction(
                self.tr('API version missmatch, please restart'),
            )
            action.setEnabled(False)
            self.menu.addAction(
                self.tr('Restart everpad'), self.kill_all,
            )
            return
        if get_auth_token():
            pin_notes = self.app.provider.find_notes(
                '', dbus.Array([], signature='i'),
                dbus.Array([], signature='i'), 0,
                20, Note.ORDER_UPDATED_DESC, 1,
            )
            notes = self.app.provider.find_notes(
                '', dbus.Array([], signature='i'),
                dbus.Array([], signature='i'), 0,
                20 - len(pin_notes), Note.ORDER_UPDATED_DESC, 0,
            )
            if len(notes) + len(pin_notes) or self.app.provider.is_first_synced():
                self.menu.addAction(self.tr('All Notes'), self.show_all_notes)
                self.menu.addSeparator()
                if len(pin_notes):
                    for struct in pin_notes:
                        self._add_note(struct)
                    self.menu.addSeparator()
                for struct in notes:
                    self._add_note(struct)
                self.menu.addSeparator()
                self.menu.addAction(self.tr('Create Note'), self.create)
                first_sync = False
            else:
                first_sync = True
            if self.app.provider.get_status() == STATUS_SYNC:
                action = self.menu.addAction(
                    self.tr('Wait, first sync in progress') if first_sync
                    else self.tr('Sync in progress')
                )
                action.setEnabled(False)
            else:
                if first_sync:
                    label = self.tr('Please perform first sync')
                else:
                    label = self.tr('Last sync: %s') % self.app.provider.get_last_sync()
                self.menu.addAction(label, Slot()(self.app.provider.sync))
        self.menu.addAction(self.tr('Settings and Management'), self.show_management)
        self.menu.addSeparator()
        self.menu.addAction(self.tr('Exit'), self.exit)

    def open(self, note, search_term=''):
        old_note_window = self.opened_notes.get(note.id, None)
        if old_note_window and not getattr(old_note_window, 'closed', True):
            editor = self.opened_notes[note.id]
            editor.activateWindow()
        else:
            editor = Editor(self.app, note)
            editor.show()
            self.opened_notes[note.id] = editor
        if search_term:
            editor.findbar.set_search_term(search_term)
            editor.findbar.show()
        return editor

    @Slot()
    def create(self, attach=None, notebook_id=NONE_ID):
        note_struct = Note(  # maybe replace NONE's to somthing better
            id=NONE_ID,
            title=self.tr('New note'),
            content=self.tr("New note content"),
            tags=dbus.Array([], signature='i'),
            notebook=notebook_id,
            created=NONE_VAL,
            updated=NONE_VAL,
            place='',
        ).struct
        note = Note.from_tuple(
            self.app.provider.create_note(note_struct),
        )
        editor = self.open(note)
        if attach:
            editor.resource_edit.add_attach(attach)

    @Slot()
    def show_all_notes(self):
        if not hasattr(self, 'list') or getattr(self.list, 'closed', True):
            self.list = List(self.app)
            self.list.show()
        else:
            self.list.activateWindow()

    @Slot()
    def show_management(self):
        if not hasattr(self, 'management') or getattr(self.management, 'closed', True):
            self.management = Management(self.app)
            self.management.show()
        else:
            self.management.activateWindow()

    @Slot()
    def exit(self):
        sys.exit(0)
class MTTSettingsMenu(QMenu):
    def __init__(self, parent=None):
        super(MTTSettingsMenu, self).__init__(parent)

        self.view = parent
        self.is_master_cmd = False
        # power user state
        self.power_user = MTTSettings.value('powerUser')

        self.__create_actions()
        self.__populate_menu()

    def keyPressEvent(self, event):
        if event.modifiers() == Qt.ControlModifier:
            self.is_master_cmd = True

        super(MTTSettingsMenu, self).keyPressEvent(event)

    def keyReleaseEvent(self, event):
        self.is_master_cmd = False
        super(MTTSettingsMenu, self).keyReleaseEvent(event)

    def __create_actions(self):
        def add_action(lbl, tip, cmd, checkable=False, checked=False):
            a = QAction(lbl, self)
            a.setStatusTip(tip)
            a.triggered.connect(cmd)
            if checkable:
                a.setCheckable(True)
                a.setChecked(checked)

            return a

        self.help_a = add_action('Help', 'Opens the online Help page',
                                 self.on_settings_help)

        self.switch_edit_a = add_action(
            'Switch Edit/Source', 'Replace "Edit" button by "Source" button',
            self.on_switch_source_edit_menu, True,
            MTTSettings.value('switchEdit'))

        self.heads_up_a = add_action('HeadsUp Message',
                                     'Show HeadsUp Message in viewport',
                                     self.on_toggle_headsup, True,
                                     MTTSettings.value('showHeadsUp'))

        self.focus_filter_a = add_action('Focus Filter Field at Startup',
                                         'Focus filter field at startup',
                                         self.on_toggle_focus, True,
                                         MTTSettings.value('filterFocus'))

        self.force_relative_path_a = add_action(
            'Force Relative Path',
            'Set a relative path when selecting a new file',
            self.on_force_relative_path, True,
            MTTSettings.value('forceRelativePath'))

        self.show_real_attr_value_a = add_action(
            'Show Real Attribute Value',
            'Show fullpath instead of filtering path as Attribute Editor',
            self.on_show_real_attribute_value, True,
            MTTSettings.value('showRealAttributeValue'))

        self.manage_quick_filter_a = add_action(
            'Manage Quick Filters',
            'Manage filters that popup with right clic in filter field',
            self.on_filter_manage_quick_filter)

        self.clear_completion_cache_a = add_action(
            'Clear Completion Cache',
            'Erase auto completion cache of filter field',
            self.on_filter_clear_completion_cache)

        self.override_panels_a = add_action(
            'Add CreateNode Button to Editors',
            ('Add "Create Node" to HyperShade and '
             'Node Editor for the current session'), self.on_override_panels)

        self.export_to_csv = add_action(
            'Export Texture List as CSV',
            'Export current textures into a csv file',
            self.view.model.export_as_csv)

        self.about = add_action('About', 'About', self.on_settings_about)

    def __populate_menu(self):
        self.addAction(self.help_a)

        self.addSeparator()

        self.addAction(self._get_menu_header('SETTINGS'))
        self.addAction(self.switch_edit_a)
        self.addAction(self.heads_up_a)
        self.addAction(self.focus_filter_a)
        self.addAction(self.force_relative_path_a)
        self.addAction(self.show_real_attr_value_a)
        self.addMenu(self._create_instance_menu())
        self.addMenu(self._create_theme_menu())

        self.addSeparator()

        self.addAction(self._get_menu_header('FILTER OPTIONS'))
        self.addAction(self.manage_quick_filter_a)
        self.addAction(self.clear_completion_cache_a)

        self.addSeparator()

        self.addAction(self._get_menu_header('MISC'))
        self.addAction(self.override_panels_a)
        self.addAction(self.export_to_csv)

        self.addSeparator()

        self.addAction(self._get_menu_header('DEBUG'))
        self.addMenu(self._create_debug_menu())

        self.addSeparator()

        self.addAction(self.about)

    def _get_menu_header(self, title):
        header = QAction(title, self)
        header.setEnabled(False)
        return header

    def _create_instance_menu(self):
        self.instance_menu = QMenu(self)
        self.instance_menu.setTitle('Prompt Instance Delay')
        self.instance_menu.aboutToShow.connect(
            self.on_show_prompt_instance_delay_menu)

        return self.instance_menu

    def _create_theme_menu(self):
        theme_menu = QMenu(self)
        theme_menu.setTitle('Buttons Theme')
        theme_menu.setTearOffEnabled(True)
        theme_menu.setWindowTitle(TAG)
        theme_actions = QActionGroup(self)
        theme_actions.setExclusive(True)
        # create ordered theme list
        custom_order_theme = sorted(THEMES.iterkeys())
        custom_order_theme.remove('Maya Theme')
        custom_order_theme.insert(0, 'Maya Theme')
        default_item = True
        for theme in custom_order_theme:
            current_theme_action = QAction(theme, theme_actions)
            current_theme_action.setCheckable(True)
            current_theme_action.setChecked(
                MTTSettings.value('theme', 'Maya Theme') == theme)
            current_theme_action.triggered.connect(self.on_change_theme)
            theme_menu.addAction(current_theme_action)

            if default_item:
                theme_menu.addSeparator()
                default_item = False

        return theme_menu

    def _create_debug_menu(self):
        self.debug_menu = QMenu(self)
        self.debug_menu.setTitle('Debug Menu')
        self.debug_menu.aboutToShow.connect(self.on_show_debug_menu)

        return self.debug_menu

    def on_change_theme(self):
        self.view.on_choose_theme(self.sender().text())

    def on_show_debug_menu(self):
        self.debug_menu.clear()

        if self.is_master_cmd or self.power_user:
            power_user_mode = QAction('Power User Mode', self)
            power_user_mode.setCheckable(True)
            power_user_mode.setChecked(MTTSettings.value('powerUser'))
            power_user_mode.triggered.connect(self.__on_toggle_power_user)
            self.debug_menu.addAction(power_user_mode)
            self.is_master_cmd = False

            self.debug_menu.addSeparator()

        open_pref_folder_action = QAction('Open Preferences Folder', self)
        open_pref_folder_action.setStatusTip('Open MTT preference folder')
        open_pref_folder_action.triggered.connect(
            self.on_open_preference_folder)
        self.debug_menu.addAction(open_pref_folder_action)

        self.debug_menu.addSeparator()

        database_dump_csv = QAction('Dump Database as CSV', self)
        database_dump_csv.triggered.connect(self.view.model.database_dump_csv)
        self.debug_menu.addAction(database_dump_csv)

        database_dump_sql = QAction('Dump Database as SQL', self)
        database_dump_sql.triggered.connect(self.view.model.database_dump_sql)
        self.debug_menu.addAction(database_dump_sql)

        self.debug_menu.addSeparator()

        support_info = QMenu(self)
        support_info.setTitle('Supported Node Type')
        support_info.aboutToShow.connect(self.on_show_supported_type)
        self.debug_menu.addMenu(support_info)

    def on_filter_clear_completion_cache(self):
        """ Clear filter auto completion cache """
        self.view.on_filter_set_text('')
        MTTSettings.remove('filterCompletionWildcard')
        MTTSettings.remove('filterCompletionRegExp')
        self.view.completion_model.setStringList([])

    def on_switch_source_edit_menu(self):
        state = MTTSettings.value('switchEdit')
        MTTSettings.set_value('switchEdit', not state)
        self.view.on_set_source_edit_menu(not state)

    def on_show_real_attribute_value(self):
        self.view.model.layoutAboutToBeChanged.emit()
        show_real_attribute_state = MTTSettings.value('showRealAttributeValue')
        MTTSettings.set_value('showRealAttributeValue',
                              not show_real_attribute_state)
        self.view._layout_changed()

    def on_filter_manage_quick_filter(self):
        """ Open Quick Filter words manager and save its content """
        manager = MTTQuickFilterManager(self)
        if manager.exec_():
            lists = manager.get_lists()
            # save list in settings
            MTTSettings.set_value('filterQuickWordsWildcard',
                                  ';;'.join(lists[0]))
            MTTSettings.set_value('filterQuickWordsRegExp',
                                  ';;'.join(lists[1]))
            # set current list
            self.view.quick_filter_words = lists[MTTSettings.value('filterRE')]
        manager.deleteLater()

    @staticmethod
    def on_toggle_headsup():
        state = MTTSettings.value('showHeadsUp')
        MTTSettings.set_value('showHeadsUp', not state)

    @staticmethod
    def on_toggle_focus():
        state = MTTSettings.value('filterFocus')
        MTTSettings.set_value('filterFocus', not state)

    @staticmethod
    def on_force_relative_path():
        state = MTTSettings.value('forceRelativePath')
        MTTSettings.set_value('forceRelativePath', not state)

    def on_show_supported_type(self):
        node_types = sorted(
            [n_type for (n_type, nice, attr) in MTTSettings.SUPPORTED_TYPE] +
            MTTSettings.UNSUPPORTED_TYPE)
        support_info = self.sender()
        support_info.clear()

        for node_type in node_types:
            current = QAction(node_type, self)
            current.setEnabled(False)
            current.setCheckable(True)
            current.setChecked(node_type not in MTTSettings.UNSUPPORTED_TYPE)
            support_info.addAction(current)

    def __on_toggle_power_user(self):
        state = MTTSettings.value('powerUser')
        MTTSettings.set_value('powerUser', not state)
        self.power_user = not state

    @staticmethod
    def on_open_preference_folder():
        """ Open preference folder """
        folder_path = os.path.dirname(MTTSettings.filename())
        cmds.launchImageEditor(viewImageFile=folder_path)

    @staticmethod
    def on_override_panels():
        """ Override HyperShade and NodeEditor creation callback"""
        override_info_box = QMessageBox()
        override_info_box.setWindowTitle(WINDOW_TITLE)
        override_info_box.setIcon(QMessageBox.Information)
        override_info_box.setText(
            'Buttons will be added to HyperShade toolbar and Node Editor toolbar.<br/>'
            'Changes will exists during this session.')
        override_info_box.setInformativeText(
            '<i>Read Help to set this settings permanent</i>')
        override_info_box.setStandardButtons(QMessageBox.Ok)
        override_info_box.setDefaultButton(QMessageBox.Ok)
        override_info_box.exec_()

        mttOverridePanels.override_panels()

    def on_settings_about(self):

        special_list = map(
            lambda x: x.replace(' ', '&nbsp;'),
            sorted([
                u'Beno\xeet Stordeur', u'Fran\xe7ois Jumel', 'Jonathan Lorber',
                'Norbert Cretinon', 'Gilles Hoff'
            ]))
        QMessageBox.about(
            self.parent(), WINDOW_TITLE, '<b>Maya Texture Toolkit v{:.02f}</b>'
            u'<p>{} - \xa9 2014 - 2016'
            '</p>'
            '<p>Special thanks to :<br/>'
            '<i>{}</i>'
            '</p>'.format(__version__, __author__, ', '.join(special_list)))

    @staticmethod
    def on_settings_help():
        help_wiki = 'https://github.com/Bioeden/dbMayaTextureToolkit/wiki'
        webbrowser.open(help_wiki)

    def on_show_prompt_instance_delay_menu(self):
        prompt_instance_state = cmds.optionVar(
            query='MTT_prompt_instance_state')

        if prompt_instance_state == PROMPT_INSTANCE_WAIT:
            elapsed_time = time() - cmds.optionVar(
                query='MTT_prompt_instance_suspend')
            if elapsed_time > PROMPT_INSTANCE_WAIT_DURATION:
                prompt_instance_state = PROMPT_INSTANCE_ASK
                cmds.optionVar(
                    iv=['MTT_prompt_instance_state', prompt_instance_state])
            else:
                mtt_log('Remaining %.2fs' %
                        (PROMPT_INSTANCE_WAIT_DURATION - elapsed_time))
        elif prompt_instance_state == PROMPT_INSTANCE_SESSION:
            if 'mtt_prompt_session' not in __main__.__dict__:
                prompt_instance_state = PROMPT_INSTANCE_ASK
                cmds.optionVar(
                    iv=['MTT_prompt_instance_state', prompt_instance_state])

        self.instance_menu.clear()

        prompt_delay = QActionGroup(self)
        prompt_delay.setExclusive(True)
        for i in range(len(PROMPT_INSTANCE_STATE.keys())):
            current_delay_action = QAction(PROMPT_INSTANCE_STATE[i],
                                           prompt_delay)
            current_delay_action.setCheckable(True)
            current_delay_action.setChecked(prompt_instance_state == i)
            current_delay_action.triggered.connect(
                partial(self.view.on_choose_instance_delay, i, prompt=i != 0))
            self.instance_menu.addAction(current_delay_action)
Пример #14
0
    def notifyOntologyAdded(self, ontology):
        """
        Notify that an ontology was added to the index.
        
        Parameter :
        
        - ontology : The added ontology.
        """
        if ontology is None:
            return
        self.addRecentOntology(ontology)
        i = len(self.menuOntology.actions()) - 3
        ontologyMenu = None
        for x in range(i, len(self.menuOntology.actions())):
            a = self.menuOntology.actions()[x]
            if a.text() == ontology.name:
                # Don't need to add menu.
                ontologyMenu = a.menu()
                break

        if ontologyMenu is None:
            ontologyMenu = QMenu(self)
            ontologyMenu.setTitle(ontology.name)
        ontologyMenu.clear()
        # Update action
        icon = QIcon()
        icon.addPixmap(QPixmap(":/actions/gfx/actions/update-product.png"),
                       QIcon.Normal, QIcon.Off)
        actionUpdate = ontologyMenu.addAction("Update")
        actionUpdate.setData(ontology)
        actionUpdate.setIcon(icon)
        actionUpdate.setIconVisibleInMenu(True)
        actionUpdate.triggered.connect(partial(self._updateOntology_,
                                               ontology))
        icon = QIcon()
        icon.addPixmap(QPixmap(":/actions/gfx/actions/document-revert.png"),
                       QIcon.Normal, QIcon.Off)
        actionRevert = ontologyMenu.addAction("Revert")
        actionRevert.setData(ontology)
        actionRevert.setIcon(icon)
        actionRevert.setIconVisibleInMenu(True)
        actionRevert.triggered.connect(
            partial(self._revertOntology_, ontology, ontologyMenu))
        icon = QIcon()
        icon.addPixmap(
            QPixmap(":/actions/gfx/actions/document-properties.png"),
            QIcon.Normal, QIcon.Off)
        actionProperties = ontologyMenu.addAction("Properties")
        actionProperties.setData(ontology)
        actionProperties.setIconVisibleInMenu(True)
        actionProperties.setIcon(icon)
        actionProperties.triggered.connect(
            partial(self._showOntologyProperties_, ontology))
        ontologyMenu.addSeparator()
        # Close action
        icon = QIcon()
        icon.addPixmap(QPixmap(":/actions/gfx/actions/document-close.png"),
                       QIcon.Normal, QIcon.Off)
        actionClose = ontologyMenu.addAction("Close")
        actionClose.setIcon(icon)
        actionClose.setIconVisibleInMenu(True)
        actionClose.setData(ontology)
        actionClose.triggered.connect(
            partial(self._closeOntology_, ontology, ontologyMenu))
        ontologyMenu.addSeparator()
        # Add ontology menu to menu bar
        self.menuOntology.addMenu(ontologyMenu)
Пример #15
0
class LogFilter(QFrame):
    def __init__(self, parent=None):
        super(LogFilter, self).__init__(parent=parent)
        setup_ui(self)
        self.filter_model = FilterModel(parent=self)
        self._viewer = None
        self.revs_menu = QMenu(parent=self)
        self.revs_separator = None
        self.rev_actions = QActionGroup(self)
        self.rev_actions.addAction(self.action_all_refs)
        self.select_revs_button.setMenu(self.revs_menu)
        self.action_all_refs.revs = None
        self.action_all_refs.triggered.connect(self.show_all_refs)
        self.action_select_branches.triggered.connect(self.pick_branches)
        self.filter_text.textEdited.connect(self.filter_text_edited)

    @property
    def source_model(self):
        return self.filter_model.sourceModel()

    @source_model.setter
    def source_model(self, model):
        self.filter_model.setSourceModel(model)
        self.revs_menu.clear()
        for action in self.rev_actions.actions():
            if action is not self.action_all_refs:
                self.rev_actions.removeAction(action)
        self.revs_menu.addAction(self.action_all_refs)
        if not model.repo.head_ref:
            self.revs_menu.addAction(self.create_rev_action(model.repo, 'HEAD'))
        for branch in model.repo.branches:
            self.revs_menu.addAction(self.create_rev_action(model.repo, branch))
        if model.all:
            self._select_action(self.action_all_refs)
        else:
            selected_revs = model.revs
            if not selected_revs:
                if model.repo.head_ref:
                    selected_revs = (model.repo.head_ref,)
                else:
                    selected_revs = ('HEAD',)
            action = self._find_rev_action(selected_revs)
            if not action:
                action = self.create_rev_action(model.repo, model.revs)
                self.revs_menu.addAction(action)
            self._select_action(action)
        self.revs_separator = self.revs_menu.addSeparator()
        self.revs_menu.addAction(self.action_select_branches)

    @property
    def viewer(self):
        return self._viewer

    @viewer.setter
    def viewer(self, new_viewer):
        self._viewer = new_viewer
        self._viewer.setModel(self.filter_model)

    def create_rev_action(self, repo, *revs):
        action = QAction(self.revs_menu)
        action.revs = revs
        action.setText(', '.join(str(rev) for rev in revs))
        action.setCheckable(True)
        action.setActionGroup(self.rev_actions)
        action.triggered.connect(self._revs_action_triggered)
        return action

    def show_all_refs(self):
        self._select_action(self.action_all_refs)
        with busy_cursor():
            self.source_model.revs = ()
            self.source_model.all = True
            self.source_model.refresh()

    def pick_branches(self):
        dialog = PickBranchesDialog(repo=self.source_model.repo, parent=self)
        if dialog.exec_() == dialog.Accepted:
            self.show_revs(*dialog.selected_branches)

    def _select_action(self, action):
        action.setChecked(True)
        self.select_revs_button.setText(action.text())

    def _revs_action_triggered(self):
        self._select_action(self.sender())
        with busy_cursor():
            self.source_model.revs = self.sender().revs
            self.source_model.all = False
            self.source_model.refresh()

    def _find_rev_action(self, revs):
        return next((action for action in self.rev_actions.actions()
            if action.revs == revs), None)

    def show_revs(self, *revs):
        action = self._find_rev_action(revs)
        if not action:
            action = self.create_rev_action(self.source_model.repo, *revs)
            self.revs_menu.insertAction(self.revs_separator, action)
        self._select_action(action)
        with busy_cursor():
            self.source_model.revs = revs
            self.source_model.all = False
            self.source_model.refresh()

    def filter_text_edited(self, text):
        if text:
            self.viewer.hideColumn(0)
            self.filter_model.filters += self.filter_graph_row
        else:
            self.filter_model.filters -= self.filter_graph_row
            self.viewer.showColumn(0)

    def filter_graph_row(self, graph_row):
        return commit_matches_text(graph_row.log_entry, self.filter_text.text())