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:
|
||||
\code
|
||||
MyInterfaceEx *objectEx = new MyInterfaceEx;
|
||||
Aggregate *aggregate = new Aggregate;
|
||||
aggregate->add(object);
|
||||
aggregate->add(objectEx);
|
||||
Aggregate::aggregate({object, objectEx})
|
||||
\endcode
|
||||
The aggregate bundles the two objects together.
|
||||
If we have any part of the collection we get all parts:
|
||||
@@ -130,7 +128,7 @@
|
||||
\sa add(), remove()
|
||||
*/
|
||||
|
||||
using namespace Aggregation;
|
||||
namespace Aggregation {
|
||||
|
||||
/*!
|
||||
Returns the aggregate object of \a obj if there is one. Otherwise returns 0.
|
||||
@@ -156,6 +154,20 @@ QReadWriteLock &Aggregate::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.
|
||||
The parent is directly passed to the QObject part
|
||||
@@ -165,7 +177,7 @@ Aggregate::Aggregate(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
QWriteLocker locker(&lock());
|
||||
aggregateMap().insert(this, this);
|
||||
construct();
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -241,3 +253,39 @@ void Aggregate::remove(QObject *component)
|
||||
}
|
||||
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();
|
||||
|
||||
private:
|
||||
friend void aggregate(QList<QObject *>);
|
||||
enum PrivateConstructor { PrivateConstructor };
|
||||
Aggregate(enum PrivateConstructor);
|
||||
void construct();
|
||||
|
||||
void deleteSelf(QObject *obj);
|
||||
|
||||
static QHash<QObject *, Aggregate *> &aggregateMap();
|
||||
@@ -58,6 +63,8 @@ private:
|
||||
QList<QObject *> m_components;
|
||||
};
|
||||
|
||||
AGGREGATION_EXPORT void aggregate(QList<QObject *> components);
|
||||
|
||||
// get a component via global template function
|
||||
template <typename T> T *query(Aggregate *obj)
|
||||
{
|
||||
|
||||
@@ -131,9 +131,7 @@ static QFrame *createHelper(QAbstractItemView *treeView,
|
||||
vbox->addWidget(treeView);
|
||||
vbox->addWidget(placeHolder);
|
||||
|
||||
auto agg = new Aggregation::Aggregate;
|
||||
agg->add(treeView);
|
||||
agg->add(finder);
|
||||
Aggregation::aggregate({treeView, finder});
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
@@ -116,10 +116,9 @@ SearchResultWidget::SearchResultWidget(QWidget *parent) :
|
||||
this, &SearchResultWidget::filterInvalidated);
|
||||
connect(m_searchResultTreeView, &SearchResultTreeView::filterChanged,
|
||||
this, &SearchResultWidget::filterChanged);
|
||||
auto agg = new Aggregation::Aggregate;
|
||||
agg->add(m_searchResultTreeView);
|
||||
agg->add(new ItemViewFind(m_searchResultTreeView,
|
||||
ItemDataRoles::ResultLineRole));
|
||||
|
||||
auto find = new ItemViewFind(m_searchResultTreeView, ItemDataRoles::ResultLineRole);
|
||||
Aggregation::aggregate({m_searchResultTreeView, find});
|
||||
layout->addWidget(m_searchResultTreeView);
|
||||
|
||||
m_infoBarDisplay.setTarget(layout, 2);
|
||||
|
||||
@@ -2531,9 +2531,7 @@ void ICorePrivate::changeLog()
|
||||
auto textEdit = new QTextBrowser;
|
||||
textEdit->setOpenExternalLinks(true);
|
||||
|
||||
auto aggregate = new Aggregation::Aggregate;
|
||||
aggregate->add(textEdit);
|
||||
aggregate->add(new Core::BaseTextFind(textEdit));
|
||||
Aggregation::aggregate({textEdit, new BaseTextFind(textEdit)});
|
||||
|
||||
new MarkdownHighlighter(textEdit->document());
|
||||
|
||||
|
||||
@@ -64,9 +64,8 @@ QWidget *LocatorManager::createLocatorInputWidget(QWidget *window)
|
||||
{
|
||||
auto locatorWidget = createStaticLocatorWidget(Locator::instance());
|
||||
// register locator widget for this window
|
||||
auto agg = new Aggregation::Aggregate;
|
||||
agg->add(window);
|
||||
agg->add(locatorWidget);
|
||||
Aggregation::aggregate({window, locatorWidget});
|
||||
|
||||
return locatorWidget;
|
||||
}
|
||||
|
||||
|
||||
@@ -174,9 +174,7 @@ OutputWindow::OutputWindow(Context context, const Key &settingsKey, QWidget *par
|
||||
p.setColor(QPalette::HighlightedText, activeHighlightedText);
|
||||
setPalette(p);
|
||||
|
||||
auto agg = new Aggregation::Aggregate;
|
||||
agg->add(this);
|
||||
agg->add(new BaseTextFind(this));
|
||||
Aggregation::aggregate({this, new BaseTextFind(this)});
|
||||
}
|
||||
|
||||
OutputWindow::~OutputWindow()
|
||||
|
||||
@@ -78,9 +78,7 @@ Console::Console()
|
||||
itemDelegate, &ConsoleItemDelegate::currentChanged);
|
||||
m_consoleView->setItemDelegate(itemDelegate);
|
||||
|
||||
auto aggregate = new Aggregation::Aggregate();
|
||||
aggregate->add(m_consoleView);
|
||||
aggregate->add(new Core::ItemViewFind(m_consoleView));
|
||||
Aggregation::aggregate({m_consoleView, new Core::ItemViewFind(m_consoleView)});
|
||||
|
||||
vbox->addWidget(m_consoleView);
|
||||
vbox->addWidget(new Core::FindToolBarPlaceHolder(m_consoleWidget));
|
||||
|
||||
@@ -410,13 +410,8 @@ LogWindow::LogWindow(DebuggerEngine *engine)
|
||||
layout->addWidget(new Core::FindToolBarPlaceHolder(this));
|
||||
setLayout(layout);
|
||||
|
||||
auto aggregate = new Aggregation::Aggregate;
|
||||
aggregate->add(m_combinedText);
|
||||
aggregate->add(new Core::BaseTextFind(m_combinedText));
|
||||
|
||||
aggregate = new Aggregation::Aggregate;
|
||||
aggregate->add(m_inputText);
|
||||
aggregate->add(new Core::BaseTextFind(m_inputText));
|
||||
Aggregation::aggregate({m_combinedText, new Core::BaseTextFind(m_combinedText)});
|
||||
Aggregation::aggregate({m_inputText, new Core::BaseTextFind(m_inputText)});
|
||||
|
||||
connect(m_inputText, &InputPane::statusMessageRequested,
|
||||
this, &LogWindow::statusMessageRequested);
|
||||
@@ -657,13 +652,8 @@ GlobalLogWindow::GlobalLogWindow()
|
||||
layout->addWidget(new Core::FindToolBarPlaceHolder(this));
|
||||
setLayout(layout);
|
||||
|
||||
auto aggregate = new Aggregation::Aggregate;
|
||||
aggregate->add(m_rightPane);
|
||||
aggregate->add(new Core::BaseTextFind(m_rightPane));
|
||||
|
||||
aggregate = new Aggregation::Aggregate;
|
||||
aggregate->add(m_leftPane);
|
||||
aggregate->add(new Core::BaseTextFind(m_leftPane));
|
||||
Aggregation::aggregate({m_rightPane, new Core::BaseTextFind(m_rightPane)});
|
||||
Aggregation::aggregate({m_leftPane, new Core::BaseTextFind(m_leftPane)});
|
||||
|
||||
connect(m_leftPane->clearContentsAction(), &QAction::triggered,
|
||||
this, &GlobalLogWindow::clearContents);
|
||||
|
||||
@@ -341,9 +341,7 @@ HelpViewer *createHelpViewer()
|
||||
viewer, &HelpViewer::setScrollWheelZoomingEnabled);
|
||||
|
||||
// add find support
|
||||
auto agg = new Aggregation::Aggregate;
|
||||
agg->add(viewer);
|
||||
agg->add(new HelpViewerFindSupport(viewer));
|
||||
Aggregation::aggregate({viewer, new HelpViewerFindSupport(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->setAutoAcceptChildRows(true);
|
||||
|
||||
auto agg = new Aggregation::Aggregate;
|
||||
agg->add(&d->m_treeView);
|
||||
agg->add(new Core::ItemViewFind(&d->m_treeView, TaskModel::Description));
|
||||
auto find = new Core::ItemViewFind(&d->m_treeView, TaskModel::Description);
|
||||
Aggregation::aggregate({&d->m_treeView, find});
|
||||
|
||||
d->m_treeView.setHeaderHidden(true);
|
||||
d->m_treeView.setExpandsOnDoubleClick(false);
|
||||
|
||||
@@ -107,9 +107,7 @@ QmlProfilerTraceView::QmlProfilerTraceView(QWidget *parent, QmlProfilerViewManag
|
||||
d->m_mainView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
setFocusProxy(d->m_mainView);
|
||||
|
||||
auto agg = new Aggregation::Aggregate;
|
||||
agg->add(d->m_mainView);
|
||||
agg->add(new TraceViewFindSupport(this, modelManager));
|
||||
Aggregation::aggregate({d->m_mainView, new TraceViewFindSupport(this, modelManager)});
|
||||
|
||||
groupLayout->addWidget(d->m_mainView);
|
||||
groupLayout->addWidget(new Core::FindToolBarPlaceHolder(this));
|
||||
|
||||
@@ -1071,14 +1071,12 @@ TextEditorWidgetPrivate::TextEditorWidgetPrivate(TextEditorWidget *parent)
|
||||
, m_editorContext(Id::generate())
|
||||
{
|
||||
m_selectionHighlightOverlay->show();
|
||||
auto aggregate = new Aggregation::Aggregate;
|
||||
m_find = new TextEditorWidgetFind(q);
|
||||
connect(m_find, &BaseTextFind::highlightAllRequested,
|
||||
this, &TextEditorWidgetPrivate::highlightSearchResultsSlot);
|
||||
connect(m_find, &BaseTextFind::findScopeChanged,
|
||||
this, &TextEditorWidgetPrivate::setFindScope);
|
||||
aggregate->add(m_find);
|
||||
aggregate->add(q);
|
||||
Aggregation::aggregate({q, m_find});
|
||||
|
||||
m_extraArea = new TextEditExtraArea(q);
|
||||
m_extraArea->setMouseTracking(true);
|
||||
|
||||
@@ -213,9 +213,8 @@ void TodoOutputPane::createTreeView()
|
||||
|
||||
m_todoTreeView = new TodoOutputTreeView();
|
||||
m_todoTreeView->setModel(m_filteredTodoItemsModel);
|
||||
auto agg = new Aggregation::Aggregate;
|
||||
agg->add(m_todoTreeView);
|
||||
agg->add(new Core::ItemViewFind(m_todoTreeView));
|
||||
|
||||
Aggregation::aggregate({m_todoTreeView, new Core::ItemViewFind(m_todoTreeView)});
|
||||
|
||||
connect(m_todoTreeView, &TodoOutputTreeView::activated, this, &TodoOutputPane::todoTreeViewClicked);
|
||||
}
|
||||
|
||||
@@ -213,9 +213,7 @@ void VcsBaseSubmitEditor::setParameters(const VcsBaseSubmitEditorParameters &par
|
||||
updateFileModel();
|
||||
});
|
||||
|
||||
auto aggregate = new Aggregation::Aggregate;
|
||||
aggregate->add(new BaseTextFind(descriptionEdit));
|
||||
aggregate->add(this);
|
||||
Aggregation::aggregate({this, new BaseTextFind(descriptionEdit)});
|
||||
}
|
||||
|
||||
VcsBaseSubmitEditor::~VcsBaseSubmitEditor()
|
||||
|
||||
@@ -16,6 +16,7 @@ private slots:
|
||||
void queryAggregation();
|
||||
void queryAll();
|
||||
void parentAggregate();
|
||||
void aggregateFunction();
|
||||
};
|
||||
|
||||
class Interface1 : public QObject
|
||||
@@ -177,6 +178,23 @@ void tst_Aggregate::parentAggregate()
|
||||
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)
|
||||
|
||||
#include "tst_aggregate.moc"
|
||||
|
||||
Reference in New Issue
Block a user