Index: channels/__init__.py ================================================================== --- channels/__init__.py +++ channels/__init__.py @@ -142,13 +142,14 @@ # save reference to main window/glade API self.parent = parent self.gtk_list = parent.get_widget(self.module+"_list") self.gtk_cat = parent.get_widget(self.module+"_cat") - # category tree + # last category, and prepare genre tree + self.current = conf.state(self.module).get("current") self.display_categories() - + # update column names for field,title in list(self.titles.items()): self.update_datamap(field, title=title) # prepare stream list @@ -170,10 +171,40 @@ else: log.INFO("status():", *v) #--------------------- streams/model data accesss --------------------------- + + # traverse category TreeModel to set current, expand parent nodes + def select_current(self, name): + log.UI("reselect .current category in treelist:", name) + model = self.gtk_cat.get_model() + iter = model.get_iter_first() + self.iter_cats(name, model, iter) + + # iterate over children to find current category + def iter_cats(self, name, model, iter): + while iter: + val = model.get_value(iter, 0) + if val == name: + #log.UI("FOUND CATEGORY", name, "→select") + self.gtk_cat.get_selection().select_iter(iter) + self.gtk_cat.set_cursor(model.get_path(iter)) + return True + if model.iter_has_child(iter): + found = self.iter_cats(name, model, model.iter_children(iter)) + if found: + self.gtk_cat.expand_row(model.get_path(iter), 0) + return True + iter = model.iter_next(iter) + + # selected category + def currentcat(self): + (model, iter) = self.gtk_cat.get_selection().get_selected() + if (type(iter) == gtk.TreeIter): + self.current = model.get_value(iter, 0) + return self.current # Get list of stations in current category def stations(self): return self.streams.get(self.current, []) @@ -282,20 +313,19 @@ self.status("Category parsed empty.") self.streams[category] = self.nothing_found log.INFO("Oooops, parser returned nothing for category " + category) # Update treeview/model (if category is still selected) - log.UI("load columns datamap streams") if self.current == category: + log.UI("load() → uikit.columns({}.streams[{}])".format(self.module, category), [inspect.stack()[x][3] for x in range(1,5)]) uikit.do(uikit.columns, self.gtk_list, self.datamap, self.prepare(self.streams[category])) if y: uikit.do(self.gtk_list.scroll_to_point, 0, y + 1) # scroll to previous position, +1 px, because # somehow Gtk.TreeView else stumbles over itself when scrolling to the same position the 2nd time - # set pointer - self.status("") - self.status(1.0) + # unset statusbar + self.status() # store current streams data def save(self): conf.save("cache/" + self.module, self.streams, gz=1) @@ -402,25 +432,21 @@ self.categories = ["empty"] self.display_categories() # Select first category if not self.current: - self.current = self.str_from_struct(self.categories) or None log.STAT(self.module, "→ first_show(); use first category as current =", self.current) - self.shown = 0, + self.current = self.str_from_struct(self.categories) or None + + # put selection/cursor on last position + if True: + uikit.do(self.select_current, self.current) + #uikit.do(lambda:self.gtk_list.get_selection().select_path(self.shown)) # Show current category in any case log.UI(self.module, "→ first_show(); station list → load(", self.current, ")") self.load(self.current) - - # put selection/cursor on last position - if True:#self.shown != None: - log.STAT(self.module+".first_show()", "select last known category treelist position =", self.shown) - try: - uikit.do(lambda:self.gtk_list.get_selection().select_path(self.shown)) - except: - pass # Invoke only once self.shown = 55555 @@ -448,30 +474,26 @@ uikit.do(self.display_categories) # insert content into gtk category list def display_categories(self): - log.UI(self.module+".display_categories()", "mk tree, expand_all, select first path, currentcat") + log.UI("{}.display_categories(), uikit.tree(#{}), expand_all(#<20), select_current(={})".format(self.module, len(self.categories), self.current)) # rebuild gtk.TreeView uikit.tree(self.gtk_cat, self.categories, title="Category", icon=gtk.STOCK_OPEN) # if it's a short list of categories, there's probably subfolders if len(self.categories) < 20: self.gtk_cat.expand_all() - # select any first element - self.gtk_cat.get_selection().select_path("0") #set_cursor - self.currentcat() + # Select last .current or any first element + if self.current: + self.select_current(self.current) + #self.currentcat() + #else: self.gtk_cat.get_selection().select_path("0") #set_cursor - # selected category - def currentcat(self): - (model, iter) = self.gtk_cat.get_selection().get_selected() - if (type(iter) == gtk.TreeIter): - self.current = model.get_value(iter, 0) - return self.current # Insert/append new station rows - used by importing/drag'n'drop plugins def insert_rows(self, rows, y=None): streams = self.streams[self.current] Index: channels/links.py ================================================================== --- channels/links.py +++ channels/links.py @@ -103,6 +103,6 @@ # add to bookmarks parent.bookmarks.streams[self.module] = self.streams # redraw category - parent.bookmarks.reload_if_current(self.module) +# parent.bookmarks.reload_if_current(self.module) Index: config.py ================================================================== --- config.py +++ config.py @@ -252,10 +252,19 @@ self.play["audio/mpeg"] = self.play["audio/mp3"] del self.play["audio/mp3"] if self.tmp == "/tmp": self.tmp = "/tmp/streamtuner2" + + # Shortcut to `state.json` loading (currently selected categories etc.) + def state(self, module=None, d={}): + if not d: + d.update(conf.load("state")) + if module: + return d.get(module, {}) + return d + # check for existing filename in directory list def find_in_dirs(self, dirs, file): for d in dirs: if os.path.exists(d+"/"+file): Index: st2.py ================================================================== --- st2.py +++ st2.py @@ -236,11 +236,11 @@ log.UI("main.channel_switch() :=", self.current_channel) self.update_title() # if first selected, load current category # (run in thread, to make it look speedy on first startup) self.thread( - self.channel().first_show + self.channel().first_show ) # Invoked from the menu instead, uses module name instead of numeric tab id def channel_switch_by_name(self, name): self.notebook_channels.set_current_page(self.channel_names.index(name)) @@ -427,21 +427,20 @@ log.INIT("load_plugin_channels: error initializing:", name, ", exception:") traceback.print_exc() # load application state (widget sizes, selections, etc.) def init_app_state(self): - winlayout = conf.load("window") if (winlayout): try: uikit.app_restore(self, winlayout) except Exception as e: log.APPSTATE_RESTORE(e) # may fail for disabled/reordered plugin channels - winstate = conf.load("state") - if (winstate): - for id,prev in winstate.items(): - try: self.channels[id].current = prev["current"] - except Exception as e: log.APPSTATE_RESTORE(e) + #winstate = conf.state() # now handled by channels.gui() already + #if (winstate): + # for id,prev in winstate.items(): + # try: self.channels[id].current = prev["current"] + # except Exception as e: log.APPSTATE_RESTORE(e) # store window/widget states (sizes, selections, etc.) def save_app_state(self, widget): # gtk widget states widgetnames = ["win_streamtuner2", "toolbar", "notebook_channels", ] \ Index: uikit.py ================================================================== --- uikit.py +++ uikit.py @@ -331,12 +331,12 @@ if method == "rows:expanded": w.collapse_all() for i in args: w.expand_row(treepath(i), False) # - selected - if method == "row:selected": - w.get_selection().select_path(treepath(args)) + # if method == "row:selected": + # w.get_selection().select_path(treepath(args)) # gtk.Toolbar if method == "icon_size": w.set_icon_size(args) if method == "style": w.set_style(args)