def saveAs(self, event=None, fileName=None):
    """Save a Leo outline to a file with a new filename."""
    c = self
    p = c.p
    # Do this now: w may go away.
    w = g.app.gui.get_focus(c)
    inBody = g.app.gui.widget_name(w).startswith('body')
    if inBody: p.saveCursorAndScroll()
    if g.app.disableSave:
        g.es("save commands disabled", color="purple")
        return
    c.init_error_dialogs()
    # 2013/09/28: add fileName keyword arg for leoBridge scripts.
    if fileName:
        c.frame.title = g.computeWindowTitle(fileName)
        c.mFileName = fileName
    # Make sure we never pass None to the ctor.
    if not c.mFileName:
        c.frame.title = ""
    if not fileName:
        fileName = ''.join(c.k.givenArgs)
    if not fileName:
        fileName = g.app.gui.runSaveFileDialog(
            c,
            initialfile=c.mFileName,
            title="Save As",
            filetypes=[
                ("Leo files", "*.leo *.db"),
            ],
            defaultextension=g.defaultLeoFileExtension(c))
    c.bringToFront()
    if fileName:
        # Fix bug 998090: save file as doesn't remove entry from open file list.
        if c.mFileName:
            g.app.forgetOpenFile(c.mFileName)
        # Don't change mFileName until the dialog has suceeded.
        c.mFileName = g.ensure_extension(fileName,
                                         g.defaultLeoFileExtension(c))
        # Part of the fix for https://bugs.launchpad.net/leo-editor/+bug/1194209
        c.frame.title = title = c.computeWindowTitle(c.mFileName)
        c.frame.setTitle(title)
        # 2013/08/04: use c.computeWindowTitle.
        c.openDirectory = c.frame.openDirectory = g.os_path_dirname(
            c.mFileName)
        # Bug fix in 4.4b2.
        # Calls c.clearChanged() if no error.
        if g.app.qt_use_tabs and hasattr(c.frame, 'top'):
            c.frame.top.leo_master.setTabName(c, c.mFileName)
        c.fileCommands.saveAs(c.mFileName)
        g.app.recentFilesManager.updateRecentFiles(c.mFileName)
        g.chdir(c.mFileName)
    # Done in FileCommands.saveAs.
    # c.redraw_after_icons_changed()
    c.raise_error_dialogs(kind='write')
    # *Safely* restore focus, without using the old w directly.
    if inBody:
        c.bodyWantsFocus()
        p.restoreCursorAndScroll()
    else:
        c.treeWantsFocus()
def saveAs(self, event=None, fileName=None):
    '''Save a Leo outline to a file with a new filename.'''
    c = self; p = c.p
    # Do this now: w may go away.
    w = g.app.gui.get_focus(c)
    inBody = g.app.gui.widget_name(w).startswith('body')
    if inBody: p.saveCursorAndScroll()
    if g.app.disableSave:
        g.es("save commands disabled", color="purple")
        return
    c.init_error_dialogs()
    # 2013/09/28: add fileName keyword arg for leoBridge scripts.
    if fileName:
        c.frame.title = g.computeWindowTitle(fileName)
        c.mFileName = fileName
    # Make sure we never pass None to the ctor.
    if not c.mFileName:
        c.frame.title = ""
    if not fileName:
        fileName = ''.join(c.k.givenArgs)
    if not fileName:
        fileName = g.app.gui.runSaveFileDialog(c,
            initialfile=c.mFileName,
            title="Save As",
            filetypes=[g.fileFilters('LEOFILES')],
            defaultextension=g.defaultLeoFileExtension(c))
    c.bringToFront()
    if fileName:
        # Fix bug 998090: save file as doesn't remove entry from open file list.
        if c.mFileName:
            g.app.forgetOpenFile(c.mFileName)
        # Don't change mFileName until the dialog has suceeded.
        c.mFileName = g.ensure_extension(fileName, g.defaultLeoFileExtension(c))
        # Part of the fix for https://bugs.launchpad.net/leo-editor/+bug/1194209
        c.frame.title = title = c.computeWindowTitle(c.mFileName)
        c.frame.setTitle(title)
            # 2013/08/04: use c.computeWindowTitle.
        c.openDirectory = c.frame.openDirectory = g.os_path_dirname(c.mFileName)
            # Bug fix in 4.4b2.
        # Calls c.setChanged(False) if no error.
        if g.app.qt_use_tabs and hasattr(c.frame, 'top'):
            c.frame.top.leo_master.setTabName(c, c.mFileName)
        c.fileCommands.saveAs(c.mFileName)
        g.app.recentFilesManager.updateRecentFiles(c.mFileName)
        g.chdir(c.mFileName)
    # Done in FileCommands.saveAs.
    # c.redraw_after_icons_changed()
    c.raise_error_dialogs(kind='write')
    # *Safely* restore focus, without using the old w directly.
    if inBody:
        c.bodyWantsFocus()
        p.restoreCursorAndScroll()
    else:
        c.treeWantsFocus()
