Commit df5cd3d6 authored by Thomas Hartmann's avatar Thomas Hartmann Committed by hjk

QmlDesigner: de-templatize

Since the templates add unnecessary complexity, we use
function pointers instead.

Change-Id: I023b3907ad8826c25d985aba0fed1d5a69265b15
Reviewed-by: default avatarhjk <qthjk@ovi.com>
parent 23a56bb0
......@@ -224,45 +224,39 @@ QmlModelView *DesignerActionManager::view()
return instance()->m_view.data();
}
template <class ACTION,
class ENABLED = SelectionContextFunctors::Always,
class VISIBILITY = SelectionContextFunctors::Always>
class VisiblityModelNodeActionFactory : public ModelNodeActionFactory<ACTION, ENABLED, VISIBILITY>
class VisiblityModelNodeAction : public ModelNodeAction
{
public:
VisiblityModelNodeActionFactory(const QString &description, const QString &category, int priority) :
ModelNodeActionFactory<ACTION, ENABLED, VISIBILITY>(description, category, priority)
VisiblityModelNodeAction(const QString &description, const QString &category, int priority,
ModelNodeOperations::SelectionAction action,
SelectionContextFunction enabled = &SelectionContextFunctors::always,
SelectionContextFunction visibility = &SelectionContextFunctors::always) :
ModelNodeAction(description, category, priority, action, enabled, visibility)
{}
virtual void updateContext()
{
this->m_action->setSelectionContext(this->m_selectionContext);
if (this->m_selectionContext.isValid()) {
this->m_action->setEnabled(this->isEnabled(this->m_selectionContext));
this->m_action->setVisible(this->isVisible(this->m_selectionContext));
m_action->setSelectionContext(m_selectionContext);
if (m_selectionContext.isValid()) {
m_action->setEnabled(isEnabled(m_selectionContext));
m_action->setVisible(isVisible(m_selectionContext));
this->m_action->setCheckable(true);
QmlItemNode itemNode = QmlItemNode(this->m_selectionContext.currentSingleSelectedNode());
m_action->setCheckable(true);
QmlItemNode itemNode = QmlItemNode(m_selectionContext.currentSingleSelectedNode());
if (itemNode.isValid())
this->m_action->setChecked(itemNode.instanceValue("visible").toBool());
m_action->setChecked(itemNode.instanceValue("visible").toBool());
else
this->m_action->setEnabled(false);
m_action->setEnabled(false);
}
}
};
template <void (*T)(const SelectionContext &)>
struct Functor {
void operator() (const SelectionContext &selectionState) { T(selectionState); }
};
class SelectionModelNodeAction : public MenuDesignerAction<SelectionContextFunctors::Always, SelectionContextFunctors::SelectionEnabled>
class SelectionModelNodeAction : public MenuDesignerAction
{
typedef ActionTemplate<Functor<ModelNodeOperations::select> > SelectionAction;
typedef QSharedPointer<SelectionAction> SelectionActionPtr;
public:
SelectionModelNodeAction(const QString &displayName, const QString &menuId, int priority) :
MenuDesignerAction<SelectionContextFunctors::Always, SelectionContextFunctors::SelectionEnabled>(displayName, menuId, priority)
MenuDesignerAction(displayName, menuId, priority,
&SelectionContextFunctors::always, &SelectionContextFunctors::selectionEnabled)
{}
virtual void updateContext()
......@@ -277,7 +271,7 @@ public:
if (m_action->isEnabled()) {
ModelNode parentNode;
if (m_selectionContext.singleSelected() && !m_selectionContext.currentSingleSelectedNode().isRootNode()) {
SelectionAction* selectionAction = new SelectionAction(QString());
ActionTemplate *selectionAction = new ActionTemplate(QString(), &ModelNodeOperations::select);
selectionAction->setParent(m_menu.data());
parentNode = m_selectionContext.currentSingleSelectedNode().parentProperty().parentModelNode();
......@@ -294,8 +288,8 @@ public:
&& contains(node, m_selectionContext.scenePos())
&& !node.isRootNode()) {
m_selectionContext.setTargetNode(node);
SelectionAction* selectionAction =
new SelectionAction(QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select: %1")).arg(captionForModelNode(node)));
QString what = QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select: %1")).arg(captionForModelNode(node));
ActionTemplate *selectionAction = new ActionTemplate(what, &ModelNodeOperations::select);
selectionAction->setSelectionContext(m_selectionContext);
m_menu->addAction(selectionAction);
......@@ -311,68 +305,105 @@ char zProperty[] = "z";
char widthProperty[] = "width";
char heightProperty[] = "height";
void DesignerActionManager::createDefaultDesignerActions()
using namespace SelectionContextFunctors;
bool multiSelection(const SelectionContext &context)
{
typedef Functor<ModelNodeOperations::resetPosition> resetPositionFunctor;
return !singleSelection(context);
}
bool singleSelectionAndInBaseState(const SelectionContext &context)
{
return singleSelection(context) && inBaseState(context);
}
bool multiSelectionAndInBaseState(const SelectionContext &context)
{
return multiSelection(context) && inBaseState(context);
}
bool selectionHasProperty1or2(const SelectionContext &context, const char *x, const char *y)
{
return selectionHasProperty(context, x) || selectionHasProperty(context, y);
}
bool selectionHasSameParentAndInBaseState(const SelectionContext &context)
{
return selectionHasSameParent(context) && inBaseState(context);
}
bool selectionCanBeLayouted(const SelectionContext &context)
{
return selectionHasSameParentAndInBaseState(context) && inBaseState(context);
}
bool selectionNotEmptyAndHasZProperty(const SelectionContext &context)
{
return selectionNotEmpty(context) && selectionHasProperty(context, zProperty);
}
bool selectionNotEmptyAndHasWidthOrHeightProperty(const SelectionContext &context)
{
return selectionNotEmpty(context)
&& selectionHasProperty1or2(context, widthProperty, heightProperty);
}
bool selectionNotEmptyAndHasXorYProperty(const SelectionContext &context)
{
return selectionNotEmpty(context)
&& selectionHasProperty1or2(context, xProperty, yProperty);
}
void DesignerActionManager::createDefaultDesignerActions()
{
using namespace SelectionContextFunctors;
using namespace ComponentCoreConstants;
typedef Not<SingleSelection> MultiSelection;
typedef And<SingleSelection, InBaseState> SingleSelection_And_InBaseState;
typedef And<MultiSelection, InBaseState> MultiSelection_And_InBaseState;
typedef Or<SelectionHasProperty<xProperty>, SelectionHasProperty<yProperty> >
SelectionHasPropertyX_Or_SelectionHasPropertyY;
typedef Or<SelectionHasProperty<widthProperty>, SelectionHasProperty<heightProperty> >
SelectionHasPropertyWidth_Or_SelectionHasPropertyHeight;
typedef And<SelectionHasSameParent, InBaseState> SelectionHasSameParent_And_InBaseState;
typedef And<SelectionHasSameParent_And_InBaseState, MultiSelection> SelectionCanBeLayouted;
using namespace ModelNodeOperations;
addDesignerAction(new SelectionModelNodeAction(selectionCategoryDisplayName, selectionCategory, prioritySelectionCategory));
addDesignerAction(new MenuDesignerAction<Always>(stackCategoryDisplayName, stackCategory, priorityStackCategory));
addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::toFront>, SingleSelection>
(toFrontDisplayName, stackCategory, 200));
addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::toBack>, SingleSelection>
(toBackDisplayName, stackCategory, 180));
addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::raise>, SelectionNotEmpty>
(raiseDisplayName, stackCategory, 160));
addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::lower>, SelectionNotEmpty>
(lowerDisplayName, stackCategory, 140));
addDesignerAction(new SeperatorDesignerAction<>(stackCategory, 120));
addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::resetZ>,
And<SelectionNotEmpty, SelectionHasProperty<zProperty> > >
(resetZDisplayName, stackCategory, 100));
addDesignerAction(new MenuDesignerAction<SelectionNotEmpty>(editCategoryDisplayName, editCategory, priorityEditCategory));
addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::resetPosition>,
And<SelectionNotEmpty, SelectionHasPropertyWidth_Or_SelectionHasPropertyHeight> >
(resetPositionDisplayName, editCategory, 200));
addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::resetSize>,
And<SelectionNotEmpty, SelectionHasPropertyX_Or_SelectionHasPropertyY> >
(resetSizeDisplayName, editCategory, 180));
addDesignerAction(new VisiblityModelNodeActionFactory<Functor<ModelNodeOperations::setVisible>, SingleSelectedItem>
(visibilityDisplayName, editCategory, 160));
addDesignerAction(new MenuDesignerAction<SingleSelection_And_InBaseState>(anchorsCategoryDisplayName, anchorsCategory, priorityAnchorsCategory));
addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::anchorsFill>, SingleSelectionItemNotAnchored>
(anchorsFillDisplayName, anchorsCategory, 200));
addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::anchorsReset>,
SingleSelectionItemIsAnchored>(anchorsResetDisplayName, anchorsCategory, 180));
addDesignerAction(new MenuDesignerAction<MultiSelection_And_InBaseState>(layoutCategoryDisplayName, layoutCategory, priorityLayoutCategory));
addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::layoutRow>, SelectionCanBeLayouted>
(layoutRowDisplayName, layoutCategory, 200));
addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::layoutColumn>, SelectionCanBeLayouted>
(layoutColumnDisplayName, layoutCategory, 180));
addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::layoutColumn>, SelectionCanBeLayouted>
(layoutGridDisplayName, layoutCategory, 160));
addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::layoutFlow>, SelectionCanBeLayouted>
(layoutFlowDisplayName, layoutCategory, 140));
addDesignerAction(new SeperatorDesignerAction<>(rootCategory, priorityTopLevelSeperator));
addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::goIntoComponent>,
SelectionIsComponent>(goIntoComponentDisplayName, rootCategory, priorityGoIntoComponent));
addDesignerAction(new MenuDesignerAction(stackCategoryDisplayName, stackCategory, priorityStackCategory, &always));
addDesignerAction(new ModelNodeAction
(toFrontDisplayName, stackCategory, 200, &toFront, &singleSelection));
addDesignerAction(new ModelNodeAction
(toBackDisplayName, stackCategory, 180, &toBack, &singleSelection));
addDesignerAction(new ModelNodeAction
(raiseDisplayName, stackCategory, 160, &raise, &selectionNotEmpty));
addDesignerAction(new ModelNodeAction
(lowerDisplayName, stackCategory, 140, &lower, &selectionNotEmpty));
addDesignerAction(new SeperatorDesignerAction(stackCategory, 120));
addDesignerAction(new ModelNodeAction
(resetZDisplayName, stackCategory, 100, &resetZ, &selectionNotEmptyAndHasZProperty));
addDesignerAction(new MenuDesignerAction(editCategoryDisplayName, editCategory, priorityEditCategory, &selectionNotEmpty));
addDesignerAction(new ModelNodeAction
(resetPositionDisplayName, editCategory, 200, &resetPosition, &selectionNotEmptyAndHasXorYProperty));
addDesignerAction(new ModelNodeAction
(resetSizeDisplayName, editCategory, 180, &resetSize, &selectionNotEmptyAndHasWidthOrHeightProperty));
addDesignerAction(new VisiblityModelNodeAction
(visibilityDisplayName, editCategory, 160, &setVisible, &singleSelectedItem));
addDesignerAction(new MenuDesignerAction(anchorsCategoryDisplayName, anchorsCategory,
priorityAnchorsCategory, &singleSelectionAndInBaseState));
addDesignerAction(new ModelNodeAction
(anchorsFillDisplayName, anchorsCategory, 200, &anchorsFill, &singleSelectionItemIsNotAnchored));
addDesignerAction(new ModelNodeAction
(anchorsResetDisplayName, anchorsCategory, 180, &anchorsReset, &singleSelectionItemIsAnchored));
addDesignerAction(new MenuDesignerAction(layoutCategoryDisplayName, layoutCategory,
priorityLayoutCategory, &multiSelectionAndInBaseState));
addDesignerAction(new ModelNodeAction
(layoutRowDisplayName, layoutCategory, 200, &layoutRow, &selectionCanBeLayouted));
addDesignerAction(new ModelNodeAction
(layoutColumnDisplayName, layoutCategory, 180, &layoutColumn, &selectionCanBeLayouted));
addDesignerAction(new ModelNodeAction
(layoutGridDisplayName, layoutCategory, 160, &layoutGrid, &selectionCanBeLayouted));
addDesignerAction(new ModelNodeAction
(layoutFlowDisplayName, layoutCategory, 140, &layoutFlow, &selectionCanBeLayouted));
addDesignerAction(new SeperatorDesignerAction(rootCategory, priorityTopLevelSeperator));
addDesignerAction(new ModelNodeAction
(goIntoComponentDisplayName, rootCategory, priorityGoIntoComponent, &goIntoComponent, &selectionIsComponent));
}
DesignerActionManager *DesignerActionManager::instance()
......
......@@ -219,9 +219,10 @@ static inline void openInlineComponent(const ModelNode &node)
//rootModelNode.setAuxiliaryData("height", height);
}
void ComponentUtils::goIntoComponent(const ModelNode &modelNode)
{
namespace ComponentUtils {
void goIntoComponent(const ModelNode &modelNode)
{
if (modelNode.isValid() && modelNodeIsComponent(modelNode)) {
if (isFileComponent(modelNode))
openFileForComponent(modelNode);
......@@ -230,9 +231,12 @@ void ComponentUtils::goIntoComponent(const ModelNode &modelNode)
}
}
} // namespace ComponentUtils
namespace SelectionContextFunctors {
bool SingleSelectionItemIsAnchored::operator() (const SelectionContext &selectionState) {
bool singleSelectionItemIsAnchored(const SelectionContext &selectionState)
{
QmlItemNode itemNode(selectionState.currentSingleSelectedNode());
if (selectionState.isInBaseState() && itemNode.isValid()) {
bool anchored = itemNode.instanceHasAnchors();
......@@ -241,7 +245,8 @@ bool SingleSelectionItemIsAnchored::operator() (const SelectionContext &selectio
return false;
}
bool SingleSelectionItemNotAnchored::operator() (const SelectionContext &selectionState) {
bool singleSelectionItemIsNotAnchored(const SelectionContext &selectionState)
{
QmlItemNode itemNode(selectionState.currentSingleSelectedNode());
if (selectionState.isInBaseState() && itemNode.isValid()) {
bool anchored = itemNode.instanceHasAnchors();
......@@ -250,12 +255,12 @@ bool SingleSelectionItemNotAnchored::operator() (const SelectionContext &selecti
return false;
}
bool SelectionHasSameParent::operator() (const SelectionContext &selectionState)
bool selectionHasSameParent(const SelectionContext &selectionState)
{
return !selectionState.selectedModelNodes().isEmpty() && itemsHaveSameParent(selectionState.selectedModelNodes());
}
bool SelectionIsComponent::operator() (const SelectionContext &selectionState)
bool selectionIsComponent(const SelectionContext &selectionState)
{
return modelNodeIsComponent(selectionState.currentSingleSelectedNode());
}
......
......@@ -31,6 +31,7 @@
#define MODELNODECONTEXTMENU_HELPER_H
#include "modelnodecontextmenu.h"
#include "modelnodeoperations.h"
#include "designeractionmanager.h"
#include <QAction>
......@@ -38,114 +39,70 @@
namespace QmlDesigner {
namespace SelectionContextFunctors {
struct Always {
bool operator() (const SelectionContext &) {
return true;
}
};
struct InBaseState {
bool operator() (const SelectionContext &selectionState) {
return selectionState.isInBaseState();
}
};
struct SingleSelection {
bool operator() (const SelectionContext &selectionState) {
return selectionState.singleSelected();
}
};
typedef bool (*SelectionContextFunction)(const SelectionContext &);
struct SelectionEnabled {
bool operator() (const SelectionContext &selectionState) {
return selectionState.showSelectionTools();
}
};
struct SelectionNotEmpty {
bool operator() (const SelectionContext &selectionState) {
return !selectionState.selectedModelNodes().isEmpty();
}
};
struct SingleSelectionNotRoot {
bool operator() (const SelectionContext &selectionState) {
return selectionState.singleSelected()
&& !selectionState.currentSingleSelectedNode().isRootNode();
}
};
template <class T1, class T2>
struct And {
bool operator() (const SelectionContext &selectionState) {
T1 t1;
T2 t2;
return t1(selectionState) && t2(selectionState);
}
};
namespace SelectionContextFunctors {
template <class T1, class T2>
struct Or {
bool operator() (const SelectionContext &selectionState) {
T1 t1;
T2 t2;
return t1(selectionState) || t2(selectionState);
}
};
inline bool always(const SelectionContext &)
{
return true;
}
template <class T1>
struct Not {
bool operator() (const SelectionContext &selectionState) {
T1 t1;
return !t1(selectionState);
}
};
inline bool inBaseState(const SelectionContext &selectionState)
{
return selectionState.isInBaseState();
}
template <char* PROPERTYNAME>
struct SelectionHasProperty {
bool operator() (const SelectionContext &selectionState) {
foreach (const ModelNode &modelNode, selectionState.selectedModelNodes())
if (modelNode.hasProperty(QLatin1String(PROPERTYNAME)))
return true;
return false;
}
};
inline bool singleSelection(const SelectionContext &selectionState)
{
return selectionState.singleSelected();
}
struct SelectionHasSameParent {
bool operator() (const SelectionContext &selectionState);
};
inline bool selectionEnabled(const SelectionContext &selectionState)
{
return selectionState.showSelectionTools();
}
struct SelectionIsComponent {
bool operator() (const SelectionContext &selectionState);
};
inline bool selectionNotEmpty(const SelectionContext &selectionState)
{
return !selectionState.selectedModelNodes().isEmpty();
}
struct SingleSelectionItemIsAnchored {
bool operator() (const SelectionContext &selectionState);
};
inline bool singleSelectionNotRoot(const SelectionContext &selectionState)
{
return selectionState.singleSelected()
&& !selectionState.currentSingleSelectedNode().isRootNode();
}
struct SingleSelectionItemNotAnchored {
bool operator() (const SelectionContext &selectionState);
};
inline bool selectionHasProperty(const SelectionContext &selectionState, const char *property)
{
foreach (const ModelNode &modelNode, selectionState.selectedModelNodes())
if (modelNode.hasProperty(QLatin1String(property)))
return true;
return false;
}
struct SingleSelectedItem {
bool operator() (const SelectionContext &selectionState) {
QmlItemNode itemNode(selectionState.currentSingleSelectedNode());
return itemNode.isValid();
}
};
inline bool singleSelectedItem(const SelectionContext &selectionState)
{
QmlItemNode itemNode(selectionState.currentSingleSelectedNode());
return itemNode.isValid();
}
} //SelectionStateFunctors
bool selectionHasSameParent(const SelectionContext &selectionState);
bool selectionIsComponent(const SelectionContext &selectionState);
bool selectionIsComponent(const SelectionContext &selectionState);
bool singleSelectionItemIsAnchored(const SelectionContext &selectionState);
bool singleSelectionItemIsNotAnchored(const SelectionContext &selectionState);
} // namespace SelectionStateFunctors
class ComponentUtils {
public:
static void goIntoComponent(const ModelNode &modelNode);
};
class DefaultAction : public QAction {
namespace ComponentUtils {
void goIntoComponent(const ModelNode &modelNode);
}
class DefaultAction : public QAction
{
Q_OBJECT
public:
......@@ -155,7 +112,7 @@ public:
}
public slots: //virtual method instead of slot
virtual void actionTriggered(bool )
virtual void actionTriggered(bool)
{ }
void setSelectionContext(const SelectionContext &selectionContext)
......@@ -167,19 +124,36 @@ protected:
SelectionContext m_selectionContext;
};
class ActionTemplate : public DefaultAction
{
public:
ActionTemplate(const QString &description, ModelNodeOperations::SelectionAction action)
: DefaultAction(description), m_action(action)
{ }
public /*slots*/:
virtual void actionTriggered(bool b)
{
m_selectionContext.setToggled(b);
return m_action(m_selectionContext);
}
ModelNodeOperations::SelectionAction m_action;
};
class DefaultDesignerAction : public AbstractDesignerAction
{
public:
DefaultDesignerAction(const QString &description) : m_action(new DefaultAction(description))
DefaultDesignerAction() : m_action(new DefaultAction(QString()))
{}
DefaultDesignerAction(DefaultAction *action) : m_action(action)
{}
virtual QAction *action() const
{ return m_action; }
QAction *action() const { return m_action; }
virtual void setCurrentContext(const SelectionContext &selectionContext)
void setCurrentContext(const SelectionContext &selectionContext)
{
m_selectionContext = selectionContext;
updateContext();
......@@ -199,41 +173,30 @@ protected:
SelectionContext m_selectionContext;
};
template <class ENABLED = SelectionContextFunctors::Always,
class VISIBILITY = SelectionContextFunctors::Always>
class MenuDesignerAction : public AbstractDesignerAction
{
public:
MenuDesignerAction(const QString &displayName, const QString &menuId, int priority) :
MenuDesignerAction(const QString &displayName, const QString &menuId, int priority,
SelectionContextFunction enabled = &SelectionContextFunctors::always,
SelectionContextFunction visibility = &SelectionContextFunctors::always) :
m_displayName(displayName),
m_menuId(menuId),
m_priority(priority),
m_menu(new QMenu)
m_menu(new QMenu),
m_enabled(enabled),
m_visibility(visibility)
{
m_menu->setTitle(displayName);
m_action = m_menu->menuAction();
}
virtual bool isVisible(const SelectionContext &m_selectionState) const
{ VISIBILITY visibility; return visibility(m_selectionState); }
virtual bool isEnabled(const SelectionContext &m_selectionState) const
{ ENABLED enabled; return enabled(m_selectionState); }
virtual QString category() const
{ return QString(""); }
virtual QString menuId() const
{ return m_menuId; }
virtual int priority() const
{ return m_priority; }
virtual AbstractDesignerAction::Type type() const
{ return AbstractDesignerAction::Menu; }
virtual QAction *action() const
{ return m_action; }
bool isVisible(const SelectionContext &m_selectionState) const { return m_visibility(m_selectionState); }
bool isEnabled(const SelectionContext &m_selectionState) const { return m_enabled(m_selectionState); }
QString category() const { return QString(); }
QString menuId() const { return m_menuId; }
int priority() const { return m_priority; }