Пример #1
0
    def __init__(self, parent, worker, config, configfile):
        QDialog.__init__(self, parent)

        self.worker = worker
        self.config = config
        self.configfile = configfile
        self.setStyleSheet("QGroupBox { font-weight: bold; } ")
        self.setWindowTitle('Settings')
        layout = QGridLayout()

        # Categories
        self.category_list = QListWidget()
        category_media = QListWidgetItem(getIcon('media-playback-start'), 'Media', self.category_list)
        category_sync = QListWidgetItem(getIcon('view-refresh'), 'Sync', self.category_list)
        category_ui = QListWidgetItem(getIcon('window-new'), 'User Interface', self.category_list)
        category_theme = QListWidgetItem(getIcon('applications-graphics'), 'Theme', self.category_list)
        self.category_list.setSelectionMode(QAbstractItemView.SingleSelection)
        self.category_list.setCurrentRow(0)
        self.category_list.setMaximumWidth(self.category_list.sizeHintForColumn(0) + 15)
        self.category_list.setFocus()
        self.category_list.currentItemChanged.connect(self.s_switch_page)

        # Media tab
        page_media = QWidget()
        page_media_layout = QVBoxLayout()
        page_media_layout.setAlignment(QtCore.Qt.AlignTop)

        # Group: Media settings
        g_media = QGroupBox('Media settings')
        g_media.setFlat(True)
        g_media_layout = QFormLayout()
        self.tracker_enabled = QCheckBox()
        self.tracker_enabled.toggled.connect(self.tracker_type_change)

        self.tracker_type = QComboBox()
        for (n, label) in utils.available_trackers:
            self.tracker_type.addItem(label, n)
        self.tracker_type.currentIndexChanged.connect(self.tracker_type_change)

        self.tracker_interval = QSpinBox()
        self.tracker_interval.setRange(5, 1000)
        self.tracker_interval.setMaximumWidth(60)
        self.tracker_process = QLineEdit()
        self.tracker_update_wait = QSpinBox()
        self.tracker_update_wait.setRange(0, 1000)
        self.tracker_update_wait.setMaximumWidth(60)
        self.tracker_update_close = QCheckBox()
        self.tracker_update_prompt = QCheckBox()
        self.tracker_not_found_prompt = QCheckBox()

        g_media_layout.addRow('Enable tracker', self.tracker_enabled)
        g_media_layout.addRow('Tracker type', self.tracker_type)
        g_media_layout.addRow('Tracker interval (seconds)', self.tracker_interval)
        g_media_layout.addRow('Process name (regex)', self.tracker_process)
        g_media_layout.addRow('Wait before updating (seconds)', self.tracker_update_wait)
        g_media_layout.addRow('Wait until the player is closed', self.tracker_update_close)
        g_media_layout.addRow('Ask before updating', self.tracker_update_prompt)
        g_media_layout.addRow('Ask to add new shows', self.tracker_not_found_prompt)

        g_media.setLayout(g_media_layout)

        # Group: Plex settings
        g_plex = QGroupBox('Plex Media Server')
        g_plex.setFlat(True)
        self.plex_host = QLineEdit()
        self.plex_port = QLineEdit()
        self.plex_user = QLineEdit()
        self.plex_passw = QLineEdit()
        self.plex_passw.setEchoMode(QLineEdit.Password)
        self.plex_obey_wait = QCheckBox()

        g_plex_layout = QGridLayout()
        g_plex_layout.addWidget(QLabel('Host and Port'),                   0, 0, 1, 1)
        g_plex_layout.addWidget(self.plex_host,                            0, 1, 1, 1)
        g_plex_layout.addWidget(self.plex_port,                            0, 2, 1, 2)
        g_plex_layout.addWidget(QLabel('Use "wait before updating" time'), 1, 0, 1, 1)
        g_plex_layout.addWidget(self.plex_obey_wait,                       1, 2, 1, 1)
        g_plex_layout.addWidget(QLabel('myPlex login (claimed server)'),   2, 0, 1, 1)
        g_plex_layout.addWidget(self.plex_user,                            2, 1, 1, 1)
        g_plex_layout.addWidget(self.plex_passw,                           2, 2, 1, 2)

        g_plex.setLayout(g_plex_layout)

        # Group: Library
        g_playnext = QGroupBox('Library')
        g_playnext.setFlat(True)
        self.player = QLineEdit()
        self.player_browse = QPushButton('Browse...')
        self.player_browse.clicked.connect(self.s_player_browse)
        lbl_searchdirs = QLabel('Media directories')
        lbl_searchdirs.setAlignment(QtCore.Qt.AlignTop)
        self.searchdirs = QListWidget()
        self.searchdirs_add = QPushButton('Add...')
        self.searchdirs_add.clicked.connect(self.s_searchdirs_add)
        self.searchdirs_remove = QPushButton('Remove')
        self.searchdirs_remove.clicked.connect(self.s_searchdirs_remove)
        self.searchdirs_buttons = QVBoxLayout()
        self.searchdirs_buttons.setAlignment(QtCore.Qt.AlignTop)
        self.searchdirs_buttons.addWidget(self.searchdirs_add)
        self.searchdirs_buttons.addWidget(self.searchdirs_remove)
        self.searchdirs_buttons.addWidget(QSplitter())
        self.library_autoscan = QCheckBox()
        self.scan_whole_list = QCheckBox()
        self.library_full_path = QCheckBox()


        g_playnext_layout = QGridLayout()
        g_playnext_layout.addWidget(QLabel('Player'),                    0, 0, 1, 1)
        g_playnext_layout.addWidget(self.player,                         0, 1, 1, 1)
        g_playnext_layout.addWidget(self.player_browse,                  0, 2, 1, 1)
        g_playnext_layout.addWidget(lbl_searchdirs,                      1, 0, 1, 1)
        g_playnext_layout.addWidget(self.searchdirs,                     1, 1, 1, 1)
        g_playnext_layout.addLayout(self.searchdirs_buttons,             1, 2, 1, 1)
        g_playnext_layout.addWidget(QLabel('Rescan Library at startup'), 2, 0, 1, 2)
        g_playnext_layout.addWidget(self.library_autoscan,               2, 2, 1, 1)
        g_playnext_layout.addWidget(QLabel('Scan through whole list'),   3, 0, 1, 2)
        g_playnext_layout.addWidget(self.scan_whole_list,                3, 2, 1, 1)
        g_playnext_layout.addWidget(QLabel('Take subdirectory name into account'), 4, 0, 1, 2)
        g_playnext_layout.addWidget(self.library_full_path,              4, 2, 1, 1)

        g_playnext.setLayout(g_playnext_layout)

        # Media form
        page_media_layout.addWidget(g_media)
        page_media_layout.addWidget(g_plex)
        page_media_layout.addWidget(g_playnext)
        page_media.setLayout(page_media_layout)

        # Sync tab
        page_sync = QWidget()
        page_sync_layout = QVBoxLayout()
        page_sync_layout.setAlignment(QtCore.Qt.AlignTop)

        # Group: Autoretrieve
        g_autoretrieve = QGroupBox('Autoretrieve')
        g_autoretrieve.setFlat(True)
        self.autoretrieve_off = QRadioButton('Disabled')
        self.autoretrieve_always = QRadioButton('Always at start')
        self.autoretrieve_days = QRadioButton('After n days')
        self.autoretrieve_days.toggled.connect(self.s_autoretrieve_days)
        self.autoretrieve_days_n = QSpinBox()
        self.autoretrieve_days_n.setRange(1, 100)
        g_autoretrieve_layout = QGridLayout()
        g_autoretrieve_layout.setColumnStretch(0, 1)
        g_autoretrieve_layout.addWidget(self.autoretrieve_off,    0, 0, 1, 1)
        g_autoretrieve_layout.addWidget(self.autoretrieve_always, 1, 0, 1, 1)
        g_autoretrieve_layout.addWidget(self.autoretrieve_days,   2, 0, 1, 1)
        g_autoretrieve_layout.addWidget(self.autoretrieve_days_n, 2, 1, 1, 1)
        g_autoretrieve.setLayout(g_autoretrieve_layout)

        # Group: Autosend
        g_autosend = QGroupBox('Autosend')
        g_autosend.setFlat(True)
        self.autosend_off = QRadioButton('Disabled')
        self.autosend_always = QRadioButton('Immediately after every change')
        self.autosend_minutes = QRadioButton('After n minutes')
        self.autosend_minutes.toggled.connect(self.s_autosend_minutes)
        self.autosend_minutes_n = QSpinBox()
        self.autosend_minutes_n.setRange(1, 1000)
        self.autosend_size = QRadioButton('After the queue reaches n items')
        self.autosend_size.toggled.connect(self.s_autosend_size)
        self.autosend_size_n = QSpinBox()
        self.autosend_size_n.setRange(2, 20)
        self.autosend_at_exit = QCheckBox('At exit')
        g_autosend_layout = QGridLayout()
        g_autosend_layout.setColumnStretch(0, 1)
        g_autosend_layout.addWidget(self.autosend_off,      0, 0, 1, 1)
        g_autosend_layout.addWidget(self.autosend_always,   1, 0, 1, 1)
        g_autosend_layout.addWidget(self.autosend_minutes,    2, 0, 1, 1)
        g_autosend_layout.addWidget(self.autosend_minutes_n,  2, 1, 1, 1)
        g_autosend_layout.addWidget(self.autosend_size,     3, 0, 1, 1)
        g_autosend_layout.addWidget(self.autosend_size_n,   3, 1, 1, 1)
        g_autosend_layout.addWidget(self.autosend_at_exit,  4, 0, 1, 1)
        g_autosend.setLayout(g_autosend_layout)

        # Group: Extra
        g_extra = QGroupBox('Additional options')
        g_extra.setFlat(True)
        self.auto_status_change = QCheckBox('Change status automatically')
        self.auto_status_change.toggled.connect(self.s_auto_status_change)
        self.auto_status_change_if_scored = QCheckBox('Change status automatically only if scored')
        self.auto_date_change = QCheckBox('Change start and finish dates automatically')
        g_extra_layout = QVBoxLayout()
        g_extra_layout.addWidget(self.auto_status_change)
        g_extra_layout.addWidget(self.auto_status_change_if_scored)
        g_extra_layout.addWidget(self.auto_date_change)
        g_extra.setLayout(g_extra_layout)

        # Sync layout
        page_sync_layout.addWidget(g_autoretrieve)
        page_sync_layout.addWidget(g_autosend)
        page_sync_layout.addWidget(g_extra)
        page_sync.setLayout(page_sync_layout)

        # UI tab
        page_ui = QWidget()
        page_ui_layout = QFormLayout()
        page_ui_layout.setAlignment(QtCore.Qt.AlignTop)

        # Group: Icon
        g_icon = QGroupBox('Notification Icon')
        g_icon.setFlat(True)
        self.tray_icon = QCheckBox('Show tray icon')
        self.tray_icon.toggled.connect(self.s_tray_icon)
        self.close_to_tray = QCheckBox('Close to tray')
        self.start_in_tray = QCheckBox('Start minimized to tray')
        self.tray_api_icon = QCheckBox('Use API icon as tray icon')
        self.notifications = QCheckBox('Show notification when tracker detects new media')
        g_icon_layout = QVBoxLayout()
        g_icon_layout.addWidget(self.tray_icon)
        g_icon_layout.addWidget(self.close_to_tray)
        g_icon_layout.addWidget(self.start_in_tray)
        g_icon_layout.addWidget(self.tray_api_icon)
        g_icon_layout.addWidget(self.notifications)
        g_icon.setLayout(g_icon_layout)

        # Group: Window
        g_window = QGroupBox('Window')
        g_window.setFlat(True)
        self.remember_geometry = QCheckBox('Remember window size and position')
        self.remember_columns = QCheckBox('Remember column layouts and widths')
        self.columns_per_api = QCheckBox('Use different visible columns per API')
        g_window_layout = QVBoxLayout()
        g_window_layout.addWidget(self.remember_geometry)
        g_window_layout.addWidget(self.remember_columns)
        g_window_layout.addWidget(self.columns_per_api)
        g_window.setLayout(g_window_layout)

        # Group: Lists
        g_lists = QGroupBox('Lists')
        g_lists.setFlat(True)
        self.filter_bar_position = QComboBox()
        filter_bar_positions = [(FilterBar.PositionHidden,     'Hidden'),
                                (FilterBar.PositionAboveLists, 'Above lists'),
                                (FilterBar.PositionBelowLists, 'Below lists')]
        for (n, label) in filter_bar_positions:
            self.filter_bar_position.addItem(label, n)
        self.inline_edit = QCheckBox('Enable in-line editing')
        g_lists_layout = QFormLayout()
        g_lists_layout.addRow('Filter bar position:', self.filter_bar_position)
        g_lists_layout.addRow(self.inline_edit)
        g_lists.setLayout(g_lists_layout)

        # UI layout
        page_ui_layout.addWidget(g_icon)
        page_ui_layout.addWidget(g_window)
        page_ui_layout.addWidget(g_lists)
        page_ui.setLayout(page_ui_layout)

        # Theming tab
        page_theme = QWidget()
        page_theme_layout = QFormLayout()
        page_theme_layout.setAlignment(QtCore.Qt.AlignTop)

        # Group: Episode Bar
        g_ep_bar = QGroupBox('Episode Bar')
        g_ep_bar.setFlat(True)
        self.ep_bar_style = QComboBox()
        ep_bar_styles = [(ShowsTableDelegate.BarStyleBasic,  'Basic'),
                         (ShowsTableDelegate.BarStyle04,     'Trackma'),
                         (ShowsTableDelegate.BarStyleHybrid, 'Hybrid')]
        for (n, label) in ep_bar_styles:
            self.ep_bar_style.addItem(label, n)
        self.ep_bar_style.currentIndexChanged.connect(self.s_ep_bar_style)
        self.ep_bar_text = QCheckBox('Show text label')
        g_ep_bar_layout = QFormLayout()
        g_ep_bar_layout.addRow('Style:', self.ep_bar_style)
        g_ep_bar_layout.addRow(self.ep_bar_text)
        g_ep_bar.setLayout(g_ep_bar_layout)

        # Group: Colour scheme
        g_scheme = QGroupBox('Color Scheme')
        g_scheme.setFlat(True)
        col_tabs = [('rows',     '&Row highlights'),
                    ('progress', '&Progress widget')]
        self.colors = {}
        self.colors['rows'] = [('is_playing',  'Playing'),
                               ('is_queued',   'Queued'),
                               ('new_episode', 'New Episode'),
                               ('is_airing',   'Airing'),
                               ('not_aired',   'Unaired')]
        self.colors['progress'] = [('progress_bg',       'Background'),
                                   ('progress_fg',       'Watched bar'),
                                   ('progress_sub_bg',   'Aired episodes'),
                                   ('progress_sub_fg',   'Stored episodes'),
                                   ('progress_complete', 'Complete')]
        self.color_buttons = []
        self.syscolor_buttons = []
        g_scheme_layout = QGridLayout()
        tw_scheme = QTabWidget()
        for (key, tab_title) in col_tabs:
            page = QFrame()
            page_layout = QGridLayout()
            col = 0
            # Generate widgets from the keys and values
            for (key, label) in self.colors[key]:
                self.color_buttons.append(QPushButton())
                # self.color_buttons[-1].setStyleSheet('background-color: ' + getColor(self.config['colors'][key]).name())
                self.color_buttons[-1].setFocusPolicy(QtCore.Qt.NoFocus)
                self.color_buttons[-1].clicked.connect(self.s_color_picker(key, False))
                self.syscolor_buttons.append(QPushButton('System Colors'))
                self.syscolor_buttons[-1].clicked.connect(self.s_color_picker(key, True))
                page_layout.addWidget(QLabel(label),             col, 0, 1, 1)
                page_layout.addWidget(self.color_buttons[-1],    col, 1, 1, 1)
                page_layout.addWidget(self.syscolor_buttons[-1], col, 2, 1, 1)
                col += 1
            page.setLayout(page_layout)
            tw_scheme.addTab(page, tab_title)
        g_scheme_layout.addWidget(tw_scheme)
        g_scheme.setLayout(g_scheme_layout)

        # UI layout
        page_theme_layout.addWidget(g_ep_bar)
        page_theme_layout.addWidget(g_scheme)
        page_theme.setLayout(page_theme_layout)

        # Content
        self.contents = QStackedWidget()
        self.contents.addWidget(page_media)
        self.contents.addWidget(page_sync)
        self.contents.addWidget(page_ui)
        self.contents.addWidget(page_theme)
        if pyqt_version is not 5:
            self.contents.layout().setMargin(0)

        # Bottom buttons
        bottombox = QDialogButtonBox(
            QDialogButtonBox.Ok
            | QDialogButtonBox.Apply
            | QDialogButtonBox.Cancel
        )
        bottombox.accepted.connect(self.s_save)
        bottombox.button(QDialogButtonBox.Apply).clicked.connect(self._save)
        bottombox.rejected.connect(self.reject)

        # Main layout finish
        layout.addWidget(self.category_list,  0, 0, 1, 1)
        layout.addWidget(self.contents,       0, 1, 1, 1)
        layout.addWidget(bottombox,           1, 0, 1, 2)
        layout.setColumnStretch(1, 1)

        self._load()
        self.update_colors()

        self.setLayout(layout)