def open_theme_file(self, event):
    """Open a theme file in a new session and apply the theme."""
    c = event and event.get('c')
    if not c:
        return
    # Get the file name.
    themes_dir = g.os_path_finalize_join(g.app.loadDir, '..', 'themes')
    fn = g.app.gui.runOpenFileDialog(
        c,
        title="Open Theme File",
        filetypes=[
            ("Leo files", "*.leo *.db"),
            ("All files", "*"),
        ],
        defaultextension=g.defaultLeoFileExtension(c),
        startpath=themes_dir,
    )
    if not fn:
        return
    leo_dir = g.os_path_finalize_join(g.app.loadDir, '..', '..')
    os.chdir(leo_dir)
    #
    # #1425: Open the theme file in a separate process.
    command = f'{g.sys.executable} {g.app.loadDir}/runLeo.py "{fn}"'
    g.execute_shell_commands(command)  # #1564.
    os.chdir(leo_dir)
def setReferenceFile(self, event=None):
    '''
    Shows a file open dialog allowing you to select a **reference** Leo
    document to which this outline will be connected.
       
    This command creates a **special separator node**, a top-level node
    whose headline is `---begin-private-area---` and whose body is the path
    to reference Leo file.
    
    The separator node splits the outline into two parts. The **public
    part** consists of all nodes above the separator node. The **private
    part** consists of all nodes below the separator node.
       
    The update-ref-file and read-ref-file commands operate on the **public
    part** of the outline. The update-ref-file command saves *only* the
    public part of the outline to reference Leo file. The read-ref-file
    command *completely replaces* the public part of the outline with the
    contents of reference Leo file.
    '''
    c = self
    table = [ g.fileFilters("LEOFILES"),]
    fileName = g.app.gui.runOpenFileDialog(c,
            title="Select reference Leo file",
            filetypes=table,
            defaultextension=g.defaultLeoFileExtension(c))
    if not fileName: return
    c.fileCommands.setReferenceFile(fileName)
def setReferenceFile(self, event=None):
    '''
    Shows a file open dialog allowing you to select a **reference** Leo
    document to which this outline will be connected.
       
    This command creates a **special separator node**, a top-level node
    whose headline is `---begin-private-area---` and whose body is the path
    to reference Leo file.
    
    The separator node splits the outline into two parts. The **public
    part** consists of all nodes above the separator node. The **private
    part** consists of all nodes below the separator node.
       
    The update-ref-file and read-ref-file commands operate on the **public
    part** of the outline. The update-ref-file command saves *only* the
    public part of the outline to reference Leo file. The read-ref-file
    command *completely replaces* the public part of the outline with the
    contents of reference Leo file.
    '''
    c = self
    table = [ g.fileFilters("LEOFILES"),]
    fileName = g.app.gui.runOpenFileDialog(c,
            title="Select reference Leo file",
            filetypes=table,
            defaultextension=g.defaultLeoFileExtension(c))
    if not fileName: return
    c.fileCommands.setReferenceFile(fileName)
