Commit 8c606507 authored by Jacek Sowiński's avatar Jacek Sowiński

Allow actions on multiple ids without MultiCommand

This feature means that commands like `tag`, `append` or `dep` can work
now with multiple (marked) todo items in column UI.
parent 9cd39304
...@@ -38,6 +38,7 @@ from topydo.ui.columns.ConsoleWidget import ConsoleWidget ...@@ -38,6 +38,7 @@ from topydo.ui.columns.ConsoleWidget import ConsoleWidget
from topydo.ui.columns.KeystateWidget import KeystateWidget from topydo.ui.columns.KeystateWidget import KeystateWidget
from topydo.ui.columns.TodoWidget import TodoWidget from topydo.ui.columns.TodoWidget import TodoWidget
from topydo.ui.columns.TodoListWidget import TodoListWidget from topydo.ui.columns.TodoListWidget import TodoListWidget
from topydo.ui.columns.Transaction import Transaction
from topydo.ui.columns.Utils import PaletteItem, to_urwid_color from topydo.ui.columns.Utils import PaletteItem, to_urwid_color
from topydo.ui.columns.ViewWidget import ViewWidget from topydo.ui.columns.ViewWidget import ViewWidget
from topydo.ui.columns.ColumnLayout import columns from topydo.ui.columns.ColumnLayout import columns
...@@ -269,11 +270,6 @@ class UIApplication(CLIApplicationBase): ...@@ -269,11 +270,6 @@ class UIApplication(CLIApplicationBase):
self._last_cmd = (p_command, p_output == self._output) self._last_cmd = (p_command, p_output == self._output)
if '{}' in p_command:
if self._has_marked_todos():
p_todo_id = ' '.join(self.marked_todos)
p_command = p_command.format(p_todo_id)
try: try:
p_command = shlex.split(p_command) p_command = shlex.split(p_command)
except ValueError as verr: except ValueError as verr:
...@@ -281,24 +277,30 @@ class UIApplication(CLIApplicationBase): ...@@ -281,24 +277,30 @@ class UIApplication(CLIApplicationBase):
return return
try: try:
(subcommand, args) = get_subcommand(p_command) subcommand, args = get_subcommand(p_command)
except ConfigError as cerr: except ConfigError as cerr:
self._print_to_console( self._print_to_console(
'Error: {}. Check your aliases configuration.'.format(cerr)) 'Error: {}. Check your aliases configuration.'.format(cerr))
return return
self._backup(subcommand, args) env_args = (self.todolist, p_output, self._output, self._input)
ids = None
if '{}' in args:
ids = self.marked_todos if self._has_marked_todos() else [p_todo_id]
transaction = Transaction(subcommand, env_args, ids)
transaction.prepare(args)
try: try:
command = subcommand( self._backup(subcommand, args)
args, except TypeError:
self.todolist, self._print_to_console('Error: no todo item was marked for this'
p_output, ' action.')
self._output, return
self._input,
)
if command.execute() != False: try:
if transaction.execute():
self._post_execute() self._post_execute()
except TypeError: except TypeError:
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2017 Bram Schoenmakers <bram@topydo.org>
#
# This program 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.
#
# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
from topydo.lib.MultiCommand import MultiCommand
class Transaction(object):
"""
This class implements basic handling of executing any subcommand on multiple
todo items.
"""
def __init__(self, p_subcommand=None, p_env_args=(), p_todo_ids=None):
self._multi = issubclass(p_subcommand, MultiCommand)
self._cmd = lambda op: p_subcommand(op, *p_env_args)
self._todo_ids = p_todo_ids
self._operations = []
def prepare(self, p_args):
"""
Prepares list of operations to execute based on p_args, list of
todo items contained in _todo_ids attribute and _subcommand
attribute.
"""
if self._todo_ids:
id_position = p_args.index('{}')
# Not using MultiCommand abilities would make EditCommand awkward
if self._multi:
p_args[id_position:id_position + 1] = self._todo_ids
self._operations.append(p_args)
else:
for todo_id in self._todo_ids:
operation_args = p_args[:]
operation_args[id_position] = todo_id
self._operations.append(operation_args)
else:
self._operations.append(p_args)
def execute(self):
"""
Executes each operation from _operations attribute.
"""
last_operation = len(self._operations) - 1
for i, operation in enumerate(self._operations):
command = self._cmd(operation)
if command.execute() is False:
return False
elif i == last_operation:
return True
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