#@+leo-ver=5-thin
#@+node:edream.110203113231.724: * @file mod_autosave.py
""" Autosaves the Leo outline every so often.

The time between saves is given by the setting, with default as shown::

    @int mod_autosave_interval = 300

This plugin is active only if::

    @bool mod_autosave_active = True

"""

# By Paul Paterson. Rewritten by EKR.
import leo.core.leoGlobals as g
# import leo.plugins.qt_text as qt_text
from leo.core.leoQt import QtWidgets
import time
# The global settings dict.
gDict = {} # Keys are commanders, values are settings dicts.

#@+others
#@+node:ekr.20060108123141.2: ** init
def init ():
    '''Return True if the plugin has loaded successfully.'''
    ok = not g.app.unitTesting
        # Don't want autosave after unit testing.
    if ok:
        # Register the handlers...
        g.registerHandler('after-create-leo-frame',onCreate)
        g.plugin_signon( __name__ )
    return ok
#@+node:edream.110203113231.726: ** onCreate (mod_autosave.py)
def onCreate(tag, keywords):
    """Handle the per-Leo-file settings."""
    global gDict
    c = keywords.get('c')
    if g.app.unitTesting or g.app.killed or not c or not c.exists:
        return
    # Do nothing here if we already have registered the idle-time hook.
    d = gDict.get(c.hash())
    if not d:
        active = c.config.getBool('mod_autosave_active',default=False)
        interval = c.config.getInt('mod_autosave_interval')
        if active:
            # Create an entry in the global settings dict.
            gDict[c.hash()] = {
                'last':time.time(),
                'interval':interval,
            }
            message = "auto save %s sec. after changes" % (interval)
            g.registerHandler('idle',onIdle)
        else:
            message = "@bool mod_autosave_active=False"
        g.es(message, color='orange')
#@+node:ekr.20100904062957.10654: ** onIdle
def onIdle (tag,keywords):
    """Save the current document if it has a name"""
    global gDict
    guiName = g.app.gui.guiName()
    if guiName not in ('qt','qttabs'):
        return
    c = keywords.get('c')
    d = gDict.get(c.hash())
    if c and d and c.exists and c.mFileName and not g.app.killed and not g.unitTesting:
        # Wait the entire interval after c is first changed or saved.
        # Imo (EKR) this is the desired behavior.
        # It gives the user a chance to revert changes before they are changed.
        if c.changed:
            w = c.get_focus()
            if isinstance(w, QtWidgets.QLineEdit):
                # Saving now would destroy the focus.
                # There is **no way** to recreate outline editing after a redraw.
                pass
            else:
                last = d.get('last')
                interval = d.get('interval')
                if time.time()-last >= interval:
                    g.es_print("Autosave: %s" % time.ctime(),color="orange")
                    c.fileCommands.save(c.mFileName)
                    c.set_focus(w,force=True)
                    d['last'] = time.time()
                    gDict[c.hash()] = d
        else:
            d['last'] = time.time()
            gDict[c.hash()] = d
#@-others
#@@language python
#@@tabwidth -4
#@-leo
