17 from functools
import (cmp_to_key)
21 from wx.lib.mixins.listctrl
import ListCtrlAutoWidthMixin
24 from ..controller.filecontrollers
import ResourceFileController, TestCaseFileController
25 from ..pluginapi
import Plugin
26 from ..action
import ActionInfo
27 from ..publish.messages
import RideOpenSuite, RideOpenResource, RideImportSetting, RideUserKeyword, RideNewProject
28 from ..usages.UsageRunner
import Usages
29 from ..widgets
import PopupMenuItem, ButtonWithHandler, Label, Font, HtmlWindow, ImageProvider, RIDEDialog
31 ALL_KEYWORDS =
'<all keywords>'
32 ALL_USER_KEYWORDS =
'<all user keywords>'
33 ALL_LIBRARY_KEYWORDS =
'<all library keywords>'
40 Plugin.__init__(self, app)
48 doc=
'Search keywords from libraries and resources',
49 icon=ImageProvider().KW_SEARCH_ICON,
54 RideImportSetting, RideUserKeyword, RideNewProject)
59 self.
_dialog_dialog.show_search_with_criteria()
62 self.
dirtydirty =
True
65 if not self.
dirtydirty:
71 self.
dirtydirty =
False
74 def search(self, pattern, search_docs, source_filter):
82 if isinstance(item, (TestCaseFileController, ResourceFileController)):
83 callable =
lambda x: self.
_show_resource_show_resource(os.path.basename(item.source))
84 return [PopupMenuItem(
'Search Keywords', callable=callable)]
88 self.
_dialog_dialog.show_search_with_criteria(source=resource)
91 self.
_dialog_dialog.show_search_with_criteria(pattern=pattern)
99 def __init__(self, pattern='', search_docs=True, source_filter=ALL_KEYWORDS):
114 if self.
_source_filter_source_filter == ALL_USER_KEYWORDS
and kw.is_user_keyword():
116 if self.
_source_filter_source_filter == ALL_LIBRARY_KEYWORDS
and kw.is_library_keyword():
121 return utils.normalize(pattern)
in utils.normalize(string)
127 RIDEDialog.__init__(self, title=
"Search Keywords", parent=parent, size=(650, 400),
128 style=wx.DEFAULT_FRAME_STYLE | wx.FRAME_FLOAT_ON_PARENT)
130 self.SetLayoutDirection(wx.Layout_LeftToRight)
131 self.SetBackgroundColour(Colour(self.color_background))
132 self.SetForegroundColour(Colour(self.color_foreground))
138 self.CenterOnParent()
141 self.SetSizer(wx.BoxSizer(wx.VERTICAL))
145 self.SetSize((700,500))
151 self.Sizer.Add(line1, 0, wx.ALL, 3)
154 self.Sizer.Add(line2, 0, wx.ALL, 3)
157 return wx.BoxSizer(wx.HORIZONTAL)
160 sizer.Add(Label(self, label=
'Search term: '))
162 style=wx.TE_PROCESS_ENTER)
163 self.
_search_control_search_control.SetBackgroundColour(Colour(self.color_secondary_background))
164 self.
_search_control_search_control.SetForegroundColour(Colour(self.color_secondary_foreground))
168 self.
_use_doc_use_doc = wx.CheckBox(self, label=
'Search documentation')
169 self.
_use_doc_use_doc.SetValue(
True)
173 sizer.Add(Label(self, label=
'Source: '))
174 self.
_source_filter_source_filter = wx.ComboBox(self, value=ALL_KEYWORDS, size=(300, -1),
175 choices=self.
_get_sources_get_sources(), style=wx.CB_READONLY)
176 self.
_source_filter_source_filter.SetBackgroundColour(Colour(self.color_secondary_background))
177 self.
_source_filter_source_filter.SetForegroundColour(Colour(self.color_secondary_foreground))
182 for kw
in self.
_plugin_plugin.all_keywords:
183 if kw.source
not in sources:
184 sources.append(kw.source)
185 return [ALL_KEYWORDS, ALL_USER_KEYWORDS, ALL_LIBRARY_KEYWORDS] + sorted(sources)
189 self.
_list_list.SetSize(self.Size)
196 self.
_find_usages_button_find_usages_button.SetBackgroundColour(Colour(self.color_secondary_background))
197 self.
_find_usages_button_find_usages_button.SetForegroundColour(Colour(self.color_secondary_foreground))
201 self.Sizer.Add(component, 1, wx.EXPAND | wx.ALL, 3)
208 self.Bind(wx.EVT_SEARCHCTRL_SEARCH_BTN, self.
OnSearchOnSearch,
211 self.Bind(wx.EVT_ACTIVATE, self.
OnActivateOnActivate)
212 self.Bind(wx.EVT_CLOSE, self.
OnCloseOnClose)
215 self.Bind(wx.EVT_LIST_COL_CLICK, self.
OnColClickOnColClick)
218 col = event.GetColumn()
219 if self.
_sort_order_sort_order.is_sortable_column(col):
225 if self.
_plugin_plugin.have_keywords_changed():
244 self._last_selected_kw = self._keywords[event.Index]
245 self._update_details()
293 self.
_use_doc_use_doc.SetValue(search_docs)
297 if not self.IsShown():
333 headers = [
'Name',
'Source',
'Description']
335 def __init__(self, keywords, sort_order, search_criteria=None):
336 self.extend(self.
_sort_sort(keywords, sort_order, search_criteria))
338 def _sort(self, keywords, sort_order, search_criteria=None):
339 if sort_order.default_order:
340 return self.
_sort_by_search_sort_by_search(keywords, sort_order, search_criteria)
344 search_criteria = search_criteria.lower()
345 starts_with = [kw
for kw
in keywords
if kw.name.lower().startswith(search_criteria)]
346 name_contains = [kw
for kw
in keywords
if (search_criteria
in kw.name.lower()
347 and kw
not in starts_with)]
348 doc_contains = [kw
for kw
in keywords
if (search_criteria
in kw.details.lower()
349 and kw
not in starts_with
350 and kw
not in name_contains)]
352 for to_sort
in (starts_with, name_contains, doc_contains):
353 result.extend(self.
_sort_by_attr_sort_by_attr(to_sort, sort_order))
359 reverse=
not sort_order.sort_up)
363 return (a > b) - (a < b)
370 return getattr(kw, attr_name).
lower()
376 style = wx.LC_REPORT|wx.NO_BORDER|wx.LC_SINGLE_SEL|wx.LC_HRULES|wx.LC_VIRTUAL
377 wx.ListCtrl.__init__(self, parent, style=style)
378 ListCtrlAutoWidthMixin.__init__(self)
379 self.SetBackgroundColour(Colour(parent.color_background))
380 self.SetForegroundColour(Colour(parent.color_foreground))
385 self.Bind(wx.EVT_LEFT_UP, self.
OnLeftUpOnLeftUp)
388 for col, title
in enumerate(_KeywordData.headers):
389 self.InsertColumn(col, title)
390 self.SetBackgroundColour(Colour(self.GetParent().color_background))
391 self.SetForegroundColour(Colour(self.GetParent().color_foreground))
392 self.SetColumnWidth(0, 250)
395 if wx.VERSION < (4, 1, 0):
396 attr = wx.ListItemAttr()
399 attr.SetTextColour(wx.BLUE)
400 attr.SetFont(Font().underlined)
404 imglist = wx.ImageList(16, 16)
405 imglist.Add(wx.ArtProvider.GetBitmap(wx.ART_GO_UP, wx.ART_OTHER, (16, 16)))
406 self.SetImageList(imglist, wx.IMAGE_LIST_SMALL)
411 self.SetItemCount(len(self.
_keywords_keywords))
412 self.SetBackgroundColour(Colour(self.GetParent().color_secondary_background))
413 self.SetForegroundColour(Colour(self.GetParent().color_secondary_foreground))
415 index = self.
_keywords_keywords.index(kw_selection)
420 item, flags = self.HitTest(event.Position)
421 if item == wx.NOT_FOUND:
424 if kw.is_user_keyword()
and (flags & wx.LIST_HITTEST_ONITEMICON):
425 self.
_plugin_plugin.select_user_keyword_node(kw.item)
429 return [kw.name, kw.source, kw.shortdoc][col]
432 if self.
_keywords_keywords[item].is_user_keyword():
Used to create menu entries, keyboard shortcuts and/or toolbar buttons.
Entry point to RIDE plugin API – all plugins must extend this class.
def subscribe(self, listener, *topics)
Start to listen to messages with the given topics.
def unsubscribe_all(self)
Stops to listen to all messages this plugin has subscribed to.
def register_action(self, action_info)
Registers a menu entry and optionally a shortcut and a toolbar icon.
def unregister_actions(self)
Unregisters all actions registered by this plugin.
def register_search_action(self, description, handler, icon, default=False)
def OnSearch(self, event)
def _add_keyword_details(self)
def _add_pattern_filter(self, sizer)
def __init__(self, parent, searcher)
def _get_search_text(self)
def OnFindUsages(self, event)
def _add_search_control(self)
def _update_keyword_selection(self)
def _update_sources(self)
def show_search_with_criteria(self, pattern='', search_docs=True, source=ALL_KEYWORDS)
def _add_doc_filter(self, sizer)
def OnActivate(self, event)
def OnSourceFilterChange(self, event)
def _horizontal_sizer(self)
def _update_widgets(self, pattern, search_docs, source)
def _update_details(self)
def _create_components(self)
def OnItemSelected(self, event)
def _add_to_sizer(self, component)
def _get_search_criteria(self)
def _populate_search(self)
def OnColClick(self, event)
def OnUseDocChange(self, event)
def _add_source_filter(self, sizer)
def _add_keyword_list(self)
A plugin for searching keywords based on name or documentation.
def enable(self)
This method is called by RIDE when the plugin is enabled.
def _search_resource(self, item)
def show_search_for(self, pattern)
def have_keywords_changed(self)
def search(self, pattern, search_docs, source_filter)
def _show_resource(self, resource)
def disable(self)
Called by RIDE when the plugin is disabled.
def OnSearch(self, event)
def mark_dirty(self, message)
def _sort_by_search(self, keywords, sort_order, search_criteria)
def _get_comparator_for(self, atrr_name)
def __init__(self, keywords, sort_order, search_criteria=None)
def _sort_by_attr(self, keywords, sort_order)
def _sort(self, keywords, sort_order, search_criteria=None)
def _value_lowerer(self, kw, attr_name)
def OnLeftUp(self, event)
def __init__(self, parent, plugin)
def _create_image_list(self)
def _create_link_attribute(self)
def OnGetItemText(self, row, col)
def show_keywords(self, keywords, kw_selection)
def OnGetItemImage(self, item)
def _create_headers(self)
def _contains(self, string, pattern)
def _matches_source_filter(self, kw)
def __init__(self, pattern='', search_docs=True, source_filter=ALL_KEYWORDS)
def is_sortable_column(self, col)
def _has_been_sorted_by(self, col)