File: frigcal-products/unzipped/frigcal_configs_base.py

# -*- coding: utf-8 -*-
r"""
======================================================================================
frigcal_configs_base.py:
Default configuration settings, in Python code, loaded at frigcal startup.

DON'T EDIT THIS FILE: instead, tailor your frigcal's appearance and behavior
by adding code to "frigcal_configs.py" that reassigns any of the names here.
That way, your settings will be immune to changes in this file on upgrades.

This file is shipped in UTF-8 Unicode and Windows end-line formats; see
UserGuide.html's "Using the Program" => "Configurations File" section. 

BASE AND USER FILES
-------------------
As of version 2.0, configuration settings are now split into two files:

    frigcal_configs_base.py
        this base file, with system-provided defaults and examples

    frigcal_configs.py
        the user file, with any user-provided customizations (EDIT THIS)

These files are related and used by frigcal as follows:

  -The base file has all the preset defaults, and may change in new versions
  -The user file imports "*" from the base and overrides any of its settings
  -frigcal imports all its settings from the user file, not the base

This simplifies editing work when upgrading to new releases: users normally
need just copy over their prior user file to the new release's folder, instead
of pasting individual settings into the new base file.  Users should still
inspect the base file to see if any new settings are available, and in-place
edits in this base file still work as before (but are discouraged).


THE ESSENTIALS
--------------

HOW TO EDIT
  This file gives multiple example settings for some names; per normal Python
  semantics, only the LAST assignment listed and run will be used.  These
  example settings may be freely changed, reordered, commented-out, or deleted.
  Each name should generally be assigned once, though the program fills in
  defaults (and prints warnings on the console) if they are not.

FOR COLORS
  Give a string color name (e.g., 'maroon') or RGB hex-code triple string
  '#RRGGBB'.  For example, '#B7DA8D' is moss green, and '#DD76C7' is rose.
  Try http://www.tcl.tk/man/tcl8.4/TkCmd/colors.htm for defined color names.
  [1.7] For custom colors, see the newly-included "pickcolor.py" utility script;
  it displays a chosen color's '#RRGGBB' string in a GUI, for cut-and-paste.
  Caution: using the same color for text and background will be unreadable.

FOR FONTS
  Give either a tuple ('family', size?, 'style? style? ...) or a string
  'family size? style? style? ...' if the family name contains no spaces.
  The optional size must appear second; negative means pixels instead of
  points, 0 means default size, and omission means 0.  Styles may include
  any mix of: 'bold', 'normal' (non-bold) 'italic', 'roman' (non-italic),
  'underline', and 'overstrike'.  The default style is 'normal roman'.

  For example: ('arial', 16, 'bold'), 'courier 14 normal', 'times 15 italic',
  ('consolas', 12, 'bold italic underline').  Some partial specifiers work
  too ('times', 'times 20'), but don't skip the size ('times bold' fails).
  Note: on Linux, some Asian characters may render better if non-bold,
  and larger font sizes may help in general; see LINUX_ASIAN_FONTS below.
  In [2.0], some fonts have been tailored for Mac OS X appearance as well.

EDIT WITH CARE
  frigcal won't start if there is a syntax error in this file (and you'll get
  error details in both the console window and a GUI popup), so be careful with
  changes here.  You may want to save a backup copy before making edits.  If
  there are no syntax errors, most invalid or missing setting values do not
  cause the program to fail or stop, but are replaced with defaults and may
  trigger messages on the console; please verify your values.  Import this
  module separately in a Python interactive session to error check.


ADDITIONAL NOTES
----------------

USING NON-ENGLISH STRINGS HERE [1.7]
  The first line in this file gives the Unicode encoding of its content,
  including all its embedded string literals.  Python defaults to UTF-8
  (which handles simple ASCII) if no such line is present, but other encodings
  can be used above too (e.g., latin-1).  You can also use Python's '\uhhhh'
  and '\Uhhhhhhhh' Unicode code-point escapes in any of this file's strings.
  Non-English strings can be used in file paths, category names, and more;
  see the example in event-color category names below.

EVENT FOREGROUND COLORS [1.7]
  As of version 1.7, event summary color values can be either a string giving
  background only (the former scheme), or a 2-item tuple giving both background
  and foreground colors (the new enhanced scheme). For example, a color setting:

    'wheat'
         sets the event widget's background color only, leaving its
         foreground (the event text) the default black

    ('navy', 'orange')
         sets the event widget's background color to 'navy' and its
         foreground (the event text) color to 'orange'

  In all cases, the default event background and foreground are white and black,
  and each color value may still be either a color name or #RRGGBB hex code.
  Caution: using the same color for text and background will be unreadable, and
  some error cases may result in this; see the console for color error messages.

COLOR NAME CHANGES [1.6]
  Standard Windows installs of Pythons 3.4+ use version 8.6 of the Tk library
  underlying tkinter, which changes the meaning of four color names.  "green",
  "purple", "maroon", and "grey/gray" render more darkly, and some of the new
  8.6 name equivalents aren't available in older Tk versions (e.g., the former
  "green" becomes "lime", but "lime" doesn't work in prior Tks!).

  This file maps changed colors to portable names (e.g., GREEN).  As a rule of
  thumb, though, using '#RRGGBB' hex strings instead of color names will make
  your colors portable across all Pythons and Tks (see "pickcolor.py" to create
  these strings).  For more details on this Tk change:

    http://learning-python.com/books/python-changes-2014-plus.html#s359
    http://www.tcl.tk/cgi-bin/tct/tip/403.html
    https://bugs.python.org/issue23982, or
    https://www.tcl.tk/man/tcl/TkCmd/colors.htm.

TBDs
  A plain text configs file wouldn't require Python coding skills, but also
  wouldn't help much, as errors may still preclude program launch.  Values
  could also be verified once at startup instead of on each config.
======================================================================================
"""


