aboutsummaryrefslogtreecommitdiffstats
path: root/mobility
diff options
context:
space:
mode:
authorLauro Neto <lauro.neto@openbossa.org>2011-10-11 15:27:17 -0300
committerLauro Neto <lauro.neto@openbossa.org>2011-10-11 17:33:37 -0300
commit53bd4b768ea773723f6eba338ecb2cee0facf591 (patch)
treea9c2508da5652fac0a50b0693b286a255f9c86cc /mobility
parent9a286e730292c7effa5d091723a95f6e9f440f81 (diff)
Add QtOrganizer example.
It's a little bit verbose on the code (like the phonebook) as QtContact and QtOrganizer are quite complex modules (lots of classes and enums) Reviewer: Luciano Wolf <luciano.wolf@openbossa.org> Reviewer: Bruno Araujo <bruno.araujo@openbossa.org>
Diffstat (limited to 'mobility')
-rw-r--r--mobility/organizer/qml/OverviewPage.qml56
-rw-r--r--mobility/organizer/qml/TodoEdit.qml239
-rw-r--r--mobility/organizer/qml/main.qml10
-rw-r--r--mobility/organizer/qml/qmltodo.py274
4 files changed, 579 insertions, 0 deletions
diff --git a/mobility/organizer/qml/OverviewPage.qml b/mobility/organizer/qml/OverviewPage.qml
new file mode 100644
index 0000000..4f4f4ed
--- /dev/null
+++ b/mobility/organizer/qml/OverviewPage.qml
@@ -0,0 +1,56 @@
+
+import QtQuick 1.1
+import com.nokia.meego 1.0
+import com.nokia.extras 1.1
+
+Page {
+ id: overviewPage
+ anchors.margins: UiConstants.DefaultMargin
+ orientationLock: PageOrientation.LockPortrait
+
+ Label {
+ anchors.centerIn: parent
+ text: "No tasks"
+ visible: manager.todos.length == 0
+ }
+
+ Flickable {
+ anchors.fill: parent
+ clip: true
+
+ flickableDirection: Flickable.VerticalFlick
+ contentHeight: todoButtons.height
+ contentWidth: todoButtons.width
+
+ ButtonColumn {
+ id: todoButtons
+
+ // On N9 it seems that displayWidth keeps pointing to the larger
+ // side of the screen, even in portrait mode...
+ width: screen.displayHeight - 2 * UiConstants.DefaultMargin
+
+ Repeater {
+ model: manager.todos
+ Button {
+ text: modelData
+ onClicked: {
+ manager.editExistingTodo(index)
+ pageStack.push(Qt.createComponent("TodoEdit.qml"))
+ }
+ }
+ }
+ }
+ }
+
+ tools: ToolBarLayout {
+ id: mainTools
+ ToolButton {
+ text: "Add Task"
+ onClicked: {
+ manager.editNewTodo() // Prepare new todo info
+ pageStack.push(Qt.createComponent("TodoEdit.qml"))
+ }
+ }
+ }
+
+}
diff --git a/mobility/organizer/qml/TodoEdit.qml b/mobility/organizer/qml/TodoEdit.qml
new file mode 100644
index 0000000..65c60d6
--- /dev/null
+++ b/mobility/organizer/qml/TodoEdit.qml
@@ -0,0 +1,239 @@
+
+import QtQuick 1.1
+import com.nokia.meego 1.0
+import com.nokia.extras 1.1
+
+Page {
+ id: editPage
+ anchors.margins: UiConstants.DefaultMargin
+ orientationLock: PageOrientation.LockPortrait
+
+ property int todoId: -1
+
+ Flickable {
+ anchors.fill: parent
+ contentHeight: editCol.height
+ flickableDirection: Flickable.VerticalFlick
+
+ Column {
+ id: editCol
+
+ width: parent.width
+ anchors.horizontalCenter: parent.horizontalCenter
+ spacing: 10
+
+ Label {
+ text: "Subject"
+ }
+
+ TextField {
+ id: subjectField
+ text: manager.todoSubject
+
+ Keys.onReturnPressed: {
+ parent.focus = true;
+ }
+ }
+
+ Label {
+ text: "Start Date"
+ }
+
+ Column {
+ spacing: 20
+ Button {
+ id: selectStartDateButton
+ text: manager.todoStartDateTime[1] + "/" + manager.todoStartDateTime[2] + "/" + manager.todoStartDateTime[0]
+
+ onClicked: {
+ startDateSelector.day = manager.todoStartDateTime[2];
+ startDateSelector.month = manager.todoStartDateTime[1];
+ startDateSelector.year = manager.todoStartDateTime[0];
+ startDateSelector.open()
+ }
+
+ DatePickerDialog {
+ id: startDateSelector
+
+ onAccepted: {
+ manager.setTodoStartDate(year, month, day)
+ }
+ }
+ }
+
+ Button {
+ id: selectStartTimeButton
+ text: manager.todoStartDateTime[3]+ ":" + manager.todoStartDateTime[4]
+
+ onClicked: {
+ startTimeSelector.hour = manager.todoStartDateTime[3];
+ startTimeSelector.minute = manager.todoStartDateTime[4];
+ startTimeSelector.open()
+ }
+
+ TimePickerDialog {
+ id: startTimeSelector
+ fields: DateTime.Hours | DateTime.Minutes
+ acceptButtonText: "Confirm"
+ rejectButtonText: "Cancel"
+
+ onAccepted: {
+ manager.setTodoStartTime(hour, minute)
+ }
+
+ }
+ }
+
+ }
+
+ Label {
+ text: "Due Date"
+ }
+
+ Column {
+ spacing: 20
+ Button {
+ id: selectDueDateButton
+ text: manager.todoDueDateTime[1] + "/" + manager.todoDueDateTime[2] + "/" + manager.todoDueDateTime[0]
+
+ onClicked: {
+ dueDateSelector.day = manager.todoDueDateTime[2];
+ dueDateSelector.month = manager.todoDueDateTime[1];
+ dueDateSelector.year = manager.todoDueDateTime[0];
+ dueDateSelector.open()
+ }
+
+ DatePickerDialog {
+ id: dueDateSelector
+
+ onAccepted: {
+ manager.setTodoDueDate(year, month, day)
+ }
+ }
+ }
+
+ Button {
+ id: selectDueTimeButton
+ text: manager.todoDueDateTime[3]+ ":" + manager.todoDueDateTime[4]
+
+ onClicked: {
+ dueTimeSelector.hour = manager.todoDueDateTime[3];
+ dueTimeSelector.minute = manager.todoDueDateTime[4];
+ dueTimeSelector.open()
+ }
+
+ TimePickerDialog {
+ id: dueTimeSelector
+ fields: DateTime.Hours | DateTime.Minutes
+ acceptButtonText: "Confirm"
+ rejectButtonText: "Cancel"
+
+ onAccepted: {
+ manager.setTodoDueTime(hour, minute)
+ }
+ }
+ }
+
+ }
+
+ Label {
+ text: "Status"
+ }
+
+ Button {
+ id: statusButton
+ text: statusSelection.model.get(statusSelection.selectedIndex).name
+
+ onClicked: {
+ statusSelection.open();
+ }
+
+
+ SelectionDialog {
+ id: statusSelection
+ titleText: "Select status"
+ selectedIndex: manager.todoStatus
+
+ model: ListModel {
+ ListElement { name: "Not started" }
+ ListElement { name: "In progress" }
+ ListElement { name: "Complete" }
+ }
+
+ onAccepted: {
+ manager.todoStatus = statusSelection.selectedIndex;
+ }
+ }
+ }
+
+ Label {
+ text: "Priority"
+ }
+
+ Button {
+ id: priorityButton
+ text: prioritySelection.model.get(prioritySelection.selectedIndex).name
+
+ onClicked: {
+ prioritySelection.open();
+ }
+
+
+ SelectionDialog {
+ id: prioritySelection
+ titleText: "Select priority"
+ selectedIndex: manager.todoPriority
+
+ model: ListModel {
+ ListElement { name: "Unknown" }
+ ListElement { name: "Highest" }
+ ListElement { name: "Extremely high" }
+ ListElement { name: "Very high" }
+ ListElement { name: "High" }
+ ListElement { name: "Medium" }
+ ListElement { name: "Low" }
+ ListElement { name: "Very low" }
+ ListElement { name: "Extremely low" }
+ ListElement { name: "Lowest" }
+ }
+
+ onAccepted: {
+ manager.todoPriority = prioritySelection.selectedIndex;
+ }
+ }
+ }
+ }
+ }
+
+ tools: ToolBarLayout {
+ id: editTools
+ ToolButton {
+ text: "Save"
+ onClicked: {
+ console.log("Saving new task")
+ manager.todoSubject = subjectField.text; // Other fields are handled by dialog.accept signal
+ manager.saveTodo();
+ pageStack.pop();
+ }
+ }
+ ToolButton {
+ text: "Delete"
+ enabled: !manager.isNewTodo
+ onClicked: {
+ console.log("Deleting todo.");
+ manager.deleteCurrent();
+ pageStack.pop();
+ }
+ }
+ ToolButton {
+ text: "Cancel"
+ onClicked: {
+ console.log("Cancel task edit");
+ console.log("Is new todo?" + manager.isNewTodo);
+ manager.reload();
+ pageStack.pop();
+ }
+ }
+ }
+
+}
diff --git a/mobility/organizer/qml/main.qml b/mobility/organizer/qml/main.qml
new file mode 100644
index 0000000..88c1b95
--- /dev/null
+++ b/mobility/organizer/qml/main.qml
@@ -0,0 +1,10 @@
+
+import QtQuick 1.1
+import com.nokia.meego 1.0
+
+PageStackWindow {
+
+ id: rootWindow
+ showStatusBar: false
+ initialPage: OverviewPage { }
+}
diff --git a/mobility/organizer/qml/qmltodo.py b/mobility/organizer/qml/qmltodo.py
new file mode 100644
index 0000000..a3523f2
--- /dev/null
+++ b/mobility/organizer/qml/qmltodo.py
@@ -0,0 +1,274 @@
+'''
+ Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ All rights reserved.
+ Contact: Nokia Corporation (qt-info@nokia.com)
+
+ This file is part of the Qt Mobility Components.
+
+ $QT_BEGIN_LICENSE:LGPL$
+ No Commercial Usage
+ This file contains pre-release code and may not be distributed.
+ You may use this file in accordance with the terms and conditions
+ contained in the Technology Preview License Agreement accompanying
+ this package.
+
+ GNU Lesser General Public License Usage
+ Alternatively, this file may be used under the terms of the GNU Lesser
+ General Public License version 2.1 as published by the Free Software
+ Foundation and appearing in the file LICENSE.LGPL included in the
+ packaging of this file. Please review the following information to
+ ensure the GNU Lesser General Public License version 2.1 requirements
+ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+
+ In addition, as a special exception, Nokia gives you certain additional
+ rights. These rights are described in the Nokia Qt LGPL Exception
+ version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+
+ If you have questions regarding the use of this file, please contact
+ Nokia at qt-info@nokia.com.
+'''
+
+import os
+import sys
+
+from PySide.QtCore import QObject, Signal, Slot, Property, QUrl, qWarning
+from PySide.QtCore import QAbstractItemModel, QDate, QDateTime, QTime
+from PySide.QtGui import QApplication
+from PySide.QtDeclarative import QDeclarativeView
+from QtMobility.Organizer import QOrganizerManager, QOrganizerItemSortOrder
+from QtMobility.Organizer import QOrganizerTodo, QOrganizerTodoTime
+from QtMobility.Organizer import QOrganizerItemFilter, QOrganizerItemDetailFilter
+from QtMobility.Organizer import QOrganizerItemPriority, QOrganizerTodoProgress
+from QtMobility.Organizer import QOrganizerItemType
+
+
+class TodoManager(QObject):
+
+ def __init__(self):
+ QObject.__init__(self)
+
+ self.manager = QOrganizerManager("memory")
+ self._todos = [] # FIXME Use a model instead of a string list as model
+ self._todo = None # Current todo being edited or created
+
+ self.reload()
+
+ @Slot()
+ def reload(self):
+ self._todos = []
+
+ sortOrder = QOrganizerItemSortOrder()
+ sortOrder.setDetailDefinitionName(QOrganizerTodoTime.DefinitionName,
+ QOrganizerTodoTime.FieldDueDateTime)
+
+ todoFilter = QOrganizerItemFilter()
+
+ items = self.manager.items(todoFilter, [sortOrder])
+
+ todos = []
+ for item in items:
+ if item.type() == QOrganizerItemType.TypeTodo:
+ todo = QOrganizerTodo(item)
+
+ display = todo.startDateTime().toString("yy/MM/dd hh:mm") +\
+ "-" + todo.dueDateTime().toString("yy/MM/dd hh:mm") +\
+ "\n" + todo.displayLabel()
+
+ todos.append((display, todo))
+
+ self._todos = todos
+ self.todosChanged.emit()
+
+ @Slot()
+ def deleteCurrent(self):
+ self.manager.removeItem(self._todo.id())
+ self.reload()
+
+ currentTodoChanged = Signal()
+
+ @Slot()
+ def editNewTodo(self):
+ """Sets the current todo to a newly created todo"""
+ newTodo = QOrganizerTodo()
+ newTodo.setPriority(QOrganizerItemPriority.HighPriority)
+ newTodo.setStatus(QOrganizerTodoProgress.StatusNotStarted)
+ currentDateTime = QDateTime(QDate.currentDate(), QTime.currentTime())
+ newTodo.setStartDateTime(currentDateTime)
+ newTodo.setDueDateTime(currentDateTime.addSecs(60*60))
+
+ self._todo = newTodo
+ self._todo.isNewTodo = True
+ self.currentTodoChanged.emit()
+
+ @Property(bool, notify=currentTodoChanged)
+ def isNewTodo(self):
+ return self._todo.isNewTodo if self._todo else True
+
+ @Slot(int)
+ def editExistingTodo(self, index):
+ self._todo = self._todos[index][1]
+ self._todo.isNewTodo = False
+ self.currentTodoChanged.emit()
+
+ @Slot()
+ def saveTodo(self):
+ self.manager.saveItem(self._todo)
+ self._todo = None
+ self.reload()
+
+ todosChanged = Signal()
+ @Property("QStringList", notify=todosChanged)
+ def todos(self):
+ return [x[0] for x in self._todos]
+
+ @todos.setter
+ def setTodo(self, value):
+ self._todos = value
+ self.todosChanged.emit()
+
+ # Subject
+ currentTodoSubjectChanged = Signal()
+
+ @Property(str, notify=currentTodoSubjectChanged)
+ def todoSubject(self):
+ return self._todo.displayLabel()
+
+ @todoSubject.setter
+ def setTodoSubject(self, value):
+ self._todo.setDisplayLabel(value)
+ self.currentTodoSubjectChanged.emit()
+
+ # Dates and times
+ def datetimeToStrList(self, datetime):
+ date = datetime.date()
+ time = datetime.time()
+ return (("%02d "*5) % (date.year(), date.month(), date.day(),
+ time.hour(), time.minute())).split()
+
+# @Slot(result="QStringList")
+ @Property("QStringList", notify=currentTodoChanged)
+ def todoStartDateTime(self):
+ return self.datetimeToStrList(self._todo.startDateTime())
+
+ @Slot(int, int, int)
+ def setTodoStartDate(self, year, month, day):
+ orig_time = self._todo.startDateTime().time()
+ date = QDate(year, month, day)
+ datetime = QDateTime(date, orig_time)
+
+ self._todo.setStartDateTime(datetime)
+ self.currentTodoChanged.emit()
+
+ @Slot(int, int)
+ def setTodoStartTime(self, hour, minute):
+ orig_date = self._todo.startDateTime().date()
+ time = QTime(hour, minute)
+ datetime = QDateTime(orig_date, time)
+
+ self._todo.setStartDateTime(datetime)
+ self.currentTodoChanged.emit()
+
+ @Property("QStringList", notify=currentTodoChanged)
+ def todoDueDateTime(self):
+ return self.datetimeToStrList(self._todo.dueDateTime())
+
+ @Slot(int, int, int)
+ def setTodoDueDate(self, year, month, day):
+ orig_time = self._todo.dueDateTime().time()
+ date = QDate(year, month, day)
+ datetime = QDateTime(date, orig_time)
+
+ self._todo.setDueDateTime(datetime)
+
+ self.currentTodoChanged.emit()
+
+ @Slot(int, int)
+ def setTodoDueTime(self, hour, minute):
+ orig_date = self._todo.dueDateTime().date()
+ time = QTime(hour, minute)
+ datetime = QDateTime(orig_date, time)
+
+ self._todo.setDueDateTime(datetime)
+
+ self.currentTodoChanged.emit()
+
+ # Status
+
+ Status = [
+ QOrganizerTodoProgress.StatusNotStarted,
+ QOrganizerTodoProgress.StatusInProgress,
+ QOrganizerTodoProgress.StatusComplete,
+ ]
+
+ @Property(int, notify=currentTodoChanged)
+ def todoStatus(self):
+ status = self._todo.status()
+ try:
+ index = self.Status.index(status)
+ return index
+ except ValueError:
+ return 0
+
+ @todoStatus.setter
+ def setTodoStatus(self, value):
+ try:
+ self._todo.setStatus(self.Status[value])
+ self.currentTodoChanged.emit()
+ except IndexError:
+ pass # Fail silently...
+
+ # Priority
+
+ Priority = [
+ QOrganizerItemPriority.UnknownPriority,
+ QOrganizerItemPriority.HighestPriority,
+ QOrganizerItemPriority.ExtremelyHighPriority,
+ QOrganizerItemPriority.VeryHighPriority,
+ QOrganizerItemPriority.HighPriority,
+ QOrganizerItemPriority.MediumPriority,
+ QOrganizerItemPriority.LowPriority,
+ QOrganizerItemPriority.VeryLowPriority,
+ QOrganizerItemPriority.ExtremelyLowPriority,
+ QOrganizerItemPriority.LowestPriority,
+ ]
+
+ @Property(int, notify=currentTodoChanged)
+ def todoPriority(self):
+ priority = self._todo.priority()
+ try:
+ index = self.Priority.index(priority)
+ return index
+ except ValueError:
+ return 0
+
+ @todoPriority.setter
+ def setTodoPriority(self, value):
+ try:
+ self._todo.setPriority(self.Priority[value])
+ self.currentTodoChanged.emit()
+ except IndexError:
+ pass # Fail silently...
+
+
+def main():
+ app = QApplication([])
+ view = QDeclarativeView()
+ manager = TodoManager()
+ context = view.rootContext()
+ context.setContextProperty("manager", manager)
+
+ url = QUrl('main.qml')
+ view.setSource(url)
+
+ if "-no-fs" not in sys.argv:
+ view.showFullScreen()
+ else:
+ view.show()
+
+ app.exec_()
+
+
+if __name__ == '__main__':
+ main()
+
+