彻底改版2.0
This commit is contained in:
824
third/designer/lib/shared/actioneditor.cpp
Normal file
824
third/designer/lib/shared/actioneditor.cpp
Normal file
@@ -0,0 +1,824 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "actioneditor_p.h"
|
||||
#include "filterwidget_p.h"
|
||||
#include "actionrepository_p.h"
|
||||
#include "iconloader_p.h"
|
||||
#include "newactiondialog_p.h"
|
||||
#include "qdesigner_menu_p.h"
|
||||
#include "qdesigner_command_p.h"
|
||||
#include "qdesigner_propertycommand_p.h"
|
||||
#include "qdesigner_objectinspector_p.h"
|
||||
#include "qdesigner_utils_p.h"
|
||||
#include "qsimpleresource_p.h"
|
||||
#include "formwindowbase_p.h"
|
||||
#include "qdesigner_taskmenu_p.h"
|
||||
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
#include <QtDesigner/QDesignerPropertyEditorInterface>
|
||||
#include <QtDesigner/QDesignerPropertySheetExtension>
|
||||
#include <QtDesigner/QExtensionManager>
|
||||
#include <QtDesigner/QDesignerMetaDataBaseInterface>
|
||||
#include <QtDesigner/QDesignerIconCacheInterface>
|
||||
#include <QtDesigner/private/abstractsettings_p.h>
|
||||
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtGui/QToolBar>
|
||||
#include <QtGui/QSplitter>
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtGui/QClipboard>
|
||||
#include <QtGui/QItemDelegate>
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QVBoxLayout>
|
||||
#include <QtGui/QLineEdit>
|
||||
#include <QtGui/QLabel>
|
||||
#include <QtGui/QPushButton>
|
||||
#include <QtGui/QToolButton>
|
||||
#include <QtGui/QContextMenuEvent>
|
||||
#include <QtGui/QItemSelection>
|
||||
|
||||
#include <QtCore/QRegExp>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QSignalMapper>
|
||||
#include <QtCore/QBuffer>
|
||||
|
||||
Q_DECLARE_METATYPE(QAction*)
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static const char *actionEditorViewModeKey = "ActionEditorViewMode";
|
||||
|
||||
static const char *iconPropertyC = "icon";
|
||||
static const char *shortcutPropertyC = "shortcut";
|
||||
static const char *toolTipPropertyC = "toolTip";
|
||||
static const char *checkablePropertyC = "checkable";
|
||||
static const char *objectNamePropertyC = "objectName";
|
||||
static const char *textPropertyC = "text";
|
||||
|
||||
namespace qdesigner_internal {
|
||||
//-------- ActionGroupDelegate
|
||||
class ActionGroupDelegate: public QItemDelegate
|
||||
{
|
||||
public:
|
||||
ActionGroupDelegate(QObject *parent)
|
||||
: QItemDelegate(parent) {}
|
||||
|
||||
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
if (option.state & QStyle::State_Selected)
|
||||
painter->fillRect(option.rect, option.palette.highlight());
|
||||
|
||||
QItemDelegate::paint(painter, option, index);
|
||||
}
|
||||
|
||||
virtual void drawFocus(QPainter * /*painter*/, const QStyleOptionViewItem &/*option*/, const QRect &/*rect*/) const {}
|
||||
};
|
||||
|
||||
//-------- ActionEditor
|
||||
ActionEditor::ActionEditor(QDesignerFormEditorInterface *core, QWidget *parent, Qt::WindowFlags flags) :
|
||||
QDesignerActionEditorInterface(parent, flags),
|
||||
m_core(core),
|
||||
m_actionGroups(0),
|
||||
m_actionView(new ActionView),
|
||||
m_actionNew(new QAction(tr("New..."), this)),
|
||||
m_actionEdit(new QAction(tr("Edit..."), this)),
|
||||
m_actionNavigateToSlot(new QAction(tr("Go to slot..."), this)),
|
||||
m_actionCopy(new QAction(tr("Copy"), this)),
|
||||
m_actionCut(new QAction(tr("Cut"), this)),
|
||||
m_actionPaste(new QAction(tr("Paste"), this)),
|
||||
m_actionSelectAll(new QAction(tr("Select all"), this)),
|
||||
m_actionDelete(new QAction(tr("Delete"), this)),
|
||||
m_viewModeGroup(new QActionGroup(this)),
|
||||
m_iconViewAction(0),
|
||||
m_listViewAction(0),
|
||||
m_filterWidget(0),
|
||||
m_selectAssociatedWidgetsMapper(0)
|
||||
{
|
||||
m_actionView->initialize(m_core);
|
||||
m_actionView->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
setWindowTitle(tr("Actions"));
|
||||
|
||||
QVBoxLayout *l = new QVBoxLayout(this);
|
||||
l->setMargin(0);
|
||||
l->setSpacing(0);
|
||||
|
||||
QToolBar *toolbar = new QToolBar;
|
||||
toolbar->setIconSize(QSize(22, 22));
|
||||
toolbar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
l->addWidget(toolbar);
|
||||
// edit actions
|
||||
QIcon documentNewIcon = QIcon::fromTheme("document-new", createIconSet(QLatin1String("filenew.png")));
|
||||
m_actionNew->setIcon(documentNewIcon);
|
||||
m_actionNew->setEnabled(false);
|
||||
connect(m_actionNew, SIGNAL(triggered()), this, SLOT(slotNewAction()));
|
||||
toolbar->addAction(m_actionNew);
|
||||
|
||||
connect(m_actionSelectAll, SIGNAL(triggered()), m_actionView, SLOT(selectAll()));
|
||||
|
||||
m_actionCut->setEnabled(false);
|
||||
connect(m_actionCut, SIGNAL(triggered()), this, SLOT(slotCut()));
|
||||
QIcon editCutIcon = QIcon::fromTheme("edit-cut", createIconSet(QLatin1String("editcut.png")));
|
||||
m_actionCut->setIcon(editCutIcon);
|
||||
|
||||
m_actionCopy->setEnabled(false);
|
||||
connect(m_actionCopy, SIGNAL(triggered()), this, SLOT(slotCopy()));
|
||||
QIcon editCopyIcon = QIcon::fromTheme("edit-copy", createIconSet(QLatin1String("editcopy.png")));
|
||||
m_actionCopy->setIcon(editCopyIcon);
|
||||
toolbar->addAction(m_actionCopy);
|
||||
|
||||
connect(m_actionPaste, SIGNAL(triggered()), this, SLOT(slotPaste()));
|
||||
QIcon editPasteIcon = QIcon::fromTheme("edit-paste", createIconSet(QLatin1String("editpaste.png")));
|
||||
m_actionPaste->setIcon(editPasteIcon);
|
||||
toolbar->addAction(m_actionPaste);
|
||||
|
||||
m_actionEdit->setEnabled(false);
|
||||
connect(m_actionEdit, SIGNAL(triggered()), this, SLOT(editCurrentAction()));
|
||||
|
||||
connect(m_actionNavigateToSlot, SIGNAL(triggered()), this, SLOT(navigateToSlotCurrentAction()));
|
||||
|
||||
QIcon editDeleteIcon = QIcon::fromTheme("edit-delete", createIconSet(QLatin1String("editdelete.png")));
|
||||
m_actionDelete->setIcon(editDeleteIcon);
|
||||
m_actionDelete->setEnabled(false);
|
||||
connect(m_actionDelete, SIGNAL(triggered()), this, SLOT(slotDelete()));
|
||||
toolbar->addAction(m_actionDelete);
|
||||
|
||||
// Toolbutton with menu containing action group for detailed/icon view. Steal the icons from the file dialog.
|
||||
//
|
||||
QMenu *configureMenu;
|
||||
toolbar->addWidget(createConfigureMenuButton(tr("Configure Action Editor"), &configureMenu));
|
||||
|
||||
connect(m_viewModeGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotViewMode(QAction*)));
|
||||
m_iconViewAction = m_viewModeGroup->addAction(tr("Icon View"));
|
||||
m_iconViewAction->setData(QVariant(ActionView::IconView));
|
||||
m_iconViewAction->setCheckable(true);
|
||||
m_iconViewAction->setIcon(style()->standardIcon (QStyle::SP_FileDialogListView));
|
||||
configureMenu->addAction(m_iconViewAction);
|
||||
|
||||
m_listViewAction = m_viewModeGroup->addAction(tr("Detailed View"));
|
||||
m_listViewAction->setData(QVariant(ActionView::DetailedView));
|
||||
m_listViewAction->setCheckable(true);
|
||||
m_listViewAction->setIcon(style()->standardIcon (QStyle::SP_FileDialogDetailedView));
|
||||
configureMenu->addAction(m_listViewAction);
|
||||
// filter
|
||||
m_filterWidget = new FilterWidget(toolbar);
|
||||
connect(m_filterWidget, SIGNAL(filterChanged(QString)), this, SLOT(setFilter(QString)));
|
||||
m_filterWidget->setEnabled(false);
|
||||
toolbar->addWidget(m_filterWidget);
|
||||
|
||||
// main layout
|
||||
QSplitter *splitter = new QSplitter(Qt::Horizontal);
|
||||
splitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
||||
splitter->addWidget(m_actionView);
|
||||
l->addWidget(splitter);
|
||||
|
||||
#if 0 // ### implement me
|
||||
m_actionGroups = new QListWidget(splitter);
|
||||
splitter->addWidget(m_actionGroups);
|
||||
m_actionGroups->setItemDelegate(new ActionGroupDelegate(m_actionGroups));
|
||||
m_actionGroups->setMovement(QListWidget::Static);
|
||||
m_actionGroups->setResizeMode(QListWidget::Fixed);
|
||||
m_actionGroups->setIconSize(QSize(48, 48));
|
||||
m_actionGroups->setFlow(QListWidget::TopToBottom);
|
||||
m_actionGroups->setViewMode(QListWidget::IconMode);
|
||||
m_actionGroups->setWrapping(false);
|
||||
#endif
|
||||
|
||||
connect(m_actionView, SIGNAL(resourceImageDropped(QString,QAction*)),
|
||||
this, SLOT(resourceImageDropped(QString,QAction*)));
|
||||
|
||||
connect(m_actionView, SIGNAL(currentChanged(QAction*)),this, SLOT(slotCurrentItemChanged(QAction*)));
|
||||
// make it possible for vs integration to reimplement edit action dialog
|
||||
connect(m_actionView, SIGNAL(activated(QAction*)), this, SIGNAL(itemActivated(QAction*)));
|
||||
|
||||
connect(m_actionView,SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
||||
this, SLOT(slotSelectionChanged(QItemSelection,QItemSelection)));
|
||||
|
||||
connect(m_actionView, SIGNAL(contextMenuRequested(QContextMenuEvent*,QAction*)),
|
||||
this, SLOT(slotContextMenuRequested(QContextMenuEvent*,QAction*)));
|
||||
|
||||
connect(this, SIGNAL(itemActivated(QAction*)), this, SLOT(editAction(QAction*)));
|
||||
|
||||
restoreSettings();
|
||||
updateViewModeActions();
|
||||
}
|
||||
|
||||
// Utility to create a configure button with menu for usage on toolbars
|
||||
QToolButton *ActionEditor::createConfigureMenuButton(const QString &t, QMenu **ptrToMenu)
|
||||
{
|
||||
QToolButton *configureButton = new QToolButton;
|
||||
QAction *configureAction = new QAction(t, configureButton);
|
||||
QIcon configureIcon = QIcon::fromTheme("document-properties", createIconSet(QLatin1String("configure.png")));
|
||||
configureAction->setIcon(configureIcon);
|
||||
QMenu *configureMenu = new QMenu;
|
||||
configureAction->setMenu(configureMenu);
|
||||
configureButton->setDefaultAction(configureAction);
|
||||
configureButton->setPopupMode(QToolButton::InstantPopup);
|
||||
*ptrToMenu = configureMenu;
|
||||
return configureButton;
|
||||
}
|
||||
|
||||
ActionEditor::~ActionEditor()
|
||||
{
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
QAction *ActionEditor::actionNew() const
|
||||
{
|
||||
return m_actionNew;
|
||||
}
|
||||
|
||||
QAction *ActionEditor::actionDelete() const
|
||||
{
|
||||
return m_actionDelete;
|
||||
}
|
||||
|
||||
QDesignerFormWindowInterface *ActionEditor::formWindow() const
|
||||
{
|
||||
return m_formWindow;
|
||||
}
|
||||
|
||||
void ActionEditor::setFormWindow(QDesignerFormWindowInterface *formWindow)
|
||||
{
|
||||
if (formWindow != 0 && formWindow->mainContainer() == 0)
|
||||
formWindow = 0;
|
||||
|
||||
// we do NOT rely on this function to update the action editor
|
||||
if (m_formWindow == formWindow)
|
||||
return;
|
||||
|
||||
if (m_formWindow != 0) {
|
||||
const ActionList actionList = qFindChildren<QAction*>(m_formWindow->mainContainer());
|
||||
foreach (QAction *action, actionList)
|
||||
disconnect(action, SIGNAL(changed()), this, SLOT(slotActionChanged()));
|
||||
}
|
||||
|
||||
m_formWindow = formWindow;
|
||||
|
||||
m_actionView->model()->clearActions();
|
||||
|
||||
m_actionEdit->setEnabled(false);
|
||||
m_actionCopy->setEnabled(false);
|
||||
m_actionCut->setEnabled(false);
|
||||
m_actionDelete->setEnabled(false);
|
||||
|
||||
if (!formWindow || !formWindow->mainContainer()) {
|
||||
m_actionNew->setEnabled(false);
|
||||
m_filterWidget->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
m_actionNew->setEnabled(true);
|
||||
m_filterWidget->setEnabled(true);
|
||||
|
||||
const ActionList actionList = qFindChildren<QAction*>(formWindow->mainContainer());
|
||||
foreach (QAction *action, actionList)
|
||||
if (!action->isSeparator() && core()->metaDataBase()->item(action) != 0) {
|
||||
// Show unless it has a menu. However, listen for change on menu actions also as it might be removed
|
||||
if (!action->menu())
|
||||
m_actionView->model()->addAction(action);
|
||||
connect(action, SIGNAL(changed()), this, SLOT(slotActionChanged()));
|
||||
}
|
||||
|
||||
setFilter(m_filter);
|
||||
}
|
||||
|
||||
void ActionEditor::slotSelectionChanged(const QItemSelection& selected, const QItemSelection& /*deselected*/)
|
||||
{
|
||||
const bool hasSelection = !selected.indexes().empty();
|
||||
m_actionCopy->setEnabled(hasSelection);
|
||||
m_actionCut->setEnabled(hasSelection);
|
||||
m_actionDelete->setEnabled(hasSelection);
|
||||
}
|
||||
|
||||
void ActionEditor::slotCurrentItemChanged(QAction *action)
|
||||
{
|
||||
QDesignerFormWindowInterface *fw = formWindow();
|
||||
if (!fw)
|
||||
return;
|
||||
|
||||
const bool hasCurrentAction = action != 0;
|
||||
m_actionEdit->setEnabled(hasCurrentAction);
|
||||
|
||||
if (!action) {
|
||||
fw->clearSelection();
|
||||
return;
|
||||
}
|
||||
|
||||
QDesignerObjectInspector *oi = qobject_cast<QDesignerObjectInspector *>(core()->objectInspector());
|
||||
|
||||
if (action->associatedWidgets().empty()) {
|
||||
// Special case: action not in object tree. Deselect all and set in property editor
|
||||
fw->clearSelection(false);
|
||||
if (oi)
|
||||
oi->clearSelection();
|
||||
core()->propertyEditor()->setObject(action);
|
||||
} else {
|
||||
if (oi)
|
||||
oi->selectObject(action);
|
||||
}
|
||||
}
|
||||
|
||||
void ActionEditor::slotActionChanged()
|
||||
{
|
||||
QAction *action = qobject_cast<QAction*>(sender());
|
||||
Q_ASSERT(action != 0);
|
||||
|
||||
ActionModel *model = m_actionView->model();
|
||||
const int row = model->findAction(action);
|
||||
if (row == -1) {
|
||||
if (action->menu() == 0) // action got its menu deleted, create item
|
||||
model->addAction(action);
|
||||
} else if (action->menu() != 0) { // action got its menu created, remove item
|
||||
model->removeRow(row);
|
||||
} else {
|
||||
// action text or icon changed, update item
|
||||
model->update(row);
|
||||
}
|
||||
}
|
||||
|
||||
QDesignerFormEditorInterface *ActionEditor::core() const
|
||||
{
|
||||
return m_core;
|
||||
}
|
||||
|
||||
QString ActionEditor::filter() const
|
||||
{
|
||||
return m_filter;
|
||||
}
|
||||
|
||||
void ActionEditor::setFilter(const QString &f)
|
||||
{
|
||||
m_filter = f;
|
||||
m_actionView->filter(m_filter);
|
||||
}
|
||||
|
||||
// Set changed state of icon property, reset when icon is cleared
|
||||
static void refreshIconPropertyChanged(const QAction *action, QDesignerPropertySheetExtension *sheet)
|
||||
{
|
||||
sheet->setChanged(sheet->indexOf(QLatin1String(iconPropertyC)), !action->icon().isNull());
|
||||
}
|
||||
|
||||
void ActionEditor::manageAction(QAction *action)
|
||||
{
|
||||
action->setParent(formWindow()->mainContainer());
|
||||
core()->metaDataBase()->add(action);
|
||||
|
||||
if (action->isSeparator() || action->menu() != 0)
|
||||
return;
|
||||
|
||||
QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), action);
|
||||
sheet->setChanged(sheet->indexOf(QLatin1String(objectNamePropertyC)), true);
|
||||
sheet->setChanged(sheet->indexOf(QLatin1String(textPropertyC)), true);
|
||||
refreshIconPropertyChanged(action, sheet);
|
||||
|
||||
m_actionView->setCurrentIndex(m_actionView->model()->addAction(action));
|
||||
connect(action, SIGNAL(changed()), this, SLOT(slotActionChanged()));
|
||||
}
|
||||
|
||||
void ActionEditor::unmanageAction(QAction *action)
|
||||
{
|
||||
core()->metaDataBase()->remove(action);
|
||||
action->setParent(0);
|
||||
|
||||
disconnect(action, SIGNAL(changed()), this, SLOT(slotActionChanged()));
|
||||
|
||||
const int row = m_actionView->model()->findAction(action);
|
||||
if (row != -1)
|
||||
m_actionView->model()->remove(row);
|
||||
}
|
||||
|
||||
// Set an initial property and mark it as changed in the sheet
|
||||
static void setInitialProperty(QDesignerPropertySheetExtension *sheet, const QString &name, const QVariant &value)
|
||||
{
|
||||
const int index = sheet->indexOf(name);
|
||||
Q_ASSERT(index != -1);
|
||||
sheet->setProperty(index, value);
|
||||
sheet->setChanged(index, true);
|
||||
}
|
||||
|
||||
void ActionEditor::slotNewAction()
|
||||
{
|
||||
NewActionDialog dlg(this);
|
||||
dlg.setWindowTitle(tr("New action"));
|
||||
|
||||
if (dlg.exec() == QDialog::Accepted) {
|
||||
const ActionData actionData = dlg.actionData();
|
||||
m_actionView->clearSelection();
|
||||
|
||||
QAction *action = new QAction(formWindow());
|
||||
action->setObjectName(actionData.name);
|
||||
formWindow()->ensureUniqueObjectName(action);
|
||||
action->setText(actionData.text);
|
||||
|
||||
QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), action);
|
||||
if (!actionData.toolTip.isEmpty())
|
||||
setInitialProperty(sheet, QLatin1String(toolTipPropertyC), actionData.toolTip);
|
||||
|
||||
if (actionData.checkable)
|
||||
setInitialProperty(sheet, QLatin1String(checkablePropertyC), QVariant(true));
|
||||
|
||||
if (!actionData.keysequence.value().isEmpty())
|
||||
setInitialProperty(sheet, QLatin1String(shortcutPropertyC), qVariantFromValue(actionData.keysequence));
|
||||
|
||||
sheet->setProperty(sheet->indexOf(QLatin1String(iconPropertyC)), qVariantFromValue(actionData.icon));
|
||||
|
||||
AddActionCommand *cmd = new AddActionCommand(formWindow());
|
||||
cmd->init(action);
|
||||
formWindow()->commandHistory()->push(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool isSameIcon(const QIcon &i1, const QIcon &i2)
|
||||
{
|
||||
return i1.serialNumber() == i2.serialNumber();
|
||||
}
|
||||
|
||||
// return a FormWindow command to apply an icon or a reset command in case it
|
||||
// is empty.
|
||||
|
||||
static QDesignerFormWindowCommand *setIconPropertyCommand(const PropertySheetIconValue &newIcon, QAction *action, QDesignerFormWindowInterface *fw)
|
||||
{
|
||||
const QString iconProperty = QLatin1String(iconPropertyC);
|
||||
if (newIcon.paths().isEmpty()) {
|
||||
ResetPropertyCommand *cmd = new ResetPropertyCommand(fw);
|
||||
cmd->init(action, iconProperty);
|
||||
return cmd;
|
||||
}
|
||||
SetPropertyCommand *cmd = new SetPropertyCommand(fw);
|
||||
cmd->init(action, iconProperty, qVariantFromValue(newIcon));
|
||||
return cmd;
|
||||
}
|
||||
|
||||
// return a FormWindow command to apply a QKeySequence or a reset command
|
||||
// in case it is empty.
|
||||
|
||||
static QDesignerFormWindowCommand *setKeySequencePropertyCommand(const PropertySheetKeySequenceValue &ks, QAction *action, QDesignerFormWindowInterface *fw)
|
||||
{
|
||||
const QString shortcutProperty = QLatin1String(shortcutPropertyC);
|
||||
if (ks.value().isEmpty()) {
|
||||
ResetPropertyCommand *cmd = new ResetPropertyCommand(fw);
|
||||
cmd->init(action, shortcutProperty);
|
||||
return cmd;
|
||||
}
|
||||
SetPropertyCommand *cmd = new SetPropertyCommand(fw);
|
||||
cmd->init(action, shortcutProperty, qVariantFromValue(ks));
|
||||
return cmd;
|
||||
}
|
||||
|
||||
// return a FormWindow command to apply a POD value or reset command in case
|
||||
// it is equal to the default value.
|
||||
|
||||
template <class T>
|
||||
QDesignerFormWindowCommand *setPropertyCommand(const QString &name, T value, T defaultValue,
|
||||
QObject *o, QDesignerFormWindowInterface *fw)
|
||||
{
|
||||
if (value == defaultValue) {
|
||||
ResetPropertyCommand *cmd = new ResetPropertyCommand(fw);
|
||||
cmd->init(o, name);
|
||||
return cmd;
|
||||
}
|
||||
SetPropertyCommand *cmd = new SetPropertyCommand(fw);
|
||||
cmd->init(o, name, QVariant(value));
|
||||
return cmd;
|
||||
}
|
||||
|
||||
// Return the text value of a string property via PropertySheetStringValue
|
||||
static inline QString textPropertyValue(const QDesignerPropertySheetExtension *sheet, const QString &name)
|
||||
{
|
||||
const int index = sheet->indexOf(name);
|
||||
Q_ASSERT(index != -1);
|
||||
const PropertySheetStringValue ps = qVariantValue<PropertySheetStringValue>(sheet->property(index));
|
||||
return ps.value();
|
||||
}
|
||||
|
||||
void ActionEditor::editAction(QAction *action)
|
||||
{
|
||||
if (!action)
|
||||
return;
|
||||
|
||||
NewActionDialog dlg(this);
|
||||
dlg.setWindowTitle(tr("Edit action"));
|
||||
|
||||
ActionData oldActionData;
|
||||
QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), action);
|
||||
oldActionData.name = action->objectName();
|
||||
oldActionData.text = action->text();
|
||||
oldActionData.toolTip = textPropertyValue(sheet, QLatin1String(toolTipPropertyC));
|
||||
oldActionData.icon = qVariantValue<PropertySheetIconValue>(sheet->property(sheet->indexOf(QLatin1String(iconPropertyC))));
|
||||
oldActionData.keysequence = ActionModel::actionShortCut(sheet);
|
||||
oldActionData.checkable = action->isCheckable();
|
||||
dlg.setActionData(oldActionData);
|
||||
|
||||
if (!dlg.exec())
|
||||
return;
|
||||
|
||||
// figure out changes and whether to start a macro
|
||||
const ActionData newActionData = dlg.actionData();
|
||||
const unsigned changeMask = newActionData.compare(oldActionData);
|
||||
if (changeMask == 0u)
|
||||
return;
|
||||
|
||||
const bool severalChanges = (changeMask != ActionData::TextChanged) && (changeMask != ActionData::NameChanged)
|
||||
&& (changeMask != ActionData::ToolTipChanged) && (changeMask != ActionData::IconChanged)
|
||||
&& (changeMask != ActionData::CheckableChanged) && (changeMask != ActionData::KeysequenceChanged);
|
||||
|
||||
QDesignerFormWindowInterface *fw = formWindow();
|
||||
QUndoStack *undoStack = fw->commandHistory();
|
||||
if (severalChanges)
|
||||
fw->beginCommand(QLatin1String("Edit action"));
|
||||
|
||||
if (changeMask & ActionData::NameChanged)
|
||||
undoStack->push(createTextPropertyCommand(QLatin1String(objectNamePropertyC), newActionData.name, action, fw));
|
||||
|
||||
if (changeMask & ActionData::TextChanged)
|
||||
undoStack->push(createTextPropertyCommand(QLatin1String(textPropertyC), newActionData.text, action, fw));
|
||||
|
||||
if (changeMask & ActionData::ToolTipChanged)
|
||||
undoStack->push(createTextPropertyCommand(QLatin1String(toolTipPropertyC), newActionData.toolTip, action, fw));
|
||||
|
||||
if (changeMask & ActionData::IconChanged)
|
||||
undoStack->push(setIconPropertyCommand(newActionData.icon, action, fw));
|
||||
|
||||
if (changeMask & ActionData::CheckableChanged)
|
||||
undoStack->push(setPropertyCommand(QLatin1String(checkablePropertyC), newActionData.checkable, false, action, fw));
|
||||
|
||||
if (changeMask & ActionData::KeysequenceChanged)
|
||||
undoStack->push(setKeySequencePropertyCommand(newActionData.keysequence, action, fw));
|
||||
|
||||
if (severalChanges)
|
||||
fw->endCommand();
|
||||
}
|
||||
|
||||
void ActionEditor::editCurrentAction()
|
||||
{
|
||||
if (QAction *a = m_actionView->currentAction())
|
||||
editAction(a);
|
||||
}
|
||||
|
||||
void ActionEditor::navigateToSlotCurrentAction()
|
||||
{
|
||||
if (QAction *a = m_actionView->currentAction())
|
||||
QDesignerTaskMenu::navigateToSlot(m_core, a, QLatin1String("triggered()"));
|
||||
}
|
||||
|
||||
void ActionEditor::deleteActions(QDesignerFormWindowInterface *fw, const ActionList &actions)
|
||||
{
|
||||
// We need a macro even in the case of single action because the commands might cause the
|
||||
// scheduling of other commands (signal slots connections)
|
||||
const QString description = actions.size() == 1 ?
|
||||
tr("Remove action '%1'").arg(actions.front()->objectName()) : tr("Remove actions");
|
||||
fw->beginCommand(description);
|
||||
foreach(QAction *action, actions) {
|
||||
RemoveActionCommand *cmd = new RemoveActionCommand(fw);
|
||||
cmd->init(action);
|
||||
fw->commandHistory()->push(cmd);
|
||||
}
|
||||
fw->endCommand();
|
||||
}
|
||||
|
||||
void ActionEditor::copyActions(QDesignerFormWindowInterface *fwi, const ActionList &actions)
|
||||
{
|
||||
FormWindowBase *fw = qobject_cast<FormWindowBase *>(fwi);
|
||||
if (!fw )
|
||||
return;
|
||||
|
||||
FormBuilderClipboard clipboard;
|
||||
clipboard.m_actions = actions;
|
||||
|
||||
if (clipboard.empty())
|
||||
return;
|
||||
|
||||
QEditorFormBuilder *formBuilder = fw->createFormBuilder();
|
||||
Q_ASSERT(formBuilder);
|
||||
|
||||
QBuffer buffer;
|
||||
if (buffer.open(QIODevice::WriteOnly))
|
||||
if (formBuilder->copy(&buffer, clipboard))
|
||||
qApp->clipboard()->setText(QString::fromUtf8(buffer.buffer()), QClipboard::Clipboard);
|
||||
delete formBuilder;
|
||||
}
|
||||
|
||||
void ActionEditor::slotDelete()
|
||||
{
|
||||
QDesignerFormWindowInterface *fw = formWindow();
|
||||
if (!fw)
|
||||
return;
|
||||
|
||||
const ActionView::ActionList selection = m_actionView->selectedActions();
|
||||
if (selection.empty())
|
||||
return;
|
||||
|
||||
deleteActions(fw, selection);
|
||||
}
|
||||
|
||||
QString ActionEditor::actionTextToName(const QString &text, const QString &prefix)
|
||||
{
|
||||
QString name = text;
|
||||
if (name.isEmpty())
|
||||
return QString();
|
||||
|
||||
name[0] = name.at(0).toUpper();
|
||||
name.prepend(prefix);
|
||||
const QString underscore = QString(QLatin1Char('_'));
|
||||
name.replace(QRegExp(QString(QLatin1String("[^a-zA-Z_0-9]"))), underscore);
|
||||
name.replace(QRegExp(QLatin1String("__*")), underscore);
|
||||
if (name.endsWith(underscore.at(0)))
|
||||
name.truncate(name.size() - 1);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
void ActionEditor::resourceImageDropped(const QString &path, QAction *action)
|
||||
{
|
||||
QDesignerFormWindowInterface *fw = formWindow();
|
||||
if (!fw)
|
||||
return;
|
||||
|
||||
QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), action);
|
||||
const PropertySheetIconValue oldIcon =
|
||||
qVariantValue<PropertySheetIconValue>(sheet->property(sheet->indexOf(QLatin1String(iconPropertyC))));
|
||||
PropertySheetIconValue newIcon;
|
||||
newIcon.setPixmap(QIcon::Normal, QIcon::Off, PropertySheetPixmapValue(path));
|
||||
if (newIcon.paths().isEmpty() || newIcon.paths() == oldIcon.paths())
|
||||
return;
|
||||
|
||||
fw->commandHistory()->push(setIconPropertyCommand(newIcon , action, fw));
|
||||
}
|
||||
|
||||
void ActionEditor::mainContainerChanged()
|
||||
{
|
||||
// Invalidate references to objects kept in model
|
||||
if (sender() == formWindow())
|
||||
setFormWindow(0);
|
||||
}
|
||||
|
||||
void ActionEditor::slotViewMode(QAction *a)
|
||||
{
|
||||
m_actionView->setViewMode(a->data().toInt());
|
||||
updateViewModeActions();
|
||||
}
|
||||
|
||||
void ActionEditor::slotSelectAssociatedWidget(QWidget *w)
|
||||
{
|
||||
QDesignerFormWindowInterface *fw = formWindow();
|
||||
if (!fw )
|
||||
return;
|
||||
|
||||
QDesignerObjectInspector *oi = qobject_cast<QDesignerObjectInspector *>(core()->objectInspector());
|
||||
if (!oi)
|
||||
return;
|
||||
|
||||
fw->clearSelection(); // Actually, there are no widgets selected due to focus in event handling. Just to be sure.
|
||||
oi->selectObject(w);
|
||||
}
|
||||
|
||||
void ActionEditor::restoreSettings()
|
||||
{
|
||||
QDesignerSettingsInterface *settings = m_core->settingsManager();
|
||||
m_actionView->setViewMode(settings->value(QLatin1String(actionEditorViewModeKey), 0).toInt());
|
||||
updateViewModeActions();
|
||||
}
|
||||
|
||||
void ActionEditor::saveSettings()
|
||||
{
|
||||
QDesignerSettingsInterface *settings = m_core->settingsManager();
|
||||
settings->setValue(QLatin1String(actionEditorViewModeKey), m_actionView->viewMode());
|
||||
}
|
||||
|
||||
void ActionEditor::updateViewModeActions()
|
||||
{
|
||||
switch (m_actionView->viewMode()) {
|
||||
case ActionView::IconView:
|
||||
m_iconViewAction->setChecked(true);
|
||||
break;
|
||||
case ActionView::DetailedView:
|
||||
m_listViewAction->setChecked(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ActionEditor::slotCopy()
|
||||
{
|
||||
QDesignerFormWindowInterface *fw = formWindow();
|
||||
if (!fw )
|
||||
return;
|
||||
|
||||
const ActionView::ActionList selection = m_actionView->selectedActions();
|
||||
if (selection.empty())
|
||||
return;
|
||||
|
||||
copyActions(fw, selection);
|
||||
}
|
||||
|
||||
void ActionEditor::slotCut()
|
||||
{
|
||||
QDesignerFormWindowInterface *fw = formWindow();
|
||||
if (!fw )
|
||||
return;
|
||||
|
||||
const ActionView::ActionList selection = m_actionView->selectedActions();
|
||||
if (selection.empty())
|
||||
return;
|
||||
|
||||
copyActions(fw, selection);
|
||||
deleteActions(fw, selection);
|
||||
}
|
||||
|
||||
void ActionEditor::slotPaste()
|
||||
{
|
||||
FormWindowBase *fw = qobject_cast<FormWindowBase *>(formWindow());
|
||||
if (!fw)
|
||||
return;
|
||||
m_actionView->clearSelection();
|
||||
fw->paste(FormWindowBase::PasteActionsOnly);
|
||||
}
|
||||
|
||||
void ActionEditor::slotContextMenuRequested(QContextMenuEvent *e, QAction *item)
|
||||
{
|
||||
// set up signal mapper
|
||||
if (!m_selectAssociatedWidgetsMapper) {
|
||||
m_selectAssociatedWidgetsMapper = new QSignalMapper(this);
|
||||
connect(m_selectAssociatedWidgetsMapper, SIGNAL(mapped(QWidget*)), this, SLOT(slotSelectAssociatedWidget(QWidget*)));
|
||||
}
|
||||
|
||||
QMenu menu(this);
|
||||
menu.addAction(m_actionNew);
|
||||
menu.addSeparator();
|
||||
menu.addAction(m_actionEdit);
|
||||
if (QDesignerTaskMenu::isSlotNavigationEnabled(m_core))
|
||||
menu.addAction(m_actionNavigateToSlot);
|
||||
|
||||
// Associated Widgets
|
||||
if (QAction *action = m_actionView->currentAction()) {
|
||||
const QWidgetList associatedWidgets = ActionModel::associatedWidgets(action);
|
||||
if (!associatedWidgets.empty()) {
|
||||
QMenu *associatedWidgetsSubMenu = menu.addMenu(tr("Used In"));
|
||||
foreach (QWidget *w, associatedWidgets) {
|
||||
QAction *action = associatedWidgetsSubMenu->addAction(w->objectName());
|
||||
m_selectAssociatedWidgetsMapper->setMapping(action, w);
|
||||
connect(action, SIGNAL(triggered()), m_selectAssociatedWidgetsMapper, SLOT(map()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
menu.addSeparator();
|
||||
menu.addAction(m_actionCut);
|
||||
menu.addAction(m_actionCopy);
|
||||
menu.addAction(m_actionPaste);
|
||||
menu.addAction(m_actionSelectAll);
|
||||
menu.addAction(m_actionDelete);
|
||||
menu.addSeparator();
|
||||
menu.addAction(m_iconViewAction);
|
||||
menu.addAction(m_listViewAction);
|
||||
|
||||
emit contextMenuRequested(&menu, item);
|
||||
|
||||
menu.exec(e->globalPos());
|
||||
e->accept();
|
||||
}
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
168
third/designer/lib/shared/actioneditor_p.h
Normal file
168
third/designer/lib/shared/actioneditor_p.h
Normal file
@@ -0,0 +1,168 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef ACTIONEDITOR_H
|
||||
#define ACTIONEDITOR_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
#include <QtDesigner/QDesignerActionEditorInterface>
|
||||
|
||||
#include <QtCore/QPointer>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDesignerPropertyEditorInterface;
|
||||
class QDesignerSettingsInterface;
|
||||
class QMenu;
|
||||
class QActionGroup;
|
||||
class QSignalMapper;
|
||||
class QItemSelection;
|
||||
class QListWidget;
|
||||
class QPushButton;
|
||||
class QLineEdit;
|
||||
class QToolButton;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
class ActionView;
|
||||
class ResourceMimeData;
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT ActionEditor: public QDesignerActionEditorInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ActionEditor(QDesignerFormEditorInterface *core, QWidget *parent = 0, Qt::WindowFlags flags = 0);
|
||||
virtual ~ActionEditor();
|
||||
|
||||
QDesignerFormWindowInterface *formWindow() const;
|
||||
virtual void setFormWindow(QDesignerFormWindowInterface *formWindow);
|
||||
|
||||
virtual QDesignerFormEditorInterface *core() const;
|
||||
|
||||
QAction *actionNew() const;
|
||||
QAction *actionDelete() const;
|
||||
|
||||
QString filter() const;
|
||||
|
||||
virtual void manageAction(QAction *action);
|
||||
virtual void unmanageAction(QAction *action);
|
||||
|
||||
static QString actionTextToName(const QString &text, const QString &prefix = QLatin1String("action"));
|
||||
|
||||
// Utility to create a configure button with menu for usage on toolbars
|
||||
static QToolButton *createConfigureMenuButton(const QString &t, QMenu **ptrToMenu);
|
||||
|
||||
public slots:
|
||||
void setFilter(const QString &filter);
|
||||
void mainContainerChanged();
|
||||
|
||||
private slots:
|
||||
void slotCurrentItemChanged(QAction *item);
|
||||
void slotSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
|
||||
void editAction(QAction *item);
|
||||
void editCurrentAction();
|
||||
void navigateToSlotCurrentAction();
|
||||
void slotActionChanged();
|
||||
void slotNewAction();
|
||||
void slotDelete();
|
||||
void resourceImageDropped(const QString &path, QAction *action);
|
||||
void slotContextMenuRequested(QContextMenuEvent *, QAction *);
|
||||
void slotViewMode(QAction *a);
|
||||
void slotSelectAssociatedWidget(QWidget *w);
|
||||
void slotCopy();
|
||||
void slotCut();
|
||||
void slotPaste();
|
||||
|
||||
signals:
|
||||
void itemActivated(QAction *item);
|
||||
// Context menu for item or global menu if item == 0.
|
||||
void contextMenuRequested(QMenu *menu, QAction *item);
|
||||
|
||||
private:
|
||||
typedef QList<QAction *> ActionList;
|
||||
void deleteActions(QDesignerFormWindowInterface *formWindow, const ActionList &);
|
||||
void copyActions(QDesignerFormWindowInterface *formWindow, const ActionList &);
|
||||
|
||||
void restoreSettings();
|
||||
void saveSettings();
|
||||
|
||||
void updateViewModeActions();
|
||||
|
||||
QDesignerFormEditorInterface *m_core;
|
||||
QPointer<QDesignerFormWindowInterface> m_formWindow;
|
||||
QListWidget *m_actionGroups;
|
||||
|
||||
ActionView *m_actionView;
|
||||
|
||||
QAction *m_actionNew;
|
||||
QAction *m_actionEdit;
|
||||
QAction *m_actionNavigateToSlot;
|
||||
QAction *m_actionCopy;
|
||||
QAction *m_actionCut;
|
||||
QAction *m_actionPaste;
|
||||
QAction *m_actionSelectAll;
|
||||
QAction *m_actionDelete;
|
||||
|
||||
QActionGroup *m_viewModeGroup;
|
||||
QAction *m_iconViewAction;
|
||||
QAction *m_listViewAction;
|
||||
|
||||
QString m_filter;
|
||||
QWidget *m_filterWidget;
|
||||
QSignalMapper *m_selectAssociatedWidgetsMapper;
|
||||
};
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // ACTIONEDITOR_H
|
||||
108
third/designer/lib/shared/actionprovider_p.h
Normal file
108
third/designer/lib/shared/actionprovider_p.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef ACTIONPROVIDER_H
|
||||
#define ACTIONPROVIDER_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtDesigner/extension.h>
|
||||
#include <QtCore/QPoint>
|
||||
#include <QtCore/QRect>
|
||||
#include <QtGui/QApplication>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QAction;
|
||||
|
||||
class QDesignerActionProviderExtension
|
||||
{
|
||||
public:
|
||||
virtual ~QDesignerActionProviderExtension() {}
|
||||
|
||||
virtual QRect actionGeometry(QAction *action) const = 0;
|
||||
virtual QAction *actionAt(const QPoint &pos) const = 0;
|
||||
|
||||
virtual void adjustIndicator(const QPoint &pos) = 0;
|
||||
};
|
||||
|
||||
// Find action at the given position for a widget that has actionGeometry() (QToolBar,
|
||||
// QMenuBar, QMenu). They usually have actionAt(), but that fails since Designer usually sets
|
||||
// WA_TransparentForMouseEvents on the widgets.
|
||||
template <class Widget>
|
||||
int actionIndexAt(const Widget *w, const QPoint &pos, Qt::Orientation orientation)
|
||||
{
|
||||
const QList<QAction*> actions = w->actions();
|
||||
const int actionCount = actions.count();
|
||||
if (actionCount == 0)
|
||||
return -1;
|
||||
// actionGeometry() can be wrong sometimes; it returns a geometry that
|
||||
// stretches to the end of the toolbar/menu bar. So, check from the beginning
|
||||
// in the case of a horizontal right-to-left orientation.
|
||||
const bool checkTopRight = orientation == Qt::Horizontal && w->layoutDirection() == Qt::RightToLeft;
|
||||
const QPoint topRight = QPoint(w->rect().width(), 0);
|
||||
for (int index = 0; index < actionCount; ++index) {
|
||||
QRect g = w->actionGeometry(actions.at(index));
|
||||
if (checkTopRight)
|
||||
g.setTopRight(topRight);
|
||||
else
|
||||
g.setTopLeft(QPoint(0, 0));
|
||||
|
||||
if (g.contains(pos))
|
||||
return index;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Q_DECLARE_EXTENSION_INTERFACE(QDesignerActionProviderExtension, "com.trolltech.Qt.Designer.ActionProvider")
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // ACTIONPROVIDER_H
|
||||
663
third/designer/lib/shared/actionrepository.cpp
Normal file
663
third/designer/lib/shared/actionrepository.cpp
Normal file
@@ -0,0 +1,663 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "actionrepository_p.h"
|
||||
#include "qtresourceview_p.h"
|
||||
#include "iconloader_p.h"
|
||||
#include "qdesigner_utils_p.h"
|
||||
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
#include <QtDesigner/QDesignerPropertySheetExtension>
|
||||
#include <QtDesigner/QExtensionManager>
|
||||
|
||||
#include <QtGui/QDrag>
|
||||
#include <QtGui/QContextMenuEvent>
|
||||
#include <QtGui/QStandardItemModel>
|
||||
#include <QtGui/QToolButton>
|
||||
#include <QtGui/QPixmap>
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QHeaderView>
|
||||
#include <QtGui/QToolBar>
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtGui/qevent.h>
|
||||
#include <QtCore/QSet>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
Q_DECLARE_METATYPE(QAction*)
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace {
|
||||
enum { listModeIconSize = 16, iconModeIconSize = 24 };
|
||||
}
|
||||
|
||||
static const char *actionMimeType = "action-repository/actions";
|
||||
static const char *plainTextMimeType = "text/plain";
|
||||
|
||||
static inline QAction *actionOfItem(const QStandardItem* item)
|
||||
{
|
||||
return qvariant_cast<QAction*>(item->data(qdesigner_internal::ActionModel::ActionRole));
|
||||
}
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
// ----------- ActionModel
|
||||
ActionModel::ActionModel(QWidget *parent ) :
|
||||
QStandardItemModel(parent),
|
||||
m_emptyIcon(emptyIcon()),
|
||||
m_core(0)
|
||||
{
|
||||
QStringList headers;
|
||||
headers += tr("Name");
|
||||
headers += tr("Used");
|
||||
headers += tr("Text");
|
||||
headers += tr("Shortcut");
|
||||
headers += tr("Checkable");
|
||||
headers += tr("ToolTip");
|
||||
Q_ASSERT(NumColumns == headers.size());
|
||||
setHorizontalHeaderLabels(headers);
|
||||
}
|
||||
|
||||
void ActionModel::clearActions()
|
||||
{
|
||||
removeRows(0, rowCount());
|
||||
}
|
||||
|
||||
int ActionModel::findAction(QAction *action) const
|
||||
{
|
||||
const int rows = rowCount();
|
||||
for (int i = 0; i < rows; i++)
|
||||
if (action == actionOfItem(item(i)))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ActionModel::update(int row)
|
||||
{
|
||||
Q_ASSERT(m_core);
|
||||
// need to create the row list ... grrr..
|
||||
if (row >= rowCount())
|
||||
return;
|
||||
|
||||
QStandardItemList list;
|
||||
for (int i = 0; i < NumColumns; i++)
|
||||
list += item(row, i);
|
||||
|
||||
setItems(m_core, actionOfItem(list.front()), m_emptyIcon, list);
|
||||
}
|
||||
|
||||
void ActionModel::remove(int row)
|
||||
{
|
||||
qDeleteAll(takeRow(row));
|
||||
}
|
||||
|
||||
QModelIndex ActionModel::addAction(QAction *action)
|
||||
{
|
||||
Q_ASSERT(m_core);
|
||||
QStandardItemList items;
|
||||
const Qt::ItemFlags flags = Qt::ItemIsSelectable|Qt::ItemIsDropEnabled|Qt::ItemIsDragEnabled|Qt::ItemIsEnabled;
|
||||
|
||||
QVariant itemData;
|
||||
qVariantSetValue(itemData, action);
|
||||
|
||||
for (int i = 0; i < NumColumns; i++) {
|
||||
QStandardItem *item = new QStandardItem;
|
||||
item->setData(itemData, ActionRole);
|
||||
item->setFlags(flags);
|
||||
items.push_back(item);
|
||||
}
|
||||
setItems(m_core, action, m_emptyIcon, items);
|
||||
appendRow(items);
|
||||
return indexFromItem(items.front());
|
||||
}
|
||||
|
||||
// Find the associated menus and toolbars, ignore toolbuttons
|
||||
QWidgetList ActionModel::associatedWidgets(const QAction *action)
|
||||
{
|
||||
QWidgetList rc = action->associatedWidgets();
|
||||
for (QWidgetList::iterator it = rc.begin(); it != rc.end(); )
|
||||
if (qobject_cast<const QMenu *>(*it) || qobject_cast<const QToolBar *>(*it)) {
|
||||
++it;
|
||||
} else {
|
||||
it = rc.erase(it);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
// shortcut is a fake property, need to retrieve it via property sheet.
|
||||
PropertySheetKeySequenceValue ActionModel::actionShortCut(QDesignerFormEditorInterface *core, QAction *action)
|
||||
{
|
||||
QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), action);
|
||||
if (!sheet)
|
||||
return PropertySheetKeySequenceValue();
|
||||
return actionShortCut(sheet);
|
||||
}
|
||||
|
||||
PropertySheetKeySequenceValue ActionModel::actionShortCut(const QDesignerPropertySheetExtension *sheet)
|
||||
{
|
||||
const int index = sheet->indexOf(QLatin1String("shortcut"));
|
||||
if (index == -1)
|
||||
return PropertySheetKeySequenceValue();
|
||||
return qvariant_cast<PropertySheetKeySequenceValue>(sheet->property(index));
|
||||
}
|
||||
|
||||
void ActionModel::setItems(QDesignerFormEditorInterface *core, QAction *action,
|
||||
const QIcon &defaultIcon,
|
||||
QStandardItemList &sl)
|
||||
{
|
||||
|
||||
// Tooltip, mostly for icon view mode
|
||||
QString firstTooltip = action->objectName();
|
||||
const QString text = action->text();
|
||||
if (!text.isEmpty()) {
|
||||
firstTooltip += QLatin1Char('\n');
|
||||
firstTooltip += text;
|
||||
}
|
||||
|
||||
Q_ASSERT(sl.size() == NumColumns);
|
||||
|
||||
QStandardItem *item = sl[NameColumn];
|
||||
item->setText(action->objectName());
|
||||
QIcon icon = action->icon();
|
||||
if (icon.isNull())
|
||||
icon = defaultIcon;
|
||||
item->setIcon(icon);
|
||||
item->setToolTip(firstTooltip);
|
||||
item->setWhatsThis(firstTooltip);
|
||||
// Used
|
||||
const QWidgetList associatedDesignerWidgets = associatedWidgets(action);
|
||||
const bool used = !associatedDesignerWidgets.empty();
|
||||
item = sl[UsedColumn];
|
||||
item->setCheckState(used ? Qt::Checked : Qt::Unchecked);
|
||||
if (used) {
|
||||
QString usedToolTip;
|
||||
const QString separator = QLatin1String(", ");
|
||||
const int count = associatedDesignerWidgets.size();
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (i)
|
||||
usedToolTip += separator;
|
||||
usedToolTip += associatedDesignerWidgets.at(i)->objectName();
|
||||
}
|
||||
item->setToolTip(usedToolTip);
|
||||
} else {
|
||||
item->setToolTip(QString());
|
||||
}
|
||||
// text
|
||||
item = sl[TextColumn];
|
||||
item->setText(action->text());
|
||||
item->setToolTip(action->text());
|
||||
// shortcut
|
||||
const QString shortcut = actionShortCut(core, action).value().toString(QKeySequence::NativeText);
|
||||
item = sl[ShortCutColumn];
|
||||
item->setText(shortcut);
|
||||
item->setToolTip(shortcut);
|
||||
// checkable
|
||||
sl[CheckedColumn]->setCheckState(action->isCheckable() ? Qt::Checked : Qt::Unchecked);
|
||||
// ToolTip. This might be multi-line, rich text
|
||||
QString toolTip = action->toolTip();
|
||||
item = sl[ToolTipColumn];
|
||||
item->setToolTip(toolTip);
|
||||
item->setText(toolTip.replace(QLatin1Char('\n'), QLatin1Char(' ')));
|
||||
}
|
||||
|
||||
QMimeData *ActionModel::mimeData(const QModelIndexList &indexes ) const
|
||||
{
|
||||
ActionRepositoryMimeData::ActionList actionList;
|
||||
|
||||
QSet<QAction*> actions;
|
||||
foreach (const QModelIndex &index, indexes)
|
||||
if (QStandardItem *item = itemFromIndex(index))
|
||||
if (QAction *action = actionOfItem(item))
|
||||
actions.insert(action);
|
||||
return new ActionRepositoryMimeData(actions.toList(), Qt::CopyAction);
|
||||
}
|
||||
|
||||
// Resource images are plain text. The drag needs to be restricted, however.
|
||||
QStringList ActionModel::mimeTypes() const
|
||||
{
|
||||
return QStringList(QLatin1String(plainTextMimeType));
|
||||
}
|
||||
|
||||
QString ActionModel::actionName(int row) const
|
||||
{
|
||||
return item(row, NameColumn)->text();
|
||||
}
|
||||
|
||||
bool ActionModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &)
|
||||
{
|
||||
if (action != Qt::CopyAction)
|
||||
return false;
|
||||
|
||||
QStandardItem *droppedItem = item(row, column);
|
||||
if (!droppedItem)
|
||||
return false;
|
||||
|
||||
|
||||
QtResourceView::ResourceType type;
|
||||
QString path;
|
||||
if (!QtResourceView::decodeMimeData(data, &type, &path) || type != QtResourceView::ResourceImage)
|
||||
return false;
|
||||
|
||||
emit resourceImageDropped(path, actionOfItem(droppedItem));
|
||||
return true;
|
||||
}
|
||||
|
||||
QAction *ActionModel::actionAt(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return 0;
|
||||
QStandardItem *i = itemFromIndex(index);
|
||||
if (!i)
|
||||
return 0;
|
||||
return actionOfItem(i);
|
||||
}
|
||||
|
||||
// helpers
|
||||
|
||||
static bool handleImageDragEnterMoveEvent(QDropEvent *event)
|
||||
{
|
||||
QtResourceView::ResourceType type;
|
||||
const bool rc = QtResourceView::decodeMimeData(event->mimeData(), &type) && type == QtResourceView::ResourceImage;
|
||||
if (rc)
|
||||
event->acceptProposedAction();
|
||||
else
|
||||
event->ignore();
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void handleImageDropEvent(const QAbstractItemView *iv, QDropEvent *event, ActionModel *am)
|
||||
{
|
||||
const QModelIndex index = iv->indexAt(event->pos());
|
||||
if (!index.isValid()) {
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!handleImageDragEnterMoveEvent(event))
|
||||
return;
|
||||
|
||||
am->dropMimeData(event->mimeData(), event->proposedAction(), index.row(), 0, iv->rootIndex());
|
||||
}
|
||||
|
||||
// Basically mimic QAbstractItemView's startDrag routine, except that
|
||||
// another pixmap is used, we don't want the whole row.
|
||||
|
||||
void startActionDrag(QWidget *dragParent, ActionModel *model, const QModelIndexList &indexes, Qt::DropActions supportedActions)
|
||||
{
|
||||
if (indexes.empty())
|
||||
return;
|
||||
|
||||
QDrag *drag = new QDrag(dragParent);
|
||||
QMimeData *data = model->mimeData(indexes);
|
||||
drag->setMimeData(data);
|
||||
if (ActionRepositoryMimeData *actionMimeData = qobject_cast<ActionRepositoryMimeData *>(data))
|
||||
drag->setPixmap(ActionRepositoryMimeData::actionDragPixmap(actionMimeData->actionList().front()));
|
||||
|
||||
drag->start(supportedActions);
|
||||
}
|
||||
|
||||
// ---------------- ActionTreeView:
|
||||
ActionTreeView::ActionTreeView(ActionModel *model, QWidget *parent) :
|
||||
QTreeView(parent),
|
||||
m_model(model)
|
||||
{
|
||||
setDragEnabled(true);
|
||||
setAcceptDrops(true);
|
||||
setDropIndicatorShown(true);
|
||||
setDragDropMode(DragDrop);
|
||||
setModel(model);
|
||||
setRootIsDecorated(false);
|
||||
setTextElideMode(Qt::ElideMiddle);
|
||||
|
||||
setModel(model);
|
||||
connect(this, SIGNAL(activated(QModelIndex)), this, SLOT(slotActivated(QModelIndex)));
|
||||
connect(header(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(resizeColumnToContents(int)));
|
||||
|
||||
setIconSize(QSize(listModeIconSize, listModeIconSize));
|
||||
|
||||
}
|
||||
|
||||
QAction *ActionTreeView::currentAction() const
|
||||
{
|
||||
return m_model->actionAt(currentIndex());
|
||||
}
|
||||
|
||||
void ActionTreeView::filter(const QString &text)
|
||||
{
|
||||
const int rowCount = m_model->rowCount();
|
||||
const bool empty = text.isEmpty();
|
||||
const QModelIndex parent = rootIndex();
|
||||
for (int i = 0; i < rowCount; i++)
|
||||
setRowHidden(i, parent, !empty && !m_model->actionName(i).contains(text, Qt::CaseInsensitive));
|
||||
}
|
||||
|
||||
void ActionTreeView::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
handleImageDragEnterMoveEvent(event);
|
||||
}
|
||||
|
||||
void ActionTreeView::dragMoveEvent(QDragMoveEvent *event)
|
||||
{
|
||||
handleImageDragEnterMoveEvent(event);
|
||||
}
|
||||
|
||||
void ActionTreeView::dropEvent(QDropEvent *event)
|
||||
{
|
||||
handleImageDropEvent(this, event, m_model);
|
||||
}
|
||||
|
||||
void ActionTreeView::focusInEvent(QFocusEvent *event)
|
||||
{
|
||||
QTreeView::focusInEvent(event);
|
||||
// Make property editor display current action
|
||||
if (QAction *a = currentAction())
|
||||
emit currentChanged(a);
|
||||
}
|
||||
|
||||
void ActionTreeView::contextMenuEvent(QContextMenuEvent *event)
|
||||
{
|
||||
emit contextMenuRequested(event, m_model->actionAt(indexAt(event->pos())));
|
||||
}
|
||||
|
||||
void ActionTreeView::currentChanged(const QModelIndex ¤t, const QModelIndex &/*previous*/)
|
||||
{
|
||||
emit currentChanged(m_model->actionAt(current));
|
||||
}
|
||||
|
||||
void ActionTreeView::slotActivated(const QModelIndex &index)
|
||||
{
|
||||
emit activated(m_model->actionAt(index));
|
||||
}
|
||||
|
||||
void ActionTreeView::startDrag(Qt::DropActions supportedActions)
|
||||
{
|
||||
startActionDrag(this, m_model, selectedIndexes(), supportedActions);
|
||||
}
|
||||
|
||||
// ---------------- ActionListView:
|
||||
ActionListView::ActionListView(ActionModel *model, QWidget *parent) :
|
||||
QListView(parent),
|
||||
m_model(model)
|
||||
{
|
||||
setDragEnabled(true);
|
||||
setAcceptDrops(true);
|
||||
setDropIndicatorShown(true);
|
||||
setDragDropMode(DragDrop);
|
||||
setModel(model);
|
||||
setTextElideMode(Qt::ElideMiddle);
|
||||
connect(this, SIGNAL(activated(QModelIndex)), this, SLOT(slotActivated(QModelIndex)));
|
||||
|
||||
// We actually want 'Static' as the user should be able to
|
||||
// drag away actions only (not to rearrange icons).
|
||||
// We emulate that by not accepting our own
|
||||
// drag data. 'Static' causes the list view to disable drag and drop
|
||||
// on the viewport.
|
||||
setMovement(Snap);
|
||||
setViewMode(IconMode);
|
||||
setIconSize(QSize(iconModeIconSize, iconModeIconSize));
|
||||
setGridSize(QSize(4 * iconModeIconSize, 2 * iconModeIconSize));
|
||||
setSpacing(iconModeIconSize / 3);
|
||||
}
|
||||
|
||||
QAction *ActionListView::currentAction() const
|
||||
{
|
||||
return m_model->actionAt(currentIndex());
|
||||
}
|
||||
|
||||
void ActionListView::filter(const QString &text)
|
||||
{
|
||||
const int rowCount = m_model->rowCount();
|
||||
const bool empty = text.isEmpty();
|
||||
for (int i = 0; i < rowCount; i++)
|
||||
setRowHidden(i, !empty && !m_model->actionName(i).contains(text, Qt::CaseInsensitive));
|
||||
}
|
||||
|
||||
void ActionListView::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
handleImageDragEnterMoveEvent(event);
|
||||
}
|
||||
|
||||
void ActionListView::dragMoveEvent(QDragMoveEvent *event)
|
||||
{
|
||||
handleImageDragEnterMoveEvent(event);
|
||||
}
|
||||
|
||||
void ActionListView::dropEvent(QDropEvent *event)
|
||||
{
|
||||
handleImageDropEvent(this, event, m_model);
|
||||
}
|
||||
|
||||
void ActionListView::focusInEvent(QFocusEvent *event)
|
||||
{
|
||||
QListView::focusInEvent(event);
|
||||
// Make property editor display current action
|
||||
if (QAction *a = currentAction())
|
||||
emit currentChanged(a);
|
||||
}
|
||||
|
||||
void ActionListView::contextMenuEvent(QContextMenuEvent *event)
|
||||
{
|
||||
emit contextMenuRequested(event, m_model->actionAt(indexAt(event->pos())));
|
||||
}
|
||||
|
||||
void ActionListView::currentChanged(const QModelIndex ¤t, const QModelIndex & /*previous*/)
|
||||
{
|
||||
emit currentChanged(m_model->actionAt(current));
|
||||
}
|
||||
|
||||
void ActionListView::slotActivated(const QModelIndex &index)
|
||||
{
|
||||
emit activated(m_model->actionAt(index));
|
||||
}
|
||||
|
||||
void ActionListView::startDrag(Qt::DropActions supportedActions)
|
||||
{
|
||||
startActionDrag(this, m_model, selectedIndexes(), supportedActions);
|
||||
}
|
||||
|
||||
// ActionView
|
||||
ActionView::ActionView(QWidget *parent) :
|
||||
QStackedWidget(parent),
|
||||
m_model(new ActionModel(this)),
|
||||
m_actionTreeView(new ActionTreeView(m_model)),
|
||||
m_actionListView(new ActionListView(m_model))
|
||||
{
|
||||
addWidget(m_actionListView);
|
||||
addWidget(m_actionTreeView);
|
||||
// Wire signals
|
||||
connect(m_actionTreeView, SIGNAL(contextMenuRequested(QContextMenuEvent*,QAction*)),
|
||||
this, SIGNAL(contextMenuRequested(QContextMenuEvent*,QAction*)));
|
||||
connect(m_actionListView, SIGNAL(contextMenuRequested(QContextMenuEvent*,QAction*)),
|
||||
this, SIGNAL(contextMenuRequested(QContextMenuEvent*,QAction*)));
|
||||
|
||||
// make it possible for vs integration to reimplement edit action dialog
|
||||
// [which it shouldn't do actually]
|
||||
connect(m_actionListView, SIGNAL(activated(QAction*)), this, SIGNAL(activated(QAction*)));
|
||||
connect(m_actionTreeView, SIGNAL(activated(QAction*)), this, SIGNAL(activated(QAction*)));
|
||||
|
||||
connect(m_actionListView, SIGNAL(currentChanged(QAction*)),this, SLOT(slotCurrentChanged(QAction*)));
|
||||
connect(m_actionTreeView, SIGNAL(currentChanged(QAction*)),this, SLOT(slotCurrentChanged(QAction*)));
|
||||
|
||||
connect(m_model, SIGNAL(resourceImageDropped(QString,QAction*)),
|
||||
this, SIGNAL(resourceImageDropped(QString,QAction*)));
|
||||
|
||||
// sync selection models
|
||||
QItemSelectionModel *selectionModel = m_actionTreeView->selectionModel();
|
||||
m_actionListView->setSelectionModel(selectionModel);
|
||||
connect(selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
||||
this, SIGNAL(selectionChanged(QItemSelection,QItemSelection)));
|
||||
}
|
||||
|
||||
int ActionView::viewMode() const
|
||||
{
|
||||
return currentWidget() == m_actionListView ? IconView : DetailedView;
|
||||
}
|
||||
|
||||
void ActionView::setViewMode(int lm)
|
||||
{
|
||||
if (viewMode() == lm)
|
||||
return;
|
||||
|
||||
switch (lm) {
|
||||
case IconView:
|
||||
setCurrentWidget(m_actionListView);
|
||||
break;
|
||||
case DetailedView:
|
||||
setCurrentWidget(m_actionTreeView);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ActionView::slotCurrentChanged(QAction *action)
|
||||
{
|
||||
// emit only for currently visible
|
||||
if (sender() == currentWidget())
|
||||
emit currentChanged(action);
|
||||
}
|
||||
|
||||
void ActionView::filter(const QString &text)
|
||||
{
|
||||
m_actionTreeView->filter(text);
|
||||
m_actionListView->filter(text);
|
||||
}
|
||||
|
||||
void ActionView::selectAll()
|
||||
{
|
||||
m_actionTreeView->selectAll();
|
||||
}
|
||||
|
||||
void ActionView::clearSelection()
|
||||
{
|
||||
m_actionTreeView->selectionModel()->clearSelection();
|
||||
}
|
||||
|
||||
void ActionView::setCurrentIndex(const QModelIndex &index)
|
||||
{
|
||||
m_actionTreeView->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
QAction *ActionView::currentAction() const
|
||||
{
|
||||
return m_actionListView->currentAction();
|
||||
}
|
||||
|
||||
void ActionView::setSelectionMode(QAbstractItemView::SelectionMode sm)
|
||||
{
|
||||
m_actionTreeView->setSelectionMode(sm);
|
||||
m_actionListView->setSelectionMode(sm);
|
||||
}
|
||||
|
||||
QAbstractItemView::SelectionMode ActionView::selectionMode() const
|
||||
{
|
||||
return m_actionListView->selectionMode();
|
||||
}
|
||||
|
||||
QItemSelection ActionView::selection() const
|
||||
{
|
||||
return m_actionListView->selectionModel()->selection();
|
||||
}
|
||||
|
||||
ActionView::ActionList ActionView::selectedActions() const
|
||||
{
|
||||
ActionList rc;
|
||||
foreach (const QModelIndex &index, selection().indexes())
|
||||
if (index.column() == 0)
|
||||
rc += actionOfItem(m_model->itemFromIndex(index));
|
||||
return rc;
|
||||
}
|
||||
// ---------- ActionRepositoryMimeData
|
||||
ActionRepositoryMimeData::ActionRepositoryMimeData(QAction *a, Qt::DropAction dropAction) :
|
||||
m_dropAction(dropAction)
|
||||
{
|
||||
m_actionList += a;
|
||||
}
|
||||
|
||||
ActionRepositoryMimeData::ActionRepositoryMimeData(const ActionList &al, Qt::DropAction dropAction) :
|
||||
m_dropAction(dropAction),
|
||||
m_actionList(al)
|
||||
{
|
||||
}
|
||||
|
||||
QStringList ActionRepositoryMimeData::formats() const
|
||||
{
|
||||
return QStringList(QLatin1String(actionMimeType));
|
||||
}
|
||||
|
||||
QPixmap ActionRepositoryMimeData::actionDragPixmap(const QAction *action)
|
||||
{
|
||||
|
||||
// Try to find a suitable pixmap. Grab either widget or icon.
|
||||
const QIcon icon = action->icon();
|
||||
if (!icon.isNull())
|
||||
return icon.pixmap(QSize(22, 22));
|
||||
|
||||
foreach (QWidget *w, action->associatedWidgets())
|
||||
if (QToolButton *tb = qobject_cast<QToolButton *>(w))
|
||||
return QPixmap::grabWidget(tb);
|
||||
|
||||
// Create a QToolButton
|
||||
QToolButton *tb = new QToolButton;
|
||||
tb->setText(action->text());
|
||||
tb->setToolButtonStyle(Qt::ToolButtonTextOnly);
|
||||
#ifdef Q_WS_WIN // Force alien off to make adjustSize() take the system minimumsize into account.
|
||||
tb->createWinId();
|
||||
#endif
|
||||
tb->adjustSize();
|
||||
const QPixmap rc = QPixmap::grabWidget(tb);
|
||||
tb->deleteLater();
|
||||
return rc;
|
||||
}
|
||||
|
||||
void ActionRepositoryMimeData::accept(QDragMoveEvent *event) const
|
||||
{
|
||||
if (event->proposedAction() == m_dropAction) {
|
||||
event->acceptProposedAction();
|
||||
} else {
|
||||
event->setDropAction(m_dropAction);
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
269
third/designer/lib/shared/actionrepository_p.h
Normal file
269
third/designer/lib/shared/actionrepository_p.h
Normal file
@@ -0,0 +1,269 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef ACTIONREPOSITORY_H
|
||||
#define ACTIONREPOSITORY_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
#include <QtCore/QMimeData>
|
||||
#include <QtGui/QStandardItemModel>
|
||||
#include <QtGui/QTreeView>
|
||||
#include <QtGui/QListView>
|
||||
#include <QtGui/QStackedWidget>
|
||||
#include <QtGui/QIcon>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QPixmap;
|
||||
|
||||
class QDesignerFormEditorInterface;
|
||||
class QDesignerPropertySheetExtension;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
class PropertySheetKeySequenceValue;
|
||||
|
||||
// Shared model of actions, to be used for several views (detailed/icon view).
|
||||
class QDESIGNER_SHARED_EXPORT ActionModel: public QStandardItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Columns { NameColumn, UsedColumn, TextColumn, ShortCutColumn, CheckedColumn, ToolTipColumn, NumColumns };
|
||||
enum { ActionRole = Qt::UserRole + 1000 };
|
||||
|
||||
explicit ActionModel(QWidget *parent = 0);
|
||||
void initialize(QDesignerFormEditorInterface *core) { m_core = core; }
|
||||
|
||||
void clearActions();
|
||||
QModelIndex addAction(QAction *a);
|
||||
// remove row
|
||||
void remove(int row);
|
||||
// update the row from the underlying action
|
||||
void update(int row);
|
||||
|
||||
// return row of action or -1.
|
||||
int findAction(QAction *) const;
|
||||
|
||||
QString actionName(int row) const;
|
||||
QAction *actionAt(const QModelIndex &index) const;
|
||||
|
||||
virtual QMimeData *mimeData(const QModelIndexList &indexes) const;
|
||||
virtual QStringList mimeTypes() const;
|
||||
virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
|
||||
|
||||
// Find the associated menus and toolbars, ignore toolbuttons
|
||||
static QWidgetList associatedWidgets(const QAction *action);
|
||||
|
||||
// Retrieve shortcut via property sheet as it is a fake property
|
||||
static PropertySheetKeySequenceValue actionShortCut(QDesignerFormEditorInterface *core, QAction *action);
|
||||
static PropertySheetKeySequenceValue actionShortCut(const QDesignerPropertySheetExtension *ps);
|
||||
|
||||
signals:
|
||||
void resourceImageDropped(const QString &path, QAction *action);
|
||||
|
||||
private:
|
||||
typedef QList<QStandardItem *> QStandardItemList;
|
||||
|
||||
void initializeHeaders();
|
||||
static void setItems(QDesignerFormEditorInterface *core, QAction *a,
|
||||
const QIcon &defaultIcon,
|
||||
QStandardItemList &sl);
|
||||
|
||||
const QIcon m_emptyIcon;
|
||||
|
||||
QDesignerFormEditorInterface *m_core;
|
||||
};
|
||||
|
||||
// Internal class that provides the detailed view of actions.
|
||||
class ActionTreeView: public QTreeView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ActionTreeView(ActionModel *model, QWidget *parent = 0);
|
||||
QAction *currentAction() const;
|
||||
|
||||
public slots:
|
||||
void filter(const QString &text);
|
||||
|
||||
signals:
|
||||
void contextMenuRequested(QContextMenuEvent *event, QAction *);
|
||||
void currentChanged(QAction *action);
|
||||
void activated(QAction *action);
|
||||
|
||||
protected slots:
|
||||
virtual void currentChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
|
||||
protected:
|
||||
virtual void dragEnterEvent(QDragEnterEvent *event);
|
||||
virtual void dragMoveEvent(QDragMoveEvent *event);
|
||||
virtual void dropEvent(QDropEvent *event);
|
||||
virtual void focusInEvent(QFocusEvent *event);
|
||||
virtual void contextMenuEvent(QContextMenuEvent *event);
|
||||
virtual void startDrag(Qt::DropActions supportedActions);
|
||||
|
||||
private slots:
|
||||
void slotActivated(const QModelIndex &);
|
||||
|
||||
private:
|
||||
ActionModel *m_model;
|
||||
};
|
||||
|
||||
// Internal class that provides the icon view of actions.
|
||||
class ActionListView: public QListView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ActionListView(ActionModel *model, QWidget *parent = 0);
|
||||
QAction *currentAction() const;
|
||||
|
||||
public slots:
|
||||
void filter(const QString &text);
|
||||
|
||||
signals:
|
||||
void contextMenuRequested(QContextMenuEvent *event, QAction *);
|
||||
void currentChanged(QAction *action);
|
||||
void activated(QAction *action);
|
||||
|
||||
protected slots:
|
||||
virtual void currentChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
|
||||
protected:
|
||||
virtual void dragEnterEvent(QDragEnterEvent *event);
|
||||
virtual void dragMoveEvent(QDragMoveEvent *event);
|
||||
virtual void dropEvent(QDropEvent *event);
|
||||
virtual void focusInEvent(QFocusEvent *event);
|
||||
virtual void contextMenuEvent(QContextMenuEvent *event);
|
||||
virtual void startDrag(Qt::DropActions supportedActions);
|
||||
|
||||
private slots:
|
||||
void slotActivated(const QModelIndex &);
|
||||
|
||||
private:
|
||||
ActionModel *m_model;
|
||||
};
|
||||
|
||||
// Action View that can be switched between detailed and icon view
|
||||
// using a QStackedWidget of ActionListView / ActionTreeView
|
||||
// that share the item model and the selection model.
|
||||
|
||||
class ActionView : public QStackedWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
// Separate initialize() function takes core argument to make this
|
||||
// thing usable as promoted widget.
|
||||
explicit ActionView(QWidget *parent = 0);
|
||||
void initialize(QDesignerFormEditorInterface *core) { m_model->initialize(core); }
|
||||
|
||||
// View mode
|
||||
enum { DetailedView, IconView };
|
||||
int viewMode() const;
|
||||
void setViewMode(int lm);
|
||||
|
||||
void setSelectionMode(QAbstractItemView::SelectionMode sm);
|
||||
QAbstractItemView::SelectionMode selectionMode() const;
|
||||
|
||||
ActionModel *model() const { return m_model; }
|
||||
|
||||
QAction *currentAction() const;
|
||||
void setCurrentIndex(const QModelIndex &index);
|
||||
|
||||
typedef QList<QAction*> ActionList;
|
||||
ActionList selectedActions() const;
|
||||
QItemSelection selection() const;
|
||||
|
||||
public slots:
|
||||
void filter(const QString &text);
|
||||
void selectAll();
|
||||
void clearSelection();
|
||||
|
||||
signals:
|
||||
void contextMenuRequested(QContextMenuEvent *event, QAction *);
|
||||
void currentChanged(QAction *action);
|
||||
void activated(QAction *action);
|
||||
void selectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
|
||||
void resourceImageDropped(const QString &data, QAction *action);
|
||||
|
||||
private slots:
|
||||
void slotCurrentChanged(QAction *action);
|
||||
|
||||
private:
|
||||
ActionModel *m_model;
|
||||
ActionTreeView *m_actionTreeView;
|
||||
ActionListView *m_actionListView;
|
||||
};
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT ActionRepositoryMimeData: public QMimeData
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
typedef QList<QAction*> ActionList;
|
||||
|
||||
ActionRepositoryMimeData(const ActionList &, Qt::DropAction dropAction);
|
||||
ActionRepositoryMimeData(QAction *, Qt::DropAction dropAction);
|
||||
|
||||
const ActionList &actionList() const { return m_actionList; }
|
||||
virtual QStringList formats() const;
|
||||
|
||||
static QPixmap actionDragPixmap(const QAction *action);
|
||||
|
||||
// Utility to accept with right action
|
||||
void accept(QDragMoveEvent *event) const;
|
||||
private:
|
||||
const Qt::DropAction m_dropAction;
|
||||
ActionList m_actionList;
|
||||
};
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // ACTIONREPOSITORY_H
|
||||
112
third/designer/lib/shared/addlinkdialog.ui
Normal file
112
third/designer/lib/shared/addlinkdialog.ui
Normal file
@@ -0,0 +1,112 @@
|
||||
<ui version="4.0" >
|
||||
<class>AddLinkDialog</class>
|
||||
<widget class="QDialog" name="AddLinkDialog" >
|
||||
<property name="windowTitle" >
|
||||
<string>Insert Link</string>
|
||||
</property>
|
||||
<property name="sizeGripEnabled" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="modal" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" >
|
||||
<item>
|
||||
<layout class="QFormLayout" >
|
||||
<item row="0" column="0" >
|
||||
<widget class="QLabel" name="label" >
|
||||
<property name="text" >
|
||||
<string>Title:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" >
|
||||
<widget class="QLineEdit" name="titleInput" >
|
||||
<property name="minimumSize" >
|
||||
<size>
|
||||
<width>337</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" >
|
||||
<widget class="QLabel" name="label_2" >
|
||||
<property name="text" >
|
||||
<string>URL:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" >
|
||||
<widget class="QLineEdit" name="urlInput" />
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer" >
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0" >
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line" >
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox" >
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons" >
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>AddLinkDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>AddLinkDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
262
third/designer/lib/shared/codedialog.cpp
Normal file
262
third/designer/lib/shared/codedialog.cpp
Normal file
@@ -0,0 +1,262 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "codedialog_p.h"
|
||||
#include "qdesigner_utils_p.h"
|
||||
#include "iconloader_p.h"
|
||||
|
||||
#include <texteditfindwidget.h>
|
||||
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtGui/QClipboard>
|
||||
#include <QtGui/QDialogButtonBox>
|
||||
#include <QtGui/QFileDialog>
|
||||
#include <QtGui/QIcon>
|
||||
#include <QtGui/QKeyEvent>
|
||||
#include <QtGui/QMessageBox>
|
||||
#include <QtGui/QPushButton>
|
||||
#include <QtGui/QTextEdit>
|
||||
#include <QtGui/QToolBar>
|
||||
#include <QtGui/QVBoxLayout>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QTemporaryFile>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
// ----------------- CodeDialogPrivate
|
||||
struct CodeDialog::CodeDialogPrivate {
|
||||
CodeDialogPrivate();
|
||||
|
||||
QTextEdit *m_textEdit;
|
||||
TextEditFindWidget *m_findWidget;
|
||||
QString m_formFileName;
|
||||
};
|
||||
|
||||
CodeDialog::CodeDialogPrivate::CodeDialogPrivate()
|
||||
: m_textEdit(new QTextEdit)
|
||||
, m_findWidget(new TextEditFindWidget)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------- CodeDialog
|
||||
CodeDialog::CodeDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
m_impl(new CodeDialogPrivate)
|
||||
{
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
QVBoxLayout *vBoxLayout = new QVBoxLayout;
|
||||
|
||||
// Edit tool bar
|
||||
QToolBar *toolBar = new QToolBar;
|
||||
|
||||
const QIcon saveIcon = createIconSet(QLatin1String("filesave.png"));
|
||||
QAction *saveAction = toolBar->addAction(saveIcon, tr("Save..."));
|
||||
connect(saveAction, SIGNAL(triggered()), this, SLOT(slotSaveAs()));
|
||||
|
||||
const QIcon copyIcon = createIconSet(QLatin1String("editcopy.png"));
|
||||
QAction *copyAction = toolBar->addAction(copyIcon, tr("Copy All"));
|
||||
connect(copyAction, SIGNAL(triggered()), this, SLOT(copyAll()));
|
||||
|
||||
QAction *findAction = toolBar->addAction(
|
||||
TextEditFindWidget::findIconSet(),
|
||||
tr("&Find in Text..."),
|
||||
m_impl->m_findWidget, SLOT(activate()));
|
||||
findAction->setShortcut(QKeySequence::Find);
|
||||
|
||||
vBoxLayout->addWidget(toolBar);
|
||||
|
||||
// Edit
|
||||
m_impl->m_textEdit->setReadOnly(true);
|
||||
m_impl->m_textEdit->setMinimumSize(QSize(
|
||||
m_impl->m_findWidget->minimumSize().width(),
|
||||
500));
|
||||
vBoxLayout->addWidget(m_impl->m_textEdit);
|
||||
|
||||
// Find
|
||||
m_impl->m_findWidget->setTextEdit(m_impl->m_textEdit);
|
||||
vBoxLayout->addWidget(m_impl->m_findWidget);
|
||||
|
||||
// Button box
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
|
||||
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
|
||||
// Disable auto default
|
||||
QPushButton *closeButton = buttonBox->button(QDialogButtonBox::Close);
|
||||
closeButton->setAutoDefault(false);
|
||||
vBoxLayout->addWidget(buttonBox);
|
||||
|
||||
setLayout(vBoxLayout);
|
||||
}
|
||||
|
||||
CodeDialog::~CodeDialog()
|
||||
{
|
||||
delete m_impl;
|
||||
}
|
||||
|
||||
void CodeDialog::setCode(const QString &code)
|
||||
{
|
||||
m_impl->m_textEdit->setPlainText(code);
|
||||
}
|
||||
|
||||
QString CodeDialog::code() const
|
||||
{
|
||||
return m_impl->m_textEdit->toPlainText();
|
||||
}
|
||||
|
||||
void CodeDialog::setFormFileName(const QString &f)
|
||||
{
|
||||
m_impl->m_formFileName = f;
|
||||
}
|
||||
|
||||
QString CodeDialog::formFileName() const
|
||||
{
|
||||
return m_impl->m_formFileName;
|
||||
}
|
||||
|
||||
bool CodeDialog::generateCode(const QDesignerFormWindowInterface *fw,
|
||||
QString *code,
|
||||
QString *errorMessage)
|
||||
{
|
||||
// Generate temporary file name similar to form file name
|
||||
// (for header guards)
|
||||
QString tempPattern = QDir::tempPath();
|
||||
if (!tempPattern.endsWith(QDir::separator())) // platform-dependant
|
||||
tempPattern += QDir::separator();
|
||||
const QString fileName = fw->fileName();
|
||||
if (fileName.isEmpty()) {
|
||||
tempPattern += QLatin1String("designer");
|
||||
} else {
|
||||
tempPattern += QFileInfo(fileName).baseName();
|
||||
}
|
||||
tempPattern += QLatin1String("XXXXXX.ui");
|
||||
// Write to temp file
|
||||
QTemporaryFile tempFormFile(tempPattern);
|
||||
|
||||
tempFormFile.setAutoRemove(true);
|
||||
if (!tempFormFile.open()) {
|
||||
*errorMessage = tr("A temporary form file could not be created in %1.").arg(QDir::tempPath());
|
||||
return false;
|
||||
}
|
||||
const QString tempFormFileName = tempFormFile.fileName();
|
||||
tempFormFile.write(fw->contents().toUtf8());
|
||||
if (!tempFormFile.flush()) {
|
||||
*errorMessage = tr("The temporary form file %1 could not be written.").arg(tempFormFileName);
|
||||
return false;
|
||||
}
|
||||
tempFormFile.close();
|
||||
// Run uic
|
||||
QByteArray rc;
|
||||
if (!runUIC(tempFormFileName, UIC_GenerateCode, rc, *errorMessage))
|
||||
return false;
|
||||
*code = QString::fromUtf8(rc);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CodeDialog::showCodeDialog(const QDesignerFormWindowInterface *fw,
|
||||
QWidget *parent,
|
||||
QString *errorMessage)
|
||||
{
|
||||
QString code;
|
||||
if (!generateCode(fw, &code, errorMessage))
|
||||
return false;
|
||||
|
||||
CodeDialog dialog(parent);
|
||||
dialog.setWindowTitle(tr("%1 - [Code]").arg(fw->mainContainer()->windowTitle()));
|
||||
dialog.setCode(code);
|
||||
dialog.setFormFileName(fw->fileName());
|
||||
dialog.exec();
|
||||
return true;
|
||||
}
|
||||
|
||||
void CodeDialog::slotSaveAs()
|
||||
{
|
||||
// build the default relative name 'ui_sth.h'
|
||||
const QString headerSuffix = QString(QLatin1Char('h'));
|
||||
QString filter;
|
||||
const QString uiFile = formFileName();
|
||||
|
||||
if (!uiFile.isEmpty()) {
|
||||
filter = QLatin1String("ui_");
|
||||
filter += QFileInfo(uiFile).baseName();
|
||||
filter += QLatin1Char('.');
|
||||
filter += headerSuffix;
|
||||
}
|
||||
// file dialog
|
||||
while (true) {
|
||||
const QString fileName =
|
||||
QFileDialog::getSaveFileName (this, tr("Save Code"), filter, tr("Header Files (*.%1)").arg(headerSuffix));
|
||||
if (fileName.isEmpty())
|
||||
break;
|
||||
|
||||
QFile file(fileName);
|
||||
if (!file.open(QIODevice::WriteOnly|QIODevice::Text)) {
|
||||
warning(tr("The file %1 could not be opened: %2").arg(fileName).arg(file.errorString()));
|
||||
continue;
|
||||
}
|
||||
file.write(code().toUtf8());
|
||||
if (!file.flush()) {
|
||||
warning(tr("The file %1 could not be written: %2").arg(fileName).arg(file.errorString()));
|
||||
continue;
|
||||
}
|
||||
file.close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CodeDialog::warning(const QString &msg)
|
||||
{
|
||||
QMessageBox::warning(
|
||||
this, tr("%1 - Error").arg(windowTitle()),
|
||||
msg, QMessageBox::Close);
|
||||
}
|
||||
|
||||
void CodeDialog::copyAll()
|
||||
{
|
||||
QApplication::clipboard()->setText(code());
|
||||
}
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
100
third/designer/lib/shared/codedialog_p.h
Normal file
100
third/designer/lib/shared/codedialog_p.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef CODEPREVIEWDIALOG_H
|
||||
#define CODEPREVIEWDIALOG_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
#include <QtGui/QDialog>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDesignerFormWindowInterface;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
// Dialog for viewing code.
|
||||
class QDESIGNER_SHARED_EXPORT CodeDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
explicit CodeDialog(QWidget *parent = 0);
|
||||
public:
|
||||
virtual ~CodeDialog();
|
||||
|
||||
static bool generateCode(const QDesignerFormWindowInterface *fw,
|
||||
QString *code,
|
||||
QString *errorMessage);
|
||||
|
||||
static bool showCodeDialog(const QDesignerFormWindowInterface *fw,
|
||||
QWidget *parent,
|
||||
QString *errorMessage);
|
||||
|
||||
private slots:
|
||||
void slotSaveAs();
|
||||
void copyAll();
|
||||
|
||||
private:
|
||||
void setCode(const QString &code);
|
||||
QString code() const;
|
||||
void setFormFileName(const QString &f);
|
||||
QString formFileName() const;
|
||||
|
||||
void warning(const QString &msg);
|
||||
|
||||
struct CodeDialogPrivate;
|
||||
CodeDialogPrivate *m_impl;
|
||||
};
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // CODEPREVIEWDIALOG_H
|
||||
1612
third/designer/lib/shared/connectionedit.cpp
Normal file
1612
third/designer/lib/shared/connectionedit.cpp
Normal file
File diff suppressed because it is too large
Load Diff
324
third/designer/lib/shared/connectionedit_p.h
Normal file
324
third/designer/lib/shared/connectionedit_p.h
Normal file
@@ -0,0 +1,324 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
|
||||
#ifndef CONNECTIONEDIT_H
|
||||
#define CONNECTIONEDIT_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
|
||||
#include <QtCore/QMultiMap>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QPointer>
|
||||
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/QPixmap>
|
||||
#include <QtGui/QPolygonF>
|
||||
|
||||
#include <QtGui/QUndoCommand>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDesignerFormWindowInterface;
|
||||
class QUndoStack;
|
||||
class QMenu;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
class Connection;
|
||||
class ConnectionEdit;
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT CETypes
|
||||
{
|
||||
public:
|
||||
typedef QList<Connection*> ConnectionList;
|
||||
typedef QMap<Connection*, Connection*> ConnectionSet;
|
||||
typedef QMap<QWidget*, QWidget*> WidgetSet;
|
||||
|
||||
class EndPoint {
|
||||
public:
|
||||
enum Type { Source, Target };
|
||||
explicit EndPoint(Connection *_con = 0, Type _type = Source) : con(_con), type(_type) {}
|
||||
bool isNull() const { return con == 0; }
|
||||
bool operator == (const EndPoint &other) const { return con == other.con && type == other.type; }
|
||||
bool operator != (const EndPoint &other) const { return !operator == (other); }
|
||||
Connection *con;
|
||||
Type type;
|
||||
};
|
||||
enum LineDir { UpDir = 0, DownDir, RightDir, LeftDir };
|
||||
};
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT Connection : public CETypes
|
||||
{
|
||||
public:
|
||||
explicit Connection(ConnectionEdit *edit);
|
||||
explicit Connection(ConnectionEdit *edit, QObject *source, QObject *target);
|
||||
virtual ~Connection() {}
|
||||
|
||||
QObject *object(EndPoint::Type type) const
|
||||
{
|
||||
return (type == EndPoint::Source ? m_source : m_target);
|
||||
}
|
||||
|
||||
QWidget *widget(EndPoint::Type type) const
|
||||
{
|
||||
return qobject_cast<QWidget*>(object(type));
|
||||
}
|
||||
|
||||
QPoint endPointPos(EndPoint::Type type) const;
|
||||
QRect endPointRect(EndPoint::Type) const;
|
||||
void setEndPoint(EndPoint::Type type, QObject *w, const QPoint &pos)
|
||||
{ type == EndPoint::Source ? setSource(w, pos) : setTarget(w, pos); }
|
||||
|
||||
bool isVisible() const;
|
||||
virtual void updateVisibility();
|
||||
void setVisible(bool b);
|
||||
|
||||
virtual QRegion region() const;
|
||||
bool contains(const QPoint &pos) const;
|
||||
virtual void paint(QPainter *p) const;
|
||||
|
||||
void update(bool update_widgets = true) const;
|
||||
void checkWidgets();
|
||||
|
||||
QString label(EndPoint::Type type) const
|
||||
{ return type == EndPoint::Source ? m_source_label : m_target_label; }
|
||||
void setLabel(EndPoint::Type type, const QString &text);
|
||||
QRect labelRect(EndPoint::Type type) const;
|
||||
QPixmap labelPixmap(EndPoint::Type type) const
|
||||
{ return type == EndPoint::Source ? m_source_label_pm : m_target_label_pm; }
|
||||
|
||||
ConnectionEdit *edit() const { return m_edit; }
|
||||
|
||||
virtual void inserted() {}
|
||||
virtual void removed() {}
|
||||
|
||||
private:
|
||||
QPoint m_source_pos, m_target_pos;
|
||||
QObject *m_source, *m_target;
|
||||
QList<QPoint> m_knee_list;
|
||||
QPolygonF m_arrow_head;
|
||||
ConnectionEdit *m_edit;
|
||||
QString m_source_label, m_target_label;
|
||||
QPixmap m_source_label_pm, m_target_label_pm;
|
||||
QRect m_source_rect, m_target_rect;
|
||||
bool m_visible;
|
||||
|
||||
void setSource(QObject *source, const QPoint &pos);
|
||||
void setTarget(QObject *target, const QPoint &pos);
|
||||
void updateKneeList();
|
||||
void trimLine();
|
||||
void updatePixmap(EndPoint::Type type);
|
||||
LineDir labelDir(EndPoint::Type type) const;
|
||||
bool ground() const;
|
||||
QRect groundRect() const;
|
||||
};
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT ConnectionEdit : public QWidget, public CETypes
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ConnectionEdit(QWidget *parent, QDesignerFormWindowInterface *form);
|
||||
virtual ~ConnectionEdit();
|
||||
|
||||
inline const QPointer<QWidget> &background() const { return m_bg_widget; }
|
||||
|
||||
void setSelected(Connection *con, bool sel);
|
||||
bool selected(const Connection *con) const;
|
||||
|
||||
int connectionCount() const { return m_con_list.size(); }
|
||||
Connection *connection(int i) const { return m_con_list.at(i); }
|
||||
int indexOfConnection(Connection *con) const { return m_con_list.indexOf(con); }
|
||||
|
||||
virtual void setSource(Connection *con, const QString &obj_name);
|
||||
virtual void setTarget(Connection *con, const QString &obj_name);
|
||||
|
||||
QUndoStack *undoStack() const { return m_undo_stack; }
|
||||
|
||||
void clear();
|
||||
|
||||
void showEvent(QShowEvent * /*e*/)
|
||||
{
|
||||
updateBackground();
|
||||
}
|
||||
|
||||
signals:
|
||||
void aboutToAddConnection(int idx);
|
||||
void connectionAdded(Connection *con);
|
||||
void aboutToRemoveConnection(Connection *con);
|
||||
void connectionRemoved(int idx);
|
||||
void connectionSelected(Connection *con);
|
||||
void widgetActivated(QWidget *wgt);
|
||||
void connectionChanged(Connection *con);
|
||||
|
||||
public slots:
|
||||
void selectNone();
|
||||
void selectAll();
|
||||
virtual void deleteSelected();
|
||||
virtual void setBackground(QWidget *background);
|
||||
virtual void updateBackground();
|
||||
virtual void widgetRemoved(QWidget *w);
|
||||
virtual void objectRemoved(QObject *o);
|
||||
|
||||
void updateLines();
|
||||
void enableUpdateBackground(bool enable);
|
||||
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent *e);
|
||||
virtual void mouseMoveEvent(QMouseEvent *e);
|
||||
virtual void mousePressEvent(QMouseEvent *e);
|
||||
virtual void mouseReleaseEvent(QMouseEvent *e);
|
||||
virtual void keyPressEvent(QKeyEvent *e);
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent *e);
|
||||
virtual void resizeEvent(QResizeEvent *e);
|
||||
virtual void contextMenuEvent(QContextMenuEvent * event);
|
||||
|
||||
virtual Connection *createConnection(QWidget *source, QWidget *target);
|
||||
virtual void modifyConnection(Connection *con);
|
||||
|
||||
virtual QWidget *widgetAt(const QPoint &pos) const;
|
||||
virtual void createContextMenu(QMenu &menu);
|
||||
void addConnection(Connection *con);
|
||||
QRect widgetRect(QWidget *w) const;
|
||||
|
||||
enum State { Editing, Connecting, Dragging };
|
||||
State state() const;
|
||||
|
||||
virtual void endConnection(QWidget *target, const QPoint &pos);
|
||||
|
||||
const ConnectionList &connectionList() const { return m_con_list; }
|
||||
const ConnectionSet &selection() const { return m_sel_con_set; }
|
||||
Connection *takeConnection(Connection *con);
|
||||
Connection *newlyAddedConnection() { return m_tmp_con; }
|
||||
void clearNewlyAddedConnection();
|
||||
|
||||
void findObjectsUnderMouse(const QPoint &pos);
|
||||
|
||||
private:
|
||||
void startConnection(QWidget *source, const QPoint &pos);
|
||||
void continueConnection(QWidget *target, const QPoint &pos);
|
||||
void abortConnection();
|
||||
|
||||
void startDrag(const EndPoint &end_point, const QPoint &pos);
|
||||
void continueDrag(const QPoint &pos);
|
||||
void endDrag(const QPoint &pos);
|
||||
void adjustHotSopt(const EndPoint &end_point, const QPoint &pos);
|
||||
Connection *connectionAt(const QPoint &pos) const;
|
||||
EndPoint endPointAt(const QPoint &pos) const;
|
||||
void paintConnection(QPainter *p, Connection *con,
|
||||
WidgetSet *heavy_highlight_set,
|
||||
WidgetSet *light_highlight_set) const;
|
||||
void paintLabel(QPainter *p, EndPoint::Type type, Connection *con);
|
||||
|
||||
|
||||
QPointer<QWidget> m_bg_widget;
|
||||
QUndoStack *m_undo_stack;
|
||||
bool m_enable_update_background;
|
||||
|
||||
Connection *m_tmp_con; // the connection we are currently editing
|
||||
ConnectionList m_con_list;
|
||||
bool m_start_connection_on_drag;
|
||||
EndPoint m_end_point_under_mouse;
|
||||
QPointer<QWidget> m_widget_under_mouse;
|
||||
|
||||
EndPoint m_drag_end_point;
|
||||
QPoint m_old_source_pos, m_old_target_pos;
|
||||
ConnectionSet m_sel_con_set;
|
||||
const QColor m_inactive_color;
|
||||
const QColor m_active_color;
|
||||
|
||||
private:
|
||||
friend class Connection;
|
||||
friend class AddConnectionCommand;
|
||||
friend class DeleteConnectionsCommand;
|
||||
friend class SetEndPointCommand;
|
||||
};
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT CECommand : public QUndoCommand, public CETypes
|
||||
{
|
||||
public:
|
||||
explicit CECommand(ConnectionEdit *edit)
|
||||
: m_edit(edit) {}
|
||||
|
||||
virtual bool mergeWith(const QUndoCommand *) { return false; }
|
||||
|
||||
ConnectionEdit *edit() const { return m_edit; }
|
||||
|
||||
private:
|
||||
ConnectionEdit *m_edit;
|
||||
};
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT AddConnectionCommand : public CECommand
|
||||
{
|
||||
public:
|
||||
AddConnectionCommand(ConnectionEdit *edit, Connection *con);
|
||||
virtual void redo();
|
||||
virtual void undo();
|
||||
private:
|
||||
Connection *m_con;
|
||||
};
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT DeleteConnectionsCommand : public CECommand
|
||||
{
|
||||
public:
|
||||
DeleteConnectionsCommand(ConnectionEdit *edit, const ConnectionList &con_list);
|
||||
virtual void redo();
|
||||
virtual void undo();
|
||||
private:
|
||||
ConnectionList m_con_list;
|
||||
};
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // CONNECTIONEDIT_H
|
||||
188
third/designer/lib/shared/csshighlighter.cpp
Normal file
188
third/designer/lib/shared/csshighlighter.cpp
Normal file
@@ -0,0 +1,188 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "csshighlighter_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
CssHighlighter::CssHighlighter(QTextDocument *document)
|
||||
: QSyntaxHighlighter(document)
|
||||
{
|
||||
}
|
||||
|
||||
void CssHighlighter::highlightBlock(const QString& text)
|
||||
{
|
||||
enum Token { ALNUM, LBRACE, RBRACE, COLON, SEMICOLON, COMMA, QUOTE, SLASH, STAR };
|
||||
static const int transitions[10][9] = {
|
||||
{ Selector, Property, Selector, Pseudo, Property, Selector, Quote, MaybeComment, Selector }, // Selector
|
||||
{ Property, Property, Selector, Value, Property, Property, Quote, MaybeComment, Property }, // Property
|
||||
{ Value, Property, Selector, Value, Property, Value, Quote, MaybeComment, Value }, // Value
|
||||
{ Pseudo1, Property, Selector, Pseudo2, Selector, Selector, Quote, MaybeComment, Pseudo }, // Pseudo
|
||||
{ Pseudo1, Property, Selector, Pseudo, Selector, Selector, Quote, MaybeComment, Pseudo1 }, // Pseudo1
|
||||
{ Pseudo2, Property, Selector, Pseudo, Selector, Selector, Quote, MaybeComment, Pseudo2 }, // Pseudo2
|
||||
{ Quote, Quote, Quote, Quote, Quote, Quote, -1, Quote, Quote }, // Quote
|
||||
{ -1, -1, -1, -1, -1, -1, -1, -1, Comment }, // MaybeComment
|
||||
{ Comment, Comment, Comment, Comment, Comment, Comment, Comment, Comment, MaybeCommentEnd }, // Comment
|
||||
{ Comment, Comment, Comment, Comment, Comment, Comment, Comment, -1, MaybeCommentEnd } // MaybeCommentEnd
|
||||
};
|
||||
|
||||
int lastIndex = 0;
|
||||
bool lastWasSlash = false;
|
||||
int state = previousBlockState(), save_state;
|
||||
if (state == -1) {
|
||||
// As long as the text is empty, leave the state undetermined
|
||||
if (text.isEmpty()) {
|
||||
setCurrentBlockState(-1);
|
||||
return;
|
||||
}
|
||||
// The initial state is based on the precense of a : and the absense of a {.
|
||||
// This is because Qt style sheets support both a full stylesheet as well as
|
||||
// an inline form with just properties.
|
||||
state = save_state = (text.indexOf(QLatin1Char(':')) > -1 &&
|
||||
text.indexOf(QLatin1Char('{')) == -1) ? Property : Selector;
|
||||
} else {
|
||||
save_state = state>>16;
|
||||
state &= 0x00ff;
|
||||
}
|
||||
|
||||
if (state == MaybeCommentEnd) {
|
||||
state = Comment;
|
||||
} else if (state == MaybeComment) {
|
||||
state = save_state;
|
||||
}
|
||||
|
||||
for (int i = 0; i < text.length(); i++) {
|
||||
int token = ALNUM;
|
||||
const QChar c = text.at(i);
|
||||
const char a = c.toAscii();
|
||||
|
||||
if (state == Quote) {
|
||||
if (a == '\\') {
|
||||
lastWasSlash = true;
|
||||
} else {
|
||||
if (a == '\"' && !lastWasSlash) {
|
||||
token = QUOTE;
|
||||
}
|
||||
lastWasSlash = false;
|
||||
}
|
||||
} else {
|
||||
switch (a) {
|
||||
case '{': token = LBRACE; break;
|
||||
case '}': token = RBRACE; break;
|
||||
case ':': token = COLON; break;
|
||||
case ';': token = SEMICOLON; break;
|
||||
case ',': token = COMMA; break;
|
||||
case '\"': token = QUOTE; break;
|
||||
case '/': token = SLASH; break;
|
||||
case '*': token = STAR; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
int new_state = transitions[state][token];
|
||||
|
||||
if (new_state != state) {
|
||||
bool include_token = new_state == MaybeCommentEnd || (state == MaybeCommentEnd && new_state!= Comment)
|
||||
|| state == Quote;
|
||||
highlight(text, lastIndex, i-lastIndex+include_token, state);
|
||||
|
||||
if (new_state == Comment) {
|
||||
lastIndex = i-1; // include the slash and star
|
||||
} else {
|
||||
lastIndex = i + ((token == ALNUM || new_state == Quote) ? 0 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (new_state == -1) {
|
||||
state = save_state;
|
||||
} else if (state <= Pseudo2) {
|
||||
save_state = state;
|
||||
state = new_state;
|
||||
} else {
|
||||
state = new_state;
|
||||
}
|
||||
}
|
||||
|
||||
highlight(text, lastIndex, text.length() - lastIndex, state);
|
||||
setCurrentBlockState(state + (save_state<<16));
|
||||
}
|
||||
|
||||
void CssHighlighter::highlight(const QString &text, int start, int length, int state)
|
||||
{
|
||||
if (start >= text.length() || length <= 0)
|
||||
return;
|
||||
|
||||
QTextCharFormat format;
|
||||
|
||||
switch (state) {
|
||||
case Selector:
|
||||
setFormat(start, length, Qt::darkRed);
|
||||
break;
|
||||
case Property:
|
||||
setFormat(start, length, Qt::blue);
|
||||
break;
|
||||
case Value:
|
||||
setFormat(start, length, Qt::black);
|
||||
break;
|
||||
case Pseudo1:
|
||||
setFormat(start, length, Qt::darkRed);
|
||||
break;
|
||||
case Pseudo2:
|
||||
setFormat(start, length, Qt::darkRed);
|
||||
break;
|
||||
case Quote:
|
||||
setFormat(start, length, Qt::darkMagenta);
|
||||
break;
|
||||
case Comment:
|
||||
case MaybeCommentEnd:
|
||||
format.setForeground(Qt::darkGreen);
|
||||
setFormat(start, length, format);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
82
third/designer/lib/shared/csshighlighter_p.h
Normal file
82
third/designer/lib/shared/csshighlighter_p.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef CSSHIGHLIGHTER_H
|
||||
#define CSSHIGHLIGHTER_H
|
||||
|
||||
#include <QtGui/QSyntaxHighlighter>
|
||||
#include "shared_global_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT CssHighlighter : public QSyntaxHighlighter
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CssHighlighter(QTextDocument *document);
|
||||
|
||||
protected:
|
||||
void highlightBlock(const QString&);
|
||||
void highlight(const QString&, int, int, int/*State*/);
|
||||
|
||||
private:
|
||||
enum State { Selector, Property, Value, Pseudo, Pseudo1, Pseudo2, Quote,
|
||||
MaybeComment, Comment, MaybeCommentEnd };
|
||||
};
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // CSSHIGHLIGHTER_H
|
||||
498
third/designer/lib/shared/defaultgradients.xml
Normal file
498
third/designer/lib/shared/defaultgradients.xml
Normal file
@@ -0,0 +1,498 @@
|
||||
<gradients>
|
||||
<gradient name="BlackWhite" >
|
||||
<gradientData spread="PadSpread" startX="0" startY="0" coordinateMode="StretchToDeviceMode" type="LinearGradient" endX="1" endY="0" >
|
||||
<stopData position="0" >
|
||||
<colorData g="0" r="0" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="1" >
|
||||
<colorData g="255" r="255" a="255" b="255" />
|
||||
</stopData>
|
||||
</gradientData>
|
||||
</gradient>
|
||||
<gradient name="Czech" >
|
||||
<gradientData centerX="0.5" centerY="0.5" spread="RepeatSpread" coordinateMode="StretchToDeviceMode" type="ConicalGradient" angle="0" >
|
||||
<stopData position="0" >
|
||||
<colorData g="255" r="255" a="255" b="255" />
|
||||
</stopData>
|
||||
<stopData position="0.373978669201521" >
|
||||
<colorData g="255" r="255" a="255" b="255" />
|
||||
</stopData>
|
||||
<stopData position="0.3739913434727503" >
|
||||
<colorData g="30" r="33" a="255" b="255" />
|
||||
</stopData>
|
||||
<stopData position="0.6240176679340937" >
|
||||
<colorData g="30" r="33" a="255" b="255" />
|
||||
</stopData>
|
||||
<stopData position="0.6240430164765525" >
|
||||
<colorData g="0" r="255" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="1" >
|
||||
<colorData g="0" r="255" a="255" b="0" />
|
||||
</stopData>
|
||||
</gradientData>
|
||||
</gradient>
|
||||
<gradient name="Dutch" >
|
||||
<gradientData spread="PadSpread" startX="0" startY="0" coordinateMode="StretchToDeviceMode" type="LinearGradient" endX="0" endY="1" >
|
||||
<stopData position="0" >
|
||||
<colorData g="0" r="255" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.3397947548460661" >
|
||||
<colorData g="0" r="255" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.339798898163606" >
|
||||
<colorData g="255" r="255" a="255" b="255" />
|
||||
</stopData>
|
||||
<stopData position="0.6624439732888147" >
|
||||
<colorData g="255" r="255" a="255" b="255" />
|
||||
</stopData>
|
||||
<stopData position="0.6624690150250417" >
|
||||
<colorData g="0" r="0" a="255" b="255" />
|
||||
</stopData>
|
||||
<stopData position="1" >
|
||||
<colorData g="0" r="0" a="255" b="255" />
|
||||
</stopData>
|
||||
</gradientData>
|
||||
</gradient>
|
||||
<gradient name="Eye" >
|
||||
<gradientData centerX="0.5" centerY="0.5" radius="0.5" spread="PadSpread" focalX="0.5" focalY="0.5" coordinateMode="StretchToDeviceMode" type="RadialGradient" >
|
||||
<stopData position="0" >
|
||||
<colorData g="0" r="0" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.1939699465240642" >
|
||||
<colorData g="0" r="0" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.202312192513369" >
|
||||
<colorData g="97" r="122" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.4955143315508022" >
|
||||
<colorData g="58" r="76" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.5048191443850267" >
|
||||
<colorData g="255" r="255" a="255" b="255" />
|
||||
</stopData>
|
||||
<stopData position="0.79" >
|
||||
<colorData g="255" r="255" a="255" b="255" />
|
||||
</stopData>
|
||||
<stopData position="1" >
|
||||
<colorData g="158" r="255" a="255" b="158" />
|
||||
</stopData>
|
||||
</gradientData>
|
||||
</gradient>
|
||||
<gradient name="Flare1" >
|
||||
<gradientData centerX="0.5" centerY="0.5" radius="0.5" spread="PadSpread" focalX="0.5" focalY="0.5" coordinateMode="StretchToDeviceMode" type="RadialGradient" >
|
||||
<stopData position="0" >
|
||||
<colorData g="255" r="255" a="255" b="255" />
|
||||
</stopData>
|
||||
<stopData position="0.1" >
|
||||
<colorData g="255" r="255" a="255" b="255" />
|
||||
</stopData>
|
||||
<stopData position="0.2" >
|
||||
<colorData g="176" r="255" a="167" b="176" />
|
||||
</stopData>
|
||||
<stopData position="0.3" >
|
||||
<colorData g="151" r="255" a="92" b="151" />
|
||||
</stopData>
|
||||
<stopData position="0.4" >
|
||||
<colorData g="125" r="255" a="51" b="125" />
|
||||
</stopData>
|
||||
<stopData position="0.5" >
|
||||
<colorData g="76" r="255" a="205" b="76" />
|
||||
</stopData>
|
||||
<stopData position="0.52" >
|
||||
<colorData g="76" r="255" a="205" b="76" />
|
||||
</stopData>
|
||||
<stopData position="0.6" >
|
||||
<colorData g="180" r="255" a="84" b="180" />
|
||||
</stopData>
|
||||
<stopData position="1" >
|
||||
<colorData g="255" r="255" a="0" b="255" />
|
||||
</stopData>
|
||||
</gradientData>
|
||||
</gradient>
|
||||
<gradient name="Flare2" >
|
||||
<gradientData centerX="0.5" centerY="0.5" radius="0.5" spread="PadSpread" focalX="0.5" focalY="0.5" coordinateMode="StretchToDeviceMode" type="RadialGradient" >
|
||||
<stopData position="0" >
|
||||
<colorData g="0" r="0" a="0" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.52" >
|
||||
<colorData g="0" r="0" a="0" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.5649999999999999" >
|
||||
<colorData g="121" r="82" a="33" b="76" />
|
||||
</stopData>
|
||||
<stopData position="0.65" >
|
||||
<colorData g="235" r="159" a="64" b="148" />
|
||||
</stopData>
|
||||
<stopData position="0.7219251336898396" >
|
||||
<colorData g="238" r="255" a="129" b="150" />
|
||||
</stopData>
|
||||
<stopData position="0.77" >
|
||||
<colorData g="128" r="255" a="204" b="128" />
|
||||
</stopData>
|
||||
<stopData position="0.89" >
|
||||
<colorData g="128" r="191" a="64" b="255" />
|
||||
</stopData>
|
||||
<stopData position="1" >
|
||||
<colorData g="0" r="0" a="0" b="0" />
|
||||
</stopData>
|
||||
</gradientData>
|
||||
</gradient>
|
||||
<gradient name="Flare3" >
|
||||
<gradientData centerX="0.5" centerY="0.5" radius="0.5" spread="PadSpread" focalX="0.5" focalY="0.5" coordinateMode="StretchToDeviceMode" type="RadialGradient" >
|
||||
<stopData position="0" >
|
||||
<colorData g="235" r="255" a="206" b="235" />
|
||||
</stopData>
|
||||
<stopData position="0.35" >
|
||||
<colorData g="188" r="255" a="80" b="188" />
|
||||
</stopData>
|
||||
<stopData position="0.4" >
|
||||
<colorData g="162" r="255" a="80" b="162" />
|
||||
</stopData>
|
||||
<stopData position="0.425" >
|
||||
<colorData g="132" r="255" a="156" b="132" />
|
||||
</stopData>
|
||||
<stopData position="0.44" >
|
||||
<colorData g="128" r="252" a="80" b="128" />
|
||||
</stopData>
|
||||
<stopData position="1" >
|
||||
<colorData g="255" r="255" a="0" b="255" />
|
||||
</stopData>
|
||||
</gradientData>
|
||||
</gradient>
|
||||
<gradient name="German" >
|
||||
<gradientData spread="PadSpread" startX="0" startY="0" coordinateMode="StretchToDeviceMode" type="LinearGradient" endX="0" endY="1" >
|
||||
<stopData position="0" >
|
||||
<colorData g="0" r="0" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.33" >
|
||||
<colorData g="0" r="0" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.34" >
|
||||
<colorData g="30" r="255" a="255" b="30" />
|
||||
</stopData>
|
||||
<stopData position="0.66" >
|
||||
<colorData g="0" r="255" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.67" >
|
||||
<colorData g="255" r="255" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="1" >
|
||||
<colorData g="255" r="255" a="255" b="0" />
|
||||
</stopData>
|
||||
</gradientData>
|
||||
</gradient>
|
||||
<gradient name="Golden" >
|
||||
<gradientData centerX="0.5" centerY="0.5" spread="PadSpread" coordinateMode="StretchToDeviceMode" type="ConicalGradient" angle="0" >
|
||||
<stopData position="0" >
|
||||
<colorData g="40" r="35" a="255" b="3" />
|
||||
</stopData>
|
||||
<stopData position="0.16" >
|
||||
<colorData g="106" r="136" a="255" b="22" />
|
||||
</stopData>
|
||||
<stopData position="0.225" >
|
||||
<colorData g="140" r="166" a="255" b="41" />
|
||||
</stopData>
|
||||
<stopData position="0.285" >
|
||||
<colorData g="181" r="204" a="255" b="74" />
|
||||
</stopData>
|
||||
<stopData position="0.345" >
|
||||
<colorData g="219" r="235" a="255" b="102" />
|
||||
</stopData>
|
||||
<stopData position="0.415" >
|
||||
<colorData g="236" r="245" a="255" b="112" />
|
||||
</stopData>
|
||||
<stopData position="0.52" >
|
||||
<colorData g="190" r="209" a="255" b="76" />
|
||||
</stopData>
|
||||
<stopData position="0.57" >
|
||||
<colorData g="156" r="187" a="255" b="51" />
|
||||
</stopData>
|
||||
<stopData position="0.635" >
|
||||
<colorData g="142" r="168" a="255" b="42" />
|
||||
</stopData>
|
||||
<stopData position="0.695" >
|
||||
<colorData g="174" r="202" a="255" b="68" />
|
||||
</stopData>
|
||||
<stopData position="0.75" >
|
||||
<colorData g="202" r="218" a="255" b="86" />
|
||||
</stopData>
|
||||
<stopData position="0.8149999999999999" >
|
||||
<colorData g="187" r="208" a="255" b="73" />
|
||||
</stopData>
|
||||
<stopData position="0.88" >
|
||||
<colorData g="156" r="187" a="255" b="51" />
|
||||
</stopData>
|
||||
<stopData position="0.9350000000000001" >
|
||||
<colorData g="108" r="137" a="255" b="26" />
|
||||
</stopData>
|
||||
<stopData position="1" >
|
||||
<colorData g="40" r="35" a="255" b="3" />
|
||||
</stopData>
|
||||
</gradientData>
|
||||
</gradient>
|
||||
<gradient name="Japanese" >
|
||||
<gradientData centerX="0.5" centerY="0.5" radius="0.5" spread="PadSpread" focalX="0.5" focalY="0.5" coordinateMode="StretchToDeviceMode" type="RadialGradient" >
|
||||
<stopData position="0" >
|
||||
<colorData g="0" r="255" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.4799044117647059" >
|
||||
<colorData g="0" r="255" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.5226851604278074" >
|
||||
<colorData g="255" r="255" a="255" b="255" />
|
||||
</stopData>
|
||||
<stopData position="1" >
|
||||
<colorData g="255" r="255" a="255" b="255" />
|
||||
</stopData>
|
||||
</gradientData>
|
||||
</gradient>
|
||||
<gradient name="Norwegian" >
|
||||
<gradientData spread="RepeatSpread" startX="0" startY="0" coordinateMode="StretchToDeviceMode" type="LinearGradient" endX="1" endY="0" >
|
||||
<stopData position="0" >
|
||||
<colorData g="0" r="255" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.17" >
|
||||
<colorData g="0" r="255" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.18" >
|
||||
<colorData g="255" r="255" a="255" b="255" />
|
||||
</stopData>
|
||||
<stopData position="0.2102117403738299" >
|
||||
<colorData g="255" r="255" a="255" b="255" />
|
||||
</stopData>
|
||||
<stopData position="0.2202117403738299" >
|
||||
<colorData g="16" r="0" a="255" b="255" />
|
||||
</stopData>
|
||||
<stopData position="0.2798973635190806" >
|
||||
<colorData g="16" r="0" a="255" b="255" />
|
||||
</stopData>
|
||||
<stopData position="0.2898973635190806" >
|
||||
<colorData g="255" r="255" a="255" b="255" />
|
||||
</stopData>
|
||||
<stopData position="0.32" >
|
||||
<colorData g="255" r="255" a="255" b="255" />
|
||||
</stopData>
|
||||
<stopData position="0.33" >
|
||||
<colorData g="0" r="255" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="1" >
|
||||
<colorData g="0" r="255" a="255" b="0" />
|
||||
</stopData>
|
||||
</gradientData>
|
||||
</gradient>
|
||||
<gradient name="Pastels" >
|
||||
<gradientData spread="PadSpread" startX="0" startY="0" coordinateMode="StretchToDeviceMode" type="LinearGradient" endX="1" endY="0" >
|
||||
<stopData position="0" >
|
||||
<colorData g="224" r="245" a="255" b="176" />
|
||||
</stopData>
|
||||
<stopData position="0.09" >
|
||||
<colorData g="189" r="246" a="255" b="237" />
|
||||
</stopData>
|
||||
<stopData position="0.14" >
|
||||
<colorData g="207" r="194" a="255" b="246" />
|
||||
</stopData>
|
||||
<stopData position="0.19" >
|
||||
<colorData g="160" r="184" a="255" b="168" />
|
||||
</stopData>
|
||||
<stopData position="0.25" >
|
||||
<colorData g="186" r="171" a="255" b="248" />
|
||||
</stopData>
|
||||
<stopData position="0.32" >
|
||||
<colorData g="248" r="243" a="255" b="224" />
|
||||
</stopData>
|
||||
<stopData position="0.385" >
|
||||
<colorData g="162" r="249" a="255" b="183" />
|
||||
</stopData>
|
||||
<stopData position="0.47" >
|
||||
<colorData g="115" r="100" a="255" b="124" />
|
||||
</stopData>
|
||||
<stopData position="0.58" >
|
||||
<colorData g="205" r="251" a="255" b="202" />
|
||||
</stopData>
|
||||
<stopData position="0.65" >
|
||||
<colorData g="128" r="170" a="255" b="185" />
|
||||
</stopData>
|
||||
<stopData position="0.75" >
|
||||
<colorData g="222" r="252" a="255" b="204" />
|
||||
</stopData>
|
||||
<stopData position="0.805" >
|
||||
<colorData g="122" r="206" a="255" b="218" />
|
||||
</stopData>
|
||||
<stopData position="0.86" >
|
||||
<colorData g="223" r="254" a="255" b="175" />
|
||||
</stopData>
|
||||
<stopData position="0.91" >
|
||||
<colorData g="236" r="254" a="255" b="244" />
|
||||
</stopData>
|
||||
<stopData position="1" >
|
||||
<colorData g="191" r="255" a="255" b="221" />
|
||||
</stopData>
|
||||
</gradientData>
|
||||
</gradient>
|
||||
<gradient name="Polish" >
|
||||
<gradientData spread="PadSpread" startX="0" startY="0" coordinateMode="StretchToDeviceMode" type="LinearGradient" endX="0" endY="1" >
|
||||
<stopData position="0" >
|
||||
<colorData g="255" r="255" a="255" b="255" />
|
||||
</stopData>
|
||||
<stopData position="0.495" >
|
||||
<colorData g="255" r="255" a="255" b="255" />
|
||||
</stopData>
|
||||
<stopData position="0.505" >
|
||||
<colorData g="0" r="255" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="1" >
|
||||
<colorData g="0" r="255" a="255" b="0" />
|
||||
</stopData>
|
||||
</gradientData>
|
||||
</gradient>
|
||||
<gradient name="Rainbow" >
|
||||
<gradientData spread="PadSpread" startX="0" startY="0" coordinateMode="StretchToDeviceMode" type="LinearGradient" endX="1" endY="0" >
|
||||
<stopData position="0" >
|
||||
<colorData g="0" r="255" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.166" >
|
||||
<colorData g="255" r="255" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.333" >
|
||||
<colorData g="255" r="0" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.5" >
|
||||
<colorData g="255" r="0" a="255" b="255" />
|
||||
</stopData>
|
||||
<stopData position="0.666" >
|
||||
<colorData g="0" r="0" a="255" b="255" />
|
||||
</stopData>
|
||||
<stopData position="0.833" >
|
||||
<colorData g="0" r="255" a="255" b="255" />
|
||||
</stopData>
|
||||
<stopData position="1" >
|
||||
<colorData g="0" r="255" a="255" b="0" />
|
||||
</stopData>
|
||||
</gradientData>
|
||||
</gradient>
|
||||
<gradient name="Sky" >
|
||||
<gradientData spread="PadSpread" startX="0" startY="1" coordinateMode="StretchToDeviceMode" type="LinearGradient" endX="0" endY="0" >
|
||||
<stopData position="0" >
|
||||
<colorData g="0" r="0" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.05" >
|
||||
<colorData g="8" r="14" a="255" b="73" />
|
||||
</stopData>
|
||||
<stopData position="0.36" >
|
||||
<colorData g="17" r="28" a="255" b="145" />
|
||||
</stopData>
|
||||
<stopData position="0.6" >
|
||||
<colorData g="14" r="126" a="255" b="81" />
|
||||
</stopData>
|
||||
<stopData position="0.75" >
|
||||
<colorData g="11" r="234" a="255" b="11" />
|
||||
</stopData>
|
||||
<stopData position="0.79" >
|
||||
<colorData g="70" r="244" a="255" b="5" />
|
||||
</stopData>
|
||||
<stopData position="0.86" >
|
||||
<colorData g="136" r="255" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.9350000000000001" >
|
||||
<colorData g="236" r="239" a="255" b="55" />
|
||||
</stopData>
|
||||
</gradientData>
|
||||
</gradient>
|
||||
<gradient name="SunRay" >
|
||||
<gradientData centerX="0" centerY="0" spread="RepeatSpread" coordinateMode="StretchToDeviceMode" type="ConicalGradient" angle="135" >
|
||||
<stopData position="0" >
|
||||
<colorData g="255" r="255" a="69" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.375" >
|
||||
<colorData g="255" r="255" a="69" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.4235329090018885" >
|
||||
<colorData g="255" r="251" a="145" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.45" >
|
||||
<colorData g="255" r="247" a="208" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.4775811200061043" >
|
||||
<colorData g="244" r="255" a="130" b="71" />
|
||||
</stopData>
|
||||
<stopData position="0.5187165775401069" >
|
||||
<colorData g="218" r="255" a="130" b="71" />
|
||||
</stopData>
|
||||
<stopData position="0.55" >
|
||||
<colorData g="255" r="255" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.5775401069518716" >
|
||||
<colorData g="203" r="255" a="130" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.625" >
|
||||
<colorData g="255" r="255" a="69" b="0" />
|
||||
</stopData>
|
||||
<stopData position="1" >
|
||||
<colorData g="255" r="255" a="69" b="0" />
|
||||
</stopData>
|
||||
</gradientData>
|
||||
</gradient>
|
||||
<gradient name="Tropical" >
|
||||
<gradientData spread="PadSpread" startX="0" startY="0" coordinateMode="StretchToDeviceMode" type="LinearGradient" endX="1" endY="0" >
|
||||
<stopData position="0" >
|
||||
<colorData g="41" r="9" a="255" b="4" />
|
||||
</stopData>
|
||||
<stopData position="0.08500000000000001" >
|
||||
<colorData g="79" r="2" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="0.19" >
|
||||
<colorData g="147" r="50" a="255" b="22" />
|
||||
</stopData>
|
||||
<stopData position="0.275" >
|
||||
<colorData g="191" r="236" a="255" b="49" />
|
||||
</stopData>
|
||||
<stopData position="0.39" >
|
||||
<colorData g="61" r="243" a="255" b="34" />
|
||||
</stopData>
|
||||
<stopData position="0.555" >
|
||||
<colorData g="81" r="135" a="255" b="60" />
|
||||
</stopData>
|
||||
<stopData position="0.667" >
|
||||
<colorData g="75" r="121" a="255" b="255" />
|
||||
</stopData>
|
||||
<stopData position="0.825" >
|
||||
<colorData g="255" r="164" a="255" b="244" />
|
||||
</stopData>
|
||||
<stopData position="0.885" >
|
||||
<colorData g="222" r="104" a="255" b="71" />
|
||||
</stopData>
|
||||
<stopData position="1" >
|
||||
<colorData g="128" r="93" a="255" b="0" />
|
||||
</stopData>
|
||||
</gradientData>
|
||||
</gradient>
|
||||
<gradient name="Wave" >
|
||||
<gradientData centerX="0.5" centerY="0.5" radius="0.077" spread="RepeatSpread" focalX="0.5" focalY="0.5" coordinateMode="StretchToDeviceMode" type="RadialGradient" >
|
||||
<stopData position="0" >
|
||||
<colorData g="169" r="0" a="147" b="255" />
|
||||
</stopData>
|
||||
<stopData position="0.4973262032085561" >
|
||||
<colorData g="0" r="0" a="147" b="0" />
|
||||
</stopData>
|
||||
<stopData position="1" >
|
||||
<colorData g="169" r="0" a="147" b="255" />
|
||||
</stopData>
|
||||
</gradientData>
|
||||
</gradient>
|
||||
<gradient name="Wood" >
|
||||
<gradientData spread="PadSpread" startX="0" startY="0" coordinateMode="StretchToDeviceMode" type="LinearGradient" endX="1" endY="0" >
|
||||
<stopData position="0" >
|
||||
<colorData g="178" r="255" a="255" b="102" />
|
||||
</stopData>
|
||||
<stopData position="0.55" >
|
||||
<colorData g="148" r="235" a="255" b="61" />
|
||||
</stopData>
|
||||
<stopData position="0.98" >
|
||||
<colorData g="0" r="0" a="255" b="0" />
|
||||
</stopData>
|
||||
<stopData position="1" >
|
||||
<colorData g="0" r="0" a="0" b="0" />
|
||||
</stopData>
|
||||
</gradientData>
|
||||
</gradient>
|
||||
</gradients>
|
||||
467
third/designer/lib/shared/deviceprofile.cpp
Normal file
467
third/designer/lib/shared/deviceprofile.cpp
Normal file
@@ -0,0 +1,467 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "deviceprofile_p.h"
|
||||
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
#include <widgetfactory_p.h>
|
||||
#include <qdesigner_utils_p.h>
|
||||
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtGui/QFont>
|
||||
#include <QtGui/QDesktopWidget>
|
||||
#include <QtGui/QStyle>
|
||||
#include <QtGui/QStyleFactory>
|
||||
#include <QtGui/QApplication>
|
||||
|
||||
#include <QtCore/QSharedData>
|
||||
#include <QtCore/QTextStream>
|
||||
|
||||
#include <QtCore/QXmlStreamWriter>
|
||||
#include <QtCore/QXmlStreamReader>
|
||||
|
||||
|
||||
static const char *dpiXPropertyC = "_q_customDpiX";
|
||||
static const char *dpiYPropertyC = "_q_customDpiY";
|
||||
|
||||
// XML serialization
|
||||
static const char *xmlVersionC="1.0";
|
||||
static const char *rootElementC="deviceprofile";
|
||||
static const char *nameElementC = "name";
|
||||
static const char *fontFamilyElementC = "fontfamily";
|
||||
static const char *fontPointSizeElementC = "fontpointsize";
|
||||
static const char *dPIXElementC = "dpix";
|
||||
static const char *dPIYElementC = "dpiy";
|
||||
static const char *styleElementC = "style";
|
||||
|
||||
/* DeviceProfile:
|
||||
* For preview purposes (preview, widget box, new form dialog), the
|
||||
* QDesignerFormBuilder applies the settings to the form main container
|
||||
* (Point being here that the DPI must be set directly for size calculations
|
||||
* to be correct).
|
||||
* For editing purposes, FormWindow applies the settings to the form container
|
||||
* as not to interfere with the font settings of the form main container.
|
||||
* In addition, the widgetfactory maintains the system settings style
|
||||
* and applies it when creating widgets. */
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
// ---------------- DeviceProfileData
|
||||
class DeviceProfileData : public QSharedData {
|
||||
public:
|
||||
DeviceProfileData();
|
||||
void fromSystem();
|
||||
void clear();
|
||||
|
||||
QString m_fontFamily;
|
||||
int m_fontPointSize;
|
||||
QString m_style;
|
||||
int m_dpiX;
|
||||
int m_dpiY;
|
||||
QString m_name;
|
||||
};
|
||||
|
||||
DeviceProfileData::DeviceProfileData() :
|
||||
m_fontPointSize(-1),
|
||||
m_dpiX(-1),
|
||||
m_dpiY(-1)
|
||||
{
|
||||
}
|
||||
|
||||
void DeviceProfileData::clear()
|
||||
{
|
||||
m_fontPointSize = -1;
|
||||
m_dpiX = 0;
|
||||
m_dpiY = 0;
|
||||
m_name.clear();
|
||||
m_style.clear();
|
||||
}
|
||||
|
||||
void DeviceProfileData::fromSystem()
|
||||
{
|
||||
const QFont appFont = QApplication::font();
|
||||
m_fontFamily = appFont.family();
|
||||
m_fontPointSize = appFont.pointSize();
|
||||
DeviceProfile::systemResolution(&m_dpiX, &m_dpiY);
|
||||
m_style.clear();
|
||||
}
|
||||
|
||||
// ---------------- DeviceProfile
|
||||
DeviceProfile::DeviceProfile() :
|
||||
m_d(new DeviceProfileData)
|
||||
{
|
||||
}
|
||||
|
||||
DeviceProfile::DeviceProfile(const DeviceProfile &o) :
|
||||
m_d(o.m_d)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
DeviceProfile& DeviceProfile::operator=(const DeviceProfile &o)
|
||||
{
|
||||
m_d.operator=(o.m_d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
DeviceProfile::~DeviceProfile()
|
||||
{
|
||||
}
|
||||
|
||||
void DeviceProfile::clear()
|
||||
{
|
||||
m_d->clear();
|
||||
}
|
||||
|
||||
bool DeviceProfile::isEmpty() const
|
||||
{
|
||||
return m_d->m_name.isEmpty();
|
||||
}
|
||||
|
||||
QString DeviceProfile::fontFamily() const
|
||||
{
|
||||
return m_d->m_fontFamily;
|
||||
}
|
||||
|
||||
void DeviceProfile::setFontFamily(const QString &f)
|
||||
{
|
||||
m_d->m_fontFamily = f;
|
||||
}
|
||||
|
||||
int DeviceProfile::fontPointSize() const
|
||||
{
|
||||
return m_d->m_fontPointSize;
|
||||
}
|
||||
|
||||
void DeviceProfile::setFontPointSize(int p)
|
||||
{
|
||||
m_d->m_fontPointSize = p;
|
||||
}
|
||||
|
||||
QString DeviceProfile::style() const
|
||||
{
|
||||
return m_d->m_style;
|
||||
}
|
||||
|
||||
void DeviceProfile::setStyle(const QString &s)
|
||||
{
|
||||
m_d->m_style = s;
|
||||
}
|
||||
|
||||
int DeviceProfile::dpiX() const
|
||||
{
|
||||
return m_d->m_dpiX;
|
||||
}
|
||||
|
||||
void DeviceProfile::setDpiX(int d)
|
||||
{
|
||||
m_d->m_dpiX = d;
|
||||
}
|
||||
|
||||
int DeviceProfile::dpiY() const
|
||||
{
|
||||
return m_d->m_dpiY;
|
||||
}
|
||||
|
||||
void DeviceProfile::setDpiY(int d)
|
||||
{
|
||||
m_d->m_dpiY = d;
|
||||
}
|
||||
|
||||
void DeviceProfile::fromSystem()
|
||||
{
|
||||
m_d->fromSystem();
|
||||
}
|
||||
|
||||
QString DeviceProfile::name() const
|
||||
{
|
||||
return m_d->m_name;
|
||||
}
|
||||
|
||||
void DeviceProfile::setName(const QString &n)
|
||||
{
|
||||
m_d->m_name = n;
|
||||
}
|
||||
|
||||
void DeviceProfile::systemResolution(int *dpiX, int *dpiY)
|
||||
{
|
||||
const QDesktopWidget *dw = qApp->desktop();
|
||||
*dpiX = dw->logicalDpiX();
|
||||
*dpiY = dw->logicalDpiY();
|
||||
}
|
||||
|
||||
class FriendlyWidget : public QWidget {
|
||||
friend class DeviceProfile;
|
||||
};
|
||||
|
||||
void DeviceProfile::widgetResolution(const QWidget *w, int *dpiX, int *dpiY)
|
||||
{
|
||||
const FriendlyWidget *fw = static_cast<const FriendlyWidget*>(w);
|
||||
*dpiX = fw->metric(QPaintDevice::PdmDpiX);
|
||||
*dpiY = fw->metric(QPaintDevice::PdmDpiY);
|
||||
}
|
||||
|
||||
QString DeviceProfile::toString() const
|
||||
{
|
||||
const DeviceProfileData &d = *m_d;
|
||||
QString rc;
|
||||
QTextStream(&rc) << "DeviceProfile:name=" << d.m_name << " Font=" << d.m_fontFamily << ' '
|
||||
<< d.m_fontPointSize << " Style=" << d.m_style << " DPI=" << d.m_dpiX << ',' << d.m_dpiY;
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Apply font to widget
|
||||
static void applyFont(const QString &family, int size, DeviceProfile::ApplyMode am, QWidget *widget)
|
||||
{
|
||||
QFont currentFont = widget->font();
|
||||
if (currentFont.pointSize() == size && currentFont.family() == family)
|
||||
return;
|
||||
switch (am) {
|
||||
case DeviceProfile::ApplyFormParent:
|
||||
// Invisible form parent: Apply all
|
||||
widget->setFont(QFont(family, size));
|
||||
break;
|
||||
case DeviceProfile::ApplyPreview: {
|
||||
// Preview: Apply only subproperties that have not been changed by designer properties
|
||||
bool apply = false;
|
||||
const uint resolve = currentFont.resolve();
|
||||
if (!(resolve & QFont::FamilyResolved)) {
|
||||
currentFont.setFamily(family);
|
||||
apply = true;
|
||||
}
|
||||
if (!(resolve & QFont::SizeResolved)) {
|
||||
currentFont.setPointSize(size);
|
||||
apply = true;
|
||||
}
|
||||
if (apply)
|
||||
widget->setFont(currentFont);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceProfile::applyDPI(int dpiX, int dpiY, QWidget *widget)
|
||||
{
|
||||
int sysDPIX, sysDPIY; // Set dynamic variables in case values are different from system DPI
|
||||
systemResolution(&sysDPIX, &sysDPIY);
|
||||
if (dpiX != sysDPIX && dpiY != sysDPIY) {
|
||||
widget->setProperty(dpiXPropertyC, QVariant(dpiX));
|
||||
widget->setProperty(dpiYPropertyC, QVariant(dpiY));
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceProfile::apply(const QDesignerFormEditorInterface *core, QWidget *widget, ApplyMode am) const
|
||||
{
|
||||
if (isEmpty())
|
||||
return;
|
||||
|
||||
const DeviceProfileData &d = *m_d;
|
||||
|
||||
if (!d.m_fontFamily.isEmpty())
|
||||
applyFont(d.m_fontFamily, d.m_fontPointSize, am, widget);
|
||||
|
||||
applyDPI(d.m_dpiX, d.m_dpiY, widget);
|
||||
|
||||
if (!d.m_style.isEmpty()) {
|
||||
if (WidgetFactory *wf = qobject_cast<qdesigner_internal::WidgetFactory *>(core->widgetFactory()))
|
||||
wf->applyStyleTopLevel(d.m_style, widget);
|
||||
}
|
||||
}
|
||||
|
||||
bool DeviceProfile::equals(const DeviceProfile& rhs) const
|
||||
{
|
||||
const DeviceProfileData &d = *m_d;
|
||||
const DeviceProfileData &rhs_d = *rhs.m_d;
|
||||
return d.m_fontPointSize == rhs_d.m_fontPointSize &&
|
||||
d.m_dpiX == rhs_d.m_dpiX && d.m_dpiY == rhs_d.m_dpiY && d.m_fontFamily == rhs_d.m_fontFamily &&
|
||||
d.m_style == rhs_d.m_style && d.m_name == rhs_d.m_name;
|
||||
}
|
||||
|
||||
static inline void writeElement(QXmlStreamWriter &writer, const QString &element, const QString &cdata)
|
||||
{
|
||||
writer.writeStartElement(element);
|
||||
writer.writeCharacters(cdata);
|
||||
writer.writeEndElement();
|
||||
}
|
||||
|
||||
QString DeviceProfile::toXml() const
|
||||
{
|
||||
const DeviceProfileData &d = *m_d;
|
||||
QString rc;
|
||||
QXmlStreamWriter writer(&rc);
|
||||
writer.writeStartDocument(QLatin1String(xmlVersionC));
|
||||
writer.writeStartElement(QLatin1String(rootElementC));
|
||||
writeElement(writer, QLatin1String(nameElementC), d.m_name);
|
||||
|
||||
if (!d.m_fontFamily.isEmpty())
|
||||
writeElement(writer, QLatin1String(fontFamilyElementC), d.m_fontFamily);
|
||||
if (d.m_fontPointSize >= 0)
|
||||
writeElement(writer, QLatin1String(fontPointSizeElementC), QString::number(d.m_fontPointSize));
|
||||
if (d.m_dpiX > 0)
|
||||
writeElement(writer, QLatin1String(dPIXElementC), QString::number(d.m_dpiX));
|
||||
if (d.m_dpiY > 0)
|
||||
writeElement(writer, QLatin1String(dPIYElementC), QString::number(d.m_dpiY));
|
||||
if (!d.m_style.isEmpty())
|
||||
writeElement(writer, QLatin1String(styleElementC), d.m_style);
|
||||
|
||||
writer.writeEndElement();
|
||||
writer.writeEndDocument();
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Switch stages when encountering a start element (state table) */
|
||||
enum ParseStage { ParseBeginning, ParseWithinRoot,
|
||||
ParseName, ParseFontFamily, ParseFontPointSize, ParseDPIX, ParseDPIY, ParseStyle,
|
||||
ParseError };
|
||||
|
||||
static ParseStage nextStage(ParseStage currentStage, const QStringRef &startElement)
|
||||
{
|
||||
switch (currentStage) {
|
||||
case ParseBeginning:
|
||||
if (startElement == QLatin1String(rootElementC))
|
||||
return ParseWithinRoot;
|
||||
break;
|
||||
case ParseWithinRoot:
|
||||
case ParseName:
|
||||
case ParseFontFamily:
|
||||
case ParseFontPointSize:
|
||||
case ParseDPIX:
|
||||
case ParseDPIY:
|
||||
case ParseStyle:
|
||||
if (startElement == QLatin1String(nameElementC))
|
||||
return ParseName;
|
||||
if (startElement == QLatin1String(fontFamilyElementC))
|
||||
return ParseFontFamily;
|
||||
if (startElement == QLatin1String(fontPointSizeElementC))
|
||||
return ParseFontPointSize;
|
||||
if (startElement == QLatin1String(dPIXElementC))
|
||||
return ParseDPIX;
|
||||
if (startElement == QLatin1String(dPIYElementC))
|
||||
return ParseDPIY;
|
||||
if (startElement == QLatin1String(styleElementC))
|
||||
return ParseStyle;
|
||||
break;
|
||||
case ParseError:
|
||||
break;
|
||||
}
|
||||
return ParseError;
|
||||
}
|
||||
|
||||
static bool readIntegerElement(QXmlStreamReader &reader, int *v)
|
||||
{
|
||||
const QString e = reader.readElementText();
|
||||
bool ok;
|
||||
*v = e.toInt(&ok);
|
||||
//: Reading a number for an embedded device profile
|
||||
if (!ok)
|
||||
reader.raiseError(QApplication::translate("DeviceProfile", "'%1' is not a number.").arg(e));
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool DeviceProfile::fromXml(const QString &xml, QString *errorMessage)
|
||||
{
|
||||
DeviceProfileData &d = *m_d;
|
||||
d.fromSystem();
|
||||
|
||||
QXmlStreamReader reader(xml);
|
||||
|
||||
ParseStage ps = ParseBeginning;
|
||||
QXmlStreamReader::TokenType tt = QXmlStreamReader::NoToken;
|
||||
int iv = 0;
|
||||
do {
|
||||
tt = reader.readNext();
|
||||
if (tt == QXmlStreamReader::StartElement) {
|
||||
ps = nextStage(ps, reader.name());
|
||||
switch (ps) {
|
||||
case ParseBeginning:
|
||||
case ParseWithinRoot:
|
||||
break;
|
||||
case ParseError:
|
||||
reader.raiseError(QApplication::translate("DeviceProfile", "An invalid tag <%1> was encountered.").arg(reader.name().toString()));
|
||||
tt = QXmlStreamReader::Invalid;
|
||||
break;
|
||||
case ParseName:
|
||||
d.m_name = reader.readElementText();
|
||||
break;
|
||||
case ParseFontFamily:
|
||||
d.m_fontFamily = reader.readElementText();
|
||||
break;
|
||||
case ParseFontPointSize:
|
||||
if (readIntegerElement(reader, &iv)) {
|
||||
d.m_fontPointSize = iv;
|
||||
} else {
|
||||
tt = QXmlStreamReader::Invalid;
|
||||
}
|
||||
break;
|
||||
case ParseDPIX:
|
||||
if (readIntegerElement(reader, &iv)) {
|
||||
d.m_dpiX = iv;
|
||||
} else {
|
||||
tt = QXmlStreamReader::Invalid;
|
||||
}
|
||||
break;
|
||||
case ParseDPIY:
|
||||
if (readIntegerElement(reader, &iv)) {
|
||||
d.m_dpiY = iv;
|
||||
} else {
|
||||
tt = QXmlStreamReader::Invalid;
|
||||
}
|
||||
break;
|
||||
case ParseStyle:
|
||||
d.m_style = reader.readElementText();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (tt != QXmlStreamReader::Invalid && tt != QXmlStreamReader::EndDocument);
|
||||
|
||||
if (reader.hasError()) {
|
||||
*errorMessage = reader.errorString();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
152
third/designer/lib/shared/deviceprofile_p.h
Normal file
152
third/designer/lib/shared/deviceprofile_p.h
Normal file
@@ -0,0 +1,152 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef DEVICEPROFILE_H
|
||||
#define DEVICEPROFILE_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QSharedDataPointer>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDesignerFormEditorInterface;
|
||||
class QWidget;
|
||||
class QStyle;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
class DeviceProfileData;
|
||||
|
||||
/* DeviceProfile for embedded design. They influence
|
||||
* default properties (for example, fonts), dpi and
|
||||
* style of the form. This class represents a device
|
||||
* profile. */
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT DeviceProfile {
|
||||
public:
|
||||
DeviceProfile();
|
||||
|
||||
DeviceProfile(const DeviceProfile&);
|
||||
DeviceProfile& operator=(const DeviceProfile&);
|
||||
~DeviceProfile();
|
||||
|
||||
void clear();
|
||||
|
||||
// Device name
|
||||
QString name() const;
|
||||
void setName(const QString &);
|
||||
|
||||
// System settings active
|
||||
bool isEmpty() const;
|
||||
|
||||
// Default font family of the embedded system
|
||||
QString fontFamily() const;
|
||||
void setFontFamily(const QString &);
|
||||
|
||||
// Default font size of the embedded system
|
||||
int fontPointSize() const;
|
||||
void setFontPointSize(int p);
|
||||
|
||||
// Display resolution of the embedded system
|
||||
int dpiX() const;
|
||||
void setDpiX(int d);
|
||||
int dpiY() const;
|
||||
void setDpiY(int d);
|
||||
|
||||
// Style
|
||||
QString style() const;
|
||||
void setStyle(const QString &);
|
||||
|
||||
// Initialize from desktop system
|
||||
void fromSystem();
|
||||
|
||||
static void systemResolution(int *dpiX, int *dpiY);
|
||||
static void widgetResolution(const QWidget *w, int *dpiX, int *dpiY);
|
||||
|
||||
bool equals(const DeviceProfile& rhs) const;
|
||||
|
||||
// Apply to form/preview (using font inheritance)
|
||||
enum ApplyMode {
|
||||
/* Pre-Apply to parent widget of form being edited: Apply font
|
||||
* and make use of property inheritance to be able to modify the
|
||||
* font property freely. */
|
||||
ApplyFormParent,
|
||||
/* Post-Apply to preview widget: Change only inherited font
|
||||
* sub properties. */
|
||||
ApplyPreview
|
||||
};
|
||||
void apply(const QDesignerFormEditorInterface *core, QWidget *widget, ApplyMode am) const;
|
||||
|
||||
static void applyDPI(int dpiX, int dpiY, QWidget *widget);
|
||||
|
||||
QString toString() const;
|
||||
|
||||
QString toXml() const;
|
||||
bool fromXml(const QString &xml, QString *errorMessage);
|
||||
|
||||
private:
|
||||
QSharedDataPointer<DeviceProfileData> m_d;
|
||||
};
|
||||
|
||||
inline bool operator==(const DeviceProfile &s1, const DeviceProfile &s2)
|
||||
{ return s1.equals(s2); }
|
||||
inline bool operator!=(const DeviceProfile &s1, const DeviceProfile &s2)
|
||||
{ return !s1.equals(s2); }
|
||||
|
||||
}
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // DEVICEPROFILE_H
|
||||
265
third/designer/lib/shared/dialoggui.cpp
Normal file
265
third/designer/lib/shared/dialoggui.cpp
Normal file
@@ -0,0 +1,265 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "dialoggui_p.h"
|
||||
|
||||
#include <QtGui/QFileIconProvider>
|
||||
#include <QtGui/QIcon>
|
||||
#include <QtGui/QImage>
|
||||
#include <QtGui/QImageReader>
|
||||
#include <QtGui/QPixmap>
|
||||
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QSet>
|
||||
|
||||
// QFileDialog on X11 does not provide an image preview. Display icons.
|
||||
#ifdef Q_WS_X11
|
||||
# define IMAGE_PREVIEW
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
// Icon provider that reads out the known image formats
|
||||
class IconProvider : public QFileIconProvider {
|
||||
Q_DISABLE_COPY(IconProvider)
|
||||
|
||||
public:
|
||||
IconProvider();
|
||||
virtual QIcon icon (const QFileInfo &info) const;
|
||||
|
||||
inline bool loadCheck(const QFileInfo &info) const;
|
||||
QImage loadImage(const QString &fileName) const;
|
||||
|
||||
private:
|
||||
QSet<QString> m_imageFormats;
|
||||
};
|
||||
|
||||
IconProvider::IconProvider()
|
||||
{
|
||||
// Determine a list of readable extensions (upper and lower case)
|
||||
typedef QList<QByteArray> ByteArrayList;
|
||||
const ByteArrayList fmts = QImageReader::supportedImageFormats();
|
||||
const ByteArrayList::const_iterator cend = fmts.constEnd();
|
||||
for (ByteArrayList::const_iterator it = fmts.constBegin(); it != cend; ++it) {
|
||||
const QString suffix = QString::fromUtf8(it->constData());
|
||||
m_imageFormats.insert(suffix.toLower());
|
||||
m_imageFormats.insert(suffix.toUpper());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Check by extension and type if this appears to be a loadable image
|
||||
bool IconProvider::loadCheck(const QFileInfo &info) const
|
||||
{
|
||||
if (info.isFile() && info.isReadable()) {
|
||||
const QString suffix = info.suffix();
|
||||
if (!suffix.isEmpty())
|
||||
return m_imageFormats.contains(suffix);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QImage IconProvider::loadImage(const QString &fileName) const
|
||||
{
|
||||
QFile file(fileName);
|
||||
if (file.open(QIODevice::ReadOnly)) {
|
||||
QImageReader imgReader(&file);
|
||||
if (imgReader.canRead()) {
|
||||
QImage image;
|
||||
if (imgReader.read(&image))
|
||||
return image;
|
||||
}
|
||||
}
|
||||
return QImage();
|
||||
}
|
||||
|
||||
QIcon IconProvider::icon (const QFileInfo &info) const
|
||||
{
|
||||
// Don't get stuck on large images.
|
||||
const qint64 maxSize = 131072;
|
||||
if (loadCheck(info) && info.size() < maxSize) {
|
||||
const QImage image = loadImage(info.absoluteFilePath());
|
||||
if (!image.isNull())
|
||||
return QIcon(QPixmap::fromImage(image, Qt::ThresholdDither|Qt::AutoColor));
|
||||
}
|
||||
return QFileIconProvider::icon(info);
|
||||
}
|
||||
|
||||
// ---------------- DialogGui
|
||||
DialogGui::DialogGui() :
|
||||
m_iconProvider(0)
|
||||
{
|
||||
}
|
||||
|
||||
DialogGui::~DialogGui()
|
||||
{
|
||||
delete m_iconProvider;
|
||||
}
|
||||
|
||||
QFileIconProvider *DialogGui::ensureIconProvider()
|
||||
{
|
||||
if (!m_iconProvider)
|
||||
m_iconProvider = new IconProvider;
|
||||
return m_iconProvider;
|
||||
}
|
||||
|
||||
QMessageBox::StandardButton
|
||||
DialogGui::message(QWidget *parent, Message /*context*/, QMessageBox::Icon icon,
|
||||
const QString &title, const QString &text, QMessageBox::StandardButtons buttons,
|
||||
QMessageBox::StandardButton defaultButton)
|
||||
{
|
||||
QMessageBox::StandardButton rc = QMessageBox::NoButton;
|
||||
switch (icon) {
|
||||
case QMessageBox::Information:
|
||||
rc = QMessageBox::information(parent, title, text, buttons, defaultButton);
|
||||
break;
|
||||
case QMessageBox::Warning:
|
||||
rc = QMessageBox::warning(parent, title, text, buttons, defaultButton);
|
||||
break;
|
||||
case QMessageBox::Critical:
|
||||
rc = QMessageBox::critical(parent, title, text, buttons, defaultButton);
|
||||
break;
|
||||
case QMessageBox::Question:
|
||||
rc = QMessageBox::question(parent, title, text, buttons, defaultButton);
|
||||
break;
|
||||
case QMessageBox::NoIcon:
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
QMessageBox::StandardButton
|
||||
DialogGui::message(QWidget *parent, Message /*context*/, QMessageBox::Icon icon,
|
||||
const QString &title, const QString &text, const QString &informativeText,
|
||||
QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
|
||||
{
|
||||
QMessageBox msgBox(icon, title, text, buttons, parent);
|
||||
msgBox.setDefaultButton(defaultButton);
|
||||
msgBox.setInformativeText(informativeText);
|
||||
return static_cast<QMessageBox::StandardButton>(msgBox.exec());
|
||||
}
|
||||
|
||||
QMessageBox::StandardButton
|
||||
DialogGui::message(QWidget *parent, Message /*context*/, QMessageBox::Icon icon,
|
||||
const QString &title, const QString &text, const QString &informativeText, const QString &detailedText,
|
||||
QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
|
||||
{
|
||||
QMessageBox msgBox(icon, title, text, buttons, parent);
|
||||
msgBox.setDefaultButton(defaultButton);
|
||||
msgBox.setInformativeText(informativeText);
|
||||
msgBox.setDetailedText(detailedText);
|
||||
return static_cast<QMessageBox::StandardButton>(msgBox.exec());
|
||||
}
|
||||
|
||||
QString DialogGui::getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options)
|
||||
{
|
||||
return QFileDialog::getExistingDirectory(parent, caption, dir, options);
|
||||
}
|
||||
|
||||
QString DialogGui::getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)
|
||||
{
|
||||
return QFileDialog::getOpenFileName(parent, caption, dir, filter, selectedFilter, options);
|
||||
}
|
||||
|
||||
QStringList DialogGui::getOpenFileNames(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)
|
||||
{
|
||||
return QFileDialog::getOpenFileNames(parent, caption, dir, filter, selectedFilter, options);
|
||||
}
|
||||
|
||||
QString DialogGui::getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)
|
||||
{
|
||||
return QFileDialog::getSaveFileName(parent, caption, dir, filter, selectedFilter, options);
|
||||
}
|
||||
|
||||
void DialogGui::initializeImageFileDialog(QFileDialog &fileDialog, QFileDialog::Options options, QFileDialog::FileMode fm)
|
||||
{
|
||||
fileDialog.setConfirmOverwrite( !(options & QFileDialog::DontConfirmOverwrite) );
|
||||
fileDialog.setResolveSymlinks( !(options & QFileDialog::DontResolveSymlinks) );
|
||||
fileDialog.setIconProvider(ensureIconProvider());
|
||||
fileDialog.setFileMode(fm);
|
||||
}
|
||||
|
||||
QString DialogGui::getOpenImageFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options )
|
||||
{
|
||||
|
||||
#ifdef IMAGE_PREVIEW
|
||||
QFileDialog fileDialog(parent, caption, dir, filter);
|
||||
initializeImageFileDialog(fileDialog, options, QFileDialog::ExistingFile);
|
||||
if (fileDialog.exec() != QDialog::Accepted)
|
||||
return QString();
|
||||
|
||||
const QStringList selectedFiles = fileDialog.selectedFiles();
|
||||
if (selectedFiles.empty())
|
||||
return QString();
|
||||
|
||||
if (selectedFilter)
|
||||
*selectedFilter = fileDialog.selectedFilter();
|
||||
|
||||
return selectedFiles.front();
|
||||
#else
|
||||
return getOpenFileName(parent, caption, dir, filter, selectedFilter, options);
|
||||
#endif
|
||||
}
|
||||
|
||||
QStringList DialogGui::getOpenImageFileNames(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options )
|
||||
{
|
||||
#ifdef IMAGE_PREVIEW
|
||||
QFileDialog fileDialog(parent, caption, dir, filter);
|
||||
initializeImageFileDialog(fileDialog, options, QFileDialog::ExistingFiles);
|
||||
if (fileDialog.exec() != QDialog::Accepted)
|
||||
return QStringList();
|
||||
|
||||
const QStringList selectedFiles = fileDialog.selectedFiles();
|
||||
if (!selectedFiles.empty() && selectedFilter)
|
||||
*selectedFilter = fileDialog.selectedFilter();
|
||||
|
||||
return selectedFiles;
|
||||
#else
|
||||
return getOpenFileNames(parent, caption, dir, filter, selectedFilter, options);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
107
third/designer/lib/shared/dialoggui_p.h
Normal file
107
third/designer/lib/shared/dialoggui_p.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef DIALOGGUI
|
||||
#define DIALOGGUI
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "shared_global_p.h"
|
||||
#include <abstractdialoggui_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QFileIconProvider;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT DialogGui : public QDesignerDialogGuiInterface
|
||||
{
|
||||
public:
|
||||
DialogGui();
|
||||
virtual ~DialogGui();
|
||||
|
||||
virtual QMessageBox::StandardButton
|
||||
message(QWidget *parent, Message context, QMessageBox::Icon icon,
|
||||
const QString &title, const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok,
|
||||
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
|
||||
|
||||
virtual QMessageBox::StandardButton
|
||||
message(QWidget *parent, Message context, QMessageBox::Icon icon,
|
||||
const QString &title, const QString &text, const QString &informativeText,
|
||||
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
|
||||
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
|
||||
|
||||
virtual QMessageBox::StandardButton
|
||||
message(QWidget *parent, Message context, QMessageBox::Icon icon,
|
||||
const QString &title, const QString &text, const QString &informativeText, const QString &detailedText,
|
||||
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
|
||||
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
|
||||
|
||||
virtual QString getExistingDirectory(QWidget *parent = 0, const QString &caption = QString(), const QString &dir = QString(), QFileDialog::Options options = QFileDialog::ShowDirsOnly);
|
||||
virtual QString getOpenFileName(QWidget *parent = 0, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0);
|
||||
virtual QStringList getOpenFileNames(QWidget *parent = 0, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0);
|
||||
virtual QString getSaveFileName(QWidget *parent = 0, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0);
|
||||
|
||||
virtual QString getOpenImageFileName(QWidget *parent = 0, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0);
|
||||
virtual QStringList getOpenImageFileNames(QWidget *parent = 0, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0);
|
||||
|
||||
private:
|
||||
QFileIconProvider *ensureIconProvider();
|
||||
void initializeImageFileDialog(QFileDialog &fd, QFileDialog::Options options, QFileDialog::FileMode);
|
||||
|
||||
QFileIconProvider *m_iconProvider;
|
||||
};
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // DIALOGGUI
|
||||
120
third/designer/lib/shared/extensionfactory_p.h
Normal file
120
third/designer/lib/shared/extensionfactory_p.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef SHARED_EXTENSIONFACTORY_H
|
||||
#define SHARED_EXTENSIONFACTORY_H
|
||||
|
||||
#include <QtDesigner/default_extensionfactory.h>
|
||||
#include <QtDesigner/QExtensionManager>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
// Extension factory for registering an extension for an object type.
|
||||
template <class ExtensionInterface, class Object, class Extension>
|
||||
class ExtensionFactory: public QExtensionFactory
|
||||
{
|
||||
public:
|
||||
explicit ExtensionFactory(const QString &iid, QExtensionManager *parent = 0);
|
||||
|
||||
// Convenience for registering the extension. Do not use for derived classes.
|
||||
static void registerExtension(QExtensionManager *mgr, const QString &iid);
|
||||
|
||||
protected:
|
||||
virtual QObject *createExtension(QObject *qObject, const QString &iid, QObject *parent) const;
|
||||
|
||||
private:
|
||||
// Can be overwritten to perform checks on the object.
|
||||
// Default does a qobject_cast to the desired class.
|
||||
virtual Object *checkObject(QObject *qObject) const;
|
||||
|
||||
const QString m_iid;
|
||||
};
|
||||
|
||||
template <class ExtensionInterface, class Object, class Extension>
|
||||
ExtensionFactory<ExtensionInterface, Object, Extension>::ExtensionFactory(const QString &iid, QExtensionManager *parent) :
|
||||
QExtensionFactory(parent),
|
||||
m_iid(iid)
|
||||
{
|
||||
}
|
||||
|
||||
template <class ExtensionInterface, class Object, class Extension>
|
||||
Object *ExtensionFactory<ExtensionInterface, Object, Extension>::checkObject(QObject *qObject) const
|
||||
{
|
||||
return qobject_cast<Object*>(qObject);
|
||||
}
|
||||
|
||||
template <class ExtensionInterface, class Object, class Extension>
|
||||
QObject *ExtensionFactory<ExtensionInterface, Object, Extension>::createExtension(QObject *qObject, const QString &iid, QObject *parent) const
|
||||
{
|
||||
if (iid != m_iid)
|
||||
return 0;
|
||||
|
||||
Object *object = checkObject(qObject);
|
||||
if (!object)
|
||||
return 0;
|
||||
|
||||
return new Extension(object, parent);
|
||||
}
|
||||
|
||||
template <class ExtensionInterface, class Object, class Extension>
|
||||
void ExtensionFactory<ExtensionInterface, Object, Extension>::registerExtension(QExtensionManager *mgr, const QString &iid)
|
||||
{
|
||||
ExtensionFactory *factory = new ExtensionFactory(iid, mgr);
|
||||
mgr->registerExtensions(factory, iid);
|
||||
}
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // SHARED_EXTENSIONFACTORY_H
|
||||
252
third/designer/lib/shared/filterwidget.cpp
Normal file
252
third/designer/lib/shared/filterwidget.cpp
Normal file
@@ -0,0 +1,252 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "filterwidget_p.h"
|
||||
#include "iconloader_p.h"
|
||||
|
||||
#include <QtGui/QVBoxLayout>
|
||||
#include <QtGui/QHBoxLayout>
|
||||
#include <QtGui/QLineEdit>
|
||||
#include <QtGui/QFocusEvent>
|
||||
#include <QtGui/QPalette>
|
||||
#include <QtGui/QCursor>
|
||||
#include <QtGui/QToolButton>
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QStyle>
|
||||
#include <QtGui/QStyleOption>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QPropertyAnimation>
|
||||
|
||||
enum { debugFilter = 0 };
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
HintLineEdit::HintLineEdit(QWidget *parent) :
|
||||
QLineEdit(parent),
|
||||
m_defaultFocusPolicy(focusPolicy()),
|
||||
m_refuseFocus(false)
|
||||
{
|
||||
}
|
||||
|
||||
IconButton::IconButton(QWidget *parent)
|
||||
: QToolButton(parent)
|
||||
{
|
||||
setCursor(Qt::ArrowCursor);
|
||||
}
|
||||
|
||||
void IconButton::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter painter(this);
|
||||
// Note isDown should really use the active state but in most styles
|
||||
// this has no proper feedback
|
||||
QIcon::Mode state = QIcon::Disabled;
|
||||
if (isEnabled())
|
||||
state = isDown() ? QIcon::Selected : QIcon::Normal;
|
||||
QPixmap iconpixmap = icon().pixmap(QSize(ICONBUTTON_SIZE, ICONBUTTON_SIZE),
|
||||
state, QIcon::Off);
|
||||
QRect pixmapRect = QRect(0, 0, iconpixmap.width(), iconpixmap.height());
|
||||
pixmapRect.moveCenter(rect().center());
|
||||
painter.setOpacity(m_fader);
|
||||
painter.drawPixmap(pixmapRect, iconpixmap);
|
||||
}
|
||||
|
||||
void IconButton::animateShow(bool visible)
|
||||
{
|
||||
if (visible) {
|
||||
QPropertyAnimation *animation = new QPropertyAnimation(this, "fader");
|
||||
animation->setDuration(160);
|
||||
animation->setEndValue(1.0);
|
||||
animation->start(QAbstractAnimation::DeleteWhenStopped);
|
||||
} else {
|
||||
QPropertyAnimation *animation = new QPropertyAnimation(this, "fader");
|
||||
animation->setDuration(160);
|
||||
animation->setEndValue(0.0);
|
||||
animation->start(QAbstractAnimation::DeleteWhenStopped);
|
||||
}
|
||||
}
|
||||
|
||||
bool HintLineEdit::refuseFocus() const
|
||||
{
|
||||
return m_refuseFocus;
|
||||
}
|
||||
|
||||
void HintLineEdit::setRefuseFocus(bool v)
|
||||
{
|
||||
if (v == m_refuseFocus)
|
||||
return;
|
||||
m_refuseFocus = v;
|
||||
setFocusPolicy(m_refuseFocus ? Qt::NoFocus : m_defaultFocusPolicy);
|
||||
}
|
||||
|
||||
void HintLineEdit::mousePressEvent(QMouseEvent *e)
|
||||
{
|
||||
if (debugFilter)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
// Explicitly focus on click.
|
||||
if (m_refuseFocus && !hasFocus())
|
||||
setFocus(Qt::OtherFocusReason);
|
||||
QLineEdit::mousePressEvent(e);
|
||||
}
|
||||
|
||||
void HintLineEdit::focusInEvent(QFocusEvent *e)
|
||||
{
|
||||
if (debugFilter)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
if (m_refuseFocus) {
|
||||
// Refuse the focus if the mouse it outside. In addition to the mouse
|
||||
// press logic, this prevents a re-focussing which occurs once
|
||||
// we actually had focus
|
||||
const Qt::FocusReason reason = e->reason();
|
||||
if (reason == Qt::ActiveWindowFocusReason || reason == Qt::PopupFocusReason) {
|
||||
const QPoint mousePos = mapFromGlobal(QCursor::pos());
|
||||
const bool refuse = !geometry().contains(mousePos);
|
||||
if (debugFilter)
|
||||
qDebug() << Q_FUNC_INFO << refuse ;
|
||||
if (refuse) {
|
||||
e->ignore();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QLineEdit::focusInEvent(e);
|
||||
}
|
||||
|
||||
// ------------------- FilterWidget
|
||||
FilterWidget::FilterWidget(QWidget *parent, LayoutMode lm) :
|
||||
QWidget(parent),
|
||||
m_editor(new HintLineEdit(this)),
|
||||
m_button(new IconButton(m_editor)),
|
||||
m_buttonwidth(0)
|
||||
{
|
||||
m_editor->setPlaceholderText(tr("Filter"));
|
||||
|
||||
// Let the style determine minimum height for our widget
|
||||
QSize size(ICONBUTTON_SIZE + 6, ICONBUTTON_SIZE + 2);
|
||||
|
||||
// Note KDE does not reserve space for the highlight color
|
||||
if (style()->inherits("OxygenStyle")) {
|
||||
size = size.expandedTo(QSize(24, 0));
|
||||
}
|
||||
|
||||
// Make room for clear icon
|
||||
QMargins margins = m_editor->textMargins();
|
||||
if (layoutDirection() == Qt::LeftToRight)
|
||||
margins.setRight(size.width());
|
||||
else
|
||||
margins.setLeft(size.width());
|
||||
|
||||
m_editor->setTextMargins(margins);
|
||||
|
||||
QHBoxLayout *l = new QHBoxLayout(this);
|
||||
l->setMargin(0);
|
||||
l->setSpacing(0);
|
||||
if (lm == LayoutAlignRight)
|
||||
l->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
|
||||
|
||||
l->addWidget(m_editor);
|
||||
|
||||
// KDE has custom icons for this. Notice that icon namings are counter intuitive
|
||||
// If these icons are not avaiable we use the freedesktop standard name before
|
||||
// falling back to a bundled resource
|
||||
QIcon icon = QIcon::fromTheme(layoutDirection() == Qt::LeftToRight ?
|
||||
QLatin1String("edit-clear-locationbar-rtl") :
|
||||
QLatin1String("edit-clear-locationbar-ltr"),
|
||||
QIcon::fromTheme("edit-clear", createIconSet(QLatin1String("cleartext.png"))));
|
||||
|
||||
m_button->setIcon(icon);
|
||||
m_button->setToolTip(tr("Clear text"));
|
||||
connect(m_button, SIGNAL(clicked()), this, SLOT(reset()));
|
||||
connect(m_editor, SIGNAL(textChanged(QString)), this, SLOT(checkButton(QString)));
|
||||
connect(m_editor, SIGNAL(textEdited(QString)), this, SIGNAL(filterChanged(QString)));
|
||||
}
|
||||
|
||||
QString FilterWidget::text() const
|
||||
{
|
||||
return m_editor->text();
|
||||
}
|
||||
|
||||
void FilterWidget::checkButton(const QString &text)
|
||||
{
|
||||
if (m_oldText.isEmpty() || text.isEmpty())
|
||||
m_button->animateShow(!m_editor->text().isEmpty());
|
||||
m_oldText = text;
|
||||
}
|
||||
|
||||
void FilterWidget::reset()
|
||||
{
|
||||
if (debugFilter)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
if (!m_editor->text().isEmpty()) {
|
||||
// Editor has lost focus once this is pressed
|
||||
m_editor->clear();
|
||||
emit filterChanged(QString());
|
||||
}
|
||||
}
|
||||
|
||||
void FilterWidget::resizeEvent(QResizeEvent *)
|
||||
{
|
||||
QRect contentRect = m_editor->rect();
|
||||
if (layoutDirection() == Qt::LeftToRight) {
|
||||
const int iconoffset = m_editor->textMargins().right() + 4;
|
||||
m_button->setGeometry(contentRect.adjusted(m_editor->width() - iconoffset, 0, 0, 0));
|
||||
} else {
|
||||
const int iconoffset = m_editor->textMargins().left() + 4;
|
||||
m_button->setGeometry(contentRect.adjusted(0, 0, -m_editor->width() + iconoffset, 0));
|
||||
}
|
||||
}
|
||||
|
||||
bool FilterWidget::refuseFocus() const
|
||||
{
|
||||
return m_editor->refuseFocus();
|
||||
}
|
||||
|
||||
void FilterWidget::setRefuseFocus(bool v)
|
||||
{
|
||||
m_editor->setRefuseFocus(v);
|
||||
}
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
151
third/designer/lib/shared/filterwidget_p.h
Normal file
151
third/designer/lib/shared/filterwidget_p.h
Normal file
@@ -0,0 +1,151 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef FILTERWIDGET_H
|
||||
#define FILTERWIDGET_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/QLineEdit>
|
||||
#include <QtGui/QColor>
|
||||
#include <QtGui/QToolButton>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QToolButton;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
/* This widget should never have initial focus
|
||||
* (ie, be the first widget of a dialog, else, the hint cannot be displayed.
|
||||
* For situations, where it is the only focusable control (widget box),
|
||||
* there is a special "refuseFocus()" mode, in which it clears the focus
|
||||
* policy and focusses explicitly on click (note that setting Qt::ClickFocus
|
||||
* is not sufficient for that as an ActivationFocus will occur). */
|
||||
|
||||
#define ICONBUTTON_SIZE 16
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT HintLineEdit : public QLineEdit {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit HintLineEdit(QWidget *parent = 0);
|
||||
|
||||
bool refuseFocus() const;
|
||||
void setRefuseFocus(bool v);
|
||||
|
||||
protected:
|
||||
virtual void mousePressEvent(QMouseEvent *event);
|
||||
virtual void focusInEvent(QFocusEvent *e);
|
||||
|
||||
private:
|
||||
const Qt::FocusPolicy m_defaultFocusPolicy;
|
||||
bool m_refuseFocus;
|
||||
};
|
||||
|
||||
// IconButton: This is a simple helper class that represents clickable icons
|
||||
|
||||
class IconButton: public QToolButton
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(float fader READ fader WRITE setFader)
|
||||
public:
|
||||
IconButton(QWidget *parent);
|
||||
void paintEvent(QPaintEvent *event);
|
||||
float fader() { return m_fader; }
|
||||
void setFader(float value) { m_fader = value; update(); }
|
||||
void animateShow(bool visible);
|
||||
|
||||
private:
|
||||
float m_fader;
|
||||
};
|
||||
|
||||
// FilterWidget: For filtering item views, with reset button Uses HintLineEdit.
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT FilterWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum LayoutMode {
|
||||
// For use in toolbars: Expand to the right
|
||||
LayoutAlignRight,
|
||||
// No special alignment
|
||||
LayoutAlignNone
|
||||
};
|
||||
|
||||
explicit FilterWidget(QWidget *parent = 0, LayoutMode lm = LayoutAlignRight);
|
||||
|
||||
QString text() const;
|
||||
void resizeEvent(QResizeEvent *);
|
||||
bool refuseFocus() const; // see HintLineEdit
|
||||
void setRefuseFocus(bool v);
|
||||
|
||||
signals:
|
||||
void filterChanged(const QString &);
|
||||
|
||||
public slots:
|
||||
void reset();
|
||||
|
||||
private slots:
|
||||
void checkButton(const QString &text);
|
||||
|
||||
private:
|
||||
HintLineEdit *m_editor;
|
||||
IconButton *m_button;
|
||||
int m_buttonwidth;
|
||||
QString m_oldText;
|
||||
};
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
534
third/designer/lib/shared/formlayoutmenu.cpp
Normal file
534
third/designer/lib/shared/formlayoutmenu.cpp
Normal file
@@ -0,0 +1,534 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "formlayoutmenu_p.h"
|
||||
#include "layoutinfo_p.h"
|
||||
#include "qdesigner_command_p.h"
|
||||
#include "qdesigner_utils_p.h"
|
||||
#include "qdesigner_propertycommand_p.h"
|
||||
#include "ui_formlayoutrowdialog.h"
|
||||
|
||||
#include <QtDesigner/QDesignerFormWindowInterface>
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
#include <QtDesigner/QDesignerWidgetFactoryInterface>
|
||||
#include <QtDesigner/QDesignerPropertySheetExtension>
|
||||
#include <QtDesigner/QExtensionManager>
|
||||
#include <QtDesigner/QDesignerWidgetDataBaseInterface>
|
||||
#include <QtDesigner/QDesignerLanguageExtension>
|
||||
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/QFormLayout>
|
||||
#include <QtGui/QUndoStack>
|
||||
#include <QtGui/QDialog>
|
||||
#include <QtGui/QPushButton>
|
||||
#include <QtGui/QRegExpValidator>
|
||||
|
||||
#include <QtCore/QPair>
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QRegExp>
|
||||
#include <QtCore/QMultiHash>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
static const char *buddyPropertyC = "buddy";
|
||||
static const char *fieldWidgetBaseClasses[] = {
|
||||
"QLineEdit", "QComboBox", "QSpinBox", "QDoubleSpinBox", "QCheckBox",
|
||||
"QDateEdit", "QTimeEdit", "QDateTimeEdit", "QDial", "QWidget"
|
||||
};
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
// Struct that describes a row of controls (descriptive label and control) to
|
||||
// be added to a form layout.
|
||||
struct FormLayoutRow {
|
||||
FormLayoutRow() : buddy(false) {}
|
||||
|
||||
QString labelName;
|
||||
QString labelText;
|
||||
QString fieldClassName;
|
||||
QString fieldName;
|
||||
bool buddy;
|
||||
};
|
||||
|
||||
// A Dialog to edit a FormLayoutRow. Lets the user input a label text, label
|
||||
// name, field widget type, field object name and buddy setting. As the
|
||||
// user types the label text; the object names to be used for label and field
|
||||
// are updated. It also checks the buddy setting depending on whether the
|
||||
// label text contains a buddy marker.
|
||||
class FormLayoutRowDialog : public QDialog {
|
||||
Q_DISABLE_COPY(FormLayoutRowDialog)
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FormLayoutRowDialog(QDesignerFormEditorInterface *core,
|
||||
QWidget *parent);
|
||||
|
||||
FormLayoutRow formLayoutRow() const;
|
||||
|
||||
bool buddy() const;
|
||||
void setBuddy(bool);
|
||||
|
||||
// Accessors for form layout row numbers using 0..[n-1] convention
|
||||
int row() const;
|
||||
void setRow(int);
|
||||
void setRowRange(int, int);
|
||||
|
||||
QString fieldClass() const;
|
||||
QString labelText() const;
|
||||
|
||||
static QStringList fieldWidgetClasses(QDesignerFormEditorInterface *core);
|
||||
|
||||
private slots:
|
||||
void labelTextEdited(const QString &text);
|
||||
void labelNameEdited(const QString &text);
|
||||
void fieldNameEdited(const QString &text);
|
||||
void buddyClicked();
|
||||
void fieldClassChanged(int);
|
||||
|
||||
private:
|
||||
bool isValid() const;
|
||||
void updateObjectNames(bool updateLabel, bool updateField);
|
||||
void updateOkButton();
|
||||
|
||||
// Check for buddy marker in string
|
||||
const QRegExp m_buddyMarkerRegexp;
|
||||
|
||||
Ui::FormLayoutRowDialog m_ui;
|
||||
bool m_labelNameEdited;
|
||||
bool m_fieldNameEdited;
|
||||
bool m_buddyClicked;
|
||||
};
|
||||
|
||||
FormLayoutRowDialog::FormLayoutRowDialog(QDesignerFormEditorInterface *core,
|
||||
QWidget *parent) :
|
||||
QDialog(parent),
|
||||
m_buddyMarkerRegexp(QLatin1String("\\&[^&]")),
|
||||
m_labelNameEdited(false),
|
||||
m_fieldNameEdited(false),
|
||||
m_buddyClicked(false)
|
||||
{
|
||||
Q_ASSERT(m_buddyMarkerRegexp.isValid());
|
||||
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
setModal(true);
|
||||
m_ui.setupUi(this);
|
||||
connect(m_ui.labelTextLineEdit, SIGNAL(textEdited(QString)), this, SLOT(labelTextEdited(QString)));
|
||||
|
||||
QRegExpValidator *nameValidator = new QRegExpValidator(QRegExp(QLatin1String("^[a-zA-Z0-9_]+$")), this);
|
||||
Q_ASSERT(nameValidator->regExp().isValid());
|
||||
|
||||
m_ui.labelNameLineEdit->setValidator(nameValidator);
|
||||
connect(m_ui.labelNameLineEdit, SIGNAL(textEdited(QString)),
|
||||
this, SLOT(labelNameEdited(QString)));
|
||||
|
||||
m_ui.fieldNameLineEdit->setValidator(nameValidator);
|
||||
connect(m_ui.fieldNameLineEdit, SIGNAL(textEdited(QString)),
|
||||
this, SLOT(fieldNameEdited(QString)));
|
||||
|
||||
connect(m_ui.buddyCheckBox, SIGNAL(clicked()), this, SLOT(buddyClicked()));
|
||||
|
||||
m_ui.fieldClassComboBox->addItems(fieldWidgetClasses(core));
|
||||
m_ui.fieldClassComboBox->setCurrentIndex(0);
|
||||
connect(m_ui.fieldClassComboBox, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(fieldClassChanged(int)));
|
||||
|
||||
updateOkButton();
|
||||
}
|
||||
|
||||
FormLayoutRow FormLayoutRowDialog::formLayoutRow() const
|
||||
{
|
||||
FormLayoutRow rc;
|
||||
rc.labelText = labelText();
|
||||
rc.labelName = m_ui.labelNameLineEdit->text();
|
||||
rc.fieldClassName = fieldClass();
|
||||
rc.fieldName = m_ui.fieldNameLineEdit->text();
|
||||
rc.buddy = buddy();
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool FormLayoutRowDialog::buddy() const
|
||||
{
|
||||
return m_ui.buddyCheckBox->checkState() == Qt::Checked;
|
||||
}
|
||||
|
||||
void FormLayoutRowDialog::setBuddy(bool b)
|
||||
{
|
||||
m_ui.buddyCheckBox->setCheckState(b ? Qt::Checked : Qt::Unchecked);
|
||||
}
|
||||
|
||||
// Convert rows to 1..n convention for users
|
||||
int FormLayoutRowDialog::row() const
|
||||
{
|
||||
return m_ui.rowSpinBox->value() - 1;
|
||||
}
|
||||
|
||||
void FormLayoutRowDialog::setRow(int row)
|
||||
{
|
||||
m_ui.rowSpinBox->setValue(row + 1);
|
||||
}
|
||||
|
||||
void FormLayoutRowDialog::setRowRange(int from, int to)
|
||||
{
|
||||
m_ui.rowSpinBox->setMinimum(from + 1);
|
||||
m_ui.rowSpinBox->setMaximum(to + 1);
|
||||
m_ui.rowSpinBox->setEnabled(to - from > 0);
|
||||
}
|
||||
|
||||
QString FormLayoutRowDialog::fieldClass() const
|
||||
{
|
||||
return m_ui.fieldClassComboBox->itemText(m_ui.fieldClassComboBox->currentIndex());
|
||||
}
|
||||
|
||||
QString FormLayoutRowDialog::labelText() const
|
||||
{
|
||||
return m_ui.labelTextLineEdit->text();
|
||||
}
|
||||
|
||||
bool FormLayoutRowDialog::isValid() const
|
||||
{
|
||||
// Check for non-empty names and presence of buddy marker if checked
|
||||
const QString name = labelText();
|
||||
if (name.isEmpty() || m_ui.labelNameLineEdit->text().isEmpty() || m_ui.fieldNameLineEdit->text().isEmpty())
|
||||
return false;
|
||||
if (buddy() && !name.contains(m_buddyMarkerRegexp))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void FormLayoutRowDialog::updateOkButton()
|
||||
{
|
||||
m_ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(isValid());
|
||||
}
|
||||
|
||||
void FormLayoutRowDialog::labelTextEdited(const QString &text)
|
||||
{
|
||||
updateObjectNames(true, true);
|
||||
// Set buddy if '&' is present unless the user changed it
|
||||
if (!m_buddyClicked)
|
||||
setBuddy(text.contains(m_buddyMarkerRegexp));
|
||||
|
||||
updateOkButton();
|
||||
}
|
||||
|
||||
// Get a suitable object name postfix from a class name:
|
||||
// "namespace::QLineEdit"->"LineEdit"
|
||||
static inline QString postFixFromClassName(QString className)
|
||||
{
|
||||
const int index = className.lastIndexOf(QLatin1String("::"));
|
||||
if (index != -1)
|
||||
className.remove(0, index + 2);
|
||||
if (className.size() > 2)
|
||||
if (className.at(0) == QLatin1Char('Q') || className.at(0) == QLatin1Char('K'))
|
||||
if (className.at(1).isUpper())
|
||||
className.remove(0, 1);
|
||||
return className;
|
||||
}
|
||||
|
||||
// Helper routines to filter out characters for converting texts into
|
||||
// class name prefixes. Only accepts ASCII characters/digits and underscores.
|
||||
|
||||
enum PrefixCharacterKind { PC_Digit, PC_UpperCaseLetter, PC_LowerCaseLetter,
|
||||
PC_Other, PC_Invalid };
|
||||
|
||||
static inline PrefixCharacterKind prefixCharacterKind(const QChar &c)
|
||||
{
|
||||
switch (c.category()) {
|
||||
case QChar::Number_DecimalDigit:
|
||||
return PC_Digit;
|
||||
case QChar::Letter_Lowercase: {
|
||||
const char a = c.toAscii();
|
||||
if (a >= 'a' && a <= 'z')
|
||||
return PC_LowerCaseLetter;
|
||||
}
|
||||
break;
|
||||
case QChar::Letter_Uppercase: {
|
||||
const char a = c.toAscii();
|
||||
if (a >= 'A' && a <= 'Z')
|
||||
return PC_UpperCaseLetter;
|
||||
}
|
||||
break;
|
||||
case QChar::Punctuation_Connector:
|
||||
if (c.toAscii() == '_')
|
||||
return PC_Other;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return PC_Invalid;
|
||||
}
|
||||
|
||||
// Convert the text the user types into a usable class name prefix by filtering
|
||||
// characters, lower-casing the first character and camel-casing subsequent
|
||||
// words. ("zip code:") --> ("zipCode").
|
||||
|
||||
static QString prefixFromLabel(const QString &prefix)
|
||||
{
|
||||
QString rc;
|
||||
const int length = prefix.size();
|
||||
bool lastWasAcceptable = false;
|
||||
for (int i = 0 ; i < length; i++) {
|
||||
const QChar c = prefix.at(i);
|
||||
const PrefixCharacterKind kind = prefixCharacterKind(c);
|
||||
const bool acceptable = kind != PC_Invalid;
|
||||
if (acceptable) {
|
||||
if (rc.isEmpty()) {
|
||||
// Lower-case first character
|
||||
rc += kind == PC_UpperCaseLetter ? c.toLower() : c;
|
||||
} else {
|
||||
// Camel-case words
|
||||
rc += !lastWasAcceptable && kind == PC_LowerCaseLetter ? c.toUpper() : c;
|
||||
}
|
||||
}
|
||||
lastWasAcceptable = acceptable;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
void FormLayoutRowDialog::updateObjectNames(bool updateLabel, bool updateField)
|
||||
{
|
||||
// Generate label + field object names from the label text, that is,
|
||||
// "&Zip code:" -> "zipcodeLabel", "zipcodeLineEdit" unless the user
|
||||
// edited it.
|
||||
const bool doUpdateLabel = !m_labelNameEdited && updateLabel;
|
||||
const bool doUpdateField = !m_fieldNameEdited && updateField;
|
||||
if (!doUpdateLabel && !doUpdateField)
|
||||
return;
|
||||
|
||||
const QString prefix = prefixFromLabel(labelText());
|
||||
// Set names
|
||||
if (doUpdateLabel)
|
||||
m_ui.labelNameLineEdit->setText(prefix + QLatin1String("Label"));
|
||||
if (doUpdateField)
|
||||
m_ui.fieldNameLineEdit->setText(prefix + postFixFromClassName(fieldClass()));
|
||||
}
|
||||
|
||||
void FormLayoutRowDialog::fieldClassChanged(int)
|
||||
{
|
||||
updateObjectNames(false, true);
|
||||
}
|
||||
|
||||
void FormLayoutRowDialog::labelNameEdited(const QString & /*text*/)
|
||||
{
|
||||
m_labelNameEdited = true; // stop auto-updating after user change
|
||||
updateOkButton();
|
||||
}
|
||||
|
||||
void FormLayoutRowDialog::fieldNameEdited(const QString & /*text*/)
|
||||
{
|
||||
m_fieldNameEdited = true; // stop auto-updating after user change
|
||||
updateOkButton();
|
||||
}
|
||||
|
||||
void FormLayoutRowDialog::buddyClicked()
|
||||
{
|
||||
m_buddyClicked = true; // stop auto-updating after user change
|
||||
updateOkButton();
|
||||
}
|
||||
|
||||
/* Create a list of classes suitable for field widgets. Take the fixed base
|
||||
* classes provided and look in the widget database for custom widgets derived
|
||||
* from them ("QLineEdit", "CustomLineEdit", "QComboBox"...). */
|
||||
QStringList FormLayoutRowDialog::fieldWidgetClasses(QDesignerFormEditorInterface *core)
|
||||
{
|
||||
// Base class -> custom widgets map
|
||||
typedef QMultiHash<QString, QString> ClassMap;
|
||||
|
||||
static QStringList rc;
|
||||
if (rc.empty()) {
|
||||
const int fwCount = sizeof(fieldWidgetBaseClasses)/sizeof(const char*);
|
||||
// Turn known base classes into list
|
||||
QStringList baseClasses;
|
||||
for (int i = 0; i < fwCount; i++)
|
||||
baseClasses.push_back(QLatin1String(fieldWidgetBaseClasses[i]));
|
||||
// Scan for custom widgets that inherit them and store them in a
|
||||
// multimap of base class->custom widgets unless we have a language
|
||||
// extension installed which might do funny things with custom widgets.
|
||||
ClassMap customClassMap;
|
||||
if (qt_extension<QDesignerLanguageExtension *>(core->extensionManager(), core) == 0) {
|
||||
const QDesignerWidgetDataBaseInterface *wdb = core->widgetDataBase();
|
||||
const int wdbCount = wdb->count();
|
||||
for (int w = 0; w < wdbCount; ++w) {
|
||||
// Check for non-container custom types that extend the
|
||||
// respective base class.
|
||||
const QDesignerWidgetDataBaseItemInterface *dbItem = wdb->item(w);
|
||||
if (!dbItem->isPromoted() && !dbItem->isContainer() && dbItem->isCustom()) {
|
||||
const int index = baseClasses.indexOf(dbItem->extends());
|
||||
if (index != -1)
|
||||
customClassMap.insert(baseClasses.at(index), dbItem->name());
|
||||
}
|
||||
}
|
||||
}
|
||||
// Compile final list, taking each base class and append custom widgets
|
||||
// based on it.
|
||||
for (int i = 0; i < fwCount; i++) {
|
||||
rc.push_back(baseClasses.at(i));
|
||||
rc += customClassMap.values(baseClasses.at(i));
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
// ------------------ Utilities
|
||||
|
||||
static QFormLayout *managedFormLayout(const QDesignerFormEditorInterface *core, const QWidget *w)
|
||||
{
|
||||
QLayout *l = 0;
|
||||
if (LayoutInfo::managedLayoutType(core, w, &l) == LayoutInfo::Form)
|
||||
return qobject_cast<QFormLayout *>(l);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Create the widgets of a control row and apply text properties contained
|
||||
// in the struct, called by addFormLayoutRow()
|
||||
static QPair<QWidget *,QWidget *>
|
||||
createWidgets(const FormLayoutRow &row, QWidget *parent,
|
||||
QDesignerFormWindowInterface *formWindow)
|
||||
{
|
||||
QDesignerFormEditorInterface *core = formWindow->core();
|
||||
QDesignerWidgetFactoryInterface *wf = core->widgetFactory();
|
||||
|
||||
QPair<QWidget *,QWidget *> rc = QPair<QWidget *,QWidget *>(wf->createWidget(QLatin1String("QLabel"), parent),
|
||||
wf->createWidget(row.fieldClassName, parent));
|
||||
// Set up properties of the label
|
||||
const QString objectNameProperty = QLatin1String("objectName");
|
||||
QDesignerPropertySheetExtension *labelSheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), rc.first);
|
||||
int nameIndex = labelSheet->indexOf(objectNameProperty);
|
||||
labelSheet->setProperty(nameIndex, qVariantFromValue(PropertySheetStringValue(row.labelName)));
|
||||
labelSheet->setChanged(nameIndex, true);
|
||||
formWindow->ensureUniqueObjectName(rc.first);
|
||||
const int textIndex = labelSheet->indexOf(QLatin1String("text"));
|
||||
labelSheet->setProperty(textIndex, qVariantFromValue(PropertySheetStringValue(row.labelText)));
|
||||
labelSheet->setChanged(textIndex, true);
|
||||
// Set up properties of the control
|
||||
QDesignerPropertySheetExtension *controlSheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), rc.second);
|
||||
nameIndex = controlSheet->indexOf(objectNameProperty);
|
||||
controlSheet->setProperty(nameIndex, qVariantFromValue(PropertySheetStringValue(row.fieldName)));
|
||||
controlSheet->setChanged(nameIndex, true);
|
||||
formWindow->ensureUniqueObjectName(rc.second);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Create a command sequence on the undo stack of the form window that creates
|
||||
// the widgets of the row and inserts them into the form layout.
|
||||
static void addFormLayoutRow(const FormLayoutRow &formLayoutRow, int row, QWidget *w,
|
||||
QDesignerFormWindowInterface *formWindow)
|
||||
{
|
||||
QFormLayout *formLayout = managedFormLayout(formWindow->core(), w);
|
||||
Q_ASSERT(formLayout);
|
||||
QUndoStack *undoStack = formWindow->commandHistory();
|
||||
const QString macroName = QCoreApplication::translate("Command", "Add '%1' to '%2'").arg(formLayoutRow.labelText, formLayout->objectName());
|
||||
undoStack->beginMacro(macroName);
|
||||
|
||||
// Create a list of widget insertion commands and pass them a cell position
|
||||
const QPair<QWidget *,QWidget *> widgetPair = createWidgets(formLayoutRow, w, formWindow);
|
||||
|
||||
InsertWidgetCommand *labelCmd = new InsertWidgetCommand(formWindow);
|
||||
labelCmd->init(widgetPair.first, false, row, 0);
|
||||
undoStack->push(labelCmd);
|
||||
InsertWidgetCommand *controlCmd = new InsertWidgetCommand(formWindow);
|
||||
controlCmd->init(widgetPair.second, false, row, 1);
|
||||
undoStack->push(controlCmd);
|
||||
if (formLayoutRow.buddy) {
|
||||
SetPropertyCommand *buddyCommand = new SetPropertyCommand(formWindow);
|
||||
buddyCommand->init(widgetPair.first, QLatin1String(buddyPropertyC), widgetPair.second->objectName());
|
||||
undoStack->push(buddyCommand);
|
||||
}
|
||||
undoStack->endMacro();
|
||||
}
|
||||
|
||||
// ---------------- FormLayoutMenu
|
||||
FormLayoutMenu::FormLayoutMenu(QObject *parent) :
|
||||
QObject(parent),
|
||||
m_separator1(new QAction(this)),
|
||||
m_populateFormAction(new QAction(tr("Add form layout row..."), this)),
|
||||
m_separator2(new QAction(this))
|
||||
{
|
||||
m_separator1->setSeparator(true);
|
||||
connect(m_populateFormAction, SIGNAL(triggered()), this, SLOT(slotAddRow()));
|
||||
m_separator2->setSeparator(true);
|
||||
}
|
||||
|
||||
void FormLayoutMenu::populate(QWidget *w, QDesignerFormWindowInterface *fw, ActionList &actions)
|
||||
{
|
||||
switch (LayoutInfo::managedLayoutType(fw->core(), w)) {
|
||||
case LayoutInfo::Form:
|
||||
if (!actions.empty() && !actions.back()->isSeparator())
|
||||
actions.push_back(m_separator1);
|
||||
actions.push_back(m_populateFormAction);
|
||||
actions.push_back(m_separator2);
|
||||
m_widget = w;
|
||||
break;
|
||||
default:
|
||||
m_widget = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void FormLayoutMenu::slotAddRow()
|
||||
{
|
||||
QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(m_widget);
|
||||
Q_ASSERT(m_widget && fw);
|
||||
const int rowCount = managedFormLayout(fw->core(), m_widget)->rowCount();
|
||||
|
||||
FormLayoutRowDialog dialog(fw->core(), fw);
|
||||
dialog.setRowRange(0, rowCount);
|
||||
dialog.setRow(rowCount);
|
||||
|
||||
if (dialog.exec() != QDialog::Accepted)
|
||||
return;
|
||||
addFormLayoutRow(dialog.formLayoutRow(), dialog.row(), m_widget, fw);
|
||||
}
|
||||
|
||||
QAction *FormLayoutMenu::preferredEditAction(QWidget *w, QDesignerFormWindowInterface *fw)
|
||||
{
|
||||
if (LayoutInfo::managedLayoutType(fw->core(), w) == LayoutInfo::Form) {
|
||||
m_widget = w;
|
||||
return m_populateFormAction;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#include "formlayoutmenu.moc"
|
||||
|
||||
100
third/designer/lib/shared/formlayoutmenu_p.h
Normal file
100
third/designer/lib/shared/formlayoutmenu_p.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef FORMLAYOUTMENU
|
||||
#define FORMLAYOUTMENU
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "shared_global_p.h"
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QPointer>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDesignerFormWindowInterface;
|
||||
|
||||
class QAction;
|
||||
class QWidget;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
// Task menu to be used for form layouts. Offers an options "Add row" which
|
||||
// pops up a dialog in which the user can specify label name, text and buddy.
|
||||
class QDESIGNER_SHARED_EXPORT FormLayoutMenu : public QObject
|
||||
{
|
||||
Q_DISABLE_COPY(FormLayoutMenu)
|
||||
Q_OBJECT
|
||||
public:
|
||||
typedef QList<QAction *> ActionList;
|
||||
|
||||
explicit FormLayoutMenu(QObject *parent);
|
||||
|
||||
// Populate a list of actions with the form layout actions.
|
||||
void populate(QWidget *w, QDesignerFormWindowInterface *fw, ActionList &actions);
|
||||
// For implementing QDesignerTaskMenuExtension::preferredEditAction():
|
||||
// Return appropriate action for double clicking.
|
||||
QAction *preferredEditAction(QWidget *w, QDesignerFormWindowInterface *fw);
|
||||
|
||||
private slots:
|
||||
void slotAddRow();
|
||||
|
||||
private:
|
||||
QAction *m_separator1;
|
||||
QAction *m_populateFormAction;
|
||||
QAction *m_separator2;
|
||||
QPointer<QWidget> m_widget;
|
||||
};
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // FORMLAYOUTMENU
|
||||
166
third/designer/lib/shared/formlayoutrowdialog.ui
Normal file
166
third/designer/lib/shared/formlayoutrowdialog.ui
Normal file
@@ -0,0 +1,166 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>FormLayoutRowDialog</class>
|
||||
<widget class="QDialog" name="FormLayoutRowDialog">
|
||||
<property name="windowTitle">
|
||||
<string>Add Form Layout Row</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::ExpandingFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelTextLabel">
|
||||
<property name="text">
|
||||
<string>&Label text:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>labelTextLineEdit</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="labelTextLineEdit">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>180</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="labelNameLineEdit"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="fieldClassLabel">
|
||||
<property name="text">
|
||||
<string>Field &type:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>fieldClassComboBox</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="fieldClassComboBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="fieldNameLabel">
|
||||
<property name="text">
|
||||
<string>&Field name:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>fieldNameLineEdit</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="buddyLabel">
|
||||
<property name="text">
|
||||
<string>&Buddy:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>buddyCheckBox</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QCheckBox" name="buddyCheckBox">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="rowLabel">
|
||||
<property name="text">
|
||||
<string>&Row:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>rowSpinBox</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QSpinBox" name="rowSpinBox"/>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="fieldNameLineEdit"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labelNameLabel">
|
||||
<property name="text">
|
||||
<string>Label &name:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>labelNameLineEdit</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>FormLayoutRowDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>FormLayoutRowDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
502
third/designer/lib/shared/formwindowbase.cpp
Normal file
502
third/designer/lib/shared/formwindowbase.cpp
Normal file
@@ -0,0 +1,502 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "formwindowbase_p.h"
|
||||
#include "connectionedit_p.h"
|
||||
#include "qdesigner_command_p.h"
|
||||
#include "qdesigner_propertysheet_p.h"
|
||||
#include "qdesigner_propertyeditor_p.h"
|
||||
#include "qdesigner_menu_p.h"
|
||||
#include "qdesigner_menubar_p.h"
|
||||
#include "shared_settings_p.h"
|
||||
#include "grid_p.h"
|
||||
#include "deviceprofile_p.h"
|
||||
#include "qdesigner_utils_p.h"
|
||||
|
||||
#include "qsimpleresource_p.h"
|
||||
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
#include <QtDesigner/QDesignerContainerExtension>
|
||||
#include <QtDesigner/QExtensionManager>
|
||||
#include <QtDesigner/QDesignerTaskMenuExtension>
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtGui/QListWidget>
|
||||
#include <QtGui/QTreeWidget>
|
||||
#include <QtGui/QTableWidget>
|
||||
#include <QtGui/QComboBox>
|
||||
#include <QtGui/QTabWidget>
|
||||
#include <QtGui/QToolBox>
|
||||
#include <QtGui/QToolBar>
|
||||
#include <QtGui/QStatusBar>
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QLabel>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
class FormWindowBasePrivate {
|
||||
public:
|
||||
explicit FormWindowBasePrivate(QDesignerFormEditorInterface *core);
|
||||
|
||||
static Grid m_defaultGrid;
|
||||
|
||||
QDesignerFormWindowInterface::Feature m_feature;
|
||||
Grid m_grid;
|
||||
bool m_hasFormGrid;
|
||||
DesignerPixmapCache *m_pixmapCache;
|
||||
DesignerIconCache *m_iconCache;
|
||||
QtResourceSet *m_resourceSet;
|
||||
QMap<QDesignerPropertySheet *, QMap<int, bool> > m_reloadableResources; // bool is dummy, QMap used as QSet
|
||||
QMap<QDesignerPropertySheet *, QObject *> m_reloadablePropertySheets;
|
||||
const DeviceProfile m_deviceProfile;
|
||||
FormWindowBase::LineTerminatorMode m_lineTerminatorMode;
|
||||
FormWindowBase::SaveResourcesBehaviour m_saveResourcesBehaviour;
|
||||
};
|
||||
|
||||
FormWindowBasePrivate::FormWindowBasePrivate(QDesignerFormEditorInterface *core) :
|
||||
m_feature(QDesignerFormWindowInterface::DefaultFeature),
|
||||
m_grid(m_defaultGrid),
|
||||
m_hasFormGrid(false),
|
||||
m_pixmapCache(0),
|
||||
m_iconCache(0),
|
||||
m_resourceSet(0),
|
||||
m_deviceProfile(QDesignerSharedSettings(core).currentDeviceProfile()),
|
||||
m_lineTerminatorMode(FormWindowBase::NativeLineTerminator),
|
||||
m_saveResourcesBehaviour(FormWindowBase::SaveAll)
|
||||
{
|
||||
}
|
||||
|
||||
Grid FormWindowBasePrivate::m_defaultGrid;
|
||||
|
||||
FormWindowBase::FormWindowBase(QDesignerFormEditorInterface *core, QWidget *parent, Qt::WindowFlags flags) :
|
||||
QDesignerFormWindowInterface(parent, flags),
|
||||
m_d(new FormWindowBasePrivate(core))
|
||||
{
|
||||
syncGridFeature();
|
||||
m_d->m_pixmapCache = new DesignerPixmapCache(this);
|
||||
m_d->m_iconCache = new DesignerIconCache(m_d->m_pixmapCache, this);
|
||||
}
|
||||
|
||||
FormWindowBase::~FormWindowBase()
|
||||
{
|
||||
delete m_d;
|
||||
}
|
||||
|
||||
DesignerPixmapCache *FormWindowBase::pixmapCache() const
|
||||
{
|
||||
return m_d->m_pixmapCache;
|
||||
}
|
||||
|
||||
DesignerIconCache *FormWindowBase::iconCache() const
|
||||
{
|
||||
return m_d->m_iconCache;
|
||||
}
|
||||
|
||||
QtResourceSet *FormWindowBase::resourceSet() const
|
||||
{
|
||||
return m_d->m_resourceSet;
|
||||
}
|
||||
|
||||
void FormWindowBase::setResourceSet(QtResourceSet *resourceSet)
|
||||
{
|
||||
m_d->m_resourceSet = resourceSet;
|
||||
}
|
||||
|
||||
void FormWindowBase::addReloadableProperty(QDesignerPropertySheet *sheet, int index)
|
||||
{
|
||||
m_d->m_reloadableResources[sheet][index] = true;
|
||||
}
|
||||
|
||||
void FormWindowBase::removeReloadableProperty(QDesignerPropertySheet *sheet, int index)
|
||||
{
|
||||
m_d->m_reloadableResources[sheet].remove(index);
|
||||
if (m_d->m_reloadableResources[sheet].count() == 0)
|
||||
m_d->m_reloadableResources.remove(sheet);
|
||||
}
|
||||
|
||||
void FormWindowBase::addReloadablePropertySheet(QDesignerPropertySheet *sheet, QObject *object)
|
||||
{
|
||||
if (qobject_cast<QTreeWidget *>(object) ||
|
||||
qobject_cast<QTableWidget *>(object) ||
|
||||
qobject_cast<QListWidget *>(object) ||
|
||||
qobject_cast<QComboBox *>(object))
|
||||
m_d->m_reloadablePropertySheets[sheet] = object;
|
||||
}
|
||||
|
||||
void FormWindowBase::removeReloadablePropertySheet(QDesignerPropertySheet *sheet)
|
||||
{
|
||||
m_d->m_reloadablePropertySheets.remove(sheet);
|
||||
}
|
||||
|
||||
void FormWindowBase::reloadProperties()
|
||||
{
|
||||
pixmapCache()->clear();
|
||||
iconCache()->clear();
|
||||
QMapIterator<QDesignerPropertySheet *, QMap<int, bool> > itSheet(m_d->m_reloadableResources);
|
||||
while (itSheet.hasNext()) {
|
||||
QDesignerPropertySheet *sheet = itSheet.next().key();
|
||||
QMapIterator<int, bool> itIndex(itSheet.value());
|
||||
while (itIndex.hasNext()) {
|
||||
const int index = itIndex.next().key();
|
||||
const QVariant newValue = sheet->property(index);
|
||||
if (qobject_cast<QLabel *>(sheet->object()) && sheet->propertyName(index) == QLatin1String("text")) {
|
||||
const PropertySheetStringValue newString = qVariantValue<PropertySheetStringValue>(newValue);
|
||||
// optimize a bit, reset only if the text value might contain a reference to qt resources
|
||||
// (however reloading of icons other than taken from resources might not work here)
|
||||
if (newString.value().contains(QLatin1String(":/"))) {
|
||||
const QVariant resetValue = qVariantFromValue(PropertySheetStringValue());
|
||||
sheet->setProperty(index, resetValue);
|
||||
}
|
||||
}
|
||||
sheet->setProperty(index, newValue);
|
||||
}
|
||||
if (QTabWidget *tabWidget = qobject_cast<QTabWidget *>(sheet->object())) {
|
||||
const int count = tabWidget->count();
|
||||
const int current = tabWidget->currentIndex();
|
||||
const QString currentTabIcon = QLatin1String("currentTabIcon");
|
||||
for (int i = 0; i < count; i++) {
|
||||
tabWidget->setCurrentIndex(i);
|
||||
const int index = sheet->indexOf(currentTabIcon);
|
||||
sheet->setProperty(index, sheet->property(index));
|
||||
}
|
||||
tabWidget->setCurrentIndex(current);
|
||||
} else if (QToolBox *toolBox = qobject_cast<QToolBox *>(sheet->object())) {
|
||||
const int count = toolBox->count();
|
||||
const int current = toolBox->currentIndex();
|
||||
const QString currentItemIcon = QLatin1String("currentItemIcon");
|
||||
for (int i = 0; i < count; i++) {
|
||||
toolBox->setCurrentIndex(i);
|
||||
const int index = sheet->indexOf(currentItemIcon);
|
||||
sheet->setProperty(index, sheet->property(index));
|
||||
}
|
||||
toolBox->setCurrentIndex(current);
|
||||
}
|
||||
}
|
||||
QMapIterator<QDesignerPropertySheet *, QObject *> itSh(m_d->m_reloadablePropertySheets);
|
||||
while (itSh.hasNext()) {
|
||||
QObject *object = itSh.next().value();
|
||||
reloadIconResources(iconCache(), object);
|
||||
}
|
||||
}
|
||||
|
||||
void FormWindowBase::resourceSetActivated(QtResourceSet *resource, bool resourceSetChanged)
|
||||
{
|
||||
if (resource == resourceSet() && resourceSetChanged) {
|
||||
reloadProperties();
|
||||
emit pixmapCache()->reloaded();
|
||||
emit iconCache()->reloaded();
|
||||
if (QDesignerPropertyEditor *propertyEditor = qobject_cast<QDesignerPropertyEditor *>(core()->propertyEditor()))
|
||||
propertyEditor->reloadResourceProperties();
|
||||
}
|
||||
}
|
||||
|
||||
QVariantMap FormWindowBase::formData()
|
||||
{
|
||||
QVariantMap rc;
|
||||
if (m_d->m_hasFormGrid)
|
||||
m_d->m_grid.addToVariantMap(rc, true);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void FormWindowBase::setFormData(const QVariantMap &vm)
|
||||
{
|
||||
Grid formGrid;
|
||||
m_d->m_hasFormGrid = formGrid.fromVariantMap(vm);
|
||||
if (m_d->m_hasFormGrid)
|
||||
m_d->m_grid = formGrid;
|
||||
}
|
||||
|
||||
QPoint FormWindowBase::grid() const
|
||||
{
|
||||
return QPoint(m_d->m_grid.deltaX(), m_d->m_grid.deltaY());
|
||||
}
|
||||
|
||||
void FormWindowBase::setGrid(const QPoint &grid)
|
||||
{
|
||||
m_d->m_grid.setDeltaX(grid.x());
|
||||
m_d->m_grid.setDeltaY(grid.y());
|
||||
}
|
||||
|
||||
bool FormWindowBase::hasFeature(Feature f) const
|
||||
{
|
||||
return f & m_d->m_feature;
|
||||
}
|
||||
|
||||
static void recursiveUpdate(QWidget *w)
|
||||
{
|
||||
w->update();
|
||||
|
||||
const QObjectList &l = w->children();
|
||||
const QObjectList::const_iterator cend = l.constEnd();
|
||||
for (QObjectList::const_iterator it = l.constBegin(); it != cend; ++it) {
|
||||
if (QWidget *w = qobject_cast<QWidget*>(*it))
|
||||
recursiveUpdate(w);
|
||||
}
|
||||
}
|
||||
|
||||
void FormWindowBase::setFeatures(Feature f)
|
||||
{
|
||||
m_d->m_feature = f;
|
||||
const bool enableGrid = f & GridFeature;
|
||||
m_d->m_grid.setVisible(enableGrid);
|
||||
m_d->m_grid.setSnapX(enableGrid);
|
||||
m_d->m_grid.setSnapY(enableGrid);
|
||||
emit featureChanged(f);
|
||||
recursiveUpdate(this);
|
||||
}
|
||||
|
||||
FormWindowBase::Feature FormWindowBase::features() const
|
||||
{
|
||||
return m_d->m_feature;
|
||||
}
|
||||
|
||||
bool FormWindowBase::gridVisible() const
|
||||
{
|
||||
return m_d->m_grid.visible() && currentTool() == 0;
|
||||
}
|
||||
|
||||
FormWindowBase::SaveResourcesBehaviour FormWindowBase::saveResourcesBehaviour() const
|
||||
{
|
||||
return m_d->m_saveResourcesBehaviour;
|
||||
}
|
||||
|
||||
void FormWindowBase::setSaveResourcesBehaviour(SaveResourcesBehaviour behaviour)
|
||||
{
|
||||
m_d->m_saveResourcesBehaviour = behaviour;
|
||||
}
|
||||
|
||||
void FormWindowBase::syncGridFeature()
|
||||
{
|
||||
if (m_d->m_grid.snapX() || m_d->m_grid.snapY())
|
||||
m_d->m_feature |= GridFeature;
|
||||
else
|
||||
m_d->m_feature &= ~GridFeature;
|
||||
}
|
||||
|
||||
void FormWindowBase::setDesignerGrid(const Grid& grid)
|
||||
{
|
||||
m_d->m_grid = grid;
|
||||
syncGridFeature();
|
||||
recursiveUpdate(this);
|
||||
}
|
||||
|
||||
const Grid &FormWindowBase::designerGrid() const
|
||||
{
|
||||
return m_d->m_grid;
|
||||
}
|
||||
|
||||
bool FormWindowBase::hasFormGrid() const
|
||||
{
|
||||
return m_d->m_hasFormGrid;
|
||||
}
|
||||
|
||||
void FormWindowBase::setHasFormGrid(bool b)
|
||||
{
|
||||
m_d->m_hasFormGrid = b;
|
||||
}
|
||||
|
||||
void FormWindowBase::setDefaultDesignerGrid(const Grid& grid)
|
||||
{
|
||||
FormWindowBasePrivate::m_defaultGrid = grid;
|
||||
}
|
||||
|
||||
const Grid &FormWindowBase::defaultDesignerGrid()
|
||||
{
|
||||
return FormWindowBasePrivate::m_defaultGrid;
|
||||
}
|
||||
|
||||
QMenu *FormWindowBase::initializePopupMenu(QWidget * /*managedWidget*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Widget under mouse for finding the Widget to highlight
|
||||
// when doing DnD. Restricts to pages by geometry if a container with
|
||||
// a container extension (or one of its helper widgets) is hit; otherwise
|
||||
// returns the widget as such (be it managed/unmanaged)
|
||||
|
||||
QWidget *FormWindowBase::widgetUnderMouse(const QPoint &formPos, WidgetUnderMouseMode /* wum */)
|
||||
{
|
||||
// widget_under_mouse might be some temporary thing like the dropLine. We need
|
||||
// the actual widget that's part of the edited GUI.
|
||||
QWidget *rc = widgetAt(formPos);
|
||||
if (!rc || qobject_cast<ConnectionEdit*>(rc))
|
||||
return 0;
|
||||
|
||||
if (rc == mainContainer()) {
|
||||
// Refuse main container areas if the main container has a container extension,
|
||||
// for example when hitting QToolBox/QTabWidget empty areas.
|
||||
if (qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), rc))
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
// If we hit on container extension type container, make sure
|
||||
// we use the top-most current page
|
||||
if (QWidget *container = findContainer(rc, false))
|
||||
if (QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), container)) {
|
||||
// For container that do not have a "stacked" nature (QToolBox, QMdiArea),
|
||||
// make sure the position is within the current page
|
||||
const int ci = c->currentIndex();
|
||||
if (ci < 0)
|
||||
return 0;
|
||||
QWidget *page = c->widget(ci);
|
||||
QRect pageGeometry = page->geometry();
|
||||
pageGeometry.moveTo(page->mapTo(this, pageGeometry.topLeft()));
|
||||
if (!pageGeometry.contains(formPos))
|
||||
return 0;
|
||||
return page;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void FormWindowBase::deleteWidgetList(const QWidgetList &widget_list)
|
||||
{
|
||||
// We need a macro here even for single widgets because the some components (for example,
|
||||
// the signal slot editor are connected to widgetRemoved() and add their
|
||||
// own commands (for example, to delete w's connections)
|
||||
const QString description = widget_list.size() == 1 ?
|
||||
tr("Delete '%1'").arg(widget_list.front()->objectName()) : tr("Delete");
|
||||
|
||||
commandHistory()->beginMacro(description);
|
||||
foreach (QWidget *w, widget_list) {
|
||||
emit widgetRemoved(w);
|
||||
DeleteWidgetCommand *cmd = new DeleteWidgetCommand(this);
|
||||
cmd->init(w);
|
||||
commandHistory()->push(cmd);
|
||||
}
|
||||
commandHistory()->endMacro();
|
||||
}
|
||||
|
||||
QMenu *FormWindowBase::createExtensionTaskMenu(QDesignerFormWindowInterface *fw, QObject *o, bool trailingSeparator)
|
||||
{
|
||||
typedef QList<QAction *> ActionList;
|
||||
ActionList actions;
|
||||
// 1) Standard public extension
|
||||
QExtensionManager *em = fw->core()->extensionManager();
|
||||
if (const QDesignerTaskMenuExtension *extTaskMenu = qt_extension<QDesignerTaskMenuExtension*>(em, o))
|
||||
actions += extTaskMenu->taskActions();
|
||||
if (const QDesignerTaskMenuExtension *intTaskMenu = qobject_cast<QDesignerTaskMenuExtension *>(em->extension(o, QLatin1String("QDesignerInternalTaskMenuExtension")))) {
|
||||
if (!actions.empty()) {
|
||||
QAction *a = new QAction(fw);
|
||||
a->setSeparator(true);
|
||||
actions.push_back(a);
|
||||
}
|
||||
actions += intTaskMenu->taskActions();
|
||||
}
|
||||
if (actions.empty())
|
||||
return 0;
|
||||
if (trailingSeparator && !actions.back()->isSeparator()) {
|
||||
QAction *a = new QAction(fw);
|
||||
a->setSeparator(true);
|
||||
actions.push_back(a);
|
||||
}
|
||||
QMenu *rc = new QMenu;
|
||||
const ActionList::const_iterator cend = actions.constEnd();
|
||||
for (ActionList::const_iterator it = actions.constBegin(); it != cend; ++it)
|
||||
rc->addAction(*it);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void FormWindowBase::emitObjectRemoved(QObject *o)
|
||||
{
|
||||
emit objectRemoved(o);
|
||||
}
|
||||
|
||||
DeviceProfile FormWindowBase::deviceProfile() const
|
||||
{
|
||||
return m_d->m_deviceProfile;
|
||||
}
|
||||
|
||||
QString FormWindowBase::styleName() const
|
||||
{
|
||||
return m_d->m_deviceProfile.isEmpty() ? QString() : m_d->m_deviceProfile.style();
|
||||
}
|
||||
|
||||
void FormWindowBase::emitWidgetRemoved(QWidget *w)
|
||||
{
|
||||
emit widgetRemoved(w);
|
||||
}
|
||||
|
||||
QString FormWindowBase::deviceProfileName() const
|
||||
{
|
||||
return m_d->m_deviceProfile.isEmpty() ? QString() : m_d->m_deviceProfile.name();
|
||||
}
|
||||
|
||||
void FormWindowBase::setLineTerminatorMode(FormWindowBase::LineTerminatorMode mode)
|
||||
{
|
||||
m_d->m_lineTerminatorMode = mode;
|
||||
}
|
||||
|
||||
FormWindowBase::LineTerminatorMode FormWindowBase::lineTerminatorMode() const
|
||||
{
|
||||
return m_d->m_lineTerminatorMode;
|
||||
}
|
||||
|
||||
void FormWindowBase::triggerDefaultAction(QWidget *widget)
|
||||
{
|
||||
if (QAction *action = qdesigner_internal::preferredEditAction(core(), widget))
|
||||
QTimer::singleShot(0, action, SIGNAL(triggered()));
|
||||
}
|
||||
|
||||
void FormWindowBase::setupDefaultAction(QDesignerFormWindowInterface *fw)
|
||||
{
|
||||
QObject::connect(fw, SIGNAL(activated(QWidget*)), fw, SLOT(triggerDefaultAction(QWidget*)));
|
||||
}
|
||||
|
||||
QString FormWindowBase::fileContents() const
|
||||
{
|
||||
const bool oldValue = QSimpleResource::setWarningsEnabled(false);
|
||||
const QString rc = contents();
|
||||
QSimpleResource::setWarningsEnabled(oldValue);
|
||||
return rc;
|
||||
}
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
205
third/designer/lib/shared/formwindowbase_p.h
Normal file
205
third/designer/lib/shared/formwindowbase_p.h
Normal file
@@ -0,0 +1,205 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef FORMWINDOWBASE_H
|
||||
#define FORMWINDOWBASE_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
|
||||
#include <QtDesigner/QDesignerFormWindowInterface>
|
||||
|
||||
#include <QtCore/QVariantMap>
|
||||
#include <QtCore/QList>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDesignerDnDItemInterface;
|
||||
class QMenu;
|
||||
class QtResourceSet;
|
||||
class QDesignerPropertySheet;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
class QEditorFormBuilder;
|
||||
class DeviceProfile;
|
||||
class Grid;
|
||||
|
||||
class DesignerPixmapCache;
|
||||
class DesignerIconCache;
|
||||
class FormWindowBasePrivate;
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT FormWindowBase: public QDesignerFormWindowInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum HighlightMode { Restore, Highlight };
|
||||
enum SaveResourcesBehaviour { SaveAll, SaveOnlyUsedQrcFiles, DontSaveQrcFiles };
|
||||
|
||||
explicit FormWindowBase(QDesignerFormEditorInterface *core, QWidget *parent = 0, Qt::WindowFlags flags = 0);
|
||||
virtual ~FormWindowBase();
|
||||
|
||||
QVariantMap formData();
|
||||
void setFormData(const QVariantMap &vm);
|
||||
|
||||
// Return contents without warnings. Should be 'contents(bool quiet)'
|
||||
QString fileContents() const;
|
||||
|
||||
// Return the widget containing the form. This is used to
|
||||
// apply embedded design settings to that are inherited (for example font).
|
||||
// These are meant to be applied to the form only and not to the other editors
|
||||
// in the widget stack.
|
||||
virtual QWidget *formContainer() const = 0;
|
||||
|
||||
// Deprecated
|
||||
virtual QPoint grid() const;
|
||||
|
||||
// Deprecated
|
||||
virtual void setGrid(const QPoint &grid);
|
||||
|
||||
virtual bool hasFeature(Feature f) const;
|
||||
virtual Feature features() const;
|
||||
virtual void setFeatures(Feature f);
|
||||
|
||||
const Grid &designerGrid() const;
|
||||
void setDesignerGrid(const Grid& grid);
|
||||
|
||||
bool hasFormGrid() const;
|
||||
void setHasFormGrid(bool b);
|
||||
|
||||
bool gridVisible() const;
|
||||
|
||||
SaveResourcesBehaviour saveResourcesBehaviour() const;
|
||||
void setSaveResourcesBehaviour(SaveResourcesBehaviour behaviour);
|
||||
|
||||
static const Grid &defaultDesignerGrid();
|
||||
static void setDefaultDesignerGrid(const Grid& grid);
|
||||
|
||||
// Overwrite to initialize and return a full popup menu for a managed widget
|
||||
virtual QMenu *initializePopupMenu(QWidget *managedWidget);
|
||||
// Helper to create a basic popup menu from task menu extensions (internal/public)
|
||||
static QMenu *createExtensionTaskMenu(QDesignerFormWindowInterface *fw, QObject *o, bool trailingSeparator = true);
|
||||
|
||||
virtual bool dropWidgets(const QList<QDesignerDnDItemInterface*> &item_list, QWidget *target,
|
||||
const QPoint &global_mouse_pos) = 0;
|
||||
|
||||
// Helper to find the widget at the mouse position with some flags.
|
||||
enum WidgetUnderMouseMode { FindSingleSelectionDropTarget, FindMultiSelectionDropTarget };
|
||||
QWidget *widgetUnderMouse(const QPoint &formPos, WidgetUnderMouseMode m);
|
||||
|
||||
virtual QWidget *widgetAt(const QPoint &pos) = 0;
|
||||
virtual QWidget *findContainer(QWidget *w, bool excludeLayout) const = 0;
|
||||
|
||||
void deleteWidgetList(const QWidgetList &widget_list);
|
||||
|
||||
virtual void highlightWidget(QWidget *w, const QPoint &pos, HighlightMode mode = Highlight) = 0;
|
||||
|
||||
enum PasteMode { PasteAll, PasteActionsOnly };
|
||||
virtual void paste(PasteMode pasteMode) = 0;
|
||||
|
||||
// Factory method to create a form builder
|
||||
virtual QEditorFormBuilder *createFormBuilder() = 0;
|
||||
|
||||
virtual bool blockSelectionChanged(bool blocked) = 0;
|
||||
virtual void emitSelectionChanged() = 0;
|
||||
|
||||
DesignerPixmapCache *pixmapCache() const;
|
||||
DesignerIconCache *iconCache() const;
|
||||
QtResourceSet *resourceSet() const;
|
||||
void setResourceSet(QtResourceSet *resourceSet);
|
||||
void addReloadableProperty(QDesignerPropertySheet *sheet, int index);
|
||||
void removeReloadableProperty(QDesignerPropertySheet *sheet, int index);
|
||||
void addReloadablePropertySheet(QDesignerPropertySheet *sheet, QObject *object);
|
||||
void removeReloadablePropertySheet(QDesignerPropertySheet *sheet);
|
||||
void reloadProperties();
|
||||
|
||||
void emitWidgetRemoved(QWidget *w);
|
||||
void emitObjectRemoved(QObject *o);
|
||||
|
||||
DeviceProfile deviceProfile() const;
|
||||
QString styleName() const;
|
||||
QString deviceProfileName() const;
|
||||
|
||||
enum LineTerminatorMode {
|
||||
LFLineTerminator,
|
||||
CRLFLineTerminator,
|
||||
NativeLineTerminator =
|
||||
#if defined (Q_OS_WIN)
|
||||
CRLFLineTerminator
|
||||
#else
|
||||
LFLineTerminator
|
||||
#endif
|
||||
};
|
||||
|
||||
void setLineTerminatorMode(LineTerminatorMode mode);
|
||||
LineTerminatorMode lineTerminatorMode() const;
|
||||
|
||||
// Connect the 'activated' (doubleclicked) signal of the form window to a
|
||||
// slot triggering the default action (of the task menu)
|
||||
static void setupDefaultAction(QDesignerFormWindowInterface *fw);
|
||||
|
||||
public slots:
|
||||
void resourceSetActivated(QtResourceSet *resourceSet, bool resourceSetChanged);
|
||||
|
||||
private slots:
|
||||
void triggerDefaultAction(QWidget *w);
|
||||
|
||||
private:
|
||||
void syncGridFeature();
|
||||
|
||||
FormWindowBasePrivate *m_d;
|
||||
};
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // FORMWINDOWBASE_H
|
||||
186
third/designer/lib/shared/grid.cpp
Normal file
186
third/designer/lib/shared/grid.cpp
Normal file
@@ -0,0 +1,186 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "grid_p.h"
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QVector>
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/qevent.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static const bool defaultSnap = true;
|
||||
static const bool defaultVisible = true;
|
||||
static const int DEFAULT_GRID = 10;
|
||||
static const char* KEY_VISIBLE = "gridVisible";
|
||||
static const char* KEY_SNAPX = "gridSnapX";
|
||||
static const char* KEY_SNAPY = "gridSnapY";
|
||||
static const char* KEY_DELTAX = "gridDeltaX";
|
||||
static const char* KEY_DELTAY = "gridDeltaY";
|
||||
|
||||
// Insert a value into the serialization map unless default
|
||||
template <class T>
|
||||
static inline void valueToVariantMap(T value, T defaultValue, const QString &key, QVariantMap &v, bool forceKey) {
|
||||
if (forceKey || value != defaultValue)
|
||||
v.insert(key, QVariant(value));
|
||||
}
|
||||
|
||||
// Obtain a value form QVariantMap
|
||||
template <class T>
|
||||
static inline bool valueFromVariantMap(const QVariantMap &v, const QString &key, T &value) {
|
||||
const QVariantMap::const_iterator it = v.constFind(key);
|
||||
const bool found = it != v.constEnd();
|
||||
if (found)
|
||||
value = qVariantValue<T>(it.value());
|
||||
return found;
|
||||
}
|
||||
|
||||
namespace qdesigner_internal
|
||||
{
|
||||
|
||||
Grid::Grid() :
|
||||
m_visible(defaultVisible),
|
||||
m_snapX(defaultSnap),
|
||||
m_snapY(defaultSnap),
|
||||
m_deltaX(DEFAULT_GRID),
|
||||
m_deltaY(DEFAULT_GRID)
|
||||
{
|
||||
}
|
||||
|
||||
bool Grid::fromVariantMap(const QVariantMap& vm)
|
||||
{
|
||||
*this = Grid();
|
||||
valueFromVariantMap(vm, QLatin1String(KEY_VISIBLE), m_visible);
|
||||
valueFromVariantMap(vm, QLatin1String(KEY_SNAPX), m_snapX);
|
||||
valueFromVariantMap(vm, QLatin1String(KEY_SNAPY), m_snapY);
|
||||
valueFromVariantMap(vm, QLatin1String(KEY_DELTAX), m_deltaX);
|
||||
return valueFromVariantMap(vm, QLatin1String(KEY_DELTAY), m_deltaY);
|
||||
}
|
||||
|
||||
QVariantMap Grid::toVariantMap(bool forceKeys) const
|
||||
{
|
||||
QVariantMap rc;
|
||||
addToVariantMap(rc, forceKeys);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void Grid::addToVariantMap(QVariantMap& vm, bool forceKeys) const
|
||||
{
|
||||
valueToVariantMap(m_visible, defaultVisible, QLatin1String(KEY_VISIBLE), vm, forceKeys);
|
||||
valueToVariantMap(m_snapX, defaultSnap, QLatin1String(KEY_SNAPX), vm, forceKeys);
|
||||
valueToVariantMap(m_snapY, defaultSnap, QLatin1String(KEY_SNAPY), vm, forceKeys);
|
||||
valueToVariantMap(m_deltaX, DEFAULT_GRID, QLatin1String(KEY_DELTAX), vm, forceKeys);
|
||||
valueToVariantMap(m_deltaY, DEFAULT_GRID, QLatin1String(KEY_DELTAY), vm, forceKeys);
|
||||
}
|
||||
|
||||
void Grid::paint(QWidget *widget, QPaintEvent *e) const
|
||||
{
|
||||
QPainter p(widget);
|
||||
paint(p, widget, e);
|
||||
}
|
||||
|
||||
void Grid::paint(QPainter &p, const QWidget *widget, QPaintEvent *e) const
|
||||
{
|
||||
p.setPen(widget->palette().dark().color());
|
||||
|
||||
if (m_visible) {
|
||||
const int xstart = (e->rect().x() / m_deltaX) * m_deltaX;
|
||||
const int ystart = (e->rect().y() / m_deltaY) * m_deltaY;
|
||||
|
||||
const int xend = e->rect().right();
|
||||
const int yend = e->rect().bottom();
|
||||
|
||||
typedef QVector<QPointF> Points;
|
||||
static Points points;
|
||||
points.clear();
|
||||
|
||||
for (int x = xstart; x <= xend; x += m_deltaX) {
|
||||
points.reserve((yend - ystart) / m_deltaY + 1);
|
||||
for (int y = ystart; y <= yend; y += m_deltaY)
|
||||
points.push_back(QPointF(x, y));
|
||||
p.drawPoints( &(*points.begin()), points.count());
|
||||
points.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Grid::snapValue(int value, int grid) const
|
||||
{
|
||||
const int rest = value % grid;
|
||||
const int absRest = (rest < 0) ? -rest : rest;
|
||||
int offset = 0;
|
||||
if (2 * absRest > grid)
|
||||
offset = 1;
|
||||
if (rest < 0)
|
||||
offset *= -1;
|
||||
return (value / grid + offset) * grid;
|
||||
}
|
||||
|
||||
QPoint Grid::snapPoint(const QPoint &p) const
|
||||
{
|
||||
const int sx = m_snapX ? snapValue(p.x(), m_deltaX) : p.x();
|
||||
const int sy = m_snapY ? snapValue(p.y(), m_deltaY) : p.y();
|
||||
return QPoint(sx, sy);
|
||||
}
|
||||
|
||||
int Grid::widgetHandleAdjustX(int x) const
|
||||
{
|
||||
return m_snapX ? (x / m_deltaX) * m_deltaX + 1 : x;
|
||||
}
|
||||
|
||||
int Grid::widgetHandleAdjustY(int y) const
|
||||
{
|
||||
return m_snapY ? (y / m_deltaY) * m_deltaY + 1 : y;
|
||||
}
|
||||
|
||||
bool Grid::equals(const Grid &rhs) const
|
||||
{
|
||||
return m_visible == rhs.m_visible &&
|
||||
m_snapX == rhs.m_snapX &&
|
||||
m_snapY == rhs.m_snapY &&
|
||||
m_deltaX == rhs.m_deltaX &&
|
||||
m_deltaY == rhs.m_deltaY;
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
118
third/designer/lib/shared/grid_p.h
Normal file
118
third/designer/lib/shared/grid_p.h
Normal file
@@ -0,0 +1,118 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef QDESIGNER_GRID_H
|
||||
#define QDESIGNER_GRID_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
|
||||
#include <QtCore/QVariantMap>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QWidget;
|
||||
class QPaintEvent;
|
||||
class QPainter;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
// Designer grid which is able to serialize to QVariantMap
|
||||
class QDESIGNER_SHARED_EXPORT Grid
|
||||
{
|
||||
public:
|
||||
Grid();
|
||||
|
||||
bool fromVariantMap(const QVariantMap& vm);
|
||||
|
||||
void addToVariantMap(QVariantMap& vm, bool forceKeys = false) const;
|
||||
QVariantMap toVariantMap(bool forceKeys = false) const;
|
||||
|
||||
inline bool visible() const { return m_visible; }
|
||||
void setVisible(bool visible) { m_visible = visible; }
|
||||
|
||||
inline bool snapX() const { return m_snapX; }
|
||||
void setSnapX(bool snap) { m_snapX = snap; }
|
||||
|
||||
inline bool snapY() const { return m_snapY; }
|
||||
void setSnapY(bool snap) { m_snapY = snap; }
|
||||
|
||||
inline int deltaX() const { return m_deltaX; }
|
||||
void setDeltaX(int dx) { m_deltaX = dx; }
|
||||
|
||||
inline int deltaY() const { return m_deltaY; }
|
||||
void setDeltaY(int dy) { m_deltaY = dy; }
|
||||
|
||||
void paint(QWidget *widget, QPaintEvent *e) const;
|
||||
void paint(QPainter &p, const QWidget *widget, QPaintEvent *e) const;
|
||||
|
||||
QPoint snapPoint(const QPoint &p) const;
|
||||
|
||||
int widgetHandleAdjustX(int x) const;
|
||||
int widgetHandleAdjustY(int y) const;
|
||||
|
||||
inline bool operator==(const Grid &rhs) const { return equals(rhs); }
|
||||
inline bool operator!=(const Grid &rhs) const { return !equals(rhs); }
|
||||
|
||||
private:
|
||||
bool equals(const Grid &rhs) const;
|
||||
int snapValue(int value, int grid) const;
|
||||
bool m_visible;
|
||||
bool m_snapX;
|
||||
bool m_snapY;
|
||||
int m_deltaX;
|
||||
int m_deltaY;
|
||||
};
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QDESIGNER_GRID_H
|
||||
121
third/designer/lib/shared/gridpanel.cpp
Normal file
121
third/designer/lib/shared/gridpanel.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "gridpanel_p.h"
|
||||
#include "ui_gridpanel.h"
|
||||
#include "grid_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
GridPanel::GridPanel(QWidget *parentWidget) :
|
||||
QWidget(parentWidget)
|
||||
{
|
||||
m_ui = new Ui::GridPanel;
|
||||
m_ui->setupUi(this);
|
||||
|
||||
connect(m_ui->m_resetButton, SIGNAL(clicked()), this, SLOT(reset()));
|
||||
}
|
||||
|
||||
GridPanel::~GridPanel()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void GridPanel::setGrid(const Grid &g)
|
||||
{
|
||||
m_ui->m_deltaXSpinBox->setValue(g.deltaX());
|
||||
m_ui->m_deltaYSpinBox->setValue(g.deltaY());
|
||||
m_ui->m_visibleCheckBox->setCheckState(g.visible() ? Qt::Checked : Qt::Unchecked);
|
||||
m_ui->m_snapXCheckBox->setCheckState(g.snapX() ? Qt::Checked : Qt::Unchecked);
|
||||
m_ui->m_snapYCheckBox->setCheckState(g.snapY() ? Qt::Checked : Qt::Unchecked);
|
||||
}
|
||||
|
||||
void GridPanel::setTitle(const QString &title)
|
||||
{
|
||||
m_ui->m_gridGroupBox->setTitle(title);
|
||||
}
|
||||
|
||||
Grid GridPanel::grid() const
|
||||
{
|
||||
Grid rc;
|
||||
rc.setDeltaX(m_ui->m_deltaXSpinBox->value());
|
||||
rc.setDeltaY(m_ui->m_deltaYSpinBox->value());
|
||||
rc.setSnapX(m_ui->m_snapXCheckBox->checkState() == Qt::Checked);
|
||||
rc.setSnapY(m_ui->m_snapYCheckBox->checkState() == Qt::Checked);
|
||||
rc.setVisible(m_ui->m_visibleCheckBox->checkState() == Qt::Checked);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void GridPanel::reset()
|
||||
{
|
||||
setGrid(Grid());
|
||||
}
|
||||
|
||||
void GridPanel::setCheckable (bool c)
|
||||
{
|
||||
m_ui->m_gridGroupBox->setCheckable(c);
|
||||
}
|
||||
|
||||
bool GridPanel::isCheckable () const
|
||||
{
|
||||
return m_ui->m_gridGroupBox->isCheckable ();
|
||||
}
|
||||
|
||||
bool GridPanel::isChecked () const
|
||||
{
|
||||
return m_ui->m_gridGroupBox->isChecked ();
|
||||
}
|
||||
|
||||
void GridPanel::setChecked(bool c)
|
||||
{
|
||||
m_ui->m_gridGroupBox->setChecked(c);
|
||||
}
|
||||
|
||||
void GridPanel::setResetButtonVisible(bool v)
|
||||
{
|
||||
m_ui->m_resetButton->setVisible(v);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
144
third/designer/lib/shared/gridpanel.ui
Normal file
144
third/designer/lib/shared/gridpanel.ui
Normal file
@@ -0,0 +1,144 @@
|
||||
<ui version="4.0" >
|
||||
<class>qdesigner_internal::GridPanel</class>
|
||||
<widget class="QWidget" name="qdesigner_internal::GridPanel" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>393</width>
|
||||
<height>110</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="leftMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="m_gridGroupBox" >
|
||||
<property name="title" >
|
||||
<string>Grid</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<item row="0" column="0" >
|
||||
<widget class="QCheckBox" name="m_visibleCheckBox" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Visible</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" >
|
||||
<widget class="QLabel" name="label" >
|
||||
<property name="text" >
|
||||
<string>Grid &X</string>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<cstring>m_deltaXSpinBox</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2" >
|
||||
<widget class="QSpinBox" name="m_deltaXSpinBox" >
|
||||
<property name="minimum" >
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="maximum" >
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3" >
|
||||
<widget class="QCheckBox" name="m_snapXCheckBox" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Snap</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" >
|
||||
<layout class="QHBoxLayout" >
|
||||
<item>
|
||||
<widget class="QPushButton" name="m_resetButton" >
|
||||
<property name="text" >
|
||||
<string>Reset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="1" >
|
||||
<widget class="QLabel" name="label_2" >
|
||||
<property name="text" >
|
||||
<string>Grid &Y</string>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<cstring>m_deltaYSpinBox</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2" >
|
||||
<widget class="QSpinBox" name="m_deltaYSpinBox" >
|
||||
<property name="minimum" >
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="maximum" >
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3" >
|
||||
<widget class="QCheckBox" name="m_snapYCheckBox" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Snap</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
101
third/designer/lib/shared/gridpanel_p.h
Normal file
101
third/designer/lib/shared/gridpanel_p.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the Qt tools. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef GRIDPANEL_H
|
||||
#define GRIDPANEL_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
|
||||
#include <QtGui/QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
class Grid;
|
||||
|
||||
namespace Ui {
|
||||
class GridPanel;
|
||||
}
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT GridPanel : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
GridPanel(QWidget *parent = 0);
|
||||
~GridPanel();
|
||||
|
||||
void setTitle(const QString &title);
|
||||
|
||||
void setGrid(const Grid &g);
|
||||
Grid grid() const;
|
||||
|
||||
void setCheckable (bool c);
|
||||
bool isCheckable () const;
|
||||
|
||||
bool isChecked () const;
|
||||
void setChecked(bool c);
|
||||
|
||||
void setResetButtonVisible(bool v);
|
||||
|
||||
private slots:
|
||||
void reset();
|
||||
|
||||
private:
|
||||
Ui::GridPanel *m_ui;
|
||||
};
|
||||
|
||||
} // qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // GRIDPANEL_H
|
||||
198
third/designer/lib/shared/htmlhighlighter.cpp
Normal file
198
third/designer/lib/shared/htmlhighlighter.cpp
Normal file
@@ -0,0 +1,198 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtCore/QTextStream>
|
||||
|
||||
#include "htmlhighlighter_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
HtmlHighlighter::HtmlHighlighter(QTextEdit *textEdit)
|
||||
: QSyntaxHighlighter(textEdit)
|
||||
{
|
||||
QTextCharFormat entityFormat;
|
||||
entityFormat.setForeground(Qt::red);
|
||||
setFormatFor(Entity, entityFormat);
|
||||
|
||||
QTextCharFormat tagFormat;
|
||||
tagFormat.setForeground(Qt::darkMagenta);
|
||||
tagFormat.setFontWeight(QFont::Bold);
|
||||
setFormatFor(Tag, tagFormat);
|
||||
|
||||
QTextCharFormat commentFormat;
|
||||
commentFormat.setForeground(Qt::gray);
|
||||
commentFormat.setFontItalic(true);
|
||||
setFormatFor(Comment, commentFormat);
|
||||
|
||||
QTextCharFormat attributeFormat;
|
||||
attributeFormat.setForeground(Qt::black);
|
||||
attributeFormat.setFontWeight(QFont::Bold);
|
||||
setFormatFor(Attribute, attributeFormat);
|
||||
|
||||
QTextCharFormat valueFormat;
|
||||
valueFormat.setForeground(Qt::blue);
|
||||
setFormatFor(Value, valueFormat);
|
||||
}
|
||||
|
||||
void HtmlHighlighter::setFormatFor(Construct construct,
|
||||
const QTextCharFormat &format)
|
||||
{
|
||||
m_formats[construct] = format;
|
||||
rehighlight();
|
||||
}
|
||||
|
||||
void HtmlHighlighter::highlightBlock(const QString &text)
|
||||
{
|
||||
static const QLatin1Char tab = QLatin1Char('\t');
|
||||
static const QLatin1Char space = QLatin1Char(' ');
|
||||
static const QLatin1Char amp = QLatin1Char('&');
|
||||
static const QLatin1Char startTag = QLatin1Char('<');
|
||||
static const QLatin1Char endTag = QLatin1Char('>');
|
||||
static const QLatin1Char quot = QLatin1Char('"');
|
||||
static const QLatin1Char apos = QLatin1Char('\'');
|
||||
static const QLatin1Char semicolon = QLatin1Char(';');
|
||||
static const QLatin1Char equals = QLatin1Char('=');
|
||||
static const QLatin1String startComment = QLatin1String("<!--");
|
||||
static const QLatin1String endComment = QLatin1String("-->");
|
||||
static const QLatin1String endElement = QLatin1String("/>");
|
||||
|
||||
int state = previousBlockState();
|
||||
int len = text.length();
|
||||
int start = 0;
|
||||
int pos = 0;
|
||||
|
||||
while (pos < len) {
|
||||
switch (state) {
|
||||
case NormalState:
|
||||
default:
|
||||
while (pos < len) {
|
||||
QChar ch = text.at(pos);
|
||||
if (ch == startTag) {
|
||||
if (text.mid(pos, 4) == startComment) {
|
||||
state = InComment;
|
||||
} else {
|
||||
state = InTag;
|
||||
start = pos;
|
||||
while (pos < len && text.at(pos) != space
|
||||
&& text.at(pos) != endTag
|
||||
&& text.at(pos) != tab
|
||||
&& text.mid(pos, 2) != endElement)
|
||||
++pos;
|
||||
if (text.mid(pos, 2) == endElement)
|
||||
++pos;
|
||||
setFormat(start, pos - start,
|
||||
m_formats[Tag]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
} else if (ch == amp) {
|
||||
start = pos;
|
||||
while (pos < len && text.at(pos++) != semicolon)
|
||||
;
|
||||
setFormat(start, pos - start,
|
||||
m_formats[Entity]);
|
||||
} else {
|
||||
// No tag, comment or entity started, continue...
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case InComment:
|
||||
start = pos;
|
||||
while (pos < len) {
|
||||
if (text.mid(pos, 3) == endComment) {
|
||||
pos += 3;
|
||||
state = NormalState;
|
||||
break;
|
||||
} else {
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
setFormat(start, pos - start, m_formats[Comment]);
|
||||
break;
|
||||
case InTag:
|
||||
QChar quote = QChar::Null;
|
||||
while (pos < len) {
|
||||
QChar ch = text.at(pos);
|
||||
if (quote.isNull()) {
|
||||
start = pos;
|
||||
if (ch == apos || ch == quot) {
|
||||
quote = ch;
|
||||
} else if (ch == endTag) {
|
||||
++pos;
|
||||
setFormat(start, pos - start, m_formats[Tag]);
|
||||
state = NormalState;
|
||||
break;
|
||||
} else if (text.mid(pos, 2) == endElement) {
|
||||
pos += 2;
|
||||
setFormat(start, pos - start, m_formats[Tag]);
|
||||
state = NormalState;
|
||||
break;
|
||||
} else if (ch != space && text.at(pos) != tab) {
|
||||
// Tag not ending, not a quote and no whitespace, so
|
||||
// we must be dealing with an attribute.
|
||||
++pos;
|
||||
while (pos < len && text.at(pos) != space
|
||||
&& text.at(pos) != tab
|
||||
&& text.at(pos) != equals)
|
||||
++pos;
|
||||
setFormat(start, pos - start, m_formats[Attribute]);
|
||||
start = pos;
|
||||
}
|
||||
} else if (ch == quote) {
|
||||
quote = QChar::Null;
|
||||
|
||||
// Anything quoted is a value
|
||||
setFormat(start, pos - start, m_formats[Value]);
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
setCurrentBlockState(state);
|
||||
}
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
101
third/designer/lib/shared/htmlhighlighter_p.h
Normal file
101
third/designer/lib/shared/htmlhighlighter_p.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef HTMLHIGHLIGHTER_H
|
||||
#define HTMLHIGHLIGHTER_H
|
||||
|
||||
#include <QtGui/QSyntaxHighlighter>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
/* HTML syntax highlighter based on Qt Quarterly example */
|
||||
class HtmlHighlighter : public QSyntaxHighlighter
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Construct {
|
||||
Entity,
|
||||
Tag,
|
||||
Comment,
|
||||
Attribute,
|
||||
Value,
|
||||
LastConstruct = Value
|
||||
};
|
||||
|
||||
HtmlHighlighter(QTextEdit *textEdit);
|
||||
|
||||
void setFormatFor(Construct construct, const QTextCharFormat &format);
|
||||
|
||||
QTextCharFormat formatFor(Construct construct) const
|
||||
{ return m_formats[construct]; }
|
||||
|
||||
protected:
|
||||
enum State {
|
||||
NormalState = -1,
|
||||
InComment,
|
||||
InTag
|
||||
};
|
||||
|
||||
void highlightBlock(const QString &text);
|
||||
|
||||
private:
|
||||
QTextCharFormat m_formats[LastConstruct + 1];
|
||||
};
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // HTMLHIGHLIGHTER_H
|
||||
79
third/designer/lib/shared/iconloader.cpp
Normal file
79
third/designer/lib/shared/iconloader.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "iconloader_p.h"
|
||||
|
||||
#include <QtCore/QFile>
|
||||
#include <QtGui/QIcon>
|
||||
#include <QtGui/QPixmap>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
QDESIGNER_SHARED_EXPORT QIcon createIconSet(const QString &name)
|
||||
{
|
||||
QStringList candidates = QStringList()
|
||||
<< (QString::fromUtf8(":/trolltech/formeditor/images/") + name)
|
||||
#ifdef Q_WS_MAC
|
||||
<< (QString::fromUtf8(":/trolltech/formeditor/images/mac/") + name)
|
||||
#else
|
||||
<< (QString::fromUtf8(":/trolltech/formeditor/images/win/") + name)
|
||||
#endif
|
||||
<< (QString::fromUtf8(":/trolltech/formeditor/images/designer_") + name);
|
||||
|
||||
foreach (const QString &f, candidates) {
|
||||
if (QFile::exists(f))
|
||||
return QIcon(f);
|
||||
}
|
||||
|
||||
return QIcon();
|
||||
}
|
||||
|
||||
QDESIGNER_SHARED_EXPORT QIcon emptyIcon()
|
||||
{
|
||||
return QIcon(QLatin1String(":/trolltech/formeditor/images/emptyicon.png"));
|
||||
}
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
72
third/designer/lib/shared/iconloader_p.h
Normal file
72
third/designer/lib/shared/iconloader_p.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef ICONLOADER_H
|
||||
#define ICONLOADER_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QString;
|
||||
class QIcon;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
QDESIGNER_SHARED_EXPORT QIcon createIconSet(const QString &name);
|
||||
QDESIGNER_SHARED_EXPORT QIcon emptyIcon();
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // ICONLOADER_H
|
||||
543
third/designer/lib/shared/iconselector.cpp
Normal file
543
third/designer/lib/shared/iconselector.cpp
Normal file
@@ -0,0 +1,543 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "iconselector_p.h"
|
||||
#include "qdesigner_utils_p.h"
|
||||
#include "qtresourcemodel_p.h"
|
||||
#include "qtresourceview_p.h"
|
||||
#include "iconloader_p.h"
|
||||
#include "qdesigner_integration_p.h"
|
||||
#include "formwindowbase_p.h"
|
||||
|
||||
#include <abstractdialoggui_p.h>
|
||||
#include <qdesigner_integration_p.h>
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
#include <QtDesigner/QDesignerResourceBrowserInterface>
|
||||
#include <QtDesigner/QDesignerLanguageExtension>
|
||||
#include <QtDesigner/QExtensionManager>
|
||||
|
||||
#include <QtGui/QToolButton>
|
||||
#include <QtCore/QSignalMapper>
|
||||
#include <QtGui/QComboBox>
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QDialogButtonBox>
|
||||
#include <QtGui/QPushButton>
|
||||
#include <QtGui/QDialog>
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtGui/QVBoxLayout>
|
||||
#include <QtGui/QImageReader>
|
||||
#include <QtGui/QDialogButtonBox>
|
||||
#include <QtGui/QVBoxLayout>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
// -------------------- LanguageResourceDialogPrivate
|
||||
class LanguageResourceDialogPrivate {
|
||||
LanguageResourceDialog *q_ptr;
|
||||
Q_DECLARE_PUBLIC(LanguageResourceDialog)
|
||||
|
||||
public:
|
||||
LanguageResourceDialogPrivate(QDesignerResourceBrowserInterface *rb);
|
||||
void init(LanguageResourceDialog *p);
|
||||
|
||||
void setCurrentPath(const QString &filePath);
|
||||
QString currentPath() const;
|
||||
|
||||
void slotAccepted();
|
||||
void slotPathChanged(const QString &);
|
||||
|
||||
private:
|
||||
void setOkButtonEnabled(bool v) { m_dialogButtonBox->button(QDialogButtonBox::Ok)->setEnabled(v); }
|
||||
static bool checkPath(const QString &p);
|
||||
|
||||
QDesignerResourceBrowserInterface *m_browser;
|
||||
QDialogButtonBox *m_dialogButtonBox;
|
||||
};
|
||||
|
||||
LanguageResourceDialogPrivate::LanguageResourceDialogPrivate(QDesignerResourceBrowserInterface *rb) :
|
||||
q_ptr(0),
|
||||
m_browser(rb),
|
||||
m_dialogButtonBox(new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel))
|
||||
{
|
||||
setOkButtonEnabled(false);
|
||||
}
|
||||
|
||||
void LanguageResourceDialogPrivate::init(LanguageResourceDialog *p)
|
||||
{
|
||||
q_ptr = p;
|
||||
QLayout *layout = new QVBoxLayout(p);
|
||||
layout->addWidget(m_browser);
|
||||
layout->addWidget(m_dialogButtonBox);
|
||||
QObject::connect(m_dialogButtonBox, SIGNAL(accepted()), p, SLOT(slotAccepted()));
|
||||
QObject::connect(m_dialogButtonBox, SIGNAL(rejected()), p, SLOT(reject()));
|
||||
QObject::connect(m_browser, SIGNAL(currentPathChanged(QString)), p, SLOT(slotPathChanged(QString)));
|
||||
QObject::connect(m_browser, SIGNAL(pathActivated(QString)), p, SLOT(slotAccepted()));
|
||||
p->setModal(true);
|
||||
p->setWindowTitle(LanguageResourceDialog::tr("Choose Resource"));
|
||||
p->setWindowFlags(p->windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
setOkButtonEnabled(false);
|
||||
}
|
||||
|
||||
void LanguageResourceDialogPrivate::setCurrentPath(const QString &filePath)
|
||||
{
|
||||
m_browser->setCurrentPath(filePath);
|
||||
setOkButtonEnabled(checkPath(filePath));
|
||||
}
|
||||
|
||||
QString LanguageResourceDialogPrivate::currentPath() const
|
||||
{
|
||||
return m_browser->currentPath();
|
||||
}
|
||||
|
||||
bool LanguageResourceDialogPrivate::checkPath(const QString &p)
|
||||
{
|
||||
return p.isEmpty() ? false : IconSelector::checkPixmap(p, IconSelector::CheckFast);
|
||||
}
|
||||
|
||||
void LanguageResourceDialogPrivate::slotAccepted()
|
||||
{
|
||||
if (checkPath(currentPath()))
|
||||
q_ptr->accept();
|
||||
}
|
||||
|
||||
void LanguageResourceDialogPrivate::slotPathChanged(const QString &p)
|
||||
{
|
||||
setOkButtonEnabled(checkPath(p));
|
||||
}
|
||||
|
||||
// ------------ LanguageResourceDialog
|
||||
LanguageResourceDialog::LanguageResourceDialog(QDesignerResourceBrowserInterface *rb, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
d_ptr(new LanguageResourceDialogPrivate(rb))
|
||||
{
|
||||
d_ptr->init( this);
|
||||
}
|
||||
|
||||
LanguageResourceDialog::~LanguageResourceDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void LanguageResourceDialog::setCurrentPath(const QString &filePath)
|
||||
{
|
||||
d_ptr->setCurrentPath(filePath);
|
||||
}
|
||||
|
||||
QString LanguageResourceDialog::currentPath() const
|
||||
{
|
||||
return d_ptr->currentPath();
|
||||
}
|
||||
|
||||
LanguageResourceDialog* LanguageResourceDialog::create(QDesignerFormEditorInterface *core, QWidget *parent)
|
||||
{
|
||||
if (QDesignerLanguageExtension *lang = qt_extension<QDesignerLanguageExtension *>(core->extensionManager(), core))
|
||||
if (QDesignerResourceBrowserInterface *rb = lang->createResourceBrowser(0))
|
||||
return new LanguageResourceDialog(rb, parent);
|
||||
if (QDesignerIntegration *di = qobject_cast<QDesignerIntegration*>(core->integration()))
|
||||
if (QDesignerResourceBrowserInterface *rb = di->createResourceBrowser(0))
|
||||
return new LanguageResourceDialog(rb, parent);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ------------ IconSelectorPrivate
|
||||
class IconSelectorPrivate
|
||||
{
|
||||
IconSelector *q_ptr;
|
||||
Q_DECLARE_PUBLIC(IconSelector)
|
||||
public:
|
||||
IconSelectorPrivate();
|
||||
|
||||
void slotStateActivated();
|
||||
void slotSetActivated();
|
||||
void slotSetResourceActivated();
|
||||
void slotSetFileActivated();
|
||||
void slotResetActivated();
|
||||
void slotResetAllActivated();
|
||||
void slotUpdate();
|
||||
|
||||
QList<QPair<QPair<QIcon::Mode, QIcon::State>, QString> > m_stateToName; // could be static map
|
||||
|
||||
QMap<QPair<QIcon::Mode, QIcon::State>, int> m_stateToIndex;
|
||||
QMap<int, QPair<QIcon::Mode, QIcon::State> > m_indexToState;
|
||||
|
||||
QIcon m_emptyIcon;
|
||||
QComboBox *m_stateComboBox;
|
||||
QToolButton *m_iconButton;
|
||||
QAction *m_resetAction;
|
||||
QAction *m_resetAllAction;
|
||||
PropertySheetIconValue m_icon;
|
||||
DesignerIconCache *m_iconCache;
|
||||
DesignerPixmapCache *m_pixmapCache;
|
||||
QtResourceModel *m_resourceModel;
|
||||
QDesignerFormEditorInterface *m_core;
|
||||
};
|
||||
|
||||
IconSelectorPrivate::IconSelectorPrivate() :
|
||||
q_ptr(0),
|
||||
m_stateComboBox(0),
|
||||
m_iconButton(0),
|
||||
m_resetAction(0),
|
||||
m_resetAllAction(0),
|
||||
m_iconCache(0),
|
||||
m_pixmapCache(0),
|
||||
m_resourceModel(0),
|
||||
m_core(0)
|
||||
{
|
||||
}
|
||||
void IconSelectorPrivate::slotUpdate()
|
||||
{
|
||||
QIcon icon;
|
||||
if (m_iconCache)
|
||||
icon = m_iconCache->icon(m_icon);
|
||||
|
||||
QMap<QPair<QIcon::Mode, QIcon::State>, PropertySheetPixmapValue> paths = m_icon.paths();
|
||||
QMapIterator<QPair<QIcon::Mode, QIcon::State>, int> itIndex(m_stateToIndex);
|
||||
while (itIndex.hasNext()) {
|
||||
const QPair<QIcon::Mode, QIcon::State> state = itIndex.next().key();
|
||||
const PropertySheetPixmapValue pixmap = paths.value(state);
|
||||
const int index = itIndex.value();
|
||||
|
||||
QIcon pixmapIcon = QIcon(icon.pixmap(16, 16, state.first, state.second));
|
||||
if (pixmapIcon.isNull())
|
||||
pixmapIcon = m_emptyIcon;
|
||||
m_stateComboBox->setItemIcon(index, pixmapIcon);
|
||||
QFont font = q_ptr->font();
|
||||
if (!pixmap.path().isEmpty())
|
||||
font.setBold(true);
|
||||
m_stateComboBox->setItemData(index, font, Qt::FontRole);
|
||||
}
|
||||
|
||||
QPair<QIcon::Mode, QIcon::State> state = m_indexToState.value(m_stateComboBox->currentIndex());
|
||||
PropertySheetPixmapValue currentPixmap = paths.value(state);
|
||||
m_resetAction->setEnabled(!currentPixmap.path().isEmpty());
|
||||
m_resetAllAction->setEnabled(!paths.isEmpty());
|
||||
m_stateComboBox->update();
|
||||
}
|
||||
|
||||
void IconSelectorPrivate::slotStateActivated()
|
||||
{
|
||||
slotUpdate();
|
||||
}
|
||||
|
||||
void IconSelectorPrivate::slotSetActivated()
|
||||
{
|
||||
QPair<QIcon::Mode, QIcon::State> state = m_indexToState.value(m_stateComboBox->currentIndex());
|
||||
const PropertySheetPixmapValue pixmap = m_icon.pixmap(state.first, state.second);
|
||||
// Default to resource
|
||||
const PropertySheetPixmapValue::PixmapSource ps = pixmap.path().isEmpty() ? PropertySheetPixmapValue::ResourcePixmap : pixmap.pixmapSource(m_core);
|
||||
switch (ps) {
|
||||
case PropertySheetPixmapValue::LanguageResourcePixmap:
|
||||
case PropertySheetPixmapValue::ResourcePixmap:
|
||||
slotSetResourceActivated();
|
||||
break;
|
||||
case PropertySheetPixmapValue::FilePixmap:
|
||||
slotSetFileActivated();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Choose a pixmap from resource; use language-dependent resource browser if present
|
||||
QString IconSelector::choosePixmapResource(QDesignerFormEditorInterface *core, QtResourceModel *resourceModel, const QString &oldPath, QWidget *parent)
|
||||
{
|
||||
Q_UNUSED(resourceModel)
|
||||
QString rc;
|
||||
|
||||
if (LanguageResourceDialog* ldlg = LanguageResourceDialog::create(core, parent)) {
|
||||
ldlg->setCurrentPath(oldPath);
|
||||
if (ldlg->exec() == QDialog::Accepted)
|
||||
rc = ldlg->currentPath();
|
||||
delete ldlg;
|
||||
} else {
|
||||
QtResourceViewDialog dlg(core, parent);
|
||||
|
||||
QDesignerIntegration *designerIntegration = qobject_cast<QDesignerIntegration *>(core->integration());
|
||||
if (designerIntegration)
|
||||
dlg.setResourceEditingEnabled(designerIntegration->isResourceEditingEnabled());
|
||||
|
||||
dlg.selectResource(oldPath);
|
||||
if (dlg.exec() == QDialog::Accepted)
|
||||
rc = dlg.selectedResource();
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
void IconSelectorPrivate::slotSetResourceActivated()
|
||||
{
|
||||
const QPair<QIcon::Mode, QIcon::State> state = m_indexToState.value(m_stateComboBox->currentIndex());
|
||||
|
||||
PropertySheetPixmapValue pixmap = m_icon.pixmap(state.first, state.second);
|
||||
const QString oldPath = pixmap.path();
|
||||
const QString newPath = IconSelector::choosePixmapResource(m_core, m_resourceModel, oldPath, q_ptr);
|
||||
if (newPath.isEmpty() || newPath == oldPath)
|
||||
return;
|
||||
const PropertySheetPixmapValue newPixmap = PropertySheetPixmapValue(newPath);
|
||||
if (newPixmap != pixmap) {
|
||||
m_icon.setPixmap(state.first, state.second, newPixmap);
|
||||
slotUpdate();
|
||||
emit q_ptr->iconChanged(m_icon);
|
||||
}
|
||||
}
|
||||
|
||||
// Helpers for choosing image files: Check for valid image.
|
||||
bool IconSelector::checkPixmap(const QString &fileName, CheckMode cm, QString *errorMessage)
|
||||
{
|
||||
const QFileInfo fi(fileName);
|
||||
if (!fi.exists() || !fi.isFile() || !fi.isReadable()) {
|
||||
if (errorMessage)
|
||||
*errorMessage = tr("The pixmap file '%1' cannot be read.").arg(fileName);
|
||||
return false;
|
||||
}
|
||||
QImageReader reader(fileName);
|
||||
if (!reader.canRead()) {
|
||||
if (errorMessage)
|
||||
*errorMessage = tr("The file '%1' does not appear to be a valid pixmap file: %2").arg(fileName).arg(reader.errorString());
|
||||
return false;
|
||||
}
|
||||
if (cm == CheckFast)
|
||||
return true;
|
||||
|
||||
const QImage image = reader.read();
|
||||
if (image.isNull()) {
|
||||
if (errorMessage)
|
||||
*errorMessage = tr("The file '%1' could not be read: %2").arg(fileName).arg(reader.errorString());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Helpers for choosing image files: Return an image filter for QFileDialog, courtesy of StyledButton
|
||||
static QString imageFilter()
|
||||
{
|
||||
QString filter = QApplication::translate("IconSelector", "All Pixmaps (");
|
||||
const QList<QByteArray> supportedImageFormats = QImageReader::supportedImageFormats();
|
||||
const QString jpeg = QLatin1String("JPEG");
|
||||
const int count = supportedImageFormats.count();
|
||||
for (int i = 0; i< count; ++i) {
|
||||
if (i)
|
||||
filter += QLatin1Char(' ');
|
||||
filter += QLatin1String("*.");
|
||||
const QString outputFormat = QString::fromUtf8(supportedImageFormats.at(i));
|
||||
if (outputFormat != jpeg)
|
||||
filter += outputFormat.toLower();
|
||||
else
|
||||
filter += QLatin1String("jpg *.jpeg");
|
||||
}
|
||||
filter += QLatin1Char(')');
|
||||
return filter;
|
||||
}
|
||||
|
||||
// Helpers for choosing image files: Choose a file
|
||||
QString IconSelector::choosePixmapFile(const QString &directory, QDesignerDialogGuiInterface *dlgGui,QWidget *parent)
|
||||
{
|
||||
QString errorMessage;
|
||||
QString newPath;
|
||||
do {
|
||||
const QString title = tr("Choose a Pixmap");
|
||||
static const QString filter = imageFilter();
|
||||
newPath = dlgGui->getOpenImageFileName(parent, title, directory, filter);
|
||||
if (newPath.isEmpty())
|
||||
break;
|
||||
if (checkPixmap(newPath, CheckFully, &errorMessage))
|
||||
break;
|
||||
dlgGui->message(parent, QDesignerDialogGuiInterface::ResourceEditorMessage, QMessageBox::Warning, tr("Pixmap Read Error"), errorMessage);
|
||||
} while(true);
|
||||
return newPath;
|
||||
}
|
||||
|
||||
void IconSelectorPrivate::slotSetFileActivated()
|
||||
{
|
||||
QPair<QIcon::Mode, QIcon::State> state = m_indexToState.value(m_stateComboBox->currentIndex());
|
||||
|
||||
PropertySheetPixmapValue pixmap = m_icon.pixmap(state.first, state.second);
|
||||
const QString newPath = IconSelector::choosePixmapFile(pixmap.path(), m_core->dialogGui(), q_ptr);
|
||||
if (!newPath.isEmpty()) {
|
||||
const PropertySheetPixmapValue newPixmap = PropertySheetPixmapValue(newPath);
|
||||
if (!(newPixmap == pixmap)) {
|
||||
m_icon.setPixmap(state.first, state.second, newPixmap);
|
||||
slotUpdate();
|
||||
emit q_ptr->iconChanged(m_icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IconSelectorPrivate::slotResetActivated()
|
||||
{
|
||||
QPair<QIcon::Mode, QIcon::State> state = m_indexToState.value(m_stateComboBox->currentIndex());
|
||||
|
||||
PropertySheetPixmapValue pixmap = m_icon.pixmap(state.first, state.second);
|
||||
const PropertySheetPixmapValue newPixmap;
|
||||
if (!(newPixmap == pixmap)) {
|
||||
m_icon.setPixmap(state.first, state.second, newPixmap);
|
||||
slotUpdate();
|
||||
emit q_ptr->iconChanged(m_icon);
|
||||
}
|
||||
}
|
||||
|
||||
void IconSelectorPrivate::slotResetAllActivated()
|
||||
{
|
||||
const PropertySheetIconValue newIcon;
|
||||
if (!(m_icon == newIcon)) {
|
||||
m_icon = newIcon;
|
||||
slotUpdate();
|
||||
emit q_ptr->iconChanged(m_icon);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------- IconSelector
|
||||
IconSelector::IconSelector(QWidget *parent) :
|
||||
QWidget(parent), d_ptr(new IconSelectorPrivate())
|
||||
{
|
||||
d_ptr->q_ptr = this;
|
||||
|
||||
d_ptr->m_stateComboBox = new QComboBox(this);
|
||||
|
||||
QHBoxLayout *l = new QHBoxLayout(this);
|
||||
d_ptr->m_iconButton = new QToolButton(this);
|
||||
d_ptr->m_iconButton->setText(tr("..."));
|
||||
d_ptr->m_iconButton->setPopupMode(QToolButton::MenuButtonPopup);
|
||||
l->addWidget(d_ptr->m_stateComboBox);
|
||||
l->addWidget(d_ptr->m_iconButton);
|
||||
l->setMargin(0);
|
||||
|
||||
d_ptr->m_stateToName << qMakePair(qMakePair(QIcon::Normal, QIcon::Off), tr("Normal Off") );
|
||||
d_ptr->m_stateToName << qMakePair(qMakePair(QIcon::Normal, QIcon::On), tr("Normal On") );
|
||||
d_ptr->m_stateToName << qMakePair(qMakePair(QIcon::Disabled, QIcon::Off), tr("Disabled Off") );
|
||||
d_ptr->m_stateToName << qMakePair(qMakePair(QIcon::Disabled, QIcon::On), tr("Disabled On") );
|
||||
d_ptr->m_stateToName << qMakePair(qMakePair(QIcon::Active, QIcon::Off), tr("Active Off") );
|
||||
d_ptr->m_stateToName << qMakePair(qMakePair(QIcon::Active, QIcon::On), tr("Active On") );
|
||||
d_ptr->m_stateToName << qMakePair(qMakePair(QIcon::Selected, QIcon::Off), tr("Selected Off") );
|
||||
d_ptr->m_stateToName << qMakePair(qMakePair(QIcon::Selected, QIcon::On), tr("Selected On") );
|
||||
|
||||
QImage img(16, 16, QImage::Format_ARGB32_Premultiplied);
|
||||
img.fill(0);
|
||||
d_ptr->m_emptyIcon = QIcon(QPixmap::fromImage(img));
|
||||
|
||||
QMenu *setMenu = new QMenu(this);
|
||||
|
||||
QAction *setResourceAction = new QAction(tr("Choose Resource..."), this);
|
||||
QAction *setFileAction = new QAction(tr("Choose File..."), this);
|
||||
d_ptr->m_resetAction = new QAction(tr("Reset"), this);
|
||||
d_ptr->m_resetAllAction = new QAction(tr("Reset All"), this);
|
||||
d_ptr->m_resetAction->setEnabled(false);
|
||||
d_ptr->m_resetAllAction->setEnabled(false);
|
||||
//d_ptr->m_resetAction->setIcon(createIconSet(QString::fromUtf8("resetproperty.png")));
|
||||
|
||||
setMenu->addAction(setResourceAction);
|
||||
setMenu->addAction(setFileAction);
|
||||
setMenu->addSeparator();
|
||||
setMenu->addAction(d_ptr->m_resetAction);
|
||||
setMenu->addAction(d_ptr->m_resetAllAction);
|
||||
|
||||
int index = 0;
|
||||
QStringList items;
|
||||
QListIterator<QPair<QPair<QIcon::Mode, QIcon::State>, QString> > itName(d_ptr->m_stateToName);
|
||||
while (itName.hasNext()) {
|
||||
QPair<QPair<QIcon::Mode, QIcon::State>, QString> item = itName.next();
|
||||
const QPair<QIcon::Mode, QIcon::State> state = item.first;
|
||||
const QString name = item.second;
|
||||
|
||||
items.append(name);
|
||||
d_ptr->m_stateToIndex[state] = index;
|
||||
d_ptr->m_indexToState[index] = state;
|
||||
index++;
|
||||
}
|
||||
d_ptr->m_stateComboBox->addItems(items);
|
||||
|
||||
d_ptr->m_iconButton->setMenu(setMenu);
|
||||
|
||||
connect(d_ptr->m_stateComboBox, SIGNAL(activated(int)), this, SLOT(slotStateActivated()));
|
||||
connect(d_ptr->m_iconButton, SIGNAL(clicked()), this, SLOT(slotSetActivated()));
|
||||
connect(setResourceAction, SIGNAL(triggered()), this, SLOT(slotSetResourceActivated()));
|
||||
connect(setFileAction, SIGNAL(triggered()), this, SLOT(slotSetFileActivated()));
|
||||
connect(d_ptr->m_resetAction, SIGNAL(triggered()), this, SLOT(slotResetActivated()));
|
||||
connect(d_ptr->m_resetAllAction, SIGNAL(triggered()), this, SLOT(slotResetAllActivated()));
|
||||
|
||||
d_ptr->slotUpdate();
|
||||
}
|
||||
|
||||
IconSelector::~IconSelector()
|
||||
{
|
||||
}
|
||||
|
||||
void IconSelector::setIcon(const PropertySheetIconValue &icon)
|
||||
{
|
||||
if (d_ptr->m_icon == icon)
|
||||
return;
|
||||
|
||||
d_ptr->m_icon = icon;
|
||||
d_ptr->slotUpdate();
|
||||
}
|
||||
|
||||
PropertySheetIconValue IconSelector::icon() const
|
||||
{
|
||||
return d_ptr->m_icon;
|
||||
}
|
||||
|
||||
void IconSelector::setFormEditor(QDesignerFormEditorInterface *core)
|
||||
{
|
||||
d_ptr->m_core = core;
|
||||
d_ptr->m_resourceModel = core->resourceModel();
|
||||
d_ptr->slotUpdate();
|
||||
}
|
||||
|
||||
void IconSelector::setIconCache(DesignerIconCache *iconCache)
|
||||
{
|
||||
d_ptr->m_iconCache = iconCache;
|
||||
connect(iconCache, SIGNAL(reloaded()), this, SLOT(slotUpdate()));
|
||||
d_ptr->slotUpdate();
|
||||
}
|
||||
|
||||
void IconSelector::setPixmapCache(DesignerPixmapCache *pixmapCache)
|
||||
{
|
||||
d_ptr->m_pixmapCache = pixmapCache;
|
||||
connect(pixmapCache, SIGNAL(reloaded()), this, SLOT(slotUpdate()));
|
||||
d_ptr->slotUpdate();
|
||||
}
|
||||
|
||||
} // qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#include "moc_iconselector_p.cpp"
|
||||
|
||||
142
third/designer/lib/shared/iconselector_p.h
Normal file
142
third/designer/lib/shared/iconselector_p.h
Normal file
@@ -0,0 +1,142 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
|
||||
#ifndef ICONSELECTOR_H
|
||||
#define ICONSELECTOR_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/QDialog>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QtResourceModel;
|
||||
class QDesignerFormEditorInterface;
|
||||
class QDesignerDialogGuiInterface;
|
||||
class QDesignerResourceBrowserInterface;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
class DesignerIconCache;
|
||||
class DesignerPixmapCache;
|
||||
class PropertySheetIconValue;
|
||||
|
||||
// Resource Dialog that embeds the language-dependent resource widget as returned by the language extension
|
||||
class QDESIGNER_SHARED_EXPORT LanguageResourceDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
explicit LanguageResourceDialog(QDesignerResourceBrowserInterface *rb, QWidget *parent = 0);
|
||||
|
||||
public:
|
||||
virtual ~LanguageResourceDialog();
|
||||
// Factory: Returns 0 if the language extension does not provide a resource browser.
|
||||
static LanguageResourceDialog* create(QDesignerFormEditorInterface *core, QWidget *parent);
|
||||
|
||||
void setCurrentPath(const QString &filePath);
|
||||
QString currentPath() const;
|
||||
|
||||
private:
|
||||
QScopedPointer<class LanguageResourceDialogPrivate> d_ptr;
|
||||
Q_DECLARE_PRIVATE(LanguageResourceDialog)
|
||||
Q_DISABLE_COPY(LanguageResourceDialog)
|
||||
Q_PRIVATE_SLOT(d_func(), void slotAccepted())
|
||||
Q_PRIVATE_SLOT(d_func(), void slotPathChanged(QString))
|
||||
|
||||
};
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT IconSelector: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
IconSelector(QWidget *parent = 0);
|
||||
virtual ~IconSelector();
|
||||
|
||||
void setFormEditor(QDesignerFormEditorInterface *core); // required for dialog gui.
|
||||
void setIconCache(DesignerIconCache *iconCache);
|
||||
void setPixmapCache(DesignerPixmapCache *pixmapCache);
|
||||
|
||||
void setIcon(const PropertySheetIconValue &icon);
|
||||
PropertySheetIconValue icon() const;
|
||||
|
||||
// Check whether a pixmap may be read
|
||||
enum CheckMode { CheckFast, CheckFully };
|
||||
static bool checkPixmap(const QString &fileName, CheckMode cm = CheckFully, QString *errorMessage = 0);
|
||||
// Choose a pixmap from file
|
||||
static QString choosePixmapFile(const QString &directory, QDesignerDialogGuiInterface *dlgGui, QWidget *parent);
|
||||
// Choose a pixmap from resource; use language-dependent resource browser if present
|
||||
static QString choosePixmapResource(QDesignerFormEditorInterface *core, QtResourceModel *resourceModel, const QString &oldPath, QWidget *parent);
|
||||
|
||||
signals:
|
||||
void iconChanged(const PropertySheetIconValue &icon);
|
||||
private:
|
||||
QScopedPointer<class IconSelectorPrivate> d_ptr;
|
||||
Q_DECLARE_PRIVATE(IconSelector)
|
||||
Q_DISABLE_COPY(IconSelector)
|
||||
|
||||
Q_PRIVATE_SLOT(d_func(), void slotStateActivated())
|
||||
Q_PRIVATE_SLOT(d_func(), void slotSetActivated())
|
||||
Q_PRIVATE_SLOT(d_func(), void slotSetResourceActivated())
|
||||
Q_PRIVATE_SLOT(d_func(), void slotSetFileActivated())
|
||||
Q_PRIVATE_SLOT(d_func(), void slotResetActivated())
|
||||
Q_PRIVATE_SLOT(d_func(), void slotResetAllActivated())
|
||||
Q_PRIVATE_SLOT(d_func(), void slotUpdate())
|
||||
};
|
||||
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // ICONSELECTOR_H
|
||||
|
||||
57
third/designer/lib/shared/invisible_widget.cpp
Normal file
57
third/designer/lib/shared/invisible_widget.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "invisible_widget_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
InvisibleWidget::InvisibleWidget(QWidget *parent)
|
||||
: QWidget()
|
||||
{
|
||||
setAttribute(Qt::WA_NoChildEventsForParent);
|
||||
setParent(parent);
|
||||
}
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
75
third/designer/lib/shared/invisible_widget_p.h
Normal file
75
third/designer/lib/shared/invisible_widget_p.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef INVISIBLE_WIDGET_H
|
||||
#define INVISIBLE_WIDGET_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
|
||||
#include <QtGui/QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT InvisibleWidget: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
InvisibleWidget(QWidget *parent = 0);
|
||||
};
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // INVISIBLE_WIDGET_H
|
||||
1326
third/designer/lib/shared/layout.cpp
Normal file
1326
third/designer/lib/shared/layout.cpp
Normal file
File diff suppressed because it is too large
Load Diff
152
third/designer/lib/shared/layout_p.h
Normal file
152
third/designer/lib/shared/layout_p.h
Normal file
@@ -0,0 +1,152 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef LAYOUT_H
|
||||
#define LAYOUT_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
#include "layoutinfo_p.h"
|
||||
|
||||
#include <QtCore/QPointer>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QHash>
|
||||
|
||||
#include <QtGui/QLayout>
|
||||
#include <QtGui/QGridLayout>
|
||||
#include <QtGui/QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDesignerFormWindowInterface;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
class QDESIGNER_SHARED_EXPORT Layout : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY(Layout)
|
||||
protected:
|
||||
Layout(const QWidgetList &wl, QWidget *p, QDesignerFormWindowInterface *fw, QWidget *lb, LayoutInfo::Type layoutType);
|
||||
|
||||
public:
|
||||
static Layout* createLayout(const QWidgetList &widgets, QWidget *parentWidget,
|
||||
QDesignerFormWindowInterface *fw,
|
||||
QWidget *layoutBase, LayoutInfo::Type layoutType);
|
||||
|
||||
virtual ~Layout();
|
||||
|
||||
virtual void sort() = 0;
|
||||
virtual void doLayout() = 0;
|
||||
|
||||
virtual void setup();
|
||||
virtual void undoLayout();
|
||||
virtual void breakLayout();
|
||||
|
||||
const QWidgetList &widgets() const { return m_widgets; }
|
||||
QWidget *parentWidget() const { return m_parentWidget; }
|
||||
QWidget *layoutBaseWidget() const { return m_layoutBase; }
|
||||
|
||||
/* Determines whether instances of QLayoutWidget are unmanaged/hidden
|
||||
* after breaking a layout. Default is true. Can be turned off when
|
||||
* morphing */
|
||||
bool reparentLayoutWidget() const { return m_reparentLayoutWidget; }
|
||||
void setReparentLayoutWidget(bool v) { m_reparentLayoutWidget = v; }
|
||||
|
||||
protected:
|
||||
virtual void finishLayout(bool needMove, QLayout *layout = 0);
|
||||
virtual bool prepareLayout(bool &needMove, bool &needReparent);
|
||||
|
||||
void setWidgets(const QWidgetList &widgets) { m_widgets = widgets; }
|
||||
QLayout *createLayout(int type);
|
||||
void reparentToLayoutBase(QWidget *w);
|
||||
|
||||
private slots:
|
||||
void widgetDestroyed();
|
||||
|
||||
private:
|
||||
QWidgetList m_widgets;
|
||||
QWidget *m_parentWidget;
|
||||
typedef QHash<QWidget *, QRect> WidgetGeometryHash;
|
||||
WidgetGeometryHash m_geometries;
|
||||
QWidget *m_layoutBase;
|
||||
QDesignerFormWindowInterface *m_formWindow;
|
||||
const LayoutInfo::Type m_layoutType;
|
||||
QPoint m_startPoint;
|
||||
QRect m_oldGeometry;
|
||||
|
||||
bool m_reparentLayoutWidget;
|
||||
const bool m_isBreak;
|
||||
};
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
|
||||
inline int indexOfWidget(QLayout *layout, QWidget *widget)
|
||||
{
|
||||
int index = 0;
|
||||
while (QLayoutItem *item = layout->itemAt(index)) {
|
||||
if (item->widget() == widget)
|
||||
return index;
|
||||
|
||||
++index;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
} // namespace Utils
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // LAYOUT_H
|
||||
312
third/designer/lib/shared/layoutinfo.cpp
Normal file
312
third/designer/lib/shared/layoutinfo.cpp
Normal file
@@ -0,0 +1,312 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "layoutinfo_p.h"
|
||||
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
#include <QtDesigner/QDesignerContainerExtension>
|
||||
#include <QtDesigner/QDesignerMetaDataBaseInterface>
|
||||
#include <QtDesigner/QExtensionManager>
|
||||
|
||||
#include <QtGui/QHBoxLayout>
|
||||
#include <QtGui/QFormLayout>
|
||||
#include <QtGui/QSplitter>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QHash>
|
||||
#include <QtCore/QRect>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
/*!
|
||||
\overload
|
||||
*/
|
||||
LayoutInfo::Type LayoutInfo::layoutType(const QDesignerFormEditorInterface *core, const QLayout *layout)
|
||||
{
|
||||
Q_UNUSED(core)
|
||||
if (!layout)
|
||||
return NoLayout;
|
||||
else if (qobject_cast<const QHBoxLayout*>(layout))
|
||||
return HBox;
|
||||
else if (qobject_cast<const QVBoxLayout*>(layout))
|
||||
return VBox;
|
||||
else if (qobject_cast<const QGridLayout*>(layout))
|
||||
return Grid;
|
||||
else if (qobject_cast<const QFormLayout*>(layout))
|
||||
return Form;
|
||||
return UnknownLayout;
|
||||
}
|
||||
|
||||
static const QHash<QString, LayoutInfo::Type> &layoutNameTypeMap()
|
||||
{
|
||||
static QHash<QString, LayoutInfo::Type> nameTypeMap;
|
||||
if (nameTypeMap.empty()) {
|
||||
nameTypeMap.insert(QLatin1String("QVBoxLayout"), LayoutInfo::VBox);
|
||||
nameTypeMap.insert(QLatin1String("QHBoxLayout"), LayoutInfo::HBox);
|
||||
nameTypeMap.insert(QLatin1String("QGridLayout"), LayoutInfo::Grid);
|
||||
nameTypeMap.insert(QLatin1String("QFormLayout"), LayoutInfo::Form);
|
||||
}
|
||||
return nameTypeMap;
|
||||
}
|
||||
|
||||
LayoutInfo::Type LayoutInfo::layoutType(const QString &typeName)
|
||||
{
|
||||
return layoutNameTypeMap().value(typeName, NoLayout);
|
||||
}
|
||||
|
||||
QString LayoutInfo::layoutName(Type t)
|
||||
{
|
||||
return layoutNameTypeMap().key(t);
|
||||
}
|
||||
|
||||
/*!
|
||||
\overload
|
||||
*/
|
||||
LayoutInfo::Type LayoutInfo::layoutType(const QDesignerFormEditorInterface *core, const QWidget *w)
|
||||
{
|
||||
if (const QSplitter *splitter = qobject_cast<const QSplitter *>(w))
|
||||
return splitter->orientation() == Qt::Horizontal ? HSplitter : VSplitter;
|
||||
return layoutType(core, w->layout());
|
||||
}
|
||||
|
||||
LayoutInfo::Type LayoutInfo::managedLayoutType(const QDesignerFormEditorInterface *core,
|
||||
const QWidget *w,
|
||||
QLayout **ptrToLayout)
|
||||
{
|
||||
if (ptrToLayout)
|
||||
*ptrToLayout = 0;
|
||||
if (const QSplitter *splitter = qobject_cast<const QSplitter *>(w))
|
||||
return splitter->orientation() == Qt::Horizontal ? HSplitter : VSplitter;
|
||||
QLayout *layout = managedLayout(core, w);
|
||||
if (!layout)
|
||||
return NoLayout;
|
||||
if (ptrToLayout)
|
||||
*ptrToLayout = layout;
|
||||
return layoutType(core, layout);
|
||||
}
|
||||
|
||||
QWidget *LayoutInfo::layoutParent(const QDesignerFormEditorInterface *core, QLayout *layout)
|
||||
{
|
||||
Q_UNUSED(core)
|
||||
|
||||
QObject *o = layout;
|
||||
while (o) {
|
||||
if (QWidget *widget = qobject_cast<QWidget*>(o))
|
||||
return widget;
|
||||
|
||||
o = o->parent();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LayoutInfo::deleteLayout(const QDesignerFormEditorInterface *core, QWidget *widget)
|
||||
{
|
||||
if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), widget))
|
||||
widget = container->widget(container->currentIndex());
|
||||
|
||||
Q_ASSERT(widget != 0);
|
||||
|
||||
QLayout *layout = managedLayout(core, widget);
|
||||
|
||||
if (layout == 0 || core->metaDataBase()->item(layout) != 0) {
|
||||
delete layout;
|
||||
widget->updateGeometry();
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "trying to delete an unmanaged layout:" << "widget:" << widget << "layout:" << layout;
|
||||
}
|
||||
|
||||
LayoutInfo::Type LayoutInfo::laidoutWidgetType(const QDesignerFormEditorInterface *core,
|
||||
QWidget *widget,
|
||||
bool *isManaged,
|
||||
QLayout **ptrToLayout)
|
||||
{
|
||||
if (isManaged)
|
||||
*isManaged = false;
|
||||
if (ptrToLayout)
|
||||
*ptrToLayout = 0;
|
||||
|
||||
QWidget *parent = widget->parentWidget();
|
||||
if (!parent)
|
||||
return NoLayout;
|
||||
|
||||
// 1) Splitter
|
||||
if (QSplitter *splitter = qobject_cast<QSplitter*>(parent)) {
|
||||
if (isManaged)
|
||||
*isManaged = core->metaDataBase()->item(splitter);
|
||||
return splitter->orientation() == Qt::Horizontal ? HSplitter : VSplitter;
|
||||
}
|
||||
|
||||
// 2) Layout of parent
|
||||
QLayout *parentLayout = parent->layout();
|
||||
if (!parentLayout)
|
||||
return NoLayout;
|
||||
|
||||
if (parentLayout->indexOf(widget) != -1) {
|
||||
if (isManaged)
|
||||
*isManaged = core->metaDataBase()->item(parentLayout);
|
||||
if (ptrToLayout)
|
||||
*ptrToLayout = parentLayout;
|
||||
return layoutType(core, parentLayout);
|
||||
}
|
||||
|
||||
// 3) Some child layout (see below comment about Q3GroupBox)
|
||||
const QList<QLayout*> childLayouts = qFindChildren<QLayout*>(parentLayout);
|
||||
if (childLayouts.empty())
|
||||
return NoLayout;
|
||||
const QList<QLayout*>::const_iterator lcend = childLayouts.constEnd();
|
||||
for (QList<QLayout*>::const_iterator it = childLayouts.constBegin(); it != lcend; ++it) {
|
||||
QLayout *layout = *it;
|
||||
if (layout->indexOf(widget) != -1) {
|
||||
if (isManaged)
|
||||
*isManaged = core->metaDataBase()->item(layout);
|
||||
if (ptrToLayout)
|
||||
*ptrToLayout = layout;
|
||||
return layoutType(core, layout);
|
||||
}
|
||||
}
|
||||
|
||||
return NoLayout;
|
||||
}
|
||||
|
||||
QLayout *LayoutInfo::internalLayout(const QWidget *widget)
|
||||
{
|
||||
QLayout *widgetLayout = widget->layout();
|
||||
if (widgetLayout && widget->inherits("Q3GroupBox")) {
|
||||
if (widgetLayout->count()) {
|
||||
widgetLayout = widgetLayout->itemAt(0)->layout();
|
||||
} else {
|
||||
widgetLayout = 0;
|
||||
}
|
||||
}
|
||||
return widgetLayout;
|
||||
}
|
||||
|
||||
|
||||
QLayout *LayoutInfo::managedLayout(const QDesignerFormEditorInterface *core, const QWidget *widget)
|
||||
{
|
||||
if (widget == 0)
|
||||
return 0;
|
||||
|
||||
QLayout *layout = widget->layout();
|
||||
if (!layout)
|
||||
return 0;
|
||||
|
||||
return managedLayout(core, layout);
|
||||
}
|
||||
|
||||
QLayout *LayoutInfo::managedLayout(const QDesignerFormEditorInterface *core, QLayout *layout)
|
||||
{
|
||||
QDesignerMetaDataBaseInterface *metaDataBase = core->metaDataBase();
|
||||
|
||||
if (!metaDataBase)
|
||||
return layout;
|
||||
/* This code exists mainly for the Q3GroupBox class, for which
|
||||
* widget->layout() returns an internal VBoxLayout. */
|
||||
const QDesignerMetaDataBaseItemInterface *item = metaDataBase->item(layout);
|
||||
if (item == 0) {
|
||||
layout = qFindChild<QLayout*>(layout);
|
||||
item = metaDataBase->item(layout);
|
||||
}
|
||||
if (!item)
|
||||
return 0;
|
||||
return layout;
|
||||
}
|
||||
|
||||
// Is it a a dummy grid placeholder created by Designer?
|
||||
bool LayoutInfo::isEmptyItem(QLayoutItem *item)
|
||||
{
|
||||
if (item == 0) {
|
||||
qDebug() << "** WARNING Zero-item passed on to isEmptyItem(). This indicates a layout inconsistency.";
|
||||
return true;
|
||||
}
|
||||
return item->spacerItem() != 0;
|
||||
}
|
||||
|
||||
QDESIGNER_SHARED_EXPORT void getFormLayoutItemPosition(const QFormLayout *formLayout, int index, int *rowPtr, int *columnPtr, int *rowspanPtr, int *colspanPtr)
|
||||
{
|
||||
int row;
|
||||
QFormLayout::ItemRole role;
|
||||
formLayout->getItemPosition(index, &row, &role);
|
||||
const int columnspan = role == QFormLayout::SpanningRole ? 2 : 1;
|
||||
const int column = (columnspan > 1 || role == QFormLayout::LabelRole) ? 0 : 1;
|
||||
if (rowPtr)
|
||||
*rowPtr = row;
|
||||
if (columnPtr)
|
||||
*columnPtr = column;
|
||||
if (rowspanPtr)
|
||||
*rowspanPtr = 1;
|
||||
if (colspanPtr)
|
||||
*colspanPtr = columnspan;
|
||||
}
|
||||
|
||||
static inline QFormLayout::ItemRole formLayoutRole(int column, int colspan)
|
||||
{
|
||||
if (colspan > 1)
|
||||
return QFormLayout::SpanningRole;
|
||||
return column == 0 ? QFormLayout::LabelRole : QFormLayout::FieldRole;
|
||||
}
|
||||
|
||||
QDESIGNER_SHARED_EXPORT void formLayoutAddWidget(QFormLayout *formLayout, QWidget *w, const QRect &r, bool insert)
|
||||
{
|
||||
// Consistent API galore...
|
||||
if (insert) {
|
||||
const bool spanning = r.width() > 1;
|
||||
if (spanning) {
|
||||
formLayout->insertRow(r.y(), w);
|
||||
} else {
|
||||
QWidget *label = 0, *field = 0;
|
||||
if (r.x() == 0) {
|
||||
label = w;
|
||||
} else {
|
||||
field = w;
|
||||
}
|
||||
formLayout->insertRow(r.y(), label, field);
|
||||
}
|
||||
} else {
|
||||
formLayout->setWidget(r.y(), formLayoutRole(r.x(), r.width()), w);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
114
third/designer/lib/shared/layoutinfo_p.h
Normal file
114
third/designer/lib/shared/layoutinfo_p.h
Normal file
@@ -0,0 +1,114 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef LAYOUTINFO_H
|
||||
#define LAYOUTINFO_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QWidget;
|
||||
class QLayout;
|
||||
class QLayoutItem;
|
||||
class QDesignerFormEditorInterface;
|
||||
class QFormLayout;
|
||||
class QRect;
|
||||
class QString;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT LayoutInfo
|
||||
{
|
||||
public:
|
||||
enum Type
|
||||
{
|
||||
NoLayout,
|
||||
HSplitter,
|
||||
VSplitter,
|
||||
HBox,
|
||||
VBox,
|
||||
Grid,
|
||||
Form,
|
||||
UnknownLayout // QDockWindow inside QMainWindow is inside QMainWindowLayout - it doesn't mean there is no layout
|
||||
};
|
||||
|
||||
static void deleteLayout(const QDesignerFormEditorInterface *core, QWidget *widget);
|
||||
|
||||
// Examines the immediate layout of the widget (will fail for Q3Group Box).
|
||||
static Type layoutType(const QDesignerFormEditorInterface *core, const QWidget *w);
|
||||
// Examines the managed layout of the widget
|
||||
static Type managedLayoutType(const QDesignerFormEditorInterface *core, const QWidget *w, QLayout **layout = 0);
|
||||
static Type layoutType(const QDesignerFormEditorInterface *core, const QLayout *layout);
|
||||
static Type layoutType(const QString &typeName);
|
||||
static QString layoutName(Type t);
|
||||
|
||||
static QWidget *layoutParent(const QDesignerFormEditorInterface *core, QLayout *layout);
|
||||
|
||||
static Type laidoutWidgetType(const QDesignerFormEditorInterface *core, QWidget *widget, bool *isManaged = 0, QLayout **layout = 0);
|
||||
static bool inline isWidgetLaidout(const QDesignerFormEditorInterface *core, QWidget *widget) { return laidoutWidgetType(core, widget) != NoLayout; }
|
||||
|
||||
static QLayout *managedLayout(const QDesignerFormEditorInterface *core, const QWidget *widget);
|
||||
static QLayout *managedLayout(const QDesignerFormEditorInterface *core, QLayout *layout);
|
||||
static QLayout *internalLayout(const QWidget *widget);
|
||||
|
||||
// Is it a a dummy grid placeholder created by Designer?
|
||||
static bool isEmptyItem(QLayoutItem *item);
|
||||
};
|
||||
|
||||
QDESIGNER_SHARED_EXPORT void getFormLayoutItemPosition(const QFormLayout *formLayout, int index, int *rowPtr, int *columnPtr = 0, int *rowspanPtr = 0, int *colspanPtr = 0);
|
||||
QDESIGNER_SHARED_EXPORT void formLayoutAddWidget(QFormLayout *formLayout, QWidget *w, const QRect &r, bool insert);
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // LAYOUTINFO_H
|
||||
295
third/designer/lib/shared/metadatabase.cpp
Normal file
295
third/designer/lib/shared/metadatabase.cpp
Normal file
@@ -0,0 +1,295 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "metadatabase_p.h"
|
||||
#include "widgetdatabase_p.h"
|
||||
|
||||
// sdk
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
|
||||
// Qt
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtCore/qalgorithms.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace {
|
||||
const bool debugMetaDatabase = false;
|
||||
}
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
MetaDataBaseItem::MetaDataBaseItem(QObject *object)
|
||||
: m_object(object),
|
||||
m_enabled(true)
|
||||
{
|
||||
}
|
||||
|
||||
MetaDataBaseItem::~MetaDataBaseItem()
|
||||
{
|
||||
}
|
||||
|
||||
QString MetaDataBaseItem::name() const
|
||||
{
|
||||
Q_ASSERT(m_object);
|
||||
return m_object->objectName();
|
||||
}
|
||||
|
||||
void MetaDataBaseItem::setName(const QString &name)
|
||||
{
|
||||
Q_ASSERT(m_object);
|
||||
m_object->setObjectName(name);
|
||||
}
|
||||
|
||||
QString MetaDataBaseItem::customClassName() const
|
||||
{
|
||||
return m_customClassName;
|
||||
}
|
||||
void MetaDataBaseItem::setCustomClassName(const QString &customClassName)
|
||||
{
|
||||
m_customClassName = customClassName;
|
||||
}
|
||||
|
||||
|
||||
MetaDataBaseItem::TabOrder MetaDataBaseItem::tabOrder() const
|
||||
{
|
||||
return m_tabOrder;
|
||||
}
|
||||
|
||||
void MetaDataBaseItem::setTabOrder(const TabOrder &tabOrder)
|
||||
{
|
||||
m_tabOrder = tabOrder;
|
||||
}
|
||||
|
||||
bool MetaDataBaseItem::enabled() const
|
||||
{
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
void MetaDataBaseItem::setEnabled(bool b)
|
||||
{
|
||||
m_enabled = b;
|
||||
}
|
||||
|
||||
QString MetaDataBaseItem::script() const
|
||||
{
|
||||
return m_script;
|
||||
}
|
||||
|
||||
void MetaDataBaseItem::setScript(const QString &script)
|
||||
{
|
||||
m_script = script;
|
||||
}
|
||||
|
||||
QStringList MetaDataBaseItem::fakeSlots() const
|
||||
{
|
||||
return m_fakeSlots;
|
||||
}
|
||||
|
||||
void MetaDataBaseItem::setFakeSlots(const QStringList &fs)
|
||||
{
|
||||
m_fakeSlots = fs;
|
||||
}
|
||||
|
||||
QStringList MetaDataBaseItem::fakeSignals() const
|
||||
{
|
||||
return m_fakeSignals;
|
||||
}
|
||||
|
||||
void MetaDataBaseItem::setFakeSignals(const QStringList &fs)
|
||||
{
|
||||
m_fakeSignals = fs;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
MetaDataBase::MetaDataBase(QDesignerFormEditorInterface *core, QObject *parent)
|
||||
: QDesignerMetaDataBaseInterface(parent),
|
||||
m_core(core)
|
||||
{
|
||||
}
|
||||
|
||||
MetaDataBase::~MetaDataBase()
|
||||
{
|
||||
qDeleteAll(m_items);
|
||||
}
|
||||
|
||||
MetaDataBaseItem *MetaDataBase::metaDataBaseItem(QObject *object) const
|
||||
{
|
||||
MetaDataBaseItem *i = m_items.value(object);
|
||||
if (i == 0 || !i->enabled())
|
||||
return 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
void MetaDataBase::add(QObject *object)
|
||||
{
|
||||
MetaDataBaseItem *item = m_items.value(object);
|
||||
if (item != 0) {
|
||||
item->setEnabled(true);
|
||||
if (debugMetaDatabase) {
|
||||
qDebug() << "MetaDataBase::add: Existing item for " << object->metaObject()->className() << item->name();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
item = new MetaDataBaseItem(object);
|
||||
m_items.insert(object, item);
|
||||
if (debugMetaDatabase) {
|
||||
qDebug() << "MetaDataBase::add: New item " << object->metaObject()->className() << item->name();
|
||||
}
|
||||
connect(object, SIGNAL(destroyed(QObject*)),
|
||||
this, SLOT(slotDestroyed(QObject*)));
|
||||
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void MetaDataBase::remove(QObject *object)
|
||||
{
|
||||
Q_ASSERT(object);
|
||||
|
||||
if (MetaDataBaseItem *item = m_items.value(object)) {
|
||||
item->setEnabled(false);
|
||||
emit changed();
|
||||
}
|
||||
}
|
||||
|
||||
QList<QObject*> MetaDataBase::objects() const
|
||||
{
|
||||
QList<QObject*> result;
|
||||
|
||||
ItemMap::const_iterator it = m_items.begin();
|
||||
for (; it != m_items.end(); ++it) {
|
||||
if (it.value()->enabled())
|
||||
result.append(it.key());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QDesignerFormEditorInterface *MetaDataBase::core() const
|
||||
{
|
||||
return m_core;
|
||||
}
|
||||
|
||||
void MetaDataBase::slotDestroyed(QObject *object)
|
||||
{
|
||||
if (m_items.contains(object)) {
|
||||
MetaDataBaseItem *item = m_items.value(object);
|
||||
delete item;
|
||||
m_items.remove(object);
|
||||
}
|
||||
}
|
||||
|
||||
// promotion convenience
|
||||
QDESIGNER_SHARED_EXPORT bool promoteWidget(QDesignerFormEditorInterface *core,QWidget *widget,const QString &customClassName)
|
||||
{
|
||||
|
||||
MetaDataBase *db = qobject_cast<MetaDataBase *>(core->metaDataBase());
|
||||
if (!db)
|
||||
return false;
|
||||
MetaDataBaseItem *item = db->metaDataBaseItem(widget);
|
||||
if (!item) {
|
||||
db ->add(widget);
|
||||
item = db->metaDataBaseItem(widget);
|
||||
}
|
||||
// Recursive promotion occurs if there is a plugin missing.
|
||||
const QString oldCustomClassName = item->customClassName();
|
||||
if (!oldCustomClassName.isEmpty()) {
|
||||
qDebug() << "WARNING: Recursive promotion of " << oldCustomClassName << " to " << customClassName
|
||||
<< ". A plugin is missing.";
|
||||
}
|
||||
item->setCustomClassName(customClassName);
|
||||
if (debugMetaDatabase) {
|
||||
qDebug() << "Promoting " << widget->metaObject()->className() << " to " << customClassName;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QDESIGNER_SHARED_EXPORT void demoteWidget(QDesignerFormEditorInterface *core,QWidget *widget)
|
||||
{
|
||||
MetaDataBase *db = qobject_cast<MetaDataBase *>(core->metaDataBase());
|
||||
if (!db)
|
||||
return;
|
||||
MetaDataBaseItem *item = db->metaDataBaseItem(widget);
|
||||
item->setCustomClassName(QString());
|
||||
if (debugMetaDatabase) {
|
||||
qDebug() << "Demoting " << widget;
|
||||
}
|
||||
}
|
||||
|
||||
QDESIGNER_SHARED_EXPORT bool isPromoted(QDesignerFormEditorInterface *core, QWidget* widget)
|
||||
{
|
||||
const MetaDataBase *db = qobject_cast<const MetaDataBase *>(core->metaDataBase());
|
||||
if (!db)
|
||||
return false;
|
||||
const MetaDataBaseItem *item = db->metaDataBaseItem(widget);
|
||||
if (!item)
|
||||
return false;
|
||||
return !item->customClassName().isEmpty();
|
||||
}
|
||||
|
||||
QDESIGNER_SHARED_EXPORT QString promotedCustomClassName(QDesignerFormEditorInterface *core, QWidget* widget)
|
||||
{
|
||||
const MetaDataBase *db = qobject_cast<const MetaDataBase *>(core->metaDataBase());
|
||||
if (!db)
|
||||
return QString();
|
||||
const MetaDataBaseItem *item = db->metaDataBaseItem(widget);
|
||||
if (!item)
|
||||
return QString();
|
||||
return item->customClassName();
|
||||
}
|
||||
|
||||
QDESIGNER_SHARED_EXPORT QString promotedExtends(QDesignerFormEditorInterface *core, QWidget* widget)
|
||||
{
|
||||
const QString customClassName = promotedCustomClassName(core,widget);
|
||||
if (customClassName.isEmpty())
|
||||
return QString();
|
||||
const int i = core->widgetDataBase()->indexOfClassName(customClassName);
|
||||
if (i == -1)
|
||||
return QString();
|
||||
return core->widgetDataBase()->item(i)->extends();
|
||||
}
|
||||
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
142
third/designer/lib/shared/metadatabase_p.h
Normal file
142
third/designer/lib/shared/metadatabase_p.h
Normal file
@@ -0,0 +1,142 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef METADATABASE_H
|
||||
#define METADATABASE_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
|
||||
#include <QtDesigner/QDesignerMetaDataBaseInterface>
|
||||
|
||||
#include <QtCore/QHash>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtGui/QCursor>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT MetaDataBaseItem: public QDesignerMetaDataBaseItemInterface
|
||||
{
|
||||
public:
|
||||
explicit MetaDataBaseItem(QObject *object);
|
||||
virtual ~MetaDataBaseItem();
|
||||
|
||||
virtual QString name() const;
|
||||
virtual void setName(const QString &name);
|
||||
|
||||
typedef QList<QWidget*> TabOrder;
|
||||
virtual TabOrder tabOrder() const;
|
||||
virtual void setTabOrder(const TabOrder &tabOrder);
|
||||
|
||||
virtual bool enabled() const;
|
||||
virtual void setEnabled(bool b);
|
||||
|
||||
QString customClassName() const;
|
||||
void setCustomClassName(const QString &customClassName);
|
||||
|
||||
QString script() const;
|
||||
void setScript(const QString &script);
|
||||
|
||||
QStringList fakeSlots() const;
|
||||
void setFakeSlots(const QStringList &);
|
||||
|
||||
QStringList fakeSignals() const;
|
||||
void setFakeSignals(const QStringList &);
|
||||
|
||||
private:
|
||||
QObject *m_object;
|
||||
TabOrder m_tabOrder;
|
||||
bool m_enabled;
|
||||
QString m_customClassName;
|
||||
QString m_script;
|
||||
QStringList m_fakeSlots;
|
||||
QStringList m_fakeSignals;
|
||||
};
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT MetaDataBase: public QDesignerMetaDataBaseInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MetaDataBase(QDesignerFormEditorInterface *core, QObject *parent = 0);
|
||||
virtual ~MetaDataBase();
|
||||
|
||||
virtual QDesignerFormEditorInterface *core() const;
|
||||
|
||||
virtual QDesignerMetaDataBaseItemInterface *item(QObject *object) const { return metaDataBaseItem(object); }
|
||||
virtual MetaDataBaseItem *metaDataBaseItem(QObject *object) const;
|
||||
virtual void add(QObject *object);
|
||||
virtual void remove(QObject *object);
|
||||
|
||||
virtual QList<QObject*> objects() const;
|
||||
|
||||
private slots:
|
||||
void slotDestroyed(QObject *object);
|
||||
|
||||
private:
|
||||
QDesignerFormEditorInterface *m_core;
|
||||
typedef QHash<QObject *, MetaDataBaseItem*> ItemMap;
|
||||
ItemMap m_items;
|
||||
};
|
||||
|
||||
// promotion convenience
|
||||
QDESIGNER_SHARED_EXPORT bool promoteWidget(QDesignerFormEditorInterface *core,QWidget *widget,const QString &customClassName);
|
||||
QDESIGNER_SHARED_EXPORT void demoteWidget(QDesignerFormEditorInterface *core,QWidget *widget);
|
||||
QDESIGNER_SHARED_EXPORT bool isPromoted(QDesignerFormEditorInterface *core, QWidget* w);
|
||||
QDESIGNER_SHARED_EXPORT QString promotedCustomClassName(QDesignerFormEditorInterface *core, QWidget* w);
|
||||
QDESIGNER_SHARED_EXPORT QString promotedExtends(QDesignerFormEditorInterface *core, QWidget* w);
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // METADATABASE_H
|
||||
635
third/designer/lib/shared/morphmenu.cpp
Normal file
635
third/designer/lib/shared/morphmenu.cpp
Normal file
@@ -0,0 +1,635 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "morphmenu_p.h"
|
||||
#include "formwindowbase_p.h"
|
||||
#include "widgetfactory_p.h"
|
||||
#include "qdesigner_formwindowcommand_p.h"
|
||||
#include "qlayout_widget_p.h"
|
||||
#include "layoutinfo_p.h"
|
||||
#include "qdesigner_propertycommand_p.h"
|
||||
|
||||
#include <QtDesigner/QExtensionManager>
|
||||
#include <QtDesigner/QDesignerContainerExtension>
|
||||
#include <QtDesigner/QDesignerFormWindowInterface>
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
#include <QtDesigner/QDesignerLanguageExtension>
|
||||
#include <QtDesigner/QDesignerWidgetDataBaseInterface>
|
||||
#include <QtDesigner/QDesignerMetaDataBaseInterface>
|
||||
#include <QtDesigner/QDesignerPropertySheetExtension>
|
||||
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtGui/QLayout>
|
||||
#include <QtGui/QUndoStack>
|
||||
|
||||
#include <QtGui/QFrame>
|
||||
#include <QtGui/QGroupBox>
|
||||
#include <QtGui/QTabWidget>
|
||||
#include <QtGui/QStackedWidget>
|
||||
#include <QtGui/QToolBox>
|
||||
#include <QtGui/QAbstractItemView>
|
||||
#include <QtGui/QAbstractButton>
|
||||
#include <QtGui/QAbstractSpinBox>
|
||||
#include <QtGui/QTextEdit>
|
||||
#include <QtGui/QPlainTextEdit>
|
||||
#include <QtGui/QLabel>
|
||||
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtCore/QSignalMapper>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
Q_DECLARE_METATYPE(QWidgetList)
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
// Helpers for the dynamic properties that store Z/Widget order
|
||||
static const char *widgetOrderPropertyC = "_q_widgetOrder";
|
||||
static const char *zOrderPropertyC = "_q_zOrder";
|
||||
|
||||
/* Morphing in Designer:
|
||||
* It is possible to morph:
|
||||
* - Non-Containers into similar widgets by category
|
||||
* - Simple page containers into similar widgets or page-based containers with
|
||||
* a single page (in theory also into a QLayoutWidget, but this might
|
||||
* not always be appropriate).
|
||||
* - Page-based containers into page-based containers or simple containers if
|
||||
* they have just one page
|
||||
* [Page based containers meaning here having a container extension]
|
||||
* Morphing types are restricted to the basic Qt types. Morphing custom
|
||||
* widgets is considered risky since they might have unmanaged layouts
|
||||
* or the like.
|
||||
*
|
||||
* Requirements:
|
||||
* - The widget must be on a non-laid out parent or in a layout managed
|
||||
* by Designer
|
||||
* - Its child widgets must be non-laid out or in a layout managed
|
||||
* by Designer
|
||||
* Note that child widgets can be
|
||||
* - On the widget itself in the case of simple containers
|
||||
* - On several pages in the case of page-based containers
|
||||
* This is what is called 'childContainers' in the code (the widget itself
|
||||
* or the list of container extension pages).
|
||||
*
|
||||
* The Morphing process encompasses:
|
||||
* - Create a target widget and apply properties as far as applicable
|
||||
* If the target widget has a container extension, add a sufficient
|
||||
* number of pages.
|
||||
* - Transferring the child widgets over to the new childContainers.
|
||||
* In the case of a managed layout on a childContainer, this is simply
|
||||
* set on the target childContainer, which is a new Qt 4.5
|
||||
* functionality.
|
||||
* - Replace the widget itself in the parent layout
|
||||
*/
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
enum MorphCategory {
|
||||
MorphCategoryNone, MorphSimpleContainer, MorphPageContainer, MorphItemView,
|
||||
MorphButton, MorphSpinBox, MorphTextEdit
|
||||
};
|
||||
|
||||
// Determine category of a widget
|
||||
static MorphCategory category(const QWidget *w)
|
||||
{
|
||||
// Simple containers: Exact match
|
||||
const QMetaObject *mo = w->metaObject();
|
||||
if (mo == &QWidget::staticMetaObject || mo == &QFrame::staticMetaObject || mo == &QGroupBox::staticMetaObject || mo == &QLayoutWidget::staticMetaObject)
|
||||
return MorphSimpleContainer;
|
||||
if (mo == &QTabWidget::staticMetaObject || mo == &QStackedWidget::staticMetaObject || mo == &QToolBox::staticMetaObject)
|
||||
return MorphPageContainer;
|
||||
if (qobject_cast<const QAbstractItemView*>(w))
|
||||
return MorphItemView;
|
||||
if (qobject_cast<const QAbstractButton *>(w))
|
||||
return MorphButton;
|
||||
if (qobject_cast<const QAbstractSpinBox *>(w))
|
||||
return MorphSpinBox;
|
||||
if (qobject_cast<const QPlainTextEdit *>(w) || qobject_cast<const QTextEdit*>(w))
|
||||
return MorphTextEdit;
|
||||
|
||||
return MorphCategoryNone;
|
||||
}
|
||||
|
||||
/* Return the similar classes of a category. This is currently restricted
|
||||
* to the known Qt classes with no precautions to parse the Widget Database
|
||||
* (which is too risky, custom classes might have container extensions
|
||||
* or non-managed layouts, etc.). */
|
||||
|
||||
static QStringList classesOfCategory(MorphCategory cat)
|
||||
{
|
||||
typedef QMap<MorphCategory, QStringList> CandidateCache;
|
||||
static CandidateCache candidateCache;
|
||||
CandidateCache::iterator it = candidateCache.find(cat);
|
||||
if (it == candidateCache.end()) {
|
||||
it = candidateCache.insert(cat, QStringList());
|
||||
QStringList &l = it.value();
|
||||
switch (cat) {
|
||||
case MorphCategoryNone:
|
||||
break;
|
||||
case MorphSimpleContainer:
|
||||
// Do not generally allow to morph into a layout.
|
||||
// This can be risky in case of container pages,etc.
|
||||
l << QLatin1String("QWidget") << QLatin1String("QFrame") << QLatin1String("QGroupBox");
|
||||
break;
|
||||
case MorphPageContainer:
|
||||
l << QLatin1String("QTabWidget") << QLatin1String("QStackedWidget") << QLatin1String("QToolBox");
|
||||
break;
|
||||
case MorphItemView:
|
||||
l << QLatin1String("QListView") << QLatin1String("QListWidget")
|
||||
<< QLatin1String("QTreeView") << QLatin1String("QTreeWidget")
|
||||
<< QLatin1String("QTableView") << QLatin1String("QTableWidget")
|
||||
<< QLatin1String("QColumnView");
|
||||
break;
|
||||
case MorphButton:
|
||||
l << QLatin1String("QCheckBox") << QLatin1String("QRadioButton")
|
||||
<< QLatin1String("QPushButton") << QLatin1String("QToolButton")
|
||||
<< QLatin1String("QCommandLinkButton");
|
||||
break;
|
||||
case MorphSpinBox:
|
||||
l << QLatin1String("QDateTimeEdit") << QLatin1String("QDateEdit")
|
||||
<< QLatin1String("QTimeEdit")
|
||||
<< QLatin1String("QSpinBox") << QLatin1String("QDoubleSpinBox");
|
||||
break;
|
||||
case MorphTextEdit:
|
||||
l << QLatin1String("QTextEdit") << QLatin1String("QPlainTextEdit");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return it.value();
|
||||
}
|
||||
|
||||
// Return the widgets containing the children to be transferred to. This is the
|
||||
// widget itself in most cases, except for QDesignerContainerExtension cases
|
||||
static QWidgetList childContainers(const QDesignerFormEditorInterface *core, QWidget *w)
|
||||
{
|
||||
if (const QDesignerContainerExtension *ce = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), w)) {
|
||||
QWidgetList children;
|
||||
if (const int count = ce->count()) {
|
||||
for (int i = 0; i < count; i++)
|
||||
children.push_back(ce->widget(i));
|
||||
}
|
||||
return children;
|
||||
}
|
||||
QWidgetList self;
|
||||
self.push_back(w);
|
||||
return self;
|
||||
}
|
||||
|
||||
// Suggest a suitable objectname for the widget to be morphed into
|
||||
// Replace the class name parts: 'xxFrame' -> 'xxGroupBox', 'frame' -> 'groupBox'
|
||||
static QString suggestObjectName(const QString &oldClassName, const QString &newClassName, const QString &oldName)
|
||||
{
|
||||
QString oldClassPart = oldClassName;
|
||||
QString newClassPart = newClassName;
|
||||
if (oldClassPart.startsWith(QLatin1Char('Q')))
|
||||
oldClassPart.remove(0, 1);
|
||||
if (newClassPart.startsWith(QLatin1Char('Q')))
|
||||
newClassPart.remove(0, 1);
|
||||
|
||||
QString newName = oldName;
|
||||
newName.replace(oldClassPart, newClassPart);
|
||||
oldClassPart[0] = oldClassPart.at(0).toLower();
|
||||
newClassPart[0] = newClassPart.at(0).toLower();
|
||||
newName.replace(oldClassPart, newClassPart);
|
||||
return newName;
|
||||
}
|
||||
|
||||
// Find the label whose buddy the widget is.
|
||||
QLabel *buddyLabelOf(QDesignerFormWindowInterface *fw, QWidget *w)
|
||||
{
|
||||
typedef QList<QLabel*> LabelList;
|
||||
const LabelList labelList = qFindChildren<QLabel*>(fw);
|
||||
if (labelList.empty())
|
||||
return 0;
|
||||
const LabelList::const_iterator cend = labelList.constEnd();
|
||||
for (LabelList::const_iterator it = labelList.constBegin(); it != cend; ++it )
|
||||
if ( (*it)->buddy() == w)
|
||||
return *it;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Replace widgets in a widget-list type dynamic property of the parent
|
||||
// used for Z-order, etc.
|
||||
static void replaceWidgetListDynamicProperty(QWidget *parentWidget,
|
||||
QWidget *oldWidget, QWidget *newWidget,
|
||||
const char *name)
|
||||
{
|
||||
QWidgetList list = qVariantValue<QWidgetList>(parentWidget->property(name));
|
||||
const int index = list.indexOf(oldWidget);
|
||||
if (index != -1) {
|
||||
list.replace(index, newWidget);
|
||||
parentWidget->setProperty(name, qVariantFromValue(list));
|
||||
}
|
||||
}
|
||||
|
||||
/* Morph a widget into another class. Use the static addMorphMacro() to
|
||||
* add a respective command sequence to the undo stack as it emits signals
|
||||
* which cause other commands to be added. */
|
||||
class MorphWidgetCommand : public QDesignerFormWindowCommand
|
||||
{
|
||||
Q_DISABLE_COPY(MorphWidgetCommand)
|
||||
public:
|
||||
|
||||
explicit MorphWidgetCommand(QDesignerFormWindowInterface *formWindow);
|
||||
~MorphWidgetCommand();
|
||||
|
||||
// Convenience to add a morph command sequence macro
|
||||
static bool addMorphMacro(QDesignerFormWindowInterface *formWindow, QWidget *w, const QString &newClass);
|
||||
|
||||
bool init(QWidget *widget, const QString &newClass);
|
||||
|
||||
QString newWidgetName() const { return m_afterWidget->objectName(); }
|
||||
|
||||
virtual void redo();
|
||||
virtual void undo();
|
||||
|
||||
static QStringList candidateClasses(QDesignerFormWindowInterface *fw, QWidget *w);
|
||||
|
||||
private:
|
||||
static bool canMorph(QDesignerFormWindowInterface *fw, QWidget *w, int *childContainerCount = 0, MorphCategory *cat = 0);
|
||||
void morph(QWidget *before, QWidget *after);
|
||||
|
||||
QWidget *m_beforeWidget;
|
||||
QWidget *m_afterWidget;
|
||||
};
|
||||
|
||||
bool MorphWidgetCommand::addMorphMacro(QDesignerFormWindowInterface *fw, QWidget *w, const QString &newClass)
|
||||
{
|
||||
MorphWidgetCommand *morphCmd = new MorphWidgetCommand(fw);
|
||||
if (!morphCmd->init(w, newClass)) {
|
||||
qWarning("*** Unable to create a MorphWidgetCommand");
|
||||
delete morphCmd;
|
||||
return false;
|
||||
}
|
||||
QLabel *buddyLabel = buddyLabelOf(fw, w);
|
||||
// Need a macro since it adds further commands
|
||||
QUndoStack *us = fw->commandHistory();
|
||||
us->beginMacro(morphCmd->text());
|
||||
// Have the signal slot/buddy editors add their commands to delete widget
|
||||
if (FormWindowBase *fwb = qobject_cast<FormWindowBase*>(fw))
|
||||
fwb->emitWidgetRemoved(w);
|
||||
|
||||
const QString newWidgetName = morphCmd->newWidgetName();
|
||||
us->push(morphCmd);
|
||||
|
||||
// restore buddy using the QByteArray name.
|
||||
if (buddyLabel) {
|
||||
SetPropertyCommand *buddyCmd = new SetPropertyCommand(fw);
|
||||
buddyCmd->init(buddyLabel, QLatin1String("buddy"), QVariant(newWidgetName.toUtf8()));
|
||||
us->push(buddyCmd);
|
||||
}
|
||||
us->endMacro();
|
||||
return true;
|
||||
}
|
||||
|
||||
MorphWidgetCommand::MorphWidgetCommand(QDesignerFormWindowInterface *formWindow) :
|
||||
QDesignerFormWindowCommand(QString(), formWindow),
|
||||
m_beforeWidget(0),
|
||||
m_afterWidget(0)
|
||||
{
|
||||
}
|
||||
|
||||
MorphWidgetCommand::~MorphWidgetCommand()
|
||||
{
|
||||
}
|
||||
|
||||
bool MorphWidgetCommand::init(QWidget *widget, const QString &newClassName)
|
||||
{
|
||||
QDesignerFormWindowInterface *fw = formWindow();
|
||||
QDesignerFormEditorInterface *core = fw->core();
|
||||
|
||||
if (!canMorph(fw, widget))
|
||||
return false;
|
||||
|
||||
const QString oldClassName = WidgetFactory::classNameOf(core, widget);
|
||||
const QString oldName = widget->objectName();
|
||||
//: MorphWidgetCommand description
|
||||
setText(QApplication::translate("Command", "Morph %1/'%2' into %3").arg(oldClassName, oldName, newClassName));
|
||||
|
||||
m_beforeWidget = widget;
|
||||
m_afterWidget = core->widgetFactory()->createWidget(newClassName, fw);
|
||||
if (!m_afterWidget)
|
||||
return false;
|
||||
|
||||
// Set object name. Do not unique it (as to maintain it).
|
||||
m_afterWidget->setObjectName(suggestObjectName(oldClassName, newClassName, oldName));
|
||||
|
||||
// If the target has a container extension, we add enough new pages to take
|
||||
// up the children of the before widget
|
||||
if (QDesignerContainerExtension* c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_afterWidget)) {
|
||||
if (const int pageCount = childContainers(core, m_beforeWidget).size()) {
|
||||
const QString qWidget = QLatin1String("QWidget");
|
||||
const QString containerName = m_afterWidget->objectName();
|
||||
for (int i = 0; i < pageCount; i++) {
|
||||
QString name = containerName;
|
||||
name += QLatin1String("Page");
|
||||
name += QString::number(i + 1);
|
||||
QWidget *page = core->widgetFactory()->createWidget(qWidget);
|
||||
page->setObjectName(name);
|
||||
fw->ensureUniqueObjectName(page);
|
||||
c->addWidget(page);
|
||||
core->metaDataBase()->add(page);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Copy over applicable properties
|
||||
const QDesignerPropertySheetExtension *beforeSheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), widget);
|
||||
QDesignerPropertySheetExtension *afterSheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), m_afterWidget);
|
||||
const QString objectNameProperty = QLatin1String("objectName");
|
||||
const int count = beforeSheet->count();
|
||||
for (int i = 0; i < count; i++)
|
||||
if (beforeSheet->isVisible(i) && beforeSheet->isChanged(i)) {
|
||||
const QString name = beforeSheet->propertyName(i);
|
||||
if (name != objectNameProperty) {
|
||||
const int afterIndex = afterSheet->indexOf(name);
|
||||
if (afterIndex != -1 && afterSheet->isVisible(afterIndex) && afterSheet->propertyGroup(afterIndex) == beforeSheet->propertyGroup(i)) {
|
||||
afterSheet->setProperty(i, beforeSheet->property(i));
|
||||
afterSheet->setChanged(i, true);
|
||||
} else {
|
||||
// Some mismatch. The rest won't match, either
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void MorphWidgetCommand::redo()
|
||||
{
|
||||
morph(m_beforeWidget, m_afterWidget);
|
||||
}
|
||||
|
||||
void MorphWidgetCommand::undo()
|
||||
{
|
||||
morph(m_afterWidget, m_beforeWidget);
|
||||
}
|
||||
|
||||
void MorphWidgetCommand::morph(QWidget *before, QWidget *after)
|
||||
{
|
||||
QDesignerFormWindowInterface *fw = formWindow();
|
||||
|
||||
fw->unmanageWidget(before);
|
||||
|
||||
const QRect oldGeom = before->geometry();
|
||||
QWidget *parent = before->parentWidget();
|
||||
Q_ASSERT(parent);
|
||||
/* Morphing consists of main 2 steps
|
||||
* 1) Move over children (laid out, non-laid out)
|
||||
* 2) Register self with new parent (laid out, non-laid out) */
|
||||
|
||||
// 1) Move children. Loop over child containers
|
||||
QWidgetList beforeChildContainers = childContainers(fw->core(), before);
|
||||
QWidgetList afterChildContainers = childContainers(fw->core(), after);
|
||||
Q_ASSERT(beforeChildContainers.size() == afterChildContainers.size());
|
||||
const int childContainerCount = beforeChildContainers.size();
|
||||
for (int i = 0; i < childContainerCount; i++) {
|
||||
QWidget *beforeChildContainer = beforeChildContainers.at(i);
|
||||
QWidget *afterChildContainer = afterChildContainers.at(i);
|
||||
if (QLayout *childLayout = beforeChildContainer->layout()) {
|
||||
// Laid-out: Move the layout (since 4.5)
|
||||
afterChildContainer->setLayout(childLayout);
|
||||
} else {
|
||||
// Non-Laid-out: Reparent, move over
|
||||
const QObjectList c = beforeChildContainer->children();
|
||||
const QObjectList::const_iterator cend = c.constEnd();
|
||||
for (QObjectList::const_iterator it = c.constBegin(); it != cend; ++it) {
|
||||
if ( (*it)->isWidgetType()) {
|
||||
QWidget *w = static_cast<QWidget*>(*it);
|
||||
if (fw->isManaged(w)) {
|
||||
const QRect geom = w->geometry();
|
||||
w->setParent(afterChildContainer);
|
||||
w->setGeometry(geom);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
afterChildContainer->setProperty(widgetOrderPropertyC, beforeChildContainer->property(widgetOrderPropertyC));
|
||||
afterChildContainer->setProperty(zOrderPropertyC, beforeChildContainer->property(zOrderPropertyC));
|
||||
}
|
||||
|
||||
// 2) Replace the actual widget in the parent layout
|
||||
after->setGeometry(oldGeom);
|
||||
if (QLayout *containingLayout = LayoutInfo::managedLayout(fw->core(), parent)) {
|
||||
LayoutHelper *lh = LayoutHelper::createLayoutHelper(LayoutInfo::layoutType(fw->core(), containingLayout));
|
||||
Q_ASSERT(lh);
|
||||
lh->replaceWidget(containingLayout, before, after);
|
||||
delete lh;
|
||||
} else {
|
||||
before->hide();
|
||||
before->setParent(0);
|
||||
after->setParent(parent);
|
||||
after->setGeometry(oldGeom);
|
||||
}
|
||||
|
||||
// Check various properties: Z order, form tab order
|
||||
replaceWidgetListDynamicProperty(parent, before, after, widgetOrderPropertyC);
|
||||
replaceWidgetListDynamicProperty(parent, before, after, zOrderPropertyC);
|
||||
|
||||
QDesignerMetaDataBaseItemInterface *formItem = fw->core()->metaDataBase()->item(fw);
|
||||
QWidgetList tabOrder = formItem->tabOrder();
|
||||
const int tabIndex = tabOrder.indexOf(before);
|
||||
if (tabIndex != -1) {
|
||||
tabOrder.replace(tabIndex, after);
|
||||
formItem->setTabOrder(tabOrder);
|
||||
}
|
||||
|
||||
after->show();
|
||||
fw->manageWidget(after);
|
||||
|
||||
fw->clearSelection(false);
|
||||
fw->selectWidget(after);
|
||||
}
|
||||
|
||||
/* Check if morphing is possible. It must be a valid category and the parent/
|
||||
* child relationships must be either non-laidout or directly on
|
||||
* Designer-managed layouts. */
|
||||
bool MorphWidgetCommand::canMorph(QDesignerFormWindowInterface *fw, QWidget *w, int *ptrToChildContainerCount, MorphCategory *ptrToCat)
|
||||
{
|
||||
if (ptrToChildContainerCount)
|
||||
*ptrToChildContainerCount = 0;
|
||||
const MorphCategory cat = category(w);
|
||||
if (ptrToCat)
|
||||
*ptrToCat = cat;
|
||||
if (cat == MorphCategoryNone)
|
||||
return false;
|
||||
|
||||
QDesignerFormEditorInterface *core = fw->core();
|
||||
// Don't know how to fiddle class names in Jambi..
|
||||
if (qt_extension<QDesignerLanguageExtension *>(core->extensionManager(), core))
|
||||
return false;
|
||||
if (!fw->isManaged(w) || w == fw->mainContainer())
|
||||
return false;
|
||||
// Check the parent relationship. We accept only managed parent widgets
|
||||
// with a single, managed layout in which widget is a member.
|
||||
QWidget *parent = w->parentWidget();
|
||||
if (parent == 0)
|
||||
return false;
|
||||
if (QLayout *pl = LayoutInfo::managedLayout(core, parent))
|
||||
if (pl->indexOf(w) < 0 || !core->metaDataBase()->item(pl))
|
||||
return false;
|
||||
// Check Widget database
|
||||
const QDesignerWidgetDataBaseInterface *wdb = core->widgetDataBase();
|
||||
const int wdbindex = wdb->indexOfObject(w);
|
||||
if (wdbindex == -1)
|
||||
return false;
|
||||
const bool isContainer = wdb->item(wdbindex)->isContainer();
|
||||
if (!isContainer)
|
||||
return true;
|
||||
// Check children. All child containers must be non-laid-out or have managed layouts
|
||||
const QWidgetList pages = childContainers(core, w);
|
||||
const int pageCount = pages.size();
|
||||
if (ptrToChildContainerCount)
|
||||
*ptrToChildContainerCount = pageCount;
|
||||
if (pageCount) {
|
||||
for (int i = 0; i < pageCount; i++)
|
||||
if (QLayout *cl = pages.at(i)->layout())
|
||||
if (!core->metaDataBase()->item(cl))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QStringList MorphWidgetCommand::candidateClasses(QDesignerFormWindowInterface *fw, QWidget *w)
|
||||
{
|
||||
int childContainerCount;
|
||||
MorphCategory cat;
|
||||
if (!canMorph(fw, w, &childContainerCount, &cat))
|
||||
return QStringList();
|
||||
|
||||
QStringList rc = classesOfCategory(cat);
|
||||
switch (cat) {
|
||||
// Frames, etc can always be morphed into one-page page containers
|
||||
case MorphSimpleContainer:
|
||||
rc += classesOfCategory(MorphPageContainer);
|
||||
break;
|
||||
// Multipage-Containers can be morphed into simple containers if they
|
||||
// have 1 page.
|
||||
case MorphPageContainer:
|
||||
if (childContainerCount == 1)
|
||||
rc += classesOfCategory(MorphSimpleContainer);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
// MorphMenu
|
||||
MorphMenu::MorphMenu(QObject *parent) :
|
||||
QObject(parent),
|
||||
m_subMenuAction(0),
|
||||
m_menu(0),
|
||||
m_mapper(0),
|
||||
m_widget(0),
|
||||
m_formWindow(0)
|
||||
{
|
||||
}
|
||||
|
||||
void MorphMenu::populate(QWidget *w, QDesignerFormWindowInterface *fw, ActionList& al)
|
||||
{
|
||||
if (populateMenu(w, fw))
|
||||
al.push_back(m_subMenuAction);
|
||||
}
|
||||
|
||||
void MorphMenu::populate(QWidget *w, QDesignerFormWindowInterface *fw, QMenu& m)
|
||||
{
|
||||
if (populateMenu(w, fw))
|
||||
m.addAction(m_subMenuAction);
|
||||
}
|
||||
|
||||
void MorphMenu::slotMorph(const QString &newClassName)
|
||||
{
|
||||
MorphWidgetCommand::addMorphMacro(m_formWindow, m_widget, newClassName);
|
||||
}
|
||||
|
||||
bool MorphMenu::populateMenu(QWidget *w, QDesignerFormWindowInterface *fw)
|
||||
{
|
||||
m_widget = 0;
|
||||
m_formWindow = 0;
|
||||
|
||||
// Clear menu
|
||||
if (m_subMenuAction) {
|
||||
m_subMenuAction->setVisible(false);
|
||||
m_menu->clear();
|
||||
}
|
||||
|
||||
// Checks: Must not be main container
|
||||
if (w == fw->mainContainer())
|
||||
return false;
|
||||
|
||||
const QStringList c = MorphWidgetCommand::candidateClasses(fw, w);
|
||||
if (c.empty())
|
||||
return false;
|
||||
|
||||
// Pull up
|
||||
m_widget = w;
|
||||
m_formWindow = fw;
|
||||
const QString oldClassName = WidgetFactory::classNameOf(fw->core(), w);
|
||||
|
||||
if (!m_subMenuAction) {
|
||||
m_subMenuAction = new QAction(tr("Morph into"), this);
|
||||
m_menu = new QMenu;
|
||||
m_subMenuAction->setMenu(m_menu);
|
||||
m_mapper = new QSignalMapper(this);
|
||||
connect(m_mapper , SIGNAL(mapped(QString)), this, SLOT(slotMorph(QString)));
|
||||
}
|
||||
|
||||
// Add actions
|
||||
const QStringList::const_iterator cend = c.constEnd();
|
||||
for (QStringList::const_iterator it = c.constBegin(); it != cend; ++it) {
|
||||
if (*it != oldClassName) {
|
||||
QAction *a = m_menu->addAction(*it);
|
||||
m_mapper->setMapping (a, *it);
|
||||
connect(a, SIGNAL(triggered()), m_mapper, SLOT(map()));
|
||||
}
|
||||
}
|
||||
m_subMenuAction->setVisible(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
97
third/designer/lib/shared/morphmenu_p.h
Normal file
97
third/designer/lib/shared/morphmenu_p.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef MORPH_COMMAND_H
|
||||
#define MORPH_COMMAND_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
#include "qdesigner_formwindowcommand_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QAction;
|
||||
class QSignalMapper;
|
||||
class QMenu;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
/* Conveniene morph menu that acts on a single widget. */
|
||||
class QDESIGNER_SHARED_EXPORT MorphMenu : public QObject {
|
||||
Q_DISABLE_COPY(MorphMenu)
|
||||
Q_OBJECT
|
||||
public:
|
||||
typedef QList<QAction *> ActionList;
|
||||
|
||||
explicit MorphMenu(QObject *parent = 0);
|
||||
|
||||
void populate(QWidget *w, QDesignerFormWindowInterface *fw, ActionList& al);
|
||||
void populate(QWidget *w, QDesignerFormWindowInterface *fw, QMenu& m);
|
||||
|
||||
private slots:
|
||||
void slotMorph(const QString &newClassName);
|
||||
|
||||
private:
|
||||
bool populateMenu(QWidget *w, QDesignerFormWindowInterface *fw);
|
||||
|
||||
QAction *m_subMenuAction;
|
||||
QMenu *m_menu;
|
||||
QSignalMapper *m_mapper;
|
||||
|
||||
QWidget *m_widget;
|
||||
QDesignerFormWindowInterface *m_formWindow;
|
||||
};
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // MORPH_COMMAND_H
|
||||
197
third/designer/lib/shared/newactiondialog.cpp
Normal file
197
third/designer/lib/shared/newactiondialog.cpp
Normal file
@@ -0,0 +1,197 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "newactiondialog_p.h"
|
||||
#include "ui_newactiondialog.h"
|
||||
#include "richtexteditor_p.h"
|
||||
#include "actioneditor_p.h"
|
||||
#include "formwindowbase_p.h"
|
||||
#include "qdesigner_utils_p.h"
|
||||
#include "iconloader_p.h"
|
||||
|
||||
#include <QtDesigner/abstractformwindow.h>
|
||||
#include <QtDesigner/abstractformeditor.h>
|
||||
|
||||
#include <QtGui/QPushButton>
|
||||
#include <QtCore/QRegExp>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
// -------------------- ActionData
|
||||
|
||||
ActionData::ActionData() :
|
||||
checkable(false)
|
||||
{
|
||||
}
|
||||
|
||||
// Returns a combination of ChangeMask flags
|
||||
unsigned ActionData::compare(const ActionData &rhs) const
|
||||
{
|
||||
unsigned rc = 0;
|
||||
if (text != rhs.text)
|
||||
rc |= TextChanged;
|
||||
if (name != rhs.name)
|
||||
rc |= NameChanged;
|
||||
if (toolTip != rhs.toolTip)
|
||||
rc |= ToolTipChanged ;
|
||||
if (icon != rhs.icon)
|
||||
rc |= IconChanged ;
|
||||
if (checkable != rhs.checkable)
|
||||
rc |= CheckableChanged;
|
||||
if (keysequence != rhs.keysequence)
|
||||
rc |= KeysequenceChanged ;
|
||||
return rc;
|
||||
}
|
||||
|
||||
// -------------------- NewActionDialog
|
||||
NewActionDialog::NewActionDialog(ActionEditor *parent) :
|
||||
QDialog(parent, Qt::Sheet),
|
||||
m_ui(new Ui::NewActionDialog),
|
||||
m_actionEditor(parent)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
m_ui->tooltipEditor->setTextPropertyValidationMode(ValidationRichText);
|
||||
connect(m_ui->toolTipToolButton, SIGNAL(clicked()), this, SLOT(slotEditToolTip()));
|
||||
|
||||
m_ui->keysequenceResetToolButton->setIcon(createIconSet(QLatin1String("resetproperty.png")));
|
||||
connect(m_ui->keysequenceResetToolButton, SIGNAL(clicked()), this, SLOT(slotResetKeySequence()));
|
||||
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
m_ui->editActionText->setFocus();
|
||||
m_auto_update_object_name = true;
|
||||
updateButtons();
|
||||
|
||||
QDesignerFormWindowInterface *form = parent->formWindow();
|
||||
m_ui->iconSelector->setFormEditor(form->core());
|
||||
FormWindowBase *formBase = qobject_cast<FormWindowBase *>(form);
|
||||
|
||||
if (formBase) {
|
||||
m_ui->iconSelector->setPixmapCache(formBase->pixmapCache());
|
||||
m_ui->iconSelector->setIconCache(formBase->iconCache());
|
||||
}
|
||||
}
|
||||
|
||||
NewActionDialog::~NewActionDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
QString NewActionDialog::actionText() const
|
||||
{
|
||||
return m_ui->editActionText->text();
|
||||
}
|
||||
|
||||
QString NewActionDialog::actionName() const
|
||||
{
|
||||
return m_ui->editObjectName->text();
|
||||
}
|
||||
|
||||
ActionData NewActionDialog::actionData() const
|
||||
{
|
||||
ActionData rc;
|
||||
rc.text = actionText();
|
||||
rc.name = actionName();
|
||||
rc.toolTip = m_ui->tooltipEditor->text();
|
||||
rc.icon = m_ui->iconSelector->icon();
|
||||
rc.checkable = m_ui->checkableCheckBox->checkState() == Qt::Checked;
|
||||
rc.keysequence = PropertySheetKeySequenceValue(m_ui->keySequenceEdit->keySequence());
|
||||
return rc;
|
||||
}
|
||||
|
||||
void NewActionDialog::setActionData(const ActionData &d)
|
||||
{
|
||||
m_ui->editActionText->setText(d.text);
|
||||
m_ui->editObjectName->setText(d.name);
|
||||
m_ui->iconSelector->setIcon(d.icon);
|
||||
m_ui->tooltipEditor->setText(d.toolTip);
|
||||
m_ui->keySequenceEdit->setKeySequence(d.keysequence.value());
|
||||
m_ui->checkableCheckBox->setCheckState(d.checkable ? Qt::Checked : Qt::Unchecked);
|
||||
|
||||
m_auto_update_object_name = false;
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
void NewActionDialog::on_editActionText_textEdited(const QString &text)
|
||||
{
|
||||
if (text.isEmpty())
|
||||
m_auto_update_object_name = true;
|
||||
|
||||
if (m_auto_update_object_name)
|
||||
m_ui->editObjectName->setText(ActionEditor::actionTextToName(text));
|
||||
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
void NewActionDialog::on_editObjectName_textEdited(const QString&)
|
||||
{
|
||||
updateButtons();
|
||||
m_auto_update_object_name = false;
|
||||
}
|
||||
|
||||
void NewActionDialog::slotEditToolTip()
|
||||
{
|
||||
const QString oldToolTip = m_ui->tooltipEditor->text();
|
||||
RichTextEditorDialog richTextDialog(m_actionEditor->core(), this);
|
||||
richTextDialog.setText(oldToolTip);
|
||||
if (richTextDialog.showDialog() == QDialog::Rejected)
|
||||
return;
|
||||
const QString newToolTip = richTextDialog.text();
|
||||
if (newToolTip != oldToolTip)
|
||||
m_ui->tooltipEditor->setText(newToolTip);
|
||||
}
|
||||
|
||||
void NewActionDialog::slotResetKeySequence()
|
||||
{
|
||||
m_ui->keySequenceEdit->setKeySequence(QKeySequence());
|
||||
m_ui->keySequenceEdit->setFocus(Qt::MouseFocusReason);
|
||||
}
|
||||
|
||||
void NewActionDialog::updateButtons()
|
||||
{
|
||||
QPushButton *okButton = m_ui->buttonBox->button(QDialogButtonBox::Ok);
|
||||
okButton->setEnabled(!actionText().isEmpty() && !actionName().isEmpty());
|
||||
}
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
277
third/designer/lib/shared/newactiondialog.ui
Normal file
277
third/designer/lib/shared/newactiondialog.ui
Normal file
@@ -0,0 +1,277 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<comment>*********************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
*********************************************************************</comment>
|
||||
<class>qdesigner_internal::NewActionDialog</class>
|
||||
<widget class="QDialog" name="qdesigner_internal::NewActionDialog">
|
||||
<property name="windowTitle">
|
||||
<string>New Action...</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="textLabel">
|
||||
<property name="text">
|
||||
<string>&Text:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>editActionText</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="editActionText">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>255</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="objectNameLabel">
|
||||
<property name="text">
|
||||
<string>Object &name:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>editObjectName</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="editObjectName"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="iconLabel">
|
||||
<property name="text">
|
||||
<string>&Icon:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>iconSelector</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="qdesigner_internal::IconSelector" name="iconSelector" native="true"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="shortcutLabel">
|
||||
<property name="text">
|
||||
<string>Shortcut:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QCheckBox" name="checkableCheckBox">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="checkableLabel">
|
||||
<property name="text">
|
||||
<string>Checkable:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="toolTipLabel">
|
||||
<property name="text">
|
||||
<string>ToolTip:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<layout class="QHBoxLayout" name="toolTipLayout">
|
||||
<item>
|
||||
<widget class="TextPropertyEditor" name="tooltipEditor" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="toolTipToolButton">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<layout class="QHBoxLayout" name="keysequenceLayout">
|
||||
<item>
|
||||
<widget class="QtKeySequenceEdit" name="keySequenceEdit" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="keysequenceResetToolButton">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>qdesigner_internal::IconSelector</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>iconselector_p.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QtKeySequenceEdit</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>qtpropertybrowserutils_p.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>TextPropertyEditor</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>textpropertyeditor_p.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>editActionText</tabstop>
|
||||
<tabstop>editObjectName</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>qdesigner_internal::NewActionDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>165</x>
|
||||
<y>162</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>291</x>
|
||||
<y>94</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>qdesigner_internal::NewActionDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>259</x>
|
||||
<y>162</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>293</x>
|
||||
<y>128</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
124
third/designer/lib/shared/newactiondialog_p.h
Normal file
124
third/designer/lib/shared/newactiondialog_p.h
Normal file
@@ -0,0 +1,124 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef NEWACTIONDIALOG_P_H
|
||||
#define NEWACTIONDIALOG_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "qdesigner_utils_p.h" // PropertySheetIconValue
|
||||
|
||||
#include <QtGui/QDialog>
|
||||
#include <QtGui/QKeySequence>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
namespace Ui {
|
||||
class NewActionDialog;
|
||||
}
|
||||
|
||||
class ActionEditor;
|
||||
|
||||
struct ActionData {
|
||||
|
||||
enum ChangeMask {
|
||||
TextChanged = 0x1, NameChanged = 0x2, ToolTipChanged = 0x4,
|
||||
IconChanged = 0x8, CheckableChanged = 0x10, KeysequenceChanged = 0x20
|
||||
};
|
||||
|
||||
ActionData();
|
||||
// Returns a combination of ChangeMask flags
|
||||
unsigned compare(const ActionData &rhs) const;
|
||||
|
||||
QString text;
|
||||
QString name;
|
||||
QString toolTip;
|
||||
PropertySheetIconValue icon;
|
||||
bool checkable;
|
||||
PropertySheetKeySequenceValue keysequence;
|
||||
};
|
||||
|
||||
inline bool operator==(const ActionData &a1, const ActionData &a2) { return a1.compare(a2) == 0u; }
|
||||
inline bool operator!=(const ActionData &a1, const ActionData &a2) { return a1.compare(a2) != 0u; }
|
||||
|
||||
class NewActionDialog: public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit NewActionDialog(ActionEditor *parent);
|
||||
virtual ~NewActionDialog();
|
||||
|
||||
ActionData actionData() const;
|
||||
void setActionData(const ActionData &d);
|
||||
|
||||
QString actionText() const;
|
||||
QString actionName() const;
|
||||
|
||||
private slots:
|
||||
void on_editActionText_textEdited(const QString &text);
|
||||
void on_editObjectName_textEdited(const QString &text);
|
||||
void slotEditToolTip();
|
||||
void slotResetKeySequence();
|
||||
|
||||
private:
|
||||
Ui::NewActionDialog *m_ui;
|
||||
ActionEditor *m_actionEditor;
|
||||
bool m_auto_update_object_name;
|
||||
|
||||
void updateButtons();
|
||||
};
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // NEWACTIONDIALOG_P_H
|
||||
586
third/designer/lib/shared/newformwidget.cpp
Normal file
586
third/designer/lib/shared/newformwidget.cpp
Normal file
@@ -0,0 +1,586 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "newformwidget_p.h"
|
||||
#include "ui_newformwidget.h"
|
||||
#include "qdesigner_formbuilder_p.h"
|
||||
#include "sheet_delegate_p.h"
|
||||
#include "widgetdatabase_p.h"
|
||||
#include "shared_settings_p.h"
|
||||
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
#include <QtDesigner/QDesignerFormWindowInterface>
|
||||
#include <QtDesigner/QExtensionManager>
|
||||
#include <QtDesigner/QDesignerLanguageExtension>
|
||||
#include <QtDesigner/QDesignerWidgetDataBaseInterface>
|
||||
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QBuffer>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QTextStream>
|
||||
|
||||
#include <QtGui/QHeaderView>
|
||||
#include <QtGui/QTreeWidgetItem>
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QPushButton>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
enum { profileComboIndexOffset = 1 };
|
||||
enum { debugNewFormWidget = 0 };
|
||||
|
||||
enum NewForm_CustomRole {
|
||||
// File name (templates from resources, paths)
|
||||
TemplateNameRole = Qt::UserRole + 100,
|
||||
// Class name (widgets from Widget data base)
|
||||
ClassNameRole = Qt::UserRole + 101
|
||||
};
|
||||
|
||||
static const char *newFormObjectNameC = "Form";
|
||||
|
||||
// Create a form name for an arbitrary class. If it is Qt, qtify it,
|
||||
// else return "Form".
|
||||
static QString formName(const QString &className)
|
||||
{
|
||||
if (!className.startsWith(QLatin1Char('Q')))
|
||||
return QLatin1String(newFormObjectNameC);
|
||||
QString rc = className;
|
||||
rc.remove(0, 1);
|
||||
return rc;
|
||||
}
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
struct TemplateSize {
|
||||
const char *name;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
static const struct TemplateSize templateSizes[] =
|
||||
{
|
||||
{ QT_TRANSLATE_NOOP("qdesigner_internal::NewFormWidget", "Default size"), 0, 0 },
|
||||
{ QT_TRANSLATE_NOOP("qdesigner_internal::NewFormWidget", "QVGA portrait (240x320)"), 240, 320 },
|
||||
{ QT_TRANSLATE_NOOP("qdesigner_internal::NewFormWidget", "QVGA landscape (320x240)"), 320, 240 },
|
||||
{ QT_TRANSLATE_NOOP("qdesigner_internal::NewFormWidget", "VGA portrait (480x640)"), 480, 640 },
|
||||
{ QT_TRANSLATE_NOOP("qdesigner_internal::NewFormWidget", "VGA landscape (640x480)"), 640, 480 }
|
||||
};
|
||||
|
||||
/* -------------- NewForm dialog.
|
||||
* Designer takes new form templates from:
|
||||
* 1) Files located in directories specified in resources
|
||||
* 2) Files located in directories specified as user templates
|
||||
* 3) XML from container widgets deemed usable for form templates by the widget
|
||||
* database
|
||||
* 4) XML from custom container widgets deemed usable for form templates by the
|
||||
* widget database
|
||||
*
|
||||
* The widget database provides helper functions to obtain lists of names
|
||||
* and xml for 3,4.
|
||||
*
|
||||
* Fixed-size forms for embedded platforms are obtained as follows:
|
||||
* 1) If the origin is a file:
|
||||
* - Check if the file exists in the subdirectory "/<width>x<height>/" of
|
||||
* the path (currently the case for the dialog box because the button box
|
||||
* needs to be positioned)
|
||||
* - Scale the form using the QWidgetDatabase::scaleFormTemplate routine.
|
||||
* 2) If the origin is XML:
|
||||
* - Scale the form using the QWidgetDatabase::scaleFormTemplate routine.
|
||||
*
|
||||
* The tree widget item roles indicate which type of entry it is
|
||||
* (TemplateNameRole = file name 1,2, ClassNameRole = class name 3,4)
|
||||
*/
|
||||
|
||||
NewFormWidget::NewFormWidget(QDesignerFormEditorInterface *core, QWidget *parentWidget) :
|
||||
QDesignerNewFormWidgetInterface(parentWidget),
|
||||
m_core(core),
|
||||
m_ui(new Ui::NewFormWidget),
|
||||
m_currentItem(0),
|
||||
m_acceptedItem(0)
|
||||
{
|
||||
typedef QList<qdesigner_internal::DeviceProfile> DeviceProfileList;
|
||||
|
||||
m_ui->setupUi(this);
|
||||
m_ui->treeWidget->setItemDelegate(new qdesigner_internal::SheetDelegate(m_ui->treeWidget, this));
|
||||
m_ui->treeWidget->header()->hide();
|
||||
m_ui->treeWidget->header()->setStretchLastSection(true);
|
||||
m_ui->lblPreview->setBackgroundRole(QPalette::Base);
|
||||
QDesignerSharedSettings settings(m_core);
|
||||
|
||||
QString uiExtension = QLatin1String("ui");
|
||||
QString templatePath = QLatin1String(":/trolltech/designer/templates/forms");
|
||||
|
||||
QDesignerLanguageExtension *lang = qt_extension<QDesignerLanguageExtension *>(core->extensionManager(), core);
|
||||
if (lang) {
|
||||
templatePath = QLatin1String(":/templates/forms");
|
||||
uiExtension = lang->uiExtension();
|
||||
}
|
||||
|
||||
// Resource templates
|
||||
const QString formTemplate = settings.formTemplate();
|
||||
QTreeWidgetItem *selectedItem = 0;
|
||||
loadFrom(templatePath, true, uiExtension, formTemplate, selectedItem);
|
||||
// Additional template paths
|
||||
const QStringList formTemplatePaths = settings.formTemplatePaths();
|
||||
const QStringList::const_iterator ftcend = formTemplatePaths.constEnd();
|
||||
for (QStringList::const_iterator it = formTemplatePaths.constBegin(); it != ftcend; ++it)
|
||||
loadFrom(*it, false, uiExtension, formTemplate, selectedItem);
|
||||
|
||||
// Widgets/custom widgets
|
||||
if (!lang) {
|
||||
//: New Form Dialog Categories
|
||||
loadFrom(tr("Widgets"), qdesigner_internal::WidgetDataBase::formWidgetClasses(core), formTemplate, selectedItem);
|
||||
loadFrom(tr("Custom Widgets"), qdesigner_internal::WidgetDataBase::customFormWidgetClasses(core), formTemplate, selectedItem);
|
||||
}
|
||||
|
||||
// Still no selection - default to first item
|
||||
if (selectedItem == 0 && m_ui->treeWidget->topLevelItemCount() != 0) {
|
||||
QTreeWidgetItem *firstTopLevel = m_ui->treeWidget->topLevelItem(0);
|
||||
if (firstTopLevel->childCount() > 0)
|
||||
selectedItem = firstTopLevel->child(0);
|
||||
}
|
||||
|
||||
// Open parent, select and make visible
|
||||
if (selectedItem) {
|
||||
m_ui->treeWidget->setCurrentItem(selectedItem);
|
||||
m_ui->treeWidget->setItemSelected(selectedItem, true);
|
||||
m_ui->treeWidget->scrollToItem(selectedItem->parent());
|
||||
}
|
||||
// Fill profile combo
|
||||
m_deviceProfiles = settings.deviceProfiles();
|
||||
m_ui->profileComboBox->addItem(tr("None"));
|
||||
connect(m_ui->profileComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotDeviceProfileIndexChanged(int)));
|
||||
if (m_deviceProfiles.empty()) {
|
||||
m_ui->profileComboBox->setEnabled(false);
|
||||
} else {
|
||||
const DeviceProfileList::const_iterator dcend = m_deviceProfiles.constEnd();
|
||||
for (DeviceProfileList::const_iterator it = m_deviceProfiles.constBegin(); it != dcend; ++it)
|
||||
m_ui->profileComboBox->addItem(it->name());
|
||||
const int ci = settings.currentDeviceProfileIndex();
|
||||
if (ci >= 0)
|
||||
m_ui->profileComboBox->setCurrentIndex(ci + profileComboIndexOffset);
|
||||
}
|
||||
// Fill size combo
|
||||
const int sizeCount = sizeof(templateSizes)/ sizeof(TemplateSize);
|
||||
for (int i = 0; i < sizeCount; i++) {
|
||||
const QSize size = QSize(templateSizes[i].width, templateSizes[i].height);
|
||||
m_ui->sizeComboBox->addItem(tr(templateSizes[i].name), size);
|
||||
}
|
||||
|
||||
setTemplateSize(settings.newFormSize());
|
||||
|
||||
if (debugNewFormWidget)
|
||||
qDebug() << Q_FUNC_INFO << "Leaving";
|
||||
}
|
||||
|
||||
NewFormWidget::~NewFormWidget()
|
||||
{
|
||||
QDesignerSharedSettings settings (m_core);
|
||||
settings.setNewFormSize(templateSize());
|
||||
// Do not change previously stored item if dialog was rejected
|
||||
if (m_acceptedItem)
|
||||
settings.setFormTemplate(m_acceptedItem->text(0));
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void NewFormWidget::on_treeWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *)
|
||||
{
|
||||
if (debugNewFormWidget)
|
||||
qDebug() << Q_FUNC_INFO << current;
|
||||
if (!current)
|
||||
return;
|
||||
|
||||
if (!current->parent()) { // Top level item: Ensure expanded when browsing down
|
||||
return;
|
||||
}
|
||||
|
||||
m_currentItem = current;
|
||||
|
||||
emit currentTemplateChanged(showCurrentItemPixmap());
|
||||
}
|
||||
|
||||
bool NewFormWidget::showCurrentItemPixmap()
|
||||
{
|
||||
bool rc = false;
|
||||
if (m_currentItem) {
|
||||
const QPixmap pixmap = formPreviewPixmap(m_currentItem);
|
||||
if (pixmap.isNull()) {
|
||||
m_ui->lblPreview->setText(tr("Error loading form"));
|
||||
} else {
|
||||
m_ui->lblPreview->setPixmap(pixmap);
|
||||
rc = true;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
void NewFormWidget::on_treeWidget_itemActivated(QTreeWidgetItem *item)
|
||||
{
|
||||
if (debugNewFormWidget)
|
||||
qDebug() << Q_FUNC_INFO << item;
|
||||
|
||||
if (item->data(0, TemplateNameRole).isValid() || item->data(0, ClassNameRole).isValid())
|
||||
emit templateActivated();
|
||||
}
|
||||
|
||||
QPixmap NewFormWidget::formPreviewPixmap(const QTreeWidgetItem *item)
|
||||
{
|
||||
// Cache pixmaps per item/device profile
|
||||
const ItemPixmapCacheKey cacheKey(item, profileComboIndex());
|
||||
ItemPixmapCache::iterator it = m_itemPixmapCache.find(cacheKey);
|
||||
if (it == m_itemPixmapCache.end()) {
|
||||
// file or string?
|
||||
const QVariant fileName = item->data(0, TemplateNameRole);
|
||||
QPixmap rc;
|
||||
if (fileName.type() == QVariant::String) {
|
||||
rc = formPreviewPixmap(fileName.toString());
|
||||
} else {
|
||||
const QVariant classNameV = item->data(0, ClassNameRole);
|
||||
Q_ASSERT(classNameV.type() == QVariant::String);
|
||||
const QString className = classNameV.toString();
|
||||
QByteArray data = qdesigner_internal::WidgetDataBase::formTemplate(m_core, className, formName(className)).toUtf8();
|
||||
QBuffer buffer(&data);
|
||||
buffer.open(QIODevice::ReadOnly);
|
||||
rc = formPreviewPixmap(buffer);
|
||||
}
|
||||
if (rc.isNull()) // Retry invalid ones
|
||||
return rc;
|
||||
it = m_itemPixmapCache.insert(cacheKey, rc);
|
||||
}
|
||||
return it.value();
|
||||
}
|
||||
|
||||
QPixmap NewFormWidget::formPreviewPixmap(const QString &fileName) const
|
||||
{
|
||||
QFile f(fileName);
|
||||
if (f.open(QFile::ReadOnly)) {
|
||||
QFileInfo fi(fileName);
|
||||
const QPixmap rc = formPreviewPixmap(f, fi.absolutePath());
|
||||
f.close();
|
||||
return rc;
|
||||
}
|
||||
qWarning() << "The file " << fileName << " could not be opened: " << f.errorString();
|
||||
return QPixmap();
|
||||
}
|
||||
|
||||
QImage NewFormWidget::grabForm(QDesignerFormEditorInterface *core,
|
||||
QIODevice &file,
|
||||
const QString &workingDir,
|
||||
const qdesigner_internal::DeviceProfile &dp)
|
||||
{
|
||||
qdesigner_internal::NewFormWidgetFormBuilder
|
||||
formBuilder(core, qdesigner_internal::QDesignerFormBuilder::DisableScripts, dp);
|
||||
if (!workingDir.isEmpty())
|
||||
formBuilder.setWorkingDirectory(workingDir);
|
||||
|
||||
QWidget *widget = formBuilder.load(&file, 0);
|
||||
if (!widget)
|
||||
return QImage();
|
||||
|
||||
const QPixmap pixmap = QPixmap::grabWidget(widget);
|
||||
widget->deleteLater();
|
||||
return pixmap.toImage();
|
||||
}
|
||||
|
||||
QPixmap NewFormWidget::formPreviewPixmap(QIODevice &file, const QString &workingDir) const
|
||||
{
|
||||
const int margin = 7;
|
||||
const int shadow = 7;
|
||||
const int previewSize = 256;
|
||||
|
||||
const QImage wimage = grabForm(m_core, file, workingDir, currentDeviceProfile());
|
||||
if (wimage.isNull())
|
||||
return QPixmap();
|
||||
const QImage image = wimage.scaled(previewSize - margin * 2, previewSize - margin * 2,
|
||||
Qt::KeepAspectRatio,
|
||||
Qt::SmoothTransformation);
|
||||
|
||||
QImage dest(previewSize, previewSize, QImage::Format_ARGB32_Premultiplied);
|
||||
dest.fill(0);
|
||||
|
||||
QPainter p(&dest);
|
||||
p.drawImage(margin, margin, image);
|
||||
|
||||
p.setPen(QPen(palette().brush(QPalette::WindowText), 0));
|
||||
|
||||
p.drawRect(margin-1, margin-1, image.width() + 1, image.height() + 1);
|
||||
|
||||
const QColor dark(Qt::darkGray);
|
||||
const QColor light(Qt::transparent);
|
||||
|
||||
// right shadow
|
||||
{
|
||||
const QRect rect(margin + image.width() + 1, margin + shadow, shadow, image.height() - shadow + 1);
|
||||
QLinearGradient lg(rect.topLeft(), rect.topRight());
|
||||
lg.setColorAt(0, dark);
|
||||
lg.setColorAt(1, light);
|
||||
p.fillRect(rect, lg);
|
||||
}
|
||||
|
||||
// bottom shadow
|
||||
{
|
||||
const QRect rect(margin + shadow, margin + image.height() + 1, image.width() - shadow + 1, shadow);
|
||||
QLinearGradient lg(rect.topLeft(), rect.bottomLeft());
|
||||
lg.setColorAt(0, dark);
|
||||
lg.setColorAt(1, light);
|
||||
p.fillRect(rect, lg);
|
||||
}
|
||||
|
||||
// bottom/right corner shadow
|
||||
{
|
||||
const QRect rect(margin + image.width() + 1, margin + image.height() + 1, shadow, shadow);
|
||||
QRadialGradient g(rect.topLeft(), shadow);
|
||||
g.setColorAt(0, dark);
|
||||
g.setColorAt(1, light);
|
||||
p.fillRect(rect, g);
|
||||
}
|
||||
|
||||
// top/right corner
|
||||
{
|
||||
const QRect rect(margin + image.width() + 1, margin, shadow, shadow);
|
||||
QRadialGradient g(rect.bottomLeft(), shadow);
|
||||
g.setColorAt(0, dark);
|
||||
g.setColorAt(1, light);
|
||||
p.fillRect(rect, g);
|
||||
}
|
||||
|
||||
// bottom/left corner
|
||||
{
|
||||
const QRect rect(margin, margin + image.height() + 1, shadow, shadow);
|
||||
QRadialGradient g(rect.topRight(), shadow);
|
||||
g.setColorAt(0, dark);
|
||||
g.setColorAt(1, light);
|
||||
p.fillRect(rect, g);
|
||||
}
|
||||
|
||||
p.end();
|
||||
|
||||
return QPixmap::fromImage(dest);
|
||||
}
|
||||
|
||||
void NewFormWidget::loadFrom(const QString &path, bool resourceFile, const QString &uiExtension,
|
||||
const QString &selectedItem, QTreeWidgetItem *&selectedItemFound)
|
||||
{
|
||||
const QDir dir(path);
|
||||
|
||||
if (!dir.exists())
|
||||
return;
|
||||
|
||||
// Iterate through the directory and add the templates
|
||||
const QFileInfoList list = dir.entryInfoList(QStringList(QLatin1String("*.") + uiExtension),
|
||||
QDir::Files);
|
||||
|
||||
if (list.isEmpty())
|
||||
return;
|
||||
|
||||
const QChar separator = resourceFile ? QChar(QLatin1Char('/'))
|
||||
: QDir::separator();
|
||||
QTreeWidgetItem *root = new QTreeWidgetItem(m_ui->treeWidget);
|
||||
root->setFlags(root->flags() & ~Qt::ItemIsSelectable);
|
||||
// Try to get something that is easy to read.
|
||||
QString visiblePath = path;
|
||||
int index = visiblePath.lastIndexOf(separator);
|
||||
if (index != -1) {
|
||||
// try to find a second slash, just to be a bit better.
|
||||
const int index2 = visiblePath.lastIndexOf(separator, index - 1);
|
||||
if (index2 != -1)
|
||||
index = index2;
|
||||
visiblePath = visiblePath.mid(index + 1);
|
||||
visiblePath = QDir::toNativeSeparators(visiblePath);
|
||||
}
|
||||
|
||||
const QChar underscore = QLatin1Char('_');
|
||||
const QChar blank = QLatin1Char(' ');
|
||||
root->setText(0, visiblePath.replace(underscore, blank));
|
||||
root->setToolTip(0, path);
|
||||
|
||||
const QFileInfoList::const_iterator lcend = list.constEnd();
|
||||
for (QFileInfoList::const_iterator it = list.constBegin(); it != lcend; ++it) {
|
||||
if (!it->isFile())
|
||||
continue;
|
||||
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem(root);
|
||||
const QString text = it->baseName().replace(underscore, blank);
|
||||
if (selectedItemFound == 0 && text == selectedItem)
|
||||
selectedItemFound = item;
|
||||
item->setText(0, text);
|
||||
item->setData(0, TemplateNameRole, it->absoluteFilePath());
|
||||
}
|
||||
}
|
||||
|
||||
void NewFormWidget::loadFrom(const QString &title, const QStringList &nameList,
|
||||
const QString &selectedItem, QTreeWidgetItem *&selectedItemFound)
|
||||
{
|
||||
if (nameList.empty())
|
||||
return;
|
||||
QTreeWidgetItem *root = new QTreeWidgetItem(m_ui->treeWidget);
|
||||
root->setFlags(root->flags() & ~Qt::ItemIsSelectable);
|
||||
root->setText(0, title);
|
||||
const QStringList::const_iterator cend = nameList.constEnd();
|
||||
for (QStringList::const_iterator it = nameList.constBegin(); it != cend; ++it) {
|
||||
const QString text = *it;
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem(root);
|
||||
item->setText(0, text);
|
||||
if (selectedItemFound == 0 && text == selectedItem)
|
||||
selectedItemFound = item;
|
||||
item->setData(0, ClassNameRole, *it);
|
||||
}
|
||||
}
|
||||
|
||||
void NewFormWidget::on_treeWidget_itemPressed(QTreeWidgetItem *item)
|
||||
{
|
||||
if (item && !item->parent())
|
||||
m_ui->treeWidget->setItemExpanded(item, !m_ui->treeWidget->isItemExpanded(item));
|
||||
}
|
||||
|
||||
QSize NewFormWidget::templateSize() const
|
||||
{
|
||||
return m_ui->sizeComboBox->itemData(m_ui->sizeComboBox->currentIndex()).toSize();
|
||||
}
|
||||
|
||||
void NewFormWidget::setTemplateSize(const QSize &s)
|
||||
{
|
||||
const int index = s.isNull() ? 0 : m_ui->sizeComboBox->findData(s);
|
||||
if (index != -1)
|
||||
m_ui->sizeComboBox->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
static QString readAll(const QString &fileName, QString *errorMessage)
|
||||
{
|
||||
QFile file(fileName);
|
||||
if (!file.open(QIODevice::ReadOnly|QIODevice::Text)) {
|
||||
*errorMessage = NewFormWidget::tr("Unable to open the form template file '%1': %2").arg(fileName, file.errorString());
|
||||
return QString();
|
||||
}
|
||||
return QString::fromUtf8(file.readAll());
|
||||
}
|
||||
|
||||
QString NewFormWidget::itemToTemplate(const QTreeWidgetItem *item, QString *errorMessage) const
|
||||
{
|
||||
const QSize size = templateSize();
|
||||
// file name or string contents?
|
||||
const QVariant templateFileName = item->data(0, TemplateNameRole);
|
||||
if (templateFileName.type() == QVariant::String) {
|
||||
const QString fileName = templateFileName.toString();
|
||||
// No fixed size: just open.
|
||||
if (size.isNull())
|
||||
return readAll(fileName, errorMessage);
|
||||
// try to find a file matching the size, like "../640x480/xx.ui"
|
||||
const QFileInfo fiBase(fileName);
|
||||
QString sizeFileName;
|
||||
QTextStream(&sizeFileName) << fiBase.path() << QDir::separator()
|
||||
<< size.width() << QLatin1Char('x') << size.height() << QDir::separator()
|
||||
<< fiBase.fileName();
|
||||
if (QFileInfo(sizeFileName).isFile())
|
||||
return readAll(sizeFileName, errorMessage);
|
||||
// Nothing found, scale via DOM/temporary file
|
||||
QString contents = readAll(fileName, errorMessage);
|
||||
if (!contents.isEmpty())
|
||||
contents = qdesigner_internal::WidgetDataBase::scaleFormTemplate(contents, size, false);
|
||||
return contents;
|
||||
}
|
||||
// Content.
|
||||
const QString className = item->data(0, ClassNameRole).toString();
|
||||
QString contents = qdesigner_internal::WidgetDataBase::formTemplate(m_core, className, formName(className));
|
||||
if (!size.isNull())
|
||||
contents = qdesigner_internal::WidgetDataBase::scaleFormTemplate(contents, size, false);
|
||||
return contents;
|
||||
}
|
||||
|
||||
void NewFormWidget::slotDeviceProfileIndexChanged(int idx)
|
||||
{
|
||||
// Store index for form windows to take effect and refresh pixmap
|
||||
QDesignerSharedSettings settings(m_core);
|
||||
settings.setCurrentDeviceProfileIndex(idx - profileComboIndexOffset);
|
||||
showCurrentItemPixmap();
|
||||
}
|
||||
|
||||
int NewFormWidget::profileComboIndex() const
|
||||
{
|
||||
return m_ui->profileComboBox->currentIndex();
|
||||
}
|
||||
|
||||
qdesigner_internal::DeviceProfile NewFormWidget::currentDeviceProfile() const
|
||||
{
|
||||
const int ci = profileComboIndex();
|
||||
if (ci > 0)
|
||||
return m_deviceProfiles.at(ci - profileComboIndexOffset);
|
||||
return qdesigner_internal::DeviceProfile();
|
||||
}
|
||||
|
||||
bool NewFormWidget::hasCurrentTemplate() const
|
||||
{
|
||||
return m_currentItem != 0;
|
||||
}
|
||||
|
||||
QString NewFormWidget::currentTemplateI(QString *ptrToErrorMessage)
|
||||
{
|
||||
if (m_currentItem == 0) {
|
||||
*ptrToErrorMessage = tr("Internal error: No template selected.");
|
||||
return QString();
|
||||
}
|
||||
const QString contents = itemToTemplate(m_currentItem, ptrToErrorMessage);
|
||||
if (contents.isEmpty())
|
||||
return contents;
|
||||
|
||||
m_acceptedItem = m_currentItem;
|
||||
return contents;
|
||||
}
|
||||
|
||||
QString NewFormWidget::currentTemplate(QString *ptrToErrorMessage)
|
||||
{
|
||||
if (ptrToErrorMessage)
|
||||
return currentTemplateI(ptrToErrorMessage);
|
||||
// Do not loose the error
|
||||
QString errorMessage;
|
||||
const QString contents = currentTemplateI(&errorMessage);
|
||||
if (!errorMessage.isEmpty())
|
||||
qWarning("%s", errorMessage.toUtf8().constData());
|
||||
return contents;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
192
third/designer/lib/shared/newformwidget.ui
Normal file
192
third/designer/lib/shared/newformwidget.ui
Normal file
@@ -0,0 +1,192 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<comment>*********************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
*********************************************************************</comment>
|
||||
<class>qdesigner_internal::NewFormWidget</class>
|
||||
<widget class="QWidget" name="qdesigner_internal::NewFormWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>480</width>
|
||||
<height>194</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="treeWidget">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>128</width>
|
||||
<height>128</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="rootIsDecorated">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="columnCount">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="lblPreview">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Choose a template for a preview</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>7</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="embeddedGroup">
|
||||
<property name="title">
|
||||
<string>Embedded Design</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="profileComboBox"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="sizeComboBox"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Device:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Screen Size:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
143
third/designer/lib/shared/newformwidget_p.h
Normal file
143
third/designer/lib/shared/newformwidget_p.h
Normal file
@@ -0,0 +1,143 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef NEWFORMWIDGET_H
|
||||
#define NEWFORMWIDGET_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "shared_global_p.h"
|
||||
#include "deviceprofile_p.h"
|
||||
|
||||
#include <abstractnewformwidget_p.h>
|
||||
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/QPixmap>
|
||||
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QPair>
|
||||
#include <QtCore/QMap>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QIODevice;
|
||||
class QTreeWidgetItem;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
namespace Ui {
|
||||
class NewFormWidget;
|
||||
}
|
||||
|
||||
class QDesignerWorkbench;
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT NewFormWidget : public QDesignerNewFormWidgetInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY(NewFormWidget)
|
||||
|
||||
public:
|
||||
typedef QList<qdesigner_internal::DeviceProfile> DeviceProfileList;
|
||||
|
||||
explicit NewFormWidget(QDesignerFormEditorInterface *core, QWidget *parentWidget);
|
||||
virtual ~NewFormWidget();
|
||||
|
||||
virtual bool hasCurrentTemplate() const;
|
||||
virtual QString currentTemplate(QString *errorMessage = 0);
|
||||
|
||||
// Convenience for implementing file dialogs with preview
|
||||
static QImage grabForm(QDesignerFormEditorInterface *core,
|
||||
QIODevice &file,
|
||||
const QString &workingDir,
|
||||
const qdesigner_internal::DeviceProfile &dp);
|
||||
|
||||
private slots:
|
||||
void on_treeWidget_itemActivated(QTreeWidgetItem *item);
|
||||
void on_treeWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *);
|
||||
void on_treeWidget_itemPressed(QTreeWidgetItem *item);
|
||||
void slotDeviceProfileIndexChanged(int idx);
|
||||
|
||||
private:
|
||||
QPixmap formPreviewPixmap(const QString &fileName) const;
|
||||
QPixmap formPreviewPixmap(QIODevice &file, const QString &workingDir = QString()) const;
|
||||
QPixmap formPreviewPixmap(const QTreeWidgetItem *item);
|
||||
|
||||
void loadFrom(const QString &path, bool resourceFile, const QString &uiExtension,
|
||||
const QString &selectedItem, QTreeWidgetItem *&selectedItemFound);
|
||||
void loadFrom(const QString &title, const QStringList &nameList,
|
||||
const QString &selectedItem, QTreeWidgetItem *&selectedItemFound);
|
||||
|
||||
private:
|
||||
QString itemToTemplate(const QTreeWidgetItem *item, QString *errorMessage) const;
|
||||
QString currentTemplateI(QString *ptrToErrorMessage);
|
||||
|
||||
QSize templateSize() const;
|
||||
void setTemplateSize(const QSize &s);
|
||||
int profileComboIndex() const;
|
||||
qdesigner_internal::DeviceProfile currentDeviceProfile() const;
|
||||
bool showCurrentItemPixmap();
|
||||
|
||||
// Pixmap cache (item, profile combo index)
|
||||
typedef QPair<const QTreeWidgetItem *, int> ItemPixmapCacheKey;
|
||||
typedef QMap<ItemPixmapCacheKey, QPixmap> ItemPixmapCache;
|
||||
ItemPixmapCache m_itemPixmapCache;
|
||||
|
||||
QDesignerFormEditorInterface *m_core;
|
||||
Ui::NewFormWidget *m_ui;
|
||||
QTreeWidgetItem *m_currentItem;
|
||||
QTreeWidgetItem *m_acceptedItem;
|
||||
DeviceProfileList m_deviceProfiles;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // NEWFORMWIDGET_H
|
||||
188
third/designer/lib/shared/orderdialog.cpp
Normal file
188
third/designer/lib/shared/orderdialog.cpp
Normal file
@@ -0,0 +1,188 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "orderdialog_p.h"
|
||||
#include "iconloader_p.h"
|
||||
#include "ui_orderdialog.h"
|
||||
|
||||
#include <QtDesigner/QExtensionManager>
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
#include <QtDesigner/QDesignerContainerExtension>
|
||||
#include <QtCore/QAbstractItemModel>
|
||||
#include <QtCore/QModelIndex>
|
||||
#include <QtGui/QPushButton>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
// OrderDialog: Used to reorder the pages of QStackedWidget and QToolBox.
|
||||
// Provides up and down buttons as well as DnD via QAbstractItemView::InternalMove mode
|
||||
namespace qdesigner_internal {
|
||||
|
||||
OrderDialog::OrderDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
m_ui(new Ui::OrderDialog),
|
||||
m_format(PageOrderFormat)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
m_ui->upButton->setIcon(createIconSet(QString::fromUtf8("up.png")));
|
||||
m_ui->downButton->setIcon(createIconSet(QString::fromUtf8("down.png")));
|
||||
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
|
||||
connect(m_ui->buttonBox->button(QDialogButtonBox::Reset), SIGNAL(clicked()), this, SLOT(slotReset()));
|
||||
// Catch the remove operation of a DnD operation in QAbstractItemView::InternalMove mode to enable buttons
|
||||
// Selection mode is 'contiguous' to enable DnD of groups
|
||||
connect(m_ui->pageList->model(), SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(slotEnableButtonsAfterDnD()));
|
||||
|
||||
m_ui->upButton->setEnabled(false);
|
||||
m_ui->downButton->setEnabled(false);
|
||||
}
|
||||
|
||||
OrderDialog::~OrderDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void OrderDialog::setDescription(const QString &d)
|
||||
{
|
||||
m_ui->groupBox->setTitle(d);
|
||||
}
|
||||
|
||||
void OrderDialog::setPageList(const QWidgetList &pages)
|
||||
{
|
||||
// The QWidget* are stored in a map indexed by the old index.
|
||||
// The old index is set as user data on the item instead of the QWidget*
|
||||
// because DnD is enabled which requires the user data to serializable
|
||||
m_orderMap.clear();
|
||||
const int count = pages.count();
|
||||
for (int i=0; i < count; ++i)
|
||||
m_orderMap.insert(i, pages.at(i));
|
||||
buildList();
|
||||
}
|
||||
|
||||
void OrderDialog::buildList()
|
||||
{
|
||||
m_ui->pageList->clear();
|
||||
const OrderMap::const_iterator cend = m_orderMap.constEnd();
|
||||
for (OrderMap::const_iterator it = m_orderMap.constBegin(); it != cend; ++it) {
|
||||
QListWidgetItem *item = new QListWidgetItem();
|
||||
const int index = it.key();
|
||||
switch (m_format) {
|
||||
case PageOrderFormat:
|
||||
item->setText(tr("Index %1 (%2)").arg(index).arg(it.value()->objectName()));
|
||||
break;
|
||||
case TabOrderFormat:
|
||||
item->setText(tr("%1 %2").arg(index+1).arg(it.value()->objectName()));
|
||||
break;
|
||||
}
|
||||
item->setData(Qt::UserRole, QVariant(index));
|
||||
m_ui->pageList->addItem(item);
|
||||
}
|
||||
|
||||
if (m_ui->pageList->count() > 0)
|
||||
m_ui->pageList->setCurrentRow(0);
|
||||
}
|
||||
|
||||
void OrderDialog::slotReset()
|
||||
{
|
||||
buildList();
|
||||
}
|
||||
|
||||
QWidgetList OrderDialog::pageList() const
|
||||
{
|
||||
QWidgetList rc;
|
||||
const int count = m_ui->pageList->count();
|
||||
for (int i=0; i < count; ++i) {
|
||||
const int oldIndex = m_ui->pageList->item(i)->data(Qt::UserRole).toInt();
|
||||
rc.append(m_orderMap.value(oldIndex));
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
void OrderDialog::on_upButton_clicked()
|
||||
{
|
||||
const int row = m_ui->pageList->currentRow();
|
||||
if (row <= 0)
|
||||
return;
|
||||
|
||||
m_ui->pageList->insertItem(row - 1, m_ui->pageList->takeItem(row));
|
||||
m_ui->pageList->setCurrentRow(row - 1);
|
||||
}
|
||||
|
||||
void OrderDialog::on_downButton_clicked()
|
||||
{
|
||||
const int row = m_ui->pageList->currentRow();
|
||||
if (row == -1 || row == m_ui->pageList->count() - 1)
|
||||
return;
|
||||
|
||||
m_ui->pageList->insertItem(row + 1, m_ui->pageList->takeItem(row));
|
||||
m_ui->pageList->setCurrentRow(row + 1);
|
||||
}
|
||||
|
||||
void OrderDialog::slotEnableButtonsAfterDnD()
|
||||
{
|
||||
enableButtons(m_ui->pageList->currentRow());
|
||||
}
|
||||
|
||||
void OrderDialog::on_pageList_currentRowChanged(int r)
|
||||
{
|
||||
enableButtons(r);
|
||||
}
|
||||
|
||||
void OrderDialog::enableButtons(int r)
|
||||
{
|
||||
m_ui->upButton->setEnabled(r > 0);
|
||||
m_ui->downButton->setEnabled(r >= 0 && r < m_ui->pageList->count() - 1);
|
||||
}
|
||||
|
||||
QWidgetList OrderDialog::pagesOfContainer(const QDesignerFormEditorInterface *core, QWidget *container)
|
||||
{
|
||||
QWidgetList rc;
|
||||
if (QDesignerContainerExtension* ce = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), container)) {
|
||||
const int count = ce->count();
|
||||
for (int i = 0; i < count ;i ++)
|
||||
rc.push_back(ce->widget(i));
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
198
third/designer/lib/shared/orderdialog.ui
Normal file
198
third/designer/lib/shared/orderdialog.ui
Normal file
@@ -0,0 +1,198 @@
|
||||
<ui version="4.0" >
|
||||
<comment>*********************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
*********************************************************************</comment>
|
||||
<class>qdesigner_internal::OrderDialog</class>
|
||||
<widget class="QDialog" name="qdesigner_internal::OrderDialog" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>467</width>
|
||||
<height>310</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<string>Change Page Order</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" >
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox" >
|
||||
<property name="title" >
|
||||
<string>Page Order</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="topMargin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QListWidget" name="pageList" >
|
||||
<property name="minimumSize" >
|
||||
<size>
|
||||
<width>344</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="dragDropMode" >
|
||||
<enum>QAbstractItemView::InternalMove</enum>
|
||||
</property>
|
||||
<property name="selectionMode" >
|
||||
<enum>QAbstractItemView::ContiguousSelection</enum>
|
||||
</property>
|
||||
<property name="movement" >
|
||||
<enum>QListView::Snap</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QToolButton" name="upButton" >
|
||||
<property name="toolTip" >
|
||||
<string>Move page up</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="downButton" >
|
||||
<property name="toolTip" >
|
||||
<string>Move page down</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Expanding" hsizetype="Fixed" >
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0" >
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>99</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox" >
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons" >
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>qdesigner_internal::OrderDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>50</x>
|
||||
<y>163</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>6</x>
|
||||
<y>151</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>qdesigner_internal::OrderDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>300</x>
|
||||
<y>160</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>348</x>
|
||||
<y>148</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
114
third/designer/lib/shared/orderdialog_p.h
Normal file
114
third/designer/lib/shared/orderdialog_p.h
Normal file
@@ -0,0 +1,114 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef ORDERDIALOG_P_H
|
||||
#define ORDERDIALOG_P_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
|
||||
#include <QtGui/QDialog>
|
||||
#include <QtCore/QMap>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDesignerFormEditorInterface;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
namespace Ui {
|
||||
class OrderDialog;
|
||||
}
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT OrderDialog: public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
OrderDialog(QWidget *parent);
|
||||
virtual ~OrderDialog();
|
||||
|
||||
static QWidgetList pagesOfContainer(const QDesignerFormEditorInterface *core, QWidget *container);
|
||||
|
||||
void setPageList(const QWidgetList &pages);
|
||||
QWidgetList pageList() const;
|
||||
|
||||
void setDescription(const QString &d);
|
||||
|
||||
enum Format { // Display format
|
||||
PageOrderFormat, // Container pages, ranging 0..[n-1]
|
||||
TabOrderFormat // List of widgets, ranging 1..1
|
||||
};
|
||||
|
||||
void setFormat(Format f) { m_format = f; }
|
||||
Format format() const { return m_format; }
|
||||
|
||||
private slots:
|
||||
void on_upButton_clicked();
|
||||
void on_downButton_clicked();
|
||||
void on_pageList_currentRowChanged(int row);
|
||||
void slotEnableButtonsAfterDnD();
|
||||
void slotReset();
|
||||
|
||||
private:
|
||||
void buildList();
|
||||
void enableButtons(int r);
|
||||
|
||||
typedef QMap<int, QWidget*> OrderMap;
|
||||
OrderMap m_orderMap;
|
||||
Ui::OrderDialog* m_ui;
|
||||
Format m_format;
|
||||
};
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // ORDERDIALOG_P_H
|
||||
119
third/designer/lib/shared/plaintexteditor.cpp
Normal file
119
third/designer/lib/shared/plaintexteditor.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "plaintexteditor_p.h"
|
||||
#include "abstractsettings_p.h"
|
||||
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
|
||||
#include <QtGui/QPlainTextEdit>
|
||||
#include <QtGui/QDialogButtonBox>
|
||||
#include <QtGui/QVBoxLayout>
|
||||
#include <QtGui/QPushButton>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static const char *PlainTextDialogC = "PlainTextDialog";
|
||||
static const char *Geometry = "Geometry";
|
||||
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
PlainTextEditorDialog::PlainTextEditorDialog(QDesignerFormEditorInterface *core, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
m_editor(new QPlainTextEdit),
|
||||
m_core(core)
|
||||
{
|
||||
setWindowTitle(tr("Edit text"));
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
|
||||
QVBoxLayout *vlayout = new QVBoxLayout(this);
|
||||
vlayout->addWidget(m_editor);
|
||||
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal);
|
||||
QPushButton *ok_button = buttonBox->button(QDialogButtonBox::Ok);
|
||||
ok_button->setDefault(true);
|
||||
connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
vlayout->addWidget(buttonBox);
|
||||
|
||||
QDesignerSettingsInterface *settings = core->settingsManager();
|
||||
settings->beginGroup(QLatin1String(PlainTextDialogC));
|
||||
|
||||
if (settings->contains(QLatin1String(Geometry)))
|
||||
restoreGeometry(settings->value(QLatin1String(Geometry)).toByteArray());
|
||||
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
PlainTextEditorDialog::~PlainTextEditorDialog()
|
||||
{
|
||||
QDesignerSettingsInterface *settings = m_core->settingsManager();
|
||||
settings->beginGroup(QLatin1String(PlainTextDialogC));
|
||||
|
||||
settings->setValue(QLatin1String(Geometry), saveGeometry());
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
int PlainTextEditorDialog::showDialog()
|
||||
{
|
||||
m_editor->setFocus();
|
||||
return exec();
|
||||
}
|
||||
|
||||
void PlainTextEditorDialog::setDefaultFont(const QFont &font)
|
||||
{
|
||||
m_editor->setFont(font);
|
||||
}
|
||||
|
||||
void PlainTextEditorDialog::setText(const QString &text)
|
||||
{
|
||||
m_editor->setPlainText(text);
|
||||
}
|
||||
|
||||
QString PlainTextEditorDialog::text() const
|
||||
{
|
||||
return m_editor->toPlainText();
|
||||
}
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
89
third/designer/lib/shared/plaintexteditor_p.h
Normal file
89
third/designer/lib/shared/plaintexteditor_p.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef PLAINTEXTEDITOR_H
|
||||
#define PLAINTEXTEDITOR_H
|
||||
|
||||
#include <QtGui/QDialog>
|
||||
#include "shared_global_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QPlainTextEdit;
|
||||
class QDesignerFormEditorInterface;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT PlainTextEditorDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PlainTextEditorDialog(QDesignerFormEditorInterface *core, QWidget *parent = 0);
|
||||
~PlainTextEditorDialog();
|
||||
|
||||
int showDialog();
|
||||
|
||||
void setDefaultFont(const QFont &font);
|
||||
|
||||
void setText(const QString &text);
|
||||
QString text() const;
|
||||
|
||||
private:
|
||||
QPlainTextEdit *m_editor;
|
||||
QDesignerFormEditorInterface *m_core;
|
||||
};
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // RITCHTEXTEDITOR_H
|
||||
207
third/designer/lib/shared/plugindialog.cpp
Normal file
207
third/designer/lib/shared/plugindialog.cpp
Normal file
@@ -0,0 +1,207 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "plugindialog_p.h"
|
||||
#include "pluginmanager_p.h"
|
||||
#include "qdesigner_integration_p.h"
|
||||
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
#include <QtDesigner/QDesignerCustomWidgetCollectionInterface>
|
||||
#include <QtDesigner/QDesignerWidgetDataBaseInterface>
|
||||
|
||||
#include <QtGui/QStyle>
|
||||
#include <QtGui/QHeaderView>
|
||||
#include <QtGui/QPushButton>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QPluginLoader>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
PluginDialog::PluginDialog(QDesignerFormEditorInterface *core, QWidget *parent)
|
||||
: QDialog(parent
|
||||
#ifdef Q_WS_MAC
|
||||
, Qt::Tool
|
||||
#endif
|
||||
), m_core(core)
|
||||
{
|
||||
ui.setupUi(this);
|
||||
|
||||
ui.message->hide();
|
||||
|
||||
const QStringList headerLabels(tr("Components"));
|
||||
|
||||
ui.treeWidget->setAlternatingRowColors(false);
|
||||
ui.treeWidget->setSelectionMode(QAbstractItemView::NoSelection);
|
||||
ui.treeWidget->setHeaderLabels(headerLabels);
|
||||
ui.treeWidget->header()->hide();
|
||||
|
||||
interfaceIcon.addPixmap(style()->standardPixmap(QStyle::SP_DirOpenIcon),
|
||||
QIcon::Normal, QIcon::On);
|
||||
interfaceIcon.addPixmap(style()->standardPixmap(QStyle::SP_DirClosedIcon),
|
||||
QIcon::Normal, QIcon::Off);
|
||||
featureIcon.addPixmap(style()->standardPixmap(QStyle::SP_FileIcon));
|
||||
|
||||
setWindowTitle(tr("Plugin Information"));
|
||||
populateTreeWidget();
|
||||
|
||||
if (qobject_cast<qdesigner_internal::QDesignerIntegration *>(m_core->integration())) {
|
||||
QPushButton *updateButton = new QPushButton(tr("Refresh"));
|
||||
const QString tooltip = tr("Scan for newly installed custom widget plugins.");
|
||||
updateButton->setToolTip(tooltip);
|
||||
updateButton->setWhatsThis(tooltip);
|
||||
connect(updateButton, SIGNAL(clicked()), this, SLOT(updateCustomWidgetPlugins()));
|
||||
ui.buttonBox->addButton(updateButton, QDialogButtonBox::ActionRole);
|
||||
}
|
||||
}
|
||||
|
||||
void PluginDialog::populateTreeWidget()
|
||||
{
|
||||
ui.treeWidget->clear();
|
||||
QDesignerPluginManager *pluginManager = m_core->pluginManager();
|
||||
const QStringList fileNames = pluginManager->registeredPlugins();
|
||||
|
||||
if (!fileNames.isEmpty()) {
|
||||
QTreeWidgetItem *topLevelItem = setTopLevelItem(QLatin1String("Loaded Plugins"));
|
||||
QFont boldFont = topLevelItem->font(0);
|
||||
|
||||
foreach (const QString &fileName, fileNames) {
|
||||
QPluginLoader loader(fileName);
|
||||
const QFileInfo fileInfo(fileName);
|
||||
|
||||
QTreeWidgetItem *pluginItem = setPluginItem(topLevelItem, fileInfo.fileName(), boldFont);
|
||||
|
||||
if (QObject *plugin = loader.instance()) {
|
||||
if (const QDesignerCustomWidgetCollectionInterface *c = qobject_cast<QDesignerCustomWidgetCollectionInterface*>(plugin)) {
|
||||
foreach (const QDesignerCustomWidgetInterface *p, c->customWidgets())
|
||||
setItem(pluginItem, p->name(), p->toolTip(), p->whatsThis(), p->icon());
|
||||
} else {
|
||||
if (const QDesignerCustomWidgetInterface *p = qobject_cast<QDesignerCustomWidgetInterface*>(plugin))
|
||||
setItem(pluginItem, p->name(), p->toolTip(), p->whatsThis(), p->icon());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const QStringList notLoadedPlugins = pluginManager->failedPlugins();
|
||||
if (!notLoadedPlugins.isEmpty()) {
|
||||
QTreeWidgetItem *topLevelItem = setTopLevelItem(QLatin1String("Failed Plugins"));
|
||||
const QFont boldFont = topLevelItem->font(0);
|
||||
foreach (const QString &plugin, notLoadedPlugins) {
|
||||
const QString failureReason = pluginManager->failureReason(plugin);
|
||||
QTreeWidgetItem *pluginItem = setPluginItem(topLevelItem, plugin, boldFont);
|
||||
setItem(pluginItem, failureReason, failureReason, QString(), QIcon());
|
||||
}
|
||||
}
|
||||
|
||||
if (ui.treeWidget->topLevelItemCount() == 0) {
|
||||
ui.label->setText(tr("Qt Designer couldn't find any plugins"));
|
||||
ui.treeWidget->hide();
|
||||
} else {
|
||||
ui.label->setText(tr("Qt Designer found the following plugins"));
|
||||
}
|
||||
}
|
||||
|
||||
QIcon PluginDialog::pluginIcon(const QIcon &icon)
|
||||
{
|
||||
if (icon.isNull())
|
||||
return QIcon(QLatin1String(":/trolltech/formeditor/images/qtlogo.png"));
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
QTreeWidgetItem* PluginDialog::setTopLevelItem(const QString &itemName)
|
||||
{
|
||||
QTreeWidgetItem *topLevelItem = new QTreeWidgetItem(ui.treeWidget);
|
||||
topLevelItem->setText(0, itemName);
|
||||
ui.treeWidget->setItemExpanded(topLevelItem, true);
|
||||
topLevelItem->setIcon(0, style()->standardPixmap(QStyle::SP_DirOpenIcon));
|
||||
|
||||
QFont boldFont = topLevelItem->font(0);
|
||||
boldFont.setBold(true);
|
||||
topLevelItem->setFont(0, boldFont);
|
||||
|
||||
return topLevelItem;
|
||||
}
|
||||
|
||||
QTreeWidgetItem* PluginDialog::setPluginItem(QTreeWidgetItem *topLevelItem,
|
||||
const QString &itemName, const QFont &font)
|
||||
{
|
||||
QTreeWidgetItem *pluginItem = new QTreeWidgetItem(topLevelItem);
|
||||
pluginItem->setFont(0, font);
|
||||
pluginItem->setText(0, itemName);
|
||||
ui.treeWidget->setItemExpanded(pluginItem, true);
|
||||
pluginItem->setIcon(0, style()->standardPixmap(QStyle::SP_DirOpenIcon));
|
||||
|
||||
return pluginItem;
|
||||
}
|
||||
|
||||
void PluginDialog::setItem(QTreeWidgetItem *pluginItem, const QString &name,
|
||||
const QString &toolTip, const QString &whatsThis, const QIcon &icon)
|
||||
{
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem(pluginItem);
|
||||
item->setText(0, name);
|
||||
item->setToolTip(0, toolTip);
|
||||
item->setWhatsThis(0, whatsThis);
|
||||
item->setIcon(0, pluginIcon(icon));
|
||||
}
|
||||
|
||||
void PluginDialog::updateCustomWidgetPlugins()
|
||||
{
|
||||
if (qdesigner_internal::QDesignerIntegration *integration = qobject_cast<qdesigner_internal::QDesignerIntegration *>(m_core->integration())) {
|
||||
const int before = m_core->widgetDataBase()->count();
|
||||
integration->updateCustomWidgetPlugins();
|
||||
const int after = m_core->widgetDataBase()->count();
|
||||
if (after > before) {
|
||||
ui.message->setText(tr("New custom widget plugins have been found."));
|
||||
ui.message->show();
|
||||
} else {
|
||||
ui.message->setText(QString());
|
||||
}
|
||||
populateTreeWidget();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
136
third/designer/lib/shared/plugindialog.ui
Normal file
136
third/designer/lib/shared/plugindialog.ui
Normal file
@@ -0,0 +1,136 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<comment>*********************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
*********************************************************************</comment>
|
||||
<class>PluginDialog</class>
|
||||
<widget class="QDialog" name="PluginDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>401</width>
|
||||
<height>331</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Plugin Information</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string notr="true">TextLabel</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="treeWidget">
|
||||
<property name="textElideMode">
|
||||
<enum>Qt::ElideNone</enum>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="message">
|
||||
<property name="text">
|
||||
<string notr="true">TextLabel</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>PluginDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>154</x>
|
||||
<y>307</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>401</x>
|
||||
<y>280</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
92
third/designer/lib/shared/plugindialog_p.h
Normal file
92
third/designer/lib/shared/plugindialog_p.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef PLUGINDIALOG_H
|
||||
#define PLUGINDIALOG_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "ui_plugindialog.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDesignerFormEditorInterface;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
class PluginDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PluginDialog(QDesignerFormEditorInterface *core, QWidget *parent = 0);
|
||||
|
||||
private slots:
|
||||
void updateCustomWidgetPlugins();
|
||||
|
||||
private:
|
||||
void populateTreeWidget();
|
||||
QIcon pluginIcon(const QIcon &icon);
|
||||
QTreeWidgetItem* setTopLevelItem(const QString &itemName);
|
||||
QTreeWidgetItem* setPluginItem(QTreeWidgetItem *topLevelItem,
|
||||
const QString &itemName, const QFont &font);
|
||||
void setItem(QTreeWidgetItem *pluginItem, const QString &name,
|
||||
const QString &toolTip, const QString &whatsThis, const QIcon &icon);
|
||||
|
||||
QDesignerFormEditorInterface *m_core;
|
||||
Ui::PluginDialog ui;
|
||||
QIcon interfaceIcon;
|
||||
QIcon featureIcon;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
786
third/designer/lib/shared/pluginmanager.cpp
Normal file
786
third/designer/lib/shared/pluginmanager.cpp
Normal file
@@ -0,0 +1,786 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "pluginmanager_p.h"
|
||||
#include "qdesigner_utils_p.h"
|
||||
#include "qdesigner_qsettings_p.h"
|
||||
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
#include <QtDesigner/QDesignerCustomWidgetInterface>
|
||||
#include <QtDesigner/QExtensionManager>
|
||||
#include <QtDesigner/QDesignerLanguageExtension>
|
||||
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QSet>
|
||||
#include <QtCore/QPluginLoader>
|
||||
#include <QtCore/QLibrary>
|
||||
#include <QtCore/QLibraryInfo>
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QSettings>
|
||||
#include <QtCore/QCoreApplication>
|
||||
|
||||
#include <QtCore/QXmlStreamReader>
|
||||
#include <QtCore/QXmlStreamAttributes>
|
||||
#include <QtCore/QXmlStreamAttribute>
|
||||
|
||||
static const char *uiElementC = "ui";
|
||||
static const char *languageAttributeC = "language";
|
||||
static const char *widgetElementC = "widget";
|
||||
static const char *displayNameAttributeC = "displayname";
|
||||
static const char *classAttributeC = "class";
|
||||
static const char *customwidgetElementC = "customwidget";
|
||||
static const char *extendsElementC = "extends";
|
||||
static const char *addPageMethodC = "addpagemethod";
|
||||
static const char *propertySpecsC = "propertyspecifications";
|
||||
static const char *stringPropertySpecC = "stringpropertyspecification";
|
||||
static const char *stringPropertyNameAttrC = "name";
|
||||
static const char *stringPropertyTypeAttrC = "type";
|
||||
static const char *stringPropertyNoTrAttrC = "notr";
|
||||
static const char *jambiLanguageC = "jambi";
|
||||
|
||||
enum { debugPluginManager = 0 };
|
||||
|
||||
/* Custom widgets: Loading custom widgets is a 2-step process: PluginManager
|
||||
* scans for its plugins in the constructor. At this point, it might not be safe
|
||||
* to immediately initialize the custom widgets it finds, because the rest of
|
||||
* Designer is not initialized yet.
|
||||
* Later on, in ensureInitialized(), the plugin instances (including static ones)
|
||||
* are iterated and the custom widget plugins are initialized and added to internal
|
||||
* list of custom widgets and parsed data. Should there be a parse error or a language
|
||||
* mismatch, it kicks out the respective custom widget. The m_initialized flag
|
||||
* is used to indicate the state.
|
||||
* Later, someone might call registerNewPlugins(), which agains clears the flag via
|
||||
* registerPlugin() and triggers the process again.
|
||||
* Also note that Jambi fakes a custom widget collection that changes its contents
|
||||
* every time the project is switched. So, custom widget plugins can actually
|
||||
* disappear, and the custom widget list must be cleared and refilled in
|
||||
* ensureInitialized() after registerNewPlugins. */
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static QStringList unique(const QStringList &lst)
|
||||
{
|
||||
const QSet<QString> s = QSet<QString>::fromList(lst);
|
||||
return s.toList();
|
||||
}
|
||||
|
||||
QStringList QDesignerPluginManager::defaultPluginPaths()
|
||||
{
|
||||
QStringList result;
|
||||
|
||||
const QStringList path_list = QCoreApplication::libraryPaths();
|
||||
|
||||
const QString designer = QLatin1String("designer");
|
||||
foreach (const QString &path, path_list) {
|
||||
QString libPath = path;
|
||||
libPath += QDir::separator();
|
||||
libPath += designer;
|
||||
result.append(libPath);
|
||||
}
|
||||
|
||||
QString homeLibPath = QDir::homePath();
|
||||
homeLibPath += QDir::separator();
|
||||
homeLibPath += QLatin1String(".designer");
|
||||
homeLibPath += QDir::separator();
|
||||
homeLibPath += QLatin1String("plugins");
|
||||
|
||||
result.append(homeLibPath);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Figure out the language designer is running. ToDo: Introduce some
|
||||
// Language name API to QDesignerLanguageExtension?
|
||||
|
||||
static inline QString getDesignerLanguage(QDesignerFormEditorInterface *core)
|
||||
{
|
||||
if (QDesignerLanguageExtension *lang = qt_extension<QDesignerLanguageExtension *>(core->extensionManager(), core)) {
|
||||
if (lang->uiExtension() == QLatin1String("jui"))
|
||||
return QLatin1String(jambiLanguageC);
|
||||
return QLatin1String("unknown");
|
||||
}
|
||||
return QLatin1String("c++");
|
||||
}
|
||||
|
||||
// ---------------- QDesignerCustomWidgetSharedData
|
||||
|
||||
class QDesignerCustomWidgetSharedData : public QSharedData {
|
||||
public:
|
||||
// Type of a string property
|
||||
typedef QPair<qdesigner_internal::TextPropertyValidationMode, bool> StringPropertyType;
|
||||
typedef QHash<QString, StringPropertyType> StringPropertyTypeMap;
|
||||
|
||||
explicit QDesignerCustomWidgetSharedData(const QString &thePluginPath) : pluginPath(thePluginPath) {}
|
||||
void clearXML();
|
||||
|
||||
QString pluginPath;
|
||||
|
||||
QString xmlClassName;
|
||||
QString xmlDisplayName;
|
||||
QString xmlLanguage;
|
||||
QString xmlAddPageMethod;
|
||||
QString xmlExtends;
|
||||
|
||||
StringPropertyTypeMap xmlStringPropertyTypeMap;
|
||||
};
|
||||
|
||||
void QDesignerCustomWidgetSharedData::clearXML()
|
||||
{
|
||||
xmlClassName.clear();
|
||||
xmlDisplayName.clear();
|
||||
xmlLanguage.clear();
|
||||
xmlAddPageMethod.clear();
|
||||
xmlExtends.clear();
|
||||
xmlStringPropertyTypeMap.clear();
|
||||
}
|
||||
|
||||
// ---------------- QDesignerCustomWidgetData
|
||||
|
||||
QDesignerCustomWidgetData::QDesignerCustomWidgetData(const QString &pluginPath) :
|
||||
m_d(new QDesignerCustomWidgetSharedData(pluginPath))
|
||||
{
|
||||
}
|
||||
|
||||
QDesignerCustomWidgetData::QDesignerCustomWidgetData(const QDesignerCustomWidgetData &o) :
|
||||
m_d(o.m_d)
|
||||
{
|
||||
}
|
||||
|
||||
QDesignerCustomWidgetData& QDesignerCustomWidgetData::operator=(const QDesignerCustomWidgetData &o)
|
||||
{
|
||||
m_d.operator=(o.m_d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDesignerCustomWidgetData::~QDesignerCustomWidgetData()
|
||||
{
|
||||
}
|
||||
|
||||
bool QDesignerCustomWidgetData::isNull() const
|
||||
{
|
||||
return m_d->xmlClassName.isEmpty() || m_d->pluginPath.isEmpty();
|
||||
}
|
||||
|
||||
QString QDesignerCustomWidgetData::xmlClassName() const
|
||||
{
|
||||
return m_d->xmlClassName;
|
||||
}
|
||||
|
||||
QString QDesignerCustomWidgetData::xmlLanguage() const
|
||||
{
|
||||
return m_d->xmlLanguage;
|
||||
}
|
||||
|
||||
QString QDesignerCustomWidgetData::xmlAddPageMethod() const
|
||||
{
|
||||
return m_d->xmlAddPageMethod;
|
||||
}
|
||||
|
||||
QString QDesignerCustomWidgetData::xmlExtends() const
|
||||
{
|
||||
return m_d->xmlExtends;
|
||||
}
|
||||
|
||||
QString QDesignerCustomWidgetData::xmlDisplayName() const
|
||||
{
|
||||
return m_d->xmlDisplayName;
|
||||
}
|
||||
|
||||
QString QDesignerCustomWidgetData::pluginPath() const
|
||||
{
|
||||
return m_d->pluginPath;
|
||||
}
|
||||
|
||||
bool QDesignerCustomWidgetData::xmlStringPropertyType(const QString &name, StringPropertyType *type) const
|
||||
{
|
||||
QDesignerCustomWidgetSharedData::StringPropertyTypeMap::const_iterator it = m_d->xmlStringPropertyTypeMap.constFind(name);
|
||||
if (it == m_d->xmlStringPropertyTypeMap.constEnd()) {
|
||||
*type = StringPropertyType(qdesigner_internal::ValidationRichText, true);
|
||||
return false;
|
||||
}
|
||||
*type = it.value();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Wind a QXmlStreamReader until it finds an element. Returns index or one of FindResult
|
||||
enum FindResult { FindError = -2, ElementNotFound = -1 };
|
||||
|
||||
static int findElement(const QStringList &desiredElts, QXmlStreamReader &sr)
|
||||
{
|
||||
while (true) {
|
||||
switch(sr.readNext()) {
|
||||
case QXmlStreamReader::EndDocument:
|
||||
return ElementNotFound;
|
||||
case QXmlStreamReader::Invalid:
|
||||
return FindError;
|
||||
case QXmlStreamReader::StartElement: {
|
||||
const int index = desiredElts.indexOf(sr.name().toString().toLower());
|
||||
if (index >= 0)
|
||||
return index;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return FindError;
|
||||
}
|
||||
|
||||
static inline QString msgXmlError(const QString &name, const QString &errorMessage)
|
||||
{
|
||||
return QDesignerPluginManager::tr("An XML error was encountered when parsing the XML of the custom widget %1: %2").arg(name, errorMessage);
|
||||
}
|
||||
|
||||
static inline QString msgAttributeMissing(const QString &name)
|
||||
{
|
||||
return QDesignerPluginManager::tr("A required attribute ('%1') is missing.").arg(name);
|
||||
}
|
||||
|
||||
static qdesigner_internal::TextPropertyValidationMode typeStringToType(const QString &v, bool *ok)
|
||||
{
|
||||
*ok = true;
|
||||
if (v == QLatin1String("multiline"))
|
||||
return qdesigner_internal::ValidationMultiLine;
|
||||
if (v == QLatin1String("richtext"))
|
||||
return qdesigner_internal::ValidationRichText;
|
||||
if (v == QLatin1String("stylesheet"))
|
||||
return qdesigner_internal::ValidationStyleSheet;
|
||||
if (v == QLatin1String("singleline"))
|
||||
return qdesigner_internal::ValidationSingleLine;
|
||||
if (v == QLatin1String("objectname"))
|
||||
return qdesigner_internal::ValidationObjectName;
|
||||
if (v == QLatin1String("objectnamescope"))
|
||||
return qdesigner_internal::ValidationObjectNameScope;
|
||||
if (v == QLatin1String("url"))
|
||||
return qdesigner_internal::ValidationURL;
|
||||
*ok = false;
|
||||
return qdesigner_internal::ValidationRichText;
|
||||
}
|
||||
|
||||
static bool parsePropertySpecs(QXmlStreamReader &sr,
|
||||
QDesignerCustomWidgetSharedData::StringPropertyTypeMap *rc,
|
||||
QString *errorMessage)
|
||||
{
|
||||
const QString propertySpecs = QLatin1String(propertySpecsC);
|
||||
const QString stringPropertySpec = QLatin1String(stringPropertySpecC);
|
||||
const QString stringPropertyTypeAttr = QLatin1String(stringPropertyTypeAttrC);
|
||||
const QString stringPropertyNoTrAttr = QLatin1String(stringPropertyNoTrAttrC);
|
||||
const QString stringPropertyNameAttr = QLatin1String(stringPropertyNameAttrC);
|
||||
|
||||
while (!sr.atEnd()) {
|
||||
switch(sr.readNext()) {
|
||||
case QXmlStreamReader::StartElement: {
|
||||
if (sr.name() != stringPropertySpec) {
|
||||
*errorMessage = QDesignerPluginManager::tr("An invalid property specification ('%1') was encountered. Supported types: %2").arg(sr.name().toString(), stringPropertySpec);
|
||||
return false;
|
||||
}
|
||||
const QXmlStreamAttributes atts = sr.attributes();
|
||||
const QString name = atts.value(stringPropertyNameAttr).toString();
|
||||
const QString type = atts.value(stringPropertyTypeAttr).toString();
|
||||
const QString notrS = atts.value(stringPropertyNoTrAttr).toString(); //Optional
|
||||
|
||||
if (type.isEmpty()) {
|
||||
*errorMessage = msgAttributeMissing(stringPropertyTypeAttr);
|
||||
return false;
|
||||
}
|
||||
if (name.isEmpty()) {
|
||||
*errorMessage = msgAttributeMissing(stringPropertyNameAttr);
|
||||
return false;
|
||||
}
|
||||
bool typeOk;
|
||||
const bool noTr = notrS == QLatin1String("true") || notrS == QLatin1String("1");
|
||||
QDesignerCustomWidgetSharedData::StringPropertyType v(typeStringToType(type, &typeOk), !noTr);
|
||||
if (!typeOk) {
|
||||
*errorMessage = QDesignerPluginManager::tr("'%1' is not a valid string property specification.").arg(type);
|
||||
return false;
|
||||
}
|
||||
rc->insert(name, v);
|
||||
}
|
||||
break;
|
||||
case QXmlStreamReader::EndElement: // Outer </stringproperties>
|
||||
if (sr.name() == propertySpecs)
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QDesignerCustomWidgetData::ParseResult
|
||||
QDesignerCustomWidgetData::parseXml(const QString &xml, const QString &name, QString *errorMessage)
|
||||
{
|
||||
if (debugPluginManager)
|
||||
qDebug() << Q_FUNC_INFO << name;
|
||||
|
||||
QDesignerCustomWidgetSharedData &data = *m_d;
|
||||
data.clearXML();
|
||||
|
||||
QXmlStreamReader sr(xml);
|
||||
|
||||
bool foundUI = false;
|
||||
bool foundWidget = false;
|
||||
ParseResult rc = ParseOk;
|
||||
// Parse for the (optional) <ui> or the first <widget> element
|
||||
QStringList elements;
|
||||
elements.push_back(QLatin1String(uiElementC));
|
||||
elements.push_back(QLatin1String(widgetElementC));
|
||||
for (int i = 0; i < 2 && !foundWidget; i++) {
|
||||
switch (findElement(elements, sr)) {
|
||||
case FindError:
|
||||
*errorMessage = msgXmlError(name, sr.errorString());
|
||||
return ParseError;
|
||||
case ElementNotFound:
|
||||
*errorMessage = QDesignerPluginManager::tr("The XML of the custom widget %1 does not contain any of the elements <widget> or <ui>.").arg(name);
|
||||
return ParseError;
|
||||
case 0: { // <ui>
|
||||
const QXmlStreamAttributes attributes = sr.attributes();
|
||||
data.xmlLanguage = attributes.value(QLatin1String(languageAttributeC)).toString();
|
||||
data.xmlDisplayName = attributes.value(QLatin1String(displayNameAttributeC)).toString();
|
||||
foundUI = true;
|
||||
}
|
||||
break;
|
||||
case 1: // <widget>: Do some sanity checks
|
||||
data.xmlClassName = sr.attributes().value(QLatin1String(classAttributeC)).toString();
|
||||
if (data.xmlClassName.isEmpty()) {
|
||||
*errorMessage = QDesignerPluginManager::tr("The class attribute for the class %1 is missing.").arg(name);
|
||||
rc = ParseWarning;
|
||||
} else {
|
||||
if (data.xmlClassName != name) {
|
||||
*errorMessage = QDesignerPluginManager::tr("The class attribute for the class %1 does not match the class name %2.").arg(data.xmlClassName, name);
|
||||
rc = ParseWarning;
|
||||
}
|
||||
}
|
||||
foundWidget = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Parse out the <customwidget> element which might be present if <ui> was there
|
||||
if (!foundUI)
|
||||
return rc;
|
||||
elements.clear();
|
||||
elements.push_back(QLatin1String(customwidgetElementC));
|
||||
switch (findElement(elements, sr)) {
|
||||
case FindError:
|
||||
*errorMessage = msgXmlError(name, sr.errorString());
|
||||
return ParseError;
|
||||
case ElementNotFound:
|
||||
return rc;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Find <extends>, <addPageMethod>, <stringproperties>
|
||||
elements.clear();
|
||||
elements.push_back(QLatin1String(extendsElementC));
|
||||
elements.push_back(QLatin1String(addPageMethodC));
|
||||
elements.push_back(QLatin1String(propertySpecsC));
|
||||
while (true) {
|
||||
switch (findElement(elements, sr)) {
|
||||
case FindError:
|
||||
*errorMessage = msgXmlError(name, sr.errorString());
|
||||
return ParseError;
|
||||
case ElementNotFound:
|
||||
return rc;
|
||||
case 0: // <extends>
|
||||
data.xmlExtends = sr.readElementText();
|
||||
if (sr.tokenType() != QXmlStreamReader::EndElement) {
|
||||
*errorMessage = msgXmlError(name, sr.errorString());
|
||||
return ParseError;
|
||||
}
|
||||
break;
|
||||
case 1: // <addPageMethod>
|
||||
data.xmlAddPageMethod = sr.readElementText();
|
||||
if (sr.tokenType() != QXmlStreamReader::EndElement) {
|
||||
*errorMessage = msgXmlError(name, sr.errorString());
|
||||
return ParseError;
|
||||
}
|
||||
break;
|
||||
case 2: // <stringproperties>
|
||||
if (!parsePropertySpecs(sr, &m_d->xmlStringPropertyTypeMap, errorMessage)) {
|
||||
*errorMessage = msgXmlError(name, *errorMessage);
|
||||
return ParseError;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
// ---------------- QDesignerPluginManagerPrivate
|
||||
|
||||
class QDesignerPluginManagerPrivate {
|
||||
public:
|
||||
typedef QPair<QString, QString> ClassNamePropertyNameKey;
|
||||
|
||||
QDesignerPluginManagerPrivate(QDesignerFormEditorInterface *core);
|
||||
|
||||
void clearCustomWidgets();
|
||||
bool addCustomWidget(QDesignerCustomWidgetInterface *c,
|
||||
const QString &pluginPath,
|
||||
const QString &designerLanguage);
|
||||
void addCustomWidgets(const QObject *o,
|
||||
const QString &pluginPath,
|
||||
const QString &designerLanguage);
|
||||
|
||||
QDesignerFormEditorInterface *m_core;
|
||||
QStringList m_pluginPaths;
|
||||
QStringList m_registeredPlugins;
|
||||
// TODO: QPluginLoader also caches invalid plugins -> This seems to be dead code
|
||||
QStringList m_disabledPlugins;
|
||||
|
||||
typedef QMap<QString, QString> FailedPluginMap;
|
||||
FailedPluginMap m_failedPlugins;
|
||||
|
||||
// Synced lists of custom widgets and their data. Note that the list
|
||||
// must be ordered for collections to appear in order.
|
||||
QList<QDesignerCustomWidgetInterface *> m_customWidgets;
|
||||
QList<QDesignerCustomWidgetData> m_customWidgetData;
|
||||
|
||||
QStringList defaultPluginPaths() const;
|
||||
|
||||
bool m_initialized;
|
||||
};
|
||||
|
||||
QDesignerPluginManagerPrivate::QDesignerPluginManagerPrivate(QDesignerFormEditorInterface *core) :
|
||||
m_core(core),
|
||||
m_initialized(false)
|
||||
{
|
||||
}
|
||||
|
||||
void QDesignerPluginManagerPrivate::clearCustomWidgets()
|
||||
{
|
||||
m_customWidgets.clear();
|
||||
m_customWidgetData.clear();
|
||||
}
|
||||
|
||||
// Add a custom widget to the list if it parses correctly
|
||||
// and is of the right language
|
||||
bool QDesignerPluginManagerPrivate::addCustomWidget(QDesignerCustomWidgetInterface *c,
|
||||
const QString &pluginPath,
|
||||
const QString &designerLanguage)
|
||||
{
|
||||
if (debugPluginManager)
|
||||
qDebug() << Q_FUNC_INFO << c->name();
|
||||
|
||||
if (!c->isInitialized())
|
||||
c->initialize(m_core);
|
||||
// Parse the XML even if the plugin is initialized as Jambi might play tricks here
|
||||
QDesignerCustomWidgetData data(pluginPath);
|
||||
const QString domXml = c->domXml();
|
||||
if (!domXml.isEmpty()) { // Legacy: Empty XML means: Do not show up in widget box.
|
||||
QString errorMessage;
|
||||
const QDesignerCustomWidgetData::ParseResult pr = data.parseXml(domXml, c->name(), &errorMessage);
|
||||
switch (pr) {
|
||||
case QDesignerCustomWidgetData::ParseOk:
|
||||
break;
|
||||
case QDesignerCustomWidgetData::ParseWarning:
|
||||
qdesigner_internal::designerWarning(errorMessage);
|
||||
break;
|
||||
case QDesignerCustomWidgetData::ParseError:
|
||||
qdesigner_internal::designerWarning(errorMessage);
|
||||
return false;
|
||||
}
|
||||
// Does the language match?
|
||||
const QString pluginLanguage = data.xmlLanguage();
|
||||
if (!pluginLanguage.isEmpty() && pluginLanguage.compare(designerLanguage, Qt::CaseInsensitive))
|
||||
return false;
|
||||
}
|
||||
m_customWidgets.push_back(c);
|
||||
m_customWidgetData.push_back(data);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check the plugin interface for either a custom widget or a collection and
|
||||
// add all contained custom widgets.
|
||||
void QDesignerPluginManagerPrivate::addCustomWidgets(const QObject *o,
|
||||
const QString &pluginPath,
|
||||
const QString &designerLanguage)
|
||||
{
|
||||
if (QDesignerCustomWidgetInterface *c = qobject_cast<QDesignerCustomWidgetInterface*>(o)) {
|
||||
addCustomWidget(c, pluginPath, designerLanguage);
|
||||
return;
|
||||
}
|
||||
if (const QDesignerCustomWidgetCollectionInterface *coll = qobject_cast<QDesignerCustomWidgetCollectionInterface*>(o)) {
|
||||
foreach(QDesignerCustomWidgetInterface *c, coll->customWidgets())
|
||||
addCustomWidget(c, pluginPath, designerLanguage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ---------------- QDesignerPluginManager
|
||||
// As of 4.4, the header will be distributed with the Eclipse plugin.
|
||||
|
||||
QDesignerPluginManager::QDesignerPluginManager(QDesignerFormEditorInterface *core) :
|
||||
QObject(core),
|
||||
m_d(new QDesignerPluginManagerPrivate(core))
|
||||
{
|
||||
m_d->m_pluginPaths = defaultPluginPaths();
|
||||
const QSettings settings(qApp->organizationName(), QDesignerQSettings::settingsApplicationName());
|
||||
m_d->m_disabledPlugins = unique(settings.value(QLatin1String("PluginManager/DisabledPlugins")).toStringList());
|
||||
|
||||
// Register plugins
|
||||
updateRegisteredPlugins();
|
||||
|
||||
if (debugPluginManager)
|
||||
qDebug() << "QDesignerPluginManager::disabled: " << m_d->m_disabledPlugins << " static " << m_d->m_customWidgets.size();
|
||||
}
|
||||
|
||||
QDesignerPluginManager::~QDesignerPluginManager()
|
||||
{
|
||||
syncSettings();
|
||||
delete m_d;
|
||||
}
|
||||
|
||||
QDesignerFormEditorInterface *QDesignerPluginManager::core() const
|
||||
{
|
||||
return m_d->m_core;
|
||||
}
|
||||
|
||||
QStringList QDesignerPluginManager::findPlugins(const QString &path)
|
||||
{
|
||||
if (debugPluginManager)
|
||||
qDebug() << Q_FUNC_INFO << path;
|
||||
const QDir dir(path);
|
||||
if (!dir.exists())
|
||||
return QStringList();
|
||||
|
||||
const QFileInfoList infoList = dir.entryInfoList(QDir::Files);
|
||||
if (infoList.empty())
|
||||
return QStringList();
|
||||
|
||||
// Load symbolic links but make sure all file names are unique as not
|
||||
// to fall for something like 'libplugin.so.1 -> libplugin.so'
|
||||
QStringList result;
|
||||
const QFileInfoList::const_iterator icend = infoList.constEnd();
|
||||
for (QFileInfoList::const_iterator it = infoList.constBegin(); it != icend; ++it) {
|
||||
QString fileName;
|
||||
if (it->isSymLink()) {
|
||||
const QFileInfo linkTarget = QFileInfo(it->symLinkTarget());
|
||||
if (linkTarget.exists() && linkTarget.isFile())
|
||||
fileName = linkTarget.absoluteFilePath();
|
||||
} else {
|
||||
fileName = it->absoluteFilePath();
|
||||
}
|
||||
if (!fileName.isEmpty() && QLibrary::isLibrary(fileName) && !result.contains(fileName))
|
||||
result += fileName;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void QDesignerPluginManager::setDisabledPlugins(const QStringList &disabled_plugins)
|
||||
{
|
||||
m_d->m_disabledPlugins = disabled_plugins;
|
||||
updateRegisteredPlugins();
|
||||
}
|
||||
|
||||
void QDesignerPluginManager::setPluginPaths(const QStringList &plugin_paths)
|
||||
{
|
||||
m_d->m_pluginPaths = plugin_paths;
|
||||
updateRegisteredPlugins();
|
||||
}
|
||||
|
||||
QStringList QDesignerPluginManager::disabledPlugins() const
|
||||
{
|
||||
return m_d->m_disabledPlugins;
|
||||
}
|
||||
|
||||
QStringList QDesignerPluginManager::failedPlugins() const
|
||||
{
|
||||
return m_d->m_failedPlugins.keys();
|
||||
}
|
||||
|
||||
QString QDesignerPluginManager::failureReason(const QString &pluginName) const
|
||||
{
|
||||
return m_d->m_failedPlugins.value(pluginName);
|
||||
}
|
||||
|
||||
QStringList QDesignerPluginManager::registeredPlugins() const
|
||||
{
|
||||
return m_d->m_registeredPlugins;
|
||||
}
|
||||
|
||||
QStringList QDesignerPluginManager::pluginPaths() const
|
||||
{
|
||||
return m_d->m_pluginPaths;
|
||||
}
|
||||
|
||||
QObject *QDesignerPluginManager::instance(const QString &plugin) const
|
||||
{
|
||||
if (m_d->m_disabledPlugins.contains(plugin))
|
||||
return 0;
|
||||
|
||||
QPluginLoader loader(plugin);
|
||||
return loader.instance();
|
||||
}
|
||||
|
||||
void QDesignerPluginManager::updateRegisteredPlugins()
|
||||
{
|
||||
if (debugPluginManager)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
m_d->m_registeredPlugins.clear();
|
||||
foreach (const QString &path, m_d->m_pluginPaths)
|
||||
registerPath(path);
|
||||
}
|
||||
|
||||
bool QDesignerPluginManager::registerNewPlugins()
|
||||
{
|
||||
if (debugPluginManager)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
const int before = m_d->m_registeredPlugins.size();
|
||||
foreach (const QString &path, m_d->m_pluginPaths)
|
||||
registerPath(path);
|
||||
const bool newPluginsFound = m_d->m_registeredPlugins.size() > before;
|
||||
// We force a re-initialize as Jambi collection might return
|
||||
// different widget lists when switching projects.
|
||||
m_d->m_initialized = false;
|
||||
ensureInitialized();
|
||||
|
||||
return newPluginsFound;
|
||||
}
|
||||
|
||||
void QDesignerPluginManager::registerPath(const QString &path)
|
||||
{
|
||||
if (debugPluginManager)
|
||||
qDebug() << Q_FUNC_INFO << path;
|
||||
QStringList candidates = findPlugins(path);
|
||||
|
||||
foreach (const QString &plugin, candidates)
|
||||
registerPlugin(plugin);
|
||||
}
|
||||
|
||||
void QDesignerPluginManager::registerPlugin(const QString &plugin)
|
||||
{
|
||||
if (debugPluginManager)
|
||||
qDebug() << Q_FUNC_INFO << plugin;
|
||||
if (m_d->m_disabledPlugins.contains(plugin))
|
||||
return;
|
||||
if (m_d->m_registeredPlugins.contains(plugin))
|
||||
return;
|
||||
|
||||
QPluginLoader loader(plugin);
|
||||
if (loader.isLoaded() || loader.load()) {
|
||||
m_d->m_registeredPlugins += plugin;
|
||||
QDesignerPluginManagerPrivate::FailedPluginMap::iterator fit = m_d->m_failedPlugins.find(plugin);
|
||||
if (fit != m_d->m_failedPlugins.end())
|
||||
m_d->m_failedPlugins.erase(fit);
|
||||
return;
|
||||
}
|
||||
|
||||
const QString errorMessage = loader.errorString();
|
||||
m_d->m_failedPlugins.insert(plugin, errorMessage);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool QDesignerPluginManager::syncSettings()
|
||||
{
|
||||
QSettings settings(qApp->organizationName(), QDesignerQSettings::settingsApplicationName());
|
||||
settings.beginGroup(QLatin1String("PluginManager"));
|
||||
settings.setValue(QLatin1String("DisabledPlugins"), m_d->m_disabledPlugins);
|
||||
settings.endGroup();
|
||||
return settings.status() == QSettings::NoError;
|
||||
}
|
||||
|
||||
void QDesignerPluginManager::ensureInitialized()
|
||||
{
|
||||
if (debugPluginManager)
|
||||
qDebug() << Q_FUNC_INFO << m_d->m_initialized << m_d->m_customWidgets.size();
|
||||
|
||||
if (m_d->m_initialized)
|
||||
return;
|
||||
|
||||
const QString designerLanguage = getDesignerLanguage(m_d->m_core);
|
||||
|
||||
m_d->clearCustomWidgets();
|
||||
// Add the static custom widgets
|
||||
const QObjectList staticPluginObjects = QPluginLoader::staticInstances();
|
||||
if (!staticPluginObjects.empty()) {
|
||||
const QString staticPluginPath = QCoreApplication::applicationFilePath();
|
||||
foreach(QObject *o, staticPluginObjects)
|
||||
m_d->addCustomWidgets(o, staticPluginPath, designerLanguage);
|
||||
}
|
||||
foreach (const QString &plugin, m_d->m_registeredPlugins)
|
||||
if (QObject *o = instance(plugin))
|
||||
m_d->addCustomWidgets(o, plugin, designerLanguage);
|
||||
|
||||
m_d->m_initialized = true;
|
||||
}
|
||||
|
||||
QDesignerPluginManager::CustomWidgetList QDesignerPluginManager::registeredCustomWidgets() const
|
||||
{
|
||||
const_cast<QDesignerPluginManager*>(this)->ensureInitialized();
|
||||
return m_d->m_customWidgets;
|
||||
}
|
||||
|
||||
QDesignerCustomWidgetData QDesignerPluginManager::customWidgetData(QDesignerCustomWidgetInterface *w) const
|
||||
{
|
||||
const int index = m_d->m_customWidgets.indexOf(w);
|
||||
if (index == -1)
|
||||
return QDesignerCustomWidgetData();
|
||||
return m_d->m_customWidgetData.at(index);
|
||||
}
|
||||
|
||||
QDesignerCustomWidgetData QDesignerPluginManager::customWidgetData(const QString &name) const
|
||||
{
|
||||
const int count = m_d->m_customWidgets.size();
|
||||
for (int i = 0; i < count; i++)
|
||||
if (m_d->m_customWidgets.at(i)->name() == name)
|
||||
return m_d->m_customWidgetData.at(i);
|
||||
return QDesignerCustomWidgetData();
|
||||
}
|
||||
|
||||
QObjectList QDesignerPluginManager::instances() const
|
||||
{
|
||||
QStringList plugins = registeredPlugins();
|
||||
|
||||
QObjectList lst;
|
||||
foreach (const QString &plugin, plugins) {
|
||||
if (QObject *o = instance(plugin))
|
||||
lst.append(o);
|
||||
}
|
||||
|
||||
return lst;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
159
third/designer/lib/shared/pluginmanager_p.h
Normal file
159
third/designer/lib/shared/pluginmanager_p.h
Normal file
@@ -0,0 +1,159 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef PLUGINMANAGER_H
|
||||
#define PLUGINMANAGER_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
#include "shared_enums_p.h"
|
||||
|
||||
#include <QtCore/QSharedDataPointer>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QPair>
|
||||
#include <QtCore/QStringList>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDesignerFormEditorInterface;
|
||||
class QDesignerCustomWidgetInterface;
|
||||
class QDesignerPluginManagerPrivate;
|
||||
|
||||
class QDesignerCustomWidgetSharedData;
|
||||
|
||||
/* Information contained in the Dom XML of a custom widget. */
|
||||
class QDESIGNER_SHARED_EXPORT QDesignerCustomWidgetData {
|
||||
public:
|
||||
// StringPropertyType: validation mode and translatable flag.
|
||||
typedef QPair<qdesigner_internal::TextPropertyValidationMode, bool> StringPropertyType;
|
||||
|
||||
explicit QDesignerCustomWidgetData(const QString &pluginPath = QString());
|
||||
|
||||
enum ParseResult { ParseOk, ParseWarning, ParseError };
|
||||
ParseResult parseXml(const QString &xml, const QString &name, QString *errorMessage);
|
||||
|
||||
QDesignerCustomWidgetData(const QDesignerCustomWidgetData&);
|
||||
QDesignerCustomWidgetData& operator=(const QDesignerCustomWidgetData&);
|
||||
~QDesignerCustomWidgetData();
|
||||
|
||||
bool isNull() const;
|
||||
|
||||
QString pluginPath() const;
|
||||
|
||||
// Data as parsed from the widget's domXML().
|
||||
QString xmlClassName() const;
|
||||
// Optional. The language the plugin is supposed to be used with.
|
||||
QString xmlLanguage() const;
|
||||
// Optional. method used to add pages to a container with a container extension
|
||||
QString xmlAddPageMethod() const;
|
||||
// Optional. Base class
|
||||
QString xmlExtends() const;
|
||||
// Optional. The name to be used in the widget box.
|
||||
QString xmlDisplayName() const;
|
||||
// Type of a string property
|
||||
bool xmlStringPropertyType(const QString &name, StringPropertyType *type) const;
|
||||
|
||||
private:
|
||||
QSharedDataPointer<QDesignerCustomWidgetSharedData> m_d;
|
||||
};
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT QDesignerPluginManager: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
typedef QList<QDesignerCustomWidgetInterface*> CustomWidgetList;
|
||||
|
||||
explicit QDesignerPluginManager(QDesignerFormEditorInterface *core);
|
||||
virtual ~QDesignerPluginManager();
|
||||
|
||||
QDesignerFormEditorInterface *core() const;
|
||||
|
||||
QObject *instance(const QString &plugin) const;
|
||||
|
||||
QStringList registeredPlugins() const;
|
||||
|
||||
QStringList findPlugins(const QString &path);
|
||||
|
||||
QStringList pluginPaths() const;
|
||||
void setPluginPaths(const QStringList &plugin_paths);
|
||||
|
||||
QStringList disabledPlugins() const;
|
||||
void setDisabledPlugins(const QStringList &disabled_plugins);
|
||||
|
||||
QStringList failedPlugins() const;
|
||||
QString failureReason(const QString &pluginName) const;
|
||||
|
||||
QObjectList instances() const;
|
||||
|
||||
CustomWidgetList registeredCustomWidgets() const;
|
||||
QDesignerCustomWidgetData customWidgetData(QDesignerCustomWidgetInterface *w) const;
|
||||
QDesignerCustomWidgetData customWidgetData(const QString &className) const;
|
||||
|
||||
bool registerNewPlugins();
|
||||
|
||||
public slots:
|
||||
bool syncSettings();
|
||||
void ensureInitialized();
|
||||
|
||||
private:
|
||||
void updateRegisteredPlugins();
|
||||
void registerPath(const QString &path);
|
||||
void registerPlugin(const QString &plugin);
|
||||
|
||||
private:
|
||||
static QStringList defaultPluginPaths();
|
||||
|
||||
QDesignerPluginManagerPrivate *m_d;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // PLUGINMANAGER_H
|
||||
366
third/designer/lib/shared/previewconfigurationwidget.cpp
Normal file
366
third/designer/lib/shared/previewconfigurationwidget.cpp
Normal file
@@ -0,0 +1,366 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/* It is possible to link the skins as resources into Designer by specifying:
|
||||
* QVFB_ROOT=$$QT_SOURCE_TREE/tools/qvfb
|
||||
* RESOURCES += $$QVFB_ROOT/ClamshellPhone.qrc $$QVFB_ROOT/TouchScreenPhone.qrc ...
|
||||
* in lib/shared/shared.pri. However, this exceeds a limit of Visual Studio 6. */
|
||||
|
||||
#include "previewconfigurationwidget_p.h"
|
||||
#include "ui_previewconfigurationwidget.h"
|
||||
#include "previewmanager_p.h"
|
||||
#include "abstractsettings_p.h"
|
||||
#include "shared_settings_p.h"
|
||||
|
||||
#include <iconloader_p.h>
|
||||
#include <stylesheeteditor_p.h>
|
||||
|
||||
#include <deviceskin.h>
|
||||
|
||||
#include <QtGui/QFileDialog>
|
||||
#include <QtGui/QStyleFactory>
|
||||
#include <QtGui/QFileDialog>
|
||||
#include <QtGui/QMessageBox>
|
||||
#include <QtCore/QPair>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QSharedData>
|
||||
|
||||
|
||||
static const char *skinResourcePathC = ":/skins/";
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static const char *skinExtensionC = "skin";
|
||||
|
||||
// Pair of skin name, path
|
||||
typedef QPair<QString, QString> SkinNamePath;
|
||||
typedef QList<SkinNamePath> Skins;
|
||||
enum { SkinComboNoneIndex = 0 };
|
||||
|
||||
// find default skins (resources)
|
||||
static const Skins &defaultSkins() {
|
||||
static Skins rc;
|
||||
if (rc.empty()) {
|
||||
const QString skinPath = QLatin1String(skinResourcePathC);
|
||||
QString pattern = QLatin1String("*.");
|
||||
pattern += QLatin1String(skinExtensionC);
|
||||
const QDir dir(skinPath, pattern);
|
||||
const QFileInfoList list = dir.entryInfoList(QDir::Dirs|QDir::NoDotAndDotDot, QDir::Name);
|
||||
if (list.empty())
|
||||
return rc;
|
||||
const QFileInfoList::const_iterator lcend = list.constEnd();
|
||||
for (QFileInfoList::const_iterator it = list.constBegin(); it != lcend; ++it)
|
||||
rc.push_back(SkinNamePath(it->baseName(), it->filePath()));
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
// ------------- PreviewConfigurationWidgetPrivate
|
||||
class PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate {
|
||||
public:
|
||||
PreviewConfigurationWidgetPrivate(QDesignerFormEditorInterface *core, QGroupBox *g);
|
||||
|
||||
void slotEditAppStyleSheet();
|
||||
void slotDeleteSkinEntry();
|
||||
void slotSkinChanged(int index);
|
||||
|
||||
void retrieveSettings();
|
||||
void storeSettings() const;
|
||||
|
||||
QAbstractButton *appStyleSheetChangeButton() const { return m_ui.m_appStyleSheetChangeButton; }
|
||||
QAbstractButton *skinRemoveButton() const { return m_ui.m_skinRemoveButton; }
|
||||
QComboBox *skinCombo() const { return m_ui.m_skinCombo; }
|
||||
|
||||
QDesignerFormEditorInterface *m_core;
|
||||
|
||||
private:
|
||||
PreviewConfiguration previewConfiguration() const;
|
||||
void setPreviewConfiguration(const PreviewConfiguration &pc);
|
||||
|
||||
QStringList userSkins() const;
|
||||
void addUserSkins(const QStringList &files);
|
||||
bool canRemoveSkin(int index) const;
|
||||
int browseSkin();
|
||||
|
||||
const QString m_defaultStyle;
|
||||
QGroupBox *m_parent;
|
||||
Ui::PreviewConfigurationWidget m_ui;
|
||||
|
||||
int m_firstUserSkinIndex;
|
||||
int m_browseSkinIndex;
|
||||
int m_lastSkinIndex; // required in case browse fails
|
||||
};
|
||||
|
||||
PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::PreviewConfigurationWidgetPrivate(
|
||||
QDesignerFormEditorInterface *core, QGroupBox *g) :
|
||||
m_core(core),
|
||||
m_defaultStyle(PreviewConfigurationWidget::tr("Default")),
|
||||
m_parent(g),
|
||||
m_firstUserSkinIndex(0),
|
||||
m_browseSkinIndex(0),
|
||||
m_lastSkinIndex(0)
|
||||
{
|
||||
m_ui.setupUi(g);
|
||||
// styles
|
||||
m_ui.m_styleCombo->setEditable(false);
|
||||
QStringList styleItems(m_defaultStyle);
|
||||
styleItems += QStyleFactory::keys();
|
||||
m_ui.m_styleCombo->addItems(styleItems);
|
||||
|
||||
// sheet
|
||||
m_ui.m_appStyleSheetLineEdit->setTextPropertyValidationMode(qdesigner_internal::ValidationStyleSheet);
|
||||
m_ui.m_appStyleSheetClearButton->setIcon(qdesigner_internal::createIconSet(QString::fromUtf8("resetproperty.png")));
|
||||
QObject::connect(m_ui.m_appStyleSheetClearButton, SIGNAL(clicked()), m_ui.m_appStyleSheetLineEdit, SLOT(clear()));
|
||||
|
||||
m_ui.m_skinRemoveButton->setIcon(qdesigner_internal::createIconSet(QString::fromUtf8("editdelete.png")));
|
||||
// skins: find default skins (resources)
|
||||
m_ui.m_skinRemoveButton->setEnabled(false);
|
||||
Skins skins = defaultSkins();
|
||||
skins.push_front(SkinNamePath(PreviewConfigurationWidget::tr("None"), QString()));
|
||||
|
||||
const Skins::const_iterator scend = skins.constEnd();
|
||||
for (Skins::const_iterator it = skins.constBegin(); it != scend; ++it)
|
||||
m_ui.m_skinCombo->addItem (it->first, QVariant(it->second));
|
||||
m_browseSkinIndex = m_firstUserSkinIndex = skins.size();
|
||||
m_ui.m_skinCombo->addItem(PreviewConfigurationWidget::tr("Browse..."), QString());
|
||||
|
||||
m_ui.m_skinCombo->setMaxVisibleItems (qMax(15, 2 * m_browseSkinIndex));
|
||||
m_ui.m_skinCombo->setEditable(false);
|
||||
|
||||
retrieveSettings();
|
||||
}
|
||||
|
||||
bool PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::canRemoveSkin(int index) const
|
||||
{
|
||||
return index >= m_firstUserSkinIndex && index != m_browseSkinIndex;
|
||||
}
|
||||
|
||||
QStringList PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::userSkins() const
|
||||
{
|
||||
QStringList rc;
|
||||
for (int i = m_firstUserSkinIndex; i < m_browseSkinIndex; i++)
|
||||
rc.push_back(m_ui.m_skinCombo->itemData(i).toString());
|
||||
return rc;
|
||||
}
|
||||
|
||||
void PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::addUserSkins(const QStringList &files)
|
||||
{
|
||||
if (files.empty())
|
||||
return;
|
||||
const QStringList ::const_iterator fcend = files.constEnd();
|
||||
for (QStringList::const_iterator it = files.constBegin(); it != fcend; ++it) {
|
||||
const QFileInfo fi(*it);
|
||||
if (fi.isDir() && fi.isReadable()) {
|
||||
m_ui.m_skinCombo->insertItem(m_browseSkinIndex++, fi.baseName(), QVariant(*it));
|
||||
} else {
|
||||
qWarning() << "Unable to access the skin directory '" << *it << "'.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PreviewConfiguration PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::previewConfiguration() const
|
||||
{
|
||||
PreviewConfiguration rc;
|
||||
QString style = m_ui.m_styleCombo->currentText();
|
||||
if (style == m_defaultStyle)
|
||||
style.clear();
|
||||
const QString applicationStyleSheet = m_ui.m_appStyleSheetLineEdit->text();
|
||||
// Figure out skin. 0 is None by definition..
|
||||
const int skinIndex = m_ui.m_skinCombo->currentIndex();
|
||||
QString deviceSkin;
|
||||
if (skinIndex != SkinComboNoneIndex && skinIndex != m_browseSkinIndex)
|
||||
deviceSkin = m_ui.m_skinCombo->itemData(skinIndex).toString();
|
||||
|
||||
return PreviewConfiguration(style, applicationStyleSheet, deviceSkin);
|
||||
}
|
||||
|
||||
void PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::setPreviewConfiguration(const PreviewConfiguration &pc)
|
||||
{
|
||||
int styleIndex = m_ui.m_styleCombo->findText(pc.style());
|
||||
if (styleIndex == -1)
|
||||
styleIndex = m_ui.m_styleCombo->findText(m_defaultStyle);
|
||||
m_ui.m_styleCombo->setCurrentIndex(styleIndex);
|
||||
m_ui.m_appStyleSheetLineEdit->setText(pc.applicationStyleSheet());
|
||||
// find skin by file name. 0 is "none"
|
||||
const QString deviceSkin = pc.deviceSkin();
|
||||
int skinIndex = deviceSkin.isEmpty() ? 0 : m_ui.m_skinCombo->findData(QVariant(deviceSkin));
|
||||
if (skinIndex == -1) {
|
||||
qWarning() << "Unable to find skin '" << deviceSkin << "'.";
|
||||
skinIndex = 0;
|
||||
}
|
||||
m_ui.m_skinCombo->setCurrentIndex(skinIndex);
|
||||
}
|
||||
|
||||
void PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::slotEditAppStyleSheet()
|
||||
{
|
||||
StyleSheetEditorDialog dlg(m_core, m_parent, StyleSheetEditorDialog::ModeGlobal);
|
||||
dlg.setText(m_ui.m_appStyleSheetLineEdit->text());
|
||||
if (dlg.exec() == QDialog::Accepted)
|
||||
m_ui.m_appStyleSheetLineEdit->setText(dlg.text());
|
||||
}
|
||||
|
||||
void PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::slotDeleteSkinEntry()
|
||||
{
|
||||
const int index = m_ui.m_skinCombo->currentIndex();
|
||||
if (canRemoveSkin(index)) {
|
||||
m_ui.m_skinCombo->setCurrentIndex(SkinComboNoneIndex);
|
||||
m_ui.m_skinCombo->removeItem(index);
|
||||
m_browseSkinIndex--;
|
||||
}
|
||||
}
|
||||
|
||||
void PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::slotSkinChanged(int index)
|
||||
{
|
||||
if (index == m_browseSkinIndex) {
|
||||
m_ui.m_skinCombo->setCurrentIndex(browseSkin());
|
||||
} else {
|
||||
m_lastSkinIndex = index;
|
||||
m_ui.m_skinRemoveButton->setEnabled(canRemoveSkin(index));
|
||||
m_ui.m_skinCombo->setToolTip(index != SkinComboNoneIndex ? m_ui.m_skinCombo->itemData(index).toString() : QString());
|
||||
}
|
||||
}
|
||||
|
||||
void PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::retrieveSettings()
|
||||
{
|
||||
QDesignerSharedSettings settings(m_core);
|
||||
m_parent->setChecked(settings.isCustomPreviewConfigurationEnabled());
|
||||
setPreviewConfiguration(settings.customPreviewConfiguration());
|
||||
addUserSkins(settings.userDeviceSkins());
|
||||
}
|
||||
|
||||
void PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::storeSettings() const
|
||||
{
|
||||
QDesignerSharedSettings settings(m_core);
|
||||
settings.setCustomPreviewConfigurationEnabled(m_parent->isChecked());
|
||||
settings.setCustomPreviewConfiguration(previewConfiguration());
|
||||
settings.setUserDeviceSkins(userSkins());
|
||||
}
|
||||
|
||||
int PreviewConfigurationWidget::PreviewConfigurationWidgetPrivate::browseSkin()
|
||||
{
|
||||
QFileDialog dlg(m_parent);
|
||||
dlg.setFileMode(QFileDialog::DirectoryOnly);
|
||||
const QString title = tr("Load Custom Device Skin");
|
||||
dlg.setWindowTitle(title);
|
||||
dlg.setFilter(tr("All QVFB Skins (*.%1)").arg(QLatin1String(skinExtensionC)));
|
||||
|
||||
int rc = m_lastSkinIndex;
|
||||
do {
|
||||
if (!dlg.exec())
|
||||
break;
|
||||
|
||||
const QStringList directories = dlg.selectedFiles();
|
||||
if (directories.size() != 1)
|
||||
break;
|
||||
|
||||
// check: 1) name already there
|
||||
const QString directory = directories.front();
|
||||
const QString name = QFileInfo(directory).baseName();
|
||||
const int existingIndex = m_ui.m_skinCombo->findText(name);
|
||||
if (existingIndex != -1 && existingIndex != SkinComboNoneIndex && existingIndex != m_browseSkinIndex) {
|
||||
const QString msgTitle = tr("%1 - Duplicate Skin").arg(title);
|
||||
const QString msg = tr("The skin '%1' already exists.").arg(name);
|
||||
QMessageBox::information(m_parent, msgTitle, msg);
|
||||
break;
|
||||
}
|
||||
// check: 2) can read
|
||||
DeviceSkinParameters parameters;
|
||||
QString readError;
|
||||
if (parameters.read(directory, DeviceSkinParameters::ReadSizeOnly, &readError)) {
|
||||
const QString name = QFileInfo(directory).baseName();
|
||||
m_ui.m_skinCombo->insertItem(m_browseSkinIndex, name, QVariant(directory));
|
||||
rc = m_browseSkinIndex++;
|
||||
|
||||
break;
|
||||
} else {
|
||||
const QString msgTitle = tr("%1 - Error").arg(title);
|
||||
const QString msg = tr("%1 is not a valid skin directory:\n%2").arg(directory).arg(readError);
|
||||
QMessageBox::warning (m_parent, msgTitle, msg);
|
||||
}
|
||||
} while (true);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// ------------- PreviewConfigurationWidget
|
||||
PreviewConfigurationWidget::PreviewConfigurationWidget(QDesignerFormEditorInterface *core,
|
||||
QWidget *parent) :
|
||||
QGroupBox(parent),
|
||||
m_impl(new PreviewConfigurationWidgetPrivate(core, this))
|
||||
{
|
||||
connect(m_impl->appStyleSheetChangeButton(), SIGNAL(clicked()), this, SLOT(slotEditAppStyleSheet()));
|
||||
connect(m_impl->skinRemoveButton(), SIGNAL(clicked()), this, SLOT(slotDeleteSkinEntry()));
|
||||
connect(m_impl->skinCombo(), SIGNAL(currentIndexChanged(int)), this, SLOT(slotSkinChanged(int)));
|
||||
|
||||
m_impl->retrieveSettings();
|
||||
}
|
||||
|
||||
PreviewConfigurationWidget::~PreviewConfigurationWidget()
|
||||
{
|
||||
delete m_impl;
|
||||
}
|
||||
|
||||
void PreviewConfigurationWidget::saveState()
|
||||
{
|
||||
m_impl->storeSettings();
|
||||
}
|
||||
|
||||
void PreviewConfigurationWidget::slotEditAppStyleSheet()
|
||||
{
|
||||
m_impl->slotEditAppStyleSheet();
|
||||
}
|
||||
|
||||
void PreviewConfigurationWidget::slotDeleteSkinEntry()
|
||||
{
|
||||
m_impl->slotDeleteSkinEntry();
|
||||
}
|
||||
|
||||
void PreviewConfigurationWidget::slotSkinChanged(int index)
|
||||
{
|
||||
m_impl->slotSkinChanged(index);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
91
third/designer/lib/shared/previewconfigurationwidget.ui
Normal file
91
third/designer/lib/shared/previewconfigurationwidget.ui
Normal file
@@ -0,0 +1,91 @@
|
||||
<ui version="4.0" >
|
||||
<class>PreviewConfigurationWidget</class>
|
||||
<widget class="QGroupBox" name="PreviewConfigurationWidget" >
|
||||
<property name="windowTitle" >
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<property name="title" >
|
||||
<string>Print/Preview Configuration</string>
|
||||
</property>
|
||||
<property name="checkable" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QFormLayout" >
|
||||
<item row="0" column="0" >
|
||||
<widget class="QLabel" name="m_styleLabel" >
|
||||
<property name="text" >
|
||||
<string>Style</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" >
|
||||
<widget class="QComboBox" name="m_styleCombo" />
|
||||
</item>
|
||||
<item row="1" column="0" >
|
||||
<widget class="QLabel" name="m_appStyleSheetLabel" >
|
||||
<property name="text" >
|
||||
<string>Style sheet</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" >
|
||||
<layout class="QHBoxLayout" >
|
||||
<item>
|
||||
<widget class="qdesigner_internal::TextPropertyEditor" name="m_appStyleSheetLineEdit" >
|
||||
<property name="minimumSize" >
|
||||
<size>
|
||||
<width>149</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="m_appStyleSheetChangeButton" >
|
||||
<property name="text" >
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="m_appStyleSheetClearButton" >
|
||||
<property name="text" >
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0" >
|
||||
<widget class="QLabel" name="m_skinLabel" >
|
||||
<property name="text" >
|
||||
<string>Device skin</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" >
|
||||
<layout class="QHBoxLayout" >
|
||||
<item>
|
||||
<widget class="QComboBox" name="m_skinCombo" />
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="m_skinRemoveButton" >
|
||||
<property name="text" >
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>qdesigner_internal::TextPropertyEditor</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header location="global" >textpropertyeditor_p.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
96
third/designer/lib/shared/previewconfigurationwidget_p.h
Normal file
96
third/designer/lib/shared/previewconfigurationwidget_p.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef PREVIEWCONFIGURATIONWIDGET_H
|
||||
#define PREVIEWCONFIGURATIONWIDGET_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
|
||||
#include <QtGui/QGroupBox>
|
||||
#include <QtCore/QSharedDataPointer>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDesignerFormEditorInterface;
|
||||
class QDesignerSettingsInterface;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
// ----------- PreviewConfigurationWidget: Widget to edit the preview configuration.
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT PreviewConfigurationWidget : public QGroupBox
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PreviewConfigurationWidget(QDesignerFormEditorInterface *core,
|
||||
QWidget *parent = 0);
|
||||
virtual ~PreviewConfigurationWidget();
|
||||
void saveState();
|
||||
|
||||
private slots:
|
||||
void slotEditAppStyleSheet();
|
||||
void slotDeleteSkinEntry();
|
||||
void slotSkinChanged(int);
|
||||
|
||||
private:
|
||||
class PreviewConfigurationWidgetPrivate;
|
||||
PreviewConfigurationWidgetPrivate *m_impl;
|
||||
|
||||
PreviewConfigurationWidget(const PreviewConfigurationWidget &other);
|
||||
PreviewConfigurationWidget &operator =(const PreviewConfigurationWidget &other);
|
||||
};
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // PREVIEWCONFIGURATIONWIDGET_H
|
||||
943
third/designer/lib/shared/previewmanager.cpp
Normal file
943
third/designer/lib/shared/previewmanager.cpp
Normal file
@@ -0,0 +1,943 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "abstractsettings_p.h"
|
||||
#include "previewmanager_p.h"
|
||||
#include "qdesigner_formbuilder_p.h"
|
||||
#include "shared_settings_p.h"
|
||||
#include "shared_settings_p.h"
|
||||
#include "zoomwidget_p.h"
|
||||
#include "formwindowbase_p.h"
|
||||
#include "widgetfactory_p.h"
|
||||
|
||||
#include <deviceskin.h>
|
||||
|
||||
#include <QtDesigner/QDesignerFormWindowInterface>
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
#include <QtDesigner/QDesignerFormWindowManagerInterface>
|
||||
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/qevent.h>
|
||||
#include <QtGui/QDesktopWidget>
|
||||
#include <QtGui/QMainWindow>
|
||||
#include <QtGui/QDockWidget>
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtGui/QPixmap>
|
||||
#include <QtGui/QVBoxLayout>
|
||||
#include <QtGui/QDialog>
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QActionGroup>
|
||||
#include <QtGui/QCursor>
|
||||
#include <QtGui/QMatrix>
|
||||
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QSharedData>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static inline int compare(const qdesigner_internal::PreviewConfiguration &pc1, const qdesigner_internal::PreviewConfiguration &pc2)
|
||||
{
|
||||
int rc = pc1.style().compare(pc2.style());
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = pc1.applicationStyleSheet().compare(pc2.applicationStyleSheet());
|
||||
if (rc)
|
||||
return rc;
|
||||
return pc1.deviceSkin().compare(pc2.deviceSkin());
|
||||
}
|
||||
|
||||
namespace {
|
||||
// ------ PreviewData (data associated with a preview window)
|
||||
struct PreviewData {
|
||||
PreviewData(const QPointer<QWidget> &widget, const QDesignerFormWindowInterface *formWindow, const qdesigner_internal::PreviewConfiguration &pc);
|
||||
QPointer<QWidget> m_widget;
|
||||
const QDesignerFormWindowInterface *m_formWindow;
|
||||
qdesigner_internal::PreviewConfiguration m_configuration;
|
||||
};
|
||||
|
||||
PreviewData::PreviewData(const QPointer<QWidget>& widget,
|
||||
const QDesignerFormWindowInterface *formWindow,
|
||||
const qdesigner_internal::PreviewConfiguration &pc) :
|
||||
m_widget(widget),
|
||||
m_formWindow(formWindow),
|
||||
m_configuration(pc)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
/* In designer, we have the situation that laid-out maincontainers have
|
||||
* a geometry set (which might differ from their sizeHint()). The QGraphicsItem
|
||||
* should return that in its size hint, else such cases won't work */
|
||||
|
||||
class DesignerZoomProxyWidget : public ZoomProxyWidget {
|
||||
Q_DISABLE_COPY(DesignerZoomProxyWidget)
|
||||
public:
|
||||
DesignerZoomProxyWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
|
||||
protected:
|
||||
virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const;
|
||||
};
|
||||
|
||||
DesignerZoomProxyWidget::DesignerZoomProxyWidget(QGraphicsItem *parent, Qt::WindowFlags wFlags) :
|
||||
ZoomProxyWidget(parent, wFlags)
|
||||
{
|
||||
}
|
||||
|
||||
QSizeF DesignerZoomProxyWidget::sizeHint(Qt::SizeHint which, const QSizeF & constraint) const
|
||||
{
|
||||
if (const QWidget *w = widget())
|
||||
return QSizeF(w->size());
|
||||
return ZoomProxyWidget::sizeHint(which, constraint);
|
||||
}
|
||||
|
||||
// DesignerZoomWidget which returns DesignerZoomProxyWidget in its factory function
|
||||
class DesignerZoomWidget : public ZoomWidget {
|
||||
Q_DISABLE_COPY(DesignerZoomWidget)
|
||||
public:
|
||||
DesignerZoomWidget(QWidget *parent = 0);
|
||||
private:
|
||||
virtual QGraphicsProxyWidget *createProxyWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0) const;
|
||||
};
|
||||
|
||||
DesignerZoomWidget::DesignerZoomWidget(QWidget *parent) :
|
||||
ZoomWidget(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QGraphicsProxyWidget *DesignerZoomWidget::createProxyWidget(QGraphicsItem *parent, Qt::WindowFlags wFlags) const
|
||||
{
|
||||
return new DesignerZoomProxyWidget(parent, wFlags);
|
||||
}
|
||||
|
||||
// PreviewDeviceSkin: Forwards the key events to the window and
|
||||
// provides context menu with rotation options. Derived class
|
||||
// can apply additional transformations to the skin.
|
||||
|
||||
class PreviewDeviceSkin : public DeviceSkin
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Direction { DirectionUp, DirectionLeft, DirectionRight };
|
||||
|
||||
explicit PreviewDeviceSkin(const DeviceSkinParameters ¶meters, QWidget *parent);
|
||||
virtual void setPreview(QWidget *w);
|
||||
QSize screenSize() const { return m_screenSize; }
|
||||
|
||||
private slots:
|
||||
void slotSkinKeyPressEvent(int code, const QString& text, bool autorep);
|
||||
void slotSkinKeyReleaseEvent(int code, const QString& text, bool autorep);
|
||||
void slotPopupMenu();
|
||||
|
||||
protected:
|
||||
virtual void populateContextMenu(QMenu *) {}
|
||||
|
||||
private slots:
|
||||
void slotDirection(QAction *);
|
||||
|
||||
protected:
|
||||
// Fit the widget in case the orientation changes (transposing screensize)
|
||||
virtual void fitWidget(const QSize &size);
|
||||
// Calculate the complete transformation for the skin
|
||||
// (base class implementation provides rotation).
|
||||
virtual QMatrix skinTransform() const;
|
||||
|
||||
private:
|
||||
const QSize m_screenSize;
|
||||
Direction m_direction;
|
||||
|
||||
QAction *m_directionUpAction;
|
||||
QAction *m_directionLeftAction;
|
||||
QAction *m_directionRightAction;
|
||||
QAction *m_closeAction;
|
||||
};
|
||||
|
||||
PreviewDeviceSkin::PreviewDeviceSkin(const DeviceSkinParameters ¶meters, QWidget *parent) :
|
||||
DeviceSkin(parameters, parent),
|
||||
m_screenSize(parameters.screenSize()),
|
||||
m_direction(DirectionUp),
|
||||
m_directionUpAction(0),
|
||||
m_directionLeftAction(0),
|
||||
m_directionRightAction(0),
|
||||
m_closeAction(0)
|
||||
{
|
||||
connect(this, SIGNAL(skinKeyPressEvent(int,QString,bool)),
|
||||
this, SLOT(slotSkinKeyPressEvent(int,QString,bool)));
|
||||
connect(this, SIGNAL(skinKeyReleaseEvent(int,QString,bool)),
|
||||
this, SLOT(slotSkinKeyReleaseEvent(int,QString,bool)));
|
||||
connect(this, SIGNAL(popupMenu()), this, SLOT(slotPopupMenu()));
|
||||
}
|
||||
|
||||
void PreviewDeviceSkin::setPreview(QWidget *formWidget)
|
||||
{
|
||||
formWidget->setFixedSize(m_screenSize);
|
||||
formWidget->setParent(this, Qt::SubWindow);
|
||||
formWidget->setAutoFillBackground(true);
|
||||
setView(formWidget);
|
||||
}
|
||||
|
||||
void PreviewDeviceSkin::slotSkinKeyPressEvent(int code, const QString& text, bool autorep)
|
||||
{
|
||||
if (QWidget *focusWidget = QApplication::focusWidget()) {
|
||||
QKeyEvent e(QEvent::KeyPress,code,0,text,autorep);
|
||||
QApplication::sendEvent(focusWidget, &e);
|
||||
}
|
||||
}
|
||||
|
||||
void PreviewDeviceSkin::slotSkinKeyReleaseEvent(int code, const QString& text, bool autorep)
|
||||
{
|
||||
if (QWidget *focusWidget = QApplication::focusWidget()) {
|
||||
QKeyEvent e(QEvent::KeyRelease,code,0,text,autorep);
|
||||
QApplication::sendEvent(focusWidget, &e);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a checkable action with integer data and
|
||||
// set it checked if it matches the currentState.
|
||||
static inline QAction
|
||||
*createCheckableActionIntData(const QString &label,
|
||||
int actionValue, int currentState,
|
||||
QActionGroup *ag, QObject *parent)
|
||||
{
|
||||
QAction *a = new QAction(label, parent);
|
||||
a->setData(actionValue);
|
||||
a->setCheckable(true);
|
||||
if (actionValue == currentState)
|
||||
a->setChecked(true);
|
||||
ag->addAction(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
void PreviewDeviceSkin::slotPopupMenu()
|
||||
{
|
||||
QMenu menu(this);
|
||||
// Create actions
|
||||
if (!m_directionUpAction) {
|
||||
QActionGroup *directionGroup = new QActionGroup(this);
|
||||
connect(directionGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotDirection(QAction*)));
|
||||
directionGroup->setExclusive(true);
|
||||
m_directionUpAction = createCheckableActionIntData(tr("&Portrait"), DirectionUp, m_direction, directionGroup, this);
|
||||
//: Rotate form preview counter-clockwise
|
||||
m_directionLeftAction = createCheckableActionIntData(tr("Landscape (&CCW)"), DirectionLeft, m_direction, directionGroup, this);
|
||||
//: Rotate form preview clockwise
|
||||
m_directionRightAction = createCheckableActionIntData(tr("&Landscape (CW)"), DirectionRight, m_direction, directionGroup, this);
|
||||
m_closeAction = new QAction(tr("&Close"), this);
|
||||
connect(m_closeAction, SIGNAL(triggered()), parentWidget(), SLOT(close()));
|
||||
}
|
||||
menu.addAction(m_directionUpAction);
|
||||
menu.addAction(m_directionLeftAction);
|
||||
menu.addAction(m_directionRightAction);
|
||||
menu.addSeparator();
|
||||
populateContextMenu(&menu);
|
||||
menu.addAction(m_closeAction);
|
||||
menu.exec(QCursor::pos());
|
||||
}
|
||||
|
||||
void PreviewDeviceSkin::slotDirection(QAction *a)
|
||||
{
|
||||
const Direction newDirection = static_cast<Direction>(a->data().toInt());
|
||||
if (m_direction == newDirection)
|
||||
return;
|
||||
const Qt::Orientation newOrientation = newDirection == DirectionUp ? Qt::Vertical : Qt::Horizontal;
|
||||
const Qt::Orientation oldOrientation = m_direction == DirectionUp ? Qt::Vertical : Qt::Horizontal;
|
||||
m_direction = newDirection;
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
if (oldOrientation != newOrientation) {
|
||||
QSize size = screenSize();
|
||||
if (newOrientation == Qt::Horizontal)
|
||||
size.transpose();
|
||||
fitWidget(size);
|
||||
}
|
||||
setTransform(skinTransform());
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
|
||||
void PreviewDeviceSkin::fitWidget(const QSize &size)
|
||||
{
|
||||
view()->setFixedSize(size);
|
||||
}
|
||||
|
||||
QMatrix PreviewDeviceSkin::skinTransform() const
|
||||
{
|
||||
QMatrix newTransform;
|
||||
switch (m_direction) {
|
||||
case DirectionUp:
|
||||
break;
|
||||
case DirectionLeft:
|
||||
newTransform.rotate(270.0);
|
||||
break;
|
||||
case DirectionRight:
|
||||
newTransform.rotate(90.0);
|
||||
break;
|
||||
}
|
||||
return newTransform;
|
||||
}
|
||||
|
||||
// ------------ PreviewConfigurationPrivate
|
||||
class PreviewConfigurationData : public QSharedData {
|
||||
public:
|
||||
PreviewConfigurationData() {}
|
||||
explicit PreviewConfigurationData(const QString &style, const QString &applicationStyleSheet, const QString &deviceSkin);
|
||||
|
||||
QString m_style;
|
||||
// Style sheet to prepend (to simulate the effect od QApplication::setSyleSheet()).
|
||||
QString m_applicationStyleSheet;
|
||||
QString m_deviceSkin;
|
||||
};
|
||||
|
||||
PreviewConfigurationData::PreviewConfigurationData(const QString &style, const QString &applicationStyleSheet, const QString &deviceSkin) :
|
||||
m_style(style),
|
||||
m_applicationStyleSheet(applicationStyleSheet),
|
||||
m_deviceSkin(deviceSkin)
|
||||
{
|
||||
}
|
||||
|
||||
/* ZoomablePreviewDeviceSkin: A Zoomable Widget Preview skin. Embeds preview
|
||||
* into a ZoomWidget and this in turn into the DeviceSkin view and keeps
|
||||
* Device skin zoom + ZoomWidget zoom in sync. */
|
||||
|
||||
class ZoomablePreviewDeviceSkin : public PreviewDeviceSkin
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ZoomablePreviewDeviceSkin(const DeviceSkinParameters ¶meters, QWidget *parent);
|
||||
virtual void setPreview(QWidget *w);
|
||||
|
||||
int zoomPercent() const; // Device Skins have a double 'zoom' property
|
||||
|
||||
public slots:
|
||||
void setZoomPercent(int);
|
||||
|
||||
signals:
|
||||
void zoomPercentChanged(int);
|
||||
|
||||
protected:
|
||||
virtual void populateContextMenu(QMenu *m);
|
||||
virtual QMatrix skinTransform() const;
|
||||
virtual void fitWidget(const QSize &size);
|
||||
|
||||
private:
|
||||
ZoomMenu *m_zoomMenu;
|
||||
QAction *m_zoomSubMenuAction;
|
||||
ZoomWidget *m_zoomWidget;
|
||||
};
|
||||
|
||||
ZoomablePreviewDeviceSkin::ZoomablePreviewDeviceSkin(const DeviceSkinParameters ¶meters, QWidget *parent) :
|
||||
PreviewDeviceSkin(parameters, parent),
|
||||
m_zoomMenu(new ZoomMenu(this)),
|
||||
m_zoomSubMenuAction(0),
|
||||
m_zoomWidget(new DesignerZoomWidget)
|
||||
{
|
||||
connect(m_zoomMenu, SIGNAL(zoomChanged(int)), this, SLOT(setZoomPercent(int)));
|
||||
connect(m_zoomMenu, SIGNAL(zoomChanged(int)), this, SIGNAL(zoomPercentChanged(int)));
|
||||
m_zoomWidget->setZoomContextMenuEnabled(false);
|
||||
m_zoomWidget->setWidgetZoomContextMenuEnabled(false);
|
||||
m_zoomWidget->resize(screenSize());
|
||||
m_zoomWidget->setParent(this, Qt::SubWindow);
|
||||
m_zoomWidget->setAutoFillBackground(true);
|
||||
setView(m_zoomWidget);
|
||||
}
|
||||
|
||||
static inline qreal zoomFactor(int percent)
|
||||
{
|
||||
return qreal(percent) / 100.0;
|
||||
}
|
||||
|
||||
static inline QSize scaleSize(int zoomPercent, const QSize &size)
|
||||
{
|
||||
return zoomPercent == 100 ? size : (QSizeF(size) * zoomFactor(zoomPercent)).toSize();
|
||||
}
|
||||
|
||||
void ZoomablePreviewDeviceSkin::setPreview(QWidget *formWidget)
|
||||
{
|
||||
m_zoomWidget->setWidget(formWidget);
|
||||
m_zoomWidget->resize(scaleSize(zoomPercent(), screenSize()));
|
||||
}
|
||||
|
||||
int ZoomablePreviewDeviceSkin::zoomPercent() const
|
||||
{
|
||||
return m_zoomWidget->zoom();
|
||||
}
|
||||
|
||||
void ZoomablePreviewDeviceSkin::setZoomPercent(int zp)
|
||||
{
|
||||
if (zp == zoomPercent())
|
||||
return;
|
||||
|
||||
// If not triggered by the menu itself: Update it
|
||||
if (m_zoomMenu->zoom() != zp)
|
||||
m_zoomMenu->setZoom(zp);
|
||||
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
m_zoomWidget->setZoom(zp);
|
||||
setTransform(skinTransform());
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
|
||||
void ZoomablePreviewDeviceSkin::populateContextMenu(QMenu *menu)
|
||||
{
|
||||
if (!m_zoomSubMenuAction) {
|
||||
m_zoomSubMenuAction = new QAction(tr("&Zoom"), this);
|
||||
QMenu *zoomSubMenu = new QMenu;
|
||||
m_zoomSubMenuAction->setMenu(zoomSubMenu);
|
||||
m_zoomMenu->addActions(zoomSubMenu);
|
||||
}
|
||||
menu->addAction(m_zoomSubMenuAction);
|
||||
menu->addSeparator();
|
||||
}
|
||||
|
||||
QMatrix ZoomablePreviewDeviceSkin::skinTransform() const
|
||||
{
|
||||
// Complete transformation consisting of base class rotation and zoom.
|
||||
QMatrix rc = PreviewDeviceSkin::skinTransform();
|
||||
const int zp = zoomPercent();
|
||||
if (zp != 100) {
|
||||
const qreal factor = zoomFactor(zp);
|
||||
rc.scale(factor, factor);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
void ZoomablePreviewDeviceSkin::fitWidget(const QSize &size)
|
||||
{
|
||||
m_zoomWidget->resize(scaleSize(zoomPercent(), size));
|
||||
}
|
||||
|
||||
// ------------- PreviewConfiguration
|
||||
|
||||
static const char *styleKey = "Style";
|
||||
static const char *appStyleSheetKey = "AppStyleSheet";
|
||||
static const char *skinKey = "Skin";
|
||||
|
||||
PreviewConfiguration::PreviewConfiguration() :
|
||||
m_d(new PreviewConfigurationData)
|
||||
{
|
||||
}
|
||||
|
||||
PreviewConfiguration::PreviewConfiguration(const QString &sty, const QString &applicationSheet, const QString &skin) :
|
||||
m_d(new PreviewConfigurationData(sty, applicationSheet, skin))
|
||||
{
|
||||
}
|
||||
|
||||
PreviewConfiguration::PreviewConfiguration(const PreviewConfiguration &o) :
|
||||
m_d(o.m_d)
|
||||
{
|
||||
}
|
||||
|
||||
PreviewConfiguration &PreviewConfiguration::operator=(const PreviewConfiguration &o)
|
||||
{
|
||||
m_d.operator=(o.m_d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
PreviewConfiguration::~PreviewConfiguration()
|
||||
{
|
||||
}
|
||||
|
||||
void PreviewConfiguration::clear()
|
||||
{
|
||||
PreviewConfigurationData &d = *m_d;
|
||||
d.m_style.clear();
|
||||
d.m_applicationStyleSheet.clear();
|
||||
d.m_deviceSkin.clear();
|
||||
}
|
||||
|
||||
QString PreviewConfiguration::style() const
|
||||
{
|
||||
return m_d->m_style;
|
||||
}
|
||||
|
||||
void PreviewConfiguration::setStyle(const QString &s)
|
||||
{
|
||||
m_d->m_style = s;
|
||||
}
|
||||
|
||||
// Style sheet to prepend (to simulate the effect od QApplication::setSyleSheet()).
|
||||
QString PreviewConfiguration::applicationStyleSheet() const
|
||||
{
|
||||
return m_d->m_applicationStyleSheet;
|
||||
}
|
||||
|
||||
void PreviewConfiguration::setApplicationStyleSheet(const QString &as)
|
||||
{
|
||||
m_d->m_applicationStyleSheet = as;
|
||||
}
|
||||
|
||||
QString PreviewConfiguration::deviceSkin() const
|
||||
{
|
||||
return m_d->m_deviceSkin;
|
||||
}
|
||||
|
||||
void PreviewConfiguration::setDeviceSkin(const QString &s)
|
||||
{
|
||||
m_d->m_deviceSkin = s;
|
||||
}
|
||||
|
||||
void PreviewConfiguration::toSettings(const QString &prefix, QDesignerSettingsInterface *settings) const
|
||||
{
|
||||
const PreviewConfigurationData &d = *m_d;
|
||||
settings->beginGroup(prefix);
|
||||
settings->setValue(QLatin1String(styleKey), d.m_style);
|
||||
settings->setValue(QLatin1String(appStyleSheetKey), d.m_applicationStyleSheet);
|
||||
settings->setValue(QLatin1String(skinKey), d.m_deviceSkin);
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
void PreviewConfiguration::fromSettings(const QString &prefix, const QDesignerSettingsInterface *settings)
|
||||
{
|
||||
clear();
|
||||
QString key = prefix;
|
||||
key += QLatin1Char('/');
|
||||
const int prefixSize = key.size();
|
||||
|
||||
PreviewConfigurationData &d = *m_d;
|
||||
|
||||
const QVariant emptyString = QVariant(QString());
|
||||
|
||||
key += QLatin1String(styleKey);
|
||||
d.m_style = settings->value(key, emptyString).toString();
|
||||
|
||||
key.replace(prefixSize, key.size() - prefixSize, QLatin1String(appStyleSheetKey));
|
||||
d.m_applicationStyleSheet = settings->value(key, emptyString).toString();
|
||||
|
||||
key.replace(prefixSize, key.size() - prefixSize, QLatin1String(skinKey));
|
||||
d.m_deviceSkin = settings->value(key, emptyString).toString();
|
||||
}
|
||||
|
||||
|
||||
QDESIGNER_SHARED_EXPORT bool operator<(const PreviewConfiguration &pc1, const PreviewConfiguration &pc2)
|
||||
{
|
||||
return compare(pc1, pc2) < 0;
|
||||
}
|
||||
|
||||
QDESIGNER_SHARED_EXPORT bool operator==(const PreviewConfiguration &pc1, const PreviewConfiguration &pc2)
|
||||
{
|
||||
return compare(pc1, pc2) == 0;
|
||||
}
|
||||
|
||||
QDESIGNER_SHARED_EXPORT bool operator!=(const PreviewConfiguration &pc1, const PreviewConfiguration &pc2)
|
||||
{
|
||||
return compare(pc1, pc2) != 0;
|
||||
}
|
||||
|
||||
// ------------- PreviewManagerPrivate
|
||||
class PreviewManagerPrivate {
|
||||
public:
|
||||
PreviewManagerPrivate(PreviewManager::PreviewMode mode);
|
||||
|
||||
const PreviewManager::PreviewMode m_mode;
|
||||
|
||||
QPointer<QWidget> m_activePreview;
|
||||
|
||||
typedef QList<PreviewData> PreviewDataList;
|
||||
|
||||
PreviewDataList m_previews;
|
||||
|
||||
typedef QMap<QString, DeviceSkinParameters> DeviceSkinConfigCache;
|
||||
DeviceSkinConfigCache m_deviceSkinConfigCache;
|
||||
|
||||
QDesignerFormEditorInterface *m_core;
|
||||
bool m_updateBlocked;
|
||||
};
|
||||
|
||||
PreviewManagerPrivate::PreviewManagerPrivate(PreviewManager::PreviewMode mode) :
|
||||
m_mode(mode),
|
||||
m_core(0),
|
||||
m_updateBlocked(false)
|
||||
{
|
||||
}
|
||||
|
||||
// ------------- PreviewManager
|
||||
|
||||
PreviewManager::PreviewManager(PreviewMode mode, QObject *parent) :
|
||||
QObject(parent),
|
||||
d(new PreviewManagerPrivate(mode))
|
||||
{
|
||||
}
|
||||
|
||||
PreviewManager:: ~PreviewManager()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
|
||||
Qt::WindowFlags PreviewManager::previewWindowFlags(const QWidget *widget) const
|
||||
{
|
||||
#ifdef Q_WS_WIN
|
||||
Qt::WindowFlags windowFlags = (widget->windowType() == Qt::Window) ? Qt::Window | Qt::WindowMaximizeButtonHint : Qt::WindowFlags(Qt::Dialog);
|
||||
#else
|
||||
Q_UNUSED(widget)
|
||||
// Only Dialogs have close buttons on Mac.
|
||||
// On Linux, we don't want an additional task bar item and we don't want a minimize button;
|
||||
// we want the preview to be on top.
|
||||
Qt::WindowFlags windowFlags = Qt::Dialog;
|
||||
#endif
|
||||
return windowFlags;
|
||||
}
|
||||
|
||||
QWidget *PreviewManager::createDeviceSkinContainer(const QDesignerFormWindowInterface *fw) const
|
||||
{
|
||||
return new QDialog(fw->window());
|
||||
}
|
||||
|
||||
// Some widgets might require fake containers
|
||||
|
||||
static QWidget *fakeContainer(QWidget *w)
|
||||
{
|
||||
// Prevent a dock widget from trying to dock to Designer's main window
|
||||
// (which can be found in the parent hierarchy in MDI mode) by
|
||||
// providing a fake mainwindow
|
||||
if (QDockWidget *dock = qobject_cast<QDockWidget *>(w)) {
|
||||
// Reparent: Clear modality, propagate title and resize outer container
|
||||
const QSize size = w->size();
|
||||
w->setWindowModality(Qt::NonModal);
|
||||
dock->setFeatures(dock->features() & ~(QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable|QDockWidget::DockWidgetClosable));
|
||||
dock->setAllowedAreas(Qt::LeftDockWidgetArea);
|
||||
QMainWindow *mw = new QMainWindow;
|
||||
int leftMargin, topMargin, rightMargin, bottomMargin;
|
||||
mw->getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin);
|
||||
mw->addDockWidget(Qt::LeftDockWidgetArea, dock);
|
||||
mw->resize(size + QSize(leftMargin + rightMargin, topMargin + bottomMargin));
|
||||
return mw;
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
static PreviewConfiguration configurationFromSettings(QDesignerFormEditorInterface *core, const QString &style)
|
||||
{
|
||||
qdesigner_internal::PreviewConfiguration pc;
|
||||
const QDesignerSharedSettings settings(core);
|
||||
if (settings.isCustomPreviewConfigurationEnabled())
|
||||
pc = settings.customPreviewConfiguration();
|
||||
if (!style.isEmpty())
|
||||
pc.setStyle(style);
|
||||
return pc;
|
||||
}
|
||||
|
||||
QWidget *PreviewManager::showPreview(const QDesignerFormWindowInterface *fw, const QString &style, int deviceProfileIndex, QString *errorMessage)
|
||||
{
|
||||
return showPreview(fw, configurationFromSettings(fw->core(), style), deviceProfileIndex, errorMessage);
|
||||
}
|
||||
|
||||
QWidget *PreviewManager::showPreview(const QDesignerFormWindowInterface *fw, const QString &style, QString *errorMessage)
|
||||
{
|
||||
return showPreview(fw, style, -1, errorMessage);
|
||||
}
|
||||
|
||||
QWidget *PreviewManager::createPreview(const QDesignerFormWindowInterface *fw,
|
||||
const PreviewConfiguration &pc,
|
||||
int deviceProfileIndex,
|
||||
QString *errorMessage,
|
||||
int initialZoom)
|
||||
{
|
||||
if (!d->m_core)
|
||||
d->m_core = fw->core();
|
||||
|
||||
const bool zoomable = initialZoom > 0;
|
||||
// Figure out which profile to apply
|
||||
DeviceProfile deviceProfile;
|
||||
if (deviceProfileIndex >= 0) {
|
||||
deviceProfile = QDesignerSharedSettings(fw->core()).deviceProfileAt(deviceProfileIndex);
|
||||
} else {
|
||||
if (const FormWindowBase *fwb = qobject_cast<const FormWindowBase *>(fw))
|
||||
deviceProfile = fwb->deviceProfile();
|
||||
}
|
||||
// Create
|
||||
QWidget *formWidget = QDesignerFormBuilder::createPreview(fw, pc.style(), pc.applicationStyleSheet(), deviceProfile, errorMessage);
|
||||
if (!formWidget)
|
||||
return 0;
|
||||
|
||||
const QString title = tr("%1 - [Preview]").arg(formWidget->windowTitle());
|
||||
formWidget = fakeContainer(formWidget);
|
||||
formWidget->setWindowTitle(title);
|
||||
|
||||
// Clear any modality settings, child widget modalities must not be higher than parent's
|
||||
formWidget->setWindowModality(Qt::NonModal);
|
||||
// No skin
|
||||
const QString deviceSkin = pc.deviceSkin();
|
||||
if (deviceSkin.isEmpty()) {
|
||||
if (zoomable) { // Embed into ZoomWidget
|
||||
ZoomWidget *zw = new DesignerZoomWidget;
|
||||
connect(zw->zoomMenu(), SIGNAL(zoomChanged(int)), this, SLOT(slotZoomChanged(int)));
|
||||
zw->setWindowTitle(title);
|
||||
zw->setWidget(formWidget);
|
||||
// Keep any widgets' context menus working, do not use global menu
|
||||
zw->setWidgetZoomContextMenuEnabled(true);
|
||||
zw->setParent(fw->window(), previewWindowFlags(formWidget));
|
||||
// Make preview close when Widget closes (Dialog/accept, etc)
|
||||
formWidget->setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
connect(formWidget, SIGNAL(destroyed()), zw, SLOT(close()));
|
||||
zw->setZoom(initialZoom);
|
||||
zw->setProperty(WidgetFactory::disableStyleCustomPaintingPropertyC, QVariant(true));
|
||||
return zw;
|
||||
}
|
||||
formWidget->setParent(fw->window(), previewWindowFlags(formWidget));
|
||||
formWidget->setProperty(WidgetFactory::disableStyleCustomPaintingPropertyC, QVariant(true));
|
||||
return formWidget;
|
||||
}
|
||||
// Embed into skin. find config in cache
|
||||
PreviewManagerPrivate::DeviceSkinConfigCache::iterator it = d->m_deviceSkinConfigCache.find(deviceSkin);
|
||||
if (it == d->m_deviceSkinConfigCache.end()) {
|
||||
DeviceSkinParameters parameters;
|
||||
if (!parameters.read(deviceSkin, DeviceSkinParameters::ReadAll, errorMessage)) {
|
||||
formWidget->deleteLater();
|
||||
return 0;
|
||||
}
|
||||
it = d->m_deviceSkinConfigCache.insert(deviceSkin, parameters);
|
||||
}
|
||||
|
||||
QWidget *skinContainer = createDeviceSkinContainer(fw);
|
||||
PreviewDeviceSkin *skin = 0;
|
||||
if (zoomable) {
|
||||
ZoomablePreviewDeviceSkin *zds = new ZoomablePreviewDeviceSkin(it.value(), skinContainer);
|
||||
zds->setZoomPercent(initialZoom);
|
||||
connect(zds, SIGNAL(zoomPercentChanged(int)), this, SLOT(slotZoomChanged(int)));
|
||||
skin = zds;
|
||||
} else {
|
||||
skin = new PreviewDeviceSkin(it.value(), skinContainer);
|
||||
}
|
||||
skin->setPreview(formWidget);
|
||||
// Make preview close when Widget closes (Dialog/accept, etc)
|
||||
formWidget->setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
connect(formWidget, SIGNAL(destroyed()), skinContainer, SLOT(close()));
|
||||
skinContainer->setWindowTitle(title);
|
||||
skinContainer->setProperty(WidgetFactory::disableStyleCustomPaintingPropertyC, QVariant(true));
|
||||
return skinContainer;
|
||||
}
|
||||
|
||||
QWidget *PreviewManager::showPreview(const QDesignerFormWindowInterface *fw,
|
||||
const PreviewConfiguration &pc,
|
||||
int deviceProfileIndex,
|
||||
QString *errorMessage)
|
||||
{
|
||||
enum { Spacing = 10 };
|
||||
if (QWidget *existingPreviewWidget = raise(fw, pc))
|
||||
return existingPreviewWidget;
|
||||
|
||||
const QDesignerSharedSettings settings(fw->core());
|
||||
const int initialZoom = settings.zoomEnabled() ? settings.zoom() : -1;
|
||||
|
||||
QWidget *widget = createPreview(fw, pc, deviceProfileIndex, errorMessage, initialZoom);
|
||||
if (!widget)
|
||||
return 0;
|
||||
// Install filter for Escape key
|
||||
widget->setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
widget->installEventFilter(this);
|
||||
|
||||
switch (d->m_mode) {
|
||||
case ApplicationModalPreview:
|
||||
// Cannot do this on the Mac as the dialog would have no close button
|
||||
widget->setWindowModality(Qt::ApplicationModal);
|
||||
break;
|
||||
case SingleFormNonModalPreview:
|
||||
case MultipleFormNonModalPreview:
|
||||
widget->setWindowModality(Qt::NonModal);
|
||||
connect(fw, SIGNAL(changed()), widget, SLOT(close()));
|
||||
connect(fw, SIGNAL(destroyed()), widget, SLOT(close()));
|
||||
if (d->m_mode == SingleFormNonModalPreview)
|
||||
connect(fw->core()->formWindowManager(), SIGNAL(activeFormWindowChanged(QDesignerFormWindowInterface*)), widget, SLOT(close()));
|
||||
break;
|
||||
}
|
||||
// Semi-smart algorithm to position previews:
|
||||
// If its the first one, position relative to form.
|
||||
// 2nd, attempt to tile right (for comparing styles) or cascade
|
||||
const QSize size = widget->size();
|
||||
const bool firstPreview = d->m_previews.empty();
|
||||
if (firstPreview) {
|
||||
widget->move(fw->mapToGlobal(QPoint(Spacing, Spacing)));
|
||||
} else {
|
||||
if (QWidget *lastPreview = d->m_previews.back().m_widget) {
|
||||
QDesktopWidget *desktop = qApp->desktop();
|
||||
const QRect lastPreviewGeometry = lastPreview->frameGeometry();
|
||||
const QRect availGeometry = desktop->availableGeometry(desktop->screenNumber(lastPreview));
|
||||
const QPoint newPos = lastPreviewGeometry.topRight() + QPoint(Spacing, 0);
|
||||
if (newPos.x() + size.width() < availGeometry.right())
|
||||
widget->move(newPos);
|
||||
else
|
||||
widget->move(lastPreviewGeometry.topLeft() + QPoint(Spacing, Spacing));
|
||||
}
|
||||
|
||||
}
|
||||
d->m_previews.push_back(PreviewData(widget, fw, pc));
|
||||
widget->show();
|
||||
if (firstPreview)
|
||||
emit firstPreviewOpened();
|
||||
return widget;
|
||||
}
|
||||
|
||||
QWidget *PreviewManager::raise(const QDesignerFormWindowInterface *fw, const PreviewConfiguration &pc)
|
||||
{
|
||||
typedef PreviewManagerPrivate::PreviewDataList PreviewDataList;
|
||||
if (d->m_previews.empty())
|
||||
return false;
|
||||
|
||||
// find matching window
|
||||
const PreviewDataList::const_iterator cend = d->m_previews.constEnd();
|
||||
for (PreviewDataList::const_iterator it = d->m_previews.constBegin(); it != cend ;++it) {
|
||||
QWidget * w = it->m_widget;
|
||||
if (w && it->m_formWindow == fw && it->m_configuration == pc) {
|
||||
w->raise();
|
||||
w->activateWindow();
|
||||
return w;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PreviewManager::closeAllPreviews()
|
||||
{
|
||||
typedef PreviewManagerPrivate::PreviewDataList PreviewDataList;
|
||||
if (!d->m_previews.empty()) {
|
||||
d->m_updateBlocked = true;
|
||||
d->m_activePreview = 0;
|
||||
const PreviewDataList::iterator cend = d->m_previews.end();
|
||||
for (PreviewDataList::iterator it = d->m_previews.begin(); it != cend ;++it) {
|
||||
if (it->m_widget)
|
||||
it->m_widget->close();
|
||||
}
|
||||
d->m_previews.clear();
|
||||
d->m_updateBlocked = false;
|
||||
emit lastPreviewClosed();
|
||||
}
|
||||
}
|
||||
|
||||
void PreviewManager::updatePreviewClosed(QWidget *w)
|
||||
{
|
||||
typedef PreviewManagerPrivate::PreviewDataList PreviewDataList;
|
||||
if (d->m_updateBlocked)
|
||||
return;
|
||||
// Purge out all 0 or widgets to be deleted
|
||||
for (PreviewDataList::iterator it = d->m_previews.begin(); it != d->m_previews.end() ; ) {
|
||||
QWidget *iw = it->m_widget; // Might be 0 when catching QEvent::Destroyed
|
||||
if (iw == 0 || iw == w) {
|
||||
it = d->m_previews.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
if (d->m_previews.empty())
|
||||
emit lastPreviewClosed();
|
||||
}
|
||||
|
||||
bool PreviewManager::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
// Courtesy of designer
|
||||
do {
|
||||
if (!watched->isWidgetType())
|
||||
break;
|
||||
QWidget *previewWindow = qobject_cast<QWidget *>(watched);
|
||||
if (!previewWindow || !previewWindow->isWindow())
|
||||
break;
|
||||
|
||||
switch (event->type()) {
|
||||
case QEvent::KeyPress:
|
||||
case QEvent::ShortcutOverride: {
|
||||
const QKeyEvent *keyEvent = static_cast<const QKeyEvent *>(event);
|
||||
const int key = keyEvent->key();
|
||||
if ((key == Qt::Key_Escape
|
||||
#ifdef Q_WS_MAC
|
||||
|| (keyEvent->modifiers() == Qt::ControlModifier && key == Qt::Key_Period)
|
||||
#endif
|
||||
)) {
|
||||
previewWindow->close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QEvent::WindowActivate:
|
||||
d->m_activePreview = previewWindow;
|
||||
break;
|
||||
case QEvent::Destroy: // We don't get QEvent::Close if someone accepts a QDialog.
|
||||
updatePreviewClosed(previewWindow);
|
||||
break;
|
||||
case QEvent::Close:
|
||||
updatePreviewClosed(previewWindow);
|
||||
previewWindow->removeEventFilter (this);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} while(false);
|
||||
return QObject::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
int PreviewManager::previewCount() const
|
||||
{
|
||||
return d->m_previews.size();
|
||||
}
|
||||
|
||||
QPixmap PreviewManager::createPreviewPixmap(const QDesignerFormWindowInterface *fw, const QString &style, int deviceProfileIndex, QString *errorMessage)
|
||||
{
|
||||
return createPreviewPixmap(fw, configurationFromSettings(fw->core(), style), deviceProfileIndex, errorMessage);
|
||||
}
|
||||
|
||||
QPixmap PreviewManager::createPreviewPixmap(const QDesignerFormWindowInterface *fw, const QString &style, QString *errorMessage)
|
||||
{
|
||||
return createPreviewPixmap(fw, style, -1, errorMessage);
|
||||
}
|
||||
|
||||
QPixmap PreviewManager::createPreviewPixmap(const QDesignerFormWindowInterface *fw,
|
||||
const PreviewConfiguration &pc,
|
||||
int deviceProfileIndex,
|
||||
QString *errorMessage)
|
||||
{
|
||||
QWidget *widget = createPreview(fw, pc, deviceProfileIndex, errorMessage);
|
||||
if (!widget)
|
||||
return QPixmap();
|
||||
const QPixmap rc = QPixmap::grabWidget(widget);
|
||||
widget->deleteLater();
|
||||
return rc;
|
||||
}
|
||||
|
||||
void PreviewManager::slotZoomChanged(int z)
|
||||
{
|
||||
if (d->m_core) { // Save the last zoom chosen by the user.
|
||||
QDesignerSharedSettings settings(d->m_core);
|
||||
settings.setZoom(z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#include "previewmanager.moc"
|
||||
184
third/designer/lib/shared/previewmanager_p.h
Normal file
184
third/designer/lib/shared/previewmanager_p.h
Normal file
@@ -0,0 +1,184 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef PREVIEWMANAGER_H
|
||||
#define PREVIEWMANAGER_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QSharedDataPointer>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDesignerFormWindowInterface;
|
||||
class QWidget;
|
||||
class QPixmap;
|
||||
class QAction;
|
||||
class QActionGroup;
|
||||
class QMenu;
|
||||
class QWidget;
|
||||
class QDesignerSettingsInterface;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
// ----------- PreviewConfiguration
|
||||
|
||||
class PreviewConfigurationData;
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT PreviewConfiguration {
|
||||
public:
|
||||
PreviewConfiguration();
|
||||
explicit PreviewConfiguration(const QString &style,
|
||||
const QString &applicationStyleSheet = QString(),
|
||||
const QString &deviceSkin = QString());
|
||||
|
||||
PreviewConfiguration(const PreviewConfiguration&);
|
||||
PreviewConfiguration& operator=(const PreviewConfiguration&);
|
||||
~PreviewConfiguration();
|
||||
|
||||
QString style() const;
|
||||
void setStyle(const QString &);
|
||||
|
||||
// Style sheet to prepend (to simulate the effect od QApplication::setSyleSheet()).
|
||||
QString applicationStyleSheet() const;
|
||||
void setApplicationStyleSheet(const QString &);
|
||||
|
||||
QString deviceSkin() const;
|
||||
void setDeviceSkin(const QString &);
|
||||
|
||||
void clear();
|
||||
void toSettings(const QString &prefix, QDesignerSettingsInterface *settings) const;
|
||||
void fromSettings(const QString &prefix, const QDesignerSettingsInterface *settings);
|
||||
|
||||
private:
|
||||
QSharedDataPointer<PreviewConfigurationData> m_d;
|
||||
};
|
||||
|
||||
QDESIGNER_SHARED_EXPORT bool operator<(const PreviewConfiguration &pc1, const PreviewConfiguration &pc2);
|
||||
QDESIGNER_SHARED_EXPORT bool operator==(const PreviewConfiguration &pc1, const PreviewConfiguration &pc2);
|
||||
QDESIGNER_SHARED_EXPORT bool operator!=(const PreviewConfiguration &pc1, const PreviewConfiguration &pc2);
|
||||
|
||||
// ----------- Preview window manager.
|
||||
// Maintains a list of preview widgets with their associated form windows and configuration.
|
||||
|
||||
class PreviewManagerPrivate;
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT PreviewManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
enum PreviewMode {
|
||||
// Modal preview. Do not use on Macs as dialogs would have no close button
|
||||
ApplicationModalPreview,
|
||||
// Non modal previewing of one form in different configurations (closes if form window changes)
|
||||
SingleFormNonModalPreview,
|
||||
// Non modal previewing of several forms in different configurations
|
||||
MultipleFormNonModalPreview };
|
||||
|
||||
explicit PreviewManager(PreviewMode mode, QObject *parent);
|
||||
virtual ~PreviewManager();
|
||||
|
||||
// Show preview. Raise existing preview window if there is one with a matching
|
||||
// configuration, else create a new preview.
|
||||
QWidget *showPreview(const QDesignerFormWindowInterface *, const PreviewConfiguration &pc, int deviceProfileIndex /*=-1*/, QString *errorMessage);
|
||||
// Convenience that creates a preview using a configuration taken from the settings.
|
||||
QWidget *showPreview(const QDesignerFormWindowInterface *, const QString &style, int deviceProfileIndex /*=-1*/, QString *errorMessage);
|
||||
QWidget *showPreview(const QDesignerFormWindowInterface *, const QString &style, QString *errorMessage);
|
||||
|
||||
int previewCount() const;
|
||||
|
||||
// Create a pixmap for printing.
|
||||
QPixmap createPreviewPixmap(const QDesignerFormWindowInterface *fw, const PreviewConfiguration &pc, int deviceProfileIndex /*=-1*/, QString *errorMessage);
|
||||
// Convenience that creates a pixmap using a configuration taken from the settings.
|
||||
QPixmap createPreviewPixmap(const QDesignerFormWindowInterface *fw, const QString &style, int deviceProfileIndex /*=-1*/, QString *errorMessage);
|
||||
QPixmap createPreviewPixmap(const QDesignerFormWindowInterface *fw, const QString &style, QString *errorMessage);
|
||||
|
||||
virtual bool eventFilter(QObject *watched, QEvent *event);
|
||||
|
||||
public slots:
|
||||
void closeAllPreviews();
|
||||
|
||||
signals:
|
||||
void firstPreviewOpened();
|
||||
void lastPreviewClosed();
|
||||
|
||||
private slots:
|
||||
void slotZoomChanged(int);
|
||||
|
||||
private:
|
||||
|
||||
virtual Qt::WindowFlags previewWindowFlags(const QWidget *widget) const;
|
||||
virtual QWidget *createDeviceSkinContainer(const QDesignerFormWindowInterface *) const;
|
||||
|
||||
QWidget *raise(const QDesignerFormWindowInterface *, const PreviewConfiguration &pc);
|
||||
QWidget *createPreview(const QDesignerFormWindowInterface *,
|
||||
const PreviewConfiguration &pc,
|
||||
int deviceProfileIndex /* = -1 */,
|
||||
QString *errorMessage,
|
||||
/*Disabled by default, <0 */
|
||||
int initialZoom = -1);
|
||||
|
||||
void updatePreviewClosed(QWidget *w);
|
||||
|
||||
PreviewManagerPrivate *d;
|
||||
|
||||
PreviewManager(const PreviewManager &other);
|
||||
PreviewManager &operator =(const PreviewManager &other);
|
||||
};
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // PREVIEWMANAGER_H
|
||||
220
third/designer/lib/shared/promotionmodel.cpp
Normal file
220
third/designer/lib/shared/promotionmodel.cpp
Normal file
@@ -0,0 +1,220 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "promotionmodel_p.h"
|
||||
#include "widgetdatabase_p.h"
|
||||
|
||||
#include <QtDesigner/QDesignerWidgetDataBaseInterface>
|
||||
#include <QtDesigner/QDesignerPromotionInterface>
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
|
||||
#include <QtGui/QStandardItem>
|
||||
#include <QtCore/QCoreApplication>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace {
|
||||
typedef QList<QStandardItem *> StandardItemList;
|
||||
|
||||
// Model columns.
|
||||
enum { ClassNameColumn, IncludeFileColumn, IncludeTypeColumn, ReferencedColumn, NumColumns };
|
||||
|
||||
// Create a model row.
|
||||
StandardItemList modelRow() {
|
||||
StandardItemList rc;
|
||||
for (int i = 0; i < NumColumns; i++) {
|
||||
rc.push_back(new QStandardItem());
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Create a model row for a base class (read-only, cannot be selected).
|
||||
StandardItemList baseModelRow(const QDesignerWidgetDataBaseItemInterface *dbItem) {
|
||||
StandardItemList rc = modelRow();
|
||||
|
||||
rc[ClassNameColumn]->setText(dbItem->name());
|
||||
for (int i = 0; i < NumColumns; i++) {
|
||||
rc[i]->setFlags(Qt::ItemIsEnabled);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Create an editable model row for a promoted class.
|
||||
StandardItemList promotedModelRow(const QDesignerWidgetDataBaseInterface *widgetDataBase,
|
||||
QDesignerWidgetDataBaseItemInterface *dbItem,
|
||||
bool referenced = false) {
|
||||
|
||||
const int index = widgetDataBase->indexOf(dbItem);
|
||||
|
||||
// Associate user data: database index and enabled flag
|
||||
QVariantList userDataList;
|
||||
userDataList.push_back(QVariant(index));
|
||||
userDataList.push_back(QVariant(referenced));
|
||||
const QVariant userData(userDataList);
|
||||
|
||||
StandardItemList rc = modelRow();
|
||||
// name
|
||||
rc[ClassNameColumn]->setText(dbItem->name());
|
||||
rc[ClassNameColumn]->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled|Qt::ItemIsEditable);
|
||||
rc[ClassNameColumn]->setData(userData);
|
||||
// header
|
||||
const qdesigner_internal::IncludeSpecification spec = qdesigner_internal::includeSpecification(dbItem->includeFile());
|
||||
rc[IncludeFileColumn]->setText(spec.first);
|
||||
rc[IncludeFileColumn]->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled|Qt::ItemIsEditable);
|
||||
rc[IncludeFileColumn]->setData(userData);
|
||||
// global include
|
||||
rc[IncludeTypeColumn]->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled|Qt::ItemIsEditable|Qt::ItemIsUserCheckable);
|
||||
rc[IncludeTypeColumn]->setData(userData);
|
||||
rc[IncludeTypeColumn]->setCheckState(spec.second == qdesigner_internal::IncludeGlobal ? Qt::Checked : Qt::Unchecked);
|
||||
// referenced
|
||||
rc[ReferencedColumn]->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
|
||||
rc[ClassNameColumn]->setData(userData);
|
||||
if (!referenced) {
|
||||
//: Usage of promoted widgets
|
||||
static const QString notUsed = QCoreApplication::translate("PromotionModel", "Not used");
|
||||
rc[ReferencedColumn]->setText(notUsed);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
PromotionModel::PromotionModel(QDesignerFormEditorInterface *core) :
|
||||
m_core(core)
|
||||
{
|
||||
connect(this, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(slotItemChanged(QStandardItem*)));
|
||||
}
|
||||
|
||||
void PromotionModel::initializeHeaders() {
|
||||
setColumnCount(NumColumns);
|
||||
QStringList horizontalLabels(tr("Name"));
|
||||
horizontalLabels += tr("Header file");
|
||||
horizontalLabels += tr("Global include");
|
||||
horizontalLabels += tr("Usage");
|
||||
setHorizontalHeaderLabels (horizontalLabels);
|
||||
}
|
||||
|
||||
void PromotionModel::updateFromWidgetDatabase() {
|
||||
typedef QDesignerPromotionInterface::PromotedClasses PromotedClasses;
|
||||
|
||||
clear();
|
||||
initializeHeaders();
|
||||
|
||||
// retrieve list of pairs from DB and convert into a tree structure.
|
||||
// Set the item index as user data on the item.
|
||||
const PromotedClasses promotedClasses = m_core->promotion()->promotedClasses();
|
||||
|
||||
if (promotedClasses.empty())
|
||||
return;
|
||||
|
||||
const QSet<QString> usedPromotedClasses = m_core->promotion()->referencedPromotedClassNames();
|
||||
|
||||
QDesignerWidgetDataBaseInterface *widgetDataBase = m_core->widgetDataBase();
|
||||
QDesignerWidgetDataBaseItemInterface *baseClass = 0;
|
||||
QStandardItem *baseItem = 0;
|
||||
|
||||
const PromotedClasses::const_iterator bcend = promotedClasses.constEnd();
|
||||
for (PromotedClasses::const_iterator it = promotedClasses.constBegin(); it != bcend; ++it) {
|
||||
// Start a new base class?
|
||||
if (baseClass != it->baseItem) {
|
||||
baseClass = it->baseItem;
|
||||
const StandardItemList baseRow = baseModelRow(it->baseItem);
|
||||
baseItem = baseRow.front();
|
||||
appendRow(baseRow);
|
||||
}
|
||||
Q_ASSERT(baseItem);
|
||||
// Append derived
|
||||
baseItem->appendRow(promotedModelRow(widgetDataBase, it->promotedItem, usedPromotedClasses.contains(it->promotedItem->name())));
|
||||
}
|
||||
}
|
||||
|
||||
void PromotionModel::slotItemChanged(QStandardItem * changedItem) {
|
||||
// Retrieve DB item
|
||||
bool referenced;
|
||||
QDesignerWidgetDataBaseItemInterface *dbItem = databaseItem(changedItem, &referenced);
|
||||
Q_ASSERT(dbItem);
|
||||
// Change header or type
|
||||
switch (changedItem->column()) {
|
||||
case ClassNameColumn:
|
||||
emit classNameChanged(dbItem, changedItem->text());
|
||||
break;
|
||||
case IncludeTypeColumn:
|
||||
case IncludeFileColumn: {
|
||||
// Get both file and type items via parent.
|
||||
const QStandardItem *baseClassItem = changedItem->parent();
|
||||
const QStandardItem *fileItem = baseClassItem->child(changedItem->row(), IncludeFileColumn);
|
||||
const QStandardItem *typeItem = baseClassItem->child(changedItem->row(), IncludeTypeColumn);
|
||||
emit includeFileChanged(dbItem, buildIncludeFile(fileItem->text(), typeItem->checkState() == Qt::Checked ? IncludeGlobal : IncludeLocal));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QDesignerWidgetDataBaseItemInterface *PromotionModel::databaseItemAt(const QModelIndex &index, bool *referenced) const {
|
||||
if (const QStandardItem *item = itemFromIndex (index))
|
||||
return databaseItem(item, referenced);
|
||||
|
||||
*referenced = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
QDesignerWidgetDataBaseItemInterface *PromotionModel::databaseItem(const QStandardItem * item, bool *referenced) const {
|
||||
// Decode user data associated with item.
|
||||
const QVariant data = item->data();
|
||||
if (data.type() != QVariant::List) {
|
||||
*referenced = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const QVariantList dataList = data.toList();
|
||||
const int index = dataList[0].toInt();
|
||||
*referenced = dataList[1].toBool();
|
||||
return m_core->widgetDataBase()->item(index);
|
||||
}
|
||||
|
||||
QModelIndex PromotionModel::indexOfClass(const QString &className) const {
|
||||
const StandardItemList matches = findItems (className, Qt::MatchFixedString|Qt::MatchCaseSensitive|Qt::MatchRecursive);
|
||||
return matches.empty() ? QModelIndex() : indexFromItem (matches.front());
|
||||
}
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
98
third/designer/lib/shared/promotionmodel_p.h
Normal file
98
third/designer/lib/shared/promotionmodel_p.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef PROMOTIONMODEL_H
|
||||
#define PROMOTIONMODEL_H
|
||||
|
||||
#include <QtGui/QStandardItemModel>
|
||||
#include <QtCore/QSet>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDesignerFormEditorInterface;
|
||||
class QDesignerWidgetDataBaseItemInterface;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
// Item model representing the promoted widgets.
|
||||
class PromotionModel : public QStandardItemModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PromotionModel(QDesignerFormEditorInterface *core);
|
||||
|
||||
void updateFromWidgetDatabase();
|
||||
|
||||
// Return item at model index or 0.
|
||||
QDesignerWidgetDataBaseItemInterface *databaseItemAt(const QModelIndex &, bool *referenced) const;
|
||||
|
||||
QModelIndex indexOfClass(const QString &className) const;
|
||||
|
||||
signals:
|
||||
void includeFileChanged(QDesignerWidgetDataBaseItemInterface *, const QString &includeFile);
|
||||
void classNameChanged(QDesignerWidgetDataBaseItemInterface *, const QString &newName);
|
||||
|
||||
private slots:
|
||||
void slotItemChanged(QStandardItem * item);
|
||||
|
||||
private:
|
||||
void initializeHeaders();
|
||||
// Retrieve data base item of item or return 0.
|
||||
QDesignerWidgetDataBaseItemInterface *databaseItem(const QStandardItem * item, bool *referenced) const;
|
||||
|
||||
QDesignerFormEditorInterface *m_core;
|
||||
};
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // PROMOTIONMODEL_H
|
||||
361
third/designer/lib/shared/promotiontaskmenu.cpp
Normal file
361
third/designer/lib/shared/promotiontaskmenu.cpp
Normal file
@@ -0,0 +1,361 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "promotiontaskmenu_p.h"
|
||||
#include "qdesigner_promotiondialog_p.h"
|
||||
#include "widgetfactory_p.h"
|
||||
#include "metadatabase_p.h"
|
||||
#include "widgetdatabase_p.h"
|
||||
#include "qdesigner_command_p.h"
|
||||
#include "signalslotdialog_p.h"
|
||||
#include "qdesigner_objectinspector_p.h"
|
||||
#include "abstractintrospection_p.h"
|
||||
|
||||
#include <QtDesigner/QDesignerFormWindowInterface>
|
||||
#include <QtDesigner/QDesignerFormWindowCursorInterface>
|
||||
#include <QtDesigner/QDesignerLanguageExtension>
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
#include <QtDesigner/QExtensionManager>
|
||||
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtCore/QSignalMapper>
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static QAction *separatorAction(QObject *parent)
|
||||
{
|
||||
QAction *rc = new QAction(parent);
|
||||
rc->setSeparator(true);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline QDesignerLanguageExtension *languageExtension(QDesignerFormEditorInterface *core)
|
||||
{
|
||||
return qt_extension<QDesignerLanguageExtension*>(core->extensionManager(), core);
|
||||
}
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
PromotionTaskMenu::PromotionTaskMenu(QWidget *widget,Mode mode, QObject *parent) :
|
||||
QObject(parent),
|
||||
m_mode(mode),
|
||||
m_widget(widget),
|
||||
m_promotionMapper(0),
|
||||
m_globalEditAction(new QAction(tr("Promoted widgets..."), this)),
|
||||
m_EditPromoteToAction(new QAction(tr("Promote to ..."), this)),
|
||||
m_EditSignalsSlotsAction(new QAction(tr("Change signals/slots..."), this)),
|
||||
m_promoteLabel(tr("Promote to")),
|
||||
m_demoteLabel(tr("Demote to %1"))
|
||||
{
|
||||
connect(m_globalEditAction, SIGNAL(triggered()), this, SLOT(slotEditPromotedWidgets()));
|
||||
connect(m_EditPromoteToAction, SIGNAL(triggered()), this, SLOT(slotEditPromoteTo()));
|
||||
connect(m_EditSignalsSlotsAction, SIGNAL(triggered()), this, SLOT(slotEditSignalsSlots()));
|
||||
}
|
||||
|
||||
PromotionTaskMenu::Mode PromotionTaskMenu::mode() const
|
||||
{
|
||||
return m_mode;
|
||||
}
|
||||
|
||||
void PromotionTaskMenu::setMode(Mode m)
|
||||
{
|
||||
m_mode = m;
|
||||
}
|
||||
|
||||
void PromotionTaskMenu::setWidget(QWidget *widget)
|
||||
{
|
||||
m_widget = widget;
|
||||
}
|
||||
|
||||
void PromotionTaskMenu::setPromoteLabel(const QString &promoteLabel)
|
||||
{
|
||||
m_promoteLabel = promoteLabel;
|
||||
}
|
||||
|
||||
void PromotionTaskMenu::setEditPromoteToLabel(const QString &promoteEditLabel)
|
||||
{
|
||||
m_EditPromoteToAction->setText(promoteEditLabel);
|
||||
}
|
||||
|
||||
void PromotionTaskMenu::setDemoteLabel(const QString &demoteLabel)
|
||||
{
|
||||
m_demoteLabel = demoteLabel;
|
||||
}
|
||||
|
||||
PromotionTaskMenu::PromotionState PromotionTaskMenu::createPromotionActions(QDesignerFormWindowInterface *formWindow)
|
||||
{
|
||||
// clear out old
|
||||
if (!m_promotionActions.empty()) {
|
||||
qDeleteAll(m_promotionActions);
|
||||
m_promotionActions.clear();
|
||||
}
|
||||
// No promotion of main container
|
||||
if (formWindow->mainContainer() == m_widget)
|
||||
return NotApplicable;
|
||||
|
||||
// Check for a homogenous selection
|
||||
const PromotionSelectionList promotionSelection = promotionSelectionList(formWindow);
|
||||
|
||||
if (promotionSelection.empty())
|
||||
return NoHomogenousSelection;
|
||||
|
||||
QDesignerFormEditorInterface *core = formWindow->core();
|
||||
// if it is promoted: demote only.
|
||||
if (isPromoted(formWindow->core(), m_widget)) {
|
||||
const QString label = m_demoteLabel.arg( promotedExtends(core , m_widget));
|
||||
QAction *demoteAction = new QAction(label, this);
|
||||
connect(demoteAction, SIGNAL(triggered()), this, SLOT(slotDemoteFromCustomWidget()));
|
||||
m_promotionActions.push_back(demoteAction);
|
||||
return CanDemote;
|
||||
}
|
||||
// figure out candidates
|
||||
const QString baseClassName = WidgetFactory::classNameOf(core, m_widget);
|
||||
const WidgetDataBaseItemList candidates = promotionCandidates(core->widgetDataBase(), baseClassName );
|
||||
if (candidates.empty()) {
|
||||
// Is this thing promotable at all?
|
||||
return QDesignerPromotionDialog::baseClassNames(core->promotion()).contains(baseClassName) ? CanPromote : NotApplicable;
|
||||
}
|
||||
// Set up a signal mapper to associate class names
|
||||
if (!m_promotionMapper) {
|
||||
m_promotionMapper = new QSignalMapper(this);
|
||||
connect(m_promotionMapper, SIGNAL(mapped(QString)), this, SLOT(slotPromoteToCustomWidget(QString)));
|
||||
}
|
||||
|
||||
QMenu *candidatesMenu = new QMenu();
|
||||
// Create a sub menu
|
||||
const WidgetDataBaseItemList::const_iterator cend = candidates.constEnd();
|
||||
// Set up actions and map class names
|
||||
for (WidgetDataBaseItemList::const_iterator it = candidates.constBegin(); it != cend; ++it) {
|
||||
const QString customClassName = (*it)->name();
|
||||
QAction *action = new QAction((*it)->name(), this);
|
||||
connect(action, SIGNAL(triggered()), m_promotionMapper, SLOT(map()));
|
||||
m_promotionMapper->setMapping(action, customClassName);
|
||||
candidatesMenu->addAction(action);
|
||||
}
|
||||
// Sub menu action
|
||||
QAction *subMenuAction = new QAction(m_promoteLabel, this);
|
||||
subMenuAction->setMenu(candidatesMenu);
|
||||
m_promotionActions.push_back(subMenuAction);
|
||||
return CanPromote;
|
||||
}
|
||||
|
||||
void PromotionTaskMenu::addActions(unsigned separatorFlags, ActionList &actionList)
|
||||
{
|
||||
addActions(formWindow(), separatorFlags, actionList);
|
||||
}
|
||||
|
||||
void PromotionTaskMenu::addActions(QDesignerFormWindowInterface *fw, unsigned flags,
|
||||
ActionList &actionList)
|
||||
{
|
||||
Q_ASSERT(m_widget);
|
||||
const int previousSize = actionList.size();
|
||||
const PromotionState promotionState = createPromotionActions(fw);
|
||||
|
||||
// Promotion candidates/demote
|
||||
actionList += m_promotionActions;
|
||||
|
||||
// Edit action depending on context
|
||||
switch (promotionState) {
|
||||
case CanPromote:
|
||||
actionList += m_EditPromoteToAction;
|
||||
break;
|
||||
case CanDemote:
|
||||
if (!(flags & SuppressGlobalEdit))
|
||||
actionList += m_globalEditAction;
|
||||
if (!languageExtension(fw->core())) {
|
||||
actionList += separatorAction(this);
|
||||
actionList += m_EditSignalsSlotsAction;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (!(flags & SuppressGlobalEdit))
|
||||
actionList += m_globalEditAction;
|
||||
break;
|
||||
}
|
||||
// Add separators if required
|
||||
if (actionList.size() > previousSize) {
|
||||
if (flags & LeadingSeparator)
|
||||
actionList.insert(previousSize, separatorAction(this));
|
||||
if (flags & TrailingSeparator)
|
||||
actionList += separatorAction(this);
|
||||
}
|
||||
}
|
||||
|
||||
void PromotionTaskMenu::addActions(QDesignerFormWindowInterface *fw, unsigned flags, QMenu *menu)
|
||||
{
|
||||
ActionList actionList;
|
||||
addActions(fw, flags, actionList);
|
||||
menu->addActions(actionList);
|
||||
}
|
||||
|
||||
void PromotionTaskMenu::addActions(unsigned flags, QMenu *menu)
|
||||
{
|
||||
addActions(formWindow(), flags, menu);
|
||||
}
|
||||
|
||||
void PromotionTaskMenu::promoteTo(QDesignerFormWindowInterface *fw, const QString &customClassName)
|
||||
{
|
||||
Q_ASSERT(m_widget);
|
||||
PromoteToCustomWidgetCommand *cmd = new PromoteToCustomWidgetCommand(fw);
|
||||
cmd->init(promotionSelectionList(fw), customClassName);
|
||||
fw->commandHistory()->push(cmd);
|
||||
}
|
||||
|
||||
|
||||
void PromotionTaskMenu::slotPromoteToCustomWidget(const QString &customClassName)
|
||||
{
|
||||
promoteTo(formWindow(), customClassName);
|
||||
}
|
||||
|
||||
void PromotionTaskMenu::slotDemoteFromCustomWidget()
|
||||
{
|
||||
QDesignerFormWindowInterface *fw = formWindow();
|
||||
const PromotionSelectionList promotedWidgets = promotionSelectionList(fw);
|
||||
Q_ASSERT(!promotedWidgets.empty() && isPromoted(fw->core(), promotedWidgets.front()));
|
||||
|
||||
// ### use the undo stack
|
||||
DemoteFromCustomWidgetCommand *cmd = new DemoteFromCustomWidgetCommand(fw);
|
||||
cmd->init(promotedWidgets);
|
||||
fw->commandHistory()->push(cmd);
|
||||
}
|
||||
|
||||
void PromotionTaskMenu::slotEditPromoteTo()
|
||||
{
|
||||
Q_ASSERT(m_widget);
|
||||
// Check whether invoked over a promotable widget
|
||||
QDesignerFormWindowInterface *fw = formWindow();
|
||||
QDesignerFormEditorInterface *core = fw->core();
|
||||
const QString base_class_name = WidgetFactory::classNameOf(core, m_widget);
|
||||
Q_ASSERT(QDesignerPromotionDialog::baseClassNames(core->promotion()).contains(base_class_name));
|
||||
// Show over promotable widget
|
||||
QString promoteToClassName;
|
||||
QDialog *promotionEditor = 0;
|
||||
if (QDesignerLanguageExtension *lang = languageExtension(core))
|
||||
promotionEditor = lang->createPromotionDialog(core, base_class_name, &promoteToClassName, fw);
|
||||
if (!promotionEditor)
|
||||
promotionEditor = new QDesignerPromotionDialog(core, fw, base_class_name, &promoteToClassName);
|
||||
if (promotionEditor->exec() == QDialog::Accepted && !promoteToClassName.isEmpty()) {
|
||||
promoteTo(fw, promoteToClassName);
|
||||
}
|
||||
delete promotionEditor;
|
||||
}
|
||||
|
||||
void PromotionTaskMenu::slotEditPromotedWidgets()
|
||||
{
|
||||
// Global context, show over non-promotable widget
|
||||
QDesignerFormWindowInterface *fw = formWindow();
|
||||
if (!fw)
|
||||
return;
|
||||
editPromotedWidgets(fw->core(), fw);
|
||||
}
|
||||
|
||||
PromotionTaskMenu::PromotionSelectionList PromotionTaskMenu::promotionSelectionList(QDesignerFormWindowInterface *formWindow) const
|
||||
{
|
||||
// In multi selection mode, check for a homogenous selection (same class, same promotion state)
|
||||
// and return the list if this is the case. Also make sure m_widget
|
||||
// is the last widget in the list so that it is re-selected as the last
|
||||
// widget by the promotion commands.
|
||||
|
||||
PromotionSelectionList rc;
|
||||
|
||||
if (m_mode != ModeSingleWidget) {
|
||||
QDesignerFormEditorInterface *core = formWindow->core();
|
||||
const QDesignerIntrospectionInterface *intro = core->introspection();
|
||||
const QString className = intro->metaObject(m_widget)->className();
|
||||
const bool promoted = isPromoted(formWindow->core(), m_widget);
|
||||
// Just in case someone plugged an old-style Object Inspector
|
||||
if (QDesignerObjectInspector *designerObjectInspector = qobject_cast<QDesignerObjectInspector *>(core->objectInspector())) {
|
||||
Selection s;
|
||||
designerObjectInspector->getSelection(s);
|
||||
// Find objects of similar state
|
||||
const QWidgetList &source = m_mode == ModeManagedMultiSelection ? s.managed : s.unmanaged;
|
||||
const QWidgetList::const_iterator cend = source.constEnd();
|
||||
for (QWidgetList::const_iterator it = source.constBegin(); it != cend; ++it) {
|
||||
QWidget *w = *it;
|
||||
if (w != m_widget) {
|
||||
// Selection state mismatch
|
||||
if (intro->metaObject(w)->className() != className || isPromoted(core, w) != promoted)
|
||||
return PromotionSelectionList();
|
||||
rc.push_back(w);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rc.push_back(m_widget);
|
||||
return rc;
|
||||
}
|
||||
|
||||
QDesignerFormWindowInterface *PromotionTaskMenu::formWindow() const
|
||||
{
|
||||
// Use the QObject overload of QDesignerFormWindowInterface::findFormWindow since that works
|
||||
// for QDesignerMenus also.
|
||||
QObject *o = m_widget;
|
||||
QDesignerFormWindowInterface *result = QDesignerFormWindowInterface::findFormWindow(o);
|
||||
Q_ASSERT(result != 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
void PromotionTaskMenu::editPromotedWidgets(QDesignerFormEditorInterface *core, QWidget* parent) {
|
||||
QDesignerLanguageExtension *lang = languageExtension(core);
|
||||
// Show over non-promotable widget
|
||||
QDialog *promotionEditor = 0;
|
||||
if (lang)
|
||||
lang->createPromotionDialog(core, parent);
|
||||
if (!promotionEditor)
|
||||
promotionEditor = new QDesignerPromotionDialog(core, parent);
|
||||
promotionEditor->exec();
|
||||
delete promotionEditor;
|
||||
}
|
||||
|
||||
void PromotionTaskMenu::slotEditSignalsSlots()
|
||||
{
|
||||
QDesignerFormWindowInterface *fw = formWindow();
|
||||
if (!fw)
|
||||
return;
|
||||
SignalSlotDialog::editPromotedClass(fw->core(), m_widget, fw);
|
||||
}
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
151
third/designer/lib/shared/promotiontaskmenu_p.h
Normal file
151
third/designer/lib/shared/promotiontaskmenu_p.h
Normal file
@@ -0,0 +1,151 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef PROMOTIONTASKMENU_H
|
||||
#define PROMOTIONTASKMENU_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QPointer>
|
||||
#include <QtCore/QList>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDesignerFormWindowInterface;
|
||||
class QDesignerFormEditorInterface;
|
||||
|
||||
class QAction;
|
||||
class QMenu;
|
||||
class QWidget;
|
||||
class QSignalMapper;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
// A helper class for creating promotion context menus and handling promotion actions.
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT PromotionTaskMenu: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Mode {
|
||||
ModeSingleWidget,
|
||||
ModeManagedMultiSelection,
|
||||
ModeUnmanagedMultiSelection
|
||||
};
|
||||
|
||||
explicit PromotionTaskMenu(QWidget *widget,Mode mode = ModeManagedMultiSelection, QObject *parent = 0);
|
||||
|
||||
Mode mode() const;
|
||||
void setMode(Mode m);
|
||||
|
||||
void setWidget(QWidget *widget);
|
||||
|
||||
// Set menu labels
|
||||
void setPromoteLabel(const QString &promoteLabel);
|
||||
void setEditPromoteToLabel(const QString &promoteEditLabel);
|
||||
// Defaults to "Demote to %1".arg(class).
|
||||
void setDemoteLabel(const QString &demoteLabel);
|
||||
|
||||
typedef QList<QAction*> ActionList;
|
||||
|
||||
enum AddFlags { LeadingSeparator = 1, TrailingSeparator = 2, SuppressGlobalEdit = 4};
|
||||
|
||||
// Adds a list of promotion actions according to the current promotion state of the widget.
|
||||
void addActions(QDesignerFormWindowInterface *fw, unsigned flags, ActionList &actionList);
|
||||
// Convenience that finds the form window.
|
||||
void addActions(unsigned flags, ActionList &actionList);
|
||||
|
||||
void addActions(QDesignerFormWindowInterface *fw, unsigned flags, QMenu *menu);
|
||||
void addActions(unsigned flags, QMenu *menu);
|
||||
|
||||
// Pop up the editor in a global context.
|
||||
static void editPromotedWidgets(QDesignerFormEditorInterface *core, QWidget* parent);
|
||||
|
||||
private slots:
|
||||
void slotPromoteToCustomWidget(const QString &customClassName);
|
||||
void slotDemoteFromCustomWidget();
|
||||
void slotEditPromotedWidgets();
|
||||
void slotEditPromoteTo();
|
||||
void slotEditSignalsSlots();
|
||||
|
||||
private:
|
||||
void promoteTo(QDesignerFormWindowInterface *fw, const QString &customClassName);
|
||||
|
||||
enum PromotionState { NotApplicable, NoHomogenousSelection, CanPromote, CanDemote };
|
||||
PromotionState createPromotionActions(QDesignerFormWindowInterface *formWindow);
|
||||
QDesignerFormWindowInterface *formWindow() const;
|
||||
|
||||
typedef QList<QPointer<QWidget> > PromotionSelectionList;
|
||||
PromotionSelectionList promotionSelectionList(QDesignerFormWindowInterface *formWindow) const;
|
||||
|
||||
Mode m_mode;
|
||||
|
||||
QPointer<QWidget> m_widget;
|
||||
|
||||
QSignalMapper *m_promotionMapper;
|
||||
// Per-Widget actions
|
||||
QList<QAction *> m_promotionActions;
|
||||
|
||||
QAction *m_globalEditAction;
|
||||
QAction *m_EditPromoteToAction;
|
||||
QAction *m_EditSignalsSlotsAction;
|
||||
|
||||
QString m_promoteLabel;
|
||||
QString m_demoteLabel;
|
||||
};
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // PROMOTIONTASKMENU_H
|
||||
96
third/designer/lib/shared/propertylineedit.cpp
Normal file
96
third/designer/lib/shared/propertylineedit.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "propertylineedit_p.h"
|
||||
|
||||
#include <QtGui/QContextMenuEvent>
|
||||
#include <QtGui/QKeyEvent>
|
||||
#include <QtGui/QMenu>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
PropertyLineEdit::PropertyLineEdit(QWidget *parent) :
|
||||
QLineEdit(parent), m_wantNewLine(false)
|
||||
{
|
||||
}
|
||||
|
||||
bool PropertyLineEdit::event(QEvent *e)
|
||||
{
|
||||
// handle 'Select all' here as it is not done in the QLineEdit
|
||||
if (e->type() == QEvent::ShortcutOverride && !isReadOnly()) {
|
||||
QKeyEvent* ke = static_cast<QKeyEvent*> (e);
|
||||
if (ke->modifiers() & Qt::ControlModifier) {
|
||||
if(ke->key() == Qt::Key_A) {
|
||||
ke->accept();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return QLineEdit::event(e);
|
||||
}
|
||||
|
||||
void PropertyLineEdit::insertNewLine() {
|
||||
insertText(QLatin1String("\\n"));
|
||||
}
|
||||
|
||||
void PropertyLineEdit::insertText(const QString &text) {
|
||||
// position cursor after new text and grab focus
|
||||
const int oldCursorPosition = cursorPosition ();
|
||||
insert(text);
|
||||
setCursorPosition (oldCursorPosition + text.length());
|
||||
setFocus(Qt::OtherFocusReason);
|
||||
}
|
||||
|
||||
void PropertyLineEdit::contextMenuEvent(QContextMenuEvent *event) {
|
||||
QMenu *menu = createStandardContextMenu ();
|
||||
|
||||
if (m_wantNewLine) {
|
||||
menu->addSeparator();
|
||||
QAction* nlAction = menu->addAction(tr("Insert line break"));
|
||||
connect(nlAction, SIGNAL(triggered()), this, SLOT(insertNewLine()));
|
||||
}
|
||||
|
||||
menu->exec(event->globalPos());
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
85
third/designer/lib/shared/propertylineedit_p.h
Normal file
85
third/designer/lib/shared/propertylineedit_p.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef PROPERTYLINEEDIT_H
|
||||
#define PROPERTYLINEEDIT_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
|
||||
#include <QtGui/QLineEdit>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
// A line edit with a special context menu allowing for adding (escaped) new lines
|
||||
class PropertyLineEdit : public QLineEdit {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PropertyLineEdit(QWidget *parent);
|
||||
void setWantNewLine(bool nl) { m_wantNewLine = nl; }
|
||||
bool wantNewLine() const { return m_wantNewLine; }
|
||||
|
||||
bool event(QEvent *e);
|
||||
protected:
|
||||
void contextMenuEvent (QContextMenuEvent *event );
|
||||
private slots:
|
||||
void insertNewLine();
|
||||
private:
|
||||
void insertText(const QString &);
|
||||
bool m_wantNewLine;
|
||||
};
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // PROPERTYLINEEDIT_H
|
||||
2968
third/designer/lib/shared/qdesigner_command.cpp
Normal file
2968
third/designer/lib/shared/qdesigner_command.cpp
Normal file
File diff suppressed because it is too large
Load Diff
159
third/designer/lib/shared/qdesigner_command2.cpp
Normal file
159
third/designer/lib/shared/qdesigner_command2.cpp
Normal file
@@ -0,0 +1,159 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qdesigner_command2_p.h"
|
||||
#include "formwindowbase_p.h"
|
||||
#include "layoutinfo_p.h"
|
||||
#include "qdesigner_command_p.h"
|
||||
#include "widgetfactory_p.h"
|
||||
#include "qlayout_widget_p.h"
|
||||
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
#include <QtDesigner/QDesignerMetaDataBaseInterface>
|
||||
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtGui/QLayout>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
MorphLayoutCommand::MorphLayoutCommand(QDesignerFormWindowInterface *formWindow) :
|
||||
QDesignerFormWindowCommand(QString(), formWindow),
|
||||
m_breakLayoutCommand(new BreakLayoutCommand(formWindow)),
|
||||
m_layoutCommand(new LayoutCommand(formWindow)),
|
||||
m_newType(LayoutInfo::VBox),
|
||||
m_layoutBase(0)
|
||||
{
|
||||
}
|
||||
|
||||
MorphLayoutCommand::~MorphLayoutCommand()
|
||||
{
|
||||
delete m_layoutCommand;
|
||||
delete m_breakLayoutCommand;
|
||||
}
|
||||
|
||||
bool MorphLayoutCommand::init(QWidget *w, int newType)
|
||||
{
|
||||
int oldType;
|
||||
QDesignerFormWindowInterface *fw = formWindow();
|
||||
if (!canMorph(fw, w, &oldType) || oldType == newType)
|
||||
return false;
|
||||
m_layoutBase = w;
|
||||
m_newType = newType;
|
||||
// Find all managed widgets
|
||||
m_widgets.clear();
|
||||
const QLayout *layout = LayoutInfo::managedLayout(fw->core(), w);
|
||||
const int count = layout->count();
|
||||
for (int i = 0; i < count ; i++) {
|
||||
if (QWidget *w = layout->itemAt(i)->widget())
|
||||
if (fw->isManaged(w))
|
||||
m_widgets.push_back(w);
|
||||
}
|
||||
const bool reparentLayoutWidget = false; // leave QLayoutWidget intact
|
||||
m_breakLayoutCommand->init(m_widgets, m_layoutBase, reparentLayoutWidget);
|
||||
m_layoutCommand->init(m_layoutBase, m_widgets, static_cast<LayoutInfo::Type>(m_newType), m_layoutBase, reparentLayoutWidget);
|
||||
setText(formatDescription(core(), m_layoutBase, oldType, newType));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MorphLayoutCommand::canMorph(const QDesignerFormWindowInterface *formWindow, QWidget *w, int *ptrToCurrentType)
|
||||
{
|
||||
if (ptrToCurrentType)
|
||||
*ptrToCurrentType = LayoutInfo::NoLayout;
|
||||
// We want a managed widget or a container page
|
||||
// with a level-0 managed layout
|
||||
QDesignerFormEditorInterface *core = formWindow->core();
|
||||
QLayout *layout = LayoutInfo::managedLayout(core, w);
|
||||
if (!layout)
|
||||
return false;
|
||||
const LayoutInfo::Type type = LayoutInfo::layoutType(core, layout);
|
||||
if (ptrToCurrentType)
|
||||
*ptrToCurrentType = type;
|
||||
switch (type) {
|
||||
case LayoutInfo::HBox:
|
||||
case LayoutInfo::VBox:
|
||||
case LayoutInfo::Grid:
|
||||
case LayoutInfo::Form:
|
||||
return true;
|
||||
break;
|
||||
case LayoutInfo::NoLayout:
|
||||
case LayoutInfo::HSplitter: // Nothing doing
|
||||
case LayoutInfo::VSplitter:
|
||||
case LayoutInfo::UnknownLayout:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MorphLayoutCommand::redo()
|
||||
{
|
||||
m_breakLayoutCommand->redo();
|
||||
m_layoutCommand->redo();
|
||||
/* Transfer applicable properties which is a cross-section of the modified
|
||||
* properties except object name. */
|
||||
if (const LayoutProperties *properties = m_breakLayoutCommand->layoutProperties()) {
|
||||
const int oldMask = m_breakLayoutCommand->propertyMask();
|
||||
QLayout *newLayout = LayoutInfo::managedLayout(core(), m_layoutBase);
|
||||
const int newMask = LayoutProperties::visibleProperties(newLayout);
|
||||
const int applicableMask = (oldMask & newMask) & ~LayoutProperties::ObjectNameProperty;
|
||||
if (applicableMask)
|
||||
properties->toPropertySheet(core(), newLayout, applicableMask);
|
||||
}
|
||||
}
|
||||
|
||||
void MorphLayoutCommand::undo()
|
||||
{
|
||||
m_layoutCommand->undo();
|
||||
m_breakLayoutCommand->undo();
|
||||
}
|
||||
|
||||
QString MorphLayoutCommand::formatDescription(QDesignerFormEditorInterface * /* core*/, const QWidget *w, int oldType, int newType)
|
||||
{
|
||||
const QString oldName = LayoutInfo::layoutName(static_cast<LayoutInfo::Type>(oldType));
|
||||
const QString newName = LayoutInfo::layoutName(static_cast<LayoutInfo::Type>(newType));
|
||||
const QString widgetName = qobject_cast<const QLayoutWidget*>(w) ? w->layout()->objectName() : w->objectName();
|
||||
return QApplication::translate("Command", "Change layout of '%1' from %2 to %3").arg(widgetName, oldName, newName);
|
||||
}
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
101
third/designer/lib/shared/qdesigner_command2_p.h
Normal file
101
third/designer/lib/shared/qdesigner_command2_p.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef QDESIGNER_COMMAND2_H
|
||||
#define QDESIGNER_COMMAND2_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
#include "qdesigner_formwindowcommand_p.h"
|
||||
|
||||
#include <QtGui/QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
class LayoutCommand;
|
||||
class BreakLayoutCommand;
|
||||
|
||||
/* This command changes the type of a managed layout on a widget (including
|
||||
* red layouts of type 'QLayoutWidget') into another type, maintaining the
|
||||
* applicable properties. It does this by chaining BreakLayoutCommand and
|
||||
* LayoutCommand, parametrizing them not to actually delete/reparent
|
||||
* QLayoutWidget's. */
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT MorphLayoutCommand : public QDesignerFormWindowCommand {
|
||||
Q_DISABLE_COPY(MorphLayoutCommand)
|
||||
public:
|
||||
explicit MorphLayoutCommand(QDesignerFormWindowInterface *formWindow);
|
||||
virtual ~MorphLayoutCommand();
|
||||
|
||||
bool init(QWidget *w, int newType);
|
||||
|
||||
static bool canMorph(const QDesignerFormWindowInterface *formWindow, QWidget *w, int *ptrToCurrentType = 0);
|
||||
|
||||
virtual void redo();
|
||||
virtual void undo();
|
||||
|
||||
private:
|
||||
static QString formatDescription(QDesignerFormEditorInterface *core, const QWidget *w, int oldType, int newType);
|
||||
|
||||
BreakLayoutCommand *m_breakLayoutCommand;
|
||||
LayoutCommand *m_layoutCommand;
|
||||
int m_newType;
|
||||
QWidgetList m_widgets;
|
||||
QWidget *m_layoutBase;
|
||||
};
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QDESIGNER_COMMAND2_H
|
||||
1136
third/designer/lib/shared/qdesigner_command_p.h
Normal file
1136
third/designer/lib/shared/qdesigner_command_p.h
Normal file
File diff suppressed because it is too large
Load Diff
300
third/designer/lib/shared/qdesigner_dnditem.cpp
Normal file
300
third/designer/lib/shared/qdesigner_dnditem.cpp
Normal file
@@ -0,0 +1,300 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qdesigner_dnditem_p.h"
|
||||
#include "formwindowbase_p.h"
|
||||
#include "ui4_p.h"
|
||||
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QBitmap>
|
||||
#include <QtGui/QPixmap>
|
||||
#include <QtGui/QImage>
|
||||
#include <QtGui/QLabel>
|
||||
#include <QtGui/QDrag>
|
||||
#include <QtGui/QCursor>
|
||||
#include <QtGui/QDropEvent>
|
||||
#include <QtGui/QRgb>
|
||||
|
||||
#include <QtCore/QMultiMap>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
QDesignerDnDItem::QDesignerDnDItem(DropType type, QWidget *source) :
|
||||
m_source(source),
|
||||
m_type(type),
|
||||
m_dom_ui(0),
|
||||
m_widget(0),
|
||||
m_decoration(0)
|
||||
{
|
||||
}
|
||||
|
||||
void QDesignerDnDItem::init(DomUI *ui, QWidget *widget, QWidget *decoration,
|
||||
const QPoint &global_mouse_pos)
|
||||
{
|
||||
Q_ASSERT(widget != 0 || ui != 0);
|
||||
Q_ASSERT(decoration != 0);
|
||||
|
||||
m_dom_ui = ui;
|
||||
m_widget = widget;
|
||||
m_decoration = decoration;
|
||||
|
||||
const QRect geometry = m_decoration->geometry();
|
||||
m_hot_spot = global_mouse_pos - m_decoration->geometry().topLeft();
|
||||
}
|
||||
|
||||
QDesignerDnDItem::~QDesignerDnDItem()
|
||||
{
|
||||
if (m_decoration != 0)
|
||||
m_decoration->deleteLater();
|
||||
delete m_dom_ui;
|
||||
}
|
||||
|
||||
DomUI *QDesignerDnDItem::domUi() const
|
||||
{
|
||||
return m_dom_ui;
|
||||
}
|
||||
|
||||
QWidget *QDesignerDnDItem::decoration() const
|
||||
{
|
||||
return m_decoration;
|
||||
}
|
||||
|
||||
QPoint QDesignerDnDItem::hotSpot() const
|
||||
{
|
||||
return m_hot_spot;
|
||||
}
|
||||
|
||||
QWidget *QDesignerDnDItem::widget() const
|
||||
{
|
||||
return m_widget;
|
||||
}
|
||||
|
||||
QDesignerDnDItem::DropType QDesignerDnDItem::type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
QWidget *QDesignerDnDItem::source() const
|
||||
{
|
||||
return m_source;
|
||||
}
|
||||
|
||||
void QDesignerDnDItem::setDomUi(DomUI *dom_ui)
|
||||
{
|
||||
delete m_dom_ui;
|
||||
m_dom_ui = dom_ui;
|
||||
}
|
||||
|
||||
// ---------- QDesignerMimeData
|
||||
|
||||
// Make pixmap transparent on Windows only. Mac is transparent by default, Unix usually does not work.
|
||||
#ifdef Q_WS_WIN
|
||||
# define TRANSPARENT_DRAG_PIXMAP
|
||||
#endif
|
||||
|
||||
QDesignerMimeData::QDesignerMimeData(const QDesignerDnDItems &items, QDrag *drag) :
|
||||
m_items(items)
|
||||
{
|
||||
enum { Alpha = 200 };
|
||||
QPoint decorationTopLeft;
|
||||
switch (m_items.size()) {
|
||||
case 0:
|
||||
break;
|
||||
case 1: {
|
||||
QWidget *deco = m_items.first()->decoration();
|
||||
decorationTopLeft = deco->pos();
|
||||
const QPixmap widgetPixmap = QPixmap::grabWidget(deco);
|
||||
#ifdef TRANSPARENT_DRAG_PIXMAP
|
||||
QImage image(widgetPixmap.size(), QImage::Format_ARGB32);
|
||||
image.fill(QColor(Qt::transparent).rgba());
|
||||
QPainter painter(&image);
|
||||
painter.drawPixmap(QPoint(0, 0), widgetPixmap);
|
||||
painter.end();
|
||||
setImageTransparency(image, Alpha);
|
||||
drag->setPixmap(QPixmap::fromImage(image));
|
||||
#else
|
||||
drag->setPixmap(widgetPixmap);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
// determine size of drag decoration by uniting all geometries
|
||||
const QDesignerDnDItems::const_iterator cend = m_items.constEnd();
|
||||
QDesignerDnDItems::const_iterator it =m_items.constBegin();
|
||||
QRect unitedGeometry = (*it)->decoration()->geometry();
|
||||
for (++it; it != cend; ++it )
|
||||
unitedGeometry = unitedGeometry .united((*it)->decoration()->geometry());
|
||||
|
||||
// paint with offset. At the same time, create a mask bitmap, containing widget rectangles.
|
||||
QImage image(unitedGeometry.size(), QImage::Format_ARGB32);
|
||||
image.fill(QColor(Qt::transparent).rgba());
|
||||
QBitmap mask(unitedGeometry.size());
|
||||
mask.clear();
|
||||
// paint with offset, determine action
|
||||
QPainter painter(&image);
|
||||
QPainter maskPainter(&mask);
|
||||
decorationTopLeft = unitedGeometry.topLeft();
|
||||
for (it = m_items.constBegin() ; it != cend; ++it ) {
|
||||
QWidget *w = (*it)->decoration();
|
||||
const QPixmap wp = QPixmap::grabWidget(w);
|
||||
const QPoint pos = w->pos() - decorationTopLeft;
|
||||
painter.drawPixmap(pos, wp);
|
||||
maskPainter.fillRect(QRect(pos, wp.size()), Qt::color1);
|
||||
}
|
||||
painter.end();
|
||||
maskPainter.end();
|
||||
#ifdef TRANSPARENT_DRAG_PIXMAP
|
||||
setImageTransparency(image, Alpha);
|
||||
#endif
|
||||
QPixmap pixmap = QPixmap::fromImage(image);
|
||||
pixmap.setMask(mask);
|
||||
drag->setPixmap(pixmap);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// determine hot spot and reconstruct the exact starting position as form window
|
||||
// introduces some offset when detecting DnD
|
||||
m_globalStartPos = m_items.first()->decoration()->pos() + m_items.first()->hotSpot();
|
||||
m_hotSpot = m_globalStartPos - decorationTopLeft;
|
||||
drag->setHotSpot(m_hotSpot);
|
||||
|
||||
drag->setMimeData(this);
|
||||
}
|
||||
|
||||
QDesignerMimeData::~QDesignerMimeData()
|
||||
{
|
||||
const QDesignerDnDItems::const_iterator cend = m_items.constEnd();
|
||||
for (QDesignerDnDItems::const_iterator it = m_items.constBegin(); it != cend; ++it )
|
||||
delete *it;
|
||||
}
|
||||
|
||||
Qt::DropAction QDesignerMimeData::proposedDropAction() const
|
||||
{
|
||||
return m_items.first()->type() == QDesignerDnDItemInterface::CopyDrop ? Qt::CopyAction : Qt::MoveAction;
|
||||
}
|
||||
|
||||
Qt::DropAction QDesignerMimeData::execDrag(const QDesignerDnDItems &items, QWidget * dragSource)
|
||||
{
|
||||
if (items.empty())
|
||||
return Qt::IgnoreAction;
|
||||
|
||||
QDrag *drag = new QDrag(dragSource);
|
||||
QDesignerMimeData *mimeData = new QDesignerMimeData(items, drag);
|
||||
|
||||
// Store pointers to widgets that are to be re-shown if a move operation is canceled
|
||||
QWidgetList reshowWidgets;
|
||||
const QDesignerDnDItems::const_iterator cend = items.constEnd();
|
||||
for (QDesignerDnDItems::const_iterator it = items.constBegin(); it != cend; ++it )
|
||||
if (QWidget *w = (*it)->widget())
|
||||
if ((*it)->type() == QDesignerDnDItemInterface::MoveDrop)
|
||||
reshowWidgets.push_back(w);
|
||||
|
||||
const Qt::DropAction executedAction = drag->exec(Qt::CopyAction|Qt::MoveAction, mimeData->proposedDropAction());
|
||||
|
||||
if (executedAction == Qt::IgnoreAction && !reshowWidgets.empty())
|
||||
foreach (QWidget *w, reshowWidgets)
|
||||
w->show();
|
||||
|
||||
return executedAction;
|
||||
}
|
||||
|
||||
|
||||
void QDesignerMimeData::moveDecoration(const QPoint &globalPos) const
|
||||
{
|
||||
const QPoint relativeDistance = globalPos - m_globalStartPos;
|
||||
const QDesignerDnDItems::const_iterator cend = m_items.constEnd();
|
||||
for (QDesignerDnDItems::const_iterator it =m_items.constBegin(); it != cend; ++it ) {
|
||||
QWidget *w = (*it)->decoration();
|
||||
w->move(w->pos() + relativeDistance);
|
||||
}
|
||||
}
|
||||
|
||||
void QDesignerMimeData::removeMovedWidgetsFromSourceForm(const QDesignerDnDItems &items)
|
||||
{
|
||||
typedef QMultiMap<FormWindowBase *, QWidget *> FormWidgetMap;
|
||||
FormWidgetMap formWidgetMap;
|
||||
// Find moved widgets per form
|
||||
const QDesignerDnDItems::const_iterator cend = items.constEnd();
|
||||
for (QDesignerDnDItems::const_iterator it = items.constBegin(); it != cend; ++it )
|
||||
if ((*it)->type() == QDesignerDnDItemInterface::MoveDrop)
|
||||
if (QWidget *w = (*it)->widget())
|
||||
if (FormWindowBase *fb = qobject_cast<FormWindowBase *>((*it)->source()))
|
||||
formWidgetMap.insert(fb, w);
|
||||
if (formWidgetMap.empty())
|
||||
return;
|
||||
|
||||
foreach (FormWindowBase * fb, formWidgetMap.keys())
|
||||
fb->deleteWidgetList(formWidgetMap.values(fb));
|
||||
}
|
||||
|
||||
void QDesignerMimeData::acceptEventWithAction(Qt::DropAction desiredAction, QDropEvent *e)
|
||||
{
|
||||
if (e->proposedAction() == desiredAction) {
|
||||
e->acceptProposedAction();
|
||||
} else {
|
||||
e->setDropAction(desiredAction);
|
||||
e->accept();
|
||||
}
|
||||
}
|
||||
|
||||
void QDesignerMimeData::acceptEvent(QDropEvent *e) const
|
||||
{
|
||||
acceptEventWithAction(proposedDropAction(), e);
|
||||
}
|
||||
|
||||
void QDesignerMimeData::setImageTransparency(QImage &image, int alpha)
|
||||
{
|
||||
const int height = image.height();
|
||||
for (int l = 0; l < height; l++) {
|
||||
QRgb *line = reinterpret_cast<QRgb *>(image.scanLine(l));
|
||||
QRgb *lineEnd = line + image.width();
|
||||
for ( ; line < lineEnd; line++) {
|
||||
const QRgb rgba = *line;
|
||||
*line = qRgba(qRed(rgba), qGreen(rgba), qBlue(rgba), alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
147
third/designer/lib/shared/qdesigner_dnditem_p.h
Normal file
147
third/designer/lib/shared/qdesigner_dnditem_p.h
Normal file
@@ -0,0 +1,147 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef QDESIGNER_DNDITEM_H
|
||||
#define QDESIGNER_DNDITEM_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
#include <QtDesigner/abstractdnditem.h>
|
||||
|
||||
#include <QtCore/QPoint>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QMimeData>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDrag;
|
||||
class QImage;
|
||||
class QDropEvent;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT QDesignerDnDItem: public QDesignerDnDItemInterface
|
||||
{
|
||||
public:
|
||||
explicit QDesignerDnDItem(DropType type, QWidget *source = 0);
|
||||
virtual ~QDesignerDnDItem();
|
||||
|
||||
virtual DomUI *domUi() const;
|
||||
virtual QWidget *decoration() const;
|
||||
virtual QWidget *widget() const;
|
||||
virtual QPoint hotSpot() const;
|
||||
virtual QWidget *source() const;
|
||||
|
||||
virtual DropType type() const;
|
||||
|
||||
protected:
|
||||
void setDomUi(DomUI *dom_ui);
|
||||
void init(DomUI *ui, QWidget *widget, QWidget *decoration, const QPoint &global_mouse_pos);
|
||||
|
||||
private:
|
||||
QWidget *m_source;
|
||||
const DropType m_type;
|
||||
const QPoint m_globalStartPos;
|
||||
DomUI *m_dom_ui;
|
||||
QWidget *m_widget;
|
||||
QWidget *m_decoration;
|
||||
QPoint m_hot_spot;
|
||||
|
||||
Q_DISABLE_COPY(QDesignerDnDItem)
|
||||
};
|
||||
|
||||
// Mime data for use with designer drag and drop operations.
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT QDesignerMimeData : public QMimeData {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
typedef QList<QDesignerDnDItemInterface *> QDesignerDnDItems;
|
||||
|
||||
virtual ~QDesignerMimeData();
|
||||
|
||||
const QDesignerDnDItems &items() const { return m_items; }
|
||||
|
||||
// Execute a drag and drop operation.
|
||||
static Qt::DropAction execDrag(const QDesignerDnDItems &items, QWidget * dragSource);
|
||||
|
||||
QPoint hotSpot() const { return m_hotSpot; }
|
||||
|
||||
// Move the decoration. Required for drops over form windows as the position
|
||||
// is derived from the decoration position.
|
||||
void moveDecoration(const QPoint &globalPos) const;
|
||||
|
||||
// For a move operation, create the undo command sequence to remove
|
||||
// the widgets from the source form.
|
||||
static void removeMovedWidgetsFromSourceForm(const QDesignerDnDItems &items);
|
||||
|
||||
// Accept an event with the proper action.
|
||||
void acceptEvent(QDropEvent *e) const;
|
||||
|
||||
// Helper to accept an event with the desired action.
|
||||
static void acceptEventWithAction(Qt::DropAction desiredAction, QDropEvent *e);
|
||||
|
||||
private:
|
||||
QDesignerMimeData(const QDesignerDnDItems &items, QDrag *drag);
|
||||
Qt::DropAction proposedDropAction() const;
|
||||
|
||||
static void setImageTransparency(QImage &image, int alpha);
|
||||
|
||||
const QDesignerDnDItems m_items;
|
||||
QPoint m_globalStartPos;
|
||||
QPoint m_hotSpot;
|
||||
};
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QDESIGNER_DNDITEM_H
|
||||
140
third/designer/lib/shared/qdesigner_dockwidget.cpp
Normal file
140
third/designer/lib/shared/qdesigner_dockwidget.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qdesigner_dockwidget_p.h"
|
||||
#include "layoutinfo_p.h"
|
||||
|
||||
#include <QtDesigner/QDesignerFormWindowInterface>
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
#include <QtDesigner/QDesignerContainerExtension>
|
||||
#include <QtDesigner/QExtensionManager>
|
||||
#include <QtDesigner/QDesignerFormWindowCursorInterface>
|
||||
|
||||
#include <QtGui/QMainWindow>
|
||||
#include <QtGui/QLayout>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QDesignerDockWidget::QDesignerDockWidget(QWidget *parent)
|
||||
: QDockWidget(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QDesignerDockWidget::~QDesignerDockWidget()
|
||||
{
|
||||
}
|
||||
|
||||
bool QDesignerDockWidget::docked() const
|
||||
{
|
||||
return qobject_cast<QMainWindow*>(parentWidget()) != 0;
|
||||
}
|
||||
|
||||
void QDesignerDockWidget::setDocked(bool b)
|
||||
{
|
||||
if (QMainWindow *mainWindow = findMainWindow()) {
|
||||
QDesignerFormEditorInterface *core = formWindow()->core();
|
||||
QDesignerContainerExtension *c;
|
||||
c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), mainWindow);
|
||||
if (b && !docked()) {
|
||||
// Dock it
|
||||
// ### undo/redo stack
|
||||
setParent(0);
|
||||
c->addWidget(this);
|
||||
formWindow()->selectWidget(this, formWindow()->cursor()->isWidgetSelected(this));
|
||||
} else if (!b && docked()) {
|
||||
// Undock it
|
||||
for (int i = 0; i < c->count(); ++i) {
|
||||
if (c->widget(i) == this) {
|
||||
c->remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// #### restore the position
|
||||
setParent(mainWindow->centralWidget());
|
||||
show();
|
||||
formWindow()->selectWidget(this, formWindow()->cursor()->isWidgetSelected(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Qt::DockWidgetArea QDesignerDockWidget::dockWidgetArea() const
|
||||
{
|
||||
if (QMainWindow *mainWindow = qobject_cast<QMainWindow*>(parentWidget()))
|
||||
return mainWindow->dockWidgetArea(const_cast<QDesignerDockWidget*>(this));
|
||||
|
||||
return Qt::LeftDockWidgetArea;
|
||||
}
|
||||
|
||||
void QDesignerDockWidget::setDockWidgetArea(Qt::DockWidgetArea dockWidgetArea)
|
||||
{
|
||||
if (QMainWindow *mainWindow = qobject_cast<QMainWindow*>(parentWidget())) {
|
||||
if ((dockWidgetArea != Qt::NoDockWidgetArea)
|
||||
&& isAreaAllowed(dockWidgetArea)) {
|
||||
mainWindow->addDockWidget(dockWidgetArea, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool QDesignerDockWidget::inMainWindow() const
|
||||
{
|
||||
QMainWindow *mw = findMainWindow();
|
||||
if (mw && !mw->centralWidget()->layout()) {
|
||||
if (mw == parentWidget())
|
||||
return true;
|
||||
if (mw->centralWidget() == parentWidget())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QDesignerFormWindowInterface *QDesignerDockWidget::formWindow() const
|
||||
{
|
||||
return QDesignerFormWindowInterface::findFormWindow(const_cast<QDesignerDockWidget*>(this));
|
||||
}
|
||||
|
||||
QMainWindow *QDesignerDockWidget::findMainWindow() const
|
||||
{
|
||||
if (QDesignerFormWindowInterface *fw = formWindow())
|
||||
return qobject_cast<QMainWindow*>(fw->mainContainer());
|
||||
return 0;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
87
third/designer/lib/shared/qdesigner_dockwidget_p.h
Normal file
87
third/designer/lib/shared/qdesigner_dockwidget_p.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef QDESIGNER_DOCKWIDGET_H
|
||||
#define QDESIGNER_DOCKWIDGET_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
#include <QtGui/QDockWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDesignerFormWindowInterface;
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT QDesignerDockWidget: public QDockWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(Qt::DockWidgetArea dockWidgetArea READ dockWidgetArea WRITE setDockWidgetArea DESIGNABLE docked STORED false)
|
||||
Q_PROPERTY(bool docked READ docked WRITE setDocked DESIGNABLE inMainWindow STORED false)
|
||||
public:
|
||||
QDesignerDockWidget(QWidget *parent = 0);
|
||||
virtual ~QDesignerDockWidget();
|
||||
|
||||
bool docked() const;
|
||||
void setDocked(bool b);
|
||||
|
||||
Qt::DockWidgetArea dockWidgetArea() const;
|
||||
void setDockWidgetArea(Qt::DockWidgetArea dockWidgetArea);
|
||||
|
||||
bool inMainWindow() const;
|
||||
|
||||
private:
|
||||
QDesignerFormWindowInterface *formWindow() const;
|
||||
QMainWindow *findMainWindow() const;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QDESIGNER_DOCKWIDGET_H
|
||||
498
third/designer/lib/shared/qdesigner_formbuilder.cpp
Normal file
498
third/designer/lib/shared/qdesigner_formbuilder.cpp
Normal file
@@ -0,0 +1,498 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qdesigner_formbuilder_p.h"
|
||||
#include "dynamicpropertysheet.h"
|
||||
#include "qsimpleresource_p.h"
|
||||
#include "widgetfactory_p.h"
|
||||
#include "qdesigner_introspection_p.h"
|
||||
|
||||
#include <ui4_p.h>
|
||||
#include <formbuilderextra_p.h>
|
||||
// sdk
|
||||
#include <QtDesigner/container.h>
|
||||
#include <QtDesigner/customwidget.h>
|
||||
#include <QtDesigner/propertysheet.h>
|
||||
#include <QtDesigner/QExtensionManager>
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
#include <QtDesigner/QDesignerFormWindowInterface>
|
||||
#include <QtDesigner/QDesignerWidgetFactoryInterface>
|
||||
#include <QtDesigner/QDesignerCustomWidgetInterface>
|
||||
#include <abstractdialoggui_p.h>
|
||||
|
||||
// shared
|
||||
#include <qdesigner_propertysheet_p.h>
|
||||
#include <qdesigner_utils_p.h>
|
||||
#include <formwindowbase_p.h>
|
||||
#include <qtresourcemodel_p.h>
|
||||
#include <scripterrordialog_p.h>
|
||||
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtGui/QToolBar>
|
||||
#include <QtGui/QMenuBar>
|
||||
#include <QtGui/QMainWindow>
|
||||
#include <QtGui/QStyleFactory>
|
||||
#include <QtGui/QStyle>
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtGui/QAbstractScrollArea>
|
||||
#include <QtGui/QMessageBox>
|
||||
#include <QtGui/QPixmap>
|
||||
|
||||
#include <QtCore/QBuffer>
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/QCoreApplication>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#ifndef QT_FORMBUILDER_NO_SCRIPT
|
||||
static QString summarizeScriptErrors(const QFormScriptRunner::Errors &errors)
|
||||
{
|
||||
QString rc = QCoreApplication::translate("QDesignerFormBuilder", "Script errors occurred:");
|
||||
foreach (QFormScriptRunner::Error error, errors) {
|
||||
rc += QLatin1Char('\n');
|
||||
rc += error.errorMessage;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
QDesignerFormBuilder::QDesignerFormBuilder(QDesignerFormEditorInterface *core,
|
||||
Mode mode,
|
||||
const DeviceProfile &deviceProfile) :
|
||||
m_core(core),
|
||||
m_mode(mode),
|
||||
m_deviceProfile(deviceProfile),
|
||||
m_pixmapCache(0),
|
||||
m_iconCache(0),
|
||||
m_ignoreCreateResources(false),
|
||||
m_tempResourceSet(0),
|
||||
m_mainWidget(true)
|
||||
{
|
||||
Q_ASSERT(m_core);
|
||||
#ifndef QT_FORMBUILDER_NO_SCRIPT
|
||||
// Disable scripting in the editors.
|
||||
QFormScriptRunner::Options options = formScriptRunner()->options();
|
||||
switch (m_mode) {
|
||||
case DisableScripts:
|
||||
options |= QFormScriptRunner::DisableScripts;
|
||||
break;
|
||||
case EnableScripts:
|
||||
options |= QFormScriptRunner::DisableWarnings;
|
||||
options &= ~QFormScriptRunner::DisableScripts;
|
||||
break;
|
||||
}
|
||||
formScriptRunner()-> setOptions(options);
|
||||
#endif
|
||||
}
|
||||
|
||||
QString QDesignerFormBuilder::systemStyle() const
|
||||
{
|
||||
return m_deviceProfile.isEmpty() ?
|
||||
QString::fromUtf8(QApplication::style()->metaObject()->className()) :
|
||||
m_deviceProfile.style();
|
||||
}
|
||||
|
||||
QWidget *QDesignerFormBuilder::createWidgetFromContents(const QString &contents, QWidget *parentWidget)
|
||||
{
|
||||
QByteArray data = contents.toUtf8();
|
||||
QBuffer buffer(&data);
|
||||
buffer.open(QIODevice::ReadOnly);
|
||||
return load(&buffer, parentWidget);
|
||||
}
|
||||
|
||||
QWidget *QDesignerFormBuilder::create(DomUI *ui, QWidget *parentWidget)
|
||||
{
|
||||
m_mainWidget = true;
|
||||
QtResourceSet *resourceSet = core()->resourceModel()->currentResourceSet();
|
||||
|
||||
// reload resource properties;
|
||||
createResources(ui->elementResources());
|
||||
core()->resourceModel()->setCurrentResourceSet(m_tempResourceSet);
|
||||
|
||||
m_ignoreCreateResources = true;
|
||||
DesignerPixmapCache pixmapCache;
|
||||
DesignerIconCache iconCache(&pixmapCache);
|
||||
m_pixmapCache = &pixmapCache;
|
||||
m_iconCache = &iconCache;
|
||||
|
||||
QWidget *widget = QFormBuilder::create(ui, parentWidget);
|
||||
|
||||
core()->resourceModel()->setCurrentResourceSet(resourceSet);
|
||||
core()->resourceModel()->removeResourceSet(m_tempResourceSet);
|
||||
m_tempResourceSet = 0;
|
||||
m_ignoreCreateResources = false;
|
||||
m_pixmapCache = 0;
|
||||
m_iconCache = 0;
|
||||
|
||||
m_customWidgetsWithScript.clear();
|
||||
return widget;
|
||||
}
|
||||
|
||||
QWidget *QDesignerFormBuilder::createWidget(const QString &widgetName, QWidget *parentWidget, const QString &name)
|
||||
{
|
||||
QWidget *widget = 0;
|
||||
|
||||
if (widgetName == QLatin1String("QToolBar")) {
|
||||
widget = new QToolBar(parentWidget);
|
||||
} else if (widgetName == QLatin1String("QMenu")) {
|
||||
widget = new QMenu(parentWidget);
|
||||
} else if (widgetName == QLatin1String("QMenuBar")) {
|
||||
widget = new QMenuBar(parentWidget);
|
||||
} else {
|
||||
widget = core()->widgetFactory()->createWidget(widgetName, parentWidget);
|
||||
}
|
||||
|
||||
if (widget) {
|
||||
widget->setObjectName(name);
|
||||
if (QSimpleResource::hasCustomWidgetScript(m_core, widget))
|
||||
m_customWidgetsWithScript.insert(widget);
|
||||
}
|
||||
|
||||
if (m_mainWidget) { // We need to apply the DPI here to take effect on size hints, etc.
|
||||
m_deviceProfile.apply(m_core, widget, DeviceProfile::ApplyPreview);
|
||||
m_mainWidget = false;
|
||||
}
|
||||
return widget;
|
||||
}
|
||||
|
||||
bool QDesignerFormBuilder::addItem(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget)
|
||||
{
|
||||
// Use container extension or rely on scripts unless main window.
|
||||
if (QFormBuilder::addItem(ui_widget, widget, parentWidget))
|
||||
return true;
|
||||
|
||||
if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(m_core->extensionManager(), parentWidget)) {
|
||||
container->addWidget(widget);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QDesignerFormBuilder::addItem(DomLayoutItem *ui_item, QLayoutItem *item, QLayout *layout)
|
||||
{
|
||||
return QFormBuilder::addItem(ui_item, item, layout);
|
||||
}
|
||||
|
||||
QIcon QDesignerFormBuilder::nameToIcon(const QString &filePath, const QString &qrcPath)
|
||||
{
|
||||
Q_UNUSED(filePath)
|
||||
Q_UNUSED(qrcPath)
|
||||
qWarning() << "QDesignerFormBuilder::nameToIcon() is obsoleted";
|
||||
return QIcon();
|
||||
}
|
||||
|
||||
QPixmap QDesignerFormBuilder::nameToPixmap(const QString &filePath, const QString &qrcPath)
|
||||
{
|
||||
Q_UNUSED(filePath)
|
||||
Q_UNUSED(qrcPath)
|
||||
qWarning() << "QDesignerFormBuilder::nameToPixmap() is obsoleted";
|
||||
return QPixmap();
|
||||
}
|
||||
|
||||
/* If the property is a enum or flag value, retrieve
|
||||
* the existing enum/flag type via property sheet and use it to convert */
|
||||
|
||||
static bool readDomEnumerationValue(const DomProperty *p,
|
||||
const QDesignerPropertySheetExtension* sheet,
|
||||
QVariant &v)
|
||||
{
|
||||
switch (p->kind()) {
|
||||
case DomProperty::Set: {
|
||||
const int index = sheet->indexOf(p->attributeName());
|
||||
if (index == -1)
|
||||
return false;
|
||||
const QVariant sheetValue = sheet->property(index);
|
||||
if (qVariantCanConvert<PropertySheetFlagValue>(sheetValue)) {
|
||||
const PropertySheetFlagValue f = qvariant_cast<PropertySheetFlagValue>(sheetValue);
|
||||
bool ok = false;
|
||||
v = f.metaFlags.parseFlags(p->elementSet(), &ok);
|
||||
if (!ok)
|
||||
designerWarning(f.metaFlags.messageParseFailed(p->elementSet()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DomProperty::Enum: {
|
||||
const int index = sheet->indexOf(p->attributeName());
|
||||
if (index == -1)
|
||||
return false;
|
||||
const QVariant sheetValue = sheet->property(index);
|
||||
if (qVariantCanConvert<PropertySheetEnumValue>(sheetValue)) {
|
||||
const PropertySheetEnumValue e = qvariant_cast<PropertySheetEnumValue>(sheetValue);
|
||||
bool ok = false;
|
||||
v = e.metaEnum.parseEnum(p->elementEnum(), &ok);
|
||||
if (!ok)
|
||||
designerWarning(e.metaEnum.messageParseFailed(p->elementEnum()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void QDesignerFormBuilder::applyProperties(QObject *o, const QList<DomProperty*> &properties)
|
||||
{
|
||||
typedef QList<DomProperty*> DomPropertyList;
|
||||
|
||||
if (properties.empty())
|
||||
return;
|
||||
|
||||
QFormBuilderExtra *formBuilderExtra = QFormBuilderExtra::instance(this);
|
||||
const QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), o);
|
||||
const QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core()->extensionManager(), o);
|
||||
const bool changingMetaObject = WidgetFactory::classNameOf(core(), o) == QLatin1String("QAxWidget");
|
||||
const QDesignerMetaObjectInterface *meta = core()->introspection()->metaObject(o);
|
||||
const bool dynamicPropertiesAllowed = dynamicSheet && dynamicSheet->dynamicPropertiesAllowed();
|
||||
|
||||
QDesignerPropertySheet *designerPropertySheet = qobject_cast<QDesignerPropertySheet *>(
|
||||
core()->extensionManager()->extension(o, Q_TYPEID(QDesignerPropertySheetExtension)));
|
||||
|
||||
if (designerPropertySheet) {
|
||||
if (designerPropertySheet->pixmapCache())
|
||||
designerPropertySheet->setPixmapCache(m_pixmapCache);
|
||||
if (designerPropertySheet->iconCache())
|
||||
designerPropertySheet->setIconCache(m_iconCache);
|
||||
}
|
||||
|
||||
const DomPropertyList::const_iterator cend = properties.constEnd();
|
||||
for (DomPropertyList::const_iterator it = properties.constBegin(); it != cend; ++it) {
|
||||
DomProperty *p = *it;
|
||||
QVariant v;
|
||||
if (!readDomEnumerationValue(p, sheet, v))
|
||||
v = toVariant(o->metaObject(), p);
|
||||
|
||||
if (v.isNull())
|
||||
continue;
|
||||
|
||||
const QString attributeName = p->attributeName();
|
||||
if (formBuilderExtra->applyPropertyInternally(o, attributeName, v))
|
||||
continue;
|
||||
|
||||
// refuse fake properties like current tab name (weak test)
|
||||
if (!dynamicPropertiesAllowed) {
|
||||
if (changingMetaObject) // Changes after setting control of QAxWidget
|
||||
meta = core()->introspection()->metaObject(o);
|
||||
if (meta->indexOfProperty(attributeName) == -1)
|
||||
continue;
|
||||
}
|
||||
|
||||
QObject *obj = o;
|
||||
QAbstractScrollArea *scroll = qobject_cast<QAbstractScrollArea *>(o);
|
||||
if (scroll && attributeName == QLatin1String("cursor") && scroll->viewport())
|
||||
obj = scroll->viewport();
|
||||
|
||||
// a real property
|
||||
obj->setProperty(attributeName.toUtf8(), v);
|
||||
}
|
||||
}
|
||||
|
||||
DomWidget *QDesignerFormBuilder::createDom(QWidget *widget, DomWidget *ui_parentWidget, bool recursive)
|
||||
{
|
||||
DomWidget *ui_widget = QFormBuilder::createDom(widget, ui_parentWidget, recursive);
|
||||
QSimpleResource::addExtensionDataToDOM(this, m_core, ui_widget, widget);
|
||||
return ui_widget;
|
||||
}
|
||||
|
||||
QWidget *QDesignerFormBuilder::create(DomWidget *ui_widget, QWidget *parentWidget)
|
||||
{
|
||||
QWidget *widget = QFormBuilder::create(ui_widget, parentWidget);
|
||||
// Do not apply state if scripts are to be run in preview mode
|
||||
QSimpleResource::applyExtensionDataFromDOM(this, m_core, ui_widget, widget, m_mode == DisableScripts);
|
||||
return widget;
|
||||
}
|
||||
|
||||
void QDesignerFormBuilder::createResources(DomResources *resources)
|
||||
{
|
||||
if (m_ignoreCreateResources)
|
||||
return;
|
||||
QStringList paths;
|
||||
if (resources != 0) {
|
||||
const QList<DomResource*> dom_include = resources->elementInclude();
|
||||
foreach (DomResource *res, dom_include) {
|
||||
QString path = QDir::cleanPath(workingDirectory().absoluteFilePath(res->attributeLocation()));
|
||||
paths << path;
|
||||
}
|
||||
}
|
||||
|
||||
m_tempResourceSet = core()->resourceModel()->addResourceSet(paths);
|
||||
}
|
||||
|
||||
QLayout *QDesignerFormBuilder::create(DomLayout *ui_layout, QLayout *layout, QWidget *parentWidget)
|
||||
{
|
||||
return QFormBuilder::create(ui_layout, layout, parentWidget);
|
||||
}
|
||||
|
||||
void QDesignerFormBuilder::loadExtraInfo(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget)
|
||||
{
|
||||
QFormBuilder::loadExtraInfo(ui_widget, widget, parentWidget);
|
||||
}
|
||||
|
||||
QWidget *QDesignerFormBuilder::createPreview(const QDesignerFormWindowInterface *fw,
|
||||
const QString &styleName,
|
||||
const QString &appStyleSheet,
|
||||
const DeviceProfile &deviceProfile,
|
||||
ScriptErrors *scriptErrors,
|
||||
QString *errorMessage)
|
||||
{
|
||||
scriptErrors->clear();
|
||||
|
||||
// load
|
||||
QDesignerFormBuilder builder(fw->core(), EnableScripts, deviceProfile);
|
||||
builder.setWorkingDirectory(fw->absoluteDir());
|
||||
|
||||
const bool warningsEnabled = QSimpleResource::setWarningsEnabled(false);
|
||||
QByteArray bytes = fw->contents().toUtf8();
|
||||
QSimpleResource::setWarningsEnabled(warningsEnabled);
|
||||
|
||||
QBuffer buffer(&bytes);
|
||||
buffer.open(QIODevice::ReadOnly);
|
||||
|
||||
QWidget *widget = builder.load(&buffer, 0);
|
||||
if (!widget) { // Shouldn't happen
|
||||
*errorMessage = QCoreApplication::translate("QDesignerFormBuilder", "The preview failed to build.");
|
||||
return 0;
|
||||
}
|
||||
// Make sure palette is applied
|
||||
const QString styleToUse = styleName.isEmpty() ? builder.deviceProfile().style() : styleName;
|
||||
if (!styleToUse.isEmpty()) {
|
||||
if (WidgetFactory *wf = qobject_cast<qdesigner_internal::WidgetFactory *>(fw->core()->widgetFactory())) {
|
||||
if (styleToUse != wf->styleName())
|
||||
WidgetFactory::applyStyleToTopLevel(wf->getStyle(styleToUse), widget);
|
||||
}
|
||||
}
|
||||
#ifndef QT_FORMBUILDER_NO_SCRIPT
|
||||
// Check for script errors
|
||||
*scriptErrors = builder.formScriptRunner()->errors();
|
||||
if (!scriptErrors->empty()) {
|
||||
*errorMessage = summarizeScriptErrors(*scriptErrors);
|
||||
delete widget;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
// Fake application style sheet by prepending. (If this doesn't work, fake by nesting
|
||||
// into parent widget).
|
||||
if (!appStyleSheet.isEmpty()) {
|
||||
QString styleSheet = appStyleSheet;
|
||||
styleSheet += QLatin1Char('\n');
|
||||
styleSheet += widget->styleSheet();
|
||||
widget->setStyleSheet(styleSheet);
|
||||
}
|
||||
return widget;
|
||||
}
|
||||
|
||||
QWidget *QDesignerFormBuilder::createPreview(const QDesignerFormWindowInterface *fw, const QString &styleName)
|
||||
{
|
||||
return createPreview(fw, styleName, QString());
|
||||
}
|
||||
|
||||
QWidget *QDesignerFormBuilder::createPreview(const QDesignerFormWindowInterface *fw,
|
||||
const QString &styleName,
|
||||
const QString &appStyleSheet,
|
||||
const DeviceProfile &deviceProfile,
|
||||
QString *errorMessage)
|
||||
{
|
||||
ScriptErrors scriptErrors;
|
||||
return createPreview(fw, styleName, appStyleSheet, deviceProfile, &scriptErrors, errorMessage);
|
||||
}
|
||||
|
||||
QWidget *QDesignerFormBuilder::createPreview(const QDesignerFormWindowInterface *fw,
|
||||
const QString &styleName,
|
||||
const QString &appStyleSheet,
|
||||
QString *errorMessage)
|
||||
{
|
||||
ScriptErrors scriptErrors;
|
||||
return createPreview(fw, styleName, appStyleSheet, DeviceProfile(), &scriptErrors, errorMessage);
|
||||
}
|
||||
|
||||
QWidget *QDesignerFormBuilder::createPreview(const QDesignerFormWindowInterface *fw, const QString &styleName, const QString &appStyleSheet)
|
||||
{
|
||||
ScriptErrors scriptErrors;
|
||||
QString errorMessage;
|
||||
QWidget *widget = createPreview(fw, styleName, appStyleSheet, DeviceProfile(), &scriptErrors, &errorMessage);
|
||||
if (!widget) {
|
||||
// Display Script errors or message box
|
||||
QWidget *dialogParent = fw->core()->topLevel();
|
||||
if (scriptErrors.empty()) {
|
||||
fw->core()->dialogGui()->message(dialogParent, QDesignerDialogGuiInterface::PreviewFailureMessage,
|
||||
QMessageBox::Warning, QCoreApplication::translate("QDesignerFormBuilder", "Designer"), errorMessage, QMessageBox::Ok);
|
||||
} else {
|
||||
ScriptErrorDialog scriptErrorDialog(scriptErrors, dialogParent);
|
||||
scriptErrorDialog.exec();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return widget;
|
||||
}
|
||||
|
||||
QPixmap QDesignerFormBuilder::createPreviewPixmap(const QDesignerFormWindowInterface *fw, const QString &styleName, const QString &appStyleSheet)
|
||||
{
|
||||
QWidget *widget = createPreview(fw, styleName, appStyleSheet);
|
||||
if (!widget)
|
||||
return QPixmap();
|
||||
|
||||
const QPixmap rc = QPixmap::grabWidget (widget);
|
||||
widget->deleteLater();
|
||||
return rc;
|
||||
}
|
||||
|
||||
// ---------- NewFormWidgetFormBuilder
|
||||
|
||||
NewFormWidgetFormBuilder::NewFormWidgetFormBuilder(QDesignerFormEditorInterface *core,
|
||||
Mode mode,
|
||||
const DeviceProfile &deviceProfile) :
|
||||
QDesignerFormBuilder(core, mode, deviceProfile)
|
||||
{
|
||||
}
|
||||
|
||||
void NewFormWidgetFormBuilder::createCustomWidgets(DomCustomWidgets *dc)
|
||||
{
|
||||
QSimpleResource::handleDomCustomWidgets(core(), dc);
|
||||
}
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
181
third/designer/lib/shared/qdesigner_formbuilder_p.h
Normal file
181
third/designer/lib/shared/qdesigner_formbuilder_p.h
Normal file
@@ -0,0 +1,181 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef QDESIGNER_FORMBUILDER_H
|
||||
#define QDESIGNER_FORMBUILDER_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
#include "deviceprofile_p.h"
|
||||
|
||||
#include <QtDesigner/private/formscriptrunner_p.h>
|
||||
#include <QtDesigner/formbuilder.h>
|
||||
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QSet>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDesignerFormEditorInterface;
|
||||
class QDesignerFormWindowInterface;
|
||||
|
||||
class QPixmap;
|
||||
class QtResourceSet;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
class DesignerPixmapCache;
|
||||
class DesignerIconCache;
|
||||
|
||||
/* Form builder used for previewing forms and widget box.
|
||||
* It applies the system settings to its toplevel window. */
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT QDesignerFormBuilder: public QFormBuilder
|
||||
{
|
||||
public:
|
||||
enum Mode {
|
||||
DisableScripts,
|
||||
EnableScripts
|
||||
};
|
||||
|
||||
QDesignerFormBuilder(QDesignerFormEditorInterface *core,
|
||||
Mode mode,
|
||||
const DeviceProfile &deviceProfile = DeviceProfile());
|
||||
|
||||
QWidget *createWidgetFromContents(const QString &contents, QWidget *parentWidget = 0);
|
||||
|
||||
virtual QWidget *createWidget(DomWidget *ui_widget, QWidget *parentWidget = 0)
|
||||
{ return QFormBuilder::create(ui_widget, parentWidget); }
|
||||
|
||||
inline QDesignerFormEditorInterface *core() const
|
||||
{ return m_core; }
|
||||
|
||||
QString systemStyle() const;
|
||||
|
||||
typedef QFormScriptRunner::Errors ScriptErrors;
|
||||
// Create a preview widget (for integrations) or return 0. The widget has to be embedded into a main window.
|
||||
// Experimental, depending on script support.
|
||||
static QWidget *createPreview(const QDesignerFormWindowInterface *fw, const QString &styleName /* ="" */,
|
||||
const QString &appStyleSheet /* ="" */,
|
||||
const DeviceProfile &deviceProfile,
|
||||
ScriptErrors *scriptErrors, QString *errorMessage);
|
||||
// Convenience that pops up message boxes in case of failures.
|
||||
static QWidget *createPreview(const QDesignerFormWindowInterface *fw, const QString &styleName = QString());
|
||||
// Create a preview widget (for integrations) or return 0. The widget has to be embedded into a main window.
|
||||
static QWidget *createPreview(const QDesignerFormWindowInterface *fw, const QString &styleName, const QString &appStyleSheet, QString *errorMessage);
|
||||
static QWidget *createPreview(const QDesignerFormWindowInterface *fw, const QString &styleName, const QString &appStyleSheet, const DeviceProfile &deviceProfile, QString *errorMessage);
|
||||
// Convenience that pops up message boxes in case of failures.
|
||||
static QWidget *createPreview(const QDesignerFormWindowInterface *fw, const QString &styleName, const QString &appStyleSheet);
|
||||
|
||||
// Create a preview image
|
||||
static QPixmap createPreviewPixmap(const QDesignerFormWindowInterface *fw, const QString &styleName = QString(), const QString &appStyleSheet = QString());
|
||||
|
||||
protected:
|
||||
using QFormBuilder::createDom;
|
||||
using QFormBuilder::create;
|
||||
|
||||
virtual QWidget *create(DomUI *ui, QWidget *parentWidget);
|
||||
virtual DomWidget *createDom(QWidget *widget, DomWidget *ui_parentWidget, bool recursive = true);
|
||||
virtual QWidget *create(DomWidget *ui_widget, QWidget *parentWidget);
|
||||
virtual QLayout *create(DomLayout *ui_layout, QLayout *layout, QWidget *parentWidget);
|
||||
virtual void createResources(DomResources *resources);
|
||||
|
||||
virtual QWidget *createWidget(const QString &widgetName, QWidget *parentWidget, const QString &name);
|
||||
virtual bool addItem(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget);
|
||||
virtual bool addItem(DomLayoutItem *ui_item, QLayoutItem *item, QLayout *layout);
|
||||
|
||||
virtual QIcon nameToIcon(const QString &filePath, const QString &qrcPath);
|
||||
virtual QPixmap nameToPixmap(const QString &filePath, const QString &qrcPath);
|
||||
|
||||
virtual void applyProperties(QObject *o, const QList<DomProperty*> &properties);
|
||||
|
||||
virtual void loadExtraInfo(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget);
|
||||
|
||||
QtResourceSet *internalResourceSet() const { return m_tempResourceSet; }
|
||||
|
||||
DeviceProfile deviceProfile() const { return m_deviceProfile; }
|
||||
|
||||
private:
|
||||
QDesignerFormEditorInterface *m_core;
|
||||
const Mode m_mode;
|
||||
|
||||
typedef QSet<QWidget *> WidgetSet;
|
||||
WidgetSet m_customWidgetsWithScript;
|
||||
|
||||
const DeviceProfile m_deviceProfile;
|
||||
|
||||
DesignerPixmapCache *m_pixmapCache;
|
||||
DesignerIconCache *m_iconCache;
|
||||
bool m_ignoreCreateResources;
|
||||
QtResourceSet *m_tempResourceSet;
|
||||
bool m_mainWidget;
|
||||
};
|
||||
|
||||
// Form builder for a new form widget (preview). To allow for promoted
|
||||
// widgets in the template, it implements the handling of custom widgets
|
||||
// (adding of them to the widget database).
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT NewFormWidgetFormBuilder: public QDesignerFormBuilder {
|
||||
public:
|
||||
NewFormWidgetFormBuilder(QDesignerFormEditorInterface *core,
|
||||
Mode mode,
|
||||
const DeviceProfile &deviceProfile = DeviceProfile());
|
||||
|
||||
protected:
|
||||
virtual void createCustomWidgets(DomCustomWidgets *);
|
||||
};
|
||||
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QDESIGNER_FORMBUILDER_H
|
||||
64
third/designer/lib/shared/qdesigner_formeditorcommand.cpp
Normal file
64
third/designer/lib/shared/qdesigner_formeditorcommand.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "qdesigner_formeditorcommand_p.h"
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
// ---- QDesignerFormEditorCommand ----
|
||||
QDesignerFormEditorCommand::QDesignerFormEditorCommand(const QString &description, QDesignerFormEditorInterface *core)
|
||||
: QUndoCommand(description),
|
||||
m_core(core)
|
||||
{
|
||||
}
|
||||
|
||||
QDesignerFormEditorInterface *QDesignerFormEditorCommand::core() const
|
||||
{
|
||||
return m_core;
|
||||
}
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
83
third/designer/lib/shared/qdesigner_formeditorcommand_p.h
Normal file
83
third/designer/lib/shared/qdesigner_formeditorcommand_p.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef QDESIGNER_FORMEDITORCOMMAND_H
|
||||
#define QDESIGNER_FORMEDITORCOMMAND_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
#include <QtCore/QPointer>
|
||||
#include <QtGui/QUndoCommand>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDesignerFormEditorInterface;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT QDesignerFormEditorCommand: public QUndoCommand
|
||||
{
|
||||
|
||||
public:
|
||||
QDesignerFormEditorCommand(const QString &description, QDesignerFormEditorInterface *core);
|
||||
|
||||
protected:
|
||||
QDesignerFormEditorInterface *core() const;
|
||||
|
||||
private:
|
||||
QPointer<QDesignerFormEditorInterface> m_core;
|
||||
};
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QDESIGNER_FORMEDITORCOMMAND_H
|
||||
151
third/designer/lib/shared/qdesigner_formwindowcommand.cpp
Normal file
151
third/designer/lib/shared/qdesigner_formwindowcommand.cpp
Normal file
@@ -0,0 +1,151 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "qdesigner_formwindowcommand_p.h"
|
||||
#include "qdesigner_objectinspector_p.h"
|
||||
#include "layout_p.h"
|
||||
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
#include <QtDesigner/QDesignerFormWindowInterface>
|
||||
#include <QtDesigner/QDesignerObjectInspectorInterface>
|
||||
#include <QtDesigner/QDesignerActionEditorInterface>
|
||||
#include <QtDesigner/QDesignerMetaDataBaseInterface>
|
||||
#include <QtDesigner/QDesignerPropertySheetExtension>
|
||||
#include <QtDesigner/QDesignerPropertyEditorInterface>
|
||||
#include <QtDesigner/QExtensionManager>
|
||||
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/QLabel>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
// ---- QDesignerFormWindowCommand ----
|
||||
QDesignerFormWindowCommand::QDesignerFormWindowCommand(const QString &description,
|
||||
QDesignerFormWindowInterface *formWindow,
|
||||
QUndoCommand *parent)
|
||||
: QUndoCommand(description, parent),
|
||||
m_formWindow(formWindow)
|
||||
{
|
||||
}
|
||||
|
||||
QDesignerFormWindowInterface *QDesignerFormWindowCommand::formWindow() const
|
||||
{
|
||||
return m_formWindow;
|
||||
}
|
||||
|
||||
QDesignerFormEditorInterface *QDesignerFormWindowCommand::core() const
|
||||
{
|
||||
if (QDesignerFormWindowInterface *fw = formWindow())
|
||||
return fw->core();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QDesignerFormWindowCommand::undo()
|
||||
{
|
||||
cheapUpdate();
|
||||
}
|
||||
|
||||
void QDesignerFormWindowCommand::redo()
|
||||
{
|
||||
cheapUpdate();
|
||||
}
|
||||
|
||||
void QDesignerFormWindowCommand::cheapUpdate()
|
||||
{
|
||||
if (core()->objectInspector())
|
||||
core()->objectInspector()->setFormWindow(formWindow());
|
||||
|
||||
if (core()->actionEditor())
|
||||
core()->actionEditor()->setFormWindow(formWindow());
|
||||
}
|
||||
|
||||
QDesignerPropertySheetExtension* QDesignerFormWindowCommand::propertySheet(QObject *object) const
|
||||
{
|
||||
return qt_extension<QDesignerPropertySheetExtension*>(formWindow()->core()->extensionManager(), object);
|
||||
}
|
||||
|
||||
void QDesignerFormWindowCommand::updateBuddies(QDesignerFormWindowInterface *form,
|
||||
const QString &old_name,
|
||||
const QString &new_name)
|
||||
{
|
||||
QExtensionManager* extensionManager = form->core()->extensionManager();
|
||||
|
||||
typedef QList<QLabel*> LabelList;
|
||||
|
||||
const LabelList label_list = qFindChildren<QLabel*>(form);
|
||||
if (label_list.empty())
|
||||
return;
|
||||
|
||||
const QString buddyProperty = QLatin1String("buddy");
|
||||
const QByteArray oldNameU8 = old_name.toUtf8();
|
||||
const QByteArray newNameU8 = new_name.toUtf8();
|
||||
|
||||
const LabelList::const_iterator cend = label_list.constEnd();
|
||||
for (LabelList::const_iterator it = label_list.constBegin(); it != cend; ++it ) {
|
||||
if (QDesignerPropertySheetExtension* sheet = qt_extension<QDesignerPropertySheetExtension*>(extensionManager, *it)) {
|
||||
const int idx = sheet->indexOf(buddyProperty);
|
||||
if (idx != -1) {
|
||||
const QByteArray oldBuddy = sheet->property(idx).toByteArray();
|
||||
if (oldBuddy == oldNameU8)
|
||||
sheet->setProperty(idx, newNameU8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QDesignerFormWindowCommand::selectUnmanagedObject(QObject *unmanagedObject)
|
||||
{
|
||||
// Keep selection in sync
|
||||
if (QDesignerObjectInspector *oi = qobject_cast<QDesignerObjectInspector *>(core()->objectInspector())) {
|
||||
oi->clearSelection();
|
||||
oi->selectObject(unmanagedObject);
|
||||
}
|
||||
core()->propertyEditor()->setObject(unmanagedObject);
|
||||
}
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
98
third/designer/lib/shared/qdesigner_formwindowcommand_p.h
Normal file
98
third/designer/lib/shared/qdesigner_formwindowcommand_p.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef QDESIGNER_FORMWINDOWCOMMAND_H
|
||||
#define QDESIGNER_FORMWINDOWCOMMAND_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
|
||||
#include <QtCore/QPointer>
|
||||
#include <QtGui/QUndoCommand>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDesignerFormEditorInterface;
|
||||
class QDesignerFormWindowInterface;
|
||||
class QDesignerPropertySheetExtension;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT QDesignerFormWindowCommand: public QUndoCommand
|
||||
{
|
||||
|
||||
public:
|
||||
QDesignerFormWindowCommand(const QString &description,
|
||||
QDesignerFormWindowInterface *formWindow,
|
||||
QUndoCommand *parent = 0);
|
||||
|
||||
virtual void undo();
|
||||
virtual void redo();
|
||||
|
||||
static void updateBuddies(QDesignerFormWindowInterface *form,
|
||||
const QString &old_name, const QString &new_name);
|
||||
protected:
|
||||
QDesignerFormWindowInterface *formWindow() const;
|
||||
QDesignerFormEditorInterface *core() const;
|
||||
QDesignerPropertySheetExtension* propertySheet(QObject *object) const;
|
||||
|
||||
void cheapUpdate();
|
||||
|
||||
void selectUnmanagedObject(QObject *unmanagedObject);
|
||||
private:
|
||||
QPointer<QDesignerFormWindowInterface> m_formWindow;
|
||||
};
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QDESIGNER_COMMAND_H
|
||||
167
third/designer/lib/shared/qdesigner_formwindowmanager.cpp
Normal file
167
third/designer/lib/shared/qdesigner_formwindowmanager.cpp
Normal file
@@ -0,0 +1,167 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qdesigner_formwindowmanager_p.h"
|
||||
#include "plugindialog_p.h"
|
||||
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace qdesigner_internal;
|
||||
|
||||
/*!
|
||||
\class QDesignerFormWindowManager
|
||||
|
||||
Extends QDesignerFormWindowManagerInterface with methods to control
|
||||
the preview and printing of forms. It provides a facade that simplifies
|
||||
the complexity of the more general PreviewConfiguration & PreviewManager
|
||||
interfaces.
|
||||
|
||||
\since 4.5
|
||||
*/
|
||||
|
||||
|
||||
QDesignerFormWindowManager::QDesignerFormWindowManager(QObject *parent)
|
||||
: QDesignerFormWindowManagerInterface(parent), m_unused(0)
|
||||
{
|
||||
}
|
||||
|
||||
QDesignerFormWindowManager::~QDesignerFormWindowManager()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Allows you to intervene and control \QD's form "Preview" action. The
|
||||
function returns the original action.
|
||||
|
||||
\since 4.5
|
||||
*/
|
||||
QAction *QDesignerFormWindowManager::actionDefaultPreview() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
Allows you to intervene and control \QD's form "Preview in" style action. The
|
||||
function returns the original list of actions.
|
||||
|
||||
The method calls PreviewManager::createStyleActionGroup() internally.
|
||||
|
||||
\since 4.5
|
||||
*/
|
||||
QActionGroup *QDesignerFormWindowManager::actionGroupPreviewInStyle() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QPixmap QDesignerFormWindowManager::createPreviewPixmap(QString *errorMessage)
|
||||
|
||||
Creates a pixmap representing the preview of the currently active form.
|
||||
|
||||
The method calls PreviewManager::createPreviewPixmap() internally.
|
||||
|
||||
\since 4.5
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn QPixmap QDesignerFormWindowManager::closeAllPreviews()
|
||||
|
||||
Closes all preview windows generated by actionDefaultPreview, actionGroupPreviewInStyle
|
||||
and the corresponding methods in PreviewManager.
|
||||
|
||||
\since 4.5
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn PreviewManager *QDesignerFormWindowManager::previewManager()
|
||||
|
||||
Accesses the previewmanager implementation.
|
||||
|
||||
\since 4.5
|
||||
\internal
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QAction *QDesignerFormWindowManager::actionShowFormWindowSettingsDialog() const;
|
||||
|
||||
Allows you to intervene and control \QD's form "Form Settings" action. The
|
||||
function returns the original action.
|
||||
|
||||
\since 4.5
|
||||
\internal
|
||||
*/
|
||||
|
||||
QAction *QDesignerFormWindowManager::actionShowFormWindowSettingsDialog() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void QDesignerFormWindowManager::aboutPlugins()
|
||||
|
||||
Pops up an "About plugins" dialog.
|
||||
|
||||
\since 4.5
|
||||
\internal
|
||||
*/
|
||||
|
||||
void QDesignerFormWindowManager::aboutPlugins()
|
||||
{
|
||||
PluginDialog dlg(core(), core()->topLevel());
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn
|
||||
void QDesignerFormWindowManager::formWindowSettingsChanged(QDesignerFormWindowInterface *fw);
|
||||
|
||||
This signal is emitted when the form settings dialog was shown
|
||||
and changes have been made to the form.
|
||||
|
||||
\since 4.5
|
||||
\internal
|
||||
*/
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
||||
99
third/designer/lib/shared/qdesigner_formwindowmanager_p.h
Normal file
99
third/designer/lib/shared/qdesigner_formwindowmanager_p.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef QDESIGNER_FORMWINDOMANAGER_H
|
||||
#define QDESIGNER_FORMWINDOMANAGER_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
#include <QtDesigner/QDesignerFormWindowManagerInterface>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
class PreviewManager;
|
||||
|
||||
//
|
||||
// Convenience methods to manage form previews (ultimately forwarded to PreviewManager).
|
||||
//
|
||||
class QDESIGNER_SHARED_EXPORT QDesignerFormWindowManager
|
||||
: public QDesignerFormWindowManagerInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QDesignerFormWindowManager(QObject *parent = 0);
|
||||
virtual ~QDesignerFormWindowManager();
|
||||
|
||||
virtual QAction *actionDefaultPreview() const;
|
||||
virtual QActionGroup *actionGroupPreviewInStyle() const;
|
||||
virtual QAction *actionShowFormWindowSettingsDialog() const;
|
||||
|
||||
virtual QPixmap createPreviewPixmap(QString *errorMessage) = 0;
|
||||
|
||||
virtual PreviewManager *previewManager() const = 0;
|
||||
|
||||
Q_SIGNALS:
|
||||
void formWindowSettingsChanged(QDesignerFormWindowInterface *fw);
|
||||
|
||||
public Q_SLOTS:
|
||||
virtual void closeAllPreviews() = 0;
|
||||
void aboutPlugins();
|
||||
|
||||
private:
|
||||
void *m_unused;
|
||||
};
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QDESIGNER_FORMWINDOMANAGER_H
|
||||
496
third/designer/lib/shared/qdesigner_integration.cpp
Normal file
496
third/designer/lib/shared/qdesigner_integration.cpp
Normal file
@@ -0,0 +1,496 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qdesigner_integration_p.h"
|
||||
#include "qdesigner_propertycommand_p.h"
|
||||
#include "qdesigner_propertyeditor_p.h"
|
||||
#include "qdesigner_objectinspector_p.h"
|
||||
#include "widgetdatabase_p.h"
|
||||
#include "pluginmanager_p.h"
|
||||
#include "widgetfactory_p.h"
|
||||
#include "qdesigner_widgetbox_p.h"
|
||||
#include "qtgradientmanager.h"
|
||||
#include "qtgradientutils.h"
|
||||
#include "qtresourcemodel_p.h"
|
||||
|
||||
// sdk
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
#include <QtDesigner/QDesignerFormWindowInterface>
|
||||
#include <QtDesigner/QDesignerFormWindowManagerInterface>
|
||||
#include <QtDesigner/QDesignerFormWindowCursorInterface>
|
||||
#include <QtDesigner/QDesignerActionEditorInterface>
|
||||
#include <QtDesigner/QDesignerWidgetBoxInterface>
|
||||
#include <QtDesigner/QExtensionManager>
|
||||
#include <QtDesigner/QDesignerResourceBrowserInterface>
|
||||
#include <QtDesigner/QDesignerPropertySheetExtension>
|
||||
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QDir>
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
// ---------------- DesignerIntegrationPrivate
|
||||
class QDesignerIntegrationPrivate {
|
||||
public:
|
||||
QDesignerIntegrationPrivate()
|
||||
: m_gradientManager(0),
|
||||
m_fileWatcherBehaviour(QDesignerIntegration::PromptAndReload),
|
||||
m_resourceEditingEnabled(true),
|
||||
m_slotNavigationEnabled(false)
|
||||
{}
|
||||
|
||||
QString m_gradientsPath;
|
||||
QtGradientManager *m_gradientManager;
|
||||
QDesignerIntegration::ResourceFileWatcherBehaviour m_fileWatcherBehaviour;
|
||||
bool m_resourceEditingEnabled;
|
||||
bool m_slotNavigationEnabled;
|
||||
};
|
||||
|
||||
// -------------- QDesignerIntegration
|
||||
// As of 4.4, the header will be distributed with the Eclipse plugin.
|
||||
|
||||
QDesignerIntegration::QDesignerIntegration(QDesignerFormEditorInterface *core, QObject *parent) :
|
||||
QDesignerIntegrationInterface(core, parent),
|
||||
m_d(new QDesignerIntegrationPrivate)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
QDesignerIntegration::~QDesignerIntegration()
|
||||
{
|
||||
QFile f(m_d->m_gradientsPath);
|
||||
if (f.open(QIODevice::WriteOnly)) {
|
||||
f.write(QtGradientUtils::saveState(m_d->m_gradientManager).toUtf8());
|
||||
f.close();
|
||||
}
|
||||
delete m_d;
|
||||
}
|
||||
|
||||
void QDesignerIntegration::initialize()
|
||||
{
|
||||
//
|
||||
// integrate the `Form Editor component'
|
||||
//
|
||||
|
||||
// Extensions
|
||||
if (QDesignerPropertyEditor *designerPropertyEditor= qobject_cast<QDesignerPropertyEditor *>(core()->propertyEditor())) {
|
||||
connect(designerPropertyEditor, SIGNAL(propertyValueChanged(QString,QVariant,bool)), this, SLOT(updateProperty(QString,QVariant,bool)));
|
||||
connect(designerPropertyEditor, SIGNAL(resetProperty(QString)), this, SLOT(resetProperty(QString)));
|
||||
connect(designerPropertyEditor, SIGNAL(addDynamicProperty(QString,QVariant)),
|
||||
this, SLOT(addDynamicProperty(QString,QVariant)));
|
||||
connect(designerPropertyEditor, SIGNAL(removeDynamicProperty(QString)),
|
||||
this, SLOT(removeDynamicProperty(QString)));
|
||||
} else {
|
||||
connect(core()->propertyEditor(), SIGNAL(propertyChanged(QString,QVariant)),
|
||||
this, SLOT(updatePropertyPrivate(QString,QVariant)));
|
||||
}
|
||||
|
||||
connect(core()->formWindowManager(), SIGNAL(formWindowAdded(QDesignerFormWindowInterface*)),
|
||||
this, SLOT(setupFormWindow(QDesignerFormWindowInterface*)));
|
||||
|
||||
connect(core()->formWindowManager(), SIGNAL(activeFormWindowChanged(QDesignerFormWindowInterface*)),
|
||||
this, SLOT(updateActiveFormWindow(QDesignerFormWindowInterface*)));
|
||||
|
||||
m_d->m_gradientManager = new QtGradientManager(this);
|
||||
core()->setGradientManager(m_d->m_gradientManager);
|
||||
|
||||
QString designerFolder = QDir::homePath();
|
||||
designerFolder += QDir::separator();
|
||||
designerFolder += QLatin1String(".designer");
|
||||
m_d->m_gradientsPath = designerFolder;
|
||||
m_d->m_gradientsPath += QDir::separator();
|
||||
m_d->m_gradientsPath += QLatin1String("gradients.xml");
|
||||
|
||||
QFile f(m_d->m_gradientsPath);
|
||||
if (f.open(QIODevice::ReadOnly)) {
|
||||
QtGradientUtils::restoreState(m_d->m_gradientManager, QString::fromAscii(f.readAll()));
|
||||
f.close();
|
||||
} else {
|
||||
QFile defaultGradients(QLatin1String(":/trolltech/designer/defaultgradients.xml"));
|
||||
if (defaultGradients.open(QIODevice::ReadOnly)) {
|
||||
QtGradientUtils::restoreState(m_d->m_gradientManager, QString::fromAscii(defaultGradients.readAll()));
|
||||
defaultGradients.close();
|
||||
}
|
||||
}
|
||||
|
||||
if (WidgetDataBase *widgetDataBase = qobject_cast<WidgetDataBase*>(core()->widgetDataBase()))
|
||||
widgetDataBase->grabStandardWidgetBoxIcons();
|
||||
}
|
||||
|
||||
void QDesignerIntegration::updateProperty(const QString &name, const QVariant &value, bool enableSubPropertyHandling)
|
||||
{
|
||||
QDesignerFormWindowInterface *formWindow = core()->formWindowManager()->activeFormWindow();
|
||||
if (!formWindow)
|
||||
return;
|
||||
|
||||
Selection selection;
|
||||
getSelection(selection);
|
||||
if (selection.empty())
|
||||
return;
|
||||
|
||||
SetPropertyCommand *cmd = new SetPropertyCommand(formWindow);
|
||||
// find a reference object to compare to and to find the right group
|
||||
if (cmd->init(selection.selection(), name, value, propertyEditorObject(), enableSubPropertyHandling)) {
|
||||
formWindow->commandHistory()->push(cmd);
|
||||
} else {
|
||||
delete cmd;
|
||||
qDebug() << "Unable to set property " << name << '.';
|
||||
}
|
||||
|
||||
emit propertyChanged(formWindow, name, value);
|
||||
}
|
||||
|
||||
void QDesignerIntegration::updatePropertyPrivate(const QString &name, const QVariant &value)
|
||||
{
|
||||
updateProperty(name, value, true);
|
||||
}
|
||||
|
||||
void QDesignerIntegration::resetProperty(const QString &name)
|
||||
{
|
||||
QDesignerFormWindowInterface *formWindow = core()->formWindowManager()->activeFormWindow();
|
||||
if (!formWindow)
|
||||
return;
|
||||
|
||||
Selection selection;
|
||||
getSelection(selection);
|
||||
if (selection.empty())
|
||||
return;
|
||||
|
||||
|
||||
ResetPropertyCommand *cmd = new ResetPropertyCommand(formWindow);
|
||||
// find a reference object to find the right group
|
||||
if (cmd->init(selection.selection(), name, propertyEditorObject())) {
|
||||
formWindow->commandHistory()->push(cmd);
|
||||
} else {
|
||||
delete cmd;
|
||||
qDebug() << "** WARNING Unable to reset property " << name << '.';
|
||||
}
|
||||
}
|
||||
|
||||
void QDesignerIntegration::addDynamicProperty(const QString &name, const QVariant &value)
|
||||
{
|
||||
QDesignerFormWindowInterface *formWindow = core()->formWindowManager()->activeFormWindow();
|
||||
if (!formWindow)
|
||||
return;
|
||||
|
||||
Selection selection;
|
||||
getSelection(selection);
|
||||
if (selection.empty())
|
||||
return;
|
||||
|
||||
AddDynamicPropertyCommand *cmd = new AddDynamicPropertyCommand(formWindow);
|
||||
if (cmd->init(selection.selection(), propertyEditorObject(), name, value)) {
|
||||
formWindow->commandHistory()->push(cmd);
|
||||
} else {
|
||||
delete cmd;
|
||||
qDebug() << "** WARNING Unable to add dynamic property " << name << '.';
|
||||
}
|
||||
}
|
||||
|
||||
void QDesignerIntegration::removeDynamicProperty(const QString &name)
|
||||
{
|
||||
QDesignerFormWindowInterface *formWindow = core()->formWindowManager()->activeFormWindow();
|
||||
if (!formWindow)
|
||||
return;
|
||||
|
||||
Selection selection;
|
||||
getSelection(selection);
|
||||
if (selection.empty())
|
||||
return;
|
||||
|
||||
RemoveDynamicPropertyCommand *cmd = new RemoveDynamicPropertyCommand(formWindow);
|
||||
if (cmd->init(selection.selection(), propertyEditorObject(), name)) {
|
||||
formWindow->commandHistory()->push(cmd);
|
||||
} else {
|
||||
delete cmd;
|
||||
qDebug() << "** WARNING Unable to remove dynamic property " << name << '.';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void QDesignerIntegration::updateActiveFormWindow(QDesignerFormWindowInterface *formWindow)
|
||||
{
|
||||
Q_UNUSED(formWindow);
|
||||
updateSelection();
|
||||
}
|
||||
|
||||
void QDesignerIntegration::setupFormWindow(QDesignerFormWindowInterface *formWindow)
|
||||
{
|
||||
connect(formWindow, SIGNAL(selectionChanged()), this, SLOT(updateSelection()));
|
||||
connect(formWindow, SIGNAL(activated(QWidget*)), this, SLOT(activateWidget(QWidget*)));
|
||||
}
|
||||
|
||||
void QDesignerIntegration::updateGeometry()
|
||||
{
|
||||
}
|
||||
|
||||
void QDesignerIntegration::updateSelection()
|
||||
{
|
||||
QDesignerFormWindowInterface *formWindow = core()->formWindowManager()->activeFormWindow();
|
||||
QWidget *selection = 0;
|
||||
|
||||
if (formWindow) {
|
||||
selection = formWindow->cursor()->current();
|
||||
}
|
||||
|
||||
if (QDesignerActionEditorInterface *actionEditor = core()->actionEditor())
|
||||
actionEditor->setFormWindow(formWindow);
|
||||
|
||||
if (QDesignerPropertyEditorInterface *propertyEditor = core()->propertyEditor())
|
||||
propertyEditor->setObject(selection);
|
||||
|
||||
if (QDesignerObjectInspectorInterface *objectInspector = core()->objectInspector())
|
||||
objectInspector->setFormWindow(formWindow);
|
||||
|
||||
}
|
||||
|
||||
void QDesignerIntegration::activateWidget(QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(widget);
|
||||
}
|
||||
|
||||
QWidget *QDesignerIntegration::containerWindow(QWidget *widget) const
|
||||
{
|
||||
// Find the parent window to apply a geometry to.
|
||||
while (widget) {
|
||||
if (widget->isWindow())
|
||||
break;
|
||||
if (!qstrcmp(widget->metaObject()->className(), "QMdiSubWindow"))
|
||||
break;
|
||||
|
||||
widget = widget->parentWidget();
|
||||
}
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
void QDesignerIntegration::getSelection(Selection &s)
|
||||
{
|
||||
// Get multiselection from object inspector
|
||||
if (QDesignerObjectInspector *designerObjectInspector = qobject_cast<QDesignerObjectInspector *>(core()->objectInspector())) {
|
||||
designerObjectInspector->getSelection(s);
|
||||
// Action editor puts actions that are not on the form yet
|
||||
// into the property editor only.
|
||||
if (s.empty())
|
||||
if (QObject *object = core()->propertyEditor()->object())
|
||||
s.objects.push_back(object);
|
||||
|
||||
} else {
|
||||
// Just in case someone plugs in an old-style object inspector: Emulate selection
|
||||
s.clear();
|
||||
QDesignerFormWindowInterface *formWindow = core()->formWindowManager()->activeFormWindow();
|
||||
if (!formWindow)
|
||||
return;
|
||||
|
||||
QObject *object = core()->propertyEditor()->object();
|
||||
if (object->isWidgetType()) {
|
||||
QWidget *widget = static_cast<QWidget*>(object);
|
||||
QDesignerFormWindowCursorInterface *cursor = formWindow->cursor();
|
||||
if (cursor->isWidgetSelected(widget)) {
|
||||
s.managed.push_back(widget);
|
||||
} else {
|
||||
s.unmanaged.push_back(widget);
|
||||
}
|
||||
} else {
|
||||
s.objects.push_back(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QObject *QDesignerIntegration::propertyEditorObject()
|
||||
{
|
||||
QDesignerPropertyEditorInterface *propertyEditor = core()->propertyEditor();
|
||||
if (!propertyEditor)
|
||||
return 0;
|
||||
return propertyEditor->object();
|
||||
}
|
||||
|
||||
// Load plugins into widget database and factory.
|
||||
void QDesignerIntegration::initializePlugins(QDesignerFormEditorInterface *formEditor)
|
||||
{
|
||||
// load the plugins
|
||||
WidgetDataBase *widgetDataBase = qobject_cast<WidgetDataBase*>(formEditor->widgetDataBase());
|
||||
if (widgetDataBase) {
|
||||
widgetDataBase->loadPlugins();
|
||||
}
|
||||
|
||||
if (WidgetFactory *widgetFactory = qobject_cast<WidgetFactory*>(formEditor->widgetFactory())) {
|
||||
widgetFactory->loadPlugins();
|
||||
}
|
||||
|
||||
if (widgetDataBase) {
|
||||
widgetDataBase->grabDefaultPropertyValues();
|
||||
}
|
||||
}
|
||||
|
||||
void QDesignerIntegration::updateCustomWidgetPlugins()
|
||||
{
|
||||
QDesignerFormEditorInterface *formEditor = core();
|
||||
if (QDesignerPluginManager *pm = formEditor->pluginManager())
|
||||
pm->registerNewPlugins();
|
||||
|
||||
initializePlugins(formEditor);
|
||||
|
||||
// Do not just reload the last file as the WidgetBox merges the compiled-in resources
|
||||
// and $HOME/.designer/widgetbox.xml. This would also double the scratchpad.
|
||||
if (QDesignerWidgetBox *wb = qobject_cast<QDesignerWidgetBox*>(formEditor->widgetBox())) {
|
||||
const QDesignerWidgetBox::LoadMode oldLoadMode = wb->loadMode();
|
||||
wb->setLoadMode(QDesignerWidgetBox::LoadCustomWidgetsOnly);
|
||||
wb->load();
|
||||
wb->setLoadMode(oldLoadMode);
|
||||
}
|
||||
}
|
||||
|
||||
void QDesignerIntegration::emitObjectNameChanged(QDesignerFormWindowInterface *formWindow, QObject *object, const QString &newName, const QString &oldName)
|
||||
{
|
||||
emit objectNameChanged(formWindow, object, newName, oldName);
|
||||
}
|
||||
|
||||
void QDesignerIntegration::emitNavigateToSlot(const QString &objectName,
|
||||
const QString &signalSignature,
|
||||
const QStringList ¶meterNames)
|
||||
{
|
||||
emit navigateToSlot(objectName, signalSignature, parameterNames);
|
||||
}
|
||||
|
||||
void QDesignerIntegration::emitNavigateToSlot(const QString &slotSignature)
|
||||
{
|
||||
emit navigateToSlot(slotSignature);
|
||||
}
|
||||
|
||||
void QDesignerIntegration::requestHelp(const QDesignerFormEditorInterface *core, const QString &manual, const QString &document)
|
||||
{
|
||||
if (QDesignerIntegration *di = qobject_cast<QDesignerIntegration *>(core->integration()))
|
||||
emit di->helpRequested(manual, document);
|
||||
}
|
||||
|
||||
QDesignerResourceBrowserInterface *QDesignerIntegration::createResourceBrowser(QWidget *)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QDesignerIntegration::setResourceFileWatcherBehaviour(ResourceFileWatcherBehaviour behaviour)
|
||||
{
|
||||
m_d->m_fileWatcherBehaviour = behaviour;
|
||||
core()->resourceModel()->setWatcherEnabled(behaviour != QDesignerIntegration::NoWatcher);
|
||||
}
|
||||
|
||||
QDesignerIntegration::ResourceFileWatcherBehaviour QDesignerIntegration::resourceFileWatcherBehaviour() const
|
||||
{
|
||||
return m_d->m_fileWatcherBehaviour;
|
||||
}
|
||||
|
||||
void QDesignerIntegration::setResourceEditingEnabled(bool enable)
|
||||
{
|
||||
m_d->m_resourceEditingEnabled = enable;
|
||||
}
|
||||
|
||||
bool QDesignerIntegration::isResourceEditingEnabled() const
|
||||
{
|
||||
return m_d->m_resourceEditingEnabled;
|
||||
}
|
||||
|
||||
void QDesignerIntegration::setSlotNavigationEnabled(bool enable)
|
||||
{
|
||||
m_d->m_slotNavigationEnabled = enable;
|
||||
}
|
||||
|
||||
bool QDesignerIntegration::isSlotNavigationEnabled() const
|
||||
{
|
||||
return m_d->m_slotNavigationEnabled;
|
||||
}
|
||||
|
||||
static QString fixHelpClassName(const QString &className)
|
||||
{
|
||||
// ### generalize using the Widget Data Base
|
||||
if (className == QLatin1String("Line"))
|
||||
return QLatin1String("QFrame");
|
||||
if (className == QLatin1String("Spacer"))
|
||||
return QLatin1String("QSpacerItem");
|
||||
if (className == QLatin1String("QLayoutWidget"))
|
||||
return QLatin1String("QLayout");
|
||||
return className;
|
||||
}
|
||||
|
||||
// Return class in which the property is defined
|
||||
static QString classForProperty(QDesignerFormEditorInterface *core,
|
||||
QObject *object,
|
||||
const QString &property)
|
||||
{
|
||||
if (const QDesignerPropertySheetExtension *ps = qt_extension<QDesignerPropertySheetExtension *>(core->extensionManager(), object)) {
|
||||
const int index = ps->indexOf(property);
|
||||
if (index >= 0)
|
||||
return ps->propertyGroup(index);
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString QDesignerIntegration::contextHelpId() const
|
||||
{
|
||||
QObject *currentObject = core()->propertyEditor()->object();
|
||||
if (!currentObject)
|
||||
return QString();
|
||||
// Return a help index id consisting of "class::property"
|
||||
QString className;
|
||||
QString currentPropertyName = core()->propertyEditor()->currentPropertyName();
|
||||
if (!currentPropertyName.isEmpty())
|
||||
className = classForProperty(core(), currentObject, currentPropertyName);
|
||||
if (className.isEmpty()) {
|
||||
currentPropertyName.clear(); // We hit on some fake property.
|
||||
className = WidgetFactory::classNameOf(core(), currentObject);
|
||||
}
|
||||
QString helpId = fixHelpClassName(className);
|
||||
if (!currentPropertyName.isEmpty()) {
|
||||
helpId += QLatin1String("::");
|
||||
helpId += currentPropertyName;
|
||||
}
|
||||
return helpId;
|
||||
}
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
152
third/designer/lib/shared/qdesigner_integration_p.h
Normal file
152
third/designer/lib/shared/qdesigner_integration_p.h
Normal file
@@ -0,0 +1,152 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef QDESIGNER_INTEGRATION_H
|
||||
#define QDESIGNER_INTEGRATION_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
#include <QtDesigner/QDesignerIntegrationInterface>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDesignerFormEditorInterface;
|
||||
class QDesignerFormWindowInterface;
|
||||
class QDesignerResourceBrowserInterface;
|
||||
|
||||
class QVariant;
|
||||
class QWidget;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
struct Selection;
|
||||
class QDesignerIntegrationPrivate;
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT QDesignerIntegration: public QDesignerIntegrationInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QDesignerIntegration(QDesignerFormEditorInterface *core, QObject *parent = 0);
|
||||
virtual ~QDesignerIntegration();
|
||||
|
||||
static void requestHelp(const QDesignerFormEditorInterface *core, const QString &manual, const QString &document);
|
||||
|
||||
virtual QWidget *containerWindow(QWidget *widget) const;
|
||||
|
||||
// Load plugins into widget database and factory.
|
||||
static void initializePlugins(QDesignerFormEditorInterface *formEditor);
|
||||
void emitObjectNameChanged(QDesignerFormWindowInterface *formWindow, QObject *object,
|
||||
const QString &newName, const QString &oldName);
|
||||
void emitNavigateToSlot(const QString &objectName, const QString &signalSignature, const QStringList ¶meterNames);
|
||||
void emitNavigateToSlot(const QString &slotSignature);
|
||||
|
||||
// Create a resource browser specific to integration. Language integration takes precedence
|
||||
virtual QDesignerResourceBrowserInterface *createResourceBrowser(QWidget *parent = 0);
|
||||
|
||||
enum ResourceFileWatcherBehaviour {
|
||||
NoWatcher,
|
||||
ReloadSilently,
|
||||
PromptAndReload
|
||||
};
|
||||
|
||||
ResourceFileWatcherBehaviour resourceFileWatcherBehaviour() const;
|
||||
bool isResourceEditingEnabled() const;
|
||||
bool isSlotNavigationEnabled() const;
|
||||
|
||||
QString contextHelpId() const;
|
||||
|
||||
protected:
|
||||
|
||||
void setResourceFileWatcherBehaviour(ResourceFileWatcherBehaviour behaviour); // PromptAndReload by default
|
||||
void setResourceEditingEnabled(bool enable); // true by default
|
||||
void setSlotNavigationEnabled(bool enable); // false by default
|
||||
|
||||
signals:
|
||||
void propertyChanged(QDesignerFormWindowInterface *formWindow, const QString &name, const QVariant &value);
|
||||
void objectNameChanged(QDesignerFormWindowInterface *formWindow, QObject *object, const QString &newName, const QString &oldName);
|
||||
void helpRequested(const QString &manual, const QString &document);
|
||||
|
||||
void navigateToSlot(const QString &objectName, const QString &signalSignature, const QStringList ¶meterNames);
|
||||
void navigateToSlot(const QString &slotSignature);
|
||||
|
||||
public slots:
|
||||
virtual void updateProperty(const QString &name, const QVariant &value, bool enableSubPropertyHandling);
|
||||
// Additional signals of designer property editor
|
||||
virtual void resetProperty(const QString &name);
|
||||
virtual void addDynamicProperty(const QString &name, const QVariant &value);
|
||||
virtual void removeDynamicProperty(const QString &name);
|
||||
|
||||
virtual void updateActiveFormWindow(QDesignerFormWindowInterface *formWindow);
|
||||
virtual void setupFormWindow(QDesignerFormWindowInterface *formWindow);
|
||||
virtual void updateSelection();
|
||||
virtual void updateGeometry();
|
||||
virtual void activateWidget(QWidget *widget);
|
||||
|
||||
void updateCustomWidgetPlugins();
|
||||
|
||||
private slots:
|
||||
void updatePropertyPrivate(const QString &name, const QVariant &value);
|
||||
|
||||
private:
|
||||
void initialize();
|
||||
void getSelection(Selection &s);
|
||||
QObject *propertyEditorObject();
|
||||
|
||||
QDesignerIntegrationPrivate *m_d;
|
||||
};
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QDESIGNER_INTEGRATION_H
|
||||
372
third/designer/lib/shared/qdesigner_introspection.cpp
Normal file
372
third/designer/lib/shared/qdesigner_introspection.cpp
Normal file
@@ -0,0 +1,372 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qdesigner_introspection_p.h"
|
||||
|
||||
#include <QtCore/QMetaObject>
|
||||
#include <QtCore/QMetaEnum>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVector>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
// Qt Implementation
|
||||
static QStringList byteArrayListToStringList(const QList<QByteArray> &l)
|
||||
{
|
||||
if (l.empty())
|
||||
return QStringList();
|
||||
QStringList rc;
|
||||
const QList<QByteArray>::const_iterator cend = l.constEnd();
|
||||
for (QList<QByteArray>::const_iterator it = l.constBegin(); it != cend; ++it)
|
||||
rc += QString::fromUtf8(*it);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline QString charToQString(const char *c)
|
||||
{
|
||||
if (!c)
|
||||
return QString();
|
||||
return QString::fromUtf8(c);
|
||||
}
|
||||
|
||||
namespace {
|
||||
// ------- QDesignerMetaEnum
|
||||
class QDesignerMetaEnum : public QDesignerMetaEnumInterface {
|
||||
public:
|
||||
QDesignerMetaEnum(const QMetaEnum &qEnum);
|
||||
virtual bool isFlag() const { return m_enum.isFlag(); }
|
||||
virtual QString key(int index) const { return charToQString(m_enum.key(index)); }
|
||||
virtual int keyCount() const { return m_enum.keyCount(); }
|
||||
virtual int keyToValue(const QString &key) const { return m_enum.keyToValue(key.toUtf8()); }
|
||||
virtual int keysToValue(const QString &keys) const { return m_enum.keysToValue(keys.toUtf8()); }
|
||||
virtual QString name() const { return m_name; }
|
||||
virtual QString scope() const { return m_scope; }
|
||||
virtual QString separator() const;
|
||||
virtual int value(int index) const { return m_enum.value(index); }
|
||||
virtual QString valueToKey(int value) const { return charToQString(m_enum.valueToKey(value)); }
|
||||
virtual QString valueToKeys(int value) const { return charToQString(m_enum.valueToKeys(value)); }
|
||||
|
||||
private:
|
||||
const QMetaEnum m_enum;
|
||||
const QString m_name;
|
||||
const QString m_scope;
|
||||
};
|
||||
|
||||
QDesignerMetaEnum::QDesignerMetaEnum(const QMetaEnum &qEnum) :
|
||||
m_enum(qEnum),
|
||||
m_name(charToQString(m_enum.name())),
|
||||
m_scope(charToQString(m_enum.scope()))
|
||||
{
|
||||
}
|
||||
|
||||
QString QDesignerMetaEnum::separator() const
|
||||
{
|
||||
static const QString rc = QLatin1String("::");
|
||||
return rc;
|
||||
}
|
||||
|
||||
// ------- QDesignerMetaProperty
|
||||
class QDesignerMetaProperty : public QDesignerMetaPropertyInterface {
|
||||
public:
|
||||
QDesignerMetaProperty(const QMetaProperty &property);
|
||||
virtual ~QDesignerMetaProperty();
|
||||
|
||||
virtual const QDesignerMetaEnumInterface *enumerator() const { return m_enumerator; }
|
||||
|
||||
virtual Kind kind() const { return m_kind; }
|
||||
|
||||
virtual AccessFlags accessFlags() const { return m_access; }
|
||||
virtual Attributes attributes(const QObject *object = 0) const;
|
||||
|
||||
virtual QVariant::Type type() const { return m_property.type(); }
|
||||
virtual QString name() const { return m_name; }
|
||||
virtual QString typeName() const { return m_typeName; }
|
||||
virtual int userType() const { return m_property.userType(); }
|
||||
virtual bool hasSetter() const { return m_property.hasStdCppSet(); }
|
||||
|
||||
virtual QVariant read(const QObject *object) const { return m_property.read(object); }
|
||||
virtual bool reset(QObject *object) const { return m_property.reset(object); }
|
||||
virtual bool write(QObject *object, const QVariant &value) const { return m_property.write(object, value); }
|
||||
|
||||
private:
|
||||
const QMetaProperty m_property;
|
||||
const QString m_name;
|
||||
const QString m_typeName;
|
||||
Kind m_kind;
|
||||
AccessFlags m_access;
|
||||
Attributes m_defaultAttributes;
|
||||
QDesignerMetaEnumInterface *m_enumerator;
|
||||
};
|
||||
|
||||
QDesignerMetaProperty::QDesignerMetaProperty(const QMetaProperty &property) :
|
||||
m_property(property),
|
||||
m_name(charToQString(m_property.name())),
|
||||
m_typeName(charToQString(m_property.typeName())),
|
||||
m_kind(OtherKind),
|
||||
m_enumerator(0)
|
||||
{
|
||||
if (m_property.isFlagType() || m_property.isEnumType()) {
|
||||
const QMetaEnum metaEnum = m_property.enumerator();
|
||||
Q_ASSERT(metaEnum.isValid());
|
||||
m_enumerator = new QDesignerMetaEnum(metaEnum);
|
||||
}
|
||||
// kind
|
||||
if (m_property.isFlagType())
|
||||
m_kind = FlagKind;
|
||||
else
|
||||
if (m_property.isEnumType())
|
||||
m_kind = EnumKind;
|
||||
// flags and attributes
|
||||
if (m_property.isReadable())
|
||||
m_access |= ReadAccess;
|
||||
if (m_property.isWritable())
|
||||
m_access |= WriteAccess;
|
||||
if (m_property.isResettable())
|
||||
m_access |= ResetAccess;
|
||||
|
||||
if (m_property.isDesignable())
|
||||
m_defaultAttributes |= DesignableAttribute;
|
||||
if (m_property.isScriptable())
|
||||
m_defaultAttributes |= ScriptableAttribute;
|
||||
if (m_property.isStored())
|
||||
m_defaultAttributes |= StoredAttribute;
|
||||
if (m_property.isUser())
|
||||
m_defaultAttributes |= UserAttribute;
|
||||
}
|
||||
|
||||
QDesignerMetaProperty::~QDesignerMetaProperty()
|
||||
{
|
||||
delete m_enumerator;
|
||||
}
|
||||
|
||||
QDesignerMetaProperty::Attributes QDesignerMetaProperty::attributes(const QObject *object) const
|
||||
{
|
||||
if (!object)
|
||||
return m_defaultAttributes;
|
||||
Attributes rc;
|
||||
if (m_property.isDesignable(object))
|
||||
rc |= DesignableAttribute;
|
||||
if (m_property.isScriptable(object))
|
||||
rc |= ScriptableAttribute;
|
||||
if (m_property.isStored(object))
|
||||
rc |= StoredAttribute;
|
||||
if (m_property.isUser(object))
|
||||
rc |= UserAttribute;
|
||||
return rc;
|
||||
}
|
||||
|
||||
// -------------- QDesignerMetaMethod
|
||||
|
||||
class QDesignerMetaMethod : public QDesignerMetaMethodInterface {
|
||||
public:
|
||||
QDesignerMetaMethod(const QMetaMethod &method);
|
||||
|
||||
virtual Access access() const { return m_access; }
|
||||
virtual MethodType methodType() const { return m_methodType; }
|
||||
virtual QStringList parameterNames() const { return m_parameterNames; }
|
||||
virtual QStringList parameterTypes() const { return m_parameterTypes; }
|
||||
virtual QString signature() const { return m_signature; }
|
||||
virtual QString normalizedSignature() const { return m_normalizedSignature; }
|
||||
virtual QString tag() const { return m_tag; }
|
||||
virtual QString typeName() const { return m_typeName; }
|
||||
|
||||
private:
|
||||
Access m_access;
|
||||
MethodType m_methodType;
|
||||
const QStringList m_parameterNames;
|
||||
const QStringList m_parameterTypes;
|
||||
const QString m_signature;
|
||||
const QString m_normalizedSignature;
|
||||
const QString m_tag;
|
||||
const QString m_typeName;
|
||||
};
|
||||
|
||||
QDesignerMetaMethod::QDesignerMetaMethod(const QMetaMethod &method) :
|
||||
m_parameterNames(byteArrayListToStringList(method.parameterNames())),
|
||||
m_parameterTypes(byteArrayListToStringList(method.parameterTypes())),
|
||||
m_signature(charToQString(method.signature())),
|
||||
m_normalizedSignature(charToQString(QMetaObject::normalizedSignature(method.signature()))),
|
||||
m_tag(charToQString(method.tag())),
|
||||
m_typeName(charToQString(method.typeName()))
|
||||
{
|
||||
switch (method.access()) {
|
||||
case QMetaMethod::Public:
|
||||
m_access = Public;
|
||||
break;
|
||||
case QMetaMethod::Protected:
|
||||
m_access = Protected;
|
||||
break;
|
||||
case QMetaMethod::Private:
|
||||
m_access = Private;
|
||||
break;
|
||||
|
||||
}
|
||||
switch (method.methodType()) {
|
||||
case QMetaMethod::Constructor:
|
||||
m_methodType = Constructor;
|
||||
break;
|
||||
case QMetaMethod::Method:
|
||||
m_methodType = Method;
|
||||
break;
|
||||
case QMetaMethod::Signal:
|
||||
m_methodType = Signal;
|
||||
break;
|
||||
|
||||
case QMetaMethod::Slot:
|
||||
m_methodType = Slot;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------- QDesignerMetaObject
|
||||
class QDesignerMetaObject : public QDesignerMetaObjectInterface {
|
||||
public:
|
||||
QDesignerMetaObject(const qdesigner_internal::QDesignerIntrospection *introspection, const QMetaObject *metaObject);
|
||||
virtual ~QDesignerMetaObject();
|
||||
|
||||
virtual QString className() const { return m_className; }
|
||||
virtual const QDesignerMetaEnumInterface *enumerator(int index) const { return m_enumerators[index]; }
|
||||
virtual int enumeratorCount() const { return m_enumerators.size(); }
|
||||
virtual int enumeratorOffset() const { return m_metaObject->enumeratorOffset(); }
|
||||
|
||||
virtual int indexOfEnumerator(const QString &name) const { return m_metaObject->indexOfEnumerator(name.toUtf8()); }
|
||||
virtual int indexOfMethod(const QString &method) const { return m_metaObject->indexOfMethod(method.toUtf8()); }
|
||||
virtual int indexOfProperty(const QString &name) const { return m_metaObject->indexOfProperty(name.toUtf8()); }
|
||||
virtual int indexOfSignal(const QString &signal) const { return m_metaObject->indexOfSignal(signal.toUtf8()); }
|
||||
virtual int indexOfSlot(const QString &slot) const { return m_metaObject->indexOfSlot(slot.toUtf8()); }
|
||||
|
||||
virtual const QDesignerMetaMethodInterface *method(int index) const { return m_methods[index]; }
|
||||
virtual int methodCount() const { return m_methods.size(); }
|
||||
virtual int methodOffset() const { return m_metaObject->methodOffset(); }
|
||||
|
||||
virtual const QDesignerMetaPropertyInterface *property(int index) const { return m_properties[index]; }
|
||||
virtual int propertyCount() const { return m_properties.size(); }
|
||||
virtual int propertyOffset() const { return m_metaObject->propertyOffset(); }
|
||||
|
||||
const QDesignerMetaObjectInterface *superClass() const;
|
||||
virtual const QDesignerMetaPropertyInterface *userProperty() const { return m_userProperty; }
|
||||
|
||||
private:
|
||||
const QString m_className;
|
||||
const qdesigner_internal::QDesignerIntrospection *m_introspection;
|
||||
const QMetaObject *m_metaObject;
|
||||
|
||||
typedef QVector<QDesignerMetaEnumInterface *> Enumerators;
|
||||
Enumerators m_enumerators;
|
||||
|
||||
typedef QVector<QDesignerMetaMethodInterface *> Methods;
|
||||
Methods m_methods;
|
||||
|
||||
typedef QVector<QDesignerMetaPropertyInterface *> Properties;
|
||||
Properties m_properties;
|
||||
|
||||
QDesignerMetaPropertyInterface *m_userProperty;
|
||||
};
|
||||
|
||||
QDesignerMetaObject::QDesignerMetaObject(const qdesigner_internal::QDesignerIntrospection *introspection, const QMetaObject *metaObject) :
|
||||
m_className(charToQString(metaObject->className())),
|
||||
m_introspection(introspection),
|
||||
m_metaObject(metaObject),
|
||||
m_userProperty(0)
|
||||
{
|
||||
const int numEnumerators = metaObject->enumeratorCount();
|
||||
m_enumerators.reserve(numEnumerators);
|
||||
for (int i = 0; i < numEnumerators; i++)
|
||||
m_enumerators.push_back(new QDesignerMetaEnum(metaObject->enumerator(i)));
|
||||
const int numMethods = metaObject->methodCount();
|
||||
m_methods.reserve(numMethods);
|
||||
for (int i = 0; i < numMethods; i++)
|
||||
m_methods.push_back(new QDesignerMetaMethod(metaObject->method(i)));
|
||||
|
||||
const int numProperties = metaObject->propertyCount();
|
||||
m_properties.reserve(numProperties);
|
||||
for (int i = 0; i < numProperties; i++)
|
||||
m_properties.push_back(new QDesignerMetaProperty(metaObject->property(i)));
|
||||
|
||||
const QMetaProperty userProperty = metaObject->userProperty();
|
||||
if (userProperty.isValid())
|
||||
m_userProperty = new QDesignerMetaProperty(userProperty);
|
||||
}
|
||||
|
||||
QDesignerMetaObject::~QDesignerMetaObject()
|
||||
{
|
||||
qDeleteAll(m_enumerators);
|
||||
qDeleteAll(m_methods);
|
||||
qDeleteAll(m_properties);
|
||||
delete m_userProperty;
|
||||
}
|
||||
|
||||
const QDesignerMetaObjectInterface *QDesignerMetaObject::superClass() const
|
||||
{
|
||||
const QMetaObject *qSuperClass = m_metaObject->superClass();
|
||||
if (!qSuperClass)
|
||||
return 0;
|
||||
return m_introspection->metaObjectForQMetaObject(qSuperClass);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
QDesignerIntrospection::QDesignerIntrospection()
|
||||
{
|
||||
}
|
||||
|
||||
QDesignerIntrospection::~QDesignerIntrospection()
|
||||
{
|
||||
qDeleteAll(m_metaObjectMap.values());
|
||||
}
|
||||
|
||||
const QDesignerMetaObjectInterface* QDesignerIntrospection::metaObject(const QObject *object) const
|
||||
{
|
||||
return metaObjectForQMetaObject(object->metaObject());
|
||||
}
|
||||
|
||||
const QDesignerMetaObjectInterface* QDesignerIntrospection::metaObjectForQMetaObject(const QMetaObject *metaObject) const
|
||||
{
|
||||
MetaObjectMap::iterator it = m_metaObjectMap.find(metaObject);
|
||||
if (it == m_metaObjectMap.end())
|
||||
it = m_metaObjectMap.insert(metaObject, new QDesignerMetaObject(this, metaObject));
|
||||
return it.value();
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
84
third/designer/lib/shared/qdesigner_introspection_p.h
Normal file
84
third/designer/lib/shared/qdesigner_introspection_p.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef DESIGNERINTROSPECTION
|
||||
#define DESIGNERINTROSPECTION
|
||||
|
||||
#include "shared_global_p.h"
|
||||
#include <abstractintrospection_p.h>
|
||||
#include <QtCore/QMap>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
struct QMetaObject;
|
||||
class QWidget;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
// Qt C++ introspection with helpers to find core and meta object for an object
|
||||
class QDESIGNER_SHARED_EXPORT QDesignerIntrospection : public QDesignerIntrospectionInterface {
|
||||
public:
|
||||
QDesignerIntrospection();
|
||||
virtual ~QDesignerIntrospection();
|
||||
|
||||
virtual const QDesignerMetaObjectInterface* metaObject(const QObject *object) const;
|
||||
|
||||
const QDesignerMetaObjectInterface* metaObjectForQMetaObject(const QMetaObject *metaObject) const;
|
||||
private:
|
||||
typedef QMap<const QMetaObject*, QDesignerMetaObjectInterface*> MetaObjectMap;
|
||||
mutable MetaObjectMap m_metaObjectMap;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // DESIGNERINTROSPECTION
|
||||
371
third/designer/lib/shared/qdesigner_membersheet.cpp
Normal file
371
third/designer/lib/shared/qdesigner_membersheet.cpp
Normal file
@@ -0,0 +1,371 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qdesigner_membersheet_p.h"
|
||||
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
#include <abstractintrospection_p.h>
|
||||
|
||||
#include <QtGui/QWidget>
|
||||
|
||||
namespace {
|
||||
|
||||
class Qt3Members
|
||||
{
|
||||
public:
|
||||
static Qt3Members *instance();
|
||||
QMap<QString, QStringList> getSignals() const { return m_classNameToSignals; }
|
||||
QMap<QString, QStringList> getSlots() const { return m_classNameToSlots; }
|
||||
private:
|
||||
Qt3Members();
|
||||
static Qt3Members *m_instance;
|
||||
QMap<QString, QStringList> m_classNameToSignals;
|
||||
QMap<QString, QStringList> m_classNameToSlots;
|
||||
};
|
||||
|
||||
Qt3Members *Qt3Members::m_instance = 0;
|
||||
|
||||
Qt3Members::Qt3Members()
|
||||
{
|
||||
m_classNameToSignals[QLatin1String("QTextEdit")].append(QLatin1String("currentFontChanged(QFont)"));
|
||||
m_classNameToSignals[QLatin1String("QTextEdit")].append(QLatin1String("currentColorChanged(QColor)"));
|
||||
m_classNameToSignals[QLatin1String("QTabWidget")].append(QLatin1String("currentChanged(QWidget*)"));
|
||||
m_classNameToSignals[QLatin1String("QTabWidget")].append(QLatin1String("selected(QString)"));
|
||||
m_classNameToSignals[QLatin1String("QTabBar")].append(QLatin1String("selected(int)"));
|
||||
m_classNameToSignals[QLatin1String("QMenuBar")].append(QLatin1String("activated(int)"));
|
||||
m_classNameToSignals[QLatin1String("QMenuBar")].append(QLatin1String("highlighted(int)"));
|
||||
m_classNameToSignals[QLatin1String("QMenu")].append(QLatin1String("activated(int)"));
|
||||
m_classNameToSignals[QLatin1String("QMenu")].append(QLatin1String("highlighted(int)"));
|
||||
m_classNameToSignals[QLatin1String("QLineEdit")].append(QLatin1String("lostFocus()"));
|
||||
m_classNameToSignals[QLatin1String("QDial")].append(QLatin1String("dialPressed()"));
|
||||
m_classNameToSignals[QLatin1String("QDial")].append(QLatin1String("dialMoved(int)"));
|
||||
m_classNameToSignals[QLatin1String("QDial")].append(QLatin1String("dialReleased()"));
|
||||
m_classNameToSignals[QLatin1String("QComboBox")].append(QLatin1String("textChanged(QString)"));
|
||||
m_classNameToSignals[QLatin1String("QActionGroup")].append(QLatin1String("selected(QAction*)"));
|
||||
m_classNameToSignals[QLatin1String("QAction")].append(QLatin1String("activated(int)"));
|
||||
m_classNameToSignals[QLatin1String("QAbstractSocket")].append(QLatin1String("connectionClosed()"));
|
||||
m_classNameToSignals[QLatin1String("QAbstractSocket")].append(QLatin1String("delayedCloseFinished()"));
|
||||
|
||||
m_classNameToSlots[QLatin1String("QWidget")].append(QLatin1String("setShown(bool)"));
|
||||
m_classNameToSlots[QLatin1String("QToolButton")].append(QLatin1String("setTextPosition(QToolButton::TextPosition)"));
|
||||
m_classNameToSlots[QLatin1String("QToolButton")].append(QLatin1String("setUsesBigPixmap(bool)"));
|
||||
m_classNameToSlots[QLatin1String("QToolButton")].append(QLatin1String("setUsesTextLabel(bool)"));
|
||||
m_classNameToSlots[QLatin1String("QTextEdit")].append(QLatin1String("setModified(bool)"));
|
||||
m_classNameToSlots[QLatin1String("QTextEdit")].append(QLatin1String("setColor(QColor)"));
|
||||
m_classNameToSlots[QLatin1String("QTabWidget")].append(QLatin1String("setCurrentPage(int)"));
|
||||
m_classNameToSlots[QLatin1String("QTabWidget")].append(QLatin1String("showPage(QWidget*)"));
|
||||
m_classNameToSlots[QLatin1String("QTabWidget")].append(QLatin1String("removePage(QWidget*)"));
|
||||
m_classNameToSlots[QLatin1String("QTabBar")].append(QLatin1String("setCurrentTab(int)"));
|
||||
m_classNameToSlots[QLatin1String("QStatusBar")].append(QLatin1String("message(QString,int)"));
|
||||
m_classNameToSlots[QLatin1String("QStatusBar")].append(QLatin1String("clear()"));
|
||||
m_classNameToSlots[QLatin1String("QSplashScreen")].append(QLatin1String("message(QString,int)"));
|
||||
m_classNameToSlots[QLatin1String("QSplashScreen")].append(QLatin1String("clear()"));
|
||||
m_classNameToSlots[QLatin1String("QSlider")].append(QLatin1String("addStep()"));
|
||||
m_classNameToSlots[QLatin1String("QSlider")].append(QLatin1String("subtractStep()"));
|
||||
m_classNameToSlots[QLatin1String("QAbstractButton")].append(QLatin1String("setOn(bool)"));
|
||||
m_classNameToSlots[QLatin1String("QAction")].append(QLatin1String("setOn(bool)"));
|
||||
m_classNameToSlots[QLatin1String("QErrorMessage")].append(QLatin1String("message(QString)"));
|
||||
m_classNameToSlots[QLatin1String("QTimer")].append(QLatin1String("changeInterval(int)"));
|
||||
m_classNameToSlots[QLatin1String("QTimer")].append(QLatin1String("start(int,bool)"));
|
||||
}
|
||||
|
||||
Qt3Members *Qt3Members::instance()
|
||||
{
|
||||
if (!m_instance)
|
||||
m_instance = new Qt3Members();
|
||||
return m_instance;
|
||||
}
|
||||
}
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static QList<QByteArray> stringListToByteArray(const QStringList &l)
|
||||
{
|
||||
if (l.empty())
|
||||
return QList<QByteArray>();
|
||||
QList<QByteArray> rc;
|
||||
const QStringList::const_iterator cend = l.constEnd();
|
||||
for (QStringList::const_iterator it = l.constBegin(); it != cend; ++it)
|
||||
rc += it->toUtf8();
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Find the form editor in the hierarchy.
|
||||
// We know that the parent of the sheet is the extension manager
|
||||
// whose parent is the core.
|
||||
|
||||
static QDesignerFormEditorInterface *formEditorForObject(QObject *o) {
|
||||
do {
|
||||
if (QDesignerFormEditorInterface* core = qobject_cast<QDesignerFormEditorInterface*>(o))
|
||||
return core;
|
||||
o = o->parent();
|
||||
} while(o);
|
||||
Q_ASSERT(o);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ------------ QDesignerMemberSheetPrivate
|
||||
class QDesignerMemberSheetPrivate {
|
||||
public:
|
||||
explicit QDesignerMemberSheetPrivate(QObject *object, QObject *sheetParent);
|
||||
|
||||
QDesignerFormEditorInterface *m_core;
|
||||
const QDesignerMetaObjectInterface *m_meta;
|
||||
|
||||
class Info {
|
||||
public:
|
||||
inline Info() : visible(true) {}
|
||||
|
||||
QString group;
|
||||
bool visible;
|
||||
};
|
||||
|
||||
typedef QHash<int, Info> InfoHash;
|
||||
|
||||
Info &ensureInfo(int index);
|
||||
|
||||
InfoHash m_info;
|
||||
};
|
||||
|
||||
QDesignerMemberSheetPrivate::QDesignerMemberSheetPrivate(QObject *object, QObject *sheetParent) :
|
||||
m_core(formEditorForObject(sheetParent)),
|
||||
m_meta(m_core->introspection()->metaObject(object))
|
||||
{
|
||||
}
|
||||
|
||||
QDesignerMemberSheetPrivate::Info &QDesignerMemberSheetPrivate::ensureInfo(int index)
|
||||
{
|
||||
InfoHash::iterator it = m_info.find(index);
|
||||
if (it == m_info.end()) {
|
||||
it = m_info.insert(index, Info());
|
||||
}
|
||||
return it.value();
|
||||
}
|
||||
|
||||
// --------- QDesignerMemberSheet
|
||||
|
||||
QDesignerMemberSheet::QDesignerMemberSheet(QObject *object, QObject *parent) :
|
||||
QObject(parent),
|
||||
d(new QDesignerMemberSheetPrivate(object, parent))
|
||||
{
|
||||
}
|
||||
|
||||
QDesignerMemberSheet::~QDesignerMemberSheet()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
int QDesignerMemberSheet::count() const
|
||||
{
|
||||
return d->m_meta->methodCount();
|
||||
}
|
||||
|
||||
int QDesignerMemberSheet::indexOf(const QString &name) const
|
||||
{
|
||||
return d->m_meta->indexOfMethod(name);
|
||||
}
|
||||
|
||||
QString QDesignerMemberSheet::memberName(int index) const
|
||||
{
|
||||
return d->m_meta->method(index)->tag();
|
||||
}
|
||||
|
||||
QString QDesignerMemberSheet::declaredInClass(int index) const
|
||||
{
|
||||
const QString member = d->m_meta->method(index)->signature();
|
||||
|
||||
// Find class whose superclass does not contain the method.
|
||||
const QDesignerMetaObjectInterface *meta_obj = d->m_meta;
|
||||
|
||||
for (;;) {
|
||||
const QDesignerMetaObjectInterface *tmp = meta_obj->superClass();
|
||||
if (tmp == 0)
|
||||
break;
|
||||
if (tmp->indexOfMethod(member) == -1)
|
||||
break;
|
||||
meta_obj = tmp;
|
||||
}
|
||||
return meta_obj->className();
|
||||
}
|
||||
|
||||
QString QDesignerMemberSheet::memberGroup(int index) const
|
||||
{
|
||||
return d->m_info.value(index).group;
|
||||
}
|
||||
|
||||
void QDesignerMemberSheet::setMemberGroup(int index, const QString &group)
|
||||
{
|
||||
d->ensureInfo(index).group = group;
|
||||
}
|
||||
|
||||
QString QDesignerMemberSheet::signature(int index) const
|
||||
{
|
||||
return d->m_meta->method(index)->normalizedSignature();
|
||||
}
|
||||
|
||||
bool QDesignerMemberSheet::isVisible(int index) const
|
||||
{
|
||||
typedef QDesignerMemberSheetPrivate::InfoHash InfoHash;
|
||||
const InfoHash::const_iterator it = d->m_info.constFind(index);
|
||||
if (it != d->m_info.constEnd())
|
||||
return it.value().visible;
|
||||
|
||||
return d->m_meta->method(index)->methodType() == QDesignerMetaMethodInterface::Signal
|
||||
|| d->m_meta->method(index)->access() == QDesignerMetaMethodInterface::Public;
|
||||
}
|
||||
|
||||
void QDesignerMemberSheet::setVisible(int index, bool visible)
|
||||
{
|
||||
d->ensureInfo(index).visible = visible;
|
||||
}
|
||||
|
||||
bool QDesignerMemberSheet::isSignal(int index) const
|
||||
{
|
||||
return d->m_meta->method(index)->methodType() == QDesignerMetaMethodInterface::Signal;
|
||||
}
|
||||
|
||||
bool QDesignerMemberSheet::isSlot(int index) const
|
||||
{
|
||||
return d->m_meta->method(index)->methodType() == QDesignerMetaMethodInterface::Slot;
|
||||
}
|
||||
|
||||
bool QDesignerMemberSheet::inheritedFromWidget(int index) const
|
||||
{
|
||||
const QString name = d->m_meta->method(index)->signature();
|
||||
return declaredInClass(index) == QLatin1String("QWidget") || declaredInClass(index) == QLatin1String("QObject");
|
||||
}
|
||||
|
||||
|
||||
QList<QByteArray> QDesignerMemberSheet::parameterTypes(int index) const
|
||||
{
|
||||
return stringListToByteArray(d->m_meta->method(index)->parameterTypes());
|
||||
}
|
||||
|
||||
QList<QByteArray> QDesignerMemberSheet::parameterNames(int index) const
|
||||
{
|
||||
return stringListToByteArray(d->m_meta->method(index)->parameterNames());
|
||||
}
|
||||
|
||||
bool QDesignerMemberSheet::signalMatchesSlot(const QString &signal, const QString &slot)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
do {
|
||||
int signal_idx = signal.indexOf(QLatin1Char('('));
|
||||
int slot_idx = slot.indexOf(QLatin1Char('('));
|
||||
if (signal_idx == -1 || slot_idx == -1)
|
||||
break;
|
||||
|
||||
++signal_idx; ++slot_idx;
|
||||
|
||||
if (slot.at(slot_idx) == QLatin1Char(')'))
|
||||
break;
|
||||
|
||||
while (signal_idx < signal.size() && slot_idx < slot.size()) {
|
||||
const QChar signal_c = signal.at(signal_idx);
|
||||
const QChar slot_c = slot.at(slot_idx);
|
||||
|
||||
if (signal_c == QLatin1Char(',') && slot_c == QLatin1Char(')'))
|
||||
break;
|
||||
|
||||
if (signal_c == QLatin1Char(')') && slot_c == QLatin1Char(')'))
|
||||
break;
|
||||
|
||||
if (signal_c != slot_c) {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
||||
++signal_idx; ++slot_idx;
|
||||
}
|
||||
} while (false);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool QDesignerMemberSheet::isQt3Signal(int index) const
|
||||
{
|
||||
if (!isSignal(index))
|
||||
return false;
|
||||
|
||||
const QString className = declaredInClass(index);
|
||||
const QString signalSignature = signature(index);
|
||||
|
||||
QMap<QString, QStringList> qt3signals = Qt3Members::instance()->getSignals();
|
||||
QMap<QString, QStringList>::const_iterator it = qt3signals.constFind(className);
|
||||
if (it != qt3signals.constEnd() && (*it).contains(signalSignature))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QDesignerMemberSheet::isQt3Slot(int index) const
|
||||
{
|
||||
if (!isSlot(index))
|
||||
return false;
|
||||
|
||||
const QString className = declaredInClass(index);
|
||||
const QString slotSignature = signature(index);
|
||||
|
||||
QMap<QString, QStringList> qt3slots = Qt3Members::instance()->getSlots();
|
||||
QMap<QString, QStringList>::const_iterator it = qt3slots.constFind(className);
|
||||
if (it != qt3slots.constEnd() && (*it).contains(slotSignature))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------ QDesignerMemberSheetFactory
|
||||
|
||||
QDesignerMemberSheetFactory::QDesignerMemberSheetFactory(QExtensionManager *parent)
|
||||
: QExtensionFactory(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QObject *QDesignerMemberSheetFactory::createExtension(QObject *object, const QString &iid, QObject *parent) const
|
||||
{
|
||||
if (iid == Q_TYPEID(QDesignerMemberSheetExtension)) {
|
||||
return new QDesignerMemberSheet(object, parent);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
120
third/designer/lib/shared/qdesigner_membersheet_p.h
Normal file
120
third/designer/lib/shared/qdesigner_membersheet_p.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef QDESIGNER_MEMBERSHEET_H
|
||||
#define QDESIGNER_MEMBERSHEET_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
|
||||
#include <QtDesigner/membersheet.h>
|
||||
#include <QtDesigner/default_extensionfactory.h>
|
||||
#include <QtCore/QStringList>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDesignerMemberSheetPrivate;
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT QDesignerMemberSheet: public QObject, public QDesignerMemberSheetExtension
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDesignerMemberSheetExtension)
|
||||
|
||||
public:
|
||||
explicit QDesignerMemberSheet(QObject *object, QObject *parent = 0);
|
||||
virtual ~QDesignerMemberSheet();
|
||||
|
||||
virtual int indexOf(const QString &name) const;
|
||||
|
||||
virtual int count() const;
|
||||
virtual QString memberName(int index) const;
|
||||
|
||||
virtual QString memberGroup(int index) const;
|
||||
virtual void setMemberGroup(int index, const QString &group);
|
||||
|
||||
virtual bool isVisible(int index) const;
|
||||
virtual void setVisible(int index, bool b);
|
||||
|
||||
virtual bool isSignal(int index) const;
|
||||
virtual bool isSlot(int index) const;
|
||||
|
||||
virtual bool isQt3Signal(int index) const;
|
||||
virtual bool isQt3Slot(int index) const;
|
||||
|
||||
virtual bool inheritedFromWidget(int index) const;
|
||||
|
||||
static bool signalMatchesSlot(const QString &signal, const QString &slot);
|
||||
|
||||
virtual QString declaredInClass(int index) const;
|
||||
|
||||
virtual QString signature(int index) const;
|
||||
virtual QList<QByteArray> parameterTypes(int index) const;
|
||||
virtual QList<QByteArray> parameterNames(int index) const;
|
||||
|
||||
private:
|
||||
QDesignerMemberSheetPrivate *d;
|
||||
};
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT QDesignerMemberSheetFactory: public QExtensionFactory
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QAbstractExtensionFactory)
|
||||
|
||||
public:
|
||||
QDesignerMemberSheetFactory(QExtensionManager *parent = 0);
|
||||
|
||||
protected:
|
||||
virtual QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QDESIGNER_MEMBERSHEET_H
|
||||
1390
third/designer/lib/shared/qdesigner_menu.cpp
Normal file
1390
third/designer/lib/shared/qdesigner_menu.cpp
Normal file
File diff suppressed because it is too large
Load Diff
208
third/designer/lib/shared/qdesigner_menu_p.h
Normal file
208
third/designer/lib/shared/qdesigner_menu_p.h
Normal file
@@ -0,0 +1,208 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef QDESIGNER_MENU_H
|
||||
#define QDESIGNER_MENU_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtGui/QPixmap>
|
||||
#include <QtCore/QHash>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QTimer;
|
||||
class QLineEdit;
|
||||
|
||||
class QDesignerFormWindowInterface;
|
||||
class QDesignerActionProviderExtension;
|
||||
class QDesignerMenu;
|
||||
class QDesignerMenuBar;
|
||||
class QPainter;
|
||||
class QMimeData;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
class CreateSubmenuCommand;
|
||||
class ActionInsertionCommand;
|
||||
}
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT QDesignerMenu: public QMenu
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QDesignerMenu(QWidget *parent = 0);
|
||||
virtual ~QDesignerMenu();
|
||||
|
||||
bool eventFilter(QObject *object, QEvent *event);
|
||||
|
||||
QDesignerFormWindowInterface *formWindow() const;
|
||||
QDesignerActionProviderExtension *actionProvider();
|
||||
|
||||
QDesignerMenu *parentMenu() const;
|
||||
QDesignerMenuBar *parentMenuBar() const;
|
||||
|
||||
virtual void setVisible(bool visible);
|
||||
|
||||
void adjustSpecialActions();
|
||||
|
||||
bool interactive(bool i);
|
||||
void createRealMenuAction(QAction *action);
|
||||
void removeRealMenu(QAction *action);
|
||||
|
||||
static void drawSelection(QPainter *p, const QRect &r);
|
||||
|
||||
bool dragging() const;
|
||||
|
||||
void closeMenuChain();
|
||||
|
||||
void moveLeft();
|
||||
void moveRight();
|
||||
void moveUp(bool ctrl);
|
||||
void moveDown(bool ctrl);
|
||||
|
||||
// Helper for MenuTaskMenu extension
|
||||
void deleteAction(QAction *a);
|
||||
|
||||
private slots:
|
||||
void slotAddSeparator();
|
||||
void slotRemoveSelectedAction();
|
||||
void slotShowSubMenuNow();
|
||||
void slotDeactivateNow();
|
||||
void slotAdjustSizeNow();
|
||||
|
||||
protected:
|
||||
virtual void actionEvent(QActionEvent *event);
|
||||
virtual void dragEnterEvent(QDragEnterEvent *event);
|
||||
virtual void dragMoveEvent(QDragMoveEvent *event);
|
||||
virtual void dragLeaveEvent(QDragLeaveEvent *event);
|
||||
virtual void dropEvent(QDropEvent *event);
|
||||
virtual void paintEvent(QPaintEvent *event);
|
||||
virtual void keyPressEvent(QKeyEvent *event);
|
||||
virtual void keyReleaseEvent(QKeyEvent *event);
|
||||
virtual void showEvent(QShowEvent *event);
|
||||
|
||||
bool handleEvent(QWidget *widget, QEvent *event);
|
||||
bool handleMouseDoubleClickEvent(QWidget *widget, QMouseEvent *event);
|
||||
bool handleMousePressEvent(QWidget *widget, QMouseEvent *event);
|
||||
bool handleMouseReleaseEvent(QWidget *widget, QMouseEvent *event);
|
||||
bool handleMouseMoveEvent(QWidget *widget, QMouseEvent *event);
|
||||
bool handleContextMenuEvent(QWidget *widget, QContextMenuEvent *event);
|
||||
bool handleKeyPressEvent(QWidget *widget, QKeyEvent *event);
|
||||
|
||||
void startDrag(const QPoint &pos, Qt::KeyboardModifiers modifiers);
|
||||
|
||||
void adjustIndicator(const QPoint &pos);
|
||||
int findAction(const QPoint &pos) const;
|
||||
|
||||
QAction *currentAction() const;
|
||||
int realActionCount() const;
|
||||
enum ActionDragCheck { NoActionDrag, ActionDragOnSubMenu, AcceptActionDrag };
|
||||
ActionDragCheck checkAction(QAction *action) const;
|
||||
|
||||
void showSubMenu(QAction *action);
|
||||
|
||||
enum LeaveEditMode {
|
||||
Default = 0,
|
||||
ForceAccept
|
||||
};
|
||||
|
||||
void enterEditMode();
|
||||
void leaveEditMode(LeaveEditMode mode);
|
||||
void showLineEdit();
|
||||
|
||||
QAction *createAction(const QString &text, bool separator = false);
|
||||
QDesignerMenu *findOrCreateSubMenu(QAction *action);
|
||||
|
||||
QAction *safeActionAt(int index) const;
|
||||
QAction *safeMenuAction(QDesignerMenu *menu) const;
|
||||
bool swap(int a, int b);
|
||||
|
||||
void hideSubMenu();
|
||||
void deleteAction();
|
||||
void deactivateMenu();
|
||||
|
||||
bool canCreateSubMenu(QAction *action) const;
|
||||
QDesignerMenu *findRootMenu() const;
|
||||
QDesignerMenu *findActivatedMenu() const;
|
||||
|
||||
QRect subMenuPixmapRect(QAction *action) const;
|
||||
bool hasSubMenuPixmap(QAction *action) const;
|
||||
|
||||
void selectCurrentAction();
|
||||
|
||||
private:
|
||||
bool hideSubMenuOnCursorKey();
|
||||
bool showSubMenuOnCursorKey();
|
||||
const QPixmap m_subMenuPixmap;
|
||||
|
||||
QPoint m_startPosition;
|
||||
int m_currentIndex;
|
||||
QAction *m_addItem;
|
||||
QAction *m_addSeparator;
|
||||
QHash<QAction*, QDesignerMenu*> m_subMenus;
|
||||
QTimer *m_showSubMenuTimer;
|
||||
QTimer *m_deactivateWindowTimer;
|
||||
QTimer *m_adjustSizeTimer;
|
||||
bool m_interactive;
|
||||
QLineEdit *m_editor;
|
||||
bool m_dragging;
|
||||
int m_lastSubMenuIndex;
|
||||
|
||||
friend class qdesigner_internal::CreateSubmenuCommand;
|
||||
friend class qdesigner_internal::ActionInsertionCommand;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QDESIGNER_MENU_H
|
||||
979
third/designer/lib/shared/qdesigner_menubar.cpp
Normal file
979
third/designer/lib/shared/qdesigner_menubar.cpp
Normal file
@@ -0,0 +1,979 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qdesigner_menubar_p.h"
|
||||
#include "qdesigner_menu_p.h"
|
||||
#include "qdesigner_command_p.h"
|
||||
#include "qdesigner_propertycommand_p.h"
|
||||
#include "actionrepository_p.h"
|
||||
#include "actionprovider_p.h"
|
||||
#include "actioneditor_p.h"
|
||||
#include "qdesigner_utils_p.h"
|
||||
#include "promotiontaskmenu_p.h"
|
||||
#include "qdesigner_objectinspector_p.h"
|
||||
|
||||
#include <QtDesigner/QDesignerFormWindowInterface>
|
||||
#include <QtDesigner/QDesignerFormEditorInterface>
|
||||
#include <QtDesigner/QDesignerWidgetFactoryInterface>
|
||||
#include <QtDesigner/QExtensionManager>
|
||||
|
||||
#include <QtCore/QMimeData>
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtGui/QDrag>
|
||||
#include <QtGui/QLineEdit>
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/qevent.h>
|
||||
|
||||
Q_DECLARE_METATYPE(QAction*)
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
typedef QList<QAction *> ActionList;
|
||||
|
||||
using namespace qdesigner_internal;
|
||||
|
||||
namespace qdesigner_internal
|
||||
{
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
SpecialMenuAction::SpecialMenuAction(QObject *parent)
|
||||
: QAction(parent)
|
||||
{
|
||||
}
|
||||
|
||||
SpecialMenuAction::~SpecialMenuAction()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
QDesignerMenuBar::QDesignerMenuBar(QWidget *parent) :
|
||||
QMenuBar(parent),
|
||||
m_addMenu(new SpecialMenuAction(this)),
|
||||
m_currentIndex(0),
|
||||
m_interactive(true),
|
||||
m_editor(new QLineEdit(this)),
|
||||
m_dragging(false),
|
||||
m_lastMenuActionIndex( -1),
|
||||
m_promotionTaskMenu(new PromotionTaskMenu(this, PromotionTaskMenu::ModeSingleWidget, this))
|
||||
{
|
||||
setContextMenuPolicy(Qt::DefaultContextMenu);
|
||||
|
||||
setAcceptDrops(true); // ### fake
|
||||
// Fake property: Keep the menu bar editable in the form even if a native menu bar is used.
|
||||
setNativeMenuBar(false);
|
||||
|
||||
m_addMenu->setText(tr("Type Here"));
|
||||
addAction(m_addMenu);
|
||||
|
||||
QFont italic;
|
||||
italic.setItalic(true);
|
||||
m_addMenu->setFont(italic);
|
||||
|
||||
m_editor->setObjectName(QLatin1String("__qt__passive_editor"));
|
||||
m_editor->hide();
|
||||
m_editor->installEventFilter(this);
|
||||
installEventFilter(this);
|
||||
}
|
||||
|
||||
QDesignerMenuBar::~QDesignerMenuBar()
|
||||
{
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
QMenuBar::paintEvent(event);
|
||||
|
||||
QPainter p(this);
|
||||
|
||||
foreach (QAction *a, actions()) {
|
||||
if (qobject_cast<SpecialMenuAction*>(a)) {
|
||||
const QRect g = actionGeometry(a);
|
||||
QLinearGradient lg(g.left(), g.top(), g.left(), g.bottom());
|
||||
lg.setColorAt(0.0, Qt::transparent);
|
||||
lg.setColorAt(0.7, QColor(0, 0, 0, 32));
|
||||
lg.setColorAt(1.0, Qt::transparent);
|
||||
|
||||
p.fillRect(g, lg);
|
||||
}
|
||||
}
|
||||
|
||||
QAction *action = currentAction();
|
||||
|
||||
if (m_dragging || !action)
|
||||
return;
|
||||
|
||||
if (hasFocus()) {
|
||||
const QRect g = actionGeometry(action);
|
||||
QDesignerMenu::drawSelection(&p, g.adjusted(1, 1, -1, -1));
|
||||
} else if (action->menu() && action->menu()->isVisible()) {
|
||||
const QRect g = actionGeometry(action);
|
||||
p.drawRect(g.adjusted(1, 1, -1, -1));
|
||||
}
|
||||
}
|
||||
|
||||
bool QDesignerMenuBar::handleEvent(QWidget *widget, QEvent *event)
|
||||
{
|
||||
if (!formWindow())
|
||||
return false;
|
||||
|
||||
if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut)
|
||||
update();
|
||||
|
||||
switch (event->type()) {
|
||||
default: break;
|
||||
|
||||
case QEvent::MouseButtonDblClick:
|
||||
return handleMouseDoubleClickEvent(widget, static_cast<QMouseEvent*>(event));
|
||||
case QEvent::MouseButtonPress:
|
||||
return handleMousePressEvent(widget, static_cast<QMouseEvent*>(event));
|
||||
case QEvent::MouseButtonRelease:
|
||||
return handleMouseReleaseEvent(widget, static_cast<QMouseEvent*>(event));
|
||||
case QEvent::MouseMove:
|
||||
return handleMouseMoveEvent(widget, static_cast<QMouseEvent*>(event));
|
||||
case QEvent::ContextMenu:
|
||||
return handleContextMenuEvent(widget, static_cast<QContextMenuEvent*>(event));
|
||||
case QEvent::KeyPress:
|
||||
return handleKeyPressEvent(widget, static_cast<QKeyEvent*>(event));
|
||||
case QEvent::FocusIn:
|
||||
case QEvent::FocusOut:
|
||||
return widget != m_editor;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QDesignerMenuBar::handleMouseDoubleClickEvent(QWidget *, QMouseEvent *event)
|
||||
{
|
||||
if (!rect().contains(event->pos()))
|
||||
return true;
|
||||
|
||||
if ((event->buttons() & Qt::LeftButton) != Qt::LeftButton)
|
||||
return true;
|
||||
|
||||
event->accept();
|
||||
|
||||
m_startPosition = QPoint();
|
||||
|
||||
m_currentIndex = actionIndexAt(this, event->pos(), Qt::Horizontal);
|
||||
if (m_currentIndex != -1) {
|
||||
showLineEdit();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QDesignerMenuBar::handleKeyPressEvent(QWidget *, QKeyEvent *e)
|
||||
{
|
||||
if (m_editor->isHidden()) { // In navigation mode
|
||||
switch (e->key()) {
|
||||
|
||||
case Qt::Key_Delete:
|
||||
if (m_currentIndex == -1 || m_currentIndex >= realActionCount())
|
||||
break;
|
||||
hideMenu();
|
||||
deleteMenu();
|
||||
break;
|
||||
|
||||
case Qt::Key_Left:
|
||||
e->accept();
|
||||
moveLeft(e->modifiers() & Qt::ControlModifier);
|
||||
return true;
|
||||
|
||||
case Qt::Key_Right:
|
||||
e->accept();
|
||||
moveRight(e->modifiers() & Qt::ControlModifier);
|
||||
return true; // no update
|
||||
|
||||
case Qt::Key_Up:
|
||||
e->accept();
|
||||
moveUp();
|
||||
return true;
|
||||
|
||||
case Qt::Key_Down:
|
||||
e->accept();
|
||||
moveDown();
|
||||
return true;
|
||||
|
||||
case Qt::Key_PageUp:
|
||||
m_currentIndex = 0;
|
||||
break;
|
||||
|
||||
case Qt::Key_PageDown:
|
||||
m_currentIndex = actions().count() - 1;
|
||||
break;
|
||||
|
||||
case Qt::Key_Enter:
|
||||
case Qt::Key_Return:
|
||||
e->accept();
|
||||
enterEditMode();
|
||||
return true; // no update
|
||||
|
||||
case Qt::Key_Alt:
|
||||
case Qt::Key_Shift:
|
||||
case Qt::Key_Control:
|
||||
case Qt::Key_Escape:
|
||||
e->ignore();
|
||||
setFocus(); // FIXME: this is because some other widget get the focus when CTRL is pressed
|
||||
return true; // no update
|
||||
|
||||
default:
|
||||
if (!e->text().isEmpty() && e->text().at(0).toLatin1() >= 32) {
|
||||
showLineEdit();
|
||||
QApplication::sendEvent(m_editor, e);
|
||||
e->accept();
|
||||
} else {
|
||||
e->ignore();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else { // In edit mode
|
||||
switch (e->key()) {
|
||||
default:
|
||||
return false;
|
||||
|
||||
case Qt::Key_Control:
|
||||
e->ignore();
|
||||
return true;
|
||||
|
||||
case Qt::Key_Enter:
|
||||
case Qt::Key_Return:
|
||||
if (!m_editor->text().isEmpty()) {
|
||||
leaveEditMode(ForceAccept);
|
||||
if (m_lastFocusWidget)
|
||||
m_lastFocusWidget->setFocus();
|
||||
|
||||
m_editor->hide();
|
||||
showMenu();
|
||||
break;
|
||||
}
|
||||
// fall through
|
||||
|
||||
case Qt::Key_Escape:
|
||||
update();
|
||||
setFocus();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
e->accept();
|
||||
update();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::startDrag(const QPoint &pos)
|
||||
{
|
||||
const int index = findAction(pos);
|
||||
if (m_currentIndex == -1 || index >= realActionCount())
|
||||
return;
|
||||
|
||||
QAction *action = safeActionAt(index);
|
||||
|
||||
QDesignerFormWindowInterface *fw = formWindow();
|
||||
RemoveActionFromCommand *cmd = new RemoveActionFromCommand(fw);
|
||||
cmd->init(this, action, actions().at(index + 1));
|
||||
fw->commandHistory()->push(cmd);
|
||||
|
||||
adjustSize();
|
||||
|
||||
hideMenu(index);
|
||||
|
||||
QDrag *drag = new QDrag(this);
|
||||
drag->setPixmap(ActionRepositoryMimeData::actionDragPixmap(action));
|
||||
drag->setMimeData(new ActionRepositoryMimeData(action, Qt::MoveAction));
|
||||
|
||||
const int old_index = m_currentIndex;
|
||||
m_currentIndex = -1;
|
||||
|
||||
if (drag->start(Qt::MoveAction) == Qt::IgnoreAction) {
|
||||
InsertActionIntoCommand *cmd = new InsertActionIntoCommand(fw);
|
||||
cmd->init(this, action, safeActionAt(index));
|
||||
fw->commandHistory()->push(cmd);
|
||||
|
||||
m_currentIndex = old_index;
|
||||
adjustSize();
|
||||
}
|
||||
}
|
||||
|
||||
bool QDesignerMenuBar::handleMousePressEvent(QWidget *, QMouseEvent *event)
|
||||
{
|
||||
m_startPosition = QPoint();
|
||||
event->accept();
|
||||
|
||||
if (event->button() != Qt::LeftButton)
|
||||
return true;
|
||||
|
||||
m_startPosition = event->pos();
|
||||
const int newIndex = actionIndexAt(this, m_startPosition, Qt::Horizontal);
|
||||
const bool changed = newIndex != m_currentIndex;
|
||||
m_currentIndex = newIndex;
|
||||
updateCurrentAction(changed);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QDesignerMenuBar::handleMouseReleaseEvent(QWidget *, QMouseEvent *event)
|
||||
{
|
||||
m_startPosition = QPoint();
|
||||
|
||||
if (event->button() != Qt::LeftButton)
|
||||
return true;
|
||||
|
||||
event->accept();
|
||||
m_currentIndex = actionIndexAt(this, event->pos(), Qt::Horizontal);
|
||||
if (!m_editor->isVisible() && m_currentIndex != -1 && m_currentIndex < realActionCount())
|
||||
showMenu();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QDesignerMenuBar::handleMouseMoveEvent(QWidget *, QMouseEvent *event)
|
||||
{
|
||||
if ((event->buttons() & Qt::LeftButton) != Qt::LeftButton)
|
||||
return true;
|
||||
|
||||
if (m_startPosition.isNull())
|
||||
return true;
|
||||
|
||||
const QPoint pos = mapFromGlobal(event->globalPos());
|
||||
|
||||
if ((pos - m_startPosition).manhattanLength() < qApp->startDragDistance())
|
||||
return true;
|
||||
|
||||
const int index = actionIndexAt(this, m_startPosition, Qt::Horizontal);
|
||||
if (index < actions().count()) {
|
||||
hideMenu(index);
|
||||
update();
|
||||
}
|
||||
|
||||
startDrag(m_startPosition);
|
||||
m_startPosition = QPoint();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ActionList QDesignerMenuBar::contextMenuActions()
|
||||
{
|
||||
ActionList rc;
|
||||
if (QAction *action = safeActionAt(m_currentIndex)) {
|
||||
if (!qobject_cast<SpecialMenuAction*>(action)) {
|
||||
QVariant itemData;
|
||||
qVariantSetValue(itemData, action);
|
||||
|
||||
QAction *remove_action = new QAction(tr("Remove Menu '%1'").arg(action->menu()->objectName()), 0);
|
||||
remove_action->setData(itemData);
|
||||
connect(remove_action, SIGNAL(triggered()), this, SLOT(deleteMenu()));
|
||||
rc.push_back(remove_action);
|
||||
QAction *sep = new QAction(0);
|
||||
sep->setSeparator(true);
|
||||
rc.push_back(sep);
|
||||
}
|
||||
}
|
||||
|
||||
m_promotionTaskMenu->addActions(formWindow(), PromotionTaskMenu::TrailingSeparator, rc);
|
||||
|
||||
QAction *remove_menubar = new QAction(tr("Remove Menu Bar"), 0);
|
||||
connect(remove_menubar, SIGNAL(triggered()), this, SLOT(slotRemoveMenuBar()));
|
||||
rc.push_back(remove_menubar);
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool QDesignerMenuBar::handleContextMenuEvent(QWidget *, QContextMenuEvent *event)
|
||||
{
|
||||
event->accept();
|
||||
|
||||
m_currentIndex = actionIndexAt(this, mapFromGlobal(event->globalPos()), Qt::Horizontal);
|
||||
|
||||
update();
|
||||
|
||||
QMenu menu;
|
||||
const ActionList al = contextMenuActions();
|
||||
const ActionList::const_iterator acend = al.constEnd();
|
||||
for (ActionList::const_iterator it = al.constBegin(); it != acend; ++it)
|
||||
menu.addAction(*it);
|
||||
menu.exec(event->globalPos());
|
||||
return true;
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::slotRemoveMenuBar()
|
||||
{
|
||||
Q_ASSERT(formWindow() != 0);
|
||||
|
||||
QDesignerFormWindowInterface *fw = formWindow();
|
||||
|
||||
DeleteMenuBarCommand *cmd = new DeleteMenuBarCommand(fw);
|
||||
cmd->init(this);
|
||||
fw->commandHistory()->push(cmd);
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::focusOutEvent(QFocusEvent *event)
|
||||
{
|
||||
QMenuBar::focusOutEvent(event);
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::enterEditMode()
|
||||
{
|
||||
if (m_currentIndex >= 0 && m_currentIndex <= realActionCount()) {
|
||||
showLineEdit();
|
||||
}
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::leaveEditMode(LeaveEditMode mode)
|
||||
{
|
||||
m_editor->releaseKeyboard();
|
||||
|
||||
if (mode == Default)
|
||||
return;
|
||||
|
||||
if (m_editor->text().isEmpty())
|
||||
return;
|
||||
|
||||
QAction *action = 0;
|
||||
|
||||
QDesignerFormWindowInterface *fw = formWindow();
|
||||
Q_ASSERT(fw);
|
||||
|
||||
if (m_currentIndex >= 0 && m_currentIndex < realActionCount()) {
|
||||
action = safeActionAt(m_currentIndex);
|
||||
fw->beginCommand(QApplication::translate("Command", "Change Title"));
|
||||
} else {
|
||||
fw->beginCommand(QApplication::translate("Command", "Insert Menu"));
|
||||
const QString niceObjectName = ActionEditor::actionTextToName(m_editor->text(), QLatin1String("menu"));
|
||||
QMenu *menu = qobject_cast<QMenu*>(fw->core()->widgetFactory()->createWidget(QLatin1String("QMenu"), this));
|
||||
fw->core()->widgetFactory()->initialize(menu);
|
||||
menu->setObjectName(niceObjectName);
|
||||
menu->setTitle(tr("Menu"));
|
||||
fw->ensureUniqueObjectName(menu);
|
||||
action = menu->menuAction();
|
||||
AddMenuActionCommand *cmd = new AddMenuActionCommand(fw);
|
||||
cmd->init(action, m_addMenu, this, this);
|
||||
fw->commandHistory()->push(cmd);
|
||||
}
|
||||
|
||||
SetPropertyCommand *cmd = new SetPropertyCommand(fw);
|
||||
cmd->init(action, QLatin1String("text"), m_editor->text());
|
||||
fw->commandHistory()->push(cmd);
|
||||
fw->endCommand();
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::showLineEdit()
|
||||
{
|
||||
QAction *action = 0;
|
||||
|
||||
if (m_currentIndex >= 0 && m_currentIndex < realActionCount())
|
||||
action = safeActionAt(m_currentIndex);
|
||||
else
|
||||
action = m_addMenu;
|
||||
|
||||
if (action->isSeparator())
|
||||
return;
|
||||
|
||||
// hideMenu();
|
||||
|
||||
m_lastFocusWidget = qApp->focusWidget();
|
||||
|
||||
// open edit field for item name
|
||||
const QString text = action != m_addMenu ? action->text() : QString();
|
||||
|
||||
m_editor->setText(text);
|
||||
m_editor->selectAll();
|
||||
m_editor->setGeometry(actionGeometry(action));
|
||||
m_editor->show();
|
||||
qApp->setActiveWindow(m_editor);
|
||||
m_editor->setFocus();
|
||||
m_editor->grabKeyboard();
|
||||
}
|
||||
|
||||
bool QDesignerMenuBar::eventFilter(QObject *object, QEvent *event)
|
||||
{
|
||||
if (object != this && object != m_editor)
|
||||
return false;
|
||||
|
||||
if (!m_editor->isHidden() && object == m_editor && event->type() == QEvent::FocusOut) {
|
||||
leaveEditMode(Default);
|
||||
m_editor->hide();
|
||||
update();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dispatch = true;
|
||||
|
||||
switch (event->type()) {
|
||||
default: break;
|
||||
|
||||
case QEvent::KeyPress:
|
||||
case QEvent::KeyRelease:
|
||||
case QEvent::ContextMenu:
|
||||
case QEvent::MouseMove:
|
||||
case QEvent::MouseButtonPress:
|
||||
case QEvent::MouseButtonRelease:
|
||||
case QEvent::MouseButtonDblClick:
|
||||
dispatch = (object != m_editor);
|
||||
// no break
|
||||
|
||||
case QEvent::Enter:
|
||||
case QEvent::Leave:
|
||||
case QEvent::FocusIn:
|
||||
case QEvent::FocusOut:
|
||||
{
|
||||
QWidget *widget = qobject_cast<QWidget*>(object);
|
||||
|
||||
if (dispatch && widget && (widget == this || isAncestorOf(widget)))
|
||||
return handleEvent(widget, event);
|
||||
} break;
|
||||
|
||||
case QEvent::Shortcut:
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
int QDesignerMenuBar::findAction(const QPoint &pos) const
|
||||
{
|
||||
const int index = actionIndexAt(this, pos, Qt::Horizontal);
|
||||
if (index == -1)
|
||||
return realActionCount();
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::adjustIndicator(const QPoint &pos)
|
||||
{
|
||||
const int index = findAction(pos);
|
||||
QAction *action = safeActionAt(index);
|
||||
Q_ASSERT(action != 0);
|
||||
|
||||
if (pos != QPoint(-1, -1)) {
|
||||
QDesignerMenu *m = qobject_cast<QDesignerMenu*>(action->menu());
|
||||
if (!m || m->parentMenu()) {
|
||||
m_currentIndex = index;
|
||||
showMenu(index);
|
||||
}
|
||||
}
|
||||
|
||||
if (QDesignerActionProviderExtension *a = actionProvider()) {
|
||||
a->adjustIndicator(pos);
|
||||
}
|
||||
}
|
||||
|
||||
QDesignerMenuBar::ActionDragCheck QDesignerMenuBar::checkAction(QAction *action) const
|
||||
{
|
||||
// action belongs to another form
|
||||
if (!action || !Utils::isObjectAncestorOf(formWindow()->mainContainer(), action))
|
||||
return NoActionDrag;
|
||||
|
||||
if (!action->menu())
|
||||
return ActionDragOnSubMenu; // simple action only on sub menus
|
||||
|
||||
QDesignerMenu *m = qobject_cast<QDesignerMenu*>(action->menu());
|
||||
if (m && m->parentMenu())
|
||||
return ActionDragOnSubMenu; // it looks like a submenu
|
||||
|
||||
if (actions().contains(action))
|
||||
return ActionDragOnSubMenu; // we already have the action in the menubar
|
||||
|
||||
return AcceptActionDrag;
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
const ActionRepositoryMimeData *d = qobject_cast<const ActionRepositoryMimeData*>(event->mimeData());
|
||||
if (!d || d->actionList().empty()) {
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
QAction *action = d->actionList().first();
|
||||
switch (checkAction(action)) {
|
||||
case NoActionDrag:
|
||||
event->ignore();
|
||||
break;
|
||||
case ActionDragOnSubMenu:
|
||||
m_dragging = true;
|
||||
d->accept(event);
|
||||
break;
|
||||
case AcceptActionDrag:
|
||||
m_dragging = true;
|
||||
d->accept(event);
|
||||
adjustIndicator(event->pos());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::dragMoveEvent(QDragMoveEvent *event)
|
||||
{
|
||||
const ActionRepositoryMimeData *d = qobject_cast<const ActionRepositoryMimeData*>(event->mimeData());
|
||||
if (!d || d->actionList().empty()) {
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
QAction *action = d->actionList().first();
|
||||
|
||||
switch (checkAction(action)) {
|
||||
case NoActionDrag:
|
||||
event->ignore();
|
||||
break;
|
||||
case ActionDragOnSubMenu:
|
||||
event->ignore();
|
||||
showMenu(findAction(event->pos()));
|
||||
break;
|
||||
case AcceptActionDrag:
|
||||
d->accept(event);
|
||||
adjustIndicator(event->pos());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::dragLeaveEvent(QDragLeaveEvent *)
|
||||
{
|
||||
m_dragging = false;
|
||||
|
||||
adjustIndicator(QPoint(-1, -1));
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::dropEvent(QDropEvent *event)
|
||||
{
|
||||
m_dragging = false;
|
||||
|
||||
if (const ActionRepositoryMimeData *d = qobject_cast<const ActionRepositoryMimeData*>(event->mimeData())) {
|
||||
|
||||
QAction *action = d->actionList().first();
|
||||
if (checkAction(action) == AcceptActionDrag) {
|
||||
event->acceptProposedAction();
|
||||
int index = findAction(event->pos());
|
||||
index = qMin(index, actions().count() - 1);
|
||||
|
||||
QDesignerFormWindowInterface *fw = formWindow();
|
||||
InsertActionIntoCommand *cmd = new InsertActionIntoCommand(fw);
|
||||
cmd->init(this, action, safeActionAt(index));
|
||||
fw->commandHistory()->push(cmd);
|
||||
|
||||
m_currentIndex = index;
|
||||
update();
|
||||
adjustIndicator(QPoint(-1, -1));
|
||||
return;
|
||||
}
|
||||
}
|
||||
event->ignore();
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::actionEvent(QActionEvent *event)
|
||||
{
|
||||
QMenuBar::actionEvent(event);
|
||||
}
|
||||
|
||||
QDesignerFormWindowInterface *QDesignerMenuBar::formWindow() const
|
||||
{
|
||||
return QDesignerFormWindowInterface::findFormWindow(const_cast<QDesignerMenuBar*>(this));
|
||||
}
|
||||
|
||||
QDesignerActionProviderExtension *QDesignerMenuBar::actionProvider()
|
||||
{
|
||||
if (QDesignerFormWindowInterface *fw = formWindow()) {
|
||||
QDesignerFormEditorInterface *core = fw->core();
|
||||
return qt_extension<QDesignerActionProviderExtension*>(core->extensionManager(), this);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
QAction *QDesignerMenuBar::currentAction() const
|
||||
{
|
||||
if (m_currentIndex < 0 || m_currentIndex >= actions().count())
|
||||
return 0;
|
||||
|
||||
return safeActionAt(m_currentIndex);
|
||||
}
|
||||
|
||||
int QDesignerMenuBar::realActionCount() const
|
||||
{
|
||||
return actions().count() - 1; // 1 fake actions
|
||||
}
|
||||
|
||||
bool QDesignerMenuBar::dragging() const
|
||||
{
|
||||
return m_dragging;
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::moveLeft(bool ctrl)
|
||||
{
|
||||
if (layoutDirection() == Qt::LeftToRight) {
|
||||
movePrevious(ctrl);
|
||||
} else {
|
||||
moveNext(ctrl);
|
||||
}
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::moveRight(bool ctrl)
|
||||
{
|
||||
if (layoutDirection() == Qt::LeftToRight) {
|
||||
moveNext(ctrl);
|
||||
} else {
|
||||
movePrevious(ctrl);
|
||||
}
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::movePrevious(bool ctrl)
|
||||
{
|
||||
const bool swapped = ctrl && swapActions(m_currentIndex, m_currentIndex - 1);
|
||||
const int newIndex = qMax(0, m_currentIndex - 1);
|
||||
// Always re-select, swapping destroys order
|
||||
if (swapped || newIndex != m_currentIndex) {
|
||||
m_currentIndex = newIndex;
|
||||
updateCurrentAction(true);
|
||||
}
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::moveNext(bool ctrl)
|
||||
{
|
||||
const bool swapped = ctrl && swapActions(m_currentIndex + 1, m_currentIndex);
|
||||
const int newIndex = qMin(actions().count() - 1, m_currentIndex + 1);
|
||||
if (swapped || newIndex != m_currentIndex) {
|
||||
m_currentIndex = newIndex;
|
||||
updateCurrentAction(!ctrl);
|
||||
}
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::moveUp()
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::moveDown()
|
||||
{
|
||||
showMenu();
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::adjustSpecialActions()
|
||||
{
|
||||
removeAction(m_addMenu);
|
||||
addAction(m_addMenu);
|
||||
}
|
||||
|
||||
bool QDesignerMenuBar::interactive(bool i)
|
||||
{
|
||||
const bool old = m_interactive;
|
||||
m_interactive = i;
|
||||
return old;
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::hideMenu(int index)
|
||||
{
|
||||
if (index < 0 && m_currentIndex >= 0)
|
||||
index = m_currentIndex;
|
||||
|
||||
if (index < 0 || index >= realActionCount())
|
||||
return;
|
||||
|
||||
QAction *action = safeActionAt(index);
|
||||
|
||||
if (action && action->menu()) {
|
||||
action->menu()->hide();
|
||||
|
||||
if (QDesignerMenu *menu = qobject_cast<QDesignerMenu*>(action->menu())) {
|
||||
menu->closeMenuChain();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::deleteMenu()
|
||||
{
|
||||
deleteMenuAction(currentAction());
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::deleteMenuAction(QAction *action)
|
||||
{
|
||||
if (action && !qobject_cast<SpecialMenuAction*>(action)) {
|
||||
const int pos = actions().indexOf(action);
|
||||
QAction *action_before = 0;
|
||||
if (pos != -1)
|
||||
action_before = safeActionAt(pos + 1);
|
||||
|
||||
QDesignerFormWindowInterface *fw = formWindow();
|
||||
RemoveMenuActionCommand *cmd = new RemoveMenuActionCommand(fw);
|
||||
cmd->init(action, action_before, this, this);
|
||||
fw->commandHistory()->push(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::showMenu(int index)
|
||||
{
|
||||
if (index < 0 && m_currentIndex >= 0)
|
||||
index = m_currentIndex;
|
||||
|
||||
if (index < 0 || index >= realActionCount())
|
||||
return;
|
||||
|
||||
m_currentIndex = index;
|
||||
QAction *action = currentAction();
|
||||
|
||||
if (action && action->menu()) {
|
||||
if (m_lastMenuActionIndex != -1 && m_lastMenuActionIndex != index) {
|
||||
hideMenu(m_lastMenuActionIndex);
|
||||
}
|
||||
|
||||
m_lastMenuActionIndex = index;
|
||||
QMenu *menu = action->menu();
|
||||
const QRect g = actionGeometry(action);
|
||||
|
||||
if (!menu->isVisible()) {
|
||||
if ((menu->windowFlags() & Qt::Popup) != Qt::Popup)
|
||||
menu->setWindowFlags(Qt::Popup);
|
||||
menu->adjustSize();
|
||||
if (layoutDirection() == Qt::LeftToRight) {
|
||||
menu->move(mapToGlobal(g.bottomLeft()));
|
||||
} else {
|
||||
// The position is not initially correct due to the unknown width,
|
||||
// causing it to overlap a bit the first time it is invoked.
|
||||
const QSize menuSize = menu->size();
|
||||
QPoint point = g.bottomRight() - QPoint(menu->width(), 0);
|
||||
menu->move(mapToGlobal(point));
|
||||
}
|
||||
menu->setFocus(Qt::MouseFocusReason);
|
||||
menu->raise();
|
||||
menu->show();
|
||||
} else {
|
||||
menu->raise();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QAction *QDesignerMenuBar::safeActionAt(int index) const
|
||||
{
|
||||
if (index < 0 || index >= actions().count())
|
||||
return 0;
|
||||
|
||||
return actions().at(index);
|
||||
}
|
||||
|
||||
bool QDesignerMenuBar::swapActions(int a, int b)
|
||||
{
|
||||
const int left = qMin(a, b);
|
||||
int right = qMax(a, b);
|
||||
|
||||
QAction *action_a = safeActionAt(left);
|
||||
QAction *action_b = safeActionAt(right);
|
||||
|
||||
if (action_a == action_b
|
||||
|| !action_a
|
||||
|| !action_b
|
||||
|| qobject_cast<SpecialMenuAction*>(action_a)
|
||||
|| qobject_cast<SpecialMenuAction*>(action_b))
|
||||
return false; // nothing to do
|
||||
|
||||
right = qMin(right, realActionCount());
|
||||
if (right < 0)
|
||||
return false; // nothing to do
|
||||
|
||||
formWindow()->beginCommand(QApplication::translate("Command", "Move action"));
|
||||
|
||||
QAction *action_b_before = safeActionAt(right + 1);
|
||||
|
||||
QDesignerFormWindowInterface *fw = formWindow();
|
||||
RemoveActionFromCommand *cmd1 = new RemoveActionFromCommand(fw);
|
||||
cmd1->init(this, action_b, action_b_before, false);
|
||||
fw->commandHistory()->push(cmd1);
|
||||
|
||||
QAction *action_a_before = safeActionAt(left + 1);
|
||||
|
||||
InsertActionIntoCommand *cmd2 = new InsertActionIntoCommand(fw);
|
||||
cmd2->init(this, action_b, action_a_before, false);
|
||||
fw->commandHistory()->push(cmd2);
|
||||
|
||||
RemoveActionFromCommand *cmd3 = new RemoveActionFromCommand(fw);
|
||||
cmd3->init(this, action_a, action_b, false);
|
||||
fw->commandHistory()->push(cmd3);
|
||||
|
||||
InsertActionIntoCommand *cmd4 = new InsertActionIntoCommand(fw);
|
||||
cmd4->init(this, action_a, action_b_before, true);
|
||||
fw->commandHistory()->push(cmd4);
|
||||
|
||||
fw->endCommand();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
event->ignore();
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::keyReleaseEvent(QKeyEvent *event)
|
||||
{
|
||||
event->ignore();
|
||||
}
|
||||
|
||||
void QDesignerMenuBar::updateCurrentAction(bool selectAction)
|
||||
{
|
||||
update();
|
||||
|
||||
if (!selectAction)
|
||||
return;
|
||||
|
||||
QAction *action = currentAction();
|
||||
if (!action || action == m_addMenu)
|
||||
return;
|
||||
|
||||
QMenu *menu = action->menu();
|
||||
if (!menu)
|
||||
return;
|
||||
|
||||
QDesignerObjectInspector *oi = 0;
|
||||
if (QDesignerFormWindowInterface *fw = formWindow())
|
||||
oi = qobject_cast<QDesignerObjectInspector *>(fw->core()->objectInspector());
|
||||
|
||||
if (!oi)
|
||||
return;
|
||||
|
||||
oi->clearSelection();
|
||||
oi->selectObject(menu);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
179
third/designer/lib/shared/qdesigner_menubar_p.h
Normal file
179
third/designer/lib/shared/qdesigner_menubar_p.h
Normal file
@@ -0,0 +1,179 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of Qt Designer. This header
|
||||
// file may change from version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#ifndef QDESIGNER_MENUBAR_H
|
||||
#define QDESIGNER_MENUBAR_H
|
||||
|
||||
#include "shared_global_p.h"
|
||||
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QMenuBar>
|
||||
|
||||
#include <QtCore/QPointer>
|
||||
#include <QtCore/QMimeData>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDesignerFormWindowInterface;
|
||||
class QDesignerActionProviderExtension;
|
||||
|
||||
class QLineEdit;
|
||||
class QMimeData;
|
||||
|
||||
namespace qdesigner_internal {
|
||||
class PromotionTaskMenu;
|
||||
|
||||
class SpecialMenuAction: public QAction
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SpecialMenuAction(QObject *parent = 0);
|
||||
virtual ~SpecialMenuAction();
|
||||
};
|
||||
|
||||
} // namespace qdesigner_internal
|
||||
|
||||
class QDESIGNER_SHARED_EXPORT QDesignerMenuBar: public QMenuBar
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QDesignerMenuBar(QWidget *parent = 0);
|
||||
virtual ~QDesignerMenuBar();
|
||||
|
||||
bool eventFilter(QObject *object, QEvent *event);
|
||||
|
||||
QDesignerFormWindowInterface *formWindow() const;
|
||||
QDesignerActionProviderExtension *actionProvider();
|
||||
|
||||
void adjustSpecialActions();
|
||||
bool interactive(bool i);
|
||||
bool dragging() const;
|
||||
|
||||
void moveLeft(bool ctrl = false);
|
||||
void moveRight(bool ctrl = false);
|
||||
void moveUp();
|
||||
void moveDown();
|
||||
|
||||
// Helpers for MenuTaskMenu/MenuBarTaskMenu extensions
|
||||
QList<QAction *> contextMenuActions();
|
||||
void deleteMenuAction(QAction *action);
|
||||
|
||||
private slots:
|
||||
void deleteMenu();
|
||||
void slotRemoveMenuBar();
|
||||
|
||||
protected:
|
||||
virtual void actionEvent(QActionEvent *event);
|
||||
virtual void dragEnterEvent(QDragEnterEvent *event);
|
||||
virtual void dragMoveEvent(QDragMoveEvent *event);
|
||||
virtual void dragLeaveEvent(QDragLeaveEvent *event);
|
||||
virtual void dropEvent(QDropEvent *event);
|
||||
virtual void paintEvent(QPaintEvent *event);
|
||||
virtual void focusOutEvent(QFocusEvent *event);
|
||||
virtual void keyPressEvent(QKeyEvent *event);
|
||||
virtual void keyReleaseEvent(QKeyEvent *event);
|
||||
|
||||
bool handleEvent(QWidget *widget, QEvent *event);
|
||||
bool handleMouseDoubleClickEvent(QWidget *widget, QMouseEvent *event);
|
||||
bool handleMousePressEvent(QWidget *widget, QMouseEvent *event);
|
||||
bool handleMouseReleaseEvent(QWidget *widget, QMouseEvent *event);
|
||||
bool handleMouseMoveEvent(QWidget *widget, QMouseEvent *event);
|
||||
bool handleContextMenuEvent(QWidget *widget, QContextMenuEvent *event);
|
||||
bool handleKeyPressEvent(QWidget *widget, QKeyEvent *event);
|
||||
|
||||
void startDrag(const QPoint &pos);
|
||||
|
||||
enum ActionDragCheck { NoActionDrag, ActionDragOnSubMenu, AcceptActionDrag };
|
||||
ActionDragCheck checkAction(QAction *action) const;
|
||||
|
||||
void adjustIndicator(const QPoint &pos);
|
||||
int findAction(const QPoint &pos) const;
|
||||
|
||||
QAction *currentAction() const;
|
||||
int realActionCount() const;
|
||||
|
||||
enum LeaveEditMode {
|
||||
Default = 0,
|
||||
ForceAccept
|
||||
};
|
||||
|
||||
void enterEditMode();
|
||||
void leaveEditMode(LeaveEditMode mode);
|
||||
void showLineEdit();
|
||||
|
||||
void showMenu(int index = -1);
|
||||
void hideMenu(int index = -1);
|
||||
|
||||
QAction *safeActionAt(int index) const;
|
||||
|
||||
bool swapActions(int a, int b);
|
||||
|
||||
private:
|
||||
void updateCurrentAction(bool selectAction);
|
||||
void movePrevious(bool ctrl);
|
||||
void moveNext(bool ctrl);
|
||||
|
||||
QAction *m_addMenu;
|
||||
QPointer<QMenu> m_activeMenu;
|
||||
QPoint m_startPosition;
|
||||
int m_currentIndex;
|
||||
bool m_interactive;
|
||||
QLineEdit *m_editor;
|
||||
bool m_dragging;
|
||||
int m_lastMenuActionIndex;
|
||||
QPointer<QWidget> m_lastFocusWidget;
|
||||
qdesigner_internal::PromotionTaskMenu* m_promotionTaskMenu;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QDESIGNER_MENUBAR_H
|
||||
80
third/designer/lib/shared/qdesigner_objectinspector.cpp
Normal file
80
third/designer/lib/shared/qdesigner_objectinspector.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qdesigner_objectinspector_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace qdesigner_internal {
|
||||
|
||||
QDesignerObjectInspector::QDesignerObjectInspector(QWidget *parent, Qt::WindowFlags flags) :
|
||||
QDesignerObjectInspectorInterface(parent, flags)
|
||||
{
|
||||
}
|
||||
|
||||
void QDesignerObjectInspector::mainContainerChanged()
|
||||
{
|
||||
}
|
||||
|
||||
void Selection::clear()
|
||||
{
|
||||
managed.clear();
|
||||
unmanaged.clear();
|
||||
objects.clear();
|
||||
}
|
||||
|
||||
bool Selection::empty() const
|
||||
{
|
||||
return managed.empty() && unmanaged.empty() && objects.empty();
|
||||
}
|
||||
|
||||
QObjectList Selection::selection() const
|
||||
{
|
||||
QObjectList rc(objects);
|
||||
foreach (QObject* o, managed)
|
||||
rc.push_back(o);
|
||||
foreach (QObject* o, unmanaged)
|
||||
rc.push_back(o);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user