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