~noskcaj/ubuntu/wily/gnome-weather/3.16

« back to all changes in this revision

Viewing changes to src/window.js

  • Committer: Package Import Robot
  • Author(s): Jackson Doak
  • Date: 2014-12-20 18:32:08 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20141220183208-e2895ntfyv23x1m3
Tags: 3.14.1-0ubuntu1
* New upstream release.
* Fix a typo in watch file
* Change binary to arch: all
* Update d/copyright for this release

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// -*- Mode: js; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*-
2
 
//
3
 
// Copyright (c) 2012 Giovanni Campagna <scampa.giovanni@gmail.com>
4
 
//
5
 
// Gnome Weather is free software; you can redistribute it and/or modify
6
 
// it under the terms of the GNU General Public License as published by the
7
 
// Free Software Foundation; either version 2 of the License, or (at your
8
 
// option) any later version.
9
 
//
10
 
// Gnome Weather is distributed in the hope that it will be useful, but
11
 
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 
// or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13
 
// for more details.
14
 
//
15
 
// You should have received a copy of the GNU General Public License along
16
 
// with Gnome Weather; if not, write to the Free Software Foundation,
17
 
// Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 
 
19
 
const GLib = imports.gi.GLib;
20
 
const GObject = imports.gi.GObject;
21
 
const Gtk = imports.gi.Gtk;
22
 
const GWeather = imports.gi.GWeather;
23
 
const Lang = imports.lang;
24
 
 
25
 
const City = imports.city;
26
 
const Params = imports.params;
27
 
const World = imports.world;
28
 
const Util = imports.util;
29
 
 
30
 
const Gettext = imports.gettext;
31
 
const Tweener = imports.tweener.tweener;
32
 
 
33
 
const Page = {
34
 
    WORLD: 0,
35
 
    CITY: 1
36
 
};
37
 
 
38
 
const NewLocationController = new Lang.Class({
39
 
    Name: 'NewLocationController',
40
 
 
41
 
    _init: function(parentWindow, worldModel) {
42
 
        this._worldModel = worldModel;
43
 
 
44
 
        let builder = Util.loadUI('/org/gnome/Weather/Application/new-location-dialog.ui',
45
 
                                  { 'parent-window': parentWindow });
46
 
 
47
 
        let dialog = builder.get_object('location-dialog');
48
 
        let entry = builder.get_object('location-entry');
49
 
 
50
 
        dialog.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL);
51
 
        dialog.add_button(Gtk.STOCK_ADD, Gtk.ResponseType.OK);
52
 
        dialog.set_default_response(Gtk.ResponseType.OK);
53
 
 
54
 
        dialog.connect('response', Lang.bind(this, this._onResponse));
55
 
        entry.connect('notify::location', Lang.bind(this, this._locationChanged));
56
 
 
57
 
        this._dialog = dialog;
58
 
        this._entry = entry;
59
 
    },
60
 
 
61
 
    run: function() {
62
 
        this._dialog.show();
63
 
        this._locationChanged(this._entry);
64
 
    },
65
 
 
66
 
    _onResponse: function(dialog, response) {
67
 
        dialog.destroy();
68
 
 
69
 
        if (response != Gtk.ResponseType.OK)
70
 
            return;
71
 
 
72
 
        let location = this._entry.location;
73
 
        if (!location)
74
 
            return;
75
 
 
76
 
        this._worldModel.addLocation(location);
77
 
    },
78
 
 
79
 
    _locationChanged: function(entry) {
80
 
        this._dialog.set_response_sensitive(Gtk.ResponseType.OK, entry.location != null);
81
 
    }
82
 
});
83
 
 
84
 
