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
, mode
):
119 QObserver
.__init
__(self
, model
, view
)
120 self
.add_observables(
127 input = self
.search_callback
,
128 max_results
= self
.search_callback
,
129 start_date
= self
.search_callback
,
130 end_date
= self
.search_callback
,
134 button_search
= self
.search_callback
,
135 button_browse
= self
.browse_callback
,
136 commit_list
= self
.display_callback
,
137 # Radio buttons trigger a search
138 radio_revision
= self
.search_callback
,
139 radio_range
= self
.search_callback
,
140 radio_message
= self
.search_callback
,
141 radio_path
= self
.search_callback
,
142 radio_diff
= self
.search_callback
,
143 radio_author
= self
.search_callback
,
144 radio_committer
= self
.search_callback
,
145 radio_daterange
= self
.search_callback
,
150 def update_fonts(self
):
151 font
= self
.model
.get_global_ugit_fontui()
153 qfont
= QtGui
.QFont()
154 qfont
.fromString(font
)
155 self
.view
.commit_list
.setFont(qfont
)
156 font
= self
.model
.get_global_ugit_fontdiff()
158 qfont
= QtGui
.QFont()
159 qfont
.fromString(font
)
160 self
.view
.commit_text
.setFont(qfont
)
162 def set_mode(self
, mode
):
163 radio
= getattr(self
.view
, mode
)
164 radio
.setChecked(True)
166 def radio_to_mode(self
, radio_button
):
167 return str(radio_button
.objectName())
170 for name
in SEARCH_ENGINES
:
171 radiobutton
= getattr(self
.view
, name
)
172 if radiobutton
.isChecked():
175 def search_callback(self
, *args
):
176 engineclass
= SEARCH_ENGINES
.get(self
.get_mode())
178 print ("mode: '%s' is currently unimplemented"
181 self
.results
= engineclass(self
.model
).search()
183 self
.display_results()
185 self
.view
.commit_list
.clear()
186 self
.view
.commit_text
.setText('')
188 def browse_callback(self
):
189 paths
= QtGui
.QFileDialog
.getOpenFileNames(
191 self
.tr("Choose Path(s)"))
195 lenprefix
= len(os
.getcwd()) + 1
196 for path
in map(lambda x
: unicode(x
), paths
):
197 if not path
.startswith(os
.getcwd()):
199 filepaths
.append(path
[lenprefix
:])
200 input = ':'.join(filepaths
)
201 self
.model
.set_input('')
203 self
.model
.set_input(input)
205 def display_results(self
):
206 commit_list
= map(lambda x
: x
[1], self
.results
)
207 self
.model
.set_commit_list(commit_list
)
208 qtutils
.set_listwidget_strings(
209 self
.view
.commit_list
,
212 def display_callback(self
, *args
):
213 widget
= self
.view
.commit_list
214 row
, selected
= qtutils
.get_selected_row(widget
)
215 if not selected
or len(self
.results
) < row
:
217 revision
= self
.results
[row
][0]
218 qtutils
.set_clipboard(revision
)
219 diff
= self
.model
.get_commit_diff(revision
)
220 self
.view
.commit_text
.setText(diff
)
222 def search_commits(model
, mode
, browse
):
223 def get_date(timespec
):
224 return '%04d-%02d-%02d' % time
.localtime(timespec
)[:3]
226 model
= model
.clone()
234 view
= SearchView(None)
235 ctl
= SearchController(model
, view
, mode
)
236 model
.set_start_date(get_date(time
.time()-(87640*7)))
237 model
.set_end_date(get_date(time
.time()+87640))
240 ctl
.browse_callback()