ontv r467 - in trunk: ontv scripts



Author: johans
Date: Thu Nov  6 20:51:44 2008
New Revision: 467
URL: http://svn.gnome.org/viewvc/ontv?rev=467&view=rev

Log:
Renamed modules to better confirm to PEP-8.

Added:
   trunk/ontv/applet.py   (contents, props changed)
      - copied, changed from r466, /trunk/ontv/OnTVApplet.py
   trunk/ontv/assistant.py   (contents, props changed)
      - copied, changed from r466, /trunk/ontv/XMLTVAssistant.py
   trunk/ontv/channel.py   (contents, props changed)
      - copied, changed from r466, /trunk/ontv/Channel.py
   trunk/ontv/config.py   (contents, props changed)
      - copied, changed from r466, /trunk/ontv/Configuration.py
   trunk/ontv/dialogs.py
   trunk/ontv/gui.py   (contents, props changed)
      - copied, changed from r466, /trunk/ontv/GUI.py
   trunk/ontv/keybinder.py   (props changed)
      - copied unchanged from r466, /trunk/ontv/KeyBinder.py
   trunk/ontv/listings.py   (props changed)
      - copied unchanged from r466, /trunk/ontv/Listings.py
   trunk/ontv/main.py   (contents, props changed)
      - copied, changed from r466, /trunk/ontv/Main.py
   trunk/ontv/notify.py   (contents, props changed)
      - copied, changed from r466, /trunk/ontv/Notification.py
   trunk/ontv/program.py   (contents, props changed)
      - copied, changed from r466, /trunk/ontv/Program.py
   trunk/ontv/reminders.py   (props changed)
      - copied unchanged from r466, /trunk/ontv/Reminders.py
   trunk/ontv/utils.py   (props changed)
      - copied unchanged from r466, /trunk/ontv/Utils.py
   trunk/ontv/window.py   (contents, props changed)
      - copied, changed from r466, /trunk/ontv/ProgramWindow.py
   trunk/ontv/xmltv_file.py   (contents, props changed)
      - copied, changed from r466, /trunk/ontv/XMLTVFile.py
Removed:
   trunk/ontv/AboutDialog.py
   trunk/ontv/Channel.py
   trunk/ontv/ChannelDialog.py
   trunk/ontv/Configuration.py
   trunk/ontv/GUI.py
   trunk/ontv/KeyBinder.py
   trunk/ontv/Listings.py
   trunk/ontv/Main.py
   trunk/ontv/Notification.py
   trunk/ontv/OnTVApplet.py
   trunk/ontv/PreferencesDialog.py
   trunk/ontv/Program.py
   trunk/ontv/ProgramDialog.py
   trunk/ontv/ProgramWindow.py
   trunk/ontv/Reminders.py
   trunk/ontv/SearchDialog.py
   trunk/ontv/TimeSpan.py
   trunk/ontv/Utils.py
   trunk/ontv/XMLTVAssistant.py
   trunk/ontv/XMLTVFile.py
Modified:
   trunk/ontv/Makefile.am
   trunk/scripts/ontv.in

Modified: trunk/ontv/Makefile.am
==============================================================================
--- trunk/ontv/Makefile.am	(original)
+++ trunk/ontv/Makefile.am	Thu Nov  6 20:51:44 2008
@@ -3,27 +3,22 @@
 ontvdir = $(pythondir)/ontv
 
 ontv_PYTHON =			\
-	AboutDialog.py		\
-	Channel.py		\
-	ChannelDialog.py	\
-	Configuration.py	\
-	GUI.py			\
+	applet.py		\
+	assistant.py		\
+	channel.py		\
+	config.py		\
+	dialogs.py		\
+	gui.py			\
 	__init__.py		\
-	KeyBinder.py		\
-	Listings.py		\
-	Main.py			\
-	Notification.py		\
-	OnTVApplet.py		\
-	PreferencesDialog.py	\
-	Program.py		\
-	ProgramDialog.py	\
-	ProgramWindow.py	\
-	Reminders.py		\
-	SearchDialog.py		\
-	TimeSpan.py		\
-	Utils.py		\
-	XMLTVAssistant.py	\
-	XMLTVFile.py		\
+	keybinder.py		\
+	listings.py		\
+	main.py			\
+	notify.py		\
+	program.py		\
+	reminders.py		\
+	utils.py		\
+	window.py		\
+	xmltv_file.py		\
 	xmltv.py
 
 DISTCLEANFILES = __init__.py

Copied: trunk/ontv/applet.py (from r466, /trunk/ontv/OnTVApplet.py)
==============================================================================
--- /trunk/ontv/OnTVApplet.py	(original)
+++ trunk/ontv/applet.py	Thu Nov  6 20:51:44 2008
@@ -24,16 +24,14 @@
 import gtk
 import gnomeapplet
 
-import GUI
-from Configuration import Configuration
-from XMLTVFile import XMLTVFile
-from Reminders import Reminders
-from KeyBinder import KeyBinder
-from ProgramWindow import ProgramWindow
-from PreferencesDialog import PreferencesDialog
-from SearchDialog import SearchDialog
-from AboutDialog import AboutDialog
-from XMLTVAssistant import XMLTVAssistant
+import gui
+from assistant import XMLTVAssistant
+from config import Configuration
+from dialogs import PreferencesDialog, SearchDialog, AboutDialog
+from keybinder import KeyBinder
+from window import ProgramWindow
+from reminders import Reminders
+from xmltv_file import XMLTVFile
 from ontv import NAME, VERSION, UI_DIR, LOCALE_DIR
 
 class OnTVApplet(object):
@@ -80,7 +78,7 @@
         self.image = gtk.Image()
         if not self.config.standalone:
             size = self.applet.get_size()
-            pixbuf = GUI.load_icon("ontv", size, size)
+            pixbuf = gui.load_icon("ontv", size, size)
             if pixbuf.get_width() != size or pixbuf.get_height() != size:
                 pixbuf = pixbuf.scale_simple(size-4, size-4,
                                              gtk.gdk.INTERP_BILINEAR)
@@ -104,8 +102,8 @@
 
     def run(self):
         if self.configure or self.config.grabber_command == '':
-            assistant = XMLTVAssistant(self.config, self.xmltvfile)
-            assistant.show()
+            xmltv_assistant = XMLTVAssistant(self.config, self.xmltvfile)
+            xmltv_assistant.show()
         else:
             self.xmltvfile.connect("downloading", self.__xmltvfile_activity,
                                    (_("Downloading"),))
@@ -143,7 +141,7 @@
             self.pw.upt.hide()
 
     def __change_size(self, widget, size):