def saveTo(self, event=None, fileName=None, silent=False):
    """Save a Leo outline to a file, leaving the file associated with the Leo outline unchanged."""
    c = self
    p = c.p
    # Do this now: w may go away.
    w = g.app.gui.get_focus(c)
    inBody = g.app.gui.widget_name(w).startswith('body')
    if inBody:
        p.saveCursorAndScroll()
    if g.app.disableSave:
        g.es("save commands disabled", color="purple")
        return
    c.init_error_dialogs()
    # Add fileName keyword arg for leoBridge scripts.
    if not fileName:
        # set local fileName, _not_ c.mFileName
        fileName = ''.join(c.k.givenArgs)
    if not fileName:
        fileName = g.app.gui.runSaveFileDialog(
            c,
            initialfile=c.mFileName,
            title="Save To",
            filetypes=[
                ("Leo files", "*.leo *.db"),
            ],
            defaultextension=g.defaultLeoFileExtension(c))
    c.bringToFront()
    if fileName:
        fileName = g.ensure_extension(fileName, g.defaultLeoFileExtension(c))
        c.fileCommands.saveTo(fileName, silent=silent)
        g.app.recentFilesManager.updateRecentFiles(fileName)
        g.chdir(fileName)
    c.raise_error_dialogs(kind='write')
    # *Safely* restore focus, without using the old w directly.
    if inBody:
        c.bodyWantsFocus()
        p.restoreCursorAndScroll()
    else:
        c.treeWantsFocus()
    c.outerUpdate()
Example #7
0
def open(self, event=None):
    '''Open a Leo window containing the contents of a .leo file.'''
    c = self
    # Close the window if this command completes successfully?
    closeFlag = (
        c.frame.startupWindow and
        # The window was open on startup
        not c.changed and not c.frame.saved and
        # The window has never been changed
        g.app.numberOfUntitledWindows == 1
        # Only one untitled window has ever been opened
    )
    table = [
        # 2010/10/09: Fix an interface blunder. Show all files by default.
        ("All files", "*"),
        g.fileFilters("LEOFILES"),
        ("Python files", "*.py"),
    ]
    fileName = ''.join(c.k.givenArgs)
    if not fileName:
        fileName = g.app.gui.runOpenFileDialog(
            c,
            title="Open",
            filetypes=table,
            defaultextension=g.defaultLeoFileExtension(c))
    c.bringToFront()
    c.init_error_dialogs()
    ok = False
    if fileName:
        if g.app.loadManager.isLeoFile(fileName):
            c2 = g.openWithFileName(fileName, old_c=c)
            if c2:
                c2.k.makeAllBindings()
                # Fix #579: Key bindings don't take for commands defined in plugins.
                g.chdir(fileName)
                g.setGlobalOpenDir(fileName)
            if c2 and closeFlag:
                g.app.destroyWindow(c.frame)
        elif c.looksLikeDerivedFile(fileName):
            # Create an @file node for files containing Leo sentinels.
            ok = c.importCommands.importDerivedFiles(parent=c.p,
                                                     paths=[fileName],
                                                     command='Open')
        else:
            # otherwise, create an @edit node.
            ok = c.createNodeFromExternalFile(fileName)
    c.raise_error_dialogs(kind='write')
    g.app.runAlreadyOpenDialog(c)
    # openWithFileName sets focus if ok.
    if not ok:
        c.initialFocusHelper()
def saveTo(self, event=None, fileName=None):
    '''Save a Leo outline to a file, leaving the file associated with the Leo outline unchanged.'''
    c = self; p = c.p
    # Do this now: w may go away.
    w = g.app.gui.get_focus(c)
    inBody = g.app.gui.widget_name(w).startswith('body')
    if inBody:
        p.saveCursorAndScroll()
    if g.app.disableSave:
        g.es("save commands disabled", color="purple")
        return
    c.init_error_dialogs()
    # Add fileName keyword arg for leoBridge scripts.
    if not fileName:
        # set local fileName, _not_ c.mFileName
        fileName = ''.join(c.k.givenArgs)
    if not fileName:
        fileName = g.app.gui.runSaveFileDialog(c,
            initialfile=c.mFileName,
            title="Save To",
            filetypes=[g.fileFilters('LEOFILES')],
            defaultextension=g.defaultLeoFileExtension(c))
    c.bringToFront()
    if fileName:
        fileName = g.ensure_extension(fileName, g.defaultLeoFileExtension(c))
        c.fileCommands.saveTo(fileName)
        g.app.recentFilesManager.updateRecentFiles(fileName)
        g.chdir(fileName)
    c.raise_error_dialogs(kind='write')
    # *Safely* restore focus, without using the old w directly.
    if inBody:
        c.bodyWantsFocus()
        p.restoreCursorAndScroll()
    else:
        c.treeWantsFocus()
    c.outerUpdate()
