Skip to content

Commit 29d8cdc

Browse files
committed
Update task position in tree after postpone
1 parent 0d039a4 commit 29d8cdc

3 files changed

Lines changed: 61 additions & 26 deletions

File tree

ff-qtah/FF/Qt/MainWindow.hs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,10 @@ new progName storage = do
7575
agendaTasks <- TaskListWidget.new
7676
QSplitter.addWidget agendaSplitter agendaTasks.parent
7777

78-
taskWidget <- TaskWidget.new storage
78+
taskWidget <-
79+
TaskWidget.new
80+
storage
81+
(TaskListWidget.upsertTask agendaTasks) -- on task updated
7982
QWidget.hide taskWidget.parent
8083
QSplitter.addWidget agendaSplitter taskWidget.parent
8184

ff-qtah/FF/Qt/TaskListWidget.hs

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ module FF.Qt.TaskListWidget (
1515
upsertTask,
1616
) where
1717

18-
import Control.Monad (void)
18+
import Control.Monad (void, when)
19+
import Data.Foldable (for_)
1920
import Data.IORef (IORef, modifyIORef, newIORef, readIORef)
20-
import Data.Map.Strict (Map)
21+
import Data.Map.Strict (Map, (!))
2122
import Data.Map.Strict qualified as Map
2223
import Data.Text qualified as Text
2324
import Data.Time (getCurrentTime, toGregorian, utctDay)
@@ -46,7 +47,10 @@ import FF.Types (
4647
import FF.UI (sampleLabel)
4748

4849
data TaskListWidget = TaskListWidget
49-
{parent :: QTreeWidget, modeItems :: IORef (Map TaskMode QTreeWidgetItem)}
50+
{ parent :: QTreeWidget
51+
, modeItems :: IORef (Map TaskMode QTreeWidgetItem)
52+
, taskItems :: IORef (Map String (TaskMode, QTreeWidgetItem))
53+
}
5054

5155
{- | Value order in this enumeration defines the field order in the tree widget.
5256
0th column mustn't be hideable, because when 0th column is hidden,
@@ -60,9 +64,6 @@ data Field
6064
SortKeyField
6165
deriving (Bounded, Enum)
6266

63-
fieldCount :: Int
64-
fieldCount = fromEnum (maxBound :: Field) + 1
65-
6667
fieldsToStrings :: (Field -> String) -> [String]
6768
fieldsToStrings f = map f [minBound .. maxBound]
6869

@@ -99,8 +100,9 @@ new = do
99100
QTreeWidget.sortItems parent (fromEnum SortKeyField) Qt.AscendingOrder
100101

101102
modeItems <- newIORef mempty
103+
taskItems <- newIORef mempty
102104

103-
let this = TaskListWidget{parent, modeItems}
105+
let this = TaskListWidget{parent, modeItems, taskItems}
104106

105107
setDebugInfoVisible this False
106108

@@ -112,18 +114,34 @@ setDebugInfoVisible this v = do
112114
QTreeView.setColumnHidden this.parent (fromEnum SortKeyField) $ not v
113115
QTreeView.setHeaderHidden this.parent $ not v
114116

115-
-- Only insertion is implemeted. TODO implement update.
116117
upsertTask :: TaskListWidget -> EntityView Note -> IO ()
117118
upsertTask this entity = do
118119
today <- utctDay <$> getCurrentTime
119120
let mode = taskMode today note
121+
mExisting <- Map.lookup noteId <$> readIORef this.taskItems
122+
case mExisting of
123+
Nothing -> do
124+
modeItem <- getOrCreateModeItem this mode
125+
item <- createTaskItem modeItem entity
126+
modifyIORef this.taskItems $ Map.insert noteId (mode, item)
127+
Just (oldMode, item) -> do
128+
updateTaskItem item entity
129+
when (oldMode /= mode) do
130+
oldModeItem <- (! oldMode) <$> readIORef this.modeItems
131+
idx <- QTreeWidgetItem.indexOfChild oldModeItem item
132+
void $ QTreeWidgetItem.takeChild oldModeItem idx
133+
newModeItem <- getOrCreateModeItem this mode
134+
QTreeWidgetItem.addChild newModeItem item
135+
modifyIORef this.taskItems $ Map.insert noteId (mode, item)
136+
where
137+
Entity{entityId = DocId noteId, entityVal = NoteView{note}} = entity
138+
139+
getOrCreateModeItem :: TaskListWidget -> TaskMode -> IO QTreeWidgetItem
140+
getOrCreateModeItem this mode = do
120141
mModeItem <- Map.lookup mode <$> readIORef this.modeItems
121-
modeItem <- case mModeItem of
142+
case mModeItem of
122143
Just item -> pure item
123144
Nothing -> createModeItem this mode
124-
createTaskItem modeItem entity
125-
where
126-
Entity{entityVal = NoteView{note}} = entity
127145

128146
createModeItem :: TaskListWidget -> TaskMode -> IO QTreeWidgetItem
129147
createModeItem this mode = do
@@ -148,17 +166,26 @@ createModeItem this mode = do
148166
modifyIORef this.modeItems $ Map.insert mode item
149167
pure item
150168

151-
createTaskItem :: QTreeWidgetItem -> EntityView Note -> IO ()
169+
createTaskItem :: QTreeWidgetItem -> EntityView Note -> IO QTreeWidgetItem
152170
createTaskItem modeItem entity =
153-
void $
154-
QTreeWidgetItem.newWithParentItemAndStringsAndType
155-
modeItem
156-
( fieldsToStrings \case
157-
IdField -> noteId
158-
SortKeyField -> sortKey
159-
TitleField -> title
160-
)
161-
(itemTypeToInt Task)
171+
QTreeWidgetItem.newWithParentItemAndStringsAndType
172+
modeItem
173+
(fieldsToStrings $ taskItemField entity)
174+
(itemTypeToInt Task)
175+
176+
updateTaskItem :: QTreeWidgetItem -> EntityView Note -> IO ()
177+
updateTaskItem item entity =
178+
for_ [minBound .. maxBound] \field ->
179+
QTreeWidgetItem.setText
180+
item
181+
(fromEnum field)
182+
(taskItemField entity field)
183+
184+
taskItemField :: EntityView Note -> Field -> String
185+
taskItemField entity = \case
186+
IdField -> noteId
187+
SortKeyField -> sortKey
188+
TitleField -> title
162189
where
163190
Entity{entityId = DocId noteId, entityVal = NoteView{note}} = entity
164191
title = concat $ take 1 $ lines $ fromRgaM note.note_text

ff-qtah/FF/Qt/TaskWidget.hs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import FF (cmdPostpone, fromRgaM, viewNote)
3333
import FF.Types (
3434
Entity (..),
3535
EntityDoc,
36+
EntityView,
3637
Note (..),
3738
NoteId,
3839
View (NoteView, note),
@@ -51,10 +52,11 @@ data TaskWidget = TaskWidget
5152
, start :: DateComponent
5253
, end :: DateComponent
5354
, noteId :: IORef (Maybe NoteId)
55+
, onTaskUpdated :: EntityView Note -> IO ()
5456
}
5557

56-
new :: Storage.Handle -> IO TaskWidget
57-
new storage = do
58+
new :: Storage.Handle -> (EntityView Note -> IO ()) -> IO TaskWidget
59+
new storage onTaskUpdated = do
5860
parent <- QScrollArea.new
5961

6062
innerWidget <- QFrame.new
@@ -97,6 +99,7 @@ new storage = do
9799
, start
98100
, end
99101
, noteId
102+
, onTaskUpdated
100103
}
101104

102105
connect_ postpone QAbstractButton.clickedSignal $ postponeSlot this
@@ -118,13 +121,15 @@ reload this noteId = do
118121

119122
update :: TaskWidget -> EntityDoc Note -> IO ()
120123
update this noteDoc = do
121-
Entity{entityVal} <- runStorage this.storage $ viewNote noteDoc
124+
entity <- runStorage this.storage $ viewNote noteDoc
125+
let Entity{entityVal} = entity
122126
let NoteView{note} = entityVal
123127
let Note{note_text, note_start, note_end} = note
124128
QLabel.setText this.textContent $ fromRgaM note_text
125129
DateComponent.setDate this.start note_start
126130
DateComponent.setDate this.end note_end
127131
QWidget.adjustSize this.innerWidget
132+
this.onTaskUpdated entity
128133

129134
makeSimpleSizePolicy :: QSizePolicyPolicy -> IO QSizePolicy
130135
makeSimpleSizePolicy policy =

0 commit comments

Comments
 (0)