def setUp(self): self.app = wx.App() self.frame = wx.Frame(None) self._model = self._create_model() self._tree = Tree( self.frame, ActionRegisterer(AuiManager(self.frame), MenuBar(self.frame), ToolBar(self.frame), ShortcutRegistry(self.frame))) images = TreeImageList() self._tree._images = images self._tree.SetImageList(images) self._tree.populate(self._model) self._expand_all()
def setUp(self): settings = FakeSettings() self.app = wx.App() self.frame = wx.Frame(None) self.frame.tree = Tree( self.frame, ActionRegisterer(AuiManager(self.frame), MenuBar(self.frame), ToolBar(self.frame), ShortcutRegistry(self.frame)), settings) self.frame.Show() self._tags_list = utils.NormalizedDict() self._tags_list = { "tag-11": [1, 2], "tag-02": [3], "tag-12": [4, 8, 12], "tag-2": [5, 6, 7], "tag-3": [9], "tag-21": [10, 11, 12], "tag-22": [10], "tag-1": [14], "tag-03": [15], "a-01-a2": [1], "08-b": [2], "3-2-1-tag-2c": [3, 6, 8], "8-B-1": [3, 4, 5], "2-b": [7, 3], "a-1-a3": [8, 9, 10, 11], "3-2-03-tag-2a": [12], "a-01-a03": [1], "b-1-a01": [2], "b-01-a01": [15] } self.model = self._create_model() self._tagsdialog = _ViewAllTagsDialog(self.frame, self.model)
def _init_ui(self): # self._mgr.AddPane(wx.Panel(self), aui.AuiPaneInfo().CenterPane()) ##### self.splitter = wx.SplitterWindow(self, style=wx.SP_LIVE_UPDATE) # self._mgr.AddPane(wx.Panel(self), aui.AuiPaneInfo().CenterPane()) # set up default notebook style self._notebook_style = aui.AUI_NB_DEFAULT_STYLE | \ aui.AUI_NB_TAB_EXTERNAL_MOVE | wx.NO_BORDER # TODO self._notebook_theme = 0 (allow to select themes for notebooks) # self.notebook = NoteBook(self.splitter, self._application, # self._notebook_style) self.notebook = NoteBook(self, self._application, self._notebook_style) self._mgr.AddPane(self.notebook, aui.AuiPaneInfo().Name("notebook_editors"). CenterPane().PaneBorder(False)) ################ Test # self._mgr.AddPane(self.CreateTextCtrl(), # aui.AuiPaneInfo().Name("text_content"). # CenterPane().Hide().MinimizeButton(True)) # # self._mgr.AddPane(self.CreateHTMLCtrl(), # aui.AuiPaneInfo().Name("html_content"). # CenterPane().Hide().MinimizeButton(True)) # # self._mgr.AddPane(self.CreateNotebook(), # aui.AuiPaneInfo().Name("notebook_content"). # CenterPane().PaneBorder(False)) #################### # self._mgr.AddPane(self.CreateSizeReportCtrl(), aui.AuiPaneInfo(). # Name("test1").Caption( # "Pane Caption").Top().MinimizeButton(True)) mb = MenuBar(self) self.toolbar = ToolBar(self) self.toolbar.SetMinSize(wx.Size(100, 60)) # self.SetToolBar(self.toolbar.GetToolBar()) self._mgr.AddPane(self.toolbar, aui.AuiPaneInfo().Name("maintoolbar"). ToolbarPane().Top()) self.actions = ActionRegisterer(self._mgr, mb, self.toolbar, ShortcutRegistry(self)) """ ##### Test tb3 = self.testToolbar() self._mgr.AddPane(tb3, aui.AuiPaneInfo().Name("tb3").Caption("Toolbar 3"). ToolbarPane().Top().Row(1).Position(1)) ##### End Test """ # Tree is always created here self.tree = Tree(self, self.actions, self._application.settings) self.tree.SetMinSize(wx.Size(120, 200)) # TreePlugin will manage showing the Tree self.actions.register_actions(ActionInfoCollection(_menudata, self, self.tree)) ###### File explorer panel is always created here self.filemgr = FileExplorer(self, self._controller) self.filemgr.SetMinSize(wx.Size(120, 200)) mb.take_menu_bar_into_use() self.CreateStatusBar() self.SetIcons(ImageProvider().PROGICONS) # tell the manager to "commit" all the changes just made self._mgr.Update()
class RideFrame(with_metaclass(classmaker(), wx.Frame, RideEventHandler)): def __init__(self, application, controller): size = application.settings.get('mainframe size', (1100, 700)) wx.Frame.__init__(self, parent=None, id = wx.ID_ANY, title='RIDE', pos=application.settings.get('mainframe position', (50, 30)), size=size, style=wx.DEFAULT_FRAME_STYLE | wx.SUNKEN_BORDER) # set Left to Right direction (while we don't have localization) self.SetLayoutDirection(wx.Layout_LeftToRight) # self.SetLayoutDirection(wx.Layout_RightToLeft) self._mgr = aui.AuiManager() # tell AuiManager to manage this frame self._mgr.SetManagedWindow(self) # set frame icon # self.SetIcon(Icon('widgets/robot.ico')) # Maybe is not needed # self.SetMinSize(size) self.SetMinSize(wx.Size(400, 300)) self.ensure_on_screen() if application.settings.get('mainframe maximized', False): self.Maximize() self._application = application self._controller = controller self.favicon = Icon(os.path.join(os.path.dirname(__file__), "..", "widgets","robot.ico"), wx.BITMAP_TYPE_ICO, 256, 256) self.SetIcon(self.favicon) #TODO use SetIcons for all sizes self._init_ui() self._plugin_manager = PluginManager(self.notebook) self._review_dialog = None self._view_all_tags_dialog = None #, self, self.actions, # self._application.settings) self.Bind(wx.EVT_CLOSE, self.OnClose) self.Bind(wx.EVT_SIZE, self.OnSize) self.Bind(wx.EVT_MOVE, self.OnMove) self.Bind(wx.EVT_MAXIMIZE, self.OnMaximize) self.Bind(wx.EVT_DIRCTRL_FILEACTIVATED, self.OnOpenFile) self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnMenuOpenFile) self._subscribe_messages() wx.CallAfter(self.actions.register_tools) # DEBUG def _subscribe_messages(self): for listener, topic in [ (lambda msg: self.SetStatusText('Saved %s' % msg.path), RideSaved), (lambda msg: self.SetStatusText('Saved all files'), RideSaveAll), (self._set_label, RideTreeSelection), (self._show_validation_error, RideInputValidationError), (self._show_modification_prevented_error, RideModificationPrevented) ]: PUBLISHER.subscribe(listener, topic) def _set_label(self, message): self.SetTitle(self._create_title(message)) def _create_title(self, message): title = 'RIDE' if message: item = message.item title += ' - ' + item.datafile.name if not item.is_modifiable(): title += ' (READ ONLY)' return title def _show_validation_error(self, message): wx.MessageBox(message.message, 'Validation Error', style=wx.ICON_ERROR) def _show_modification_prevented_error(self, message): wx.MessageBox("\"%s\" is read only" % message.controller.datafile_controller.filename, "Modification prevented", style=wx.ICON_ERROR) def _init_ui(self): # self._mgr.AddPane(wx.Panel(self), aui.AuiPaneInfo().CenterPane()) ##### self.splitter = wx.SplitterWindow(self, style=wx.SP_LIVE_UPDATE) # self._mgr.AddPane(wx.Panel(self), aui.AuiPaneInfo().CenterPane()) # set up default notebook style self._notebook_style = aui.AUI_NB_DEFAULT_STYLE | \ aui.AUI_NB_TAB_EXTERNAL_MOVE | wx.NO_BORDER # TODO self._notebook_theme = 0 (allow to select themes for notebooks) # self.notebook = NoteBook(self.splitter, self._application, # self._notebook_style) self.notebook = NoteBook(self, self._application, self._notebook_style) self._mgr.AddPane(self.notebook, aui.AuiPaneInfo().Name("notebook_editors"). CenterPane().PaneBorder(False)) ################ Test # self._mgr.AddPane(self.CreateTextCtrl(), # aui.AuiPaneInfo().Name("text_content"). # CenterPane().Hide().MinimizeButton(True)) # # self._mgr.AddPane(self.CreateHTMLCtrl(), # aui.AuiPaneInfo().Name("html_content"). # CenterPane().Hide().MinimizeButton(True)) # # self._mgr.AddPane(self.CreateNotebook(), # aui.AuiPaneInfo().Name("notebook_content"). # CenterPane().PaneBorder(False)) #################### # self._mgr.AddPane(self.CreateSizeReportCtrl(), aui.AuiPaneInfo(). # Name("test1").Caption( # "Pane Caption").Top().MinimizeButton(True)) mb = MenuBar(self) self.toolbar = ToolBar(self) self.toolbar.SetMinSize(wx.Size(100, 60)) # self.SetToolBar(self.toolbar.GetToolBar()) self._mgr.AddPane(self.toolbar, aui.AuiPaneInfo().Name("maintoolbar"). ToolbarPane().Top()) self.actions = ActionRegisterer(self._mgr, mb, self.toolbar, ShortcutRegistry(self)) """ ##### Test tb3 = self.testToolbar() self._mgr.AddPane(tb3, aui.AuiPaneInfo().Name("tb3").Caption("Toolbar 3"). ToolbarPane().Top().Row(1).Position(1)) ##### End Test """ # Tree is always created here self.tree = Tree(self, self.actions, self._application.settings) self.tree.SetMinSize(wx.Size(120, 200)) # TreePlugin will manage showing the Tree self.actions.register_actions(ActionInfoCollection(_menudata, self, self.tree)) ###### File explorer panel is always created here self.filemgr = FileExplorer(self, self._controller) self.filemgr.SetMinSize(wx.Size(120, 200)) mb.take_menu_bar_into_use() self.CreateStatusBar() self.SetIcons(ImageProvider().PROGICONS) # tell the manager to "commit" all the changes just made self._mgr.Update() def testToolbar(self): #### More testing prepend_items, append_items = [], [] item = aui.AuiToolBarItem() item.SetKind(wx.ITEM_SEPARATOR) append_items.append(item) item = aui.AuiToolBarItem() item.SetKind(wx.ITEM_NORMAL) item.SetId(ID_CustomizeToolbar) item.SetLabel("Customize...") append_items.append(item) tb3 = aui.AuiToolBar(self, -1, wx.DefaultPosition, wx.DefaultSize, agwStyle=aui.AUI_TB_DEFAULT_STYLE | aui.AUI_TB_OVERFLOW) tb3.SetToolBitmapSize(wx.Size(16, 16)) tb3_bmp1 = wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, wx.Size(16, 16)) tb3.AddSimpleTool(ID_SampleItem + 16, "Check 1", tb3_bmp1, "Check 1", aui.ITEM_CHECK) tb3.AddSimpleTool(ID_SampleItem + 17, "Check 2", tb3_bmp1, "Check 2", aui.ITEM_CHECK) tb3.AddSimpleTool(ID_SampleItem + 18, "Check 3", tb3_bmp1, "Check 3", aui.ITEM_CHECK) tb3.AddSimpleTool(ID_SampleItem + 19, "Check 4", tb3_bmp1, "Check 4", aui.ITEM_CHECK) tb3.AddSeparator() tb3.AddSimpleTool(ID_SampleItem + 20, "Radio 1", tb3_bmp1, "Radio 1", aui.ITEM_RADIO) tb3.AddSimpleTool(ID_SampleItem + 21, "Radio 2", tb3_bmp1, "Radio 2", aui.ITEM_RADIO) tb3.AddSimpleTool(ID_SampleItem + 22, "Radio 3", tb3_bmp1, "Radio 3", aui.ITEM_RADIO) tb3.AddSeparator() tb3.AddSimpleTool(ID_SampleItem + 23, "Radio 1 (Group 2)", tb3_bmp1, "Radio 1 (Group 2)", aui.ITEM_RADIO) tb3.AddSimpleTool(ID_SampleItem + 24, "Radio 2 (Group 2)", tb3_bmp1, "Radio 2 (Group 2)", aui.ITEM_RADIO) tb3.AddSimpleTool(ID_SampleItem + 25, "Radio 3 (Group 2)", tb3_bmp1, "Radio 3 (Group 2)", aui.ITEM_RADIO) tb3.SetCustomOverflowItems(prepend_items, append_items) tb3.Realize() return tb3 def get_selected_datafile(self): return self.tree.get_selected_datafile() def get_selected_datafile_controller(self): return self.tree.get_selected_datafile_controller() def OnClose(self, event): if self._allowed_to_exit(): perspective = self._mgr.SavePerspective() self._application.settings.set('AUI Perspective', perspective) PUBLISHER.unsubscribe(self._set_label, RideTreeSelection) RideClosing().publish() # deinitialize the frame manager self._mgr.UnInit() self.Destroy() else: wx.CloseEvent.Veto(event) def OnSize(self, event): if not self.IsMaximized(): self._application.settings['mainframe maximized'] = False self._application.settings['mainframe size'] = self.DoGetSize() event.Skip() def OnMove(self, event): # When the window is Iconized, a move event is also raised, but we # don't want to update the position in the settings file if not self.IsIconized() and not self.IsMaximized(): self._application.settings['mainframe position'] =\ self.DoGetPosition() event.Skip() def OnMaximize(self, event): self._application.settings['mainframe maximized'] = True event.Skip() def OnReleasenotes(self, event): pass def _allowed_to_exit(self): if self.has_unsaved_changes(): ret = wx.MessageBox("There are unsaved modifications.\n" "Do you want to save your changes before " "exiting?", "Warning", wx.ICON_WARNING | wx.CANCEL | wx.YES_NO) if ret == wx.CANCEL: return False if ret == wx.YES: self.save() return True def has_unsaved_changes(self): return self._controller.is_dirty() def OnNewProject(self, event): if not self.check_unsaved_modifications(): return NewProjectDialog(self._controller).execute() self._populate_tree() def _populate_tree(self): self.tree.populate(self._controller) self.filemgr.update_tree() def OnOpenFile(self, event): if not self.filemgr: return # EVT_DIRCTRL_FILEACTIVATED from os.path import splitext robottypes = self._application.settings.get('robot types', ['robot', 'resource' 'txt', 'tsv', 'html']) path = self.filemgr.GetFilePath() ext = '' if len(path) > 0: ext = splitext(path) ext = ext[1].replace('.', '') # print("DEBUG: path %s ext %s" % (path, ext)) if len(ext) > 0 and ext in robottypes: if not self.check_unsaved_modifications(): return if self.open_suite(path): return from robotide.editor import customsourceeditor customsourceeditor.main(path) def OnMenuOpenFile(self, event): if not self.filemgr: return # TODO: Use widgets/popupmenu tools path = self.filemgr.GetFilePath() if len(path) > 0: self.OnOpenFile(event) else: path = self.filemgr.GetPath() if not self.check_unsaved_modifications(): return self.open_suite(path) # It is a directory, do not edit event.Skip() def OnOpenTestSuite(self, event): if not self.check_unsaved_modifications(): return path = RobotFilePathDialog( self, self._controller, self._application.settings).execute() if path: if self.open_suite(path): return from robotide.editor import customsourceeditor customsourceeditor.main(path) def check_unsaved_modifications(self): if self.has_unsaved_changes(): ret = wx.MessageBox("There are unsaved modifications.\n" "Do you want to proceed without saving?", "Warning", wx.ICON_WARNING | wx.YES_NO) return ret == wx.YES return True def open_suite(self, path): self._controller.update_default_dir(path) try: err = self._controller.load_datafile(path, LoadProgressObserver(self)) finally: if isinstance(err, UserWarning): # raise err # Just leave message in Parser Log return False self._populate_tree() return True def refresh_datafile(self, item, event): self.tree.refresh_datafile(item, event) if self.filemgr: self.filemgr.ReCreateTree() def OnOpenDirectory(self, event): if self.check_unsaved_modifications(): path = wx.DirSelector(message="Choose a directory containing Robot" " files", default_path=self._controller.default_dir) if path: self.open_suite(path) def OnSave(self, event): self.save() def OnSaveAll(self, event): self.save_all() def save_all(self): self._show_dialog_for_files_without_format() self._controller.execute(SaveAll()) def save(self, controller=None): if controller is None: controller = self.get_selected_datafile_controller() if controller is not None: if not controller.has_format(): self._show_dialog_for_files_without_format(controller) else: controller.execute(SaveFile()) def _show_dialog_for_files_without_format(self, controller=None): files_without_format = self._controller.get_files_without_format( controller) for f in files_without_format: self._show_format_dialog_for(f) def _show_format_dialog_for(self, file_controller_without_format): InitFileFormatDialog(file_controller_without_format).execute() def OnExit(self, event): self.Close() def OnManagePlugins(self, event): self._plugin_manager.show(self._application.get_plugins()) def OnViewAllTags(self, event): if self._view_all_tags_dialog is None: self._view_all_tags_dialog = ViewAllTagsDialog(self._controller, self) self._view_all_tags_dialog.show_dialog() def OnSearchUnusedKeywords(self, event): if self._review_dialog is None: self._review_dialog = ReviewDialog(self._controller, self) self._review_dialog.show_dialog() def OnPreferences(self, event): dlg = PreferenceEditor(self, "RIDE - Preferences", self._application.preferences, style='tree') # I would prefer that this not be modal, but making it non- # modal opens up a can of worms. We don't want to have to deal # with settings getting changed out from under us while the # dialog is open. dlg.ShowModal() dlg.Destroy() def OnAbout(self, event): dlg = AboutDialog() dlg.ShowModal() dlg.Destroy() def OnShortcutkeys(self, event): dialog = ShortcutKeysDialog() dialog.Show() def OnReportaProblem(self, event): wx.LaunchDefaultBrowser("https://github.com/robotframework/RIDE/issues" "?utf8=%E2%9C%93&q=is%3Aissue+%22search" "%20your%20problem%22" ) def OnUserGuide(self, event): wx.LaunchDefaultBrowser("http://robotframework.org/robotframework/" "#user-guide") def OnWiki(self, event): wx.LaunchDefaultBrowser("https://github.com/robotframework/RIDE/wiki") def _has_data(self): return self._controller.data is not None def _refresh(self): self._controller.update_namespace() # This code is copied from http://wiki.wxpython.org/EnsureFrameIsOnScreen, # and adapted to fit our code style. def ensure_on_screen(self): try: display_id = wx.Display.GetFromWindow(self) except NotImplementedError: display_id = 0 if display_id == -1: display_id = 0 geometry = wx.Display(display_id).GetGeometry() position = self.GetPosition() if position.x < geometry.x: position.x = geometry.x if position.y < geometry.y: position.y = geometry.y size = self.GetSize() if size.width > geometry.width: size.width = geometry.width position.x = geometry.x elif position.x + size.width > geometry.x + geometry.width: position.x = geometry.x + geometry.width - size.width if size.height > geometry.height: size.height = geometry.height position.y = geometry.y elif position.y + size.height > geometry.y + geometry.height: position.y = geometry.y + geometry.height - size.height self.SetPosition(position) self.SetSize(size) # DEBUG just some testing def CreateSizeReportCtrl(self, width=80, height=80): ctrl = SizeReportCtrl(self, -1, wx.DefaultPosition, wx.Size(width, height), self._mgr) return ctrl
class _BaseSuiteTreeTest(unittest.TestCase): def setUp(self): self.app = wx.App() self.frame = wx.Frame(None) self._model = self._create_model() self._tree = Tree( self.frame, ActionRegisterer(AuiManager(self.frame), MenuBar(self.frame), ToolBar(self.frame), ShortcutRegistry(self.frame))) images = TreeImageList() self._tree._images = images self._tree.SetImageList(images) self._tree.populate(self._model) self._expand_all() def tearDown(self): PUBLISHER.unsubscribe_all() wx.CallAfter(self.frame.Close) wx.CallAfter(self.app.ExitMainLoop) self.app.MainLoop() # With this here, there is no Segmentation fault self.app = None def _create_model(self): suite = self._create_directory_suite('/top_suite') suite.children = [ self._create_file_suite('sub_suite_%d.txt' % i) for i in range(3) ] res = ResourceFile() res.source = 'resource.txt' res.keyword_table.keywords.append(UserKeyword(res, 'Resource Keyword')) library_manager = LibraryManager(':memory:') library_manager.create_database() model = Project(Namespace(FakeSettings()), library_manager=library_manager) model._controller = TestDataDirectoryController(suite) rfc = ResourceFileController(res, project=model) model.resources.append(rfc) model.insert_into_suite_structure(rfc) return model def _create_directory_suite(self, source): return self._create_suite(TestDataDirectory, source, is_dir=True) def _create_file_suite(self, source): suite = self._create_suite(TestCaseFile, source) suite.testcase_table.tests = [ TestCase(suite, '%s Fake Test %d' % (suite.name, i)) for i in range(5) ] return suite def _create_suite(self, suite_class, source, is_dir=False): suite = suite_class() suite.source = source if is_dir: suite.directory = source suite.keyword_table.keywords = [ UserKeyword(suite.keyword_table, '%s Fake UK %d' % (suite.name, i)) for i in range(5) ] return suite def _expand_all(self): for node in self._tree._datafile_nodes[1:]: self._tree._expand_and_render_children(node) def _get_selected_label(self): return self._tree.GetItemText(self._tree.GetSelection()) def _get_node(self, label): node = self._tree._controller.find_node_with_label( self._tree._root, label) return node or self._tree._controller.find_node_with_label( self._tree._root, '*' + label) def _select_node(self, label): self._tree.SelectItem(self._get_node(label))