Coverage for src/robotide/editor/__init__.py: 62%

202 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 1ab

17import wx 1ab

18 

19from .editorcreator import EditorCreator 1ab

20from ..pluginapi import (Plugin, action_info_collection, TreeAwarePluginMixin) 1ab

21from ..publish import (RideTreeSelection, RideNotebookTabChanging, RideNotebookTabChanged, RideSaving) 1ab

22from ..publish.messages import RideDataFileRemoved 1ab

23from ..widgets import PopupCreator 1ab

24 

25_ = wx.GetTranslation # To keep linter/code analyser happy 1ab

26builtins.__dict__['_'] = wx.GetTranslation 1ab

27 

28 

29def get_menudata(): 1ab

30 # Menus to translate 

31 edit_0 = _("[Edit]\n") 1ac

32 edit_1 = _("&Undo | Undo last modification | Ctrlcmd-Z\n") 1ac

33 edit_2 = _("&Redo | Redo modification | Ctrlcmd-Y\n") 1ac

34 SEPARATOR = "---\n" 1ac

35 edit_3 = _("Cu&t | Cut | Ctrlcmd-X\n") 1ac

36 edit_4 = _("&Copy | Copy | Ctrlcmd-C\n") 1ac

37 edit_5 = _("&Paste | Paste | Ctrlcmd-V\n") 1ac

38 edit_6 = _("&Insert | Insert | Shift-Ctrl-V\n") 1ac

39 edit_7 = _("&Delete | Delete | Del\n") 1ac

40 edit_8 = _("Comment Rows | Comment selected rows | Ctrlcmd-3\n") 1ac

41 edit_9 = _("Comment Cells | Comment cells with # | Ctrlcmd-Shift-3\n") 1ac

42 edit_10 = _("Uncomment Rows | Uncomment selected rows | Ctrlcmd-4\n") 1ac

43 edit_11 = _("Uncomment Cells | Uncomment cells with # | Ctrlcmd-Shift-4\n") 1ac

44 edit_12 = _("Insert Cells | Insert Cells | Ctrlcmd-Shift-I\n") 1ac

45 edit_13 = _("Delete Cells | Delete Cells | Ctrlcmd-Shift-D\n") 1ac

46 edit_14 = _("Insert Rows | Insert Rows | Ctrlcmd-I\n") 1ac

47 edit_15 = _("Delete Rows | Delete Rows | Ctrlcmd-D\n") 1ac

48 edit_16 = _("Move Rows Up | Move Rows Up | Alt-Up\n") 1ac

49 edit_17 = _("Move Rows Down | Move Rows Down | Alt-Down\n") 1ac

50 tools_0 = _("[Tools]\n") 1ac

51 tools_1 = _("Content Assistance (Ctrl-Space or Ctrl-Alt-Space) | Show possible keyword and variable completions" 1ac

52 " | | | POSITION-70\n") 

53 

54 return (edit_0 + edit_1 + edit_2 + SEPARATOR + edit_3 + edit_4 + edit_5 + edit_6 + edit_7 + SEPARATOR + 1ac

55 edit_8 + edit_9 + edit_10 + edit_11 + SEPARATOR + edit_12 + edit_13 + edit_14 + edit_15 + edit_16 + 

56 edit_17 + tools_0 + tools_1) 

57 

58 

59_EDIT_nt = """[Edit] 1ab

60&Undo | Undo last modification | Ctrlcmd-Z 

61&Redo | Redo modification | Ctrlcmd-Y 

62--- 

63Cu&t | Cut | Ctrlcmd-X 

64&Copy | Copy | Ctrlcmd-C 

65&Paste | Paste | Ctrlcmd-V 

66&Insert | Insert | Shift-Ctrl-V 

67&Delete | Delete | Del 

68--- 

69Comment Rows | Comment selected rows | Ctrlcmd-3 

70Comment Cells | Comment cells with # | Ctrlcmd-Shift-3 

71Uncomment Rows | Uncomment selected rows | Ctrlcmd-4 

72Uncomment Cells | Uncomment cells with # | Ctrlcmd-Shift-4 

73--- 

74Insert Cells | Insert Cells | Ctrlcmd-Shift-I 

75Delete Cells | Delete Cells | Ctrlcmd-Shift-D 

76Insert Rows | Insert Rows | Ctrlcmd-I 

77Delete Rows | Delete Rows | Ctrlcmd-D 

78Move Rows Up | Move Rows Up | Alt-Up 

79Move Rows Down | Move Rows Down | Alt-Down 

80[Tools] 

81Content Assistance (Ctrl-Space or Ctrl-Alt-Space) | Show possible keyword and variable completions | | | POSITION-70 

82""" 

