Skip to content

Commit

Permalink
Fix issue 298: Crash on quit with multiple viewports open
Browse files Browse the repository at this point in the history
  • Loading branch information
dacap committed Jan 26, 2014
1 parent 11f864d commit c2e50ac
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 23 deletions.
76 changes: 53 additions & 23 deletions src/app/ui/workspace.cpp
Expand Up @@ -71,10 +71,17 @@ void Workspace::removeView(WorkspaceView* view)
ASSERT(it != m_views.end());
m_views.erase(it);

m_activePart->removeView(view);
if (m_activePart->getViewCount() == 0 &&
m_activePart->getParent() != this) {
m_activePart = destroyPart(m_activePart);
WorkspacePart* part = getPartByView(view);
ASSERT(part != NULL);

part->removeView(view);
if (part->getViewCount() == 0 &&
part->getParent() != this) {
bool activePartRemoved = (m_activePart == part);
WorkspacePart* otherPart = destroyPart(part);

if (activePartRemoved)
m_activePart = otherPart;
}

App::instance()->getMainWindow()->getTabsBar()->removeTab(dynamic_cast<TabView*>(view));
Expand Down Expand Up @@ -173,29 +180,18 @@ WorkspacePart* Workspace::destroyPart(WorkspacePart* part)

void Workspace::makeUnique(WorkspaceView* view)
{
std::vector<WorkspacePart*> parts;
std::queue<Widget*> remaining;
remaining.push(getFirstChild());
while (!remaining.empty()) {
Widget* widget = remaining.front();
remaining.pop();
WorkspaceParts parts;
enumAllParts(parts);

WorkspacePart* part = dynamic_cast<WorkspacePart*>(widget);
if (part && part->getParent() != this) {
while (part->getActiveView()) {
for (WorkspaceParts::iterator it=parts.begin(), end=parts.end(); it != end; ++it) {
WorkspacePart* part = *it;
if (part->getParent() != this) {
while (part->getActiveView())
part->removeView(part->getActiveView());
}
parts.push_back(part);
}
else {
UI_FOREACH_WIDGET(widget->getChildren(), it) {
remaining.push(*it);
}
}
}

for (std::vector<WorkspacePart*>::iterator
it = parts.begin(), end = parts.end(); it != end; ++it) {
for (WorkspaceParts::iterator it=parts.begin(), end=parts.end(); it != end; ++it) {
WorkspacePart* part = *it;
if (part->getParent() != this)
destroyPart(part);
Expand All @@ -205,7 +201,7 @@ void Workspace::makeUnique(WorkspaceView* view)
ASSERT(uniquePart != NULL);
m_activePart = uniquePart;

for (WorkspaceViews::iterator it = m_views.begin(), end = m_views.end(); it != end; ++it) {
for (WorkspaceViews::iterator it=m_views.begin(), end=m_views.end(); it != end; ++it) {
WorkspaceView* v = *it;
if (!v->getContentWidget()->getParent())
uniquePart->addView(v);
Expand All @@ -214,4 +210,38 @@ void Workspace::makeUnique(WorkspaceView* view)
setActiveView(view);
}

WorkspacePart* Workspace::getPartByView(WorkspaceView* view)
{
WorkspaceParts parts;
enumAllParts(parts);

for (WorkspaceParts::iterator it=parts.begin(), end=parts.end(); it != end; ++it) {
WorkspacePart* part = *it;
if (part->hasView(view))
return part;
}

return NULL;
}

void Workspace::enumAllParts(WorkspaceParts& parts)
{
std::queue<Widget*> remaining;
remaining.push(getFirstChild());
while (!remaining.empty()) {
Widget* widget = remaining.front();
remaining.pop();

WorkspacePart* part = dynamic_cast<WorkspacePart*>(widget);
if (part) {
parts.push_back(part);
}
else {
UI_FOREACH_WIDGET(widget->getChildren(), it) {
remaining.push(*it);
}
}
}
}

} // namespace app
4 changes: 4 additions & 0 deletions src/app/ui/workspace.h
Expand Up @@ -49,7 +49,11 @@ namespace app {
Signal0<void> ActiveViewChanged;

private:
typedef std::vector<WorkspacePart*> WorkspaceParts;

WorkspacePart* destroyPart(WorkspacePart* part);
WorkspacePart* getPartByView(WorkspaceView* view);
void enumAllParts(WorkspaceParts& parts);

// All views of all parts.
WorkspaceViews m_views;
Expand Down
5 changes: 5 additions & 0 deletions src/app/ui/workspace_part.cpp
Expand Up @@ -87,4 +87,9 @@ void WorkspacePart::setActiveView(WorkspaceView* view)
layout();
}

bool WorkspacePart::hasView(WorkspaceView* view)
{
return (std::find(m_views.begin(), m_views.end(), view) != m_views.end());
}

} // namespace app
2 changes: 2 additions & 0 deletions src/app/ui/workspace_part.h
Expand Up @@ -38,6 +38,8 @@ namespace app {
WorkspaceView* getActiveView() { return m_activeView; }
void setActiveView(WorkspaceView* view);

bool hasView(WorkspaceView* view);

private:
WorkspaceView* m_activeView;
WorkspaceViews m_views;
Expand Down

0 comments on commit c2e50ac

Please sign in to comment.