def open(self, event=None):
    '''Open a Leo window containing the contents of a .leo file.'''
    c = self
    # Close the window if this command completes successfully?
    closeFlag = (
        c.frame.startupWindow and
            # The window was open on startup
        not c.changed and not c.frame.saved and
            # The window has never been changed
        g.app.numberOfUntitledWindows == 1
            # Only one untitled window has ever been opened
    )
    table = [
        # 2010/10/09: Fix an interface blunder. Show all files by default.
        ("All files", "*"),
        g.fileFilters("LEOFILES"),
        ("Python files", "*.py"),]
    fileName = ''.join(c.k.givenArgs)
    if not fileName:
        fileName = g.app.gui.runOpenFileDialog(c,
            title="Open",
            filetypes=table,
            defaultextension=g.defaultLeoFileExtension(c))
    c.bringToFront()
    c.init_error_dialogs()
    ok = False
    if fileName:
        if g.app.loadManager.isLeoFile(fileName):
            c2 = g.openWithFileName(fileName, old_c=c)
            if c2:
                c2.k.makeAllBindings()
                    # Fix #579: Key bindings don't take for commands defined in plugins.
                g.chdir(fileName)
                g.setGlobalOpenDir(fileName)
            if c2 and closeFlag:
                g.app.destroyWindow(c.frame)
        elif c.looksLikeDerivedFile(fileName):
            # Create an @file node for files containing Leo sentinels.
            ok = c.importCommands.importDerivedFiles(parent=c.p,
                paths=[fileName], command='Open')
        else:
            # otherwise, create an @edit node.
            ok = c.createNodeFromExternalFile(fileName)
    c.raise_error_dialogs(kind='write')
    g.app.runAlreadyOpenDialog(c)
    # openWithFileName sets focus if ok.
    if not ok:
        c.initialFocusHelper()
def save_node_as_xml_outline(self, event=None):
    """Save a node with its subtree as a Leo outline file."""
    c = event.c
    xml = c.fileCommands.outline_to_clipboard_string()

    fileName = g.app.gui.runSaveFileDialog(
        c,
        title="Save To",
        filetypes=[
            ("Leo files", "*.leo"),
        ],
        defaultextension=g.defaultLeoFileExtension(c))

    if fileName:
        with open(fileName, 'w', encoding='utf-8') as f:
            f.write(xml)
def open_theme_file_helper(event, closeFlag, fn):
    '''Open a theme file and apply the theme.'''
    trace = False and not g.unitTesting
    c = event and event.get('c')
    if not c: return
    old_dir = g.os_path_abspath(os.curdir)
    themes_dir = g.os_path_finalize_join(g.app.loadDir, '..', 'themes')
    if fn:
        fn = c.styleSheetManager.find_theme_file(fn)
        if not fn: return
    else:
        fn = g.app.gui.runOpenFileDialog(c,
            title="Open Theme",
            filetypes=[
                 g.fileFilters("LEOFILES"),
                ("All files", "*"),
            ],
            defaultextension=g.defaultLeoFileExtension(c),
            startpath=themes_dir,
        )
    c.bringToFront()
    c.init_error_dialogs()
    # Adapted from c.open().
    if fn and g.app.loadManager.isLeoFile(fn):
        # Close the file if it is already open, provided there is another.
        aList = g.app.commanders()
        if len(aList) > 1:
            for c2 in aList:
                if trace: g.trace('COMPARE\n%s\n%s' % (fn, c2.fileName()))
                if fn == c2.fileName():
                    if trace: g.trace('===== CLOSING', fn)
                    c2.close(new_c=c)
                    break
        c2 = g.openWithFileName(fn, old_c=c)
        if c2:
            c2.k.makeAllBindings()
            g.chdir(fn)
            g.setGlobalOpenDir(fn)
            if closeFlag:
                g.app.destroyWindow(c2.frame)
                g.app.windowList.remove(c2.frame)
    os.chdir(old_dir)
    c.raise_error_dialogs(kind='write')
    g.app.runAlreadyOpenDialog(c)
    c.initialFocusHelper()
