1
// -*- Mode: js; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*-
3
// Copyright (c) 2012 Giovanni Campagna <scampa.giovanni@gmail.com>
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.
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
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
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;
25
const City = imports.city;
26
const Params = imports.params;
27
const World = imports.world;
28
const Util = imports.util;
30
const Gettext = imports.gettext;
31
const Tweener = imports.tweener.tweener;
38
const NewLocationController = new Lang.Class({
39
Name: 'NewLocationController',
41
_init: function(parentWindow, worldModel) {
42
this._worldModel = worldModel;
44
let builder = Util.loadUI('/org/gnome/Weather/Application/new-location-dialog.ui',
45
{ 'parent-window': parentWindow });
47
let dialog = builder.get_object('location-dialog');
48
let entry = builder.get_object('location-entry');
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);
54
dialog.connect('response', Lang.bind(this, this._onResponse));
55
entry.connect('notify::location', Lang.bind(this, this._locationChanged));
57
this._dialog = dialog;
63
this._locationChanged(this._entry);
66
_onResponse: function(dialog, response) {
69
if (response != Gtk.ResponseType.OK)
72
let location = this._entry.location;
76
this._worldModel.addLocation(location);
79
_locationChanged: function(entry) {
80
this._dialog.set_response_sensitive(Gtk.ResponseType.OK, entry.location != null);
84
const MainWindow = new Lang.Class({
86
Extends: Gtk.ApplicationWindow,
88
_init: function(params) {
89
params = Params.fill(params, { width_request: 700,
90
height_request: 520 });
93
this._world = this.application.world;
94
this._currentInfo = null;
95
this._currentPage = Page.WORLD;
96
this._pageWidgets = [[],[]];
98
Util.initActions(this,
99
[{ name: 'new-location',
100
activate: this._newLocation },
102
activate: this._showAbout },
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) },
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 },
118
activate: this.update }]);
120
let builder = new Gtk.Builder();
121
builder.add_from_resource('/org/gnome/Weather/Application/window.ui');
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;
130
let newButton = builder.get_object('new-button');
131
this._pageWidgets[Page.WORLD].push(newButton);
133
let goWorldButton = builder.get_object('world-button');
134
this._pageWidgets[Page.CITY].push(goWorldButton);
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');
140
let select = builder.get_object('select-button');
141
this._pageWidgets[Page.WORLD].push(select);
143
let refresh = builder.get_object('refresh-button');
144
this._pageWidgets[Page.CITY].push(refresh);
146
let selectDone = builder.get_object('done-button');
147
this._pageWidgets[Page.WORLD].push(selectDone);
149
let selectionBar = builder.get_object('selection-bar');
150
let selectionMenu = builder.get_object("selection-menu");
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');
156
this._deleteButton = builder.get_object('delete-button');
158
this._cityView = new City.WeatherView({ hexpand: true,
160
this._stack.add(this._cityView);
162
this._worldView = new World.WorldContentView(this.application.model, { visible: true });
163
let iconView = this._worldView.iconView;
164
this._stack.add(this._worldView);
166
iconView.connect('item-activated', Lang.bind(this, this._itemActivated));
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);
173
this._header.get_style_context().remove_class('selection-mode');
174
this._header.set_custom_title(null);
177
let selectionState = new GLib.Variant('b', iconView.selection_mode);
178
this.lookup_action('selection-mode').set_state(selectionState);
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);
195
this._stack.set_visible_child(this._worldView);
197
iconView.connect('view-selection-changed', Lang.bind(this, function() {
198
let items = iconView.get_selection();
202
if (items.length > 0) {
203
label = Gettext.ngettext("%d selected",
205
items.length).format(items.length);
208
label = _("Click on locations to select them");
212
this._selectionMenuButtonLabel.label = label;
213
this._deleteButton.sensitive = sensitive;
219
for (let i = 0; i < this._pageWidgets[Page.CITY].length; i++)
220
this._pageWidgets[Page.CITY][i].hide();
224
this._cityView.update();
227
_getTitle: function() {
228
if (this._currentPage == Page.WORLD)
229
return [_("World Weather"), null];
231
let location = this._cityView.info.location;
233
if (location.get_level() == GWeather.LocationLevel.WEATHER_STATION)
234
city = location.get_parent();
236
let country = city.get_parent();
238
country.get_level() > GWeather.LocationLevel.COUNTRY)
239
country = country.get_parent();
242
return [city.get_name(), country.get_name()];
244
return [city.get_name(), null];
247
_goToPage: function(page) {
248
if (page == this._currentPage)
251
for (let i = 0; i < this._pageWidgets[this._currentPage].length; i++)
252
this._pageWidgets[this._currentPage][i].hide();
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();
260
this._currentPage = page;
262
let [title, subtitle] = this._getTitle();
263
this._header.title = title;
264
this._header.subtitle = subtitle;
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);
274
showInfo: function(info) {
275
this._cityView.info = info;
276
this._stack.set_visible_child(this._cityView);
277
this._goToPage(Page.CITY);
280
_goWorld: function() {
281
this._stack.set_visible_child(this._worldView);
282
this._goToPage(Page.WORLD);
285
_newLocation: function() {
286
let controller = new NewLocationController(this.get_toplevel(),
287
this._worldView.model);
292
_setSelectionMode: function(action, param) {
293
this._worldView.iconView.selection_mode = param.get_boolean();
294
this._deleteButton.sensitive = false;
297
_selectAll: function() {
298
this._worldView.iconView.selection_mode = true;
299
this._worldView.iconView.select_all();
302
_selectNone: function() {
303
this._worldView.iconView.unselect_all();
306
_showAbout: function() {
307
let artists = [ 'Jakub Steiner <jimmac@gmail.com>',
308
'Pink Sherbet Photography (D. Sharon Pruitt)',
311
'DBduo Photography (Daniel R. Blume)',
313
'Tech Haven Ministries',
315
let aboutDialog = new Gtk.AboutDialog(
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',
333
aboutDialog.connect('response', function() {
334
aboutDialog.destroy();
338
_deleteSelected: function() {
339
let items = this._worldView.iconView.get_selection();
340
let model = this._worldView.iconView.model;
342
for (let i = items.length - 1; i >= 0; i--) {
343
let [res, iter] = model.get_iter(items[i]);
345
model.removeLocation(iter);
348
this._worldView.iconView.selection_mode = false;