summaryrefslogtreecommitdiffstats
path: root/deluge/ui/console/modes/torrentlist/filtersidebar.py
blob: 114365e044e67d33e21ebcce0a4a764faf16edb3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# -*- coding: utf-8 -*-
#
# Copyright (C) 2016 bendikro <bro.devel+deluge@gmail.com>
#
# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# the additional special exception to link portions of this program with the OpenSSL library.
# See LICENSE for more details.
#

import curses
import logging

from deluge.component import Component
from deluge.decorators import overrides
from deluge.ui.client import client
from deluge.ui.console.utils import curses_util as util
from deluge.ui.console.widgets import BaseInputPane
from deluge.ui.console.widgets.sidebar import Sidebar

log = logging.getLogger(__name__)


class FilterSidebar(Sidebar, Component):
    """The sidebar in the main torrentview

    Shows the different states of the torrents and allows to filter the
    torrents based on state.

    """

    def __init__(self, torrentlist, config):
        self.config = config
        height = curses.LINES - 2
        width = self.config['torrentview']['sidebar_width']
        Sidebar.__init__(
            self,
            torrentlist,
            width,
            height,
            title=' Filter ',
            border_off_north=1,
            allow_resize=True,
        )
        Component.__init__(self, 'FilterSidebar')
        self.checked_index = 0
        kwargs = {
            'checked_char': '*',
            'unchecked_char': '-',
            'checkbox_format': ' %s ',
            'col': 0,
        }
        self.add_checked_input('All', 'All', checked=True, **kwargs)
        self.add_checked_input('Active', 'Active', **kwargs)
        self.add_checked_input(
            'Downloading', 'Downloading', color='green,black', **kwargs
        )
        self.add_checked_input('Seeding', 'Seeding', color='cyan,black', **kwargs)
        self.add_checked_input('Paused', 'Paused', **kwargs)
        self.add_checked_input('Error', 'Error', color='red,black', **kwargs)
        self.add_checked_input('Checking', 'Checking', color='blue,black', **kwargs)
        self.add_checked_input('Queued', 'Queued', **kwargs)
        self.add_checked_input(
            'Allocating', 'Allocating', color='yellow,black', **kwargs
        )
        self.add_checked_input('Moving', 'Moving', color='green,black', **kwargs)

    @overrides(Component)
    def update(self):
        if not self.hidden() and client.connected():
            d = client.core.get_filter_tree(True, []).addCallback(
                self._cb_update_filter_tree
            )

            def on_filter_tree_updated(changed):
                if changed:
                    self.refresh()

            d.addCallback(on_filter_tree_updated)

    def _cb_update_filter_tree(self, filter_items):
        """Callback function on client.core.get_filter_tree"""
        states = filter_items['state']
        largest_count = 0
        largest_state_width = 0
        for state in states:
            largest_state_width = max(len(state[0]), largest_state_width)
            largest_count = max(int(state[1]), largest_count)

        border_and_spacing = 6  # Account for border + whitespace
        filter_state_width = largest_state_width
        filter_count_width = self.width - filter_state_width - border_and_spacing

        changed = False
        for state in states:
            field = self.get_input(state[0])
            if field:
                txt = (
                    '%%-%ds%%%ds'
                    % (filter_state_width, filter_count_width)
                    % (state[0], state[1])
                )
                if field.set_message(txt):
                    changed = True
        return changed

    @overrides(BaseInputPane)
    def immediate_action_cb(self, state_changed=True):
        if state_changed:
            self.parent.torrentview.set_torrent_filter(
                self.inputs[self.active_input].name
            )

    @overrides(Sidebar)
    def handle_read(self, c):
        if c == util.KEY_SPACE:
            if self.checked_index != self.active_input:
                self.inputs[self.checked_index].set_value(False)
                Sidebar.handle_read(self, c)
                self.checked_index = self.active_input
            return util.ReadState.READ
        else:
            return Sidebar.handle_read(self, c)

    @overrides(Sidebar)
    def on_resize(self, width):
        sidebar_width = self.config['torrentview']['sidebar_width']
        if sidebar_width != width:
            self.config['torrentview']['sidebar_width'] = width
            self.config.save()
        self.resize_window(self.height, width)
        self.parent.toggle_sidebar()
        self.refresh()