def save_as_xml(self, event=None):
    """
    Save a Leo outline as a .leo file with a new file name.
    """
    c = self
    fileName = g.app.gui.runSaveFileDialog(
        c,
        initialfile=c.mFileName,  # .leo will be added if necessary.
        title="Save As XML",
        filetypes=[("Leo files", "*.leo")],
        defaultextension=g.defaultLeoFileExtension(c))
    if not fileName:
        return
    if not fileName.endswith('.leo'):
        fileName = f"{fileName}.leo"
    # Leo 6.4: Using save-to instead of save-as allows two versions of the file.
    c.saveTo(fileName=fileName)
    c.fileCommands.putSavedMessage(fileName)
def open_theme_file(self, event):
    '''Open a theme file and apply the theme.'''
    c = event and event.get('c')
    if not c: return
    themes_dir = g.os_path_finalize_join(g.app.loadDir, '..', 'themes')
    fn = g.app.gui.runOpenFileDialog(c,
        title="Open Theme File",
        filetypes=[
             g.fileFilters("LEOFILES"),
            ("All files", "*"),
        ],
        defaultextension=g.defaultLeoFileExtension(c),
        startpath=themes_dir,
    )
    if not fn:
        return
    leo_dir = g.os_path_finalize_join(g.app.loadDir, '..', '..')
    os.chdir(leo_dir)
    command = 'python launchLeo.py "%s"' % fn
    os.system(command)
    os.chdir(leo_dir)
Example #14
0
def open_theme_file(self, event):
    '''Open a theme file and apply the theme.'''
    c = event and event.get('c')
    if not c: return
    themes_dir = g.os_path_finalize_join(g.app.loadDir, '..', 'themes')
    fn = g.app.gui.runOpenFileDialog(c,
        title="Open Theme File",
        filetypes=[
             g.fileFilters("LEOFILES"),
            ("All files", "*"),
        ],
        defaultextension=g.defaultLeoFileExtension(c),
        startpath=themes_dir,
    )
    if not fn:
        return
    leo_dir = g.os_path_finalize_join(g.app.loadDir, '..', '..')
    os.chdir(leo_dir)
    command = 'python launchLeo.py "%s"' % fn
    os.system(command)
    os.chdir(leo_dir)
def open_theme_file(self, event):
    """Open a theme file in a new session and apply the theme."""
    c = event and event.get('c')
    if not c: return
    themes_dir = g.os_path_finalize_join(g.app.loadDir, '..', 'themes')
    fn = g.app.gui.runOpenFileDialog(
        c,
        title="Open Theme File",
        filetypes=[
            ("Leo files", "*.leo *.db"),
            ("All files", "*"),
        ],
        defaultextension=g.defaultLeoFileExtension(c),
        startpath=themes_dir,
    )
    if not fn:
        return
    leo_dir = g.os_path_finalize_join(g.app.loadDir, '..', '..')
    os.chdir(leo_dir)

    #--/start: Opening a theme file locks the initiating Leo session #1425
    #command = f'python launchLeo.py "{fn}"'
    #os.system(command)

    # fix idea 1:
    command = f'{g.sys.executable} {g.app.loadDir}/runLeo.py "{fn}"'

    # # fix idea 2:
    # if g.sys.argv[0].endswith('.py'):
    # command = f'{g.sys.executable} {g.sys.argv[0]} "{fn}"'
    # else:
    # command = f'{g.sys.argv[0]} "{fn}"'

    # g.es_print(command)
    g.subprocess.Popen(command)
    # --/end
    os.chdir(leo_dir)
