Coverage for src/robotide/ui/preview.py: 0%

148 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-05-06 10:40 +0100

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 

16import builtins 

17import wx 

18import wx.html 

19from io import StringIO 

20from ..pluginapi import Plugin, TreeAwarePluginMixin 

21from ..action import ActionInfo 

22from ..publish import (RideTreeSelection, RideNotebookTabChanged, RideTestCaseAdded, RideUserKeywordAdded) 

23from ..robotapi import TestCase, UserKeyword 

24from ..widgets import ButtonWithHandler, Font 

25from ..utils import Printing 

26 

27_ = wx.GetTranslation # To keep linter/code analyser happy 

28builtins.__dict__['_'] = wx.GetTranslation 

29 

30 

31class PreviewPlugin(Plugin, TreeAwarePluginMixin): 

32 __doc__ = _("""(Obsolete) Provides preview of the test data in HTML, TSV and TXT formats.""") 

33 

34 datafile = property(lambda self: self.get_selected_datafile()) 

35 

36 def __init__(self, application): 

37 Plugin.__init__(self, application, default_settings={'format': 'HTML'}) 

38 self._panel = None 

39 

40 def enable(self): 

41 self.register_action(ActionInfo(_('Tools'), _('Preview'), self.on_show_preview, 

42 shortcut='F6', 

43 doc=_('Show preview of the current file'), 

44 position=71)) 

45 self.subscribe(self.on_tree_selection, RideTreeSelection) 

46 self.subscribe(self.on_tab_changed, RideNotebookTabChanged) 

47 self.subscribe(self._update_preview, RideTestCaseAdded) 

48 self.subscribe(self._update_preview, RideUserKeywordAdded) 

49 self.add_self_as_tree_aware_plugin() 

50 

51 def disable(self): 

52 self.remove_self_from_tree_aware_plugins() 

53 self.unsubscribe_all() 

54 self.unregister_actions() 

55 self.delete_tab(self._panel) 

56 self._panel = None 

57 

58 def is_focused(self): 

59 return self.tab_is_visible(self._panel) 

60 

61 def on_show_preview(self, event): 

62 __ = event 

63 if not self._panel: 

64 self._panel = PreviewPanel(self, self.notebook) 

65 self.show_tab(self._panel) 

66 self._update_preview(None) 

67 

68 def on_tree_selection(self, message): 

69 if self.is_focused(): 

70 self._panel.tree_node_selected(message.item) 

71 

72 def on_tab_changed(self, message): 

73 _ = message 

74 self._update_preview(None) 

75 

76 def _update_preview(self, message): 

77 _ = message 

78 if self.is_focused() and self.datafile: 

79 self._panel.update_preview() 

80 

81 

82class PreviewPanel(wx.Panel): 

83 _formats = ['HTML', _('Text (Spaces)'), _('Text (Pipes)')] 

84 

85 def __init__(self, parent, notebook): 

86 wx.Panel.__init__(self, notebook) 

87 self._parent = parent 

88 main_sizer = wx.BoxSizer(wx.VERTICAL) 

89 self.SetSizer(main_sizer) 

90 self._format = parent.format 

91 self.__view = None 

92 self._printing = Printing(self) 

93 box = wx.BoxSizer(wx.HORIZONTAL) 

94 box.Add(self._chooser()) 

95 if wx.VERSION < (4, 1, 0): 

96 box.Add(self._print_button(), 1, wx.ALIGN_CENTER_VERTICAL | wx.EXPAND) 

97 else: 

98 box.Add(self._print_button(), 1, wx.EXPAND) 

99 self.Sizer.Add(box) 

100 notebook.AddPage(self, _("Preview")) 

101 

102 def on_print(self, evt): 

103 _ = evt 

104 self._printing.preview_text(self._get_content()) 

105 

106 @property 

107 def _file_format(self): 

108 if self._format == 'HTML': 

109 return self._format.lower() 

110 return 'txt' 

111 

112 @property 

113 def _pipe_separated(self): 

114 return 'Pipes' in self._format 

115 

116 def _chooser(self): 

117 chooser = wx.RadioBox(self, label=_('Format'), choices=self._formats) 

118 chooser.SetStringSelection(self._format) 

119 self.Bind(wx.EVT_RADIOBOX, self.on_type_changed, chooser) 

120 return chooser 

121 

122 def _print_button(self): 

123 return ButtonWithHandler(self, _('Print'), mk_handler='Print', handler=self.on_print) 

124 

125 @property 

126 def _view(self): 

127 view_class = HtmlView if self._file_format == 'html' else TxtView 

128 if isinstance(self.__view, view_class): 

129 return self.__view 

130 self._remove_current_view() 

131 self.__view = self._create_view(view_class) 

132 return self.__view 

133 

134 def _remove_current_view(self): 

135 if self.__view: 

136 self.Sizer.Remove(self.__view) 

137 self.__view.Destroy() 

138 

139 def _create_view(self, view_class): 

140 view = view_class(self) 

141 self.Sizer.Add(view, 1, wx.EXPAND | wx.ALL, border=8) 

142 self.Sizer.Layout() 

143 return view 

144 

145 def tree_node_selected(self, item): 

146 self.update_preview() 

147 self._view.scroll_to_subitem(item) 

148 

149 def update_preview(self): 

150 self._view.set_content(self._get_content()) 

151 

152 def _get_content(self): 

153 datafile = self._parent.datafile 

154 if not datafile: 

155 return '' 

156 output = StringIO() 

157 try: 

158 datafile.save( 

159 output=output, 

160 format=self._file_format, 

161 pipe_separated=self._pipe_separated, 

162 txt_separating_spaces=self._parent.global_settings['txt number of spaces'] 

163 ) 

164 except Exception as e: 

165 return "Creating preview of '%s' failed: %s" % (datafile.name, e) 

166 else: 

167 return output.getvalue() 

168 

169 def on_type_changed(self, event): 

170 self._format = event.String 

171 self.update_preview() 

172 self._parent.save_setting('format', self._format) 

173 

174 

175class HtmlView(wx.html.HtmlWindow): 

176 

177 def __init__(self, parent): 

178 wx.html.HtmlWindow.__init__(self, parent) 

179 self.SetStandardFonts() 

180 

181 def set_content(self, content): 

182 self.SetPage(content) 

183 

184 def scroll_to_subitem(self, item): 

185 anchor = self._get_anchor(item.data) 

186 if self.HasAnchor(anchor): 

187 self.ScrollToAnchor(anchor) 

188 self.ScrollLines(-1) 

189 else: 

190 self.Scroll(0, 0) 

191 

192 @staticmethod 

193 def _get_anchor(data): 

194 if isinstance(data, UserKeyword): 

195 return 'keyword_%s' % data.name 

196 if isinstance(data, TestCase): 

197 return 'test_%s' % data.name 

198 return '' 

199 

200 

201class TxtView(wx.TextCtrl): 

202 

203 def __init__(self, parent): 

204 wx.TextCtrl.__init__(self, parent, style=wx.TE_MULTILINE | wx.TE_NOHIDESEL) 

205 self.SetEditable(False) 

206 self.SetFont(Font().fixed) 

207 

208 def set_content(self, content): 

209 self.SetValue(content) 

210 

211 def scroll_to_subitem(self, item): 

212 """ Just ignore it """ 

213 pass