-rw-r--r-- | core/pim/todo/.cvsignore | 4 | ||||
-rw-r--r-- | core/pim/todo/Makefile.in | 201 | ||||
-rw-r--r-- | core/pim/todo/main.cpp | 36 | ||||
-rw-r--r-- | core/pim/todo/mainwindow.cpp | 466 | ||||
-rw-r--r-- | core/pim/todo/mainwindow.h | 73 | ||||
-rw-r--r-- | core/pim/todo/qpe-todo.control | 9 | ||||
-rw-r--r-- | core/pim/todo/todo.pro | 19 | ||||
-rw-r--r-- | core/pim/todo/todoentry.ui | 266 | ||||
-rw-r--r-- | core/pim/todo/todoentryimpl.cpp | 142 | ||||
-rw-r--r-- | core/pim/todo/todoentryimpl.h | 61 | ||||
-rw-r--r-- | core/pim/todo/todotable.cpp | 859 | ||||
-rw-r--r-- | core/pim/todo/todotable.h | 207 |
12 files changed, 2343 insertions, 0 deletions
diff --git a/core/pim/todo/.cvsignore b/core/pim/todo/.cvsignore new file mode 100644 index 0000000..5ed04d8 --- a/dev/null +++ b/core/pim/todo/.cvsignore | |||
@@ -0,0 +1,4 @@ | |||
1 | moc_* | ||
2 | Makefile | ||
3 | todoentry.h | ||
4 | todoentry.cpp | ||
diff --git a/core/pim/todo/Makefile.in b/core/pim/todo/Makefile.in new file mode 100644 index 0000000..f3c5f0e --- a/dev/null +++ b/core/pim/todo/Makefile.in | |||
@@ -0,0 +1,201 @@ | |||
1 | ############################################################################# | ||
2 | |||
3 | ####### Compiler, tools and options | ||
4 | |||
5 | CXX =$(SYSCONF_CXX) $(QT_CXX_MT) | ||
6 | CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) | ||
7 | CC =$(SYSCONF_CC) $(QT_C_MT) | ||
8 | CFLAGS =$(SYSCONF_CFLAGS) | ||
9 | INCPATH =-I$(QPEDIR)/include | ||
10 | LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT) | ||
11 | LIBS =$(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP) | ||
12 | MOC =$(SYSCONF_MOC) | ||
13 | UIC =$(SYSCONF_UIC) | ||
14 | |||
15 | ####### Target | ||
16 | |||
17 | DESTDIR = $(QPEDIR)/bin/ | ||
18 | VER_MAJ = 1 | ||
19 | VER_MIN = 0 | ||
20 | VER_PATCH = 0 | ||
21 | TARGET= todolist | ||
22 | TARGET1 = lib$(TARGET).so.$(VER_MAJ) | ||
23 | |||
24 | ####### Files | ||
25 | |||
26 | HEADERS =mainwindow.h \ | ||
27 | todotable.h \ | ||
28 | todoentryimpl.h | ||
29 | SOURCES =main.cpp \ | ||
30 | mainwindow.cpp \ | ||
31 | todotable.cpp \ | ||
32 | todoentryimpl.cpp | ||
33 | OBJECTS =main.o \ | ||
34 | mainwindow.o \ | ||
35 | todotable.o \ | ||
36 | todoentryimpl.o \ | ||
37 | todoentry.o | ||
38 | INTERFACES = todoentry.ui | ||
39 | UICDECLS = todoentry.h | ||
40 | UICIMPLS = todoentry.cpp | ||
41 | SRCMOC =moc_mainwindow.cpp \ | ||
42 | moc_todotable.cpp \ | ||
43 | moc_todoentryimpl.cpp \ | ||
44 | moc_todoentry.cpp | ||
45 | OBJMOC =moc_mainwindow.o \ | ||
46 | moc_todotable.o \ | ||
47 | moc_todoentryimpl.o \ | ||
48 | moc_todoentry.o | ||
49 | |||
50 | |||
51 | ####### Implicit rules | ||
52 | |||
53 | .SUFFIXES: .cpp .cxx .cc .C .c | ||
54 | |||
55 | .cpp.o: | ||
56 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
57 | |||
58 | .cxx.o: | ||
59 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
60 | |||
61 | .cc.o: | ||
62 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
63 | |||
64 | .C.o: | ||
65 | $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< | ||
66 | |||
67 | .c.o: | ||
68 | $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< | ||
69 | |||
70 | ####### Build rules | ||
71 | |||
72 | |||
73 | all: $(DESTDIR)$(TARGET) | ||
74 | |||
75 | $(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) | ||
76 | $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) | ||
77 | |||
78 | moc: $(SRCMOC) | ||
79 | |||
80 | tmake: | ||
81 | tmake todo.pro | ||
82 | |||
83 | clean: | ||
84 | -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) | ||
85 | -rm -f *~ core | ||
86 | -rm -f allmoc.cpp | ||
87 | |||
88 | ####### Extension Modules | ||
89 | |||
90 | listpromodules: | ||
91 | @echo | ||
92 | |||
93 | listallmodules: | ||
94 | @echo | ||
95 | |||
96 | listaddonpromodules: | ||
97 | @echo | ||
98 | |||
99 | listaddonentmodules: | ||
100 | @echo | ||
101 | |||
102 | |||
103 | REQUIRES= | ||
104 | |||
105 | ####### Sub-libraries | ||
106 | |||
107 | |||
108 | ###### Combined headers | ||
109 | |||
110 | |||
111 | |||
112 | ####### Compile | ||
113 | |||
114 | main.o: main.cpp \ | ||
115 | mainwindow.h \ | ||
116 | $(QPEDIR)/include/qpe/qpeapplication.h | ||
117 | |||
118 | mainwindow.o: mainwindow.cpp \ | ||
119 | mainwindow.h \ | ||
120 | todoentryimpl.h \ | ||
121 | todoentry.h \ | ||
122 | $(QPEDIR)/include/qpe/task.h \ | ||
123 | $(QPEDIR)/include/qpe/palmtoprecord.h \ | ||
124 | $(QPEDIR)/include/qpe/stringutil.h \ | ||
125 | todotable.h \ | ||
126 | $(QPEDIR)/include/qpe/categories.h \ | ||
127 | $(QPEDIR)/include/qpe/qpeapplication.h \ | ||
128 | $(QPEDIR)/include/qpe/config.h \ | ||
129 | $(QPEDIR)/include/qpe/finddialog.h \ | ||
130 | $(QPEDIR)/include/qpe/global.h \ | ||
131 | $(QPEDIR)/include/qpe/ir.h \ | ||
132 | $(QPEDIR)/include/qpe/qpemenubar.h \ | ||
133 | $(QPEDIR)/include/qpe/qpemessagebox.h \ | ||
134 | $(QPEDIR)/include/qpe/resource.h \ | ||
135 | $(QPEDIR)/include/qpe/qpetoolbar.h | ||
136 | |||
137 | todotable.o: todotable.cpp \ | ||
138 | todotable.h \ | ||
139 | $(QPEDIR)/include/qpe/categories.h \ | ||
140 | $(QPEDIR)/include/qpe/task.h \ | ||
141 | $(QPEDIR)/include/qpe/palmtoprecord.h \ | ||
142 | $(QPEDIR)/include/qpe/stringutil.h \ | ||
143 | $(QPEDIR)/include/qpe/categoryselect.h \ | ||
144 | $(QPEDIR)/include/qpe/xmlreader.h | ||
145 | |||
146 | todoentryimpl.o: todoentryimpl.cpp \ | ||
147 | todoentryimpl.h \ | ||
148 | todoentry.h \ | ||
149 | $(QPEDIR)/include/qpe/task.h \ | ||
150 | $(QPEDIR)/include/qpe/palmtoprecord.h \ | ||
151 | $(QPEDIR)/include/qpe/stringutil.h \ | ||
152 | $(QPEDIR)/include/qpe/categoryselect.h \ | ||
153 | $(QPEDIR)/include/qpe/datebookmonth.h \ | ||
154 | $(QPEDIR)/include/qpe/event.h \ | ||
155 | $(QPEDIR)/include/qpe/global.h \ | ||
156 | $(QPEDIR)/include/qpe/imageedit.h \ | ||
157 | $(QPEDIR)/include/qpe/timestring.h | ||
158 | |||
159 | todoentry.h: todoentry.ui | ||
160 | $(UIC) todoentry.ui -o $(INTERFACE_DECL_PATH)/todoentry.h | ||
161 | |||
162 | todoentry.cpp: todoentry.ui | ||
163 | $(UIC) todoentry.ui -i todoentry.h -o todoentry.cpp | ||
164 | |||
165 | todoentry.o: todoentry.cpp \ | ||
166 | todoentry.h \ | ||
167 | todoentry.ui | ||
168 | |||
169 | moc_mainwindow.o: moc_mainwindow.cpp \ | ||
170 | mainwindow.h | ||
171 | |||
172 | moc_todotable.o: moc_todotable.cpp \ | ||
173 | todotable.h \ | ||
174 | $(QPEDIR)/include/qpe/categories.h \ | ||
175 | $(QPEDIR)/include/qpe/task.h \ | ||
176 | $(QPEDIR)/include/qpe/palmtoprecord.h \ | ||
177 | $(QPEDIR)/include/qpe/stringutil.h | ||
178 | |||
179 | moc_todoentryimpl.o: moc_todoentryimpl.cpp \ | ||
180 | todoentryimpl.h \ | ||
181 | todoentry.h \ | ||
182 | $(QPEDIR)/include/qpe/task.h \ | ||
183 | $(QPEDIR)/include/qpe/palmtoprecord.h \ | ||
184 | $(QPEDIR)/include/qpe/stringutil.h | ||
185 | |||
186 | moc_todoentry.o: moc_todoentry.cpp \ | ||
187 | todoentry.h | ||
188 | |||
189 | moc_mainwindow.cpp: mainwindow.h | ||
190 | $(MOC) mainwindow.h -o moc_mainwindow.cpp | ||
191 | |||
192 | moc_todotable.cpp: todotable.h | ||
193 | $(MOC) todotable.h -o moc_todotable.cpp | ||
194 | |||
195 | moc_todoentryimpl.cpp: todoentryimpl.h | ||
196 | $(MOC) todoentryimpl.h -o moc_todoentryimpl.cpp | ||
197 | |||
198 | moc_todoentry.cpp: todoentry.h | ||
199 | $(MOC) todoentry.h -o moc_todoentry.cpp | ||
200 | |||
201 | |||
diff --git a/core/pim/todo/main.cpp b/core/pim/todo/main.cpp new file mode 100644 index 0000000..4e1c8a1 --- a/dev/null +++ b/core/pim/todo/main.cpp | |||
@@ -0,0 +1,36 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | |||
21 | #include "mainwindow.h" | ||
22 | |||
23 | #include <qpe/qpeapplication.h> | ||
24 | |||
25 | int main( int argc, char **argv ) | ||
26 | { | ||
27 | QPEApplication a( argc, argv ); | ||
28 | |||
29 | TodoWindow mw; | ||
30 | QObject::connect( &a, SIGNAL( flush() ), &mw, SLOT( flush() ) ); | ||
31 | QObject::connect( &a, SIGNAL( reload() ), &mw, SLOT( reload() ) ); | ||
32 | |||
33 | a.showMainWidget(&mw); | ||
34 | |||
35 | return a.exec(); | ||
36 | } | ||
diff --git a/core/pim/todo/mainwindow.cpp b/core/pim/todo/mainwindow.cpp new file mode 100644 index 0000000..fb85a09 --- a/dev/null +++ b/core/pim/todo/mainwindow.cpp | |||
@@ -0,0 +1,466 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | |||
21 | #include "mainwindow.h" | ||
22 | #include "todoentryimpl.h" | ||
23 | #include "todotable.h" | ||
24 | |||
25 | #include <qpe/qpeapplication.h> | ||
26 | #include <qpe/config.h> | ||
27 | #include <qpe/finddialog.h> | ||
28 | #include <qpe/global.h> | ||
29 | #include <qpe/ir.h> | ||
30 | #include <qpe/qpemenubar.h> | ||
31 | #include <qpe/qpemessagebox.h> | ||
32 | #include <qpe/resource.h> | ||
33 | #include <qpe/task.h> | ||
34 | #include <qpe/qpetoolbar.h> | ||
35 | |||
36 | #include <qaction.h> | ||
37 | #include <qarray.h> | ||
38 | #include <qdatastream.h> | ||
39 | #include <qdatetime.h> | ||
40 | #include <qfile.h> | ||
41 | #include <qmessagebox.h> | ||
42 | #include <qpopupmenu.h> | ||
43 | |||
44 | #include <sys/stat.h> | ||
45 | #include <sys/types.h> | ||
46 | #include <fcntl.h> | ||
47 | #include <unistd.h> | ||
48 | |||
49 | #include <stdlib.h> | ||
50 | |||
51 | static QString todolistXMLFilename() | ||
52 | { | ||
53 | return Global::applicationFileName("todolist","todolist.xml"); | ||
54 | } | ||
55 | |||
56 | static QString categoriesXMLFilename() | ||
57 | { | ||
58 | return Global::applicationFileName("todolist","categories.xml"); | ||
59 | } | ||
60 | |||
61 | TodoWindow::TodoWindow( QWidget *parent, const char *name, WFlags f = 0 ) : | ||
62 | QMainWindow( parent, name, f ), syncing(FALSE) | ||
63 | { | ||
64 | // QTime t; | ||
65 | // t.start(); | ||
66 | |||
67 | setCaption( tr("Todo") ); | ||
68 | QString str; | ||
69 | table = new TodoTable( this ); | ||
70 | table->setColumnWidth( 2, 10 ); | ||
71 | table->setPaintingEnabled( FALSE ); | ||
72 | table->setUpdatesEnabled( FALSE ); | ||
73 | table->viewport()->setUpdatesEnabled( FALSE ); | ||
74 | |||
75 | { | ||
76 | str = todolistXMLFilename(); | ||
77 | if ( str.isNull() ) | ||
78 | QMessageBox::critical( this, | ||
79 | tr("Out of Space"), | ||
80 | tr("Unable to create startup files\n" | ||
81 | "Free up some space\n" | ||
82 | "before you enter any data") ); | ||
83 | else | ||
84 | table->load( str ); | ||
85 | } | ||
86 | |||
87 | // repeat for categories... | ||
88 | str = categoriesXMLFilename(); | ||
89 | if ( str.isNull() ) | ||
90 | QMessageBox::critical( this, | ||
91 | tr( "Out of Space" ), | ||
92 | tr( "Unable to create startup files\n" | ||
93 | "Free up some space\n" | ||
94 | "before you enter any data") ); | ||
95 | |||
96 | setCentralWidget( table ); | ||
97 | setToolBarsMovable( FALSE ); | ||
98 | |||
99 | // qDebug("after load: t=%d", t.elapsed() ); | ||
100 | |||
101 | Config config( "todo" ); | ||
102 | config.setGroup( "View" ); | ||
103 | bool complete = config.readBoolEntry( "ShowComplete", true ); | ||
104 | table->setShowCompleted( complete ); | ||
105 | QString category = config.readEntry( "Category", QString::null ); | ||
106 | table->setShowCategory( category ); | ||
107 | |||
108 | QPEToolBar *bar = new QPEToolBar( this ); | ||
109 | bar->setHorizontalStretchable( TRUE ); | ||
110 | |||
111 | QPEMenuBar *mb = new QPEMenuBar( bar ); | ||
112 | |||
113 | catMenu = new QPopupMenu( this ); | ||
114 | QPopupMenu *edit = new QPopupMenu( this ); | ||
115 | contextMenu = new QPopupMenu( this ); | ||
116 | |||
117 | bar = new QPEToolBar( this ); | ||
118 | |||
119 | QAction *a = new QAction( tr( "New Task" ), Resource::loadPixmap( "new" ), | ||
120 | QString::null, 0, this, 0 ); | ||
121 | connect( a, SIGNAL( activated() ), | ||
122 | this, SLOT( slotNew() ) ); | ||
123 | a->addTo( bar ); | ||
124 | a->addTo( edit ); | ||
125 | a = new QAction( tr( "Edit" ), Resource::loadIconSet( "edit" ), | ||
126 | QString::null, 0, this, 0 ); | ||
127 | connect( a, SIGNAL( activated() ), | ||
128 | this, SLOT( slotEdit() ) ); | ||
129 | a->addTo( bar ); | ||
130 | a->addTo( edit ); | ||
131 | a->addTo( contextMenu ); | ||
132 | a->setEnabled( FALSE ); | ||
133 | editAction = a; | ||
134 | a = new QAction( tr( "Delete" ), Resource::loadIconSet( "trash" ), | ||
135 | QString::null, 0, this, 0 ); | ||
136 | connect( a, SIGNAL( activated() ), | ||
137 | this, SLOT( slotDelete() ) ); | ||
138 | a->addTo( bar ); | ||
139 | a->addTo( edit ); | ||
140 | a->addTo( contextMenu ); | ||
141 | a->setEnabled( FALSE ); | ||
142 | deleteAction = a; | ||
143 | |||
144 | if ( Ir::supported() ) { | ||
145 | a = new QAction( tr( "Beam" ), Resource::loadPixmap( "beam" ), | ||
146 | QString::null, 0, this, 0 ); | ||
147 | connect( a, SIGNAL( activated() ), | ||
148 | this, SLOT( slotBeam() ) ); | ||
149 | a->addTo( edit ); | ||
150 | a->addTo( bar ); | ||
151 | } | ||
152 | |||
153 | a = new QAction( tr( "Find" ), Resource::loadIconSet( "mag" ), | ||
154 | QString::null, 0, this, 0 ); | ||
155 | connect( a, SIGNAL( activated() ), | ||
156 | this, SLOT( slotFind() ) ); | ||
157 | a->addTo( bar ); | ||
158 | a->addTo( edit ); | ||
159 | if ( table->numRows() ) | ||
160 | a->setEnabled( TRUE ); | ||
161 | else | ||
162 | a->setEnabled( FALSE ); | ||
163 | |||
164 | //a->setEnabled( FALSE ); | ||
165 | findAction = a; | ||
166 | // qDebug("mainwindow #2: t=%d", t.elapsed() ); | ||
167 | |||
168 | completedAction = new QAction( QString::null, tr("Completed tasks"), 0, this, 0, TRUE ); | ||
169 | |||
170 | catMenu->setCheckable( true ); | ||
171 | populateCategories(); | ||
172 | |||
173 | mb->insertItem( tr( "Task" ), edit ); | ||
174 | mb->insertItem( tr( "View" ), catMenu ); | ||
175 | |||
176 | resize( 200, 300 ); | ||
177 | if ( table->numRows() > 0 ) | ||
178 | currentEntryChanged( 0, 0 ); | ||
179 | connect( table, SIGNAL( signalEdit() ), | ||
180 | this, SLOT( slotEdit() ) ); | ||
181 | connect( table, SIGNAL(signalShowMenu(const QPoint &)), | ||
182 | this, SLOT( slotShowPopup(const QPoint &)) ); | ||
183 | |||
184 | // qDebug("mainwindow #3: t=%d", t.elapsed() ); | ||
185 | table->updateVisible(); | ||
186 | table->setUpdatesEnabled( TRUE ); | ||
187 | table->setPaintingEnabled( TRUE ); | ||
188 | table->viewport()->setUpdatesEnabled( TRUE ); | ||
189 | |||
190 | connect( completedAction, SIGNAL( toggled(bool) ), this, SLOT( showCompleted(bool) ) ); | ||
191 | connect( catMenu, SIGNAL(activated(int)), this, SLOT(setCategory(int)) ); | ||
192 | connect( table, SIGNAL( currentChanged( int, int ) ), | ||
193 | this, SLOT( currentEntryChanged( int, int ) ) ); | ||
194 | |||
195 | // qDebug("done: t=%d", t.elapsed() ); | ||
196 | } | ||
197 | |||
198 | void TodoWindow::slotNew() | ||
199 | { | ||
200 | if(syncing) { | ||
201 | QMessageBox::warning(this, tr("Todo"), | ||
202 | tr("Can not edit data, currently syncing")); | ||
203 | return; | ||
204 | } | ||
205 | |||
206 | int id; | ||
207 | id = -1; | ||
208 | QArray<int> ids; | ||
209 | ids = table->currentEntry().categories(); | ||
210 | if ( ids.count() ) | ||
211 | id = ids[0]; | ||
212 | NewTaskDialog e( id, this, 0, TRUE ); | ||
213 | |||
214 | Task todo; | ||
215 | |||
216 | #if defined(Q_WS_QWS) || defined(_WS_QWS_) | ||
217 | e.showMaximized(); | ||
218 | #endif | ||
219 | int ret = e.exec(); | ||
220 | |||
221 | if ( ret == QDialog::Accepted ) { | ||
222 | table->setPaintingEnabled( false ); | ||
223 | todo = e.todoEntry(); | ||
224 | todo.assignUid(); | ||
225 | table->addEntry( todo ); | ||
226 | table->setPaintingEnabled( true ); | ||
227 | findAction->setEnabled( TRUE ); | ||
228 | } | ||
229 | // I'm afraid we must call this every time now, otherwise | ||
230 | // spend expensive time comparing all these strings... | ||
231 | populateCategories(); | ||
232 | } | ||
233 | |||
234 | TodoWindow::~TodoWindow() | ||
235 | { | ||
236 | } | ||
237 | |||
238 | void TodoWindow::slotDelete() | ||
239 | { | ||
240 | if(syncing) { | ||
241 | QMessageBox::warning(this, tr("Todo"), | ||
242 | tr("Can not edit data, currently syncing")); | ||
243 | return; | ||
244 | } | ||
245 | |||
246 | if ( table->currentRow() == -1 ) | ||
247 | return; | ||
248 | |||
249 | QString strName = table->text( table->currentRow(), 2 ).left( 30 ); | ||
250 | |||
251 | if ( !QPEMessageBox::confirmDelete( this, tr( "Todo" ), strName ) ) | ||
252 | return; | ||
253 | |||
254 | |||
255 | |||
256 | table->setPaintingEnabled( false ); | ||
257 | table->removeCurrentEntry(); | ||
258 | table->setPaintingEnabled( true ); | ||
259 | |||
260 | if ( table->numRows() == 0 ) { | ||
261 | currentEntryChanged( -1, 0 ); | ||
262 | findAction->setEnabled( FALSE ); | ||
263 | } | ||
264 | } | ||
265 | |||
266 | void TodoWindow::slotEdit() | ||
267 | { | ||
268 | if(syncing) { | ||
269 | QMessageBox::warning(this, tr("Todo"), | ||
270 | tr("Can not edit data, currently syncing")); | ||
271 | return; | ||
272 | } | ||
273 | |||
274 | Task todo = table->currentEntry(); | ||
275 | |||
276 | NewTaskDialog e( todo, this, 0, TRUE ); | ||
277 | e.setCaption( tr( "Edit Task" ) ); | ||
278 | |||
279 | #if defined(Q_WS_QWS) || defined(_WS_QWS_) | ||
280 | e.showMaximized(); | ||
281 | #endif | ||
282 | int ret = e.exec(); | ||
283 | |||
284 | if ( ret == QDialog::Accepted ) { | ||
285 | table->setPaintingEnabled( false ); | ||
286 | todo = e.todoEntry(); | ||
287 | table->replaceCurrentEntry( todo ); | ||
288 | table->setPaintingEnabled( true ); | ||
289 | } | ||
290 | populateCategories(); | ||
291 | |||
292 | } | ||
293 | |||
294 | void TodoWindow::slotShowPopup( const QPoint &p ) | ||
295 | { | ||
296 | contextMenu->popup( p ); | ||
297 | } | ||
298 | |||
299 | void TodoWindow::showCompleted( bool s ) | ||
300 | { | ||
301 | if ( !table->isUpdatesEnabled() ) | ||
302 | return; | ||
303 | table->setPaintingEnabled( false ); | ||
304 | table->setShowCompleted( s ); | ||
305 | table->setPaintingEnabled( true ); | ||
306 | } | ||
307 | |||
308 | void TodoWindow::currentEntryChanged( int r, int ) | ||
309 | { | ||
310 | if ( r != -1 && table->rowHeight( r ) > 0 ) { | ||
311 | editAction->setEnabled( TRUE ); | ||
312 | deleteAction->setEnabled( TRUE ); | ||
313 | } else { | ||
314 | editAction->setEnabled( FALSE ); | ||
315 | deleteAction->setEnabled( FALSE ); | ||
316 | } | ||
317 | } | ||
318 | |||
319 | void TodoWindow::setCategory( int c ) | ||
320 | { | ||
321 | if ( c <= 0 ) return; | ||
322 | if ( !table->isUpdatesEnabled() ) | ||
323 | return; | ||
324 | table->setPaintingEnabled( false ); | ||
325 | for ( unsigned int i = 1; i < catMenu->count(); i++ ) | ||
326 | catMenu->setItemChecked( i, c == (int)i ); | ||
327 | if ( c == 1 ) { | ||
328 | table->setShowCategory( QString::null ); | ||
329 | setCaption( tr("Todo") + " - " + tr( "All" ) ); | ||
330 | } else if ( c == (int)catMenu->count() - 1 ) { | ||
331 | table->setShowCategory( tr( "Unfiled" ) ); | ||
332 | setCaption( tr("Todo") + " - " + tr( "Unfiled" ) ); | ||
333 | } else { | ||
334 | QString cat = table->categories()[c - 2]; | ||
335 | table->setShowCategory( cat ); | ||
336 | setCaption( tr("Todo") + " - " + cat ); | ||
337 | } | ||
338 | table->setPaintingEnabled( true ); | ||
339 | } | ||
340 | |||
341 | void TodoWindow::populateCategories() | ||
342 | { | ||
343 | catMenu->clear(); | ||
344 | |||
345 | completedAction->addTo( catMenu ); | ||
346 | completedAction->setOn( table->showCompleted() ); | ||
347 | |||
348 | int id, | ||
349 | rememberId; | ||
350 | id = 1; | ||
351 | catMenu->insertItem( tr( "All" ), id++ ); | ||
352 | // catMenu->insertSeparator(); | ||
353 | QStringList categories = table->categories(); | ||
354 | categories.append( tr( "Unfiled" ) ); | ||
355 | for ( QStringList::Iterator it = categories.begin(); | ||
356 | it != categories.end(); ++it ) { | ||
357 | catMenu->insertItem( *it, id ); | ||
358 | if ( *it == table->showCategory() ) | ||
359 | rememberId = id; | ||
360 | ++id; | ||
361 | } | ||
362 | if ( table->showCategory().isEmpty() ) | ||
363 | setCategory( 1 ); | ||
364 | else | ||
365 | setCategory( rememberId ); | ||
366 | } | ||
367 | |||
368 | void TodoWindow::reload() | ||
369 | { | ||
370 | table->clear(); | ||
371 | table->load( todolistXMLFilename() ); | ||
372 | syncing = FALSE; | ||
373 | } | ||
374 | |||
375 | void TodoWindow::flush() | ||
376 | { | ||
377 | syncing = TRUE; | ||
378 | table->save( todolistXMLFilename() ); | ||
379 | } | ||
380 | |||
381 | void TodoWindow::closeEvent( QCloseEvent *e ) | ||
382 | { | ||
383 | if(syncing) { | ||
384 | /* no need to save if in the middle of syncing */ | ||
385 | e->accept(); | ||
386 | return; | ||
387 | } | ||
388 | |||
389 | if ( table->save( todolistXMLFilename() ) ) { | ||
390 | e->accept(); | ||
391 | // repeat for categories... | ||
392 | // if writing configs fail, it will emit an | ||
393 | // error, but I feel that it is "ok" for us to exit | ||
394 | // espically since we aren't told if the write succeeded... | ||
395 | Config config( "todo" ); | ||
396 | config.setGroup( "View" ); | ||
397 | config.writeEntry( "ShowComplete", table->showCompleted() ); | ||
398 | config.writeEntry( "Category", table->showCategory() ); | ||
399 | } else { | ||
400 | if ( QMessageBox::critical( this, tr("Out of space"), | ||
401 | tr("Todo was unable\n" | ||
402 | "to save your changes.\n" | ||
403 | "Free up some space\n" | ||
404 | "and try again.\n" | ||
405 | "\nQuit Anyway?"), | ||
406 | QMessageBox::Yes|QMessageBox::Escape, | ||
407 | QMessageBox::No|QMessageBox::Default) | ||
408 | != QMessageBox::No ) | ||
409 | e->accept(); | ||
410 | else | ||
411 | e->ignore(); | ||
412 | } | ||
413 | } | ||
414 | |||
415 | void TodoWindow::slotFind() | ||
416 | { | ||
417 | // put everything back to view all for searching... | ||
418 | if ( !catMenu->isItemChecked( 0 ) ) | ||
419 | setCategory( 0 ); | ||
420 | |||
421 | FindDialog dlg( "Todo List", this ); | ||
422 | QObject::connect( &dlg, | ||
423 | SIGNAL(signalFindClicked(const QString &, | ||
424 | bool, bool, int)), | ||
425 | table, | ||
426 | SLOT(slotDoFind(const QString&, bool, bool, int)) ); | ||
427 | QObject::connect( table, SIGNAL(signalNotFound()), &dlg, | ||
428 | SLOT(slotNotFound()) ); | ||
429 | QObject::connect( table, SIGNAL(signalWrapAround()), &dlg, | ||
430 | SLOT(slotWrapAround()) ); | ||
431 | dlg.exec(); | ||
432 | if ( table->numSelections() ) | ||
433 | table->clearSelection(); | ||
434 | table->clearFindRow(); | ||
435 | } | ||
436 | |||
437 | |||
438 | void TodoWindow::setDocument( const QString &filename ) | ||
439 | { | ||
440 | if ( filename.find(".vcs") != int(filename.length()) - 4 ) return; | ||
441 | |||
442 | QValueList<Task> tl = Task::readVCalendar( filename ); | ||
443 | for( QValueList<Task>::Iterator it = tl.begin(); it != tl.end(); ++it ) { | ||
444 | table->addEntry( *it ); | ||
445 | } | ||
446 | } | ||
447 | |||
448 | static const char * beamfile = "/tmp/obex/todo.vcs"; | ||
449 | |||
450 | void TodoWindow::slotBeam() | ||
451 | { | ||
452 | unlink( beamfile ); // delete if exists | ||
453 | Task c = table->currentEntry(); | ||
454 | mkdir("/tmp/obex/", 0755); | ||
455 | Task::writeVCalendar( beamfile, c ); | ||
456 | Ir *ir = new Ir( this ); | ||
457 | connect( ir, SIGNAL( done( Ir * ) ), this, SLOT( beamDone( Ir * ) ) ); | ||
458 | QString description = c.description(); | ||
459 | ir->send( beamfile, description, "text/x-vCalendar" ); | ||
460 | } | ||
461 | |||
462 | void TodoWindow::beamDone( Ir *ir ) | ||
463 | { | ||
464 | delete ir; | ||
465 | unlink( beamfile ); | ||
466 | } | ||
diff --git a/core/pim/todo/mainwindow.h b/core/pim/todo/mainwindow.h new file mode 100644 index 0000000..f4fcd1b --- a/dev/null +++ b/core/pim/todo/mainwindow.h | |||
@@ -0,0 +1,73 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | |||
21 | #ifndef MAINWINDOW_H | ||
22 | #define MAINWINDOW_H | ||
23 | |||
24 | #include <qmainwindow.h> | ||
25 | |||
26 | class TodoTable; | ||
27 | class QAction; | ||
28 | class QPopupMenu; | ||
29 | class Ir; | ||
30 | |||
31 | class TodoWindow : public QMainWindow | ||
32 | { | ||
33 | Q_OBJECT | ||
34 | |||
35 | public: | ||
36 | TodoWindow( QWidget *parent = 0, const char *name = 0, WFlags f = 0 ); | ||
37 | ~TodoWindow(); | ||
38 | |||
39 | public slots: | ||
40 | void flush(); | ||
41 | void reload(); | ||
42 | |||
43 | protected slots: | ||
44 | void slotNew(); | ||
45 | void slotDelete(); | ||
46 | void slotEdit(); | ||
47 | void slotShowPopup( const QPoint & ); | ||
48 | void showCompleted( bool ); | ||
49 | void currentEntryChanged( int r, int c ); | ||
50 | void setCategory( int ); | ||
51 | void slotFind(); | ||
52 | void setDocument( const QString & ); | ||
53 | void slotBeam(); | ||
54 | void beamDone( Ir * ); | ||
55 | |||
56 | protected: | ||
57 | void closeEvent( QCloseEvent *e ); | ||
58 | |||
59 | private: | ||
60 | void populateCategories(); | ||
61 | |||
62 | private: | ||
63 | TodoTable *table; | ||
64 | QAction *editAction, | ||
65 | *deleteAction, | ||
66 | *findAction, | ||
67 | * completedAction; | ||
68 | QPopupMenu *contextMenu, *catMenu; | ||
69 | |||
70 | bool syncing; | ||
71 | }; | ||
72 | |||
73 | #endif | ||
diff --git a/core/pim/todo/qpe-todo.control b/core/pim/todo/qpe-todo.control new file mode 100644 index 0000000..80195a0 --- a/dev/null +++ b/core/pim/todo/qpe-todo.control | |||
@@ -0,0 +1,9 @@ | |||
1 | Files: bin/todolist apps/Applications/todo.desktop | ||
2 | Priority: optional | ||
3 | Section: qpe/applications | ||
4 | Maintainer: Warwick Allison <warwick@trolltech.com> | ||
5 | Architecture: arm | ||
6 | Version: $QPE_VERSION-3 | ||
7 | Depends: qpe-base ($QPE_VERSION) | ||
8 | Description: TODO-list manager | ||
9 | A Todo-list manager for the Qtopia environment. | ||
diff --git a/core/pim/todo/todo.pro b/core/pim/todo/todo.pro new file mode 100644 index 0000000..e28ea1c --- a/dev/null +++ b/core/pim/todo/todo.pro | |||
@@ -0,0 +1,19 @@ | |||
1 | TEMPLATE= app | ||
2 | CONFIG = qt warn_on release | ||
3 | DESTDIR = $(QPEDIR)/bin | ||
4 | HEADERS= mainwindow.h \ | ||
5 | todotable.h \ | ||
6 | todoentryimpl.h | ||
7 | SOURCES= main.cpp \ | ||
8 | mainwindow.cpp \ | ||
9 | todotable.cpp \ | ||
10 | todoentryimpl.cpp | ||
11 | |||
12 | INTERFACES= todoentry.ui | ||
13 | |||
14 | TARGET = todolist | ||
15 | INCLUDEPATH += $(QPEDIR)/include | ||
16 | DEPENDPATH+= $(QPEDIR)/include | ||
17 | LIBS += -lqpe | ||
18 | |||
19 | TRANSLATIONS = ../i18n/de/todolist.ts | ||
diff --git a/core/pim/todo/todoentry.ui b/core/pim/todo/todoentry.ui new file mode 100644 index 0000000..c735e76 --- a/dev/null +++ b/core/pim/todo/todoentry.ui | |||
@@ -0,0 +1,266 @@ | |||
1 | <!DOCTYPE UI><UI> | ||
2 | <class>NewTaskDialogBase</class> | ||
3 | <comment>********************************************************************* | ||
4 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
5 | ** | ||
6 | ** This file is part of Qtopia Environment. | ||
7 | ** | ||
8 | ** This file may be distributed and/or modified under the terms of the | ||
9 | ** GNU General Public License version 2 as published by the Free Software | ||
10 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
11 | ** packaging of this file. | ||
12 | ** | ||
13 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
14 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
15 | ** | ||
16 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
17 | ** | ||
18 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
19 | ** not clear to you. | ||
20 | ** | ||
21 | *********************************************************************</comment> | ||
22 | <widget> | ||
23 | <class>QDialog</class> | ||
24 | <property stdset="1"> | ||
25 | <name>name</name> | ||
26 | <cstring>NewTaskDialogBase</cstring> | ||
27 | </property> | ||
28 | <property stdset="1"> | ||
29 | <name>geometry</name> | ||
30 | <rect> | ||
31 | <x>0</x> | ||
32 | <y>0</y> | ||
33 | <width>249</width> | ||
34 | <height>321</height> | ||
35 | </rect> | ||
36 | </property> | ||
37 | <property stdset="1"> | ||
38 | <name>caption</name> | ||
39 | <string>New Task</string> | ||
40 | </property> | ||
41 | <property> | ||
42 | <name>layoutMargin</name> | ||
43 | </property> | ||
44 | <property> | ||
45 | <name>layoutSpacing</name> | ||
46 | </property> | ||
47 | <vbox> | ||
48 | <property stdset="1"> | ||
49 | <name>margin</name> | ||
50 | <number>0</number> | ||
51 | </property> | ||
52 | <property stdset="1"> | ||
53 | <name>spacing</name> | ||
54 | <number>0</number> | ||
55 | </property> | ||
56 | <widget> | ||
57 | <class>QLayoutWidget</class> | ||
58 | <property stdset="1"> | ||
59 | <name>name</name> | ||
60 | <cstring>Layout4</cstring> | ||
61 | </property> | ||
62 | <hbox> | ||
63 | <property stdset="1"> | ||
64 | <name>margin</name> | ||
65 | <number>0</number> | ||
66 | </property> | ||
67 | <property stdset="1"> | ||
68 | <name>spacing</name> | ||
69 | <number>6</number> | ||
70 | </property> | ||
71 | <widget> | ||
72 | <class>QLabel</class> | ||
73 | <property stdset="1"> | ||
74 | <name>name</name> | ||
75 | <cstring>TextLabel2</cstring> | ||
76 | </property> | ||
77 | <property stdset="1"> | ||
78 | <name>text</name> | ||
79 | <string>Priority:</string> | ||
80 | </property> | ||
81 | </widget> | ||
82 | <widget> | ||
83 | <class>QComboBox</class> | ||
84 | <item> | ||
85 | <property> | ||
86 | <name>text</name> | ||
87 | <string>1 - Very High</string> | ||
88 | </property> | ||
89 | </item> | ||
90 | <item> | ||
91 | <property> | ||
92 | <name>text</name> | ||
93 | <string>2 - High</string> | ||
94 | </property> | ||
95 | </item> | ||
96 | <item> | ||
97 | <property> | ||
98 | <name>text</name> | ||
99 | <string>3 - Normal</string> | ||
100 | </property> | ||
101 | </item> | ||
102 | <item> | ||
103 | <property> | ||
104 | <name>text</name> | ||
105 | <string>4 - Low</string> | ||
106 | </property> | ||
107 | </item> | ||
108 | <item> | ||
109 | <property> | ||
110 | <name>text</name> | ||
111 | <string>5 - Very Low</string> | ||
112 | </property> | ||
113 | </item> | ||
114 | <property stdset="1"> | ||
115 | <name>name</name> | ||
116 | <cstring>comboPriority</cstring> | ||
117 | </property> | ||
118 | <property stdset="1"> | ||
119 | <name>sizePolicy</name> | ||
120 | <sizepolicy> | ||
121 | <hsizetype>7</hsizetype> | ||
122 | <vsizetype>0</vsizetype> | ||
123 | </sizepolicy> | ||
124 | </property> | ||
125 | <property stdset="1"> | ||
126 | <name>currentItem</name> | ||
127 | <number>2</number> | ||
128 | </property> | ||
129 | </widget> | ||
130 | </hbox> | ||
131 | </widget> | ||
132 | <widget> | ||
133 | <class>QLayoutWidget</class> | ||
134 | <property stdset="1"> | ||
135 | <name>name</name> | ||
136 | <cstring>Layout3</cstring> | ||
137 | </property> | ||
138 | <hbox> | ||
139 | <property stdset="1"> | ||
140 | <name>margin</name> | ||
141 | <number>0</number> | ||
142 | </property> | ||
143 | <property stdset="1"> | ||
144 | <name>spacing</name> | ||
145 | <number>6</number> | ||
146 | </property> | ||
147 | <widget> | ||
148 | <class>QLabel</class> | ||
149 | <property stdset="1"> | ||
150 | <name>name</name> | ||
151 | <cstring>TextLabel3</cstring> | ||
152 | </property> | ||
153 | <property stdset="1"> | ||
154 | <name>frameShape</name> | ||
155 | <enum>NoFrame</enum> | ||
156 | </property> | ||
157 | <property stdset="1"> | ||
158 | <name>text</name> | ||
159 | <string>Category:</string> | ||
160 | </property> | ||
161 | </widget> | ||
162 | <widget> | ||
163 | <class>CategorySelect</class> | ||
164 | <property stdset="1"> | ||
165 | <name>name</name> | ||
166 | <cstring>comboCategory</cstring> | ||
167 | </property> | ||
168 | </widget> | ||
169 | </hbox> | ||
170 | </widget> | ||
171 | <widget> | ||
172 | <class>QLayoutWidget</class> | ||
173 | <property stdset="1"> | ||
174 | <name>name</name> | ||
175 | <cstring>Layout4</cstring> | ||
176 | </property> | ||
177 | <hbox> | ||
178 | <property stdset="1"> | ||
179 | <name>margin</name> | ||
180 | <number>0</number> | ||
181 | </property> | ||
182 | <property stdset="1"> | ||
183 | <name>spacing</name> | ||
184 | <number>6</number> | ||
185 | </property> | ||
186 | <widget> | ||
187 | <class>QCheckBox</class> | ||
188 | <property stdset="1"> | ||
189 | <name>name</name> | ||
190 | <cstring>checkCompleted</cstring> | ||
191 | </property> | ||
192 | <property stdset="1"> | ||
193 | <name>text</name> | ||
194 | <string>&Completed</string> | ||
195 | </property> | ||
196 | </widget> | ||
197 | <widget> | ||
198 | <class>QCheckBox</class> | ||
199 | <property stdset="1"> | ||
200 | <name>name</name> | ||
201 | <cstring>checkDate</cstring> | ||
202 | </property> | ||
203 | <property stdset="1"> | ||
204 | <name>text</name> | ||
205 | <string>D&ue</string> | ||
206 | </property> | ||
207 | </widget> | ||
208 | <widget> | ||
209 | <class>QPushButton</class> | ||
210 | <property stdset="1"> | ||
211 | <name>name</name> | ||
212 | <cstring>buttonDate</cstring> | ||
213 | </property> | ||
214 | <property stdset="1"> | ||
215 | <name>enabled</name> | ||
216 | <bool>false</bool> | ||
217 | </property> | ||
218 | <property stdset="1"> | ||
219 | <name>text</name> | ||
220 | <string>1 Jan 2001</string> | ||
221 | </property> | ||
222 | </widget> | ||
223 | </hbox> | ||
224 | </widget> | ||
225 | <widget> | ||
226 | <class>QMultiLineEdit</class> | ||
227 | <property stdset="1"> | ||
228 | <name>name</name> | ||
229 | <cstring>txtTodo</cstring> | ||
230 | </property> | ||
231 | </widget> | ||
232 | </vbox> | ||
233 | </widget> | ||
234 | <customwidgets> | ||
235 | <customwidget> | ||
236 | <class>CategorySelect</class> | ||
237 | <header location="global">qpe/categoryselect.h</header> | ||
238 | <sizehint> | ||
239 | <width>-1</width> | ||
240 | <height>-1</height> | ||
241 | </sizehint> | ||
242 | <container>0</container> | ||
243 | <sizepolicy> | ||
244 | <hordata>7</hordata> | ||
245 | <verdata>1</verdata> | ||
246 | </sizepolicy> | ||
247 | <pixmap>image0</pixmap> | ||
248 | </customwidget> | ||
249 | </customwidgets> | ||
250 | <images> | ||
251 | <image> | ||
252 | <name>image0</name> | ||
253 | <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data> | ||
254 | </image> | ||
255 | </images> | ||
256 | <connections> | ||
257 | <connection> | ||
258 | <sender>checkDate</sender> | ||
259 | <signal>toggled(bool)</signal> | ||
260 | <receiver>buttonDate</receiver> | ||
261 | <slot>setEnabled(bool)</slot> | ||
262 | </connection> | ||
263 | <slot access="protected">dateChanged( const QString & )</slot> | ||
264 | <slot access="protected">dateChanged( int, int, int )</slot> | ||
265 | </connections> | ||
266 | </UI> | ||
diff --git a/core/pim/todo/todoentryimpl.cpp b/core/pim/todo/todoentryimpl.cpp new file mode 100644 index 0000000..79206de --- a/dev/null +++ b/core/pim/todo/todoentryimpl.cpp | |||
@@ -0,0 +1,142 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | |||
21 | #include "todoentryimpl.h" | ||
22 | |||
23 | #include <qpe/categoryselect.h> | ||
24 | #include <qpe/datebookmonth.h> | ||
25 | #include <qpe/global.h> | ||
26 | #include <qpe/imageedit.h> | ||
27 | #include <qpe/task.h> | ||
28 | #include <qpe/timestring.h> | ||
29 | |||
30 | #include <qmessagebox.h> | ||
31 | #include <qpopupmenu.h> | ||
32 | #include <qtoolbutton.h> | ||
33 | #include <qcombobox.h> | ||
34 | #include <qcheckbox.h> | ||
35 | #include <qlineedit.h> | ||
36 | #include <qmultilineedit.h> | ||
37 | #include <qlabel.h> | ||
38 | #include <qtimer.h> | ||
39 | #include <qapplication.h> | ||
40 | |||
41 | |||
42 | NewTaskDialog::NewTaskDialog( const Task& task, QWidget *parent, | ||
43 | const char *name, bool modal, WFlags fl ) | ||
44 | : NewTaskDialogBase( parent, name, modal, fl ), | ||
45 | todo( task ) | ||
46 | { | ||
47 | todo.setCategories( task.categories() ); | ||
48 | if ( todo.hasDueDate() ) | ||
49 | date = todo.dueDate(); | ||
50 | else | ||
51 | date = QDate::currentDate(); | ||
52 | |||
53 | init(); | ||
54 | comboPriority->setCurrentItem( task.priority() - 1 ); | ||
55 | |||
56 | checkCompleted->setChecked( task.isCompleted() ); | ||
57 | checkDate->setChecked( task.hasDueDate() ); | ||
58 | buttonDate->setText( TimeString::longDateString( date ) ); | ||
59 | |||
60 | txtTodo->setText( task.description() ); | ||
61 | } | ||
62 | |||
63 | /* | ||
64 | * Constructs a NewTaskDialog which is a child of 'parent', with the | ||
65 | * name 'name' and widget flags set to 'f' | ||
66 | * | ||
67 | * The dialog will by default be modeless, unless you set 'modal' to | ||
68 | * TRUE to construct a modal dialog. | ||
69 | */ | ||
70 | NewTaskDialog::NewTaskDialog( int id, QWidget* parent, const char* name, bool modal, | ||
71 | WFlags fl ) | ||
72 | : NewTaskDialogBase( parent, name, modal, fl ), | ||
73 | date( QDate::currentDate() ) | ||
74 | { | ||
75 | if ( id != -1 ) { | ||
76 | QArray<int> ids( 1 ); | ||
77 | ids[0] = id; | ||
78 | todo.setCategories( ids ); | ||
79 | } | ||
80 | init(); | ||
81 | } | ||
82 | |||
83 | void NewTaskDialog::init() | ||
84 | { | ||
85 | QPopupMenu *m1 = new QPopupMenu( this ); | ||
86 | picker = new DateBookMonth( m1, 0, TRUE ); | ||
87 | m1->insertItem( picker ); | ||
88 | buttonDate->setPopup( m1 ); | ||
89 | comboCategory->setCategories( todo.categories(), "Todo List", tr("Todo List") ); | ||
90 | |||
91 | connect( picker, SIGNAL( dateClicked( int, int, int ) ), | ||
92 | this, SLOT( dateChanged( int, int, int ) ) ); | ||
93 | |||
94 | buttonDate->setText( TimeString::longDateString( date ) ); | ||
95 | picker->setDate( date.year(), date.month(), date.day() ); | ||
96 | } | ||
97 | |||
98 | /* | ||
99 | * Destroys the object and frees any allocated resources | ||
100 | */ | ||
101 | NewTaskDialog::~NewTaskDialog() | ||
102 | { | ||
103 | // no need to delete child widgets, Qt does it all for us | ||
104 | } | ||
105 | void NewTaskDialog::dateChanged( int y, int m, int d ) | ||
106 | { | ||
107 | date = QDate( y, m, d ); | ||
108 | buttonDate->setText( TimeString::longDateString( date ) ); | ||
109 | } | ||
110 | |||
111 | /*! | ||
112 | */ | ||
113 | |||
114 | Task NewTaskDialog::todoEntry() | ||
115 | { | ||
116 | todo.setDueDate( date, checkDate->isChecked() ); | ||
117 | if ( comboCategory->currentCategory() != -1 ) { | ||
118 | todo.setCategories( comboCategory->currentCategories() ); | ||
119 | } | ||
120 | todo.setPriority( comboPriority->currentItem() + 1 ); | ||
121 | todo.setCompleted( checkCompleted->isChecked() ); | ||
122 | |||
123 | todo.setDescription( txtTodo->text() ); | ||
124 | |||
125 | return todo; | ||
126 | } | ||
127 | |||
128 | |||
129 | /*! | ||
130 | |||
131 | */ | ||
132 | |||
133 | void NewTaskDialog::accept() | ||
134 | { | ||
135 | QString strText = txtTodo->text(); | ||
136 | if ( !strText || strText == "") { | ||
137 | // hmm... just decline it then, the user obviously didn't care about it | ||
138 | QDialog::reject(); | ||
139 | return; | ||
140 | } | ||
141 | QDialog::accept(); | ||
142 | } | ||
diff --git a/core/pim/todo/todoentryimpl.h b/core/pim/todo/todoentryimpl.h new file mode 100644 index 0000000..932d66e --- a/dev/null +++ b/core/pim/todo/todoentryimpl.h | |||
@@ -0,0 +1,61 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | |||
21 | #ifndef NEWTASKDIALOG_H | ||
22 | #define NEWTASKDIALOG_H | ||
23 | |||
24 | #include "todoentry.h" | ||
25 | |||
26 | #include <qpe/task.h> | ||
27 | |||
28 | #include <qdatetime.h> | ||
29 | #include <qpalette.h> | ||
30 | |||
31 | class QLabel; | ||
32 | class QTimer; | ||
33 | class DateBookMonth; | ||
34 | |||
35 | class NewTaskDialog : public NewTaskDialogBase | ||
36 | { | ||
37 | Q_OBJECT | ||
38 | |||
39 | public: | ||
40 | NewTaskDialog( const Task &task, QWidget *parent = 0, const char* name = 0, | ||
41 | bool modal = FALSE, WFlags fl = 0 ); | ||
42 | NewTaskDialog( int id, QWidget* parent = 0, const char* name = 0, | ||
43 | bool modal = FALSE, WFlags fl = 0 ); | ||
44 | ~NewTaskDialog(); | ||
45 | |||
46 | Task todoEntry(); | ||
47 | |||
48 | protected slots: | ||
49 | void dateChanged( int y, int m, int d ); | ||
50 | |||
51 | protected: | ||
52 | virtual void accept(); | ||
53 | |||
54 | private: | ||
55 | void init(); | ||
56 | Task todo; | ||
57 | QDate date; | ||
58 | DateBookMonth *picker; | ||
59 | }; | ||
60 | |||
61 | #endif // NEWTASKDIALOG_H | ||
diff --git a/core/pim/todo/todotable.cpp b/core/pim/todo/todotable.cpp new file mode 100644 index 0000000..77d3389 --- a/dev/null +++ b/core/pim/todo/todotable.cpp | |||
@@ -0,0 +1,859 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | |||
21 | #include "todotable.h" | ||
22 | |||
23 | #include <qpe/categoryselect.h> | ||
24 | #include <qpe/xmlreader.h> | ||
25 | |||
26 | #include <qasciidict.h> | ||
27 | #include <qcombobox.h> | ||
28 | #include <qfile.h> | ||
29 | #include <qpainter.h> | ||
30 | #include <qtextcodec.h> | ||
31 | #include <qtimer.h> | ||
32 | #include <qdatetime.h> | ||
33 | |||
34 | #include <qcursor.h> | ||
35 | #include <qregexp.h> | ||
36 | |||
37 | #include <errno.h> | ||
38 | #include <stdlib.h> | ||
39 | |||
40 | |||
41 | |||
42 | static bool taskCompare( const Task &task, const QRegExp &r, int category ); | ||
43 | |||
44 | static QString journalFileName(); | ||
45 | |||
46 | CheckItem::CheckItem( QTable *t, const QString &key ) | ||
47 | : QTableItem( t, Never, "" ), checked( FALSE ), sortKey( key ) | ||
48 | { | ||
49 | } | ||
50 | |||
51 | QString CheckItem::key() const | ||
52 | { | ||
53 | return sortKey; | ||
54 | } | ||
55 | |||
56 | void CheckItem::setChecked( bool b ) | ||
57 | { | ||
58 | checked = b; | ||
59 | table()->updateCell( row(), col() ); | ||
60 | } | ||
61 | |||
62 | void CheckItem::toggle() | ||
63 | { | ||
64 | TodoTable *parent = static_cast<TodoTable*>(table()); | ||
65 | Task newTodo = parent->currentEntry(); | ||
66 | checked = !checked; | ||
67 | newTodo.setCompleted( checked ); | ||
68 | table()->updateCell( row(), col() ); | ||
69 | parent->replaceCurrentEntry( newTodo, true ); | ||
70 | } | ||
71 | |||
72 | bool CheckItem::isChecked() const | ||
73 | { | ||
74 | return checked; | ||
75 | } | ||
76 | |||
77 | static const int BoxSize = 10; | ||
78 | |||
79 | void CheckItem::paint( QPainter *p, const QColorGroup &cg, const QRect &cr, | ||
80 | bool ) | ||
81 | { | ||
82 | p->fillRect( 0, 0, cr.width(), cr.height(), cg.brush( QColorGroup::Base ) ); | ||
83 | |||
84 | int marg = ( cr.width() - BoxSize ) / 2; | ||
85 | int x = 0; | ||
86 | int y = ( cr.height() - BoxSize ) / 2; | ||
87 | p->setPen( QPen( cg.text() ) ); | ||
88 | p->drawRect( x + marg, y, BoxSize, BoxSize ); | ||
89 | p->drawRect( x + marg+1, y+1, BoxSize-2, BoxSize-2 ); | ||
90 | p->setPen( darkGreen ); | ||
91 | x += 1; | ||
92 | y += 1; | ||
93 | if ( checked ) { | ||
94 | QPointArray a( 7*2 ); | ||
95 | int i, xx, yy; | ||
96 | xx = x+1+marg; | ||
97 | yy = y+2; | ||
98 | for ( i=0; i<3; i++ ) { | ||
99 | a.setPoint( 2*i, xx, yy ); | ||
100 | a.setPoint( 2*i+1, xx, yy+2 ); | ||
101 | xx++; yy++; | ||
102 | } | ||
103 | yy -= 2; | ||
104 | for ( i=3; i<7; i++ ) { | ||
105 | a.setPoint( 2*i, xx, yy ); | ||
106 | a.setPoint( 2*i+1, xx, yy+2 ); | ||
107 | xx++; yy--; | ||
108 | } | ||
109 | p->drawLineSegments( a ); | ||
110 | } | ||
111 | } | ||
112 | |||
113 | |||
114 | ComboItem::ComboItem( QTable *t, EditType et ) | ||
115 | : QTableItem( t, et, "3" ), cb( 0 ) | ||
116 | { | ||
117 | setReplaceable( FALSE ); | ||
118 | } | ||
119 | |||
120 | QWidget *ComboItem::createEditor() const | ||
121 | { | ||
122 | QString txt = text(); | ||
123 | ( (ComboItem*)this )->cb = new QComboBox( table()->viewport() ); | ||
124 | cb->insertItem( "1" ); | ||
125 | cb->insertItem( "2" ); | ||
126 | cb->insertItem( "3" ); | ||
127 | cb->insertItem( "4" ); | ||
128 | cb->insertItem( "5" ); | ||
129 | cb->setCurrentItem( txt.toInt() - 1 ); | ||
130 | return cb; | ||
131 | } | ||
132 | |||
133 | void ComboItem::setContentFromEditor( QWidget *w ) | ||
134 | { | ||
135 | TodoTable *parent = static_cast<TodoTable*>(table()); | ||
136 | Task newTodo = parent->currentEntry(); | ||
137 | |||
138 | if ( w->inherits( "QComboBox" ) ) | ||
139 | setText( ( (QComboBox*)w )->currentText() ); | ||
140 | else | ||
141 | QTableItem::setContentFromEditor( w ); | ||
142 | newTodo.setPriority( text().toInt() ); | ||
143 | parent->replaceCurrentEntry( newTodo, true ); | ||
144 | } | ||
145 | |||
146 | void ComboItem::setText( const QString &s ) | ||
147 | { | ||
148 | if ( cb ) | ||
149 | cb->setCurrentItem( s.toInt() - 1 ); | ||
150 | QTableItem::setText( s ); | ||
151 | } | ||
152 | |||
153 | QString ComboItem::text() const | ||
154 | { | ||
155 | if ( cb ) | ||
156 | return cb->currentText(); | ||
157 | return QTableItem::text(); | ||
158 | } | ||
159 | |||
160 | |||
161 | |||
162 | TodoTable::TodoTable( QWidget *parent, const char *name ) | ||
163 | // #ifdef QT_QTABLE_NOHEADER_CONSTRUCTOR | ||
164 | // : QTable( 0, 3, parent, name, TRUE ), | ||
165 | // #else | ||
166 | : QTable( 0, 3, parent, name ), | ||
167 | // #endif | ||
168 | showComp( true ), | ||
169 | enablePainting( true ), | ||
170 | mCat( 0 ), | ||
171 | currFindRow( -2 ) | ||
172 | { | ||
173 | mCat.load( categoryFileName() ); | ||
174 | setSorting( TRUE ); | ||
175 | setSelectionMode( NoSelection ); | ||
176 | setColumnStretchable( 2, TRUE ); | ||
177 | setColumnWidth( 0, 20 ); | ||
178 | setColumnWidth( 1, 35 ); | ||
179 | setLeftMargin( 0 ); | ||
180 | verticalHeader()->hide(); | ||
181 | horizontalHeader()->setLabel( 0, tr( "C." ) ); | ||
182 | horizontalHeader()->setLabel( 1, tr( "Prior." ) ); | ||
183 | horizontalHeader()->setLabel( 2, tr( "Description" ) ); | ||
184 | connect( this, SIGNAL( clicked( int, int, int, const QPoint & ) ), | ||
185 | this, SLOT( slotClicked( int, int, int, const QPoint & ) ) ); | ||
186 | connect( this, SIGNAL( pressed( int, int, int, const QPoint & ) ), | ||
187 | this, SLOT( slotPressed( int, int, int, const QPoint & ) ) ); | ||
188 | connect( this, SIGNAL( valueChanged( int, int ) ), | ||
189 | this, SLOT( slotCheckPriority( int, int ) ) ); | ||
190 | connect( this, SIGNAL( currentChanged( int, int ) ), | ||
191 | this, SLOT( slotCurrentChanged( int, int ) ) ); | ||
192 | |||
193 | menuTimer = new QTimer( this ); | ||
194 | connect( menuTimer, SIGNAL(timeout()), this, SLOT(slotShowMenu()) ); | ||
195 | } | ||
196 | |||
197 | void TodoTable::addEntry( const Task &todo ) | ||
198 | { | ||
199 | int row = numRows(); | ||
200 | setNumRows( row + 1 ); | ||
201 | updateJournal( todo, ACTION_ADD ); | ||
202 | insertIntoTable( new Task(todo), row ); | ||
203 | setCurrentCell(row, currentColumn()); | ||
204 | updateVisible(); | ||
205 | } | ||
206 | |||
207 | void TodoTable::slotClicked( int row, int col, int, const QPoint &pos ) | ||
208 | { | ||
209 | if ( !cellGeometry( row, col ).contains(pos) ) | ||
210 | return; | ||
211 | // let's switch on the column number... | ||
212 | switch ( col ) | ||
213 | { | ||
214 | case 0: { | ||
215 | CheckItem *i = static_cast<CheckItem*>(item( row, col )); | ||
216 | if ( i ) { | ||
217 | int x = pos.x() - columnPos( col ); | ||
218 | int y = pos.y() - rowPos( row ); | ||
219 | int w = columnWidth( col ); | ||
220 | int h = rowHeight( row ); | ||
221 | if ( i && x >= ( w - BoxSize ) / 2 && x <= ( w - BoxSize ) / 2 + BoxSize && | ||
222 | y >= ( h - BoxSize ) / 2 && y <= ( h - BoxSize ) / 2 + BoxSize ) { | ||
223 | i->toggle(); | ||
224 | } | ||
225 | emit signalDoneChanged( i->isChecked() ); | ||
226 | } | ||
227 | } | ||
228 | break; | ||
229 | case 1: | ||
230 | break; | ||
231 | case 2: | ||
232 | // may as well edit it... | ||
233 | menuTimer->stop(); | ||
234 | // emit signalEdit(); | ||
235 | break; | ||
236 | } | ||
237 | } | ||
238 | |||
239 | void TodoTable::slotPressed( int row, int col, int, const QPoint &pos ) | ||
240 | { | ||
241 | if ( col == 2 && cellGeometry( row, col ).contains(pos) ) | ||
242 | menuTimer->start( 750, TRUE ); | ||
243 | } | ||
244 | |||
245 | void TodoTable::slotShowMenu() | ||
246 | { | ||
247 | emit signalShowMenu( QCursor::pos() ); | ||
248 | } | ||
249 | |||
250 | void TodoTable::slotCurrentChanged( int, int ) | ||
251 | { | ||
252 | menuTimer->stop(); | ||
253 | } | ||
254 | |||
255 | void TodoTable::internalAddEntries( QList<Task> &list ) | ||
256 | { | ||
257 | setNumRows( list.count() ); | ||
258 | int row = 0; | ||
259 | Task *it; | ||
260 | for ( it = list.first(); it; it = list.next() ) | ||
261 | insertIntoTable( it, row++ ); | ||
262 | } | ||
263 | |||
264 | |||
265 | Task TodoTable::currentEntry() const | ||
266 | { | ||
267 | QTableItem *i = item( currentRow(), 0 ); | ||
268 | if ( !i || rowHeight( currentRow() ) <= 0 ) | ||
269 | return Task(); | ||
270 | Task *todo = todoList[(CheckItem*)i]; | ||
271 | todo->setCompleted( ( (CheckItem*)item( currentRow(), 0 ) )->isChecked() ); | ||
272 | todo->setPriority( ( (ComboItem*)item( currentRow(), 1 ) )->text().toInt() ); | ||
273 | return *todo; | ||
274 | } | ||
275 | |||
276 | void TodoTable::replaceCurrentEntry( const Task &todo, bool fromTableItem ) | ||
277 | { | ||
278 | int row = currentRow(); | ||
279 | updateJournal( todo, ACTION_REPLACE, row ); | ||
280 | |||
281 | if ( !fromTableItem ) { | ||
282 | journalFreeReplaceEntry( todo, row ); | ||
283 | updateVisible(); | ||
284 | } | ||
285 | } | ||
286 | |||
287 | void TodoTable::removeCurrentEntry() | ||
288 | { | ||
289 | Task *oldTodo; | ||
290 | int row = currentRow(); | ||
291 | CheckItem *chk; | ||
292 | |||
293 | chk = static_cast<CheckItem*>(item(row, 0 )); | ||
294 | if ( !chk ) | ||
295 | return; | ||
296 | oldTodo = todoList[chk]; | ||
297 | todoList.remove( chk ); | ||
298 | oldTodo->setCompleted( chk->isChecked() ); | ||
299 | oldTodo->setPriority( static_cast<ComboItem*>(item(row, 1))->text().toInt() ); | ||
300 | realignTable( row ); | ||
301 | updateVisible(); | ||
302 | updateJournal( *oldTodo, ACTION_REMOVE, row ); | ||
303 | delete oldTodo; | ||
304 | } | ||
305 | |||
306 | |||
307 | bool TodoTable::save( const QString &fn ) | ||
308 | { | ||
309 | QString strNewFile = fn + ".new"; | ||
310 | QFile f( strNewFile ); | ||
311 | if ( !f.open( IO_WriteOnly|IO_Raw ) ) | ||
312 | return false; | ||
313 | |||
314 | QString buf("<!DOCTYPE Tasks>\n<Tasks>\n"); | ||
315 | QCString str; | ||
316 | int total_written; | ||
317 | |||
318 | for ( QMap<CheckItem*, Task *>::Iterator it = todoList.begin(); | ||
319 | it != todoList.end(); ++it ) { | ||
320 | if ( !item( it.key()->row(), 0 ) ) | ||
321 | continue; | ||
322 | Task *todo = *it; | ||
323 | // sync item with table | ||
324 | todo->setCompleted( ((CheckItem*)item(it.key()->row(), 0))->isChecked() ); | ||
325 | todo->setPriority( ((ComboItem*)item( it.key()->row(), 1))->text().toInt() ); | ||
326 | buf += "<Task"; | ||
327 | todo->save( buf ); | ||
328 | buf += " />\n"; | ||
329 | str = buf.utf8(); | ||
330 | total_written = f.writeBlock( str.data(), str.length() ); | ||
331 | if ( total_written != int(str.length()) ) { | ||
332 | f.close(); | ||
333 | QFile::remove( strNewFile ); | ||
334 | return false; | ||
335 | } | ||
336 | buf = ""; | ||
337 | } | ||
338 | |||
339 | buf += "</Tasks>\n"; | ||
340 | str = buf.utf8(); | ||
341 | total_written = f.writeBlock( str.data(), str.length() ); | ||
342 | if ( total_written != int(str.length()) ) { | ||
343 | f.close(); | ||
344 | QFile::remove( strNewFile ); | ||
345 | return false; | ||
346 | } | ||
347 | f.close(); | ||
348 | |||
349 | // now do the rename | ||
350 | if ( ::rename( strNewFile, fn ) < 0 ) | ||
351 | qWarning( "problem renaming file %s to %s errno %d", | ||
352 | strNewFile.latin1(), fn.latin1(), errno ); | ||
353 | |||
354 | // remove the journal | ||
355 | QFile::remove( journalFileName() ); | ||
356 | return true; | ||
357 | } | ||
358 | |||
359 | void TodoTable::load( const QString &fn ) | ||
360 | { | ||
361 | loadFile( fn, false ); | ||
362 | if ( QFile::exists(journalFileName()) ) { | ||
363 | loadFile( journalFileName(), true ); | ||
364 | save( fn ); | ||
365 | } | ||
366 | // QTable::sortColumn(2,TRUE,TRUE); | ||
367 | // QTable::sortColumn(1,TRUE,TRUE); | ||
368 | QTable::sortColumn(0,TRUE,TRUE); | ||
369 | setCurrentCell( 0, 2 ); | ||
370 | } | ||
371 | |||
372 | void TodoTable::updateVisible() | ||
373 | { | ||
374 | if ( !isUpdatesEnabled() ) | ||
375 | return; | ||
376 | |||
377 | // qDebug("--> updateVisible!"); | ||
378 | |||
379 | int visible = 0; | ||
380 | int id = mCat.id( "Todo List", showCat ); | ||
381 | for ( int row = 0; row < numRows(); row++ ) { | ||
382 | CheckItem *ci = (CheckItem *)item( row, 0 ); | ||
383 | Task *t = todoList[ci]; | ||
384 | QArray<int> vlCats = t->categories(); | ||
385 | bool hide = false; | ||
386 | if ( !showComp && ci->isChecked() ) | ||
387 | hide = true; | ||
388 | if ( !showCat.isEmpty() ) { | ||
389 | if ( showCat == tr( "Unfiled" ) ) { | ||
390 | if ( vlCats.count() > 0 ) | ||
391 | hide = true; | ||
392 | } else { | ||
393 | // do some comparing, we have to reverse our idea here... | ||
394 | if ( !hide ) { | ||
395 | hide = true; | ||
396 | for ( uint it = 0; it < vlCats.count(); ++it ) { | ||
397 | if ( vlCats[it] == id ) { | ||
398 | hide = false; | ||
399 | break; | ||
400 | } | ||
401 | } | ||
402 | } | ||
403 | } | ||
404 | } | ||
405 | if ( hide ) { | ||
406 | if ( currentRow() == row ) | ||
407 | setCurrentCell( -1, 0 ); | ||
408 | if ( rowHeight( row ) > 0 ) | ||
409 | hideRow( row ); | ||
410 | } else { | ||
411 | if ( rowHeight( row ) == 0 ) { | ||
412 | showRow( row ); | ||
413 | adjustRow( row ); | ||
414 | } | ||
415 | visible++; | ||
416 | } | ||
417 | } | ||
418 | if ( !visible ) | ||
419 | setCurrentCell( -1, 0 ); | ||
420 | } | ||
421 | |||
422 | void TodoTable::viewportPaintEvent( QPaintEvent *pe ) | ||
423 | { | ||
424 | if ( enablePainting ) | ||
425 | QTable::viewportPaintEvent( pe ); | ||
426 | } | ||
427 | |||
428 | void TodoTable::setPaintingEnabled( bool e ) | ||
429 | { | ||
430 | if ( e != enablePainting ) { | ||
431 | if ( !enablePainting ) { | ||
432 | enablePainting = true; | ||
433 | rowHeightChanged( 0 ); | ||
434 | viewport()->update(); | ||
435 | } else { | ||
436 | enablePainting = false; | ||
437 | } | ||
438 | } | ||
439 | } | ||
440 | |||
441 | void TodoTable::clear() | ||
442 | { | ||
443 | for ( QMap<CheckItem*, Task *>::Iterator it = todoList.begin(); | ||
444 | it != todoList.end(); ++it ) { | ||
445 | Task *todo = *it; | ||
446 | delete todo; | ||
447 | } | ||
448 | todoList.clear(); | ||
449 | for ( int r = 0; r < numRows(); ++r ) { | ||
450 | for ( int c = 0; c < numCols(); ++c ) { | ||
451 | if ( cellWidget( r, c ) ) | ||
452 | clearCellWidget( r, c ); | ||
453 | clearCell( r, c ); | ||
454 | } | ||
455 | } | ||
456 | setNumRows( 0 ); | ||
457 | } | ||
458 | |||
459 | void TodoTable::sortColumn( int col, bool /*ascending*/, bool /*wholeRows*/ ) | ||
460 | { | ||
461 | // The default for wholeRows is false, however | ||
462 | // for this todo table we want to exchange complete | ||
463 | // rows when sorting. Also, we always want ascending, since | ||
464 | // the values have a logical order. | ||
465 | QTable::sortColumn( col, TRUE, TRUE ); | ||
466 | updateVisible(); | ||
467 | } | ||
468 | |||
469 | void TodoTable::slotCheckPriority(int row, int col ) | ||
470 | { | ||
471 | // kludgey work around to make forward along the updated priority... | ||
472 | if ( col == 1 ) { | ||
473 | // let everyone know!! | ||
474 | ComboItem* i = static_cast<ComboItem*>( item( row, col ) ); | ||
475 | emit signalPriorityChanged( i->text().toInt() ); | ||
476 | } | ||
477 | } | ||
478 | |||
479 | |||
480 | void TodoTable::updateJournal( const Task &todo, journal_action action, int row ) | ||
481 | { | ||
482 | QFile f( journalFileName() ); | ||
483 | if ( !f.open(IO_WriteOnly|IO_Append) ) | ||
484 | return; | ||
485 | QString buf; | ||
486 | QCString str; | ||
487 | buf = "<Task"; | ||
488 | todo.save( buf ); | ||
489 | buf += " Action=\"" + QString::number( int(action) ) + "\""; | ||
490 | buf += " Row=\"" + QString::number( row ) + "\""; | ||
491 | buf += "/>\n"; | ||
492 | str = buf.utf8(); | ||
493 | f.writeBlock( str.data(), str.length() ); | ||
494 | f.close(); | ||
495 | } | ||
496 | |||
497 | void TodoTable::rowHeightChanged( int row ) | ||
498 | { | ||
499 | if ( enablePainting ) | ||
500 | QTable::rowHeightChanged( row ); | ||
501 | } | ||
502 | |||
503 | void TodoTable::loadFile( const QString &strFile, bool fromJournal ) | ||
504 | { | ||
505 | QFile f( strFile ); | ||
506 | if ( !f.open(IO_ReadOnly) ) | ||
507 | return; | ||
508 | |||
509 | int action, row; | ||
510 | action = 0; row = 0; | ||
511 | |||
512 | enum Attribute { | ||
513 | FCompleted = 0, | ||
514 | FHasDate, | ||
515 | FPriority, | ||
516 | FCategories, | ||
517 | FDescription, | ||
518 | FDateYear, | ||
519 | FDateMonth, | ||
520 | FDateDay, | ||
521 | FUid, | ||
522 | FAction, | ||
523 | FRow | ||
524 | }; | ||
525 | |||
526 | QAsciiDict<int> dict( 31 ); | ||
527 | QList<Task> list; | ||
528 | dict.setAutoDelete( TRUE ); | ||
529 | dict.insert( "Completed", new int(FCompleted) ); | ||
530 | dict.insert( "HasDate", new int(FHasDate) ); | ||
531 | dict.insert( "Priority", new int(FPriority) ); | ||
532 | dict.insert( "Categories", new int(FCategories) ); | ||
533 | dict.insert( "Description", new int(FDescription) ); | ||
534 | dict.insert( "DateYear", new int(FDateYear) ); | ||
535 | dict.insert( "DateMonth", new int(FDateMonth) ); | ||
536 | dict.insert( "DateDay", new int(FDateDay) ); | ||
537 | dict.insert( "Uid", new int(FUid) ); | ||
538 | dict.insert( "Action", new int(FAction) ); | ||
539 | dict.insert( "Row", new int(FRow) ); | ||
540 | |||
541 | QByteArray ba = f.readAll(); | ||
542 | f.close(); | ||
543 | char* dt = ba.data(); | ||
544 | int len = ba.size(); | ||
545 | bool hasDueDate = FALSE; | ||
546 | |||
547 | action = ACTION_ADD; | ||
548 | int i = 0; | ||
549 | char *point; | ||
550 | while ( ( point = strstr( dt+i, "<Task " ) ) != NULL ) { | ||
551 | // new Task | ||
552 | i = point - dt; | ||
553 | Task *todo = new Task; | ||
554 | int dtY = 0, dtM = 0, dtD = 0; | ||
555 | |||
556 | i += 5; | ||
557 | |||
558 | while( 1 ) { | ||
559 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) | ||
560 | ++i; | ||
561 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) | ||
562 | break; | ||
563 | // we have another attribute, read it. | ||
564 | int j = i; | ||
565 | while ( j < len && dt[j] != '=' ) | ||
566 | ++j; | ||
567 | char *attr = dt+i; | ||
568 | dt[j] = '\0'; | ||
569 | i = ++j; // skip = | ||
570 | while ( i < len && dt[i] != '"' ) | ||
571 | ++i; | ||
572 | j = ++i; | ||
573 | bool haveUtf = FALSE; | ||
574 | bool haveEnt = FALSE; | ||
575 | while ( j < len && dt[j] != '"' ) { | ||
576 | if ( ((unsigned char)dt[j]) > 0x7f ) | ||
577 | haveUtf = TRUE; | ||
578 | if ( dt[j] == '&' ) | ||
579 | haveEnt = TRUE; | ||
580 | ++j; | ||
581 | } | ||
582 | if ( i == j ) { | ||
583 | // empty value | ||
584 | i = j + 1; | ||
585 | continue; | ||
586 | } | ||
587 | QCString value( dt+i, j-i+1 ); | ||
588 | i = j + 1; | ||
589 | int *lookup = dict[ attr ]; | ||
590 | if ( !lookup ) { | ||
591 | todo->setCustomField(attr, value); | ||
592 | continue; | ||
593 | } | ||
594 | switch( *lookup ) { | ||
595 | case FCompleted: | ||
596 | todo->setCompleted( value.toInt() ); | ||
597 | break; | ||
598 | case FHasDate: | ||
599 | // leave... | ||
600 | hasDueDate = value.toInt(); | ||
601 | break; | ||
602 | case FPriority: | ||
603 | todo->setPriority( value.toInt() ); | ||
604 | break; | ||
605 | case FCategories: { | ||
606 | //QString str = Qtopia::plainString( value ); | ||
607 | todo->setCategories( Qtopia::Record::idsFromString( value ) ); | ||
608 | break; | ||
609 | } | ||
610 | case FDescription: | ||
611 | { | ||
612 | QString str = (haveUtf ? QString::fromUtf8( value ) | ||
613 | : QString::fromLatin1( value ) ); | ||
614 | if ( haveEnt ) | ||
615 | str = Qtopia::plainString( str ); | ||
616 | todo->setDescription( str ); | ||
617 | break; | ||
618 | } | ||
619 | case FDateYear: | ||
620 | dtY = value.toInt(); | ||
621 | break; | ||
622 | case FDateMonth: | ||
623 | dtM = value.toInt(); | ||
624 | break; | ||
625 | case FDateDay: | ||
626 | dtD = value.toInt(); | ||
627 | break; | ||
628 | case FUid: | ||
629 | todo->setUid( value.toInt() ); | ||
630 | break; | ||
631 | case FAction: | ||
632 | action = value.toInt(); | ||
633 | break; | ||
634 | case FRow: | ||
635 | row = value.toInt(); | ||
636 | break; | ||
637 | default: | ||
638 | qDebug( "huh??? missing enum? -- attr.: %s", attr ); | ||
639 | break; | ||
640 | } | ||
641 | } | ||
642 | |||
643 | if ( dtY != 0 && dtM != 0 && dtD != 0 ) | ||
644 | todo->setDueDate( QDate( dtY, dtM, dtD), hasDueDate ); | ||
645 | else | ||
646 | todo->setHasDueDate( hasDueDate ); | ||
647 | |||
648 | // if ( categoryList.find( todo.category() ) == categoryList.end() ) | ||
649 | // categoryList.append( todo.category() ); | ||
650 | |||
651 | |||
652 | // sadly we can't delay adding of items from the journal to get | ||
653 | // the proper effect, but then, the journal should _never_ be | ||
654 | // that huge | ||
655 | |||
656 | switch( action ) { | ||
657 | case ACTION_ADD: | ||
658 | if ( fromJournal ) { | ||
659 | int myrows = numRows(); | ||
660 | setNumRows( myrows + 1 ); | ||
661 | insertIntoTable( todo, myrows ); | ||
662 | delete todo; | ||
663 | } else | ||
664 | list.append( todo ); | ||
665 | break; | ||
666 | case ACTION_REMOVE: | ||
667 | journalFreeRemoveEntry( row ); | ||
668 | break; | ||
669 | case ACTION_REPLACE: | ||
670 | journalFreeReplaceEntry( *todo, row ); | ||
671 | delete todo; | ||
672 | break; | ||
673 | default: | ||
674 | break; | ||
675 | } | ||
676 | } | ||
677 | // qDebug("parsing done=%d", t.elapsed() ); | ||
678 | if ( list.count() > 0 ) { | ||
679 | internalAddEntries( list ); | ||
680 | list.clear(); | ||
681 | } | ||
682 | // qDebug("loading done: t=%d", t.elapsed() ); | ||
683 | } | ||
684 | |||
685 | void TodoTable::journalFreeReplaceEntry( const Task &todo, int row ) | ||
686 | { | ||
687 | QString strTodo; | ||
688 | strTodo = todo.description().left(40).simplifyWhiteSpace(); | ||
689 | if ( row == -1 ) { | ||
690 | QMapIterator<CheckItem*, Task *> it; | ||
691 | for ( it = todoList.begin(); it != todoList.end(); ++it ) { | ||
692 | if ( *(*it) == todo ) { | ||
693 | row = it.key()->row(); | ||
694 | it.key()->setChecked( todo.isCompleted() ); | ||
695 | static_cast<ComboItem*>(item(row, 1))->setText( QString::number(todo.priority()) ); | ||
696 | item( row, 2 )->setText( strTodo ); | ||
697 | *(*it) = todo; | ||
698 | } | ||
699 | } | ||
700 | } else { | ||
701 | Task *t = todoList[static_cast<CheckItem*>(item(row, 0))]; | ||
702 | todoList.remove( static_cast<CheckItem*>(item(row, 0)) ); | ||
703 | delete t; | ||
704 | static_cast<CheckItem*>(item(row, 0))->setChecked( todo.isCompleted() ); | ||
705 | static_cast<ComboItem*>(item(row, 1))->setText( QString::number(todo.priority()) ); | ||
706 | item( row, 2 )->setText( strTodo ); | ||
707 | todoList.insert( static_cast<CheckItem*>(item(row,0)), new Task(todo) ); | ||
708 | } | ||
709 | } | ||
710 | |||
711 | void TodoTable::journalFreeRemoveEntry( int row ) | ||
712 | { | ||
713 | CheckItem *chk; | ||
714 | chk = static_cast<CheckItem*>(item(row, 0 )); | ||
715 | if ( !chk ) | ||
716 | return; | ||
717 | todoList.remove( chk ); | ||
718 | |||
719 | realignTable( row ); | ||
720 | } | ||
721 | |||
722 | void TodoTable::keyPressEvent( QKeyEvent *e ) | ||
723 | { | ||
724 | if ( e->key() == Key_Space || e->key() == Key_Return ) { | ||
725 | switch ( currentColumn() ) { | ||
726 | case 0: { | ||
727 | CheckItem *i = static_cast<CheckItem*>(item(currentRow(), | ||
728 | currentColumn())); | ||
729 | if ( i ) | ||
730 | i->toggle(); | ||
731 | break; | ||
732 | } | ||
733 | case 1: | ||
734 | break; | ||
735 | case 2: | ||
736 | emit signalEdit(); | ||
737 | default: | ||
738 | break; | ||
739 | } | ||
740 | } else { | ||
741 | QTable::keyPressEvent( e ); | ||
742 | } | ||
743 | } | ||
744 | |||
745 | QStringList TodoTable::categories() | ||
746 | { | ||
747 | // This is called seldom, so calling a load in here | ||
748 | // should be fine. | ||
749 | mCat.load( categoryFileName() ); | ||
750 | QStringList categoryList = mCat.labels( "Todo List" ); | ||
751 | return categoryList; | ||
752 | } | ||
753 | |||
754 | void TodoTable::slotDoFind( const QString &findString, bool caseSensitive, | ||
755 | bool backwards, int category ) | ||
756 | { | ||
757 | // we have to iterate through the table, this gives the illusion that | ||
758 | // sorting is actually being used. | ||
759 | if ( currFindRow < -1 ) | ||
760 | currFindRow = currentRow() - 1; | ||
761 | clearSelection( TRUE ); | ||
762 | int rows, | ||
763 | row; | ||
764 | CheckItem *chk; | ||
765 | QRegExp r( findString ); | ||
766 | |||
767 | r.setCaseSensitive( caseSensitive ); | ||
768 | rows = numRows(); | ||
769 | static bool wrapAround = true; | ||
770 | |||
771 | if ( !backwards ) { | ||
772 | for ( row = currFindRow + 1; row < rows; row++ ) { | ||
773 | chk = static_cast<CheckItem*>( item(row, 0) ); | ||
774 | if ( taskCompare(*(todoList[chk]), r, category) ) | ||
775 | break; | ||
776 | } | ||
777 | } else { | ||
778 | for ( row = currFindRow - 1; row > -1; row-- ) { | ||
779 | chk = static_cast<CheckItem*>( item(row, 0) ); | ||
780 | if ( taskCompare(*(todoList[chk]), r, category) ) | ||
781 | break; | ||
782 | } | ||
783 | } | ||
784 | if ( row >= rows || row < 0 ) { | ||
785 | if ( row < 0 ) | ||
786 | currFindRow = rows; | ||
787 | else | ||
788 | currFindRow = -1; | ||
789 | if ( wrapAround ) | ||
790 | emit signalWrapAround(); | ||
791 | else | ||
792 | emit signalNotFound(); | ||
793 | wrapAround = !wrapAround; | ||
794 | } else { | ||
795 | currFindRow = row; | ||
796 | QTableSelection foundSelection; | ||
797 | foundSelection.init( currFindRow, 0 ); | ||
798 | foundSelection.expandTo( currFindRow, numCols() - 1 ); | ||
799 | addSelection( foundSelection ); | ||
800 | setCurrentCell( currFindRow, numCols() - 1 ); | ||
801 | // we should always be able to wrap around and find this again, | ||
802 | // so don't give confusing not found message... | ||
803 | wrapAround = true; | ||
804 | } | ||
805 | } | ||
806 | |||
807 | int TodoTable::showCategoryId() const | ||
808 | { | ||
809 | int id; | ||
810 | id = -1; | ||
811 | // if allcategories are selected, you get unfiled... | ||
812 | if ( showCat != tr( "Unfiled" ) && showCat != tr( "All" ) ) | ||
813 | id = mCat.id( "Todo List", showCat ); | ||
814 | return id; | ||
815 | } | ||
816 | |||
817 | static bool taskCompare( const Task &task, const QRegExp &r, int category ) | ||
818 | { | ||
819 | bool returnMe; | ||
820 | QArray<int> cats; | ||
821 | cats = task.categories(); | ||
822 | |||
823 | returnMe = false; | ||
824 | if ( (category == -1 && cats.count() == 0) || category == -2 ) | ||
825 | returnMe = task.match( r ); | ||
826 | else { | ||
827 | int i; | ||
828 | for ( i = 0; i < int(cats.count()); i++ ) { | ||
829 | if ( cats[i] == category ) { | ||
830 | returnMe = task.match( r ); | ||
831 | break; | ||
832 | } | ||
833 | } | ||
834 | } | ||
835 | return returnMe; | ||
836 | } | ||
837 | |||
838 | static QString journalFileName() | ||
839 | { | ||
840 | QString str; | ||
841 | str = getenv( "HOME" ); | ||
842 | str += "/.todojournal"; | ||
843 | return str; | ||
844 | } | ||
845 | |||
846 | // int TodoTable::rowHeight( int ) const | ||
847 | // { | ||
848 | // return 18; | ||
849 | // } | ||
850 | |||
851 | // int TodoTable::rowPos( int row ) const | ||
852 | // { | ||
853 | // return 18*row; | ||
854 | // } | ||
855 | |||
856 | // int TodoTable::rowAt( int pos ) const | ||
857 | // { | ||
858 | // return QMIN( pos/18, numRows()-1 ); | ||
859 | // } | ||
diff --git a/core/pim/todo/todotable.h b/core/pim/todo/todotable.h new file mode 100644 index 0000000..4f3a064 --- a/dev/null +++ b/core/pim/todo/todotable.h | |||
@@ -0,0 +1,207 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | |||
21 | #ifndef TODOTABLE_H | ||
22 | #define TODOTABLE_H | ||
23 | |||
24 | #include <qpe/categories.h> | ||
25 | #include <qpe/stringutil.h> | ||
26 | #include <qpe/task.h> | ||
27 | |||
28 | #include <qtable.h> | ||
29 | #include <qmap.h> | ||
30 | #include <qguardedptr.h> | ||
31 | |||
32 | class Node; | ||
33 | class QComboBox; | ||
34 | class QTimer; | ||
35 | |||
36 | class CheckItem : public QTableItem | ||
37 | { | ||
38 | public: | ||
39 | CheckItem( QTable *t, const QString &sortkey ); | ||
40 | |||
41 | void setChecked( bool b ); | ||
42 | void toggle(); | ||
43 | bool isChecked() const; | ||
44 | void setKey( const QString &key ) { sortKey = key; } | ||
45 | QString key() const; | ||
46 | |||
47 | void paint( QPainter *p, const QColorGroup &cg, const QRect &cr, bool selected ); | ||
48 | |||
49 | private: | ||
50 | bool checked; | ||
51 | QString sortKey; | ||
52 | }; | ||
53 | |||
54 | class ComboItem : public QTableItem | ||
55 | { | ||
56 | public: | ||
57 | ComboItem( QTable *t, EditType et ); | ||
58 | QWidget *createEditor() const; | ||
59 | void setContentFromEditor( QWidget *w ); | ||
60 | void setText( const QString &s ); | ||
61 | int alignment() const { return Qt::AlignCenter; } | ||
62 | |||
63 | QString text() const; | ||
64 | |||
65 | private: | ||
66 | QGuardedPtr<QComboBox> cb; | ||
67 | |||
68 | }; | ||
69 | |||
70 | class TodoTextItem : public QTableItem | ||
71 | { | ||
72 | public: | ||
73 | TodoTextItem( QTable *t, const QString & str ) | ||
74 | :QTableItem( t, QTableItem::Never, str ) {} | ||
75 | |||
76 | QString key () const { return Qtopia::buildSortKey( text() ); } | ||
77 | }; | ||
78 | |||
79 | |||
80 | |||
81 | enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE }; | ||
82 | |||
83 | class TodoTable : public QTable | ||
84 | { | ||
85 | Q_OBJECT | ||
86 | |||
87 | public: | ||
88 | TodoTable( QWidget *parent = 0, const char * name = 0 ); | ||
89 | void addEntry( const Task &todo ); | ||
90 | void clearFindRow() { currFindRow = -2; } | ||
91 | |||
92 | Task currentEntry() const; | ||
93 | void replaceCurrentEntry( const Task &todo, bool fromTableItem = false ); | ||
94 | |||
95 | QStringList categories(); | ||
96 | |||
97 | void setShowCompleted( bool sc ) { showComp = sc; updateVisible(); } | ||
98 | bool showCompleted() const { return showComp; } | ||
99 | |||
100 | void setShowCategory( const QString &c ) { showCat = c; updateVisible(); } | ||
101 | const QString &showCategory() const { return showCat; } | ||
102 | int showCategoryId() const; | ||
103 | |||
104 | bool save( const QString &fn ); | ||
105 | void load( const QString &fn ); | ||
106 | void clear(); | ||
107 | void removeCurrentEntry(); | ||
108 | |||
109 | void setPaintingEnabled( bool e ); | ||
110 | |||
111 | virtual void sortColumn( int col, bool ascending, bool /*wholeRows*/ ); | ||
112 | |||
113 | // int rowHeight( int ) const; | ||
114 | // int rowPos( int row ) const; | ||
115 | // virtual int rowAt( int pos ) const; | ||
116 | |||
117 | signals: | ||
118 | void signalEdit(); | ||
119 | void signalDoneChanged( bool b ); | ||
120 | void signalPriorityChanged( int i ); | ||
121 | void signalShowMenu( const QPoint & ); | ||
122 | void signalNotFound(); | ||
123 | void signalWrapAround(); | ||
124 | |||
125 | protected: | ||
126 | void keyPressEvent( QKeyEvent *e ); | ||
127 | |||
128 | private: | ||
129 | void updateVisible(); | ||
130 | void viewportPaintEvent( QPaintEvent * ); | ||
131 | void internalAddEntries( QList<Task> &list); | ||
132 | inline void insertIntoTable( Task *todo, int row ); | ||
133 | void updateJournal( const Task &todo, journal_action action, int row = -1); | ||
134 | void mergeJournal(); | ||
135 | void journalFreeReplaceEntry( const Task &todo, int row ); | ||
136 | void journalFreeRemoveEntry( int row ); | ||
137 | inline void realignTable( int row ); | ||
138 | void loadFile( const QString &strFile, bool fromJournal = false ); | ||
139 | |||
140 | private slots: | ||
141 | void slotClicked( int row, int col, int button, const QPoint &pos ); | ||
142 | void slotPressed( int row, int col, int button, const QPoint &pos ); | ||
143 | void slotCheckPriority(int row, int col ); | ||
144 | void slotCurrentChanged(int row, int col ); | ||
145 | void slotDoFind( const QString &findString, bool caseSensetive, | ||
146 | bool backwards, int category ); | ||
147 | void slotShowMenu(); | ||
148 | void rowHeightChanged( int row ); | ||
149 | |||
150 | private: | ||
151 | friend class TodoWindow; | ||
152 | |||
153 | QMap<CheckItem*, Task *> todoList; | ||
154 | QStringList categoryList; | ||
155 | bool showComp; | ||
156 | QString showCat; | ||
157 | QTimer *menuTimer; | ||
158 | bool enablePainting; | ||
159 | Categories mCat; | ||
160 | int currFindRow; | ||
161 | }; | ||
162 | |||
163 | |||
164 | inline void TodoTable::insertIntoTable( Task *todo, int row ) | ||
165 | { | ||
166 | QString sortKey = (char) ((todo->isCompleted() ? 'a' : 'A') | ||
167 | + todo->priority() ) | ||
168 | + Qtopia::buildSortKey( todo->description() ); | ||
169 | CheckItem *chk = new CheckItem( this, sortKey ); | ||
170 | chk->setChecked( todo->isCompleted() ); | ||
171 | ComboItem *cmb = new ComboItem( this, QTableItem::WhenCurrent ); | ||
172 | cmb->setText( QString::number( todo->priority() ) ); | ||
173 | QTableItem *ti = new TodoTextItem( this, todo->description().left(40).simplifyWhiteSpace() ); | ||
174 | ti->setReplaceable( false ); | ||
175 | |||
176 | setItem( row, 0, chk ); | ||
177 | setItem( row, 1, cmb ); | ||
178 | setItem( row, 2, ti ); | ||
179 | |||
180 | todoList.insert( chk, todo ); | ||
181 | } | ||
182 | |||
183 | inline void TodoTable::realignTable( int row ) | ||
184 | { | ||
185 | QTableItem *ti1, | ||
186 | *ti2, | ||
187 | *ti3; | ||
188 | int totalRows = numRows(); | ||
189 | for ( int curr = row; curr < totalRows - 1; curr++ ) { | ||
190 | // this is bad, we must take the item out and then | ||
191 | // set it. In the end, it behaves no worse (time wise) | ||
192 | // then the old way of saving the entries to file, clearing | ||
193 | // the table re-reading in the file and resetting the table | ||
194 | ti1 = item( curr + 1, 0 ); | ||
195 | ti2 = item( curr + 1, 1 ); | ||
196 | ti3 = item( curr + 1, 2 ); | ||
197 | takeItem( ti1 ); | ||
198 | takeItem( ti2 ); | ||
199 | takeItem( ti3 ); | ||
200 | setItem( curr, 0, ti1 ); | ||
201 | setItem( curr, 1, ti2 ); | ||
202 | setItem( curr, 2, ti3 ); | ||
203 | } | ||
204 | setNumRows( totalRows - 1 ); | ||
205 | } | ||
206 | |||
207 | #endif | ||