Coverage for src/robotide/ui/excludes_dialogs.py: 30%

82 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 

16from datetime import datetime 1ab

17 

18import wx 1ab

19from wx import Colour 1ab

20from wx.adv import HyperlinkCtrl, EVT_HYPERLINK 1ab

21 

22from .preferences_dialogs import PreferencesPanel 1ab

23from ..publish.messages import RideSettingsChanged 1ab

24from ..widgets import RIDEDialog, HtmlWindow 1ab

25 

26 

27class ExcludePreferences(PreferencesPanel): 1ab

28 location = 'Excludes' 1ab

29 title = 'Excludes' 1ab

30 

31 def __init__(self, settings, *args, **kwargs): 1ab

32 super(ExcludePreferences, self).__init__(*args, **kwargs) 

33 self._settings = settings 

34 self._general_settings = self._settings['General'] 

35 self.font = self.GetFont() 

36 self.font.SetFaceName(self._general_settings['font face']) 

37 self.font.SetPointSize(self._general_settings['font size']) 

38 self.SetFont(self.font) 

39 self.SetBackgroundColour(Colour(self._general_settings['background'])) 

40 self.color_secondary_background = Colour(self._general_settings['secondary background']) 

41 self.SetForegroundColour(Colour(self._general_settings['foreground'])) 

42 self.color_secondary_foreground = Colour(self._general_settings['secondary foreground']) 

43 self._create_sizer() 

44 

45 def _create_sizer(self): 1ab

46 sizer = wx.BoxSizer(orient=wx.VERTICAL) 

47 self._add_help_dialog(sizer) 

48 self._add_fs_exclusion_help(sizer) 

49 self._add_text_box(sizer) 

50 self._add_button_and_status(sizer) 

51 self.SetSizer(sizer) 

52 

53 def _add_help_dialog(self, sizer): 1ab

54 need_help = HyperlinkCtrl(self, wx.ID_ANY, '', 'Need help?') 

55 need_help.SetBackgroundColour(Colour(self.color_secondary_background)) 

56 need_help.SetForegroundColour(Colour(self.color_secondary_foreground)) 

57 sizer.Add(need_help) 

58 self.Bind(EVT_HYPERLINK, self.on_help) 

59 

60 def _add_fs_exclusion_help(self, sizer): 1ab

61 exclude_help = wx.StaticText(self, label='Since v2.0.8, files are also excluded from filesystem' 

62 ' monitoring changes.') 

63 exclude_help.SetBackgroundColour(Colour(self._general_settings['background'])) 

64 exclude_help.SetForegroundColour(Colour(self._general_settings['foreground'])) 

65 sizer.Add(exclude_help) 

66 

67 def _add_text_box(self, sizer): 1ab

68 self._text_box = wx.TextCtrl(self, style=wx.TE_MULTILINE | wx.TE_NOHIDESEL, size=wx.Size(570, 100), 

69 value=self._settings.excludes.get_excludes()) 

70 self._text_box.SetBackgroundColour(Colour(self.color_secondary_background)) 

71 self._text_box.SetForegroundColour(Colour(self.color_secondary_foreground)) 

72 sizer.Add(self._text_box, proportion=wx.EXPAND) 

73 

74 def _add_button_and_status(self, sizer): 1ab

75 # DEBUG wxPhoenix 

76 status_and_button_sizer = wx.GridSizer(rows=1, cols=2, vgap=10, hgap=10) 

77 save_button = wx.Button(self, id=wx.ID_SAVE) 

78 save_button.SetBackgroundColour(Colour(self.color_secondary_background)) 

79 save_button.SetForegroundColour(Colour(self.color_secondary_foreground)) 

80 status_and_button_sizer.Add(save_button) 

81 self.Bind(wx.EVT_BUTTON, self.on_save) 

82 self._status_label = wx.StaticText(self) 

83 status_and_button_sizer.Add(self._status_label) 

84 sizer.Add(status_and_button_sizer) 

85 

86 def on_save(self, event): 1ab

87 __ = event 

88 text = self._text_box.GetValue() 

89 self._settings.excludes.write_excludes(set(text.split('\n'))) 

90 RideSettingsChanged(keys=('Excludes', 'saved'), old=None, new=None).publish() 