# For platform/version-dependent settings
import sys, tkinter, os



# For platform-specific choices (available in frigcal_configs.py too)

RunningOnMac     = sys.platform.startswith('darwin')       # all OS (X)
RunningOnWindows = sys.platform.startswith('win')          # all Windows
RunningOnLinux   = sys.platform.startswith('linux')        # all Linux



# For Python- or Tk-specific choices

PyVersion = float(sys.version[:3])    # e.g., '3.5.0 ...' => 3.5
TkVersion = tkinter.TkVersion         # e.g., 8.5 or 8.6 (Win Py 3.4+ use Tk 8.6)
print('Using Python', PyVersion, 'and Tk', TkVersion)    # display versions [1.6]



# Portable color choices that differ between Tk 8.6 and earlier (see above) [1.6]

GREEN  = 'green'  if TkVersion < 8.6 else 'lime'         # 'lime' only in 8.6+
PURPLE = 'medium purple'                                 # same in all versions
MAROON = 'maroon' if TkVersion < 8.6 else 'indian red'   # not exactly, but close
GRAY   = 'grey'   if TkVersion < 8.6 else 'silver'       # 'silver' only in 8.6+



#=====================================================================================
# MONTH AND IMAGE WINDOW BEHAVIOR (last setting wins: multiple examples)
#=====================================================================================


# Event click/press bindings model, 'mouse' or 'touch': see UserGuide.html

clickmode = 'touch'         # single-press model
clickmode = 'mouse'         # double-press model, with inline summary edits



# Month windows' initial size in pixels or % (but fully resizable thereafter)

initwinsize = None          # if None, automatically sized by content (but may vary)
initwinsize = '1000x800'    # string giving absolute pixels: '<width>x<height>'
initwinsize = 0.75          # float <= 1.0 giving % of full screen's width and height
initwinsize = (0.60, 0.80)  # tuple = (% of full screen width, % of full screen height)



# Month windows' minimum size in pixels (to avoid shrinking too much if few events)

minwinsize = None           # if None, no limit on shrink (but some controls vanish)
minwinsize = initwinsize    # if same, can only grow, not shrink
minwinsize = '650x400'      # pixels: '<width>x<height>'



# Month windows' start position (or add at end of initwinsize: '800x600+10+10') 

initwinposition = '+10+10'  # start +X+Y offset in pixels from top left (clones too)
initwinposition = None      # if None, default = GUI chooses (generally preferred)



