Internet radio browser GUI for music/video streams from various directory services.

โŒˆโŒ‹ โŽ‡ branch:  streamtuner2


Check-in [6fab0e7170]

Overview
Comment:Made channel tabs reorderable. Now kept in config/window.json as `tab_order` and current page saved as `tab_current` instead of pageno. Disabled progressbar changes for ahttp, made search_server search run in a thread so status can be shown.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 6fab0e71703f85523999aeb4cbf0db08eabd20a5
User & Date: mario on 2015-04-03 20:43:42
Other Links: manifest | tags
Context
2015-04-03
20:46
Removed Gtk `theme` configuration options. (Didn't work anymore.) -- Addendum: If anyone has been using this, please drop me a line; it could become a plugin now.. check-in: ad852f14fe user: mario tags: trunk
20:43
Made channel tabs reorderable. Now kept in config/window.json as `tab_order` and current page saved as `tab_current` instead of pageno. Disabled progressbar changes for ahttp, made search_server search run in a thread so status can be shown. check-in: 6fab0e7170 user: mario tags: trunk
17:37
Removed doubled radio button grouping in GtkBuilder file for search_dialog. check-in: 5377cdecb5 user: mario tags: trunk
Changes

Modified PACKAGERS from [3311a1cdd3] to [aedd6e0017].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

This is a short summary for distribution package maintainers.
For regular end-user documentation see the help/ pages.


Structural changes in 2.1.5 (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.

 โ†’ The previous `st2.py` still exists, but is now supposed to
   reside in `/usr/share/streamtuner2/st2.py` along with all
   other modules.

 โ†’ Theoretically it's now possible to change the target path
   even (just edit `bin`).

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.


Renames
-------

 ยท bookmarks, configdialog, streamedit were extracted into
   channels/ - which is why the main module got lighter.


|


|
|

















|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

This is a short summary for distribution package maintainers.
For regular end-user documentation please see the help/ pages.


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.

 โ†’ The previous `st2.py` still exists, but is now supposed to
   reside in `/usr/share/streamtuner2/st2.py` along with all
   other modules.

 โ†’ Theoretically it's now possible to change the target path
   even (just edit `bin`).

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 have been soaked into the .py includes.
Though one could still package any static *.png alongside.
(Both will remain supported, for simplicity.)


Renames
-------

 ยท bookmarks, configdialog, streamedit were extracted into
   channels/ - which is why the main module got lighter.
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

 โ†’ and `logo.png` is the pixmap/app icon


Removed
-------

Some plugin PNGs may have been removed already. (Embedded
binary data may violate some distro guidelines(?), but hey,
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 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.


Dependencies







|

|


|







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

 โ†’ and `logo.png` is the pixmap/app icon


Removed
-------

Most plugin PNGs may have been removed already. (Embedded
binary data may violate some distro guidelines(?), but hey,
fewer files are fewer files!)

And the streamtuner2.png logo is now source-embedded instead,
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.


Dependencies
98
99
100
101
102
103
104

105
106




107
108
109
110
111
112
113
114
115




116
117
118
119
120
121
122

Lazy installation
-----------------

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..






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.)






Repo
----

The source code is hosted in a Fossil repo.








>


>
>
>
>









>
>
>
>







98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

Lazy installation
-----------------

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
----

The source code is hosted in a Fossil repo.

Modified ahttp.py from [20908d5cb6] to [eff6de2cac].

73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
        r = session.get(url, params=params, headers=headers, timeout=9.75)

    __print__( dbg.HTTP, r.request.headers );
    __print__( dbg.HTTP, r.headers );
            
    # finish, clean statusbar
    #progress_feedback(0.9)
    progress_feedback("")

    # result
    __print__( dbg.INFO, "Content-Length", len(r.content) )
    if not content:
        return r
    elif binary:
        return r.content







|







73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
        r = session.get(url, params=params, headers=headers, timeout=9.75)

    __print__( dbg.HTTP, r.request.headers );
    __print__( dbg.HTTP, r.headers );
            
    # finish, clean statusbar
    #progress_feedback(0.9)
    #progress_feedback("")

    # result
    __print__( dbg.INFO, "Content-Length", len(r.content) )
    if not content:
        return r
    elif binary:
        return r.content

Modified channels/__init__.py from [af174af9c9] to [98bda28d4c].

569
570
571
572
573
574
575

576


        # 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)









>

569
570
571
572
573
574
575
576
577


        # 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)

Modified channels/search.py from [0a5546848e] to [8e5b1ccd0f].

76
77
78
79
80
81
82

83
84
85
86
87
88
89
90
91
92
93
94
95

96
97
98
99
100
101
102
                            row["genre"] = c + " " + row.get("genre", "")
                            entries.append(row)
        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.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")
        
        
    # live search on directory server homepages
    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:

                __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", "")
                    entries += add
                except:







>
|












>







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
                            row["genre"] = c + " " + row.get("genre", "")
                            entries.append(row)
        self.show_results(entries)

    # display "search" in "bookmarks"
    def show_results(self, entries):
        self.main.status(1.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")
        
        
    # live search on directory server homepages
    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", "")
                    entries += add
                except:

Modified config.py from [31dd5cfc2a] to [2f8e9d09d8].

137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
        self.show_bookmarks = 1
        self.show_favicons = 1
        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

        







<







137
138
139
140
141
142
143

144
145
146
147
148
149
150
        self.show_bookmarks = 1
        self.show_favicons = 1
        self.load_favicon = 1
        self.heuristic_bookmark_update = 0
        self.retain_deleted = 0
        self.auto_save_appstate = 1
        self.theme = "" #"MountainDew"

        self.reuse_m3u = 1
        self.google_homepage = 0
        self.windows = platform.system()=="Windows"
        self.pyquery = 1
        self.debug = 0

        

Modified gtk3.xml from [3744082ff5] to [803063bf6c].

786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
                              <packing>
                                <property name="expand">True</property>
                                <property name="fill">True</property>
                                <property name="position">0</property>
                              </packing>
                            </child>
                            <child>
                              <object class="GtkHBox" id="hbox6">
                                <property name="visible">True</property>
                                <property name="can_focus">False</property>
                                <child>
                                  <object class="GtkLabel" id="label27">
                                    <property name="visible">True</property>
                                    <property name="can_focus">False</property>
                                    <property name="xalign">0.40999999642372131</property>
                                    <property name="label" translatable="yes">Tab ordering</property>
                                  </object>
                                  <packing>
                                    <property name="expand">False</property>
                                    <property name="fill">True</property>
                                    <property name="padding">6</property>
                                    <property name="position">0</property>
                                  </packing>
                                </child>
                                <child>
                                  <object class="GtkEntry" id="config_channel_order">
                                    <property name="visible">True</property>
                                    <property name="can_focus">True</property>
                                    <property name="invisible_char">โ—</property>
                                    <property name="primary_icon_activatable">False</property>
                                    <property name="secondary_icon_activatable">False</property>
                                  </object>
                                  <packing>
                                    <property name="expand">True</property>
                                    <property name="fill">True</property>
                                    <property name="position">1</property>
                                  </packing>
                                </child>
                              </object>
                              <packing>
                                <property name="expand">True</property>
                                <property name="fill">True</property>
                                <property name="position">1</property>
                              </packing>
                            </child>
                            <child>
                              <object class="GtkHSeparator" id="hseparator1">
                                <property name="visible">True</property>
                                <property name="can_focus">False</property>
                              </object>
                              <packing>







<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







786
787
788
789
790
791
792



793

































794
795
796
797
798
799
800
                              <packing>
                                <property name="expand">True</property>
                                <property name="fill">True</property>
                                <property name="position">0</property>
                              </packing>
                            </child>
                            <child>



                              <placeholder/>

































                            </child>
                            <child>
                              <object class="GtkHSeparator" id="hseparator1">
                                <property name="visible">True</property>
                                <property name="can_focus">False</property>
                              </object>
                              <packing>
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
                    <property name="label" translatable="yes">all channels</property>
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="receives_default">False</property>
                    <property name="xalign">0.5</property>
                    <property name="active">True</property>
                    <property name="draw_indicator">True</property>
                    <!--property name="group">search_dialog_current</property-->
                  </object>
                  <packing>
                    <property name="expand">True</property>
                    <property name="fill">True</property>
                    <property name="position">1</property>
                  </packing>
                </child>







<







1175
1176
1177
1178
1179
1180
1181

1182
1183
1184
1185
1186
1187
1188
                    <property name="label" translatable="yes">all channels</property>
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="receives_default">False</property>
                    <property name="xalign">0.5</property>
                    <property name="active">True</property>
                    <property name="draw_indicator">True</property>

                  </object>
                  <packing>
                    <property name="expand">True</property>
                    <property name="fill">True</property>
                    <property name="position">1</property>
                  </packing>
                </child>
1978
1979
1980
1981
1982
1983
1984




































1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000






2001
2002
2003
2004
2005
2006
2007
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>




































            <child>
              <object class="GtkEntry" id="timer_value">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="invisible_char">โ—</property>
                <property name="text" translatable="yes">Fri,Sat 20:00-21:00</property>
                <property name="primary_icon_activatable">False</property>
                <property name="secondary_icon_activatable">False</property>
              </object>
              <packing>
                <property name="left_attach">1</property>
                <property name="right_attach">2</property>
                <property name="top_attach">1</property>
                <property name="bottom_attach">2</property>
              </packing>
            </child>






            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
















>
>
>
>
>
>







1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <object class="GtkEntry" id="timer_value">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="invisible_char">โ—</property>
                <property name="text" translatable="yes">Fri,Sat 20:00-21:00</property>
                <property name="primary_icon_activatable">False</property>
                <property name="secondary_icon_activatable">False</property>
              </object>
              <packing>
                <property name="left_attach">1</property>
                <property name="right_attach">2</property>
                <property name="top_attach">1</property>
                <property name="bottom_attach">2</property>
              </packing>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
3129
3130
3131
3132
3133
3134
3135



3136
3137
3138
3139
3140
3141
3142
                  </object>
                  <packing>
                    <property name="resize">True</property>
                    <property name="shrink">True</property>
                  </packing>
                </child>
              </object>



            </child>
            <child type="tab">
              <object class="GtkHBox" id="c_bookmarks">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <signal name="popup-menu" handler="on_homepage_channel_clicked" swapped="no"/>
                <child>







>
>
>







3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
                  </object>
                  <packing>
                    <property name="resize">True</property>
                    <property name="shrink">True</property>
                  </packing>
                </child>
              </object>
              <packing>
                <property name="reorderable">True</property>
              </packing>
            </child>
            <child type="tab">
              <object class="GtkHBox" id="c_bookmarks">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <signal name="popup-menu" handler="on_homepage_channel_clicked" swapped="no"/>
                <child>

Modified st2.py from [1e504cb8ac] to [5fd894f832].

193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
           # "menu_bugreport": lambda w: BugReport(),
            "menu_copy": self.menu_copy,
            "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_cancel": self.search.cancel,
            "true": lambda w,*args: True,
            # win_streamedit
            "streamedit_open": self.streamedit.open,
            "streamedit_save": self.streamedit.save,
            "streamedit_new": self.streamedit.new,
            "streamedit_cancel": self.streamedit.cancel,







|







193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
           # "menu_bugreport": lambda w: BugReport(),
            "menu_copy": self.menu_copy,
            "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": 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,
            "streamedit_new": self.streamedit.new,
            "streamedit_cancel": self.streamedit.cancel,
382
383
384
385
386
387
388

389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407




    # shortcut to statusbar
    # (hacked to work from within threads, circumvents the statusbar msg pool actually)
    def status(self, text="", sbar_msg=[]):

        # 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()
            uikit.do(lambda:self.statusbar.pop(sbar_cid))
        # 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))
                if (text <= 0):  # unknown state
                    uikit.do(lambda:self.progress.pulse())
        # add text
        elif (type(text)==str):
            sbar_msg.append(1)
            uikit.do(lambda:self.statusbar.push(sbar_cid, text))
        pass







>











|







382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408




    # 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()
            uikit.do(lambda:self.statusbar.pop(sbar_cid))
        # 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() 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)
            uikit.do(lambda:self.statusbar.push(sbar_cid, text))
        pass

Modified uikit.py from [efa7474e76] to [2c0d4193cf].

297
298
299
300
301
302
303
304
305


306
307
308
309
310
311
312
                    r[wn]["row:selected"] = paths[0]
            # gtk.Toolbar
            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())


        #print(r)
        return r

    gtk_position_type_enum = [gtk.POS_LEFT, gtk.POS_RIGHT, gtk.POS_TOP, gtk.POS_BOTTOM]


    #-- restore window and widget properties







<

>
>







297
298
299
300
301
302
303

304
305
306
307
308
309
310
311
312
313
                    r[wn]["row:selected"] = paths[0]
            # gtk.Toolbar
            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]["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]


    #-- restore window and widget properties
339
340
341
342
343
344
345
346
347
348
349
350








351
352
353
354
355
356
357
                    w.get_selection().select_path(tuple(args))
                # gtk.Toolbar
                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"])









        pass



    #-- Save-As dialog
    #
    @staticmethod







|
|
|
|
|
>
>
>
>
>
>
>
>







340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
                    w.get_selection().select_path(tuple(args))
                # gtk.Toolbar
                if method == "icon_size":
                    w.set_icon_size(args)
                if method == "style":
                    w.set_style(args)
                # gtk.Notebook
                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
    #
    @staticmethod