forked from qt-creator/qt-creator
ModelEditor: Synchronize browser and diagram selection
Change-Id: Idfbf2db98123e00bc3cef13869a0535a35e41f42 Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
@@ -33,6 +33,7 @@
|
|||||||
#include <coreplugin/actionmanager/actioncontainer.h>
|
#include <coreplugin/actionmanager/actioncontainer.h>
|
||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
|
#include <utils/icon.h>
|
||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QShortcut>
|
#include <QShortcut>
|
||||||
@@ -53,6 +54,7 @@ public:
|
|||||||
QAction *deleteAction = 0;
|
QAction *deleteAction = 0;
|
||||||
QAction *selectAllAction = 0;
|
QAction *selectAllAction = 0;
|
||||||
QAction *openParentDiagramAction = 0;
|
QAction *openParentDiagramAction = 0;
|
||||||
|
QAction *synchronizeBrowserAction = 0;
|
||||||
QAction *exportDiagramAction = 0;
|
QAction *exportDiagramAction = 0;
|
||||||
QAction *zoomInAction = 0;
|
QAction *zoomInAction = 0;
|
||||||
QAction *zoomOutAction = 0;
|
QAction *zoomOutAction = 0;
|
||||||
@@ -116,6 +118,11 @@ QAction *ActionHandler::openParentDiagramAction() const
|
|||||||
return d->openParentDiagramAction;
|
return d->openParentDiagramAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QAction *ActionHandler::synchronizeBrowserAction() const
|
||||||
|
{
|
||||||
|
return d->synchronizeBrowserAction;
|
||||||
|
}
|
||||||
|
|
||||||
QAction *ActionHandler::exportDiagramAction() const
|
QAction *ActionHandler::exportDiagramAction() const
|
||||||
{
|
{
|
||||||
return d->exportDiagramAction;
|
return d->exportDiagramAction;
|
||||||
@@ -196,6 +203,13 @@ void ActionHandler::createActions()
|
|||||||
registerCommand(Constants::ACTION_ADD_COMPONENT, nullptr, Core::Context());
|
registerCommand(Constants::ACTION_ADD_COMPONENT, nullptr, Core::Context());
|
||||||
registerCommand(Constants::ACTION_ADD_CLASS, nullptr, Core::Context());
|
registerCommand(Constants::ACTION_ADD_CLASS, nullptr, Core::Context());
|
||||||
registerCommand(Constants::ACTION_ADD_CANVAS_DIAGRAM, nullptr, Core::Context());
|
registerCommand(Constants::ACTION_ADD_CANVAS_DIAGRAM, nullptr, Core::Context());
|
||||||
|
d->synchronizeBrowserAction = registerCommand(
|
||||||
|
Constants::ACTION_SYNC_BROWSER, nullptr, Core::Context(), true,
|
||||||
|
tr("Synchronize Browser and Diagram<br><i><small>Press&Hold for options</small></i>"))->action();
|
||||||
|
static const Utils::Icon
|
||||||
|
LINK_ICON({{ QStringLiteral(":/core/images/linkicon.png"), Utils::Theme::IconsBaseColor }});
|
||||||
|
d->synchronizeBrowserAction->setIcon(LINK_ICON.icon());
|
||||||
|
d->synchronizeBrowserAction->setCheckable(true);
|
||||||
|
|
||||||
auto editPropertiesAction = new QAction(tr("Edit Element Properties"), Core::ICore::mainWindow());
|
auto editPropertiesAction = new QAction(tr("Edit Element Properties"), Core::ICore::mainWindow());
|
||||||
Core::Command *editPropertiesCommand = Core::ActionManager::registerAction(
|
Core::Command *editPropertiesCommand = Core::ActionManager::registerAction(
|
||||||
|
@@ -63,6 +63,7 @@ public:
|
|||||||
QAction *deleteAction() const;
|
QAction *deleteAction() const;
|
||||||
QAction *selectAllAction() const;
|
QAction *selectAllAction() const;
|
||||||
QAction *openParentDiagramAction() const;
|
QAction *openParentDiagramAction() const;
|
||||||
|
QAction *synchronizeBrowserAction() const;
|
||||||
QAction *exportDiagramAction() const;
|
QAction *exportDiagramAction() const;
|
||||||
QAction *zoomInAction() const;
|
QAction *zoomInAction() const;
|
||||||
QAction *zoomOutAction() const;
|
QAction *zoomOutAction() const;
|
||||||
|
@@ -94,6 +94,7 @@
|
|||||||
#include <QToolBox>
|
#include <QToolBox>
|
||||||
#include <QUndoStack>
|
#include <QUndoStack>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
#include <QMenu>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@@ -127,6 +128,9 @@ public:
|
|||||||
QComboBox *diagramSelector = 0;
|
QComboBox *diagramSelector = 0;
|
||||||
SelectedArea selectedArea = SelectedArea::Nothing;
|
SelectedArea selectedArea = SelectedArea::Nothing;
|
||||||
QString lastExportDirPath;
|
QString lastExportDirPath;
|
||||||
|
QAction *syncBrowserWithDiagramAction = 0;
|
||||||
|
QAction *syncDiagramWithBrowserAction = 0;
|
||||||
|
QAction *syncEachOtherAction = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
ModelEditor::ModelEditor(UiController *uiController, ActionHandler *actionHandler, QWidget *parent)
|
ModelEditor::ModelEditor(UiController *uiController, ActionHandler *actionHandler, QWidget *parent)
|
||||||
@@ -168,9 +172,21 @@ bool ModelEditor::restoreState(const QByteArray &state)
|
|||||||
QDataStream stream(state);
|
QDataStream stream(state);
|
||||||
int version = 0;
|
int version = 0;
|
||||||
stream >> version;
|
stream >> version;
|
||||||
if (version == 1) {
|
if (version >= 1) {
|
||||||
qmt::Uid uid;
|
qmt::Uid uid;
|
||||||
stream >> uid;
|
stream >> uid;
|
||||||
|
if (version >= 2) {
|
||||||
|
bool sync = false;
|
||||||
|
bool syncBrowserWithDiagram = false;
|
||||||
|
bool syncDiagramWithBrowser = false;
|
||||||
|
bool syncEachOther = false;
|
||||||
|
stream >> sync >> syncBrowserWithDiagram >> syncDiagramWithBrowser >> syncEachOther;
|
||||||
|
d->actionHandler->synchronizeBrowserAction()->setChecked(sync);
|
||||||
|
d->syncBrowserWithDiagramAction->setChecked(
|
||||||
|
syncBrowserWithDiagram || (!syncDiagramWithBrowser && !syncEachOther));
|
||||||
|
d->syncDiagramWithBrowserAction->setChecked(syncDiagramWithBrowser);
|
||||||
|
d->syncEachOtherAction->setChecked(syncEachOther);
|
||||||
|
}
|
||||||
if (uid.isValid()) {
|
if (uid.isValid()) {
|
||||||
qmt::MDiagram *diagram = d->document->documentController()->modelController()->findObject<qmt::MDiagram>(uid);
|
qmt::MDiagram *diagram = d->document->documentController()->modelController()->findObject<qmt::MDiagram>(uid);
|
||||||
if (diagram) {
|
if (diagram) {
|
||||||
@@ -320,6 +336,23 @@ void ModelEditor::init(QWidget *parent)
|
|||||||
QIcon(QStringLiteral(":/modelinglib/48x48/canvas-diagram.png")),
|
QIcon(QStringLiteral(":/modelinglib/48x48/canvas-diagram.png")),
|
||||||
tr("Add Canvas Diagram"), d->toolbar));
|
tr("Add Canvas Diagram"), d->toolbar));
|
||||||
toolbarLayout->addSpacing(20);
|
toolbarLayout->addSpacing(20);
|
||||||
|
|
||||||
|
auto syncToggleButton = new Core::CommandButton(Constants::ACTION_SYNC_BROWSER, d->toolbar);
|
||||||
|
syncToggleButton->setDefaultAction(d->actionHandler->synchronizeBrowserAction());
|
||||||
|
QMenu *syncMenu = new QMenu(syncToggleButton);
|
||||||
|
QActionGroup *syncGroup = new QActionGroup(syncMenu);
|
||||||
|
d->syncBrowserWithDiagramAction = syncMenu->addAction(QStringLiteral("Synchronize Browser with Diagram"));
|
||||||
|
d->syncBrowserWithDiagramAction->setCheckable(true);
|
||||||
|
d->syncBrowserWithDiagramAction->setActionGroup(syncGroup);
|
||||||
|
d->syncDiagramWithBrowserAction = syncMenu->addAction(QStringLiteral("Synchronize Diagram with Browser"));
|
||||||
|
d->syncDiagramWithBrowserAction->setCheckable(true);
|
||||||
|
d->syncDiagramWithBrowserAction->setActionGroup(syncGroup);
|
||||||
|
d->syncEachOtherAction = syncMenu->addAction(QStringLiteral("Synchronize Each Other"));
|
||||||
|
d->syncEachOtherAction->setCheckable(true);
|
||||||
|
d->syncEachOtherAction->setActionGroup(syncGroup);
|
||||||
|
syncToggleButton->setMenu(syncMenu);
|
||||||
|
d->syncBrowserWithDiagramAction->setChecked(true);
|
||||||
|
toolbarLayout->addWidget(syncToggleButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelEditor::initDocument()
|
void ModelEditor::initDocument()
|
||||||
@@ -745,13 +778,17 @@ void ModelEditor::expandModelTreeToDepth(int depth)
|
|||||||
d->modelTreeView->expandToDepth(depth);
|
d->modelTreeView->expandToDepth(depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *ModelEditor::createToolbarCommandButton(const Core::Id &id, const std::function<void()> &slot,
|
QToolButton *ModelEditor::createToolbarCommandButton(const Core::Id &id, const std::function<void()> &slot,
|
||||||
const QIcon &icon, const QString &toolTipBase,
|
const QIcon &icon, const QString &toolTipBase,
|
||||||
QWidget *parent)
|
QWidget *parent)
|
||||||
{
|
{
|
||||||
auto button = new Core::CommandButton(id, parent);
|
auto button = new Core::CommandButton(id, parent);
|
||||||
button->setIcon(icon);
|
auto action = new QAction(button);
|
||||||
button->setToolTipBase(toolTipBase);
|
action->setIcon(icon);
|
||||||
|
action->setToolTip(toolTipBase);
|
||||||
|
button->setDefaultAction(action);
|
||||||
|
//button->setIcon(icon);
|
||||||
|
//button->setToolTipBase(toolTipBase);
|
||||||
connect(button, &Core::CommandButton::clicked, this, slot);
|
connect(button, &Core::CommandButton::clicked, this, slot);
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
@@ -854,6 +891,7 @@ void ModelEditor::onTreeViewSelectionChanged(const QItemSelection &selected,
|
|||||||
Q_UNUSED(selected);
|
Q_UNUSED(selected);
|
||||||
Q_UNUSED(deselected);
|
Q_UNUSED(deselected);
|
||||||
|
|
||||||
|
synchronizeDiagramWithBrowser();
|
||||||
updateSelectedArea(SelectedArea::TreeView);
|
updateSelectedArea(SelectedArea::TreeView);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -911,8 +949,10 @@ void ModelEditor::onNewElementCreated(qmt::DElement *element, qmt::MDiagram *dia
|
|||||||
|
|
||||||
void ModelEditor::onDiagramSelectionChanged(const qmt::MDiagram *diagram)
|
void ModelEditor::onDiagramSelectionChanged(const qmt::MDiagram *diagram)
|
||||||
{
|
{
|
||||||
if (diagram == currentDiagram())
|
if (diagram == currentDiagram()) {
|
||||||
|
synchronizeBrowserWithDiagram(diagram);
|
||||||
updateSelectedArea(SelectedArea::Diagram);
|
updateSelectedArea(SelectedArea::Diagram);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelEditor::onDiagramModified(const qmt::MDiagram *diagram)
|
void ModelEditor::onDiagramModified(const qmt::MDiagram *diagram)
|
||||||
@@ -1258,11 +1298,15 @@ QByteArray ModelEditor::saveState(const qmt::MDiagram *diagram) const
|
|||||||
{
|
{
|
||||||
QByteArray state;
|
QByteArray state;
|
||||||
QDataStream stream(&state, QIODevice::WriteOnly);
|
QDataStream stream(&state, QIODevice::WriteOnly);
|
||||||
stream << 1; // version number
|
stream << 2; // version number
|
||||||
if (diagram)
|
if (diagram)
|
||||||
stream << diagram->uid();
|
stream << diagram->uid();
|
||||||
else
|
else
|
||||||
stream << qmt::Uid::invalidUid();
|
stream << qmt::Uid::invalidUid();
|
||||||
|
stream << d->actionHandler->synchronizeBrowserAction()->isChecked()
|
||||||
|
<< d->syncBrowserWithDiagramAction->isChecked()
|
||||||
|
<< d->syncDiagramWithBrowserAction->isChecked()
|
||||||
|
<< d->syncEachOtherAction->isChecked();
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1287,5 +1331,79 @@ void ModelEditor::onEditSelectedElement()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ModelEditor::isSyncBrowserWithDiagram() const
|
||||||
|
{
|
||||||
|
return d->actionHandler->synchronizeBrowserAction()->isChecked()
|
||||||
|
&& (d->syncBrowserWithDiagramAction->isChecked() || d->syncEachOtherAction->isChecked());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ModelEditor::isSyncDiagramWithBrowser() const
|
||||||
|
{
|
||||||
|
return d->actionHandler->synchronizeBrowserAction()->isChecked()
|
||||||
|
&& (d->syncDiagramWithBrowserAction->isChecked() || d->syncEachOtherAction->isChecked());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelEditor::synchronizeDiagramWithBrowser()
|
||||||
|
{
|
||||||
|
if (isSyncDiagramWithBrowser()) {
|
||||||
|
if (currentDiagram()) {
|
||||||
|
bool done = false;
|
||||||
|
qmt::DocumentController *documentController = d->document->documentController();
|
||||||
|
QModelIndexList indexes = d->modelTreeView->selectedSourceModelIndexes();
|
||||||
|
if (!indexes.isEmpty()) {
|
||||||
|
foreach (const QModelIndex &index, indexes) {
|
||||||
|
if (index.isValid()) {
|
||||||
|
qmt::MElement *modelElement = documentController->treeModel()->element(index);
|
||||||
|
if (modelElement) {
|
||||||
|
foreach (qmt::DElement *diagramElement, currentDiagram()->diagramElements()) {
|
||||||
|
if (diagramElement->modelUid() == modelElement->uid()) {
|
||||||
|
// disconnect temporarily avoiding double update of properties Ui
|
||||||
|
disconnect(documentController->diagramsManager(), &qmt::DiagramsManager::diagramSelectionChanged,
|
||||||
|
this, &ModelEditor::onDiagramSelectionChanged);
|
||||||
|
d->diagramView->diagramSceneModel()->selectElement(diagramElement);
|
||||||
|
connect(documentController->diagramsManager(), &qmt::DiagramsManager::diagramSelectionChanged,
|
||||||
|
this, &ModelEditor::onDiagramSelectionChanged, Qt::QueuedConnection);
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (done)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelEditor::synchronizeBrowserWithDiagram(const qmt::MDiagram *diagram)
|
||||||
|
{
|
||||||
|
if (isSyncBrowserWithDiagram()) {
|
||||||
|
qmt::DocumentController *documentController = d->document->documentController();
|
||||||
|
qmt::DSelection selection = documentController->diagramsManager()->diagramSceneModel(diagram)->selectedElements();
|
||||||
|
if (!selection.isEmpty()) {
|
||||||
|
foreach (qmt::DSelection::Index index, selection.indices()) {
|
||||||
|
qmt::DElement *diagramElement = documentController->diagramController()->findElement(index.elementKey(), diagram);
|
||||||
|
if (diagramElement) {
|
||||||
|
qmt::MElement *modelElement = documentController->modelController()->findElement(diagramElement->modelUid());
|
||||||
|
if (modelElement) {
|
||||||
|
QModelIndex index = d->modelTreeViewServant->treeModel()->indexOf(modelElement);
|
||||||
|
if (index.isValid()) {
|
||||||
|
// disconnect temporarily avoiding double update of properties Ui
|
||||||
|
disconnect(d->modelTreeView->selectionModel(), &QItemSelectionModel::selectionChanged,
|
||||||
|
this, &ModelEditor::onTreeViewSelectionChanged);
|
||||||
|
d->modelTreeView->selectFromSourceModelIndex(index);
|
||||||
|
connect(d->modelTreeView->selectionModel(), &QItemSelectionModel::selectionChanged,
|
||||||
|
this, &ModelEditor::onTreeViewSelectionChanged, Qt::QueuedConnection);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace ModelEditor
|
} // namespace ModelEditor
|
||||||
|
@@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QItemSelection;
|
class QItemSelection;
|
||||||
|
class QToolButton;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace qmt {
|
namespace qmt {
|
||||||
@@ -101,7 +102,7 @@ private:
|
|||||||
void showProperties(qmt::MDiagram *diagram, const QList<qmt::DElement *> &diagramElements);
|
void showProperties(qmt::MDiagram *diagram, const QList<qmt::DElement *> &diagramElements);
|
||||||
void clearProperties();
|
void clearProperties();
|
||||||
void expandModelTreeToDepth(int depth);
|
void expandModelTreeToDepth(int depth);
|
||||||
QWidget *createToolbarCommandButton(const Core::Id &id, const std::function<void()> &slot,
|
QToolButton *createToolbarCommandButton(const Core::Id &id, const std::function<void()> &slot,
|
||||||
const QIcon &icon,
|
const QIcon &icon,
|
||||||
const QString &toolTipBase, QWidget *parent);
|
const QString &toolTipBase, QWidget *parent);
|
||||||
bool updateButtonIconByTheme(QAbstractButton *button, const QString &name);
|
bool updateButtonIconByTheme(QAbstractButton *button, const QString &name);
|
||||||
@@ -148,8 +149,11 @@ private:
|
|||||||
void addToNavigationHistory(const qmt::MDiagram *diagram);
|
void addToNavigationHistory(const qmt::MDiagram *diagram);
|
||||||
QByteArray saveState(const qmt::MDiagram *diagram) const;
|
QByteArray saveState(const qmt::MDiagram *diagram) const;
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onEditSelectedElement();
|
void onEditSelectedElement();
|
||||||
|
bool isSyncBrowserWithDiagram() const;
|
||||||
|
bool isSyncDiagramWithBrowser() const;
|
||||||
|
void synchronizeDiagramWithBrowser();
|
||||||
|
void synchronizeBrowserWithDiagram(const qmt::MDiagram *diagram);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ModelEditorPrivate *d;
|
ModelEditorPrivate *d;
|
||||||
|
@@ -43,6 +43,7 @@ const char ACTION_ADD_PACKAGE[] = "ModelEditor.Action.AddPackage";
|
|||||||
const char ACTION_ADD_COMPONENT[] = "ModelEditor.Action.AddComponent";
|
const char ACTION_ADD_COMPONENT[] = "ModelEditor.Action.AddComponent";
|
||||||
const char ACTION_ADD_CLASS[] = "ModelEditor.Action.AddClass";
|
const char ACTION_ADD_CLASS[] = "ModelEditor.Action.AddClass";
|
||||||
const char ACTION_ADD_CANVAS_DIAGRAM[] = "ModelEditor.Action.AddCanvasDiagram";
|
const char ACTION_ADD_CANVAS_DIAGRAM[] = "ModelEditor.Action.AddCanvasDiagram";
|
||||||
|
const char ACTION_SYNC_BROWSER[] = "ModelEditor.Action.SynchronizeBrowser";
|
||||||
|
|
||||||
const char EXPLORER_GROUP_MODELING[] = "ModelEditor.ProjectFolder.Group.Modeling";
|
const char EXPLORER_GROUP_MODELING[] = "ModelEditor.ProjectFolder.Group.Modeling";
|
||||||
const char ACTION_EXPLORER_OPEN_DIAGRAM[] = "ModelEditor.Action.Explorer.OpenDiagram";
|
const char ACTION_EXPLORER_OPEN_DIAGRAM[] = "ModelEditor.Action.Explorer.OpenDiagram";
|
||||||
|
Reference in New Issue
Block a user