Diffstat (limited to 'noncore/apps/tableviewer/tableviewer.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/apps/tableviewer/tableviewer.cpp | 455 |
1 files changed, 455 insertions, 0 deletions
diff --git a/noncore/apps/tableviewer/tableviewer.cpp b/noncore/apps/tableviewer/tableviewer.cpp new file mode 100644 index 0000000..0d4a412 --- a/dev/null +++ b/noncore/apps/tableviewer/tableviewer.cpp | |||
@@ -0,0 +1,455 @@ | |||
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 | /* local includes */ | ||
22 | #include "tableviewer.h" | ||
23 | #include "ui/tvbrowseview.h" | ||
24 | #include "ui/tvfilterview.h" | ||
25 | #include "ui/tvlistview.h" | ||
26 | #include "ui/tveditview.h" | ||
27 | #include "ui/tvkeyedit.h" | ||
28 | #include "db/datacache.h" | ||
29 | |||
30 | /* QPE includes */ | ||
31 | #include "fileselector.h" | ||
32 | #include "resource.h" | ||
33 | |||
34 | /* QTE includes */ | ||
35 | #include <qpe/qpemenubar.h> | ||
36 | #include <qpopupmenu.h> | ||
37 | #include <qapplication.h> | ||
38 | #include <qwidgetstack.h> | ||
39 | #include <qlayout.h> | ||
40 | #include <qbuffer.h> | ||
41 | |||
42 | /*! | ||
43 | \class TableViewerWindow | ||
44 | \brief The main window widget of the application | ||
45 | |||
46 | This is the main widget of the table viewer application. | ||
47 | It is the co-ordination point. | ||
48 | */ | ||
49 | |||
50 | /*! | ||
51 | Constructs a new TableViewerWindow | ||
52 | */ | ||
53 | TableViewerWindow::TableViewerWindow(QWidget *parent, const char *name, WFlags f) | ||
54 | : QMainWindow(parent, name, f) | ||
55 | { | ||
56 | setCaption(tr("Table Viewer")); | ||
57 | |||
58 | /* Build data */ | ||
59 | ds = new DBStore(); | ||
60 | doc.setType("text/x-xml-tableviewer"); | ||
61 | doc.setName("table"); | ||
62 | |||
63 | dirty = FALSE; | ||
64 | ts.current_column = 0; | ||
65 | ts.kRep = ds->getKeys(); | ||
66 | |||
67 | /* build menus */ | ||
68 | menu = new QPEMenuBar(this, 0); | ||
69 | |||
70 | QPopupMenu *file_menu = new QPopupMenu; | ||
71 | file_menu->insertItem("New", this, SLOT(newDocument())); | ||
72 | |||
73 | file_menu->insertItem("Open", this, SLOT(selectDocument())); | ||
74 | file_menu->insertSeparator(); | ||
75 | file_menu->insertItem("Properties"); | ||
76 | |||
77 | /* later will want to set this up to clean up first via this, SLOT(quit) */ | ||
78 | menu->insertItem("Document", file_menu); | ||
79 | |||
80 | QPopupMenu *edit_menu = new QPopupMenu; | ||
81 | edit_menu->insertItem("Edit Item", this, SLOT(editItemSlot())); | ||
82 | edit_menu->insertItem("Edit Keys", this, SLOT(editKeysSlot())); | ||
83 | edit_menu->insertItem("Edit filters", this, SLOT(filterViewSlot())); | ||
84 | menu->insertItem("Edit", edit_menu); | ||
85 | |||
86 | QPopupMenu *view_menu = new QPopupMenu; | ||
87 | view_menu->insertItem("Browse View", this, SLOT(browseViewSlot())); | ||
88 | view_menu->insertItem("List View", this, SLOT(listViewSlot())); | ||
89 | menu->insertItem("View", view_menu); | ||
90 | |||
91 | QVBoxLayout *main_layout = new QVBoxLayout; | ||
92 | |||
93 | /* Build tool bar */ | ||
94 | navigation = new QPEToolBar(this, "navigation"); | ||
95 | QToolButton *newItemButton = new QToolButton( | ||
96 | QIconSet(Resource::loadImage("new")), "New Item", QString::null, | ||
97 | this, SLOT(newItemSlot()), navigation, "New Item"); | ||
98 | QToolButton *editItemButton = new QToolButton( | ||
99 | QIconSet(Resource::loadImage("edit")), "Edit Item", QString::null, | ||
100 | this, SLOT(editItemSlot()), navigation, "Edit Item"); | ||
101 | QToolButton *deleteItemButton = new QToolButton( | ||
102 | QIconSet(Resource::loadImage("trash")), "Delete Item", | ||
103 | QString::null, this, | ||
104 | SLOT(deleteItemSlot()), navigation, "Delete Item"); | ||
105 | |||
106 | navigation->addSeparator(); | ||
107 | |||
108 | QToolButton *firstItemButton = new QToolButton( | ||
109 | QIconSet(Resource::loadImage("fastback")), "First Item", | ||
110 | QString::null, this, | ||
111 | SLOT(firstItem()), navigation, "First Item"); | ||
112 | QToolButton *previousItemButton = new QToolButton( | ||
113 | QIconSet(Resource::loadImage("back")), "Previous Item", | ||
114 | QString::null, this, | ||
115 | SLOT(previousItem()), navigation, "Previous Item"); | ||
116 | QToolButton *nextItemButton = new QToolButton( | ||
117 | QIconSet(Resource::loadImage("forward")), "Next Item", | ||
118 | QString::null, this, | ||
119 | SLOT(nextItem()), navigation, "Next Item"); | ||
120 | QToolButton *lastItemButton = new QToolButton( | ||
121 | QIconSet(Resource::loadImage("fastforward")), "Last Item", | ||
122 | QString::null, this, | ||
123 | SLOT(lastItem()), navigation, "Last Item"); | ||
124 | |||
125 | navigation->addSeparator(); | ||
126 | QToolButton *browseButton = new QToolButton( | ||
127 | QIconSet(Resource::loadImage("day")), "View Single Item", | ||
128 | QString::null, this, | ||
129 | SLOT(browseViewSlot()), navigation, "View Single Item"); | ||
130 | QToolButton *listButton = new QToolButton( | ||
131 | QIconSet(Resource::loadImage("month")), "View Multiple Items", | ||
132 | QString::null, this, | ||
133 | SLOT(listViewSlot()), navigation, "View Multiple Items"); | ||
134 | |||
135 | setToolBarsMovable(FALSE); | ||
136 | setToolBarsMovable(FALSE); | ||
137 | setToolBarsMovable(FALSE); | ||
138 | |||
139 | /* Build widgets */ | ||
140 | browseView = new TVBrowseView(&ts, this, 0); | ||
141 | listView = new TVListView(&ts, this, 0); | ||
142 | filterView = new TVFilterView(&ts, this, 0); | ||
143 | fileSelector = new FileSelector("text/csv;text/x-xml-tableviewer", | ||
144 | this, "fileselector"); | ||
145 | fileSelector->setNewVisible(FALSE); | ||
146 | fileSelector->setCloseVisible(FALSE); | ||
147 | |||
148 | cw = new QWidgetStack(this, 0); | ||
149 | cw->addWidget(listView, ListState); | ||
150 | cw->addWidget(browseView, BrowseState); | ||
151 | cw->addWidget(filterView, FilterState); | ||
152 | cw->addWidget(fileSelector, FileState); | ||
153 | |||
154 | current_view = FileState; | ||
155 | cw->raiseWidget(current_view); | ||
156 | fileSelector->reread(); | ||
157 | |||
158 | connect(browseView, SIGNAL(searchOnKey(int, TVVariant)), | ||
159 | this, SLOT(searchOnKey(int, TVVariant))); | ||
160 | connect(browseView, SIGNAL(sortChanged(int)), | ||
161 | this, SLOT(setPrimaryKey(int))); | ||
162 | |||
163 | connect(fileSelector, SIGNAL(closeMe()), this, SLOT(browseViewSlot())); | ||
164 | connect(fileSelector, SIGNAL(fileSelected(const DocLnk &)), | ||
165 | this, SLOT(openDocument(const DocLnk &))); | ||
166 | |||
167 | main_layout->addWidget(menu); | ||
168 | main_layout->addWidget(cw); | ||
169 | |||
170 | setCentralWidget(cw); | ||
171 | |||
172 | } | ||
173 | |||
174 | /*! | ||
175 | Destroys the TableViewerWindow | ||
176 | */ | ||
177 | TableViewerWindow::~TableViewerWindow() | ||
178 | { | ||
179 | if(dirty) | ||
180 | saveDocument(); | ||
181 | } | ||
182 | |||
183 | /*! | ||
184 | Opens a file dialog and loads the file specified by the dialog | ||
185 | */ | ||
186 | void TableViewerWindow::selectDocument() | ||
187 | { | ||
188 | if(dirty) | ||
189 | saveDocument(); | ||
190 | current_view = FileState; | ||
191 | cw->raiseWidget(current_view); | ||
192 | fileSelector->reread(); | ||
193 | } | ||
194 | |||
195 | void TableViewerWindow::saveDocument() | ||
196 | { | ||
197 | if(!dirty) | ||
198 | return; | ||
199 | |||
200 | FileManager fm; | ||
201 | QIODevice *dev = fm.saveFile(doc); | ||
202 | |||
203 | if(!ds->saveSource(dev, doc.type())){ | ||
204 | qWarning("Save unsuccessful"); | ||
205 | return; | ||
206 | } | ||
207 | dev->close(); | ||
208 | dirty = FALSE; | ||
209 | } | ||
210 | |||
211 | void TableViewerWindow::newDocument() | ||
212 | { | ||
213 | DocLnk nf; | ||
214 | nf.setType("text/x-xml-tableviewer"); | ||
215 | nf.setName("table"); | ||
216 | |||
217 | delete ds; | ||
218 | ds = new DBStore(); | ||
219 | |||
220 | ts.current_column = 0; | ||
221 | ts.kRep = ds->getKeys(); | ||
222 | browseView->reset(); | ||
223 | listView->reset(); | ||
224 | filterView->reset(); | ||
225 | |||
226 | doc = nf; | ||
227 | dirty = FALSE; | ||
228 | |||
229 | current_view = BrowseState; | ||
230 | cw->raiseWidget(current_view); | ||
231 | |||
232 | /* now set up for editing the keys */ | ||
233 | ts.kRep->addKey("key", TVVariant::String); | ||
234 | editKeysSlot(); | ||
235 | } | ||
236 | |||
237 | void TableViewerWindow::openDocument(const DocLnk &f) | ||
238 | { | ||
239 | |||
240 | if (!f.isValid()) | ||
241 | return; | ||
242 | |||
243 | FileManager fm; | ||
244 | QIODevice *dev = fm.openFile(f); | ||
245 | doc = f; | ||
246 | |||
247 | if(ds->openSource(dev, doc.type())) { | ||
248 | DataElem *d; | ||
249 | |||
250 | browseView->reset(); | ||
251 | listView->reset(); | ||
252 | filterView->reset(); | ||
253 | |||
254 | current_view = BrowseState; | ||
255 | cw->raiseWidget(current_view); | ||
256 | |||
257 | /* set up new table state and ensure sub widgets have a reference */ | ||
258 | ts.current_column = 0; | ||
259 | ts.kRep = ds->getKeys(); | ||
260 | browseView->rebuildKeys(); | ||
261 | listView->rebuildKeys(); | ||
262 | filterView->rebuildKeys(); | ||
263 | |||
264 | ds->first(); | ||
265 | /* set up the list view */ | ||
266 | listView->clearItems(); | ||
267 | do { | ||
268 | d = ds->getCurrentData(); | ||
269 | if(d) | ||
270 | listView->addItem(d); | ||
271 | } while(ds->next()); | ||
272 | |||
273 | /* Set up browse view, Will be based of structure of listView */ | ||
274 | listView->first(); | ||
275 | ts.current_elem = listView->getCurrentData(); | ||
276 | browseView->rebuildData(); | ||
277 | listView->rebuildData(); | ||
278 | |||
279 | QString scratch = "Table Viewer";/* later take from constant */ | ||
280 | scratch += " - "; | ||
281 | scratch += ds->getName(); | ||
282 | setCaption(tr(scratch)); | ||
283 | |||
284 | dirty = FALSE; | ||
285 | } else { | ||
286 | qWarning(tr("could not load Document")); | ||
287 | } | ||
288 | dev->close(); | ||
289 | } | ||
290 | |||
291 | /*! | ||
292 | Moves to the next item of the current table | ||
293 | */ | ||
294 | void TableViewerWindow::nextItem() | ||
295 | { | ||
296 | listView->next(); | ||
297 | ts.current_elem = listView->getCurrentData(); | ||
298 | browseView->rebuildData(); | ||
299 | } | ||
300 | |||
301 | /*! | ||
302 | Moves to the previous item of the current table | ||
303 | */ | ||
304 | void TableViewerWindow::previousItem() | ||
305 | { | ||
306 | listView->previous(); | ||
307 | ts.current_elem = listView->getCurrentData(); | ||
308 | browseView->rebuildData(); | ||
309 | } | ||
310 | |||
311 | /*! | ||
312 | Raises the List View. This is a mode change for the application. | ||
313 | */ | ||
314 | void TableViewerWindow::listViewSlot() | ||
315 | { | ||
316 | if(current_view == FilterState) | ||
317 | applyFilter(); | ||
318 | current_view = ListState; | ||
319 | cw->raiseWidget(current_view); | ||
320 | } | ||
321 | |||
322 | void TableViewerWindow::applyFilter() | ||
323 | { | ||
324 | DataElem *d; | ||
325 | |||
326 | listView->clearItems(); | ||
327 | ds->first(); | ||
328 | do { | ||
329 | d = ds->getCurrentData(); | ||
330 | if(d) | ||
331 | if(filterView->passesFilter(d)) | ||
332 | listView->addItem(d); | ||
333 | } while(ds->next()); | ||
334 | listView->first(); | ||
335 | listView->rebuildData(); | ||
336 | } | ||
337 | |||
338 | /*! | ||
339 | Raises the Browse View. This is a mode change for the application. | ||
340 | */ | ||
341 | void TableViewerWindow::browseViewSlot() | ||
342 | { | ||
343 | if(current_view == FilterState) | ||
344 | applyFilter(); | ||
345 | |||
346 | ts.current_elem = listView->getCurrentData(); | ||
347 | browseView->rebuildData(); | ||
348 | |||
349 | current_view = BrowseState; | ||
350 | cw->raiseWidget(current_view); | ||
351 | } | ||
352 | |||
353 | /*! | ||
354 | Raises the List View. This is a mode change for the application. | ||
355 | */ | ||
356 | void TableViewerWindow::filterViewSlot() | ||
357 | { | ||
358 | current_view = FilterState; | ||
359 | cw->raiseWidget(current_view); | ||
360 | } | ||
361 | |||
362 | |||
363 | |||
364 | |||
365 | void TableViewerWindow::editItemSlot() | ||
366 | { | ||
367 | if(TVEditView::openEditItemDialog(&ts, ts.current_elem, this)) { | ||
368 | listView->rebuildData(); | ||
369 | browseView->rebuildData(); | ||
370 | dirty = TRUE; | ||
371 | } | ||
372 | } | ||
373 | |||
374 | void TableViewerWindow::newItemSlot() | ||
375 | { | ||
376 | DataElem *d = new DataElem(ds); | ||
377 | if (TVEditView::openEditItemDialog(&ts, d, this)) { | ||
378 | |||
379 | ds->addItem(d); | ||
380 | ts.current_elem = d; | ||
381 | applyFilter(); | ||
382 | listView->rebuildData(); | ||
383 | browseView->rebuildData(); | ||
384 | dirty = TRUE; | ||
385 | } | ||
386 | } | ||
387 | |||
388 | void TableViewerWindow::deleteItemSlot() | ||
389 | { | ||
390 | /* delete the actual item, then do a 'filter' */ | ||
391 | DataElem *to_remove = ts.current_elem; | ||
392 | |||
393 | if(!to_remove) | ||
394 | return; | ||
395 | |||
396 | listView->removeItem(); | ||
397 | ds->removeItem(to_remove); | ||
398 | |||
399 | applyFilter(); | ||
400 | listView->rebuildData(); | ||
401 | browseView->rebuildData(); | ||
402 | dirty = TRUE; | ||
403 | } | ||
404 | |||
405 | void TableViewerWindow::editKeysSlot() | ||
406 | { | ||
407 | DataElem *d; | ||
408 | KeyList *k = TVKeyEdit::openEditKeysDialog(&ts, this); | ||
409 | |||
410 | if(k) { | ||
411 | /* set as new keys */ | ||
412 | ds->setKeys(k); | ||
413 | |||
414 | ts.current_column = 0; | ||
415 | ts.kRep = k; | ||
416 | |||
417 | browseView->reset(); | ||
418 | listView->reset(); | ||
419 | filterView->reset(); | ||
420 | |||
421 | browseView->rebuildKeys(); | ||
422 | listView->rebuildKeys(); | ||
423 | filterView->rebuildKeys(); | ||
424 | |||
425 | ds->first(); | ||
426 | /* set up the list view */ | ||
427 | listView->clearItems(); | ||
428 | do { | ||
429 | d = ds->getCurrentData(); | ||
430 | if(d) | ||
431 | listView->addItem(d); | ||
432 | } while(ds->next()); | ||
433 | |||
434 | /* Set up browse view, Will be based of structure of listView */ | ||
435 | dirty = TRUE; | ||
436 | } | ||
437 | } | ||
438 | |||
439 | /*! | ||
440 | A Slot that allows for widgets above to indicate a search should be | ||
441 | done on a specified key index for a specified value | ||
442 | */ | ||
443 | void TableViewerWindow::searchOnKey(int i, TVVariant v) | ||
444 | { | ||
445 | listView->findItem(i, v); | ||
446 | ts.current_elem = listView->getCurrentData(); | ||
447 | browseView->rebuildData(); | ||
448 | } | ||
449 | |||
450 | void TableViewerWindow::setPrimaryKey(int i) | ||
451 | { | ||
452 | ts.current_column = i; | ||
453 | listView->rebuildData(); | ||
454 | browseView->rebuildData(); | ||
455 | } | ||