1 """File finder widgets"""
3 from functools
import partial
5 from qtpy
import QtCore
6 from qtpy
import QtWidgets
7 from qtpy
.QtCore
import Qt
8 from qtpy
.QtCore
import Signal
11 from ..qtutils
import get
12 from ..utils
import Group
15 from .. import gitcmds
16 from .. import hotkeys
19 from .. import qtutils
20 from . import completion
22 from . import filetree
23 from . import standard
27 def finder(context
, paths
=None):
28 """Prompt and use 'git grep' to find the content."""
29 parent
= qtutils
.active_window()
30 widget
= new_finder(context
, paths
=paths
, parent
=parent
)
36 def new_finder(context
, paths
=None, parent
=None):
37 """Create a finder widget"""
38 widget
= Finder(context
, parent
=parent
)
39 widget
.search_for(paths
or '')
43 def add_wildcards(arg
):
44 """Add "*" around user input to generate ls-files pathspec matches
47 add_wildcards('x') == \
48 add_wildcards('*x') == \
49 add_wildcards('x*') == \
54 if not arg
.startswith('*'):
56 if not arg
.endswith('*'):
61 def show_help(context
):
62 """Show the help page"""
69 Enter = Edit Selected Files
70 Spacebar = Open File Using Default Application
71 Ctrl + L = Focus Text Entry Field
74 The up and down arrows change focus between the text entry field
78 title
= N_('Help - Find Files')
79 return text
.text_dialog(context
, help_text
, title
)
82 class FindFilesThread(QtCore
.QThread
):
83 """Finds files asynchronously"""
85 result
= Signal(object)
87 def __init__(self
, context
, parent
):
88 QtCore
.QThread
.__init
__(self
, parent
)
89 self
.context
= context
93 context
= self
.context
98 args
= [add_wildcards(arg
) for arg
in utils
.shell_split(query
)]
99 filenames
= gitcmds
.tracked_files(context
, *args
)
100 if query
== self
.query
:
101 self
.result
.emit(filenames
)
106 class Finder(standard
.Dialog
):
107 """File Finder dialog"""
109 def __init__(self
, context
, parent
=None):
110 standard
.Dialog
.__init
__(self
, parent
)
111 self
.context
= context
112 self
.setWindowTitle(N_('Find Files'))
113 if parent
is not None:
114 self
.setWindowModality(Qt
.WindowModal
)
116 label
= os
.path
.basename(core
.getcwd()) + '/'
117 self
.input_label
= QtWidgets
.QLabel(label
)
118 self
.input_txt
= completion
.GitTrackedLineEdit(context
, hint
=N_('<path> ...'))
120 self
.tree
= filetree
.FileTree(parent
=self
)
122 self
.edit_button
= qtutils
.edit_button(default
=True)
123 self
.edit_button
.setShortcut(hotkeys
.EDIT
)
125 name
= cmds
.OpenDefaultApp
.name()
126 icon
= icons
.default_app()
127 self
.open_default_button
= qtutils
.create_button(text
=name
, icon
=icon
)
128 self
.open_default_button
.setShortcut(hotkeys
.PRIMARY_ACTION
)
130 self
.button_group
= Group(self
.edit_button
, self
.open_default_button
)
131 self
.button_group
.setEnabled(False)
133 self
.refresh_button
= qtutils
.refresh_button()
134 self
.refresh_button
.setShortcut(hotkeys
.REFRESH
)
136 self
.help_button
= qtutils
.create_button(
137 text
=N_('Help'), tooltip
=N_('Show help\nShortcut: ?'), icon
=icons
.question()
140 self
.close_button
= qtutils
.close_button()
142 self
.input_layout
= qtutils
.hbox(
143 defs
.no_margin
, defs
.button_spacing
, self
.input_label
, self
.input_txt
146 self
.bottom_layout
= qtutils
.hbox(
153 self
.open_default_button
,
157 self
.main_layout
= qtutils
.vbox(
164 self
.setLayout(self
.main_layout
)
165 self
.setFocusProxy(self
.input_txt
)
167 thread
= self
.worker_thread
= FindFilesThread(context
, self
)
168 thread
.result
.connect(self
.process_result
, type=Qt
.QueuedConnection
)
170 self
.input_txt
.textChanged
.connect(lambda s
: self
.search())
171 self
.input_txt
.activated
.connect(self
.focus_tree
)
172 self
.input_txt
.down
.connect(self
.focus_tree
)
173 self
.input_txt
.enter
.connect(self
.focus_tree
)
175 item_selection_changed
= self
.tree_item_selection_changed
176 self
.tree
.itemSelectionChanged
.connect(item_selection_changed
)
177 self
.tree
.up
.connect(self
.focus_input
)
178 self
.tree
.space
.connect(self
.open_default
)
181 self
, 'Focus Input', self
.focus_input
, hotkeys
.FOCUS
, hotkeys
.FINDER
184 self
.show_help_action
= qtutils
.add_action(
185 self
, N_('Show Help'), partial(show_help
, context
), hotkeys
.QUESTION
188 qtutils
.connect_button(self
.edit_button
, self
.edit
)
189 qtutils
.connect_button(self
.open_default_button
, self
.open_default
)
190 qtutils
.connect_button(self
.refresh_button
, self
.search
)
191 qtutils
.connect_button(self
.help_button
, partial(show_help
, context
))
192 qtutils
.connect_button(self
.close_button
, self
.close
)
193 qtutils
.add_close_action(self
)
195 self
.init_size(parent
=parent
)
197 def focus_tree(self
):
200 def focus_input(self
):
201 self
.input_txt
.setFocus()
204 self
.button_group
.setEnabled(False)
205 self
.refresh_button
.setEnabled(False)
206 query
= get(self
.input_txt
)
207 self
.worker_thread
.query
= query
208 self
.worker_thread
.start()
210 def search_for(self
, txt
):
211 self
.input_txt
.set_value(txt
)
214 def process_result(self
, filenames
):
215 self
.tree
.set_filenames(filenames
, select
=True)
216 self
.refresh_button
.setEnabled(True)
219 context
= self
.context
220 paths
= self
.tree
.selected_filenames()
221 cmds
.do(cmds
.Edit
, context
, paths
, background_editor
=True)
223 def open_default(self
):
224 context
= self
.context
225 paths
= self
.tree
.selected_filenames()
226 cmds
.do(cmds
.OpenDefaultApp
, context
, paths
)
228 def tree_item_selection_changed(self
):
229 enabled
= bool(self
.tree
.selected_item())
230 self
.button_group
.setEnabled(enabled
)