From 9b4d7572f04402d923f5c80b30f26b8a03db47fd Mon Sep 17 00:00:00 2001 From: Morgan McMillian Date: Sat, 20 Jan 2018 15:44:35 -0800 Subject: [PATCH] Initial project import --- .cproject | 177 +++++ .project | 45 ++ Makefile | 6 + RenamedTodo.pro | 6 + assets/.assets.index | 50 ++ assets/AboutPage.qml | 106 +++ assets/AppCover.qml | 103 +++ assets/EditSheet.qml | 384 +++++++++++ assets/FilterPage.qml | 105 +++ assets/HelpPage.qml | 35 + assets/SettingsPage.qml | 272 ++++++++ assets/TaskItem.qml | 179 +++++ assets/TaskPage.qml | 114 ++++ assets/VisualStyle.bright/Appointment.png | Bin 0 -> 493 bytes assets/VisualStyle.bright/ArrowCircleAlt.png | Bin 0 -> 1088 bytes assets/VisualStyle.bright/PriceTag.png | Bin 0 -> 542 bytes assets/VisualStyle.bright/Watch.png | Bin 0 -> 682 bytes assets/VisualStyle.dark/Appointment.png | Bin 0 -> 1692 bytes assets/VisualStyle.dark/ArrowCircleAlt.png | Bin 0 -> 3116 bytes assets/VisualStyle.dark/PriceTag.png | Bin 0 -> 1397 bytes assets/VisualStyle.dark/Watch.png | Bin 0 -> 1931 bytes assets/Watch_a.png | Bin 0 -> 840 bytes assets/help.html | 81 +++ assets/humane.js | 150 +++++ assets/icons/123.png | Bin 0 -> 2452 bytes assets/icons/Add.png | Bin 0 -> 941 bytes assets/icons/Capitalize.png | Bin 0 -> 2404 bytes assets/icons/Check.png | Bin 0 -> 2469 bytes assets/icons/Clock.png | Bin 0 -> 4272 bytes assets/icons/Clock_a.png | Bin 0 -> 3455 bytes assets/icons/Date.png | Bin 0 -> 3087 bytes assets/icons/Delete.png | Bin 0 -> 2931 bytes assets/icons/DownBox.png | Bin 0 -> 2482 bytes assets/icons/Funnel.png | Bin 0 -> 2006 bytes assets/icons/Info.png | Bin 0 -> 4014 bytes assets/icons/Pencil.png | Bin 0 -> 3484 bytes assets/icons/PriceTag.png | Bin 0 -> 2087 bytes assets/icons/Recycle.png | Bin 0 -> 3136 bytes assets/icons/Search.png | Bin 0 -> 4168 bytes assets/icons/Sort.png | Bin 0 -> 1674 bytes assets/icons/Undo.png | Bin 0 -> 2436 bytes assets/icons/abc.png | Bin 0 -> 2477 bytes assets/icons/ic_bbm.png | Bin 0 -> 836 bytes assets/icons/invoke.png | Bin 0 -> 1197 bytes assets/icons/rtd_512_3-110.png | Bin 0 -> 3809 bytes assets/icons/rtd_512_3-144.png | Bin 0 -> 4529 bytes assets/icons/rtd_512_3-86.png | Bin 0 -> 2649 bytes assets/icons/rtd_512_3-90.png | Bin 0 -> 2885 bytes assets/icons/rtd_512_3-96.png | Bin 0 -> 3091 bytes assets/icons/rtd_splash_1440s.png | Bin 0 -> 26047 bytes assets/icons/rtd_splash_720s.png | Bin 0 -> 16929 bytes assets/icons/rtd_splash_768p.png | Bin 0 -> 17342 bytes assets/main.qml | 398 +++++++++++ bar-descriptor.xml | 118 ++++ config.pri | 134 ++++ precompiled.h | 5 + src/LocalFile.cpp | 103 +++ src/LocalFile.h | 48 ++ src/TaskModel.cpp | 664 +++++++++++++++++++ src/TaskModel.h | 112 ++++ src/applicationui.cpp | 107 +++ src/applicationui.hpp | 60 ++ src/main.cpp | 38 ++ translations/Makefile | 12 + translations/RenamedTodo.pro | 1 + translations/RenamedTodo.ts | 4 + 66 files changed, 3617 insertions(+) create mode 100644 .cproject create mode 100644 .project create mode 100644 Makefile create mode 100644 RenamedTodo.pro create mode 100644 assets/.assets.index create mode 100644 assets/AboutPage.qml create mode 100644 assets/AppCover.qml create mode 100644 assets/EditSheet.qml create mode 100644 assets/FilterPage.qml create mode 100644 assets/HelpPage.qml create mode 100644 assets/SettingsPage.qml create mode 100644 assets/TaskItem.qml create mode 100644 assets/TaskPage.qml create mode 100644 assets/VisualStyle.bright/Appointment.png create mode 100644 assets/VisualStyle.bright/ArrowCircleAlt.png create mode 100644 assets/VisualStyle.bright/PriceTag.png create mode 100644 assets/VisualStyle.bright/Watch.png create mode 100644 assets/VisualStyle.dark/Appointment.png create mode 100644 assets/VisualStyle.dark/ArrowCircleAlt.png create mode 100644 assets/VisualStyle.dark/PriceTag.png create mode 100644 assets/VisualStyle.dark/Watch.png create mode 100644 assets/Watch_a.png create mode 100644 assets/help.html create mode 100644 assets/humane.js create mode 100644 assets/icons/123.png create mode 100644 assets/icons/Add.png create mode 100644 assets/icons/Capitalize.png create mode 100644 assets/icons/Check.png create mode 100644 assets/icons/Clock.png create mode 100644 assets/icons/Clock_a.png create mode 100644 assets/icons/Date.png create mode 100644 assets/icons/Delete.png create mode 100644 assets/icons/DownBox.png create mode 100644 assets/icons/Funnel.png create mode 100644 assets/icons/Info.png create mode 100644 assets/icons/Pencil.png create mode 100644 assets/icons/PriceTag.png create mode 100644 assets/icons/Recycle.png create mode 100644 assets/icons/Search.png create mode 100644 assets/icons/Sort.png create mode 100644 assets/icons/Undo.png create mode 100644 assets/icons/abc.png create mode 100644 assets/icons/ic_bbm.png create mode 100644 assets/icons/invoke.png create mode 100644 assets/icons/rtd_512_3-110.png create mode 100644 assets/icons/rtd_512_3-144.png create mode 100644 assets/icons/rtd_512_3-86.png create mode 100644 assets/icons/rtd_512_3-90.png create mode 100644 assets/icons/rtd_512_3-96.png create mode 100644 assets/icons/rtd_splash_1440s.png create mode 100644 assets/icons/rtd_splash_720s.png create mode 100644 assets/icons/rtd_splash_768p.png create mode 100644 assets/main.qml create mode 100644 bar-descriptor.xml create mode 100644 config.pri create mode 100644 precompiled.h create mode 100644 src/LocalFile.cpp create mode 100644 src/LocalFile.h create mode 100644 src/TaskModel.cpp create mode 100644 src/TaskModel.h create mode 100644 src/applicationui.cpp create mode 100644 src/applicationui.hpp create mode 100644 src/main.cpp create mode 100644 translations/Makefile create mode 100644 translations/RenamedTodo.pro create mode 100644 translations/RenamedTodo.ts diff --git a/.cproject b/.cproject new file mode 100644 index 0000000..f48122e --- /dev/null +++ b/.cproject @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..2e56c96 --- /dev/null +++ b/.project @@ -0,0 +1,45 @@ + + + RenamedTodo + + + + + + com.rim.tad.tools.qml.core.qmlFileBuilder + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + + + org.eclipse.wst.jsdt.core.javascriptValidator + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + auto,full,incremental, + + + + + com.qnx.tools.bbt.xml.core.bbtXMLValidationBuilder + + + + + + org.eclipse.wst.jsdt.core.jsNature + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + com.qnx.tools.ide.bbt.core.bbtnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.qt.core.qtNature + com.rim.tad.tools.qml.core.qmlNature + + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f034d2b --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +QMAKE_TARGET = RenamedTodo +PROJECT_DIR := $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))) +I18N_DIR := $(PROJECT_DIR)/translations + +include mk/cs-base.mk + diff --git a/RenamedTodo.pro b/RenamedTodo.pro new file mode 100644 index 0000000..f895c00 --- /dev/null +++ b/RenamedTodo.pro @@ -0,0 +1,6 @@ +APP_NAME = RenamedTodo + +CONFIG += qt warn_on cascades10 +LIBS += -lbbsystem -lbb + +include(config.pri) diff --git a/assets/.assets.index b/assets/.assets.index new file mode 100644 index 0000000..fba1c37 --- /dev/null +++ b/assets/.assets.index @@ -0,0 +1,50 @@ +1 +48 +AboutPage.qml +AppCover.qml +EditSheet.qml +FilterPage.qml +help.html +HelpPage.qml +humane.js +icons/123.png +icons/abc.png +icons/Add.png +icons/Capitalize.png +icons/Check.png +icons/Clock.png +icons/Clock_a.png +icons/Date.png +icons/Delete.png +icons/DownBox.png +icons/Funnel.png +icons/ic_bbm.png +icons/Info.png +icons/invoke.png +icons/Pencil.png +icons/PriceTag.png +icons/Recycle.png +icons/rtd_512_3-110.png +icons/rtd_512_3-144.png +icons/rtd_512_3-86.png +icons/rtd_512_3-90.png +icons/rtd_512_3-96.png +icons/rtd_splash_1440s.png +icons/rtd_splash_720s.png +icons/rtd_splash_768p.png +icons/Search.png +icons/Sort.png +icons/Undo.png +main.qml +SettingsPage.qml +TaskItem.qml +TaskPage.qml +VisualStyle.bright/Appointment.png +VisualStyle.bright/ArrowCircleAlt.png +VisualStyle.bright/PriceTag.png +VisualStyle.bright/Watch.png +VisualStyle.dark/Appointment.png +VisualStyle.dark/ArrowCircleAlt.png +VisualStyle.dark/PriceTag.png +VisualStyle.dark/Watch.png +Watch_a.png diff --git a/assets/AboutPage.qml b/assets/AboutPage.qml new file mode 100644 index 0000000..f70416a --- /dev/null +++ b/assets/AboutPage.qml @@ -0,0 +1,106 @@ +/* + * Copyright 2012-2018 Morgan McMillian + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import bb.cascades 1.0 + +Page { + ScrollView { + Container { + layout: DockLayout { + } + horizontalAlignment: HorizontalAlignment.Fill + Container { + horizontalAlignment: HorizontalAlignment.Fill + Container { + horizontalAlignment: HorizontalAlignment.Center + preferredHeight: 35.0 + } + Container { + horizontalAlignment: HorizontalAlignment.Center + Label { + text: "Renamed Todo" + textStyle.fontSize: FontSize.Large + } + } + Container { + horizontalAlignment: HorizontalAlignment.Center + Label { + text: "v" + appversion + textStyle.fontSize: FontSize.Small + } + } + Container { + horizontalAlignment: HorizontalAlignment.Center + Label { + text: "Copyright (c) Morgan McMillian 2012-2018" + textStyle.fontSize: FontSize.XSmall + } + } + Container { + horizontalAlignment: HorizontalAlignment.Center + Label { + text: "All rights reserved." + textStyle.fontSize: FontSize.XSmall + } + } + Container { + horizontalAlignment: HorizontalAlignment.Center + preferredHeight: 40.0 + } + Container { + horizontalAlignment: HorizontalAlignment.Center + Label { + text: "https://monkeystew.org/renamed-todo/" + textStyle.fontSize: FontSize.XSmall + content.flags: TextContentFlag.ActiveText + } + } + Container { + horizontalAlignment: HorizontalAlignment.Center + preferredHeight: 30.0 + } + Container { + horizontalAlignment: HorizontalAlignment.Center + preferredHeight: 30.0 + } + Container { + horizontalAlignment: HorizontalAlignment.Center + preferredHeight: 30.0 + } + Divider { + + } + Container { + horizontalAlignment: HorizontalAlignment.Center + preferredHeight: 30.0 + } + Container { + leftPadding: 10.0 + rightPadding: 10.0 + horizontalAlignment: HorizontalAlignment.Fill + Button { + text: "Email Support" + horizontalAlignment: HorizontalAlignment.Center + onClicked: { + _Taskslayer.getSupport(0) + } + } + } + + } + } + } +} diff --git a/assets/AppCover.qml b/assets/AppCover.qml new file mode 100644 index 0000000..add4eaf --- /dev/null +++ b/assets/AppCover.qml @@ -0,0 +1,103 @@ +/* + * Copyright 2012-2018 Morgan McMillian + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import bb.cascades 1.0 +import "humane.js" as HumaneDate + +SceneCover { + // SceneCover + property alias topList: topList + property bool empty + id: appCover + content: Container { + Container { + visible: empty ? false : true + ListView { + dataModel: ArrayDataModel { + id: topList + } + listItemComponents: [ + ListItemComponent { + Container { + layout: StackLayout { + } + Container { + layout: DockLayout { + } + horizontalAlignment: HorizontalAlignment.Fill + leftPadding: 10.0 + rightPadding: 10.0 + topPadding: 10.0 + Container { + layout: StackLayout { + orientation: LayoutOrientation.LeftToRight + } + Container { + minWidth: 50.0 + Label { + text: ListItemData.priority + textStyle.fontSize: FontSize.Medium + textStyle.color: Color.Blue + } + } + } + Container { + layout: StackLayout { + } + leftPadding: 30.0 + Container { + Label { + text: ListItemData.detail + multiline: true + textStyle.fontSize: FontSize.XSmall + textStyle.color: Color.Black + } + } + Container { + Label { + text: HumaneDate.humaneDate(ListItemData.dateCreated) + textStyle.fontSize: FontSize.XXSmall + textStyle.color: Color.Gray + } + } + } + } + Divider { + } + } + } + ] + } + } + Container { + layout: DockLayout { + } + visible: empty + verticalAlignment: VerticalAlignment.Fill + horizontalAlignment: HorizontalAlignment.Fill + opacity: 1.0 + Container { + verticalAlignment: VerticalAlignment.Center + horizontalAlignment: HorizontalAlignment.Center + topPadding: 100.0 + Label { + text: "no tasks" + horizontalAlignment: HorizontalAlignment.Center + } + } + } + } // end content +}// end SceneCover diff --git a/assets/EditSheet.qml b/assets/EditSheet.qml new file mode 100644 index 0000000..04d7a11 --- /dev/null +++ b/assets/EditSheet.qml @@ -0,0 +1,384 @@ +/* + * Copyright 2012-2018 Morgan McMillian + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import bb.cascades 1.0 +import bb.system 1.0 + +Sheet { + id: editSheet + signal saveTask(string text) + signal modifySetting(string setting, variant value) + property alias text: taskText.text + property alias textfield: taskText + property alias title: addBar.title + property alias pri: priority.selectedValue + property alias labels: labels + property bool displayed: false + property bool datenew + property bool newtask + property bool taskitem + Page { + id: addPage + titleBar: TitleBar { + id: addBar + title: "Add" + dismissAction: ActionItem { + title: "Cancel" + onTriggered: { + editSheet.close() + taskText.text = "" + priority.resetSelectedOption() + } + } + acceptAction: ActionItem { + title: "Save" + onTriggered: { + editSheet.close() + editSheet.saveTask(taskText.text) + priority.resetSelectedOption() + } + } + } + Container { + layout: StackLayout { + } + Container { + leftPadding: 10.0 + rightPadding: 10.0 + topPadding: 10.0 + bottomPadding: 10.0 + TextArea { + id: taskText + preferredHeight: 720.0 + } + Container { + id: toolbar + layout: StackLayout { + orientation: LayoutOrientation.LeftToRight + } +// background: Color.create("#262626") +// preferredWidth: 768.0 + Container { + leftPadding: 25.0 + rightPadding: 25.0 + minHeight: 81.0 + ImageButton { + defaultImageSource: "asset:///ArrowCircleAlt.png" + onClicked: { + taskText.preferredHeight = 200.0 + priority.visible = true + priority.expanded = true + toolbar.visible = false + } + } + } + Container { + leftPadding: 25.0 + rightPadding: 25.0 + minHeight: 81.0 + ImageButton { + defaultImageSource: "asset:///PriceTag.png" + onClicked: { + taskText.preferredHeight = 200.0 + labels.visible = true + labels.expanded = true + toolbar.visible = false + } + } + } + Container { + leftPadding: 25.0 + rightPadding: 25.0 + minHeight: 81.0 + ImageButton { + defaultImageSource: "asset:///Appointment.png" + onClicked: { + taskText.preferredHeight = 200.0 + duedate.visible = true + duebtn.visible = true + duedate.expanded = true + toolbar.visible = false + } + } + } + Container { + visible: newtask + leftPadding: 25.0 + rightPadding: 25.0 + minHeight: 81.0 + ImageToggleButton { + imageSourceDefault: "asset:///Watch.png" + imageSourceChecked: "asset:///Watch_a.png" + checked: datenew + onCheckedChanged: { + if (checked) { + modifySetting("datenew", true) + createToggleToast.body = "Date new tasks enabled" + } else { + modifySetting("datenew", false) + createToggleToast.body = "Date new tasks disabled" + } + displayed ? createToggleToast.show() : displayed = true + } + } + } + } + DropDown { + id: priority + title: "Priority" + visible: false + preferredWidth: 720.0 + onSelectedIndexChanged: { + //console.log("priority set to : " + selectedValue); + if (selectedValue == "-") { + taskText.text = taskText.text.replace(/\([A-Z]\)\s/, ""); + } else { + if (taskText.text.match(/\([A-Z]\)/)) { + taskText.text = taskText.text.replace(/\([A-Z]\)/, "(" + + selectedValue + ")"); + } else { + taskText.text = "(" + selectedValue + ") " + taskText.text; + } + } + priority.visible = false + toolbar.visible = true + taskText.preferredHeight = 720.0 + taskText.requestFocus() + } + onExpandedChanged: { + if (expanded === false) { + priority.visible = false + toolbar.visible = true + taskText.preferredHeight = 720.0 + taskText.requestFocus() + } + } + Option { + text: "-" + value: "-" + } + Option { + text: "A" + value: "A" + selected: editSheet.pri == "A" + } + Option { + text: "B" + value: "B" + selected: editSheet.pri == "B" + } + Option { + text: "C" + value: "C" + selected: editSheet.pri == "C" + } + Option { + text: "D" + value: "D" + selected: editSheet.pri == "D" + } + Option { + text: "E" + value: "E" + selected: editSheet.pri == "E" + } + Option { + text: "F" + value: "F" + selected: editSheet.pri == "F" + } + Option { + text: "G" + value: "G" + selected: editSheet.pri == "G" + } + Option { + text: "H" + value: "H" + selected: editSheet.pri == "H" + } + Option { + text: "I" + value: "I" + selected: editSheet.pri == "I" + } + Option { + text: "J" + value: "J" + selected: editSheet.pri == "J" + } + Option { + text: "K" + value: "K" + selected: editSheet.pri == "K" + } + Option { + text: "L" + value: "L" + selected: editSheet.pri == "L" + } + Option { + text: "M" + value: "M" + selected: editSheet.pri == "M" + } + Option { + text: "N" + value: "N" + selected: editSheet.pri == "N" + } + Option { + text: "O" + value: "O" + selected: editSheet.pri == "O" + } + Option { + text: "P" + value: "P" + selected: editSheet.pri == "P" + } + Option { + text: "Q" + value: "Q" + selected: editSheet.pri == "Q" + } + Option { + text: "R" + value: "R" + selected: editSheet.pri == "R" + } + Option { + text: "S" + value: "S" + selected: editSheet.pri == "S" + } + Option { + text: "T" + value: "T" + selected: editSheet.pri == "T" + } + Option { + text: "U" + value: "U" + selected: editSheet.pri == "U" + } + Option { + text: "V" + value: "V" + selected: editSheet.pri == "V" + } + Option { + text: "W" + value: "W" + selected: editSheet.pri == "W" + } + Option { + text: "X" + value: "X" + selected: editSheet.pri == "X" + } + Option { + text: "Y" + value: "Y" + selected: editSheet.pri == "Y" + } + Option { + text: "Z" + value: "Z" + selected: editSheet.pri == "Z" + } + } + DropDown { + id: labels + title: "Project or Context" + visible: false + preferredWidth: 720.0 + onSelectedIndexChanged: { + if (selectedValue != undefined) { + taskText.text = taskText.text + selectedValue + " " + } + labels.visible = false + toolbar.visible = true + taskText.preferredHeight = 720.0 + taskText.requestFocus() + } + onExpandedChanged: { + if (expanded === false) { + labels.visible = false + toolbar.visible = true + taskText.preferredHeight = 720.0 + taskText.requestFocus() + } + } + } + DateTimePicker { + id: duedate + title: "Due date" + visible: false + preferredWidth: 720.0 + } + Container { + id: duebtn + visible: false + layout: StackLayout { + orientation: LayoutOrientation.LeftToRight + } + Button { + text: "Nevermind" + onClicked: { + duedate.visible = false + duebtn.visible = false + toolbar.visible = true + taskText.preferredHeight = 720.0 + taskText.requestFocus() + } + preferredWidth: 350.0 + } + Button { + text: "Add date" + onClicked: { + if (taskitem) { + taskText.text = taskText.text + + "due:" + taskItem.ListItem.view.dataModel.formatDate(duedate.value) + " " + } else { + taskText.text = taskText.text + + "due:" + taskModel.formatDate(duedate.value) + " " + } +// taskText.text = taskText.text + +// "due:" + taskModel.formatDate(duedate.value) + " " + duedate.visible = false + duebtn.visible = false + toolbar.visible = true + taskText.preferredHeight = 720.0 + taskText.requestFocus() + } + preferredWidth: 350.0 + } + } +// Divider { +// } + } + } + onCreationCompleted: { + // TODO this + } + attachedObjects: [ + SystemToast { + id: createToggleToast + } + ] + } +} diff --git a/assets/FilterPage.qml b/assets/FilterPage.qml new file mode 100644 index 0000000..9b6e6ad --- /dev/null +++ b/assets/FilterPage.qml @@ -0,0 +1,105 @@ +/* + * Copyright 2012-2018 Morgan McMillian + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import bb.cascades 1.0 + +Page { + id: filterPage + property alias filterModel: filterModel + property alias warningtext: warningtext + signal resetFilter() + titleBar: TitleBar { + id: titleBar + title: " Filter List" + } + Container { + Container { + id: warningtext + leftPadding: 30.0 + topPadding: 30.0 + rightPadding: 30.0 + bottomPadding: 30.0 + visible: false + Label { + text: "There are no project or context tags in your task list to " + + "filter on. You can define a project tag by prefixing some text " + + "with the + symbol or a context tag with the @ symbol in your tasks." + multiline: true + textStyle.fontStyle: FontStyle.Italic + } + } + ListView { + id: filterList + dataModel: GroupDataModel { + id: filterModel + sortingKeys: [ "type" ] + grouping: ItemGrouping.ByFullValue + signal changeFilter(string filter, bool enabled) + } + listItemComponents: [ + ListItemComponent { + type: "listItem" + Container { + id: filterItem + layout: StackLayout { + } + Container { + layout: DockLayout { + } + horizontalAlignment: HorizontalAlignment.Fill + topPadding: 15.0 + leftPadding: 20.0 + rightPadding: 30.0 + Label { + text: ListItemData.title + } + CheckBox { + id: filterCheck + horizontalAlignment: HorizontalAlignment.Right + // TODO: checked: need it out of the taskModel + checked: ListItemData.checked + onCheckedChanged: { + //console.log(filterCheck.checked) + filterItem.ListItem.view.dataModel.changeFilter(ListItemData.title, filterCheck.checked) + } + } + } + Divider { + } + } + } + ] + function itemType(data, indexPath) { + if (indexPath.length == 1) { + return "header"; + } else { + return "listItem"; + } + } + } + } + actions: [ + ActionItem { + title: "Reset" + imageSource: "icons/Delete.png" + ActionBar.placement: ActionBarPlacement.OnBar + onTriggered: { + resetFilter(); + navi.pop(); + } + } + ] +} diff --git a/assets/HelpPage.qml b/assets/HelpPage.qml new file mode 100644 index 0000000..f06aa4c --- /dev/null +++ b/assets/HelpPage.qml @@ -0,0 +1,35 @@ +/* + * Copyright 2012-2018 Morgan McMillian + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import bb.cascades 1.0 + +Page { + id: helpPage + titleBar: TitleBar { + title: " Help" + } + Container { + layout: DockLayout { + } + ScrollView { + WebView { + id: webView + url: "local:///assets/help.html" + settings.defaultFontSize: 30 + } + } + } +} diff --git a/assets/SettingsPage.qml b/assets/SettingsPage.qml new file mode 100644 index 0000000..1ea50f5 --- /dev/null +++ b/assets/SettingsPage.qml @@ -0,0 +1,272 @@ +/* + * Copyright 2012-2018 Morgan McMillian + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import bb.cascades 1.0 +import bb.cascades.pickers 1.0 + +Page { + id: settingsPage + signal modifySetting(string setting, variant value) + property bool datenew + property bool windowsbreak + property bool autoarchive + property int sort + property string path + property string sync + property string dboxpath + titleBar: TitleBar { + title: " Settings" + } + ScrollView { + Container { + layout: StackLayout {} + Container { + topPadding: 15.0 + } + Container { + layout: DockLayout {} + horizontalAlignment: HorizontalAlignment.Fill + verticalAlignment: VerticalAlignment.Fill + Container { + verticalAlignment: VerticalAlignment.Center + leftPadding: 30.0 + Label { + text: "Date new tasks" + textStyle.fontWeight: FontWeight.Bold + } + } + Container { + rightPadding: 30.0 + horizontalAlignment: HorizontalAlignment.Right + ToggleButton { + checked: datenew + onCheckedChanged: { + if (checked) { + modifySetting("datenew", true) + } else { + modifySetting("datenew", false) + } + } + } + } + } + Divider {} + Container { + layout: DockLayout {} + horizontalAlignment: HorizontalAlignment.Fill + verticalAlignment: VerticalAlignment.Fill + Container { + leftPadding: 30.0 + verticalAlignment: VerticalAlignment.Center + Label { + text: "Windows line breaks" + textStyle.fontWeight: FontWeight.Bold + } + } + Container { + rightPadding: 30.0 + horizontalAlignment: HorizontalAlignment.Right + ToggleButton { + checked: windowsbreak + onCheckedChanged: { + if (checked) { + modifySetting("windowsbreak", true) + } else { + modifySetting("windowsbreak", false) + } + } + } + } + } + Divider {} + Container { + layout: DockLayout {} + horizontalAlignment: HorizontalAlignment.Fill + verticalAlignment: VerticalAlignment.Fill + Container { + leftPadding: 30.0 + verticalAlignment: VerticalAlignment.Center + Label { + text: "Auto archive" + textStyle.fontWeight: FontWeight.Bold + } + } + Container { + rightPadding: 30.0 + horizontalAlignment: HorizontalAlignment.Right + ToggleButton { + checked: autoarchive + onCheckedChanged: { + if (checked) { + modifySetting("autoarchive", true) + } else { + modifySetting("autoarchive", false) + } + } + } + } + } + Divider {} + Container { + layout: DockLayout {} + horizontalAlignment: HorizontalAlignment.Fill + Container { + leftPadding: 30.0 + rightPadding: 30.0 + DropDown { + title: "Sort by:" + preferredWidth: 1440.0 + onSelectedIndexChanged: { + modifySetting("sort", selectedValue) + } + Option { + text: "Priority" + value: 0 + selected: sort == 0 + } + Option { + text: "Due date" + value: 3 + selected: sort == 3 + } + Option { + text: "Line number" + value: 1 + selected: sort == 1 + } + Option { + text: "Text A>Z" + value: 2 + selected: sort == 2 + } + } + } + } + Divider {} + Container { + layout: DockLayout {} + horizontalAlignment: HorizontalAlignment.Fill + Container { + leftPadding: 30.0 + rightPadding: 30.0 + DropDown { + title: "File location:" + preferredWidth: 1440.0 + onSelectedIndexChanged: { + modifySetting("path", selectedValue) + } + Option { + text: "Local sandbox" + value: "data/todo" + selected: path == "data/todo" + } + Option { + text: "Local shared" + value: "shared/misc/todo" + selected: path == "shared/misc/todo" + } + } + } + } + Divider {} + Container { + layout: DockLayout {} + horizontalAlignment: HorizontalAlignment.Fill + Container { + leftPadding: 30.0 + rightPadding: 30.0 + DropDown { + title: "Storage:" + preferredWidth: 1440.0 + onSelectedIndexChanged: { + if (sync != selectedValue) { + modifySetting("sync", selectedValue) + } + } + Option { + text: "Local only" + value: "local" + selected: sync == "local" + } + } + } + } + Container { + layout: DockLayout {} + horizontalAlignment: HorizontalAlignment.Fill + Container { + leftPadding: 30.0 + rightPadding: 30.0 + topPadding: 10.0 + TextField { + id: dboxPath + hintText: "Dropbox location" + text: dboxpath + visible: sync == "dropbox" + onTextChanged: { + if (dboxPath.text.length > 0) { + modifySetting("dbox_path", dboxPath.text) + } + } + } + } + } + Divider {} + Container { + layout: DockLayout {} + horizontalAlignment: HorizontalAlignment.Fill + leftPadding: 30.0 + rightPadding: 30.0 + Button { + preferredWidth: 1440.0 + text: "Export sandbox files" + onClicked: { + exportPicker.open() + } + } + } + Divider {} + Container { + layout: DockLayout {} + horizontalAlignment: HorizontalAlignment.Fill + leftPadding: 30.0 + rightPadding: 30.0 + Button { + preferredWidth: 1440.0 + text: "Purge local sandbox" + onClicked: { + taskModel.promptPurgeSandbox() + } + } + } + Divider {} + } + } + attachedObjects: [ + FilePicker { + id: exportPicker + title: "Export" + mode: FilePicker.SaverMultiple + type: FileType.Document + viewMode: FilePickerViewMode.ListView + defaultSaveFileNames: ["todo.txt","done.txt"] + onFileSelected: { + console.log("FileSelected signal received : " + selectedFiles); + taskModel.exportFiles(selectedFiles) + } + } + ] +} diff --git a/assets/TaskItem.qml b/assets/TaskItem.qml new file mode 100644 index 0000000..34bafca --- /dev/null +++ b/assets/TaskItem.qml @@ -0,0 +1,179 @@ +/* + * Copyright 2012-2018 Morgan McMillian + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import bb.cascades 1.0 +import "humane.js" as HumaneDate + +Container { + id: taskItem + Container { + layout: StackLayout { + } + Container { + layout: DockLayout { + } + horizontalAlignment: HorizontalAlignment.Fill + leftPadding: 10.0 + rightPadding: 10.0 + topPadding: 10.0 + Container { + layout: StackLayout { + orientation: LayoutOrientation.LeftToRight + } + Container { + minWidth: 50.0 + Label { + text: ListItemData.priority + textStyle.fontSize: FontSize.Large + //textStyle.color: Color.Blue + textStyle.color: getPriorityColor(ListItemData.priority) + } + } + } + Container { + layout: StackLayout { + } + leftPadding: 40.0 + Container { + Label { + text: ListItemData.detail + multiline: true + textStyle.fontSize: FontSize.Medium + //textStyle.color: ListItemData.complete ? Color.Gray : Color.Black + textStyle.color: getDetailColor(ListItemData.complete) + } + } + Container { + layout: StackLayout { + orientation: LayoutOrientation.LeftToRight + } + topPadding: 5.0 + Container { + rightPadding: ListItemData.dateDue.length > 0 ? 10.0 : 0 + Label { + text: ListItemData.dateDue.length > 0 ? "Due " + + HumaneDate.humaneDate(ListItemData.dateDue) : "" + textStyle.fontSize: FontSize.XXSmall + textStyle.color: Color.Gray + textStyle.fontWeight: FontWeight.Bold + } + } + Container { + Label { + text: ListItemData.complete ? "Completed " + + HumaneDate.humaneDate(ListItemData.dateCompleted) : + ListItemData.dateCreated ? "Created " + + HumaneDate.humaneDate(ListItemData.dateCreated) : "" + textStyle.fontSize: FontSize.XXSmall + //textStyle.color: ListItemData.complete ? Color.LightGray : Color.Gray + textStyle.color: Color.Gray + } + } + } + } + } + Divider { + } + } + function getDetailColor(complete) { + if (complete) return Color.Gray; + switch (Application.themeSupport.theme.colorTheme.style) { + case VisualStyle.Bright: + return Color.Black; + case VisualStyle.Dark: + return Color.White; + } + return Color.Black; + } + function getPriorityColor(priority) { + // TODO make each priority a different color + switch (Application.themeSupport.theme.colorTheme.style) { + case VisualStyle.Bright: + return Color.Blue; + case VisualStyle.Dark: + return Color.Yellow; + } + return Color.Gray; + } + contextActions: [ + ActionSet { + title: ListItemData.detail + ActionItem { + title: "Edit" + imageSource: "icons/Pencil.png" + onTriggered: { + editItem.open() + editItem.newtask = false; + editItem.text = ListItemData.text +// editItem.pri = ListItemData.priority + editItem.labels.removeAll(); + for (var i = 0; i < taskItem.ListItem.view.dataModel.filters.length; i ++) { + var o = opt.createObject(); + o.text = taskItem.ListItem.view.dataModel.filters[i].title; + o.value = taskItem.ListItem.view.dataModel.filters[i].title; + editItem.labels.add(o); + } + editItem.textfield.requestFocus(); + } + } + ActionItem { + title: "Complete" + imageSource: "icons/Check.png" + enabled: ListItemData.complete ? false : true + onTriggered: { + taskItem.ListItem.view.dataModel.setValue(taskItem.ListItem.indexPath, "complete", true) + } + } + ActionItem { + title: "Undo Complete" + imageSource: "icons/Undo.png" + enabled: ListItemData.complete + onTriggered: { + taskItem.ListItem.view.dataModel.setValue(taskItem.ListItem.indexPath, "complete", false) + } + } + InvokeActionItem { + title: "Share" + query { + mimeType: "text/plain" + invokeActionId: "bb.action.SHARE" + } + data: ListItemData.text + } + DeleteActionItem { + title: "Delete" + onTriggered: { + taskItem.ListItem.view.dataModel.promptDelete(taskItem.ListItem.indexPath) + } + } + } + ] + attachedObjects: [ + EditSheet { + id: editItem + title: "Edit" + taskitem: true + onSaveTask: { + taskItem.ListItem.view.dataModel.updateTask(taskItem.ListItem.indexPath, text) + } + }, + ComponentDefinition { + id: opt + Option { + } + } + ] +} diff --git a/assets/TaskPage.qml b/assets/TaskPage.qml new file mode 100644 index 0000000..67d1ebe --- /dev/null +++ b/assets/TaskPage.qml @@ -0,0 +1,114 @@ +/* + * Copyright 2012-2018 Morgan McMillian + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import bb.cascades 1.0 + +Page { + id: taskPage + signal itemUpdate(int idx, string text) + signal setValue(int idx, string key, variant value) + signal delTask(int idx) + property alias title: titleBar.title + property string itemtext + property variant idx + property bool complete + titleBar: TitleBar { + id: titleBar + title: " Task" + } + Container { + layout: DockLayout { + } + Container { + topPadding: 30 + leftPadding: 30 + rightPadding: 30 + Label { + id: taskText + multiline: true + text: itemtext + } + } + } + actions: [ + ActionItem { + title: "Edit" + imageSource: "icons/Pencil.png" + ActionBar.placement: ActionBarPlacement.OnBar + onTriggered: { + editItem.open() + editItem.newtask = false + editItem.text = itemtext + editItem.labels.removeAll(); + for (var i = 0; i < taskModel.filters.length; i ++) { + var o = opt.createObject(); + o.text = taskModel.filters[i].title; + o.value = taskModel.filters[i].title; + editItem.labels.add(o); + } + editItem.textfield.requestFocus() + } + }, + ActionItem { + title: "Complete" + imageSource: "icons/Check.png" + enabled: complete ? false : true + onTriggered: { + setValue(idx, "complete", true) + navi.pop() + } + }, + ActionItem { + title: "Undo Complete" + imageSource: "icons/Undo.png" + enabled: complete + onTriggered: { + setValue(idx, "complete", false) + navi.pop() + } + }, + InvokeActionItem { + title: "Share" + query { + mimeType: "text/plain" + invokeActionId: "bb.action.SHARE" + } + data: itemtext + }, + DeleteActionItem { + title: "Delete" + onTriggered: { + delTask(idx) + navi.pop() + } + } + ] + attachedObjects: [ + EditSheet { + id: editItem + title: "Edit" + onSaveTask: { + itemUpdate(idx, text) + itemtext = text + } + }, + ComponentDefinition { + id: opt + Option { + } + } + ] +} diff --git a/assets/VisualStyle.bright/Appointment.png b/assets/VisualStyle.bright/Appointment.png new file mode 100644 index 0000000000000000000000000000000000000000..7ebf9d29fb89135500ec662e14c99287616b0084 GIT binary patch literal 493 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 Rz108!002ovPDHLkV1haVgvtN_ literal 0 HcmV?d00001 diff --git a/assets/Watch_a.png b/assets/Watch_a.png new file mode 100644 index 0000000000000000000000000000000000000000..250c82509ea45d2fbbdb9ca03d56bac2db39124e GIT binary patch literal 840 zcmV-O1GoH%P)Px#32;bRa{vGf6951U69E94oEQKA00(qQO+^RZ2m=-Y49+8wcmMzb+DSw~RCwC$ zoY9fmFc5}+7~Vq(l;F&`0AB}O2e<*}r~s%S#0}t7z;%H0?isiWLJ2M*4|0aPM1r|H z?@BWN|9Bp5r4Q|{R$2^D6h%=~j~c02Dx2>B5^+04`k)PQqG&4tkPUGqj_HhqNQi_; z5h5WHA|X^#T(97S5i3DE@iqvc5p;D^v$z5$q8>^-1JPjNvsiR8EXgxp`8 zc%m5#06bU#{&g+66=DAO(nq4{JF&R#QF0XNvv>q7(k+0>k!aT8LoAyo01L~LjYe>P zr6mB{ieI5@=HbS~vdKC({#O->G*{2bWi#vIqe@)vYbCBMe|z=<(75#(z@z2K6u>-O zcYdoA06zdPAZtgWiKb#%YSykd5{-C5n;>SHE!FN#?EAk1;zh!RhXL`jCrx}0WlVtg z2=O|=mJmNz6`4Jt2TdYdg*!)8gm-PCO$oSqm5fIBu@bKX%%zXJ;)i$}VC8do6OUll zj&kum@(wWGEsoJ91b{I^tWc!uPzE!O6ks0GfP8Lo>JNOT?G6<_tMdo#2L{m`Rn?ws zSFm3r++AV`MubR+gh+@tG!1BuUt)#0>#i+**WAgKnmag%tz{+dy8~2T0L>T_yrM6N zOAE*Zz`-L(TXX3Nz&1>X?#uE7K6(_*(OG8kmR#a0x4)QZDiB*uJMSi?1#sbrgJK7_ z{U#Q7Ikiw}|22uk_JwUEyV9gOWsh*T*i}L{UCpJn^eYWU$`gX%p~K9QNX}6BImSrX zwGJLP-YWgtvSpvU{Z~s%ts6ku+S$avtp|Wx&HERf_u`bz0eU|Qs#y#4?O;mgCS S#s^IR0000 + + Renamed Todo Help + + +

 

+
+ Q: What is the todo.txt file format? +
+

+ The todo.txt file is simply a plain text file that follows a specification + created by Gina Trapani and used in applications published by the Todo.txt Community. The todo.txt file is both human and machine readable by following a few simple rules. You can find more information including the specifications here. +

+
+
+
+ Q: How do I add filters? +
+

+ Filters are created automatically by special text identified in the tasks you create. The two kinds of text it looks for are projects and contexts. +

+ Project:  + Denoted by prefixing some text with "+"
+ Context:  + Denoted by prefixing some text with "@"
+

+ So for example the task "Contact Tom by @email to discuss the new +program" results in "@email" and "+program" added to the filter list. +

+
+
+
+ Q: What is the difference between "Local sandbox" and "Local shared" in the file location settings? +
+

+ Local sandbox:  + The todo.txt file is located within the application sandbox + storage space and is only accessible to this app. This is the + default location when you start the app for the first time and the best + option if you do not need or want your file accessible from any other + application or process.
+ Local shared:  + The todo.txt file is located within the shared application storage space + in "Shared/misc/todo". This location is accessible from any other + application. +

+
+
+
+ Q: Can I export my todo.txt list from the local sandbox? +
+

+ You can export the todo.txt and done.txt files from your local sandbox by + opening the "Settings" page in the pull down menu at the top of the screen + and pressing the "Export sandbox files". From there you will be prompted to + select an accessible location. +

+
+
+
+ Q: What happened to Dropbox support? +
+

+ Dropbox support has been temporarily removed from this open source edition. I plan to + rework a large portion of the sync code and re-introduce it along with support for + other cloud providers soon. +

+
+
+
+ Q: How can I get some additional help? +
+

+ For any feedback or questions you can send me email or visit us at monkeystew.org +

+
+

 

+ + \ No newline at end of file diff --git a/assets/humane.js b/assets/humane.js new file mode 100644 index 0000000..87fc202 --- /dev/null +++ b/assets/humane.js @@ -0,0 +1,150 @@ +/* + * Javascript Humane Dates + * Copyright (c) 2008 Dean Landolt (deanlandolt.com) + * Re-write by Zach Leatherman (zachleat.com) + * + * Adopted from the John Resig's pretty.js + * at http://ejohn.org/blog/javascript-pretty-date + * and henrah's proposed modification + * at http://ejohn.org/blog/javascript-pretty-date/#comment-297458 + * + * Licensed under the MIT license. + */ + +function humaneDate(date, compareTo){ + + if(!date) { + return; + } + + var testme = new Date; + compareTo = testme.getFullYear() + "-" + (testme.getMonth()+1) + "-" + testme.getDate(); + + var lang = { + ago: 'ago', + from: 'from now', + now: 'today', + minute: 'minute', + minutes: 'minutes', + hour: 'hour', + hours: 'hours', + today: 'today', + day: 'day', + days: 'days', + week: 'week', + weeks: 'weeks', + month: 'month', + months: 'months', + year: 'year', + years: 'years' + }, + formats = [ + [60, lang.now], + [3600, lang.minute, lang.minutes, 60], // 60 minutes, 1 minute + [86400, lang.hour, lang.hours, 3600], // 24 hours, 1 hour + [604800, lang.day, lang.days, 86400], // 7 days, 1 day + [2628000, lang.week, lang.weeks, 604800], // ~1 month, 1 week + [31536000, lang.month, lang.months, 2628000], // 1 year, ~1 month + [Infinity, lang.year, lang.years, 31536000] // Infinity, 1 year + ], + isString = typeof date == 'string', + date = isString ? + new Date(('' + date).replace(/-/g,"/").replace(/[TZ]/g," ")) : + date, + cIsString = typeof compareTo == 'string', + compareTo = cIsString ? + new Date(('' + compareTo).replace(/-/g,"/").replace(/[TZ]/g," ")) : + compareTo, + seconds = (compareTo - date + + (compareTo.getTimezoneOffset() - + // if we received a GMT time from a string, doesn't include time zone bias + // if we got a date object, the time zone is built in, we need to remove it. + (isString ? 0 : date.getTimezoneOffset()) + ) * 60000 + ) / 1000, + token; + + if(seconds < 0) { + seconds = Math.abs(seconds); + token = lang.from ? ' ' + lang.from : ''; + } else { + token = lang.ago ? ' ' + lang.ago : ''; + } + + /* + * 0 seconds && < 60 seconds Now + * 60 seconds 1 Minute + * > 60 seconds && < 60 minutes X Minutes + * 60 minutes 1 Hour + * > 60 minutes && < 24 hours X Hours + * 24 hours 1 Day + * > 24 hours && < 7 days X Days + * 7 days 1 Week + * > 7 days && < ~ 1 Month X Weeks + * ~ 1 Month 1 Month + * > ~ 1 Month && < 1 Year X Months + * 1 Year 1 Year + * > 1 Year X Years + * + * Single units are +10%. 1 Year shows first at 1 Year + 10% + */ + + function normalize(val, single) + { + var margin = 0.1; + if(val >= single && val <= single * (1+margin)) { + return single; + } + return val; + } + + for(var i = 0, format = formats[0]; formats[i]; format = formats[++i]) { + if(seconds < format[0]) { + if(i === 0) { + // Now + return format[1]; + } + + var val = Math.ceil(normalize(seconds, format[3]) / (format[3])); + + // Since the source is only passing a date don't reference hours, use today + if (format[2] == lang.hours) { return lang.today; } + + // Again, since it's only the date adjust the days value to round down + if (format[2] == lang.days) { + val = Math.floor(normalize(seconds, format[3]) / (format[3])); + } + + return val + + ' ' + + (val != 1 ? format[2] : format[1]) + + (i > 0 ? token : ''); + } + } +}; + +if(typeof jQuery != 'undefined') { + jQuery.fn.humaneDates = function(options) + { + var settings = jQuery.extend({ + 'lowercase': false + }, options); + + return this.each(function() + { + var $t = jQuery(this), + date = $t.attr('datetime') || $t.attr('title'); + + date = humaneDate(date); + + if(date && settings['lowercase']) { + date = date.toLowerCase(); + } + + if(date && $t.html() != date) { + // don't modify the dom if we don't have to + $t.html(date); + } + }); + }; +} diff --git a/assets/icons/123.png b/assets/icons/123.png new file mode 100644 index 0000000000000000000000000000000000000000..44235575c3f35df14033650ec706c6156703c89d GIT binary patch literal 2452 zcmZ`*eLU0q7ypJdiZ-csg-o8gSDq<(*w5JJXW8zRyOnur9vX^iLWt_-Ve`}wjp7== zn>>V(hp4b}cd5`2lk1^j*Hgm~_FMn|e&@W-=e*8&o!9HUKIe1J`*YGfF>XqVYKi~= zD4~!pIH|^d7m&R4e3FH>ma2UeoEsdd=~thZ8u9_|ZZ3f2J3oF=d0*;LxQ4`20N~(} z@3IdlVnU_P1JNiC#DQ@|#e*8ALw%?7q+zNk7w2DYd|D*NY5`aY(->1@Ym)NyS9ZSMpD^UC=!R^6)(L#Z?sKDT|&OFt+Awsa4KE zH;fgB4_vlr(}SU!M@I`=P720F;!^P;{lS~z^$(XAqTBw#8zqvhO}=C+saO{L|ETVl z?5d+-Y{H{SrsRRyhL(VdL%T(+@(2c86`EO6GjC}r`iz9%LeVE4SE;P1pdt+=)Gj5P zr&(nnXdno<12#98)7A!nd=l!b{XJrB!EwZ@NA<}P^Zl@5wG zEWDnLlZicisxmDV35Jw2kRa^Ag9i_v2qeninn=$D0V!rpc*Fg0kRMHH;-CM7mIbGz zGE{5@59wwBeS z(xB+7b4mIOSJN^)Za$}fOK7=EL}r4c5OURwt-p<(A72D(r?8KKBUfm+xQW-h%QY`d zDX^|(ZmTt>zu-D1#cabN_&M{=*F3HFBpDJug{MX{TUO%OfnZLcWWdRQCCCY;Iagan znrCXE=bbQU6f|&>n@>_eU=MMOxKXE1a-c{iJ<*#aX22)glTi~(@ zi}8`_Zdg@Fza1F<*u?#?_Uuz2;_gLZ8x^p<|P`Ai93b8y}j}GX3sNiS9hkS zrkr?$jM$Rtot>SQ!otE@A3grKrHzevp@kwi{f=V7RT;GGX$XFYS^UHn=3>6C{N3g2 zczt1LHKI9#18w9fe<9}UQrmo(#l^*Eqh{WY99Sqe{*k#T{^r}V*fiGBChd*gJ<Vx=hzTm$7zx_yx*%ZxpeSPOF&zkV~}utq7W>@6vgH0j0Fb;QB@JE)qWML>a7YKfv5UXHgdx?w4ZJ-~Ko0=)^z_QXQ~J0+vrJ<46`B?t+fK3* z+}09D9qI7=ZThutwN((_6&#sm`a5I0>0so}Vk6MInQU$1U6#> zPd#fVs57!!CDa3tK$UnYo}|kRTIz-tbucUDPqur`?qdy|fpy1@y004w1Oid<*%;+^ z@2Zahz-eXR968*-IxkV4ZA1}}`>0?@Bkw_l;XJj??W?`y!{+8@01MmP9l7(XDk9B& zR^FczkMGmBi5TA$Ntzj3S@7H08;>%K-TVo_1i zcKZqPV1-9k5Z>CK1}o7&nV_7)#!NOmh1uL_f}+{Iy!g8!pqiT zWMkrj9+Q$<2Fle*j(d?Ash&im?CoBtLbR{U#X6cwJi~(Bq;o&AEJihtC9sBt3FL1Z zi-IRVjyrWbD!?3+06!Y+=ql1sm-opzWV-2kUgp_wp%OiY`jL}13@A+%ZK1q2rw5~Eg2QAYrUg*qVuE~(o=wI>JB$I70{t@P$>s$!u`q*YKZMO_8b3$vCRZewL>XhWNlV7 z*rIjwLrIJxe+kf#ECF&z?5XE{35-J?A_UZvgj17K@0P7Mf1am7Zvt0K-L zu#FRU-Ad}Ukvmiih&RIGNXG(Fsbih>x5ZVe(+yOshsFX9_LQi$Q zIZ{>R!hssGYy~&N=AO#!R_Vh*Ci8i1F}4IG2z5N1LrG~ zxv0tX++Q_RA>RBSv{MeT;<`hZRER38;k8M&Urt_AIt!MJBEtk3FTx$qcX&bq3=8{L z#N71;m0%;|qGy-FUUx}4^I!L%Ar`pM&-eBvcRNkpyVaf7sOp9&(5TdRSVXpPRX>xl~LR&A!dYX7wNmnKSg}}Jf!2MGG E3m$)~;Q#;t literal 0 HcmV?d00001 diff --git a/assets/icons/Add.png b/assets/icons/Add.png new file mode 100644 index 0000000000000000000000000000000000000000..cdae0224eab0653004e36c47e1a3bd60b95276ac GIT binary patch literal 941 zcmV;e15*5nP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyt@ z3m*kNK%2n;00S*aL_t(|+U=aZZW~7s$7g3haN_YfBESKXK1HfDse_b$48w)rAkUG` zuV5pHTXz8hNP$$T7NF{Qn%$jAk)y*#x+5veOXL3o2oN~l-QJJ;F|)fQ5dZ)H00000 z006*e#ArTV6Nk}}!iHD{nGBYvrLFYl@ zLlZw!a3(&sOmSWs>d|LNrZG=_iYHlEtSa3lu~l5 z)#`_im&E687bKcBerj%ZHT_wMq$)c1WlM&ho>B?8TioO8s?6hd&!98*e1 z4@x;_a?a6av*BlH&ZlzU&@<3h}%5I`n#nq z^OFeNW-D{C+E(CpQRXsRU+xoV;k(YtXRMMTOmsn;}-P|nWIej=hDnb|D~ zrd5?hM2BH`JC5Vur4)b6EY4H|BQyVXvK{ly&CQ#;ySpMH_TTKFo_<7l_HxA)iA z*FR%)o)D2xYhB#8nHkkuNkkGP?ljMRo8wj_BsM&$fQ$taArTS*Btjx2LLz`fNQ6WH ziC?kAQ=Eus;z#4EO0`xhr7YSRHvI=gGs0Vu7=~f+L_|yezF@nbkQ>==+=N7C{&0VP z|C^aD@=|N1oO5O7e<1OH-V@Ou!!RsbBA7OLl9^Qk0000000000K=b?yECH_r{tF`X P00000NkvXXu0mjf0Y9gH literal 0 HcmV?d00001 diff --git a/assets/icons/Capitalize.png b/assets/icons/Capitalize.png new file mode 100644 index 0000000000000000000000000000000000000000..29aa3f9882746eea95056a5017666043d9eae7a8 GIT binary patch literal 2404 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 literal 0 HcmV?d00001 diff --git a/assets/icons/Clock.png b/assets/icons/Clock.png new file mode 100644 index 0000000000000000000000000000000000000000..26fe71f5d19ca87471f688728b80b1252d105526 GIT binary patch literal 4272 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 literal 0 HcmV?d00001 diff --git a/assets/icons/Delete.png b/assets/icons/Delete.png new file mode 100644 index 0000000000000000000000000000000000000000..acfc5d52ce4ede22b82782e13cadaf7b70c9e8cf GIT binary patch literal 2931 zcmV-(3yk!MP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyu5 z0UrqL747H%01ER-L_t(|+U=ZMP8&@YfKOkmyX{1N&C_@!LO+gofU^Vd0J8#M1q>@7 zSpm)pLRNsYg5UpRIYa}BkOC6Ig1+BsUiw%?r!T%^=XXgKRs?bR>vOMD2VlFlYrD2< zyS8hAOIU|ZP)geX&=LfpA&TOjAP67`FSo`R!`F3^BsTys0Dx=LGzb4kh?LS60CZ$o z-jijyEz2@Uk_4hCf+&i=0nCC-k_3_@fjEvKilR{zMg2IAzXHI8X_})y79ypz0RUY^ zQ4UpAZ7PZaS$I6aJdm6;0%Hu~IEExiAc`W0q6oq;gdhkm;yC_nn&!nH1CdhN6a?W! z)3mOts(|ohS^f=P89;={|4fo(ESafPB1i~=;5rC`Q`0ni8w-(A+DPFY5ki0v@*6w^ zR|IX6RiNS!h9UUA55Dg&9j34(fJcOo6J6IEgb?6WcM;$w0g5Uf1Oa%S2cGBkqbNFF zh9eRdEq#(CeK8E9t!Wyd`l8*N1{|vFi_K2>_gR=Im9Fc8>$=CLX?|Qwh?LS6A>`69 zjE1IZW9iG_eBu#f$$CqO@t_lrCuGS()WGvJP&N!9)w|dun6@Q76GtUtGxh-U$9Kg&;js2 z@s+~tXCO92QEW+)1pEt~RW{Dd3)b;-(N5a7J@S43!@MAcc^yctRy(WJYM^P_3+GX! zR;XHN^usWOFbprkF#HAp1JgA7RUs1qv_w(dQxv7GC`wCFlo$4wx54~gvg+-+E?AZ| zH%MV#2}FP>fmwjOx}sf5Lytia1fS;3GAN}@Q4|jeAzea9gAg(XTBZ>wk&6H+%((H6 zVHjWP^?D(|>{Cy{f$O^cFbq$tByPsY;K(qHLtWP!We+wB(s3MketsT=VfbMsX(Oey zb#rs``0((+9LHf%6tN^p7{8JvVNnz@&-2*R(-XVDzh^f$H;LaySqEH zEQ^6bQ<5Z56a{o$2g5Mhl+yn$b%Vp<@a)&GU+nq$Irk}}1iG%v z9v>gs?d>fa4u?mptf>6>@uPcxf6r{&W?>kXN+Rw#j$`I|9(#OzWIuoYWNDRY@sda> zZR@&zgqcXz3+G9oWmyNiySpD(1&~tO)imuK_cuwFgdSX$WgvuLlySZkh_Wo7>AGGD z5QACAalp3igH=>e^5Ru2c1)TkVz7=NbzN^!N{po@X1s_F?=WAdaB!aUPpi!=zE?AzVAaAh7iYbZhkJyGN`Hwgpk8Yq*0u} z7Vh&IK$#QRn=Bn^q38zs;V8nGMxp;mES+DBIle(g|p6XcXzkv`~EfB z#=MXRK~|}>Sf82|Q540!B3sCN=93YscIacR9h}@}Sb6QDk@<)_Kk{HMF%_aln!nFZ^R9gVDIg4W% z|0j8skkoz*HXUFJaa075Q|qZAHu3;wK?1;N(*a`QP;{J7)n!ozv9*kbqjdy`&LvM0 zvkqojh@*cHKmdS7mC%$Oe2HaGrmCd=hX5SgyQ=2WsU1sE89gK3txX5Wf1j%6tC=Ad zePHVL8=DTWEV0ORul1)^=LzB_kR)ku(*aUS8=@#Ss=CRtDPbi<(=hdeTv=ti&qK^gBSIvE zw2BIr>kKgc4u?hk<(aD-{h8uK(=o{*MSDjj}U!?4+%#-dCMFUtn{3(Ls))D4=N? z)a&�DzmDo9>%8Z`K+hrL?JO+6kVi=bfi>J?6ct>b+P|^&JI4@Zv-)PZ~8%gIcZD zet3BJvhDy=k9=O$XNkwbNs@f7l5;DMZM-s4 zbR3-Cau`g~pkE2mG|hqMdHphwc*u>fqRp)Vz*enRJJWT&vQ04U9Q!npeVyc&;y6A| zyS{Q8fcPvX@Amw<0MsY(KOA0>$*Mc>nkg#=T(E&0APajx*Dp!&xs#HVGkrp_=5`nIfC$ zc^s)vM-%Fzi3kiU2H^z_u*-QAt3=UkZ6U|-g1wK2%NtFinO z=SQyiz7IhV^usXx3^QKWrIfY=LD*MSwL=JLs;Y_wk;2glc>pcT>hJ9Ae3+HRyqCtu zAhT&yS%H%WiYa9nhJ!ec`)Pj<*6s$TX^ztBId)~VB}w{^EXyrLQJP$X`uNg%)gCaV zO92kzIG*c@?jpt)j0b4&s$JC#g)e?|0Y3|(Xa)oZ_1Rb1=mOrXaJL=6vaDW`B**i% z2QF%mMpIFgFNR@^V=;b+P*MDt9j1Zr%chZJhiObQL?fHdr4vbJwt-85h+%~w2xqlg zt&1Qhor#kj=feM6o~O^gFMCLQT@d3y&-0EK+Ci~|5Ti>7IpaqNWJg;qbMbS;__-5l zR4|C5=wQ*8mX=r0mzR`PiD^*nFndEV)wCo?S-A_ucA%kl{! zq>VL3Ud87by2h)0)={DNO#${8W5>(9thACQL`rE}lB7dC7~%)8@e`J^F!4QaAB)ER zW#Z70@B2N**r#RRu~`{J-irf3S5?)0jPbG|$|RFK^Wde@ckvn%Jzs66Yznj^Nzz_= zXQr8*tdy0+>};_(jt5Z`^%-N|0HFUGqflQJVv*XXZ;L7^qcoctt;0ax?b@#G+OF-| duI*aa^?wrDT(Liy87Tk&002ovPDHLkV1l%tYrFse literal 0 HcmV?d00001 diff --git a/assets/icons/DownBox.png b/assets/icons/DownBox.png new file mode 100644 index 0000000000000000000000000000000000000000..a3168c632de01f4a11895bb2f439bd78ec0c485c GIT binary patch literal 2482 zcmV;j2~GBiP)Px#24YJ`L;wH)0002_L%V+f000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2i*Y* z0U;^>MvFZF00}ZlL_t(|+U=ZMXdKrW$G`8)IcLt987Ycmq(E_0J5nPlR0_CP1vj)0 ztrKdZzNLlI2R}4@YWmR9zJ$_}6kI5UULH&c6ch`4}=4--Pt-2l-!$DMP}0l*)prlz{S^R$4w z8WTdEkWx-_&Vdk8l%?FFA}rlG2TCcZ*Xs{E=bi3@_`C%pGBYpv-vZ-xbcNdWjRBHo=@WDX)KrPh>EKQ+c&)mjJJ9N$=L zKk1zN9_RcHN-2b4IJvyM{Mmc&z4yYvAac&X9flzwqSsnuyH7Nm`adQnCSLDk{PX9}pTFy_yFLQ|Utx@S&N&JpP5{7> zZa8$j3oI@!-Wi7B!$>0D3zsfkx}&cUCnhEy<(%IZ1Oa&OL2LcrTCH|+x1?#cTJ5A#>K*4? z78Tq!G&J;R-yohjbA}5cjxok!L!TqLgxqF?J*?5)eW>06YW$4{^@HTHEoW zPY3}*$Yy~c2m;?)>kNXxbIuO|z^@o%;GBEkz`UL7HS=enlzK!&#uzZh4hta;13Ace29a|vV zAXcl@z~3^4_xd?dp8TmDW#AH z*z2ZLKW@}k7EcI4N+|%q7_`}gYS%YxYoOcfiS<*hbIH1ag~y3|30l$fq=WdPt?OM8 zlkPM!C_;2l0Q05)qAX}oAn737B^OtEYb`qGAm3_jXBW-Ils?<-J~Wn?w@70QDy8a5 zsk*fm+f5y_wkqdba?WMet{s#H2C>eW)O2 zuB)|%jg5`h4<0=DLMP)~yLRp4&3t#D8_Pg$U$!n6 z5_ZCIJ_4mmh$X}l;`XZ~dsTf2aq?+iub{T3ll{!AX}_#6-$KY@#BQ5g0FZ@AH?>;x zt%iQ2gS1cX?6b7a7?YhfgnGT+?UF+3^*Rtjz!>z%x-ML>OjwghK-uoZE{r1~GxP19C>(zy>UcGuq2=M|U z&Sb67JrUwGk7;bXN;V4A4L&5 z=T3OWUb}S9Eir%MfKrM=2%jVgNGYFKU0wZg z5!a|ztA~UTPe)Poxj2r2bH4c;%$`^i^Al+SiBS}Ne|2^B=iQ9IyuADoDdnG|D4LJs z7#L$WJxH{d*2GPa&4WZ3hM`ZAgeFPyt+lnaXV0BG7jAdl*Is*VERN%INs`C+{I{=4=hc6~cGAX6J$%Xro>J6-llb>K7WE{sB zMbVc>M@OGtT3Q-z$AyQ7hyR`=$+(o#hhYf$HLzc9JkU~DHrebL9p~I9Ndi$6J(48J z&#KkxzW3Wi;y6B?Szs83nB~obY7-2so|vCBr4%{mK8|CMQXUsVJXxt!_H7jhMp1Ms zj^q0>7alagfkMo?TpnaI{P|`SMJHZ)<(1()Kq=+PY!~i#7_%dC=XT>r0PsnYAR-1CMNbFViE+wd>DoUi34{$ z#P#(6og3J|Kf2KthQ3-e-rEe7-8PQvmKLh^=vC{)vI?uRq*iqSk=z`gfpq0MJm+9I;s we%h~~=%BEl1}s&oRH;&>N|h>As#J&iKTf7Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyt@ z3m_x6lQaMT00&k{L_t(|+U=WfXdPJ$sXB8XDax-Ozc*9Bc=K~Y%56&3%iveHuNt}E2Ew#`e@CX#mB1R6u$ z>)bo{%-nO2ADma-hGyCPotN(YLCA-^nK$#BbLO1;CjbtI!{Kl^91e%W;cz%!4Y8hs zrlzI>0O(?70RZ6pJ_sRp)Qwwf!CL!&2}0OPrP5gMxq|f^#LRC6fS-Gw_l__OAqavU z7d_TmFvfr}rV{{u001YpH4*^;YPH&Dq9}T@ySp2rC<4#(c8ow~1|k9}B}gg%&CKtq zR4U1~O9TM8diCn_eSLlJ@9OH}Fbu^`Noi{>Xsw}MuXBFMd=!X@tCzu&}hd`c-b zhloH#z|3va@-(l7neSF)B4Xe7pgM~^202mq?novr8H%StkrYTr! zU-9IN7HF*nB4R{@BuTDotsBM|2*Z$f?b;PYQS_(6B?16cDwQXslz&W;1c->6X;YNQ z)(B)~NYhkEDdT#*{*gG2KcH#9W#=aru|#$2)1WCz>?aESl_0|Nusq?F&t zn{aNuvF$1*M8sNap_F+?i}Hh;=O2oOT}>lq4f*{s37efyr0QvOA2EwU^F zYwea+>y`armSsXpiCLC?v0AO_Rnqv8C0H>FMbi4#V)M@B2VRV2rtjh*#P!odEz29z2*e8jWu&rRH;y zo7#l8z9NhZ)lxIXPMOegFHVQVE0*oMjoLX<8c`9Gq%Pi2wk@!^0Cw zsS`<(z-EuFTdQ&2RF4ZGPOSF%@$vD#QmOQl&d$zJ-}gBm&0rkIUxS^%%*@O)i;Ih_ zwYGVo;pXp+V6A0DFKX* ziECLWr~Vdi}+ff2h@JN24hERJmL}Rw|W55Cm+k z1u3OaNcv>)D>391v9^LS`w2*nK%a<>|y|=gb zU%kD(Z!DL~Yg+toooF@2Fd~X9%Wf0VgZZ@oU2)7Tno*ip;AJBE4kA7?FfcH?X^nnS zMW$A(eWI_g@9FODZZ4HdYl_B}QHhXJo+F|UCQ0%(Wunn zYmLHuWMUEVXM6VS`RnUiA`#soqAP2Wm>&mOmKj8Rz8x~E=tvYq1Z$nRZC2(i%dC@_ z5C1kYYxBC7c)#EzI*CrAljv{~okSkZmbUcTv)(=-+NcDysjn5W}7K6~K6fw^{j=!Hsb-DjO| z_r1F{L~AV&@vJfCF=NcRYPEW&U0*$gM`FGZ51!|NF$T2Oq_w_?h@Y)it1s?^7N<~& zxi~M5V@Q(ZmbLbuaU4HBG&J;&ozy25oz85noz+@@(^~u6!NI}v;8;6TQ&XLjlaszP o;cz${4u`|xa5x+e$NkIy01oTL=u*KYlK=n!07*qoM6N<$f~}LyasU7T literal 0 HcmV?d00001 diff --git a/assets/icons/Info.png b/assets/icons/Info.png new file mode 100644 index 0000000000000000000000000000000000000000..1e867c7e5a6716c85457307419e0407e0cb2bfbb GIT binary patch literal 4014 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 literal 0 HcmV?d00001 diff --git a/assets/icons/PriceTag.png b/assets/icons/PriceTag.png new file mode 100644 index 0000000000000000000000000000000000000000..df0988d4273806fdb6618ec916ff6ca04ca4f3c7 GIT binary patch literal 2087 zcmV+?2-x?DP)38>U19#du_}ZNnYD4gPbnjn^u~eG&ASqp&BtO z@5UNwW_0oVVP6)FH2d3c&i6ZKjs_r2nlx$Bq)C$|O`0de4a$k$zI|H~Me!#HAs!(F z9M|5dGsb{Y3Y1cbQhH%*Y-}a!a}x#u;Muchk)kN)6h%2A2m<1HKGgA)QgB_DuhnWl zymjl=_xJAIyY@^~;)M$r_yY$HoF|05g)!y@K>&nMsP|xuf$O?p+cp@6abtOT`OyCT z`zy}`#Odj2Y3tUlpAte&sHzH*B!M6ZZC}bkh@R(x<2YcNCew9&c6D`iV&A@fYeNlD z(=s^V^1h-dzsh7XkpOH3DM=C#LVytR zG9ly-`F#FcLj!SodRiiceAFpG##r;m^E~i84=AP0-}xYUo(D;iKvh-17{87&{(UzU z**A(aH8sTtn@CuI4HpDTX%k)$8bSyVLcsI4k5Hv6h&2*xT+#0DOxO!go@Ez5|-33ASy2%=7$TJFvoEwWLf?-A>`W_V-N%Z1VLD* zKlOSYOw$Bi*Kd@|(`!k%;Cd_UCXk5TC3H-b=@cQhv#|!QfCMuuWunn z>4B6|a2y8!;Bq#bHQPC6$BrGB9LLdv9ef>-Mh6cwKSxQAf!%oECR4dJN@=OxV~WM1 zRz^{qIaa`MLV+bJz04&PCEs;tLcwnRe8<(EUaomfOlap<| zndf;j&-35mI4+W@WFio!rl$BaXU2G#>l!~xK+MnMpO z5CW9azumicuZ9r%_xA1E-PYIU^Z8w>s$L<4Y>{QTIfw3Bh`C%Y)6kgH5jT+yAqK|C ze^{3FuVS(IF+%8nj4_Wf_5x$<2eK@m!5DAB7>8Dv#39DH9{4nnjYZejYPH&Hl+rq5 zYzZN>O%z3tBnc!*0-om~?2WEOAqG6~bP@ntK_Z0wF%l@H5&&%T8&GgLEb2rCF-8w; z8>A0P5QHbBInMKl1Y$SqfpNg>2AY4|W;2>tAhxUr_7q?gX6JY>`h8XpFV7~w~3 zV7p`D1VZQ~{{Ioy4uB0$Tsn6B$LR#sMC zjbd+NTM!F{0+-EZ&l!gCfoYm+wrzv!x&s5!9|QdgtX8YDi;IhgqS__fcJAK2%K-r7 z^Z9p5rP6A-TxPayGuL%P?^;MQ{;meYFxcYaA}bb)*JfvDxAg2kIyX1RH7fI1sZ?5C zU0v;KkU@ZtA3tWrV)1iL)4mzY%29_vk7A7fsH*A<{w}L9-!18d#+asgGKwY=8N>$2 zH!#M3?l+K|dEn^iXeqAGunOJTgfSjI}%W$|IBZz@9*i(<6J~fjxs5he!6x17q*bNqJ;1J+Lp5&*$HH z^ypE!)2>Y^ZGLBEX=#bh&(B{U=q}ua{=C}>$X1P+pP#=zGc)rXJZtIHBZtldllI7d z^1yxtdbCt3Eo}y}72v~%4=+XWn1Nvg`Nl>dHv-u0;{~3Did+tkku783=YvpzJzvi+ z6bi>wRsB>|)o+NR2#hiRAwZEma%Jct`dyn4@`)r#TPUT>w(Z$Ur7{uqOq)C$|O`0@m(xge#%vWmRNhput RhUowR002ovPDHLkV1m{m;K=|0 literal 0 HcmV?d00001 diff --git a/assets/icons/Recycle.png b/assets/icons/Recycle.png new file mode 100644 index 0000000000000000000000000000000000000000..128abbeb286a23809b0caf6cbfd9a9871fd499e4 GIT binary patch literal 3136 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 B?`{A9 literal 0 HcmV?d00001 diff --git a/assets/icons/Sort.png b/assets/icons/Sort.png new file mode 100644 index 0000000000000000000000000000000000000000..f4f573bd46f65cd542455edfb77eb6bc83a0408b GIT binary patch literal 1674 zcmV;526g#~P)RXyI(6#QsncaiDRqA<|0_8Vz#f2q zl~Vm%fJhH?-U)ynfDwS%3A&&UVBHOTlTuF47NSzB&lnp7K>%xQUnwM9=dcIOjda7$~LieIJxkFvh?+hwuB(oyFPU z355_NSB36w6GA{KMHq$Qcn&2iOOwDrAG>al}Z6JzYT-o~}Ha-kYI=RZ$jdCnH1QtFX&e(#0}A!OCif$#fZ zj6n#|BZN#kh=rx$oc~-`g>{IPAv3t9A=4NlA!H(i=+%eGh5=Nzbr1xjn}%2nlYtv1 z+d!;Zo?^)Kl~RM7g%|`u=?Q(`-^GxZYhw`&C)Y4!NP{XIaL)VHVX{k%s)0O7u0AQm zYChg&EnH`LPLZom3bC4xn*dzZ)|Z~E$qrSxG#@vGcul!_Ylyz@PpZRY-^WSUl&i^> zRoE9od}oa9U4=ETSgzM>d_@y9X@Y9JCqCT&=nZL863E>TJ+R{>Ee^^HY7o+HaLSZk3a$--f+ zMVh9_vJ82iBhT{>=W@TFrYWqoAI{^>k>|O4+H+C4dfndP#BF%TaSUti(n_rEs<|Dt z>i6mZvn)fFWh+4^N#btANGbIqrJOgZ>?S{J6=G2Z{Uk~7{{D_AidGI3*M^KSxZ&e@ zUU{+A3XY-(Ns^RRw+v*OrikMh0PX=i0C?Q>pIUY^9YD8q92{ct+Q)R46aD@B_tEpb zk*i7v#Z|M`diLeZmw%4YUh4vZvsA}w=baQqQTc{Jp63gdSgEd^RXm)y-?ohltMqll zrdjXLpFjO5ik2=dD>Ro+N=<_x7ziN{hT+=vuKxN+^?PnTbf4=SMV4h{_h_x( zq?C^bZ|4JR2;e&*q(>?JP-XS0>wvD>zIBityk*_vI;+r+)}AMxN>a*sk|bkmE%H1s zAy7)o!&$6VlX+Riy6@M|<8Dxzrbv=xCZ(KRJj4RzlQHJadDf=O!zNX2R`EjUkJg?i zo`d2z{$Y$k9LME));2(A_@gL-*7`|G`F2$hrIa(R^@}s@ZG)^%%0D z<6+ZlxOj+C%DFLSC(BcBV`I!rO8IiL5S!%cCi(d4Ay#wsrfO`Ok8c8Ek*haao~HTu zCLk8Mx_rvBZmXh6KE4@<9HCm-Jw#3EM@>utSnKE5f4E>|04 zX3p}YX}WhlJ{rX83rp^BFFPG-Ph^#nBpJJEOp*j~9PgEnj|S0Qs4-^Yh@z;v{di2v zGu2v`*P*q31Mt-L-)eQ=*%*U7&k@HlJkMJQ_@~O%@9*#5lO*XC?c9o`IV8j>fLYHwY=~0Ixl-zvwRQwxuY7#-QcC@IX|FJ!Bg9@up;M<$ojP^u)TvXaPPeK50c>L2 Uq95b87XSbN07*qoM6N<$f&jiL{{R30 literal 0 HcmV?d00001 diff --git a/assets/icons/Undo.png b/assets/icons/Undo.png new file mode 100644 index 0000000000000000000000000000000000000000..1b8dcd63352e9ebe631300d711da88771965cdfa GIT binary patch literal 2436 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 z zonHSTe97Tc2u_pEd} z>&ir@TCFnQqX=z@_|PV_*=&?Ip~p0`g}@yB=0SrT1=K8=_=_gAUaxGtq;bjwF;F84ps{v(=$yF`+x!|p0YbURwn1#CF0xI{M5obc zFyE7i?B#N)tpOR8i6o9MvWr0eh-`u~qHA9j*^9;ER>LxtQRK~LGgM>~D5WCX zH@c6^HkQnZY!jz*XpNiC=L21h!qg22X;DtlE^3^PjRYGYeh|1!3Re6A!a|)0hCEv|YxI|a-Cf}wov%ovLlH=Rypi>KRew}+V#-5 zKwZ<>?f3iE0#pi->>v4;I9hEC`-9nEu>c|r5CIVo0TBj>fM}+D3ormI|I_sW*deR{ O0000Ntz?D5Po&++@ie%WX5HD~>2UA}LvH6%%rBuSDaNs=T` z0+UinXPl31sK&JlC#070%)pL1ftx~VQj%k%3-=4$nPXySOvd+h0;_l#y{V=gr(7v*1Xd%QIWjf1PUYTdA#er8rKZ-C$XhK0 zeiNZi(u9-nMhk)4Gb?G|0$T~J;Hj8wk|twdt1jH%ji;olV#cpH z_#BMt@@I?>ft3;hH{sNw*h*&M=cvSwcn!Dd&IWjY3*1{mUuAo9YBFJ5i znFAOD%eKHO9*K8`WXAAOi;C^VUs#O=9hBQsau)8tJ|F6{aW9@}Q^~#%`bWfgr?e^a zrVa%DhAW2447w1zOIEyscX4ri3H6Jl3px;3#nZzr6q&90zDBd_JKTj6J8Xefd}f#~ zvQAUm->7sbuK>?WgdU99(Y+Kt!g-l_g&(KCt`J66`M1kH=}fC~$rU5ppYeqc9G z3+%;9F;4!_;k)->YnT3yp7=sXH{9P5t$j*}ekk(yH3gGqPba-}FpgZTjxP0a$>$%4 z!1`dY7SBcowmw?hzJV4xSm##0jisyS@o$UgK8#B3K8TZPUyP%bZU`Jqi6To`h$Z;D z;O|@27JGj>hyu^St$0rDH!bsZVZ&>%Pf%6xAntEyZGAC*t{OnuBMQd7R!oQl;g`tc zAC3v+%tKvbKg)4T$b+xc7Fq`q-_D2-rAY3`g2>?pwIj$&;@(QNv))TXaJw@8cZt+C zC8}DNy3n?mp zVna4IMs1U;sC7+=Y^T1JAA{p1Ns=TPx#32;bRa{vGf6951U69E94oEQKA00(qQO+^RZ2m=oy3;h}EMF0Q*C3HntbVF}# zZDnqB07G(RVRU6=Aa`kWXdrWMZDk-wNlj3BAYyW1X>Q_OZ%hCH4nj#pK~#9!?VW9G zTjzDhf6wKcDC*4;^}N-i?Iv^(hkEg3>dHv z`&eM8KkUQM4%?S~88!^4+cnE#XQ^WpNVCLlR>id|#daD?r1&CIq$u)|_vP%v6-n8( zBZ{IVQo4V@fDIUw`26oV=YP&~&bf*WoH%j9DmAMoO$9UwqjMBY$JeRqC- zJ_(>UNQ(g90$y;>sZH4vK`9jzky8r`3vZ|sCr)^Qe-V)v0F+WvCDcXRS)LM+f>P>X z&*0$Tqrl%OrCie58wwDmR6s>xE&c&V)r<9usxEANaCC-IQ+<`kyw`$TN1dj%pdU=Y~ORHor zW>H>6>1JtniQBmAaZkTV3_m)|+>=2>jQZEy{ukZr7O~f9@lq|IG400J)>V^ z^5sd!o*V-Ku>?Vw_`L~i!zO<@k8Rjg(iPWLwhIDd0gnIqae9vTAhv*j(v(A>5{`c5 zD2v)6c`c9Ff{`&?;`ST;5B4+r>MXuNAK0K!HDRKZazc-$h&&TP^J^%jC{k=Gc`k9= zjc30z%;bwsJQG_S(r$}1N-1oy@%p`teQ^v=mj`|fx=*K^D7(b%HO8JABYHB5r`zLL z)g4Hyk%vMMG{45kVGn8x&^DjiGqBOa z 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 X3Y~2S46ZZm00000NkvXXu0mjfl-XmL literal 0 HcmV?d00001 diff --git a/assets/icons/rtd_512_3-144.png b/assets/icons/rtd_512_3-144.png new file mode 100644 index 0000000000000000000000000000000000000000..74ee9ebae33cf66ef5a7eb72231978e57f866a85 GIT binary patch literal 4529 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 P00000NkvXXu0mjfu=Kwd literal 0 HcmV?d00001 diff --git a/assets/icons/rtd_512_3-86.png b/assets/icons/rtd_512_3-86.png new file mode 100644 index 0000000000000000000000000000000000000000..780d57251165ad49ba7d6146b7ba0a5b05faf961 GIT binary patch literal 2649 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 Hu0mjf%p?>n literal 0 HcmV?d00001 diff --git a/assets/icons/rtd_512_3-90.png b/assets/icons/rtd_512_3-90.png new file mode 100644 index 0000000000000000000000000000000000000000..a34ac59b603334c98e3a44f54c1ea5ceace8a8db GIT binary patch literal 2885 zcmV-L3%c})P)Px#32;bRa{vGf6951U69E94oEQKA00(qQO+^RZ2m=oz2z?8Sz5oCKC3HntbVF}# zZDnqB07G(RVRU6=Aa`kWXdrWMZDk-wNlj3BAYyW1X>Q_OZ%hCH3Z_X!K~#9!?VVX{ zTxS`Epa0C6u{|^1#&+X4^>~Rr*@&C2RH8ztfLJbCfrQ$o5-B~ z?|HxX`~L4g767B8qXO6s+zVVQgix`foRB~ecmjCk)TvXN7#$rILWmy%k68FrC0++U zZR_st9+Of&C4`WGuyCn(3;=dTN_npk0t@6S>WGy0DME;ArIZ#LRm52c(X2=*)$@$D zqBa_KKh1>e2y@ zZU?)6yc>tdLGLGfnK&?k9@I&kPFRetRP=nbhwFcRJ@!sJGAB`;Dp%ieHO;-vwDh-F z$*>aP`=*brU*3w85)2TEz>o$lJuM7q(CU* zJRk~EO4L@Bp?ijKjks_QIm_;CUU7`JxoqtE!7e)YbRrFjK)eq`p$L$mx>W{0KS;-( z4xHZdz`mk7cWRr;*iXl3x~j4{T}ZVxd{#nqOW+%hfHWCa)qF zYlXyQu+!_rJ>*84(h!OuyOgznzOWG4@vR-Whux;LC=%qnjO3-n-eIS6PbZmZhMb-w zr{};Z0BDcLvtJ0&ut4wl&JNo5w3o!>OX_x$Lffu3932i)b196Bfsrz-je0wQXmT2^fW$A|&uGP=;JwR>qAEpKX;MmLP7-)3K*Q2A$bdjU}*o4xl(ezOfHzsSxMlx0is8v=x6nsgIv*M zIQH`~?45RI{x-wxKWEYXmCfYcAL_~rG1%geyN0o>c&*gMJ_gWdMOGW?}sI&bR4Ip{>#ihHo$ zyS>;{TS1axNYnB~k3|VRA0ib_nGbg(`2SK4vUk|=J?KN&&Fp`v)r|Z~h1#Yvv~P&k z9j&-VTm^&O_nAJNUgxS0ay7Y7gn|~<2)z^{8_RAOkV^vE;c>A0C%aMG)S~(fQc8yJ z8OC#y2iJ%TrFrd3H*IRdyVqM#`!kklVbBNGb8&<)ve+1Lu%))d`=LEiH84(!Elgh;{lGNP;f}NzbRzgO{fu zsSKkP*!kE_+P1Y7-D9{EIDNPGkxgU~HbMMk{338h9vDH`Og68znw^)7#s4l6JrYGb ztC5T6*oaXOqX)k*NZYnHFhD_}9PgcHw&GCm?)74Cx6|TnS!Qkbhr4kPufH^vCx{l% z2)+;`HIpiOX1SJ8(AaJ=oFsZUij)%9fXnpD(%e{6jt^IC3a#5)iI2xYfRQp7d2j@^ zRb4sn8mG@hGx(qMlZ|K5{rZM(h!q5MHl8IJN)mZ9!ql@|ywIWP0OocoL(dqX&f$Hy7 z_@DHXnoDiSqNFB3=OZhe?K$B*V!KS(MZi=zRE} z^mFXH$IwC=D3r|Zyvxw1bQa!TARS3>h_+|ZKv#2%vNoY{=>9`299%FTX`bChF+o8H zLEz~CnOKHoC`mm=O?G9S{Mkt+4@@G3SyC4Yc3v|4&-lqiGw1=GdX1WGx)1*;%%S@a zk;~-FesqDCT|Bx-{B)djBwf(%rz@J#`Ot$phre+cJ*b;9a*2nWw{k|(;M`x%nN9q2 zDe5_D{so$3Fv*dJj}SW*GYb@XX)Aa3H)qK#WYGK?^&XeyQ$IO9$MHvx6FV9+9f_37 zx}ERJ%^#d68BCIzOVwluu_1v5b9(5+k4`Z6uepn>K>?X~hPl`0$ZA>AvuPS3F6$R) zWLh%*i*X_cBW9!j{1j5?r4X4|#@yG}Ah97f-H-ojoao^wLI@)NiLi8h$=s~dKwlx+ z5Z_cX(gw#LJI?IuvrIldiIkG`e40iI;q&qu1~ay6lX$KKOkZ3Kr{g z_BHBt)SBJ(@L;Q28P*Dby0CZEyh%&9Ys6?PYQ$(Os+bg(hHAM*V3g*95&ih`A-j$IHc^=P%l=42?{QP{zwjU j6hesCfX|MPk01L#@H7l$$#GSH00000NkvXXu0mjfqU?S$ literal 0 HcmV?d00001 diff --git a/assets/icons/rtd_512_3-96.png b/assets/icons/rtd_512_3-96.png new file mode 100644 index 0000000000000000000000000000000000000000..97a570592158538fce5576970cf7d2d9d4617333 GIT binary patch literal 3091 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 literal 0 HcmV?d00001 diff --git a/assets/icons/rtd_splash_1440s.png b/assets/icons/rtd_splash_1440s.png new file mode 100644 index 0000000000000000000000000000000000000000..a0331c77a9f3051976c7e6ebbb55e08cc8f918b5 GIT binary patch literal 26047 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 literal 0 HcmV?d00001 diff --git a/assets/icons/rtd_splash_720s.png b/assets/icons/rtd_splash_720s.png new file mode 100644 index 0000000000000000000000000000000000000000..fba0bc1e46560fdba356a64be973335f349faecc GIT binary patch literal 16929 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 literal 0 HcmV?d00001 diff --git a/assets/icons/rtd_splash_768p.png b/assets/icons/rtd_splash_768p.png new file mode 100644 index 0000000000000000000000000000000000000000..0895f2469aa0a34f0a1915eb5bef58cedf7f2720 GIT binary patch literal 17342 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 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import bb.cascades 1.0 +import com.monkeystew.taskmodel 1.0 + +NavigationPane { + id: navi + property string appversion + property variant coverpage + Menu.definition: MenuDefinition { + helpAction: HelpActionItem { + onTriggered: { + var page = helpPage.createObject() + navi.push(page) + } + } + settingsAction: SettingsActionItem { + onTriggered: { + var page = settingsPage.createObject(); + page.modifySetting.connect(taskModel.modifySetting) + page.datenew = taskModel.setting("datenew", false) + page.windowsbreak = taskModel.setting("windowsbreak", false) + page.autoarchive = taskModel.setting("autoarchive", false) + page.sort = taskModel.setting("sort", 0) + page.path = taskModel.setting("path", "data/todo") + page.sync = taskModel.setting("sync", "local") + page.dboxpath = taskModel.setting("dbox_path", "/todo/todo.txt") + navi.push(page) + } + } + actions: [ + ActionItem { + title: "About" + imageSource: "asset:///icons/Info.png" + onTriggered: { + var page = aboutPage.createObject() + navi.push(page) + } + } +// ActionItem { +// title: "Invite" +// imageSource: "asset:///icons/ic_bbm.png" +// onTriggered: { +// _Taskslayer.sendBBMInvite() +// } +// } + ] + } + Page { + id: mainPage + titleBar: TitleBar { + id: titleBar + title: " Renamed Todo" + visibility: ChromeVisibility.Default + } + Container { + Container { + id: searchContainer + visible: false + layout: StackLayout { + orientation: LayoutOrientation.LeftToRight + } + preferredHeight: 120.0 + //background: Color.create("#0098F0") + background: mainPage.getSearchBackground() + Container { + verticalAlignment: VerticalAlignment.Center + leftPadding: 15.0 + rightPadding: 10.0 + TextField { + id: searchField + hintText: "Search" + onTextChanging: { + taskModel.search(searchField.text); + } + } + } + Container { + maxWidth: 220.0 + verticalAlignment: VerticalAlignment.Center + leftPadding: 10.0 + rightPadding: 15.0 + Button { + text: "Cancel" + onClicked: { + titleBar.visibility = ChromeVisibility.Default + searchContainer.visible = false + searchField.text = "" + } + } + } + } + Container { + horizontalAlignment: HorizontalAlignment.Fill + Container { + id: appliedFilters + layout: DockLayout { + } + visible: false + horizontalAlignment: HorizontalAlignment.Fill + Container { + background: Color.create("#333333") + horizontalAlignment: HorizontalAlignment.Fill + Label { + id: filterList + text: taskModel.activeFilters() + textStyle.color: Color.White + textStyle.fontSize: FontSize.XSmall + } + } + } + } + Container { + id: sortdropdown + horizontalAlignment: HorizontalAlignment.Center + visible: false + DropDown { + id: sortselection + title: "Sort" + onSelectedIndexChanged: { + if (selectedValue != undefined) { + taskModel.sort = selectedValue + sortdropdown.visible = false + } + } + Option { + text: "Priority" + value: 0 + } + Option { + text: "Due date" + value: 3 + } + Option { + text: "Line number" + value: 1 + } + Option { + text: "Text A>Z" + value: 2 + } + } + } + ListView { + id: listView + dataModel: taskModel + listItemComponents: [ + ListItemComponent { + TaskItem { + // see TaskItem.qml + } + } + ] + onTriggered: { + var chosenItem = taskModel.data(indexPath) + var page = taskPage.createObject(); + page.itemUpdate.connect(taskModel.updateTask) + page.setValue.connect(taskModel.setValue) + page.delTask.connect(taskModel.promptDelete) + page.itemtext = chosenItem.text + page.complete = chosenItem.complete + page.idx = indexPath + navi.push(page) + } + /*leadingVisual: TextField { + * id: searchField + * onTextChanging: { + * // + * } + * }*/ + } + } + attachedObjects: [ + TaskModel { + id: taskModel + }, + EditSheet { + id: addNew + onSaveTask: { + taskModel.addFullTask(text) + } + }, + ComponentDefinition { + id: taskPage + source: "asset:///TaskPage.qml" + }, + ComponentDefinition { + id: filterPage + source: "asset:///FilterPage.qml" + }, + ComponentDefinition { + id: settingsPage + source: "asset:///SettingsPage.qml" + }, + ComponentDefinition { + id: aboutPage + source: "asset:///AboutPage.qml" + }, + ComponentDefinition { + id: helpPage + source: "asset:///HelpPage.qml" + }, + ComponentDefinition { + id: appCover + source: "asset:///AppCover.qml" + }, + ComponentDefinition { + id: opt + Option {} + } + ] + actions: [ + ActionItem { + title: "Add" + imageSource: "asset:///icons/Add.png" + ActionBar.placement: ActionBarPlacement.OnBar + onTriggered: { + addNew.open(); + addNew.newtask = true; + addNew.datenew = taskModel.setting("datenew", false); + addNew.modifySetting.connect(taskModel.modifySetting); + addNew.text = ""; + addNew.labels.removeAll(); + for (var i=0; i < taskModel.filters.length; i++) { + var o = opt.createObject(); + o.text = taskModel.filters[i].title; + o.value = taskModel.filters[i].title; + addNew.labels.add(o); + } + addNew.textfield.requestFocus(); + } + }, + ActionItem { + id: searchButton + title: "Search" + imageSource: "asset:///icons/Search.png" + ActionBar.placement: ActionBarPlacement.OnBar + onTriggered: { + if (searchContainer.visible) { + titleBar.visibility = ChromeVisibility.Default + searchContainer.visible = false + searchField.text = "" + } else { + searchContainer.visible = true + searchField.requestFocus() + titleBar.visibility = ChromeVisibility.Hidden + } + } + }, + ActionItem { + title: "Filter" + imageSource: "asset:///icons/Funnel.png" + ActionBar.placement: ActionBarPlacement.OnBar + onTriggered: { + var page = filterPage.createObject(); + if (taskModel.filters.length <= 0) { + if (appliedFilters.visible) { + taskModel.resetFilter() + } else { + page.warningtext.visible = true + } + } + page.filterModel.insertList(taskModel.filters); + page.filterModel.changeFilter.connect(taskModel.changeFilter); + page.resetFilter.connect(taskModel.resetFilter); + navi.push(page); + } + }, + ActionItem { + title: "Sort" + imageSource: "asset:///icons/Sort.png" + onTriggered: { + sortdropdown.visible = sortdropdown.visible ? false : true + sortselection.resetSelectedIndex() + } + }, +// ActionItem { +// title: "Sort by priority" +// imageSource: "icons/Capitalize.png" +// onTriggered: { +// taskModel.sort = 0; +// } +// }, +// ActionItem { +// title: "Sort by line" +// imageSource: "icons/123.png" +// onTriggered: { +// taskModel.sort = 1; +// } +// }, +// ActionItem { +// title: "Sort by text (a>z)" +// imageSource: "icons/abc.png" +// onTriggered: { +// taskModel.sort = 2; +// } +// }, +// ActionItem { +// title: "Sort by due date" +// onTriggered: { +// taskModel.sort = 3; +// } +// }, + ActionItem { + title: "Archive" + imageSource: "asset:///icons/DownBox.png" + onTriggered: { + taskModel.archive(); + } + }, + ActionItem { + title: "Reload" + imageSource: "asset:///icons/Recycle.png" + onTriggered: { + taskModel.refresh(); + taskModel.setView(); + } + } + ] + onCreationCompleted: { + taskModel.refresh(); + taskModel.setView(); + _Taskslayer.addNewTask.connect(newTask) + _Taskslayer.searchTaskList.connect(searchTasks) + taskModel.listUpdated.connect(listUpdated) + coverpage = appCover.createObject(); + coverpage.topList.append(taskModel.tododata) + if (taskModel.tododata.length > 0) { + coverpage.empty = false + } else { + coverpage.empty = true + } + Application.cover = coverpage + console.log(themeStyleToString(Application.themeSupport.theme.colorTheme.style)) + } + function searchTasks(data) { + searchContainer.visible = true + searchField.requestFocus() + searchField.text = data + titleBar.visibility = ChromeVisibility.Hidden + } + function newTask(data) { + addNew.open(); + addNew.newtask = true; + addNew.datenew = taskModel.setting("datenew", false); + addNew.modifySetting.connect(taskModel.modifySetting); + addNew.text = data; + addNew.textfield.requestFocus(); + } + function listUpdated() { + coverpage.topList.clear() + coverpage.topList.append(taskModel.tododata) + if (taskModel.tododata.length > 0) { + coverpage.empty = false + } else { + coverpage.empty = true + } + } + function themeStyleToString(style) { + switch (style) { + case VisualStyle.Bright: + return "Theme: Bright" + case VisualStyle.Dark: + return "Theme: Dark" + } + return "Theme: UNKNOWN :(" + } + function getSearchBackground() { + switch (Application.themeSupport.theme.colorTheme.style) { + case VisualStyle.Bright: + return Color.create("#0098F0") + case VisualStyle.Dark: + return Color.create("#262626") + } + return Color.Gray; + } + } + onPopTransitionEnded: { + page.destroy() + taskModel.setView() + filterList.text = taskModel.activeFilters() + appliedFilters.visible = taskModel.activeFilters().length > 0 ? true : false + } +} diff --git a/bar-descriptor.xml b/bar-descriptor.xml new file mode 100644 index 0000000..d0a35e8 --- /dev/null +++ b/bar-descriptor.xml @@ -0,0 +1,118 @@ + + + + + + + + com.monkeystew.RenamedTodo + + armle-v7 + RenamedTodo + + + Qnx/Cascades + armle-v7 + RenamedTodo.so + + + armle-v7 + RenamedTodo + + + x86 + RenamedTodo + + + + Renamed Todo + + + 0.9.0 + + + 1 + + + + + + The RenamedTodo application + + + + + + The Renamed Todo applicationn + + rtd_512_3-86.png + rtd_512_3-90.png + rtd_512_3-96.png + rtd_512_3-110.png + rtd_512_3-144.png + + + rtd_splash_1440s.png + rtd_splash_720s.png + rtd_splash_768p.png + + gYAAgP-_4D6fs0QDWOhZdtQjf2I + Morgan McMillian + + + + + + true + none + + + + + + assets + + + + + + rtd_512_3-86.png + rtd_512_3-90.png + rtd_512_3-96.png + rtd_512_3-110.png + rtd_512_3-144.png + rtd_splash_1440s.png + rtd_splash_720s.png + rtd_splash_768p.png + + + run_native + + + diff --git a/config.pri b/config.pri new file mode 100644 index 0000000..848532f --- /dev/null +++ b/config.pri @@ -0,0 +1,134 @@ +# Config.pri file version 2.0. Auto-generated by IDE. Any changes made by user will be lost! +BASEDIR = $$quote($$_PRO_FILE_PWD_) + +device { + CONFIG(debug, debug|release) { + profile { + CONFIG += \ + config_pri_assets \ + config_pri_source_group1 + } else { + CONFIG += \ + config_pri_assets \ + config_pri_source_group1 + } + + } + + CONFIG(release, debug|release) { + !profile { + CONFIG += \ + config_pri_assets \ + config_pri_source_group1 + } + } +} + +simulator { + CONFIG(debug, debug|release) { + !profile { + CONFIG += \ + config_pri_assets \ + config_pri_source_group1 + } + } +} + +config_pri_assets { + OTHER_FILES += \ + $$quote($$BASEDIR/assets/AboutPage.qml) \ + $$quote($$BASEDIR/assets/AppCover.qml) \ + $$quote($$BASEDIR/assets/EditSheet.qml) \ + $$quote($$BASEDIR/assets/FilterPage.qml) \ + $$quote($$BASEDIR/assets/HelpPage.qml) \ + $$quote($$BASEDIR/assets/SettingsPage.qml) \ + $$quote($$BASEDIR/assets/TaskItem.qml) \ + $$quote($$BASEDIR/assets/TaskPage.qml) \ + $$quote($$BASEDIR/assets/VisualStyle.bright/Appointment.png) \ + $$quote($$BASEDIR/assets/VisualStyle.bright/ArrowCircleAlt.png) \ + $$quote($$BASEDIR/assets/VisualStyle.bright/PriceTag.png) \ + $$quote($$BASEDIR/assets/VisualStyle.bright/Watch.png) \ + $$quote($$BASEDIR/assets/VisualStyle.dark/Appointment.png) \ + $$quote($$BASEDIR/assets/VisualStyle.dark/ArrowCircleAlt.png) \ + $$quote($$BASEDIR/assets/VisualStyle.dark/PriceTag.png) \ + $$quote($$BASEDIR/assets/VisualStyle.dark/Watch.png) \ + $$quote($$BASEDIR/assets/Watch_a.png) \ + $$quote($$BASEDIR/assets/help.html) \ + $$quote($$BASEDIR/assets/humane.js) \ + $$quote($$BASEDIR/assets/icons/123.png) \ + $$quote($$BASEDIR/assets/icons/Add.png) \ + $$quote($$BASEDIR/assets/icons/Capitalize.png) \ + $$quote($$BASEDIR/assets/icons/Check.png) \ + $$quote($$BASEDIR/assets/icons/Clock.png) \ + $$quote($$BASEDIR/assets/icons/Clock_a.png) \ + $$quote($$BASEDIR/assets/icons/Date.png) \ + $$quote($$BASEDIR/assets/icons/Delete.png) \ + $$quote($$BASEDIR/assets/icons/DownBox.png) \ + $$quote($$BASEDIR/assets/icons/Funnel.png) \ + $$quote($$BASEDIR/assets/icons/Info.png) \ + $$quote($$BASEDIR/assets/icons/Pencil.png) \ + $$quote($$BASEDIR/assets/icons/PriceTag.png) \ + $$quote($$BASEDIR/assets/icons/Recycle.png) \ + $$quote($$BASEDIR/assets/icons/Search.png) \ + $$quote($$BASEDIR/assets/icons/Sort.png) \ + $$quote($$BASEDIR/assets/icons/Undo.png) \ + $$quote($$BASEDIR/assets/icons/abc.png) \ + $$quote($$BASEDIR/assets/icons/ic_bbm.png) \ + $$quote($$BASEDIR/assets/icons/invoke.png) \ + $$quote($$BASEDIR/assets/icons/rtd_512_3-110.png) \ + $$quote($$BASEDIR/assets/icons/rtd_512_3-144.png) \ + $$quote($$BASEDIR/assets/icons/rtd_512_3-86.png) \ + $$quote($$BASEDIR/assets/icons/rtd_512_3-90.png) \ + $$quote($$BASEDIR/assets/icons/rtd_512_3-96.png) \ + $$quote($$BASEDIR/assets/icons/rtd_splash_1440s.png) \ + $$quote($$BASEDIR/assets/icons/rtd_splash_720s.png) \ + $$quote($$BASEDIR/assets/icons/rtd_splash_768p.png) \ + $$quote($$BASEDIR/assets/main.qml) +} + +config_pri_source_group1 { + SOURCES += \ + $$quote($$BASEDIR/src/LocalFile.cpp) \ + $$quote($$BASEDIR/src/TaskModel.cpp) \ + $$quote($$BASEDIR/src/applicationui.cpp) \ + $$quote($$BASEDIR/src/main.cpp) + + HEADERS += \ + $$quote($$BASEDIR/src/LocalFile.h) \ + $$quote($$BASEDIR/src/TaskModel.h) \ + $$quote($$BASEDIR/src/applicationui.hpp) +} + +CONFIG += precompile_header + +PRECOMPILED_HEADER = $$quote($$BASEDIR/precompiled.h) + +lupdate_inclusion { + SOURCES += \ + $$quote($$BASEDIR/../src/*.c) \ + $$quote($$BASEDIR/../src/*.c++) \ + $$quote($$BASEDIR/../src/*.cc) \ + $$quote($$BASEDIR/../src/*.cpp) \ + $$quote($$BASEDIR/../src/*.cxx) \ + $$quote($$BASEDIR/../assets/*.qml) \ + $$quote($$BASEDIR/../assets/*.js) \ + $$quote($$BASEDIR/../assets/*.qs) \ + $$quote($$BASEDIR/../assets/VisualStyle.bright/*.qml) \ + $$quote($$BASEDIR/../assets/VisualStyle.bright/*.js) \ + $$quote($$BASEDIR/../assets/VisualStyle.bright/*.qs) \ + $$quote($$BASEDIR/../assets/VisualStyle.dark/*.qml) \ + $$quote($$BASEDIR/../assets/VisualStyle.dark/*.js) \ + $$quote($$BASEDIR/../assets/VisualStyle.dark/*.qs) \ + $$quote($$BASEDIR/../assets/icons/*.qml) \ + $$quote($$BASEDIR/../assets/icons/*.js) \ + $$quote($$BASEDIR/../assets/icons/*.qs) + + HEADERS += \ + $$quote($$BASEDIR/../src/*.h) \ + $$quote($$BASEDIR/../src/*.h++) \ + $$quote($$BASEDIR/../src/*.hh) \ + $$quote($$BASEDIR/../src/*.hpp) \ + $$quote($$BASEDIR/../src/*.hxx) +} + +TRANSLATIONS = $$quote($${TARGET}.ts) diff --git a/precompiled.h b/precompiled.h new file mode 100644 index 0000000..db268e3 --- /dev/null +++ b/precompiled.h @@ -0,0 +1,5 @@ +// This file is used to store precompiled headers. + +#include +#include +#include diff --git a/src/LocalFile.cpp b/src/LocalFile.cpp new file mode 100644 index 0000000..fb02c18 --- /dev/null +++ b/src/LocalFile.cpp @@ -0,0 +1,103 @@ +/* + * Copyright 2012-2018 Morgan McMillian + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "LocalFile.h" + +LocalFile::LocalFile() { + mPath = "data/todo"; + mFile = mPath + "/todo.txt"; + mDone = mPath + "/done.txt"; + if (!dir.exists(mPath)) { + dir.mkdir(mPath); + } +} + +LocalFile::~LocalFile() { + // TODO Auto-generated destructor stub +} + +QStringList LocalFile::load() const { + QStringList data; + QFile file(mFile); + file.open(QIODevice::ReadOnly); + QTextStream in(&file); + while (!in.atEnd()) { + QString line = in.readLine(); + data << line; + } + return data; +} + +QStringList LocalFile::loadArchive() const { + QStringList data; + QFile file(mDone); + file.open(QIODevice::ReadOnly); + QTextStream in(&file); + while (!in.atEnd()) { + QString line = in.readLine(); + data << line; + } + return data; +} + +void LocalFile::save(const QStringList &data) { + QSettings settings; + QString lnend = settings.value("windowsbreak").toBool() ? "\r\n" : "\n"; + QFile file(mFile); + file.open(QIODevice::WriteOnly); + QTextStream out(&file); + foreach (QString line, data) { + out << line << lnend; + } + file.close(); +} + +void LocalFile::saveArchive(const QStringList &data) { + QSettings settings; + QString lnend = settings.value("windowsbreak").toBool() ? "\r\n" : "\n"; + QFile file(mDone); + file.open(QIODevice::WriteOnly); + QTextStream out(&file); + foreach (QString line, data) { + out << line << lnend; + } + file.close(); +} + +void LocalFile::archive(const QStringList &data) { + QSettings settings; + QString lnend = settings.value("windowsbreak").toBool() ? "\r\n" : "\n"; + QFile file(mDone); + file.open(QIODevice::Append); + QTextStream out(&file); + foreach (QString line, data) { + out << line << lnend; + } + file.close(); +} + +QString LocalFile::path() const { + return mPath; +} + +void LocalFile::setPath(const QString &path) { + mPath = path; + if (!dir.exists(mPath)) { + dir.mkdir(mPath); + } + mFile = mPath + "/todo.txt"; + mDone = mPath + "/done.txt"; +} diff --git a/src/LocalFile.h b/src/LocalFile.h new file mode 100644 index 0000000..4e79428 --- /dev/null +++ b/src/LocalFile.h @@ -0,0 +1,48 @@ +/* + * Copyright 2012-2018 Morgan McMillian + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LOCALFILE_H_ +#define LOCALFILE_H_ + +#include +#include +#include +#include +#include + +class LocalFile { + +public: + LocalFile(); + virtual ~LocalFile(); + + QStringList load() const; + QStringList loadArchive() const; + QString path() const; + void save(const QStringList &data); + void saveArchive(const QStringList &data); + void setPath(const QString &path); + void archive(const QStringList &data); + +private: + QDir dir; + QString mPath; + QString mFile; + QString mDone; + +}; + +#endif /* LOCALFILE_H_ */ diff --git a/src/TaskModel.cpp b/src/TaskModel.cpp new file mode 100644 index 0000000..836a161 --- /dev/null +++ b/src/TaskModel.cpp @@ -0,0 +1,664 @@ +/* + * Copyright 2012-2018 Morgan McMillian + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "TaskModel.h" + +TaskModel::TaskModel(QObject* parent) { + setParent(parent); + + QSettings settings; + + mOffline = false; + mDelete = -1; + + ts_settings = new QSettings("Morgan McMillian", "RenamedTodo"); + + toast = new SystemToast(this); + + mSort = settings.value("sort").toInt(); + if (!mSort) mSort = PRIORITY; + + QString fpath = settings.value("path").toString(); + if (!fpath.isNull()) { + localfile.setPath(fpath); + } + + regxComp.setPattern("^x "); + regxPri.setPattern("\\(([A-Z])\\) "); + regxDate.setPattern("([0-9]{4}-[0-9]{2}-[0-9]{2}) ?"); + regxProj.setPattern("(\\+[^ ]+)"); + regxCtx.setPattern("(@[^ ]+)"); + + qDebug() << "I am life! " << this; + +} + +TaskModel::~TaskModel() { + delete toast; + qDebug() << "I am death! " << this; +} + +int TaskModel::sort() const { + return mSort; +} + +void TaskModel::setSort(const int &sort) { + QSettings settings; + mSort = sort; + settings.setValue("sort", sort); + setView(); + emit listUpdated(); +} + +QVariant TaskModel::setting(const QString &setting, const QVariant &defVal) const { + QSettings settings; + if (settings.value(setting).isNull()) { + return defVal; + } + return settings.value(setting); +} + +QString TaskModel::activeFilters() { + QString filterlist; + foreach(QString item, mFilters) { + filterlist = filterlist + item + ","; + } + if (filterlist.size() > 0) { + return " Filter: " + filterlist; + } else { + return ""; + } +} + +QString TaskModel::formatDate(const QDateTime &date) const { + return date.toString("yyyy-MM-dd"); +} + +void TaskModel::modifySetting(const QString &setting, const QVariant &value) { + QSettings settings; + settings.setValue(setting, value); + if (setting == "sort") mSort = value.toInt(); + if (setting == "path") { + localfile.setPath(value.toString()); + load(); + } +} + +void TaskModel::onFileDataChanged(QStringList data) { + localfile.save(data); + load(); + setView(); +} + +void TaskModel::onArchiveData(QStringList data) { + localfile.saveArchive(data); + mArchiveData = data; +} + +QVariantList TaskModel::filters() const { + QVariantList filters; + foreach (QString project, mProjects) { + QVariantMap map; + map["type"] = "Projects"; + map["title"] = project; + if (mFilters.indexOf(project) >= 0) { + map["checked"] = true; + } else { + map["checked"] = false; + } + filters.append(map); + } + foreach (QString context, mContexts) { + QVariantMap map; + map["type"] = "Contexts"; + map["title"] = context; + if (mFilters.indexOf(context) >= 0) { + map["checked"] = true; + } else { + map["checked"] = false; + } + filters.append(map); + } + foreach (QString duedate, mDueDates) { + QVariantMap map; + qDebug() << "::" + duedate; + map["type"] = "Due Dates"; + map["title"] = duedate; + if (mFilters.indexOf(duedate) >= 0) { + map["checked"] = true; + } else { + map["checked"] = false; + } + filters.append(map); + } + return filters; +} + +QVariantList TaskModel::tododata() { + QVariantList rData; + foreach (QString item, mTodoList) { + QVariantMap map = parseTask(item); + rData.append(map); + } + return rData; +} + +void TaskModel::refresh() { + QSettings settings; + load(); + emit listUpdated(); +} + +void TaskModel::commit() { + QSettings settings; + QString lnend = settings.value("windowsbreak").toBool() ? "\r\n" : "\n"; + save(); +} + +void TaskModel::load() { + mTodoData.clear(); + QStringList dummy; + dummy = localfile.load(); + foreach (QString item, dummy) { + QVariantMap map = parseTask(item); + mTodoData.append(map); + } + + mArchiveData = localfile.loadArchive(); +} + +void TaskModel::save() { + QStringList data; + foreach (QVariant map, mTodoData) { + QString listitem = buildTask(map.toMap()); + data.append(listitem); + } + localfile.save(data); + load(); + setView(); + emit listUpdated(); +} + +void TaskModel::archive() { + QSettings settings; + QString lnend = settings.value("windowsbreak").toBool() ? "\r\n" : "\n"; + foreach (QVariant map, mTodoData) { + QVariantMap task = map.toMap(); + if (task["complete"].toBool()) { + QString architem = buildTask(task); + mArchiveData.append(architem); + mTodoData.removeAt(mTodoData.indexOf(task)); + } + } + if (mArchiveData.size() > 0) { + localfile.saveArchive(mArchiveData); + commit(); + } else { + load(); + setView(); + } +} + +void TaskModel::search(const QString &text) { + mSearch = text; + setView(); +} + +void TaskModel::setValue(int idx, const QString &key, const QVariant &value) { + //qDebug() << "index: " << idx; + //qDebug() << "key: " << key; + //qDebug() << "value: " << value; + //qDebug() << "check: " << QVariantListDataModel::value(idx).value(); + QSettings settings; + if (idx >=0 && idx < size()) { + QVariantMap current = QVariantListDataModel::value(idx).value(); + QVariantMap updated = current; + updated[key] = value; + if (key == "complete" && value == true) { + updated["priority"] = ""; + updated["dateCompleted"] = QDate::currentDate().toString("yyyy-MM-dd"); + } else if (key == "complete" && value == false) { + updated["dateCompleted"] = ""; + } + QString rtask = buildTask(updated); + updated["text"] = QVariant(rtask); + //qDebug() << "current: " << current; + //qDebug() << "idx: " << idx; + //qDebug() << "orig idx: " << mTodoData.indexOf(current); + //qDebug() << "test0:" << mTodoData.value(0); + //qDebug() << "testX:" << mTodoData.value(mTodoData.size()-1); + int origidx = mTodoData.indexOf(current); + mTodoData.replace(origidx, updated); + //setView(); + commit(); + if (key == "complete" && value == true && settings.value("autoarchive").toBool()) { + archive(); + } + } + //qDebug() << "new: " << QVariantListDataModel::value(idx).value(); +} + +void TaskModel::exportFiles(const QStringList &files) { + + QString epath = files[0]; + QRegExp epathrgx("todo.txt$"); + epath.replace(epathrgx, ""); + + LocalFile exportfrom; + LocalFile exportto; + exportto.setPath(epath); + + QStringList todo = exportfrom.load(); + QStringList done = exportfrom.loadArchive(); + + exportto.save(todo); + exportto.saveArchive(done); +} + +void TaskModel::promptPurgeSandbox() { + dialog = new SystemDialog("PURGE", "CANCEL"); + dialog->setTitle("Purge local sandbox"); + dialog->setBody("Erase local sandbox files? WARNING This cannot be undone."); + + bool success = QObject::connect(dialog, SIGNAL(finished(bb::system::SystemUiResult::Type)), + this, SLOT(onConfirmPurge(bb::system::SystemUiResult::Type))); + + if (success) { + dialog->show(); + } else { + dialog->deleteLater(); + } +} + +void TaskModel::onConfirmPurge(bb::system::SystemUiResult::Type value) { + QStringList empty; + LocalFile sandbox; + switch(value) { + case bb::system::SystemUiResult::ConfirmButtonSelection: + qDebug() << "PURGE"; + sandbox.save(empty); + sandbox.saveArchive(empty); + load(); + setView(); + break; + case bb::system::SystemUiResult::CancelButtonSelection: + qDebug() << "CANCEL"; + break; + default: + break; + } + + dialog->deleteLater(); +} + +void TaskModel::promptDelete(int idx) { + dialog = new SystemDialog("DELETE", "CANCEL"); + dialog->setTitle("Delete Task"); + dialog->setBody("Permanently delete this Entry?"); + + bool success = QObject::connect(dialog, SIGNAL(finished(bb::system::SystemUiResult::Type)), + this, SLOT(onDeleteTask(bb::system::SystemUiResult::Type))); + + if (success) { + mDelete = idx; + dialog->show(); + } else { + mDelete = -1; + dialog->deleteLater(); + } + +} + +void TaskModel::onDeleteTask(bb::system::SystemUiResult::Type value) { + switch(value) { + case bb::system::SystemUiResult::ConfirmButtonSelection: + //qDebug() << "DELETE"; + delTask(mDelete); + break; + case bb::system::SystemUiResult::CancelButtonSelection: + //qDebug() << "CANCEL"; + mDelete = -1; + break; + default: + break; + } + + dialog->deleteLater(); +} + +void TaskModel::delTask(int idx) { + if (idx >=0 && idx < size()) { + QVariantMap current = QVariantListDataModel::value(idx).value(); + int origidx = mTodoData.indexOf(current); + //qDebug() << "idx: " << idx; + //qDebug() << "orig idx: " << mTodoData.indexOf(current); + mTodoData.removeAt(origidx); + //setView(); + commit(); + mDelete = -1; + } +} + +void TaskModel::changeFilter(const QString &filter, const bool &enabled) { + int idx = mFilters.indexOf(filter); + if (enabled) { + if (idx == -1) mFilters.append(filter); + } else { + if (idx >= 0) mFilters.removeAt(idx); + } + //qDebug() << "Filter List: " << mFilters; +} + +void TaskModel::resetFilter() { + mFilters.clear(); + setView(); + toast->setBody("Filters removed."); + toast->show(); +} + +void TaskModel::addFullTask(const QString &task) { + QVariantMap map = parseTask(task); + QSettings settings; + if (settings.value("datenew").toBool()) { + map["dateCreated"] = QDate::currentDate().toString("yyyy-MM-dd"); + } + mTodoData.append(map); + //setView(); + commit(); +} + +void TaskModel::updateTask(int idx, const QString &task) { + if (idx >=0 && idx < size()) { + QVariantMap current = QVariantListDataModel::value(idx).value(); + int origidx = mTodoData.indexOf(current); + QVariantMap map = parseTask(task); + if (origidx >= 0) { + mTodoData.replace(origidx, map); + //setView(); + commit(); + } else { + // TODO produce some error message + qDebug() << "ERROR: origidx = " << origidx; + } + } +} + +QVariantMap TaskModel::parseTask(QString rawTask) { + QVariantMap task; + int pos = 0; + + QString item = rawTask; + bool complete = false; + QString priority = ""; + QString dateCompleted = ""; + QString dateCreated = ""; + QString dateDue = ""; + QString detail = ""; + + //qDebug() << "..parsing projects.."; + QStringList prj; + pos = 0; + while ((pos = regxProj.indexIn(item,pos)) != -1) { + prj << regxProj.cap(1); + pos += regxProj.matchedLength(); + } + if (prj.size() > 0) { + foreach (QString p, prj) { + if (mProjects.indexOf(p) < 0) { + mProjects << p; + } + } + } + //qDebug() << "my projects: " << mProjects; + + //qDebug() << "..parsing contexts.."; + QStringList ctx; + pos = 0; + while ((pos = regxCtx.indexIn(item,pos)) != -1) { + ctx << regxCtx.cap(1); + pos += regxCtx.matchedLength(); + } + if (ctx.size() > 0) { + foreach (QString c, ctx) { + if (mContexts.indexOf(c) < 0) { + mContexts << c; + } + } + } + //qDebug() << "my contexts: " << mContexts; + + QRegExp regxDue("due:([0-9]{4}-[0-9]{2}-[0-9]{2}) ?"); + if (regxDue.indexIn(item,0) != -1) { + dateDue = regxDue.cap(1); + QString duestr = "due:" + dateDue; + if (dateDue.length() > 0) { + if (mDueDates.indexOf(duestr) < 0) { + mDueDates << duestr; + } + } + } + + //qDebug() << "---*****---"; + if (regxComp.indexIn(item) == 0) { + //qDebug() << "complete: true"; + complete = true; + item.replace(regxComp, ""); + pos = 0; + QStringList dates; + while ((pos = regxDate.indexIn(item,pos)) != -1) { + dates << regxDate.cap(1); + pos += regxDate.matchedLength(); + } + if (dates.size() > 0) { + //qDebug() << "completed: " << dates.at(0); + dateCompleted = dates.at(0); + if (dates.size() >= 2) { + //qDebug() << "created: " << dates.at(1); + dateCreated = dates.at(1); + pos = regxDate.indexIn(item,0); + item.replace(QRegExp("^([0-9]{4}-[0-9]{2}-[0-9]{2} )"), ""); + } + } + pos = regxDate.indexIn(item,0); + item.replace(QRegExp("^([0-9]{4}-[0-9]{2}-[0-9]{2} )"), ""); + } else if (regxDate.indexIn(item) >= 0 && regxDate.indexIn(item) < 5) { + dateCreated = regxDate.cap(1); +// item.replace(regxDate.cap(1) + " ", ""); +// item.replace(QRegExp("^([0-9]{4}-[0-9]{2}-[0-9]{2} )"), ""); + item.remove(regxDate.indexIn(item), 11); + } + if (regxPri.indexIn(item) >= 0) { + //qDebug() << "priority: " << regxPri.cap(1); + priority = regxPri.cap(1); + item.replace(regxPri, ""); + } + detail = item; + + task["complete"] = QVariant(complete); + task["priority"] = QVariant(priority); + task["dateCompleted"] = QVariant(dateCompleted); + task["dateCreated"] = QVariant(dateCreated); + task["dateDue"] = QVariant(dateDue); + task["detail"] = QVariant(detail); + task["text"] = QVariant(rawTask); + + return task; +} + +QString TaskModel::buildTask(const QVariantMap &task) { + QString text = ""; + bool complete = task["complete"].toBool(); + QString priority = task["priority"].toString(); + QString dateCompleted = task["dateCompleted"].toString(); + QString dateCreated = task["dateCreated"].toString(); + QString detail = task["detail"].toString(); + if (complete) text = text + "x "; + if (priority.length() > 0) text = text + "(" + priority + ") "; + if (dateCompleted.length() > 0) text = text + dateCompleted + " "; + if (dateCreated.length() > 0) text = text + dateCreated + " "; + if (detail.length() > 0) text = text + detail; + return text; +} + +bool TaskModel::sortByPriority(const QString &a, const QString &b) { + QString matchA; + QString matchB; + + QRegExp pri("\\(([A-Z])\\) "); + QRegExp done("^x "); + QRegExp date("([0-9]{4}-[0-9]{2}-[0-9]{2}) ?"); + QRegExp sca("^@"); + QRegExp scp("^\\+"); + + if (pri.indexIn(a) >= 0) { + matchA = pri.cap(1); + } else if (done.indexIn(a) == 0) { + matchA = "}"; + } else { + matchA = a.toLower(); + matchA.replace(date,""); + matchA.replace(sca,""); + matchA.replace(scp,""); + } + //qDebug() << "a: " << a; + //qDebug() << "matchA: " << matchA; + if (pri.indexIn(b) >= 0) { + matchB = pri.cap(1); + } else if (done.indexIn(b) == 0) { + matchB = "}"; + } else { + matchB = b.toLower(); + matchB.replace(date,""); + matchB.replace(sca,""); + matchB.replace(scp,""); + } + //qDebug() << "b: " << b; + //qDebug() << "matchB: " << matchB; + return matchA < matchB; +} + +bool TaskModel::sortByText(const QString &a, const QString &b) { + QString matchA = a; + QString matchB = b; + + QRegExp pri("\\([A-Z]\\) "); + QRegExp done("^x "); + QRegExp date("([0-9]{4}-[0-9]{2}-[0-9]{2}) ?"); + QRegExp sca("^@"); + QRegExp scp("^\\+"); + + matchA.replace(done, ""); + matchA.replace(pri, ""); + matchA.replace(date, ""); + matchA.replace(sca,""); + matchA.replace(scp,""); + //qDebug() << "A: " << matchA; + matchB.replace(done, ""); + matchB.replace(pri, ""); + matchB.replace(date, ""); + matchB.replace(sca,""); + matchB.replace(scp,""); + //qDebug() << "B: " << matchB; + + return matchA.toLower() < matchB.toLower(); +} + +bool TaskModel::sortByDueDate(const QString &a, const QString &b) { + QString matchA = a; + QString matchB = b; + + QRegExp regxDue("(due:)([0-9]{4}-[0-9]{2}-[0-9]{2}) ?"); + QRegExp pri("\\([A-Z]\\) "); + QRegExp done("^x "); + QRegExp date("([0-9]{4}-[0-9]{2}-[0-9]{2}) ?"); + QRegExp sca("^@"); + QRegExp scp("^\\+"); + + if (regxDue.indexIn(a,0) != -1) { + matchA = regxDue.cap(2); + } else if (done.indexIn(a) == 0) { + matchA = "}"; + } else { + matchA.replace(done, ""); + matchA.replace(pri, ""); + matchA.replace(date, ""); + matchA.replace(sca,""); + matchA.replace(scp,""); + } + + if (regxDue.indexIn(b,0) != -1) { + matchB = regxDue.cap(2); + } else if (done.indexIn(b) == 0) { + matchB = "}"; + } else { + matchB.replace(done, ""); + matchB.replace(pri, ""); + matchB.replace(date, ""); + matchB.replace(sca,""); + matchB.replace(scp,""); + } + + return matchA.toLower() < matchB.toLower(); +} + +void TaskModel::setView() { + + mTodoList.clear(); + mProjects.clear(); + mContexts.clear(); + mDueDates.clear(); + //qDebug() << "::" << mFilters; + foreach (QVariant map, mTodoData) { + QString listitem = buildTask(map.toMap()); + if (mSearch.length() > 0) { + if (listitem.contains(mSearch, Qt::CaseInsensitive)) { + mTodoList.append(listitem); + } + } else if (mFilters.length() > 0) { + // TODO this results in an "or" condition, probably should be "and" instead + foreach (QString filter, mFilters) { + if (listitem.indexOf(filter) >=0) { + mTodoList.append(listitem); + break; + } + } + } else { + mTodoList.append(listitem); + } + } + clear(); + + switch (mSort) { + case PRIORITY: + qSort(mTodoList.begin(), mTodoList.end(), sortByPriority); + break; + case ID: + // this is the default + break; + case TEXT: + qSort(mTodoList.begin(), mTodoList.end(), sortByText); + break; + case DUE: + qSort(mTodoList.begin(), mTodoList.end(), sortByDueDate); + break; + } + + foreach (QString item, mTodoList) { + QVariantMap map = parseTask(item); + append(map); + } + emit listUpdated(); +} diff --git a/src/TaskModel.h b/src/TaskModel.h new file mode 100644 index 0000000..48ee141 --- /dev/null +++ b/src/TaskModel.h @@ -0,0 +1,112 @@ +/* + * Copyright 2012-2018 Morgan McMillian + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TASKMODEL_H_ +#define TASKMODEL_H_ + +#include +#include +#include +#include +#include +#include + +#include "LocalFile.h" + +using namespace bb::cascades; +using namespace bb::system; + +class TaskModel: public bb::cascades::QVariantListDataModel { + Q_OBJECT + + Q_PROPERTY(int sort READ sort WRITE setSort NOTIFY sortChanged) + Q_PROPERTY(QVariantList filters READ filters FINAL) + Q_PROPERTY(QVariantList tododata READ tododata FINAL) + +public: + TaskModel(QObject* parent = 0); + virtual ~TaskModel(); + + enum SortType { PRIORITY, ID, TEXT, DUE }; + Q_ENUMS(SortType); + + int sort() const; + void setSort(const int &sort); + QVariantList filters() const; + QVariantList tododata(); + + Q_INVOKABLE void refresh(); + Q_INVOKABLE void commit(); + Q_INVOKABLE void load(); + Q_INVOKABLE void save(); + Q_INVOKABLE void archive(); + Q_INVOKABLE void search(const QString &text); + Q_INVOKABLE QVariant setting(const QString &setting, const QVariant &defVal) const; + Q_INVOKABLE QString activeFilters(); + Q_INVOKABLE QString formatDate(const QDateTime &date) const; + Q_INVOKABLE void promptPurgeSandbox(); + Q_INVOKABLE void exportFiles(const QStringList &files); + Q_SLOT void setView(); + Q_SLOT void setValue(int idx, const QString &key, const QVariant &value); + Q_SLOT void updateTask(int idx, const QString &task); + Q_SLOT void addFullTask(const QString &task); + Q_SLOT void promptDelete(int idx); + Q_SLOT void delTask(int idx); + Q_SLOT void changeFilter(const QString &filter, const bool &enabled); + Q_SLOT void resetFilter(); + Q_SLOT void modifySetting(const QString &setting, const QVariant &value); + Q_SLOT void onFileDataChanged(QStringList data); + Q_SLOT void onArchiveData(QStringList data); + Q_SLOT void onDeleteTask(bb::system::SystemUiResult::Type value); + Q_SLOT void onConfirmPurge(bb::system::SystemUiResult::Type value); + + Q_SIGNAL void sortChanged(SortType sort); + Q_SIGNAL void listUpdated(); + +private: + + QVariantMap parseTask(QString rawTask); + QString buildTask(const QVariantMap &task); + static bool sortByPriority(const QString &a, const QString &b); + static bool sortByText(const QString &a, const QString &b); + static bool sortByDueDate(const QString &a, const QString &b); + + QRegExp regxComp; + QRegExp regxPri; + QRegExp regxDate; + QRegExp regxProj; + QRegExp regxCtx; + + QSettings *ts_settings; + LocalFile localfile; + SystemDialog *dialog; + SystemToast *toast; + + QStringList mProjects; + QStringList mContexts; + QStringList mDueDates; + QStringList mFilters; + QStringList mTodoList; + QStringList mArchiveData; + QVariantList mTodoData; + QString mSearch; + int mSort; + int mDelete; + bool mOffline; + +}; + +#endif /* TASKMODEL_H_ */ diff --git a/src/applicationui.cpp b/src/applicationui.cpp new file mode 100644 index 0000000..7a23067 --- /dev/null +++ b/src/applicationui.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2011-2015 BlackBerry Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "applicationui.hpp" +#include "TaskModel.h" + +#include +#include +#include +#include +#include +#include +#include + +using namespace bb::cascades; + +ApplicationUI::ApplicationUI() : + QObject() +{ + // prepare the invoke manager + invokeManager = new bb::system::InvokeManager(this); + connect(invokeManager, SIGNAL(invoked(const bb::system::InvokeRequest&)), + this, SLOT(onInvoke(const bb::system::InvokeRequest&))); + + // prepare the localization + m_pTranslator = new QTranslator(this); + m_pLocaleHandler = new LocaleHandler(this); + + bool res = QObject::connect(m_pLocaleHandler, SIGNAL(systemLanguageChanged()), this, SLOT(onSystemLanguageChanged())); + // This is only available in Debug builds + Q_ASSERT(res); + // Since the variable is not used in the app, this is added to avoid a + // compiler warning + Q_UNUSED(res); + + // initial load + onSystemLanguageChanged(); + + qmlRegisterType("com.monkeystew.taskmodel", 1, 0, "TaskModel"); + qmlRegisterType("bb.cascades", 1, 0, "SceneCover"); + qmlRegisterUncreatableType("bb.cascades", 1, 0, "AbstractCover", + "An AbstractCover cannot be created."); + + // Create scene document from main.qml asset, the parent is set + // to ensure the document gets destroyed properly at shut down. + QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this); + qml->setContextProperty("_Taskslayer", this); + + // Create root object for the UI + AbstractPane *root = qml->createRootObject(); + + // Set created root object as the application scene + Application::instance()->setScene(root); + + bb::ApplicationInfo appinfo; + qDebug() << "APP VER_ " << appinfo.version(); + root->setProperty("appversion", appinfo.version()); +} + +void ApplicationUI::onSystemLanguageChanged() +{ + QCoreApplication::instance()->removeTranslator(m_pTranslator); + // Initiate, load and install the application translation files. + QString locale_string = QLocale().name(); + QString file_name = QString("RenamedTodo_%1").arg(locale_string); + if (m_pTranslator->load(file_name, "app/native/qm")) { + QCoreApplication::instance()->installTranslator(m_pTranslator); + } +} + +void ApplicationUI::onInvoke(const bb::system::InvokeRequest& request) +{ + if (request.action() == "bb.action.SHARE") { + Q_EMIT addNewTask(QString::fromUtf8(request.data())); + } else if (request.action() == "bb.action.SEARCH.EXTENDED") { + Q_EMIT searchTaskList(QString::fromUtf8(request.data())); + } +} + +void ApplicationUI::getSupport(const int target) +{ + bb::system::InvokeRequest request; + + switch(target) + { + case 0: + request.setTarget("sys.pim.uib.email.hybridcomposer"); + request.setAction("bb.action.COMPOSE"); + request.setMimeType("message/rfc822"); + request.setUri(QUrl("mailto:rtd@monkeystew.com?subject=Renamed Todo for BlackBerry 10")); + invokeManager->invoke(request); + break; + } +} diff --git a/src/applicationui.hpp b/src/applicationui.hpp new file mode 100644 index 0000000..bb6f3fc --- /dev/null +++ b/src/applicationui.hpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011-2015 BlackBerry Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ApplicationUI_HPP_ +#define ApplicationUI_HPP_ + +#include +#include +#include + +namespace bb +{ + namespace cascades + { + class LocaleHandler; + } +} + +class QTranslator; + +/*! + * @brief Application UI object + * + * Use this object to create and init app UI, to create context objects, to register the new meta types etc. + */ +class ApplicationUI : public QObject +{ + Q_OBJECT +public: + ApplicationUI(); + virtual ~ApplicationUI() {} + + Q_INVOKABLE void getSupport(const int target); + +Q_SIGNALS: + void addNewTask(QString data); + void searchTaskList(QString data); +private slots: + void onSystemLanguageChanged(); + void onInvoke(const bb::system::InvokeRequest &request); +private: + QTranslator* m_pTranslator; + bb::cascades::LocaleHandler* m_pLocaleHandler; + bb::system::InvokeManager *invokeManager; +}; + +#endif /* ApplicationUI_HPP_ */ diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..b955edf --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011-2015 BlackBerry Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "applicationui.hpp" + +#include + +#include +#include + +#include + +using namespace bb::cascades; + +Q_DECL_EXPORT int main(int argc, char **argv) +{ + Application app(argc, argv); + + // Create the Application UI object, this is where the main.qml file + // is loaded and the application scene is set. + ApplicationUI appui; + + // Enter the application main event loop. + return Application::exec(); +} diff --git a/translations/Makefile b/translations/Makefile new file mode 100644 index 0000000..0eeb116 --- /dev/null +++ b/translations/Makefile @@ -0,0 +1,12 @@ +QMAKE_TARGET = RenamedTodo +LUPDATE = $(QNX_HOST)/usr/bin/lupdate +LRELEASE = $(QNX_HOST)/usr/bin/lrelease + +update: $(QMAKE_TARGET).pro FORCE + $(LUPDATE) $(QMAKE_TARGET).pro + +release: $(QMAKE_TARGET).pro $(QMAKE_TARGET).ts + $(LRELEASE) $(QMAKE_TARGET).pro + +FORCE: + diff --git a/translations/RenamedTodo.pro b/translations/RenamedTodo.pro new file mode 100644 index 0000000..2192878 --- /dev/null +++ b/translations/RenamedTodo.pro @@ -0,0 +1 @@ +include (../RenamedTodo.pro) diff --git a/translations/RenamedTodo.ts b/translations/RenamedTodo.ts new file mode 100644 index 0000000..07a7469 --- /dev/null +++ b/translations/RenamedTodo.ts @@ -0,0 +1,4 @@ + + + +