GettingThingsDone: WikidPadHooks.py

# -*- coding: latin-1 -*-
# above line added to avoid deprecation warnings regarding unicode (see below)

from os.path import join         # for what is that needed here? Is it really needed

WIKIDPAD_PLUGIN = (("hooks", 1),)


def startup(wikidPad):
    """
    Called when application starts
    """

    pass

def newWiki(wikidPad, wikiName, wikiDir):
    """
    Called when a new wiki is about to be created.

    wikiName -- name of the wiki (already checked to be a proper CamelCase word)
    wikiDir -- directory to create the wiki in (more precisely the .wiki config
           file). This directory may already exist
    """
    pass

def createdWiki(wikidPad, wikiName, wikiDir):
    """
    Called when creation of a new wiki was done successfully.

    The home wiki word (equals name of the wiki) is not yet loaded.

    wikiName -- name of the wiki
    wikiDir -- directory the wiki was created in
    """
    pass

def openWiki(wikidPad, wikiConfig):
    """
    Called when an existing wiki is about to be opened.

    wikiConfig -- path to the .wiki config file
    """
    pass

def openedWiki(wikidPad, wikiName, wikiConfig):
    """
    Called when an existing wiki was opened successfully

    wikiName -- name of the wiki
    wikiConfig -- path to the .wiki config file
    """
    pass

def openWikiWord(wikidPad, wikiWord):
    """
    Called when a new or existing wiki word is about to be opened.
    The previous active page is already saved, new one is not yet loaded.

    wikiWord -- name of the wiki word to open
    """
    pass

def newWikiWord(wikidPad, wikiWord):
    """
    Called when a new wiki word is about to be created.
    The wikidPad.currentWikiPage of the new word is already available

    wikiWord -- name of the wiki word to create
    """
    pass