Пример #2
0
    def data(self, index, role):
        row, column = index.row(), index.column()
        show = self.showlist[row]

        if role == QtCore.Qt.DisplayRole:
            if column == ShowListModel.COL_ID:
                return show['id']
            elif column == ShowListModel.COL_TITLE:
                title_str = show['title']
                if show['id'] in self.altnames:
                    title_str += " [%s]" % self.altnames[show['id']]
                return title_str
            elif column == ShowListModel.COL_MY_PROGRESS:
                return "{} / {}".format(show['my_progress'], show['total']
                                        or '?')
            elif column == ShowListModel.COL_MY_SCORE:
                return show['my_score']
            elif column == ShowListModel.COL_PERCENT:
                #return "{:.0%}".format(show['my_progress'] / 100)
                if show['total']:
                    total = show['total']
                else:
                    total = (int(show['my_progress'] / 12) +
                             1) * 12  # Round up to the next cour

                if row in self.eps:
                    return (show['my_progress'], total, self.eps[row][0],
                            self.eps[row][1])
                else:
                    return (show['my_progress'], total, None, None)
            elif column == ShowListModel.COL_NEXT_EP:
                return self.next_ep.get(row, '-')
            elif column == ShowListModel.COL_START_DATE:
                return self._date(show['start_date'])
            elif column == ShowListModel.COL_END_DATE:
                return self._date(show['end_date'])
            elif column == ShowListModel.COL_MY_START:
                return self._date(show['my_start_date'])
            elif column == ShowListModel.COL_MY_FINISH:
                return self._date(show['my_finish_date'])
            elif column == ShowListModel.COL_MY_TAGS:
                return show.get('my_tags', '-')
            elif column == ShowListModel.COL_MY_STATUS:
                return self.mediainfo['statuses_dict'][show['my_status']]
        elif role == QtCore.Qt.BackgroundRole:
            return self.colors.get(row)
        elif role == QtCore.Qt.DecorationRole:
            if column == ShowListModel.COL_TITLE and show['id'] in self.playing:
                return getIcon('media-playback-start')
        elif role == QtCore.Qt.TextAlignmentRole:
            if column in [
                    ShowListModel.COL_MY_PROGRESS, ShowListModel.COL_MY_SCORE
            ]:
                return QtCore.Qt.AlignHCenter
        elif role == QtCore.Qt.ToolTipRole:
            if column == ShowListModel.COL_PERCENT:
                tooltip = "Watched: %d<br>" % show['my_progress']
                if self.eps.get(row):
                    (aired_eps, library_eps) = self.eps.get(row)
                    if aired_eps:
                        tooltip += "Aired (estimated): %d<br>" % aired_eps
                    if library_eps:
                        tooltip += "Latest available: %d<br>" % max(
                            library_eps)
                tooltip += "Total: %d" % show['total']

                return tooltip
        elif role == QtCore.Qt.EditRole:
            if column == ShowListModel.COL_MY_PROGRESS:
                return (show['my_progress'], show['total'], 0, 1)
            elif column == ShowListModel.COL_MY_SCORE:
                if isinstance(self.mediainfo['score_step'], float):
                    decimals = len(
                        str(self.mediainfo['score_step']).split('.')[1])
                else:
                    decimals = 0

                return (show['my_score'], self.mediainfo['score_max'],
                        decimals, self.mediainfo['score_step'])
