MEventSummary::~MEventSummary(){}
+void MEventSummary::setTestTemplateFile(const QString& t)
+{
+ testTemplate=t;
+}
+
void MEventSummary::getSummaryData()
{
MTGetEventSummary ges=req->queryGetEventSummary(eventid);
void MEventSummary::print()
{
- MTemplate tf=req->templateStore()->getTemplate("eventsummary");
+ MTemplate tf;
+ if(testTemplate.isEmpty())
+ tf=req->templateStore()->getTemplate("eventsummary");
+ else
+ tf.setFile(testTemplate);
if(!tf.isValid()){
QMessageBox::warning(this,tr("Warning"),tr("Unable to get template file (eventsummary). Giving up."));
return;
}
MOdtSignalRenderer rend(tf);
connect(&rend,SIGNAL(getVariable(QString,QVariant&)), this,SLOT(getVariable(QString,QVariant&)));
- connect(&rend,SIGNAL(getLoopIterations(QString,int&)),this,SLOT(getLoopIterations(QString,int&)));
+ connect(&rend,SIGNAL(getLoopIterations(QString,int&)), this,SLOT(getLoopIterations(QString,int&)));
connect(&rend,SIGNAL(setLoopIteration(QString,int)), this,SLOT(setLoopIteration(QString,int)));
rend.renderToPrinter();
}
void MEventSummary::saveas()
{
- MTemplate tf=req->templateStore()->getTemplate("eventsummary");
+ MTemplate tf;
+ if(testTemplate.isEmpty())
+ tf=req->templateStore()->getTemplate("eventsummary");
+ else
+ tf.setFile(testTemplate);
if(!tf.isValid()){
QMessageBox::warning(this,tr("Warning"),tr("Unable to get template file (eventsummary). Giving up."));
return;
/**deletes MEventSummary*/
~MEventSummary();
+ ///set a test template
+ void setTestTemplateFile(const QString&);
+
private slots:
/**internal: print summary*/
void print();
QMap<int,MOOrder>orders;
QMap<int,MOCustomerInfo>customers;
QMap<QString,int>loopiter;
+ QString testTemplate;
//get summary
void getSummaryData();
updateData();
}
+void MOrderWindow::setTestTemplateFile(QString tf)
+{
+ m_testTemplate=tf;
+}
+
static const int ITEM_TICKET=1;
static const int ITEM_VOUCHER=2;
static const int ITEM_ITEM=3;
void MOrderWindow::printBill()
{
//get template
- MTemplate tf=req->templateStore()->getTemplate("bill");
+ MTemplate tf;
+ if(m_testTemplate.isEmpty()){
+ tf=req->templateStore()->getTemplate("bill");
+ }else
+ tf.setFile(m_testTemplate);
if(!tf.isValid()){
QMessageBox::warning(this,tr("Warning"),tr("Unable to get template file (bill). Giving up."));
return;
void MOrderWindow::saveBill()
{
//get template
- MTemplate tf=req->templateStore()->getTemplate("bill");
+ MTemplate tf;
+ if(m_testTemplate.isEmpty())
+ tf=req->templateStore()->getTemplate("bill");
+ else
+ tf.setFile(m_testTemplate);
if(!tf.isValid()){
QMessageBox::warning(this,tr("Warning"),tr("Unable to get template file (bill). Giving up."));
return;
public:
/**creates the order window*/
MOrderWindow(QWidget*,const MOOrder&);
+
+ /**used by the ODF editor: sets the template file to use for testing*/
+ void setTestTemplateFile(QString);
private slots:
/**internal: updates the labels and the ticket table*/
QStandardItemModel *m_model;
QAction*m_res2order,*m_cancel,*m_ship,*m_pay,*m_payv,*m_refund;
QMap<QString,int>m_loopiter;
+ QString m_testTemplate;
//printing buffer
struct TickInfo{
void MCartTab::cartAddTicket()
{
- QStandardItemModel*eventmodel=emit eventModel();
- if(!eventmodel)return;
//create ticket selection dialog
- QDialog dlg;
- dlg.setWindowTitle(tr("Select Event to order Ticket"));
- QTableView*tv;
- QHBoxLayout*hl;
- QVBoxLayout*vl;
- dlg.setLayout(vl=new QVBoxLayout);
- vl->addWidget(tv=new QTableView,10);
- tv->setModel(eventmodel);
- tv->setEditTriggers(QAbstractItemView::NoEditTriggers);
- tv->resizeColumnsToContents();
- vl->addSpacing(15);
- vl->addLayout(hl=new QHBoxLayout,0);
- hl->addStretch(10);
- QPushButton*p;
- hl->addWidget(p=new QPushButton(tr("Select")),0);
- connect(p,SIGNAL(clicked()),&dlg,SLOT(accept()));
- connect(tv,SIGNAL(doubleClicked(const QModelIndex&)),&dlg,SLOT(accept()));
- hl->addWidget(p=new QPushButton(tr("Cancel")),0);
- connect(p,SIGNAL(clicked()),&dlg,SLOT(reject()));
- //wait for it
- if(dlg.exec()!=QDialog::Accepted)return;
- //get selection
- QModelIndex idx=tv->currentIndex();
- if(!idx.isValid())return;
- int id=eventmodel->data(eventmodel->index(idx.row(),0),Qt::UserRole).toInt();
- if(id<0)return;
+ int id=-1;bool ok=false;
+ getEventId(id,ok);
+ if(id<0 || !ok)return;
addTicketForEvent(id);
}
~MCartTab();
signals:
- /**must be connected to the slot in the event tab: returns the event model
- TODO: refactor to be more elegant - don't use model!*/
- QStandardItemModel*eventModel();
/**must be connected to the slot in the event tab: returns the currently selected event ID*/
int currentEventId();
/**must be connected to the slot in the event tab: returns the currently selected event title*/
/**emitted when the cart tab wants focus because something important changed*/
void requestFocus();
+ ///select an event
+ void getEventId(int&,bool&);
+
public slots:
/**order ticket from event tab*/
void eventOrderTicket();
{
MPriceCategoryDialog(this,false).exec();
}
+
+void MEventsTab::selectEventId(int& eid, bool& ok) const
+{
+ QList<int>ids;
+ selectEventIds(ids,false);
+ ok=ids.size()>=1;
+ if(ok)eid=ids[0];
+}
+
+void MEventsTab::selectEventIds(QList< int >& eids, bool multi) const
+{
+ eids.clear();
+ QDialog dlg;
+ dlg.setWindowTitle(tr("Select Event"));
+ QTableView*tv;
+ QHBoxLayout*hl;
+ QVBoxLayout*vl;
+ dlg.setLayout(vl=new QVBoxLayout);
+ vl->addWidget(tv=new QTableView,10);
+ tv->setModel(eventmodel);
+ tv->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ tv->setSelectionBehavior(QAbstractItemView::SelectRows);
+ tv->setSelectionMode(multi?QAbstractItemView::MultiSelection:QAbstractItemView::SingleSelection);
+ tv->resizeColumnsToContents();
+ vl->addSpacing(15);
+ vl->addLayout(hl=new QHBoxLayout,0);
+ hl->addStretch(10);
+ QPushButton*p;
+ hl->addWidget(p=new QPushButton(tr("Select")),0);
+ connect(p,SIGNAL(clicked()),&dlg,SLOT(accept()));
+ connect(tv,SIGNAL(doubleClicked(const QModelIndex&)),&dlg,SLOT(accept()));
+ hl->addWidget(p=new QPushButton(tr("Cancel")),0);
+ connect(p,SIGNAL(clicked()),&dlg,SLOT(reject()));
+ //wait for it
+ if(dlg.exec()!=QDialog::Accepted)return;
+ //get selection
+ QModelIndexList ilst=tv->selectionModel()->selectedIndexes();
+ if(ilst.size()<1){
+ qDebug("nothing selected");
+ return;
+ }
+ //get events
+ for(int i=0;i<ilst.size();i++){
+ int eid=eventmodel->data(eventmodel->index(ilst[i].row(),0),Qt::UserRole).toInt();
+ if(!eids.contains(eid))eids.append(eid);
+ }
+}
/**edit price categories*/
void editPriceCat();
public slots:
- /**returns event table model*/
- QStandardItemModel*eventModel(){return eventmodel;}
/**returns the currently selected event (as ID) or -1 if none is selected*/
int currentEventId()const;
/**returns the currently selected event start time as string*/
/**update list of events*/
void updateEvents();
+
+ ///shows an event selection dialog and returns the selected event
+ /// \param eid the ID of the selected event, if the dialog was normally closed
+ /// \param ok true if the dialog was closed normally, false if the user aborted
+ void selectEventId(int&eid,bool&ok)const;
+ ///shows an event selection dialog and returns the selected event
+ /// \param eids the list of IDs of the selected events, empty if nothing was selected or the user aborted
+ /// \param multi true if multiple IDs can be selected, false if only one can be selec ted
+ void selectEventIds(QList<int>&eids,bool multi=true)const;
signals:
/**order ticket from event tab*/
void MOrdersTab::orderByEvent()
{
- //display selection dialog
- QDialog d(this);
- d.setWindowTitle(tr("Select Event"));
- QVBoxLayout*vl;
- QHBoxLayout*hl;
- d.setLayout(vl=new QVBoxLayout);
- QTableView*tv;
- vl->addWidget(tv=new QTableView,10);
- tv->setEditTriggers(QAbstractItemView::NoEditTriggers);
- QStandardItemModel*eventmodel=emit eventModel();
- tv->setModel(eventmodel);
- tv->resizeColumnsToContents();
- vl->addLayout(hl=new QHBoxLayout,0);
- hl->addStretch(10);
- QPushButton*p;
- hl->addWidget(p=new QPushButton(tr("Ok")),0);
- connect(p,SIGNAL(clicked()),&d,SLOT(accept()));
- hl->addWidget(p=new QPushButton(tr("Cancel")),0);
- connect(p,SIGNAL(clicked()),&d,SLOT(reject()));
- //wait for user
- if(d.exec()!=QDialog::Accepted)
- return;
- //get selection
- QModelIndexList ilst=tv->selectionModel()->selectedIndexes();
- if(ilst.size()<1){
- qDebug("nothing selected");
- return;
- }
//get events
QList<qint64>eventids;
- for(int i=0;i<ilst.size();i++){
- int eid=eventmodel->data(eventmodel->index(ilst[i].row(),0),Qt::UserRole).toInt();
- if(!eventids.contains(eid))eventids.append(eid);
- }
+ QList<int>eids;
+ selectEventIds(eids);
+ if(eids.size()<1)return;
+ for(int id:eids)eventids.append(id);
//request data and display
resetModel();
MTGetOrdersByEvents obe=req->queryGetOrdersByEvents(eventids,oldestOrderStamp(OldestForEvent));
signals:
/**needs to be connected to the event tab*/
- QStandardItemModel*eventModel();
+ void selectEventIds(QList<int>&);
private:
/**helper function: enters a single order into the model*/
carttab=new MCartTab(pk);
addTab(carttab,tr("Shopping Cart"),carttab->menu());
connect(eventtab,SIGNAL(eventOrderTicket()),carttab,SLOT(eventOrderTicket()));
- connect(carttab,SIGNAL(eventModel()), eventtab,SLOT(eventModel()), Qt::DirectConnection);
+ connect(carttab,SIGNAL(getEventId(int&,bool&)), eventtab,SLOT(selectEventId(int&,bool&)), Qt::DirectConnection);
connect(carttab,SIGNAL(currentEventId()), eventtab,SLOT(currentEventId()), Qt::DirectConnection);
connect(carttab,SIGNAL(currentEventTitle()), eventtab,SLOT(currentEventTitle()), Qt::DirectConnection);
connect(carttab,SIGNAL(currentEventStart()), eventtab,SLOT(currentEventStart()), Qt::DirectConnection);
//Order List Tab
addTab(ordertab=new MOrdersTab(pk),tr("Order List"));
- connect(ordertab,SIGNAL(eventModel()), eventtab,SLOT(eventModel()), Qt::DirectConnection);
+ connect(ordertab,SIGNAL(selectEventIds(QList<int>&)), eventtab,SLOT(selectEventIds(QList<int>&)), Qt::DirectConnection);
//Entrance Control Tab
entrancetab=new MEntranceTab(pk);
void MOverview::editOdfTemplate()
{
MOdfEditor *oe=new MOdfEditor(this);
+ connect(oe,SIGNAL(getEvent(int&,bool&)),eventtab,SLOT(selectEventId(int&,bool&)));
oe->show();
}
#include "lambda.h"
#include "vlambda.h"
-#include "MOTicket"
-#include "MOVoucher"
+#include "orderwin.h"
+#include "eventsummary.h"
+
+#include "MOOrder"
+#include "msinterface.h"
#include <DPtr>
#include <QMenu>
#include <QMenuBar>
#include <QMessageBox>
+#include <QPointer>
#include <QPointF>
#include <QPushButton>
#include <QScrollArea>
#include <QTreeView>
#include <QUnZip>
#include <QZip>
+#include <MTGetOrder>
class DPTR_CLASS_NAME(MOdfEditor)
QStackedWidget*mStack;
QLabel*mSpecial;
//tree menu
- QAction*maAddIntoCalc,*maWrapInCond,*maAddIntoComment,*maInsBehindElse,*maWrapInLoop;
+ QAction*maAddIntoCalc,*maWrapInCond,*maAddIntoComment;
+ QAction*maInsBehindElse,*maWrapInLoop;
QAction*maInsBehindCalc,*maInsBehindComment,*maUnwrap,*maDelItem;
void setActions(const QList<QAction*>&);
//current node
QModelIndex mCurIndex;
QDomNode mCurNode;
bool mChanged;
+ //test printing
+ QString mTestFile;
+ QPointer<MOrderWindow>mTestOrderWin;
+ QPointer<MEventSummary>mTestEventWin;
//file contents
struct File{
QString name;
d->maUnwrap=m->addAction(tr("Unwrap Loop/Condition"),this,SLOT(unwrapItem()));
d->maDelItem=m->addAction(tr("&Remove Item"),this,SLOT(delItem()));
- m=mb->addMenu(tr("&Data"));
- m->addAction(tr("Import from Order..."));
- m->addSeparator();
- m->addAction(tr("Test Printing..."));
- m->addAction(tr("Save Test Document..."));
+ m=mb->addMenu(tr("&Test"));
+ m->addAction(tr("Test with &Order..."),this,SLOT(testOrder()));
+ m->addAction(tr("Test with Event &Summary..."),this,SLOT(testEventSum()));
//central
QSplitter*central=new QSplitter(Qt::Vertical);
updateDisplay();
}
+MOdfEditor::~MOdfEditor()
+{
+ cleanTestFile();
+}
+
+void MOdfEditor::cleanTestFile()
+{
+ if(!d->mTestFile.isEmpty()){
+ QFile(d->mTestFile).remove();
+ d->mTestFile.clear();
+ }
+ if(d->mTestOrderWin)
+ d->mTestOrderWin->deleteLater();
+ if(d->mTestEventWin)
+ d->mTestEventWin->deleteLater();
+}
+
void MOdfEditor::setChanged(bool ch)
{
if(ch!=d->mChanged)
void MOdfEditor::loadFile(QString fn,bool istempl)
{
qDebug()<<"loading ODF template file"<<fn;
+ cleanTestFile();
//try to open the file
if(fn=="")return;
QFile fd(fn);
}
void MOdfEditor::saveFileAs()
{
- QString fn=QFileDialog::getSaveFileName(this,tr("Save Ticket Template"),d->mFileName);
+ QString fn=QFileDialog::getSaveFileName(this,tr("Save ODF Template"),d->mFileName,tr("ODF Template (*%1);;All ODF Templates (*.od?t);;All Files (*)").arg(detectTemplateType()));
if(fn!=""){
d->mFileName=fn;
saveFile(fn);
}
}
+void MOdfEditor::testSave()
+{
+ //generate temp file
+ if(d->mTestFile.isEmpty()){
+ QTemporaryFile tf(QDir::tempPath()+"/msmokeXXXXXX"+QFileInfo(d->mFileName).completeBaseName()+detectTemplateType());
+ tf.setAutoRemove(false);
+ tf.open();
+ d->mTestFile=tf.fileName();
+ }
+ //save the file
+ saveFile(d->mTestFile);
+}
+
+QString MOdfEditor::detectTemplateType() const
+{
+ //get document
+ QDomDocument doc=d->mDomModel->domDocument();
+ if(doc.isNull())return QString();
+ //recurse through elements: helper lambda to do it
+ const auto findElement=[](const QDomElement&el,const QString&nm)->QDomElement{
+ QDomNodeList nl=el.childNodes();
+ for(int i=0;i<nl.size();i++){
+ QDomElement el2=nl.at(i).toElement();
+ if(el2.isNull())continue;
+ const QString &tn=el2.tagName().split(':',QString::SkipEmptyParts).takeLast();
+ if(tn==nm)return el2;
+ }
+ //not found
+ return QDomElement();
+ };
+ //template
+ QDomElement el=doc.documentElement();
+ if(el.isNull() || el.tagName()!= (OdfTemplatePrefix+":template"))
+ return QString();
+ //-> *:document-content
+ el=findElement(el,"document-content");
+ if(el.isNull())return QString();
+ //-> *:-> *:body
+ el=findElement(el,"body");
+ if(el.isNull())return QString();
+ // -> *:text(odtt)/spreadsheet(odst)/database(odbt)/drawing(odgt)/presentation(odpt)
+ QDomNodeList nl=el.childNodes();
+ for(int i=0;i<nl.size();i++){
+ QDomElement el2=nl.at(i).toElement();
+ if(el2.isNull())continue;
+ const QString &tn=el2.tagName().split(':',QString::SkipEmptyParts).takeLast();
+ if(tn=="text")return ".odtt";
+ if(tn=="spreadsheet")return ".odst";
+ if(tn=="database")return ".odbt";
+ if(tn=="drawing")return ".odgt";
+ if(tn=="presentation")return ".odpt";
+ }
+ //not found
+ return QString();
+}
+
+void MOdfEditor::testOrder()
+{
+ //save it
+ testSave();
+ //open order win if not already open
+ if(d->mTestOrderWin.isNull()){
+ bool ok;
+ qint64 oid=QInputDialog::getInt(this,tr("Test with Order"),tr("Please enter the Order ID of the order you want to use for testing:"),0,0,0x7fffffff,1,&ok);
+ if(!ok)return;
+ MTGetOrder go=req->queryGetOrder(oid);
+ if(go.hasError()){
+ QMessageBox::warning(this,tr("Warning"),tr("Sorry I cannot retrieve this order: %1").arg(go.errorString()));
+ return;
+ }
+ MOOrder ord=go.getorder();
+ d->mTestOrderWin=new MOrderWindow(this,ord);
+ d->mTestOrderWin->setTestTemplateFile(d->mTestFile);
+ }
+ //bring into foreground
+ d->mTestOrderWin->show();
+ d->mTestOrderWin->raise();
+ d->mTestOrderWin->activateWindow();
+}
+
+void MOdfEditor::testEventSum()
+{
+ //save it
+ testSave();
+ //create window
+ if(d->mTestEventWin.isNull()){
+ //get event
+ int eid=-1;bool ok=false;
+ getEvent(eid,ok);
+ if(!ok || eid<0)return;
+ //open
+ d->mTestEventWin=new MEventSummary(this,eid);
+ d->mTestEventWin->setTestTemplateFile(d->mTestFile);
+ }
+ //bring into foreground
+ d->mTestEventWin->show();
+ d->mTestEventWin->raise();
+ d->mTestEventWin->activateWindow();
+}
+
void MOdfEditor::updateDisplay()
{
if(d->mFileName=="")
#include <DPtrBase>
+class MOEvent;
class QFile;
class QIODevice;
class QDomNode;
public:
///instantiates the editor
MOdfEditor(QWidget* parent = 0, Qt::WindowFlags f = 0);
+ ///clean it up
+ virtual ~MOdfEditor();
public slots:
///loads a template file, this is a helper for openFile and download
void wrapInLoop();
///helper: unwrap the loop or condition
void unwrapItem();
+
+ ///helper: test new template on an order
+ void testOrder();
+ ///helper: test new template on an event summary
+ void testEventSum();
+ ///helper: save into the test file
+ void testSave();
signals:
///used to switch to the correct editor widget
void switchStack(int);
+ ///used to select an event
+ void getEvent(int&,bool&);
private:
///helper to save the current node when selection changes
void saveCurrentNode();
///helper to display a tag
void displayTag();
+ ///helper to determine template type
+ /// \returns correct file extension (.odtt, .odst, ...) or empty string if the type cannot be determined
+ QString detectTemplateType()const;
+ ///cleans up the test file
+ void cleanTestFile();
};
#endif
MTemplate::MTemplate(QString fn){m_fname=fn;}
MTemplate::MTemplate(QString fn,QString chk,QString dsc,QString flg)
{m_fname=fn;m_checksum=chk;m_descr=dsc;m_flags=flg;}
+
+MTemplate::MTemplate(const MTemplate& t)
+{
+ m_fname=t.m_fname;
+ m_checksum=t.m_checksum;
+ m_descr=t.m_descr;
+ m_flags=t.m_flags;
+}
+
+MTemplate& MTemplate::operator=(const MTemplate&t)
+{
+ m_fname=t.m_fname;
+ m_checksum=t.m_checksum;
+ m_descr=t.m_descr;
+ m_flags=t.m_flags;
+ return *this;
+}
+
+void MTemplate::setFile(const QString& s)
+{
+ m_fname=s;
+ m_checksum=m_descr=m_flags=QString();
+}
+
QString MTemplate::cacheFileName()const{return m_fname;}
QString MTemplate::fileName()const
/**creates a temporary template by a physical file name*/
MTemplate(QString fn);
+ /**copies a template*/
+ MTemplate(const MTemplate&);
+
+ ///copies a template
+ MTemplate& operator=(const MTemplate&);
+
+ ///reinitializes the template from the given file name
+ void setFile(const QString&);
+
/**returns the name/path of the cache file, if it exists*/
QString cacheFileName()const;