def openedWikiWord(wikidPad, wikiWord):
    """
    Called when a new or existing wiki word was opened successfully.

    wikiWord -- name of the wiki word to create

    ============================================================================================

    """
    from WikidPadStarter import VERSION_STRING        # e.g. "wikidPad 1.8beta6"
    import pwiki.srePersistent as pre

    from re      import compile, match, sub
    import re
    from time    import strftime, strptime, mktime, localtime, time
    from string  import lstrip, replace
    def getEditor(with_todos=0):
        version=VERSION_STRING[9:12]                      # e.g. "1.8"
        if VERSION_STRING[13:17] == "beta":
            betaversion = int(VERSION_STRING[17:])
        else:
            betaversion = 0
        if version < "1.9":
            if wikidPad.wikiName == "WikidPadHelp": 
                in_help=1
                editor=0
                todosFull=0
            else:
                editor    = wikidPad.getActiveEditor()
                if with_todos: todosFull = wikidPad.wikiData.getTodos()
        else:
            if wikidPad.getMainControl().wikiName == "WikidPadHelp": 
                in_help=1
                editor=0
                todosFull=0
            else:
                in_help=0
                if with_todos: todosFull = wikidPad.getMainControl().wikiData.getTodos()
                if version == "1.9" and betaversion <6 :
                    editor    = wikidPad.getSubControl("textedit")
                else:
                    editor    = wikidPad.getActiveEditor()
        if with_todos:                    
            return editor, todosFull, in_help
        else:
            return editor, in_help
    def clearFromStart(editor):
        #clean the page code - after :start: markup
        st = editor.FindText(0, editor.GetLength(), "[:start:]", 0)
        st = editor.PositionFromLine(1+editor.LineFromPosition(st))
        editor.SetSelection(st, editor.GetLength())
        editor.ReplaceSelection("\n")

    if (wikiWord.upper() == "TODO"):
        formatting = wikidPad.getFormatting()
        editor,todosFull,in_help=getEditor(with_todos=1)
        if in_help: return
        # tags contains the (Tag, TagHeader) pairs - customize the list of sort categories here:
        # TagHeaders are the descriptive headings that will be shown for each category.
        tags = [
                ('Tickler','Things to Remember','#0000ff'),
                ('_spec.SPACER',''),
                ('Active','Active - On Work Now','#ff00ff'),
                ('_spec.SPACER',''),
                ('Next','Next Actions','#ff0000'),
                ('_spec.SPACER',''),
                ('Highest','HIGHEST Priority!!!','#cc0000'),
                ('_spec.SPACER','',''),
                ('High','HIGH Priority!','#800000'),
                ('_spec.SPACER','',''),
                ('ThisWeek','Tasks for This Week','#808000'),
                ('_spec.SPACER','',''),
                ('Later','To be done Later','#008080'),
                ('_spec.SPACER','',''),
                ('TimeToTime','To be Done from time to time',''),
                ('_spec.SPACER','',''),
                ('Low','LOW Priority',''),
                ('_spec.SPACER','',''),
                ('VeryLow','Lowest Priority','#303030'),
                ('_spec.SPACER','',''),
                ('SomeDay','SomeDay / Maybe','#808080')
                ]
        
        # MikeCrowe -- Untagged always at end of list
        tagEnd = [
                ('_spec.SPACER',''),
                ('_spec.NOTAGS','Untagged Todos')]


        srchstr = wikiWord[4:]
    
        # get all todos with 'todo' in them to seperate list to be used here:
        todos = [todo for todo in todosFull if ('todo' in todo[1]) ] # and srchstr in todo[1]) ]

        clearFromStart(editor)
        # handle the page by displaying all keywords with srchstr  -> list all todos :
        tagAdded = True    #used to stop two spacers in a row
        checkTags = [tag[0] for tag in tags]

        # MikeCrowe -- code to search for tags not in above list and automatically add
        for todo in todos:
            allTodo = todo[1].split(":")
            words = allTodo[0].split(".")
            for word in words[1:]:
                if not word in checkTags:
                    tags.append( ("_spec.SPACER","") )
                    tags.append( (word,"Tagged "+word) )
                    checkTags.append(word)
        tags = tags + tagEnd

        for tag in tags:
            wroteHeader = False   #used to make sure that header is written only once - in a non-empty category
            
            # handle special tag '_spec.SPACER' by writing SPACERs in the tag list:
            if tag[0] == '_spec.SPACER' and tagAdded:
                editor.AddText('\n' + ('-'*70) + '\n')
                tagAdded = False
    
            # handle special NOTAG in the tag list
            # This displays all untagged todos   :
            elif tag[0] != '_spec.NOTAGS':
                addedColor=0
                for todo in todos:
                    if (tag[0] in todo[1]):
                        if not wroteHeader:
                            if (len(tag)>2 and  tag[2] != ''):
                                addedColor=1
                                editor.AddText("\n<font color="+tag[2]+">\n")
                            editor.AddText('\n++ ' + tag[1] + ' :\n')
                            wroteHeader = True
                        s = str(todo[1])
                        s1=s[:s.find(':')]
                        s1=re.sub(r'(todo|Active|Highest|High|Next|ThisWeek|Later|SomeDay|TimeToTime|Low|VeryLow|Tickler).','',s1)
                        editor.AddText(' * '+ s1+ ' -> [' +str(todo[0]) + ']: ' +  s[s.find(':')+1:] + '\n')
                        todos[todos.index(todo)] = ('DEL','DEL') #marks that todo to be ignored
                        tagAdded = True
                if (addedColor):
                    editor.AddText("\n</font>\n")
                    addedColor=0
            # handle normal Tags - write the todos for that tag:
            else:
                for todo in todos:
                    foundTag = False
                    for t in tags:
                        if t[0] in todo[1]:
                            foundTag = True
                            break
                        
                    if not foundTag and todo[0] != 'DEL':
                        if not wroteHeader:
                            editor.AddText('\n++ ' + tag[1] + ' :\n')
                            wroteHeader = True
                        s = str(todo[1])
                        editor.AddText(' * '+ str(todo[0]) + ': '+  s[s.find(':')+1:] + '\n')

                        todos[todos.index(todo)] = ('DEL','DEL') #marks that todo to be ignored
                        tagAdded = True
    elif (wikiWord == "DoneTasks"):
        editor,todosFull,in_help=getEditor(with_todos=1)
        if in_help: return
        clearFromStart(editor)
        dones = [todo for todo in todosFull if ('done.' in todo[1] and (not  'DoneTasks' in todo[0]  ) ) ]
        for todo in dones:
            editor.AddText("  * ")
            editor.AddText(str("["+todo[0]+"]:"))
            editor.AddText("  ")
            editor.AddText(str(todo[1].replace("done."," ")))
            editor.AddText("\n")
        editor.AddText("\n----\n");
    elif (wikiWord[:8] == "ListProp"):
        formatting = wikidPad.getFormatting()
        editor,in_help=getEditor()
        if in_help: return
        clearFromStart(editor)
        list =wikiWord.split("yyy")
        keyword = list[0].replace("xxx",".")
        if len(list) == 2:
            searchterm =list[1].replace("zzz"," ")
        else:
            searchterm =""
        values =wikidPad.getMainControl().wikiData.getPropertyNamesStartingWith(keyword[8:].lower())
        values.sort()
        for val in values:
            editor.AddText("++ %s\n" % val)
            if searchterm =="":
                allvalues = wikidPad.getMainControl().wikiData.getDistinctPropertyValues(val)
                allvalues.sort()
                for listitem in allvalues:
                    editor.AddText("+++ %s\n" % listitem)
                    words =wikidPad.getMainControl().wikiData.getWordsWithPropertyValue(val,listitem)
                    for word in words:
                        cc = formatting.isCcWikiWord(word)
                        if cc:
                            editor.AddText(" * %s\n" % word)
                        else:
                            editor.AddText(" * [%s]\n" % word)
                    editor.AddText("\n")
            else:
                editor.AddText("+++ %s\n" % searchterm)
                words =wikidPad.getMainControl().wikiData.getWordsWithPropertyValue(val,searchterm)
                for word in words:
                    cc = formatting.isCcWikiWord(word)
                    if cc:
                        editor.AddText(" * %s\n" % word)
                    else:
                        editor.AddText(" * [%s]\n" % word)
                editor.AddText("\n")
            editor.AddText("\n")



def savingWikiWord(wikidPad, wikiWord):
    """
    Called when a new or existing wiki word is about to be saved

    wikiWord -- name of the wiki word to create
    """
    pass

def savedWikiWord(wikidPad, wikiWord):
    """
    Called when a wiki word was saved successfully

    wikiWord -- name of the wiki word to create
    """
    pass

def renamedWikiWord(wikidPad, fromWord, toWord):
    """
    Called when a wiki word was renamed successfully.

    The changed data is already saved in the fileset,
    the GUI is not updated yet, the renamed page is not yet loaded.

    fromWord -- name of the wiki word before renaming
    toWord -- name of the wiki word after renaming
    """
    pass

def deletedWikiWord(wikidPad, wikiWord):
    """
    Called when a wiki word was deleted successfully.

    The changed data is already saved in the fileset,
    the GUI is not updated yet, another page (normally
    the last in history before the deleted one) is not yet loaded.

    wikiWord -- name of the deleted wiki word
    """
    pass

def exit(wikidPad):
    """
    Called when the application is about to exit.

    The global and the wiki configuration (if any) are saved already,
    the current wiki page (if any) is saved already.
    """
    pass