Commit 422d9b06 authored by Michał Góral's avatar Michał Góral

Config defaults, task filters etc

parent 10f65f08
......@@ -38,14 +38,11 @@ def run():
cfg = config.config()
tw = taskw.TaskWarrior()
# TODO test block
cfg.add_block('default', name='blabla')
cfg.add_block('default', name='otherblbl')
urwid_loop = urwid.MainLoop(None, unhandled_input=unhandled_handler)
palette.register(urwid_loop.screen, cfg)
urwid_loop.widget = widgets.MainWindow(cfg, tw)
urwid_loop.widget = widgets.MainWindow(urwid_loop.screen, cfg, tw)
......@@ -48,6 +48,7 @@ class Block:
fmt = attr.ib('<m class=highlight>{id: >4}</m> {description}')
filter = attr.ib(None)
sort = attr.ib(None)
height = attr.ib('100%')
......@@ -64,6 +65,8 @@ class Config:
settings = attr.ib()
def add_block(self, agenda_name, **kwargs):
'''Adds a new block to specified agenda. Keywords are passed directly
to Block constructor. Agenda is created if it doesn't exist yet.'''
if agenda_name not in self.agendas:
self.agendas[agenda_name] = Agenda(agenda_name)
......@@ -71,7 +74,13 @@ class Config:
def set_color(self, name, fg='', bg=''):
self.colors[name] = (fg, bg)
'''Defines a color pair (foreground and background) with a given name.
It can be later used e.g. in blocks's format strings.'''
self.colors[name] = (fg.strip(), bg.strip())
def set(self, key, value):
'''Changes a setting'''
self.settings[key.strip()] = value.strip()
def _default_keys(self):
......@@ -93,6 +102,21 @@ class Config:
def _create_default_blocks(cfg):
name='Next tasks',
fmt = '{id: >4} <m class=highlight>{priority:<2}</m>{description} <m class=highlight>{tags:>}</m>',
name='Recently completed',
filter='status:completed limit:10',
fmt = '{description}',
def config_path():
'''Returns a path to the configuration file, which is searched in a way
......@@ -124,4 +148,7 @@ def config():
except FileNotFoundError:
if not cfg.agendas:
return cfg
# Copyright (C) 2019 Michał Góral.
# This file is part of TWC
# TWC 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.
# TWC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with TWC. If not, see <>.
'''TaskWarrior utilities'''
import shlex
def process_filter(f):
if not f:
return []
return shlex.split(f)
def filter_tasks(filter_string, tw):
query = process_filter(filter_string)
return tw._get_task_objects(*query, 'export')
......@@ -18,12 +18,28 @@
import re
import urwid
import taskw
import attr
from collections import defaultdict
import twc.markup as markup
import twc.twutils as twutils
def _dim(dimstr, realdim):
if dimstr.endswith('%'):
dimstr = int(dimstr[:-1])
return int(realdim * dimstr / 100)
return int(dimstr)
class Task(urwid.Text):
def __init__(self, data, fmt):
formatted = fmt.format(**data)
def __init__(self, screen, data, fmt):
# TODO: how can term be used? (mgl, 2019-04-11)
data['tags'] = ':'.join(data.setdefault('tags', []))
# defaultdict handles optional attributes, which are specified
# in a format string, but not seen in current task
formatted = fmt.format_map(defaultdict(str, **data))
parser = markup.Parser()
......@@ -35,23 +51,29 @@ class Task(urwid.Text):
return key
class BlockView(urwid.ListBox):
def __init__(self, cfg, tw, block):
tasks = tw.load_tasks()['pending']
textboxes = [Task(t, block.fmt) for t in tasks]
class BlockView(urwid.BoxAdapter):
def __init__(self, screen, tw, block):
self.block = block
self.tasks = twutils.filter_tasks(block.filter, tw)
textboxes = [Task(screen, t, self.block.fmt) for t in self.tasks]
lw = urwid.ListBox(urwid.SimpleFocusListWalker(textboxes))
lb = urwid.LineBox(lw,
height = _dim(self.block.height, screen.get_cols_rows()[1])
super().__init__(lb, height=height)
class AgendaView(urwid.Pile): # TODO: hack - should be a scrollable list of lists (list of blocks) (mgl, 2019-04-10)
def __init__(self, cfg, tw, agenda):
blocks = [urwid.Frame(BlockView(cfg, tw, block)) for block in agenda.blocks]
class AgendaView(urwid.ListBox):
def __init__(self, screen, tw, agenda):
blocks = [BlockView(screen, tw, block) for block in agenda.blocks]
class MainWindow(urwid.Frame):
'''Urwid top widget.'''
def __init__(self, cfg, tw):
def __init__(self, screen, cfg, tw):
name = next(iter(cfg.agendas))
agenda = cfg.agendas[name]
self.view = AgendaView(cfg, tw, agenda)
self.view = AgendaView(screen, tw, agenda)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment