diff options
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | src/msd/msd_browse.py | 238 | ||||
-rw-r--r-- | src/msd/msd_main_window.py | 67 | ||||
-rw-r--r-- | src/msd/msd_upnp.py | 6 |
4 files changed, 68 insertions, 244 deletions
@@ -1 +1,2 @@ Mark Ryan <mark.d.ryan@intel.com> +Jussi Kukkonen <jussi.kukkonen@intel.com> diff --git a/src/msd/msd_browse.py b/src/msd/msd_browse.py index 1c1b087..de677d3 100644 --- a/src/msd/msd_browse.py +++ b/src/msd/msd_browse.py @@ -16,219 +16,51 @@ # 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # # Mark Ryan <mark.d.ryan@intel.com> +# Jussi Kukkonen <jussi.kukkonen@intel.com> # import pygtk pygtk.require('2.0') import gtk -import dateutil.parser -import datetime +from msd_generic_model import * from msd_sort_order import * from msd_upnp import * -class TreeNode(object): +class BrowseModel(GenericModel): + def __init__(self, root, sort_order): + super(BrowseModel, self).__init__() - filter = ["Artist", "DisplayName", "URLs", "Date", "Path", - "Type"] - buffer_size = 50 - - def __init__(self, props, parent, sort_order): - self.__props = props - self.__container = None - self.__max_items = 0 - self.__parent = parent self.__sort_order = sort_order - if self.is_container(): - self.__container = Container(props["Path"]) - try: - self.__max_items = self.__container.get_prop("ChildCount") - except Exception: - pass - self.__children = [None] * self.__max_items - - def is_container(self): - return self.__props["Type"] == "container" - - def reset_children(self): - self.__children = [None] * self.__max_items - - def get_num_children(self): - return self.__max_items - - def get_props(self): - return self.__props - - def get_parent(self): - return self.__parent - - def flush(self): - self.__flush_down() - if self.__parent: - self.__parent.__flush_up(self) - - def __flush_down(self): - i = 0; - while i < self.__max_items: - if self.__children[i]: - self.__children[i].__flush_down() - self.__children[i] = None - i = i + 1 - - def __flush_up(self, child): - i = 0; - while i < self.__max_items: - if self.__children[i]: - if child != self.__children[i]: - self.__children[i].__flush_down() - self.__children[i] = None - i = i + 1 - if self.__parent: - self.__parent.__flush_up(self) - - def get_child(self, child): - retval = None - if child < self.__max_items: - retval = self.__children[child] - if not retval: - i = child + 1 - while (i < self.__max_items and (i - child) < - TreeNode.buffer_size and not self.__children[i]): - i = i + 1 - try: - sort_descriptor = self.__sort_order.get_upnp_sort_order() - try: - result = self.__container.list_children(child, - i - child, - TreeNode.filter, - sort_descriptor) - except Exception: - result = self.__container.list_children(child, - i - child, - TreeNode.filter) - i = child - for props in result: - self.__children[i] = TreeNode(props, self, - self.__sort_order) - i = i + 1 - retval = self.__children[child] - except Exception: - pass - - return retval - -class BrowseModel(gtk.GenericTreeModel): - columns = (("DisplayName", str), ("Artist", str), ("Date", str), - ("Type",str), ("Path", str), ("URLs", str)) - - def __init__(self, root): - gtk.GenericTreeModel.__init__(self) - self.__root = root - def flush(self): - self.__root.flush() - - def on_get_flags(self): - return gtk.TREE_MODEL_LIST_ONLY | gtk.TREE_MODEL_ITERS_PERSIST - - def on_get_n_columns(self): - return len(BrowseModel.columns) - - def on_get_column_type(self, n): - return BrowseModel.columns[n][1] - - def __get_num_of_children(self): - num = self.__root.get_num_children() - if self.__root.get_parent(): - num = num + 1 - return num - - def on_get_iter(self, path): - if path[0] >= self.__get_num_of_children(): - raise ValueError("Invalid Path") - return path[0] - - def on_get_path(self, rowref): - return (rowref,) - - def adjusted_on_get_value(self, rowref, col): - retval = None - key = BrowseModel.columns[col][0] - node = self.__root.get_child(rowref) - props = node.get_props() - if key in props: - data = props[key] - if node.is_container(): - if col == 0: - retval = data - else: - if col == 2: - date = dateutil.parser.parse(data) - retval = date.strftime("%x") - elif col == 3: - data = data[0].upper() + data[1:] - period = data.find('.') - if period >=0: - retval = data[:period] - else: - retval = data - elif col == 5: - retval = data[0] - else: - retval = data - elif not node.is_container(): - if col == 1: - retval = "Unknown" - elif col == 2: - retval = datetime.date.today().strftime("%x") - else: - retval = "" - - return retval - - def on_get_value(self, rowref, col): - if self.__root.get_parent(): - if rowref == 0: - if col == 0: - retval = ".." - else: - retval = "" - else: - retval = self.adjusted_on_get_value(rowref - 1, col) - else: - retval = self.adjusted_on_get_value(rowref, col) - - return retval - - def on_iter_next(self, rowref): - retval = None - rowref = rowref + 1 - if rowref < self.__get_num_of_children(): - retval = rowref - - return retval - - def on_iter_children(self, rowref): - retval = 0 - if rowref: - retval = None - return retval - - def on_iter_has_child(self, rowref): - return False - - def on_iter_n_children(self, rowref): - retval = 0 - if not rowref: - retval = self.__get_num_of_children() - return retval - - def on_iter_nth_child(self, rowref, child): - retval = None - if not rowref and child < self.__get_num_of_children(): - retval = child - return retval - - def on_iter_parent(self, rowref): - return None + try: + # if this container is in a container, add ".." row + parent = root.get_prop('Parent') + if (parent != root.get_prop('Path')): + self._set_static_row(["..", + None, + None, + "Container", + parent, + None, + False]) + except: + pass + + try: + self.__child_count = self.__root.get_prop("ChildCount") + except: + pass + + self.set_request_range (0, GenericModel.max_items_per_fetch - 1) + + def __on_browse_reply (self, result): + self._on_reply(result, self.__child_count) + + def fetch_items(self, start, count): + sort_descriptor = self.__sort_order.get_upnp_sort_order() + self.__root.list_children(start, count, + GenericModel.filter, + sort_descriptor, + self.__on_browse_reply, self._on_error) diff --git a/src/msd/msd_main_window.py b/src/msd/msd_main_window.py index 43291e7..1b0e245 100644 --- a/src/msd/msd_main_window.py +++ b/src/msd/msd_main_window.py @@ -73,10 +73,8 @@ class MainWindow(object): 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 + browse_model = BrowseModel(Container(path), + self.__sort_order) self.__browse_view.set_model(browse_model) self.__browse_path = path @@ -129,23 +127,26 @@ class MainWindow(object): tv.set_model(model) def __cell_data_func(self, column, cell, model, tree_iter): - # Only search model supports set_request_range at the moment - if self.__search_view.get_model() == model: - path = model.get_path (tree_iter) - - # This could be a lot smarter: should fetch data so that - # there's always at least 1 visible_range preloaded: - # that way e.g. pressing PgDn would not show "Loading" - requested_range = model.get_request_range() - if (path[0] >= requested_range[0] and - path[0] <= requested_range[1]): - return + path = model.get_path (tree_iter) + # This could be a lot smarter: should fetch data so that + # there's always at least 1 visible_range preloaded: + # that way e.g. pressing PgDn would not show "Loading" + requested_range = model.get_request_range() + if (path[0] >= requested_range[0] and + path[0] <= requested_range[1]): + return + + if self.__notebook.get_current_page() == 0: visible_range = self.__search_view.get_visible_range() - if (visible_range): - visible_count = visible_range[1][0] - visible_range[0][0] - model.set_request_range(max(0, visible_range[0][0] - visible_count // 2), - min(len(model) - 1, visible_range[1][0] + visible_count // 2)) + else: + visible_range = self.__browse_view.get_visible_range() + + if (visible_range): + visible_count = visible_range[1][0] - visible_range[0][0] + start = visible_range[0][0] - visible_count // 2 + end = visible_range[1][0] + visible_count // 2 + model.set_request_range(max(0, start), min(len(model) - 1, end)) def __create_column(self, treeview, name, col, width, sort_by, cell_data_func=None): renderer = gtk.CellRendererText() @@ -170,7 +171,13 @@ class MainWindow(object): path = model.get_value(rowref, model.COL_PATH) url = model.get_value(rowref, model.COL_URL) - if url != "": + if (ctype == "Container"): + if self.__notebook.get_current_page() == 1: + browse_model = BrowseModel(Container(path), + self.__sort_order) + self.__browse_path = path + self.__browse_view.set_model(browse_model) + elif url != "": if ctype == "Image": self.__window.remove(self.__main_view) self.__overlay = PlayWindowImage(name, url, @@ -191,24 +198,6 @@ class MainWindow(object): 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) @@ -230,7 +219,7 @@ class MainWindow(object): 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) + treeview.connect("row-activated", self.__content_clicked) self.__browse_view = treeview; notebook.append_page(scrollwin, gtk.Label("Browse")) diff --git a/src/msd/msd_upnp.py b/src/msd/msd_upnp.py index bb81c67..63bafc2 100644 --- a/src/msd/msd_upnp.py +++ b/src/msd/msd_upnp.py @@ -47,8 +47,10 @@ class Container(MediaObject): reply_handler=on_reply, error_handler=on_error) - def list_children(self, offset, count, fltr, sort=""): - return self.__containerIF.ListChildrenEx(offset, count, fltr, sort) + def list_children(self, offset, count, fltr, sort="", on_reply=None, on_error=None): + return self.__containerIF.ListChildrenEx(offset, count, fltr, sort, + reply_handler=on_reply, + error_handler=on_error) class State(object): |