$$PWD/sclock.h \
$$PWD/formula.h \
$$PWD/lambda.h \
+ $$PWD/vlambda.h \
$$PWD/msengine.h \
$$PWD/dommodel.h
$$PWD/waitcursor.cpp \
$$PWD/sclock.cpp \
$$PWD/formula.cpp \
+ $$PWD/vlambda.cpp \
$$PWD/msengine.cpp \
$$PWD/dommodel.cpp
--- /dev/null
+//
+// C++ Interface: misc
+//
+// Description: miscellaneous helper functions
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2012
+//
+// Copyright: See README/COPYING.GPL files that come with this distribution
+//
+//
+
+#include "vlambda.h"
+#include <QDebug>
+
+using namespace std;
+using namespace MVLambdaNS;
+
+//static
+void MVLambdaBase::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
+{
+ if (_c == QMetaObject::InvokeMetaMethod) {
+ //Q_ASSERT(staticMetaObject.cast(_o));//there is no static meta-object
+ MVLambdaBase *_t = static_cast<MVLambdaBase *>(_o);
+ if(_id== 0 && _t != nullptr) _t->do_call(_a);
+ }
+}
+
+
+//static
+const QMetaObjectExtraData MVLambdaBase::staticMetaObjectExtraData = {
+ 0, MVLambdaBase::qt_static_metacall
+};
+
+
+MVLambdaBase::MVLambdaBase(int cnt,QByteArray rt, QByteArray cn, QObject* parent)
+:QObject(parent),m_count(cnt),m_callparm(cn),m_callret(rt),
+qt_meta_data({ // content:
+ 6, // revision
+ 0, // classname
+ 0, 0, // classinfo
+ 1, 14, // methods (14 is start of method info)
+ 0, 0, // properties
+ 0, 0, // enums/sets
+ 0, 0, // constructors
+ 0, // flags
+ 0, // signalCount
+
+ // slots: signature, parameters, type, tag, flags
+ 10, 8, 8, 8, 0x0a,
+ 0 // eod
+})
+{
+ qDebug()<<"instantiated "<<QString("%2 call(%1)").arg(cn.data()).arg(rt.data());
+ //init string data and meta data array
+ string_metadata=QByteArray("MVLambda\0\0call(",15)+cn+QByteArray(")\0",2);
+ qt_meta_data[15]=string_metadata.size();
+ for(int i=1;i<m_count;i++)string_metadata+=",";//params have no name
+ string_metadata.append(char(0));
+ qt_meta_data[16]=string_metadata.size();
+ string_metadata+=rt;
+ string_metadata.append(char(0));
+ // !!!!!!!
+ // after this line string_metadata must not be changed
+ // !!!!!!!
+ //register meta object
+ meta_object=QMetaObject({{&QObject::staticMetaObject, string_metadata.data(),
+ qt_meta_data, &MVLambdaBase::staticMetaObjectExtraData}});
+}
+
+void* MVLambdaNS::MVLambdaBase::qt_metacast(const char* _clname)
+{
+ if (!_clname) return 0;
+ if (!strcmp(_clname, "MVLambda"))
+ return static_cast<void*>(this);
+ return QObject::qt_metacast(_clname);
+}
+
+int MVLambdaBase::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+ _id = QObject::qt_metacall(_c, _id, _a);
+ if (_id < 0)
+ return _id;
+ if (_c == QMetaObject::InvokeMetaMethod) {
+ if (_id < 1)
+ do_call(_a);
+ _id -= 1;
+ }
+ return _id;
+}
--- /dev/null
+//
+// C++ Interface: variadic lambda class
+//
+// Description: a lambda to slot wrapper that can use arbitrary slot signatures
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2012
+//
+// Copyright: See README/COPYING.GPL files that come with this distribution
+//
+//
+
+#ifndef MAGICSMOKE_VLAMBDA_H
+#define MAGICSMOKE_VLAMBDA_H
+
+#include <functional>
+#include <QObject>
+#include "vlambda_p.h"
+
+/// Namespace for functions and sub-templates that are internal to the variadic lambda wrapper MVLambda.
+namespace MVLambdaNS {
+/// \internal workarout for missing "final" keyword in GCC 4.6
+//TODO: remove this as soon as "final" is available
+class MVLFinal{protected:MVLFinal(){}};
+
+/// \internal base class for variadic lambda wrapper
+class MVLambdaBase:public QObject
+{
+ const int m_count;
+ const QByteArray m_callparm,m_callret;
+ uint qt_meta_data[20];
+ QByteArray string_metadata;
+ QMetaObject meta_object;
+ virtual void do_call(void**)=0;
+ static void qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a);
+ static const QMetaObjectExtraData staticMetaObjectExtraData;
+ protected:
+// MVLambdaBase(const MVLambdaBase&m):QObject(parent()),m_callname(m.m_callname){}
+ MVLambdaBase ( int c,QByteArray rt, QByteArray cn, QObject* parent);
+
+ const QByteArray callParams()const{return m_callparm;}
+ const QByteArray callReturn()const{return m_callret;}
+
+ /*static void qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
+ {
+ if (_c == QMetaObject::InvokeMetaMethod) {
+ Q_ASSERT(staticMetaObject.cast(_o));
+ MVLambda<Ret(Args...)> *_t = static_cast<MVLambda<Ret(Args...)> *>(_o);
+ if (_id==0)MVLambdaNS::Call<Args...>(_a,_t->call();
+ }
+ Q_UNUSED(_a);
+ }*/
+ public:
+ const QMetaObject *metaObject() const{return &meta_object;}
+ void *qt_metacast(const char *_clname);
+ int qt_metacall(QMetaObject::Call _c, int _id, void **_a);
+
+};
+
+//end of namespace
+};
+
+template<typename _Signature>class MVLambda;
+
+///wrapper for simple lambda expression, so it can be used with signals
+template<typename Ret,typename...Args>
+class MVLambda<Ret(Args...)> :public MVLambdaNS::MVLambdaBase,virtual private MVLambdaNS::MVLFinal
+{
+ private:
+ std::function<Ret(Args...)>m_ptr;
+ /// \internal interface for the Qt meta object system
+ virtual void do_call(void**a){
+ MVLambdaNS::Call<Ret(Args...)>(a,[&](Args...args)->Ret{return this->call(args...);});
+ }
+ public:
+ ///instantiates the lambda object, e.g.
+ /// \code
+ ///int x=55;
+ ///QPushButton button("Push me!");
+ ///MLambda lambda([&x](){qDebug()<<"x is"<<x;});
+ ///connect(&button,SIGNAL(clicked()),&lambda,SLOT(call()));
+ ///button.show();
+ /// \endcode
+ ///the above code will show the value of the variable 'x' whenever the user clicks the button
+ MVLambda(std::function<Ret(Args...)>l,QObject* parent = 0)
+ :MVLambdaBase(MVLambdaNS::Count<Args...>::count, MVLambdaNS::TypeStr<Ret>::get(), MVLambdaNS::TypeStr<Args...>::get(), parent), m_ptr(l){}
+
+ ///generic slot that transparently executes the lambda expression
+ Ret call(Args...args){if(m_ptr)return m_ptr(args...);else return Ret();}
+};
+
+#endif
--- /dev/null
+//
+// C++ Interface: variadic lambda
+//
+// Description: helpers for variadic lambda
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2012
+//
+// Copyright: See README/COPYING.GPL files that come with this distribution
+//
+//
+
+#ifndef MAGICSMOKE_VLAMBDA_P_H
+#define MAGICSMOKE_VLAMBDA_P_H
+
+#include <functional>
+#include <QObject>
+#include <QVariant>
+#include <QByteArray>
+
+namespace MVLambdaNS {
+/// \internal helper for lambda template: determines the string representation of the functions type signature
+template<typename...A>class TypeStr;
+
+template <typename F,typename...Args>
+class TypeStr<F,Args...>{
+public:
+static const QByteArray get()
+{return TypeStr<F>::get()+","+TypeStr<Args...>::get();}
+};
+
+template <typename T>
+class TypeStr<T>{
+public: static const QByteArray get()
+{T t;return QVariant::fromValue(t).typeName();}
+};
+
+template <typename T>
+class TypeStr<T&>{
+public: static const QByteArray get()
+{T t;return QByteArray(QVariant::fromValue(t).typeName())+"&";}
+};
+template <typename T>
+class TypeStr<const T&>{
+public: static const QByteArray get()
+{T t;return QByteArray("const ")+QVariant::fromValue(t).typeName()+"&";}
+};
+template <typename T>
+class TypeStr<T*>{
+public: static const QByteArray get()
+{T t;return QByteArray(QVariant::fromValue(t).typeName())+"*";}
+};
+template <typename T>
+class TypeStr<const T*>{
+public: static const QByteArray get()
+{T t;return QByteArray("const ")+QVariant::fromValue(t).typeName()+"*";}
+};
+
+template<>
+class TypeStr<>{
+public: static const QByteArray get()
+{return QByteArray();}
+};
+
+template<>
+class TypeStr<void>{
+public: static const QByteArray get()
+{return QByteArray();}
+};
+
+
+
+//////////////////////////////////////////////////////
+template<typename ...Args>class Count;
+
+template<typename T,typename ...Args>
+class Count<T,Args...>{public: static const int count=Count<Args...>::count + 1;};
+
+template<>
+class Count<>{public: static const int count=0;};
+///////////////////////////////////////////////////////
+template<typename Sig>class Call;
+
+template<typename R,typename T,typename...Args>
+class Call<R(T,Args...)>
+{
+ public:
+ Call(void**vl,std::function<R(T,Args...)>cb)
+ {
+ R r;
+ Call<void(Args...)>(vl+1,[&](Args...args){r=cb(*reinterpret_cast<T*>(vl[0]),args...);});
+ if(vl[0])*reinterpret_cast<R*>(vl[0])=r;
+ }
+};
+template<typename R,typename T>
+class Call<R(T)>
+{
+ public:
+ Call(void**vl,std::function<R(T)>cb)
+ {
+ R r=cb(*reinterpret_cast<T*>(vl[1]));
+ if(vl[0])*reinterpret_cast<R*>(vl[0])=r;
+ }
+};
+template<typename R>
+class Call<R()>
+{
+ public:
+ Call(void**vl,std::function<R()>cb)
+ {
+ R r=cb();
+ if(vl[0])*reinterpret_cast<R*>(vl[0])=r;
+ }
+};
+
+
+template<typename T,typename...Args>
+class Call<void(T,Args...)>
+{
+ public:
+ Call(void**vl,std::function<void(T,Args...)>cb)
+ {
+ Call<void(Args...)>(vl+1,[&](Args...args){cb(*reinterpret_cast<T*>(vl[1]),args...);});
+ }
+};
+template<typename T>
+class Call<void(T)>
+{
+ public:
+ Call(void**vl,std::function<void(T)>cb)
+ {
+ cb(*reinterpret_cast<T*>(vl[1]));
+ }
+};
+template<>
+class Call<void()>
+{
+ public:
+ Call(void**,std::function<void()>cb)
+ {
+ cb();
+ }
+};
+
+//end of namespace
+};
+
+#endif
#include "misc.h"
#include "odtrender.h"
#include "dommodel.h"
+#include "lambda.h"
+#include "vlambda.h"
#include "MOTicket"
#include "MOVoucher"
QTableView*mTagAttrs;
QStandardItemModel*mTagAttrModel;
//tree menu
- QAction*maAddCalc,*maAddCond,*maAddComment,*maAddElse,*maAddLoop;
- QAction*maInsCalc,*maInsComment,*maUnwrap,*maDelItem;
+ QAction*maAddIntoCalc,*maWrapInCond,*maAddIntoComment,*maInsBehindElse,*maWrapInLoop;
+ QAction*maInsBehindCalc,*maInsBehindComment,*maUnwrap,*maDelItem;
void setActions(const QList<QAction*>&);
//current node
QModelIndex mCurIndex;
m->addSeparator();
m->addAction(tr("&Close"),this,SLOT(close()));
- m=mb->addMenu(tr("&Edit"));
- d->maAddCalc=m->addAction(tr("Insert &Calculation into current"));
- d->maInsCalc=m->addAction(tr("Insert Calculation behind current"));
- d->maAddCond=m->addAction(tr("&Wrap in Condition"));
- d->maAddLoop=m->addAction(tr("Wrap in &Loop"));
- d->maAddElse=m->addAction(tr("Insert &Else behind current"));
- d->maAddComment=m->addAction(tr("Insert Comment into current"));
- d->maInsComment=m->addAction(tr("Insert Comment behind current"));
+ QMenu*medit=m=mb->addMenu(tr("&Edit"));
+ d->maAddIntoCalc=m->addAction(tr("Insert &Calculation into current"));
+ d->maInsBehindCalc=m->addAction(tr("Insert Calculation behind current"));
+ d->maWrapInCond=m->addAction(tr("&Wrap in Condition"));
+ d->maWrapInLoop=m->addAction(tr("Wrap in &Loop"));
+ d->maInsBehindElse=m->addAction(tr("Insert &Else behind current"));
+ d->maAddIntoComment=m->addAction(tr("Insert Comment into current"));
+ d->maInsBehindComment=m->addAction(tr("Insert Comment behind current"));
m->addSeparator();
d->maUnwrap=m->addAction(tr("Unwrap Loop/Condition"));
d->maDelItem=m->addAction(tr("&Remove Item"),this,SLOT(delItem()));
d->mDomTree->header()->setResizeMode(0,QHeaderView::ResizeToContents);
d->mDomTree->header()->setStretchLastSection(false);
connect(d->mDomTree->selectionModel(),SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this,SLOT(selectionChange()));
+ MVLambda<void(QPoint)> *ml;
+ ml=new MVLambda<void(QPoint)>([=](QPoint p){
+ QModelIndex idx=d->mDomTree->indexAt(p);
+ if(idx.isValid())
+ medit->popup(d->mDomTree->mapToGlobal(p));
+ },this);
+ connect(d->mDomTree,SIGNAL(customContextMenuRequested(QPoint)),ml,SLOT(call(QPoint)));
+ d->mDomTree->setContextMenuPolicy(Qt::CustomContextMenu);
//the editors...
QStackedWidget*stack;
if(idxl.size()!=1){
emit switchStack(d->st_none);
if(idxl.size()>1)
- d->setActions(QList<QAction*>()<<d->maAddCond<<d->maAddLoop);
+ d->setActions(QList<QAction*>()<<d->maWrapInCond<<d->maWrapInLoop);
return;
}
//check element type
if(d->mCurNode.isComment()){
emit switchStack(d->st_comment);
d->mComment->setText(d->mCurNode.nodeValue());
- d->setActions(QList<QAction*>()<<d->maAddCalc<<d->maInsComment<<d->maDelItem<<(allowElse?d->maAddElse:nullptr));
+ d->setActions(QList<QAction*>()<<d->maInsBehindCalc<<d->maInsBehindComment<<d->maDelItem<<(allowElse?d->maInsBehindElse:nullptr));
return;
}
//is it normal text?
if(d->mCurNode.isCharacterData()){
emit switchStack(d->st_text);
d->mText->setText(d->mCurNode.nodeValue());
- d->setActions(QList<QAction*>()<<d->maAddCalc<<d->maAddComment<<d->maAddCond<<d->maAddLoop<<d->maDelItem<<(allowElse?d->maAddElse:nullptr));
+ d->setActions(QList<QAction*>()<<d->maInsBehindCalc<<d->maInsBehindComment<<d->maWrapInCond<<d->maWrapInLoop<<d->maDelItem<<(allowElse?d->maInsBehindElse:nullptr));
return;
}
//henceforth we are only interested in elements.
if(!d->mCurNode.isElement()){
emit switchStack(d->st_none);
- d->setActions(QList<QAction*>()<<d->maAddCalc<<d->maAddComment<<d->maDelItem<<(allowElse?d->maAddElse:nullptr));
+ d->setActions(QList<QAction*>()<<d->maInsBehindCalc<<d->maInsBehindComment<<d->maDelItem<<(allowElse?d->maInsBehindElse:nullptr));
return;
}
//is it special?
if(nn[1]=="loop"){
emit switchStack(d->st_loop);
d->mLoopVar->setText(el.attribute("variable"));
+ d->setActions(QList<QAction*>()<<d->maInsBehindCalc<<d->maInsBehindComment<<d->maAddIntoCalc<<d->maAddIntoComment<<d->maWrapInCond<<d->maWrapInLoop<<d->maUnwrap<<d->maDelItem<<(allowElse?d->maInsBehindElse:nullptr));
#warning implement correct actions for special tags
return;
}
if(nn[1]=="calculate"){
emit switchStack(d->st_calc);
d->mCalcExpr->setText(el.attribute("exec"));
+ d->setActions(QList<QAction*>()<<d->maInsBehindCalc<<d->maInsBehindComment<<d->maAddIntoCalc<<d->maAddIntoComment<<d->maWrapInCond<<d->maWrapInLoop<<d->maDelItem<<(allowElse?d->maInsBehindElse:nullptr));
return;
}
if(nn[1]=="if"){
emit switchStack(d->st_cond);
d->mCondExpr->setText(el.attribute("select"));
+ d->setActions(QList<QAction*>()<<d->maInsBehindCalc<<d->maInsBehindComment<<d->maAddIntoCalc<<d->maAddIntoComment<<d->maWrapInCond<<d->maWrapInLoop<<d->maUnwrap<<d->maDelItem<<(allowElse?d->maInsBehindElse:nullptr));
return;
}
- //else
- emit switchStack(d->st_none);
- return;
- }else{
- emit switchStack(d->st_tag);
- #warning implement correct actions for normal tags
- displayTag();
- return;
+ //else: fall through to normal tags
}
+ //else: other tags
+ d->setActions(QList<QAction*>()<<d->maInsBehindCalc<<d->maInsBehindComment<<d->maAddIntoCalc<<d->maAddIntoComment<<d->maWrapInCond<<d->maWrapInLoop<<d->maDelItem<<(allowElse?d->maInsBehindElse:nullptr));
+ emit switchStack(d->st_tag);
+ displayTag();
}
void MOdfEditor::displayTag()
void MOdfEditor::Private::setActions(const QList< QAction* >& act)
{
- maAddCalc->setEnabled(act.contains(maAddCalc));
- maAddCond->setEnabled(act.contains(maAddCond));
- maAddComment->setEnabled(act.contains(maAddComment));
- maAddElse->setEnabled(act.contains(maAddElse));
- maAddLoop->setEnabled(act.contains(maAddLoop));
- maInsCalc->setEnabled(act.contains(maInsCalc));
- maInsComment->setEnabled(act.contains(maInsComment));
+ maAddIntoCalc->setEnabled(act.contains( maAddIntoCalc));
+ maWrapInCond->setEnabled(act.contains( maWrapInCond));
+ maAddIntoComment->setEnabled(act.contains( maAddIntoComment));
+ maInsBehindElse->setEnabled(act.contains( maInsBehindElse));
+ maWrapInLoop->setEnabled(act.contains( maWrapInLoop));
+ maInsBehindCalc->setEnabled(act.contains( maInsBehindCalc));
+ maInsBehindComment->setEnabled(act.contains( maInsBehindComment));
maUnwrap->setEnabled(act.contains(maUnwrap));
maDelItem->setEnabled(act.contains(maDelItem));
}