wizard: make it fully scriptable
authorkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Thu, 21 Oct 2010 20:08:55 +0000 (20:08 +0000)
committerkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Thu, 21 Oct 2010 20:08:55 +0000 (20:08 +0000)
jsengine: load extensions, exec files
config: add script config
templates: add script templates
overview: make more accessable to scripting, exec startup script

git-svn-id: https://silmor.de/svn/softmagic/smoke/trunk@607 6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33

17 files changed:
src/dialogs/configdialog.cpp
src/dialogs/configdialog.h
src/dialogs/wizard.cpp
src/dialogs/wizard.h
src/iface/msinterface.cpp
src/iface/msinterface.h
src/mwin/overview.cpp
src/mwin/overview.h
src/script/init.js [new file with mode: 0644]
src/script/jsengine.cpp
src/script/jsengine.h
src/script/script.pri
src/script/scriptfiles.qrc [new file with mode: 0644]
src/script/startup.js [new file with mode: 0644]
src/script/wizard.js [new file with mode: 0644]
src/templates/templates.cpp
src/templates/templates.h

index 4d04e5a..0a7e722 100644 (file)
@@ -146,6 +146,35 @@ MConfigDialog::MConfigDialog()
        hl->addWidget(pb=new QPushButton(tr("Probe Server")));
        connect(pb,SIGNAL(clicked()),this,SLOT(serverProbe()));
        
+       tab->addTab(w=new QWidget,tr("Scripting"));
+       w->setLayout(gl=new QGridLayout);
+       gl->setColumnStretch(4,1);
+       lctr=0;
+       gl->addWidget(lab=new QLabel(tr("You can set scripting preferences here. You have the following options:\nAllow: if active scripts from this source are allowed to run.\nPriority: locations with the lowest value are searched first, when a script it found the other locations are ignored.")),lctr,0,1,5);
+       lab->setWordWrap(true);
+       gl->addWidget(lab=new QLabel(tr("Server side scripts:")),++lctr,0);
+       lab->setAlignment(Qt::AlignRight);
+       gl->addWidget(asrscript=new QCheckBox(tr("allow")),lctr,1);
+       gl->addWidget(new QLabel(tr("Prio:")),lctr,2);
+       gl->addWidget(psrscript=new QSpinBox,lctr,3);
+       psrscript->setRange(0,100);
+       gl->addWidget(lab=new QLabel(tr("Built in scripts:")),++lctr,0);
+       lab->setAlignment(Qt::AlignRight);
+       gl->addWidget(abiscript=new QCheckBox(tr("allow")),lctr,1);
+       gl->addWidget(new QLabel(tr("Prio:")),lctr,2);
+       gl->addWidget(pbiscript=new QSpinBox,lctr,3);
+       pbiscript->setRange(0,100);
+       gl->addWidget(lab=new QLabel(tr("User local scripts:")),++lctr,0);
+       lab->setAlignment(Qt::AlignRight);
+       gl->addWidget(ausscript=new QCheckBox(tr("allow")),lctr,1);
+       gl->addWidget(new QLabel(tr("Prio:")),lctr,2);
+       gl->addWidget(pusscript=new QSpinBox,lctr,3);
+       pusscript->setRange(0,100);
+       gl->addWidget(lab=new QLabel(tr("User script path:")),++lctr,0);
+       lab->setAlignment(Qt::AlignRight);
+       gl->addWidget(usrscript=new QLineEdit,lctr,1,1,4);
+       gl->setRowStretch(++lctr,1);
+       
        setSizeGripEnabled(true);
        
        initProfiles();
@@ -211,6 +240,13 @@ void MConfigDialog::loadProfile()
        username->setText(set.value("username").toString());
        sslexcept=new MSslExceptions(::dataDir+"/profile."+key+"/sslexceptions.xml");
        sslFillModel();
+       abiscript->setChecked(set.value("script/allowbuiltin",true).toBool());
+       ausscript->setChecked(set.value("script/allowuser",false).toBool());
+       asrscript->setChecked(set.value("script/allowserver",false).toBool());
+       pbiscript->setValue(set.value("script/priobuiltin",10).toInt());
+       pusscript->setValue(set.value("script/priouser",0).toInt());
+       psrscript->setValue(set.value("script/prioserver",20).toInt());
+       usrscript->setText(set.value("script/userpath",dataDir+"/userscripts").toString());
 }
 
 void MConfigDialog::saveProfile()
