forked from qt-creator/qt-creator
ProjectWindow: Cache widgets that are used on the project mode
Task-number: QTCREATORBUG-8182 Change-Id: Ica47a0258b2ad91bcc530cd2b7c4516d671d4ad1 Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
This commit is contained in:
@@ -129,6 +129,13 @@ QStringList DoubleTabWidget::subTabs(int index) const
|
|||||||
return QStringList();
|
return QStringList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DoubleTabWidget::setSubTabs(int index, const QStringList &subTabs)
|
||||||
|
{
|
||||||
|
if (index >= 0 && index < m_tabs.size())
|
||||||
|
m_tabs[index].subTabs = subTabs;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
void DoubleTabWidget::setCurrentIndex(int index, int subIndex)
|
void DoubleTabWidget::setCurrentIndex(int index, int subIndex)
|
||||||
{
|
{
|
||||||
Q_ASSERT(index < m_tabs.size());
|
Q_ASSERT(index < m_tabs.size());
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ public:
|
|||||||
int currentSubIndex() const;
|
int currentSubIndex() const;
|
||||||
|
|
||||||
QStringList subTabs(int index) const;
|
QStringList subTabs(int index) const;
|
||||||
|
void setSubTabs(int index, const QStringList &subTabs);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void currentIndexChanged(int index, int subIndex);
|
void currentIndexChanged(int index, int subIndex);
|
||||||
|
|||||||
@@ -270,6 +270,7 @@ struct ProjectExplorerPluginPrivate {
|
|||||||
bool m_shuttingDown;
|
bool m_shuttingDown;
|
||||||
bool m_ignoreDocumentManagerChangedFile;
|
bool m_ignoreDocumentManagerChangedFile;
|
||||||
QStringList m_arguments;
|
QStringList m_arguments;
|
||||||
|
QList<ProjectPanelFactory *> m_panelFactories;
|
||||||
};
|
};
|
||||||
|
|
||||||
ProjectExplorerPluginPrivate::ProjectExplorerPluginPrivate() :
|
ProjectExplorerPluginPrivate::ProjectExplorerPluginPrivate() :
|
||||||
@@ -325,7 +326,6 @@ ProjectExplorerPlugin::~ProjectExplorerPlugin()
|
|||||||
delete d->m_kitManager; // remove all the profile informations
|
delete d->m_kitManager; // remove all the profile informations
|
||||||
delete d->m_toolChainManager;
|
delete d->m_toolChainManager;
|
||||||
ProjectPanelFactory::destroyFactories();
|
ProjectPanelFactory::destroyFactories();
|
||||||
|
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ void ProjectWindow::aboutToShutdown()
|
|||||||
{
|
{
|
||||||
showProperties(-1, -1); // that's a bit stupid, but otherwise stuff is still
|
showProperties(-1, -1); // that's a bit stupid, but otherwise stuff is still
|
||||||
// connected to the session
|
// connected to the session
|
||||||
|
m_cache.clear();
|
||||||
disconnect(KitManager::instance(), 0, this, 0);
|
disconnect(KitManager::instance(), 0, this, 0);
|
||||||
disconnect(SessionManager::instance(), 0, this, 0);
|
disconnect(SessionManager::instance(), 0, this, 0);
|
||||||
}
|
}
|
||||||
@@ -109,41 +110,34 @@ void ProjectWindow::removedTarget(Target *)
|
|||||||
projectUpdated(p);
|
projectUpdated(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectWindow::projectUpdated(Project *p)
|
void ProjectWindow::projectUpdated(Project *project)
|
||||||
{
|
{
|
||||||
// Called after a project was configured
|
// Called after a project was configured
|
||||||
int index = m_tabWidget->currentIndex();
|
int currentIndex = m_tabWidget->currentIndex();
|
||||||
if (deregisterProject(p)) // might return false if the project is unloading
|
int oldSubIndex = m_tabWidget->currentSubIndex();
|
||||||
registerProject(p);
|
|
||||||
m_tabWidget->setCurrentIndex(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList ProjectWindow::tabDisplayNamesFor(Project *project)
|
removeCurrentWidget();
|
||||||
{
|
|
||||||
QStringList subTabs;
|
|
||||||
foreach (ProjectPanelFactory *panelFactory, ProjectPanelFactory::factories()) {
|
|
||||||
if (panelFactory->supports(project))
|
|
||||||
subTabs << panelFactory->displayName();
|
|
||||||
}
|
|
||||||
return subTabs;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ProjectWindow::insertPosFor(Project *project)
|
int newSubIndex = m_cache.recheckFactories(project, oldSubIndex);
|
||||||
{
|
if (newSubIndex == -1)
|
||||||
int newIndex = -1;
|
newSubIndex = 0;
|
||||||
for (int i = 0; i <= m_tabIndexToProject.count(); ++i) {
|
m_tabWidget->setSubTabs(currentIndex, m_cache.tabNames(project));
|
||||||
if (i == m_tabIndexToProject.count() ||
|
m_ignoreChange = true;
|
||||||
m_tabIndexToProject.at(i)->displayName() > project->displayName()) {
|
m_tabWidget->setCurrentIndex(currentIndex, newSubIndex);
|
||||||
newIndex = i;
|
m_ignoreChange = false;
|
||||||
break;
|
|
||||||
}
|
QWidget *widget = m_cache.widgetFor(project, newSubIndex);
|
||||||
|
if (widget) {
|
||||||
|
m_currentWidget = widget;
|
||||||
|
m_centralWidget->addWidget(m_currentWidget);
|
||||||
|
m_centralWidget->setCurrentWidget(m_currentWidget);
|
||||||
|
m_currentWidget->show();
|
||||||
}
|
}
|
||||||
return newIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectWindow::projectDisplayNameChanged(Project *project)
|
void ProjectWindow::projectDisplayNameChanged(Project *project)
|
||||||
{
|
{
|
||||||
int index = m_tabIndexToProject.indexOf(project);
|
int index = m_cache.indexForProject(project);
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -151,11 +145,11 @@ void ProjectWindow::projectDisplayNameChanged(Project *project)
|
|||||||
bool isCurrentIndex = m_tabWidget->currentIndex() == index;
|
bool isCurrentIndex = m_tabWidget->currentIndex() == index;
|
||||||
int subIndex = m_tabWidget->currentSubIndex();
|
int subIndex = m_tabWidget->currentSubIndex();
|
||||||
QStringList subTabs = m_tabWidget->subTabs(index);
|
QStringList subTabs = m_tabWidget->subTabs(index);
|
||||||
m_tabIndexToProject.removeAt(index);
|
|
||||||
m_tabWidget->removeTab(index);
|
m_tabWidget->removeTab(index);
|
||||||
|
|
||||||
int newIndex = insertPosFor(project);
|
m_cache.sort();
|
||||||
m_tabIndexToProject.insert(newIndex, project);
|
|
||||||
|
int newIndex = m_cache.indexForProject(project);
|
||||||
m_tabWidget->insertTab(newIndex, project->displayName(), project->projectFilePath().toString(), subTabs);
|
m_tabWidget->insertTab(newIndex, project->displayName(), project->projectFilePath().toString(), subTabs);
|
||||||
|
|
||||||
if (isCurrentIndex)
|
if (isCurrentIndex)
|
||||||
@@ -165,16 +159,14 @@ void ProjectWindow::projectDisplayNameChanged(Project *project)
|
|||||||
|
|
||||||
void ProjectWindow::registerProject(ProjectExplorer::Project *project)
|
void ProjectWindow::registerProject(ProjectExplorer::Project *project)
|
||||||
{
|
{
|
||||||
if (!project || m_tabIndexToProject.contains(project))
|
if (m_cache.isRegistered(project))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// find index to insert:
|
m_cache.registerProject(project);
|
||||||
int index = insertPosFor(project);
|
m_tabWidget->insertTab(m_cache.indexForProject(project),
|
||||||
|
project->displayName(),
|
||||||
// Add the project specific pages
|
project->projectFilePath().toString(),
|
||||||
QStringList subtabs = tabDisplayNamesFor(project);
|
m_cache.tabNames(project));
|
||||||
m_tabIndexToProject.insert(index, project);
|
|
||||||
m_tabWidget->insertTab(index, project->displayName(), project->projectFilePath().toString(), subtabs);
|
|
||||||
|
|
||||||
connect(project, SIGNAL(removedTarget(ProjectExplorer::Target*)),
|
connect(project, SIGNAL(removedTarget(ProjectExplorer::Target*)),
|
||||||
this, SLOT(removedTarget(ProjectExplorer::Target*)));
|
this, SLOT(removedTarget(ProjectExplorer::Target*)));
|
||||||
@@ -182,11 +174,14 @@ void ProjectWindow::registerProject(ProjectExplorer::Project *project)
|
|||||||
|
|
||||||
bool ProjectWindow::deregisterProject(ProjectExplorer::Project *project)
|
bool ProjectWindow::deregisterProject(ProjectExplorer::Project *project)
|
||||||
{
|
{
|
||||||
int index = m_tabIndexToProject.indexOf(project);
|
int index = m_cache.indexForProject(project);
|
||||||
if (index < 0)
|
if (index == -1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_tabIndexToProject.removeAt(index);
|
QVector<QWidget *> deletedWidgets = m_cache.deregisterProject(project);
|
||||||
|
if (deletedWidgets.contains(m_currentWidget))
|
||||||
|
m_currentWidget = 0;
|
||||||
|
|
||||||
m_tabWidget->removeTab(index);
|
m_tabWidget->removeTab(index);
|
||||||
disconnect(project, SIGNAL(removedTarget(ProjectExplorer::Target*)),
|
disconnect(project, SIGNAL(removedTarget(ProjectExplorer::Target*)),
|
||||||
this, SLOT(removedTarget(ProjectExplorer::Target*)));
|
this, SLOT(removedTarget(ProjectExplorer::Target*)));
|
||||||
@@ -195,7 +190,7 @@ bool ProjectWindow::deregisterProject(ProjectExplorer::Project *project)
|
|||||||
|
|
||||||
void ProjectWindow::startupProjectChanged(ProjectExplorer::Project *p)
|
void ProjectWindow::startupProjectChanged(ProjectExplorer::Project *p)
|
||||||
{
|
{
|
||||||
int index = m_tabIndexToProject.indexOf(p);
|
int index = m_cache.indexForProject(p);
|
||||||
if (index != -1)
|
if (index != -1)
|
||||||
m_tabWidget->setCurrentIndex(index);
|
m_tabWidget->setCurrentIndex(index);
|
||||||
}
|
}
|
||||||
@@ -205,36 +200,18 @@ void ProjectWindow::showProperties(int index, int subIndex)
|
|||||||
if (m_ignoreChange)
|
if (m_ignoreChange)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (index < 0 || index >= m_tabIndexToProject.count()) {
|
removeCurrentWidget();
|
||||||
removeCurrentWidget();
|
Project *project = m_cache.projectFor(index);
|
||||||
|
if (!project) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Project *project = m_tabIndexToProject.at(index);
|
QWidget *widget = m_cache.widgetFor(project, subIndex);
|
||||||
|
if (widget) {
|
||||||
// Set up custom panels again:
|
|
||||||
int pos = 0;
|
|
||||||
ProjectPanelFactory *fac = 0;
|
|
||||||
|
|
||||||
foreach (ProjectPanelFactory *panelFactory, ProjectPanelFactory::factories()) {
|
|
||||||
if (panelFactory->supports(project)) {
|
|
||||||
if (subIndex == pos) {
|
|
||||||
fac = panelFactory;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
++pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fac) {
|
|
||||||
removeCurrentWidget();
|
|
||||||
|
|
||||||
QWidget *widget = fac->createWidget(project);
|
|
||||||
Q_ASSERT(widget);
|
|
||||||
|
|
||||||
m_currentWidget = widget;
|
m_currentWidget = widget;
|
||||||
m_centralWidget->addWidget(m_currentWidget);
|
m_centralWidget->addWidget(m_currentWidget);
|
||||||
m_centralWidget->setCurrentWidget(m_currentWidget);
|
m_centralWidget->setCurrentWidget(m_currentWidget);
|
||||||
|
m_currentWidget->show();
|
||||||
if (hasFocus()) // we get assigned focus from setFocusToCurrentMode, pass that on
|
if (hasFocus()) // we get assigned focus from setFocusToCurrentMode, pass that on
|
||||||
m_currentWidget->setFocus();
|
m_currentWidget->setFocus();
|
||||||
}
|
}
|
||||||
@@ -246,9 +223,167 @@ void ProjectWindow::removeCurrentWidget()
|
|||||||
{
|
{
|
||||||
if (m_currentWidget) {
|
if (m_currentWidget) {
|
||||||
m_centralWidget->removeWidget(m_currentWidget);
|
m_centralWidget->removeWidget(m_currentWidget);
|
||||||
if (m_currentWidget) {
|
m_currentWidget->hide();
|
||||||
delete m_currentWidget;
|
m_currentWidget = 0;
|
||||||
m_currentWidget = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WidgetCache
|
||||||
|
void WidgetCache::registerProject(Project *project)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(!isRegistered(project), return);
|
||||||
|
|
||||||
|
QList<ProjectPanelFactory *> fac = ProjectPanelFactory::factories();
|
||||||
|
int factorySize = fac.size();
|
||||||
|
|
||||||
|
ProjectInfo info;
|
||||||
|
info.project = project;
|
||||||
|
info.widgets.resize(factorySize);
|
||||||
|
info.supports.resize(factorySize);
|
||||||
|
|
||||||
|
for (int i = 0; i < factorySize; ++i)
|
||||||
|
info.supports[i] = fac.at(i)->supports(project);
|
||||||
|
|
||||||
|
m_projects.append(info);
|
||||||
|
sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<QWidget *> WidgetCache::deregisterProject(Project *project)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(isRegistered(project), return QVector<QWidget *>());
|
||||||
|
|
||||||
|
int index = indexForProject(project);
|
||||||
|
ProjectInfo info = m_projects.at(index);
|
||||||
|
QVector<QWidget *> deletedWidgets = info.widgets;
|
||||||
|
qDeleteAll(info.widgets);
|
||||||
|
m_projects.removeAt(index);
|
||||||
|
return deletedWidgets;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList WidgetCache::tabNames(Project *project) const
|
||||||
|
{
|
||||||
|
int index = indexForProject(project);
|
||||||
|
if (index == -1)
|
||||||
|
return QStringList();
|
||||||
|
|
||||||
|
QList<ProjectPanelFactory *> fac = ProjectPanelFactory::factories();
|
||||||
|
|
||||||
|
ProjectInfo info = m_projects.at(index);
|
||||||
|
int end = info.supports.size();
|
||||||
|
QStringList names;
|
||||||
|
for (int i = 0; i < end; ++i)
|
||||||
|
if (info.supports.at(i))
|
||||||
|
names << fac.at(i)->displayName();
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WidgetCache::factoryIndex(int projectIndex, int supportsIndex) const
|
||||||
|
{
|
||||||
|
QList<ProjectPanelFactory *> fac = ProjectPanelFactory::factories();
|
||||||
|
int end = fac.size();
|
||||||
|
const ProjectInfo &info = m_projects.at(projectIndex);
|
||||||
|
for (int i = 0; i < end; ++i) {
|
||||||
|
if (info.supports.at(i)) {
|
||||||
|
if (supportsIndex == 0)
|
||||||
|
return i;
|
||||||
|
else
|
||||||
|
--supportsIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *WidgetCache::widgetFor(Project *project, int supportsIndex)
|
||||||
|
{
|
||||||
|
int projectIndex = indexForProject(project);
|
||||||
|
if (projectIndex == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
QList<ProjectPanelFactory *> fac = ProjectPanelFactory::factories();
|
||||||
|
|
||||||
|
int factoryIndex = factoryIndex(projectIndex, supportsIndex);
|
||||||
|
if (factoryIndex < 0 ||factoryIndex >= m_projects.at(projectIndex).widgets.size())
|
||||||
|
return 0;
|
||||||
|
if (!m_projects.at(projectIndex).widgets.at(factoryIndex))
|
||||||
|
m_projects[projectIndex].widgets[factoryIndex] = fac.at(factoryIndex)->createWidget(project);
|
||||||
|
return m_projects.at(projectIndex).widgets.at(factoryIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WidgetCache::isRegistered(Project *project) const
|
||||||
|
{
|
||||||
|
return Utils::anyOf(m_projects, [&project](ProjectInfo pinfo) {
|
||||||
|
return pinfo.project == project;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
int WidgetCache::indexForProject(Project *project) const
|
||||||
|
{
|
||||||
|
return Utils::indexOf(m_projects, [&project](ProjectInfo pinfo) {
|
||||||
|
return pinfo.project == project;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Project *WidgetCache::projectFor(int projectIndex) const
|
||||||
|
{
|
||||||
|
if (projectIndex < 0)
|
||||||
|
return 0;
|
||||||
|
if (projectIndex >= m_projects.size())
|
||||||
|
return 0;
|
||||||
|
return m_projects.at(projectIndex).project;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetCache::sort()
|
||||||
|
{
|
||||||
|
Utils::sort(m_projects, [](const ProjectInfo &a, const ProjectInfo &b) -> bool {
|
||||||
|
QString aName = a.project->displayName();
|
||||||
|
QString bName = b.project->displayName();
|
||||||
|
if (aName == bName) {
|
||||||
|
Utils::FileName aPath = a.project->projectFilePath();
|
||||||
|
Utils::FileName bPath = b.project->projectFilePath();
|
||||||
|
if (aPath == bPath)
|
||||||
|
return a.project < b.project;
|
||||||
|
else
|
||||||
|
return aPath < bPath;
|
||||||
|
} else {
|
||||||
|
return aName < bName;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
int WidgetCache::recheckFactories(Project *project, int oldSupportsIndex)
|
||||||
|
{
|
||||||
|
int projectIndex = indexForProject(project);
|
||||||
|
int factoryIndex = factoryIndex(projectIndex, oldSupportsIndex);
|
||||||
|
|
||||||
|
ProjectInfo &info = m_projects[projectIndex];
|
||||||
|
QList<ProjectPanelFactory *> fac = ProjectPanelFactory::factories();
|
||||||
|
int end = fac.size();
|
||||||
|
|
||||||
|
for (int i = 0; i < end; ++i) {
|
||||||
|
info.supports[i] = fac.at(i)->supports(project);
|
||||||
|
if (!info.supports.at(i)) {
|
||||||
|
delete info.widgets.at(i);
|
||||||
|
info.widgets[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (factoryIndex < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!info.supports.at(factoryIndex))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
int newIndex = 0;
|
||||||
|
for (int i = 0; i < factoryIndex; ++i) {
|
||||||
|
if (info.supports.at(i))
|
||||||
|
++newIndex;
|
||||||
|
}
|
||||||
|
return newIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetCache::clear()
|
||||||
|
{
|
||||||
|
while (!m_projects.isEmpty())
|
||||||
|
deregisterProject(m_projects.first().project);
|
||||||
|
}
|
||||||
|
|||||||
@@ -47,6 +47,37 @@ namespace Internal {
|
|||||||
|
|
||||||
class DoubleTabWidget;
|
class DoubleTabWidget;
|
||||||
|
|
||||||
|
class WidgetCache
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void registerProject(Project *project);
|
||||||
|
QVector<QWidget *> deregisterProject(Project *project);
|
||||||
|
|
||||||
|
bool isRegistered(Project *project) const;
|
||||||
|
int indexForProject(Project *project) const;
|
||||||
|
Project *projectFor(int projectIndex) const;
|
||||||
|
QStringList tabNames(Project *project) const;
|
||||||
|
|
||||||
|
QWidget *widgetFor(Project *project, int factoryIndex);
|
||||||
|
|
||||||
|
void sort();
|
||||||
|
int recheckFactories(Project *project, int oldSupportsIndex);
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int factoryIndex(int projectIndex, int supportsIndex) const;
|
||||||
|
|
||||||
|
class ProjectInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Project *project;
|
||||||
|
QVector<bool> supports;
|
||||||
|
QVector<QWidget *> widgets;
|
||||||
|
};
|
||||||
|
QList<ProjectInfo> m_projects; //ordered by displaynames of the projects
|
||||||
|
};
|
||||||
|
|
||||||
class ProjectWindow : public QWidget
|
class ProjectWindow : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -58,7 +89,7 @@ public:
|
|||||||
void aboutToShutdown();
|
void aboutToShutdown();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void projectUpdated(ProjectExplorer::Project *p);
|
void projectUpdated(ProjectExplorer::Project *project);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void projectDisplayNameChanged(ProjectExplorer::Project *p);
|
void projectDisplayNameChanged(ProjectExplorer::Project *p);
|
||||||
@@ -70,14 +101,12 @@ private slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void removeCurrentWidget();
|
void removeCurrentWidget();
|
||||||
static QStringList tabDisplayNamesFor(Project *project);
|
|
||||||
int insertPosFor(Project *project);
|
|
||||||
|
|
||||||
bool m_ignoreChange;
|
bool m_ignoreChange;
|
||||||
DoubleTabWidget *m_tabWidget;
|
DoubleTabWidget *m_tabWidget;
|
||||||
QStackedWidget *m_centralWidget;
|
QStackedWidget *m_centralWidget;
|
||||||
QWidget *m_currentWidget;
|
QWidget *m_currentWidget;
|
||||||
QList<ProjectExplorer::Project *> m_tabIndexToProject;
|
WidgetCache m_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
Reference in New Issue
Block a user