def save(self, event=None, fileName=None):
    '''Save a Leo outline to a file.'''
    if False and g.app.gui.guiName() == 'curses':
        g.trace('===== Save disabled in curses gui =====')
        return
    c = self
    p = c.p
    # Do this now: w may go away.
    w = g.app.gui.get_focus(c)
    inBody = g.app.gui.widget_name(w).startswith('body')
    if inBody:
        p.saveCursorAndScroll()
    if g.unitTesting and g.app.unitTestDict.get('init_error_dialogs') is not None:
        # A kludge for unit testing:
        # indicated that c.init_error_dialogs and c.raise_error_dialogs
        # will be called below, *without* actually saving the .leo file.
        c.init_error_dialogs()
        c.raise_error_dialogs(kind='write')
        return
    if g.app.disableSave:
        g.es("save commands disabled", color="purple")
        return
    c.init_error_dialogs()
    # 2013/09/28: use the fileName keyword argument if given.
    # This supports the leoBridge.
    # Make sure we never pass None to the ctor.
    if fileName:
        c.frame.title = g.computeWindowTitle(fileName)
        c.mFileName = fileName
    if not c.mFileName:
        c.frame.title = ""
        c.mFileName = ""
    if c.mFileName:
        # Calls c.setChanged(False) if no error.
        g.app.syntax_error_files = []
        c.fileCommands.save(c.mFileName)
        c.syntaxErrorDialog()
    else:
        root = c.rootPosition()
        if not root.next() and root.isAtEditNode():
            # There is only a single @edit node in the outline.
            # A hack to allow "quick edit" of non-Leo files.
            # See https://bugs.launchpad.net/leo-editor/+bug/381527
            fileName = None
            # Write the @edit node if needed.
            if root.isDirty():
                c.atFileCommands.writeOneAtEditNode(root,
                    toString=False, force=True)
            c.setChanged(False)
        else:
            fileName = ''.join(c.k.givenArgs)
            if not fileName:
                fileName = g.app.gui.runSaveFileDialog(c,
                    initialfile=c.mFileName,
                    title="Save",
                    filetypes=[g.fileFilters('LEOFILES')],
                    defaultextension=g.defaultLeoFileExtension(c))
        c.bringToFront()
        if fileName:
            # Don't change mFileName until the dialog has suceeded.
            c.mFileName = g.ensure_extension(fileName, g.defaultLeoFileExtension(c))
            c.frame.title = c.computeWindowTitle(c.mFileName)
            c.frame.setTitle(c.computeWindowTitle(c.mFileName))
                # 2013/08/04: use c.computeWindowTitle.
            c.openDirectory = c.frame.openDirectory = g.os_path_dirname(c.mFileName)
                # Bug fix in 4.4b2.
            if g.app.qt_use_tabs and hasattr(c.frame, 'top'):
                c.frame.top.leo_master.setTabName(c, c.mFileName)
            c.fileCommands.save(c.mFileName)
            g.app.recentFilesManager.updateRecentFiles(c.mFileName)
            g.chdir(c.mFileName)
    # Done in FileCommands.save.
    # c.redraw_after_icons_changed()
    c.raise_error_dialogs(kind='write')
    # *Safely* restore focus, without using the old w directly.
    if inBody:
        c.bodyWantsFocus()
        p.restoreCursorAndScroll()
    else:
        c.treeWantsFocus()
