diff options
Diffstat (limited to 'src/msd/msd_main_window.py')
-rw-r--r-- | src/msd/msd_main_window.py | 320 |
1 files changed, 320 insertions, 0 deletions
diff --git a/src/msd/msd_main_window.py b/src/msd/msd_main_window.py new file mode 100644 index 0000000..62c3b29 --- /dev/null +++ b/src/msd/msd_main_window.py @@ -0,0 +1,320 @@ +# media-service-demo +# +# Copyright (C) 2012 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU Lesser General Public License, +# version 2.1, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License +# for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# +# Mark Ryan <mark.d.ryan@intel.com> +# + +import pygtk +pygtk.require('2.0') +import gtk +import glib +import dbus +import dbus.service +import dbus.mainloop.glib +import os + +from msd_utils import * +from msd_upnp import * +from msd_search import * +from msd_browse import * +from msd_player import * + +class MainWindow(object): + + container_padding = 2 + + def delete_event(self, widget, event, data=None): + return False + + def destroy(self, widget, data=None): + if self.__overlay: + self.__overlay.cancel_playback() + gtk.main_quit() + + def __append_server_list_row(self, list_store, key, value): + name, image = value + if image: + image = image.get_pixbuf() + image = image.scale_simple(32, 32, gtk.gdk.INTERP_BILINEAR) + return list_store.append([image, name, key]) + + def __create_server_list_store(self): + list_store = gtk.ListStore(gtk.gdk.Pixbuf, str, str) + for key, value in self.__state.get_server_list().iteritems(): + self.__append_server_list_row(list_store, key, value) + return list_store + + def __change_server(self, page, sel): + model, row = sel.get_selected() + if row != None: + path = model.get_value(row, 2) + if page == 0: + if self.__search_path != path: + search_model = SearchModel(Container(path), + self.__search_entry.get_text(), + self.__images.get_active(), + self.__videos.get_active(), + self.__music.get_active(), + self.__sort_order) + self.__search_view.set_model(search_model) + self.__search_path = path + elif self.__browse_path != path: + props = { "Path" : path, "Type": "container" } + self.__browse_tree = TreeNode(props, None, self.__sort_order) + browse_model = BrowseModel(self.__browse_tree) + self.__browse_node = self.__browse_tree + self.__browse_view.set_model(browse_model) + self.__browse_path = path + + def __server_selected(self, sel): + page = self.__notebook.get_current_page() + self.__change_server(page, sel) + + def __select_server(self, rowref): + selection = self.__server_view.get_selection() + if selection.count_selected_rows() == 0: + liststore = self.__server_view.get_model() + selection = self.__server_view.get_selection() + selection.select_iter(rowref) + self.__server_view.set_cursor(liststore.get_path(rowref)) + + def __create_server_list(self, table): + liststore = self.__create_server_list_store() + treeview = gtk.TreeView(liststore) + treeview.set_headers_visible(True) + + column = gtk.TreeViewColumn() + column.set_title("Servers") + renderer = gtk.CellRendererPixbuf() + column.pack_start(renderer, expand=False) + column.add_attribute(renderer, 'pixbuf', 0) + renderer = gtk.CellRendererText() + column.pack_start(renderer, expand=False) + column.add_attribute(renderer, 'text', 1) + treeview.append_column(column) + + treeview.set_headers_clickable(True) + + treeview.get_selection().connect("changed", self.__server_selected) + + scrollwin = gtk.ScrolledWindow() + scrollwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC); + scrollwin.add(treeview) + table.attach(scrollwin, left_attach=0, right_attach=1, + top_attach=0, bottom_attach=1) + self.__server_view = treeview; + + def __column_clicked(self, column, sort_by): + self.__sort_order.set_sort_by(sort_by) + tv = column.get_tree_view() + model = tv.get_model() + model.flush() + tv.set_model(None) + tv.set_model(model) + + def __create_column(self, treeview, name, col, width, sort_by): + renderer = gtk.CellRendererText() + column = gtk.TreeViewColumn(name, renderer) + column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) + column.set_fixed_width(width) + column.add_attribute(renderer, 'text', col) + column.connect("clicked", self.__column_clicked, sort_by) + treeview.append_column(column) + + def __close_overlay(self): + self.__window.remove(self.__overlay.get_container()) + self.__window.add(self.__main_view) + self.__overlay = None + + def __content_clicked(self, treeview, path, col): + model = treeview.get_model() + rowref = model.get_iter(path) + name = model.get_value(rowref, 0) + ctype = model.get_value(rowref, 3) + path = model.get_value(rowref, 4) + url = model.get_value(rowref, 5) + + if url != "": + if ctype == "Image": + self.__window.remove(self.__main_view) + self.__overlay = PlayWindowImage(name, url, + self.__close_overlay) + self.__window.add(self.__overlay.get_container()) + elif ctype == "Video": + self.__window.remove(self.__main_view) + self.__overlay = PlayWindowVideo(name, url, + self.__close_overlay) + self.__window.add(self.__overlay.get_container()) + elif ctype == "Audio": + try: + album_art_url = MediaObject(path).get_prop("AlbumArtURL") + except Exception: + album_art_url = None + self.__window.remove(self.__main_view) + self.__overlay = PlayWindowAudio(name, url, album_art_url, + self.__close_overlay) + self.__window.add(self.__overlay.get_container()) + + def __browse_content_clicked(self, treeview, path, col): + if self.__browse_node != self.__browse_tree and path[0] == 0: + self.__browse_node.reset_children() + self.__browse_node = self.__browse_node.get_parent() + browse_model = BrowseModel(self.__browse_node) + self.__browse_view.set_model(browse_model) + else: + child = path[0] + if self.__browse_node != self.__browse_tree: + child = child - 1 + node = self.__browse_node.get_child(child) + if node.is_container(): + self.__browse_node = node + browse_model = BrowseModel(self.__browse_node) + self.__browse_view.set_model(browse_model) + else: + self.__content_clicked(treeview, path, col) + + def __create_common_list(self, store): + treeview = gtk.TreeView(store) + treeview.set_headers_visible(True) + treeview.set_fixed_height_mode(True) + + self.__create_column(treeview, "Title", 0, 300, "DisplayName") + self.__create_column(treeview, "Date", 2, 100, "Date") + self.__create_column(treeview, "Type", 3, 75, "Type") + self.__create_column(treeview, "Author", 1, 100, "Artist") + + treeview.set_headers_clickable(True) + treeview.set_rules_hint(True) + + scrollwin = gtk.ScrolledWindow() + scrollwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC); + scrollwin.add(treeview) + return (scrollwin, treeview) + + def __create_browse_view(self, notebook): + tree_store = gtk.TreeStore(str, str, str, str) + scrollwin, treeview = self.__create_common_list(tree_store) + treeview.connect("row-activated", self.__browse_content_clicked) + self.__browse_view = treeview; + notebook.append_page(scrollwin, gtk.Label("Browse")) + + def __create_search_list(self, container): + list_store = gtk.ListStore(str, str, str, str) + scrollwin, treeview = self.__create_common_list(list_store) + container.pack_start(scrollwin, True, True, 0) + treeview.connect("row-activated", self.__content_clicked) + self.__search_view = treeview; + + def __search_criteria_changed(self, obj): + self.__search_path = None + self.__server_selected(self.__server_view.get_selection()) + + def __create_check_box(self, title, container): + cb = gtk.CheckButton(title) + cb.set_active(True) + cb.connect("toggled", self.__search_criteria_changed) + container.pack_start(cb, True, True, MainWindow.container_padding) + return cb + + def __create_search_controls(self, container): + label = gtk.Label("Search: ") + self.__search_entry = gtk.Entry() + self.__search_entry.set_text("") + self.__search_entry.connect("activate", self.__search_criteria_changed) + container.pack_start(label, True, True, MainWindow.container_padding) + container.pack_start(self.__search_entry, True, True, + MainWindow.container_padding) + self.__music = self.__create_check_box("Music", container) + self.__images = self.__create_check_box("Images", container) + self.__videos = self.__create_check_box("Video", container) + + def __create_search_view(self, notebook): + vbox = gtk.VBox(False, 0) + hbox = gtk.HBox(True, 0) + self.__create_search_list(vbox) + self.__create_search_controls(hbox) + vbox.pack_start(hbox, False, True, MainWindow.container_padding) + notebook.append_page(vbox, gtk.Label("Search")) + + def __page_changed(self, notebook, page, page_number): + sel = self.__server_view.get_selection() + if sel: + self.__change_server(page_number, sel) + + def __create_notebook(self, table): + notebook = gtk.Notebook() + self.__create_search_view(notebook) + self.__create_browse_view(notebook) + notebook.connect("switch-page", self.__page_changed) + table.attach(notebook, left_attach=1, right_attach=4, + top_attach=0, bottom_attach=1) + self.__notebook = notebook + + def __create_widgets(self, window): + table = gtk.Table(rows=1, columns=4, homogeneous=True) + self.__create_server_list(table) + self.__create_notebook(table) + window.add(table) + self.__main_view = table + + def __create_window(self): + window = gtk.Window(gtk.WINDOW_TOPLEVEL) + window.set_title("Media Service Demo") + window.set_resizable(True) + window.set_default_size(640, 480) + window.connect("delete_event", self.delete_event) + window.connect("destroy", self.destroy) + self.__create_widgets(window) + window.show_all() + self.__window = window + + def __found_server(self, path): + liststore = self.__server_view.get_model() + value = self.__state.get_server_list()[path] + rowref = self.__append_server_list_row(liststore, path, value) + self.__select_server(rowref) + + def __lost_server(self, path): + liststore = self.__server_view.get_model() + rowref = liststore.get_iter_first() + while rowref and liststore.get_value(rowref, 2) != path: + rowref = liststore.iter_next(rowref) + if rowref: + path_to_delete = liststore.get_path(rowref) + selection = self.__server_view.get_selection() + selected_path = liststore.get_path(selection.get_selected()[1]) + liststore.remove(rowref) + if path_to_delete == selected_path: + rowref = liststore.get_iter_first() + if rowref: + selection.select_iter(rowref) + self.__server_view.set_cursor(liststore.get_path(rowref)) + + def __init__(self, state): + self.__search_path = None + self.__browse_path = None + self.__state = state + self.__state.set_lost_server_cb(self.__lost_server) + self.__state.set_found_server_cb(self.__found_server) + self.__create_window() + self.__overlay = None + self.__sort_order = SortOrder() + + liststore = self.__server_view.get_model() + rowref = liststore.get_iter_first() + if rowref: + self.__select_server(rowref) |