forked from qt-creator/qt-creator
Aggregation: Add a convenience function to create simple aggregates
Change-Id: I03300f1fcc20314d392012fd288ef0fc2501d403 Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -59,9 +59,7 @@
|
|||||||
at any point using an aggregate:
|
at any point using an aggregate:
|
||||||
\code
|
\code
|
||||||
MyInterfaceEx *objectEx = new MyInterfaceEx;
|
MyInterfaceEx *objectEx = new MyInterfaceEx;
|
||||||
Aggregate *aggregate = new Aggregate;
|
Aggregate::aggregate({object, objectEx})
|
||||||
aggregate->add(object);
|
|
||||||
aggregate->add(objectEx);
|
|
||||||
\endcode
|
\endcode
|
||||||
The aggregate bundles the two objects together.
|
The aggregate bundles the two objects together.
|
||||||
If we have any part of the collection we get all parts:
|
If we have any part of the collection we get all parts:
|
||||||
@@ -130,7 +128,7 @@
|
|||||||
\sa add(), remove()
|
\sa add(), remove()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using namespace Aggregation;
|
namespace Aggregation {
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the aggregate object of \a obj if there is one. Otherwise returns 0.
|
Returns the aggregate object of \a obj if there is one. Otherwise returns 0.
|
||||||
@@ -156,6 +154,20 @@ QReadWriteLock &Aggregate::lock()
|
|||||||
return lock;
|
return lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs without locking.
|
||||||
|
\internal
|
||||||
|
*/
|
||||||
|
Aggregate::Aggregate(enum PrivateConstructor)
|
||||||
|
{
|
||||||
|
construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Aggregate::construct()
|
||||||
|
{
|
||||||
|
aggregateMap().insert(this, this);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Creates a new aggregate with the given \a parent.
|
Creates a new aggregate with the given \a parent.
|
||||||
The parent is directly passed to the QObject part
|
The parent is directly passed to the QObject part
|
||||||
@@ -165,7 +177,7 @@ Aggregate::Aggregate(QObject *parent)
|
|||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
{
|
{
|
||||||
QWriteLocker locker(&lock());
|
QWriteLocker locker(&lock());
|
||||||
aggregateMap().insert(this, this);
|
construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -241,3 +253,39 @@ void Aggregate::remove(QObject *component)
|
|||||||
}
|
}
|
||||||
emit changed();
|
emit changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This is a convenience function that creates a new Aggregate and adds all
|
||||||
|
\a components to it. If any components already belong to an Aggregate,
|
||||||
|
the remaining components are added to that instead.
|
||||||
|
The components may not belong to different Aggregates to begin with.
|
||||||
|
|
||||||
|
\sa Aggregate
|
||||||
|
*/
|
||||||
|
void aggregate(QList<QObject *> components)
|
||||||
|
{
|
||||||
|
QWriteLocker locker(&Aggregate::lock());
|
||||||
|
Aggregate *agg = nullptr;
|
||||||
|
QList<QObject *> toAdd;
|
||||||
|
for (QObject *comp : components) {
|
||||||
|
Aggregate *existing = Aggregate::aggregateMap().value(comp);
|
||||||
|
if (existing) {
|
||||||
|
if (agg && agg != existing) {
|
||||||
|
qWarning() << "Cannot aggregate components that belong to different aggregates" << components;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
agg = existing;
|
||||||
|
} else {
|
||||||
|
toAdd << comp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!agg)
|
||||||
|
agg = new Aggregate(Aggregate::PrivateConstructor); // we already have locked
|
||||||
|
for (QObject *comp : toAdd) { // add
|
||||||
|
agg->m_components.append(comp);
|
||||||
|
QObject::connect(comp, &QObject::destroyed, agg, &Aggregate::deleteSelf);
|
||||||
|
Aggregate::aggregateMap().insert(comp, agg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Aggregation
|
||||||
|
|||||||
@@ -51,6 +51,11 @@ signals:
|
|||||||
void changed();
|
void changed();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend void aggregate(QList<QObject *>);
|
||||||
|
enum PrivateConstructor { PrivateConstructor };
|
||||||
|
Aggregate(enum PrivateConstructor);
|
||||||
|
void construct();
|
||||||
|
|
||||||
void deleteSelf(QObject *obj);
|
void deleteSelf(QObject *obj);
|
||||||
|
|
||||||
static QHash<QObject *, Aggregate *> &aggregateMap();
|
static QHash<QObject *, Aggregate *> &aggregateMap();
|
||||||
@@ -58,6 +63,8 @@ private:
|
|||||||
QList<QObject *> m_components;
|
QList<QObject *> m_components;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
AGGREGATION_EXPORT void aggregate(QList<QObject *> components);
|
||||||
|
|
||||||
// get a component via global template function
|
// get a component via global template function
|
||||||
template <typename T> T *query(Aggregate *obj)
|
template <typename T> T *query(Aggregate *obj)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -131,9 +131,7 @@ static QFrame *createHelper(QAbstractItemView *treeView,
|
|||||||
vbox->addWidget(treeView);
|
vbox->addWidget(treeView);
|
||||||
vbox->addWidget(placeHolder);
|
vbox->addWidget(placeHolder);
|
||||||
|
|
||||||
auto agg = new Aggregation::Aggregate;
|
Aggregation::aggregate({treeView, finder});
|
||||||
agg->add(treeView);
|
|
||||||
agg->add(finder);
|
|
||||||
|
|
||||||
return widget;
|
return widget;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,10 +116,9 @@ SearchResultWidget::SearchResultWidget(QWidget *parent) :
|
|||||||
this, &SearchResultWidget::filterInvalidated);
|
this, &SearchResultWidget::filterInvalidated);
|
||||||
connect(m_searchResultTreeView, &SearchResultTreeView::filterChanged,
|
connect(m_searchResultTreeView, &SearchResultTreeView::filterChanged,
|
||||||
this, &SearchResultWidget::filterChanged);
|
this, &SearchResultWidget::filterChanged);
|
||||||
auto agg = new Aggregation::Aggregate;
|
|
||||||
agg->add(m_searchResultTreeView);
|
auto find = new ItemViewFind(m_searchResultTreeView, ItemDataRoles::ResultLineRole);
|
||||||
agg->add(new ItemViewFind(m_searchResultTreeView,
|
Aggregation::aggregate({m_searchResultTreeView, find});
|
||||||
ItemDataRoles::ResultLineRole));
|
|
||||||
layout->addWidget(m_searchResultTreeView);
|
layout->addWidget(m_searchResultTreeView);
|
||||||
|
|
||||||
m_infoBarDisplay.setTarget(layout, 2);
|
m_infoBarDisplay.setTarget(layout, 2);
|
||||||
|
|||||||
@@ -2531,9 +2531,7 @@ void ICorePrivate::changeLog()
|
|||||||
auto textEdit = new QTextBrowser;
|
auto textEdit = new QTextBrowser;
|
||||||
textEdit->setOpenExternalLinks(true);
|
textEdit->setOpenExternalLinks(true);
|
||||||
|
|
||||||
auto aggregate = new Aggregation::Aggregate;
|
Aggregation::aggregate({textEdit, new BaseTextFind(textEdit)});
|
||||||
aggregate->add(textEdit);
|
|
||||||
aggregate->add(new Core::BaseTextFind(textEdit));
|
|
||||||
|
|
||||||
new MarkdownHighlighter(textEdit->document());
|
new MarkdownHighlighter(textEdit->document());
|
||||||
|
|
||||||
|
|||||||
@@ -64,9 +64,8 @@ QWidget *LocatorManager::createLocatorInputWidget(QWidget *window)
|
|||||||
{
|
{
|
||||||
auto locatorWidget = createStaticLocatorWidget(Locator::instance());
|
auto locatorWidget = createStaticLocatorWidget(Locator::instance());
|
||||||
// register locator widget for this window
|
// register locator widget for this window
|
||||||
auto agg = new Aggregation::Aggregate;
|
Aggregation::aggregate({window, locatorWidget});
|
||||||
agg->add(window);
|
|
||||||
agg->add(locatorWidget);
|
|
||||||
return locatorWidget;
|
return locatorWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -174,9 +174,7 @@ OutputWindow::OutputWindow(Context context, const Key &settingsKey, QWidget *par
|
|||||||
p.setColor(QPalette::HighlightedText, activeHighlightedText);
|
p.setColor(QPalette::HighlightedText, activeHighlightedText);
|
||||||
setPalette(p);
|
setPalette(p);
|
||||||
|
|
||||||
auto agg = new Aggregation::Aggregate;
|
Aggregation::aggregate({this, new BaseTextFind(this)});
|
||||||
agg->add(this);
|
|
||||||
agg->add(new BaseTextFind(this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputWindow::~OutputWindow()
|
OutputWindow::~OutputWindow()
|
||||||
|
|||||||
@@ -78,9 +78,7 @@ Console::Console()
|
|||||||
itemDelegate, &ConsoleItemDelegate::currentChanged);
|
itemDelegate, &ConsoleItemDelegate::currentChanged);
|
||||||
m_consoleView->setItemDelegate(itemDelegate);
|
m_consoleView->setItemDelegate(itemDelegate);
|
||||||
|
|
||||||
auto aggregate = new Aggregation::Aggregate();
|
Aggregation::aggregate({m_consoleView, new Core::ItemViewFind(m_consoleView)});
|
||||||
aggregate->add(m_consoleView);
|
|
||||||
aggregate->add(new Core::ItemViewFind(m_consoleView));
|
|
||||||
|
|
||||||
vbox->addWidget(m_consoleView);
|
vbox->addWidget(m_consoleView);
|
||||||
vbox->addWidget(new Core::FindToolBarPlaceHolder(m_consoleWidget));
|
vbox->addWidget(new Core::FindToolBarPlaceHolder(m_consoleWidget));
|
||||||
|
|||||||
@@ -410,13 +410,8 @@ LogWindow::LogWindow(DebuggerEngine *engine)
|
|||||||
layout->addWidget(new Core::FindToolBarPlaceHolder(this));
|
layout->addWidget(new Core::FindToolBarPlaceHolder(this));
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
|
|
||||||
auto aggregate = new Aggregation::Aggregate;
|
Aggregation::aggregate({m_combinedText, new Core::BaseTextFind(m_combinedText)});
|
||||||
aggregate->add(m_combinedText);
|
Aggregation::aggregate({m_inputText, new Core::BaseTextFind(m_inputText)});
|
||||||
aggregate->add(new Core::BaseTextFind(m_combinedText));
|
|
||||||
|
|
||||||
aggregate = new Aggregation::Aggregate;
|
|
||||||
aggregate->add(m_inputText);
|
|
||||||
aggregate->add(new Core::BaseTextFind(m_inputText));
|
|
||||||
|
|
||||||
connect(m_inputText, &InputPane::statusMessageRequested,
|
connect(m_inputText, &InputPane::statusMessageRequested,
|
||||||
this, &LogWindow::statusMessageRequested);
|
this, &LogWindow::statusMessageRequested);
|
||||||
@@ -657,13 +652,8 @@ GlobalLogWindow::GlobalLogWindow()
|
|||||||
layout->addWidget(new Core::FindToolBarPlaceHolder(this));
|
layout->addWidget(new Core::FindToolBarPlaceHolder(this));
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
|
|
||||||
auto aggregate = new Aggregation::Aggregate;
|
Aggregation::aggregate({m_rightPane, new Core::BaseTextFind(m_rightPane)});
|
||||||
aggregate->add(m_rightPane);
|
Aggregation::aggregate({m_leftPane, new Core::BaseTextFind(m_leftPane)});
|
||||||
aggregate->add(new Core::BaseTextFind(m_rightPane));
|
|
||||||
|
|
||||||
aggregate = new Aggregation::Aggregate;
|
|
||||||
aggregate->add(m_leftPane);
|
|
||||||
aggregate->add(new Core::BaseTextFind(m_leftPane));
|
|
||||||
|
|
||||||
connect(m_leftPane->clearContentsAction(), &QAction::triggered,
|
connect(m_leftPane->clearContentsAction(), &QAction::triggered,
|
||||||
this, &GlobalLogWindow::clearContents);
|
this, &GlobalLogWindow::clearContents);
|
||||||
|
|||||||
@@ -341,9 +341,7 @@ HelpViewer *createHelpViewer()
|
|||||||
viewer, &HelpViewer::setScrollWheelZoomingEnabled);
|
viewer, &HelpViewer::setScrollWheelZoomingEnabled);
|
||||||
|
|
||||||
// add find support
|
// add find support
|
||||||
auto agg = new Aggregation::Aggregate;
|
Aggregation::aggregate({viewer, new HelpViewerFindSupport(viewer)});
|
||||||
agg->add(viewer);
|
|
||||||
agg->add(new HelpViewerFindSupport(viewer));
|
|
||||||
|
|
||||||
return viewer;
|
return viewer;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,9 +172,8 @@ TaskWindow::TaskWindow() : d(std::make_unique<TaskWindowPrivate>())
|
|||||||
d->m_filter = new Internal::TaskFilterModel(d->m_model);
|
d->m_filter = new Internal::TaskFilterModel(d->m_model);
|
||||||
d->m_filter->setAutoAcceptChildRows(true);
|
d->m_filter->setAutoAcceptChildRows(true);
|
||||||
|
|
||||||
auto agg = new Aggregation::Aggregate;
|
auto find = new Core::ItemViewFind(&d->m_treeView, TaskModel::Description);
|
||||||
agg->add(&d->m_treeView);
|
Aggregation::aggregate({&d->m_treeView, find});
|
||||||
agg->add(new Core::ItemViewFind(&d->m_treeView, TaskModel::Description));
|
|
||||||
|
|
||||||
d->m_treeView.setHeaderHidden(true);
|
d->m_treeView.setHeaderHidden(true);
|
||||||
d->m_treeView.setExpandsOnDoubleClick(false);
|
d->m_treeView.setExpandsOnDoubleClick(false);
|
||||||
|
|||||||
@@ -107,9 +107,7 @@ QmlProfilerTraceView::QmlProfilerTraceView(QWidget *parent, QmlProfilerViewManag
|
|||||||
d->m_mainView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
d->m_mainView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
setFocusProxy(d->m_mainView);
|
setFocusProxy(d->m_mainView);
|
||||||
|
|
||||||
auto agg = new Aggregation::Aggregate;
|
Aggregation::aggregate({d->m_mainView, new TraceViewFindSupport(this, modelManager)});
|
||||||
agg->add(d->m_mainView);
|
|
||||||
agg->add(new TraceViewFindSupport(this, modelManager));
|
|
||||||
|
|
||||||
groupLayout->addWidget(d->m_mainView);
|
groupLayout->addWidget(d->m_mainView);
|
||||||
groupLayout->addWidget(new Core::FindToolBarPlaceHolder(this));
|
groupLayout->addWidget(new Core::FindToolBarPlaceHolder(this));
|
||||||
|
|||||||
@@ -1071,14 +1071,12 @@ TextEditorWidgetPrivate::TextEditorWidgetPrivate(TextEditorWidget *parent)
|
|||||||
, m_editorContext(Id::generate())
|
, m_editorContext(Id::generate())
|
||||||
{
|
{
|
||||||
m_selectionHighlightOverlay->show();
|
m_selectionHighlightOverlay->show();
|
||||||
auto aggregate = new Aggregation::Aggregate;
|
|
||||||
m_find = new TextEditorWidgetFind(q);
|
m_find = new TextEditorWidgetFind(q);
|
||||||
connect(m_find, &BaseTextFind::highlightAllRequested,
|
connect(m_find, &BaseTextFind::highlightAllRequested,
|
||||||
this, &TextEditorWidgetPrivate::highlightSearchResultsSlot);
|
this, &TextEditorWidgetPrivate::highlightSearchResultsSlot);
|
||||||
connect(m_find, &BaseTextFind::findScopeChanged,
|
connect(m_find, &BaseTextFind::findScopeChanged,
|
||||||
this, &TextEditorWidgetPrivate::setFindScope);
|
this, &TextEditorWidgetPrivate::setFindScope);
|
||||||
aggregate->add(m_find);
|
Aggregation::aggregate({q, m_find});
|
||||||
aggregate->add(q);
|
|
||||||
|
|
||||||
m_extraArea = new TextEditExtraArea(q);
|
m_extraArea = new TextEditExtraArea(q);
|
||||||
m_extraArea->setMouseTracking(true);
|
m_extraArea->setMouseTracking(true);
|
||||||
|
|||||||
@@ -213,9 +213,8 @@ void TodoOutputPane::createTreeView()
|
|||||||
|
|
||||||
m_todoTreeView = new TodoOutputTreeView();
|
m_todoTreeView = new TodoOutputTreeView();
|
||||||
m_todoTreeView->setModel(m_filteredTodoItemsModel);
|
m_todoTreeView->setModel(m_filteredTodoItemsModel);
|
||||||
auto agg = new Aggregation::Aggregate;
|
|
||||||
agg->add(m_todoTreeView);
|
Aggregation::aggregate({m_todoTreeView, new Core::ItemViewFind(m_todoTreeView)});
|
||||||
agg->add(new Core::ItemViewFind(m_todoTreeView));
|
|
||||||
|
|
||||||
connect(m_todoTreeView, &TodoOutputTreeView::activated, this, &TodoOutputPane::todoTreeViewClicked);
|
connect(m_todoTreeView, &TodoOutputTreeView::activated, this, &TodoOutputPane::todoTreeViewClicked);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -213,9 +213,7 @@ void VcsBaseSubmitEditor::setParameters(const VcsBaseSubmitEditorParameters &par
|
|||||||
updateFileModel();
|
updateFileModel();
|
||||||
});
|
});
|
||||||
|
|
||||||
auto aggregate = new Aggregation::Aggregate;
|
Aggregation::aggregate({this, new BaseTextFind(descriptionEdit)});
|
||||||
aggregate->add(new BaseTextFind(descriptionEdit));
|
|
||||||
aggregate->add(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VcsBaseSubmitEditor::~VcsBaseSubmitEditor()
|
VcsBaseSubmitEditor::~VcsBaseSubmitEditor()
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ private slots:
|
|||||||
void queryAggregation();
|
void queryAggregation();
|
||||||
void queryAll();
|
void queryAll();
|
||||||
void parentAggregate();
|
void parentAggregate();
|
||||||
|
void aggregateFunction();
|
||||||
};
|
};
|
||||||
|
|
||||||
class Interface1 : public QObject
|
class Interface1 : public QObject
|
||||||
@@ -177,6 +178,23 @@ void tst_Aggregate::parentAggregate()
|
|||||||
QCOMPARE(Aggregation::Aggregate::parentAggregate(component11), (Aggregation::Aggregate *)0);
|
QCOMPARE(Aggregation::Aggregate::parentAggregate(component11), (Aggregation::Aggregate *)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_Aggregate::aggregateFunction()
|
||||||
|
{
|
||||||
|
Interface1 component1;
|
||||||
|
auto component2 = new Interface2;
|
||||||
|
Aggregation::aggregate({&component1, component2});
|
||||||
|
Aggregation::Aggregate *agg = Aggregation::Aggregate::parentAggregate(&component1);
|
||||||
|
QCOMPARE(Aggregation::query<Interface1>(component2), &component1);
|
||||||
|
QCOMPARE(Aggregation::query<Interface2>(&component1), component2);
|
||||||
|
|
||||||
|
auto component3 = new Interface3;
|
||||||
|
Aggregation::aggregate({component2, component3});
|
||||||
|
QCOMPARE(Aggregation::Aggregate::parentAggregate(component3), agg);
|
||||||
|
QCOMPARE(Aggregation::query<Interface1>(component3), &component1);
|
||||||
|
QCOMPARE(Aggregation::query<Interface2>(component3), component2);
|
||||||
|
QCOMPARE(Aggregation::query<Interface3>(&component1), component3);
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(tst_Aggregate)
|
QTEST_GUILESS_MAIN(tst_Aggregate)
|
||||||
|
|
||||||
#include "tst_aggregate.moc"
|
#include "tst_aggregate.moc"
|
||||||
|
|||||||
Reference in New Issue
Block a user