Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create interactive command for curses interface (for discussion purposes) #66

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 33 additions & 63 deletions todoman/interactive.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ def save(self, *args):
'''
Save the current state of the Item and the Todo to which it
refers in the associated Database.

(Item, *args) -> None
'''
# Todoman and Urwid have inverted notions of state. According to Urwid,
# the state of something that is done is 'False'.
Expand All @@ -62,10 +60,8 @@ def has_priority(self):
'''
Returns True iff the Item refers to a Todo with a priority that
is set (i.e. not None and above zero).

(self) -> bool
'''
return self.todo.priority not in [None, 0]
return self.todo.priority not in (None, 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's time to implement Todo.is_urgent as a wrapper around this, so we stop duplicating todo.priority not in [None, 0] al over the place.

Also, I think it can never be None, because of how the getter is written.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove this if we use the normal formatter instead of generate_label



class Page(urwid.Frame):
Expand All @@ -87,7 +83,8 @@ def __init__(self, parent, callback):
It is usually a method of the underlying Page. If callback is
None, use the default.

(Page, Main, function) -> None
:type parent: Main
:type callback: function
'''
self.parent = parent
if callback:
Expand All @@ -102,17 +99,13 @@ def open_page(self, page_to_open):
'''
Open a page over the existing stack of pages. page_to_open is the
Page object to display.

(Page, Page) -> None
'''
self.parent._open_page(page_to_open)

@property
def statusbar(self):
'''
Returns the current contents of the statusbar of the Todomanpage.

(Page) -> str
'''
return self.footer.contents[0].original_widget.text

Expand All @@ -121,8 +114,6 @@ def statusbar(self, text):
'''
Sets the given text as the current text in the statusbar of the
Page.

(self, str) -> None
'''
self.footer.contents
self.footer.contents[0][0].original_widget.set_text(text)
Expand All @@ -145,8 +136,6 @@ def reload(self):
'''
Dummy method. Page subclasses that need a reload should
implement one under this name.

(Page) -> None
'''
return None

Expand All @@ -167,7 +156,9 @@ def __init__(self, parent, callback, database):
is responsible for passing information to the underlying Page.
It is usually a method of the underlying Page.

(ItemListPage, Main, function, Database) -> None
:param parent: Main
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not the right format, it's :param TYPE NAME, for example :param int amount.

:param callback: function
:param database: Database
'''
self.parent = parent
self.database = database
Expand All @@ -181,8 +172,6 @@ def items_to_display(self):
'''
Create a list of Items to display, based on the associated
Database and the current done_is_hidden setting.

(ItemListPage) -> [Item]
'''
items = []
for t in self.database.todos():
Expand Down Expand Up @@ -213,8 +202,6 @@ def move_database_chooser(self):
def callback_copy_to(self, database):
'''
Copy the Item in focus to Database database.

(ItemListPage, Database) -> None
'''
if database != self.database:
database.save(self.body.focus.todo)
Expand Down Expand Up @@ -244,8 +231,6 @@ def generate_label(self, item):
'''
Return a label for a given Item for display in the
ItemListPage listing.

(ItemListPage, Item) -> str
'''
return "{0} {1}".format(
'!' if item.has_priority else ' ', item.todo.summary
Expand All @@ -255,47 +240,39 @@ def keypress(self, size, key):
'''
Make the different commands in the ItemListPage view work.

(ItemListPage, int(?), str) -> str
:type size: int
:type key: str
:rtype: str
'''
if key == 'l':
self.list_chooser()
return None
if key == 'm':
elif key == 'm':
self.move_database_chooser()
return None
if key == 'c':
elif key == 'c':
self.copy_database_chooser()
return None
if key == 'd':
elif key == 'd':
self.delete()
return None
if key == 'D':
elif key == 'D':
self.delete_all_done()
return None
if key == 'esc':
elif key == 'esc':
self.parent.close_page(self)
return None
if key == 'h':
elif key == 'h':
self.toggle_hide_completed_items()
return None
if key == 'e':
elif key == 'e':
self.item_details()
return None
if key == 'n':
elif key == 'n':
self.new_item()
return None
if key == 'j':
elif key == 'j':
return super().keypress(size, 'down')
if key == 'k':
elif key == 'k':
return super().keypress(size, 'up')
return super().keypress(size, key)
else:
return super().keypress(size, key)

def list_chooser(self):
'''
Open a ListsPage from which to choose the
ItemListPage to display.

(ItemListPage) -> None
'''
new_page = ListsPage(
self.parent,
Expand Down Expand Up @@ -324,8 +301,6 @@ def item_details(self):
'''
Open a ItemDetailsPage in which the user can edit the selected
Item.

(ItemListPage) -> None
'''
new_page = ItemDetailsPage(
self.parent,
Expand All @@ -338,8 +313,6 @@ def new_item(self):
'''
Create a new Item and open a ItemDetailsPage in which
the user can edit the new item.

(ItemListPage) -> None
'''
item = Item(None, self.database, self.generate_label)
new_page = ItemDetailsPage(self.parent, self.callback, item)
Expand All @@ -348,17 +321,13 @@ def new_item(self):
def toggle_hide_completed_items(self):
'''
Toggle whether completed items are still displayed in the Page.

(ItemListPage) -> None
'''
self.done_is_hidden = not self.done_is_hidden
self.reload()

def delete_all_done(self):
'''
Delete all Items for which the associated Todos are completed.

(ItemListPage) -> None
'''
to_delete = []
for item in self.body.body:
Expand All @@ -370,8 +339,6 @@ def delete_all_done(self):
def reload(self):
'''
Reload all Items in the ListBox from the underlying Database.

(ItemListPage) -> None
'''
items = self.items_to_display()
self.body = urwid.ListBox(urwid.SimpleFocusListWalker(items))
Expand All @@ -396,8 +363,9 @@ def __init__(self, parent, callback, item):
is responsible for passing information to the underlying Page.
It is usually a method of the underlying Page.

(ItemDetailsPage, Main, function, Item)
-> None
:type parent: Main
:type callback: function
:type item: Item
'''
self.parent = parent
self.item = item
Expand All @@ -415,13 +383,11 @@ def __init__(self, parent, callback, item):
self.body.body.contents[-1].contents[1][0].set_text("")
super().__init__(parent, callback)

def close_page(self, dummy, should_save):
def close_page(self, _, should_save):
'''
Callback for closing the ItemDetailsPage. Will attempt to save
all associated data if shouldSave is True. Will discard all changes
otherwise.

(ItemDetailsPage, Button, bool) -> None
'''
if should_save:
try:
Expand All @@ -439,7 +405,8 @@ def keypress(self, size, key):
'''
Make the different commands in the ItemDetailsPage view work.

(ItemDetailsPage, int(?), str) -> str
:type size: int
:type key: str
'''
if key == 'esc':
self.close_page(None, False)
Expand All @@ -462,7 +429,8 @@ def __init__(self, parent, callback):
is responsible for passing information to the underlying Page.
It is usually a method of the underlying Page.

(ListsPage, Main, function) -> None
:type parent: Main
:type callback: function
'''
self.parent = parent
buttons = []
Expand All @@ -480,15 +448,17 @@ def close_page(self, button, database):
Close the current page, returning the selected database to the
underlying page.

(ListsPage, Button, Database) -> None
:type button: Button
:type database: Database
'''
self.parent.close_page(self, database=database)

def keypress(self, size, key):
'''
Make the different commands in the ListsPage view work.

(ListsPage, int(?), str) -> str
:type size: int
:type key: str
'''
if key == 'esc':
self.parent.close_page(self)
Expand Down