83 

84 

85class EditorPlugin(Plugin, TreeAwarePluginMixin): 1ab

86 

87 def __init__(self, application): 1ab

88 self.__doc__ = _("""The default editor plugin. Also known as Grid or Cell Editor. 

89 

90 This plugin implements editors for the various items of Robot Framework 

91 test data. 

92 """) 

93 Plugin.__init__(self, application, name='Editor') 

94 self._tab = None 

95 self.name = _('Editor') 

96 self.grid_popup_creator = PopupCreator() 

97 self._creator = EditorCreator(self.register_editor) 

98 self._editor = None 

99 

100 def enable(self): 1ab

101 self._creator.register_editors() 

102 self._show_editor() 

103 _menudata = get_menudata() 

104 self.register_actions(action_info_collection(_menudata, self._tab, data_nt=_EDIT_nt, container=self._tab)) 

105 self.subscribe(self.on_tree_item_selected, RideTreeSelection) 

106 self.subscribe(self.on_tab_changed, RideNotebookTabChanged) 

107 self.subscribe(self.on_tab_changing, RideNotebookTabChanging) 

108 self.subscribe(self.on_save_to_model, RideSaving) 

109 self.subscribe(self.on_file_deleted, RideDataFileRemoved) 

110 self.add_self_as_tree_aware_plugin() 

111 

112 def disable(self): 1ab

113 self.remove_self_from_tree_aware_plugins() 

114 self.unsubscribe_all() 

115 self.delete_tab(self._tab) 

116 wx.CallLater(500, self.unregister_actions()) 

117 self._tab = None 

118 self._editor = None 

119 

120 def is_focused(self): 1ab

121 return self.tab_is_visible(self._tab) 

122 

123 def highlight_cell(self, obj, row, column): 1ab

124 self.show() 

125 self._editor.highlight_cell(obj, row, column) 

126 

127 def highlight(self, text): 1ab

128 self.show() 

129 self._editor.highlight(text) 

130 

131 def show(self): 1ab

132 self.show_tab(self._tab) 

133 

134 def register_context_menu_hook_to_grid(self, hook): 1ab

135 """ Used to register own items to grid's right click context menu 

136 

137 hook is called with current selection (list of list containing 

138 values) and it is expected to return list of PopupMenuItem. 

139 If user selects one of the returned PopupMenuItem, related function 

140 is called with one argument, the wx event. 

141 """ 

142 self.grid_popup_creator.add_hook(hook) 

143 

144 def unregister_context_menu_hook_to_grid(self, hook): 1ab

145 self.grid_popup_creator.remove_hook(hook) 

146 

147 def _show_editor(self): 1ab

148 if not self._tab: 

149 self._tab = _EditorTab(self) 

150 self.add_tab(self._tab, self._tab.plugin.name, allow_closing=False) 

151 if self.is_focused(): 

152 self._editor = self._create_editor() 

153 self._tab.show_editor(self._editor) 

154 

155 def _create_editor(self): 1ab

156 return self._creator.editor_for(self, self._tab, self.tree) 

157 

158 def on_tree_item_selected(self, message): 1ab

159 self._show_editor() 

160 if not self.is_focused() and \ 

161 not self.is_focus_on_tree_aware_plugin() and \ 

162 (not message or not message.silent): 

163 self._editor = self._create_editor() 

164 self._tab.show_editor(self._editor) 

165 self.show() 

166 if self._editor: 

167 self._editor.tree_item_selected(message.item) 

168 

169 def get_selected_datafile(self): 1ab

170 if self._editor and self._editor.controller: 170 ↛ 171line 170 didn't jump to line 171 because the condition on line 170 was never true

171 return self._editor.controller.datafile 

172 return Plugin.get_selected_datafile(self) 

173 

174 def on_open_editor(self, event): 1ab

175 __ = event 

176 self._show_editor() 

177 

178 def on_tab_changed(self, message): 1ab

179 __ = message 

180 self._show_editor() 

181 

182 def on_tab_changing(self, message): 1ab

183 if 'Editor' in message.oldtab: 183 ↛ exitline 183 didn't return from function 'on_tab_changing' because the condition on line 183 was always true