def save(self, event=None, fileName=None):
    '''Save a Leo outline to a file.'''
    if False and g.app.gui.guiName() == 'curses':
        g.trace('===== Save disabled in curses gui =====')
        return
    c = self
    p = c.p
    # Do this now: w may go away.
    w = g.app.gui.get_focus(c)
    inBody = g.app.gui.widget_name(w).startswith('body')
    if inBody:
        p.saveCursorAndScroll()
    if g.unitTesting and g.app.unitTestDict.get('init_error_dialogs') is not None:
        # A kludge for unit testing:
        # indicated that c.init_error_dialogs and c.raise_error_dialogs
        # will be called below, *without* actually saving the .leo file.
        c.init_error_dialogs()
        c.raise_error_dialogs(kind='write')
        return
    if g.app.disableSave:
        g.es("save commands disabled", color="purple")
        return
    c.init_error_dialogs()
    # 2013/09/28: use the fileName keyword argument if given.
    # This supports the leoBridge.
    # Make sure we never pass None to the ctor.
    if fileName:
        c.frame.title = g.computeWindowTitle(fileName)
        c.mFileName = fileName
    if not c.mFileName:
        c.frame.title = ""
        c.mFileName = ""
    if c.mFileName:
        # Calls c.setChanged(False) if no error.
        g.app.syntax_error_files = []
        c.fileCommands.save(c.mFileName)
        c.syntaxErrorDialog()
    else:
        root = c.rootPosition()
        if not root.next() and root.isAtEditNode():
            # There is only a single @edit node in the outline.
            # A hack to allow "quick edit" of non-Leo files.
            # See https://bugs.launchpad.net/leo-editor/+bug/381527
            fileName = None
            # Write the @edit node if needed.
            if root.isDirty():
                c.atFileCommands.writeOneAtEditNode(root,
                    toString=False, force=True)
            c.setChanged(False)
        else:
            fileName = ''.join(c.k.givenArgs)
            if not fileName:
                fileName = g.app.gui.runSaveFileDialog(c,
                    initialfile=c.mFileName,
                    title="Save",
                    filetypes=[g.fileFilters('LEOFILES')],
                    defaultextension=g.defaultLeoFileExtension(c))
        c.bringToFront()
        if fileName:
            # Don't change mFileName until the dialog has suceeded.
            c.mFileName = g.ensure_extension(fileName, g.defaultLeoFileExtension(c))
            c.frame.title = c.computeWindowTitle(c.mFileName)
            c.frame.setTitle(c.computeWindowTitle(c.mFileName))
                # 2013/08/04: use c.computeWindowTitle.
            c.openDirectory = c.frame.openDirectory = g.os_path_dirname(c.mFileName)
                # Bug fix in 4.4b2.
            if g.app.qt_use_tabs and hasattr(c.frame, 'top'):
                c.frame.top.leo_master.setTabName(c, c.mFileName)
            c.fileCommands.save(c.mFileName)
            g.app.recentFilesManager.updateRecentFiles(c.mFileName)
            g.chdir(c.mFileName)
    # Done in FileCommands.save.
    # c.redraw_after_icons_changed()
    c.raise_error_dialogs(kind='write')
    # *Safely* restore focus, without using the old w directly.
    if inBody:
        c.bodyWantsFocus()
        p.restoreCursorAndScroll()
    else:
        c.treeWantsFocus()