Пример #3
0
    def __init__(self, parent, worker, config, configfile):
        QDialog.__init__(self, parent)

        self.worker = worker
        self.config = config
        self.configfile = configfile
        self.setStyleSheet("QGroupBox { font-weight: bold; } ")
        self.setWindowTitle('Settings')
        layout = QGridLayout()

        # Categories
        self.category_list = QListWidget()
        category_media = QListWidgetItem(getIcon('media-playback-start'),
                                         'Media', self.category_list)
        category_sync = QListWidgetItem(getIcon('view-refresh'), 'Sync',
                                        self.category_list)
        category_ui = QListWidgetItem(getIcon('window-new'), 'User Interface',
                                      self.category_list)
        category_theme = QListWidgetItem(getIcon('applications-graphics'),
                                         'Theme', self.category_list)
        self.category_list.setSelectionMode(QAbstractItemView.SingleSelection)
        self.category_list.setCurrentRow(0)
        self.category_list.setMaximumWidth(
            self.category_list.sizeHintForColumn(0) + 15)
        self.category_list.setFocus()
        self.category_list.currentItemChanged.connect(self.s_switch_page)

        # Media tab
        page_media = QWidget()
        page_media_layout = QVBoxLayout()
        page_media_layout.setAlignment(QtCore.Qt.AlignTop)

        # Group: Media settings
        g_media = QGroupBox('Media settings')
        g_media.setFlat(True)
        g_media_layout = QFormLayout()
        self.tracker_enabled = QCheckBox()
        self.tracker_enabled.toggled.connect(self.tracker_type_change)

        self.tracker_type = QComboBox()
        for (n, label) in utils.available_trackers:
            self.tracker_type.addItem(label, n)
        self.tracker_type.currentIndexChanged.connect(self.tracker_type_change)

        self.tracker_interval = QSpinBox()
        self.tracker_interval.setRange(5, 1000)
        self.tracker_interval.setMaximumWidth(60)
        self.tracker_process = QLineEdit()
        self.tracker_update_wait = QSpinBox()
        self.tracker_update_wait.setRange(0, 1000)
        self.tracker_update_wait.setMaximumWidth(60)
        self.tracker_update_close = QCheckBox()
        self.tracker_update_prompt = QCheckBox()
        self.tracker_not_found_prompt = QCheckBox()
        self.tracker_ignore_not_next = QCheckBox()

        g_media_layout.addRow('Enable tracker', self.tracker_enabled)
        g_media_layout.addRow('Tracker type', self.tracker_type)
        g_media_layout.addRow('Tracker interval (seconds)',
                              self.tracker_interval)
        g_media_layout.addRow('Process name (regex)', self.tracker_process)
        g_media_layout.addRow('Wait before updating (seconds)',
                              self.tracker_update_wait)
        g_media_layout.addRow('Wait until the player is closed',
                              self.tracker_update_close)
        g_media_layout.addRow('Ask before updating',
                              self.tracker_update_prompt)
        g_media_layout.addRow('Ask to add new shows',
                              self.tracker_not_found_prompt)
        g_media_layout.addRow('Ignore if not next episode',
                              self.tracker_ignore_not_next)

        g_media.setLayout(g_media_layout)

        # Group: Plex settings
        g_plex = QGroupBox('Plex Media Server')
        g_plex.setFlat(True)
        self.plex_host = QLineEdit()
        self.plex_port = QLineEdit()
        self.plex_user = QLineEdit()
        self.plex_passw = QLineEdit()
        self.plex_passw.setEchoMode(QLineEdit.Password)
        self.plex_obey_wait = QCheckBox()

        g_plex_layout = QGridLayout()
        g_plex_layout.addWidget(QLabel('Host and Port'), 0, 0, 1, 1)
        g_plex_layout.addWidget(self.plex_host, 0, 1, 1, 1)
        g_plex_layout.addWidget(self.plex_port, 0, 2, 1, 2)
        g_plex_layout.addWidget(QLabel('Use "wait before updating" time'), 1,
                                0, 1, 1)
        g_plex_layout.addWidget(self.plex_obey_wait, 1, 2, 1, 1)
        g_plex_layout.addWidget(QLabel('myPlex login (claimed server)'), 2, 0,
                                1, 1)
        g_plex_layout.addWidget(self.plex_user, 2, 1, 1, 1)
        g_plex_layout.addWidget(self.plex_passw, 2, 2, 1, 2)

        g_plex.setLayout(g_plex_layout)

        # Group: Jellyfin settings
        g_jellyfin = QGroupBox('Jellyfin')
        g_jellyfin.setFlat(True)
        self.jellyfin_host = QLineEdit()
        self.jellyfin_port = QLineEdit()
        self.jellyfin_user = QLineEdit()
        self.jellyfin_apikey = QLineEdit()

        g_jellyfin_layout = QGridLayout()
        g_jellyfin_layout.addWidget(QLabel('Host and Port'), 0, 0, 1, 1)
        g_jellyfin_layout.addWidget(self.jellyfin_host, 0, 1, 1, 1)
        g_jellyfin_layout.addWidget(self.jellyfin_port, 0, 2, 1, 2)
        g_jellyfin_layout.addWidget(QLabel('API and User'), 1, 0, 1, 1)
        g_jellyfin_layout.addWidget(self.jellyfin_apikey, 1, 1, 1, 1)
        g_jellyfin_layout.addWidget(self.jellyfin_user, 1, 2, 1, 2)

        g_jellyfin.setLayout(g_jellyfin_layout)

        # Group: Kodi settings
        g_kodi = QGroupBox('Kodi')
        g_kodi.setFlat(True)
        self.kodi_host = QLineEdit()
        self.kodi_port = QLineEdit()
        self.kodi_user = QLineEdit()
        self.kodi_passw = QLineEdit()
        self.kodi_passw.setEchoMode(QLineEdit.Password)
        self.kodi_obey_wait = QCheckBox()

        g_kodi_layout = QGridLayout()
        g_kodi_layout.addWidget(QLabel('Host and Port'), 0, 0, 1, 1)
        g_kodi_layout.addWidget(self.kodi_host, 0, 1, 1, 1)
        g_kodi_layout.addWidget(self.kodi_port, 0, 2, 1, 2)
        g_kodi_layout.addWidget(QLabel('Use "wait before updating" time'), 1,
                                0, 1, 1)
        g_kodi_layout.addWidget(self.kodi_obey_wait, 1, 2, 1, 1)
        g_kodi_layout.addWidget(QLabel('Kodi login'), 2, 0, 1, 1)
        g_kodi_layout.addWidget(self.kodi_user, 2, 1, 1, 1)
        g_kodi_layout.addWidget(self.kodi_passw, 2, 2, 1, 2)

        g_kodi.setLayout(g_kodi_layout)

        # Group: Library
        g_playnext = QGroupBox('Library')
        g_playnext.setFlat(True)
        self.player = QLineEdit()
        self.player_browse = QPushButton('Browse...')
        self.player_browse.clicked.connect(self.s_player_browse)
        lbl_searchdirs = QLabel('Media directories')
        lbl_searchdirs.setAlignment(QtCore.Qt.AlignTop)
        self.searchdirs = QListWidget()
        self.searchdirs_add = QPushButton('Add...')
        self.searchdirs_add.clicked.connect(self.s_searchdirs_add)
        self.searchdirs_remove = QPushButton('Remove')
        self.searchdirs_remove.clicked.connect(self.s_searchdirs_remove)
        self.searchdirs_buttons = QVBoxLayout()
        self.searchdirs_buttons.setAlignment(QtCore.Qt.AlignTop)
        self.searchdirs_buttons.addWidget(self.searchdirs_add)
        self.searchdirs_buttons.addWidget(self.searchdirs_remove)
        self.searchdirs_buttons.addWidget(QSplitter())
        self.library_autoscan = QCheckBox()
        self.scan_whole_list = QCheckBox()
        self.library_full_path = QCheckBox()

        g_playnext_layout = QGridLayout()
        g_playnext_layout.addWidget(QLabel('Player'), 0, 0, 1, 1)
        g_playnext_layout.addWidget(self.player, 0, 1, 1, 1)
        g_playnext_layout.addWidget(self.player_browse, 0, 2, 1, 1)
        g_playnext_layout.addWidget(lbl_searchdirs, 1, 0, 1, 1)
        g_playnext_layout.addWidget(self.searchdirs, 1, 1, 1, 1)
        g_playnext_layout.addLayout(self.searchdirs_buttons, 1, 2, 1, 1)
        g_playnext_layout.addWidget(QLabel('Rescan Library at startup'), 2, 0,
                                    1, 2)
        g_playnext_layout.addWidget(self.library_autoscan, 2, 2, 1, 1)
        g_playnext_layout.addWidget(QLabel('Scan through whole list'), 3, 0, 1,
                                    2)
        g_playnext_layout.addWidget(self.scan_whole_list, 3, 2, 1, 1)
        g_playnext_layout.addWidget(
            QLabel('Take subdirectory name into account'), 4, 0, 1, 2)
        g_playnext_layout.addWidget(self.library_full_path, 4, 2, 1, 1)

        g_playnext.setLayout(g_playnext_layout)

        # Media form
        page_media_layout.addWidget(g_media)
        page_media_layout.addWidget(g_plex)
        page_media_layout.addWidget(g_jellyfin)
        page_media_layout.addWidget(g_kodi)
        page_media_layout.addWidget(g_playnext)
        page_media.setLayout(page_media_layout)

        # Sync tab
        page_sync = QWidget()
        page_sync_layout = QVBoxLayout()
        page_sync_layout.setAlignment(QtCore.Qt.AlignTop)

        # Group: Autoretrieve
        g_autoretrieve = QGroupBox('Autoretrieve')
        g_autoretrieve.setFlat(True)
        self.autoretrieve_off = QRadioButton('Disabled')
        self.autoretrieve_always = QRadioButton('Always at start')
        self.autoretrieve_days = QRadioButton('After n days')
        self.autoretrieve_days.toggled.connect(self.s_autoretrieve_days)
        self.autoretrieve_days_n = QSpinBox()
        self.autoretrieve_days_n.setRange(1, 100)
        g_autoretrieve_layout = QGridLayout()
        g_autoretrieve_layout.setColumnStretch(0, 1)
        g_autoretrieve_layout.addWidget(self.autoretrieve_off, 0, 0, 1, 1)
        g_autoretrieve_layout.addWidget(self.autoretrieve_always, 1, 0, 1, 1)
        g_autoretrieve_layout.addWidget(self.autoretrieve_days, 2, 0, 1, 1)
        g_autoretrieve_layout.addWidget(self.autoretrieve_days_n, 2, 1, 1, 1)
        g_autoretrieve.setLayout(g_autoretrieve_layout)

        # Group: Autosend
        g_autosend = QGroupBox('Autosend')
        g_autosend.setFlat(True)
        self.autosend_off = QRadioButton('Disabled')
        self.autosend_always = QRadioButton('Immediately after every change')
        self.autosend_minutes = QRadioButton('After n minutes')
        self.autosend_minutes.toggled.connect(self.s_autosend_minutes)
        self.autosend_minutes_n = QSpinBox()
        self.autosend_minutes_n.setRange(1, 1000)
        self.autosend_size = QRadioButton('After the queue reaches n items')
        self.autosend_size.toggled.connect(self.s_autosend_size)
        self.autosend_size_n = QSpinBox()
        self.autosend_size_n.setRange(2, 20)
        self.autosend_at_exit = QCheckBox('At exit')
        g_autosend_layout = QGridLayout()
        g_autosend_layout.setColumnStretch(0, 1)
        g_autosend_layout.addWidget(self.autosend_off, 0, 0, 1, 1)
        g_autosend_layout.addWidget(self.autosend_always, 1, 0, 1, 1)
        g_autosend_layout.addWidget(self.autosend_minutes, 2, 0, 1, 1)
        g_autosend_layout.addWidget(self.autosend_minutes_n, 2, 1, 1, 1)
        g_autosend_layout.addWidget(self.autosend_size, 3, 0, 1, 1)
        g_autosend_layout.addWidget(self.autosend_size_n, 3, 1, 1, 1)
        g_autosend_layout.addWidget(self.autosend_at_exit, 4, 0, 1, 1)
        g_autosend.setLayout(g_autosend_layout)

        # Group: Extra
        g_extra = QGroupBox('Additional options')
        g_extra.setFlat(True)
        self.auto_status_change = QCheckBox('Change status automatically')
        self.auto_status_change.toggled.connect(self.s_auto_status_change)
        self.auto_status_change_if_scored = QCheckBox(
            'Change status automatically only if scored')
        self.auto_date_change = QCheckBox(
            'Change start and finish dates automatically')
        g_extra_layout = QVBoxLayout()
        g_extra_layout.addWidget(self.auto_status_change)
        g_extra_layout.addWidget(self.auto_status_change_if_scored)
        g_extra_layout.addWidget(self.auto_date_change)
        g_extra.setLayout(g_extra_layout)

        # Sync layout
        page_sync_layout.addWidget(g_autoretrieve)
        page_sync_layout.addWidget(g_autosend)
        page_sync_layout.addWidget(g_extra)
        page_sync.setLayout(page_sync_layout)

        # UI tab
        page_ui = QWidget()
        page_ui_layout = QFormLayout()
        page_ui_layout.setAlignment(QtCore.Qt.AlignTop)

        # Group: Icon
        g_icon = QGroupBox('Notification Icon')
        g_icon.setFlat(True)
        self.tray_icon = QCheckBox('Show tray icon')
        self.tray_icon.toggled.connect(self.s_tray_icon)
        self.close_to_tray = QCheckBox('Close to tray')
        self.start_in_tray = QCheckBox('Start minimized to tray')
        self.tray_api_icon = QCheckBox('Use API icon as tray icon')
        self.notifications = QCheckBox(
            'Show notification when tracker detects new media')
        g_icon_layout = QVBoxLayout()
        g_icon_layout.addWidget(self.tray_icon)
        g_icon_layout.addWidget(self.close_to_tray)
        g_icon_layout.addWidget(self.start_in_tray)
        g_icon_layout.addWidget(self.tray_api_icon)
        g_icon_layout.addWidget(self.notifications)
        g_icon.setLayout(g_icon_layout)

        # Group: Window
        g_window = QGroupBox('Window')
        g_window.setFlat(True)
        self.remember_geometry = QCheckBox('Remember window size and position')
        self.remember_columns = QCheckBox('Remember column layouts and widths')
        self.columns_per_api = QCheckBox(
            'Use different visible columns per API')
        g_window_layout = QVBoxLayout()
        g_window_layout.addWidget(self.remember_geometry)
        g_window_layout.addWidget(self.remember_columns)
        g_window_layout.addWidget(self.columns_per_api)
        g_window.setLayout(g_window_layout)

        # Group: Lists
        g_lists = QGroupBox('Lists')
        g_lists.setFlat(True)
        self.filter_bar_position = QComboBox()
        filter_bar_positions = [(FilterBar.PositionHidden, 'Hidden'),
                                (FilterBar.PositionAboveLists, 'Above lists'),
                                (FilterBar.PositionBelowLists, 'Below lists')]
        for (n, label) in filter_bar_positions:
            self.filter_bar_position.addItem(label, n)
        self.inline_edit = QCheckBox('Enable in-line editing')
        g_lists_layout = QFormLayout()
        g_lists_layout.addRow('Filter bar position:', self.filter_bar_position)
        g_lists_layout.addRow(self.inline_edit)
        g_lists.setLayout(g_lists_layout)

        # UI layout
        page_ui_layout.addWidget(g_icon)
        page_ui_layout.addWidget(g_window)
        page_ui_layout.addWidget(g_lists)
        page_ui.setLayout(page_ui_layout)

        # Theming tab
        page_theme = QWidget()
        page_theme_layout = QFormLayout()
        page_theme_layout.setAlignment(QtCore.Qt.AlignTop)

        # Group: Episode Bar
        g_ep_bar = QGroupBox('Episode Bar')
        g_ep_bar.setFlat(True)
        self.ep_bar_style = QComboBox()
        ep_bar_styles = [(ShowsTableDelegate.BarStyleBasic, 'Basic'),
                         (ShowsTableDelegate.BarStyle04, 'Trackma'),
                         (ShowsTableDelegate.BarStyleHybrid, 'Hybrid')]
        for (n, label) in ep_bar_styles:
            self.ep_bar_style.addItem(label, n)
        self.ep_bar_style.currentIndexChanged.connect(self.s_ep_bar_style)
        self.ep_bar_text = QCheckBox('Show text label')
        g_ep_bar_layout = QFormLayout()
        g_ep_bar_layout.addRow('Style:', self.ep_bar_style)
        g_ep_bar_layout.addRow(self.ep_bar_text)
        g_ep_bar.setLayout(g_ep_bar_layout)

        # Group: Colour scheme
        g_scheme = QGroupBox('Color Scheme')
        g_scheme.setFlat(True)
        col_tabs = [('rows', '&Row highlights'),
                    ('progress', '&Progress widget')]
        self.colors = {}
        self.colors['rows'] = [('is_playing', 'Playing'),
                               ('is_queued', 'Queued'),
                               ('new_episode', 'New Episode'),
                               ('is_airing', 'Airing'),
                               ('not_aired', 'Unaired')]
        self.colors['progress'] = [('progress_bg', 'Background'),
                                   ('progress_fg', 'Watched bar'),
                                   ('progress_sub_bg', 'Aired episodes'),
                                   ('progress_sub_fg', 'Stored episodes'),
                                   ('progress_complete', 'Complete')]
        self.color_buttons = []
        self.syscolor_buttons = []
        g_scheme_layout = QGridLayout()
        tw_scheme = QTabWidget()
        for (key, tab_title) in col_tabs:
            page = QFrame()
            page_layout = QGridLayout()
            col = 0
            # Generate widgets from the keys and values
            for (key, label) in self.colors[key]:
                self.color_buttons.append(QPushButton())
                # self.color_buttons[-1].setStyleSheet('background-color: ' + getColor(self.config['colors'][key]).name())
                self.color_buttons[-1].setFocusPolicy(QtCore.Qt.NoFocus)
                self.color_buttons[-1].clicked.connect(
                    self.s_color_picker(key, False))
                self.syscolor_buttons.append(QPushButton('System Colors'))
                self.syscolor_buttons[-1].clicked.connect(
                    self.s_color_picker(key, True))
                page_layout.addWidget(QLabel(label), col, 0, 1, 1)
                page_layout.addWidget(self.color_buttons[-1], col, 1, 1, 1)
                page_layout.addWidget(self.syscolor_buttons[-1], col, 2, 1, 1)
                col += 1
            page.setLayout(page_layout)
            tw_scheme.addTab(page, tab_title)
        g_scheme_layout.addWidget(tw_scheme)
        g_scheme.setLayout(g_scheme_layout)

        # UI layout
        page_theme_layout.addWidget(g_ep_bar)
        page_theme_layout.addWidget(g_scheme)
        page_theme.setLayout(page_theme_layout)

        # Content
        self.contents = QStackedWidget()
        for page in (page_media, page_sync, page_ui, page_theme):
            scrollable_page = QScrollArea()
            scrollable_page.setWidgetResizable(True)
            scrollable_page.setWidget(page)
            self.contents.addWidget(scrollable_page)

        if pyqt_version != 5:
            self.contents.layout().setMargin(0)

        # Bottom buttons
        bottombox = QDialogButtonBox(QDialogButtonBox.Ok
                                     | QDialogButtonBox.Apply
                                     | QDialogButtonBox.Cancel)
        bottombox.accepted.connect(self.s_save)
        bottombox.button(QDialogButtonBox.Apply).clicked.connect(self._save)
        bottombox.rejected.connect(self.reject)

        # Main layout finish
        layout.addWidget(self.category_list, 0, 0, 1, 1)
        layout.addWidget(self.contents, 0, 1, 1, 1)
        layout.addWidget(bottombox, 1, 0, 1, 2)
        layout.setColumnStretch(1, 1)

        self._load()
        self.update_colors()

        self.setLayout(layout)
