5 from PyQt4
import QtGui
7 from ugit
.observer
import Observer
8 from ugit
.qobserver
import QObserver
9 from ugit
import qtutils
10 from ugit
.views
import SearchView
13 class SearchEngine(object):
14 def __init__(self
, model
):
16 self
.parse
= self
.model
.parse_rev_list
20 def get_rev_args(self
):
21 max = self
.model
.get_max_results()
22 return { "max-count": max, "pretty": "oneline" }
23 def get_common_args(self
):
24 return (self
.model
.get_input(),
27 if not self
.validate():
29 return self
.get_results()
31 return len(self
.model
.get_input()) > 1
32 def get_results(self
):
35 class RevisionSearch(SearchEngine
):
36 def get_results(self
):
37 input, args
= self
.get_common_args()
38 expr
= re
.compile(input)
39 revs
= self
.parse(self
.model
.rev_list(all
=True, **args
))
40 return [ r
for r
in revs
if expr
.match(r
[0]) ]
42 class RevisionRangeSearch(SearchEngine
):
44 self
.RE
= re
.compile(r
'[^.]+\.\..+')
46 return bool(self
.RE
.match(self
.model
.get_input()))
47 def get_results(self
):
48 input, args
= self
.get_common_args()
49 return self
.parse(self
.model
.rev_list(input, **args
))
51 class PathSearch(SearchEngine
):
52 def get_results(self
):
53 input, args
= self
.get_common_args()
54 paths
= ['--'] + input.split(':')
55 return self
.parse(self
.model
.rev_list(all
=True,*paths
,**args
))
57 class MessageSearch(SearchEngine
):
58 def get_results(self
):
59 input, args
= self
.get_common_args()
61 self
.model
.rev_list(grep
=input, all
=True, **args
))
63 class AuthorSearch(SearchEngine
):
64 def get_results(self
):
65 input, args
= self
.get_common_args()
67 self
.model
.rev_list(author
=input, all
=True, **args
))
69 class CommitterSearch(SearchEngine
):
70 def get_results(self
):
71 input, args
= self
.get_common_args()
73 self
.model
.rev_list(committer
=input, all
=True, **args
))
75 class DiffSearch(SearchEngine
):
76 def get_results(self
):
77 input, args
= self
.get_common_args()
79 self
.model
.log('-S'+input, all
=True, **args
))
81 class DateRangeSearch(SearchEngine
):
84 def get_results(self
):
85 args
= self
.get_rev_args()
89 after
=self
.model
.get_start_date(),
90 before
=self
.model
.get_end_date(),
94 # Modes for this controller.
95 # Note: names correspond to radio button names for convenience
96 REVISION_ID
= 'radio_revision'
97 REVISION_RANGE
= 'radio_range'
99 MESSAGE
= 'radio_message'
101 AUTHOR
= 'radio_author'
102 COMMITTER
= 'radio_committer'
103 DATE_RANGE
= 'radio_daterange'
105 # Each search type is handled by a distinct SearchEngine subclass
107 REVISION_ID
: RevisionSearch
,
108 REVISION_RANGE
: RevisionRangeSearch
,
110 MESSAGE
: MessageSearch
,
112 AUTHOR
: AuthorSearch
,
113 COMMITTER
: CommitterSearch
,
114 DATE_RANGE
: DateRangeSearch
,
117 class SearchController(QObserver
):
118 def init(self
, model
, view
):
119 self
.add_observables(
126 input = self
.search_callback
,
127 max_results
= self
.search_callback
,
128 start_date
= self
.search_callback
,
129 end_date
= self
.search_callback
,
133 button_search
= self
.search_callback
,
134 button_browse
= self
.browse_callback
,
135 commit_list
= self
.display_callback
,
136 # Radio buttons trigger a search
137 radio_revision
= self
.search_callback
,
138 radio_range
= self
.search_callback
,
139 radio_message
= self
.search_callback
,
140 radio_path
= self
.search_callback
,
141 radio_diff
= self
.search_callback
,
142 radio_author
= self
.search_callback
,
143 radio_committer
= self
.search_callback
,
144 radio_daterange
= self
.search_callback
,
148 def update_fonts(self
):
149 font
= self
.model
.get_global_ugit_fontui()
151 qfont
= QtGui
.QFont()
152 qfont
.fromString(font
)
153 self
.view
.commit_list
.setFont(qfont
)
154 font
= self
.model
.get_global_ugit_fontdiff()
156 qfont
= QtGui
.QFont()
157 qfont
.fromString(font
)
158 self
.view
.commit_text
.setFont(qfont
)
160 def set_mode(self
, mode
):
161 radio
= getattr(self
.view
, mode
)
162 radio
.setChecked(True)
164 def radio_to_mode(self
, radio_button
):
165 return str(radio_button
.objectName())
168 for name
in SEARCH_ENGINES
:
169 radiobutton
= getattr(self
.view
, name
)
170 if radiobutton
.isChecked():
173 def search_callback(self
, *args
):
174 engineclass
= SEARCH_ENGINES
.get(self
.get_mode())
176 print ("mode: '%s' is currently unimplemented"
179 self
.results
= engineclass(self
.model
).search()
181 self
.display_results()
183 self
.view
.commit_list
.clear()
184 self
.view
.commit_text
.setText('')
186 def browse_callback(self
):
187 paths
= QtGui
.QFileDialog
.getOpenFileNames(
189 self
.tr("Choose Path(s)"))
193 lenprefix
= len(os
.getcwd()) + 1
194 for path
in map(lambda x
: unicode(x
), paths
):
195 if not path
.startswith(os
.getcwd()):
197 filepaths
.append(path
[lenprefix
:])
198 input = ':'.join(filepaths
)
199 self
.model
.set_input('')
201 self
.model
.set_input(input)
203 def display_results(self
):
204 commit_list
= map(lambda x
: x
[1], self
.results
)
205 self
.model
.set_commit_list(commit_list
)
206 qtutils
.set_listwidget_strings(
207 self
.view
.commit_list
,
210 def display_callback(self
, *args
):
211 widget
= self
.view
.commit_list
212 row
, selected
= qtutils
.get_selected_row(widget
)
213 if not selected
or len(self
.results
) < row
:
215 revision
= self
.results
[row
][0]
216 qtutils
.set_clipboard(revision
)
217 diff
= self
.model
.get_commit_diff(revision
)
218 self
.view
.commit_text
.setText(diff
)
220 def search_commits(model
, mode
, browse
):
221 def get_date(timespec
):
222 return '%04d-%02d-%02d' % time
.localtime(timespec
)[:3]
224 model
= model
.clone()
232 view
= SearchView(None)
233 ctl
= SearchController(model
, view
)
235 model
.set_start_date(get_date(time
.time()-(87640*7)))
236 model
.set_end_date(get_date(time
.time()+87640))
239 ctl
.browse_callback()