as_reportpanel.cpp

changeset 1
d64aaa7d146f
child 3
c1941114ca88
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/as_reportpanel.cpp	Fri Nov 28 11:21:08 2008 +0100
     1.3 @@ -0,0 +1,762 @@
     1.4 +//
     1.5 +//  OSSP asgui - Accounting system graphical user interface
     1.6 +//  Copyright (c) 2002-2004 The OSSP Project (http://www.ossp.org/)
     1.7 +//  Copyright (c) 2002-2004 Ralf S. Engelschall <rse@engelschall.com>
     1.8 +//  Copyright (c) 2002-2004 Michael Schloh von Bennewitz <michael@schloh.com>
     1.9 +//  Copyright (c) 2002-2004 Cable & Wireless Telecommunications Services GmbH
    1.10 +//
    1.11 +//  This file is part of OSSP asgui, an accounting system graphical user
    1.12 +//  interface which can be found at http://www.ossp.org/pkg/tool/asgui/.
    1.13 +//
    1.14 +//  Permission to use, copy, modify, and distribute this software for
    1.15 +//  any purpose with or without fee is hereby granted, provided that
    1.16 +//  the above copyright notice and this permission notice appear in all
    1.17 +//  copies.
    1.18 +//
    1.19 +//  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
    1.20 +//  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    1.21 +//  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    1.22 +//  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
    1.23 +//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    1.24 +//  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    1.25 +//  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
    1.26 +//  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    1.27 +//  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    1.28 +//  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
    1.29 +//  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    1.30 +//  SUCH DAMAGE.
    1.31 +//
    1.32 +//  as_reportpanel.cpp: ISO C++ implementation
    1.33 +//
    1.34 +
    1.35 +#include <qvariant.h>
    1.36 +#include <qpushbutton.h>
    1.37 +#include <qtextedit.h>
    1.38 +#include <qtoolbutton.h>
    1.39 +#include <qbuttongroup.h>
    1.40 +#include <qpopupmenu.h>
    1.41 +#include <qlayout.h>
    1.42 +#include <qtooltip.h>
    1.43 +#include <qwhatsthis.h>
    1.44 +#include <qtextstream.h>
    1.45 +#include <qfiledialog.h>
    1.46 +#include <qprinter.h>
    1.47 +#include <qpaintdevicemetrics.h>
    1.48 +#include <qpainter.h>
    1.49 +#include <qfile.h>
    1.50 +#include <qdir.h>
    1.51 +
    1.52 +#include "as_reportpanel.h"
    1.53 +#include "as_numdial.h"
    1.54 +#include "as_table.h"
    1.55 +#include "as_pref.h"
    1.56 +#include "as_generic.h"
    1.57 +#include "as_const.h"
    1.58 +#include "as_except.h"
    1.59 +
    1.60 +// Version information
    1.61 +#define _AS_VERSION_CPP_AS_HEADER_
    1.62 +#include "as_version.cpp"
    1.63 +#undef  _AS_VERSION_CPP_AS_HEADER_
    1.64 +
    1.65 +
    1.66 +namespace AS {
    1.67 +
    1.68 +//
    1.69 +// Constructs a Reportpanel as a child of 'pParent', with the 
    1.70 +// name 'kszName' and widget flags set to 'Flags'.
    1.71 +//
    1.72 +// The dialog will by default be modal, unless you set 'bModal' to
    1.73 +// false to construct a modeless dialog.
    1.74 +//
    1.75 +Reportpanel::Reportpanel(TiTable *pTable, Preferences *pPreferences,
    1.76 +                         QWidget *pParent, const char *kszName,
    1.77 +                         bool bModal, WFlags Flags)
    1.78 +                         : QDialog(pParent, kszName, bModal, Flags)
    1.79 +{
    1.80 +    // Boilerplate code to initialize the panel
    1.81 +    if (!kszName)
    1.82 +        this->setName("Reportpanel");
    1.83 +
    1.84 +    // Make panel resizeable
    1.85 +    this->setSizeGripEnabled(true);
    1.86 +    this->setSizePolicy(QSizePolicy((QSizePolicy::SizeType)5,
    1.87 +        (QSizePolicy::SizeType)5, 0, 0, this->sizePolicy().hasHeightForWidth()));
    1.88 +
    1.89 +    // Store matrix and prefs members
    1.90 +    m_pReptable = pTable;
    1.91 +    m_pReprefs  = pPreferences;
    1.92 +    m_pPrinter  = new QPrinter;
    1.93 +
    1.94 +    // Preset number of weeks and months to report
    1.95 +    m_nWeeks = m_pReprefs->getNumber(TITRAQ_PREFREPORTWEEKS, TITRAQ_DEFREPORTWEEKS);
    1.96 +    m_nMonths = m_pReprefs->getNumber(TITRAQ_PREFREPORTMONTHS, TITRAQ_DEFREPORTMONTHS);
    1.97 +
    1.98 +    // Build panel using already constructed widgets and layouts
    1.99 +    m_pFormlay = new QVBoxLayout(this, 11, 6, "Formlayout");
   1.100 +    m_pToolay = new QHBoxLayout(0, 0, 6, "Toolbuttonlay"); 
   1.101 +    m_pPushlay = new QHBoxLayout(0, 0, 6, "Pushbuttonlay"); 
   1.102 +
   1.103 +    // Groupbox and its text display
   1.104 +    m_pBrowser = new QTextEdit(this, "Reportbrowser");
   1.105 +    m_pBrowser->setTextFormat(PlainText);
   1.106 +    m_pBrowser->setReadOnly(true);
   1.107 +    m_pBrowser->setFont(QFont("Courier", 10));
   1.108 +    m_pFormlay->addWidget(m_pBrowser);
   1.109 +    m_pFormlay->addSpacing(6);
   1.110 +    m_pFormlay->addLayout(m_pToolay);
   1.111 +    m_pFormlay->addSpacing(6);
   1.112 +    m_pFormlay->addLayout(m_pPushlay);
   1.113 +
   1.114 +    // Tool button suite
   1.115 +    m_pWeekmonthgroup = new QButtonGroup(this, "Weekmonthgroup");
   1.116 +    m_pWeekmonthgroup->setColumnLayout(0, Qt::Horizontal);
   1.117 +    m_pWeekmonthgroup->layout()->setSpacing(11);
   1.118 +    m_pWeekmonthgroup->layout()->setMargin(0);
   1.119 +    m_pWeekmonthlay = new QHBoxLayout(m_pWeekmonthgroup->layout());
   1.120 +    m_pWeekmonthgroup->setFrameShape(QFrame::NoFrame);
   1.121 +    m_pWeekmonthgroup->setExclusive(true);
   1.122 +    m_pWeeklybutt = new QToolButton(m_pWeekmonthgroup, "Weeklybutton");
   1.123 +//    m_pWeeklybutt->setPaletteBackgroundColor(QColor(198, 196, 186));
   1.124 +    m_pWeeklybutt->setFocusPolicy(QWidget::TabFocus);
   1.125 +    m_pWeeklybutt->setCursor(QCursor(13));
   1.126 +    m_pWeeklybutt->setToggleButton(true);
   1.127 +    m_pMonthlybutt = new QToolButton(m_pWeekmonthgroup, "Monthlybutton");
   1.128 +//    m_pMonthlybutt->setPaletteBackgroundColor(QColor(198, 196, 186));
   1.129 +    m_pMonthlybutt->setFocusPolicy(QWidget::TabFocus);
   1.130 +    m_pMonthlybutt->setCursor(QCursor(13));
   1.131 +    m_pMonthlybutt->setToggleButton(true);
   1.132 +
   1.133 +    // Popup for number of weeks
   1.134 +    m_pWeekpop = new QPopupMenu(this);
   1.135 +    if (m_pWeekpop == NULL) // Sanity check
   1.136 +        throw Genexcept("Weekly toolbutton popup creation failed.");
   1.137 +    m_pWeekpop->insertItem(trUtf8("One week"), this, SLOT(reportWeeks(int)));
   1.138 +    m_pWeekpop->insertItem(trUtf8("Two weeks"), this, SLOT(reportWeeks(int)));
   1.139 +    m_pWeekpop->insertItem(trUtf8("Three weeks"), this, SLOT(reportWeeks(int)));
   1.140 +    m_pWeekpop->insertItem(trUtf8("Four weeks"), this, SLOT(reportWeeks(int)));
   1.141 +    m_pWeekpop->insertItem(trUtf8("N... weeks"), this, SLOT(reportWeeks(int)));
   1.142 +    m_pWeekpop->setCheckable(true);
   1.143 +    m_pWeeklybutt->setPopup(m_pWeekpop);
   1.144 +    m_pWeeklybutt->setPopupDelay(TITRAQ_POPUPMSECS);
   1.145 +
   1.146 +    { // Initialize check button correctly
   1.147 +        int nPosition = (m_nWeeks < m_pWeekpop->count()) ? m_nWeeks : m_pWeekpop->count();
   1.148 +        m_pWeekpop->setItemChecked(m_pWeekpop->idAt(--nPosition), true);
   1.149 +    }
   1.150 +
   1.151 +    // Popup for number of months
   1.152 +    m_pMonthpop = new QPopupMenu(this);
   1.153 +    if (m_pMonthpop == NULL) // Sanity check
   1.154 +        throw Genexcept("Monthly toolbutton popup creation failed.");
   1.155 +    m_pMonthpop->insertItem(trUtf8("One month"), this, SLOT(reportMonths(int)));
   1.156 +    m_pMonthpop->insertItem(trUtf8("Two months"), this, SLOT(reportMonths(int)));
   1.157 +    m_pMonthpop->insertItem(trUtf8("Three months"), this, SLOT(reportMonths(int)));
   1.158 +    m_pMonthpop->insertItem(trUtf8("Four months"), this, SLOT(reportMonths(int)));
   1.159 +    m_pMonthpop->insertItem(trUtf8("N... months"), this, SLOT(reportMonths(int)));
   1.160 +    m_pMonthpop->setCheckable(true);
   1.161 +    m_pMonthlybutt->setPopup(m_pMonthpop);
   1.162 +    m_pMonthlybutt->setPopupDelay(TITRAQ_POPUPMSECS);
   1.163 +
   1.164 +    { // Initialize check button correctly
   1.165 +        int nPosition = (m_nMonths < m_pMonthpop->count()) ? m_nMonths : m_pMonthpop->count();
   1.166 +        m_pMonthpop->setItemChecked(m_pMonthpop->idAt(--nPosition), true);
   1.167 +    }
   1.168 +
   1.169 +    // Add our tool buttons
   1.170 +    m_pWeekmonthlay->addWidget(m_pWeeklybutt);
   1.171 +    m_pWeekmonthlay->addWidget(m_pMonthlybutt);
   1.172 +    m_pToolay->addWidget(m_pWeekmonthgroup);
   1.173 +
   1.174 +    // Push button suite
   1.175 +    m_pSavebutt = new QPushButton(this, "Savebutton");
   1.176 +    m_pSavebutt->setPaletteBackgroundColor(QColor(202, 194, 182));
   1.177 +    m_pSavebutt->setCursor(QCursor(13));
   1.178 +    m_pPrintbutt = new QPushButton(this, "Printbutton");
   1.179 +    m_pPrintbutt->setPaletteBackgroundColor(QColor(198, 196, 186));
   1.180 +    m_pPrintbutt->setCursor(QCursor(13));
   1.181 +#ifdef QT_NO_PRINTER
   1.182 +    m_pPrintbutt->setEnabled(false);
   1.183 +#endif
   1.184 +    m_pDismissbutt = new QPushButton(this, "Dismissbutton");
   1.185 +    m_pDismissbutt->setPaletteBackgroundColor(QColor(198, 196, 186));
   1.186 +    m_pDismissbutt->setCursor(QCursor(13));
   1.187 +    m_pDismissbutt->setDefault(true);
   1.188 +    m_pPushlay->addWidget(m_pSavebutt);
   1.189 +    m_pPushlay->addWidget(m_pPrintbutt);
   1.190 +    m_pPushlay->addWidget(m_pDismissbutt);
   1.191 +
   1.192 +    // Connect signals to slots, accept() and reject() are Qt implicit
   1.193 +    connect(m_pWeeklybutt, SIGNAL(clicked(void)), SLOT(reportWeeks(void)));
   1.194 +    connect(m_pMonthlybutt, SIGNAL(clicked(void)), SLOT(reportMonths(void)));
   1.195 +    connect(m_pSavebutt, SIGNAL(clicked(void)), SLOT(saveReport(void)));
   1.196 +    connect(m_pPrintbutt, SIGNAL(clicked(void)), SLOT(printReport(void)));
   1.197 +    connect(m_pDismissbutt, SIGNAL(clicked(void)), SLOT(accept(void)));
   1.198 +    this->resize(QSize(464, 332).expandedTo(minimumSizeHint()));
   1.199 +    this->textChange();
   1.200 +}
   1.201 +
   1.202 +//
   1.203 +// Overload QDialog::exec(), and generate a report before executing modally
   1.204 +//
   1.205 +int Reportpanel::exec(void)
   1.206 +{
   1.207 +    int nRet = 0;
   1.208 +    int nPeriod = m_pReprefs->getNumber(TITRAQ_PREFREPORTYPE, TITRAQ_DEFREPORTYPE);
   1.209 +
   1.210 +    switch (nPeriod) {
   1.211 +    case TITRAQ_REPORTWEEK:
   1.212 +        this->reportWeeks(1);
   1.213 +        m_pWeekmonthgroup->setButton(TITRAQ_REPORTWEEK);
   1.214 +        break;
   1.215 +    case TITRAQ_REPORTMONTH:
   1.216 +        this->reportMonths(1);
   1.217 +        m_pWeekmonthgroup->setButton(TITRAQ_REPORTMONTH);
   1.218 +        break;
   1.219 +    default:
   1.220 +        throw Genexcept("Reportpanel: Modal event loop entered with no report period.");
   1.221 +        break;
   1.222 +    }
   1.223 +
   1.224 +    nRet = QDialog::exec(); // Blast off
   1.225 +
   1.226 +    // Before losing scope, the preferred report period
   1.227 +    m_pReprefs->setNumber(TITRAQ_PREFREPORTYPE,
   1.228 +        m_pWeekmonthgroup->id(m_pWeekmonthgroup->selected()));
   1.229 +    m_pReprefs->setNumber(TITRAQ_PREFREPORTWEEKS, m_nWeeks);
   1.230 +    m_pReprefs->setNumber(TITRAQ_PREFREPORTMONTHS, m_nMonths);
   1.231 +    return nRet;
   1.232 +}
   1.233 +
   1.234 +//
   1.235 +// Makes a new weekly report of so many weeks
   1.236 +//
   1.237 +void Reportpanel::reportWeeks(int nMenuid)
   1.238 +{
   1.239 +    // Range of weeks to report
   1.240 +    int nFirstweek, nLastweek;
   1.241 +
   1.242 +    // Menu index, first item is always 0
   1.243 +    int nIndex = m_pWeekpop->indexOf(nMenuid);      // Corresponds to weeks
   1.244 +    int nLastid = 0;                                // Last menu id selected
   1.245 +
   1.246 +    if (m_nWeeks < m_pWeekpop->count())
   1.247 +        nLastid = m_pWeekpop->idAt(m_nWeeks - 1);   // Probably not last item
   1.248 +    else
   1.249 +        nLastid = m_pWeekpop->idAt(m_pWeekpop->count() - 1); // Last item selected
   1.250 +
   1.251 +    // Set the button in case from a menu selection
   1.252 +    m_pWeekmonthgroup->setButton(TITRAQ_REPORTWEEK);
   1.253 +
   1.254 +    // Update m_nWeeks only if user prefers a different number
   1.255 +    if (nIndex >= 0) {
   1.256 +        // User selected N... to indicate an arbitrary number
   1.257 +        if (nIndex == m_pWeekpop->count() - 1) {
   1.258 +            Numdial Weeksinput;
   1.259 +            Weeksinput.setNum(m_nWeeks);
   1.260 +            if (Weeksinput.exec() == QDialog::Accepted) {
   1.261 +                m_nWeeks = Weeksinput.getNum();
   1.262 +                m_pWeekpop->setItemChecked(nLastid, false);
   1.263 +                m_pWeekpop->setItemChecked(nMenuid, true);
   1.264 +            }
   1.265 +            else
   1.266 +                return;
   1.267 +        }
   1.268 +        else { // User selected a preset menu item such as '2 weeks'
   1.269 +            m_nWeeks = nIndex + 1;
   1.270 +            m_pWeekpop->setItemChecked(nLastid, false);
   1.271 +            m_pWeekpop->setItemChecked(nMenuid, true);
   1.272 +        }
   1.273 +    }
   1.274 +
   1.275 +    // Clear data window
   1.276 +    m_pBrowser->setUpdatesEnabled(false);
   1.277 +    m_pBrowser->clear();
   1.278 +
   1.279 +    // Determine first and last week numbers, then write header
   1.280 +    nLastweek = QDate::currentDate().weekNumber();
   1.281 +    if (m_nWeeks > 1) {
   1.282 +        nFirstweek = QDate::currentDate().addDays(m_nWeeks * -7).weekNumber() + 1;
   1.283 +        this->writeHeader(nFirstweek, nLastweek);
   1.284 +    }
   1.285 +    else
   1.286 +        this->writeHeader(nLastweek);
   1.287 +
   1.288 +    // Write new contents to data window
   1.289 +    m_pBrowser->append(this->getWeektotals(QDate::currentDate(), m_nWeeks));
   1.290 +    if (m_pReprefs->getBool(TITRAQ_PREFDETAILON, TITRAQ_DEFDETAILON))
   1.291 +        m_pBrowser->append(this->getWeekdetails(QDate::currentDate(), m_nWeeks));
   1.292 +    this->writeFooter();
   1.293 +    m_pBrowser->setCursorPosition(0, 0);
   1.294 +    m_pBrowser->ensureCursorVisible();
   1.295 +    m_pBrowser->setUpdatesEnabled(true);
   1.296 +    m_pBrowser->repaint(false);
   1.297 +}
   1.298 +
   1.299 +//
   1.300 +// Makes a new monthly report of so many months
   1.301 +//
   1.302 +void Reportpanel::reportMonths(int nMenuid)
   1.303 +{
   1.304 +    // Range of months to report
   1.305 +    QString Firstmonth, Lastmonth;
   1.306 +
   1.307 +    // Menu index, first item is always 0
   1.308 +    int nIndex = m_pMonthpop->indexOf(nMenuid);     // Corresponds to months
   1.309 +    int nLastid = 0;                                // Last menu id selected
   1.310 +
   1.311 +    if (m_nMonths < m_pMonthpop->count())
   1.312 +        nLastid = m_pMonthpop->idAt(m_nMonths - 1); // Probably not last item
   1.313 +    else
   1.314 +        nLastid = m_pMonthpop->idAt(m_pMonthpop->count() - 1); // Last item selected
   1.315 +
   1.316 +    // Set the button in case from a menu selection
   1.317 +    m_pWeekmonthgroup->setButton(TITRAQ_REPORTMONTH);
   1.318 +
   1.319 +    // Update m_nMonths only if user prefers a different number
   1.320 +    if (nIndex >= 0) {
   1.321 +        // User selected N... to indicate an arbitrary number
   1.322 +        if (nIndex == m_pMonthpop->count() - 1) {
   1.323 +            Numdial Monthsinput;
   1.324 +            Monthsinput.setNum(m_nMonths);
   1.325 +            if (Monthsinput.exec() == QDialog::Accepted) {
   1.326 +                m_nMonths = Monthsinput.getNum();
   1.327 +                m_pMonthpop->setItemChecked(nLastid, false);
   1.328 +                m_pMonthpop->setItemChecked(nMenuid, true);
   1.329 +            }
   1.330 +            else
   1.331 +                return;
   1.332 +        }
   1.333 +        else { // User selected a preset menu item such as '2 months'
   1.334 +            m_nMonths = nIndex + 1;
   1.335 +            m_pMonthpop->setItemChecked(nLastid, false);
   1.336 +            m_pMonthpop->setItemChecked(nMenuid, true);
   1.337 +        }
   1.338 +    }
   1.339 +
   1.340 +    // Clear data window
   1.341 +    m_pBrowser->setUpdatesEnabled(false);
   1.342 +    m_pBrowser->clear();
   1.343 +
   1.344 +    // Determine first and last month names, then write header
   1.345 +    Lastmonth = QDate::longMonthName(QDate::currentDate().month());
   1.346 +    if (m_nMonths > 1) {
   1.347 +        int nMonth = (QDate::currentDate().addMonths(m_nMonths * -1).month() + 12) % 12 + 1;
   1.348 +        Firstmonth = QDate::longMonthName(nMonth);
   1.349 +        this->writeHeader(Firstmonth, Lastmonth);
   1.350 +    }
   1.351 +    else
   1.352 +        this->writeHeader(Lastmonth);
   1.353 +
   1.354 +    // Write new contents to data window
   1.355 +    m_pBrowser->append(this->getMonthtotals(QDate::currentDate(), m_nMonths));
   1.356 +    if (m_pReprefs->getBool(TITRAQ_PREFDETAILON, TITRAQ_DEFDETAILON)) {
   1.357 +        m_pBrowser->append(this->getMonthdetails(QDate::currentDate(), m_nMonths));
   1.358 +    }
   1.359 +    this->writeFooter();
   1.360 +    m_pBrowser->setCursorPosition(0, 0);
   1.361 +    m_pBrowser->ensureCursorVisible();
   1.362 +    m_pBrowser->setUpdatesEnabled(true);
   1.363 +    m_pBrowser->repaint(false);
   1.364 +}
   1.365 +
   1.366 +//
   1.367 +// Writes a report header to the display window
   1.368 +//
   1.369 +void Reportpanel::writeHeader(int nWeeknum)
   1.370 +{
   1.371 +    QString Header;
   1.372 +    Header = QString("Accounting System ");
   1.373 +    Header += QString(asgui_version.v_short);
   1.374 +    Header += trUtf8("\nLocal report, username '");
   1.375 +    Header += m_pReprefs->getString(TITRAQ_PREFUSER, TITRAQ_DEFUSER);
   1.376 +    Header += QString("'\n");
   1.377 +    Header += trUtf8("Date ");
   1.378 +    Header += QDate::currentDate().toString(Qt::ISODate);
   1.379 +    Header += trUtf8(", Time ");
   1.380 +    Header += QTime::currentTime().toString(Qt::ISODate);
   1.381 +    Header += trUtf8("\nReporting for week %1...").arg(nWeeknum);
   1.382 +    Header += QString("\n\n");
   1.383 +    m_pBrowser->setText(Header);
   1.384 +}
   1.385 +
   1.386 +//
   1.387 +// Writes a report header to the display window
   1.388 +//
   1.389 +void Reportpanel::writeHeader(QString Month)
   1.390 +{
   1.391 +    QString Header;
   1.392 +    Header = QString("Accounting System ");
   1.393 +    Header += QString(asgui_version.v_short);
   1.394 +    Header += trUtf8("\nLocal report, username '");
   1.395 +    Header += m_pReprefs->getString(TITRAQ_PREFUSER, TITRAQ_DEFUSER);
   1.396 +    Header += QString("'\n");
   1.397 +    Header += trUtf8("Date ");
   1.398 +    Header += QDate::currentDate().toString(Qt::ISODate);
   1.399 +    Header += trUtf8(", Time ");
   1.400 +    Header += QTime::currentTime().toString(Qt::ISODate);
   1.401 +    Header += trUtf8("\nReporting for month %1...").arg(Month);
   1.402 +    Header += QString("\n\n");
   1.403 +    m_pBrowser->setText(Header);
   1.404 +}
   1.405 +
   1.406 +//
   1.407 +// Writes a report header to the display window
   1.408 +//
   1.409 +void Reportpanel::writeHeader(int nFirst, int nLast)
   1.410 +{
   1.411 +    QString Header;
   1.412 +    Header = QString("Accounting System ");
   1.413 +    Header += QString(asgui_version.v_short);
   1.414 +    Header += trUtf8("\nLocal report, username '");
   1.415 +    Header += m_pReprefs->getString(TITRAQ_PREFUSER, TITRAQ_DEFUSER);
   1.416 +    Header += QString("'\n");
   1.417 +    Header += trUtf8("Date ");
   1.418 +    Header += QDate::currentDate().toString(Qt::ISODate);
   1.419 +    Header += trUtf8(", Time ");
   1.420 +    Header += QTime::currentTime().toString(Qt::ISODate);
   1.421 +    Header += trUtf8("\nReporting for weeks %1 through %2...").arg(nFirst).arg(nLast);
   1.422 +    Header += QString("\n\n");
   1.423 +    m_pBrowser->setText(Header);
   1.424 +}
   1.425 +
   1.426 +//
   1.427 +// Writes a report header to the display window
   1.428 +//
   1.429 +void Reportpanel::writeHeader(QString First, QString Last)
   1.430 +{
   1.431 +    QString Header;
   1.432 +    Header = QString("Accounting System ");
   1.433 +    Header += QString(asgui_version.v_short);
   1.434 +    Header += trUtf8("\nLocal report, username '");
   1.435 +    Header += m_pReprefs->getString(TITRAQ_PREFUSER, TITRAQ_DEFUSER);
   1.436 +    Header += QString("'\n");
   1.437 +    Header += trUtf8("Date ");
   1.438 +    Header += QDate::currentDate().toString(Qt::ISODate);
   1.439 +    Header += trUtf8(", Time ");
   1.440 +    Header += QTime::currentTime().toString(Qt::ISODate);
   1.441 +    Header += trUtf8("\nReporting months %1 through %2...").arg(First).arg(Last);
   1.442 +    Header += QString("\n\n");
   1.443 +    m_pBrowser->setText(Header);
   1.444 +}
   1.445 +
   1.446 +//
   1.447 +// Writes a report footer to the display window
   1.448 +//
   1.449 +void Reportpanel::writeFooter(void)
   1.450 +{
   1.451 +    if (m_pReprefs->getBool(TITRAQ_PREFSIGNATON, TITRAQ_DEFSIGNATON)) {
   1.452 +        m_pBrowser->append(trUtf8("\n\nPrint name ________________________________________\n"));
   1.453 +        m_pBrowser->append(trUtf8("\n\nSignature  ________________________________________"));
   1.454 +    }
   1.455 +}
   1.456 +
   1.457 +//
   1.458 +// Returns one week of details data
   1.459 +//
   1.460 +QString Reportpanel::getWeekdetails(QDate Dayref, int nWeeks)
   1.461 +{
   1.462 +    QString Data;       // Output string
   1.463 +    QString Tempstring; // Temp churning
   1.464 +    int nRows = m_pReptable->numRows();
   1.465 +
   1.466 +    // Find range boundaries
   1.467 +    Q_ASSERT(nWeeks > 0);
   1.468 +    QDate Tempdate;
   1.469 +    QDate Firstday;
   1.470 +    QDate Lastday;
   1.471 +    Firstday = Dayref.addDays(Dayref.dayOfWeek() * -1 + 1);
   1.472 +    Firstday = Firstday.addDays((nWeeks - 1) * -7);
   1.473 +    Lastday  = Firstday.addDays(7 * nWeeks);
   1.474 +
   1.475 +    // Write some quick header text to the outgoing string
   1.476 +    Data  = trUtf8("\nDate       Hours Account details\n");
   1.477 +    Data += QString("---------- ----- ----------------------------------------\n");
   1.478 +
   1.479 +    // Build the long week data string
   1.480 +    for (int nIter = nRows - 1; nIter >= 0; nIter--) {
   1.481 +        // Work on this tuple only if it within the reporting range
   1.482 +        Tempstring = m_pReptable->text(nIter, TITRAQ_IDXTASK);
   1.483 +        Tempdate = QDate::fromString(m_pReptable->text(nIter, TITRAQ_IDXDATE), Qt::ISODate);
   1.484 +        if (!Tempstring.isEmpty() && Firstday <= Tempdate && Tempdate < Lastday) {
   1.485 +            Tempstring = m_pReptable->text(nIter, TITRAQ_IDXDATE);
   1.486 +            if (!Tempstring.isEmpty())
   1.487 +                Data += Tempstring;
   1.488 +            Tempstring = m_pReptable->text(nIter, TITRAQ_IDXAMOUNT);
   1.489 +            if (!Tempstring.isEmpty())
   1.490 +                Data += QString(TITRAQ_SEPARATORTOK) + Tempstring;
   1.491 +            Tempstring = m_pReptable->text(nIter, TITRAQ_IDXTASK);
   1.492 +            if (!Tempstring.isEmpty())
   1.493 +                Data += QString(TITRAQ_SEPARATORTOK) + Tempstring;
   1.494 +            Data += QString("\n"); // Finish off line
   1.495 +        }
   1.496 +    }
   1.497 +
   1.498 +    return Data;
   1.499 +}
   1.500 +
   1.501 +//
   1.502 +// Returns one week of totals data
   1.503 +//
   1.504 +QString Reportpanel::getWeektotals(QDate Dayref, int nWeeks)
   1.505 +{
   1.506 +    using namespace std;                            // Needed for maps and hash
   1.507 +    map<string, string> Hashtasks;                  // Hashtable to store tasks
   1.508 +    multimap<string, string> Hashhours;             // Hashtable to store hours
   1.509 +    map<string, string>::iterator Taskiter;         // Hashtable task iterator
   1.510 +    multimap<string, string>::iterator Houriter;    // Hashtable hour iterator
   1.511 +
   1.512 +    QString Totals;                         // Data totals to return for writing
   1.513 +    QString Tempstring;                     // Temporary processing string
   1.514 +    QDate   Tempdate;                       // Temporary processing date
   1.515 +    int     nRows = m_pReptable->numRows();
   1.516 +
   1.517 +    // Find range boundaries
   1.518 +    Q_ASSERT(nWeeks > 0);
   1.519 +    QDate Firstday;
   1.520 +    QDate Lastday;
   1.521 +    Firstday = Dayref.addDays(Dayref.dayOfWeek() * -1 + 1);
   1.522 +    Firstday = Firstday.addDays((nWeeks - 1) * -7);
   1.523 +    Lastday  = Firstday.addDays(7 * nWeeks);
   1.524 +
   1.525 +    // Parse the table for interesting values
   1.526 +    for (int nIter = 0; nIter < nRows; nIter++) {
   1.527 +        // Work on this tuple only if it within the reporting range
   1.528 +        Tempstring = m_pReptable->text(nIter, TITRAQ_IDXTASK);
   1.529 +        Tempdate = QDate::fromString(m_pReptable->text(nIter, TITRAQ_IDXDATE), Qt::ISODate);
   1.530 +        if (!Tempstring.isEmpty() && Firstday <= Tempdate && Tempdate < Lastday) {
   1.531 +            string Convstring = Tempstring;         // Convert to string (can't cast?)
   1.532 +            QTime Intable = QTime::fromString(m_pReptable->text(nIter, TITRAQ_IDXAMOUNT), Qt::ISODate);
   1.533 +            int nTothours = QString(Hashtasks[Convstring]).section(':', 0, 0).toInt() + Intable.hour();
   1.534 +            int nTotminut = QString(Hashtasks[Convstring]).section(':', 1, 1).toInt() + Intable.minute();
   1.535 +            nTothours += nTotminut / 60;
   1.536 +            nTotminut %= 60;
   1.537 +            QString Hours = QString::number(nTothours).rightJustify(3, ' ');
   1.538 +            QString Mins  = QString::number(nTotminut).rightJustify(2, '0');
   1.539 +            string Timestring = Hours + ':' + Mins; // Convert to string (can't cast?)
   1.540 +            Hashtasks[Convstring] = Timestring;     // Finally store in hashtable
   1.541 +        }
   1.542 +    }
   1.543 +
   1.544 +    // Reverse copy the tasks hashtable to both sort and index by amount key
   1.545 +    for (Taskiter = Hashtasks.begin(); Taskiter != Hashtasks.end(); Taskiter++)
   1.546 +        Hashhours.insert(pair<string, string>(Taskiter->second, Taskiter->first));
   1.547 +
   1.548 +    // Write the actual data totals to the outgoing string in reverse order
   1.549 +    for (Houriter = Hashhours.begin(); Houriter != Hashhours.end(); Houriter++)
   1.550 +        Totals = Houriter->first + ' ' + Houriter->second + '\n' + Totals;
   1.551 +
   1.552 +    // Write some quick header text to the outgoing string in reverse order
   1.553 +    Totals = QString("------ ----------------------------------------\n") + Totals;
   1.554 +    Totals = trUtf8("Total  Account summary\n") + Totals;
   1.555 +
   1.556 +    return Totals; // The outgoing string... its finally gone, let's go to bed
   1.557 +}
   1.558 +
   1.559 +//
   1.560 +// Returns one month of details data
   1.561 +//
   1.562 +QString Reportpanel::getMonthdetails(QDate Dayref, int nMonths)
   1.563 +{
   1.564 +    QString Data;       // Output string
   1.565 +    QString Tempstring; // Temp churning
   1.566 +    QDate Tempdate;     // For comparing
   1.567 +    QDate Firstday;     // Minimum boundary
   1.568 +    QDate Lastday;      // Maximum boundary
   1.569 +    int nRows = m_pReptable->numRows();
   1.570 +
   1.571 +    // Find range boundaries
   1.572 +    Q_ASSERT(nMonths > 0);
   1.573 +    int nYear = Dayref.year();
   1.574 +    int nMonth = (Dayref.addMonths(nMonths * -1).month() + 12) % 12 + 1;
   1.575 +    if (nMonth > Dayref.month())
   1.576 +        nYear--;
   1.577 +    Firstday = QDate(nYear, nMonth, 1);
   1.578 +    Lastday  = QDate(Dayref.year(), Dayref.month(), Dayref.daysInMonth());
   1.579 +
   1.580 +    // Write some quick header text to the outgoing string
   1.581 +    Data  = trUtf8("\nDate       Hours Account details\n");
   1.582 +    Data += QString("---------- ----- ----------------------------------------\n");
   1.583 +
   1.584 +    // Build the long week data string
   1.585 +    for (int nIter = nRows - 1; nIter >= 0; nIter--) {
   1.586 +        // Work on this tuple only if it within the reporting range
   1.587 +        Tempstring = m_pReptable->text(nIter, TITRAQ_IDXTASK);
   1.588 +        Tempdate = QDate::fromString(m_pReptable->text(nIter, TITRAQ_IDXDATE), Qt::ISODate);
   1.589 +        if (!Tempstring.isEmpty() && Firstday <= Tempdate && Tempdate < Lastday) {
   1.590 +            Tempstring = m_pReptable->text(nIter, TITRAQ_IDXDATE);
   1.591 +            if (!Tempstring.isEmpty())
   1.592 +                Data += Tempstring;
   1.593 +            Tempstring = m_pReptable->text(nIter, TITRAQ_IDXAMOUNT);
   1.594 +            if (!Tempstring.isEmpty())
   1.595 +                Data += QString(TITRAQ_SEPARATORTOK) + Tempstring;
   1.596 +            Tempstring = m_pReptable->text(nIter, TITRAQ_IDXTASK);
   1.597 +            if (!Tempstring.isEmpty())
   1.598 +                Data += QString(TITRAQ_SEPARATORTOK) + Tempstring;
   1.599 +            Data += trUtf8("\n"); // Finish off line
   1.600 +        }
   1.601 +    }
   1.602 +
   1.603 +    return Data;
   1.604 +}
   1.605 +
   1.606 +//
   1.607 +// Returns one month of totals data
   1.608 +//
   1.609 +QString Reportpanel::getMonthtotals(QDate Dayref, int nMonths)
   1.610 +{
   1.611 +    using namespace std;                            // Needed for maps and hash
   1.612 +    map<string, string> Hashtasks;                  // Hashtable to store tasks
   1.613 +    multimap<string, string> Hashhours;             // Hashtable to store hours
   1.614 +    map<string, string>::iterator Taskiter;         // Hashtable task iterator
   1.615 +    multimap<string, string>::iterator Houriter;    // Hashtable hour iterator
   1.616 +
   1.617 +    QString Totals;                         // Data totals to return for writing
   1.618 +    QString Tempstring;                     // Temporary processing string
   1.619 +    QDate   Tempdate;                       // Temporary processing date
   1.620 +    int     nRows = m_pReptable->numRows();
   1.621 +
   1.622 +    // Find range boundaries
   1.623 +    Q_ASSERT(nMonths > 0);
   1.624 +    int nYear = Dayref.year();
   1.625 +    int nMonth = (Dayref.addMonths(nMonths * -1).month() + 12) % 12 + 1;
   1.626 +    if (nMonth > Dayref.month())
   1.627 +        nYear--;
   1.628 +    QDate Firstday = QDate(nYear, nMonth, 1);
   1.629 +    QDate Lastday  = QDate(Dayref.year(), Dayref.month(), Dayref.daysInMonth());
   1.630 +
   1.631 +    // Parse the table for interesting values
   1.632 +    for (int nIter = 0; nIter < nRows; nIter++) {
   1.633 +        // Work on this tuple only if it within the reporting range
   1.634 +        Tempstring = m_pReptable->text(nIter, TITRAQ_IDXTASK);
   1.635 +        Tempdate = QDate::fromString(m_pReptable->text(nIter, TITRAQ_IDXDATE), Qt::ISODate);
   1.636 +        if (!Tempstring.isEmpty() && Firstday <= Tempdate && Tempdate < Lastday) {
   1.637 +            string Convstring = Tempstring;         // Convert to string (can't cast?)
   1.638 +            QTime Intable = QTime::fromString(m_pReptable->text(nIter, TITRAQ_IDXAMOUNT), Qt::ISODate);
   1.639 +            int nTothours = QString(Hashtasks[Convstring]).section(':', 0, 0).toInt() + Intable.hour();
   1.640 +            int nTotminut = QString(Hashtasks[Convstring]).section(':', 1, 1).toInt() + Intable.minute();
   1.641 +            nTothours += nTotminut / 60;
   1.642 +            nTotminut %= 60;
   1.643 +            QString Hours = QString::number(nTothours).rightJustify(3, ' ');
   1.644 +            QString Mins  = QString::number(nTotminut).rightJustify(2, '0');
   1.645 +            string Timestring = Hours + ':' + Mins; // Convert to string (can't cast?)
   1.646 +            Hashtasks[Convstring] = Timestring;     // Finally store in hashtable
   1.647 +        }
   1.648 +    }
   1.649 +
   1.650 +    // Reverse copy the tasks hashtable to both sort and index by amount key
   1.651 +    for (Taskiter = Hashtasks.begin(); Taskiter != Hashtasks.end(); Taskiter++)
   1.652 +        Hashhours.insert(pair<string, string>(Taskiter->second, Taskiter->first));
   1.653 +
   1.654 +    // Write the actual data totals to the outgoing string in reverse order
   1.655 +    for (Houriter = Hashhours.begin(); Houriter != Hashhours.end(); Houriter++)
   1.656 +        Totals = Houriter->first + ' ' + Houriter->second + '\n' + Totals;
   1.657 +
   1.658 +    // Write some quick header text to the outgoing string in reverse order
   1.659 +    Totals = QString("------ ----------------------------------------\n") + Totals;
   1.660 +    Totals = trUtf8("Total  Account summary\n") + Totals;
   1.661 +
   1.662 +    return Totals; // The outgoing string... its finally gone, let's go to bed
   1.663 +}
   1.664 +
   1.665 +//
   1.666 +// Saves the currently displayed local report
   1.667 +//
   1.668 +void Reportpanel::saveReport(void)
   1.669 +{
   1.670 +    int nResult = 0;        // For checking user's answer
   1.671 +    QFile Report;           // The resulting report file
   1.672 +    QString Filestring;     // The user chosen file name to save
   1.673 +    QString Openas = m_pReprefs->getString(TITRAQ_PREFHOME, TITRAQ_DEFHOME);
   1.674 +
   1.675 +    // And then get the name of the selected file to save to
   1.676 +    Filestring = QFileDialog::getSaveFileName(Openas, trUtf8("Text files (*.txt);;All Files (*)"), this, trUtf8("ChooserDialog"), trUtf8("Choose a file to save"), NULL, false);
   1.677 +    if (!Filestring.isEmpty()) {
   1.678 +        if (QFile::exists(Filestring)) {
   1.679 +            nResult = QMessageBox::warning(this, QString(TITRAQ_APPTITLE)
   1.680 +                    + ' ' + asgui_version.v_short, trUtf8(TITRAQ_OVERWRITE),
   1.681 +                      trUtf8("&Yes"), trUtf8("&No"), NULL, 1, 1);
   1.682 +            if (nResult = QMessageBox::Ok) {                // Overwrite a file
   1.683 +                Report.setName(Filestring);                 // User wished name
   1.684 +                Report.open(IO_WriteOnly | IO_Truncate);    // Open report file
   1.685 +                QTextStream Outstream(&Report);             // Convert to stream
   1.686 +                Outstream << m_pBrowser->text();            // Write the data
   1.687 +                Report.close();                             // Finish by closing
   1.688 +            }
   1.689 +        }
   1.690 +        else { // User gave a file name, and there was no preexisting file there
   1.691 +            Report.setName(Filestring);                 // User wished name
   1.692 +            Report.open(IO_WriteOnly | IO_Truncate);    // Open report file
   1.693 +            QTextStream Outstream(&Report);             // Convert to stream
   1.694 +            Outstream << m_pBrowser->text();            // Write the data
   1.695 +            Report.close();                             // Finish by closing
   1.696 +        }
   1.697 +    }
   1.698 +    // Otherwise, user did not select a valid file and push okay button
   1.699 +}
   1.700 +
   1.701 +//
   1.702 +// Prints the currently displayed local report
   1.703 +//
   1.704 +void Reportpanel::printReport(void)
   1.705 +{
   1.706 +#ifndef QT_NO_PRINTER
   1.707 +    if (m_pPrinter->setup(this)) {      // Opens printer dialog
   1.708 +        m_pPrinter->setFullPage(true);  // Set our own margins
   1.709 +        QPainter Paint;                 // Our painter (for pages)
   1.710 +        Paint.begin(m_pPrinter);        // Paint on printer
   1.711 +        Paint.setFont(m_pBrowser->font());
   1.712 +        QFontMetrics Fontmetrics = Paint.fontMetrics();
   1.713 +        QPaintDeviceMetrics Devmetrics(m_pPrinter); // Need width/height of printer surface
   1.714 +        const int knMargin = Devmetrics.logicalDpiX() / 2;  // Half-inch margin
   1.715 +        int nYpos   = knMargin;                             // Y position for each line
   1.716 +        int nPageno = 1;                                    // The starting page number
   1.717 +
   1.718 +        for (int nIter = 0; nIter < m_pBrowser->lines() && !m_pPrinter->aborted(); nIter++) {
   1.719 +            // See if there is some space on this page to paint on
   1.720 +            if (nYpos + Fontmetrics.lineSpacing() > Devmetrics.height() - knMargin) {
   1.721 +//                QString Printmsg(trUtf8("Printing page "))
   1.722 +//                    + QString::number(++nPageno) + QString("...");
   1.723 +//                m_pStatus()->message(Printmsg);             // Not in scope (crap)
   1.724 +                if (!m_pPrinter->newPage()) // Start new page
   1.725 +                    break;                  // Some error
   1.726 +                nYpos = knMargin;           // Back to top of page
   1.727 +            }
   1.728 +            Paint.drawText(knMargin, nYpos, Devmetrics.width() - 2 * knMargin,
   1.729 +                Fontmetrics.lineSpacing(), Qt::ExpandTabs, m_pBrowser->text(nIter));
   1.730 +            nYpos += Fontmetrics.lineSpacing();
   1.731 +        }
   1.732 +        Paint.end(); // Send job to printer
   1.733 +//        m_pStatus()->message(trUtf8("Printing completed"), 2000); // Not in scope
   1.734 +    }
   1.735 +//    m_pStatusBar()->message(trUtf8("Printing completed"), 2000);  // Not in scope
   1.736 +#endif
   1.737 +}
   1.738 +
   1.739 +//
   1.740 +// Sets the strings of the subwidgets using the current language
   1.741 +//
   1.742 +void Reportpanel::textChange(void)
   1.743 +{
   1.744 +    this->setCaption(trUtf8("AS local report", "Local report using weekly or monthly data."));
   1.745 +
   1.746 +    // Top level push buttons associated with accept and save slots
   1.747 +    m_pSavebutt->setText(trUtf8("Save As...", "Comment for Savebutton"));
   1.748 +    QToolTip::add(m_pSavebutt, trUtf8("Saves the report text", "Comment for tooltip Savebutton"));
   1.749 +    QWhatsThis::add(m_pSavebutt, trUtf8("The save button saves the report text to a file", "Comment for whatsThis Savebutton"));
   1.750 +    m_pPrintbutt->setText(trUtf8("Print...", "Comment for Printbutton"));
   1.751 +    QToolTip::add(m_pPrintbutt, trUtf8("Print the report text", "Comment for tooltip Printbutton"));
   1.752 +    QWhatsThis::add(m_pPrintbutt, trUtf8("The print button prints the report text to a file", "Comment for whatsThis Printbutton"));
   1.753 +    m_pDismissbutt->setText(trUtf8("Dismiss", "Comment for Dismissbutton"));
   1.754 +    QToolTip::add(m_pDismissbutt, trUtf8("Closes the report panel", "Comment for tooltip Dismissbutton"));
   1.755 +    QWhatsThis::add(m_pDismissbutt, trUtf8("The dismiss button dismisses the report panel", "Comment for whatsThis Dismissbutton"));
   1.756 +
   1.757 +    // Inner tool buttons for new local report generation
   1.758 +    m_pWeeklybutt->setText(trUtf8("Weekly", "Comment for Weeklybutt"));
   1.759 +    QToolTip::add(m_pWeeklybutt, trUtf8("Hold down for options", "Comment for tooltip Weeklybutt"));
   1.760 +    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"));
   1.761 +    m_pMonthlybutt->setText(trUtf8("Monthly", "Comment for Monthlybutt"));
   1.762 +    QToolTip::add(m_pMonthlybutt, trUtf8("Hold down for options", "Comment for tooltip Monthlybutt"));
   1.763 +    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"));
   1.764 +}
   1.765 +} // namespace AS

mercurial