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/editormanager/editormanager.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <utils/icon.h>
|
||||
|
||||
#include <QAction>
|
||||
#include <QShortcut>
|
||||
@@ -53,6 +54,7 @@ public:
|
||||
QAction *deleteAction = 0;
|
||||
QAction *selectAllAction = 0;
|
||||
QAction *openParentDiagramAction = 0;
|
||||
QAction *synchronizeBrowserAction = 0;
|
||||
QAction *exportDiagramAction = 0;
|
||||
QAction *zoomInAction = 0;
|
||||
QAction *zoomOutAction = 0;
|
||||
@@ -116,6 +118,11 @@ QAction *ActionHandler::openParentDiagramAction() const
|
||||
return d->openParentDiagramAction;
|
||||
}
|
||||
|
||||
QAction *ActionHandler::synchronizeBrowserAction() const
|
||||
{
|
||||
return d->synchronizeBrowserAction;
|
||||
}
|
||||
|
||||
QAction *ActionHandler::exportDiagramAction() const
|
||||
{
|
||||
return d->exportDiagramAction;
|
||||
@@ -196,6 +203,13 @@ void ActionHandler::createActions()
|
||||
registerCommand(Constants::ACTION_ADD_COMPONENT, nullptr, Core::Context());
|
||||
registerCommand(Constants::ACTION_ADD_CLASS, 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());
|
||||
Core::Command *editPropertiesCommand = Core::ActionManager::registerAction(
|
||||
|
@@ -63,6 +63,7 @@ public:
|
||||
QAction *deleteAction() const;
|
||||
QAction *selectAllAction() const;
|
||||
QAction *openParentDiagramAction() const;
|
||||
QAction *synchronizeBrowserAction() const;
|
||||
QAction *exportDiagramAction() const;
|
||||
QAction *zoomInAction() const;
|
||||
QAction *zoomOutAction() const;
|
||||
|
@@ -94,6 +94,7 @@
|
||||
#include <QToolBox>
|
||||
#include <QUndoStack>
|
||||
#include <QVBoxLayout>
|
||||
#include <QMenu>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -127,6 +128,9 @@ public:
|
||||
QComboBox *diagramSelector = 0;
|
||||
SelectedArea selectedArea = SelectedArea::Nothing;
|
||||
QString lastExportDirPath;
|
||||
QAction *syncBrowserWithDiagramAction = 0;
|
||||
QAction *syncDiagramWithBrowserAction = 0;
|
||||
QAction *syncEachOtherAction = 0;
|
||||
};
|
||||
|
||||
ModelEditor::ModelEditor(UiController *uiController, ActionHandler *actionHandler, QWidget *parent)
|
||||
@@ -168,9 +172,21 @@ bool ModelEditor::restoreState(const QByteArray &state)
|
||||
QDataStream stream(state);
|
||||
int version = 0;
|
||||
stream >> version;
|
||||
if (version == 1) {
|
||||
if (version >= 1) {
|
||||
qmt::Uid 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()) {
|
||||
qmt::MDiagram *diagram = d->document->documentController()->modelController()->findObject<qmt::MDiagram>(uid);
|
||||
if (diagram) {
|
||||
@@ -320,6 +336,23 @@ void ModelEditor::init(QWidget *parent)
|
||||
QIcon(QStringLiteral(":/modelinglib/48x48/canvas-diagram.png")),
|
||||
tr("Add Canvas Diagram"), d->toolbar));
|
||||
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()
|
||||
@@ -745,13 +778,17 @@ void ModelEditor::expandModelTreeToDepth(int depth)
|
||||
d->modelTreeView->expandToDepth(depth);
|
||||
}
|
||||
|
||||
QWidget *ModelEditor::createToolbarCommandButton(const Core::Id &id, const std::function<void()> &slot,
|
||||
const QIcon &icon, const QString &toolTipBase,
|
||||
QWidget *parent)
|
||||
QToolButton *ModelEditor::createToolbarCommandButton(const Core::Id &id, const std::function<void()> &slot,
|
||||
const QIcon &icon, const QString &toolTipBase,
|
||||
QWidget *parent)
|
||||
{
|
||||
auto button = new Core::CommandButton(id, parent);
|
||||
button->setIcon(icon);
|
||||
button->setToolTipBase(toolTipBase);
|
||||
auto action = new QAction(button);
|
||||
action->setIcon(icon);
|
||||
action->setToolTip(toolTipBase);
|
||||
button->setDefaultAction(action);
|
||||
//button->setIcon(icon);
|
||||
//button->setToolTipBase(toolTipBase);
|
||||
connect(button, &Core::CommandButton::clicked, this, slot);
|
||||
return button;
|
||||
}
|
||||
@@ -854,6 +891,7 @@ void ModelEditor::onTreeViewSelectionChanged(const QItemSelection &selected,
|
||||
Q_UNUSED(selected);
|
||||
Q_UNUSED(deselected);
|
||||
|
||||
synchronizeDiagramWithBrowser();
|
||||
updateSelectedArea(SelectedArea::TreeView);
|
||||
}
|
||||
|
||||
@@ -911,8 +949,10 @@ void ModelEditor::onNewElementCreated(qmt::DElement *element, qmt::MDiagram *dia
|
||||
|
||||
void ModelEditor::onDiagramSelectionChanged(const qmt::MDiagram *diagram)
|
||||
{
|
||||
if (diagram == currentDiagram())
|
||||
if (diagram == currentDiagram()) {
|
||||
synchronizeBrowserWithDiagram(diagram);
|
||||
updateSelectedArea(SelectedArea::Diagram);
|
||||
}
|
||||
}
|
||||
|
||||
void ModelEditor::onDiagramModified(const qmt::MDiagram *diagram)
|
||||
@@ -1258,11 +1298,15 @@ QByteArray ModelEditor::saveState(const qmt::MDiagram *diagram) const
|
||||
{
|
||||
QByteArray state;
|
||||
QDataStream stream(&state, QIODevice::WriteOnly);
|
||||
stream << 1; // version number
|
||||
stream << 2; // version number
|
||||
if (diagram)
|
||||
stream << diagram->uid();
|
||||
else
|
||||
stream << qmt::Uid::invalidUid();
|
||||
stream << d->actionHandler->synchronizeBrowserAction()->isChecked()
|
||||
<< d->syncBrowserWithDiagramAction->isChecked()
|
||||
<< d->syncDiagramWithBrowserAction->isChecked()
|
||||
<< d->syncEachOtherAction->isChecked();
|
||||
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 ModelEditor
|
||||
|
@@ -33,6 +33,7 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QItemSelection;
|
||||
class QToolButton;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace qmt {
|
||||
@@ -101,7 +102,7 @@ private:
|
||||
void showProperties(qmt::MDiagram *diagram, const QList<qmt::DElement *> &diagramElements);
|
||||
void clearProperties();
|
||||
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 QString &toolTipBase, QWidget *parent);
|
||||
bool updateButtonIconByTheme(QAbstractButton *button, const QString &name);
|
||||
@@ -148,8 +149,11 @@ private:
|
||||
void addToNavigationHistory(const qmt::MDiagram *diagram);
|
||||
QByteArray saveState(const qmt::MDiagram *diagram) const;
|
||||
|
||||
private slots:
|
||||
void onEditSelectedElement();
|
||||
bool isSyncBrowserWithDiagram() const;
|
||||
bool isSyncDiagramWithBrowser() const;
|
||||
void synchronizeDiagramWithBrowser();
|
||||
void synchronizeBrowserWithDiagram(const qmt::MDiagram *diagram);
|
||||
|
||||
private:
|
||||
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_CLASS[] = "ModelEditor.Action.AddClass";
|
||||
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 ACTION_EXPLORER_OPEN_DIAGRAM[] = "ModelEditor.Action.Explorer.OpenDiagram";
|
||||
|
Reference in New Issue
Block a user