as_reportpanel.cpp

Fri, 28 Nov 2008 14:20:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 28 Nov 2008 14:20:00 +0100
changeset 2
e8292658d5b3
child 3
c1941114ca88
permissions
-rw-r--r--

Added tag ASGUI_0.7.7 for changeset d64aaa7d146f

     1 //
     2 //  OSSP asgui - Accounting system graphical user interface
     3 //  Copyright (c) 2002-2004 The OSSP Project (http://www.ossp.org/)
     4 //  Copyright (c) 2002-2004 Ralf S. Engelschall <rse@engelschall.com>
     5 //  Copyright (c) 2002-2004 Michael Schloh von Bennewitz <michael@schloh.com>
     6 //  Copyright (c) 2002-2004 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://www.ossp.org/pkg/tool/asgui/.
    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_reportpanel.cpp: ISO C++ implementation
    30 //
    32 #include <qvariant.h>
    33 #include <qpushbutton.h>
    34 #include <qtextedit.h>
    35 #include <qtoolbutton.h>
    36 #include <qbuttongroup.h>
    37 #include <qpopupmenu.h>
    38 #include <qlayout.h>
    39 #include <qtooltip.h>
    40 #include <qwhatsthis.h>
    41 #include <qtextstream.h>
    42 #include <qfiledialog.h>
    43 #include <qprinter.h>
    44 #include <qpaintdevicemetrics.h>
    45 #include <qpainter.h>
    46 #include <qfile.h>
    47 #include <qdir.h>
    49 #include "as_reportpanel.h"
    50 #include "as_numdial.h"
    51 #include "as_table.h"
    52 #include "as_pref.h"
    53 #include "as_generic.h"
    54 #include "as_const.h"
    55 #include "as_except.h"
    57 // Version information
    58 #define _AS_VERSION_CPP_AS_HEADER_
    59 #include "as_version.cpp"
    60 #undef  _AS_VERSION_CPP_AS_HEADER_
    63 namespace AS {
    65 //
    66 // Constructs a Reportpanel as a child of 'pParent', with the 
    67 // name 'kszName' and widget flags set to 'Flags'.
    68 //
    69 // The dialog will by default be modal, unless you set 'bModal' to
    70 // false to construct a modeless dialog.
    71 //
    72 Reportpanel::Reportpanel(TiTable *pTable, Preferences *pPreferences,
    73                          QWidget *pParent, const char *kszName,
    74                          bool bModal, WFlags Flags)
    75                          : QDialog(pParent, kszName, bModal, Flags)
    76 {
    77     // Boilerplate code to initialize the panel
    78     if (!kszName)
    79         this->setName("Reportpanel");
    81     // Make panel resizeable
    82     this->setSizeGripEnabled(true);
    83     this->setSizePolicy(QSizePolicy((QSizePolicy::SizeType)5,
    84         (QSizePolicy::SizeType)5, 0, 0, this->sizePolicy().hasHeightForWidth()));
    86     // Store matrix and prefs members
    87     m_pReptable = pTable;
    88     m_pReprefs  = pPreferences;
    89     m_pPrinter  = new QPrinter;
    91     // Preset number of weeks and months to report
    92     m_nWeeks = m_pReprefs->getNumber(TITRAQ_PREFREPORTWEEKS, TITRAQ_DEFREPORTWEEKS);
    93     m_nMonths = m_pReprefs->getNumber(TITRAQ_PREFREPORTMONTHS, TITRAQ_DEFREPORTMONTHS);
    95     // Build panel using already constructed widgets and layouts
    96     m_pFormlay = new QVBoxLayout(this, 11, 6, "Formlayout");
    97     m_pToolay = new QHBoxLayout(0, 0, 6, "Toolbuttonlay"); 
    98     m_pPushlay = new QHBoxLayout(0, 0, 6, "Pushbuttonlay"); 
   100     // Groupbox and its text display
   101     m_pBrowser = new QTextEdit(this, "Reportbrowser");
   102     m_pBrowser->setTextFormat(PlainText);
   103     m_pBrowser->setReadOnly(true);
   104     m_pBrowser->setFont(QFont("Courier", 10));
   105     m_pFormlay->addWidget(m_pBrowser);
   106     m_pFormlay->addSpacing(6);
   107     m_pFormlay->addLayout(m_pToolay);
   108     m_pFormlay->addSpacing(6);
   109     m_pFormlay->addLayout(m_pPushlay);
   111     // Tool button suite
   112     m_pWeekmonthgroup = new QButtonGroup(this, "Weekmonthgroup");
   113     m_pWeekmonthgroup->setColumnLayout(0, Qt::Horizontal);
   114     m_pWeekmonthgroup->layout()->setSpacing(11);
   115     m_pWeekmonthgroup->layout()->setMargin(0);
   116     m_pWeekmonthlay = new QHBoxLayout(m_pWeekmonthgroup->layout());
   117     m_pWeekmonthgroup->setFrameShape(QFrame::NoFrame);
   118     m_pWeekmonthgroup->setExclusive(true);
   119     m_pWeeklybutt = new QToolButton(m_pWeekmonthgroup, "Weeklybutton");
   120 //    m_pWeeklybutt->setPaletteBackgroundColor(QColor(198, 196, 186));
   121     m_pWeeklybutt->setFocusPolicy(QWidget::TabFocus);
   122     m_pWeeklybutt->setCursor(QCursor(13));
   123     m_pWeeklybutt->setToggleButton(true);
   124     m_pMonthlybutt = new QToolButton(m_pWeekmonthgroup, "Monthlybutton");
   125 //    m_pMonthlybutt->setPaletteBackgroundColor(QColor(198, 196, 186));
   126     m_pMonthlybutt->setFocusPolicy(QWidget::TabFocus);
   127     m_pMonthlybutt->setCursor(QCursor(13));
   128     m_pMonthlybutt->setToggleButton(true);
   130     // Popup for number of weeks
   131     m_pWeekpop = new QPopupMenu(this);
   132     if (m_pWeekpop == NULL) // Sanity check
   133         throw Genexcept("Weekly toolbutton popup creation failed.");
   134     m_pWeekpop->insertItem(trUtf8("One week"), this, SLOT(reportWeeks(int)));
   135     m_pWeekpop->insertItem(trUtf8("Two weeks"), this, SLOT(reportWeeks(int)));
   136     m_pWeekpop->insertItem(trUtf8("Three weeks"), this, SLOT(reportWeeks(int)));
   137     m_pWeekpop->insertItem(trUtf8("Four weeks"), this, SLOT(reportWeeks(int)));
   138     m_pWeekpop->insertItem(trUtf8("N... weeks"), this, SLOT(reportWeeks(int)));
   139     m_pWeekpop->setCheckable(true);
   140     m_pWeeklybutt->setPopup(m_pWeekpop);
   141     m_pWeeklybutt->setPopupDelay(TITRAQ_POPUPMSECS);
   143     { // Initialize check button correctly
   144         int nPosition = (m_nWeeks < m_pWeekpop->count()) ? m_nWeeks : m_pWeekpop->count();
   145         m_pWeekpop->setItemChecked(m_pWeekpop->idAt(--nPosition), true);
   146     }
   148     // Popup for number of months
   149     m_pMonthpop = new QPopupMenu(this);
   150     if (m_pMonthpop == NULL) // Sanity check
   151         throw Genexcept("Monthly toolbutton popup creation failed.");
   152     m_pMonthpop->insertItem(trUtf8("One month"), this, SLOT(reportMonths(int)));
   153     m_pMonthpop->insertItem(trUtf8("Two months"), this, SLOT(reportMonths(int)));
   154     m_pMonthpop->insertItem(trUtf8("Three months"), this, SLOT(reportMonths(int)));
   155     m_pMonthpop->insertItem(trUtf8("Four months"), this, SLOT(reportMonths(int)));
   156     m_pMonthpop->insertItem(trUtf8("N... months"), this, SLOT(reportMonths(int)));
   157     m_pMonthpop->setCheckable(true);
   158     m_pMonthlybutt->setPopup(m_pMonthpop);
   159     m_pMonthlybutt->setPopupDelay(TITRAQ_POPUPMSECS);
   161     { // Initialize check button correctly
   162         int nPosition = (m_nMonths < m_pMonthpop->count()) ? m_nMonths : m_pMonthpop->count();
   163         m_pMonthpop->setItemChecked(m_pMonthpop->idAt(--nPosition), true);
   164     }
   166     // Add our tool buttons
   167     m_pWeekmonthlay->addWidget(m_pWeeklybutt);
   168     m_pWeekmonthlay->addWidget(m_pMonthlybutt);
   169     m_pToolay->addWidget(m_pWeekmonthgroup);
   171     // Push button suite
   172     m_pSavebutt = new QPushButton(this, "Savebutton");
   173     m_pSavebutt->setPaletteBackgroundColor(QColor(202, 194, 182));
   174     m_pSavebutt->setCursor(QCursor(13));
   175     m_pPrintbutt = new QPushButton(this, "Printbutton");
   176     m_pPrintbutt->setPaletteBackgroundColor(QColor(198, 196, 186));
   177     m_pPrintbutt->setCursor(QCursor(13));
   178 #ifdef QT_NO_PRINTER
   179     m_pPrintbutt->setEnabled(false);
   180 #endif
   181     m_pDismissbutt = new QPushButton(this, "Dismissbutton");
   182     m_pDismissbutt->setPaletteBackgroundColor(QColor(198, 196, 186));
   183     m_pDismissbutt->setCursor(QCursor(13));
   184     m_pDismissbutt->setDefault(true);
   185     m_pPushlay->addWidget(m_pSavebutt);
   186     m_pPushlay->addWidget(m_pPrintbutt);
   187     m_pPushlay->addWidget(m_pDismissbutt);
   189     // Connect signals to slots, accept() and reject() are Qt implicit
   190     connect(m_pWeeklybutt, SIGNAL(clicked(void)), SLOT(reportWeeks(void)));
   191     connect(m_pMonthlybutt, SIGNAL(clicked(void)), SLOT(reportMonths(void)));
   192     connect(m_pSavebutt, SIGNAL(clicked(void)), SLOT(saveReport(void)));
   193     connect(m_pPrintbutt, SIGNAL(clicked(void)), SLOT(printReport(void)));
   194     connect(m_pDismissbutt, SIGNAL(clicked(void)), SLOT(accept(void)));
   195     this->resize(QSize(464, 332).expandedTo(minimumSizeHint()));
   196     this->textChange();
   197 }
   199 //
   200 // Overload QDialog::exec(), and generate a report before executing modally
   201 //
   202 int Reportpanel::exec(void)
   203 {
   204     int nRet = 0;
   205     int nPeriod = m_pReprefs->getNumber(TITRAQ_PREFREPORTYPE, TITRAQ_DEFREPORTYPE);
   207     switch (nPeriod) {
   208     case TITRAQ_REPORTWEEK:
   209         this->reportWeeks(1);
   210         m_pWeekmonthgroup->setButton(TITRAQ_REPORTWEEK);
   211         break;
   212     case TITRAQ_REPORTMONTH:
   213         this->reportMonths(1);
   214         m_pWeekmonthgroup->setButton(TITRAQ_REPORTMONTH);
   215         break;
   216     default:
   217         throw Genexcept("Reportpanel: Modal event loop entered with no report period.");
   218         break;
   219     }
   221     nRet = QDialog::exec(); // Blast off
   223     // Before losing scope, the preferred report period
   224     m_pReprefs->setNumber(TITRAQ_PREFREPORTYPE,
   225         m_pWeekmonthgroup->id(m_pWeekmonthgroup->selected()));
   226     m_pReprefs->setNumber(TITRAQ_PREFREPORTWEEKS, m_nWeeks);
   227     m_pReprefs->setNumber(TITRAQ_PREFREPORTMONTHS, m_nMonths);
   228     return nRet;
   229 }
   231 //
   232 // Makes a new weekly report of so many weeks
   233 //
   234 void Reportpanel::reportWeeks(int nMenuid)
   235 {
   236     // Range of weeks to report
   237     int nFirstweek, nLastweek;
   239     // Menu index, first item is always 0
   240     int nIndex = m_pWeekpop->indexOf(nMenuid);      // Corresponds to weeks
   241     int nLastid = 0;                                // Last menu id selected
   243     if (m_nWeeks < m_pWeekpop->count())
   244         nLastid = m_pWeekpop->idAt(m_nWeeks - 1);   // Probably not last item
   245     else
   246         nLastid = m_pWeekpop->idAt(m_pWeekpop->count() - 1); // Last item selected
   248     // Set the button in case from a menu selection
   249     m_pWeekmonthgroup->setButton(TITRAQ_REPORTWEEK);
   251     // Update m_nWeeks only if user prefers a different number
   252     if (nIndex >= 0) {
   253         // User selected N... to indicate an arbitrary number
   254         if (nIndex == m_pWeekpop->count() - 1) {
   255             Numdial Weeksinput;
   256             Weeksinput.setNum(m_nWeeks);
   257             if (Weeksinput.exec() == QDialog::Accepted) {
   258                 m_nWeeks = Weeksinput.getNum();
   259                 m_pWeekpop->setItemChecked(nLastid, false);
   260                 m_pWeekpop->setItemChecked(nMenuid, true);
   261             }
   262             else
   263                 return;
   264         }
   265         else { // User selected a preset menu item such as '2 weeks'
   266             m_nWeeks = nIndex + 1;
   267             m_pWeekpop->setItemChecked(nLastid, false);
   268             m_pWeekpop->setItemChecked(nMenuid, true);
   269         }
   270     }
   272     // Clear data window
   273     m_pBrowser->setUpdatesEnabled(false);
   274     m_pBrowser->clear();
   276     // Determine first and last week numbers, then write header
   277     nLastweek = QDate::currentDate().weekNumber();
   278     if (m_nWeeks > 1) {
   279         nFirstweek = QDate::currentDate().addDays(m_nWeeks * -7).weekNumber() + 1;
   280         this->writeHeader(nFirstweek, nLastweek);
   281     }
   282     else
   283         this->writeHeader(nLastweek);
   285     // Write new contents to data window
   286     m_pBrowser->append(this->getWeektotals(QDate::currentDate(), m_nWeeks));
   287     if (m_pReprefs->getBool(TITRAQ_PREFDETAILON, TITRAQ_DEFDETAILON))
   288         m_pBrowser->append(this->getWeekdetails(QDate::currentDate(), m_nWeeks));
   289     this->writeFooter();
   290     m_pBrowser->setCursorPosition(0, 0);
   291     m_pBrowser->ensureCursorVisible();
   292     m_pBrowser->setUpdatesEnabled(true);
   293     m_pBrowser->repaint(false);
   294 }
   296 //
   297 // Makes a new monthly report of so many months
   298 //
   299 void Reportpanel::reportMonths(int nMenuid)
   300 {
   301     // Range of months to report
   302     QString Firstmonth, Lastmonth;
   304     // Menu index, first item is always 0
   305     int nIndex = m_pMonthpop->indexOf(nMenuid);     // Corresponds to months
   306     int nLastid = 0;                                // Last menu id selected
   308     if (m_nMonths < m_pMonthpop->count())
   309         nLastid = m_pMonthpop->idAt(m_nMonths - 1); // Probably not last item
   310     else
   311         nLastid = m_pMonthpop->idAt(m_pMonthpop->count() - 1); // Last item selected
   313     // Set the button in case from a menu selection
   314     m_pWeekmonthgroup->setButton(TITRAQ_REPORTMONTH);
   316     // Update m_nMonths only if user prefers a different number
   317     if (nIndex >= 0) {
   318         // User selected N... to indicate an arbitrary number
   319         if (nIndex == m_pMonthpop->count() - 1) {
   320             Numdial Monthsinput;
   321             Monthsinput.setNum(m_nMonths);
   322             if (Monthsinput.exec() == QDialog::Accepted) {
   323                 m_nMonths = Monthsinput.getNum();
   324                 m_pMonthpop->setItemChecked(nLastid, false);
   325                 m_pMonthpop->setItemChecked(nMenuid, true);
   326             }
   327             else
   328                 return;
   329         }
   330         else { // User selected a preset menu item such as '2 months'
   331             m_nMonths = nIndex + 1;
   332             m_pMonthpop->setItemChecked(nLastid, false);
   333             m_pMonthpop->setItemChecked(nMenuid, true);
   334         }
   335     }
   337     // Clear data window
   338     m_pBrowser->setUpdatesEnabled(false);
   339     m_pBrowser->clear();
   341     // Determine first and last month names, then write header
   342     Lastmonth = QDate::longMonthName(QDate::currentDate().month());
   343     if (m_nMonths > 1) {
   344         int nMonth = (QDate::currentDate().addMonths(m_nMonths * -1).month() + 12) % 12 + 1;
   345         Firstmonth = QDate::longMonthName(nMonth);
   346         this->writeHeader(Firstmonth, Lastmonth);
   347     }
   348     else
   349         this->writeHeader(Lastmonth);
   351     // Write new contents to data window
   352     m_pBrowser->append(this->getMonthtotals(QDate::currentDate(), m_nMonths));
   353     if (m_pReprefs->getBool(TITRAQ_PREFDETAILON, TITRAQ_DEFDETAILON)) {
   354         m_pBrowser->append(this->getMonthdetails(QDate::currentDate(), m_nMonths));
   355     }
   356     this->writeFooter();
   357     m_pBrowser->setCursorPosition(0, 0);
   358     m_pBrowser->ensureCursorVisible();
   359     m_pBrowser->setUpdatesEnabled(true);
   360     m_pBrowser->repaint(false);
   361 }
   363 //
   364 // Writes a report header to the display window
   365 //
   366 void Reportpanel::writeHeader(int nWeeknum)
   367 {
   368     QString Header;
   369     Header = QString("Accounting System ");
   370     Header += QString(asgui_version.v_short);
   371     Header += trUtf8("\nLocal report, username '");
   372     Header += m_pReprefs->getString(TITRAQ_PREFUSER, TITRAQ_DEFUSER);
   373     Header += QString("'\n");
   374     Header += trUtf8("Date ");
   375     Header += QDate::currentDate().toString(Qt::ISODate);
   376     Header += trUtf8(", Time ");
   377     Header += QTime::currentTime().toString(Qt::ISODate);
   378     Header += trUtf8("\nReporting for week %1...").arg(nWeeknum);
   379     Header += QString("\n\n");
   380     m_pBrowser->setText(Header);
   381 }
   383 //
   384 // Writes a report header to the display window
   385 //
   386 void Reportpanel::writeHeader(QString Month)
   387 {
   388     QString Header;
   389     Header = QString("Accounting System ");
   390     Header += QString(asgui_version.v_short);
   391     Header += trUtf8("\nLocal report, username '");
   392     Header += m_pReprefs->getString(TITRAQ_PREFUSER, TITRAQ_DEFUSER);
   393     Header += QString("'\n");
   394     Header += trUtf8("Date ");
   395     Header += QDate::currentDate().toString(Qt::ISODate);
   396     Header += trUtf8(", Time ");
   397     Header += QTime::currentTime().toString(Qt::ISODate);
   398     Header += trUtf8("\nReporting for month %1...").arg(Month);
   399     Header += QString("\n\n");
   400     m_pBrowser->setText(Header);
   401 }
   403 //
   404 // Writes a report header to the display window
   405 //
   406 void Reportpanel::writeHeader(int nFirst, int nLast)
   407 {
   408     QString Header;
   409     Header = QString("Accounting System ");
   410     Header += QString(asgui_version.v_short);
   411     Header += trUtf8("\nLocal report, username '");
   412     Header += m_pReprefs->getString(TITRAQ_PREFUSER, TITRAQ_DEFUSER);
   413     Header += QString("'\n");
   414     Header += trUtf8("Date ");
   415     Header += QDate::currentDate().toString(Qt::ISODate);
   416     Header += trUtf8(", Time ");
   417     Header += QTime::currentTime().toString(Qt::ISODate);
   418     Header += trUtf8("\nReporting for weeks %1 through %2...").arg(nFirst).arg(nLast);
   419     Header += QString("\n\n");
   420     m_pBrowser->setText(Header);
   421 }
   423 //
   424 // Writes a report header to the display window
   425 //
   426 void Reportpanel::writeHeader(QString First, QString Last)
   427 {
   428     QString Header;
   429     Header = QString("Accounting System ");
   430     Header += QString(asgui_version.v_short);
   431     Header += trUtf8("\nLocal report, username '");
   432     Header += m_pReprefs->getString(TITRAQ_PREFUSER, TITRAQ_DEFUSER);
   433     Header += QString("'\n");
   434     Header += trUtf8("Date ");
   435     Header += QDate::currentDate().toString(Qt::ISODate);
   436     Header += trUtf8(", Time ");
   437     Header += QTime::currentTime().toString(Qt::ISODate);
   438     Header += trUtf8("\nReporting months %1 through %2...").arg(First).arg(Last);
   439     Header += QString("\n\n");
   440     m_pBrowser->setText(Header);
   441 }
   443 //
   444 // Writes a report footer to the display window
   445 //
   446 void Reportpanel::writeFooter(void)
   447 {
   448     if (m_pReprefs->getBool(TITRAQ_PREFSIGNATON, TITRAQ_DEFSIGNATON)) {
   449         m_pBrowser->append(trUtf8("\n\nPrint name ________________________________________\n"));
   450         m_pBrowser->append(trUtf8("\n\nSignature  ________________________________________"));
   451     }
   452 }
   454 //
   455 // Returns one week of details data
   456 //
   457 QString Reportpanel::getWeekdetails(QDate Dayref, int nWeeks)
   458 {
   459     QString Data;       // Output string
   460     QString Tempstring; // Temp churning
   461     int nRows = m_pReptable->numRows();
   463     // Find range boundaries
   464     Q_ASSERT(nWeeks > 0);
   465     QDate Tempdate;
   466     QDate Firstday;
   467     QDate Lastday;
   468     Firstday = Dayref.addDays(Dayref.dayOfWeek() * -1 + 1);
   469     Firstday = Firstday.addDays((nWeeks - 1) * -7);
   470     Lastday  = Firstday.addDays(7 * nWeeks);
   472     // Write some quick header text to the outgoing string
   473     Data  = trUtf8("\nDate       Hours Account details\n");
   474     Data += QString("---------- ----- ----------------------------------------\n");
   476     // Build the long week data string
   477     for (int nIter = nRows - 1; nIter >= 0; nIter--) {
   478         // Work on this tuple only if it within the reporting range
   479         Tempstring = m_pReptable->text(nIter, TITRAQ_IDXTASK);
   480         Tempdate = QDate::fromString(m_pReptable->text(nIter, TITRAQ_IDXDATE), Qt::ISODate);
   481         if (!Tempstring.isEmpty() && Firstday <= Tempdate && Tempdate < Lastday) {
   482             Tempstring = m_pReptable->text(nIter, TITRAQ_IDXDATE);
   483             if (!Tempstring.isEmpty())
   484                 Data += Tempstring;
   485             Tempstring = m_pReptable->text(nIter, TITRAQ_IDXAMOUNT);
   486             if (!Tempstring.isEmpty())
   487                 Data += QString(TITRAQ_SEPARATORTOK) + Tempstring;
   488             Tempstring = m_pReptable->text(nIter, TITRAQ_IDXTASK);
   489             if (!Tempstring.isEmpty())
   490                 Data += QString(TITRAQ_SEPARATORTOK) + Tempstring;
   491             Data += QString("\n"); // Finish off line
   492         }
   493     }
   495     return Data;
   496 }
   498 //
   499 // Returns one week of totals data
   500 //
   501 QString Reportpanel::getWeektotals(QDate Dayref, int nWeeks)
   502 {
   503     using namespace std;                            // Needed for maps and hash
   504     map<string, string> Hashtasks;                  // Hashtable to store tasks
   505     multimap<string, string> Hashhours;             // Hashtable to store hours
   506     map<string, string>::iterator Taskiter;         // Hashtable task iterator
   507     multimap<string, string>::iterator Houriter;    // Hashtable hour iterator
   509     QString Totals;                         // Data totals to return for writing
   510     QString Tempstring;                     // Temporary processing string
   511     QDate   Tempdate;                       // Temporary processing date
   512     int     nRows = m_pReptable->numRows();
   514     // Find range boundaries
   515     Q_ASSERT(nWeeks > 0);
   516     QDate Firstday;
   517     QDate Lastday;
   518     Firstday = Dayref.addDays(Dayref.dayOfWeek() * -1 + 1);
   519     Firstday = Firstday.addDays((nWeeks - 1) * -7);
   520     Lastday  = Firstday.addDays(7 * nWeeks);
   522     // Parse the table for interesting values
   523     for (int nIter = 0; nIter < nRows; nIter++) {
   524         // Work on this tuple only if it within the reporting range
   525         Tempstring = m_pReptable->text(nIter, TITRAQ_IDXTASK);
   526         Tempdate = QDate::fromString(m_pReptable->text(nIter, TITRAQ_IDXDATE), Qt::ISODate);
   527         if (!Tempstring.isEmpty() && Firstday <= Tempdate && Tempdate < Lastday) {
   528             string Convstring = Tempstring;         // Convert to string (can't cast?)
   529             QTime Intable = QTime::fromString(m_pReptable->text(nIter, TITRAQ_IDXAMOUNT), Qt::ISODate);
   530             int nTothours = QString(Hashtasks[Convstring]).section(':', 0, 0).toInt() + Intable.hour();
   531             int nTotminut = QString(Hashtasks[Convstring]).section(':', 1, 1).toInt() + Intable.minute();
   532             nTothours += nTotminut / 60;
   533             nTotminut %= 60;
   534             QString Hours = QString::number(nTothours).rightJustify(3, ' ');
   535             QString Mins  = QString::number(nTotminut).rightJustify(2, '0');
   536             string Timestring = Hours + ':' + Mins; // Convert to string (can't cast?)
   537             Hashtasks[Convstring] = Timestring;     // Finally store in hashtable
   538         }
   539     }
   541     // Reverse copy the tasks hashtable to both sort and index by amount key
   542     for (Taskiter = Hashtasks.begin(); Taskiter != Hashtasks.end(); Taskiter++)
   543         Hashhours.insert(pair<string, string>(Taskiter->second, Taskiter->first));
   545     // Write the actual data totals to the outgoing string in reverse order
   546     for (Houriter = Hashhours.begin(); Houriter != Hashhours.end(); Houriter++)
   547         Totals = Houriter->first + ' ' + Houriter->second + '\n' + Totals;
   549     // Write some quick header text to the outgoing string in reverse order
   550     Totals = QString("------ ----------------------------------------\n") + Totals;
   551     Totals = trUtf8("Total  Account summary\n") + Totals;
   553     return Totals; // The outgoing string... its finally gone, let's go to bed
   554 }
   556 //
   557 // Returns one month of details data
   558 //
   559 QString Reportpanel::getMonthdetails(QDate Dayref, int nMonths)
   560 {
   561     QString Data;       // Output string
   562     QString Tempstring; // Temp churning
   563     QDate Tempdate;     // For comparing
   564     QDate Firstday;     // Minimum boundary
   565     QDate Lastday;      // Maximum boundary
   566     int nRows = m_pReptable->numRows();
   568     // Find range boundaries
   569     Q_ASSERT(nMonths > 0);
   570     int nYear = Dayref.year();
   571     int nMonth = (Dayref.addMonths(nMonths * -1).month() + 12) % 12 + 1;
   572     if (nMonth > Dayref.month())
   573         nYear--;
   574     Firstday = QDate(nYear, nMonth, 1);
   575     Lastday  = QDate(Dayref.year(), Dayref.month(), Dayref.daysInMonth());
   577     // Write some quick header text to the outgoing string
   578     Data  = trUtf8("\nDate       Hours Account details\n");
   579     Data += QString("---------- ----- ----------------------------------------\n");
   581     // Build the long week data string
   582     for (int nIter = nRows - 1; nIter >= 0; nIter--) {
   583         // Work on this tuple only if it within the reporting range
   584         Tempstring = m_pReptable->text(nIter, TITRAQ_IDXTASK);
   585         Tempdate = QDate::fromString(m_pReptable->text(nIter, TITRAQ_IDXDATE), Qt::ISODate);
   586         if (!Tempstring.isEmpty() && Firstday <= Tempdate && Tempdate < Lastday) {
   587             Tempstring = m_pReptable->text(nIter, TITRAQ_IDXDATE);
   588             if (!Tempstring.isEmpty())
   589                 Data += Tempstring;
   590             Tempstring = m_pReptable->text(nIter, TITRAQ_IDXAMOUNT);
   591             if (!Tempstring.isEmpty())
   592                 Data += QString(TITRAQ_SEPARATORTOK) + Tempstring;
   593             Tempstring = m_pReptable->text(nIter, TITRAQ_IDXTASK);
   594             if (!Tempstring.isEmpty())
   595                 Data += QString(TITRAQ_SEPARATORTOK) + Tempstring;
   596             Data += trUtf8("\n"); // Finish off line
   597         }
   598     }
   600     return Data;
   601 }
   603 //
   604 // Returns one month of totals data
   605 //
   606 QString Reportpanel::getMonthtotals(QDate Dayref, int nMonths)
   607 {
   608     using namespace std;                            // Needed for maps and hash
   609     map<string, string> Hashtasks;                  // Hashtable to store tasks
   610     multimap<string, string> Hashhours;             // Hashtable to store hours
   611     map<string, string>::iterator Taskiter;         // Hashtable task iterator
   612     multimap<string, string>::iterator Houriter;    // Hashtable hour iterator
   614     QString Totals;                         // Data totals to return for writing
   615     QString Tempstring;                     // Temporary processing string
   616     QDate   Tempdate;                       // Temporary processing date
   617     int     nRows = m_pReptable->numRows();
   619     // Find range boundaries
   620     Q_ASSERT(nMonths > 0);
   621     int nYear = Dayref.year();
   622     int nMonth = (Dayref.addMonths(nMonths * -1).month() + 12) % 12 + 1;
   623     if (nMonth > Dayref.month())
   624         nYear--;
   625     QDate Firstday = QDate(nYear, nMonth, 1);
   626     QDate Lastday  = QDate(Dayref.year(), Dayref.month(), Dayref.daysInMonth());
   628     // Parse the table for interesting values
   629     for (int nIter = 0; nIter < nRows; nIter++) {
   630         // Work on this tuple only if it within the reporting range
   631         Tempstring = m_pReptable->text(nIter, TITRAQ_IDXTASK);
   632         Tempdate = QDate::fromString(m_pReptable->text(nIter, TITRAQ_IDXDATE), Qt::ISODate);
   633         if (!Tempstring.isEmpty() && Firstday <= Tempdate && Tempdate < Lastday) {
   634             string Convstring = Tempstring;         // Convert to string (can't cast?)
   635             QTime Intable = QTime::fromString(m_pReptable->text(nIter, TITRAQ_IDXAMOUNT), Qt::ISODate);
   636             int nTothours = QString(Hashtasks[Convstring]).section(':', 0, 0).toInt() + Intable.hour();
   637             int nTotminut = QString(Hashtasks[Convstring]).section(':', 1, 1).toInt() + Intable.minute();
   638             nTothours += nTotminut / 60;
   639             nTotminut %= 60;
   640             QString Hours = QString::number(nTothours).rightJustify(3, ' ');
   641             QString Mins  = QString::number(nTotminut).rightJustify(2, '0');
   642             string Timestring = Hours + ':' + Mins; // Convert to string (can't cast?)
   643             Hashtasks[Convstring] = Timestring;     // Finally store in hashtable
   644         }
   645     }
   647     // Reverse copy the tasks hashtable to both sort and index by amount key
   648     for (Taskiter = Hashtasks.begin(); Taskiter != Hashtasks.end(); Taskiter++)
   649         Hashhours.insert(pair<string, string>(Taskiter->second, Taskiter->first));
   651     // Write the actual data totals to the outgoing string in reverse order
   652     for (Houriter = Hashhours.begin(); Houriter != Hashhours.end(); Houriter++)
   653         Totals = Houriter->first + ' ' + Houriter->second + '\n' + Totals;
   655     // Write some quick header text to the outgoing string in reverse order
   656     Totals = QString("------ ----------------------------------------\n") + Totals;
   657     Totals = trUtf8("Total  Account summary\n") + Totals;
   659     return Totals; // The outgoing string... its finally gone, let's go to bed
   660 }
   662 //
   663 // Saves the currently displayed local report
   664 //
   665 void Reportpanel::saveReport(void)
   666 {
   667     int nResult = 0;        // For checking user's answer
   668     QFile Report;           // The resulting report file
   669     QString Filestring;     // The user chosen file name to save
   670     QString Openas = m_pReprefs->getString(TITRAQ_PREFHOME, TITRAQ_DEFHOME);
   672     // And then get the name of the selected file to save to
   673     Filestring = QFileDialog::getSaveFileName(Openas, trUtf8("Text files (*.txt);;All Files (*)"), this, trUtf8("ChooserDialog"), trUtf8("Choose a file to save"), NULL, false);
   674     if (!Filestring.isEmpty()) {
   675         if (QFile::exists(Filestring)) {
   676             nResult = QMessageBox::warning(this, QString(TITRAQ_APPTITLE)
   677                     + ' ' + asgui_version.v_short, trUtf8(TITRAQ_OVERWRITE),
   678                       trUtf8("&Yes"), trUtf8("&No"), NULL, 1, 1);
   679             if (nResult = QMessageBox::Ok) {                // Overwrite a file
   680                 Report.setName(Filestring);                 // User wished name
   681                 Report.open(IO_WriteOnly | IO_Truncate);    // Open report file
   682                 QTextStream Outstream(&Report);             // Convert to stream
   683                 Outstream << m_pBrowser->text();            // Write the data
   684                 Report.close();                             // Finish by closing
   685             }
   686         }
   687         else { // User gave a file name, and there was no preexisting file there
   688             Report.setName(Filestring);                 // User wished name
   689             Report.open(IO_WriteOnly | IO_Truncate);    // Open report file
   690             QTextStream Outstream(&Report);             // Convert to stream
   691             Outstream << m_pBrowser->text();            // Write the data
   692             Report.close();                             // Finish by closing
   693         }
   694     }
   695     // Otherwise, user did not select a valid file and push okay button
   696 }
   698 //
   699 // Prints the currently displayed local report
   700 //
   701 void Reportpanel::printReport(void)
   702 {
   703 #ifndef QT_NO_PRINTER
   704     if (m_pPrinter->setup(this)) {      // Opens printer dialog
   705         m_pPrinter->setFullPage(true);  // Set our own margins
   706         QPainter Paint;                 // Our painter (for pages)
   707         Paint.begin(m_pPrinter);        // Paint on printer
   708         Paint.setFont(m_pBrowser->font());
   709         QFontMetrics Fontmetrics = Paint.fontMetrics();
   710         QPaintDeviceMetrics Devmetrics(m_pPrinter); // Need width/height of printer surface
   711         const int knMargin = Devmetrics.logicalDpiX() / 2;  // Half-inch margin
   712         int nYpos   = knMargin;                             // Y position for each line
   713         int nPageno = 1;                                    // The starting page number
   715         for (int nIter = 0; nIter < m_pBrowser->lines() && !m_pPrinter->aborted(); nIter++) {
   716             // See if there is some space on this page to paint on
   717             if (nYpos + Fontmetrics.lineSpacing() > Devmetrics.height() - knMargin) {
   718 //                QString Printmsg(trUtf8("Printing page "))
   719 //                    + QString::number(++nPageno) + QString("...");
   720 //                m_pStatus()->message(Printmsg);             // Not in scope (crap)
   721                 if (!m_pPrinter->newPage()) // Start new page
   722                     break;                  // Some error
   723                 nYpos = knMargin;           // Back to top of page
   724             }
   725             Paint.drawText(knMargin, nYpos, Devmetrics.width() - 2 * knMargin,
   726                 Fontmetrics.lineSpacing(), Qt::ExpandTabs, m_pBrowser->text(nIter));
   727             nYpos += Fontmetrics.lineSpacing();
   728         }
   729         Paint.end(); // Send job to printer
   730 //        m_pStatus()->message(trUtf8("Printing completed"), 2000); // Not in scope
   731     }
   732 //    m_pStatusBar()->message(trUtf8("Printing completed"), 2000);  // Not in scope
   733 #endif
   734 }
   736 //
   737 // Sets the strings of the subwidgets using the current language
   738 //
   739 void Reportpanel::textChange(void)
   740 {
   741     this->setCaption(trUtf8("AS local report", "Local report using weekly or monthly data."));
   743     // Top level push buttons associated with accept and save slots
   744     m_pSavebutt->setText(trUtf8("Save As...", "Comment for Savebutton"));
   745     QToolTip::add(m_pSavebutt, trUtf8("Saves the report text", "Comment for tooltip Savebutton"));
   746     QWhatsThis::add(m_pSavebutt, trUtf8("The save button saves the report text to a file", "Comment for whatsThis Savebutton"));
   747     m_pPrintbutt->setText(trUtf8("Print...", "Comment for Printbutton"));
   748     QToolTip::add(m_pPrintbutt, trUtf8("Print the report text", "Comment for tooltip Printbutton"));
   749     QWhatsThis::add(m_pPrintbutt, trUtf8("The print button prints the report text to a file", "Comment for whatsThis Printbutton"));
   750     m_pDismissbutt->setText(trUtf8("Dismiss", "Comment for Dismissbutton"));
   751     QToolTip::add(m_pDismissbutt, trUtf8("Closes the report panel", "Comment for tooltip Dismissbutton"));
   752     QWhatsThis::add(m_pDismissbutt, trUtf8("The dismiss button dismisses the report panel", "Comment for whatsThis Dismissbutton"));
   754     // Inner tool buttons for new local report generation
   755     m_pWeeklybutt->setText(trUtf8("Weekly", "Comment for Weeklybutt"));
   756     QToolTip::add(m_pWeeklybutt, trUtf8("Hold down for options", "Comment for tooltip Weeklybutt"));
   757     QWhatsThis::add(m_pWeeklybutt, trUtf8("The Weekly button generates a new weekly report.\nHold this button down to specify many weeks.", "Comment for whatsThis Weeklybutt"));
   758     m_pMonthlybutt->setText(trUtf8("Monthly", "Comment for Monthlybutt"));
   759     QToolTip::add(m_pMonthlybutt, trUtf8("Hold down for options", "Comment for tooltip Monthlybutt"));
   760     QWhatsThis::add(m_pMonthlybutt, trUtf8("The Monthly button makes a new monthly report.\nHold this button down to specify how many months.", "Comment for whatsThis Monthlybutt"));
   761 }
   762 } // namespace AS

mercurial