const MainWindow = new Lang.Class({
85
 
    Name: 'MainWindow',
86
 
    Extends: Gtk.ApplicationWindow,
87
 
 
88
 
    _init: function(params) {
89
 
        params = Params.fill(params, { width_request: 700,
90
 
                                       height_request: 520 });
91
 
        this.parent(params);
92
 
 
93
 
        this._world = this.application.world;
94
 
        this._currentInfo = null;
95
 
        this._currentPage = Page.WORLD;
96
 
        this._pageWidgets = [[],[]];
97
 
 
98
 
        Util.initActions(this,
99
 
                         [{ name: 'new-location',
100
 
                            activate: this._newLocation },
101
 
                          { name: 'about',
102
 
                            activate: this._showAbout },
103
 
                          { name: 'close',
104
 
                            activate: this._close },
105
 
                          { name: 'selection-mode',
106
 
                            activate: this._setSelectionMode,
107
 
                            parameter_type: new GLib.VariantType('b'),
108
 
                            state: new GLib.Variant('b', false) },
109
 
                          { name: 'go-world',
110
 
                            activate: this._goWorld },
111
 
                          { name: 'select-all',
112
 
                            activate: this._selectAll },
113
 
                          { name: 'select-none',
114
 
                            activate: this._selectNone },
115
 
                          { name: 'delete-selected',
116
 
                            activate: this._deleteSelected },
117
 
                          { name: 'refresh',
118
 
                            activate: this.update }]);
119
 
 
120
 
        let builder = new Gtk.Builder();
121
 
        builder.add_from_resource('/org/gnome/Weather/Application/window.ui');
122
 
 
123
 
        let grid = builder.get_object('main-panel');
124
 
        this._header = builder.get_object('header-bar');
125
 
        this.set_titlebar(this._header);
126
 
        let [title, subtitle] = this._getTitle();
127
 
        this._header.title = title;
128
 
        this._header.subtitle = subtitle;
129
 
 
130
 
        let newButton = builder.get_object('new-button');
131
 
        this._pageWidgets[Page.WORLD].push(newButton);
132
 
 
133
 
        let goWorldButton = builder.get_object('world-button');
134
 
        this._pageWidgets[Page.CITY].push(goWorldButton);
135
 
 
136
 
        let goWorldButtonImage = builder.get_object('world-button-image');
137
 
        goWorldButtonImage.icon_name = (goWorldButton.get_direction() == Gtk.TextDirection.RTL ?
138
 
                                        'go-previous-rtl-symbolic' : 'go-previous-symbolic');
139
 
 
140
 
        let select = builder.get_object('select-button');
141
 
        this._pageWidgets[Page.WORLD].push(select);
142
 
 
143
 
        let refresh = builder.get_object('refresh-button');
144
 
        this._pageWidgets[Page.CITY].push(refresh);
145
 
 
146
 
        let selectDone = builder.get_object('done-button');
147
 
        this._pageWidgets[Page.WORLD].push(selectDone);
148
 
 
149
 
        let selectionBar = builder.get_object('selection-bar');
150
 
        let selectionMenu = builder.get_object("selection-menu");
151
 
 
152
 
        this._selectionMenuButton = builder.get_object('selection-menu-button');
153
 
        this._selectionMenuButtonLabel = builder.get_object('selection-menu-button-label');
154
 
        this._stack = builder.get_object('main-stack');
155
 
 
156
 
        this._deleteButton = builder.get_object('delete-button');
157
 
 
158
 
        this._cityView = new City.WeatherView({ hexpand: true,
159
 
                                                vexpand: true });
160
 
        this._stack.add(this._cityView);
161
 
 
162
 
        this._worldView = new World.WorldContentView(this.application.model, { visible: true });
163
 
        let iconView = this._worldView.iconView;
164
 
        this._stack.add(this._worldView);
165
 
 
166
 
        iconView.connect('item-activated', Lang.bind(this, this._itemActivated));
167
 
 
168
 
        iconView.connect('notify::selection-mode', Lang.bind(this, function() {
169
 
            if (iconView.selection_mode) {
170
 
                this._header.get_style_context().add_class('selection-mode');
171
 
                this._header.set_custom_title(this._selectionMenuButton);
172
 
            } else {
173
 
                this._header.get_style_context().remove_class('selection-mode');
174
 
                this._header.set_custom_title(null);
175
 
            }
176
 
 
177
 
            let selectionState = new GLib.Variant('b', iconView.selection_mode);
178
 
            this.lookup_action('selection-mode').set_state(selectionState);
179
 
        }));
180
 
 
181
 
        iconView.bind_property('selection-mode', newButton, 'visible',
182
 
                               GObject.BindingFlags.INVERT_BOOLEAN);
183
 
        iconView.bind_property('selection-mode', this._header, 'show-close-button',
184
 
                               GObject.BindingFlags.INVERT_BOOLEAN);
185
 
        iconView.bind_property('selection-mode', select, 'visible',
186
 
                               GObject.BindingFlags.INVERT_BOOLEAN);
187
 
        iconView.bind_property('selection-mode', selectDone, 'visible',
188
 
                               GObject.BindingFlags.SYNC_CREATE);
189
 
        iconView.bind_property('selection-mode', selectionBar, 'visible',
190
 
                               GObject.BindingFlags.SYNC_CREATE);
191
 
        this._worldView.bind_property('empty', this.lookup_action('selection-mode'), 'enabled',
192
 
                                      GObject.BindingFlags.SYNC_CREATE |
193
 
                                      GObject.BindingFlags.INVERT_BOOLEAN);
194
 
 
195
 
        this._stack.set_visible_child(this._worldView);
196
 
 
197
 
        iconView.connect('view-selection-changed', Lang.bind(this, function() {
198
 
            let items = iconView.get_selection();
199
 
            let label;
200
 
            let sensitive;
201
 
 
202
 
            if (items.length > 0) {
203
 
                label = Gettext.ngettext("%d selected",
204
 
                                         "%d selected",
205
 
                                         items.length).format(items.length);
206
 
                sensitive = true;
207
 
            } else {
208
 
                label = _("Click on locations to select them");
209
 
                sensitive = false;
210
 
            }
211
 
 
212
 
            this._selectionMenuButtonLabel.label = label;
213
 
            this._deleteButton.sensitive = sensitive;
214
 
        }));
215
 
 
216
 
        this.add(grid);
217
 
        grid.show_all();
218
 
 
219
 
        for (let i = 0; i < this._pageWidgets[Page.CITY].length; i++)
220
 
            this._pageWidgets[Page.CITY][i].hide();
221
 
    },
222
 
 
223
 
    update: function() {
224
 
        this._cityView.update();
225
 
    },
226
 
 
227
 
    _getTitle: function() {
228
 
        if (this._currentPage == Page.WORLD)
229
 
            return [_("World Weather"), null];
230
 
 
231
 
        let location = this._cityView.info.location;
232
 
        let city = location;
233
 
        if (location.get_level() == GWeather.LocationLevel.WEATHER_STATION)
234
 
            city = location.get_parent();
235
 
 
236
 
        let country = city.get_parent();
237
 
        while (country &&
238
 
               country.get_level() > GWeather.LocationLevel.COUNTRY)
239
 
            country = country.get_parent();
240
 
 
241
 
        if (country)
242
 
            return [city.get_name(), country.get_name()];
243
 
        else
244
 
            return [city.get_name(), null];
245
 
    },
246
 
 
247
 
    _goToPage: function(page) {
248
 
        if (page == this._currentPage)
249
 
            return;
250
 
 
251
 
        for (let i = 0; i < this._pageWidgets[this._currentPage].length; i++)
252
 
            this._pageWidgets[this._currentPage][i].hide();
253
 
 
254
 
        for (let i = 0; i < this._pageWidgets[page].length; i++) {
255
 
            let widget = this._pageWidgets[page][i];
256
 
            if (!widget.no_show_all)
257
 
                this._pageWidgets[page][i].show();
258
 
        }
259
 
 
260
 
        this._currentPage = page;
261
 
 
262
 
        let [title, subtitle] = this._getTitle();
263
 
        this._header.title = title;
264
 
        this._header.subtitle = subtitle;
265
 
    },
266
 
 
267
 
    _itemActivated: function(view, id, path) {
268
 
        let [ok, iter] = view.model.get_iter(path);
269
 
        let info = view.model.get_value(iter, World.Columns.INFO);
270
 
 
271
 
        this.showInfo(info);
272
 
    },
273
 
 
274
 
    showInfo: function(info) {
275
 
        this._cityView.info = info;
276
 
        this._stack.set_visible_child(this._cityView);
277
 
        this._goToPage(Page.CITY);
278
 
    },
279
 
 
280
 
    _goWorld: function() {
281
 
        this._stack.set_visible_child(this._worldView);
282
 
        this._goToPage(Page.WORLD);
283
 
    },
284
 
 
285
 
    _newLocation: function() {
286
 
        let controller = new NewLocationController(this.get_toplevel(),
287
 
                                                   this._worldView.model);
288
 
 
289
 
        controller.run();
290
 
    },
291
 
 
292
 
    _setSelectionMode: function(action, param) {
293
 
        this._worldView.iconView.selection_mode = param.get_boolean();
294
 
        this._deleteButton.sensitive = false;
295
 
    },
296
 
 
297
 
    _selectAll: function() {
298
 
        this._worldView.iconView.selection_mode = true;
299
 
        this._worldView.iconView.select_all();
300
 
    },
301
 
 
302
 
    _selectNone: function() {
303
 
        this._worldView.iconView.unselect_all();
304
 
    },
305
 
 
306
 
    _showAbout: function() {
307
 
        let artists = [ 'Jakub Steiner <jimmac@gmail.com>',
308
 
                        'Pink Sherbet Photography (D. Sharon Pruitt)',
309
 
                        'Elliott Brown',
310
 
                        'Analogick',
311
 
                        'DBduo Photography (Daniel R. Blume)',
312
 
                        'davharuk',
313
 
                        'Tech Haven Ministries',
314
 
                        'Jim Pennucci' ];
315
 
        let aboutDialog = new Gtk.AboutDialog(
316
 
            { artists: artists,
317
 
              authors: [ 'Giovanni Campagna <gcampagna@src.gnome.org>' ],
318
 
              translator_credits: _("translator-credits"),
319
 
              program_name: _("Weather"),
320
 
              comments: _("A weather application"),
321
 
              copyright: 'Copyright 2013 The Weather Developers',
322
 
              license_type: Gtk.License.GPL_2_0,
323
 
              logo_icon_name: 'org.gnome.Weather.Application',
324
 
              version: pkg.version,
325
 
              website: 'https://wiki.gnome.org/Apps/Weather',
326
 
              wrap_license: true,
327
 
              modal: true,
328
 
              transient_for: this,
329
 
              use_header_bar: true
330
 
            });
331
 
 
332
 
        aboutDialog.show();
333
 
        aboutDialog.connect('response', function() {
334
 
            aboutDialog.destroy();
335
 
        });
336
 
    },
337
 
 
338
 
    _deleteSelected: function() {
339
 
        let items = this._worldView.iconView.get_selection();
340
 
        let model = this._worldView.iconView.model;
341
 
 
342
 
        for (let i = items.length - 1; i >= 0; i--) {
343
 
            let [res, iter] = model.get_iter(items[i]);
344
 
            if (res)
345
 
                model.removeLocation(iter);
346
 
        }
347
 
 
348
 
        this._worldView.iconView.selection_mode = false;
349
 
    },
350
 
 
351
 
    _close: function() {
352
 
        this.destroy();
353
 
    }
354
 
});