Skip to content

Commit

Permalink
version 1.2
Browse files Browse the repository at this point in the history
  • Loading branch information
simonwiles committed Aug 27, 2015
1 parent 50773e1 commit d590a5e
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 53 deletions.
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -23,6 +23,7 @@ Notes:

Version History:
----------------
* v1.2 (2015-08-26) -- update support for more environments, including multiple distinct instances of the applet.
* v1.1 (2014-12-18) -- first Cinnamon 2.4 compatible version.
* v1.0 (2013-08-28) -- rewrite to update to Cinnamon 2.0 support, and move to the Cinnamon 1.8+ settings api.
* v0.6 (2013-06-25) -- minor optimization.
Expand All @@ -36,3 +37,4 @@ Credits:
* Clem and the Mint Team for the original calendar applet
* [mbokil](http://cinnamon-spices.linuxmint.com/users/view/354) for the idea and code to move the "Date and Time Settings" to a right-click menu.
* Maciej Katafiasz, a.k.a. [mathrick](https://github.com/mathrick) for the overdue update to `GLib` for the timezone handling.
* [gsmcmullin](https://github.com/gsmcmullin) for code updates
62 changes: 32 additions & 30 deletions calendar@simonwiles.net/applet.js
@@ -1,15 +1,17 @@
/*
* World Clock Calendar applet calendar@simonwiles.net
* Fork of the Cinnamon calendar applet with support for displaying multiple timezones.
* version 1.0
* version 1.2
*/

/* global imports, global */
/* exported _onVertSepRepaint, main */
"use strict";

const EXTENSION_UUID = "calendar@simonwiles.net";
const APPLET_DIR = imports.ui.appletManager.appletMeta[EXTENSION_UUID].path;

const Applet = imports.ui.applet;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Clutter = imports.gi.Clutter;
Expand All @@ -21,7 +23,6 @@ const Settings = imports.ui.settings;
const AppletDir = imports.ui.appletManager.applets[EXTENSION_UUID];
const Calendar = AppletDir.calendar;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;

let DEFAULT_FORMAT = _("%l:%M %p");

Expand All @@ -30,16 +31,16 @@ function _onVertSepRepaint (area)
let cr = area.get_context();
let themeNode = area.get_theme_node();
let [width, height] = area.get_surface_size();
let stippleColor = themeNode.get_color('-stipple-color');
let stippleWidth = themeNode.get_length('-stipple-width');
let stippleColor = themeNode.get_color("-stipple-color");
let stippleWidth = themeNode.get_length("-stipple-width");
let x = Math.floor(width/2) + 0.5;
cr.moveTo(x, 0);
cr.lineTo(x, height);
Clutter.cairo_set_source_color(cr, stippleColor);
cr.setDash([1, 3], 1); // Hard-code for now
cr.setLineWidth(stippleWidth);
cr.stroke();
};
}

function rpad(str, pad_with, length) {
while (str.length < length) { str = str + pad_with; }
Expand Down Expand Up @@ -67,7 +68,7 @@ MyApplet.prototype = {
this._initContextMenu();
this._initRightClickMenu();

this._calendarArea = new St.BoxLayout({name: 'calendarArea' });
this._calendarArea = new St.BoxLayout({name: "calendarArea" });
this.menu.addActor(this._calendarArea);

// Fill up the first column
Expand All @@ -77,7 +78,7 @@ MyApplet.prototype = {

// Date
this._date = new St.Label();
this._date.style_class = 'datemenu-date-label';
this._date.style_class = "datemenu-date-label";
vbox.add(this._date);

this._eventSource = null;
Expand All @@ -102,15 +103,16 @@ MyApplet.prototype = {

this._worldclocks = [];
this._worldclock_labels = [];
for (i in this.worldclocks) { this._worldclocks[i] = this.worldclocks[i].split('|'); }
var i;
for (i in this.worldclocks) { this._worldclocks[i] = this.worldclocks[i].split("|"); }
for (i in this._worldclocks) {
this._worldclocks[i][1] = GLib.TimeZone.new(this._worldclocks[i][1]);

let tz = new St.BoxLayout({vertical: false})
let tz_label = new St.Label({ style_class: 'datemenu-date-label', text: this._worldclocks[i][0] });
tz.add(tz_label, {x_align: St.Align.START, expand: true, x_fill: false})
this._worldclock_labels[i] = new St.Label({ style_class: 'datemenu-date-label' });
tz.add(this._worldclock_labels[i], {x_align: St.Align.END, expand: true, x_fill: false})
let tz = new St.BoxLayout({vertical: false});
let tz_label = new St.Label({ style_class: "datemenu-date-label", text: this._worldclocks[i][0] });
tz.add(tz_label, {x_align: St.Align.START, expand: true, x_fill: false});
this._worldclock_labels[i] = new St.Label({ style_class: "datemenu-date-label" });
tz.add(this._worldclock_labels[i], {x_align: St.Align.END, expand: true, x_fill: false});
this._worldclocks_box.add(tz);
}
this.max_length = this._worldclocks.reduce(function (a, b) { return a[0].length > b[0].length ? a : b; })[0].length;
Expand All @@ -130,11 +132,11 @@ MyApplet.prototype = {
// https://bugzilla.gnome.org/show_bug.cgi?id=655129
this._upClient = new UPowerGlib.Client();
try {
this._upClient.connect('notify-resume', this._updateClockAndDate);
this._upClient.connect('notify-resume', addWorldClocks);
this._upClient.connect("notify-resume", this._updateClockAndDate);
this._upClient.connect("notify-resume", addWorldClocks);
} catch (e) {
this._upClient.connect('notify::resume', this._updateClockAndDate);
this._upClient.connect('notify::resume', addWorldClocks);
this._upClient.connect("notify::resume", this._updateClockAndDate);
this._upClient.connect("notify::resume", addWorldClocks);
}

// Start the clock
Expand Down Expand Up @@ -182,12 +184,12 @@ MyApplet.prototype = {

let tooltip = [];
tooltip.push(dateFormattedFull);
for (i in this._worldclocks) {
let tz = this._get_world_time(displayDate, this._worldclocks[i][1])
for (var i in this._worldclocks) {
let tz = this._get_world_time(displayDate, this._worldclocks[i][1]);
this._worldclock_labels[i].set_text(tz);
tooltip.push(rpad(this._worldclocks[i][0], '\xA0', this.max_length + 10) + tz);
tooltip.push(rpad(this._worldclocks[i][0], "\xA0", this.max_length + 10) + tz);
}
this.set_applet_tooltip(tooltip.join('\n'));
this.set_applet_tooltip(tooltip.join("\n"));

if (dateFormattedFull !== this._lastDateFormattedFull) {
this._date.set_text(dateFormattedFull);
Expand Down Expand Up @@ -219,7 +221,7 @@ MyApplet.prototype = {
}

// Whenever the menu is opened, select today
this.menu.connect('open-state-changed', Lang.bind(this, function(menu, isOpen) {
this.menu.connect("open-state-changed", Lang.bind(this, function(menu, isOpen) {
if (isOpen) {
let now = new Date();
/* Passing true to setDate() forces events to be reloaded. We
Expand All @@ -233,7 +235,7 @@ MyApplet.prototype = {
* properly working
*
* Since this only happens when the menu is opened, the cost
* isn't very big.
* isn"t very big.
*/
this._calendar.setDate(now, true);
// No need to update this._eventList as ::selected-date-changed
Expand All @@ -252,20 +254,20 @@ MyApplet.prototype = {
},

_launch_applet_config: function() {
Util.spawn(['cinnamon-settings', 'applets', EXTENSION_UUID]);
Util.spawn(["cinnamon-settings", "applets", EXTENSION_UUID]);
},

_launch_worldclocks_config: function() {
Util.spawnCommandLine("/usr/bin/env python2 " + APPLET_DIR + "/world_clock_calendar_settings.py");
Util.spawnCommandLine("/usr/bin/env python2 " + APPLET_DIR + "/world_clock_calendar_settings.py --instance-id " + this.instance_id);
},

_initRightClickMenu: function () {
// this._applet_context_menu.addMenuItem(new Applet.MenuItem(
// _("Configure applet"), "system-run-symbolic", Lang.bind(this, this._launch_applet_config)));
this._applet_context_menu.addMenuItem(new Applet.MenuItem(
_('Configure applet'), 'system-run-symbolic', Lang.bind(this, this._launch_applet_config)));
this._applet_context_menu.addMenuItem(new Applet.MenuItem(
_('Edit World Clocks'), 'system-run-symbolic', Lang.bind(this, this._launch_worldclocks_config)));
_("Edit World Clocks"), "system-run-symbolic", Lang.bind(this, this._launch_worldclocks_config)));
this._applet_context_menu.addMenuItem(new Applet.MenuItem(
_('Date and Time Settings'), 'system-run-symbolic', Lang.bind(this, this._launch_dateandtime_settings)));
_("Date and Time Settings"), "system-run-symbolic", Lang.bind(this, this._launch_dateandtime_settings)));
},

};
Expand Down
28 changes: 16 additions & 12 deletions calendar@simonwiles.net/calendar.js
Expand Up @@ -12,15 +12,9 @@ const Settings = imports.ui.settings;

const MSECS_IN_DAY = 24 * 60 * 60 * 1000;
const WEEKDATE_HEADER_WIDTH_DIGITS = 3;
const SHOW_WEEKDATE_KEY = 'show-weekdate';

String.prototype.capitalize = function() {
return this.charAt(0).toUpperCase() + this.slice(1);
}

String.prototype.first_cap = function() {
return this.charAt(0).toUpperCase();
}
const SHOW_WEEKDATE_KEY = 'show-week-numbers';
const FIRST_WEEKDAY_KEY = 'first-day-of-week';
const DESKTOP_SCHEMA = 'org.cinnamon.desktop.interface';

// in org.cinnamon.desktop.interface
const CLOCK_FORMAT_KEY = 'clock-format';
Expand Down Expand Up @@ -175,11 +169,14 @@ Calendar.prototype = {
this.settings = settings;

this.settings.connect("changed::show-week-numbers", Lang.bind(this, this._onSettingsChange));
this.desktop_settings = new Gio.Settings({ schema: DESKTOP_SCHEMA });
this.desktop_settings.connect("changed::" + FIRST_WEEKDAY_KEY, Lang.bind(this, this._onSettingsChange));
this.show_week_numbers = this.settings.getValue("show-week-numbers");

// Find the ordering for month/year in the calendar heading

switch (Gettext_gtk30.gettext('calendar:MY')) {
let var_name = 'calendar:MY';
switch (Gettext_gtk30.gettext(var_name)) {
case 'calendar:MY':
this._headerMonthFirst = true;
break;
Expand All @@ -206,7 +203,14 @@ Calendar.prototype = {
},

_onSettingsChange: function(object, key, old_val, new_val) {
this.show_week_numbers = new_val;
switch (key) {
case SHOW_WEEKDATE_KEY:
this.show_week_numbers = new_val;
break;
case FIRST_WEEKDAY_KEY:
this._weekStart = Cinnamon.util_get_week_start();
break;
}
this._buildHeader();
this._update(false);
},
Expand Down Expand Up @@ -416,7 +420,7 @@ Calendar.prototype = {
{ row: row, col: offsetCols + (7 + iter.getDay() - this._weekStart) % 7 });

if (this.show_week_numbers && iter.getDay() == 4) {
let label = new St.Label({ text: _getCalendarWeekForDate(iter).toString(),
let label = new St.Label({ text: iter.toLocaleFormat('%V'),
style_class: 'calendar-day-base calendar-week-number'});
this.actor.add(label,
{ row: row, col: 0, y_align: St.Align.MIDDLE });
Expand Down
3 changes: 2 additions & 1 deletion calendar@simonwiles.net/metadata.json
Expand Up @@ -2,5 +2,6 @@
"uuid": "calendar@simonwiles.net",
"name": "World Clock Calendar",
"description": "Fork of the Cinnamon calendar applet with support for displaying multiple timezones",
"icon": "stock_calendar"
"icon": "stock_calendar",
"max-instances": -1
}
36 changes: 26 additions & 10 deletions calendar@simonwiles.net/world_clock_calendar_settings.py
Expand Up @@ -10,6 +10,7 @@
__license__ = 'GPL http://www.gnu.org/licenses/gpl.txt'
__date__ = '2012-2013'

import argparse
import collections
import io
import os
Expand All @@ -21,8 +22,11 @@
# (included in the standard library for Python >= 2.6) if not.
try:
import simplejson as json
JSONDecodeError = json.JSONDecodeError
except ImportError:
import json
class JSONDecodeError(Exception):
pass

APPLET_DIR = os.path.dirname(os.path.abspath(__file__))

Expand All @@ -35,12 +39,11 @@
class SettingsWindow(Gtk.Window):
""" Build settings panel window """

def __init__(self):

def __init__(self, args):
metadata = json.load(io.open(
os.path.join(APPLET_DIR, 'metadata.json'), 'r', encoding='utf8'))

self.settings = AppletSettings(metadata['uuid'])
self.settings = AppletSettings(metadata['uuid'], args.instance_id)
Gtk.Window.__init__(self, title=metadata['name'])

self.set_size_request(400, 300)
Expand Down Expand Up @@ -235,15 +238,17 @@ def _exit_application(self, *args):

class AppletSettings(object):

def __init__(self, uuid):
def __init__(self, uuid, instance_id):

_fn_basename = instance_id if instance_id is not None else uuid
self.settings_json = os.path.expanduser(os.path.join(
'~', '.cinnamon', 'configs', uuid, '{}.json'.format(uuid)))
'~', '.cinnamon', 'configs', uuid, '{}.json'.format(_fn_basename)))

try:
with io.open(self.settings_json, 'r', encoding='utf8') as handle:
self.settings = json.loads(
handle.read(), object_pairs_hook=collections.OrderedDict)
except (IOError, json.JSONDecodeError) as excptn:
except (IOError, ValueError, JSONDecodeError) as excptn:
default_schema = os.path.join(APPLET_DIR, 'settings-schema.json')
with io.open(default_schema, 'r', encoding='utf8') as handle:
self.settings = json.loads(
Expand All @@ -261,7 +266,7 @@ def set(self, key, value):
def save(self):
with io.open(self.settings_json, 'w', encoding='utf-8') as handle:
handle.write(unicode(json.dumps(
self.settings, ensure_ascii=False, indent=2)))
self.settings, ensure_ascii=True, indent=2)))


class CellRendererAutoComplete(Gtk.CellRendererText):
Expand Down Expand Up @@ -310,15 +315,26 @@ def do_start_editing(
def focus_out(self, entry, event, path):
""" to ensure that changes are saved when the dialogue is closed with
the widget still focussed, I'm emitting 'edited' on this event
instead of 'editing-done'. The is probably not the correct way,
instead of 'editing-done'. This is probably not the correct way,
but it works very nicely :) """
new_value = entry.get_text()
if self.force_match and new_value not in self.completion_entries:
return
self.emit('edited', path, new_value)


if __name__ == "__main__":
def main():

parser = argparse.ArgumentParser(description=__program_name__)

parser.add_argument(
'-i', '--instance-id', action='store', default=None,
help='applet instance-id')

SettingsWindow()
SettingsWindow(parser.parse_args())
Gtk.main()



if __name__ == "__main__":
main()
Binary file added releases/calendar@simonwiles.net_1.2.zip
Binary file not shown.

0 comments on commit d590a5e

Please sign in to comment.