Fri, 05 Dec 2008 23:14:02 +0100
Port to the Qt4 API and bump version pending release engineering.
1 //
2 // OSSP asgui - Accounting system graphical user interface
3 // Copyright (c) 2002-2008 The OSSP Project (http://www.ossp.org/)
4 // Copyright (c) 2002-2008 Ralf S. Engelschall <rse@engelschall.com>
5 // Copyright (c) 2002-2008 Michael Schloh von Bennewitz <michael@schloh.com>
6 // Copyright (c) 2002-2008 Cable & Wireless Telecommunications Services GmbH
7 //
8 // This file is part of OSSP asgui, an accounting system graphical user
9 // interface which can be found at http://asgui.europalab.com/.
10 //
11 // Permission to use, copy, modify, and distribute this software for
12 // any purpose with or without fee is hereby granted, provided that
13 // the above copyright notice and this permission notice appear in all
14 // copies.
15 //
16 // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
17 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 // IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
20 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 // USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26 // OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 // SUCH DAMAGE.
28 //
29 // as_slot.cpp: ISO C++ implementation
30 //
32 #define QT3_SUPPORT
34 // system headers
35 #include <memory>
36 #include <cstring>
38 // Qt headers
39 #include <q3filedialog.h>
40 #include <qcombobox.h>
41 #include <qclipboard.h>
42 #include <qmenudata.h>
43 #include <qdatastream.h>
44 #include <qstatusbar.h>
45 #include <qaction.h>
46 #include <q3popupmenu.h>
48 // Qt style headers
49 #include <qcdestyle.h>
50 #include <qcleanlooksstyle.h>
51 #include <qcommonstyle.h>
52 #include <qmotifstyle.h>
53 #include <qplastiquestyle.h>
54 #include <qwindowscestyle.h>
55 #include <qwindowsmobilestyle.h>
56 #include <qwindowsstyle.h>
57 #include <qwindowsvistastyle.h>
58 #include <qwindowsxpstyle.h>
60 //Added by qt3to4:
61 #include <QPixmap>
62 #include <QCloseEvent>
63 #include <Q3TextStream>
64 #include <Q3MemArray>
65 #include <Q3Action>
67 // User interface
68 #include "as_const.h" // Application constants
69 #include "as_except.h" // Exception classes
70 #include "as_tableitem.h" // For our custom table items
71 #include "as_generic.h" // Generic classes
72 #include "as_uuid.h" // UUID classes
73 #include "as_datedit.h" // Derived from QDateEdit
74 #include "as_amount.h" // Derived from QTimeEdit
75 #include "as_crc.h" // Useful Qualistring class
76 #include "as_pref.h" // For Preferences class
77 #include "as_panel.h" // For Prefpanel class
78 #include "as_reportpanel.h" // For Reportpanel class
79 #include "as_helpanel.h" // For Helpanel class
80 #include "as_sfile.h" // For Simplefile class
81 #include "as_table.h" // For TiTable class
83 // RPC headers
84 #ifdef HAVE_ESOAP
85 #include <easysoap/SOAP.h>
86 #endif // HAVE_ESOAP
87 #ifdef HAVE_MICO
88 #include <coss/CosNaming.h>
89 #include "as_stub.h" // CORBA stubs and skeletons
90 #endif // HAVE_MICO
92 // Icon pixel maps
93 #include "as_gfx/cwlogo.xpm" // static const char *s_kpcCwlogo_xpm[]
94 #include "as_gfx/ossplogo.xpm" // static const char *s_kpcOssplogo_xpm[]
95 #include "as_gfx/statok.xpm" // static const char *s_kpcStatokay_xpm[]
96 #include "as_gfx/staterr.xpm" // static const char *s_kpcStaterror_xpm[]
97 #include "as_gfx/statwrn.xpm" // static const char *s_kpcStatwarn_xpm[]
98 #include "as_gfx/statvoid.xpm" // static const char *s_kpcStatvoid_xpm[]
101 //
102 // Cut an entry
103 //
104 void Titraqform::cutEntry(void)
105 {
106 this->copyEntry(); // Reuse slot
107 this->delEntry(); // Reuse slot
108 }
110 //
111 // Copy an entry
112 //
113 void Titraqform::copyEntry(void)
114 {
115 QString Selection; // Will hold the selected text
116 QClipboard *pClip; // Will reference the global clipboard
118 // Initialize data and clipboard handle
119 Selection = getRowdata(); // Use accessor
120 pClip = QApplication::clipboard();
122 Q_ASSERT(!Selection.isNull());
123 pClip->setText(Selection, QClipboard::Selection); // Doesn't work on Windows
124 pClip->setText(Selection, QClipboard::Clipboard); // Works on both equally
125 }
127 //
128 // Paste an entry
129 //
130 void Titraqform::pasteEntry(void)
131 {
132 int nRows = 0; // Paste so many rows as are stored
133 QString Selection; // Will receive the clipboard text
134 QClipboard *pClip = NULL; // Will reference the global clipboard
136 pClip = QApplication::clipboard(); // Prime the clips
137 Selection = pClip->text(QClipboard::Clipboard); // Windows and Unix
138 nRows = Selection.count(QChar('\n')); // How many rows
139 if (Selection.isNull() && nRows > 0) { // Ignore empty clipboards
140 this->addEntry(nRows); // Reuse slot
141 setRowdata(Selection); // Use accessor
143 // Update line numbers for this new row and all subsequent rows
144 for (int nIter = m_pMaintable->currentRow(); nIter < m_pMaintable->numRows(); nIter++)
145 m_pMaintable->setText(nIter, TITRAQ_IDXLINE, QString::number(nIter).rightJustify(4, QChar('0')));
147 // Do basic data validation to warn against missing fields
148 for (int nIter = 0; nIter < nRows; nIter++)
149 this->validateRow(m_pMaintable->currentRow() + nIter, 0);
151 m_pStatbar->message(QString::number(nRows) + trUtf8(" rows pasted"), 4000);
152 updEdit(m_pMaintable->currentRow()); // Reflect in the update controls
153 }
154 else // Well, I guess the user tried to paste an empty clipboard
155 m_pStatbar->message(trUtf8("The clipboard is empty"), 4000);
156 }
158 //
159 // Append a blank row entry
160 //
161 void Titraqform::addEntry(int nRows)
162 {
163 Q3TableSelection Select; // Highlighted text
164 int nTotal = 0; // Total row select
165 int nCurrent = 0; // Current row
166 std::auto_ptr<AS::Uuid> pGuid(new AS::Uuid); // For GUID production
168 // Decide how many rows to add
169 Select = m_pMaintable->selection(0);
170 if (nRows > 0)
171 nTotal = nRows;
172 else
173 nTotal = Select.bottomRow() - Select.topRow() + 1;
175 // Optimize viewing by repainting cells only once after processing
176 m_pMaintable->setUpdatesEnabled(false);
178 // Add a row after selection and focus to the new row
179 if (Select.bottomRow() + 1 != m_pMaintable->numRows()) { // Add upwards
180 m_pMaintable->insertRows(Select.topRow(), nTotal);
181 m_pMaintable->setDirty(); // Set data to dirty state
182 m_pMaintable->setCurrentCell(Select.topRow(), m_pMaintable->currentColumn());
184 // According to Trolltech, insertRows() "clears the selection(s)".
185 // They are pretty wrong about that, so unfortunately we'll have to
186 // take care of the dirty work ourselves with a clearSelection().
187 m_pMaintable->clearSelection(false);
188 m_pMaintable->selectRow(m_pMaintable->currentRow());
190 // Update relevant data fields for all new rows
191 for (int nIter = 0; nIter < nTotal; nIter++) {
192 m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXSTATUS, QString(QChar('W')));
193 m_pMaintable->setPixmap(Select.topRow() + nIter, TITRAQ_IDXSTATUS, QPixmap(s_kpcStatwarn_xpm));
194 m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXUSER, m_pPrefs->getString(TITRAQ_PREFUSER, TITRAQ_DEFUSER));
195 pGuid->genId();
196 m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXGUID, QString::fromStdString(pGuid->getString()));
197 m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXCRC, "0"); // 0 = invalid entry
198 m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXREV, "0"); // Entry not revised
199 m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXDATE, QDate::currentDate().toString(Qt::ISODate));
200 m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXSTART, "00:00");
201 m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXFINISH, "00:00");
202 m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXAMOUNT, "00:00");
203 // m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXTASK, "/");
204 // m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXREMARK, "Remark");
205 m_pMaintable->setText(Select.topRow() + nIter, TITRAQ_IDXCRC, "1"); // 0 = invalid entry
206 this->calcCrc(Select.topRow() + nIter, -1);
207 }
208 }
209 else { // Special case on last row add downwards
210 m_pMaintable->insertRows(Select.bottomRow() + 1, nTotal);
211 m_pMaintable->setDirty(); // Set data to dirty state
212 m_pMaintable->setCurrentCell(Select.bottomRow() + 1, m_pMaintable->currentColumn());
214 // According to Trolltech, insertRows() "clears the selection(s)".
215 // They are pretty wrong about that, so unfortunately we'll have to
216 // take care of the dirty work ourselves with a clearSelection().
217 m_pMaintable->clearSelection(false);
218 m_pMaintable->selectRow(m_pMaintable->currentRow());
220 // Update relevant data fields for all new rows
221 for (int nIter = 1; nIter <= nTotal; nIter++) {
222 m_pMaintable->setText(Select.bottomRow() + nIter, TITRAQ_IDXSTATUS, QString(QChar('W')));
223 m_pMaintable->setPixmap(Select.bottomRow() + nIter, TITRAQ_IDXSTATUS, QPixmap(s_kpcStatwarn_xpm));
224 m_pMaintable->setText(Select.bottomRow() + nIter, TITRAQ_IDXUSER, m_pPrefs->getString(TITRAQ_PREFUSER, TITRAQ_DEFUSER));
225 pGuid->genId();
226 m_pMaintable->setText(Select.bottomRow() + nIter, TITRAQ_IDXGUID, QString::fromStdString(pGuid->getString()));
227 m_pMaintable->setText(Select.bottomRow() + nIter, TITRAQ_IDXCRC, "0");
228 m_pMaintable->setText(Select.bottomRow() + nIter, TITRAQ_IDXREV, "0");
229 m_pMaintable->setText(Select.bottomRow() + nIter, TITRAQ_IDXDATE, QDate::currentDate().toString(Qt::ISODate));
230 m_pMaintable->setText(Select.bottomRow() + nIter, TITRAQ_IDXSTART, "00:00");
231 m_pMaintable->setText(Select.bottomRow() + nIter, TITRAQ_IDXFINISH, "00:00");
232 m_pMaintable->setText(Select.bottomRow() + nIter, TITRAQ_IDXAMOUNT, "00:00");
233 // m_pMaintable->setText(Select.bottomRow() + nIter, TITRAQ_IDXTASK, "/");
234 // m_pMaintable->setText(Select.bottomRow() + nIter, TITRAQ_IDXREMARK, "Remark");
235 this->calcCrc(Select.bottomRow() + nIter, -1);
236 }
237 }
239 // Update line numbers for this new row and all subsequent rows
240 for (int nIter = m_pMaintable->currentRow(); nIter < m_pMaintable->numRows(); nIter++)
241 m_pMaintable->setText(nIter, TITRAQ_IDXLINE, QString::number(nIter).rightJustify(4, QChar('0')));
243 updEdit(m_pMaintable->currentRow()); // Reflect in the update controls
244 m_pStatusedit->setPixmap(QPixmap(s_kpcStatwarn_xpm)); // Show pixmap
246 m_pMaintable->setUpdatesEnabled(true); // Turn updates back on
247 m_pMaintable->repaintContents(true); // Do a general repaint of table
248 m_pMaintable->ensureCellVisible(m_pMaintable->currentRow() + nTotal - 1, m_pMaintable->currentColumn());
249 m_pMaintable->ensureCellVisible(m_pMaintable->currentRow(), m_pMaintable->currentColumn());
251 // In case we added the first and only row entry,
252 // do post state adjustments like icon undimming
253 if (m_pMaintable->numRows() == 1) {
254 m_pDelrowact->setEnabled(true);
255 m_pRefreshact->setEnabled(true);
256 m_pCutact->setEnabled(true);
257 m_pCopyact->setEnabled(true);
259 // Brighten all the edit controls also
260 m_pLineedit->setEnabled(true);
261 m_pUseredit->setEnabled(true);
262 m_pGuidedit->setEnabled(true);
263 m_pCrcedit->setEnabled(true);
264 m_pRevedit->setEnabled(true);
265 m_pDateedit->setEnabled(true);
266 m_pStarttime->setEnabled(true);
267 m_pEndtime->setEnabled(true);
268 m_pAmount->setEnabled(true);
269 m_pTasks->setEnabled(true);
270 m_pRemark->setEnabled(true);
272 // And optionally the RPC actions, too
273 #if defined HAVE_MICO || defined HAVE_ESOAP
274 m_pSyncact->setEnabled(m_pPrefs->getBool(TITRAQ_PREFCORBON, TITRAQ_DEFCORBON)
275 | m_pPrefs->getBool(TITRAQ_PREFSOAPON, TITRAQ_DEFSOAPON));
276 #endif // HAVE_MICO || defined HAVE_ESOAP
277 }
278 }
280 //
281 // Delete a row entry
282 //
283 void Titraqform::delEntry(int nRows)
284 {
285 Q3TableSelection Select = m_pMaintable->selection(0); // Highlighted text
286 int nTotal = Select.bottomRow() - Select.topRow() + 1; // Total row select
287 Q3MemArray<int> Rowselect(nTotal); // Row array
289 // Calculate rows to delete from selection highlight
290 for (int nIter = 0; nIter < nTotal; ++nIter)
291 Rowselect[nIter] = Select.topRow() + nIter;
293 // Remove the row at selection and focus to the next row
294 if (m_pMaintable->currentRow() + 1 != m_pMaintable->numRows()) {
295 m_pMaintable->setCurrentCell(Select.bottomRow() + 1, m_pMaintable->currentColumn());
296 m_pMaintable->removeRows(Rowselect);
297 m_pMaintable->setDirty(); // Set data to dirty state
298 }
299 else { // Special case to handle removing of only row or last row
300 m_pMaintable->removeRows(Rowselect);
301 m_pMaintable->setDirty(); // Set data to dirty state
302 }
304 // Update line numbers for this new row and all subsequent rows
305 for (int nIter = m_pMaintable->currentRow(); nIter < m_pMaintable->numRows(); nIter++)
306 m_pMaintable->setText(nIter, TITRAQ_IDXLINE, QString::number(nIter));
308 // In case we removed the last remaining row,
309 // do post state adjustments like icon dimming
310 if (m_pMaintable->numRows() <= 0) {
311 m_pDelrowact->setEnabled(false);
312 m_pRefreshact->setEnabled(false);
313 m_pCutact->setEnabled(false);
314 m_pCopyact->setEnabled(false);
316 // Dim all the edit controls also
317 m_pStatusedit->setPixmap(s_kpcStatvoid_xpm);
318 m_pLineedit->setEnabled(false);
319 m_pUseredit->setEnabled(false);
320 m_pGuidedit->setEnabled(false);
321 m_pCrcedit->setEnabled(false);
322 m_pRevedit->setEnabled(false);
323 m_pDateedit->setEnabled(false);
324 m_pStarttime->setEnabled(false);
325 m_pEndtime->setEnabled(false);
326 m_pAmount->setEnabled(false);
327 m_pTasks->setEnabled(false);
328 m_pRemark->setEnabled(false);
330 // And optionally dim the RPC actions
331 #if defined HAVE_MICO || defined HAVE_ESOAP
332 m_pSyncact->setEnabled(false);
333 #endif // HAVE_MICO || defined HAVE_ESOAP
334 }
335 }
337 //
338 // Refresh the display of all data items
339 //
340 void Titraqform::refreshDisplay(void)
341 {
342 int nIter = 0; // Matrix iterator
343 int nRows = m_pMaintable->numRows(); // Total number of rows
345 // Sweep through matrix validating linewise
346 // data and updating line numbers for all rows
347 while (nIter < nRows) {
348 this->validateRow(nIter, 0);
349 m_pMaintable->setText(nIter, TITRAQ_IDXLINE, QString::number(nIter).rightJustify(4, QChar('0')));
350 nIter++;
351 }
353 m_pMaintable->repaintContents(false); // Do a general repaint of table
354 m_pStatbar->message(trUtf8("Display was refreshed"), 4000); // Announce result
355 }
357 //
358 // Make and display a new document window
359 //
360 void Titraqform::newDoc(void)
361 {
362 int nResult = 0; // Holds return value from save first messagebox
364 // Check modification state of current data
365 if (m_pMaintable->isDirty()) {
366 nResult = QMessageBox::information(this, QString(TITRAQ_APPTITLE)
367 + ' ' + asgui_version.v_short, trUtf8(TITRAQ_SAVEFIRST),
368 trUtf8("&Save"), trUtf8("&Discard"), trUtf8("Cancel"), 0, 2);
370 switch (nResult) {
371 case 0: // First button selected, so save first
372 this->saveFile(); // Save changes first
373 break;
374 case 1: // Second button selected, so don't save
375 break;
376 case 2: // Third button selected, so return sofort
377 default:
378 m_pStatbar->message(trUtf8("New aborted"), 4000);
379 return;
380 break;
381 }
382 }
384 if (!m_pMaintable->isDirty() || nResult == 1) { // Check modification state
385 // Fall through to implicit new doc code
386 this->setCaption(trUtf8("No file name"));
387 m_pStatbar->message(trUtf8("New document"), 4000);
388 this->enableIface(true); // Enable the interface
389 m_pMaintable->setNumRows(0); // Remove all data in table
390 this->setFilename(""); // Signal a closed doc state
391 this->addEntry(1); // Default new op adds a row
392 m_pMaintable->setDirty(false); // Start out clean
393 }
394 }
396 //
397 // Open and display an existing document
398 //
399 void Titraqform::openDoc(void)
400 {
401 int nResult = 0; // Holds return value from save first messagebox
403 //
404 // This block will guide the user to saving the contents of the timesheet
405 // before losing them in an open operation. The question and dialog box will
406 // not be raised if no open timesheet exists or if it was just serialized.
407 //
408 if (m_pMaintable->isDirty()) { // Check modification state
409 nResult = QMessageBox::information(this, QString(TITRAQ_APPTITLE)
410 + ' ' + asgui_version.v_short, trUtf8(TITRAQ_SAVEFIRST),
411 trUtf8("&Save"), trUtf8("&Discard"), trUtf8("Cancel"), 0, 2);
413 switch (nResult) {
414 case 0: // Save first
415 this->saveFile(); // Save changes first
416 break;
417 case 1: // Don't save first but do load
418 break;
419 case 2: // Don't do a load timesheet
420 default:
421 m_pStatbar->message(trUtf8("Loading aborted"), 4000);
422 return;
423 break;
424 }
425 }
427 //
428 // This block ensures that conditions of first block logic were met if
429 // applicable. If so, the user gives a file name to open or cancels the
430 // operation. The corresponding file will be opened, and if this is
431 // unsuccessful then the post state is exactly the same as the pre state.
432 //
433 if (!m_pMaintable->isDirty() || nResult == 1) { // Check modification state
434 // Make sure we correctly get the name of the default file to open
435 QString Openas = m_pPrefs->getString(TITRAQ_PREFASDIR, TITRAQ_DEFASDIR);
436 if (Openas.startsWith(TITRAQ_HOMEDIRTOK))
437 Openas = QDir::homeDirPath() + Openas.remove(0, QString(TITRAQ_HOMEDIRTOK).length() - 1);
439 // This dialog asks which file the user wants to open
440 QString Filestring = Q3FileDialog::getOpenFileName(Openas,
441 trUtf8("Accounting Data (*.as);;Text files (*.txt);;All Files (*)"),
442 this, trUtf8("ChooserDialog"), trUtf8("Choose a file to open"), NULL, false);
444 // We might have a filename to work on, so do something with it
445 if (!Filestring.isEmpty()) {
446 QFile Filetemp(Filestring); // File to load
447 try {
448 if (Filetemp.exists() && validateData(Filetemp)) { // Be extra sure
449 setFilename(Filestring); // Set the new file name
450 m_pMaintable->setNumRows(0); // Clear out old data
451 m_pMaintable->setDirty(false); // Reset dirty flag
452 loadData(Filetemp); // Pass to helper method
453 this->setCaption(Filestring); // Caption in the titlebar
454 m_pStatbar->message(trUtf8("Loaded document ") + Filestring, 4000);
455 this->enableIface(true); // Turn on the lights
456 this->setOpen(true); // Indicate doc is open
457 }
458 }
459 catch (Genexcept& Genex) { // Crap, we failed
460 m_pStatbar->message(trUtf8("Loading failed"), 4000);
461 Genex.reportErr();
462 return;
463 }
464 }
465 else // An empty filename returning from the file dialog means cancel
466 m_pStatbar->message(trUtf8("Loading aborted"), 4000);
467 }
468 }
470 //
471 // Serialize current state to the current file
472 //
473 void Titraqform::saveFile(void)
474 {
475 QString Fname;
476 Simplefile Filevents;
478 try {
479 Fname = *this->getFilename();
481 // First time saves are really just saveName in disguise
482 if (Fname.isEmpty()) {
483 try {
484 this->saveName(); // Try to 'save as'
485 return; // and short circuit
486 }
487 catch (Genexcept& Genex) {
488 // Genex.reportErr(); // Report the error
489 return; // and short circuit
490 }
491 }
493 Filevents.setName(Fname); // Construct a file to write
494 if (m_pPrefs->getBool(TITRAQ_PREFBAKON, TITRAQ_DEFBAKON))
495 Filevents.makeBackup(); // Back up to filename.bak
496 this->saveData(Filevents); // Pass to helper method
497 }
498 catch (Genexcept& Genex) {
499 Genex.reportErr();
500 }
501 // Reset and give output to main window
502 this->setCaption(Fname);
503 m_pStatbar->message(trUtf8("File %1 saved").arg(Fname), 4000);
504 m_pMaintable->setDirty(false); // Set the clean state to allow close
505 }
507 //
508 // Serialize current state to a selected file
509 //
510 void Titraqform::saveAs(void)
511 {
512 int nResult = 0; // For checking user's answer
514 // Make sure we correctly get the name of the default file to open
515 QString Openas = m_pPrefs->getString(TITRAQ_PREFASDIR, TITRAQ_DEFASDIR);
516 if (Openas.startsWith(TITRAQ_HOMEDIRTOK))
517 Openas = QDir::homeDirPath() + Openas.remove(0, QString(TITRAQ_HOMEDIRTOK).length() - 1);
519 // And then get the name of the selected file to save to
520 QString Filestring = Q3FileDialog::getSaveFileName(Openas, trUtf8("Accounting Data (*.as);;Text files (*.txt);;All Files (*)"), this, trUtf8("ChooserDialog"), trUtf8("Choose a file to save"), NULL, false);
521 if (!Filestring.isEmpty()) {
522 if (QFile::exists(Filestring)) {
523 nResult = QMessageBox::warning(this, QString(TITRAQ_APPTITLE)
524 + ' ' + asgui_version.v_short, trUtf8(TITRAQ_OVERWRITE),
525 trUtf8("&Yes"), trUtf8("&No"), NULL, 1, 1);
526 switch (nResult) {
527 case 0: // Overwrite contents
528 this->setFilename(Filestring);
529 this->saveFile();
530 break;
531 case 1: // Don't overwrite
532 default:
533 break;
534 }
535 }
536 else {
537 // Conditionally use a unique extension like '.as' if user prefers
538 if (m_pPrefs->getBool(TITRAQ_PREFEXTENDON, TITRAQ_DEFEXTENDON)) {
539 QString Extension = TITRAQ_FEXTENSION; // Logic to handle
540 if (!Filestring.endsWith(Extension)) // AS file extension
541 Filestring += Extension; // insertion
542 }
543 this->setFilename(Filestring); // Set filename of object first
544 this->saveFile(); // Finish by calling the save action
545 }
546 }
547 else
548 // User did not select a valid file and push okay button
549 m_pStatbar->message(trUtf8("Saving aborted"), 4000);
550 }
552 //
553 // Implicitly serialize current state to a selected file
554 // The main difference with saveAs is that this uses exceptions
555 //
556 void Titraqform::saveName(void)
557 {
558 int nResult = 0; // For checking user's answer
560 // Make sure we correctly get the name of the default file to open
561 QString Openas = m_pPrefs->getString(TITRAQ_PREFASDIR, TITRAQ_DEFASDIR);
562 if (Openas.startsWith(TITRAQ_HOMEDIRTOK))
563 Openas = QDir::homeDirPath() + Openas.remove(0, QString(TITRAQ_HOMEDIRTOK).length() - 1);
565 nResult = 1; // We loop on this dialog only if an indecisive user
566 while (nResult > 0) { // is hesitant to overwrite a file over and over again
567 QString Filestring = Q3FileDialog::getSaveFileName(Openas, trUtf8("Accounting Data (*.as);;Text files (*.txt);;All Files (*)"), this, trUtf8("ChooserDialog"), trUtf8("Choose a file to save"), NULL, false);
568 if (!Filestring.isEmpty()) {
569 if (QFile::exists(Filestring)) {
570 nResult = QMessageBox::warning(this, QString(TITRAQ_APPTITLE)
571 + ' ' + asgui_version.v_short, trUtf8(TITRAQ_OVERWRITE),
572 trUtf8("&Yes"), trUtf8("&No"), NULL, 1, 1);
573 switch (nResult) {
574 case 0: // Overwrite contents
575 this->setFilename(Filestring);
576 this->saveFile();
577 break;
578 case 1: // Don't overwrite
579 default:
580 break;
581 }
582 }
583 else {
585 // Conditionally use a unique extension like '.as' if user prefers
586 if (m_pPrefs->getBool(TITRAQ_PREFEXTENDON, TITRAQ_DEFEXTENDON)) {
587 QString Extension = TITRAQ_FEXTENSION; // Logic to handle
588 if (!Filestring.endsWith(Extension)) // AS file extension
589 Filestring += Extension; // insertion
590 }
591 this->setFilename(Filestring); // Set filename of object first
592 nResult = 0; // Reset our loop control
593 this->saveFile(); // Finish by calling the save action
594 }
595 }
596 else {
597 // User did not select a valid file and push okay button
598 m_pStatbar->message(trUtf8("Saving aborted"), 4000);
599 throw Genexcept(TITRAQ_SAVECANCELLED);
600 }
601 }
602 }
604 //
605 // Close current document, and then quit the application
606 //
607 void Titraqform::quitApp(void)
608 {
609 int nResult = 0;
611 if (m_pMaintable->isDirty()) {
612 nResult = QMessageBox::information(this, QString(TITRAQ_APPTITLE)
613 + ' ' + asgui_version.v_short, trUtf8(TITRAQ_SAVEFIRST),
614 trUtf8("&Save"), trUtf8("&Discard"), trUtf8("Cancel"), 0, 2);
616 switch (nResult) { // Maybe save before closing
617 case 0: // Save first
618 this->saveFile(); // Save changes first
619 break;
620 case 1: // Don't save first
621 m_pMaintable->setDirty(false);
622 break;
623 case 2: // Do nothing
624 default:
625 return; // Go away without closing
626 break;
627 }
628 }
630 // We should be clean now, but double check just in case
631 if (!m_pMaintable->isDirty())
632 qApp->quit();
633 }
635 //
636 // Close current document, displaying in main window
637 //
638 void Titraqform::closeEvent(QCloseEvent *pClosit)
639 {
640 int nResult = 0;
642 if (!this->isOpen()) // Short circuit if user
643 qApp->quit(); // selects close twice
645 // Check modification state of current data
646 if (m_pMaintable->isDirty()) {
647 nResult = QMessageBox::information(this, QString(TITRAQ_APPTITLE)
648 + ' ' + asgui_version.v_short, trUtf8(TITRAQ_SAVEFIRST),
649 trUtf8("&Save"), trUtf8("&Discard"), trUtf8("Cancel"), 0, 2);
651 switch (nResult) { // Maybe save before closing
652 case 0: // Save first
653 this->saveFile(); // Save changes first
654 break;
655 case 1: // Don't save first
656 m_pMaintable->setDirty(false);
657 break;
658 case 2: // Do nothing
659 default:
660 pClosit->ignore();
661 return; // Go away without closing
662 break;
663 }
664 }
666 if (!m_pMaintable->isDirty()) { // Check again
667 // Fall through to implicit close code
668 this->setCaption(QString(TITRAQ_APPTITLE) + ' ' + asgui_version.v_short);
669 try { // There might be problems, so wrap these last ops with error handling
670 QString Lightsout; // It's late, go to bed
671 if (this->isOpen())
672 Lightsout = trUtf8("Closed document ") + *this->getFilename();
673 this->setOpen(false); // Set doc state to closed
674 this->enableIface(false); // Turn off the lights
675 m_pStatbar->message(Lightsout, 4000);
676 }
677 catch (Genexcept& Genex) {
678 Genex.reportErr();
679 }
680 }
681 pClosit->ignore(); // Finish off by not closing
682 }
684 //
685 // Edit menu select all entries
686 //
687 void Titraqform::selAll(void)
688 {
689 Prototype Unimp;
690 Unimp.doMbox();
691 }
693 //
694 // Edit a table entry in place, without the usual edit controls
695 //
696 void Titraqform::inplaceEdit(int nRow, int nCol, int nButton, const QPoint &Mousepos)
697 {
698 // Table read only attribute must be reset here, so that editing can take
699 // place. Otherwise calls to editCell are ignored (for obvious reasons).
700 m_pMaintable->setReadOnly(false);
702 // After editCell() is called, beginEdit() and endEdit() execute. The read
703 // only attribute is reset in endEdit() to return everything to normal.
704 m_pMaintable->editCell(nRow, nCol);
706 m_pMaintable->setEdition(nCol);
707 }
709 //
710 // Update the edit controls widget sizes
711 //
712 void Titraqform::updSizes(int nSection, int nOldsize, int nNewsize)
713 {
714 switch (nSection) {
715 case TITRAQ_IDXALLCTRLS:
716 if (m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXSTATUS) > 0)
717 m_pStatusedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXSTATUS) - TITRAQ_SPACING);
718 if (m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXLINE) > 0)
719 m_pLineedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXLINE) - TITRAQ_SPACING);
720 if (m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXUSER) > 0)
721 m_pUseredit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXUSER) - TITRAQ_SPACING);
722 if (m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXGUID) > 0)
723 m_pGuidedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXGUID) - TITRAQ_SPACING);
724 if (m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXCRC) > 0)
725 m_pCrcedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXCRC) - TITRAQ_SPACING);
726 if (m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXREV) > 0)
727 m_pRevedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXREV) - TITRAQ_SPACING);
728 if (m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXDATE) > 0)
729 m_pDateedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXDATE) - TITRAQ_SPACING);
730 if (m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXSTART) > 0)
731 m_pStarttime->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXSTART) - TITRAQ_SPACING);
732 if (m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXFINISH) > 0)
733 m_pEndtime->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXFINISH) - TITRAQ_SPACING);
734 if (m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXAMOUNT) > 0)
735 m_pAmount->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXAMOUNT) - TITRAQ_SPACING);
736 if (m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXTASK) > 0)
737 m_pTasks->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXTASK) - TITRAQ_SPACING);
738 // if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXRCOL)))
739 // m_pRemark->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXREMARK) - TITRAQ_SPACING);
740 break;
741 case TITRAQ_IDXSTATUS:
742 m_pStatusedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXSTATUS) - TITRAQ_SPACING);
743 break;
744 case TITRAQ_IDXLINE:
745 m_pLineedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXLINE) - TITRAQ_SPACING);
746 break;
747 case TITRAQ_IDXUSER:
748 m_pUseredit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXUSER) - TITRAQ_SPACING);
749 break;
750 case TITRAQ_IDXGUID:
751 m_pGuidedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXGUID) - TITRAQ_SPACING);
752 break;
753 case TITRAQ_IDXCRC:
754 m_pCrcedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXCRC) - TITRAQ_SPACING);
755 break;
756 case TITRAQ_IDXREV:
757 m_pRevedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXREV) - TITRAQ_SPACING);
758 break;
759 case TITRAQ_IDXDATE:
760 m_pDateedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXDATE) - TITRAQ_SPACING);
761 break;
762 case TITRAQ_IDXSTART:
763 m_pStarttime->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXSTART) - TITRAQ_SPACING);
764 break;
765 case TITRAQ_IDXFINISH:
766 m_pEndtime->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXFINISH) - TITRAQ_SPACING);
767 break;
768 case TITRAQ_IDXAMOUNT:
769 m_pAmount->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXAMOUNT) - TITRAQ_SPACING);
770 break;
771 case TITRAQ_IDXTASK:
772 m_pTasks->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXTASK) - TITRAQ_SPACING);
773 break;
774 case TITRAQ_IDXREMARK:
775 // m_pRemark->setFixedWidth(nNewsize);
776 break;
777 default:
778 throw Genexcept("Unrecognized main window column header.");
779 break;
780 }
782 // As a last and redundant step, adjust size of first visible control
783 switch(this->getFirstcol()) {
784 case TITRAQ_IDXSTATUS:
785 m_pStatusedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXSTATUS) - TITRAQ_SPACING + TITRAQ_SPACING / 2);
786 break;
787 case TITRAQ_IDXLINE:
788 m_pLineedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXLINE) - TITRAQ_SPACING + TITRAQ_SPACING / 2);
789 break;
790 case TITRAQ_IDXUSER:
791 m_pUseredit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXUSER) - TITRAQ_SPACING + TITRAQ_SPACING / 2);
792 break;
793 case TITRAQ_IDXGUID:
794 m_pGuidedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXGUID) - TITRAQ_SPACING + TITRAQ_SPACING / 2);
795 break;
796 case TITRAQ_IDXCRC:
797 m_pCrcedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXCRC) - TITRAQ_SPACING + TITRAQ_SPACING / 2);
798 break;
799 case TITRAQ_IDXREV:
800 m_pRevedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXREV) - TITRAQ_SPACING + TITRAQ_SPACING / 2);
801 break;
802 case TITRAQ_IDXDATE:
803 m_pDateedit->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXDATE) - TITRAQ_SPACING + TITRAQ_SPACING / 2);
804 break;
805 case TITRAQ_IDXSTART:
806 m_pStarttime->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXSTART) - TITRAQ_SPACING + TITRAQ_SPACING / 2);
807 break;
808 case TITRAQ_IDXFINISH:
809 m_pEndtime->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXFINISH) - TITRAQ_SPACING + TITRAQ_SPACING / 2);
810 break;
811 case TITRAQ_IDXAMOUNT:
812 m_pAmount->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXAMOUNT) - TITRAQ_SPACING + TITRAQ_SPACING / 2);
813 break;
814 case TITRAQ_IDXTASK:
815 m_pTasks->setFixedWidth(m_pMaintable->horizontalHeader()->sectionSize(TITRAQ_IDXTASK) - TITRAQ_SPACING + TITRAQ_SPACING / 2);
816 break;
817 default: // Probably no columns are visible?
818 break;
819 }
820 }
822 //
823 // What to do if a data cell is modified
824 //
825 void Titraqform::dataChanged(int nRow, int nCol)
826 {
827 if (nCol != TITRAQ_IDXSTATUS && nCol != TITRAQ_IDXLINE)
828 m_pMaintable->setDirty(); // Mark this timesheet dirty, changes pending save
829 }
831 //
832 // Convenience member calculates CRC for current row
833 //
834 void Titraqform::calcCrc(void)
835 {
836 this->calcCrc(-1, -1);
837 }
839 //
840 // Calculates CRC for the specified row, fires when data is changed
841 //
842 void Titraqform::calcCrc(int nRow, int nCol)
843 {
844 if (nCol != TITRAQ_IDXSTATUS && nCol != TITRAQ_IDXLINE \
845 && m_pMaintable->numRows() > 0) {
846 U32 Testcrc, Valcrc;
847 QString Crcstr;
848 std::auto_ptr<Qualistring>pWholerow(new Qualistring);
849 int nRealrow = -1;
851 // Build the data that will be used in testing CRC calculation
852 nRealrow = (nRow >= 0) ? nRow : m_pMaintable->currentRow();
853 *pWholerow = m_pMaintable->text(nRealrow, TITRAQ_IDXUSER);
854 for (int nIter = TITRAQ_IDXUSER + 1; nIter < TITRAQ_IDXTAIL; nIter++)
855 if (nIter != TITRAQ_IDXCRC) // Don't checksum the checksum!
856 *pWholerow += m_pMaintable->text(nRealrow, nIter);
858 // Update the checksum and revision only if necessary
859 Testcrc = pWholerow->getCrc();
861 // FIXME: This thing is not very unportable, because toUInt != U32
862 if (Testcrc != m_pMaintable->text(nRealrow, TITRAQ_IDXCRC).toUInt()) {
864 // // Bump the revision number of our entry to control conflicts
865 // nNewrev = m_pMaintable->text(nRealrow, TITRAQ_IDXREV).toInt() + 1;
866 // m_pMaintable->setText(nRealrow, TITRAQ_IDXREV, QString::number(nNewrev));
868 // Build the data that will be used in setting CRC calculation
869 *pWholerow = m_pMaintable->text(nRealrow, TITRAQ_IDXUSER);
870 for (int nIter = TITRAQ_IDXUSER + 1; nIter < TITRAQ_IDXTAIL; nIter++)
871 if (nIter != TITRAQ_IDXCRC) // Don't checksum the checksum!
872 *pWholerow += m_pMaintable->text(nRealrow, nIter);
874 Valcrc = pWholerow->getCrc(); // Finally set the checksum to its new value
875 Crcstr = QString::number(Valcrc, 16).rightJustify(8, '0');
876 m_pMaintable->setText(nRealrow, TITRAQ_IDXCRC, "0x" + Crcstr);
877 m_pCrcedit->setText("0x" + Crcstr);
878 }
879 }
880 }
882 //
883 // Gets a hit on every table click
884 //
885 void Titraqform::onClick(int nRow, int nCol, int nButton, const QPoint &Mousepos)
886 {
887 // Give the clueless user some hints when clicking an empty timesheet
888 if (m_pMaintable->numRows() <= 0)
889 m_pStatbar->message(trUtf8("Empty timesheet, add entries first please"), 2000);
890 }
892 //
893 // Update the edit controls contents
894 //
895 void Titraqform::updEdit(int nRow, int nCol)
896 {
897 // Why is the app sending negative row signal? I don't know yet,
898 // so add in this nasty hack to fend off the debug spew on stderr
899 if (m_pMaintable->numRows() > 0 && nRow >= 0) {
900 // Field strings to check for validity and process
901 QString Textline(m_pMaintable->text(nRow, TITRAQ_IDXLINE));
902 QString Textuser(m_pMaintable->text(nRow, TITRAQ_IDXUSER));
903 QString Textguid(m_pMaintable->text(nRow, TITRAQ_IDXGUID));
904 QString Textcrc(m_pMaintable->text(nRow, TITRAQ_IDXCRC));
905 QString Textrev(m_pMaintable->text(nRow, TITRAQ_IDXREV));
906 QString Textdate(m_pMaintable->text(nRow, TITRAQ_IDXDATE));
907 QString Textstart(m_pMaintable->text(nRow, TITRAQ_IDXSTART));
908 QString Textfinish(m_pMaintable->text(nRow, TITRAQ_IDXFINISH));
909 QString Textamount(m_pMaintable->text(nRow, TITRAQ_IDXAMOUNT));
910 QString Texttask(m_pMaintable->text(nRow, TITRAQ_IDXTASK));
911 QString Textremark(m_pMaintable->text(nRow, TITRAQ_IDXREMARK));
913 // Reset the edition state member
914 m_pMaintable->setEdition();
916 // Set text of member edit controls
917 if (m_pMaintable->text(nRow, TITRAQ_IDXSTATUS).isEmpty()) // If row is empty
918 m_pStatusedit->setPixmap(s_kpcStatvoid_xpm); // add a placeholder
919 else
920 m_pStatusedit->setPixmap(m_pMaintable->pixmap(nRow, TITRAQ_IDXSTATUS));
921 m_pLineedit->setText(Textline);
922 m_pUseredit->setText(Textuser);
923 m_pGuidedit->setText(Textguid);
924 m_pCrcedit->setText(Textcrc);
925 m_pRevedit->setText(Textrev);
927 // QRegExp Shorten("/(\\w+)$"); // For stripping prefix off the current task
928 // Texttask.remove(0, Shorten.search(Texttask) + 1); // Strip leading slash
930 m_pRemark->setText(Textremark);
931 m_pTasks->setCurrentText(Texttask);
933 // Date field not suitable for empty string text
934 if (Textdate == ".")
935 m_pDateedit->setDate(QDate::currentDate());
936 else if (Textdate.isEmpty())
937 m_pDateedit->setDate(QDate::fromString("0000-00-00", Qt::ISODate));
938 else
939 m_pDateedit->setDate(QDate::fromString(Textdate, Qt::ISODate));
941 // Start time not suitable for empty string text
942 if (Textstart == ".")
943 m_pStarttime->setTime(QTime::currentTime());
944 else if (Textstart.isEmpty())
945 m_pStarttime->setTime(QTime::QTime(0, 0));
946 else
947 m_pStarttime->setTime(QTime::fromString(Textstart, Qt::ISODate));
949 // Finish time not suitable for empty string text
950 if (Textfinish == ".")
951 m_pEndtime->setTime(QTime::currentTime());
952 else if (Textfinish.isEmpty())
953 m_pEndtime->setTime(QTime::QTime(0, 0));
954 else
955 m_pEndtime->setTime(QTime::fromString(Textfinish, Qt::ISODate));
957 // Amount time not suitable for empty string text
958 if (Textamount == ".") {
959 int nDifference = m_pStarttime->time().secsTo(m_pEndtime->time());
960 m_pAmount->setTime(QTime(0, 0).addSecs(nDifference));
961 }
962 else if (Textamount.isEmpty())
963 m_pAmount->setTime(QTime::QTime(0, 0));
964 else
965 m_pAmount->setTime(QTime::fromString(Textamount, Qt::ISODate));
966 }
967 }
969 //
970 // Validate current row of the matrix
971 //
972 void Titraqform::validateRow(void)
973 {
974 this->validateRow(-1, -1);
975 }
977 //
978 // Validate specified row of the matrix
979 //
980 void Titraqform::validateRow(int nRow, int nCol)
981 {
982 int nRealrow = -1;
984 if (!this->isOpen()) { // If no data is loaded then short circuit
985 m_pStatbar->message(trUtf8("Timesheet contains no data"), 4000);
986 return;
987 }
989 nRealrow = (nRow >= 0) ? nRow : m_pMaintable->currentRow();
990 QString Statis = m_pMaintable->text(nRealrow, TITRAQ_IDXSTATUS); // Get text
992 // Review whole data validity, and set pixmap accordingly
993 if (m_pMaintable->text(nRealrow, TITRAQ_IDXUSER).isEmpty() ||
994 m_pMaintable->text(nRealrow, TITRAQ_IDXGUID).isEmpty() ||
995 m_pMaintable->text(nRealrow, TITRAQ_IDXCRC).isEmpty() ||
996 m_pMaintable->text(nRealrow, TITRAQ_IDXREV).isEmpty() ||
997 m_pMaintable->text(nRealrow, TITRAQ_IDXDATE).isEmpty() ||
998 m_pMaintable->text(nRealrow, TITRAQ_IDXSTART).isEmpty() ||
999 m_pMaintable->text(nRealrow, TITRAQ_IDXFINISH).isEmpty() ||
1000 m_pMaintable->text(nRealrow, TITRAQ_IDXAMOUNT).isEmpty() ||
1001 m_pMaintable->text(nRealrow, TITRAQ_IDXTASK).isEmpty())
1002 { // No K&R style to show where actual code begins
1003 if (Statis.startsWith(QString("W"))) { // Conditionally set pixmap to avoid overhead
1004 // FIXME: Next line commented out, and I see that this algorythm needs help
1005 // m_pStatusedit->setPixmap(m_pMaintable->pixmap(nRealrow, TITRAQ_IDXSTATUS));
1006 }
1007 else if (!Statis.startsWith(QString("E"))) { // Conditionally set pixmap to avoid overhead
1008 m_pMaintable->setText(nRealrow, TITRAQ_IDXSTATUS, Statis.replace(TITRAQ_IDXSTATERROR, sizeof(char), 'E'));
1009 m_pMaintable->setPixmap(nRealrow, TITRAQ_IDXSTATUS, QPixmap(s_kpcStaterror_xpm));
1010 m_pStatusedit->setPixmap(m_pMaintable->pixmap(nRealrow, TITRAQ_IDXSTATUS));
1011 }
1012 }
1013 else {
1014 if (!Statis.startsWith(QString("O"))) { // Conditionally set pixmap to avoid overhead
1015 m_pMaintable->setText(nRealrow, TITRAQ_IDXSTATUS, Statis.replace(TITRAQ_IDXSTATERROR, sizeof(char), 'O'));
1016 m_pMaintable->setPixmap(nRealrow, TITRAQ_IDXSTATUS, QPixmap(s_kpcStatokay_xpm));
1017 m_pStatusedit->setPixmap(m_pMaintable->pixmap(nRealrow, TITRAQ_IDXSTATUS));
1018 }
1019 }
1021 // Test for blank user field, and set to default if so
1022 if (m_pMaintable->text(nRealrow, TITRAQ_IDXUSER).isEmpty())
1023 m_pMaintable->setText(nRealrow, TITRAQ_IDXUSER, m_pPrefs->getString(TITRAQ_PREFUSER, TITRAQ_DEFUSER));
1025 // Test for blank date field, and set to default if so
1026 if (m_pMaintable->text(nRealrow, TITRAQ_IDXDATE) == ".")
1027 m_pMaintable->setText(nRealrow, TITRAQ_IDXDATE, QDate::currentDate().toString(Qt::ISODate));
1029 // Test for blank start field, and set to default if so
1030 if (m_pMaintable->text(nRealrow, TITRAQ_IDXSTART) == ".")
1031 m_pMaintable->setText(nRealrow, TITRAQ_IDXSTART, QTime::currentTime().toString("hh:mm"));
1033 // Test for blank finish field, and set to default if so
1034 if (m_pMaintable->text(nRealrow, TITRAQ_IDXFINISH) == ".")
1035 m_pMaintable->setText(nRealrow, TITRAQ_IDXFINISH, QTime::currentTime().toString("hh:mm"));
1037 // Test for blank amount field, and set to default if so
1038 if (m_pMaintable->text(nRealrow, TITRAQ_IDXAMOUNT) == ".") {
1039 QTime Begin = QTime::fromString(m_pMaintable->text(nRealrow, TITRAQ_IDXSTART), Qt::ISODate);
1040 QTime End = QTime::fromString(m_pMaintable->text(nRealrow, TITRAQ_IDXFINISH), Qt::ISODate);
1041 QString Diff = QTime(0, 0).addSecs(Begin.secsTo(End)).toString("hh:mm");
1042 m_pMaintable->setText(nRealrow, TITRAQ_IDXAMOUNT, Diff);
1043 }
1044 }
1046 //
1047 // Update the current line number column item
1048 //
1049 void Titraqform::updateLine(const QString &Instring)
1050 {
1051 m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXLINE, Instring);
1052 }
1054 //
1055 // Update the current user column item
1056 //
1057 void Titraqform::updateUser(const QString &Instring)
1058 {
1059 m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXUSER, Instring);
1060 }
1062 //
1063 // Update the current GUID column item
1064 //
1065 void Titraqform::updateGuid(const QString &Instring)
1066 {
1067 m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXGUID, Instring);
1068 }
1070 //
1071 // Update the current CRC column item
1072 //
1073 void Titraqform::updateCrc(const QString &Instring)
1074 {
1075 m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXCRC, Instring);
1076 }
1078 //
1079 // Update the current rev column item
1080 //
1081 void Titraqform::updateRev(const QString &Instring)
1082 {
1083 m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXREV, Instring);
1084 }
1086 //
1087 // Update the current date column item
1088 //
1089 void Titraqform::updateDate(const QDate &Dateup)
1090 {
1091 m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXDATE, Dateup.toString(Qt::ISODate));
1092 }
1094 //
1095 // Update the current start column item
1096 //
1097 void Titraqform::updateStart(const QTime &Startup)
1098 {
1099 m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXSTART, Startup.toString("hh:mm"));
1100 }
1102 //
1103 // Update the current finish column item
1104 //
1105 void Titraqform::updateFinish(const QTime &Finishup)
1106 {
1107 m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXFINISH, Finishup.toString("hh:mm"));
1108 }
1110 //
1111 // Update the current amount column item
1112 //
1113 void Titraqform::updateAmount(const QTime &Amountup)
1114 {
1115 m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXAMOUNT, Amountup.toString("hh:mm"));
1116 }
1118 //
1119 // Update the current task column item
1120 //
1121 void Titraqform::updateTask(const QString &Taskup)
1122 {
1123 // // FIXME: Broken
1124 // RtTableItem *pTask = NULL;
1125 // pTask = static_cast<RtTableItem *>(m_pMaintable->item(m_pMaintable->currentRow(), TITRAQ_IDXTASK));
1126 // pTask->setText(Taskup);
1128 // Don't try to use the Taskup string, because it ignores autocompletion
1129 m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXTASK, m_pTasks->currentText());
1130 }
1132 //
1133 // Update the current remark column item
1134 //
1135 void Titraqform::updateRemark(const QString &Remarkup)
1136 {
1137 m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXREMARK, Remarkup);
1138 }
1140 //
1141 // Confirm any recent editions on a whole row
1142 //
1143 void Titraqform::confirmEdit(void)
1144 {
1145 RtTableItem *pTask = NULL; // Task item is a derived class
1147 // Conversions from edit control data formats to native tabular format
1148 m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXDATE, m_pDateedit->date().toString(Qt::ISODate));
1149 m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXSTART, m_pStarttime->time().toString(Qt::ISODate));
1150 m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXFINISH, m_pEndtime->time().toString(Qt::ISODate));
1151 m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXAMOUNT, m_pAmount->time().toString(Qt::ISODate));
1153 // Specially handle task fields
1154 pTask = static_cast<RtTableItem *>(m_pMaintable->item(m_pMaintable->currentRow(), TITRAQ_IDXTASK));
1155 pTask->setText(m_pTasks->currentText());
1157 m_pMaintable->setText(m_pMaintable->currentRow(), TITRAQ_IDXREMARK, m_pRemark->text());
1158 }
1160 //
1161 // Edit menu configure preferences
1162 //
1163 void Titraqform::configPrefs(void)
1164 {
1165 QString Templine; // Used for preferences resetting
1166 Prefpanel *pUserpanel = NULL; // The user preferences panel itself
1168 // Create a new preferences panel window
1169 pUserpanel = new Prefpanel(this, "Userprefpanel");
1170 connect(pUserpanel, SIGNAL(applied(void)), SLOT(applyPrefs(void)));
1172 // Set default values to appear in initialized panel widgets
1173 pUserpanel->setAccounts(m_pPrefs->getString(TITRAQ_PREFACCOUNTS, TITRAQ_DEFACCOUNTS));
1174 pUserpanel->setEvents(m_pPrefs->getString(TITRAQ_PREFASDIR, TITRAQ_DEFASDIR));
1175 pUserpanel->setUser(m_pPrefs->getString(TITRAQ_PREFUSER, TITRAQ_DEFUSER));
1176 pUserpanel->setHome(m_pPrefs->getString(TITRAQ_PREFHOME, TITRAQ_DEFHOME));
1177 pUserpanel->setCorbahost(m_pPrefs->getString(TITRAQ_PREFCORBHOST, TITRAQ_DEFCORBHOST));
1178 pUserpanel->setSoaphost(m_pPrefs->getString(TITRAQ_PREFSOAPHOST, TITRAQ_DEFSOAPHOST));
1179 #ifdef HAVE_MICO
1180 pUserpanel->setCorbaon(m_pPrefs->getBool(TITRAQ_PREFCORBON, TITRAQ_DEFCORBON));
1181 #else
1182 pUserpanel->setCorbaon(false);
1183 pUserpanel->lockCorba();
1184 #endif
1185 #ifdef HAVE_ESOAP
1186 pUserpanel->setSoapon(m_pPrefs->getBool(TITRAQ_PREFSOAPON, TITRAQ_DEFSOAPON));
1187 #else
1188 pUserpanel->setSoapon(false);
1189 pUserpanel->lockSoap();
1190 #endif
1191 pUserpanel->setBackon(m_pPrefs->getBool(TITRAQ_PREFBAKON, TITRAQ_DEFBAKON));
1192 pUserpanel->setExtendon(m_pPrefs->getBool(TITRAQ_PREFEXTENDON, TITRAQ_DEFEXTENDON));
1193 pUserpanel->setDetailon(m_pPrefs->getBool(TITRAQ_PREFDETAILON, TITRAQ_DEFDETAILON));
1194 pUserpanel->setSignaton(m_pPrefs->getBool(TITRAQ_PREFSIGNATON, TITRAQ_DEFSIGNATON));
1196 // Set default style which can be more complicated due to mapping...
1197 switch (m_pPrefs->getNumber(TITRAQ_PREFSTYLE, TITRAQ_STYLECDE)) {
1198 case TITRAQ_STYLECDE:
1199 pUserpanel->setStyle(TITRAQ_STRCDE);
1200 break;
1201 case TITRAQ_STYLESGI:
1202 pUserpanel->setStyle(TITRAQ_STRSGI);
1203 break;
1204 case TITRAQ_STYLEMOTIF:
1205 pUserpanel->setStyle(TITRAQ_STRMOTIF);
1206 break;
1207 case TITRAQ_STYLEMPLUS:
1208 pUserpanel->setStyle(TITRAQ_STRMPLUS);
1209 break;
1210 case TITRAQ_STYLEPLAT:
1211 pUserpanel->setStyle(TITRAQ_STRPLAT);
1212 break;
1213 case TITRAQ_STYLEMSOFT:
1214 pUserpanel->setStyle(TITRAQ_STRMSOFT);
1215 break;
1216 default:
1217 pUserpanel->setStyle(TITRAQ_STRCDE); // My personal favourite ;-)
1218 break;
1219 }
1221 // Colour preferences
1222 int nRed, nGreen, nBlue;
1223 QColorGroup Origcolour, Altcolour;
1224 const QColor Origlight = QColor(TITRAQ_DEFLIGHTRED, TITRAQ_DEFLIGHTGREEN, TITRAQ_DEFLIGHTBLUE);
1225 const QColor Origdark = QColor(TITRAQ_DEFDARKRED, TITRAQ_DEFDARKGREEN, TITRAQ_DEFDARKBLUE);
1226 const QColor Altlight = QColor(TITRAQ_DEFLTALTRED, TITRAQ_DEFLTALTGREEN, TITRAQ_DEFLTALTBLUE);
1227 const QColor Altdark = QColor(TITRAQ_DEFDKALTRED, TITRAQ_DEFDKALTGREEN, TITRAQ_DEFDKALTBLUE);
1229 // Set colours to revert to if user screws up and wants out
1230 Origcolour.setColor(QColorGroup::Foreground, Origlight);
1231 Origcolour.setColor(QColorGroup::Background, Origdark);
1232 pUserpanel->setOrigcolour(&Origcolour);
1233 Altcolour.setColor(QColorGroup::Foreground, Altlight);
1234 Altcolour.setColor(QColorGroup::Background, Altdark);
1235 pUserpanel->setAltcolour(&Altcolour);
1237 // Set colour preferences saved from last session
1238 nRed = m_pPrefs->getNumber(TITRAQ_PREFLIGHTRED, TITRAQ_DEFLIGHTRED);
1239 nGreen = m_pPrefs->getNumber(TITRAQ_PREFLIGHTGREEN, TITRAQ_DEFLIGHTGREEN);
1240 nBlue = m_pPrefs->getNumber(TITRAQ_PREFLIGHTBLUE, TITRAQ_DEFLIGHTBLUE);
1241 const QColor Lightshade = QColor(nRed, nGreen, nBlue);
1242 pUserpanel->setLight(&Lightshade);
1243 nRed = m_pPrefs->getNumber(TITRAQ_PREFDARKRED, TITRAQ_DEFDARKRED);
1244 nGreen = m_pPrefs->getNumber(TITRAQ_PREFDARKGREEN, TITRAQ_DEFDARKGREEN);
1245 nBlue = m_pPrefs->getNumber(TITRAQ_PREFDARKBLUE, TITRAQ_DEFDARKBLUE);
1246 const QColor Darkshade = QColor(nRed, nGreen, nBlue);
1247 pUserpanel->setDark(&Darkshade);
1249 // Modal panel handler
1250 if (pUserpanel->exec() == QDialog::Accepted)
1251 this->applyPrefs(pUserpanel);
1253 // Dispose Panel object
1254 delete pUserpanel;
1255 }
1257 //
1258 // View menu normal
1259 //
1260 void Titraqform::normalView(void)
1261 {
1262 // All view types except normal are disabled until implemention, so
1263 // this body can remain empty, causing nothing to happen on selection.
1264 }
1266 //
1267 // View menu editing
1268 //
1269 void Titraqform::editingView(void)
1270 {
1271 // All view types except normal are disabled until implemention, so
1272 // this body can remain empty, causing nothing to happen on selection.
1273 }
1275 //
1276 // View menu timing
1277 //
1278 void Titraqform::timingView(void)
1279 {
1280 // All view types except normal are disabled until implemention, so
1281 // this body can remain empty, causing nothing to happen on selection.
1282 }
1284 //
1285 // View menu show file toolbar
1286 //
1287 void Titraqform::showFilebar(void)
1288 {
1289 if (m_pFiletools->isVisible()) {
1290 m_pFiletools->hide();
1291 m_pTbarspopup->setItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXFILEBAR), false);
1292 }
1293 else {
1294 m_pFiletools->show();
1295 m_pTbarspopup->setItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXFILEBAR), true);
1296 }
1297 }
1299 //
1300 // View menu show edit toolbar
1301 //
1302 void Titraqform::showEditbar(void)
1303 {
1304 if (m_pEdittools->isVisible()) {
1305 m_pEdittools->hide();
1306 m_pTbarspopup->setItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXEDITBAR), false);
1307 }
1308 else {
1309 m_pEdittools->show();
1310 m_pTbarspopup->setItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXEDITBAR), true);
1311 }
1312 }
1314 //
1315 // View menu show view toolbar
1316 //
1317 void Titraqform::showViewbar(void)
1318 {
1319 if (m_pViewtools->isVisible()) {
1320 m_pViewtools->hide();
1321 m_pTbarspopup->setItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXVIEWBAR), false);
1322 }
1323 else {
1324 m_pViewtools->show();
1325 m_pTbarspopup->setItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXVIEWBAR), true);
1326 }
1327 }
1329 //
1330 // View menu show prefs toolbar
1331 //
1332 void Titraqform::showPrefsbar(void)
1333 {
1334 if (m_pPrefstools->isVisible()) {
1335 m_pPrefstools->hide();
1336 m_pTbarspopup->setItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXPREFBAR), false);
1337 }
1338 else {
1339 m_pPrefstools->show();
1340 m_pTbarspopup->setItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXPREFBAR), true);
1341 }
1342 }
1344 //
1345 // View menu show whats this toolbar
1346 //
1347 void Titraqform::showWhatsbar(void)
1348 {
1349 if (m_pWhatstools->isVisible()) {
1350 m_pWhatstools->hide();
1351 m_pTbarspopup->setItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXWHATBAR), false);
1352 }
1353 else {
1354 m_pWhatstools->show();
1355 m_pTbarspopup->setItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXWHATBAR), true);
1356 }
1357 }
1359 //
1360 // View menu show status column
1361 //
1362 void Titraqform::showStatcol(void)
1363 {
1364 // Test if column is currently shown, conditionally show or hide it
1365 if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXSTATCOL))) {
1366 m_pMaintable->hideColumn(TITRAQ_IDXSTATUS);
1367 m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXSTATCOL), false);
1368 m_pStatusedit->hide();
1369 }
1370 else {
1371 m_pMaintable->showColumn(TITRAQ_IDXSTATUS);
1372 m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXSTATCOL), true);
1373 m_pStatusedit->show();
1374 }
1376 // Make sure switch take place right away and sizes are handled
1377 //m_pColspopup->updateItem(m_pColspopup->idAt(TITRAQ_IDXSTATCOL));
1378 this->updSizes(TITRAQ_IDXALLCTRLS, 0, 0); // Update size of this and next
1379 }
1381 //
1382 // View menu show line numbers column
1383 //
1384 void Titraqform::showLinecol(void)
1385 {
1386 // Test if column is currently shown, conditionally show or hide it
1387 if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXLCOL))) {
1388 m_pMaintable->hideColumn(TITRAQ_IDXLINE);
1389 m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXLCOL), false);
1390 m_pLineedit->hide();
1391 }
1392 else {
1393 m_pMaintable->showColumn(TITRAQ_IDXLINE);
1394 m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXLCOL), true);
1395 m_pLineedit->show();
1396 }
1398 // Make sure switch take place right away and sizes are handled
1399 //m_pColspopup->updateItem(m_pColspopup->idAt(TITRAQ_IDXLCOL));
1400 this->updSizes(TITRAQ_IDXALLCTRLS, 0, 0); // Update size of this and next
1401 }
1403 //
1404 // View menu show users column
1405 //
1406 void Titraqform::showUsercol(void)
1407 {
1408 // Test if column is currently shown, conditionally show or hide it
1409 if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXUCOL))) {
1410 m_pMaintable->hideColumn(TITRAQ_IDXUSER);
1411 m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXUCOL), false);
1412 m_pUseredit->hide();
1413 }
1414 else {
1415 m_pMaintable->showColumn(TITRAQ_IDXUSER);
1416 m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXUCOL), true);
1417 m_pUseredit->show();
1418 }
1420 // Make sure switch take place right away and sizes are handled
1421 this->updSizes(TITRAQ_IDXALLCTRLS, 0, 0); // Update size of this and next
1422 //m_pColspopup->updateItem(m_pColspopup->idAt(TITRAQ_IDXUCOL));
1423 }
1425 //
1426 // View menu show GUIDs column
1427 //
1428 void Titraqform::showGuidcol(void)
1429 {
1430 // Test if column is currently shown, conditionally show or hide it
1431 if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXGCOL))) {
1432 m_pMaintable->hideColumn(TITRAQ_IDXGUID);
1433 m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXGCOL), false);
1434 m_pGuidedit->hide();
1435 }
1436 else {
1437 m_pMaintable->showColumn(TITRAQ_IDXGUID);
1438 m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXGCOL), true);
1439 m_pGuidedit->show();
1440 }
1442 // Make sure switch take place right away and sizes are handled
1443 //m_pColspopup->updateItem(m_pColspopup->idAt(TITRAQ_IDXGCOL));
1444 this->updSizes(TITRAQ_IDXALLCTRLS, 0, 0); // Update size of this and next
1445 }
1447 //
1448 // View menu show CRC column
1449 //
1450 void Titraqform::showCrccol(void)
1451 {
1452 // Test if column is currently shown, conditionally show or hide it
1453 if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXCCOL))) {
1454 m_pMaintable->hideColumn(TITRAQ_IDXCRC);
1455 m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXCCOL), false);
1456 m_pCrcedit->hide();
1457 }
1458 else {
1459 m_pMaintable->showColumn(TITRAQ_IDXCRC);
1460 m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXCCOL), true);
1461 m_pCrcedit->show();
1462 }
1464 // Make sure switch take place right away and sizes are handled
1465 //m_pColspopup->updateItem(m_pColspopup->idAt(TITRAQ_IDXCCOL));
1466 this->updSizes(TITRAQ_IDXALLCTRLS, 0, 0); // Update size of this and next
1467 }
1469 //
1470 // View menu show Rev column
1471 //
1472 void Titraqform::showRevcol(void)
1473 {
1474 // Test if column is currently shown, conditionally show or hide it
1475 if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXREVCOL))) {
1476 m_pMaintable->hideColumn(TITRAQ_IDXREV);
1477 m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXREVCOL), false);
1478 m_pRevedit->hide();
1479 }
1480 else {
1481 m_pMaintable->showColumn(TITRAQ_IDXREV);
1482 m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXREVCOL), true);
1483 m_pRevedit->show();
1484 }
1486 // Make sure switch take place right away and sizes are handled
1487 //m_pColspopup->updateItem(m_pColspopup->idAt(TITRAQ_IDXREVCOL));
1488 this->updSizes(TITRAQ_IDXALLCTRLS, 0, 0); // Update size of this and next
1489 }
1491 //
1492 // View menu show dates column
1493 //
1494 void Titraqform::showDatecol(void)
1495 {
1496 // Test if column is currently shown, conditionally show or hide it
1497 if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXDCOL))) {
1498 m_pMaintable->hideColumn(TITRAQ_IDXDATE);
1499 m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXDCOL), false);
1500 m_pDateedit->hide();
1501 }
1502 else {
1503 m_pMaintable->showColumn(TITRAQ_IDXDATE);
1504 m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXDCOL), true);
1505 m_pDateedit->show();
1506 }
1508 // Make sure switch take place right away and sizes are handled
1509 //m_pColspopup->updateItem(m_pColspopup->idAt(TITRAQ_IDXDCOL));
1510 this->updSizes(TITRAQ_IDXALLCTRLS, 0, 0); // Update size of this and next
1511 }
1513 //
1514 // View menu show start time column
1515 //
1516 void Titraqform::showStartcol(void)
1517 {
1518 // Test if column is currently shown, conditionally show or hide it
1519 if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXSTARTCOL))) {
1520 m_pMaintable->hideColumn(TITRAQ_IDXSTART);
1521 m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXSTARTCOL), false);
1522 m_pStarttime->hide();
1523 }
1524 else {
1525 m_pMaintable->showColumn(TITRAQ_IDXSTART);
1526 m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXSTARTCOL), true);
1527 m_pStarttime->show();
1528 }
1530 // Make sure switch take place right away and sizes are handled
1531 //m_pColspopup->updateItem(m_pColspopup->idAt(TITRAQ_IDXSTARTCOL));
1532 this->updSizes(TITRAQ_IDXALLCTRLS, 0, 0); // Update size of this and next
1533 }
1535 //
1536 // View menu show finish time column
1537 //
1538 void Titraqform::showFinishcol(void)
1539 {
1540 // Test if column is currently shown, conditionally show or hide it
1541 if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXFCOL))) {
1542 m_pMaintable->hideColumn(TITRAQ_IDXFINISH);
1543 m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXFCOL), false);
1544 m_pEndtime->hide();
1545 }
1546 else {
1547 m_pMaintable->showColumn(TITRAQ_IDXFINISH);
1548 m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXFCOL), true);
1549 m_pEndtime->show();
1550 }
1552 // Make sure switch take place right away and sizes are handled
1553 //m_pColspopup->updateItem(m_pColspopup->idAt(TITRAQ_IDXFCOL));
1554 this->updSizes(TITRAQ_IDXALLCTRLS, 0, 0); // Update size of this and next
1555 }
1557 //
1558 // View menu show Amounts column
1559 //
1560 void Titraqform::showAmountcol(void)
1561 {
1562 // Test if column is currently shown, conditionally show or hide it
1563 if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXACOL))) {
1564 m_pMaintable->hideColumn(TITRAQ_IDXAMOUNT);
1565 m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXACOL), false);
1566 m_pAmount->hide();
1567 }
1568 else {
1569 m_pMaintable->showColumn(TITRAQ_IDXAMOUNT);
1570 m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXACOL), true);
1571 m_pAmount->show();
1572 }
1574 // Make sure switch take place right away and sizes are handled
1575 //m_pColspopup->updateItem(m_pColspopup->idAt(TITRAQ_IDXACOL));
1576 this->updSizes(TITRAQ_IDXALLCTRLS, 0, 0); // Update size of this and next
1577 }
1579 //
1580 // View menu show tasks column
1581 //
1582 void Titraqform::showTaskcol(void)
1583 {
1584 // Test if column is currently shown, conditionally show or hide it
1585 if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXTCOL))) {
1586 m_pMaintable->hideColumn(TITRAQ_IDXTASK);
1587 m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXTCOL), false);
1588 m_pTasks->hide();
1589 }
1590 else {
1591 m_pMaintable->showColumn(TITRAQ_IDXTASK);
1592 m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXTCOL), true);
1593 m_pTasks->show();
1594 }
1596 // Make sure switch take place right away and sizes are handled
1597 //m_pColspopup->updateItem(m_pColspopup->idAt(TITRAQ_IDXTCOL));
1598 this->updSizes(TITRAQ_IDXALLCTRLS, 0, 0); // Update size of this and next
1599 }
1601 //
1602 // View menu show Remarks column
1603 //
1604 void Titraqform::showRemarkcol(void)
1605 {
1606 // Test if column is currently shown, conditionally show or hide it
1607 if (m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXREMCOL))) {
1608 m_pMaintable->hideColumn(TITRAQ_IDXREMARK);
1609 m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXREMCOL), false);
1610 m_pRemark->hide();
1611 }
1612 else {
1613 m_pMaintable->showColumn(TITRAQ_IDXREMARK);
1614 m_pColspopup->setItemChecked(m_pColspopup->idAt(TITRAQ_IDXREMCOL), true);
1615 m_pRemark->show();
1616 }
1618 // Make sure switch take place right away and sizes are handled
1619 //m_pColspopup->updateItem(m_pColspopup->idAt(TITRAQ_IDXREMCOL));
1620 this->updSizes(TITRAQ_IDXALLCTRLS, 0, 0); // Update size of this and next
1621 }
1623 //
1624 // Generate a local formatted report
1625 //
1626 void Titraqform::genReport(void)
1627 {
1628 try { // Create and execute a new local report window
1629 std::auto_ptr<AS::Reportpanel> pReport(new AS::Reportpanel
1630 (m_pMaintable, m_pPrefs, this, "Locreportpanel"));
1631 pReport->exec();
1632 delete pReport.release(); // Technically unnecessary, smart pointer
1633 }
1634 catch (Genexcept& Genex) {
1635 Genex.reportErr();
1636 return;
1637 }
1638 }
1640 //
1641 // Syncronize data with server using IIOP
1642 //
1643 void Titraqform::syncIiop(void)
1644 {
1645 #ifdef HAVE_MICO
1646 // Short circuit if user has disabled CORBA transmission in prefs
1647 if (!m_pPrefs->getBool(TITRAQ_PREFCORBON, TITRAQ_DEFCORBON))
1648 return;
1650 char **ppcInargv = NULL; // Parameters to the ORB
1651 CORBA::ORB_var Orb; // The ORB iself
1653 CORBA::Object_var Nameobj; // Name service reference
1654 CosNaming::NamingContext_var Namectx; // COSS ns context
1655 CosNaming::Name Cosname; // Our requested obj name
1657 CORBA::Object_var Objcaster; // Generic CORBA object
1658 Asdatabase_var Asdbase; // Casted object to ASDB
1659 Astuple Singlerow; // A single row of AS data
1661 QString *pOrbargv = new QString(TITRAQ_ORBINIT);
1662 int nCount = pOrbargv->contains(' ');
1663 int nNamesize = 0;
1665 // Build a false incoming argv with which we initialize the ORB
1666 ppcInargv = new char *[nCount + 3]; // 3 = arg0 + last section + COSS host
1667 *ppcInargv = new char[strlen(*qApp->argv() + 2)]; // For cmd name
1668 strcpy(ppcInargv[0], *qApp->argv()); // Copy cmd name
1669 for (int nIter = 0; nIter <= nCount; nIter++) {
1670 QString Section = pOrbargv->section(' ', nIter, nIter);
1671 ppcInargv[nIter + 1] = new char[strlen(Section.ascii() + 2)];
1672 strcpy(ppcInargv[nIter + 1], Section.ascii());
1673 }
1675 // Build the single string COSS naming host name with associated port number
1676 *pOrbargv = TITRAQ_COSSPART1
1677 + m_pPrefs->getString(TITRAQ_PREFCORBHOST, TITRAQ_DEFCORBHOST)
1678 + TITRAQ_COSSPART2;
1679 nNamesize = strlen(pOrbargv->ascii());
1680 ppcInargv[nCount + 2] = new char[nNamesize];
1681 strcpy(ppcInargv[nCount + 2], pOrbargv->ascii());
1683 try {
1684 // Initialization of the ORB and COSS naming service
1685 nCount = nCount + 3; // Raise the count to include app, last sec, COSS
1686 Orb = CORBA::ORB_init(nCount, ppcInargv, "mico-local-orb");
1687 Nameobj = Orb->resolve_initial_references("NameService");
1688 Namectx = CosNaming::NamingContext::_narrow(Nameobj);
1689 if (CORBA::is_nil(Namectx)) { // Verify sanity
1690 m_pStatbar->message(trUtf8("Could not find the COSS naming service"));
1691 qWarning("Could not find the COSS naming service\n");
1692 }
1694 // Clean up our dynamically allocated array
1695 for (int nIter = 0; nIter < nCount; nIter++)
1696 delete ppcInargv[nIter];
1697 delete ppcInargv; // Free the array itself
1698 delete pOrbargv; // Free the intermediate string
1700 // Prepare the COSS name request
1701 Cosname.length(1);
1702 Cosname[0].id = CORBA::string_dup("Asdatabase");
1703 Cosname[0].kind = CORBA::string_dup("");
1705 try { // Resolve to a CORBA object
1706 Objcaster = Namectx->resolve(Cosname);
1707 }
1708 catch (CosNaming::NamingContext::NotFound &Cossex) {
1709 m_pStatbar->message(trUtf8("NotFound exception thrown"));
1710 qWarning("NotFound exception thrown\n");
1711 return;
1712 }
1713 catch (CosNaming::NamingContext::CannotProceed &Cossex) {
1714 m_pStatbar->message(trUtf8("CannotProceed exception thrown"));
1715 qWarning("CannotProceed exception thrown\n");
1716 return;
1717 }
1718 catch (CosNaming::NamingContext::InvalidName &Cossex) {
1719 m_pStatbar->message(trUtf8("InvalidName exception thrown"));
1720 qWarning("InvalidName exception thrown\n");
1721 return;
1722 }
1724 // Cast the generic CORBA object to a AS database type
1725 Asdbase = Asdatabase::_narrow(Objcaster);
1726 if (CORBA::is_nil(Asdbase)) { // Verify sanity
1727 m_pStatbar->message(trUtf8("Could not find the AS database"));
1728 qWarning("Could not find the AS database\n");
1729 return;
1730 }
1732 // Open an account object on the remote server
1733 Account_var Account = Asdbase->Open("/tmp/events.as");
1734 if (CORBA::is_nil(Account)) { // Verify sanity
1735 m_pStatbar->message(trUtf8("Could not create an account object on the server"));
1736 qWarning("Could not create an account object on the server\n");
1737 return;
1738 }
1740 // Fill account log object(s) to marshall and transmit
1741 int nRow = m_pMaintable->currentRow();
1742 Q3TableSelection Select = m_pMaintable->selection(0); // Capture selected rows
1743 int nTotal = Select.bottomRow() - Select.topRow() + 1; // Total rows selected
1745 // Remember, CORBA::stri_dup creates smart pointers
1746 for (int nIter = 0; nIter < nTotal; nIter++) {
1747 Singlerow.szUser = CORBA::string_dup(m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXUSER));
1748 Singlerow.szGuid = CORBA::string_dup(m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXGUID));
1749 Singlerow.szCrc = CORBA::string_dup(m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXCRC).remove("0x"));
1750 Singlerow.szRev = CORBA::string_dup(m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXREV));
1751 Singlerow.szDate = CORBA::string_dup(m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXDATE));
1752 Singlerow.szStart = CORBA::string_dup(m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXSTART));
1753 Singlerow.szFinish = CORBA::string_dup(m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXFINISH));
1754 Singlerow.szAmount = CORBA::string_dup(m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXAMOUNT));
1755 // Singlerow.nRev = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXREV).toUInt();
1756 // Singlerow.nDate = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXDATE).toUInt();
1757 // Singlerow.nStart = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXSTART).toUInt();
1758 // Singlerow.nFinish = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXFINISH).toUInt();
1759 // Singlerow.nAmount = m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXAMOUNT).toUInt();
1760 Singlerow.szTask = CORBA::string_dup(m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXTASK));
1761 Singlerow.szRemark = CORBA::string_dup(m_pMaintable->text(Select.topRow() + nIter, TITRAQ_IDXREMARK));
1762 Account->Log(Singlerow); // Finally transmit to server
1763 }
1765 m_pStatbar->message(trUtf8("Successful transmission of accounting data"));
1766 }
1767 catch (const CORBA::Exception &Corbex) {
1768 m_pStatbar->message(trUtf8("Caught CORBA exception: %1").arg(Corbex._repoid()));
1769 qWarning("Caught CORBA exception: %s", Corbex._repoid());
1770 }
1771 catch (...) {
1772 qWarning("Caught unknown exception\n");
1773 }
1774 #endif // HAVE_MICO
1775 }
1777 //
1778 // Syncronize data with server using SOAP
1779 //
1780 void Titraqform::syncSoap(void)
1781 {
1782 #ifdef HAVE_ESOAP
1783 // Short circuit if user has disabled SOAP transmission in prefs
1784 if (!m_pPrefs->getBool(TITRAQ_PREFSOAPON, TITRAQ_DEFSOAPON))
1785 return;
1787 USING_EASYSOAP_NAMESPACE
1789 try {
1790 SOAPMethod Logmeth("Log", TITRAQ_SOAPSPACE); // SOAP namespace
1791 SOAPString Clistr; // Outgoing parameter to marshall
1792 int nCrc; // SOAP unmarshalled return value
1794 // Build the single string SOAP end point which look like this:
1795 // "http://www.europalab.com/cgi-bin/asdbserv"
1796 QString Endpoint;
1797 Endpoint = TITRAQ_PREFIXHTTP + m_pPrefs->getString(TITRAQ_PREFSOAPHOST, TITRAQ_DEFSOAPHOST);
1798 SOAPProxy Proxy(Endpoint.ascii());
1800 // Fill account log object(s) to marshall and transmit
1801 Q3TableSelection Select = m_pMaintable->selection(0); // Capture selected rows
1802 int nTotal = Select.bottomRow() - Select.topRow() + 1; // Total rows selected
1804 // Iterate through the selection of row entries to transmit
1805 for (int nRowiter = 0; nRowiter < nTotal; nRowiter++) {
1806 QString Syncthis = m_pMaintable->text(Select.topRow() + nRowiter, TITRAQ_IDXUSER);
1807 Syncthis += ' ' + m_pMaintable->text(Select.topRow() + nRowiter, TITRAQ_IDXGUID);
1808 Syncthis += ' ' + m_pMaintable->text(Select.topRow() + nRowiter, TITRAQ_IDXCRC).remove("0x");
1809 Syncthis += ' ' + m_pMaintable->text(Select.topRow() + nRowiter, TITRAQ_IDXREV);
1810 Syncthis += ' ' + m_pMaintable->text(Select.topRow() + nRowiter, TITRAQ_IDXDATE);
1811 Syncthis += ' ' + m_pMaintable->text(Select.topRow() + nRowiter, TITRAQ_IDXSTART);
1812 Syncthis += ' ' + m_pMaintable->text(Select.topRow() + nRowiter, TITRAQ_IDXFINISH);
1813 Syncthis += ' ' + m_pMaintable->text(Select.topRow() + nRowiter, TITRAQ_IDXAMOUNT);
1814 Syncthis += ' ' + m_pMaintable->text(Select.topRow() + nRowiter, TITRAQ_IDXTASK);
1815 Syncthis += ' ' + ('"' + m_pMaintable->text(Select.topRow() + nRowiter, TITRAQ_IDXREMARK)) + '"';
1816 Clistr = Syncthis; // Build RPC parameter
1817 Logmeth.AddParameter("Tuple") << Clistr; // Prepare for marshalling
1818 const SOAPResponse &Logresp = Proxy.Execute(Logmeth);
1819 Logresp.GetReturnValue() >> nCrc;
1820 }
1821 m_pStatbar->message(trUtf8("Successful transmission, CRC returned %1").arg(nCrc));
1822 }
1823 catch (SOAPException& Soapex) { // Announce the exception we received
1824 m_pStatbar->message(trUtf8("Caught SOAP exception: %1").arg(Soapex.What().Str()));
1825 qDebug("Caught SOAP exception: %s", Soapex.What().Str());
1826 }
1827 catch (...) {
1828 qDebug("Caught unknown exception\n");
1829 }
1830 #endif // HAVE_ESOAP
1831 }
1833 //
1834 // Save user preferences
1835 //
1836 void Titraqform::savePrefs(void)
1837 {
1838 // Get check status from column menu and pass it to prefs handler
1839 m_pPrefs->setBool(TITRAQ_PREFSTATCOLON, m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXSTATCOL)));
1840 m_pPrefs->setBool(TITRAQ_PREFLCOLON, m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXLCOL)));
1841 m_pPrefs->setBool(TITRAQ_PREFUCOLON, m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXUCOL)));
1842 m_pPrefs->setBool(TITRAQ_PREFGCOLON, m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXGCOL)));
1843 m_pPrefs->setBool(TITRAQ_PREFCCOLON, m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXCCOL)));
1844 m_pPrefs->setBool(TITRAQ_PREFREVCOLON, m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXREVCOL)));
1845 m_pPrefs->setBool(TITRAQ_PREFDCOLON, m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXDCOL)));
1846 m_pPrefs->setBool(TITRAQ_PREFSTARTCOLON, m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXSTARTCOL)));
1847 m_pPrefs->setBool(TITRAQ_PREFFCOLON, m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXFCOL)));
1848 m_pPrefs->setBool(TITRAQ_PREFACOLON, m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXACOL)));
1849 m_pPrefs->setBool(TITRAQ_PREFFCOLON, m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXFCOL)));
1850 m_pPrefs->setBool(TITRAQ_PREFREMCOLON, m_pColspopup->isItemChecked(m_pColspopup->idAt(TITRAQ_IDXREMCOL)));
1852 // Get check status from toolbar menu and pass it to prefs handler
1853 m_pPrefs->setBool(TITRAQ_PREFFILEBAR, m_pTbarspopup->isItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXFILEBAR)));
1854 m_pPrefs->setBool(TITRAQ_PREFEDITBAR, m_pTbarspopup->isItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXEDITBAR)));
1855 m_pPrefs->setBool(TITRAQ_PREFVIEWBAR, m_pTbarspopup->isItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXVIEWBAR)));
1856 m_pPrefs->setBool(TITRAQ_PREFPREFBAR, m_pTbarspopup->isItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXPREFBAR)));
1857 m_pPrefs->setBool(TITRAQ_PREFWHATBAR, m_pTbarspopup->isItemChecked(m_pTbarspopup->idAt(TITRAQ_IDXWHATBAR)));
1859 // Get column widths from main table and pass it to prefs handler
1860 if (m_pMaintable->columnWidth(TITRAQ_IDXSTATUS) > 0)
1861 m_pPrefs->setNumber(TITRAQ_PREFSTATCOLWIDTH, (long)m_pMaintable->columnWidth(TITRAQ_IDXSTATUS));
1862 if (m_pMaintable->columnWidth(TITRAQ_IDXLINE) > 0)
1863 m_pPrefs->setNumber(TITRAQ_PREFLCOLWIDTH, (long)m_pMaintable->columnWidth(TITRAQ_IDXLINE));
1864 if (m_pMaintable->columnWidth(TITRAQ_IDXUSER) > 0)
1865 m_pPrefs->setNumber(TITRAQ_PREFUCOLWIDTH, (long)m_pMaintable->columnWidth(TITRAQ_IDXUSER));
1866 if (m_pMaintable->columnWidth(TITRAQ_IDXGUID) > 0)
1867 m_pPrefs->setNumber(TITRAQ_PREFGCOLWIDTH, (long)m_pMaintable->columnWidth(TITRAQ_IDXGUID));
1868 if (m_pMaintable->columnWidth(TITRAQ_IDXCRC) > 0)
1869 m_pPrefs->setNumber(TITRAQ_PREFCCOLWIDTH, (long)m_pMaintable->columnWidth(TITRAQ_IDXCRC));
1870 if (m_pMaintable->columnWidth(TITRAQ_IDXREV) > 0)
1871 m_pPrefs->setNumber(TITRAQ_PREFREVCOLWIDTH, (long)m_pMaintable->columnWidth(TITRAQ_IDXREV));
1872 if (m_pMaintable->columnWidth(TITRAQ_IDXDATE) > 0)
1873 m_pPrefs->setNumber(TITRAQ_PREFDCOLWIDTH, (long)m_pMaintable->columnWidth(TITRAQ_IDXDATE));
1874 if (m_pMaintable->columnWidth(TITRAQ_IDXSTART) > 0)
1875 m_pPrefs->setNumber(TITRAQ_PREFSTARTCOLWIDTH, (long)m_pMaintable->columnWidth(TITRAQ_IDXSTART));
1876 if (m_pMaintable->columnWidth(TITRAQ_IDXFINISH) > 0)
1877 m_pPrefs->setNumber(TITRAQ_PREFFCOLWIDTH, (long)m_pMaintable->columnWidth(TITRAQ_IDXFINISH));
1878 if (m_pMaintable->columnWidth(TITRAQ_IDXAMOUNT) > 0)
1879 m_pPrefs->setNumber(TITRAQ_PREFACOLWIDTH, (long)m_pMaintable->columnWidth(TITRAQ_IDXAMOUNT));
1880 if (m_pMaintable->columnWidth(TITRAQ_IDXTASK) > 0)
1881 m_pPrefs->setNumber(TITRAQ_PREFTCOLWIDTH, (long)m_pMaintable->columnWidth(TITRAQ_IDXTASK));
1882 if (m_pMaintable->columnWidth(TITRAQ_IDXREMARK) > 0)
1883 m_pPrefs->setNumber(TITRAQ_PREFREMCOLWIDTH, (long)m_pMaintable->columnWidth(TITRAQ_IDXREMARK));
1885 // Get sorting order and direction from table and pass it to prefs handler
1886 m_pPrefs->setNumber(TITRAQ_PREFSORTCOL, (long)m_pMaintable->getSortcol());
1887 m_pPrefs->setBool(TITRAQ_PREFSORTDIR, (long)m_pMaintable->getSortdir());
1889 // Set frame geometry preferences
1890 m_pPrefs->setNumber(TITRAQ_PREFFRAMEWIDTH, (long)this->width());
1891 m_pPrefs->setNumber(TITRAQ_PREFFRAMEHEIGHT, (long)this->height());
1893 // Remember main window layout and doc positions
1894 QString Laystring;
1895 Q3TextStream Laystream(&Laystring, QIODevice::WriteOnly);
1896 //Laystream << *this; // Persist the main window
1897 m_pPrefs->setString(TITRAQ_PREFFRAMELAY, Laystring);
1898 }
1900 //
1901 // Get help on Titraq functionality
1902 //
1903 void Titraqform::helpContents(void)
1904 {
1905 try { // Create and execute a new help contents window
1906 std::auto_ptr<AS::Helpanel> pHelpcont(new AS::Helpanel(TITRAQ_REFHELP, this, "Helpanel"));
1907 pHelpcont->exec();
1908 delete pHelpcont.release(); // Technically unnecessary, smart pointer
1909 }
1910 catch (Genexcept& Genex) {
1911 Genex.reportErr();
1912 return;
1913 }
1914 }
1916 //
1917 // Learn more about this program itself
1918 //
1919 void Titraqform::aboutTitraq(void)
1920 {
1921 QString Namever = QString(TITRAQ_APPTITLE) + ' ' + asgui_version.v_short;
1922 QMessageBox *pCwmsg = new QMessageBox(Namever,
1923 QObject::trUtf8("The as-gui is a time and task-based accounting\n"
1924 "system that acts as both a work-like punch card and\n"
1925 "time tracker. Development of as-gui is sponsored by\n"
1926 "Cable & Wireless Telecommunications Services GmbH."),
1927 QMessageBox::NoIcon, QMessageBox::Ok | QMessageBox::Default,
1928 QMessageBox::NoButton, QMessageBox::NoButton,
1929 NULL, "Titraqmessage", true, Qt::WStyle_NormalBorder);
1931 pCwmsg->setIconPixmap(QPixmap(s_kpcCwlogo_xpm));
1932 pCwmsg->exec();
1933 }
1935 //
1936 // Learn more about the OSSP
1937 //
1938 void Titraqform::aboutOSSP(void)
1939 {
1940 QString Namever = QString(TITRAQ_APPTITLE) + ' ' + asgui_version.v_short;
1941 QMessageBox *pOsspmsg = new QMessageBox(Namever,
1942 QObject::trUtf8("The open source software project (OSSP) is\n"
1943 "a collective effort aimed at implementing\n"
1944 "high-quality Unix software components,\n"
1945 "ranging from networking, multi-threading\n"
1946 "and algorithmic libraries to networking\n"
1947 "servers and development tools."),
1948 QMessageBox::NoIcon, QMessageBox::Ok | QMessageBox::Default,
1949 QMessageBox::NoButton, QMessageBox::NoButton,
1950 NULL, "Osspmessage", true, Qt::WStyle_NormalBorder);
1952 pOsspmsg->setIconPixmap(QPixmap(s_kpcOssplogo_xpm));
1953 pOsspmsg->exec();
1954 }
1956 //
1957 // Learn more about this program and Qt
1958 //
1959 void Titraqform::aboutQt(void)
1960 {
1961 QMessageBox::aboutQt(this, QString(TITRAQ_APPTITLE) + ' ' + asgui_version.v_short);
1962 }
1964 //
1965 // Apply preference values from a signal emitting object
1966 //
1967 void Titraqform::applyPrefs(void)
1968 {
1969 Prefpanel *pPan = (Prefpanel *)QObject::sender();
1970 this->applyPrefs(pPan);
1971 }
1973 //
1974 // Accept preference values from a inbound Panel object
1975 //
1976 void Titraqform::applyPrefs(Prefpanel *pPrefpanel)
1977 {
1978 m_pPrefs->setString(TITRAQ_PREFACCOUNTS, pPrefpanel->getAccounts());
1979 m_pPrefs->setString(TITRAQ_PREFASDIR, pPrefpanel->getEvents());
1980 m_pPrefs->setString(TITRAQ_PREFUSER, pPrefpanel->getUser());
1981 m_pPrefs->setString(TITRAQ_PREFHOME, pPrefpanel->getHome());
1982 m_pPrefs->setString(TITRAQ_PREFCORBHOST, pPrefpanel->getCorbahost());
1983 m_pPrefs->setString(TITRAQ_PREFSOAPHOST, pPrefpanel->getSoaphost());
1984 m_pPrefs->setBool(TITRAQ_PREFCORBON, pPrefpanel->getCorbaon());
1985 m_pPrefs->setBool(TITRAQ_PREFSOAPON, pPrefpanel->getSoapon());
1986 m_pPrefs->setBool(TITRAQ_PREFBAKON, pPrefpanel->getBackon());
1987 m_pPrefs->setBool(TITRAQ_PREFEXTENDON, pPrefpanel->getExtendon());
1988 m_pPrefs->setBool(TITRAQ_PREFDETAILON, pPrefpanel->getDetailon());
1989 m_pPrefs->setBool(TITRAQ_PREFSIGNATON, pPrefpanel->getSignaton());
1990 m_pPrefs->setNumber(TITRAQ_PREFLIGHTRED, pPrefpanel->getLight()->red());
1991 m_pPrefs->setNumber(TITRAQ_PREFLIGHTGREEN, pPrefpanel->getLight()->green());
1992 m_pPrefs->setNumber(TITRAQ_PREFLIGHTBLUE, pPrefpanel->getLight()->blue());
1993 m_pPrefs->setNumber(TITRAQ_PREFDARKRED, pPrefpanel->getDark()->red());
1994 m_pPrefs->setNumber(TITRAQ_PREFDARKGREEN, pPrefpanel->getDark()->green());
1995 m_pPrefs->setNumber(TITRAQ_PREFDARKBLUE, pPrefpanel->getDark()->blue());
1997 // Dim the lights if no RPC transports are available
1998 if (this->isOpen())
1999 m_pSyncact->setEnabled(m_pPrefs->getBool(TITRAQ_PREFCORBON, TITRAQ_DEFCORBON)
2000 | m_pPrefs->getBool(TITRAQ_PREFSOAPON, TITRAQ_DEFSOAPON));
2001 else
2002 m_pSyncact->setEnabled(false);
2004 // Get the selected style which can be more complicated due to mapping...
2005 if (pPrefpanel->getStyle() == TITRAQ_STRCDE) {
2006 m_pPrefs->setNumber(TITRAQ_PREFSTYLE, TITRAQ_STYLECDE);
2007 qApp->setStyle(new QCDEStyle);
2008 }
2009 //else if (pPrefpanel->getStyle() == TITRAQ_STRSGI) { // Not supported
2010 // m_pPrefs->setNumber(TITRAQ_PREFSTYLE, TITRAQ_STYLESGI);
2011 // qApp->setStyle(new QSGIStyle);
2012 //}
2013 else if (pPrefpanel->getStyle() == TITRAQ_STRMOTIF) {
2014 m_pPrefs->setNumber(TITRAQ_PREFSTYLE, TITRAQ_STYLEMOTIF);
2015 qApp->setStyle(new QMotifStyle);
2016 }
2017 //else if (pPrefpanel->getStyle() == TITRAQ_STRMPLUS) { // Not supported
2018 // m_pPrefs->setNumber(TITRAQ_PREFSTYLE, TITRAQ_STYLEMPLUS);
2019 // qApp->setStyle(new QMotifPlusStyle);
2020 //}
2021 //else if (pPrefpanel->getStyle() == TITRAQ_STRPLAT) { // Not supported
2022 // m_pPrefs->setNumber(TITRAQ_PREFSTYLE, TITRAQ_STYLEPLAT);
2023 // qApp->setStyle(new QPlatinumStyle);
2024 //}
2025 else if (pPrefpanel->getStyle() == TITRAQ_STRMSOFT) {
2026 m_pPrefs->setNumber(TITRAQ_PREFSTYLE, TITRAQ_STYLEMSOFT);
2027 qApp->setStyle(new QWindowsStyle);
2028 }
2029 else // My personal favourite ;-)
2030 m_pPrefs->setNumber(TITRAQ_PREFSTYLE, TITRAQ_STYLECDE);
2031 }