summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rw-r--r--src/msd/msd_browse.py238
-rw-r--r--src/msd/msd_main_window.py67
-rw-r--r--src/msd/msd_upnp.py6
4 files changed, 68 insertions, 244 deletions
diff --git a/AUTHORS b/AUTHORS
index 3bd81c5..f2bb834 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -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):