first re-commit.
This commit is contained in:
468
libMiniCash/mcmainwindowbase.cpp
Normal file
468
libMiniCash/mcmainwindowbase.cpp
Normal file
@@ -0,0 +1,468 @@
|
||||
/***************************************************************************
|
||||
|
||||
libMiniCash
|
||||
Copyright © 2013-2018 christoph holzheuer
|
||||
c.holzheuer@sourceworx.org
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include <QtGui>
|
||||
#include <QWidget>
|
||||
#include <QMessageBox>
|
||||
#include <QShortcut>
|
||||
#include <QInputDialog>
|
||||
#include <QDir>
|
||||
#include <QPalette>
|
||||
#include <QApplication>
|
||||
|
||||
#include <mcmainwindowbase.h>
|
||||
#include <mcbillingview.h>
|
||||
/// Für den Test auf CapsLock
|
||||
///#include "Windows.h"
|
||||
/*
|
||||
* bool QMyClass::checkCapsLock()
|
||||
{
|
||||
// platform dependent method of determining if CAPS LOCK is on
|
||||
#ifdef Q_OS_WIN32 // MS Windows version
|
||||
return GetKeyState(VK_CAPITAL) == 1;
|
||||
#else // X11 version (Linux/Unix/Mac OS X/etc...)
|
||||
Display * d = XOpenDisplay((char*)0);
|
||||
bool caps_state = false;
|
||||
if (d)
|
||||
{
|
||||
unsigned n;
|
||||
XkbGetIndicatorState(d, XkbUseCoreKbd, &n);
|
||||
caps_state = (n & 0x01) == 1;
|
||||
}
|
||||
return caps_state;
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Der Konstruktor, die Initialisierungen des GUI
|
||||
* und der Netzverbindung werden in den Unterklassen vorgenommen.
|
||||
*/
|
||||
|
||||
MCMainWindowBase::MCMainWindowBase( QWidget* parent )
|
||||
: QMainWindow( parent )
|
||||
{
|
||||
|
||||
/// model setzen
|
||||
_salesModel.setParent( this );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MCMainWindowBase::~MCMainWindowBase !
|
||||
*/
|
||||
|
||||
MCMainWindowBase::~MCMainWindowBase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MCMainWindowBase::transCount !
|
||||
* @return
|
||||
*/
|
||||
|
||||
QString MCMainWindowBase::transCount()
|
||||
{
|
||||
return MCSalesModel::formatInt( _transCount );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Dateipfad anhand der Vorgaben aus dem Setup-Dialog erzeugen.
|
||||
* @param key settingskey
|
||||
*
|
||||
* Dateipfad anhand der Vorgaben aus den settings zusammenbasteln, Hilfsfunktion
|
||||
*
|
||||
* @return pfad
|
||||
*/
|
||||
|
||||
QString MCMainWindowBase::fetchSetting( const QString& key )
|
||||
{
|
||||
return _mainSettings.value( key ).toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Datei-Fehlermeldung anzeigen: Meistens sind einfach die Pfadeinstellungen falsch.
|
||||
* @param filename
|
||||
* @param errormsg
|
||||
*
|
||||
* Conveniencefunction zur vereinfachten Handhabung von Dateifehlern,
|
||||
* errortxt holen, Messagebox erzeugen etc.
|
||||
* @return immer false
|
||||
*/
|
||||
|
||||
bool MCMainWindowBase::showFileError( const QString& filename, const QString& errormsg )
|
||||
{
|
||||
|
||||
QString msg( "Datei '%0' konnte nicht geöffnet werden.\nFehlercode: %1" );
|
||||
/// je schlimmer je geiler
|
||||
QMessageBox::critical( this, "Fehler", msg.arg( filename, errormsg ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Dateien & Settings initialisieren
|
||||
*
|
||||
* Wird direkt beim Programmstart aufgerufen, setzt die Vorgabewerte
|
||||
* und erzeugt die Arbeitsdateien.
|
||||
*
|
||||
* @see setupDataFile
|
||||
*
|
||||
*/
|
||||
|
||||
void MCMainWindowBase::setupDefaults()
|
||||
{
|
||||
|
||||
/// leer? dann defaults reinschreiben
|
||||
if( !_mainSettings.contains( miniCash::keyMobileDrive) )
|
||||
{
|
||||
_mainSettings.setValue( miniCash::keyMobileDrive, miniCash::mobileDrive );
|
||||
_mainSettings.setValue( miniCash::keyProfit, miniCash::profit );
|
||||
_mainSettings.setValue( miniCash::keySelfID, miniCash::selfID );
|
||||
_mainSettings.setValue( miniCash::keyFooterText, "" );
|
||||
}
|
||||
|
||||
/// solange Setup-Dialog zeigen bis die Arbeitsfiles
|
||||
/// nutzbar sind
|
||||
|
||||
bool allfine = false;
|
||||
while( !allfine )
|
||||
{
|
||||
allfine = setupDataFile();
|
||||
if( !allfine )
|
||||
{
|
||||
QString msg( "Die lokale Arbeitsdatei konnte nicht angelegt werden.\nBitte die Programmeinstellungen überprüfen." );
|
||||
QMessageBox::critical( this, "Dateifehler", msg );
|
||||
setupDataFile();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Kassendateien öffnen oder erzeugen
|
||||
*
|
||||
* Hier werden die beiden Arbeitsdateien geöffnet bzw. erzeugt: es
|
||||
* wird entschieden, ob ein zum heutigen Datum (also Freitag oder Samstag)
|
||||
* ein passender Kleidermarkt vorhanden ist.
|
||||
* Falls nicht, wird eine Kassendatei fürs heutige Datum angelegt.
|
||||
*/
|
||||
|
||||
bool MCMainWindowBase::setupDataFile()
|
||||
{
|
||||
|
||||
/// step 1: Filenamen aus Datum bauen, hack: wir nehmen immer den Freitag
|
||||
QDate date = QDate::currentDate();
|
||||
/// Hack: Am Samstag schalten wir auf Freitag
|
||||
if( date.dayOfWeek() == 6 )
|
||||
date = date.addDays( -1 );
|
||||
|
||||
/// Filenames aus Datum
|
||||
_dataFileName = date.toString( "MM-dd-yyyy" ) + miniCash::filetype;
|
||||
QString dirName = QDir::homePath() + miniCash::dataDir;
|
||||
QDir dir( dirName );
|
||||
if( !dir.exists() )
|
||||
dir.mkpath( dirName );
|
||||
|
||||
_dataFilePath = dirName + _dataFileName;
|
||||
|
||||
/// erstmal alles auf Anfang
|
||||
_transCount = 1;
|
||||
|
||||
/// Ist das File schon vorhanden ? Sonst anlegen
|
||||
QFile datafile( _dataFilePath );
|
||||
|
||||
if( !datafile.exists() )
|
||||
{
|
||||
/// hats auch wirklich geklappt?
|
||||
if( !datafile.open( QIODevice::WriteOnly ) )
|
||||
/// wenn schon der start misslingt, hat
|
||||
/// nichts mehr einen sinn
|
||||
return showFileError( _dataFilePath, datafile.errorString() );
|
||||
_mainSettings.setValue( miniCash::keyTransCount, "1" );
|
||||
}
|
||||
|
||||
/// Zählerstand lesen.
|
||||
_transCount = _mainSettings.value( miniCash::keyTransCount ).toInt();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Speichert die Transaktionsdaten in eine Datei, hier Stick und Festplatte
|
||||
* @param filename Zieldatei
|
||||
* @param result die Verkaufstransaktion
|
||||
*
|
||||
* Verkaufte Artikel auf Platte oder Stick sichern. Ds ist eine Hilfsfunktion für
|
||||
* @see onSaveTransaction, wir zweimal aufgerufen: einmal auf Stick und einmal
|
||||
* als Geheim-Backup auf Platte.
|
||||
*
|
||||
*/
|
||||
|
||||
bool MCMainWindowBase::saveTransactionToFile( const QString& filename, const QString& transaction )
|
||||
{
|
||||
QFile datafile( filename );
|
||||
if (!datafile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append ))
|
||||
return showFileError( filename, datafile.errorString() );
|
||||
|
||||
/// file nicht direkt beschreiben
|
||||
QTextStream output( &datafile );
|
||||
/// Stream füllen
|
||||
output << transaction;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Schreibt die Einkäufe eines Kunden (==Transaktion)
|
||||
* via QTextStream formatiert in einen String.
|
||||
*
|
||||
* Alle bisherigen Verkäufe, also der Inhalt des @see MCSalesModel, werden
|
||||
* mit Hilfe eines QTextStreams als Tab-Separated-Values in einen QString
|
||||
* geschrieben
|
||||
*
|
||||
* @return Die Verkaufstransaktion als String
|
||||
*
|
||||
*/
|
||||
|
||||
QString MCMainWindowBase::saveTransactionToString()
|
||||
{
|
||||
|
||||
QString result;
|
||||
QTextStream output( &result );
|
||||
|
||||
/// Stream füllen
|
||||
for( int row = 0; row < _salesModel.rowCount(); ++row )
|
||||
{
|
||||
|
||||
/// TransactionNo
|
||||
QModelIndex idx = _salesModel.index( row, MCSalesItemMap::Count );
|
||||
QString content = _salesModel.data( idx ).toString();
|
||||
output << content << " ";
|
||||
|
||||
/// SellerID
|
||||
idx = _salesModel.index( row, MCSalesItemMap::SellerID );
|
||||
content = _salesModel.data( idx ).toString();
|
||||
output << content << " ";
|
||||
|
||||
/// Laufende ArtikelNo
|
||||
idx = _salesModel.index( row, MCSalesItemMap::ItemNo );
|
||||
|
||||
/// passiert jetzt schon im model
|
||||
///output << formatInt( _salesModel.data( idx ).toInt(), 3 );
|
||||
output << _salesModel.data( idx ).toString();
|
||||
|
||||
idx = _salesModel.index( row, MCSalesItemMap::Price );
|
||||
content = _salesModel.data( idx ).toString();
|
||||
|
||||
/// Eurozeichen absäbeln, komma statt punkt wg. kompatibilität
|
||||
/// mit PCK
|
||||
|
||||
if( content.isEmpty() || content.isNull() )
|
||||
{
|
||||
/// FIX, murx: log error
|
||||
content = "0,0";
|
||||
}
|
||||
else
|
||||
{
|
||||
content = content.split( ' ' ).at(0);
|
||||
}
|
||||
|
||||
/// so sollte man es eigentlich machen
|
||||
output << Qt::right << qSetFieldWidth(15) << content << Qt::reset;
|
||||
/// datum/zeit dranhängen & zeile fertig
|
||||
QString dtstr = QDateTime::currentDateTime().toString( "MM-dd-yyyy hh:mm:ss" );
|
||||
output << ' ' << dtstr << Qt::endl;
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Vom aktuellen Kunden gekaufte Artikel auf Platte sichern.
|
||||
*
|
||||
* Speichert die vom aktuellen Kunden gekauften Artikel auf Platte.
|
||||
* @see saveTransactionToString()
|
||||
*
|
||||
*/
|
||||
|
||||
bool MCMainWindowBase::onSaveTransaction()
|
||||
{
|
||||
|
||||
// View auslesen
|
||||
/// an datei anhängen
|
||||
/// zähler zurücksetzen
|
||||
/// die Lineedits wieder löschen
|
||||
|
||||
///
|
||||
/// Step 0: gibbet überhaupt View-Daten?
|
||||
///
|
||||
|
||||
if( _salesModel.rowCount() == 0 )
|
||||
{
|
||||
QApplication::beep();
|
||||
return false;
|
||||
}
|
||||
|
||||
///
|
||||
/// Step 1: View-Daten via Textstream in einen String schreiben
|
||||
///
|
||||
|
||||
QString transaction = saveTransactionToString();
|
||||
|
||||
///
|
||||
/// Step 2a: Die (nunmehr formatierte) Transaktion speichern und sichern
|
||||
///
|
||||
|
||||
/// Offizieller Speicherort auf dem Stick bzw. nunmehr auf SSD
|
||||
if( !saveTransactionToFile( _dataFilePath, transaction ) )
|
||||
return false;
|
||||
|
||||
/// Dummy für Speichern im Netz
|
||||
emit transactionCreated( transaction );
|
||||
|
||||
///
|
||||
/// Step 4: das Zählerfeld neu setzen
|
||||
///
|
||||
_newTransCount++;
|
||||
_transCount++;
|
||||
_mainSettings.setValue( miniCash::keyTransCount, _transCount );
|
||||
|
||||
///
|
||||
/// Step 4: Die Lineedits & view wieder löschen
|
||||
///
|
||||
|
||||
_inputViewProxy->onResetView();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Verkaufstransaktionen kopieren
|
||||
*
|
||||
* Alle Verkaufstransaktionen zur Auswertung auf einen Memorystick
|
||||
* kopieren
|
||||
*
|
||||
*/
|
||||
|
||||
void MCMainWindowBase::onCopyTransactions()
|
||||
{
|
||||
|
||||
/// FIX murx
|
||||
QMessageBox msg;
|
||||
msg.setWindowTitle( "Auswertungsdatei erzeugen" );
|
||||
QString txt( "Wenn der Memorystick in Laufwerk '%0' \neingesteckt ist bitte auf 'Speichern' klicken" );
|
||||
msg.setText( txt.arg( fetchSetting( miniCash::keyMobileDrive ) ) );
|
||||
msg.setStandardButtons( QMessageBox::Save | QMessageBox::Cancel );
|
||||
msg.addButton("Speichern",QMessageBox::AcceptRole);
|
||||
msg.addButton("Abbrechen",QMessageBox::RejectRole);
|
||||
msg.setDefaultButton(QMessageBox::Save);
|
||||
msg.setIcon ( QMessageBox::Information );
|
||||
|
||||
if( msg.exec() == QMessageBox::Cancel )
|
||||
return;
|
||||
|
||||
QString target = fetchSetting( miniCash::keyMobileDrive ) + fetchSetting( miniCash::keySelfID );
|
||||
target += "_" + _dataFileName;
|
||||
|
||||
/// falls vorhanden löschen weil copy nicht überschreibt
|
||||
QFileInfo fitarget( target );
|
||||
|
||||
if( fitarget.exists() )
|
||||
QFile::remove( target );
|
||||
|
||||
if( !QFile::copy( _dataFilePath, target ) )
|
||||
{
|
||||
QString msg( "Dateifehler: Kopieren von %0\nnach %1 fehlgeschlagen.");
|
||||
QMessageBox::warning(this, "Dateifehler", msg.arg( _dataFilePath, target ) );
|
||||
|
||||
return onSetup();
|
||||
}
|
||||
|
||||
QMessageBox::information( this, "Auswertungsdatei erzeugen", "Auswertungsdatei wurde erfolgreich erzeugt." );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handbuch anzeigen
|
||||
*
|
||||
* @bug Handbuch ist noch nicht fertig.
|
||||
*/
|
||||
|
||||
void MCMainWindowBase::onHelpManual()
|
||||
{
|
||||
//QMessageBox::StandardButton reply = QMessageBox::information(this, "onHelpContents()", "onHelpContents()" );
|
||||
//_helpViewer->show();
|
||||
onHelpAbout();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Speichern und Beenden, die Toolbarversion: Es wird nachgefragt.
|
||||
*/
|
||||
|
||||
void MCMainWindowBase::onExitConfirmed()
|
||||
{
|
||||
/// murx
|
||||
QMessageBox msg;
|
||||
msg.setWindowTitle("Programm beenden");
|
||||
msg.setText("Programm wirklich beenden?");
|
||||
msg.setStandardButtons( QMessageBox::Save | QMessageBox::Cancel );
|
||||
msg.addButton("OK", QMessageBox::AcceptRole );
|
||||
msg.addButton("Abbrechen",QMessageBox::RejectRole);
|
||||
msg.setDefaultButton(QMessageBox::Save);
|
||||
msg.setIcon ( QMessageBox::Information );
|
||||
|
||||
if( msg.exec() == QMessageBox::Cancel )
|
||||
return;
|
||||
|
||||
onExit();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Speichern und Beenden, die Menuversion: Es wird nicht nachgefragt.
|
||||
*/
|
||||
|
||||
void MCMainWindowBase::onExit()
|
||||
{
|
||||
|
||||
/// Falls noch Transaktion vorhanden,
|
||||
/// diese sichern
|
||||
if( _salesModel.rowCount() != 0 )
|
||||
onSaveTransaction();
|
||||
qApp->exit();
|
||||
}
|
Reference in New Issue
Block a user