datenodes.py :  » Development » Leo » Leo-4.7.1-final » leo » plugins » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Development » Leo 
Leo » Leo 4.7.1 final » leo » plugins » datenodes.py
#@+leo-ver=4-thin
#@+node:ekr.20060807103814.1:@thin datenodes.py
#@<< docstring >>
#@+node:bobjack.20080615065747.4:<< docstring >>
"""
This plugin allows 'date nodes' to be added to the outline.

'Date nodes' are nodes that have dates in their headlines. They may be added to
the outline one at a time, a month's-worth at a time, or a year's-worth at a
time. The format of the labels (headlines) is configurable.

There are options to omit Saturdays and Sundays.

An 'Insert Date Nodes ...' submenu will be created (by default) in the 'Outline'
menu.  This menu can be suppressed by using either of the following settings:

    - @bool suppress-datenodes-menus
    - @bool suppress-all-plugins-menus

The following commands are available for use via the minibuffer or in
@menu/@popup settings.

    - datenodes-today
    - datenodes-this-month
    - datenodes-this-year

"""
#@-node:bobjack.20080615065747.4:<< docstring >>
#@nl

#@@language python
#@@tabwidth -4

__version__ = "0.7"
#@<< version history >>
#@+node:gfunch.20041207100416.2:<< version history >>
#@@nocolor
#@+at
# 
# 0.1: Initial version.
# 0.2: Improved menu structure. Added ini file.
# 0.3: Changed docstring slightly.
# 0.4: Added event=None to insert_xxx_node.
# 0.5: Added options to omit saturdays and sundays. Use leoSettings.leo 
# instead of datenodes.ini for storing options.
# 0.6: Removed @c from most nodes: this is not needed.  Also removed .ini file 
# from cvs.
# 0.7 bobjack:
#     - added plugin init method
#     - exposed the pluginController as c.theDateNodesController
#     - added support for settings:
#         - @bool suppress-datenodes-menus
#         - @bool suppress-all-plugin-menus
#     - added minibuffer commands
#         - datenodes-today
#         - datenodes-this-month
#         - datenodes-this-year
#@-at
#@nonl
#@-node:gfunch.20041207100416.2:<< version history >>
#@nl
#@<< todo >>
#@+node:bobjack.20080615065747.5:<< todo >>
#@@nocolor
#@+at
# 
# - add commands to allow day, month, year to be input via minibuffer
# 
# - add a calendar widget to allow dates to be entered via gui
# 
# - add extra methods to controller to make it easier to use the plugin from 
# scripts
# 
# - allow date ranges to be specified
# 
# - add a dialog that allows all parameters to be slected prior to insertion
#@-at
#@nonl
#@-node:bobjack.20080615065747.5:<< todo >>
#@nl

#@<< imports >>
#@+node:gfunch.20041207100416.3:<< imports >>
import leo.core.leoGlobals as g
import leo.core.leoPlugins as leoPlugins

import calendar
import codecs
import datetime
#@-node:gfunch.20041207100416.3:<< imports >>
#@nl

#@+others
#@+node:bobjack.20080615065747.2:init
def init():
    if 1: # OK for unit testing.

        leoPlugins.registerHandler("after-create-leo-frame", on_create)
        g.plugin_signon(__name__)

        return True