184 self._tab.save() 

185 

186 def on_save_to_model(self, message): 1ab

187 __ = message 

188 if self._tab: 

189 self._tab.save() 

190 

191 def on_file_deleted(self, message): 1ab

192 __ = message 

193 self._create_editor() 

194 

195 

196class _EditorTab(wx.Panel): 1ab

197 

198 def __init__(self, plugin): 1ab

199 wx.Panel.__init__(self, plugin.notebook, style=wx.SUNKEN_BORDER) 

200 self.plugin = plugin 

201 self.sizer = wx.BoxSizer(wx.VERTICAL) 

202 self.SetSizer(self.sizer) 

203 """ 

204 self.SetBackgroundColour(Colour(200, 222, 40)) 

205 self.SetOwnBackgroundColour(Colour(200, 222, 40)) 

206 self.SetForegroundColour(Colour(7, 0, 70)) 

207 self.SetOwnForegroundColour(Colour(7, 0, 70)) 

208 """ 

209 self.Refresh(True) 

210 self.editor = None 

211 

212 def show_editor(self, editor): 1ab

213 if editor is None: 

214 return 

215 if editor is self.editor: 215 ↛ 216line 215 didn't jump to line 216 because the condition on line 215 was never true

216 self.Show(True) 

217 return 

218 self.sizer.Clear() 

219 self.editor = editor 

220 self.sizer.Add(self.editor, 1, wx.ALL | wx.EXPAND) 

221 self.Layout() 

222 self.Show(True) 

223 

224 def hide_editor(self): 1ab

225 self.Show(False) 

226 

227 def on_save(self, event): 1ab

228 __ = event 

229 self.plugin.save_selected_datafile() 

230 

231 def on_undo(self, event): 1ab

232 __ = event 

233 self.editor.undo() 

234 

235 def on_redo(self, event): 1ab

236 __ = event 

237 self.editor.redo() 

238 

239 def on_cut(self, event): 1ab

240 __ = event 

241 self.editor.cut() 

242 

243 def on_copy(self, event): 1ab

244 __ = event 

245 self.editor.copy() 

246 

247 def on_paste(self, event): 1ab

248 __ = event 

249 self.editor.paste() 

250 

251 def on_insert(self, event): 1ab

252 __ = event 

253 self.editor.insert() 

254 

255 def on_insert_cells(self, event): 1ab

256 __ = event 

257 self.editor.insert_cells() 

258 

259 def on_delete_cells(self, event): 1ab

260 __ = event 

261 # print("DEBUG init delete cells call") 

262 self.editor.delete_cells() 

263 

264 def on_insert_rows(self, event): 1ab

265 __ = event 

266 self.editor.insert_rows() 

267 

268 def on_delete_rows(self, event): 1ab

269 __ = event 

270 wx.CallAfter(self.editor.delete_rows) 

271 

272 def on_move_rows_up(self, event): 1ab

273 __ = event 

274 self.editor.on_move_rows_up() 

275 

276 def on_move_rows_down(self, event): 1ab

277 __ = event 

278 self.editor.on_move_rows_down() 

279 

280 def on_delete(self, event): 1ab

281 __ = event 

282 self.editor.delete() 

283 

284 def on_comment_rows(self, event): 1ab

285 __ = event 

286 self.editor.comment_rows() 

287 

288 def on_uncomment_rows(self, event): 1ab

289 __ = event 

290 self.editor.uncomment_rows() 

291 

292 def on_sharp_comment_rows(self, event): 1ab

293 __ = event 

294 self.editor.sharp_comment_rows() 

295 

296 def on_sharp_uncomment_rows(self, event): 1ab

297 __ = event 

298 self.editor.sharp_uncomment_rows() 

299 

300 def on_comment_cells(self, event): 1ab

301 __ = event 

302 self.editor.comment_cells() 

303 

304 def on_uncomment_cells(self, event): 1ab

305 __ = event 

306 self.editor.uncomment_cells() 

307 

308 def on_content_assistance(self, event): 1ab

309 __ = event 

310 self.editor.show_content_assist() 

311 

312 def save(self, message=None): 1ab

313 __ = message 

314 if self.editor: 314 ↛ 315line 314 didn't jump to line 315 because the condition on line 314 was never true

315 self.editor.save() 

316 

317 def on_key(self, *args): 1ab

318 """ Intentional override """ 

319 pass