#! /usr/bin/env seed /* * * Weather Settings for GNOME Shell Extension Weather * * Copyright (C) 2012 * Christian METZLER * * * This file is part of gnome-shell-extension-weather. * * gnome-shell-extension-weather 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. * * gnome-shell-extension-weather 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 gnome-shell-extension-weather. If not, see . * */ const Gtk = imports.gi.Gtk; const GObject = imports.gi.GObject; const GtkBuilder = imports.gtkbuilder; const Gio = imports.gi.Gio; const Gettext = imports.gettext; const _ = Gettext.gettext; const Soup = imports.gi.Soup; const WEATHER_SETTINGS_SCHEMA = 'org.gnome.shell.extensions.weather'; const WEATHER_UNIT_KEY = 'unit'; const WEATHER_PRESSURE_UNIT_KEY = 'pressure-unit'; const WEATHER_WIND_SPEED_UNIT_KEY = 'wind-speed-unit'; const WEATHER_WIND_DIRECTION_KEY = 'wind-direction'; const WEATHER_CITY_KEY = 'city'; const WEATHER_ACTUAL_CITY_KEY = 'actual-city'; const WEATHER_TRANSLATE_CONDITION_KEY = 'translate-condition'; const WEATHER_USE_SYMBOLIC_ICONS_KEY = 'use-symbolic-icons'; const WEATHER_SHOW_TEXT_IN_PANEL_KEY = 'show-text-in-panel'; const WEATHER_POSITION_IN_PANEL_KEY = 'position-in-panel'; const WEATHER_SHOW_COMMENT_IN_PANEL_KEY = 'show-comment-in-panel'; const WEATHER_REFRESH_INTERVAL = 'refresh-interval'; // Soup session (see https://bugzilla.gnome.org/show_bug.cgi?id=661323#c64) (Simon Legner) const _httpSession = new Soup.SessionAsync(); Soup.Session.prototype.add_feature.call(_httpSession, new Soup.ProxyResolverDefault()); var WeatherSetting = function() { Gettext.textdomain("gnome-shell-extension-weather"); Gtk.init(Seed.argv); this.initWindow(); this.refreshUI(); this.showWindow(); Gtk.main(); }; WeatherSetting.prototype = { addCity : function() { var that = this; var textDialog = _("Name of the city"); var dialog = new Gtk.Dialog({title : ""}); var entry = new Gtk.Entry(); var completion = new Gtk.EntryCompletion(); entry.set_completion(completion); var completionModel = new Gtk.ListStore.c_new(1,[GObject.TYPE_STRING]); completion.set_model(completionModel); completion.set_text_column(0); completion.set_match_func(function(completion,key,iter) { if(iter) if(completionModel.get_value(iter,0).value.get_string()) return true; return false; }); entry.margin_top = 12; entry.margin_bottom = 12; var label = new Gtk.Label({label : textDialog}); dialog.set_border_width(12); dialog.set_modal(1); dialog.set_resizable(0); dialog.set_transient_for(this.Window.get_object("main-window")); dialog.add_button(Gtk.STOCK_CANCEL, 0); var d = dialog.add_button(Gtk.STOCK_OK, 1); d.set_can_default(true); d.sensitive = 0; dialog.set_default(d); entry.activates_default = true; var testLocation = function(location) { that.loadJsonAsync(encodeURI('http://query.yahooapis.com/v1/public/yql?format=json&q=select woeid from geo.places where text = "'+location+'" limit 1'),function() { d.sensitive = 0; var city = arguments[0].query; if(Number(city.count) == 0) return 0; d.sensitive = 1; }); }; entry.signal.changed.connect(function() { var location = entry.get_text(); testLocation(location); that.loadJsonAsync(encodeURI('http://query.yahooapis.com/v1/public/yql?q=select woeid,name,admin1,country from geo.places where text = "*'+location+'*" or text = "'+location+'" limit 10&format=json'),function() { if(!arguments[0]) return 0; var city = arguments[0].query; var n = Number(city.count); if(n > 0) city = city.results.place; else return 0; var iter = that.iter; completionModel.clear(); if(n > 1) { for(var i in city) { if(typeof m == "undefined") var m = {}; var current = completionModel.append(iter).iter; var cityText = city[i].name; if(city[i].admin1) cityText += ", "+city[i].admin1.content; if(city[i].country) cityText += ", "+city[i].country.code; if(m[cityText]) continue; else m[cityText] = 1; completionModel.set_value(current,0,cityText); completion.complete(); } } else { var current = completionModel.append(iter).iter; var cityText = city.name; if(city.admin1) cityText += ", "+city.admin1.content; if(city.country) cityText += ", "+city.country.code; completionModel.set_value(current,0,cityText); completion.complete(); } testLocation(location); }); return 0; }); var dialog_area = dialog.get_content_area(); dialog_area.pack_start(label); dialog_area.pack_start(entry); dialog.signal.response.connect(function(w, response_id) { if(response_id) { that.loadJsonAsync(encodeURI('http://query.yahooapis.com/v1/public/yql?format=json&q=select woeid,name,admin1,country from geo.places where text = "'+entry.get_text()+'" limit 1'),function() { var city = arguments[0].query; if(Number(city.count) > 0) city = city.results.place; else return 0; var cityText = city.name; if(city.admin1) cityText += ", "+city.admin1.content; if(city.country) cityText += ", "+city.country.code; if(that.city) that.city = that.city+" && "+city.woeid+">"+cityText; else that.city = city.woeid+">"+cityText; }); } dialog.hide(); }); dialog.show_all(); }, removeCity : function() { var that = this; var city = this.city.split(" && "); if(!city.length) return 0; var ac = this.actual_city; var textDialog = _("Remove %s ?").replace("%s",this.extractLocation(city[ac])); var dialog = new Gtk.Dialog({title : ""}); var label = new Gtk.Label({label : textDialog}); label.margin_bottom = 12; dialog.set_border_width(12); dialog.set_modal(1); dialog.set_resizable(0); dialog.set_transient_for(this.Window.get_object("main-window")); dialog.add_button(Gtk.STOCK_NO, 0); var d = dialog.add_button(Gtk.STOCK_YES, 1); d.set_can_default(true); dialog.set_default(d); var dialog_area = dialog.get_content_area(); dialog_area.pack_start(label); dialog.signal.response.connect(function(w, response_id) { if(response_id) { if(city.length == 0) city = []; if(city.length > 0 && typeof city != "object") city = [city]; if(city.length > 0) city.splice(ac,1); if(city.length > 1) that.city = city.join(" && "); else if(city[0]) that.city = city[0]; else that.city = ""; } dialog.hide(); }); dialog.show_all(); }, changeSelection : function() { var path = this.actual_city; if(arguments[0]) path = arguments[0]; path = new Gtk.TreePath.from_string(path); this.treeview.get_selection().select_path(path); }, loadJsonAsync : function(url, fun) { var here = this; var message = new Soup.Message.c_new('GET', url); _httpSession.queue_message(message, function(_httpSession, message) { if(!message.response_body.data) { fun.call(here,0); return 0; } try { var jp = JSON.parse(message.response_body.data); fun.call(here, jp); } catch(e) { fun.call(here,0); return 0; } }); }, loadConfig : function() { var that = this; var schema = WEATHER_SETTINGS_SCHEMA; if (Gio.Settings.list_schemas().indexOf(schema) == -1) throw _("Schema \"%s\" not found.").format(schema); this.Settings = new Gio.Settings({ schema: schema }); this.Settings.signal.connect("changed",function(){that.refreshUI();}); }, get units() { if(!this.Settings) this.loadConfig(); return this.Settings.get_enum(WEATHER_UNIT_KEY); }, set units() { if(!this.Settings) this.loadConfig(); this.Settings.set_enum(WEATHER_UNIT_KEY,arguments[0]); }, get pressure_unit() { if(!this.Settings) this.loadConfig(); return this.Settings.get_enum(WEATHER_PRESSURE_UNIT_KEY); }, set pressure_unit() { if(!this.Settings) this.loadConfig(); this.Settings.set_enum(WEATHER_PRESSURE_UNIT_KEY,arguments[0]); }, get wind_speed_unit() { if(!this.Settings) this.loadConfig(); return this.Settings.get_enum(WEATHER_WIND_SPEED_UNIT_KEY); }, set wind_speed_unit() { if(!this.Settings) this.loadConfig(); this.Settings.set_enum(WEATHER_WIND_SPEED_UNIT_KEY,arguments[0]); }, get wind_direction() { if(!this.Settings) this.loadConfig(); return this.Settings.get_boolean(WEATHER_WIND_DIRECTION_KEY); }, set wind_direction() { if(!this.Settings) this.loadConfig(); return this.Settings.set_boolean(WEATHER_WIND_DIRECTION_KEY,arguments[0]); }, get city() { if(!this.Settings) this.loadConfig(); return this.Settings.get_string(WEATHER_CITY_KEY); }, set city() { if(!this.Settings) this.loadConfig(); this.Settings.set_string(WEATHER_CITY_KEY,arguments[0]); }, get actual_city() { if(!this.Settings) this.loadConfig(); var a = this.Settings.get_int(WEATHER_ACTUAL_CITY_KEY); var citys = this.city.split(" && "); if(citys && typeof citys == "string") citys = [citys]; var l = citys.length-1; if(a < 0) a = 0; if(l < 0) l = 0; if(a > l) a = l; return a; }, set actual_city() { if(!this.Settings) this.loadConfig(); var a = arguments[0]; var citys = this.city.split(" && "); if(citys && typeof citys == "string") citys = [citys]; var l = citys.length-1; if(a < 0) a = 0; if(l < 0) l = 0; if(a > l) a = l; this.Settings.set_int(WEATHER_ACTUAL_CITY_KEY,a); }, get translate_condition() { if(!this.Settings) this.loadConfig(); return this.Settings.get_boolean(WEATHER_TRANSLATE_CONDITION_KEY); }, set translate_condition() { if(!this.Settings) this.loadConfig(); this.Settings.set_boolean(WEATHER_TRANSLATE_CONDITION_KEY,arguments[0]); }, get icon_type() { if(!this.Settings) this.loadConfig(); return this.Settings.get_boolean(WEATHER_USE_SYMBOLIC_ICONS_KEY); }, set icon_type() { if(!this.Settings) this.loadConfig(); this.Settings.set_boolean(WEATHER_USE_SYMBOLIC_ICONS_KEY,arguments[0]); }, get text_in_panel() { if(!this.Settings) this.loadConfig(); return this.Settings.get_boolean(WEATHER_SHOW_TEXT_IN_PANEL_KEY); }, set text_in_panel() { if(!this.Settings) this.loadConfig(); this.Settings.set_boolean(WEATHER_SHOW_TEXT_IN_PANEL_KEY,arguments[0]); }, get position_in_panel() { if(!this.Settings) this.loadConfig(); return this.Settings.get_enum(WEATHER_POSITION_IN_PANEL_KEY); }, set position_in_panel() { if(!this.Settings) this.loadConfig(); this.Settings.set_enum(WEATHER_POSITION_IN_PANEL_KEY,arguments[0]); }, get comment_in_panel() { if(!this.Settings) this.loadConfig(); return this.Settings.get_boolean(WEATHER_SHOW_COMMENT_IN_PANEL_KEY); }, set comment_in_panel() { if(!this.Settings) this.loadConfig(); this.Settings.set_boolean(WEATHER_SHOW_COMMENT_IN_PANEL_KEY,arguments[0]); }, get refresh_interval() { if(!this.Settings) this.loadConfig(); return this.Settings.get_int(WEATHER_REFRESH_INTERVAL); }, set refresh_interval() { if(!this.Settings) this.loadConfig(); this.Settings.set_int(WEATHER_REFRESH_INTERVAL,arguments[0]); }, extractLocation : function() { if(arguments[0].search(">") == -1) return _("Invalid city"); return arguments[0].split(">")[1]; }, extractWoeid : function() { if(arguments[0].search(">") == -1) return 0; return arguments[0].split(">")[0]; }, refreshUI : function() { this.Window.get_object("tree-toolbutton-remove").sensitive = Boolean(this.city.length); if(this.mCities != this.city) { if(typeof this.liststore != "undefined") this.liststore.clear(); if(this.city.length > 0) { var city = String(this.city).split(" && "); if(city && typeof city == "string") city = [city]; var iter = this.iter; for(var i in city) { var a = this.liststore.append(iter); var current = a.iter; this.liststore.set_value(current,0,this.extractLocation(city[i])); } } this.mCities = this.city; } this.changeSelection(); var config = this.configWidgets; for(var i in config) if(config[i][0].active != this[config[i][1]]) config[i][0].active = this[config[i][1]]; }, initConfigWidget : function() { var a = this.Window.get_object("right-widget-table"); a.visible = 1; a.can_focus = 0; this.widget = a; }, x : [0,1], y : [0,1], configWidgets : [], inc : function() { if(this.x[0] == 1) { this.x[0] = 0; this.x[1] = 1; this.y[0] += 1; this.y[1] += 1; } else { this.x[0] += 1; this.x[1] += 1; } }, addLabel : function(text) { var l = new Gtk.Label({label:text,xalign:0}); l.visible = 1; l.can_focus = 0; this.widget.attach(l, this.x[0],this.x[1], this.y[0],this.y[1]); this.inc(); }, addComboBox : function(a,b) { var that = this; var cf = new Gtk.ComboBoxText(); this.configWidgets.push([cf,b]); cf.visible = 1; cf.can_focus = 0; cf.width_request = 75; for(var i in a) cf.append_text(a[i]); cf.active = this[b]; cf.signal.changed.connect(function(){that[b] = arguments[0].active;}); this.widget.attach(cf, this.x[0],this.x[1], this.y[0],this.y[1]); this.inc(); }, addSwitch : function(a) { var that = this; var sw = new Gtk.Switch(); this.configWidgets.push([sw,a]); sw.visible = 1; sw.can_focus = 0; sw.active = this[a]; sw.signal.connect("notify::active",function(){that[a] = arguments[0].active;}); this.widget.attach(sw, this.x[0],this.x[1], this.y[0],this.y[1]); this.inc(); }, initWindow : function() { var that = this; this.Window = new Gtk.Builder(); this.Window.add_from_file("@EXTENSIONDIR@/weather-settings.ui"); this.Window.get_object("main-window").title = _("Weather Settings"); this.Window.connect_signals( { add_button_clicked: function(button) { that.addCity(); }, remove_button_clicked: function(button) { that.removeCity(); }, selection_changed : function(selection) { that.selectionChanged(selection); } }); this.treeview = this.Window.get_object("tree-treeview"); this.iter = new Gtk.TreeIter(); this.liststore = new Gtk.ListStore.c_new(1,[GObject.TYPE_STRING]); this.treeview.set_model(this.liststore); var column = new Gtk.TreeViewColumn() this.treeview.append_column(column); renderer = new Gtk.CellRendererText(); column.pack_start(renderer); column.set_cell_data_func(renderer,function() { arguments[1].markup = arguments[2].get_value(arguments[3],0).value.get_string(); }); this.initConfigWidget(); this.addLabel(_("Temperature Unit")); this.addComboBox(["°C","°F","K","R","°Ré","°Rø","°De","°N"],"units"); this.addLabel(_("Wind Speed Unit")); this.addComboBox(["km/h","mph","m/s","kn","ft/s"],"wind_speed_unit"); this.addLabel(_("Pressure Unit")); this.addComboBox(["hPa","inHg","bar","Pa","atm","at","Torr","psi"],"pressure_unit"); this.addLabel(_("Position in Panel")); this.addComboBox([_("Center"),_("Right"),_("Left")],"position_in_panel"); this.addLabel(_("Wind Direction by Arrows")); this.addSwitch("wind_direction"); this.addLabel(_("Translate Conditions")); this.addSwitch("translate_condition"); this.addLabel(_("Symbolic Icons")); this.addSwitch("icon_type"); this.addLabel(_("Temperature in Panel")); this.addSwitch("text_in_panel"); this.addLabel(_("Conditions in Panel")); this.addSwitch("comment_in_panel"); }, showWindow : function() { this.Window.get_object("main-window").signal.hide.connect(Gtk.main_quit); this.Window.get_object("main-window").show_all(); }, selectionChanged : function(select) { if(typeof select.get_selected_rows(this.treestore)[0] == "object") { var a = select.get_selected_rows(this.treestore)[0].to_string(); if(this.actual_city != parseInt(a)) this.actual_city = parseInt(a); } } }; new WeatherSetting();