def save(self, event=None, fileName=None):
    """
    Save a Leo outline to a file, using the existing file name unless
    the fileName kwarg is given.

    kwarg: a file name, for use by scripts using Leo's bridge.
    """
    c = self
    p = c.p
    # Do this now: w may go away.
    w = g.app.gui.get_focus(c)
    inBody = g.app.gui.widget_name(w).startswith('body')
    if inBody:
        p.saveCursorAndScroll()
    if g.app.disableSave:
        g.es("save commands disabled", color="purple")
        return
    c.init_error_dialogs()
    # 2013/09/28: use the fileName keyword argument if given.
    # This supports the leoBridge.
    # Make sure we never pass None to the ctor.
    if fileName:
        c.frame.title = g.computeWindowTitle(fileName)
        c.mFileName = fileName
    if not c.mFileName:
        c.frame.title = ""
        c.mFileName = ""
    if c.mFileName:
        # Calls c.clearChanged() if no error.
        g.app.syntax_error_files = []
        c.fileCommands.save(c.mFileName)
        c.syntaxErrorDialog()
    else:
        root = c.rootPosition()
        if not root.next() and root.isAtEditNode():
            # There is only a single @edit node in the outline.
            # A hack to allow "quick edit" of non-Leo files.
            # See https://bugs.launchpad.net/leo-editor/+bug/381527
            fileName = None
            # Write the @edit node if needed.
            if root.isDirty():
                c.atFileCommands.writeOneAtEditNode(root)
            c.clearChanged()  # Clears all dirty bits.
        else:
            fileName = ''.join(c.k.givenArgs)
            if not fileName:
                fileName = g.app.gui.runSaveFileDialog(
                    c,
                    title="Save",
                    filetypes=[
                        ("Leo files", "*.leo *.db"),
                    ],
                    defaultextension=g.defaultLeoFileExtension(c))
        c.bringToFront()
        if fileName:
            # Don't change mFileName until the dialog has suceeded.
            c.mFileName = g.ensure_extension(fileName,
                                             g.defaultLeoFileExtension(c))
            c.frame.title = c.computeWindowTitle(c.mFileName)
            c.frame.setTitle(c.computeWindowTitle(c.mFileName))
            c.openDirectory = c.frame.openDirectory = g.os_path_dirname(
                c.mFileName)
            if hasattr(c.frame, 'top'):
                c.frame.top.leo_master.setTabName(c, c.mFileName)
            c.fileCommands.save(c.mFileName)
            g.app.recentFilesManager.updateRecentFiles(c.mFileName)
            g.chdir(c.mFileName)
    # FileCommands.save calls c.redraw_after_icons_changed()
    c.raise_error_dialogs(kind='write')
    # *Safely* restore focus, without using the old w directly.
    if inBody:
        c.bodyWantsFocus()
        p.restoreCursorAndScroll()
    else:
        c.treeWantsFocus()
def open_outline(self, event=None):
    """Open a Leo window containing the contents of a .leo file."""
    c = self

    #@+others
    #@+node:ekr.20190518121302.1: *4* function: open_completer
    def open_completer(c, closeFlag, fileName):

        c.bringToFront()
        c.init_error_dialogs()
        ok = False
        if fileName:
            if g.app.loadManager.isLeoFile(fileName):
                c2 = g.openWithFileName(fileName, old_c=c)
                if c2:
                    c2.k.makeAllBindings()
                    # Fix #579: Key bindings don't take for commands defined in plugins.
                    g.chdir(fileName)
                    g.setGlobalOpenDir(fileName)
                if c2 and closeFlag:
                    g.app.destroyWindow(c.frame)
            elif c.looksLikeDerivedFile(fileName):
                # Create an @file node for files containing Leo sentinels.
                ok = c.importCommands.importDerivedFiles(parent=c.p,
                                                         paths=[fileName],
                                                         command='Open')
            else:
                # otherwise, create an @edit node.
                ok = c.createNodeFromExternalFile(fileName)
        c.raise_error_dialogs(kind='write')
        g.app.runAlreadyOpenDialog(c)
        # openWithFileName sets focus if ok.
        if not ok:
            c.initialFocusHelper()

    #@-others
    # Defines open_completer function.

    #
    # Close the window if this command completes successfully?

    closeFlag = (
        c.frame.startupWindow and
        # The window was open on startup
        not c.changed and not c.frame.saved and
        # The window has never been changed
        g.app.numberOfUntitledWindows == 1
        # Only one untitled window has ever been opened
    )
    table = [
        ("Leo files", "*.leo *.db"),
        ("Python files", "*.py"),
        ("All files", "*"),
    ]
    fileName = ''.join(c.k.givenArgs)
    if fileName:
        c.open_completer(c, closeFlag, fileName)
        return
    if False:  # This seems not to be worth the trouble.
        g.app.gui.runOpenFileDialog(
            c,
            callback=open_completer,
            defaultextension=g.defaultLeoFileExtension(c),
            filetypes=table,
            title="Open",
        )
        return
    # Equivalent to legacy code.
    fileName = g.app.gui.runOpenFileDialog(
        c,
        defaultextension=g.defaultLeoFileExtension(c),
        filetypes=table,
        title="Open",
    )
    open_completer(c, closeFlag, fileName)