91 save_label = 'Saved at %s. Reload the project for changes to take an effect.' %\ 

92 datetime.now().strftime('%H:%M:%S') 

93 self._status_label.SetLabel(save_label) 

94 

95 @staticmethod 1ab

96 def on_help(event): 1ab

97 __ = event 

98 dialog = ExcludeHelpDialog() 

99 dialog.Show() 

100 

101 

102class ExcludeHelpDialog(RIDEDialog): 1ab

103 def _execute(self): 1ab

104 """ Just ignore it """ 

105 pass 

106 

107 help = """<font size="5"> 1ab

108<h1>Excludes</h1> 

109<p> 

110Paths to excludes are described in the text box, one exclude per row. 

111These excludes are saved in a file which is located at $HOME/.robotframework/ride/excludes on POSIX-systems and 

112%APPDATA%\\RobotFramework\\ride\\excludes on Windows. 

113</p> 

114<p> 

115You can edit excludes yourself using either the text box or editing the file with an editor. After hitting "Save", close 

116the Preferences window and reload the project to make the edited exludes to take effect. You can reload the project by 

117selecting "File" from the main menu bar and then selecting your project from the list in view. 

118</p> 

119<h2>Patterns in paths</h2> 

120<p> 

121RIDE supports defining excludes with absolute paths. You can achieve relative paths with path patterns which are 

122also supported. 

123</p> 

124<p> 

125The following shell-style wildcards are supported: 

126<table width="100%" border="1"> 

127 <thead> 

128 <th><b>Pattern</b></th> 

129 <th><b>Meaning</b></th> 

130 <th><b>Examples</b></th> 

131 </thead> 

132 <tbody> 

133 <tr> 

134 <td valign="top" align="center">*</td> 

135 <td valign="top" align="center">matches everything</td> 

136 <td valign="top" align="left"> 

137 Pattern /foo/*/quu matches: 

138 <ul> 

139 <li>/foo/bar/quu</li> 

140 <li>/foo/corge/quu</li> 

141 <li><i>etc.</i></li> 

142 </ul> 

143 </td> 

144 </tr> 

145 <tr> 

146 <td valign="top" align="center">?</td> 

147 <td valign="top" align="center">matches any single character</td> 

148 <td valign="top" align="left"> 

149 Pattern C:\\MyProject\\?oo matches: 

150 <ul> 

151 <li>C:\\MyProject\\foo</li> 

152 <li>C:\\MyProject\\boo</li> 

153 <li><i>etc.</i></li> 

154 </ul> 

155 </td> 

156 </tr> 

157 <tr> 

158 <td valign="top" align="center">[seq]</td> 

159 <td valign="top" align="center">matches any character in <i>seq</i></td> 

160 <td valign="top" align="left"> 

161 Pattern C:\\MyProject\\[bf]oo matches: 

162 <ul> 

163 <li>C:\\MyProject\\foo</li> 

164 <li>C:\\MyProject\\boo</li> 

165 <li><i>and nothing else</i></li> 

166 </ul> 

167 </td> 

168 </tr> 

169 <tr> 

170 <td valign="top" align="center">[!seq]</td> 

171 <td valign="top" align="center">matches any character not in <i>seq</i></td> 

172 <td valign="top" align="left"> 

173 Pattern /foo/[!q]uu matches: 

174 <ul> 

175 <li>/foo/zuu</li> 

176 <li><i>etc.</i></li> 

177 </ul> 

178 But does not match: 

179 <ul> 

180 <li>/foo/quu</li> 

181 </ul> 

182 </td> 

183 </tr> 

184 </tbody> 

185</table> 

186</p> 

187</font>""" 

188 

189 def __init__(self): 1ab

190 RIDEDialog.__init__(self, title='Help: excludes') 

191 # set Left to Right direction (while we don't have localization) 

192 self.SetLayoutDirection(wx.Layout_LeftToRight) 

193 sizer = wx.BoxSizer(wx.VERTICAL) 

194 sizer.Add(HtmlWindow(self, (800, 600), self.help), 

195 1, 

196 flag=wx.EXPAND) 

197 self.SetSizerAndFit(sizer) 

198 

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

200 """ Just ignore it """ 

201 pass 

202 

203 def close(self): 1ab

204 self.Destroy()