summaryrefslogtreecommitdiff
path: root/src/pies/pieManager.vala
blob: eb031d0c09a42d2353286b905391b638ad9c2c5b (plain)
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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
/* 
Copyright (c) 2011 by Simon Schneegans

This program is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
more details.

You should have received a copy of the GNU General Public License along with
this program.  If not, see <http://www.gnu.org/licenses/>. 
*/

namespace GnomePie {

/////////////////////////////////////////////////////////////////////////    
/// A static class which stores all Pies. It can be used to add, delete 
/// and open Pies.
/////////////////////////////////////////////////////////////////////////

public class PieManager : GLib.Object {

    /////////////////////////////////////////////////////////////////////
    /// A map of all Pies. It contains both, dynamic and persistent Pies.
    /// They are associated to their ID's.
    /////////////////////////////////////////////////////////////////////

    public static Gee.HashMap<string, Pie?> all_pies { get; private set; }
    
    /////////////////////////////////////////////////////////////////////
    /// Stores all global hotkeys.
    /////////////////////////////////////////////////////////////////////
    
    private static BindingManager bindings;
    
    /////////////////////////////////////////////////////////////////////
    /// True, if any pie has the current focus. If it is closing this
    /// will be false already.
    /////////////////////////////////////////////////////////////////////
    
    private static bool a_pie_is_opened = false;
    
    /////////////////////////////////////////////////////////////////////
    /// Initializes all Pies. They are loaded from the pies.conf file.
    /////////////////////////////////////////////////////////////////////
    
    public static void init() {
        all_pies = new Gee.HashMap<string, Pie?>();
        bindings = new BindingManager();
        
        // load all Pies from th pies.conf file
        Pies.load();
        
        // open the according pie if it's hotkey is pressed
        bindings.on_press.connect((id) => {
            open_pie(id);
        });
    }
    
    /////////////////////////////////////////////////////////////////////
    /// Opens the Pie with the given ID, if it exists.
    /////////////////////////////////////////////////////////////////////
    
    public static void open_pie(string id) {
        if (!a_pie_is_opened) {
            Pie? pie = all_pies[id];
            
            if (pie != null) {
                a_pie_is_opened = true;
                
                var window = new PieWindow();
                window.load_pie(pie);
                window.open();
                
                window.on_closing.connect(() => {
                    a_pie_is_opened = false;
                });
            } else {
                warning("Failed to open pie with ID \"" + id + "\": ID does not exist!");
            }
        }
    }
    
    /////////////////////////////////////////////////////////////////////
    /// Returns the hotkey which the Pie with the given ID is bound to.
    /////////////////////////////////////////////////////////////////////
    
    public static string get_accelerator_of(string id) {
        return bindings.get_accelerator_of(id);
    }
    
    /////////////////////////////////////////////////////////////////////
    /// Returns a human-readable version of the hotkey which the Pie
    /// with the given ID is bound to.
    /////////////////////////////////////////////////////////////////////
    
    public static string get_accelerator_label_of(string id) {
        return bindings.get_accelerator_label_of(id);
    }
    
    /////////////////////////////////////////////////////////////////////
    /// Returns the name of the Pie with the given ID.
    /////////////////////////////////////////////////////////////////////
    
    public static string get_name_of(string id) {
        Pie? pie = all_pies[id];
        if (pie == null) return "";
        else             return pie.name;
    }
    
    /////////////////////////////////////////////////////////////////////
    /// Creates a new Pie which is displayed in the configuration dialog
    /// and gets saved.
    /////////////////////////////////////////////////////////////////////
    
    public static Pie create_persistent_pie(string name, string icon_name, string hotkey, string? desired_id = null) {
        Pie pie = create_pie(name, icon_name, 100, 999, desired_id);

        if (hotkey != "") bindings.bind(hotkey, pie.id);
        
        create_launcher(pie.id);
        
        return pie;
    }
    
    /////////////////////////////////////////////////////////////////////
    /// Creates a new Pie which is not displayed in the configuration
    /// dialog and is not saved.
    /////////////////////////////////////////////////////////////////////
    
    public static Pie create_dynamic_pie(string name, string icon_name, string? desired_id = null) {
        return create_pie(name, icon_name, 1000, 9999, desired_id);
    }
    
    /////////////////////////////////////////////////////////////////////
    /// Adds a new Pie. Can't be accesd from outer scope. Use
    /// create_persistent_pie or create_dynamic_pie instead.
    /////////////////////////////////////////////////////////////////////
    
    private static Pie create_pie(string name, string icon_name, int min_id, int max_id, string? desired_id = null) {
         var random = new GLib.Rand();
        
        string final_id;
        
        if (desired_id == null) 
            final_id = random.int_range(min_id, max_id).to_string();
        else {
            final_id = desired_id;
            final_id.canon("0123456789", '_');
            final_id = final_id.replace("_", "");
            
            int id = int.parse(final_id);
            
            if (id < min_id || id > max_id) {
                final_id = random.int_range(min_id, max_id).to_string();
                warning("The ID for pie \"" + name + "\" should be in range %u - %u! Using \"" + final_id + "\" instead of \"" + desired_id + "\"...", min_id, max_id);
            }
        }

        if (all_pies.has_key(final_id)) {
            var tmp = final_id;
            var id_number = int.parse(final_id) + 1;
            if (id_number == max_id+1) id_number = min_id;
            final_id = id_number.to_string();
            warning("Trying to add pie \"" + name + "\": ID \"" + tmp + "\" already exists! Using \"" + final_id + "\" instead...");
            return create_pie(name, icon_name, min_id, max_id, final_id);
        }

        Pie pie = new Pie(final_id, name, icon_name);
        all_pies.set(final_id, pie);
        
        return pie;
    }
    
    /////////////////////////////////////////////////////////////////////
    /// Removes the Pie with the given ID if it exists. Additionally it
    /// unbinds it's global hotkey.
    /////////////////////////////////////////////////////////////////////
    
    public static void remove_pie(string id) {
        if (all_pies.has_key(id)) {
            all_pies[id].on_remove();
            all_pies.unset(id);
            bindings.unbind(id);
            
            if (id.length == 3)
                remove_launcher(id);
        }
        else {
            warning("Failed to remove pie with ID \"" + id + "\": ID does not exist!");
        }
    }
    
    private static void create_launcher(string id) {
        if (all_pies.has_key(id)) {
            Pie? pie = all_pies[id];
            
            string launcher_entry = 
                "#!/usr/bin/env xdg-open\n" + 
                "[Desktop Entry]\n" +
                "Name=%s\n".printf(pie.name) +
                "Exec=gnome-pie -o %s\n".printf(pie.id) +
                "Encoding=UTF-8\n" +
                "Type=Application\n" +
                "Icon=%s\n".printf(pie.icon);

            // create the launcher file
            string launcher = Paths.launchers + "/%s.desktop".printf(pie.id);
            
            try {
                FileUtils.set_contents(launcher, launcher_entry);
                FileUtils.chmod(launcher, 0755);
            } catch (Error e) {
                warning(e.message);
            }
        }
    }
    
    private static void remove_launcher(string id) {
        string launcher = Paths.launchers + "/%s.desktop".printf(id);
        if (FileUtils.test(launcher, FileTest.EXISTS)) {
            FileUtils.remove(launcher);
        }
    }
}

}