@@ -230,6 +266,13 @@ void MConfigDialog::saveProfile()
        set.setValue("username",username->text());
        QDir(::dataDir).mkdir("profile."+key);
        if(sslexcept)sslexcept->savesslexcept();
+       set.setValue("script/allowbuiltin",abiscript->isChecked());
+       set.setValue("script/allowuser",ausscript->isChecked());
+       set.setValue("script/allowserver",asrscript->isChecked());
+       set.setValue("script/priobuiltin",pbiscript->value());
+       set.setValue("script/priouser",pusscript->value());
+       set.setValue("script/prioserver",psrscript->value());
+       set.setValue("script/userpath",usrscript->text());
 }
 
 void MConfigDialog::newProfile()
index c5fe29e..423c722 100644 (file)
@@ -36,9 +36,10 @@ class MConfigDialog:public QDialog
                ~MConfigDialog();
                
        private:
-               QCheckBox*useproxy;
-               QLineEdit*hostname,*hostkey,*serverurl,*proxyname,*username,*proxyuser,*proxypass;
-               QSpinBox*proxyport;
+               QCheckBox*useproxy,*abiscript,*ausscript,*asrscript;
+               QLineEdit*hostname,*hostkey,*serverurl,*proxyname,*username,
+                       *proxyuser,*proxypass,*usrscript;
+               QSpinBox*proxyport,*pbiscript,*pusscript,*psrscript;
                QListView*profiles;
                QStandardItemModel*profilemodel,*sslmodel;
                QTableView*ssltable;
index c3cf986..a43e03e 100644 (file)
 MWizard::MWizard(MOverview* parent, Qt::WindowFlags f)
        :QDialog(parent, f),m_parent(parent)
 {
+       setWindowTitle(tr("Wizard"));
        //main layout
        QVBoxLayout*vl;
-       QStackedLayout*stack;
        QHBoxLayout*hl;
        setLayout(vl=new QVBoxLayout);
-       vl->addLayout(stack=new QStackedLayout,1);
+       vl->addLayout(m_stack=new QStackedLayout,1);
        //bottom buttons
        vl->addLayout(hl=new QHBoxLayout);
        hl->addStretch(1);
        QPushButton*p;
+       hl->addWidget(p=new QPushButton(tr("Start Over")));
+       connect(p,SIGNAL(clicked()),this,SLOT(gotoStart()));
        hl->addWidget(p=new QPushButton(tr("Close Wizard")));
        connect(p,SIGNAL(clicked()),this,SLOT(accept()));
        hl->addWidget(p=new QPushButton(tr("Exit")));
        connect(p,SIGNAL(clicked()),this,SLOT(accept()));
        connect(p,SIGNAL(clicked()),parent,SLOT(close()));
        
-       //paging
-       QSignalMapper*map=new QSignalMapper(this);
-       connect(map,SIGNAL(mapped(int)),stack,SLOT(setCurrentIndex(int)));
-       QWidget*w;
-       int istart,ivou,ievt,icust,iexec;
-       
        //page: start
-       istart=stack->addWidget(w=new QWidget);
+       QWidget*w;
+       m_startid=m_stack->addWidget(w=new QWidget);
        w->setLayout(vl=new QVBoxLayout);
        vl->addStretch(1);
-       vl->addWidget(p=new QPushButton(tr("Sell Tickets")));
-       p->setEnabled(req->hasRight(req->PCreateOrder_CanSell));
-       connect(p,SIGNAL(clicked()),map,SLOT(map()));
-       connect(p,SIGNAL(clicked()),this,SLOT(saleMode()));
-       map->setMapping(p,ievt);
-       vl->addWidget(p=new QPushButton(tr("Order Tickets")));
-       p->setEnabled(req->hasRight(req->PCreateOrder_CanSell));
-       connect(p,SIGNAL(clicked()),map,SLOT(map()));
-       connect(p,SIGNAL(clicked()),this,SLOT(orderMode()));
-       map->setMapping(p,ievt);
-       vl->addWidget(p=new QPushButton(tr("Sell Voucher")));
-       p->setEnabled(req->hasRight(req->PCreateOrder_CanOrder));
-       connect(p,SIGNAL(clicked()),map,SLOT(map()));
-       connect(p,SIGNAL(clicked()),this,SLOT(saleMode()));
-       map->setMapping(p,ivou);
-       vl->addWidget(p=new QPushButton(tr("Order Voucher")));
-       p->setEnabled(req->hasRight(req->PCreateOrder_CanOrder));
-       connect(p,SIGNAL(clicked()),map,SLOT(map()));
-       connect(p,SIGNAL(clicked()),this,SLOT(orderMode()));
-       map->setMapping(p,ivou);
+       vl->addLayout(m_modelayout=new QVBoxLayout);
        vl->addStretch(1);
        
-       //page: events
+       //mode mapping...
+       m_modemap=new QSignalMapper(this);
+       connect(m_modemap,SIGNAL(mapped(int)),this,SLOT(gotoPage(int)));
+       
+       //engine
        m_jseng=new MScriptEngine(parent);
-       m_jseng->addObject("Wizard",this);
-       m_jseng->evaluate("debugger");
+       m_jseng->addObject("wizard",this);
+       m_jseng->evalFile("wizard.js");
 }
 
 MWizard::~MWizard()
