summaryrefslogtreecommitdiffstats
path: root/tools/designer/src/lib/shared
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>2010-10-22 14:10:44 (GMT)
committerFriedemann Kleint <Friedemann.Kleint@nokia.com>2010-10-22 14:10:44 (GMT)
commit2231e4f03c621459e1c261b2ed224a49877d2ddf (patch)
tree93abd9fbf65a69c052b53170c0628d6dd9345034 /tools/designer/src/lib/shared
parent03c1445ed4be734a82cea59d107c51a4be43c5f4 (diff)
downloadQt-2231e4f03c621459e1c261b2ed224a49877d2ddf.zip
Qt-2231e4f03c621459e1c261b2ed224a49877d2ddf.tar.gz
Qt-2231e4f03c621459e1c261b2ed224a49877d2ddf.tar.bz2
Designer: Support alignment in box and grid layouts.
Extend ui-format by alignment-attribute for QLayoutItem, handle it in uic and formbuilder. Support in Designer by context menu. Reviewed-by: Jarek Kobus <jaroslaw.kobus@nokia.com> Task-number: QTBUG-3120
Diffstat (limited to 'tools/designer/src/lib/shared')
-rw-r--r--tools/designer/src/lib/shared/qdesigner_command2.cpp62
-rw-r--r--tools/designer/src/lib/shared/qdesigner_command2_p.h22
-rw-r--r--tools/designer/src/lib/shared/qdesigner_taskmenu.cpp139
-rw-r--r--tools/designer/src/lib/shared/qdesigner_taskmenu_p.h1
-rw-r--r--tools/designer/src/lib/shared/qlayout_widget.cpp14
5 files changed, 233 insertions, 5 deletions
diff --git a/tools/designer/src/lib/shared/qdesigner_command2.cpp b/tools/designer/src/lib/shared/qdesigner_command2.cpp
index c16bf40..ce2128a 100644
--- a/tools/designer/src/lib/shared/qdesigner_command2.cpp
+++ b/tools/designer/src/lib/shared/qdesigner_command2.cpp
@@ -154,6 +154,68 @@ QString MorphLayoutCommand::formatDescription(QDesignerFormEditorInterface * /*
return QApplication::translate("Command", "Change layout of '%1' from %2 to %3").arg(widgetName, oldName, newName);
}
+LayoutAlignmentCommand::LayoutAlignmentCommand(QDesignerFormWindowInterface *formWindow) :
+ QDesignerFormWindowCommand(QApplication::translate("Command", "Change layout alignment"), formWindow),
+ m_newAlignment(0), m_oldAlignment(0), m_widget(0)
+{
+}
+
+bool LayoutAlignmentCommand::init(QWidget *w, Qt::Alignment alignment)
+{
+ bool enabled;
+ m_newAlignment = alignment;
+ m_oldAlignment = LayoutAlignmentCommand::alignmentOf(core(), w, &enabled);
+ m_widget = w;
+ return enabled;
+}
+
+void LayoutAlignmentCommand::redo()
+{
+ LayoutAlignmentCommand::applyAlignment(core(), m_widget, m_newAlignment);
+}
+
+void LayoutAlignmentCommand::undo()
+{
+ LayoutAlignmentCommand::applyAlignment(core(), m_widget, m_oldAlignment);
+}
+
+// Find out alignment and return whether command is enabled.
+Qt::Alignment LayoutAlignmentCommand::alignmentOf(const QDesignerFormEditorInterface *core, QWidget *w, bool *enabledIn)
+{
+ bool managed;
+ QLayout *layout;
+
+ if (enabledIn)
+ *enabledIn = false;
+ // Can only work on a managed layout
+ const LayoutInfo::Type type = LayoutInfo::laidoutWidgetType(core, w, &managed, &layout);
+ const bool enabled = layout && managed &&
+ (type == LayoutInfo::HBox || type == LayoutInfo::VBox
+ || type == LayoutInfo::Grid);
+ if (!enabled)
+ return Qt::Alignment(0);
+ // Get alignment
+ const int index = layout->indexOf(w);
+ Q_ASSERT(index >= 0);
+ if (enabledIn)
+ *enabledIn = true;
+ return layout->itemAt(index)->alignment();
+}
+
+void LayoutAlignmentCommand::applyAlignment(const QDesignerFormEditorInterface *core, QWidget *w, Qt::Alignment a)
+{
+ // Find layout and apply to item
+ QLayout *layout;
+ LayoutInfo::laidoutWidgetType(core, w, 0, &layout);
+ if (layout) {
+ const int index = layout->indexOf(w);
+ if (index >= 0) {
+ layout->itemAt(index)->setAlignment(a);
+ layout->update();
+ }
+ }
+}
+
} // namespace qdesigner_internal
QT_END_NAMESPACE
diff --git a/tools/designer/src/lib/shared/qdesigner_command2_p.h b/tools/designer/src/lib/shared/qdesigner_command2_p.h
index 5c7b9d6..4e9c95a 100644
--- a/tools/designer/src/lib/shared/qdesigner_command2_p.h
+++ b/tools/designer/src/lib/shared/qdesigner_command2_p.h
@@ -94,6 +94,28 @@ private:
QWidget *m_layoutBase;
};
+// Change the alignment of a widget in a managed grid/box layout cell.
+class LayoutAlignmentCommand : public QDesignerFormWindowCommand {
+ Q_DISABLE_COPY(LayoutAlignmentCommand)
+public:
+ explicit LayoutAlignmentCommand(QDesignerFormWindowInterface *formWindow);
+
+ bool init(QWidget *w, Qt::Alignment alignment);
+
+ virtual void redo();
+ virtual void undo();
+
+ // Find out alignment and return whether command is enabled.
+ static Qt::Alignment alignmentOf(const QDesignerFormEditorInterface *core, QWidget *w, bool *enabled = 0);
+
+private:
+ static void applyAlignment(const QDesignerFormEditorInterface *core, QWidget *w, Qt::Alignment a);
+
+ Qt::Alignment m_newAlignment;
+ Qt::Alignment m_oldAlignment;
+ QWidget *m_widget;
+};
+
} // namespace qdesigner_internal
QT_END_NAMESPACE
diff --git a/tools/designer/src/lib/shared/qdesigner_taskmenu.cpp b/tools/designer/src/lib/shared/qdesigner_taskmenu.cpp
index a607f35..cdb7d15 100644
--- a/tools/designer/src/lib/shared/qdesigner_taskmenu.cpp
+++ b/tools/designer/src/lib/shared/qdesigner_taskmenu.cpp
@@ -41,6 +41,7 @@
#include "qdesigner_taskmenu_p.h"
#include "qdesigner_command_p.h"
+#include "qdesigner_command2_p.h"
#include "richtexteditor_p.h"
#include "plaintexteditor_p.h"
#include "stylesheeteditor_p.h"
@@ -180,10 +181,128 @@ QString ObjectNameDialog::newObjectName() const
{
return m_editor->text();
}
+} // namespace
+namespace qdesigner_internal {
+
+// Sub menu displaying the alignment options of a widget in a managed
+// grid/box layout cell.
+class LayoutAlignmentMenu {
+public:
+ explicit LayoutAlignmentMenu(QObject *parent);
+
+ QAction *subMenuAction() const { return m_subMenuAction; }
+
+ void connect(QObject *receiver, const char *aSlot);
+
+ // Set up enabled state and checked actions according to widget (managed box/grid)
+ bool setAlignment(const QDesignerFormEditorInterface *core, QWidget *w);
+
+ // Return the currently checked alignment
+ Qt::Alignment alignment() const;
+
+private:
+ enum Actions { HorizNone, Left, HorizCenter, Right, VerticalNone, Top, VerticalCenter, Bottom };
+ static QAction *createAction(const QString &text, int data, QMenu *menu, QActionGroup *ag);
+
+ QAction *m_subMenuAction;
+ QActionGroup *m_horizGroup;
+ QActionGroup *m_verticalGroup;
+ QAction *m_actions[Bottom + 1];
+};
+
+QAction *LayoutAlignmentMenu::createAction(const QString &text, int data, QMenu *menu, QActionGroup *ag)
+{
+ QAction * a = new QAction(text, 0);
+ a->setCheckable(true);
+ a->setData(QVariant(data));
+ menu->addAction(a);
+ ag->addAction(a);
+ return a;
+}
+
+LayoutAlignmentMenu::LayoutAlignmentMenu(QObject *parent) :
+ m_subMenuAction(new QAction(QDesignerTaskMenu::tr("Layout Alignment"), parent)),
+ m_horizGroup(new QActionGroup(parent)),
+ m_verticalGroup(new QActionGroup(parent))
+{
+ m_horizGroup->setExclusive(true);
+ m_verticalGroup->setExclusive(true);
+
+ QMenu *menu = new QMenu;
+ m_subMenuAction->setMenu(menu);
+
+ m_actions[HorizNone] = createAction(QDesignerTaskMenu::tr("No Horizontal Alignment"), 0, menu, m_horizGroup);
+ m_actions[Left] = createAction(QDesignerTaskMenu::tr("Left"), Qt::AlignLeft, menu, m_horizGroup);
+ m_actions[HorizCenter] = createAction(QDesignerTaskMenu::tr("Center Horizontally"), Qt::AlignHCenter, menu, m_horizGroup);
+ m_actions[Right] = createAction(QDesignerTaskMenu::tr("Right"), Qt::AlignRight, menu, m_horizGroup);
+ menu->addSeparator();
+ m_actions[VerticalNone] = createAction(QDesignerTaskMenu::tr("No Vertical Alignment"), 0, menu, m_verticalGroup);
+ m_actions[Top] = createAction(QDesignerTaskMenu::tr("Top"), Qt::AlignTop, menu, m_verticalGroup);
+ m_actions[VerticalCenter] = createAction(QDesignerTaskMenu::tr("Center Vertically"), Qt::AlignVCenter, menu, m_verticalGroup);
+ m_actions[Bottom] = createAction(QDesignerTaskMenu::tr("Bottom"), Qt::AlignBottom, menu, m_verticalGroup);
+}
+
+void LayoutAlignmentMenu::connect(QObject *receiver, const char *aSlot)
+{
+ QObject::connect(m_horizGroup, SIGNAL(triggered(QAction*)), receiver, aSlot);
+ QObject::connect(m_verticalGroup, SIGNAL(triggered(QAction*)), receiver, aSlot);
+}
+
+bool LayoutAlignmentMenu::setAlignment(const QDesignerFormEditorInterface *core, QWidget *w)
+{
+ bool enabled;
+ const Qt::Alignment alignment = LayoutAlignmentCommand::alignmentOf(core, w, &enabled);
+ if (!enabled) {
+ m_subMenuAction->setEnabled(false);
+ m_actions[HorizNone]->setChecked(true);
+ m_actions[VerticalNone]->setChecked(true);
+ return false;
+ }
+ // Get alignment
+ switch (alignment & Qt::AlignHorizontal_Mask) {
+ case Qt::AlignLeft:
+ m_actions[Left]->setChecked(true);
+ break;
+ case Qt::AlignHCenter:
+ m_actions[HorizCenter]->setChecked(true);
+ break;
+ case Qt::AlignRight:
+ m_actions[Right]->setChecked(true);
+ break;
+ default:
+ m_actions[HorizNone]->setChecked(true);
+ break;
+ }
+ switch (alignment & Qt::AlignVertical_Mask) {
+ case Qt::AlignTop:
+ m_actions[Top]->setChecked(true);
+ break;
+ case Qt::AlignVCenter:
+ m_actions[VerticalCenter]->setChecked(true);
+ break;
+ case Qt::AlignBottom:
+ m_actions[Bottom]->setChecked(true);
+ break;
+ default:
+ m_actions[VerticalNone]->setChecked(true);
+ break;
+ }
+ return true;
+}
+
+Qt::Alignment LayoutAlignmentMenu::alignment() const
+{
+ Qt::Alignment alignment = 0;
+ if (const QAction *horizAction = m_horizGroup->checkedAction())
+ if (const int horizAlign = horizAction->data().toInt())
+ alignment |= static_cast<Qt::Alignment>(horizAlign);
+ if (const QAction *vertAction = m_verticalGroup->checkedAction())
+ if (const int vertAlign = vertAction->data().toInt())
+ alignment |= static_cast<Qt::Alignment>(vertAlign);
+ return alignment;
}
-namespace qdesigner_internal {
// -------------- QDesignerTaskMenuPrivate
class QDesignerTaskMenuPrivate {
public:
@@ -214,6 +333,7 @@ public:
QAction *m_navigateToSlot;
PromotionTaskMenu* m_promotionTaskMenu;
QActionGroup *m_sizeActionGroup;
+ LayoutAlignmentMenu m_layoutAlignmentMenu;
QAction *m_sizeActionsSubMenu;
};
@@ -242,6 +362,7 @@ QDesignerTaskMenuPrivate::QDesignerTaskMenuPrivate(QWidget *widget, QObject *par
m_navigateToSlot(new QAction(QDesignerTaskMenu::tr("Go to slot..."), parent)),
m_promotionTaskMenu(new PromotionTaskMenu(widget, PromotionTaskMenu::ModeManagedMultiSelection, parent)),
m_sizeActionGroup(new QActionGroup(parent)),
+ m_layoutAlignmentMenu(parent),
m_sizeActionsSubMenu(new QAction(QDesignerTaskMenu::tr("Size Constraints"), parent))
{
QMenu *sizeMenu = new QMenu;
@@ -293,6 +414,7 @@ QDesignerTaskMenu::QDesignerTaskMenu(QWidget *widget, QObject *parent) :
connect(d->m_containerFakeMethods, SIGNAL(triggered()), this, SLOT(containerFakeMethods()));
connect(d->m_navigateToSlot, SIGNAL(triggered()), this, SLOT(slotNavigateToSlot()));
connect(d->m_sizeActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(applySize(QAction*)));
+ d->m_layoutAlignmentMenu.connect(this, SLOT(slotLayoutAlignment()));
}
QDesignerTaskMenu::~QDesignerTaskMenu()
@@ -410,6 +532,9 @@ QList<QAction*> QDesignerTaskMenu::taskActions() const
actions.append(d->m_changeStyleSheet);
actions.append(d->m_separator6);
actions.append(d->m_sizeActionsSubMenu);
+ if (d->m_layoutAlignmentMenu.setAlignment(formWindow->core(), d->m_widget))
+ actions.append(d->m_layoutAlignmentMenu.subMenuAction());
+
d->m_promotionTaskMenu->setMode(formWindow->isManaged(d->m_widget) ?
PromotionTaskMenu::ModeManagedMultiSelection : PromotionTaskMenu::ModeUnmanagedMultiSelection);
d->m_promotionTaskMenu->addActions(formWindow, PromotionTaskMenu::LeadingSeparator, actions);
@@ -771,7 +896,17 @@ void QDesignerTaskMenu::setProperty(QDesignerFormWindowInterface *fw, PropertyM
}
}
-
+void QDesignerTaskMenu::slotLayoutAlignment()
+{
+ QDesignerFormWindowInterface *fw = formWindow();
+ const Qt::Alignment newAlignment = d->m_layoutAlignmentMenu.alignment();
+ LayoutAlignmentCommand *cmd = new LayoutAlignmentCommand(fw);
+ if (cmd->init(d->m_widget, newAlignment)) {
+ fw->commandHistory()->push(cmd);
+ } else {
+ delete cmd;
+ }
+}
} // namespace qdesigner_internal
QT_END_NAMESPACE
diff --git a/tools/designer/src/lib/shared/qdesigner_taskmenu_p.h b/tools/designer/src/lib/shared/qdesigner_taskmenu_p.h
index da7f572..23586f7 100644
--- a/tools/designer/src/lib/shared/qdesigner_taskmenu_p.h
+++ b/tools/designer/src/lib/shared/qdesigner_taskmenu_p.h
@@ -118,6 +118,7 @@ private slots:
void containerFakeMethods();
void slotNavigateToSlot();
void applySize(QAction *a);
+ void slotLayoutAlignment();
private:
QDesignerTaskMenuPrivate *d;
diff --git a/tools/designer/src/lib/shared/qlayout_widget.cpp b/tools/designer/src/lib/shared/qlayout_widget.cpp
index acec815..012f605 100644
--- a/tools/designer/src/lib/shared/qlayout_widget.cpp
+++ b/tools/designer/src/lib/shared/qlayout_widget.cpp
@@ -601,7 +601,7 @@ QRect LayoutHelper::itemInfo(QLayout *lt, const QWidget *widget) const
}
}
- // Grid Layout state. Datatypically store the state of a GridLayout as a map of
+ // Grid Layout state. Datatype storing the state of a GridLayout as a map of
// widgets to QRect(columns, rows) and size. Used to store the state for undo operations
// that do not change the widgets within the layout; also provides some manipulation
// functions and ability to apply the state to a layout provided its widgets haven't changed.
@@ -634,7 +634,11 @@ QRect LayoutHelper::itemInfo(QLayout *lt, const QWidget *widget) const
static CellStates cellStates(const QList<QRect> &rects, int numRows, int numColumns);
typedef QMap<QWidget *, QRect> WidgetItemMap;
+ typedef QMap<QWidget *, Qt::Alignment> WidgetAlignmentMap;
+
WidgetItemMap widgetItemMap;
+ WidgetAlignmentMap widgetAlignmentMap;
+
int rowCount;
int colCount;
};
@@ -706,8 +710,11 @@ QRect LayoutHelper::itemInfo(QLayout *lt, const QWidget *widget) const
const int count = l->count();
for (int i = 0; i < count; i++) {
QLayoutItem *item = l->itemAt(i);
- if (!LayoutInfo::isEmptyItem(item))
+ if (!LayoutInfo::isEmptyItem(item)) {
widgetItemMap.insert(item->widget(), gridItemInfo(l, i));
+ if (item->alignment())
+ widgetAlignmentMap.insert(item->widget(), item->alignment());
+ }
}
}
@@ -743,7 +750,8 @@ QRect LayoutHelper::itemInfo(QLayout *lt, const QWidget *widget) const
const LayoutItemRectMap::const_iterator icend = itemMap.constEnd();
for (LayoutItemRectMap::const_iterator it = itemMap.constBegin(); it != icend; ++it) {
const QRect info = it.value();
- grid->addItem(it.key(), info.y(), info.x(), info.height(), info.width());
+ const Qt::Alignment alignment = widgetAlignmentMap.value(it.key()->widget(), Qt::Alignment(0));
+ grid->addItem(it.key(), info.y(), info.x(), info.height(), info.width(), alignment);
}
// create spacers
const CellStates cs = cellStates(itemMap.values(), rowCount, colCount);