File: plugin-examples.md

package info (click to toggle)
rhythmbox 3.4.9-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 27,376 kB
  • sloc: ansic: 114,861; python: 4,941; xml: 730; javascript: 350; perl: 307; sh: 84; makefile: 43
file content (186 lines) | stat: -rw-r--r-- 7,029 bytes parent folder | download | duplicates (2)
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
Title: Rhythmbox plugin examples
Slug: plugin-examples

Some example bits of code on how to various things for Python Plugins.

# User Interface

## Adding a context menu to a source

How to add a context menu to a given browser source: implement [vfunc@BrowserSource.show_entry_popup] in the source.
```
class DuplicateSource(RB.BrowserSource):

	def __init__(self):
		RB.BrowserSource.__init__(self, name=_("Duplicates"))

                app = Gio.Application.get_default()
                action = Gio.SimpleAction(name="duplicate-mark-non-duplicate")
                action.connect("activate", self.mark_non_duplicate)
                app.add_action(action)

                # you can also do this bit with GtkBuilder xml if you like
                self.__popup = Gio.Menu()
                section = Gio.Menu()
                section.append("Mark Non-duplicate", "app.duplicate-mark-non-duplicate")
                self.__popup.append_section(None, section)

                section = Gio.Menu()
                section.append("Move to Trash", "app.clipboard-move-to-trash")
                section.append("Remove", "app.clipboard-delete")
                self.__popup.append_section(None, section)

                section = Gio.Menu()
                section.append("Properties", "app.clipboard-properties")
                self.__popup.append_section(None, section)

	def do_impl_show_entry_popup(self):
                menu = Gtk.Menu.new_from_model(self.__popup)
                menu.attach_to_widget(self, None)
                menu.popup(None, None, None, None, 3, Gtk.get_current_event_time())

GObject.type_register(DuplicateSource)
```

## Add Menu Items

Plugins can add items to menus and toolbars in specific locations by calling [method@Application.add_plugin_menu_item], passing an item ID that uniquely identifies the item being added, a [class@Gio.MenuItem] instance, and the name of a plugin menu location.  Some plugin menu locations:
 * 'view': the 'view' submenu of the app menu
 * 'tools': the 'tools' submenu of the app menu
 * 'edit': the edit menu that appears in most source toolbars
 * 'browser-popup': the popup menu for sources based on RBBrowserSource (library and friends)
 * 'display-page-add': the menu attached to the 'add' button in the source list toolbar
 * 'display-page-add-playlist': the playlist section of the display-page-add menu

You can find plugin menu locations by searching for 'rb-plugin-menu-link' in the GtkBuilder UI files defining menus and toolbars.

An example:

```
	def do_activate(self):

                app = Gio.Application.get_default()

                # create action
                action = Gio.SimpleAction(name="smart-playlist-create")
                action.connect("activate", self.generate_playlist)
                app.add_action(action)

                # add plugin menu item (note the "app." prefix here)
                item = Gio.MenuItem(label=("Create Smart Playlist"), detailed_action="app.smart-playlist-create")
                app.add_plugin_menu_item('browser-popup', 'create-smart-playlist', item)

	def do_deactivate(self):

                Gio.Application.get_default().remove_plugin_menu_item('browser-popup', 'create-smart-playlist')
```

# Exploring the music library

## How do I get a list of the user's playlists?

Playlists are stored in the display page model, the [iface@Gtk.TreeModel] in the left hand pane. Get a reference to the display page model with `(shell.props.display_page_model.props.model`. The "Playlists" header item is therefore `playlist_mode_header = [x for x in list(shell.props.display_page_model.props.model) if list(x)[2] == "Playlists"][0]`, and you can get a list of playlist TreeModelRows with `playlist_model_header.iterchildren()`, so

```
playlist_model_entries = [x for x in
   list(shell.props.display_page_model.props.model)
   if list(x)[2] == "Playlists"]
if playlist_model_entries:
    playlist_iter = playlist_model_entries[0].iterchildren()
    for playlist_item in playlist_iter:
        print "Playlist image: %s, name: %s, source: %s" % (playlist_item[1], playlist_item[2], playlist_item[3])
```

## How do I get a list of the user's podcast feeds?

You can interrogate the [class@RhythmDB] object to find out a number of things to do with the users library.
The following example will print out the users podcast feed:

```
db = shell.get_property("db")

def print_podcast_info(entry):
    """Takes a podcast entry and prints out its info"""
    name = entry.get_string(RB.RhythmDBPropType.ARTIST)
    uri = entry.get_string(RB.RhythmDBPropType.LOCATION)
    print "%s: %s" % (name, uri)

db.entry_foreach_by_type(db.entry_type_get_by_name("podcast-feed"), print_podcast_info)

```

## How do I create a new "Page Group"?

First, we need to create a new "page group" type and register it with RB.
```
page_group = RB.DisplayPageGroup(shell=shell, id='lastfm-playlist', name="Last.Fm Playlist", category=RB.DisplayPageGroupCategory.TRANSIENT)
shell.append_display_page(page_group, None)
```

Next, we can add a "source" to this new group.

```
## Dummy Source Class
class lfmbs(RB.BrowserSource):
  def __init__(self):
    RB.BrowserSource.__init__(self)

GObject.type_register(lfmbs)

## Insert the a new "source"
s1=GObject.new(lfmbs, shell=shell, entry_type=shell.db.entry_register_type("lfm"))
shell.append_display_page(s1, page_group)
```

## How do I jump to the playing song?

```
# get the library's Source
src = shell.props.library_source
# get the gtk widget that views the contents of that source
lst = src.get_entry_view()
# jump to a particular entry
lst.scroll_to_entry(entry)
```

## How do I get the list of songs in a source?

A source's songs are stored in `source.props.base_query_model`, a [iface@Gtk.TreeModel]. Each item in that model has two columns, a [struct@RhythmDBEntry] and a path. So, to print all songs in a source:

```
for treerow in source.props.base_query_model:
  entry, path = list(treerow)
  print entry
```

## How do I switch to a source?

If you've got a source, and want to switch Rhythmbox over to playing it:

```
player = shell.player.get_player()
player.stop()
shell.props.display_page_tree.select(your_source)
# start playing from the beginning
player.play()
# or, if you've got a specific RhythmDBEntry that you want to play
player.play_entry(entry)
```

## How do I get the metadata details of a song?

If you have a [struct@RhythmDBEntry] for a song, then you can get the metadata by querying the database with special properties. Access to the database is from `shell.props.db`. So, expanding the above example:

```
for treerow in source.props.base_query_model:
  entry, path = list(treerow)
  artist = entry.get_string(RB.RhythmDBPropType.ARTIST)
  album = entry.get_string(RB.RhythmDBPropType.ALBUM)
  title = entry.get_string(RB.RhythmDBPropType.TITLE)
  duration = entry.get_ulong(RB.RhythmDBPropType.DURATION)
  print "%s - %s" % (title, artist)
```

There are lots and lots of defined properties; see [enum@RhythmDBPropType].