@@ -82,13 +64,37 @@ MWizard::~MWizard()
        delete m_jseng;
 }
 
+int MWizard::addMode(QString md)
+{
+       int r=addPage();
+       QPushButton*p;
+       m_modelayout->addWidget(p=new QPushButton(md));
+       m_modemap->setMapping(p,r);
+       connect(p,SIGNAL(clicked()),m_modemap,SLOT(map()));
+       return r;
+}
+
+int MWizard::addPage()
+{
+       return m_stack->addWidget(new QWidget);
+}
+
+void MWizard::gotoStart()
+{
+       m_stack->setCurrentIndex(m_startid);
+}
+
+void MWizard::gotoPage(int pg)
+{
+       m_stack->setCurrentIndex(pg);
+}
 
-void MWizard::orderMode()
+QPushButton* MWizard::modeButton(int pg)
 {
-       m_mode=OrderMode;
+       return qobject_cast<QPushButton*>(m_modemap->mapping(pg));
 }
 
-void MWizard::saleMode()
+QWidget* MWizard::pageWidget(int pg)
 {
-       m_mode=SaleMode;
+       return m_stack->widget(pg);
 }
index d9451f4..9e054f6 100644 (file)
@@ -15,6 +15,9 @@
 
 #include <QDialog>
 
+class QSignalMapper;
+class QVBoxLayout;
+class QStackedLayout;
 class MScriptEngine;
 class MOverview;
 class MWizard:public QDialog
@@ -23,14 +26,22 @@ class MWizard:public QDialog
        public:
                MWizard(MOverview* parent = 0, Qt::WindowFlags f = 0);
                virtual ~MWizard();
-       private slots:
-               void saleMode();
-               void orderMode();
+               
+       public slots:
+               int addPage();
+               int addMode(QString);
+               void gotoStart();
+               void gotoPage(int);
+               QWidget* pageWidget(int);
+               QPushButton* modeButton(int);
+               
        private:
                MOverview*m_parent;
-               enum Mode {SaleMode,OrderMode};
-               Mode m_mode;
                MScriptEngine*m_jseng;
+               QStackedLayout*m_stack;
+               QVBoxLayout*m_modelayout;
+               QSignalMapper*m_modemap;
+               int m_startid;
 };
 
 #endif
index 6fb983e..d01aa70 100644 (file)
@@ -147,6 +147,10 @@ QString MSInterface::settingsGroup()const
 {
        return "profsettings/"+profileid;
 }