#@nonl
#@-node:bobjack.20080615065747.2:init
#@+node:gfunch.20041207100416.5:class DateNodes
class DateNodes:
    """Main DateNodes class"""

    # The defaults for all possible settings.
    default_settings = {
        "datenodes_body_text": "To do...",
      "datenodes_day_node_headline": "%Y-%m-%d",
        "datenodes_month_node_day_headline": "%d: %A",
        "datenodes_month_node_month_headline": "%B %Y",
        "datenodes_month_node_omit_saturdays": True,
        "datenodes_month_node_omit_sundays": True,
      "datenodes_year_node_day_headline": "%d: %A",
      "datenodes_year_node_month_headline": "%B",
      "datenodes_year_node_year_headline": "%Y",
      "datenodes_year_node_omit_saturdays": True,
      "datenodes_year_node_omit_sundays": True
    }

    # Names of settings that have to be read with getBool()
    boolean_settings = [
        "datenodes_month_node_omit_saturdays",
        "datenodes_month_node_omit_sundays", 
        "datenodes_year_node_omit_saturdays",
        "datenodes_year_node_omit_sundays"]

    ascii_encoder = codecs.getencoder("ASCII")

    #@    @+others
    #@+node:gfunch.20041207100416.6:__init__
    def __init__(self, c):
        self.c = c
        self._get_settings()

        for command, method in (
            ('datenodes-today', self.insert_day_node),
            ('datenodes-this-month', self.insert_month_node),
            ('datenodes-this-year', self.insert_year_node),
        ):
            c.k.registerCommand(command, shortcut=None, func=method)
    #@-node:gfunch.20041207100416.6:__init__
    #@+node:gfunch.20041209073652:_get_settings
    def _get_settings(self):
        """Get any configuration options."""

        settings = {}

        for setting in DateNodes.default_settings:
            if setting in DateNodes.boolean_settings:
                getter = self.c.config.getBool
            else:
                getter = self.c.config.getString

            value = getter(setting)

            if value is None:
                value = DateNodes.default_settings[setting]

            settings[setting[10:]] = value  # Omit datenodes_ prefix

        self.settings = settings
    #@-node:gfunch.20041209073652:_get_settings
    #@+node:gfunch.20041208095742:_format_node_label
    def _format_node_label(self, date, fmt):
        """Format a node label (heading)."""

        # Convert fmt to ASCII string, because strftime() doesn't like Unicode strings
        try:
            ascii_fmt = DateNodes.ascii_encoder(fmt)[0]
        except UnicodeError:
            g.es("datenodes plugin: WARNING: The format string " + fmt + " contains non-ASCII characters.")
            # Bug fix: EKR, on orders from pylint.
            ascii_fmt = DateNodes.ascii_encoder(fmt,'replace')[0]

        return date.strftime(ascii_fmt)

    #@-node:gfunch.20041208095742:_format_node_label
    #@+node:dcb.20060806185031:_insert_date_node
    def _insert_date_node(self, parent, date, format):

        c = self.c

        node = parent.insertAsLastChild()

        label = self._format_node_label(date, format)

        c.setHeadString(node,label)

        return node

    #@-node:dcb.20060806185031:_insert_date_node
    #@+node:dcb.20060806183810:_insert_day_node
    def _insert_day_node(self, parent, date, day_fmt):

        c = self.c
        day_node = self._insert_date_node(parent, date, day_fmt)

        c.setBodyString(day_node,self.settings["body_text"])

        return day_node
    #@nonl
    #@-node:dcb.20060806183810:_insert_day_node
    #@+node:gfunch.20041207100416.11:_insert_month_node
    def _insert_month_node(self, parent, date, day_fmt, month_fmt, omit_saturdays, omit_sundays):
        """Insert a months-worth of date nodes into the outline ."""

        month_node = self._insert_date_node(parent, date, month_fmt)

        year, month = date.timetuple()[:2]

        first_day_of_month, num_days = calendar.monthrange(year, month)

        for day in range(1, num_days + 1):
            day_date = datetime.date(year, month, day)
            isoweekday = day_date.isoweekday()

            if (isoweekday == 6 and omit_saturdays) or (isoweekday == 7 and omit_sundays):
                continue

            self._insert_day_node(parent = month_node, date = day_date, day_fmt = day_fmt)

        return month_node
    #@-node:gfunch.20041207100416.11:_insert_month_node
    #@+node:gfunch.20041207100416.12:_insert_year_node
    def _insert_year_node(self, parent, date, day_fmt, month_fmt, year_fmt, omit_saturdays, omit_sundays):
        """Insert a years-worth of date nodes into the outline."""

        year_node = self._insert_date_node(parent, date, year_fmt)

        year, month, day = date.timetuple()[:3]

        for month in range(1, 13):
            month_date = datetime.date(year, month, day)

            self._insert_month_node(parent = year_node, date = month_date, day_fmt = day_fmt, month_fmt = month_fmt, 
                                    omit_saturdays = omit_saturdays, omit_sundays = omit_sundays)


        return year_node
    #@nonl
    #@-node:gfunch.20041207100416.12:_insert_year_node
    #@+node:gfunch.20041208074734:insert_day_node
    def insert_day_node(self, event = None):

        today = datetime.date.today()
        day_fmt = self.settings["day_node_headline"]

        day_node = self._insert_day_node(self.c.p, today, day_fmt)

        self.c.selectPosition(day_node)



    #@-node:gfunch.20041208074734:insert_day_node
    #@+node:dcb.20060806183928:insert_month_node
    def insert_month_node(self, event = None):

        today = datetime.date.today()
        day_fmt = self.settings["month_node_day_headline"]
        month_fmt = self.settings["month_node_month_headline"]
        omit_saturdays = self.settings["month_node_omit_saturdays"]
        omit_sundays = self.settings["month_node_omit_sundays"]

        month_node = self._insert_month_node(
            self.c.p, today, day_fmt, month_fmt, omit_saturdays, omit_sundays)

        self.c.selectPosition(month_node)



    #@-node:dcb.20060806183928:insert_month_node
    #@+node:dcb.20060806184117:insert_year_node
    def insert_year_node(self, event = None):

        today = datetime.date.today()
        day_fmt = self.settings["year_node_day_headline"]
        month_fmt = self.settings["year_node_month_headline"]
        year_fmt = self.settings["year_node_year_headline"]
        omit_saturdays = self.settings["year_node_omit_saturdays"]
        omit_sundays = self.settings["year_node_omit_sundays"]

        year_node = self._insert_year_node(
            self.c.p, today, day_fmt, month_fmt, year_fmt, omit_saturdays, omit_sundays)

        self.c.selectPosition(year_node)

    #@-node:dcb.20060806184117:insert_year_node
    #@-others
#@-node:gfunch.20041207100416.5:class DateNodes
#@+node:gfunch.20041207100654:on_create
def on_create(tag, keywords):

    c = keywords.get("c")
    if not (c and c.exists):
        return

    # Rewrite to eliminate a pylint complaint.
    if hasattr(c,'theDateNodesController'):
        return

    # establish a class instance
    c.theDateNodesController = instance = DateNodes(c)

    #@    << Create the plug-in menu. >>
    #@+node:bobjack.20080615065747.3:<< Create the plug-in menu. >>
    if not (
        c.config.getBool('suppress-datenodes-menus') or
        c.config.getBool('suppress-all-plugin-menus')
    ):
        # create a menu separator
        c.frame.menu.createMenuItemsFromTable("Outline", [("-", None, None),])

        # create an expandable menu
        table = [("Single Day", None, instance.insert_day_node),
                 ("Full Month", None, instance.insert_month_node),
                 ("Full Year", None, instance.insert_year_node)]

        expandMenu = c.frame.menu.createNewMenu("Insert Date Nodes...", "Outline")
        c.frame.menu.createMenuEntries(expandMenu, table, dynamicMenu = True)
    #@-node:bobjack.20080615065747.3:<< Create the plug-in menu. >>
    #@nl

#@-node:gfunch.20041207100654:on_create
#@-others

#@-node:ekr.20060807103814.1:@thin datenodes.py
#@-leo
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.