# Month image-windows' start position (for all month's images) [1.4]

initimgposition = '+0+0'    # start +X+Y offset in pixels from top left corner
initimgposition = None      # if None, default = GUI chooses (generally preferred)



#=====================================================================================
# MONTH WINDOW APPEARANCE (last setting wins: multiple examples)
#=====================================================================================


# Month window background color

rootbg = None                   # None=tk default
rootbg = 'tan'                  # see above for format
rootbg = 'navy'                 
rootbg = 'steelblue'



# Month day-tiles background color

daysbg = None                   # None=tk default
daysbg = 'beige'                # see above for format
daysbg = 'lightblue'
daysbg = 'powderblue'



# Font for text on month day-tiles: number and events (and event-select list)

daysfont = None                              # None=tk default
daysfont = ('courier', 16, 'bold italic')    # see above for format
daysfont = ('times', 9, 'bold underline')
daysfont = ('calibri', 12, 'normal')
daysfont = ('arial', 9, 'bold')              # default

# Customize by platform: larger font on Mac and Linux [2.0]

if RunningOnMac:
    daysfont = ('arial', 10, 'bold')         # or menlo, monaco        

elif RunningOnWindows:
    pass  # use default (last) above         # or consolas

elif RunningOnLinux:
    daysfont = ('arial', 10, 'bold')         # or inconsolata



# Font for text on month and day names at top of window

monthnamefont = ('times', 12, 'bold italic')
daynamefont = ('times', 9)

# Customize by platform

if RunningOnMac:
    monthnamefont = ('arial', 15, 'bold italic')  
    daynamefont = ('monaco', 10)

elif RunningOnWindows:
    monthnamefont = ('arial', 14, 'bold italic')
    daynamefont = ('consolas', 9)

elif RunningOnLinux:
    monthnamefont = ('arial', 14, 'bold italic')
    daynamefont = ('inconsolata', 9)



# Font for text on buttons and toggles at top and bottom of month windows
# This is also used for buttons in event-edit and even-list dialog popups

controlsfont = None                          # None=tk default
controlsfont = ('arial', 8, 'bold')          # see above for format

# Customize by platform

if RunningOnMac:
    controlsfont = ('arial', 9, 'bold')      # use larger fonts on Mac



# Current-day shading color, defaults to gray if not set or None [1.6]

currentdaycolor = GRAY                       # or rootbg to match border?



#=====================================================================================
# FOOTER PANEL: size (start or fixed), background color, and font
#=====================================================================================


footerheight = 5                         # in #lines, or None=tk default
footerresize = False                     # True=grows with window, else fixed #lines
footercolor  = 'beige'                   # (see above) or None=tk default (white)
footerfont   = ('courier', 10, 'bold')   # (see above) or None=tk default


# Custom footer fonts on Mac OS X and Linux [2.0]

if RunningOnMac:
    footerfont  = ('courier', 12, 'normal')     # or menlo, monaco, etc.

elif RunningOnWindows:
    pass  # use default (last) above            # or consolas, etc.

elif RunningOnLinux:
    footerfont  = ('courier', 11, 'bold')       # or inconsolata, etc.


# Footer display control

clearfooter = False                      # True=erase footer text on go to new month



#=====================================================================================
# EVENT VIEW/EDIT DIALOG: appearance (None=tk default, see intro for values)
#=====================================================================================


eventdialogfg   = 'beige'
eventdialogbg   = 'tan'
eventdialogfont = ('courier', 12, 'bold')          # default


# Customize by platform: larger on Linux and Mac, non-bold on Mac [2.0]

if RunningOnMac:
    eventdialogfont = ('courier', 14, 'normal')    # or menlo, monaco

elif RunningOnWindows:
    pass  # use default (last) above               # or consolas

elif RunningOnLinux: 
    eventdialogfont = ('courier', 13, 'bold')      # or inconsolata


# Event view/edit dialog's description text area size (new in [2.0])

eventdialogtextheight = 10      # number lines (None=default=5; Tk default=24)
eventdialogtextwidth  = None    # number characters (None=Tk default=80)