+QString MSInterface::configSettingsGroup()const
+{
+       return "profiles/"+profileid;
+}
 
 QString MSInterface::repoPart()
 {
index db18893..6dc7bf0 100644 (file)
@@ -55,8 +55,10 @@ class MSInterface:public MInterface
                
                /**returns the directory where to store data retrieved from the server*/
                QString dataDir()const;
-               /**returns the group in which to find settings in QSettings*/
+               /**returns the group in which to find settings in QSettings, this group can be used by any class that accesses the profile*/
                QString settingsGroup()const;
+               /**returns the group where central profile settings are stored, this group is read-only for anything but the configuration dialog*/
+               QString configSettingsGroup()const;
                
                /**checks the server for compatibility*/
                bool checkServer();
index f9ac0c5..d5a4f04 100644 (file)
@@ -159,6 +159,15 @@ MOverview::MOverview(QString pk)
        if(!req->hasRight(req->RGetOrderList)){
                tab->setTabEnabled(tab->indexOf(ordertab),false);
        }
+       
+       //run init script
+       QTimer::singleShot(0,this,SLOT(runStartupScript()));
+}
+
+void MOverview::runStartupScript()
+{
+       MScriptEngine engine(this);
+       engine.evalFile("startup.js");
 }
 
 void MOverview::closeEvent(QCloseEvent*ce)
index 8efba67..64f8394 100644 (file)
@@ -55,18 +55,33 @@ class MOverview:public QMainWindow
                /**try to log in again*/
                void relogin();
                
+               /**generic check which tab is active*/
+               void tabChanged(int);
+               
+               /**set refresh timeout*/
+               void setRefresh();
+               
+               /**web request settings dialog; shows the dialog per default, just copies settings from registry to webrequest object if false*/
+               void webSettings(bool dlg=true);
+               
                /**set my own password*/
                void setMyPassword();
                
+               /**display property settings*/
+               void displaySettings();
+               /**settings for backup*/
+               void backupSettings();
+               
+               ///\internal run init scripts
+               void runStartupScript();
+               
+       public slots:
                /**manage customers*/
                void customerMgmt();
                
                /**edit shipping options*/
                void editShipping();
                
-               /**generic check which tab is active*/
-               void tabChanged(int);
-               
                /**return a ticket or voucher*/
                void ticketReturn();
                /**deduct some money from a voucher (to pay outside the system)*/
@@ -76,21 +91,10 @@ class MOverview:public QMainWindow
                
                /**refresh data that we can refresh*/
                void refreshData();
-               /**set refresh timeout*/
-               void setRefresh();
-               
-               /**web request settings dialog; shows the dialog per default, just copies settings from registry to webrequest object if false*/
-               void webSettings(bool dlg=true);
-               
-               /**display property settings*/
-               void displaySettings();
                
                /**do a backup now*/
                void doBackup();
                
-               /**settings for backup*/
-               void backupSettings();
-               
                /**switch to the cart tab*/
                void switchToCartTab();
                
diff --git a/src/script/init.js b/src/script/init.js
new file mode 100644 (file)
index 0000000..2b17c6a
--- /dev/null
@@ -0,0 +1,3 @@
+//initialize environment
+importExtension("qt.core");
+importExtension("qt.gui");
index 91b2e31..a3d4d83 100644 (file)
 #include "jsengine.h"
 #include "overview.h"
 #include "msinterface.h"
+#include "main.h"
+#include "templates.h"
 
 #include <QAction>
+#include <QDebug>
+#include <QDir>
+#include <QFileInfo>
 #include <QScriptEngineDebugger>
 #include <QSettings>
