* Fixing Window / App title stuff
[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 util.misc as misc_utils
10
11 import banners
12 import playcontrol
13 import presenter
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                 self._window.set_icon(self._store.get_pixbuf_from_store(self._store.STORE_LOOKUP["icon"]))
53                 self._window.connect("key-press-event", self._on_key_press)
54                 self._window.connect("window-state-event", self._on_window_state_change)
55
56         @property
57         def window(self):
58                 return self._window
59
60         def save_settings(self, config, sectionName):
61                 config.add_section(sectionName)
62                 config.set(sectionName, "fullscreen", str(self._windowInFullscreen))
63
64         def load_settings(self, config, sectionName):
65                 try:
66                         self._windowInFullscreen = config.getboolean(sectionName, "fullscreen")
67                 except ConfigParser.NoSectionError, e:
68                         _moduleLogger.info(
69                                 "Settings file %s is missing section %s" % (
70                                         constants._user_settings_,
71                                         e.section,
72                                 )
73                         )
74
75                 if self._windowInFullscreen:
76                         self._window.fullscreen()
77                 else:
78                         self._window.unfullscreen()
79
80         @misc_utils.log_exception(_moduleLogger)
81         def _on_window_state_change(self, widget, event, *args):
82                 if event.new_window_state & gtk.gdk.WINDOW_STATE_FULLSCREEN:
83                         self._windowInFullscreen = True
84                 else:
85                         self._windowInFullscreen = False
86                 self.emit("fullscreen", self._windowInFullscreen)
87
88         @misc_utils.log_exception(_moduleLogger)
89         def _on_key_press(self, widget, event, *args):
90                 RETURN_TYPES = (gtk.keysyms.Return, gtk.keysyms.ISO_Enter, gtk.keysyms.KP_Enter)
91                 isCtrl = bool(event.get_state() & gtk.gdk.CONTROL_MASK)
92                 if (
93                         event.keyval == gtk.keysyms.F6 or
94                         event.keyval in RETURN_TYPES and isCtrl
95                 ):
96                         # The "Full screen" hardware key has been pressed
97                         if self._windowInFullscreen:
98                                 self._window.unfullscreen ()
99                         else:
100                                 self._window.fullscreen ()
101                         return True
102                 elif (
103                         event.keyval in (gtk.keysyms.w, ) and
104                         event.get_state() & gtk.gdk.CONTROL_MASK
105                 ):
106                         self._window.destroy()
107                 elif (
108                         event.keyval in (gtk.keysyms.q, ) and
109                         event.get_state() & gtk.gdk.CONTROL_MASK
110                 ):
111                         self.emit("quit")
112                 elif event.keyval == gtk.keysyms.l and event.get_state() & gtk.gdk.CONTROL_MASK:
113                         with open(constants._user_logpath_, "r") as f:
114                                 logLines = f.xreadlines()
115                                 log = "".join(logLines)
116                                 self._clipboard.set_text(str(log))
117                         return True
118
119
120 class SourceSelector(BasicWindow):
121
122         def __init__(self, player, store):
123                 BasicWindow.__init__(self, player, store)
124
125                 self._radioButton = self._create_button("radio", "Radio")
126                 self._radioButton.connect("clicked", self._on_radio_selected)
127                 self._radioWrapper = gtk.VBox()
128                 self._radioWrapper.pack_start(self._radioButton, False, True)
129
130                 self._conferenceButton = self._create_button("conferences", "Conferences")
131                 #self._conferenceButton.connect("clicked", self._on_conference_selected)
132                 self._conferenceWrapper = gtk.VBox()
133                 self._conferenceWrapper.pack_start(self._conferenceButton, False, True)
134
135                 self._magazineButton = self._create_button("magazines", "Magazines")
136                 #self._magazineButton.connect("clicked", self._on_magazine_selected)
137                 self._magazineWrapper = gtk.VBox()
138                 self._magazineWrapper.pack_start(self._magazineButton, False, True)
139
140                 self._scriptureButton = self._create_button("scriptures", "Scriptures")
141                 #self._scriptureButton.connect("clicked", self._on_scripture_selected)
142                 self._scriptureWrapper = gtk.VBox()
143                 self._scriptureWrapper.pack_start(self._scriptureButton, False, True)
144
145                 self._buttonLayout = gtk.VBox(True, 5)
146                 self._buttonLayout.set_property("border-width", 5)
147                 self._buttonLayout.pack_start(self._radioWrapper, True, True)
148                 self._buttonLayout.pack_start(self._conferenceWrapper, True, True)
149                 self._buttonLayout.pack_start(self._magazineWrapper, True, True)
150                 self._buttonLayout.pack_start(self._scriptureWrapper, True, True)
151
152                 self._playcontrol = playcontrol.PlayControl(player, store)
153
154                 self._layout.pack_start(self._buttonLayout, True, True)
155                 self._layout.pack_start(self._playcontrol.toplevel, False, True)
156
157                 self._window.set_title(constants.__pretty_app_name__)
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._treeView = gtk.TreeView()
195
196                 self._presenter = presenter.StreamMiniPresenter(self._player, self._store)
197
198                 self._radioLayout = gtk.VBox(False)
199                 self._radioLayout.pack_start(self._header, False, False)
200                 self._radioLayout.pack_start(self._treeView, True, True)
201                 self._radioLayout.pack_start(self._presenter.toplevel, False, True)
202
203                 self._layout.pack_start(self._loadingBanner.toplevel, False, False)
204                 self._layout.pack_start(self._radioLayout, True, True)
205
206                 self._window.set_title("Radio")
207                 self._window.show_all()
208                 self._errorBanner.toplevel.hide()
209                 self._loadingBanner.toplevel.hide()
210
211         def _show_loading(self):
212                 animationPath = self._store.STORE_LOOKUP["loading"]
213                 animation = self._store.get_pixbuf_animation_from_store(animationPath)
214                 self._loadingBanner.show(animation, "Loading...")
215
216         def _hide_loading(self):
217                 self._loadingBanner.hide()