-        pixbuf = GUI.load_icon("ontv", size, size)
+        pixbuf = gui.load_icon("ontv", size, size)
         if pixbuf.get_width() != size or pixbuf.get_height() != size:
             pixbuf = pixbuf.scale_simple(size-4, size-4,
                                          gtk.gdk.INTERP_BILINEAR)

Copied: trunk/ontv/assistant.py (from r466, /trunk/ontv/XMLTVAssistant.py)
==============================================================================
--- /trunk/ontv/XMLTVAssistant.py	(original)
+++ trunk/ontv/assistant.py	Thu Nov  6 20:51:44 2008
@@ -35,7 +35,7 @@
         ed.run()
         sys.exit(1)
 
-import GUI
+import gui
 import Utils
 
 GRABBERS = {"Belgium": "tv_grab_be",
@@ -227,7 +227,7 @@
         xml_filter.set_name(_("XML files"))
         xml_filter.add_pattern("text/xml")
         filters = [xml_filter]
-        fd = GUI.FileChooserDialog(_("Select XMLTV file..."), filters)
+        fd = gui.FileChooserDialog(_("Select XMLTV file..."), filters)
         response = fd.run()
         if response == gtk.RESPONSE_OK:
             self.output_entry.set_text(fd.get_filename())
@@ -302,7 +302,7 @@
 
     def __add_page(self, page, title, type):
         self.append_page(page)
-        self.set_page_header_image(page, GUI.load_icon("ontv"))
+        self.set_page_header_image(page, gui.load_icon("ontv"))
         self.set_page_title(page, title)
         self.set_page_type(page, type)
 
@@ -344,7 +344,7 @@
 
         if page_number == 1:
             if self.installed_button.get_active() and self.country:
-                GUI.set_active_from_string(self.country_combobox, self.country)
+                gui.set_active_from_string(self.country_combobox, self.country)
 
         if page_number == 2:
             if self.installed_button.get_active():

Copied: trunk/ontv/channel.py (from r466, /trunk/ontv/Channel.py)
==============================================================================
--- /trunk/ontv/Channel.py	(original)
+++ trunk/ontv/channel.py	Thu Nov  6 20:51:44 2008
@@ -29,7 +29,7 @@
 import gtk.gdk
 import gobject
 
-import GUI
+import gui
 from ontv import IMAGES_DIR
 
 class Channel:
@@ -114,7 +114,7 @@
                     self.logo_small = None
                     return
                 self.custom_logo = False
-                ed = GUI.ErrorDialog(_("Error while loading %s" % file_name),
+                ed = gui.ErrorDialog(_("Error while loading %s" % file_name),
                                      ge.message)
                 ed.run()
                 ed.destroy()

Copied: trunk/ontv/config.py (from r466, /trunk/ontv/Configuration.py)
==============================================================================
--- /trunk/ontv/Configuration.py	(original)
+++ trunk/ontv/config.py	Thu Nov  6 20:51:44 2008
@@ -24,7 +24,7 @@
 
 import gconf
 
-from GUI import ErrorDialog
+from gui import ErrorDialog
 
 DIR_ONTV = "/apps/ontv"
 

Added: trunk/ontv/dialogs.py
==============================================================================
--- (empty file)
+++ trunk/ontv/dialogs.py	Thu Nov  6 20:51:44 2008
@@ -0,0 +1,865 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2004-2008 Johan Svedberg <johan svedberg com>
+
+# This file is part of OnTV.
+
+# OnTV is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# OnTV is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with OnTV; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+
+import struct
+import os
+from gettext import gettext as _
+
+import gtk
+import gconf
+import gobject
+import pango
+import gnome.ui
+
+import config
+import gui
+import utils
+from ChannelDialog import ChannelDialog
+from gui import ProgramContextMenu
+from ProgramDialog import ProgramDialog
+from reminders import Reminder
+from assistant import GRABBERS, XMLTVAssistant
+from ontv import NAME, VERSION
+
+class AboutDialog(gtk.AboutDialog):
+    def __init__(self):
+        gtk.AboutDialog.__init__(self)
+        gtk.about_dialog_set_email_hook(self.__url_hook, "mailto:";)
+        gtk.about_dialog_set_url_hook(self.__url_hook, "")
+
+        self.set_logo_icon_name("ontv")
+        self.set_name(NAME)
+        self.set_version(VERSION)
+        self.set_copyright("Copyright (C) 2004-2008 Johan Svedberg")
+        self.set_website("http://live.gnome.org/OnTV";)
+        self.set_comments(_("OnTV is a GNOME Applet for monitoring TV programs."))
+        self.set_authors(["Johan Svedberg <johan svedberg com>"])
+        self.set_translator_credits(_("translator-credits"))
+        self.set_license("GNU General Public License version 2")
+        self.set_artists(["Josef VybÃral <cornelius vybiral info>", "Andreas Nilsson <nisses mail home se>", "Ville PÃtsi <drc gnu org>"])
+
+        self.connect("response", lambda self, *args: self.destroy())
+
+    def __url_hook(self, widget, url, scheme):
+        gnome.ui.url_show_on_screen(scheme + url, widget.get_screen())
+
+class ChannelDialog:
+    def __init__(self, channel, pd):
+        self.channel = channel
+        self.pd = pd
+        self.__get_widgets()
+
+        if self.channel.logo_file != "":
+            self.logo_iconentry.set_filename(self.channel.logo_file)
+
+        self.__connect_widgets()
+        self.channel_label.set_text(channel.name)
+
+        self.dialog.set_title(_("Properties for channel %s") % channel.name)
+
+    def __get_widgets(self):
+        xml = gtk.glade.XML(gui.glade_file, domain=NAME.lower())
+
+        self.dialog = xml.get_widget("channel_dialog")
+
+        self.channel_label = xml.get_widget("channel_label2")
+        self.logo_iconentry = xml.get_widget("logo_iconentry")
+
+    def __connect_widgets(self):
+        self.dialog.connect("delete-event", self.__dialog_delete)
+        self.dialog.connect("response", self.__dialog_response)
+        self.logo_iconentry.connect("changed", self.__logo_iconentry_changed)
+
+    def __dialog_response(self, dialog, response):
+        dialog.destroy()
+
+    def __dialog_delete(self, dialog, event):
+        return True
+
+    def __logo_iconentry_changed(self, logo_iconentry):
+        icon_file = logo_iconentry.get_filename()
+        if not icon_file:
+            self.channel.logo_file = ""
+            self.channel.logo = self.channel.logo_small = None
+        else:
+            self.channel.logo_file = icon_file
+            self.channel.set_logo(self.channel.logo_file)
+        self.channel.custom_logo = True
+
+        logo_column = self.pd.channels_treeview.get_column(1)
+        logo_column.queue_resize()
+        self.pd.pw.update()
+        self.pd.listings.save()
+
+    def show(self):
+        self.dialog.show()
+
+class PreferencesDialog:
+    def __init__(self, ontvapplet):
+        self.ontvapplet = ontvapplet
+        self.config = ontvapplet.config
+        self.xmltvfile = ontvapplet.xmltvfile
+        self.reminders = ontvapplet.reminders
+        self.kb = ontvapplet.kb
+        self.pw = ontvapplet.pw
+        self.sd = ontvapplet.sd
+
+        self.xmltvfile.connect("loading", self.__xmltvfile_loading)
+        self.xmltvfile.connect("loading-done", self.__xmltvfile_loading_done)
+        self.xmltvfile.connect("loaded-channel",
+                               self.__xmltvfile_loaded_channel)
+        self.xmltvfile.connect("downloading-logo", self.__downloading_logo)
+        self.xmltvfile.connect("downloading-logo-done",
+                               self.__downloading_logo_done)
+
+        self.__get_widgets()
+
+        self.__make_channels_treeview()
+        self.__make_reminders_treeview()
+        self.sd.create_search_treeview_menu(self.reminders_treeview.get_model())
+        self.pw.set_reminders_model(self.reminders_treeview.get_model())
+
+        self.channels_combobox_model = gtk.ListStore(str)
+        self.channels_combobox_model.set_sort_func(0, self.__channels_model_sort_func, False)
+        self.channels_combobox_model.set_sort_column_id(0, gtk.SORT_ASCENDING)
+        self.channels_comboboxentry.set_model(self.channels_combobox_model)
+        self.channels_comboboxentry.set_text_column(0)
+        self.channels_comboboxentry.child.set_text(_("All"))
+        self.sd.channels_combobox.set_model(self.channels_combobox_model)
+
+        self.__connect_widgets()
+
+        self.__add_config_notifications()
+
+        self.grabber_command_entry.set_text(self.config.grabber_command)
+        self.output_file_entry.set_text(self.config.xmltv_file)
+        self.current_programs_checkbutton.set_active(self.config.display_current_programs)
+        self.upcoming_programs_checkbutton.set_active(self.config.display_upcoming_programs)
+        if self.config.upcoming_programs_below:
+            self.upcoming_programs_below_radiobutton.set_active(True)
+        else:
+            self.upcoming_programs_right_radiobutton.set_active(True)
+        self.channels_image.set_from_stock(gtk.STOCK_DIALOG_INFO,
+                                           gtk.ICON_SIZE_DIALOG)
+
+        self.__auto_reload_id = None
+
+    def __get_widgets(self):
+        xml = gtk.glade.XML(gui.glade_file, domain=NAME.lower())
+
+        self.dialog = xml.get_widget("preferences_dialog")
+        self.notebook = xml.get_widget("notebook")
+
+        # General tab
+        self.grabber_command_entry = xml.get_widget("grabber_command_entry")
+        self.output_file_entry = xml.get_widget("output_file_entry")
+        self.browse_button = xml.get_widget("browse_button")
+        self.current_programs_checkbutton = xml.get_widget("current_programs_checkbutton")
+        self.upcoming_programs_checkbutton = xml.get_widget("upcoming_programs_checkbutton")
+        self.position_hbox = xml.get_widget("position_hbox")
+        self.upcoming_programs_below_radiobutton = xml.get_widget("upcoming_programs_below_radiobutton")
+        self.upcoming_programs_right_radiobutton = xml.get_widget("upcoming_programs_right_radiobutton")
+
+        # Channels tab
+        self.channels_treeview = xml.get_widget("channels_treeview")
+        self.channels_image = xml.get_widget("channels_image")
+
+        # Reminders tab
+        self.reminders_treeview = xml.get_widget("reminders_treeview")
+        self.program_entry = xml.get_widget("program_entry")
+        self.channels_comboboxentry = xml.get_widget("channels_comboboxentry")
+        self.notify_spinbutton = xml.get_widget("notify_spinbutton")
+        self.add_reminder_button = xml.get_widget("add_reminder_button")
+        self.update_reminder_button = xml.get_widget("update_reminder_button")
+        self.remove_reminder_button = xml.get_widget("remove_reminder_button")
+
+    def __make_channels_treeview(self):
+        self.channels_model = gtk.ListStore(object)
+        self.channels_model.set_sort_func(0, self.__channels_model_sort_func)
+        self.channels_model.set_sort_column_id(0, gtk.SORT_ASCENDING)
+        self.channels_treeview.set_model(self.channels_model)
+
+        crtoggle = gtk.CellRendererToggle()
+        crtoggle.props.xpad = 6
+        crtoggle.props.ypad = 3
+        crtoggle.props.activatable = True
+        crtoggle.connect("toggled", self.__channels_treeview_toggled,
+                         self.channels_model)
+        selected_column = gtk.TreeViewColumn("Selected", crtoggle)
+        selected_column.set_cell_data_func(crtoggle,
+                                           self.__crtoggle_cell_data_func)
+        self.channels_treeview.append_column(selected_column)
+
+        crpixbuf = gtk.CellRendererPixbuf()
+        crpixbuf.props.xpad = 3
+        crpixbuf.props.ypad = 3
+        logo_column = gtk.TreeViewColumn("Logo", crpixbuf)
+        logo_column.set_cell_data_func(crpixbuf, self.__crpixbuf_cell_data_func)
+        self.channels_treeview.append_column(logo_column)
+
+        crtext = gtk.CellRendererText()
+        crtext.props.xpad = 3
+        crtext.props.ypad = 3
+        channel_column = gtk.TreeViewColumn("Channel", crtext)
+        channel_column.set_cell_data_func(crtext, self.__crtext_cell_data_func)
+        self.channels_treeview.append_column(channel_column)
+        self.channels_treeview.set_search_column(2)
+        self.channels_treeview.set_search_equal_func(self.__channels_treeview_search_equal)
+
+        self.channels_treeview_menu = gtk.Menu()
+        self.edit_channel_imi = gtk.ImageMenuItem(gtk.STOCK_EDIT)
+        self.edit_channel_imi.child.set_markup_with_mnemonic(_("_Properties"))
+        self.edit_channel_imi.show()
+        self.channels_treeview_menu.append(self.edit_channel_imi)
+
+    def __channels_model_sort_func(self, model, iter1, iter2, object=True):
+        channel = model.get_value(iter1, 0)
+        other_channel = model.get_value(iter2, 0)
+        if object:
+            return utils.natcmp(channel.name.lower(), other_channel.name.lower())
+        return utils.natcmp(channel.lower(), other_channel.lower())
+
+    def __channels_treeview_toggled(self, cell, path, model):
+        channel = model[path][0]
+        channel.selected = not channel.selected
+        if channel.selected:
+            self.listings.selected_channels.append(channel.name)
+        else:
+            self.listings.selected_channels.remove(channel.name)
+
+        model.row_changed(path, model.get_iter(path))
+
+        self.pw.update()
+        self.listings.save()
+
+    def __channels_treeview_search_equal(self, model, column, key, iter):
+        channel = model.get_value(iter, 0)
+        return key.lower() not in channel.name.lower()
+
+    def __crtoggle_cell_data_func(self, column, cell, model, iter):
+        channel = model.get_value(iter, 0)
+        cell.props.active = channel.selected
+
+    def __crpixbuf_cell_data_func(self, column, cell, model, iter):
+        channel = model.get_value(iter, 0)
+        cell.props.pixbuf = channel.logo
+
+    def __crtext_cell_data_func(self, column, cell, model, iter):
+        channel = model.get_value(iter, 0)
+        markup = "<b>%s</b>"
+        cell.props.markup = markup % channel.markup_escaped_name
+
+    def __make_reminders_treeview(self):
+        reminders_model = gtk.ListStore(object)
+        self.reminders_treeview.set_model(reminders_model)
+
+        program_crt = gtk.CellRendererText()
+        program_crt.props.xpad = 3
+        program_crt.props.ypad = 3
+        program_column = gtk.TreeViewColumn(_("Program"), program_crt)
+        program_column.set_cell_data_func(program_crt,
+                                          self.__program_crt_cell_data_func)
+        self.reminders_treeview.append_column(program_column)
+
+        channel_crt = gtk.CellRendererText()
+        channel_crt.props.xpad = 3
+        channel_crt.props.ypad = 3
+        channel_column = gtk.TreeViewColumn(_("Channel"), channel_crt)
+        channel_column.set_cell_data_func(channel_crt,
+                                          self.__channel_crt_cell_data_func)
+        self.reminders_treeview.append_column(channel_column)
+
+        notify_crt = gtk.CellRendererText()
+        notify_crt.props.xpad = 3
+        notify_crt.props.ypad = 3
+        notify_column = gtk.TreeViewColumn(_("Notification time"), notify_crt)
+        notify_column.set_cell_data_func(notify_crt,
+                                         self.__notify_crt_cell_data_func)
+        self.reminders_treeview.append_column(notify_column)
+
+        for reminder in self.reminders.reminders:
+            reminders_model.append([reminder])
+
+    def __program_crt_cell_data_func(self, column, cell, model, iter):
+        reminder = model.get_value(iter, 0)
+        cell.props.text = reminder.program
+
+    def __channel_crt_cell_data_func(self, column, cell, model, iter):
+        reminder = model.get_value(iter, 0)
+        cell.props.markup = reminder.channel
+
+    def __notify_crt_cell_data_func(self, column, cell, model, iter):
+        reminder = model.get_value(iter, 0)
+        cell.props.text = reminder.notify_time
+
+    def __connect_widgets(self):
+        self.dialog.connect("delete-event", self.__dialog_delete)
+        self.dialog.connect("response", self.__dialog_response)
+
+        # General tab
+        self.grabber_command_entry.connect("changed", self.__grabber_command_entry_changed)
+        self.grabber_command_entry.connect("activate", self.__grabber_command_entry_activated)
+        self.output_file_entry.connect("changed", self.__output_file_entry_changed)
+        self.output_file_entry.connect("activate", self.__output_file_entry_activated)
+        self.browse_button.connect("clicked", self.__browse_button_clicked)
+        self.current_programs_checkbutton.connect("toggled", self.__current_programs_checkbutton_toggled)
+        self.upcoming_programs_checkbutton.connect("toggled", self.__upcoming_programs_checkbutton_toggled)
+        self.upcoming_programs_below_radiobutton.connect("toggled", self.__upcoming_programs_below_radiobutton_toggled)
+
+        # Channels tab
+        self.channels_treeview.connect("row-activated",
+                                       self.__channels_treeview_row_activated)
+        self.channels_treeview.connect("button-press-event",
+                                       self.__channels_treeview_button_press,
+                                       self.channels_treeview_menu)
+        self.edit_channel_imi.connect("activate",
+                                      self.__edit_channel_imi_activate)
+
+        # Reminders tab
+        self.reminders_treeview.connect("key-press-event", self.__reminders_treeview_key_press_event)
+        selection = self.reminders_treeview.get_selection()
+        selection.connect("changed",
+                          self.__reminders_treeview_selection_changed)
+        self.program_entry.connect("changed", self.__program_entry_changed)
+        self.program_entry.connect("activate",
+                                   self.__update_reminder_button_clicked)
+        self.channels_comboboxentry.connect("changed", self.__channels_comboboxentry_changed)
+        self.channels_comboboxentry.child.connect("activate", self.__update_reminder_button_clicked)
+        self.notify_spinbutton.connect("value_changed",
+                                       self.__notify_spinbutton_value_changed)
+        self.notify_spinbutton.connect("activate",
+                                       self.__update_reminder_button_clicked)
+        self.add_reminder_button.connect("clicked",
+                                         self.__add_reminder_button_clicked)
+        self.update_reminder_button.connect("clicked", self.__update_reminder_button_clicked)
+        self.remove_reminder_button.connect("clicked", self.__remove_reminder_button_clicked)
+
+    def __dialog_response(self, dialog, response):
+        self.dialog.hide()
+
+    def __dialog_delete(self, dialog, event):
+        return True
+
+    def __grabber_command_entry_changed(self, entry):
+        self.config.grabber_command = entry.get_text()
+
+    def __grabber_command_entry_activated(self, entry):
+        self.xmltvfile.download()
+
+    def __output_file_entry_changed(self, entry):
+        self.config.xmltv_file = entry.get_text()
+
+    def __output_file_entry_activated(self, entry):
+        self.xmltvfile.load()
+
+    def __browse_button_clicked(self, button):
+        xml_filter = gtk.FileFilter()
+        xml_filter.set_name(_("XML files"))
+        xml_filter.add_pattern("text/xml")
+        filters = [xml_filter]
+        fd = gui.FileChooserDialog(_("Select XMLTV file..."), filters)
+        response = fd.run()
+        if response == gtk.RESPONSE_OK:
+            self.config.xmltv_file = fd.get_filename()
+            self.xmltvfile.load()
+            fd.hide()
+        elif response == gtk.RESPONSE_CANCEL:
+            fd.hide()
+
+    def __current_programs_checkbutton_toggled(self, checkbutton):
+        self.config.display_current_programs = checkbutton.get_active()
+
+    def __upcoming_programs_checkbutton_toggled(self, checkbutton):
+        active = checkbutton.get_active()
+        self.config.display_upcoming_programs = active
+        self.position_hbox.set_sensitive(active)
+
+    def __upcoming_programs_below_radiobutton_toggled(self, radiobutton):
+        active = radiobutton.get_active()
+        self.config.upcoming_programs_below = active
+
+    def __channels_treeview_row_activated(self, treeview, path, column):
+        self.__channels_treeview_toggled(None, path, self.channels_model)
+
+    def __channels_treeview_button_press(self, treeview, event, menu):
+        if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3:
+            menu.popup(None, None, None, event.button, event.time)
+
+    def __edit_channel_imi_activate(self, menuitem):
+        channel = gui.get_selected_value(self.channels_treeview)
+        if channel:
+            cd = ChannelDialog(channel, self)
+            cd.show()
+
+    def __reminders_treeview_selection_changed(self, selection):
+        (reminders_model, reminders_iter) = selection.get_selected()
+        if reminders_iter:
+            self.remove_reminder_button.set_sensitive(True)
+            reminder = reminders_model.get_value(reminders_iter, 0)
+            self.program_entry.set_text(reminder.program)
+            channel = pango.parse_markup(reminder.channel, u"\x00")[1]
+            self.channels_comboboxentry.child.set_text(channel)
+            self.notify_spinbutton.set_value(reminder.notify_time)
+        else:
+            self.program_entry.set_text("")
+            self.channels_comboboxentry.child.set_text("")
+            self.notify_spinbutton.set_value(5)
+            self.add_reminder_button.set_sensitive(False)
+            self.update_reminder_button.set_sensitive(False)
+            self.remove_reminder_button.set_sensitive(False)
+
+    def __reminders_treeview_key_press_event(self, treeview, event):
+        if event.keyval == gtk.keysyms.Delete:
+            self.remove_reminder_button.emit("clicked")
+
+    def __program_entry_changed(self, entry):
+        if len(entry.get_text()) > 0:
+            self.__set_reminder_buttons_sensitivity()
+        else:
+            self.add_reminder_button.set_sensitive(False)
+            self.update_reminder_button.set_sensitive(False)
+
+    def __channels_comboboxentry_changed(self, comboboxentry):
+        self.__set_reminder_buttons_sensitivity()
+
+    def __notify_spinbutton_value_changed(self, spinbutton):
+        self.__set_reminder_buttons_sensitivity()
+
+    def __set_reminder_buttons_sensitivity(self):
+        if not self.__get_reminder() in self.reminders.reminders:
+            self.add_reminder_button.set_sensitive(True)
+            if gui.has_selection(self.reminders_treeview):
+                self.update_reminder_button.set_sensitive(True)
+        else:
+            self.add_reminder_button.set_sensitive(False)
+            self.update_reminder_button.set_sensitive(False)
+
+    def __add_reminder_button_clicked(self, button):
+        reminder = self.__get_reminder()
+        if self.reminders.add(reminder):
+            reminders_model = self.reminders_treeview.get_model()
+            reminders_model.append([reminder])
+            gui.queue_resize(self.reminders_treeview)
+            self.reminders.save()
+            self.add_reminder_button.set_sensitive(False)
+            self.sd.search_treeview.get_selection().emit("changed")
+            self.pw.update()
+
+    def __get_reminder(self):
+        program = self.program_entry.get_text()
+        channel = self.channels_comboboxentry.child.get_text()
+        channel = gobject.markup_escape_text(channel)
+        notify_time = self.notify_spinbutton.get_value_as_int()
+        return Reminder(program, channel, notify_time)
+
+    def __update_reminder_button_clicked(self, button):
+        selection = self.reminders_treeview.get_selection()
+        (reminders_model, reminders_iter) = selection.get_selected()
+        if not reminders_iter:
+            self.add_reminder_button.clicked()
+        else:
+            current_reminder = reminders_model.get_value(reminders_iter, 0)
+            new_reminder = self.__get_reminder()
+            if not current_reminder is new_reminder:
+                self.reminders.update(current_reminder, new_reminder)
+                reminders_model.set_value(reminders_iter, 0, new_reminder)
+                gui.queue_resize(self.reminders_treeview)
+                self.reminders.save()
+                self.add_reminder_button.set_sensitive(False)
+                self.update_reminder_button.set_sensitive(False)
+                self.sd.search_treeview.get_selection().emit("changed")
+                self.pw.update()
+
+    def __remove_reminder_button_clicked(self, button):
+        selection = self.reminders_treeview.get_selection()
+        (reminders_model, reminders_iter) = selection.get_selected()
+        if reminders_iter:
+            reminder = reminders_model.get_value(reminders_iter, 0)
+            if self.reminders.remove(reminder):
+                reminders_model.remove(reminders_iter)
+                gui.queue_resize(self.reminders_treeview)
+                self.reminders.save()
+                self.sd.search_treeview.get_selection().emit("changed")
+
+    def __add_config_notifications(self):
+        self.config.add_notify(config.KEY_GRABBER_COMMAND,
+                               self.__grabber_command_key_changed)
+        self.config.add_notify(config.KEY_XMLTV_FILE,
+                               self.__xmltv_file_key_changed)
+        self.config.add_notify(config.KEY_SHOW_WINDOW_HOTKEY,
+                               self.__show_window_hotkey_key_changed)
+        self.config.add_notify(config.KEY_SHOW_SEARCH_PROGRAM_HOTKEY,
+                               self.__show_search_program_hotkey_key_changed)
+        self.config.add_notify(config.KEY_DISPLAY_CURRENT_PROGRAMS,
+                               self.__display_current_programs_key_changed)
+        self.config.add_notify(config.KEY_DISPLAY_UPCOMING_PROGRAMS,
+                               self.__display_upcoming_programs_key_changed)
+        self.config.add_notify(config.KEY_UPCOMING_PROGRAMS_BELOW,
+                               self.__upcoming_programs_below_key_changed)
+
+    def __grabber_command_key_changed(self, client, cnxn_id, entry, data):
+        if entry.value.type == gconf.VALUE_STRING:
+            command = entry.value.to_string()
+            self.grabber_command_entry.set_text(command)
+
+    def __xmltv_file_key_changed(self, client, cnxn_id, entry, data):
+        if entry.value.type == gconf.VALUE_STRING:
+            xmltv_file = entry.value.to_string()
+            self.xmltvfile.props.path = xmltv_file
+            self.output_file_entry.set_text(xmltv_file)
+
+    def __show_window_hotkey_key_changed(self, client, cnxn_id, entry, data):
+        if not entry.value:
+            return
+        elif entry.value.type == gconf.VALUE_STRING:
+            # Unbind the current binding if any
+            if self.kb.props.show_window_hotkey != "":
+                self.kb.unbind(self.kb.props.show_window_hotkey)
+
+            value = entry.value.to_string()
+            if value != "":
+                self.kb.props.show_window_hotkey = value
+        else:
+            pass # TODO: Output error msg
+
+    def __show_search_program_hotkey_key_changed(self, client, cnxn_id, entry,
+                                                 data):
+        if not entry.value:
+            return
+        elif entry.value.type == gconf.VALUE_STRING:
+            # Unbind the current binding if any
+            if self.kb.props.show_search_program_hotkey != "":
+                self.kb.unbind(self.kb.props.show_search_program_hotkey)
+
+            value = entry.value.to_string()
+            if value != "":
+                self.kb.props.show_search_program_hotkey = value
+        else:
+            pass # TODO: Output error msg
+
+    def __display_current_programs_key_changed(self, client, cnxn_id, entry,
+                                               data):
+        if not entry.value:
+            self.current_programs_checkbutton.set_active(True)
+        elif entry.value.type == gconf.VALUE_BOOL:
+            value = entry.value.get_bool()
+            self.current_programs_checkbutton.set_active(value)
+            if value:
+                self.pw.cpt.show()
+            else:
+                self.pw.cpt.hide()
+        else:
+            self.current_programs_checkbutton.set_active(True)
+
+    def __display_upcoming_programs_key_changed(self, client, cnxn_id, entry,
+                                                data):
+        if not entry.value:
+            self.upcoming_programs_checkbutton.set_active(True)
+        elif entry.value.type == gconf.VALUE_BOOL:
+            value = entry.value.get_bool()
+            self.upcoming_programs_checkbutton.set_active(value)
+            if value:
+                self.pw.upt.show()
+            else:
+                self.pw.upt.hide()
+        else:
+            self.upcoming_programs_checkbutton.set_active(True)
+
+    def __upcoming_programs_below_key_changed(self, client, cnxn_id, entry,
+                                              data):
+        if not entry.value:
+            self.upcoming_programs_below_radiobutton.set_active(True)
+        elif entry.value.type == gconf.VALUE_BOOL:
+            value = entry.value.get_bool()
+            self.upcoming_programs_below_radiobutton.set_active(value)
+            self.pw.position_upcoming_programs(value)
+        else:
+            self.upcoming_programs_below_radiobutton.set_active(True)
+
+    def __xmltvfile_loading(self, xmltvfile):
+        self.channels_model.clear()
+        self.channels_combobox_model.clear()
+
+    def __xmltvfile_loading_done(self, xmltvfile, listings):
+        if listings:
+            self.listings = listings
+            self.channels_combobox_model.append([_("All")])
+            self.sd.set_all_as_combo_active(self.sd.channels_combobox)
+
+    def __xmltvfile_loaded_channel(self, xmltvfile, channel):
+        self.channels_model.append([channel])
+        self.channels_combobox_model.append([channel])
+
+    def __channel_changed(self, xmltvfile, channel):
+        channels_iter = self.channels_model.get_iter_first()
+        for row in self.channels_model:
+            if row[0] is channel:
+                channels_path = self.channels_model.get_path(channels_iter)
+                self.channels_model.row_changed(channels_path, channels_iter)
+                break
+            channels_iter = self.channels_model.iter_next(channels_iter)
+
+    def __downloading_logo(self, xmltvfile, channel):
+        self.__channel_changed(xmltvfile, channel)
+
+    def __downloading_logo_done(self, xmltvfile, channel):
+        self.__channel_changed(xmltvfile, channel)
+
+    def show(self, uicomponent=None, verb=None):
+        self.dialog.show()
+
+class ProgramDialog:
+    def __init__(self, program):
+        self.__get_widgets()
+        self.__connect_widgets()
+        self.name_label.set_text(program.title)
+        self.channel_label.set_text(program.channel.name)
+        self.description_label.set_text(program.description)
+        self.air_time_label.set_text(("%s-%s\n%s") %
+                                      (program.start_time, program.stop_time,
+                                       program.date))
+
+        self.dialog.set_title(_("Details about %s") % program.title)
+        if program.channel.logo:
+            self.channel_image.set_from_pixbuf(program.channel.logo)
+        else:
+            self.channel_image.set_from_icon_name(NAME.lower(),
+                                                  gtk.ICON_SIZE_DIALOG)
+
+    def __get_widgets(self):
+        xml = gtk.glade.XML(gui.glade_file, domain=NAME.lower())
+
+        self.dialog = xml.get_widget("program_dialog")
+
+        self.name_label = xml.get_widget("name_label")
+        self.channel_image = xml.get_widget("channel_image")
+        self.channel_label = xml.get_widget("channel_label")
+        self.description_label = xml.get_widget("description_label")
+        self.air_time_label = xml.get_widget("air_time_label")
+
+    def __connect_widgets(self):
+        self.dialog.connect("delete-event", self.__dialog_delete)
+        self.dialog.connect("response", self.__dialog_response)
+
+    def __dialog_response(self, dialog, response):
+        self.dialog.destroy()
+
+    def __dialog_delete(self, dialog, event):
+        return True
+
+    def show(self):
+        self.dialog.show()
+
+TIMEOUT = 100
+
+class SearchDialog:
+    def __init__(self, xmltvfile, reminders):
+        xmltvfile.connect("loading-done", self.__xmltvfile_loading_done)
+        self.reminders = reminders
+
+        self.__get_widgets()
+        self.__make_channels_combobox()
+        self.__make_search_treeview()
+        self.__connect_widgets()
+
+        self.search_label.set_mnemonic_widget(self.search_entry)
+
+        self.__timeout_id = 0
+
+    def __get_widgets(self):
+        xml = gtk.glade.XML(gui.glade_file, domain=NAME.lower())
+
+        self.dialog = xml.get_widget("search_dialog")
+        self.close_button = xml.get_widget("search_closebutton")
+        self.details_button = xml.get_widget("details_button")
+
+        self.search_label = xml.get_widget("search_label")
+        self.search_entry = xml.get_widget("search_entry")
+        self.channels_combobox = xml.get_widget("channels_combobox")
+
+        self.search_treeview = xml.get_widget("search_treeview")
+
+    def __make_channels_combobox(self):
+        crt = gtk.CellRendererText()
+        self.channels_combobox.pack_start(crt, True)
+        self.channels_combobox.add_attribute(crt, 'text', 0)
+
+    def __make_search_treeview(self):
+        search_model = gtk.ListStore(object)
+        self.search_treeview.set_model(search_model)
+
+        crt = gtk.CellRendererText()
+        crt.props.xpad = 3
+        crt.props.ypad = 3
+        time_column = gtk.TreeViewColumn("Air time", crt)
+        time_column.set_cell_data_func(crt, self.__crt_cell_data_func)
+        self.search_treeview.append_column(time_column)
+
+        crtext = gtk.CellRendererText()
+        crtext.props.xpad = 3
+        crtext.props.ypad = 3
+        program_column = gtk.TreeViewColumn("Program", crtext)
+        program_column.set_cell_data_func(crtext, self.__crtext_cell_data_func)
+        self.search_treeview.append_column(program_column)
+
+    def __crt_cell_data_func(self, column, cell, model, iter):
+        program = model.get_value(iter, 0)
+        markup = "<b>%s-%s</b>\n<i>%s</i>"
+        cell.props.markup = markup % (program.start_time, program.stop_time,
+                                      program.date)
+
+    def __crtext_cell_data_func(self, column, cell, model, iter):
+        program = model.get_value(iter, 0)
+        markup = "<b>%s</b>\n<i>%s</i>"
+        cell.props.markup = markup % (program.markup_escaped_title,
+                                      program.channel.markup_escaped_name)
+
+    def __connect_widgets(self):
+        self.dialog.connect("delete-event", self.__dialog_delete)
+
+        self.search_entry.connect("changed", self.__search_entry_changed)
+
+        selection = self.search_treeview.get_selection()
+        selection.connect("changed", self.__search_treeview_selection_changed)
+        self.search_treeview.connect("row-activated",
+                                     self.__search_treeview_row_activated)
+
+        self.close_button.connect("clicked", self.__close_button_clicked)
+        self.details_button.connect("clicked", self.__details_button_clicked)
+
+    def __dialog_delete(self, dialog, event):
+        self.dialog.hide()
+        return True
+
+    def __search_entry_changed(self, entry):
+        if self.__timeout_id > 0:
+            gobject.source_remove(self.__timeout_id)
+
+        self.__timeout_id = gobject.timeout_add(TIMEOUT, self.__search)
+
+    def __search(self):
+        search_model = self.search_treeview.get_model()
+        search_model.clear()
+        program_column = self.search_treeview.get_column(1)
+        search = self.search_entry.get_text().strip().lower().split()
+        active = self.channels_combobox.get_active()
+        channels_model = self.channels_combobox.get_model()
+        channel = channels_model[active][0]
+
+        if len(search) > 0:
+            matches = self.listings.search_program(search, channel)
+            iter = search_model.get_iter_first()
+            for row in search_model:
+                program = row[0]
+                if not program in matches:
+                    search_model.remove(iter)
+                else:
+                    matches.remove(program)
+                    search_model.iter_next(iter)
+
+            for program in matches:
+                search_model.append([program])
+                program_column.queue_resize()
+
+        program_column.queue_resize()
+        self.search_treeview.set_cursor(0)
+        return False
+
+    def __search_treeview_selection_changed(self, selection):
+        (search_model, search_iter) = selection.get_selected()
+        if search_iter:
+            self.details_button.set_sensitive(True)
+            program = search_model.get_value(search_iter, 0)
+            reminder = Reminder(program.title,
+                                program.channel.markup_escaped_name)
+            if not reminder in self.reminders.reminders:
+                self.search_treeview_menu.add_reminder_imi.set_sensitive(True)
+            else:
+                self.search_treeview_menu.add_reminder_imi.set_sensitive(False)
+        else:
+            self.details_button.set_sensitive(False)
+            self.search_treeview_menu.add_reminder_imi.set_sensitive(False)
+
+    def __search_treeview_row_activated(self, treeview, path, column):
+        self.details_button.emit("clicked")
+
+    def __search_treeview_button_press(self, treeview, event, menu):
+        if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3:
+            search_model = treeview.get_model()
+            path = treeview.get_path_at_pos(int(event.x), int(event.y))[0]
+            program = search_model[path][0]
+            if program.description and program.description != "":
+                self.search_treeview_menu.details_imi.set_sensitive(True)
+            else:
+                self.search_treeview_menu.details_imi.set_sensitive(False)
+
+            menu.popup(None, None, None, event.button, event.time)
+
+    def __close_button_clicked(self, button):
+        self.dialog.hide()
+
+    def __details_button_clicked(self, button):
+        program = gui.get_selected_value(self.search_treeview)
+        self.__show_program_dialog(program)
+
+    def __show_program_dialog(self, program):
+        pd = ProgramDialog(program)
+        pd.show()
+
+    def __xmltvfile_loading_done(self, xmltvfile, listings):
+        if listings:
+            self.listings = listings
+            self.search_entry.emit("changed")
+
+    def set_all_as_combo_active(self, combobox):
+        channels_model = combobox.get_model()
+        channels_iter = channels_model.get_iter_first()
+        for row in channels_model:
+            if row[0] == _("All"):
+                combobox.set_active_iter(channels_iter)
+                break
+            channels_iter = channels_model.iter_next(channels_iter)
+
+    def create_search_treeview_menu(self, reminders_model):
+        self.search_treeview_menu = ProgramContextMenu(self.get_program,
+                                                       self.reminders,
+                                                       reminders_model)
+        self.search_treeview.connect("button-press-event",
+                                     self.__search_treeview_button_press,
+                                     self.search_treeview_menu)
+
+    def get_program(self):
+        return gui.get_selected_value(self.search_treeview)
+
+    def show(self, uicomponent=None, verb=None):
+        self.present()
+
+    def present(self, time=None):
+        self.search_treeview.set_cursor(0)
+        self.search_entry.grab_focus()
+        self.dialog.grab_focus()
+        if time:
+            self.dialog.present_with_time(time)
+            # Ugly, but the only way I could get it to work correct
+            self.dialog.present_with_time(time)
+        else:
+            self.dialog.present()
+
+# vim: set sw=4 et sts=4 tw=79 fo+=l:

Copied: trunk/ontv/gui.py (from r466, /trunk/ontv/GUI.py)
==============================================================================
--- /trunk/ontv/GUI.py	(original)
+++ trunk/ontv/gui.py	Thu Nov  6 20:51:44 2008
@@ -25,8 +25,8 @@
 import gtk.gdk
 import gtk.glade
 
-from ProgramDialog import ProgramDialog
-from Reminders import Reminder
+from dialogs import ProgramDialog
+from reminders import Reminder
 from ontv import NAME, DATA_DIR, LOCALE_DIR, IMAGES_DIR
 
 gtk.glade.bindtextdomain(NAME.lower(), LOCALE_DIR)

Copied: trunk/ontv/main.py (from r466, /trunk/ontv/Main.py)
==============================================================================
--- /trunk/ontv/Main.py	(original)
+++ trunk/ontv/main.py	Thu Nov  6 20:51:44 2008
@@ -30,8 +30,8 @@
 import gnome
 import gnomeapplet
 
-import GUI
-from OnTVApplet import OnTVApplet
+import gui
+from applet import OnTVApplet
 from ontv import NAME, VERSION, LOCALE_DIR
 
 def main():
@@ -61,13 +61,13 @@
 
     gnome.init(NAME, VERSION)
     gtk.gdk.threads_init()
-    gtk.window_set_default_icon_list(*GUI.get_icon_list([16,22,24,32,48]))
+    gtk.window_set_default_icon_list(*gui.get_icon_list([16,22,24,32,48]))
 
     if standalone:
         window = gtk.Window(gtk.WINDOW_TOPLEVEL)
         window.set_title(NAME)
         window.props.allow_grow = False
-        gtk.window_set_default_icon_list(*GUI.get_icon_list([16, 22, 24, 32,
+        gtk.window_set_default_icon_list(*gui.get_icon_list([16, 22, 24, 32,
                                                              48]))
         window.connect("destroy", gtk.main_quit)
         applet = gnomeapplet.Applet()

Copied: trunk/ontv/notify.py (from r466, /trunk/ontv/Notification.py)
==============================================================================
--- /trunk/ontv/Notification.py	(original)
+++ trunk/ontv/notify.py	Thu Nov  6 20:51:44 2008
@@ -23,10 +23,10 @@
 
 import gobject
 
-from ProgramDialog import ProgramDialog
+from dialogs import ProgramDialog
 
 from ontv import NAME
-from GUI import ErrorDialog
+from gui import ErrorDialog
 try:
     import pynotify
 except ImportError, ie:
@@ -43,7 +43,7 @@
         self.program = program
         self.get_readable_time = get_readable_time
 
-        from OnTVApplet import OnTVApplet
+        from applet import OnTVApplet
         self.ontvapplet = OnTVApplet()
 
         pynotify.init(NAME)

Copied: trunk/ontv/program.py (from r466, /trunk/ontv/Program.py)
==============================================================================
--- /trunk/ontv/Program.py	(original)
+++ trunk/ontv/program.py	Thu Nov  6 20:51:44 2008
@@ -23,8 +23,6 @@
 
 import gobject
 
-from TimeSpan import TimeSpan
-
 class Program:
     def __init__(self, program):
         self.title = self.__get_title(program)
@@ -64,4 +62,56 @@
     def get_time_until_stop(self):
         return self.time_span.time_until_stop()
 
+class TimeSpan:
+    """A TimeSpan represents a span of time, for example the running time of a
+    specific TV program."""
+
+    def __init__(self, start, stop):
+        """Create a TimeSpan from a start time and an stop time."""
+        self.start = start
+        self.stop = stop
+
+    def spans_time(self, time):
+        """Check if this TimeSpan includes a specific time."""
+        return time > self.start and time < self.stop
+
+    def spans_now(self):
+        """Check if this TimeSpan includes the current time."""
+        return self.spans_time(datetime.datetime.now())
+
+    def duration(self):
+        """Calculate the distance (TimeDelta) from the start of this TimeSpan,
+        to the stop of this TimeSpan."""
+        return self.stop - self.start
+
+    def time_until_start_from(self, base):
+        """Calculate the distance (TimeDelta) from a specific time, to the
+        start of this TimeSpan."""
+        return self.start - base
+
+    def time_until_start(self):
+        """Calculate the distance (TimeDelta) from the current time, to the
+        start of this TimeSpan."""
+        return self.time_until_start_from(datetime.datetime.now())
+
+    def time_from_start_from(self, base):
+        """Calculate the distance (TimeDelta) from the start of this TimeSpan,
+        to a specific time."""
+        return base - self.start
+
+    def time_from_start(self):
+        """Calculate the distance (TimeDelta) from the start of this TimeSpan,
+        to the current time."""
+        return self.time_from_start_from(datetime.datetime.now())
+
+    def time_until_stop_from(self, base):
+        """Calculate the distance (TimeDelta) from a specific time, to the stop
+        of this TimeSpan."""
+        return self.stop - base
+
+    def time_until_stop(self):
+        """Calculate the distance (TimeDelta) from the current time, to the
+        stop of this TimeSpan."""
+        return self.time_until_stop_from(datetime.datetime.now())
+
 # vim: set sw=4 et sts=4 tw=79 fo+=l:

Copied: trunk/ontv/window.py (from r466, /trunk/ontv/ProgramWindow.py)
==============================================================================
--- /trunk/ontv/ProgramWindow.py	(original)
+++ trunk/ontv/window.py	Thu Nov  6 20:51:44 2008
@@ -26,11 +26,10 @@
 import gobject
 import pango
 
-import GUI
-from Configuration import Configuration
-from GUI import ProgramContextMenu
-from Reminders import Reminders, Reminder
-from Notification import Notification
+from config import Configuration
+from gui import ProgramContextMenu
+from reminders import Reminders, Reminder
+from notify import Notification
 
 TIMEOUT = 60000
 

Copied: trunk/ontv/xmltv_file.py (from r466, /trunk/ontv/XMLTVFile.py)
==============================================================================
--- /trunk/ontv/XMLTVFile.py	(original)
+++ trunk/ontv/xmltv_file.py	Thu Nov  6 20:51:44 2008
@@ -27,12 +27,12 @@
 import gtk
 import gobject
 
-from GUI import ErrorDialog
+from gui import ErrorDialog
 import xmltv
 
-from Listings import Listings
-from Channel import Channel
-from Program import Program
+from listings import Listings
+from channel import Channel
+from program import Program
 
 class XMLTVFile(gobject.GObject):
     __gproperties__ = {"path": (str, "XMLTV file path",

Modified: trunk/scripts/ontv.in
==============================================================================
--- trunk/scripts/ontv.in	(original)
+++ trunk/scripts/ontv.in	Thu Nov  6 20:51:44 2008
@@ -26,9 +26,9 @@
 if PYTHON_DIR not in sys.path:
     sys.path.insert(0, PYTHON_DIR)
 
-from ontv import Main
+from ontv import main
 
 if __name__ == "__main__":
-    Main.main()
+    main.main()
 
 # vim: set sw=4 et sts=4 tw=79 fo+=l:



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]