# See also controlsfont above, used for buttons in event-edit (and other) dialogs



#=====================================================================================
# SPECIAL-CASE FONTS (e.g., for Asian or monospace characters on Linux)
#=====================================================================================


#-------------------------------------------------------------------------------------
# Bold fonts can make some Asian characters (and possibly others) render unreadably
# on Linux, but bold seems to work well on Windows for all fonts, and non-bold seems
# too dull for other cases to be the default (though YMMV).  You may also want to
# use a larger font size here, but this is too subjective to set a policy here.
#-------------------------------------------------------------------------------------

LINUX_ASIAN_FONTS = False   # and/or test RunningOnLinux?

if LINUX_ASIAN_FONTS:
    daysfont        = ('arial', 9, 'normal')
    footerfont      = ('courier', 10, 'normal')
    eventdialogfont = ('courier', 12, 'normal')


#-------------------------------------------------------------------------------------
# Monospace fonts: platform-specific (currently unused - example only).
# Consolas isn't monospace on Linux, but inconsolata isn't monospace on Windows.
# Courier works for monospace on all three, but may have a duller appearance.
#-------------------------------------------------------------------------------------

MONOSPACE_FONTS = False

if MONOSPACE_FONTS:
    if RunningOnMac:                               # or monaco, courier
        daysfont = ('menlo', 10, 'bold')

    elif RunningOnWindows:                         # or courier
        daysfont = ('consolas', 10, 'bold')

    elif RunningOnLinux:                           # or courier                              
        daysfont = ('inconsolata', 10, 'bold')

    else:                                          # others?
        daysfont = ('courier new', 10, 'bold')



#=====================================================================================
# ICS CALENDAR FILE FORMATTING
#=====================================================================================


#-------------------------------------------------------------------------------------
# [1.4] Retain literal backslashes in Summary and Description text, via quoted-printable
# '=5C' notation escapes?  See version 1.4 notes in UserGuide.html for full details.
# If True, retains '\' but risks file portability: other GUIs may not undo '=5C' (if any).
# If False, drops some '\', and 2-char literal '\n' becomes 1-char newline on reloads.
#-------------------------------------------------------------------------------------

retainLiteralBackslashes = True          # True=escape and retain any literal '\'



#=====================================================================================
# CALENDAR AND IMAGE FOLDERS (last setting wins: multiple examples)
#=====================================================================================


#-------------------------------------------------------------------------------------
# iCalendar '.ics' event files folder path, with auto-created 'Backups' subfolder.
# All '*.ics' files in this folder are loaded as calendars at program start-up.
# The Backups subfolder saves prior versions of changed files before they are updated.
# DEFAULT is 'Calendars\*.ics' files, in subfolder of the main script's folder.
#-------------------------------------------------------------------------------------

icspath = r'C:\my-archived-folder\Calendar\ICSFiles'         # other folders
icspath = r'Calendars\subfolder-for-event-type'              # subsets
icspath = None                                               # None=DEFAULT


#-------------------------------------------------------------------------------------
# iCalendar '.ics' files 'Backup' subfolder maximum size.
# Keep up to this many latest backups of each .ics in 'icspath\Backups' subfolder.
#-------------------------------------------------------------------------------------

maxbackups = 10


#-------------------------------------------------------------------------------------
# Month image files folder path: 12 image files, mapped to months by sorted filename.
# Image files are displayed in a popup without resizing, if Images is toggled on in
# the GUI.  Requires Pillow install, unless you use PNGs on a Python using Tk 8.6+
# (e.g., Py3.4+ on Windows), or GIF/PPM/PPGs on any Py3.X [1.6].  To use images of
# your own, either change the default folder in-place, or change the path here.  The
# DEFAULT is 'MonthImages\*.{png, jpg, etc.}' files, in subfolder of script's folder.
#-------------------------------------------------------------------------------------

imgpath = r'C:\my-archived-folder\Calendar\MonthImages'      # other folders
imgpath = r'MonthImages\AlternateMonthImages\DrawnImages1'   # alternate sets
imgpath = r'MonthImages\AlternateMonthImages\DrawnImages1\WithTrees'
imgpath = r'MonthImages\AlternateMonthImages\OriginalLabeled\Small'
imgpath = r'MonthImages\AlternateMonthImages\OriginalLabeled\Large'
imgpath = None                                               # None=DEFAULT


