Skip to content

Commit

Permalink
Fixes #7 by allowing task description word wrapping
Browse files Browse the repository at this point in the history
  • Loading branch information
sgaraud committed Aug 28, 2016
1 parent e2bd949 commit faa24e2
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 6 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ This GNOME shell extension is enabling access to [Taskwarrior](https://taskwarri
* Start/Stop tasks
* Modify task attributes
* Filter pending task list on projects, tags, etc ...
* Custom keybinding to open task list
* Custom task description string length

### Upcoming Features

* Customization through preferences menu
* More customization through preferences menu
* More keybindings
* Constant menu width

### Screenshots

Expand Down
82 changes: 82 additions & 0 deletions prefs.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@ const Lang = imports.lang;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const Convenience = Me.imports.convenience;
const Params = imports.misc.params;

const Gettext = imports.gettext.domain('taskwarrior-integration');
const _ = Gettext.gettext;

const TOGGLE_MENU = 'toggle-menu';
const DESC_LINE_LENGTH = 'max-task-description-line-length';
const TAG_LINE_LENGTH = 'max-task-tags-line-length';
let Schema = null;

function init() {
Expand Down Expand Up @@ -122,6 +125,56 @@ const TaskwarriorPrefsGrid = new GObject.Class({
this._rownum++;

return widget;
},

add_row: function(text, widget, wrap) {
let label = new Gtk.Label({
label: text,
hexpand: true,
halign: Gtk.Align.START
});
label.set_line_wrap(wrap || false);

this.attach(label, 0, this._rownum, 1, 1); // col, row, colspan, rowspan
this.attach(widget, 1, this._rownum, 1, 1);
this._rownum++;

return widget;
},

add_spin: function(label, key, adjustment_properties, type, spin_properties) {
adjustment_properties = Params.parse(adjustment_properties, {
lower: 0,
upper: 100,
step_increment: 100
});
let adjustment = new Gtk.Adjustment(adjustment_properties);

spin_properties = Params.parse(spin_properties, {
adjustment: adjustment,
numeric: true,
snap_to_ticks: true
}, true);
let spin_button = new Gtk.SpinButton(spin_properties);

if(type !== 'int') spin_button.set_digits(2);

let get_method = type === 'int' ? 'get_int' : 'get_double';
let set_method = type === 'int' ? 'set_int' : 'set_double';

spin_button.set_value(this._settings[get_method](key));
spin_button.connect('value-changed', Lang.bind(this, function(spin) {
let value;

if(type === 'int') value = spin.get_value_as_int();
else value = spin.get_value();

if(this._settings[get_method](key) !== value) {
this._settings[set_method](key, value);
}
}));

return this.add_row(label, spin_button, true);
}
});

Expand All @@ -135,13 +188,15 @@ const TaskwarriorIntegrationPrefsWidget = new GObject.Class({
this.set_orientation(Gtk.Orientation.VERTICAL);

let keybindings = this._get_keybindings_page();
let uiprefs = this._get_ui_page();

let stack = new Gtk.Stack({transition_type: Gtk.StackTransitionType.SLIDE_LEFT_RIGHT,
transition_duration: 500});
let stack_switcher = new Gtk.StackSwitcher({margin_left: 5, margin_top: 5, margin_bottom: 5, margin_right: 5,
stack: stack});

stack.add_titled(keybindings.page, keybindings.name, keybindings.name);
stack.add_titled(uiprefs.page, uiprefs.name, uiprefs.name);

this.add(stack_switcher);
this.add(stack);
Expand All @@ -159,6 +214,33 @@ const TaskwarriorIntegrationPrefsWidget = new GObject.Class({
page.add_item(keybindings_widget);

return {name: name, page: page};
},

_get_ui_page: function() {
let name = _("UI prefs");
let page = new TaskwarriorPrefsGrid(Schema);

let adjustment_properties = {
lower: 1,
upper: 4000,
step_increment: 1
};
let task_desc_size = page.add_spin(
_("Max task description line length (char):"),
DESC_LINE_LENGTH,
adjustment_properties,
'int'
);

adjustment_properties.upper = 400;
let tag_list_size = page.add_spin(
_("Max tags list line length (char):"),
TAG_LINE_LENGTH,
adjustment_properties,
'int'
);

return {name: name, page: page };
}
});

Expand Down
Binary file modified schemas/gschemas.compiled
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
<summary>Toggle the menu</summary>
<description>Key to toggle the taskwarrior menu</description>
</key>
<key name="max-task-description-line-length" type="i">
<default>160</default>
</key>
<key name="max-task-tags-line-length" type="i">
<default>80</default>
</key>
<key name="filter" type="s">
<default>''</default>
<summary>Filter for task list</summary>
Expand Down
30 changes: 26 additions & 4 deletions ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const Convenience = Me.imports.convenience;
const Taskwarrior = Me.imports.taskwarrior;
const Prefs = Me.imports.prefs;

const NOTIF_ICON = 'taskwarrior-logo';
var taskMenuList = null;
Expand Down Expand Up @@ -173,15 +174,14 @@ const TaskwarriorFilterEntry = new Lang.Class({
});

/*
* Class for widget handling core display information (task description and done button)
* Class for widget handling core display information (task description and done/start buttons)
*/
const TaskwarriorMenuItem = new Lang.Class({
Name: 'Taskwarrior.MenuItem',
Extends: PopupMenu.PopupSubMenuMenuItem,

_init: function(task) {
this.parent(task.description);

this.parent(taskDescriptionWrap(task.description, Schema.get_int(Prefs.DESC_LINE_LENGTH)));

//this.actor.add_style_class_name('task-label-data-red');

Expand Down Expand Up @@ -247,7 +247,7 @@ const TaskwarriorMenuAdvancedItem1 = new Lang.Class({
this.label_tags = new St.Label({ text: Taskwarrior.LABEL_TAGS, style_class: 'task-label-center' });
this.actor.add_child(this.label_tags);
if (typeof task.tags != 'undefined') {
this.label_tags_value = new St.Label({ text: task.tags.toString(), style_class: 'task-label-data' });
this.label_tags_value = new St.Label({ text: taskTagsListWrap(task.tags.toString(), Schema.get_int(Prefs.TAG_LINE_LENGTH)), style_class: 'task-label-data' });
}
else {
this.label_tags_value = new St.Label({ text: Taskwarrior.LABEL_EMPTY, style_class: 'task-label-data' });
Expand Down Expand Up @@ -485,4 +485,26 @@ function _userNotification(status, action, desc) {
let notification = new MessageTray.Notification(source, notif_title, notif_msg);
Main.messageTray.add(source);
source.notify(notification);
}

/*
* Function for making wordwrap of long task description
* fixes https://github.com/sgaraud/gnome-extension-taskwarrior/issues/7
* inspired by - james padolsey
*/
function taskDescriptionWrap(str, width) {

if (!str) { return str; }
var regex = '.{1,' +width+ '}(\\s|$)' + ('|\\S+?(\\s|$)');
return str.match(RegExp(regex, 'g')).join('\n');
}

/*
* Function for making wordwrap of comma separated tag list
*/
function taskTagsListWrap(str, width) {

if (!str) { return str; }
var regex = '.{1,' +width+ '}(,|$)' + ('|[^,]+?(,|$)');
return str.match(RegExp(regex, 'g')).join('\n');
}

0 comments on commit faa24e2

Please sign in to comment.