summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>2015-05-25 10:09:06 -0300
committerGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>2015-05-25 10:09:06 -0300
commit401d0bf5081911bb89ef99d6e0fbeaf6d2a7a940 (patch)
tree5472a37459de1180cca00ac2f6f39d562ae19617
parent56730c0e3379be47ef3916902b34fef736cd6464 (diff)
downloadgnome-todo-wip/task-list.tar.gz
try to update tasks et alwip/task-list
-rw-r--r--data/todo.gresource.xml1
-rw-r--r--data/ui/edit-pane.ui303
-rw-r--r--data/ui/list-view.ui194
-rw-r--r--data/ui/source-selector.ui232
-rw-r--r--data/ui/task-row.ui18
-rw-r--r--src/Makefile.am4
-rw-r--r--src/gtd-arrow-frame.c28
-rw-r--r--src/gtd-edit-pane.c365
-rw-r--r--src/gtd-edit-pane.h42
-rw-r--r--src/gtd-list-view.c52
-rw-r--r--src/gtd-list-view.h2
-rw-r--r--src/gtd-task-row.c86
-rw-r--r--src/gtd-task.c8
13 files changed, 1240 insertions, 95 deletions
diff --git a/data/todo.gresource.xml b/data/todo.gresource.xml
index 4a9de563..c8cc0c57 100644
--- a/data/todo.gresource.xml
+++ b/data/todo.gresource.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/todo">
+ <file compressed="true" preprocess="xml-stripblanks">ui/edit-pane.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/list-view.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/menus.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/task-list-item.ui</file>
diff --git a/data/ui/edit-pane.ui b/data/ui/edit-pane.ui
new file mode 100644
index 00000000..231c07fa
--- /dev/null
+++ b/data/ui/edit-pane.ui
@@ -0,0 +1,303 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.1 -->
+<interface>
+ <requires lib="gtk+" version="3.16"/>
+ <template class="GtdEditPane" parent="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">12</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolled_window">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <child>
+ <object class="GtkViewport" id="viewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkGrid" id="main_grid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_top">6</property>
+ <property name="margin_bottom">12</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkButton" id="close_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="margin_right">12</property>
+ <property name="relief">none</property>
+ <signal name="clicked" handler="gtd_edit_pane__close_button_clicked" object="GtdEditPane" swapped="no"/>
+ <child>
+ <object class="GtkImage" id="close_button_image">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">window-close-symbolic</property>
+ </object>
+ </child>
+ <style>
+ <class name="image-button"/>
+ <class name="flat"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="details_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_left">12</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Details&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparator" id="separator">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="grid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">12</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="notes_dim_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Notes</property>
+ <property name="xalign">0</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="notes_scrolled_window">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="shadow_type">in</property>
+ <property name="min_content_width">325</property>
+ <property name="min_content_height">225</property>
+ <child>
+ <object class="GtkViewport" id="notes_viewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkTextView" id="notes_textview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="accepts_tab">False</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="due_date_dim_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Due Date</property>
+ <property name="xalign">0</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="date_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="popover">date_popover</property>
+ <child>
+ <object class="GtkBox" id="date_button_box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="date_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="date_button_image">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">pan-down-symbolic</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="priority_dim_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Priority</property>
+ <property name="xalign">0</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="priority_combo">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="active">0</property>
+ <items>
+ <item translatable="yes">None</item>
+ <item translatable="yes">Low</item>
+ <item translatable="yes">Medium</item>
+ <item translatable="yes">High</item>
+ </items>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="remove_button">
+ <property name="label" translatable="yes">Delete</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">end</property>
+ <property name="vexpand">True</property>
+ <style>
+ <class name="destructive-action"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">6</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </template>
+ <object class="GtkPopover" id="date_popover">
+ <property name="can_focus">False</property>
+ <property name="border_width">12</property>
+ <property name="position">bottom</property>
+ <child>
+ <object class="GtkBox" id="date_popover_box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkCalendar" id="calendar">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="show_week_numbers">True</property>
+ <signal name="day-selected" handler="gtd_edit_pane__date_selected" object="GtdEditPane" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="no_date_button">
+ <property name="label" translatable="yes">None</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/data/ui/list-view.ui b/data/ui/list-view.ui
index e82578e3..ab1bcc5a 100644
--- a/data/ui/list-view.ui
+++ b/data/ui/list-view.ui
@@ -2,124 +2,150 @@
<!-- Generated with glade 3.18.1 -->
<interface>
<requires lib="gtk+" version="3.16"/>
- <template class="GtdListView" parent="GtkBox">
+ <template class="GtdListView" parent="GtkOverlay">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="orientation">vertical</property>
<child>
- <object class="GtkScrolledWindow" id="scrolled_window">
+ <object class="GtkBox" id="main_box">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hexpand">True</property>
- <property name="vexpand">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
<child>
- <object class="GtkViewport" id="viewport">
+ <object class="GtkScrolledWindow" id="scrolled_window">
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="shadow_type">none</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
<child>
- <object class="GtkListBox" id="listbox">
+ <object class="GtkViewport" id="viewport">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="valign">start</property>
- <property name="hexpand">True</property>
- <property name="selection_mode">none</property>
- <style>
- <class name="transparent" />
- </style>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkListBox" id="listbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="selection_mode">none</property>
+ <signal name="row-activated" handler="gtd_list_view__row_activated" object="GtdListView" swapped="no" />
+ <style>
+ <class name="transparent" />
+ </style>
+ </object>
+ </child>
</object>
</child>
</object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
</child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkRevealer" id="revealer">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="transition_type">slide-up</property>
<child>
- <object class="GtkBox" id="box">
+ <object class="GtkRevealer" id="revealer">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="orientation">vertical</property>
+ <property name="transition_type">slide-up</property>
<child>
- <object class="GtkSeparator" id="separator">
+ <object class="GtkBox" id="box">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="hexpand">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="done_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="tooltip_text" translatable="yes">Show or hide completed tasks</property>
- <property name="border_width">12</property>
- <property name="relief">none</property>
- <signal name="clicked" handler="gtd_list_view__done_button_clicked" object="GtdListView" swapped="no" />
+ <property name="orientation">vertical</property>
<child>
- <object class="GtkBox" id="done_button_box">
+ <object class="GtkSeparator" id="separator">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkImage" id="done_image">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="icon_name">zoom-in-symbolic</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
+ <property name="hexpand">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="done_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes">Show or hide completed tasks</property>
+ <property name="border_width">12</property>
+ <property name="relief">none</property>
+ <signal name="clicked" handler="gtd_list_view__done_button_clicked" object="GtdListView" swapped="no" />
<child>
- <object class="GtkLabel" id="done_label">
+ <object class="GtkBox" id="done_button_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="hexpand">True</property>
- <property name="label" translatable="yes">Done</property>
- <property name="xalign">0</property>
- <style>
- <class name="dim-label"/>
- </style>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkImage" id="done_image">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">zoom-in-symbolic</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="done_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">Done</property>
+ <property name="xalign">0</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
</child>
</object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
</child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="overlay">
+ <object class="GtkRevealer" id="edit_revealer">
+ <property name="visible">True</property>
+ <property name="halign">end</property>
+ <property name="transition_type">slide-left</property>
+ <property name="transition_duration">150</property>
+ <child>
+ <object class="GtdArrowFrame" id="arrow_frame">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtdEditPane" id="edit_pane">
+ <property name="visible">True</property>
+ <signal name="edit-finished" handler="gtd_list_view__edit_task_finished" object="GtdListView" swapped="no" />
+ </object>
</child>
</object>
</child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
</child>
</template>
</interface>
diff --git a/data/ui/source-selector.ui b/data/ui/source-selector.ui
new file mode 100644
index 00000000..a653b3fc
--- /dev/null
+++ b/data/ui/source-selector.ui
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.1 -->
+<interface>
+ <requires lib="gtk+" version="3.16"/>
+ <template class="GtdSourceSelectorDialog" parent="GtkDialog">
+ <property name="can_focus">False</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="box">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkStack" id="stack">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child>
+ <object class="GtkBox" id="setup_box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="welcome_title_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Welcome</property>
+ <style>
+ <class name="welcome-title"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="welcome_secondary_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Login to online accounts to access your tasks</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="setup_scrolledwindow">
+ <property name="width_request">400</property>
+ <property name="height_request">200</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport" id="setup_viewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkListBox" id="setup_listbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="selection_mode">none</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="local_check">
+ <property name="label" translatable="yes">Or you can just keep your tasks on this device</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="name">setup</property>
+ <property name="title" translatable="yes">Setup</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="default_box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="default_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">New task lists will be added to the selected source by default.</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="default_scrolledwindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport" id="default_viewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkListBox" id="default_listbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="selection_mode">none</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="online_accounts_button">
+ <property name="label" translatable="yes">Online Accounts</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="name">default</property>
+ <property name="title" translatable="yes">Default</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="titlebar">
+ <object class="GtkHeaderBar" id="headerbar">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="title">To Do Setup</property>
+ <child>
+ <object class="GtkButton" id="cancel_button">
+ <property name="label" translatable="yes">Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="done_button">
+ <property name="label" translatable="yes">Done</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <style>
+ <class name="suggested-action"/>
+ </style>
+ </object>
+ <packing>
+ <property name="pack_type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/data/ui/task-row.ui b/data/ui/task-row.ui
index 604657e8..2b84792c 100644
--- a/data/ui/task-row.ui
+++ b/data/ui/task-row.ui
@@ -6,6 +6,7 @@
<property name="width_request">100</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="activatable">True</property>
<property name="selectable">False</property>
<child>
<object class="GtkRevealer" id="revealer">
@@ -143,6 +144,21 @@
</packing>
</child>
<child>
+ <object class="GtkLabel" id="task_date_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">1</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkLabel" id="task_list_label">
<property name="visible">False</property>
<property name="can_focus">False</property>
@@ -153,7 +169,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">3</property>
+ <property name="position">4</property>
</packing>
</child>
</object>
diff --git a/src/Makefile.am b/src/Makefile.am
index c0362964..5b793b59 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -15,6 +15,10 @@ gnome_todo_SOURCES = \
$(BUILT_SOURCES) \
gtd-application.c \
gtd-application.h \
+ gtd-arrow-frame.c \
+ gtd-arrow-frame.h \
+ gtd-edit-pane.c \
+ gtd-edit-pane.h \
gtd-enums.h \
gtd-list-view.c \
gtd-list-view.h \
diff --git a/src/gtd-arrow-frame.c b/src/gtd-arrow-frame.c
index f9c13e64..e02d9451 100644
--- a/src/gtd-arrow-frame.c
+++ b/src/gtd-arrow-frame.c
@@ -69,6 +69,7 @@ gtd_arrow_frame_get_property (GObject *object,
switch (prop_id)
{
case PROP_TASK_ROW:
+ g_value_set_object (value, self->priv->row);
break;
default:
@@ -87,6 +88,7 @@ gtd_arrow_frame_set_property (GObject *object,
switch (prop_id)
{
case PROP_TASK_ROW:
+ gtd_arrow_frame_set_row (self, g_value_get_object (value));
break;
default:
@@ -94,6 +96,17 @@ gtd_arrow_frame_set_property (GObject *object,
}
}
+static void
+gtd_arrow_frame__row_destroyed (GtdTaskRow *row,
+ gpointer user_data)
+{
+ GtdArrowFramePrivate *priv;
+
+ g_return_if_fail (GTD_IS_ARROW_FRAME (user_data));
+
+ gtd_arrow_frame_set_row (GTD_ARROW_FRAME (user_data), NULL);
+}
+
static gint
gtd_arrow_frame__get_row_y (GtdArrowFrame *frame)
{
@@ -373,7 +386,20 @@ gtd_arrow_frame_set_row (GtdArrowFrame *frame,
{
g_return_if_fail (GTD_IS_ARROW_FRAME (frame));
+ if (frame->priv->row)
+ {
+ g_signal_handlers_disconnect_by_func (frame->priv->row, gtd_arrow_frame__row_destroyed, frame);
+ }
+
frame->priv->row = row;
- gtk_widget_queue_draw (GTK_WIDGET (frame));
+ if (row)
+ {
+ g_signal_connect (row,
+ "destroy",
+ G_CALLBACK (gtd_arrow_frame__row_destroyed),
+ frame);
+
+ gtk_widget_queue_draw (GTK_WIDGET (frame));
+ }
}
diff --git a/src/gtd-edit-pane.c b/src/gtd-edit-pane.c
new file mode 100644
index 00000000..53ab4509
--- /dev/null
+++ b/src/gtd-edit-pane.c
@@ -0,0 +1,365 @@
+/* gtd-edit-pane.c
+ *
+ * Copyright (C) 2015 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
+ *
+ * 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/>.
+ */
+
+#include "gtd-edit-pane.h"
+#include "gtd-manager.h"
+#include "gtd-task.h"
+
+#include <glib/gi18n.h>
+
+typedef struct
+{
+ GtkCalendar *calendar;
+ GtkLabel *date_label;
+ GtkTextView *notes_textview;
+ GtkComboBoxText *priority_combo;
+
+ /* task bindings */
+ GBinding *notes_binding;
+ GBinding *priority_binding;
+
+
+ GtdManager *manager;
+ GtdTask *task;
+} GtdEditPanePrivate;
+
+struct _GtdEditPane
+{
+ GtkGrid parent;
+
+ /*<private>*/
+ GtdEditPanePrivate *priv;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GtdEditPane, gtd_edit_pane, GTK_TYPE_GRID)
+
+enum {
+ PROP_0,
+ PROP_MANAGER,
+ PROP_TASK,
+ LAST_PROP
+};
+
+enum {
+ EDIT_FINISHED,
+ NUM_SIGNALS
+};
+
+static guint signals[NUM_SIGNALS] = { 0, };
+
+static void gtd_edit_pane__date_selected (GtkCalendar *calendar,
+ gpointer user_data);
+
+static void
+gtd_edit_pane__close_button_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ GtdEditPanePrivate *priv;
+
+ g_return_if_fail (GTD_IS_EDIT_PANE (user_data));
+
+ priv = GTD_EDIT_PANE (user_data)->priv;
+
+ /* save the task */
+ gtd_task_save (priv->task);
+
+ g_signal_emit (user_data, signals[EDIT_FINISHED], 0, priv->task);
+}
+
+static void
+gtd_edit_pane_update_date (GtdEditPane *pane)
+{
+ GtdEditPanePrivate *priv;
+ GDateTime *dt;
+ gchar *text;
+
+ g_return_if_fail (GTD_IS_EDIT_PANE (pane));
+
+ priv = pane->priv;
+ dt = priv->task ? gtd_task_get_due_date (priv->task) : NULL;
+ text = dt ? g_date_time_format (dt, "%x") : NULL;
+
+ if (dt)
+ {
+ g_signal_handlers_block_by_func (priv->calendar,
+ gtd_edit_pane__date_selected,
+ pane);
+
+ gtk_calendar_select_month (priv->calendar,
+ g_date_time_get_month (dt) - 1,
+ g_date_time_get_year (dt));
+ gtk_calendar_select_day (priv->calendar,
+ g_date_time_get_day_of_month (dt));
+ gtk_calendar_mark_day (priv->calendar,
+ g_date_time_get_day_of_month (dt));
+
+ g_signal_handlers_unblock_by_func (priv->calendar,
+ gtd_edit_pane__date_selected,
+ pane);
+ }
+
+ gtk_label_set_label (priv->date_label, text ? text : _("No date set"));
+
+ g_free (text);
+}
+
+static void
+gtd_edit_pane__date_selected (GtkCalendar *calendar,
+ gpointer user_data)
+{
+ GtdEditPanePrivate *priv;
+ GDateTime *new_dt;
+ gchar *text;
+ guint year;
+ guint month;
+ guint day;
+
+ g_return_if_fail (GTD_IS_EDIT_PANE (user_data));
+
+ priv = GTD_EDIT_PANE (user_data)->priv;
+
+ gtk_calendar_get_date (calendar,
+ &year,
+ &month,
+ &day);
+
+ new_dt = g_date_time_new_local (year,
+ month + 1,
+ day,
+ 0,
+ 0,
+ 0);
+
+ text = g_date_time_format (new_dt, "%x");
+
+ gtd_task_set_due_date (priv->task, new_dt);
+ gtk_label_set_label (priv->date_label, text);
+
+ g_date_time_unref (new_dt);
+ g_free (text);
+}
+
+static void
+gtd_edit_pane_finalize (GObject *object)
+{
+ GtdEditPane *self = (GtdEditPane *)object;
+ GtdEditPanePrivate *priv = gtd_edit_pane_get_instance_private (self);
+
+ G_OBJECT_CLASS (gtd_edit_pane_parent_class)->finalize (object);
+}
+
+static void
+gtd_edit_pane_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtdEditPane *self = GTD_EDIT_PANE (object);
+
+ switch (prop_id)
+ {
+ case PROP_MANAGER:
+ g_value_set_object (value, self->priv->manager);
+ break;
+
+ case PROP_TASK:
+ g_value_set_object (value, self->priv->task);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gtd_edit_pane_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtdEditPane *self = GTD_EDIT_PANE (object);
+
+ switch (prop_id)
+ {
+ case PROP_MANAGER:
+ self->priv->manager = g_value_get_object (value);
+ break;
+
+ case PROP_TASK:
+ self->priv->task = g_value_get_object (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gtd_edit_pane_class_init (GtdEditPaneClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->finalize = gtd_edit_pane_finalize;
+ object_class->get_property = gtd_edit_pane_get_property;
+ object_class->set_property = gtd_edit_pane_set_property;
+
+ /**
+ * GtdEditPane::manager:
+ *
+ * A weak reference to the application's #GtdManager instance.
+ */
+ g_object_class_install_property (
+ object_class,
+ PROP_MANAGER,
+ g_param_spec_object ("manager",
+ _("Manager of this application"),
+ _("The manager of the application"),
+ GTD_TYPE_MANAGER,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ /**
+ * GtdEditPane::task:
+ *
+ * The task that is actually being edited.
+ */
+ g_object_class_install_property (
+ object_class,
+ PROP_TASK,
+ g_param_spec_object ("task",
+ _("Task being edited"),
+ _("The task that is actually being edited"),
+ GTD_TYPE_TASK,
+ G_PARAM_READWRITE));
+
+ /**
+ * GtdEditPane::edit-finished:
+ *
+ * Emitted when the the user finishes editing the task, i.e. the pane is closed.
+ */
+ signals[EDIT_FINISHED] = g_signal_new ("edit-finished",
+ GTD_TYPE_EDIT_PANE,
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ G_TYPE_NONE,
+ 1,
+ GTD_TYPE_TASK);
+
+ /* template class */
+ gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/todo/ui/edit-pane.ui");
+
+ gtk_widget_class_bind_template_child_private (widget_class, GtdEditPane, calendar);
+ gtk_widget_class_bind_template_child_private (widget_class, GtdEditPane, date_label);
+ gtk_widget_class_bind_template_child_private (widget_class, GtdEditPane, notes_textview);
+ gtk_widget_class_bind_template_child_private (widget_class, GtdEditPane, priority_combo);
+
+ gtk_widget_class_bind_template_callback (widget_class, gtd_edit_pane__close_button_clicked);
+ gtk_widget_class_bind_template_callback (widget_class, gtd_edit_pane__date_selected);
+}
+
+static void
+gtd_edit_pane_init (GtdEditPane *self)
+{
+ self->priv = gtd_edit_pane_get_instance_private (self);
+
+ gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+GtkWidget*
+gtd_edit_pane_new (void)
+{
+ return g_object_new (GTD_TYPE_EDIT_PANE, NULL);
+}
+
+/**
+ * gtd_edit_pane_get_task:
+ * @pane: a #GtdEditPane
+ *
+ * Retrieves the currently edited #GtdTask of %pane, or %NULL if none is set.
+ *
+ * Returns: (transfer none): the current #GtdTask being edited from %pane.
+ */
+GtdTask*
+gtd_edit_pane_get_task (GtdEditPane *pane)
+{
+ g_return_val_if_fail (GTD_IS_EDIT_PANE (pane), NULL);
+
+ return pane->priv->task;
+}
+
+/**
+ * gtd_edit_pane_set_task:
+ * @pane: a #GtdEditPane
+ * @task: a #GtdTask or %NULL
+ *
+ * Sets %task as the currently editing task of %pane.
+ *
+ * Returns:
+ */
+void
+gtd_edit_pane_set_task (GtdEditPane *pane,
+ GtdTask *task)
+{
+ GtdEditPanePrivate *priv;
+
+ g_return_if_fail (GTD_IS_EDIT_PANE (pane));
+
+ priv = pane->priv;
+
+ if (priv->task != task)
+ {
+ if (priv->task)
+ {
+ g_clear_pointer (&priv->notes_binding, g_binding_unbind);
+ g_clear_pointer (&priv->priority_binding, g_binding_unbind);
+ }
+
+ priv->task = task;
+
+ if (task)
+ {
+ /* due date */
+ gtd_edit_pane_update_date (pane);
+
+ /* description */
+ gtk_text_buffer_set_text (gtk_text_view_get_buffer (priv->notes_textview),
+ gtd_task_get_description (task),
+ -1);
+ priv->notes_binding = g_object_bind_property (task,
+ "description",
+ gtk_text_view_get_buffer (priv->notes_textview),
+ "text",
+ G_BINDING_BIDIRECTIONAL);
+
+ /* priority */
+ gtk_combo_box_set_active (GTK_COMBO_BOX (priv->priority_combo), CLAMP (gtd_task_get_priority (task),
+ 0,
+ 3));
+ priv->priority_binding = g_object_bind_property (task,
+ "priority",
+ priv->priority_combo,
+ "active",
+ G_BINDING_BIDIRECTIONAL);
+ }
+
+ g_object_notify (G_OBJECT (pane), "task");
+ }
+}
diff --git a/src/gtd-edit-pane.h b/src/gtd-edit-pane.h
new file mode 100644
index 00000000..08b0f679
--- /dev/null
+++ b/src/gtd-edit-pane.h
@@ -0,0 +1,42 @@
+/* gtd-edit-pane.h
+ *
+ * Copyright (C) 2015 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
+ *
+ * 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/>.
+ */
+
+#ifndef GTD_EDIT_PANE_H
+#define GTD_EDIT_PANE_H
+
+#include "gtd-types.h"
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GTD_TYPE_EDIT_PANE (gtd_edit_pane_get_type())
+
+G_DECLARE_FINAL_TYPE (GtdEditPane, gtd_edit_pane, GTD, EDIT_PANE, GtkGrid)
+
+GtkWidget* gtd_edit_pane_new (void);
+
+GtdTask* gtd_edit_pane_get_task (GtdEditPane *pane);
+
+void gtd_edit_pane_set_task (GtdEditPane *pane,
+ GtdTask *task);
+
+G_END_DECLS
+
+#endif /* GTD_EDIT_PANE_H */
diff --git a/src/gtd-list-view.c b/src/gtd-list-view.c
index be065384..dc5816be 100644
--- a/src/gtd-list-view.c
+++ b/src/gtd-list-view.c
@@ -16,6 +16,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "gtd-arrow-frame.h"
+#include "gtd-edit-pane.h"
#include "gtd-list-view.h"
#include "gtd-manager.h"
#include "gtd-task.h"
@@ -28,6 +30,9 @@
typedef struct
{
+ GtdArrowFrame *arrow_frame;
+ GtdEditPane *edit_pane;
+ GtkRevealer *edit_revealer;
GtkListBox *listbox;
GtdTaskRow *new_task_row;
GtkRevealer *revealer;
@@ -51,7 +56,7 @@ typedef struct
struct _GtdListView
{
- GtkBox parent;
+ GtkOverlay parent;
/*<private>*/
GtdListViewPrivate *priv;
@@ -64,7 +69,7 @@ static void gtd_list_view__task_completed (GObject
GParamSpec *spec,
gpointer user_data);
-G_DEFINE_TYPE_WITH_PRIVATE (GtdListView, gtd_list_view, GTK_TYPE_BOX)
+G_DEFINE_TYPE_WITH_PRIVATE (GtdListView, gtd_list_view, GTK_TYPE_OVERLAY)
enum {
PROP_0,
@@ -76,6 +81,26 @@ enum {
};
static void
+gtd_list_view__edit_task_finished (GtdEditPane *pane,
+ GtdTask *task,
+ gpointer user_data)
+{
+ GtdListViewPrivate *priv;
+
+ g_return_if_fail (GTD_IS_TASK (task));
+ g_return_if_fail (GTD_IS_EDIT_PANE (pane));
+ g_return_if_fail (GTD_IS_LIST_VIEW (user_data));
+
+ priv = GTD_LIST_VIEW (user_data)->priv;
+
+ gtk_revealer_set_reveal_child (priv->edit_revealer, FALSE);
+
+ gtd_manager_update_task (priv->manager, task);
+
+ gtk_list_box_invalidate_sort (priv->listbox);
+}
+
+static void
gtd_list_view__color_changed (GObject *object,
GParamSpec *spec,
gpointer user_data)
@@ -193,6 +218,7 @@ gtd_list_view__clear_list (GtdListView *view)
g_return_if_fail (GTD_IS_LIST_VIEW (view));
view->priv->complete_tasks = 0;
+ gtd_arrow_frame_set_row (view->priv->arrow_frame, NULL);
children = gtk_container_get_children (GTK_CONTAINER (view->priv->listbox));
@@ -208,11 +234,28 @@ gtd_list_view__clear_list (GtdListView *view)
}
gtk_revealer_set_reveal_child (view->priv->revealer, FALSE);
+ gtk_revealer_set_reveal_child (view->priv->edit_revealer, FALSE);
g_list_free (children);
}
static void
+gtd_list_view__row_activated (GtkListBox *listbox,
+ GtdTaskRow *row,
+ gpointer user_data)
+{
+ GtdListViewPrivate *priv = GTD_LIST_VIEW (user_data)->priv;
+
+ if (row == priv->new_task_row)
+ return;
+
+ gtk_revealer_set_reveal_child (priv->edit_revealer, TRUE);
+ gtd_arrow_frame_set_row (priv->arrow_frame, row);
+
+ gtd_edit_pane_set_task (priv->edit_pane, gtd_task_row_get_task (row));
+}
+
+static void
gtd_list_view__add_task (GtdListView *view,
GtdTask *task)
{
@@ -510,6 +553,9 @@ gtd_list_view_class_init (GtdListViewClass *klass)
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/todo/ui/list-view.ui");
+ gtk_widget_class_bind_template_child_private (widget_class, GtdListView, arrow_frame);
+ gtk_widget_class_bind_template_child_private (widget_class, GtdListView, edit_pane);
+ gtk_widget_class_bind_template_child_private (widget_class, GtdListView, edit_revealer);
gtk_widget_class_bind_template_child_private (widget_class, GtdListView, listbox);
gtk_widget_class_bind_template_child_private (widget_class, GtdListView, revealer);
gtk_widget_class_bind_template_child_private (widget_class, GtdListView, done_image);
@@ -517,6 +563,8 @@ gtd_list_view_class_init (GtdListViewClass *klass)
gtk_widget_class_bind_template_child_private (widget_class, GtdListView, viewport);
gtk_widget_class_bind_template_callback (widget_class, gtd_list_view__done_button_clicked);
+ gtk_widget_class_bind_template_callback (widget_class, gtd_list_view__edit_task_finished);
+ gtk_widget_class_bind_template_callback (widget_class, gtd_list_view__row_activated);
}
static void
diff --git a/src/gtd-list-view.h b/src/gtd-list-view.h
index f5ade336..b522b151 100644
--- a/src/gtd-list-view.h
+++ b/src/gtd-list-view.h
@@ -27,7 +27,7 @@ G_BEGIN_DECLS
#define GTD_TYPE_LIST_VIEW (gtd_list_view_get_type())
-G_DECLARE_FINAL_TYPE (GtdListView, gtd_list_view, GTD, LIST_VIEW, GtkBox)
+G_DECLARE_FINAL_TYPE (GtdListView, gtd_list_view, GTD, LIST_VIEW, GtkOverlay)
GtkWidget* gtd_list_view_new (void);
diff --git a/src/gtd-task-row.c b/src/gtd-task-row.c
index 9dcf324a..2ad23450 100644
--- a/src/gtd-task-row.c
+++ b/src/gtd-task-row.c
@@ -35,6 +35,7 @@ typedef struct
/* task widgets */
GtkEntry *title_entry;
+ GtkLabel *task_date_label;
GtkLabel *task_list_label;
GtkSpinner *task_loading_spinner;
GtkLabel *title_label;
@@ -71,6 +72,65 @@ enum {
static guint signals[NUM_SIGNALS] = { 0, };
+static gboolean
+gtd_task_row__date_changed_binding (GBinding *binding,
+ const GValue *from_value,
+ GValue *to_value,
+ gpointer user_data)
+{
+ GtdTaskRowPrivate *priv;
+ GDateTime *dt;
+ gchar *new_label = NULL;
+
+ g_return_val_if_fail (GTD_IS_TASK_ROW (user_data), FALSE);
+
+ priv = GTD_TASK_ROW (user_data)->priv;
+ dt = g_value_get_boxed (from_value);
+
+ if (dt)
+ {
+ GDateTime *today = g_date_time_new_now_local ();
+ new_label = g_date_time_format (dt, "%x");
+
+ if (g_date_time_get_year (dt) == g_date_time_get_year (today) &&
+ g_date_time_get_month (dt) == g_date_time_get_month (today))
+ {
+ if (g_date_time_get_day_of_month (dt) == g_date_time_get_day_of_month (today))
+ {
+ new_label = g_strdup (_("Today"));
+ }
+ else if (g_date_time_get_day_of_month (dt) == g_date_time_get_day_of_month (today) + 1)
+ {
+ new_label = g_strdup (_("Tomorrow"));
+ }
+ else if (g_date_time_get_day_of_month (dt) == g_date_time_get_day_of_month (today) - 1)
+ {
+ new_label = g_strdup (_("Yesterday"));
+ }
+ else if (g_date_time_get_day_of_year (dt) > g_date_time_get_day_of_month (today) &&
+ g_date_time_get_day_of_year (dt) < g_date_time_get_day_of_month (today) + 7)
+ {
+ new_label = g_date_time_format (dt, "%A");
+ }
+ else
+ {
+ new_label = g_date_time_format (dt, "%x");
+ }
+ }
+
+ }
+ else
+ {
+ new_label = g_strdup (_("No date set"));
+ }
+
+ g_value_set_string (to_value, new_label);
+
+ g_free (new_label);
+
+ return TRUE;
+}
+
static GtdTask*
gtd_task_row__create_task_for_name (const gchar *name)
{
@@ -120,10 +180,6 @@ gtd_task_row__focus_in (GtkWidget *widget,
gtk_stack_set_visible_child_name (priv->new_task_stack, "entry");
gtk_widget_grab_focus (GTK_WIDGET (priv->new_task_entry));
}
- else
- {
- g_signal_emit (widget, signals[ENTER], 0);
- }
return FALSE;
}
@@ -233,10 +289,19 @@ gtd_task_row_set_property (GObject *object,
}
static void
+gtd_task_row_activate (GtkListBoxRow *row)
+{
+ GTK_LIST_BOX_ROW_CLASS (gtd_task_row_parent_class)->activate (row);
+
+ g_signal_emit (row, signals[ENTER], 0);
+}
+
+static void
gtd_task_row_class_init (GtdTaskRowClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ GtkListBoxRowClass *row_class = GTK_LIST_BOX_ROW_CLASS (klass);
object_class->finalize = gtd_task_row_finalize;
object_class->get_property = gtd_task_row_get_property;
@@ -245,6 +310,8 @@ gtd_task_row_class_init (GtdTaskRowClass *klass)
widget_class->focus_in_event = gtd_task_row__focus_in;
widget_class->key_press_event = gtd_task_row__key_press_event;
+ row_class->activate = gtd_task_row_activate;
+
/**
* GtdTaskRow::new-task-mode:
*
@@ -341,6 +408,7 @@ gtd_task_row_class_init (GtdTaskRowClass *klass)
gtk_widget_class_bind_template_child_private (widget_class, GtdTaskRow, new_task_entry);
gtk_widget_class_bind_template_child_private (widget_class, GtdTaskRow, new_task_stack);
gtk_widget_class_bind_template_child_private (widget_class, GtdTaskRow, revealer);
+ gtk_widget_class_bind_template_child_private (widget_class, GtdTaskRow, task_date_label);
gtk_widget_class_bind_template_child_private (widget_class, GtdTaskRow, task_list_label);
gtk_widget_class_bind_template_child_private (widget_class, GtdTaskRow, task_loading_spinner);
gtk_widget_class_bind_template_child_private (widget_class, GtdTaskRow, title_entry);
@@ -460,6 +528,16 @@ gtd_task_row_set_task (GtdTaskRow *row,
row->priv->task_loading_spinner,
"visible",
G_BINDING_INVERT_BOOLEAN | G_BINDING_SYNC_CREATE);
+
+ g_object_bind_property_full (task,
+ "due-date",
+ row->priv->task_date_label,
+ "label",
+ G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE,
+ gtd_task_row__date_changed_binding,
+ NULL,
+ row,
+ NULL);
}
g_object_notify (G_OBJECT (row), "task");
diff --git a/src/gtd-task.c b/src/gtd-task.c
index 3543b82b..fc219911 100644
--- a/src/gtd-task.c
+++ b/src/gtd-task.c
@@ -617,6 +617,7 @@ gtd_task_set_due_date (GtdTask *task,
{
ECalComponentDateTime comp_dt;
icaltimetype *idt;
+ gboolean changed = FALSE;
comp_dt.value = NULL;
comp_dt.tzid = NULL;
@@ -645,14 +646,14 @@ gtd_task_set_due_date (GtdTask *task,
g_date_time_unref (dt);
- g_object_notify (G_OBJECT (task), "due-date");
+ changed = TRUE;
}
else if (!dt)
{
idt = NULL;
comp_dt.tzid = NULL;
- g_object_notify (G_OBJECT (task), "due-date");
+ changed = TRUE;
}
comp_dt.value = idt;
@@ -660,6 +661,9 @@ gtd_task_set_due_date (GtdTask *task,
e_cal_component_set_dtend (task->priv->component, &comp_dt);
e_cal_component_free_datetime (&comp_dt);
+
+ if (changed)
+ g_object_notify (G_OBJECT (task), "due-date");
}
if (current_dt)