+#include <QUnZip>
+
+static QScriptValue importExtension(QScriptContext *context, QScriptEngine *engine)
+{
+       return engine->importExtension(context->argument(0).toString());
+}
+
+static QScriptValue evalFile(QScriptContext *context, QScriptEngine *engine_)
+{
+       MScriptEngine*engine=qobject_cast<MScriptEngine*>(engine_);
+       if(engine==0)
+               return context->throwError("Oops: Cannot use this engine.");
+       return engine->evalFile(context->argument(0).toString());
+}
+
+QStringList MScriptEngine::m_basepath;
 
 MScriptEngine::MScriptEngine(MOverview* par)
        :QScriptEngine(par)
 {
+       //register main window
        addObject("MainWindow",par);
+       //init wob interface
        req->initScriptEngine(this);
+       //utility functions
+        globalObject().setProperty("importExtension", newFunction(::importExtension));
+        globalObject().setProperty("evalFile", newFunction(::evalFile));
+       //initialize script sources
+       if(m_basepath.size()<1)initScriptPath();
+       //debugger anybody?
        int dm=debugMode();
        if(dm>0){
                QScriptEngineDebugger* deb=new QScriptEngineDebugger(this);
@@ -30,6 +59,8 @@ MScriptEngine::MScriptEngine(MOverview* par)
                if(dm>1)
                        deb->action(QScriptEngineDebugger::InterruptAction)->trigger();
        }
+       //load init script
+       evalFile("init.js");
 }
 void MScriptEngine::addObject(QString name, QObject* object)
 {
@@ -52,11 +83,127 @@ QStringList MScriptEngine::debugModes()
 
 int MScriptEngine::debugMode()
 {
-       return QSettings().value("profiles/"+req->profileId()+"/JSdebugMode",0).toInt();
+       return QSettings().value(req->settingsGroup()+"/JSdebugMode",0).toInt();
 }
 
 void MScriptEngine::setDebugMode(int v)
 {
        if(v>=0 && v<debugModes().size())
-               QSettings().setValue("profiles/"+req->profileId()+"/JSdebugMode",v);
+               QSettings().setValue(req->settingsGroup()+"/JSdebugMode",v);
+}
+
+static inline bool normalizeFile(QString &fn)
+{
+       QStringList fnl=fn.replace("\\","/").split("/",QString::SkipEmptyParts);
+       QRegExp allow("[a-zA-Z0-9\\._]+");
+       QStringList fnt;
+       for(int i=0;i<fnl.size();i++){
+               if(fnl[i]==".")continue;
+               if(fnl[i]==".."){
+                       if(fnt.size()==0)return false;
+                       fnt.takeLast();
+                       continue;
+               }
+               if(!allow.exactMatch(fnl[i]))return false;
+               fnt<<fnl[i];
+       }
+       fn.clear();
+       for(int i=0;i<fnt.size();i++){
+               if(i)fn+="/";
+               fn+=fnt[i];
+       }
+       return true;
+}
+
+QScriptValue MScriptEngine::evalFile(QString fn)
+{
+       QScriptContext*context=currentContext();
+       //normalize file name
+       if(!normalizeFile(fn)){
+               return context->throwError("Unable to normalize file name or illegal path component.");
+       }
+       //find file
+       for(int i=0;i<m_basepath.size();i++){
+               QString fn2=m_basepath[i]+"/"+fn;
+               QFileInfo fi(fn2);
+               if(fi.exists()&&fi.isFile()&&fi.isReadable()){
+                       QFile fd(fn2);
+                       fd.open(QIODevice::ReadOnly);
+                       QString prg=QString::fromLocal8Bit(fd.readAll());
+                       fd.close();
+                       return evaluate(prg,fn2);
+               }
+       }
+       //nothing found
+       return context->throwError("Unable to find this script.");
+}
+
+static inline void clearDir(QString dn)
+{
+       QDir dir(dn);
+       if(!dir.exists())return;
+       QFileInfoList ifl=dir.entryInfoList(QDir::AllEntries|QDir::NoDotAndDotDot);
+       for(int i=0;i<ifl.size();i++){
+               if(ifl[i].isDir()){
+                       clearDir(ifl[i].absoluteFilePath());
+                       dir.rmdir(ifl[i].fileName());
+               }else{
+                       dir.remove(ifl[i].fileName());
+               }
+       }
+}
+
+void MScriptEngine::initScriptPath()
+{
+       QSettings set;
+       //retrieve settings (or defaults)
+       set.beginGroup(req->configSettingsGroup()+"/script");
+       QMultiMap<int,QString>paths;
+       if(set.value("allowbuiltin",true).toBool())
+               paths.insert(set.value("priobuiltin",10).toInt(),":/scripts");
+       if(set.value("allowuser",false).toBool())
+               paths.insert(set.value("priouser",0).toInt(), set.value("userpath",dataDir+"/userscripts").toString());
+       bool allowserver=set.value("allowserver",false).toBool();
+       QString mydir=req->dataDir()+"/scripts";
+       if(allowserver)
+               paths.insert(set.value("prioserver",20).toInt(),mydir);
+       //sort and append to path
+       for(int i=0;i<=100;i++)
+               if(paths.contains(i))
+                       m_basepath<<paths.values(i);
+       //retrieve scripts
+       if(!allowserver)return;
+       MTemplateStore*store=req->templateStore();
+       if(store==0)return;
+       QString fn=store->getTemplate("scripts.zip").cacheFileName();
+       if(fn=="")return;
+       QFile fd(fn);
+       if(!fd.open(QIODevice::ReadOnly))return;
+       QUnZip zip;
+       if(!zip.open(&fd))return;
+       //clear old directory
+       clearDir(mydir);QDir().mkpath(mydir);mydir+="/";
+       if(!zip.gotoFirstFile())return;
+       do{
+               //get file name
+               QString fn;
+               if(!zip.getCurrentFileInfo(fn))break;
+               if(!normalizeFile(fn)){
+                       qDebug()<<"Warning: cannot normalize script file name"<<fn;
+                       continue;
+               }
+               fn=mydir+fn.toLower();
+               //create parent path
+               QDir().mkpath(QFileInfo(fn).dir().path());
+               //create file
+               QFile fdo(fn);
+               if(!fdo.open(QIODevice::WriteOnly|QIODevice::Truncate)){
+                       qDebug()<<"Warning: cannot create file"<<fn;
+                       continue;
+               }
+               qDebug()<<"creating script file"<<fn;
+               zip.getCurrentFile(fdo);
+               fdo.close();
+       }while(zip.gotoNextFile());
+       qDebug()<<"end of scripts.zip";
 }
index 35ce06d..772af77 100644 (file)
 
 class MOverview;
 
+/**MagicSmoke Scripting Engine
+
+This class already wraps all important objects and functions necessary for MagicSmoke in general.*/
 class MScriptEngine:public QScriptEngine
 {
        Q_OBJECT
        public:
+               ///construct the engine with pointer to the main window
                MScriptEngine(MOverview*);
                
+               ///add another object and its meta object
                void addObject(QString name,QObject*object);
+               ///execute a specific file, the engine searches for it
+               QScriptValue evalFile(QString);
                
+               ///returns valid debugger modes - this decides when a debugger opens for a script
                static QStringList debugModes();
+               ///returns the index of the debug mode that is currently active
                static int debugMode();
+               ///sets the index of the debug mode
                static void setDebugMode(int);
+       private:
+               static QStringList m_basepath;
+               ///helper: init m_basepath
+               static void initScriptPath();
 };
 
 #endif
index d7bdab0..d2eddcf 100644 (file)
@@ -4,4 +4,6 @@ SOURCES += \
 HEADERS += \
        script/jsengine.h
 
-INCLUDEPATH += ./script
\ No newline at end of file
+INCLUDEPATH += ./script
+
+RESOURCES += script/scriptfiles.qrc
\ No newline at end of file
diff --git a/src/script/scriptfiles.qrc b/src/script/scriptfiles.qrc
new file mode 100644 (file)
index 0000000..39856ce
--- /dev/null
@@ -0,0 +1,8 @@
+<!DOCTYPE RCC>
+<RCC version="1.0">
+    <qresource>
+        <file alias="scripts/init.js">init.js</file>
+        <file alias="scripts/startup.js">startup.js</file>
+        <file alias="scripts/wizard.js">wizard.js</file>
+    </qresource>
+</RCC>
diff --git a/src/script/startup.js b/src/script/startup.js
new file mode 100644 (file)
index 0000000..117cb33
--- /dev/null
@@ -0,0 +1,2 @@
+//startup code
+mainWindow.wizardMode();
\ No newline at end of file
diff --git a/src/script/wizard.js b/src/script/wizard.js
new file mode 100644 (file)
index 0000000..f1b8329
--- /dev/null
@@ -0,0 +1,83 @@
+//example ticket sale wizard
+function startSale()
+{
+       //main page
+       var ispg=wizard.addMode("Sell a Ticket");
+       var spg=wizard.pageWidget(ispg);
+       var vl;var hl;var p;
+       spg.setLayout(vl=new QVBoxLayout);
+       vl.addWidget(new QLabel("Hallo Welt!"),1,0);
+       vl.addLayout(hl=new QHBoxLayout);
+       hl.addStretch(1);
+       hl.addWidget(p=new QPushButton("Continue>>"),0,0);
+       //customer pages
+       var icpg=wizard.addPage();
+       var incpg=wizard.addPage();
+       var ikcpg=wizard.addPage();
+       p.clicked.connect(function(){wizard.gotoPage(icpg);});
+       //customer fork
+       var cpg=wizard.pageWidget(icpg);
+       cpg.setLayout(vl=new QVBoxLayout);
+       vl.addWidget(new QLabel("Has this customer been here before?"),0,0);
+       vl.addWidget(new QPushButton("Yes, select from list of known customers..."),0,0);
+       vl.addWidget(new QPushButton("No, create new customer..."),0,0);
+       vl.addStretch(1);
+}
+startSale();
+
+//dump built in scripts
+var dumpbtn;
+var dumppath;
+var dumplog;
+function startDump()
+{
+       var idpg=wizard.addMode("Dump built in scripts");
+       var dpg=wizard.pageWidget(idpg);
+       var vl;var p;
+       dpg.setLayout(vl=new QVBoxLayout);
+       vl.addWidget(dumpbtn=new QPushButton("Chose path..."),0,0)
+       dumpbtn.clicked.connect(dumpSelectPath);
+       vl.addWidget(dumppath=new QLineEdit,0,0);
+       vl.addSpacing(20);
+       vl.addWidget(p=new QPushButton("Start Dump"),0,0);
+       p.clicked.connect(dumpDump);
+       vl.addSpacing(20);
+       vl.addWidget(dumplog=new QTextEdit,0,0);
+       vl.addStretch(1);
+}
+function dumpSelectPath()
+{
+       var dp=QFileDialog.getExistingDirectory();
+       if(dp!="")dumppath.setText(dp);
+}
+function dumpDump(path)
+{
+       if(!path){
+               path="";
+               dumplog.setPlainText("Starting dump...");
+       }
+       var dir=new QDir(":/scripts/"+path);
+       var tdir=new QDir(dumppath.text+"/"+path);
+       var fls=dir.entryInfoList(QDir.Filters(QDir.AllEntries|QDir.NoDotAndDotDot), QDir.SortFlags(QDir.NoSort));
+       dumplog.append("going into "+dir.absolutePath());
+       for(var i=0;i<fls.length;i++){
+               var fl=fls[i];
+               if(fl.isDir()){
+                       tdir.mkdir(fl.fileName());
+                       dumpDump(path+"/"+fl.fileName());
+                       dumplog.append("creating dir "+fl.fileName());
+               }else{
+                       QFile.copy(dir.absolutePath()+"/"+fl.fileName(), tdir.absolutePath()+"/"+fl.fileName());
+                       dumplog.append("copying "+fl.fileName());
+               }
+       }
+       dumplog.append("done in "+path);
+}
+startDump();
+
+
+wizard.gotoStart();
+
+//wizard.show();
+
+//debugger
\ No newline at end of file
index d58f243..41271f4 100644 (file)
@@ -317,7 +317,7 @@ static QStringList tempBaseNames;
 QStringList MTemplate::legalBaseNames()
 {
        if(tempBaseNames.size()==0){
-               tempBaseNames<<"ticket"<<"voucher"<<"bill"<<"eventsummary";
+               tempBaseNames<<"ticket"<<"voucher"<<"bill"<<"eventsummary"<<"scripts";
        }
        return tempBaseNames;
 }
@@ -329,6 +329,8 @@ MTemplate::Types MTemplate::legalTypes(QString bn)
                return LabelTemplate;
        if(bn=="bill" || bn=="eventsummary")
                return OdfTemplate;
+       if(bn=="scripts")
+               return ZipTemplate;
        return UnknownTemplate;
 }
 
@@ -339,5 +341,7 @@ QStringList MTemplate::legalSuffixes(QString bn)
                return QStringList()<<"xtt";
        if(bn=="bill" || bn=="eventsummary")
                return QStringList()<<"odtt"<<"odst"<<"odpt"<<"odgt"<<"odbt";
+       if(bn=="scripts")
+               return QStringList()<<"zip";
        return QStringList();
 }
index 6fe0d96..b6b52ee 100644 (file)
@@ -75,7 +75,9 @@ class MTemplate
                        /**ODF template*/
                        OdfTemplate=0xff,
                        /**Label template*/
-                       LabelTemplate=0x100
+                       LabelTemplate=0x100,
+                       /**Script-Zip template*/
+                       ZipTemplate=0x200
                };
                Q_DECLARE_FLAGS(Types,Type)