Robot Framework Integrated Development Environment (RIDE)
pluginmanager.py
Go to the documentation of this file.
1 # Copyright 2008-2015 Nokia Networks
2 # Copyright 2016- Robot Framework Foundation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 import wx
17 from wx import Colour
18 from wx.adv import HyperlinkCtrl
19 from wx.lib.scrolledpanel import ScrolledPanel
20 
21 from ..context import LOG
22 from ..publish import RideLogException
23 from ..widgets import Label, RIDEDialog
24 
25 
26 class PluginManager():
27 
28  def __init__(self, notebook):
29  self._notebook_notebook = notebook
30  self._panel_panel = None
31 
32  def show(self, plugins):
33  if not self._panel_panel:
34  self._panel_panel = _PluginPanel(self._notebook_notebook.GetParent(), plugins, self._show_panel_show_panel)
35  self._show_panel_show_panel()
36 
37  def _show_panel(self):
38  self._panel_panel.Show()
39 
40 
41 class _PluginPanel(RIDEDialog):
42 
43  def __init__(self, notebook, plugins, activation_callback):
44  RIDEDialog.__init__(self, parent=notebook, title="Manage Plugins", size=(800, 600))
45  self.SetBackgroundColour(Colour(self.color_background))
46  self.SetForegroundColour(Colour(self.color_foreground))
47  sizer = wx.BoxSizer(wx.VERTICAL)
48  sizer.Add(self._create_header_create_header(), 0, flag=wx.EXPAND | wx.LEFT |
49  wx.RIGHT | wx.TOP, border=16)
50  sizer.Add(self._create_info_text_create_info_text(), 0,
51  flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=16)
52  sizer.Add(self._create_line_create_line(), 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT)
53  sizer.Add(self._create_body_create_body(plugins, activation_callback), 1,
54  flag=wx.EXPAND | wx.ALL, border=16)
55  self.SetSizer(sizer)
56  self.CenterOnParent()
57 
58  def _create_header(self):
59  header = Label(self, wx.ID_ANY, "Installed Plugins\n")
60  self.fontfont = self.GetFont()
61  self.fontfont.SetPointSize(self.font_size)
62  if self.font_facefont_face is None:
63  self.font_facefont_face = self.fontfont.GetFaceName()
64  else:
65  self.fontfont.SetFaceName(self.font_facefont_face)
66  self.SetFont(self.fontfont)
67  header.SetFont(wx.Font(wx.FontInfo(14 if self.font_size<=11 else self.font_size + 3).Bold()))
68  return header
69 
70  def _create_line(self):
71  return wx.StaticLine(self)
72 
73  def _create_body(self, plugins, activation_callback):
74  panel = ScrolledPanel(self, wx.ID_ANY, style=wx.TAB_TRAVERSAL | wx.SIZE_AUTO)
75  panel.SetupScrolling()
76  sizer = wx.FlexGridSizer(0, 2, hgap=8, vgap=8)
77  sizer.AddGrowableCol(1, 1)
78  sizer.Add(self._create_label_create_label(panel, 'Enabled'), 0, wx.BOTTOM, border=8)
79  sizer.Add(self._create_label_create_label(panel, 'Plugin'), 0, wx.BOTTOM | wx.EXPAND, border=8)
80  for plugin in sorted(plugins, key=lambda p: p.name):
81  sizer.Add(_PluginEnablationCheckBox(panel, plugin,
82  activation_callback),
83  flag=wx.ALIGN_CENTER_HORIZONTAL)
84  sizer.Add(_PluginRow(panel, plugin), 0, wx.EXPAND)
85  panel.SetSizer(sizer)
86  return panel
87 
88  def _create_info_text(self):
89  info = wx.StaticText(self, wx.ID_ANY,
90  "Info. Enabling and disabling plugins might"
91  " require RIDE restart "
92  "for menus to work.")
93  info.SetFont(wx.Font(wx.FontInfo(12).Family(wx.FONTFAMILY_SWISS).Bold(False)))
94  return info
95 
96  def _create_label(self, parent, text):
97  boldFont = self.GetFont()
98  # boldFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
99  if self.font_facefont_face:
100  boldFont.SetFaceName(self.font_facefont_face)
101  boldFont.SetWeight(wx.FONTWEIGHT_BOLD)
102  boldFont.SetPointSize(self.font_size)
103  label = Label(parent, wx.ID_ANY, text)
104  label.SetFont(boldFont)
105  return label
106 
107 
108 class _PluginEnablationCheckBox(wx.CheckBox):
109 
110  def __init__(self, parent, plugin, activation_callback):
111  wx.CheckBox.__init__(self, parent)
112  self.SetValue(plugin.enabled)
113  self.Bind(wx.EVT_CHECKBOX, self.OnCheckBoxOnCheckBox)
114  if plugin.error:
115  self.Enable(False)
116  self._plugin_plugin = plugin
117  self._callback_callback = activation_callback
118 
119  def OnCheckBox(self, event):
120  if event.IsChecked():
121  self._execute_execute(self._plugin_plugin.enable)
122  else:
123  self._execute_execute(self._plugin_plugin.disable)
124  self._callback_callback()
125 
126  def _execute(self, method):
127  try:
128  method()
129  except Exception as err:
130  self.SetValue(False)
131  self.Enable(False)
132  msg = 'Failed to %s plugin %s:\n%s\n\nYou should restart RIDE now!' % (method.__name__,
133  self._plugin_plugin.name,
134  err)
135  self._plugin_plugin.error = err
136  self._plugin_plugin.doc = msg
137  LOG.error(msg)
138  RideLogException(message=msg, exception=err, level='ERROR').publish()
139 
140 
141 class _PluginRow(wx.Panel):
142 
143  def __init__(self, parent, plugin):
144  wx.Panel.__init__(self, parent)
145  sizer = wx.BoxSizer(wx.VERTICAL)
146  sizer.Add(self._get_name_get_name(plugin))
147  for name, value in plugin.metadata.items():
148  sizer.Add(self._get_metadata_get_metadata(name, value))
149  sizer.Add(self._get_description_get_description(plugin), 0, wx.EXPAND)
150  config = plugin.config_panel(self)
151  if config:
152  sizer.Add(config, 1, wx.EXPAND | wx.LEFT, border=16)
153  self.SetSizer(sizer)
154 
155  def _get_name(self, plugin):
156  return Label(self, label=plugin.name)
157 
158  def _get_metadata(self, name, value):
159  sizer = wx.BoxSizer(wx.HORIZONTAL)
160  sizer.Add(Label(self, label='%s: ' % name))
161  if value.split('://')[0] in ['http', 'https']:
162  sizer.Add(HyperlinkCtrl(self, -1, label=value, url=value))
163  else:
164  sizer.Add(Label(self, label=value))
165  return sizer
166 
167  def _get_description(self, plugin):
168  desc = Label(self, label=plugin.doc)
169  if plugin.error:
170  desc.SetForegroundColour("firebrick")
171  return desc
This class represents a general purpose log message with a traceback appended to message text.
Definition: messages.py:117
def __init__(self, parent, plugin, activation_callback)
def _create_body(self, plugins, activation_callback)
def _create_label(self, parent, text)
def __init__(self, notebook, plugins, activation_callback)
def _get_metadata(self, name, value)
def __init__(self, parent, plugin)