Index: PACKAGERS ================================================================== --- PACKAGERS +++ PACKAGERS @@ -1,12 +1,12 @@ This is a short summary for distribution package maintainers. -For regular end-user documentation see the help/ pages. +For regular end-user documentation please see the help/ pages. -Structural changes in 2.1.5 (2015-04-xx) ----------------------------------------- +Structural changes from 2.1.5 onwards (2015-04-xx) +-------------------------------------------------- → There's a new `bin` script. It's a lightweight invocation wrapper, intended to be installed as /usr/bin/streamtuner2 now. Which hopefully avoids lengthy patches in the future. @@ -20,13 +20,13 @@ I'd still advise to use /usr/share/streamtuner2/ as main target directory though. It's not yet practical to extract into Python site-package directories. -The channel PNG files still need to reside alongside the Python -modules. Later versions may completely soak the images into the -source code (meta data section) for simpicity. +The channel PNG files have been soaked into the .py includes. +Though one could still package any static *.png alongside. +(Both will remain supported, for simplicity.) Renames ------- @@ -47,16 +47,16 @@ Removed ------- -Some plugin PNGs may have been removed already. (Embedded +Most plugin PNGs may have been removed already. (Embedded binary data may violate some distro guidelines(?), but hey, -fewer files are fewer files.) +fewer files are fewer files!) And the streamtuner2.png logo is now source-embedded instead, -the`logo.py` module provides a `logo.png` string. +the `logo.py` module provides a `logo.png` base64-string. The old `gtk2.xml` file is gone. It probably became obsolete a long while back. The gtk3.xml is instead runtime-patched to work with PyGTK/gtk2. @@ -100,21 +100,30 @@ ----------------- The new .PYZ archive bundles everything into a ZIP file. Which, given the right shebang, could just be "installed" as literal /usr/bin/streamtuner2 even. + I'm sure nobody is going to do so. But you know, it's at least a theoretical option now.. + +And this PYZ-packaging scheme is the main reason for the +restructuring, and embedded PNGs for example. (Albeit that +wasn't strictly necessary.) FPM/XPM packaging ----------------- You may have noticed (and scoffed at ;) the newer packaging method. It's now using http://fossil.include-once.org/xpm/ with the `src` filter. (That's what the meta comment blocks in the source modules were always meant for.) + +Simplifies DEB and RPM packaging, as well as PYZ generation. +(They're all workable, but decidedly rather crude packages. +So yes, proper distro packages are very much still needed.) Repo ---- Index: ahttp.py ================================================================== --- ahttp.py +++ ahttp.py @@ -75,11 +75,11 @@ __print__( dbg.HTTP, r.request.headers ); __print__( dbg.HTTP, r.headers ); # finish, clean statusbar #progress_feedback(0.9) - progress_feedback("") + #progress_feedback("") # result __print__( dbg.INFO, "Content-Length", len(r.content) ) if not content: return r Index: channels/__init__.py ================================================================== --- channels/__init__.py +++ channels/__init__.py @@ -571,6 +571,7 @@ # try to initialize superclass now, before adding to channel tabs GenericChannel.gui(self, parent) # add notebook tab tab = parent.notebook_channels.insert_page_menu(vbox, ev_label, plain_label, -1) + parent.notebook_channels.set_tab_reorderable(vbox, True) Index: channels/search.py ================================================================== --- channels/search.py +++ channels/search.py @@ -78,11 +78,12 @@ self.show_results(entries) # display "search" in "bookmarks" def show_results(self, entries): self.main.status(1.0) - self.main.channel_switch(None, "bookmarks", 0) + self.main.status("") + self.main.channel_switch(self.main.notebook_channels, "bookmarks", 0) self.main.bookmarks.set_category("search") # insert data and show self.main.channels["bookmarks"].streams["search"] = entries # we have to set it here, else .currentcat() might reset it self.main.bookmarks.load("search") @@ -91,10 +92,11 @@ def server_search(self, w): self.prepare_search() entries = [] for i,cn in enumerate([self.main.channels[c] for c in self.targets]): if cn.has_search: # "search" in cn.update_streams.func_code.co_varnames: + self.main.status("Server searching: " + cn.module) __print__(dbg.PROC, "has_search:", cn.module) try: add = cn.update_streams(cat=None, search=self.q) for row in add: row["genre"] = cn.meta["title"] + " " + row.get("genre", "") Index: config.py ================================================================== --- config.py +++ config.py @@ -139,11 +139,10 @@ self.load_favicon = 1 self.heuristic_bookmark_update = 0 self.retain_deleted = 0 self.auto_save_appstate = 1 self.theme = "" #"MountainDew" - self.channel_order = "shoutcast, xiph, internet_radio, jamendo, myoggradio, .." self.reuse_m3u = 1 self.google_homepage = 0 self.windows = platform.system()=="Windows" self.pyquery = 1 self.debug = 0 Index: gtk3.xml ================================================================== --- gtk3.xml +++ gtk3.xml @@ -788,47 +788,11 @@ True 0 - - True - False - - - True - False - 0.40999999642372131 - Tab ordering - - - False - True - 6 - 0 - - - - - True - True - - False - False - - - True - True - 1 - - - - - True - True - 1 - + True False @@ -1213,11 +1177,10 @@ True False 0.5 True True - True True 1 @@ -1980,10 +1943,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True True @@ -1996,10 +1995,16 @@ 2 1 2 + + + + + + @@ -3131,10 +3136,13 @@ True True + + True + True False Index: st2.py ================================================================== --- st2.py +++ st2.py @@ -195,11 +195,11 @@ "delete_entry": self.delete_entry, # search dialog "quicksearch_set": self.search.quicksearch_set, "search_open": self.search.menu_search, "search_go": self.search.cache_search, - "search_srv": self.search.server_search, + "search_srv": lambda *w: self.thread(lambda: self.search.server_search(None)), "search_cancel": self.search.cancel, "true": lambda w,*args: True, # win_streamedit "streamedit_open": self.streamedit.open, "streamedit_save": self.streamedit.save, @@ -384,10 +384,11 @@ # shortcut to statusbar # (hacked to work from within threads, circumvents the statusbar msg pool actually) def status(self, text="", sbar_msg=[]): + __print__(dbg.ERR, "status(", text, ")") # init sbar_cid = self.get_widget("statusbar").get_context_id("messages") # remove text while ((not text) and (type(text)==str) and len(sbar_msg)): sbar_msg.pop() @@ -395,11 +396,11 @@ # progressbar if (type(text)==float): if text >= 0.999 or text < 0.0: # completed uikit.do(lambda:self.progress.hide()) else: # show percentage - uikit.do(lambda:self.progress.show_all() or self.progress.set_fraction(text)) + uikit.do(lambda:self.progress.show() or self.progress.set_fraction(text)) if (text <= 0): # unknown state uikit.do(lambda:self.progress.pulse()) # add text elif (type(text)==str): sbar_msg.append(1) Index: uikit.py ================================================================== --- uikit.py +++ uikit.py @@ -299,12 +299,13 @@ if t == gtk.Toolbar: r[wn]["icon_size"] = int(w.get_icon_size()) r[wn]["style"] = int(w.get_style()) # gtk.Notebook if t == gtk.Notebook: - r[wn]["page"] = w.get_current_page() r[wn]["tab_pos"] = int(w.get_tab_pos()) + r[wn]["tab_order"] = [w.get_menu_label_text(w.get_nth_page(i)) for i in xrange(0, w.get_n_pages())] + r[wn]["tab_current"] = w.get_menu_label_text(w.get_nth_page(w.get_current_page())) #print(r) return r gtk_position_type_enum = [gtk.POS_LEFT, gtk.POS_RIGHT, gtk.POS_TOP, gtk.POS_BOTTOM] @@ -341,15 +342,23 @@ if method == "icon_size": w.set_icon_size(args) if method == "style": w.set_style(args) # gtk.Notebook - if method == "page": - w.set_current_page(args) if method == "tab_pos": w.set_tab_pos(r[wn]["tab_pos"]) - + if method == "tab_order": + tab_current = r[wn].get("tab_current") + for pos,ord_tabname in enumerate(args): + # compare current label list on each reordering round + for i in range(0, w.get_n_pages()): + w_tab = w.get_nth_page(i) + w_label = w.get_menu_label_text(w_tab) + if w_label == ord_tabname: + w.reorder_child(w_tab, pos) + if tab_current == ord_tabname: + w_set_current_page(pos) pass #-- Save-As dialog