fsmonitor: silence pylint warnings
[git-cola.git] / cola / models / selection.py
blob06c2a33d500e8703b862f1e48221327c2ffc3336
1 """Provides a selection model to handle selection."""
2 import collections
4 from qtpy import QtCore
5 from qtpy.QtCore import Signal
7 State = collections.namedtuple('State', 'staged unmerged modified untracked')
10 def create():
11 """Create a SelectionModel"""
12 return SelectionModel()
15 def pick(selection):
16 """Choose the first list from stage, unmerged, modified, untracked"""
17 if selection.staged:
18 files = selection.staged
19 elif selection.unmerged:
20 files = selection.unmerged
21 elif selection.modified:
22 files = selection.modified
23 elif selection.untracked:
24 files = selection.untracked
25 else:
26 files = []
27 return files
30 def union(selection):
31 """Return the union of all selected items in a sorted list"""
32 values = set(
33 selection.staged + selection.unmerged + selection.modified + selection.untracked
35 return list(sorted(values))
38 def _filter(values, remove):
39 """Filter a list in-place by removing items"""
40 remove_set = set(remove)
41 values_copy = list(values)
42 last = len(values_copy) - 1
43 for idx, value in enumerate(reversed(values)):
44 if value not in remove_set:
45 values.pop(last - idx)
48 class SelectionModel(QtCore.QObject):
49 """Provides information about selected file paths."""
51 selection_changed = Signal()
53 # These properties wrap the individual selection items
54 # to provide higher-level pseudo-selections.
55 unstaged = property(lambda self: self.unmerged + self.modified + self.untracked)
57 def __init__(self):
58 super().__init__()
59 self.staged = []
60 self.unmerged = []
61 self.modified = []
62 self.untracked = []
63 self.line_number = None
65 def reset(self):
66 self.staged = []
67 self.unmerged = []
68 self.modified = []
69 self.untracked = []
70 self.line_number = None
72 def is_empty(self):
73 return not (
74 bool(self.staged or self.unmerged or self.modified or self.untracked)
77 def set_selection(self, s):
78 """Set the new selection."""
79 self.staged = s.staged
80 self.unmerged = s.unmerged
81 self.modified = s.modified
82 self.untracked = s.untracked
83 self.selection_changed.emit()
85 def update(self, other):
86 _filter(self.staged, other.staged)
87 _filter(self.unmerged, other.unmerged)
88 _filter(self.modified, other.modified)
89 _filter(self.untracked, other.untracked)
90 self.selection_changed.emit()
92 def selection(self):
93 return State(self.staged, self.unmerged, self.modified, self.untracked)
95 def single_selection(self):
96 """Scan across staged, modified, etc. and return a single item."""
97 staged = None
98 modified = None
99 unmerged = None
100 untracked = None
101 if self.staged:
102 staged = self.staged[0]
103 elif self.modified:
104 modified = self.modified[0]
105 elif self.unmerged:
106 unmerged = self.unmerged[0]
107 elif self.untracked:
108 untracked = self.untracked[0]
109 return State(staged, unmerged, modified, untracked)
111 def filename(self):
112 paths = [path for path in self.single_selection() if path is not None]
113 if paths:
114 filename = paths[0]
115 else:
116 filename = None
117 return filename
119 def group(self):
120 """A list of selected files in various states of being"""
121 return pick(self.selection())
123 def union(self):
124 """Return the union of all selected items in a sorted list"""
125 return union(self)