def _coming_soon(self): MessageDialog.show_info( parent=self, title="Coming soon", message="We are working hard to bring this feature to you. Hang in there.", icon="clock" )
def auto_find_load_custom(self, *modules): # locate and load all custom widgets in modules # module can be a module or a path to module file self._custom_widgets = [] errors = {} for module in modules: if isinstance(module, str): try: module = import_path(module) except Exception as e: errors[module] = e continue for attr in dir(module): if type(getattr(module, attr)) == WidgetMeta: self._custom_widgets.append(getattr(module, attr)) if errors: error_msg = "\n\n".join( [f"{path}\n{error}" for path, error in errors.items()] ) MessageDialog.show_error( parent=self.window, message=f"Error loading widgets \n\n{error_msg}" ) return self._custom_widgets
def _verify_version(self): if self.builder.metadata.get("version"): _, major, __ = __version__.split(".") if major < self.builder.metadata["version"].get("major", 0): MessageDialog.show_warning( parent=self.studio, message= ("Design was made using a higher version of the studio. \n" "Some features may not be supported on this version. \n" "Update to a new version of Formation for proper handling. \n" "Note that saving may irreversibly strip off any unsupported features" ))
def preview(self): if self.designer.root_obj is None: # If there is no root object show a warning MessageDialog.show_warning( parent=self, title='Empty design', message='There is nothing to preview. Please add a root widget') return # close previous preview if any self.close_preview() window = self.current_preview = Toplevel(self) window.wm_transient(self) window.build = AppBuilder(window, node=self.designer.to_tree()) name = self.designer.design_path if self.designer.design_path is not None else "Untitled" window.build._app.title(os.path.basename(name))
def open_file(self, path=None): if path is None: path = filedialog.askopenfilename(parent=self, filetypes=[('XML', '*.xml')]) elif not os.path.exists(path): MessageDialog.show_error( parent=self, title="Missing File", message="File {} does not exist".format(path), ) return if path: self.designer.open_xml(path) self.set_path(path) pref.update_recent(path)
def _force_exit_prompt(self): return MessageDialog.builder( {"text": "Force exit", "value": True, "focus": True}, {"text": "Return to app", "value": False}, wait=True, title="Exit Failure", message="An internal failure is preventing the app from exiting. Force exit?", parent=self, icon=MessageDialog.ICON_ERROR )
def _load_design(self, path): # Loading designs is elaborate so better do it on its own thread self._load_progress = MessageDialog.show_progress( mode=MessageDialog.INDETERMINATE, message='Loading design file to studio...', parent=self.studio ) # Capture any errors that occur while loading # This helps the user single out syntax errors and other value errors try: with open(path, 'rb') as dump: self.root_obj = self.xml.load_xml(dump, self) # store the file hash so we can check for changes later self.design_path = path except Exception as e: MessageDialog.show_error(parent=self.studio, title='Error loading design', message=str(e)) finally: if self._load_progress: self._load_progress.destroy() self._load_progress = None
def save_prompt(self): return MessageDialog.builder( {"text": "Save", "value": True, "focus": True}, {"text": "Don't save", "value": False}, {"text": "Cancel", "value": None}, wait=True, title="Save design", message="This design has unsaved changes. Do you want to save them?", parent=self.studio, icon=MessageDialog.ICON_INFO )
def open_file(self, path=None): if path is None: path = filedialog.askopenfilename(parent=self, filetypes=get_file_types()) elif not os.path.exists(path): MessageDialog.show_error( parent=self, title="Missing File", message="File {} does not exist".format(path), ) return if path: # find if path is already open on the designer for context in self.contexts: if isinstance(context, DesignContext) and context.path == path: # path is open, select context.select() break else: self.create_context(DesignContext, path) self.set_path(path) pref.update_recent(path)
def reload(self, *_): if not self.design_path or self.studio.context != self.context: return if self.has_changed(): okay = MessageDialog.ask_okay_cancel( title="Confirm reload", message="All changes made will be lost", parent=self.studio) if not okay: # user made no choice or basically selected cancel return self.clear() self.studio.on_session_clear(self) self.open_file(self.design_path)
def open_file(self, path=None): if self.has_changed(): save = self.save_prompt() if save: # user opted to save saved_to = self.save() if saved_to is None: # User did not complete saving and opted to cancel return elif save is None: # user made no choice or basically selected cancel return if path: self.builder = DesignBuilder(self) progress = MessageDialog.show_progress( mode=MessageDialog.INDETERMINATE, message='Loading design file to studio...', parent=self.studio) self._load_design(path, progress) else: # if no path is supplied the default behaviour is to open a blank design self._open_default()
def about_window(parent): dialog = MessageDialog(parent, About) dialog.title("Formation") dialog.focus_set() return dialog
def _show_root_widget_warning(self): MessageDialog.show_warning(title='Invalid root widget', parent=self.studio, message='Only containers are allowed as root widgets')
def check(cls, master): dialog = MessageDialog(master, cls) dialog.title("Formation updater") dialog.focus_set() return dialog