#-------------------------------------------------------------------------------------
# On Linux + Mac: change any Windows '\' path separators to '/' [1.6].
# This code fixes paths if you keep the Windows '\' in the examples above.
#-------------------------------------------------------------------------------------

if not RunningOnWindows:
    if icspath: icspath = icspath.replace('\\', os.sep) 
    if imgpath: imgpath = imgpath.replace('\\', os.sep)      # either may be None



#=====================================================================================
# EVENT SUMMARY COLORS (by category name and/or calendar-file name)
#=====================================================================================


#-------------------------------------------------------------------------------------
# The following settings are meant as examples only: edit or replace as you prefer.
# Event category colors span calendars, and override any calendar color settings.
#
# To colorize events:
# 1) Edit the category and/or calendar color dictionaries here, giving either
#    a color name or #RRGGBB hex-code string for each color value.
# 2) Enter event category and calendar names in the GUI's View/Edit and Create
#    dialogs opened on event and day clicks, respectively.  An empty category
#    name in the GUI picks up either the calendar's color, or the color of a
#    category-dictionary entry whose key is an explicit empty string (a default). 
#
# See also the top of this file for:
#   -More on color setting values, and the chooser utility script "pickcolor.py"
#   -Notes about color name changes in in Tk 8.6+ (e.g., Python 3.4+ on Windows)
#   -Version 1.7's event foreground colors extension: color values can now be strings
#    giving background only, or (bg, fg) tuples giving both background and foreground
#
# Also note that the widget used to select from category names may have a limited
# size on some systems (e.g., Linux) and small screens; use fewer names if needed.
#-------------------------------------------------------------------------------------


#-------------------------------------------------------------------------------------
# CATEGORIES MAP: event category name => event summary widget color.
# Category entered in event's GUI, color = color name or RGB hex triple '#RRGGBB'.
# These span all calendars, and override calendar_colors below for specific events.
# Category name '' can be used to provide default for all events with no category.
# Default is 'white' if category's name is not listed here (and calendar not colored).
#-------------------------------------------------------------------------------------

category_ignorecase = True   # caseless lookup? (if True: travel=Travel, Travel=travel)


# Basic category names (color neutral)

category_colors = {
    'travel':           'tan',             # example names/colors: EDIT OR REPLACE
    'birthday':         'yellow',          # key=category, value='bg' or ('bg', 'fg')
    'anniversary':      'red',            
    'milestone':        'sky blue',
    'business':         'orange',
    'pybooks':          'pink',
    'education':         PURPLE,           # [1.6] differs in Tk 8.6+
    'politics':          MAROON,           # [1.6] differs in Tk 8.6+
    'weather':          'wheat',
    'conference':       'lavender',
    'gadgets':          'forest green',
    'other':            'light green'
    }


# Add any legacy categories (used in other calendars)

category_colors.update({
    'Red Category':     'red',
    'Green Category':    GREEN             # [1.6] differs in Tk 8.6+
    })


# Add any absolute color names (_x names appear early in list sort order);
# the leading '_' here is not significant - for sort order grouping only

category_colors.update({
    '_red':             'red',
    '_green':            GREEN,            # [1.6] differs in Tk 8.6+
    '_oldgreen':        'green',
    '_purple':           PURPLE,           # [1.6] differs in Tk 8.6+
    '_oldpurple':       'purple', 
    '_orange':          'orange',
    '_blue':            'sky blue',
    '_wheat':           'wheat',
    '_cyan':            'cyan',
    '_gray':             GRAY,             #[1.6] differs in Tk 8.6+
    '_yellow':          'yellow',
    '_lavender':        'lavender',
    '_violet':          'violet',
    '_dark red':        'indian red',
    '_beige':           'beige'            # plus _many_ more: see the web
    #,'':               'yellow'           # if used: a default category
    })


# [1.7] Add (bg, fg) color tuples (can also be mixed into other tables above);
# the leading '+' here is not significant - for sort order grouping only

