#!/usr/bin/python ########################################################### # Skin Converter Rainlendar2 version 1.0 ########################################################### import os, sys, optparse, glob, ConfigParser import xml.etree.ElementTree as ET ########################################################### # Global variables ########################################################### g_Debug = False g_Elements = {} g_Categories = [] ########################################################## # Scans the current folder for ini format skin files ########################################################## def scanIniFiles(folder): iniFiles = [] fileFilter = os.path.join(folder, "*.ini") DebugPrint("Scanning folder: " + folder) for iniFile in glob.glob(fileFilter): iniFiles.append(iniFile) DebugPrint("Found: " + iniFile) return iniFiles; ########################################################### # Converts the list of ini files to xml versions ########################################################### def convertInisToXml(iniFiles): skin = ET.Element("skin") info = ET.SubElement(skin, "info") version = ET.SubElement(info, "version") version.text = "1.0" author = ET.SubElement(info, "author") author.text = "Skin author's name" email = ET.SubElement(info, "email") email.text = "Skin author's email" comment = ET.SubElement(info, "comment") comment.text = "Converted with ConvertSkin.py" skin.append(ET.Comment("The variables")) variables = ET.SubElement(skin, "variables") if len(iniFiles) > 1: default = True for iniFile in iniFiles: basename = os.path.basename(iniFile)[:-4] subSkin = ET.Element("skin") parseIniFile(iniFile, subSkin, basename, default) variable = ET.SubElement(variables, "variable") variable.set("name", "Visible_month") variable.set("default", "0") variable.set("window", basename + " - Calendar") include = ET.SubElement(skin, "include") include.set("file", basename + ".xml") indent(subSkin) tree = ET.ElementTree(subSkin) output = os.path.join(os.path.dirname(iniFile), basename + ".xml") tree.write(output) print "Wrote: " + output default = False # Only the first skin is set as default # The category template is in the skin.xml categories = ET.SubElement(skin, "categories") createCategoryTemplate(skin, categories) # Write the skin.xml indent(skin) tree = ET.ElementTree(skin) output = os.path.join(os.path.dirname(iniFile), "skin.xml") tree.write(output) print "Wrote: " + output else: # If there is just a single ini file everything can be added to the skin.xml iniFile = iniFiles[0] parseIniFile(iniFile, skin, "", True) categories = skin.find("categories") createCategoryTemplate(skin, categories) variable = ET.SubElement(variables, "variable") variable.set("name", "Visible_month") variable.set("default", "0") variable.set("window", "Calendar") indent(skin) tree = ET.ElementTree(skin) output = os.path.join(os.path.dirname(iniFile), "skin.xml") tree.write(output) print "Wrote: " + output ########################################################### # Reads the ini file and creates the xml file ########################################################### def parseIniFile(iniFile, skin, prefix, default): config = ConfigParser.RawConfigParser() try: config.read(iniFile) except ConfigParser.ParsingError as e: print e DebugPrint("Sections in the file:" + str(config.sections())) skin.append(ET.Comment("The elements")) elements = ET.SubElement(skin, "elements") skin.append(ET.Comment("The categories")) categories = ET.SubElement(skin, "categories") window = createCalendar(skin, prefix, default) sections = config.sections() sectionMap = {"background" : "Background", "month" : "Month", "year" : "Year", "days" : "Days", "today" : "Today", "weekdays" : "Weekdays", "event" : "Event", "weeknumbers" : "WeekNumbers", "eventlist" : "EventList", "todo" : "Todo", "tooltip" : "ToolTip", "messagebox" : "MessageBox" } for i in range(0, len(sections)): sectionMap[sections[i].lower()] = sections[i] # In the older versions of the ini skins everything is under "Rainlendar" section if "Rainlendar" in config.sections(): createBackground(config, "Rainlendar", skin, window) createMonth(config, "Rainlendar", skin, window) createYear(config, "Rainlendar", skin, window) createDays(config, "Rainlendar", skin, window) createToday(config, "Rainlendar", skin, window) createWeekdays(config, "Rainlendar", skin, window) createEvent(config, "Rainlendar", skin, window) createWeekNumbers(config, "Rainlendar", skin, window) createEventList(config, "Rainlendar", skin, prefix, default) createTodoList(config, "Rainlendar", skin, prefix, default) createTooltip(config, "Rainlendar", skin) createAlarm(config, "Rainlendar", skin) else: createBackground(config, sectionMap["background"], skin, window) createMonth(config, sectionMap["month"], skin, window) createYear(config, sectionMap["year"], skin, window) createDays(config, sectionMap["days"], skin, window) createToday(config, sectionMap["today"], skin, window) createWeekdays(config, sectionMap["weekdays"], skin, window) createEvent(config, sectionMap["event"], skin, window) createWeekNumbers(config, sectionMap["weeknumbers"], skin, window) createEventList(config, sectionMap["eventlist"], skin, prefix, default) createTodoList(config, sectionMap["todo"], skin, prefix, default) createTooltip(config, sectionMap["tooltip"], skin) createAlarm(config, sectionMap["messagebox"], skin) for section in config.sections(): if section[0:6].lower() == "button": createButton(config, section, skin, prefix) elif section[0:5].lower() == "image": createImage(config, section, skin) elif section[0:4].lower() == "time": createTime(config, section, skin) elif section[0:7].lower() == "profile": createProfile(config, section, skin) ########################################################### # Creates the category template ########################################################### def createCategoryTemplate(skin, categories): template = ET.SubElement(categories, "template") setting = ET.SubElement(template, "setting") setting.set("name", "Text_color") setting.set("type", "color") setting.set("default", "255, 255, 255") setting.set("description", "The color of the text in the event and to do lists.") setting = ET.SubElement(template, "setting") setting.set("name", "Tooltip_color") setting.set("type", "color") setting.set("default", "0, 0, 0") setting.set("description", "The color of the text in the tooltip.") appearance = ET.SubElement(template, "appearance") appearance.set("element", "font.eventlist.item") appearance.set("target", "16") appearance.set("color", "#Tooltip_color#") appearance.set("align", "TOP-LEFT") window = findWindow(skin, 2) if window: eventlist = window.find("eventlist") eventlistPadding = None eventlistAlign = None if eventlist: eventlistPadding = eventlist.find("item").get("padding") eventlistAlign = eventlist.find("item").get("align") appearance = ET.SubElement(template, "appearance") appearance.set("element", "font.eventlist.item") appearance.set("target", "2") appearance.set("color", "#Text_color#") if eventlistPadding: appearance.set("padding", eventlistPadding) if eventlistAlign: appearance.set("align", eventlistAlign) if window: window = findWindow(skin, 1) todolist = window.find("todolist") todolistPadding = None if todolist: todolistPadding = todolist.find("item").get("padding") appearance = ET.SubElement(template, "appearance") appearance.set("element", "font.eventlist.item") appearance.set("target", "4") appearance.set("color", "#Text_color#") if todolistPadding: appearance.set("padding", todolistPadding) if eventlistAlign: appearance.set("align", eventlistAlign) ########################################################### # Creates the calendar window ########################################################### def createCalendar(skin, prefix, default): skin.append(ET.Comment("The calendar window")) window = ET.SubElement(skin, "window") if len(prefix) > 0: window.set("id", prefix + " - Calendar") else: window.set("id", "Calendar") window.set("threshold", "64") if default: window.set("default", "1") else: window.set("default", "0") return window ########################################################### # Creates the background image for the calendar ########################################################### def createBackground(config, section, skin, window): element = None if hasOption(config, section, "BackgroundBitmapName"): element = createBitmapElement(skin, getOption(config, section, "BackgroundBitmapName"), "1", "0", "bitmap.calendar.background") mode = "0" if hasOption(config, section, "BackgroundMode") : mode = getOption(config, section, "BackgroundMode") if mode != "1": image = ET.SubElement(window, "image") image.set("id", "background") image.set("x1", "0") image.set("y1", "0") image.set("origin1", "TOP-LEFT") image.set("x2", "0") image.set("y2", "0") image.set("origin2", "BOTTOM-RIGHT") if mode == "3": elements = skin.find("elements") solid = ET.SubElement(elements, "solid") solid.set("id", "solid.background") solid.set("color", createColor(getOption(config, section, "BackgroundSolidColor", "000000"))) image.set("scaling", "STRETCH") image.set("element", "solid.background") elif mode == "0" and element: image.set("scaling", "TILE") image.set("element", element) elif element: image.set("scaling", "STRETCH") image.set("element", element) ########################################################### # Creates the days for the calendar ########################################################### def createDays(config, section, skin, window): if getOption(config, section, "DaysEnable", "0") != "0": calendar = ET.SubElement(window, "calendar") calendar.set("id", "days") calendar.set("x", getOption(config, section, "DaysX", "0")) calendar.set("y", getOption(config, section, "DaysY", "0")) calendar.set("w", getOption(config, section, "DaysW", "0")) calendar.set("h", getOption(config, section, "DaysH", "0")) calendar.set("showmonth", "%Visible_month%") layout = getOption(config, section, "DaysLayout", "0") if layout == "1": calendar.set("layout", "HORIZONTAL") elif layout == "2": calendar.set("layout", "VERTICAL") else: calendar.set("layout", "GRID") rasterizer = getOption(config, section, "DaysRasterizer", "FONT") if rasterizer == "BITMAP": element = createBitmapElement(skin, \ getOption(config, section, "DaysBitmapName"), \ getOption(config, section, "DaysNumOfComponents", "1"), \ getOption(config, section, "DaysSeparation", "0"), \ "bitmap.days") days = ET.SubElement(calendar, "days") appearance = ET.SubElement(days, "appearance") appearance.set("layer", "0") appearance.set("priority", "-1") appearance.set("element", element) appearance.set("align", createAlign(getOption(config, section, "DaysAlign", "0"))) if hasOption(config, section, "DaysWeekendBitmapName"): element = createBitmapElement(skin, \ getOption(config, section, "DaysWeekendBitmapName"), \ getOption(config, section, "DaysNumOfComponents", "1"), \ getOption(config, section, "DaysSeparation", "0"), \ "bitmap.weekends") weekend = ET.SubElement(calendar, "weekends") appearance = ET.SubElement(weekend, "appearance") appearance.set("layer", "0") appearance.set("priority", "-1") appearance.set("element", element) appearance.set("align", createAlign(getOption(config, section, "DaysAlign", "0"))) else: element = createFontElement(skin, getOption(config, section, "DaysFont"), "font.days") days = ET.SubElement(calendar, "days") appearance = ET.SubElement(days, "appearance") appearance.set("layer", "0") appearance.set("priority", "-1") appearance.set("element", element) appearance.set("align", createAlign(getOption(config, section, "DaysAlign", "0"))) appearance.set("color", createColor(getOption(config, section, "DaysFontColor", "FFFFFF"))) if hasOption(config, section, "DaysWeekendFontColor"): element = createFontElement(skin, getOption(config, section, "DaysFont"), "font.weekend") weekend = ET.SubElement(calendar, "weekends") appearance = ET.SubElement(weekend, "appearance") appearance.set("layer", "0") appearance.set("priority", "-1") appearance.set("element", element) appearance.set("align", createAlign(getOption(config, section, "DaysAlign", "0"))) appearance.set("color", createColor(getOption(config, section, "DaysWeekendFontColor", "FFFFFF"))) ########################################################### # Creates the today for the calendar ########################################################### def createToday(config, section, skin, window): if getOption(config, section, "TodayEnable", "0") != "0": calendar = window.find("calendar") if calendar == None: print "ERROR: Unable to create the 'today' appearance since the skin doesn't contain a calendar" return # The layer depends on the "DaysIgnoreToday" setting layer = "10" if findOption(config, "Today", "DaysIgnoreToday", "0") == "1": layer = "0" rasterizer = getOption(config, section, "TodayRasterizer", "FONT") if rasterizer == "BITMAP": element = createBitmapElement(skin, \ getOption(config, section, "TodayBitmapName"), \ getOption(config, section, "TodayNumOfComponents", "1"), \ getOption(config, section, "TodaySeparation", "0"), \ "bitmap.today") today = ET.SubElement(calendar, "today") appearance = ET.SubElement(today, "appearance") appearance.set("layer", layer) appearance.set("priority", "0") appearance.set("element", element) appearance.set("align", createAlign(getOption(config, section, "TodayAlign", "0"))) else: element = createFontElement(skin, getOption(config, section, "TodayFont"), "font.today") today = ET.SubElement(calendar, "today") appearance = ET.SubElement(today, "appearance") appearance.set("layer", layer) appearance.set("priority", "0") appearance.set("element", element) appearance.set("align", createAlign(getOption(config, section, "TodayAlign", "0"))) appearance.set("color", createColor(getOption(config, section, "TodayFontColor", "FFFFFF"))) ########################################################### # Creates the weekdays for the calendar ########################################################### def createWeekdays(config, section, skin, window): if getOption(config, section, "WeekdaysEnable", "0") != "0": calendar = window.find("calendar") if calendar == None: print "ERROR: Unable to create the 'weekdays' appearance since the skin doesn't contain a calendar" return rasterizer = getOption(config, section, "WeekdaysRasterizer", "FONT") if rasterizer == "BITMAP": element = createBitmapElement(skin, \ getOption(config, section, "WeekdaysBitmapName"), \ "7", \ "0", \ "bitmap.weekdays") weekdays = ET.SubElement(calendar, "weekdays") appearance = ET.SubElement(weekdays, "appearance") appearance.set("element", element) appearance.set("align", createAlign(getOption(config, section, "WeekdaysAlign", "0"))) else: element = createFontElement(skin, getOption(config, section, "WeekdaysFont"), "font.weekdays") weekdays = ET.SubElement(calendar, "weekdays") appearance = ET.SubElement(weekdays, "appearance") appearance.set("element", element) appearance.set("align", createAlign(getOption(config, section, "WeekdaysAlign", "0"))) appearance.set("color", createColor(getOption(config, section, "WeekdaysFontColor", "FFFFFF"))) # Check if abbreviations should be used names = getOption(config, section, "WeekdayNames") if names: if len(names) == 13: weekdays.set("abbreviate", "3") elif len(names) < 28: weekdays.set("abbreviate", "1") else: weekdays.set("abbreviate", "0") # Adjust the height and y-pos of the calendar y = int(calendar.get("y")) h = int(calendar.get("h")) y = y - (h / 7) calendar.set("y", str(y)) calendar.set("h", str(h + (h / 7))) ########################################################### # Creates the event for the calendar ########################################################### def createEvent(config, section, skin, window): if getOption(config, section, "EventEnable", "0") != "0": calendar = window.find("calendar") if calendar == None: print "ERROR: Unable to create the 'event' appearance since the skin doesn't contain a calendar" return # The layer depends on the "DaysIgnoreEvent" setting layer = "5" if findOption(config, "Today", "DaysIgnoreEvent", "0") == "1": layer = "0" rasterizer = getOption(config, section, "EventRasterizer", "FONT") if rasterizer == "BITMAP": element = createBitmapElement(skin, \ getOption(config, section, "EventBitmapName"), \ getOption(config, section, "EventNumOfComponents", "1"), \ getOption(config, section, "EventSeparation", "0"), \ "bitmap.event") events = ET.SubElement(calendar, "events") appearance = ET.SubElement(events, "appearance") appearance.set("layer", layer) appearance.set("priority", "0") appearance.set("element", element) appearance.set("align", createAlign(getOption(config, section, "EventAlign", "0"))) else: element = createFontElement(skin, getOption(config, section, "EventFont"), "font.event") events = ET.SubElement(calendar, "events") appearance = ET.SubElement(events, "appearance") appearance.set("layer", layer) appearance.set("priority", "0") appearance.set("element", element) appearance.set("align", createAlign(getOption(config, section, "EventAlign", "0"))) appearance.set("color", createColor(getOption(config, section, "EventFontColor", "FFFFFF"))) ########################################################### # Creates the week numbers for the calendar ########################################################### def createWeekNumbers(config, section, skin, window): if getOption(config, section, "WeekNumbersEnable", "0") != "0": calendar = window.find("calendar") if calendar == None: print "ERROR: Unable to create the 'week numbers' appearance since the skin doesn't contain a calendar" return rasterizer = getOption(config, section, "WeekNumbersRasterizer", "FONT") if rasterizer == "BITMAP": element = createBitmapElement(skin, \ getOption(config, section, "WeekNumbersBitmapName"), \ getOption(config, section, "WeekNumbersNumOfComponents", "1"), \ getOption(config, section, "WeekNumbersSeparation", "0"), \ "bitmap.weeknumbers") weeknumbers = ET.SubElement(calendar, "weeknums") appearance = ET.SubElement(weeknumbers, "appearance") appearance.set("element", element) appearance.set("align", createAlign(getOption(config, section, "WeekNumbersAlign", "0"))) else: element = createFontElement(skin, getOption(config, section, "WeekNumbersFont"), "font.weeknumbers") weeknumbers = ET.SubElement(calendar, "weeknum") appearance = ET.SubElement(weeknumbers, "appearance") appearance.set("element", element) appearance.set("align", createAlign(getOption(config, section, "WeekNumbersAlign", "0"))) appearance.set("color", createColor(getOption(config, section, "WeekNumbersFontColor", "FFFFFF"))) # Adjust the width and x-pos of the calendar x = int(calendar.get("x")) w = int(calendar.get("w")) x = x - (w / 7) calendar.set("x", str(x)) calendar.set("w", str(w + (w / 7))) ########################################################### # Creates the month for the calendar ########################################################### def createMonth(config, section, skin, window): if getOption(config, section, "MonthEnable", "0") != "0": month = ET.SubElement(window, "month") month.set("x", getOption(config, section, "MonthX", "0")) month.set("y", getOption(config, section, "MonthY", "0")) month.set("align", createAlign(getOption(config, section, "MonthAlign", "0"))) month.set("showmonth", "%Visible_month%") rasterizer = getOption(config, section, "MonthRasterizer", "FONT") if rasterizer == "BITMAP": element = createBitmapElement(skin, \ getOption(config, section, "MonthBitmapName"), \ "12", \ "0", \ "bitmap.month") else: element = createFontElement(skin, getOption(config, section, "MonthFont"), "font.month") month.set("color", createColor(getOption(config, section, "MonthFontColor", "FFFFFF"))) if element: month.set("element", element) ########################################################### # Creates the year for the calendar ########################################################### def createYear(config, section, skin, window): if getOption(config, section, "YearEnable", "0") != "0": year = ET.SubElement(window, "year") year.set("x", getOption(config, section, "YearX", "0")) year.set("y", getOption(config, section, "YearY", "0")) year.set("align", createAlign(getOption(config, section, "YearAlign", "0"))) year.set("showmonth", "%Visible_month%") rasterizer = getOption(config, section, "YearRasterizer", "FONT") if rasterizer == "BITMAP": element = createBitmapElement(skin, \ getOption(config, section, "YearBitmapName"), \ "10", \ getOption(config, section, "YearSeparation", "0"), \ "bitmap.year") else: element = createFontElement(skin, getOption(config, section, "YearFont"), "font.year") year.set("color", createColor(getOption(config, section, "YearFontColor", "FFFFFF"))) if element: year.set("element", element) ########################################################### # Creates the to do window ########################################################### def createTodoList(config, section, skin, prefix, default): skin.append(ET.Comment("The task list window")) window = ET.SubElement(skin, "window") if len(prefix) > 0: window.set("id", prefix + " - Todo List") else: window.set("id", "Todo List") window.set("threshold", "64") if default: window.set("default", "1") else: window.set("default", "0") # The background image element = createBitmapElement(skin, getOption(config, section, "TodoBitmapName"), "1", "0", "bitmap.todo.background") image = ET.SubElement(window, "image") image.set("id", "background") image.set("x1", "0") image.set("y1", "0") image.set("origin1", "TOP-LEFT") image.set("x2", "0") image.set("y2", "0") image.set("origin2", "BOTTOM-RIGHT") image.set("element", element) image.set("scaling", "STRETCH") if hasOption(config, section, "TodoBitmapMargins"): image.set("margins", getOption(config, section, "TodoBitmapMargins")) # TODO: width = margins[0] + margins[2] # TODO: width = image width width = int(getOption(config, section, "TodoW", "0")) # TODO: wxMax(m_TodoListWidth, w); ox = 0 if hasOption(config, section, "TodoItemBitmapName"): offset = parseInts(getOption(config, section, "TodoItemOffset", "0,0"), 2) if offset[0] < 0: ox = -offset[0] offset[0] = 0 margins = parseInts(getOption(config, section, "TodoTextMargins", "0,0,0,0"), 4) separation = getOption(config, section, "TodoSeparation", "0") todo = ET.SubElement(window, "todolist") todo.set("id", "list") todo.set("x1", str(margins[0] - ox)) todo.set("y1", str(margins[1])) todo.set("origin1", "TOP-LEFT") todo.set("x2", str(-margins[2])) todo.set("y2", str(-margins[3])) todo.set("origin2", "BOTTOM-RIGHT") element = createFontElement(skin, getOption(config, section, "TodoFont"), "font.todo.item") header = ET.SubElement(todo, "header") appearance = ET.SubElement(header, "appearance") # Get the header from the event list (if there is one) eventlistWindow = findWindow(skin, 3) if eventlistWindow is not None: eventListAppearance = eventlistWindow.find("eventlist").find("header").find("appearance") appearance.set("element", eventListAppearance.get("element")) appearance.set("align", eventListAppearance.get("align")) appearance.set("color", eventListAppearance.get("color")) appearance.set("padding", eventListAppearance.get("padding")) else: appearance.set("element", element) appearance.set("align", "TOP-LEFT") appearance.set("color", createColor(getOption(config, section, "TodoFontColor", "FFFFFF"))) appearance.set("padding", str(ox) + ", 0, 0, " + separation) item = ET.SubElement(todo, "item") appearance = ET.SubElement(item, "appearance") appearance.set("element", element) appearance.set("align", "TOP-LEFT") appearance.set("color", createColor(getOption(config, section, "TodoFontColor", "FFFFFF"))) appearance.set("padding", str(ox) + ", 0, 0, " + separation) if hasOption(config, section, "TodoItemBitmapName"): image = ET.SubElement(item, "image") element = createBitmapElement(skin, getOption(config, section, "TodoItemBitmapName"), "1", "0", "bitmap.todo.image") image.set("id", "item.image") image.set("x1", str(offset[0])) image.set("y1", str(offset[1])) image.set("origin1", "TOP-LEFT") image.set("x2", "0") image.set("y2", "0") image.set("origin2", "BOTTOM-RIGHT") image.set("element", element) image.set("scaling", "NONE") image.set("align", createAlign(getOption(config, section, "TodoItemAlign", "0"))) # Add button to the top for double click actions button = ET.SubElement(window, "button") button.set("id", "top.button") button.set("x1", "0") button.set("y1", "0") button.set("origin1", "TOP-LEFT") button.set("x2", "0") button.set("y2", str(margins[1])) button.set("origin2", "TOP-RIGHT") button.set("dblcklaction", "Global_ShowTodoDialog()") ########################################################### # Creates the event list window ########################################################### def createEventList(config, section, skin, prefix, default): # The background image (check this first and bail out if it's missing) element = createBitmapElement(skin, getOption(config, section, "EventListBitmapName"), "1", "0", "bitmap.eventlist.background") if element == None: print "ERROR: The skin doesn't include event list" return skin.append(ET.Comment("The event list window")) window = ET.SubElement(skin, "window") if len(prefix) > 0: window.set("id", prefix + " - Event List") else: window.set("id", "Event List") window.set("threshold", "64") if default: window.set("default", "1") else: window.set("default", "0") image = ET.SubElement(window, "image") image.set("id", "background") image.set("x1", "0") image.set("y1", "0") image.set("origin1", "TOP-LEFT") image.set("x2", "0") image.set("y2", "0") image.set("origin2", "BOTTOM-RIGHT") image.set("element", element) image.set("scaling", "STRETCH") if hasOption(config, section, "EventListBitmapMargins"): image.set("margins", getOption(config, section, "EventListBitmapMargins")) # TODO: width = margins[0] + margins[2] # TODO: width = image width width = int(getOption(config, section, "EventListW", "0")) # TODO: wxMax(m_TodoListWidth, w); ox = 0 if hasOption(config, section, "EventListHeaderItemBitmapName"): offset = parseInts(getOption(config, section, "EventListHeaderItemOffset", "0,0"), 2) if offset[0] < 0: ox = -offset[0] offset[0] = 0 margins = parseInts(getOption(config, section, "EventListTextMargins", "0,0,0,0"), 4) eventlist = ET.SubElement(window, "eventlist") eventlist.set("id", "list") eventlist.set("x1", str(margins[0] - ox)) eventlist.set("y1", str(margins[1])) eventlist.set("origin1", "TOP-LEFT") eventlist.set("x2", str(-margins[2])) eventlist.set("y2", str(-margins[3])) eventlist.set("origin2", "BOTTOM-RIGHT") element = createFontElement(skin, getOption(config, section, "EventListHeaderFont"), "font.eventlist.header") separation = getOption(config, section, "EventListHeaderSeparation", "0") header = ET.SubElement(eventlist, "header") appearance = ET.SubElement(header, "appearance") appearance.set("element", element) appearance.set("align", "TOP-LEFT") appearance.set("color", createColor(getOption(config, section, "EventListHeaderFontColor", "FFFFFF"))) appearance.set("padding", str(ox) + ", 0, 0, " + separation) element = createFontElement(skin, getOption(config, section, "EventListFont"), "font.eventlist.item") separation = getOption(config, section, "EventListHeaderSeparation", "0") item = ET.SubElement(eventlist, "item") appearance = ET.SubElement(item, "appearance") appearance.set("element", element) appearance.set("align", "TOP-LEFT") appearance.set("color", createColor(getOption(config, section, "EventListFontColor", "FFFFFF"))) appearance.set("padding", str(ox) + ", 0, 0, " + separation) if hasOption(config, section, "EventListHeaderItemBitmapName"): image = ET.SubElement(item, "image") element = createBitmapElement(skin, getOption(config, section, "EventListHeaderItemBitmapName"), "1", "0", "bitmap.eventlist.header.image") image.set("id", "header.image") image.set("x1", str(offset[0])) image.set("y1", str(offset[1])) image.set("origin1", "TOP-LEFT") image.set("x2", "0") image.set("y2", "0") image.set("origin2", "BOTTOM-RIGHT") image.set("element", element) image.set("scaling", "NONE") image.set("align", createAlign(getOption(config, section, "EventListHeaderItemAlign", "0"))) # Add button to the top for double click actions button = ET.SubElement(window, "button") button.set("id", "top.button") button.set("x1", "0") button.set("y1", "0") button.set("origin1", "TOP-LEFT") button.set("x2", "0") button.set("y2", str(margins[1])) button.set("origin2", "TOP-RIGHT") button.set("dblcklaction", "Global_ShowEventDialog()") ########################################################### # Creates the tooltip ########################################################### def createTooltip(config, section, skin): skin.append(ET.Comment("The tooltip window")) tooltip = ET.SubElement(skin, "tooltip") tooltip.set("id", "ini.tooltip") tooltip.set("threshold", "64") tooltip.set("textmargins", "5, 5, 5, 5") tooltip.set("offset", "0, 0") # Just create a solid rectangle for the tooltip elements = skin.find("elements") solid = ET.SubElement(elements, "solid") solid.set("id", "solid.tooltip.background") solid.set("color", createColor(getOption(config, section, "ToolTipBGColor", "FFFF00"))) background = ET.SubElement(tooltip, "background") background.set("id", "ini.tooltip.background") background.set("element", "solid.tooltip.background") background.set("scaling", "TILE") background.set("x1", "0") background.set("y1", "0") background.set("origin1", "TOP-LEFT") background.set("x2", "0") background.set("y2", "0") background.set("origin2", "BOTTOM-RIGHT") element = createFontElement(skin, getOption(config, section, "ToolTipFont"), "font.tooltip.header") if element: # Change the font to bold for font in skin.find("elements").findall("font"): if font.get("id") == element: font.set("weight", "BOLD") break header = ET.SubElement(tooltip, "header") appearance = ET.SubElement(header, "appearance") appearance.set("element", element) appearance.set("align", "TOP-LEFT") appearance.set("color", createColor(getOption(config, section, "ToolTipFontColor", "000000"))) element = createFontElement(skin, getOption(config, section, "ToolTipFont"), "font.tooltip.item") if element: item = ET.SubElement(tooltip, "item") appearance = ET.SubElement(item, "appearance") appearance.set("element", element) appearance.set("align", "TOP-LEFT") appearance.set("color", createColor(getOption(config, section, "ToolTipFontColor", "000000"))) ########################################################### # Creates the alarm window ########################################################### def createAlarm(config, section, skin): element = createBitmapElement(skin, getOption(config, section, "MessageBoxBitmapName"), "1", "0", "bitmap.alarm.background") if not element: print "ERROR: MessageBoxBitmapName is missing." return skin.append(ET.Comment("The alarm window")) alarm = ET.SubElement(skin, "alarm") alarm.set("id", "ini.alarm") alarm.set("threshold", "64") alarm.set("textmargins", getOption(config, section, "MessageBoxTextMargins", "0, 0, 0, 0")) image = ET.SubElement(alarm, "image") image.set("id", "background") image.set("x1", "0") image.set("y1", "0") image.set("origin1", "TOP-LEFT") image.set("x2", "0") image.set("y2", "0") image.set("origin2", "BOTTOM-RIGHT") image.set("element", element) image.set("scaling", "STRETCH") if hasOption(config, section, "MessageBoxBitmapMargins"): image.set("margins", getOption(config, section, "MessageBoxBitmapMargins")) element = createFontElement(skin, getOption(config, section, "MessageBoxFont"), "font.alarm.item") separation = getOption(config, section, "MessageBoxSeparation", "0") item = ET.SubElement(alarm, "item") appearance = ET.SubElement(item, "appearance") appearance.set("element", element) appearance.set("align", "TOP-LEFT") appearance.set("color", createColor(getOption(config, section, "MessageBoxFontColor", "FFFFFF"))) appearance.set("padding", "0, 0, 0, " + separation) # Create the dismiss all button that covers the whole window button = ET.SubElement(alarm, "button") button.set("id", "dismiss.button") button.set("x1", "0") button.set("y1", "0") button.set("origin1", "TOP-LEFT") button.set("x2", "0") button.set("y2", "0") button.set("origin2", "BOTTOM-RIGHT") button.set("action", "Global_DismissAll()") ########################################################### # Creates a button to a window ########################################################### def createButton(config, section, skin, prefix): if len(prefix): prefix = prefix + " - " winId = getOption(config, section, "Window", "0") window = findWindow(skin, int(winId)) if window is None: print "ERROR: Unable to find the window (%s) for the button" % winId return file = getOption(config, section, "BitmapName") element = createBitmapElement(skin, file, "3", "0", "button." + os.path.split(file)[1]) x = int(getOption(config, section, "X", "0")) y = int(getOption(config, section, "Y", "0")) button = ET.SubElement(window, "button") button.set("visible", getOption(config, section, "Enabled", "1")) if element: button.set("element", element) setPos(button, x, y) command = getOption(config, section, "Command") if command: values = command.split(" ") if values[0].lower() == "!rainlendarshownext": if len(values) > 1: button.set("action", "Global_ShowMonth(+%s)" % values[1]) else: button.set("action", "Global_ShowMonth(+1)") elif values[0].lower() == "!rainlendarshowprev": if len(values) > 1: button.set("action", "Global_ShowMonth(-%s)" % values[1]) else: button.set("action", "Global_ShowMonth(-1)") elif values[0].lower() == "!rainlendarshow": button.set("action", "Global_ShowWindow()") elif values[0].lower() == "!rainlendarhide": button.set("action", "Global_HideWindow()") elif values[0].lower() == "!rainlendartoggle": button.set("action", "Global_ToggleWindow()") elif values[0].lower() == "!rainlendarshowmonth" and len(values) > 1: button.set("action", "Global_ShowMonth(%s)" % values[1]) elif values[0].lower() == "!rainlendarshowcurrent": button.set("action", "Global_ShowMonth(0)") elif values[0].lower() == "!rainlendarshowtodo": button.set("action", "Global_ShowWindow(" + prefix + "Todo List)") elif values[0].lower() == "!rainlendarhidetodo": button.set("action", "Global_HideWindow(" + prefix + "Todo List)") elif values[0].lower() == "!rainlendartoggletodo": button.set("action", "Global_ToggleWindow(" + prefix + "Todo List)") elif values[0].lower() == "!rainlendarshoweventlist": button.set("action", "Global_ShowWindow(" + prefix + "Event List)") elif values[0].lower() == "!rainlendarhideeventlist": button.set("action", "Global_HideWindow(" + prefix + "Event List)") elif values[0].lower() == "!rainlendartoggleeventlist": button.set("action", "Global_ToggleWindow(" + prefix + "Event List)") elif values[0].lower() == "!rainlendarshowcalendar": button.set("action", "Global_ShowWindow(" + prefix + "Calendar)") elif values[0].lower() == "!rainlendarhidecalendar": button.set("action", "Global_HideWindow(" + prefix + "Calendar)") elif values[0].lower() == "!rainlendartogglecalendar": button.set("action", "Global_ToggleWindow(" + prefix + "Calendar)") elif values[0].lower() == "!rainlendarabout": button.set("action", "Global_ShowAboutDialog()") elif values[0].lower() == "!rainlendaredittodo": button.set("action", "Global_ShowTodoDialog()") elif values[0].lower() == "!rainlendaraddevent": button.set("action", "Global_ShowEventDialog()") else: print "Unable to create the button action for:" + command ########################################################### # Creates an image to a window ########################################################### def createImage(config, section, skin): winId = getOption(config, section, "Window", "0") window = findWindow(skin, int(winId)) if window == None: print "ERROR: Unable to create the 'image' element since the window %s is missing" % winId return file = getOption(config, section, "BitmapName") element = createBitmapElement(skin, file, "3", "0", "image." + os.path.split(file)[1]) x = int(getOption(config, section, "X", "0")) y = int(getOption(config, section, "Y", "0")) image = ET.SubElement(window, "image") image.set("visible", getOption(config, section, "Enabled", "1")) if element: image.set("element", element) setPos(image, x, y) ########################################################### # Creates a time item to a window ########################################################### def createTime(config, section, skin): winId = getOption(config, section, "Window", "0") window = findWindow(skin, int(winId)) if window == None: print "ERROR: Unable to create the 'time' element since the window %s is missing" % winId return time = ET.SubElement(window, "time") time.set("format", getOption(config, section, "Format")) time.set("align", createAlign(getOption(config, section, "Align", "0"))) x = int(getOption(config, section, "X", "0")) y = int(getOption(config, section, "Y", "0")) setPos(time, x, y) rasterizer = getOption(config, section, "Rasterizer", "FONT") if rasterizer == "BITMAP": element = createBitmapElement(skin, \ getOption(config, section, "BitmapName"), \ "10", \ getOption(config, section, "Separation", "0"), \ "bitmap.time." + section) else: element = createFontElement(skin, getOption(config, section, "Font"), "font.time." + section) time.set("color", createColor(getOption(config, section, "FontColor", "FFFFFF"))) if element: time.set("element", element) ########################################################### # Creates a category (profile in the ini file) ########################################################### def createProfile(config, section, skin): global g_Categories name = getOption(config, section, "Name") if name in g_Categories: DebugPrint("The category " + name + " already exists") return g_Categories.append(name) categories = skin.find("categories") category = ET.SubElement(categories, "category") category.set("id", name) if hasOption(config, section, "EventIconName"): element = createBitmapElement(skin, getOption(config, section, "EventIconName"), "1", "0", "bitmap.event.icon." + name) appearance = ET.SubElement(category, "appearance") appearance.set("target", "-1") appearance.set("priority", getOption(config, section, "priority", "0")) appearance.set("showalways", "1") appearance.set("align", createAlign(getOption(config, section, "EventIconAlign", "0"))) appearance.set("element", element) appearance.set("layer", "20") if hasOption(config, section, "ToolTipFontColor"): appearance = ET.SubElement(category, "appearance") appearance.set("target", "16") appearance.set("priority", getOption(config, section, "priority", "0")) appearance.set("align", "TOP-LEFT") appearance.set("element", "font.eventlist.item") appearance.set("color", createColor(getOption(config, section, "ToolTipFontColor", "FFFFFF"))) if hasOption(config, section, "EventFontColor"): appearance = ET.SubElement(category, "appearance") appearance.set("target", "1") appearance.set("priority", getOption(config, section, "priority", "0")) appearance.set("align", "TOP-LEFT") appearance.set("element", "font.event") appearance.set("color", createColor(getOption(config, section, "EventFontColor", "FFFFFF"))) if hasOption(config, section, "EventBitmapName"): numOfComponents = findOption(config, "Event", "EventNumOfComponents", "1"); separation = findOption(config, "Event", "EventSeparation", "0"); align = createAlign(findOption(config, "Event", "EventAlign", "0")); drawAlways = findOption(config, "Event", "EventDrawAlways", "0"); ignoreEvent = findOption(config, "Days", "DaysIgnoreEvent", "0"); element = createBitmapElement(skin, \ getOption(config, section, "EventBitmapName"), \ numOfComponents, \ separation, \ "bitmap.event." + name) appearance = ET.SubElement(category, "appearance") appearance.set("target", "1") appearance.set("priority", getOption(config, section, "priority", "0")) appearance.set("align", align) appearance.set("element", element) if drawAlways == "1": appearance.set("layer", "6") elif ignoreEvent == "1": appearance.set("layer", "0") else: appearance.set("layer", "5") if hasOption(config, section, "EventListFontColor"): window = findWindow(skin, 3) eventlist = window.find("eventlist") eventlistPadding = None if eventlist: eventlistPadding = eventlist.find("item").get("padding") appearance = ET.SubElement(category, "appearance") appearance.set("target", "2") appearance.set("priority", getOption(config, section, "priority", "0")) appearance.set("align", "TOP-LEFT") appearance.set("element", "font.eventlist.item") if eventlistPadding: appearance.set("padding", eventlistPadding) appearance.set("color", createColor(getOption(config, section, "EventListFontColor", "FFFFFF"))) window = findWindow(skin, 1) todolist = window.find("todolist") todolistPadding = None if todolist: todolistPadding = todolist.find("item").get("padding") appearance = ET.SubElement(category, "appearance") appearance.set("target", "4") appearance.set("priority", getOption(config, section, "priority", "0")) appearance.set("align", "TOP-LEFT") appearance.set("element", "font.eventlist.item") if todolistPadding: appearance.set("padding", todolistPadding) appearance.set("color", createColor(getOption(config, section, "EventListFontColor", "FFFFFF"))) ########################################################### # Sets the position. Used by time, button and image. ########################################################### def setPos(item, x, y): item.set("x", str(x)) item.set("y", str(y)) if x < 0: if y < 0: item.set("origin", "BOTTOM-RIGHT") else: item.set("origin", "TOP-RIGHT") else: if y < 0: item.set("origin", "BOTTOM-LEFT") else: item.set("origin", "TOP-LEFT") ########################################################### # Finds the correct window for the window id ########################################################### def findWindow(skin, winId): DebugPrint("Searching for window: " + str(winId)) window = None windows = skin.findall("window") windows.append(None) for window in windows: if window is not None: if winId == 1: if window.find("todolist") is not None: break elif winId == 3: if window.find("eventlist") is not None: break elif winId == 2: if window.find("alarm") is not None: break else: if window.find("calendar") is not None: break if window is not None: DebugPrint("Found: " + window.get("id")) else: DebugPrint("The window was not found") return window ########################################################### # Finds the option from "Rainlendar" or given section ########################################################### def findOption(config, section, option, default): if hasOption(config, "Rainlendar", option): return getOption(config, "Rainlendar", option, default) elif hasOption(config, section, option): return getOption(config, section, option, default) return default ########################################################### # Creates a new bitmap element ########################################################### def createBitmapElement(skin, file, frames, separation, name): global g_Elements if file: elements = skin.find("elements") # The elements must be unique if name in g_Elements.keys(): if file != g_Elements[name]: DebugPrint("The element " + name + " already exists. Using " + name + "." + file + " instead") name = name + "." + file if name in g_Elements.keys(): DebugPrint("The new element name also exist so we will use that.") return name g_Elements[name] = file if frames == "10": bitmap = ET.SubElement(elements, "bitmapfont") bitmap.set("id", name) bitmap.set("file", file) bitmap.set("alphabet", "0123456789") bitmap.set("separation", separation) else: bitmap = ET.SubElement(elements, "bitmap") bitmap.set("id", name) bitmap.set("file", file) bitmap.set("frames", frames) if frames == "32": bitmap.set("ignorefirstframe", "1") return name ########################################################### # Creates a new font element ########################################################### def createFontElement(skin, fontData, name): if fontData: values = fontData.split("/") height = int(values[0]) if height < 0: height = -height * 72 / 96 style = "NORMAL" if values[5] != "0": style = "ITALIC" weight = "NORMAL" if int(values[4]) < 400: weight = "LIGHT" elif int(values[4]) > 500: weight = "BOLD" line = "NOLINE" if values[6] == "1": line = "UNDERLINE" elements = skin.find("elements") font = ET.SubElement(elements, "font") font.set("id", name) font.set("size", str(height)) font.set("family", "DEFAULT") font.set("style", style) font.set("weight", weight) font.set("line", line) font.set("uppercase", "0") font.set("facename", values[-1]) return name ########################################################### # Parses a list of integers ########################################################### def parseInts(text, count): ints = [] items = text.split(",") for item in items: ints.append(int(item)) while len(ints) < count: ints.append(0) return ints ########################################################### # Creates a color ########################################################### def createColor(color): if (len(color) >= 6): return str(int(color[4:6], 16)) + "," + str(int(color[2:4], 16)) + "," + str(int(color[0:2], 16)) + ",255" elif color == "0": return "0, 0, 0, 255" else: print "ERROR: The color " + color + " has too few characters" return "0, 0, 0, 255" ########################################################### # Creates an alignment ########################################################### def createAlign(align): if align == "0": return "TOP-LEFT" if align == "1": return "TOP-RIGHT" if align == "2": return "TOP-CENTER" if align == "16": return "CENTER-LEFT" if align == "17": return "CENTER-RIGHT" if align == "18": return "CENTER" if align == "32": return "BOTTOM-LEFT" if align == "33": return "BOTTOM-RIGHT" if align == "34": return "BOTTOM-CENTER" print "ERROR: Unknown align: " + align return "TOP-LEFT" ########################################################### # Returns the given option value ########################################################### def getOption(config, section, option, default = None): if hasOption(config, section, option): try: return config.get(section, option).decode("utf-8") except UnicodeDecodeError: return config.get(section, option).decode("iso-8859-1") except ConfigParser.NoSectionError: return config.get(section.upper(), option).decode("utf-8") else: DebugPrint("The option \"" + section + "/" + option + "\" not found. Using the default value: " + str(default)) return default ########################################################### # Returns true if the option is found ########################################################### def hasOption(config, section, option): if config.has_option(section, option): return len(config.get(section, option)) > 0 elif config.has_option(section.upper(), option): return len(config.get(section.upper(), option)) > 0 else: return False ########################################################### # Adds spaces to the elements for better looking output ########################################################### def indent(elem, level=0): i = "\n" + level*" " if len(elem): if not elem.text or not elem.text.strip(): elem.text = i + " " if not elem.tail or not elem.tail.strip(): elem.tail = i for elem in elem: indent(elem, level+1) if not elem.tail or not elem.tail.strip(): elem.tail = i else: if level and (not elem.tail or not elem.tail.strip()): elem.tail = i ########################################################### # Prints debug message ########################################################### def DebugPrint(str): global g_Debug if g_Debug: print "DEBUG: " + str ########################################################## # Main function ########################################################## if __name__ == '__main__': parser = optparse.OptionParser() parser.add_option("-d", "--debug", action="store_true", dest="debug", default=False, help="Enable debugging") parser.add_option("-f", "--folder", dest="folder", help="Select FOLDER to be scanned", metavar="FALSE") (options, args) = parser.parse_args() g_Debug = options.debug DebugPrint("Debugging enabled") if options.folder: path = os.path.join(os.getcwd(), options.folder) else: path = os.getcwd() if path.find(".") != -1: print "The path (" + path + ") must not contain '.'-character" else: iniFiles = scanIniFiles(path) if len(iniFiles) == 0: print "No ini files found from path: " + path else: convertInisToXml(iniFiles)