Package Gnumed :: Package timelinelib :: Package wxgui :: Package components :: Module search |
[frames] | no frames]

# Source Code for Module Gnumed.timelinelib.wxgui.components.search

      1  # Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018  Rickard Lindberg, Roger Lindberg
      2  #
      3  # This file is part of Timeline.
      4  #
      5  # Timeline is free software: you can redistribute it and/or modify
      6  # it under the terms of the GNU General Public License as published by
      7  # the Free Software Foundation, either version 3 of the License, or
      8  # (at your option) any later version.
      9  #
     10  # Timeline is distributed in the hope that it will be useful,
     11  # but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  # GNU General Public License for more details.
     14  #
     15  # You should have received a copy of the GNU General Public License
     16  # along with Timeline.  If not, see <http://www.gnu.org/licenses/>.
     17
     18
     19  import os.path
     20
     21  import wx
     22
     23  from timelinelib.config.paths import ICONS_DIR
     24  from timelinelib.wxgui.dialogs.eventlist.view import EventListDialog
     25
     26
     27 -class GuiCreator(object):
     28
     29 -    def _create_gui(self):
     30          self.icon_size = (16, 16)
     31          self._create_close_button()
     32          self._create_search_box()
     33          self._create_prev_button()
     34          self._create_next_button()
     35          self._create_list_button()
     36          self._create_no_match_label()
     37          self._create_single_match_label()
     38          self.Realize()
     39
     40 -    def set_focus(self):
     41          self.search.SetFocus()
     42
     43 -    def _create_search_box(self):
     44          self.search = wx.SearchCtrl(self, size=(150, -1),
     45                                      style=wx.TE_PROCESS_ENTER)
     46          self.Bind(wx.EVT_SEARCHCTRL_SEARCH_BTN,
     47                    self._search_on_search_btn, self.search)
     48          self.Bind(wx.EVT_TEXT_ENTER, self._search_on_text_enter, self.search)
     49          self.AddControl(self.search)
     50
     51 -    def _create_close_button(self):
     52          if 'wxMSW' in wx.PlatformInfo:
     53              close_bmp = wx.Bitmap(os.path.join(ICONS_DIR, "close.png"))
     54          else:
     55              close_bmp = wx.ArtProvider.GetBitmap(wx.ART_CROSS_MARK, wx.ART_TOOLBAR, self.icon_size)
     56          self.AddLabelTool(wx.ID_CLOSE, "", close_bmp, shortHelp="")
     57          self.Bind(wx.EVT_TOOL, self._btn_close_on_click, id=wx.ID_CLOSE)
     58
     59 -    def _create_prev_button(self):
     60          prev_bmp = wx.ArtProvider.GetBitmap(wx.ART_GO_BACK, wx.ART_TOOLBAR,
     61                                              self.icon_size)
     62          self.AddLabelTool(wx.ID_BACKWARD, "", prev_bmp, shortHelp="")
     63          self.Bind(wx.EVT_TOOL, self._btn_prev_on_click, id=wx.ID_BACKWARD)
     64
     65 -    def _create_next_button(self):
     66          next_bmp = wx.ArtProvider.GetBitmap(wx.ART_GO_FORWARD, wx.ART_TOOLBAR, self.icon_size)
     67          self.AddLabelTool(wx.ID_FORWARD, "", next_bmp, shortHelp="")
     68          self.Bind(wx.EVT_TOOL, self._btn_next_on_click, id=wx.ID_FORWARD)
     69
     70 -    def _create_list_button(self):
     71          list_bmp = wx.ArtProvider.GetBitmap(wx.ART_LIST_VIEW, wx.ART_TOOLBAR, self.icon_size)
     72          self.AddLabelTool(wx.ID_MORE, "", list_bmp, shortHelp="")
     73          self.Bind(wx.EVT_TOOL, self._btn_list_on_click, id=wx.ID_MORE)
     74
     75 -    def _create_no_match_label(self):
     76          self.lbl_no_match = wx.StaticText(self, label=_("No match"))
     77          self.lbl_no_match.Show(False)
     78          self.AddControl(self.lbl_no_match)
     79
     80 -    def _create_single_match_label(self):
     81          self.lbl_single_match = wx.StaticText(self, label=_("Only one match"))
     82          self.lbl_single_match.Show(False)
     83          self.AddControl(self.lbl_single_match)
     84
     85 -    def _btn_close_on_click(self, e):
     86          self.Show(False)
     87          self.GetParent().Layout()
     88
     89 -    def _search_on_search_btn(self, e):
     90          self.controller.search()
     91
     92 -    def _search_on_text_enter(self, e):
     93          self.controller.search()
     94
     95 -    def _btn_prev_on_click(self, e):
     96          self.controller.prev()
     97
     98 -    def _btn_next_on_click(self, e):
     99          self.controller.next()
    100
    101 -    def _btn_list_on_click(self, e):
    102          self.controller.list()
    103
    104
    105 -class SearchBarController(object):
    106
    107 -    def __init__(self, view):
    108          self.view = view
    109          self.result = []
    110          self.result_index = 0
    111          self.last_search = None
    112
    113 -    def set_timeline_canvas(self, timeline_canvas):
    114          self.timeline_canvas = timeline_canvas
    115          self.view.Enable(timeline_canvas is not None)
    116
    117 -    def search(self):
    118          new_search = self.view.get_value()
    119          if self.last_search is not None and self.last_search == new_search:
    120              self.next()
    121          else:
    122              self.last_search = new_search
    123              if self.timeline_canvas is not None:
    124                  self.result = self.timeline_canvas.get_filtered_events(new_search)
    125              else:
    126                  self.result = []
    127              self.result_index = 0
    128              self.navigate_to_match()
    129              self.view.update_nomatch_labels(len(self.result) == 0)
    130              self.view.update_singlematch_label(len(self.result) == 1)
    131          self.view.update_buttons()
    132
    133 -    def next(self):
    134          if not self._on_last_match():
    135              self.result_index += 1
    136              self.navigate_to_match()
    137              self.view.update_buttons()
    138
    139 -    def prev(self):
    140          if not self._on_first_match():
    141              self.result_index -= 1
    142              self.navigate_to_match()
    143              self.view.update_buttons()
    144
    145 -    def list(self):
    146          event_list = [event.get_label(self.timeline_canvas.GetTimeType()) for event in self.result]
    147          dlg = EventListDialog(self.view, event_list)
    148          if dlg.ShowModal() == wx.ID_OK:
    149              self.result_index = dlg.GetSelectedIndex()
    150              self.navigate_to_match()
    151          dlg.Destroy()
    152
    153 -    def navigate_to_match(self):
    154          if (self.timeline_canvas is not None and self.result_index in range(len(self.result))):
    155              event = self.result[self.result_index]
    156              self.timeline_canvas.Navigate(lambda tp: tp.center(event.mean_time()))
    157              self.timeline_canvas.highligt_event(event, clear=True)
    158
    159 -    def enable_backward(self):
    160          return bool(self.result and self.result_index > 0)
    161
    162 -    def enable_forward(self):
    163          return bool(self.result and self.result_index < (len(self.result) - 1))
    164
    165 -    def enable_list(self):
    166          return bool(len(self.result) > 0)
    167
    168 -    def _on_first_match(self):
    169          return self.result > 0 and self.result_index == 0
    170
    171 -    def _on_last_match(self):
    172          return self.result > 0 and self.result_index == (len(self.result) - 1)
    173
    174
    175 -class SearchBar(wx.ToolBar, GuiCreator):
    176
    177 -    def __init__(self, parent):
    178          wx.ToolBar.__init__(self, parent, style=wx.TB_HORIZONTAL | wx.TB_BOTTOM)
    179          self.controller = SearchBarController(self)
    180          self._create_gui()
    181          self.update_buttons()
    182
    183 -    def set_timeline_canvas(self, timeline_canvas):
    184          self.controller.set_timeline_canvas(timeline_canvas)
    185
    186 -    def get_value(self):
    187          return self.search.GetValue()
    188
    189 -    def update_nomatch_labels(self, nomatch):
    190          self.lbl_no_match.Show(nomatch)
    191
    192 -    def update_singlematch_label(self, singlematch):
    193          self.lbl_single_match.Show(singlematch)
    194
    195 -    def update_buttons(self):
    196          self.EnableTool(wx.ID_BACKWARD, self.controller.enable_backward())
    197          self.EnableTool(wx.ID_FORWARD, self.controller.enable_forward())
    198          self.EnableTool(wx.ID_MORE, self.controller.enable_list())
    199