Пример #4
0
    def data(self, index, role):
        row, column = index.row(), index.column()
        show = self.showlist[row]

        if role == QtCore.Qt.DisplayRole:
            if column == ShowListModel.COL_ID:
                return show['id']
            elif column == ShowListModel.COL_TITLE:
                title_str = show['title']
                if show['id'] in self.altnames:
                    title_str += " [%s]" % self.altnames[show['id']]
                return title_str
            elif column == ShowListModel.COL_MY_PROGRESS:
                return "{} / {}".format(show['my_progress'], show['total'] or '?')
            elif column == ShowListModel.COL_MY_SCORE:
                return show['my_score']
            elif column == ShowListModel.COL_PERCENT:
                #return "{:.0%}".format(show['my_progress'] / 100)
                if not self.mediainfo.get('can_play'):
                    return None

                if show['total']:
                    total = show['total']
                else:
                    total = (int(show['my_progress']/12)+1)*12 # Round up to the next cour

                if row in self.eps:
                    return (show['my_progress'], total, self.eps[row][0], self.eps[row][1])
                else:
                    return (show['my_progress'], total, None, None)
            elif column == ShowListModel.COL_NEXT_EP:
                return self.next_ep.get(row, '-')
            elif column == ShowListModel.COL_START_DATE:
                return self._date(show['start_date'])
            elif column == ShowListModel.COL_END_DATE:
                return self._date(show['end_date'])
            elif column == ShowListModel.COL_MY_START:
                return self._date(show['my_start_date'])
            elif column == ShowListModel.COL_MY_FINISH:
                return self._date(show['my_finish_date'])
            elif column == ShowListModel.COL_MY_TAGS:
                return show.get('my_tags', '-')
            elif column == ShowListModel.COL_MY_STATUS:
                return self.mediainfo['statuses_dict'][show['my_status']]
        elif role == QtCore.Qt.BackgroundRole:
            return self.colors.get(row)
        elif role == QtCore.Qt.DecorationRole:
            if column == ShowListModel.COL_TITLE and show['id'] in self.playing:
                return getIcon('media-playback-start')
        elif role == QtCore.Qt.TextAlignmentRole:
            if column in [ShowListModel.COL_MY_PROGRESS, ShowListModel.COL_MY_SCORE]:
                return QtCore.Qt.AlignHCenter
        elif role == QtCore.Qt.ToolTipRole:
            if column == ShowListModel.COL_PERCENT:
                tooltip = "Watched: %d<br>" % show['my_progress']
                if self.eps.get(row):
                    (aired_eps, library_eps) = self.eps.get(row)
                    if aired_eps:
                        tooltip += "Aired (estimated): %d<br>" % aired_eps
                    if library_eps:
                        tooltip += "Latest available: %d<br>" % max(library_eps)
                tooltip += "Total: %d" % show['total']

                return tooltip
        elif role == QtCore.Qt.EditRole:
            if column == ShowListModel.COL_MY_PROGRESS:
                return (show['my_progress'], show['total'], 0, 1)
            elif column == ShowListModel.COL_MY_SCORE:
                if isinstance(self.mediainfo['score_step'], float):
                    decimals = len(str(self.mediainfo['score_step']).split('.')[1])
                else:
                    decimals = 0

                return (show['my_score'], self.mediainfo['score_max'], decimals, self.mediainfo['score_step'])