def edit_file(widget, file, istextfile=None): '''Edit a file with and external application. This method will show a dialog to block the interface while the external application is running. The dialog is closed automatically when the application exits _after_ modifying the file. If the file is unmodified the user needs to click the "Done" button in the dialog because we can not know if the application was really done or just forked to another process. @param widget: a C{gtk} widget to use as parent for dialogs or C{None} @param file: a L{File} object @param istextfile: if C{True} the text editor is used, otherwise we ask the file browser for the correct application. When C{None} we check the mimetype of the file to determine if it is text or not. ''' ## FIXME force using real text editor, even when file has not ## text mimetype. This now goes wrong when editing e.g. a html ## template when the editor is "xdg-open" on linux or default ## os.startfile() on windows... if not file.exists(): raise FileNotFoundError(file) oldmtime = file.mtime() dialog = MessageDialog(widget, ( _('Editing file: %s') % file.basename, # T: main text for dialog for editing external files _('You are editing a file in an external application. You can close this dialog when you are done') # T: description for dialog for editing external files )) def check_close_dialog(status): if status != 0: dialog.destroy() ErrorDialog(widget, _('Could not open: %s') % file.basename).run() # T: error when external application fails else: newmtime = file.mtime() if newmtime != oldmtime: dialog.destroy() if istextfile: try: open_file(widget, file, mimetype='text/plain', callback=check_close_dialog) except NoApplicationFoundError: app = AddApplicationDialog(widget, 'text/plain').run() if app: # Try again open_file(widget, file, mimetype='text/plain', callback=check_close_dialog) else: return # Dialog was cancelled, no default set, ... else: open_file(widget, file, callback=check_close_dialog) dialog.run()
def open_file(widget, file, mimetype=None, callback=None): '''Open a file or folder @param widget: parent for new dialogs, C{Gtk.Widget} or C{None} @param file: a L{File} or L{Folder} object @param mimetype: optionally specify the mimetype to force a specific application to open this file @param callback: callback function to be passed on to L{Application.spawn()} (if the application supports a callback, otherwise it is ignored silently) @raises FileNotFoundError: if C{file} does not exist @raises NoApplicationFoundError: if a specific mimetype was given, but no default application is known for this mimetype (will not use fallback in this case - fallback would ignore the specified mimetype) ''' logger.debug('open_file(%s, %s)', file, mimetype) file = adapt_from_newfs(file) assert isinstance(file, (File, Dir)) if isinstance(file, (File)) and file.isdir(): file = Dir(file.path) if not file.exists(): raise FileNotFoundError(file) if isinstance(file, File): # File manager = ApplicationManager() if mimetype is None: entry = manager.get_default_application(file.get_mimetype()) if entry is not None: _open_with(widget, entry, file, callback) else: _open_with_filebrowser(widget, file, callback) else: entry = manager.get_default_application(mimetype) if entry is not None: _open_with(widget, entry, file, callback) else: raise NoApplicationFoundError('No Application found for: %s' % mimetype) # Do not go to fallback, we can not force # mimetype for fallback else: # Dir _open_with_filebrowser(widget, file, callback)
def rename_file(widget, file): '''Rename a file @param widget: parent for new dialogs, C{Gtk.Widget} or C{None} @param file: a L{File} object @raises FileNotFoundError: if C{file} does not exist ''' logger.debug('rename_file(%s)', file) file = localFileOrFolder(file) assert isinstance(file, LocalFile) and not isinstance(file, LocalFolder) if not file.exists(): raise FileNotFoundError(file) dialog = FileRenameDialog(widget, file) if dialog.run() == Gtk.ResponseType.OK: if file.path != dialog.new_file: file.moveto(dialog.new_file)
def delete_file(widget, file): '''Delete a file @param widget: parent for new dialogs, C{Gtk.Widget} or C{None} @param file: a L{File} object @raises FileNotFoundError: if C{file} does not exist ''' logger.debug('delete_file(%s)', file) file = localFileOrFolder(file) assert isinstance(file, LocalFile) and not isinstance(file, LocalFolder) if not file.exists(): raise FileNotFoundError(file) dialog = QuestionDialog(widget, _('Are you sure you want to delete the file \'%s\'?') % file.basename) # T: text in confirmation dialog on deleting a file if dialog.run(): TrashHelper().trash(file)