cbe1fcf3fc6d58f0c165aafd7671eef7e374e718
[watersofshiloah] / src / windows.py
1 import ConfigParser
2 import logging
3
4 import gobject
5 import gtk
6
7 import constants
8 import hildonize
9 import gtk_toolbox
10 import util.misc as misc_utils
11
12 import banners
13 import playcontrol
14
15
16 _moduleLogger = logging.getLogger(__name__)
17
18
19 class BasicWindow(gobject.GObject):
20
21         __gsignals__ = {
22                 'quit' : (
23                         gobject.SIGNAL_RUN_LAST,
24                         gobject.TYPE_NONE,
25                         (),
26                 ),
27                 'fullscreen' : (
28                         gobject.SIGNAL_RUN_LAST,
29                         gobject.TYPE_NONE,
30                         (gobject.TYPE_PYOBJECT, ),
31                 ),
32         }
33
34         def __init__(self, player, store):
35                 gobject.GObject.__init__(self)
36
37                 self._player = player
38                 self._store = store
39
40                 self._clipboard = gtk.clipboard_get()
41                 self._windowInFullscreen = False
42
43                 self._errorBanner = banners.StackingBanner()
44
45                 self._layout = gtk.VBox()
46                 self._layout.pack_start(self._errorBanner.toplevel, False, True)
47
48                 self._window = gtk.Window()
49                 self._window.add(self._layout)
50                 self._window = hildonize.hildonize_window(self, self._window)
51
52                 hildonize.set_application_title(self._window, "%s" % constants.__pretty_app_name__)
53                 self._window.set_icon(self._store.get_pixbuf_from_store(self._store.STORE_LOOKUP["icon"]))
54                 self._window.connect("key-press-event", self._on_key_press)
55                 self._window.connect("window-state-event", self._on_window_state_change)
56
57         @property
58         def window(self):
59                 return self._window
60
61         def save_settings(self, config, sectionName):
62                 config.add_section(sectionName)
63                 config.set(sectionName, "fullscreen", str(self._windowInFullscreen))
64
65         def load_settings(self, config, sectionName):
66                 try:
67                         self._windowInFullscreen = config.getboolean(sectionName, "fullscreen")
68                 except ConfigParser.NoSectionError, e:
69                         _moduleLogger.info(
70                                 "Settings file %s is missing section %s" % (
71                                         constants._user_settings_,
72                                         e.section,
73                                 )
74                         )
75
76                 if self._windowInFullscreen:
77                         self._window.fullscreen()
78                 else:
79                         self._window.unfullscreen()
80
81         @misc_utils.log_exception(_moduleLogger)
82         def _on_window_state_change(self, widget, event, *args):
83                 if event.new_window_state & gtk.gdk.WINDOW_STATE_FULLSCREEN:
84                         self._windowInFullscreen = True
85                 else:
86                         self._windowInFullscreen = False
87                 self.emit("fullscreen", self._windowInFullscreen)
88
89         @misc_utils.log_exception(_moduleLogger)
90         def _on_key_press(self, widget, event, *args):
91                 RETURN_TYPES = (gtk.keysyms.Return, gtk.keysyms.ISO_Enter, gtk.keysyms.KP_Enter)
92                 isCtrl = bool(event.get_state() & gtk.gdk.CONTROL_MASK)
93                 if (
94                         event.keyval == gtk.keysyms.F6 or
95                         event.keyval in RETURN_TYPES and isCtrl
96                 ):
97                         # The "Full screen" hardware key has been pressed
98                         if self._windowInFullscreen:
99                                 self._window.unfullscreen ()
100                         else:
101                                 self._window.fullscreen ()
102                         return True
103                 elif (
104                         event.keyval in (gtk.keysyms.w, ) and
105                         event.get_state() & gtk.gdk.CONTROL_MASK
106                 ):
107                         self._window.destroy()
108                 elif (
109                         event.keyval in (gtk.keysyms.q, ) and
110                         event.get_state() & gtk.gdk.CONTROL_MASK
111                 ):
112                         self.emit("quit")
113                 elif event.keyval == gtk.keysyms.l and event.get_state() & gtk.gdk.CONTROL_MASK:
114                         with open(constants._user_logpath_, "r") as f:
115                                 logLines = f.xreadlines()
116                                 log = "".join(logLines)
117                                 self._clipboard.set_text(str(log))
118                         return True
119
120
121 class SourceSelector(BasicWindow):
122
123         def __init__(self, player, store):
124                 BasicWindow.__init__(self, player, store)
125
126                 self._radioButton = self._create_button("radio", "Radio")
127                 self._radioButton.connect("clicked", self._on_radio_selected)
128                 self._radioWrapper = gtk.VBox()
129                 self._radioWrapper.pack_start(self._radioButton, False, True)
130
131                 self._conferenceButton = self._create_button("conferences", "Conferences")
132                 #self._conferenceButton.connect("clicked", self._on_conference_selected)
133                 self._conferenceWrapper = gtk.VBox()
134                 self._conferenceWrapper.pack_start(self._conferenceButton, False, True)
135
136                 self._magazineButton = self._create_button("magazines", "Magazines")
137                 #self._magazineButton.connect("clicked", self._on_magazine_selected)
138                 self._magazineWrapper = gtk.VBox()
139                 self._magazineWrapper.pack_start(self._magazineButton, False, True)
140
141                 self._scriptureButton = self._create_button("scriptures", "Scriptures")
142                 #self._scriptureButton.connect("clicked", self._on_scripture_selected)
143                 self._scriptureWrapper = gtk.VBox()
144                 self._scriptureWrapper.pack_start(self._scriptureButton, False, True)
145
146                 self._buttonLayout = gtk.VBox(True, 5)
147                 self._buttonLayout.set_property("border-width", 5)
148                 self._buttonLayout.pack_start(self._radioWrapper, True, True)
149                 self._buttonLayout.pack_start(self._conferenceWrapper, True, True)
150                 self._buttonLayout.pack_start(self._magazineWrapper, True, True)
151                 self._buttonLayout.pack_start(self._scriptureWrapper, True, True)
152
153                 self._playcontrol = playcontrol.PlayControl(player, store)
154
155                 self._layout.pack_start(self._buttonLayout, True, True)
156                 self._layout.pack_start(self._playcontrol.toplevel, False, True)
157
158                 self._window.show_all()
159                 self._errorBanner.toplevel.hide()
160                 self._playcontrol.toplevel.hide()
161
162         def _create_button(self, icon, message):
163                 image = self._store.get_image_from_store(self._store.STORE_LOOKUP[icon])
164
165                 label = gtk.Label()
166                 label.set_text(message)
167
168                 buttonLayout = gtk.HBox(False, 5)
169                 buttonLayout.pack_start(image, False, False)
170                 buttonLayout.pack_start(label, False, True)
171                 button = gtk.Button()
172                 button.add(buttonLayout)
173
174                 return button
175
176         @misc_utils.log_exception(_moduleLogger)
177         def _on_radio_selected(self, *args):
178                 radioView = RadioView(self._player, self._store)
179                 radioView.window.set_modal(True)
180                 radioView.window.set_transient_for(self._window)
181                 radioView.window.set_default_size(*self._window.get_size())
182
183
184 class RadioView(BasicWindow):
185
186         def __init__(self, player, store):
187                 BasicWindow.__init__(self, player, store)
188
189                 self._loadingBanner = banners.GenericBanner()
190
191                 headerPath = self._store.STORE_LOOKUP["radio_header"]
192                 self._header = self._store.get_image_from_store(headerPath)
193
194                 self._radioLayout = gtk.VBox(True, 5)
195                 self._radioLayout.set_property("border-width", 5)
196                 self._radioLayout.pack_start(self._header, False, False)
197
198                 self._layout.pack_start(self._loadingBanner.toplevel, False, False)
199                 self._layout.pack_start(self._radioLayout, True, True)
200
201                 self._window.show_all()
202                 self._errorBanner.toplevel.hide()
203                 self._loadingBanner.toplevel.hide()
204
205         def _show_loading(self):
206                 animationPath = self._store.STORE_LOOKUP["loading"]
207                 animation = self._store.get_pixbuf_animation_from_store(animationPath)
208                 self._loadingBanner.show(animation, "Loading...")
209
210         def _hide_loading(self):
211                 self._loadingBanner.hide()