1/*
2Copyright (c) 2011 by Simon Schneegans
3
4This program is free software: you can redistribute it and/or modify it
5under the terms of the GNU General Public License as published by the Free
6Software Foundation, either version 3 of the License, or (at your option)
7any later version.
8
9This program is distributed in the hope that it will be useful, but WITHOUT
10ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12more details.
13
14You should have received a copy of the GNU General Public License along with
15this program.  If not, see <http://www.gnu.org/licenses/>.
16*/
17
18namespace GnomePie {
19
20/////////////////////////////////////////////////////////////////////
21/// An ActionGroup which contains all currently plugged-in devices,
22/// such as CD-ROM's or USB-sticks.
23/////////////////////////////////////////////////////////////////////
24
25public class DevicesGroup : ActionGroup {
26
27    /////////////////////////////////////////////////////////////////////
28    /// Used to register this type of ActionGroup. It sets the display
29    /// name for this ActionGroup, it's icon name and the string used in
30    /// the pies.conf file for this kind of ActionGroups.
31    /////////////////////////////////////////////////////////////////////
32
33    public static GroupRegistry.TypeDescription register() {
34        var description = new GroupRegistry.TypeDescription();
35        description.name = _("Group: Devices");
36        description.icon = "harddrive";
37        description.description = _("Shows a Slice for each plugged in devices, like USB-Sticks.");
38        description.id = "devices";
39        return description;
40    }
41
42    /////////////////////////////////////////////////////////////////////
43    /// Two members needed to avoid useless, frequent changes of the
44    /// stored Actions.
45    /////////////////////////////////////////////////////////////////////
46
47    private bool changing = false;
48    private bool changed_again = false;
49
50    /////////////////////////////////////////////////////////////////////
51    /// The VolumeMonitor used to check for added or removed devices.
52    /////////////////////////////////////////////////////////////////////
53
54    private GLib.VolumeMonitor monitor;
55
56    /////////////////////////////////////////////////////////////////////
57    /// C'tor, initializes all members.
58    /////////////////////////////////////////////////////////////////////
59
60    public DevicesGroup(string parent_id) {
61        GLib.Object(parent_id : parent_id);
62    }
63
64    /////////////////////////////////////////////////////////////////////
65    /// Construct block loads all currently plugged-in devices and
66    /// connects signal handlers to the VolumeMonitor.
67    /////////////////////////////////////////////////////////////////////
68
69    construct {
70        this.monitor = GLib.VolumeMonitor.get();
71
72        this.load();
73
74        // add monitor
75        this.monitor.mount_added.connect(this.reload);
76        this.monitor.mount_removed.connect(this.reload);
77    }
78
79    /////////////////////////////////////////////////////////////////////
80    /// Loads all currently plugged-in devices.
81    /////////////////////////////////////////////////////////////////////
82
83    private void load() {
84        // add root device
85        this.add_action(new UriAction(_("Root"), "harddrive", "file:///"));
86
87        // add all other devices
88        foreach(var mount in this.monitor.get_mounts()) {
89            // get icon
90            var icon = mount.get_icon();
91
92            this.add_action(new UriAction(mount.get_name(), Icon.get_icon_name(icon), mount.get_root().get_uri()));
93        }
94    }
95
96    /////////////////////////////////////////////////////////////////////
97    /// Reloads all devices. Is called when the VolumeMonitor changes.
98    /////////////////////////////////////////////////////////////////////
99
100    private void reload() {
101        // avoid too frequent changes...
102        if (!this.changing) {
103            this.changing = true;
104            Timeout.add(200, () => {
105                if (this.changed_again) {
106                    this.changed_again = false;
107                    return true;
108                }
109
110                // reload
111                message("Devices changed...");
112                this.delete_all();
113                this.load();
114
115                this.changing = false;
116                return false;
117            });
118        } else {
119            this.changed_again = true;
120        }
121    }
122}
123
124}
125