summaryrefslogtreecommitdiffstats
path: root/src/designer/src/components/tabordereditor/tabordereditor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/designer/src/components/tabordereditor/tabordereditor.cpp')
-rw-r--r--src/designer/src/components/tabordereditor/tabordereditor.cpp433
1 files changed, 433 insertions, 0 deletions
diff --git a/src/designer/src/components/tabordereditor/tabordereditor.cpp b/src/designer/src/components/tabordereditor/tabordereditor.cpp
new file mode 100644
index 000000000..e372bdc14
--- /dev/null
+++ b/src/designer/src/components/tabordereditor/tabordereditor.cpp
@@ -0,0 +1,433 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tabordereditor.h"
+
+#include <metadatabase_p.h>
+#include <qdesigner_command_p.h>
+#include <qdesigner_utils_p.h>
+#include <qlayout_widget_p.h>
+#include <orderdialog_p.h>
+
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormWindowCursorInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerWidgetFactoryInterface>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+
+#include <QtGui/QPainter>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QResizeEvent>
+#include <QtGui/QMenu>
+#include <QtGui/QApplication>
+
+Q_DECLARE_METATYPE(QWidgetList)
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ enum { VBOX_MARGIN = 1, HBOX_MARGIN = 4, BG_ALPHA = 32 };
+}
+
+static QRect fixRect(const QRect &r)
+{
+ return QRect(r.x(), r.y(), r.width() - 1, r.height() - 1);
+}
+
+namespace qdesigner_internal {
+
+TabOrderEditor::TabOrderEditor(QDesignerFormWindowInterface *form, QWidget *parent) :
+ QWidget(parent),
+ m_form_window(form),
+ m_bg_widget(0),
+ m_undo_stack(form->commandHistory()),
+ m_font_metrics(font()),
+ m_current_index(0),
+ m_beginning(true)
+{
+ connect(form, SIGNAL(widgetRemoved(QWidget*)), this, SLOT(widgetRemoved(QWidget*)));
+
+ QFont tabFont = font();
+ tabFont.setPointSize(tabFont.pointSize()*2);
+ tabFont.setBold(true);
+ setFont(tabFont);
+ m_font_metrics = QFontMetrics(tabFont);
+ setAttribute(Qt::WA_MouseTracking, true);
+}
+
+QDesignerFormWindowInterface *TabOrderEditor::formWindow() const
+{
+ return m_form_window;
+}
+
+void TabOrderEditor::setBackground(QWidget *background)
+{
+ if (background == m_bg_widget) {
+ return;
+ }
+
+ m_bg_widget = background;
+ updateBackground();
+}
+
+void TabOrderEditor::updateBackground()
+{
+ if (m_bg_widget == 0) {
+ // nothing to do
+ return;
+ }
+
+ initTabOrder();
+ update();
+}
+
+void TabOrderEditor::widgetRemoved(QWidget*)
+{
+ initTabOrder();
+}
+
+void TabOrderEditor::showEvent(QShowEvent *e)
+{
+ QWidget::showEvent(e);
+ updateBackground();
+}
+
+QRect TabOrderEditor::indicatorRect(int index) const
+{
+ if (index < 0 || index >= m_tab_order_list.size())
+ return QRect();
+
+ const QWidget *w = m_tab_order_list.at(index);
+ const QString text = QString::number(index + 1);
+
+ const QPoint tl = mapFromGlobal(w->mapToGlobal(w->rect().topLeft()));
+ const QSize size = m_font_metrics.size(Qt::TextSingleLine, text);
+ QRect r(tl - QPoint(size.width(), size.height())/2, size);
+ r = QRect(r.left() - HBOX_MARGIN, r.top() - VBOX_MARGIN,
+ r.width() + HBOX_MARGIN*2, r.height() + VBOX_MARGIN*2);
+
+ return r;
+}
+
+static bool isWidgetVisible(QWidget *widget)
+{
+ while (widget && widget->parentWidget()) {
+ if (!widget->isVisibleTo(widget->parentWidget()))
+ return false;
+
+ widget = widget->parentWidget();
+ }
+
+ return true;
+}
+
+void TabOrderEditor::paintEvent(QPaintEvent *e)
+{
+ QPainter p(this);
+ p.setClipRegion(e->region());
+
+ int cur = m_current_index - 1;
+ if (m_beginning == false && cur < 0)
+ cur = m_tab_order_list.size() - 1;
+
+ for (int i = 0; i < m_tab_order_list.size(); ++i) {
+ QWidget *widget = m_tab_order_list.at(i);
+ if (!isWidgetVisible(widget))
+ continue;
+
+ const QRect r = indicatorRect(i);
+
+ QColor c = Qt::darkGreen;
+ if (i == cur)
+ c = Qt::red;
+ else if (i > cur)
+ c = Qt::blue;
+ p.setPen(c);
+ c.setAlpha(BG_ALPHA);
+ p.setBrush(c);
+ p.drawRect(fixRect(r));
+
+ p.setPen(Qt::white);
+ p.drawText(r, QString::number(i + 1), QTextOption(Qt::AlignCenter));
+ }
+}
+
+bool TabOrderEditor::skipWidget(QWidget *w) const
+{
+ if (qobject_cast<QLayoutWidget*>(w)
+ || w == formWindow()->mainContainer()
+ || w->isHidden())
+ return true;
+
+ if (!formWindow()->isManaged(w)) {
+ return true;
+ }
+
+ QExtensionManager *ext = formWindow()->core()->extensionManager();
+ if (const QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(ext, w)) {
+ const int index = sheet->indexOf(QLatin1String("focusPolicy"));
+ if (index != -1) {
+ bool ok = false;
+ Qt::FocusPolicy q = (Qt::FocusPolicy) Utils::valueOf(sheet->property(index), &ok);
+ return !ok || q == Qt::NoFocus;
+ }
+ }
+
+ return true;
+}
+
+void TabOrderEditor::initTabOrder()
+{
+ m_tab_order_list.clear();
+
+ QDesignerFormEditorInterface *core = formWindow()->core();
+
+ if (const QDesignerMetaDataBaseItemInterface *item = core->metaDataBase()->item(formWindow())) {
+ m_tab_order_list = item->tabOrder();
+ }
+
+ // Remove any widgets that have been removed form the form
+ for (int i = 0; i < m_tab_order_list.size(); ) {
+ QWidget *w = m_tab_order_list.at(i);
+ if (!formWindow()->mainContainer()->isAncestorOf(w) || skipWidget(w))
+ m_tab_order_list.removeAt(i);
+ else
+ ++i;
+ }
+
+ // Append any widgets that are in the form but are not in the tab order
+ QList<QWidget *> childQueue;
+ childQueue.append(formWindow()->mainContainer());
+ while (!childQueue.isEmpty()) {
+ QWidget *child = childQueue.takeFirst();
+ childQueue += qvariant_cast<QWidgetList>(child->property("_q_widgetOrder"));
+
+ if (skipWidget(child))
+ continue;
+
+ if (!m_tab_order_list.contains(child))
+ m_tab_order_list.append(child);
+ }
+
+ // Just in case we missed some widgets
+ QDesignerFormWindowCursorInterface *cursor = formWindow()->cursor();
+ for (int i = 0; i < cursor->widgetCount(); ++i) {
+
+ QWidget *widget = cursor->widget(i);
+ if (skipWidget(widget))
+ continue;
+
+ if (!m_tab_order_list.contains(widget))
+ m_tab_order_list.append(widget);
+ }
+
+ m_indicator_region = QRegion();
+ for (int i = 0; i < m_tab_order_list.size(); ++i) {
+ if (m_tab_order_list.at(i)->isVisible())
+ m_indicator_region |= indicatorRect(i);
+ }
+
+ if (m_current_index >= m_tab_order_list.size())
+ m_current_index = m_tab_order_list.size() - 1;
+ if (m_current_index < 0)
+ m_current_index = 0;
+}
+
+void TabOrderEditor::mouseMoveEvent(QMouseEvent *e)
+{
+ e->accept();
+#ifndef QT_NO_CURSOR
+ if (m_indicator_region.contains(e->pos()))
+ setCursor(Qt::PointingHandCursor);
+ else
+ setCursor(QCursor());
+#endif
+}
+
+int TabOrderEditor::widgetIndexAt(const QPoint &pos) const
+{
+ int target_index = -1;
+ for (int i = 0; i < m_tab_order_list.size(); ++i) {
+ if (!m_tab_order_list.at(i)->isVisible())
+ continue;
+ if (indicatorRect(i).contains(pos)) {
+ target_index = i;
+ break;
+ }
+ }
+
+ return target_index;
+}
+
+void TabOrderEditor::mousePressEvent(QMouseEvent *e)
+{
+ e->accept();
+
+ if (!m_indicator_region.contains(e->pos())) {
+ if (QWidget *child = m_bg_widget->childAt(e->pos())) {
+ QDesignerFormEditorInterface *core = m_form_window->core();
+ if (core->widgetFactory()->isPassiveInteractor(child)) {
+
+ QMouseEvent event(QEvent::MouseButtonPress,
+ child->mapFromGlobal(e->globalPos()),
+ e->button(), e->buttons(), e->modifiers());
+
+ qApp->sendEvent(child, &event);
+
+ QMouseEvent event2(QEvent::MouseButtonRelease,
+ child->mapFromGlobal(e->globalPos()),
+ e->button(), e->buttons(), e->modifiers());
+
+ qApp->sendEvent(child, &event2);
+
+ updateBackground();
+ }
+ }
+ return;
+ }
+
+ if (e->button() != Qt::LeftButton)
+ return;
+
+ const int target_index = widgetIndexAt(e->pos());
+ if (target_index == -1)
+ return;
+
+ m_beginning = false;
+
+ if (e->modifiers() & Qt::ControlModifier) {
+ m_current_index = target_index + 1;
+ if (m_current_index >= m_tab_order_list.size())
+ m_current_index = 0;
+ update();
+ return;
+ }
+
+ if (m_current_index == -1)
+ return;
+
+ m_tab_order_list.swap(target_index, m_current_index);
+
+ ++m_current_index;
+ if (m_current_index == m_tab_order_list.size())
+ m_current_index = 0;
+
+ TabOrderCommand *cmd = new TabOrderCommand(formWindow());
+ cmd->init(m_tab_order_list);
+ formWindow()->commandHistory()->push(cmd);
+}
+
+void TabOrderEditor::contextMenuEvent(QContextMenuEvent *e)
+{
+ QMenu menu(this);
+ const int target_index = widgetIndexAt(e->pos());
+ QAction *setIndex = menu.addAction(tr("Start from Here"));
+ setIndex->setEnabled(target_index >= 0);
+
+ QAction *resetIndex = menu.addAction(tr("Restart"));
+ menu.addSeparator();
+ QAction *showDialog = menu.addAction(tr("Tab Order List..."));
+ showDialog->setEnabled(m_tab_order_list.size() > 1);
+
+ QAction *result = menu.exec(e->globalPos());
+ if (result == resetIndex) {
+ m_current_index = 0;
+ m_beginning = true;
+ update();
+ } else if (result == setIndex) {
+ m_beginning = false;
+ m_current_index = target_index + 1;
+ if (m_current_index >= m_tab_order_list.size())
+ m_current_index = 0;
+ update();
+ } else if (result == showDialog) {
+ showTabOrderDialog();
+ }
+}
+
+void TabOrderEditor::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ if (e->button() != Qt::LeftButton)
+ return;
+
+ const int target_index = widgetIndexAt(e->pos());
+ if (target_index >= 0)
+ return;
+
+ m_beginning = true;
+ m_current_index = 0;
+ update();
+}
+
+void TabOrderEditor::resizeEvent(QResizeEvent *e)
+{
+ updateBackground();
+ QWidget::resizeEvent(e);
+}
+
+void TabOrderEditor::showTabOrderDialog()
+{
+ if (m_tab_order_list.size() < 2)
+ return;
+ OrderDialog dlg(this);
+ dlg.setWindowTitle(tr("Tab Order List"));
+ dlg.setDescription(tr("Tab Order"));
+ dlg.setFormat(OrderDialog::TabOrderFormat);
+ dlg.setPageList(m_tab_order_list);
+
+ if (dlg.exec() == QDialog::Rejected)
+ return;
+
+ const QWidgetList newOrder = dlg.pageList();
+ if (newOrder == m_tab_order_list)
+ return;
+
+ m_tab_order_list = newOrder;
+ TabOrderCommand *cmd = new TabOrderCommand(formWindow());
+ cmd->init(m_tab_order_list);
+ formWindow()->commandHistory()->push(cmd);
+ update();
+}
+
+}
+
+QT_END_NAMESPACE