category_colors.update({
    '+blues':           ('navy', 'white'),
    '+christmas':       ('dark green', 'red'),
    '+Важное событие':  ('black', 'orange'),
    '+purples':         ('purple', 'lavender'),       # key = 'category'
    '+packers':         ('green', 'gold'),            # value = 'bg' or ('bg', 'fg')
    '+broncos':         ('orange', 'blue'),
    '+seahawks☂':      ('navy', GREEN),
    '+重要事件':         ('indian red', 'white'),      # [1.7] non-English text 
    '+greens':          ('forest green', 'white'),    # [2.0] white foreground
    '+neons':           ('cyan', 'yellow'),
    '+goth':            ('black', GRAY),
    })


# For testing only: error cases and None=default

"""
category_colors.update({
    '+BAD1':            [1, 2, 3],
    '+BAD2':            (25,  'black'),               # fails on bg
    '+BAD3':            ('black', 25),                # fails on fg
    '+BAD4':            ('nonesuch', 'black'),
    '+BAD5':            ('black', 'nonsuch'),
    '+BADNonesuch':     'nonesuch',
    '+OKNone':          None,                         # None=''=nonmatch=>dflt
    })
"""


#-------------------------------------------------------------------------------------
# CALENDARS MAP: ics calendar file name => event summary widget color.
# File is basename (no path), color = color name or RGB hex triple '#RRGGBB'.
# These span all events in a calendar file, but category_colors above overrides these.
# Default is 'white' if a file's name is not listed here (and category not colored).
# Examples only: edit me (and okay if an ics file name in the table does not exist).
#-------------------------------------------------------------------------------------

calendar_colors = {                        # example names/colors: EDIT OR REPLACE
    'Bills.ics':        'cyan',            # key=filename, value='bg' or ('bg', 'fg')
    'Holidays.ics':     ('red', 'white'),  # [1.7] (bg, fg) tuple works here too
    'trips.ics':         GREEN,            # [1.6] differs in Tk 8.6+
    'business.ics':      GRAY,             # [1.6] differs in Tk 8.6+            
    'Personal.ics':     'beige'
    }             



#=====================================================================================
# END OF CODE (suggestions only follow)
#=====================================================================================



"""
======================================================================================

Examples of more advanced config techniques:

# 1) Proportional window height
initwinwide = 800
initwinsize = '%dx%d' % (initwinwide, int(initwinwide * .80))  # high=80% of wide

# 2) Window size per platform/version (e.g., if this implies distinct devices)
if RunningOnWindows:
    winversion = sys.getwindowsversion()
    majorminor = (winversion.major, winversion.minor)
    if majorminor >= (6, 2):
        initwinsize = '800x600'            # Windows 8=6.2, 8.1=6.3 (tablet?)
    else:
        initwinsize = '1000x800'           # Windows 7=6.1 (laptop/desktop?)
elif RunningOnLinux:
    initwinsize = '1000x800'               # Linux laptop?
else:
    initwinsize = '1000x800'               # Mac OS X laptop?

# 3) Scale window size to actual display (caveat: this pops up a temp window);
# *this has been subsumed* by a float/tuple initwinsize giving % of full screen,
# applied in frigcal.py automatically only after root Tk() window is created;

from tkinter import Tk
root = Tk()                                # get full screen size from tkinter GUI
swide = root.winfo_screenwidth()           # in pixels: (e.g., 1920)
shigh = root.winfo_screenheight()          # in pixels: (e.g., 1080)
root.destroy()
initwinsize = '%dx%d' % (int(swide * (2/3)),            # wide=2/3 of full screen
                         int(.80 * (swide * (2/3))))    # high=80% of width

# 4) Themes: prompt for a settings set/theme name in the console window at
# startup and choose from different assignment sets in this file with an 'if'

theme = input('theme?')         # 3.x only
if theme == 'blues':
    ...
    ...settings here, plus month images path?
    ...
elif theme == 'browns':
    ...
    ...other settings here
    ...
else:
    ...default settings here?
======================================================================================
"""



[Home] Books Programs Blog Python Author Training Search Email ©M.Lutz