1/*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include "MainWindow.h"
8
9#include <stdio.h>
10
11#include <new>
12
13#include <Application.h>
14#include <GroupLayoutBuilder.h>
15#include <TabView.h>
16
17#include <AutoDeleter.h>
18#include <AutoLocker.h>
19
20#include "DataSource.h"
21#include "MessageCodes.h"
22#include "ModelLoader.h"
23#include "SubWindowManager.h"
24
25#include "main_window/GeneralPage.h"
26#include "main_window/SchedulingPage.h"
27#include "main_window/TeamsPage.h"
28#include "main_window/ThreadsPage.h"
29#include "main_window/WaitObjectsPage.h"
30
31#include "thread_window/ThreadWindow.h"
32
33
34MainWindow::MainWindow(DataSource* dataSource)
35	:
36	BWindow(BRect(50, 50, 599, 499), "DebugAnalyzer", B_DOCUMENT_WINDOW,
37		B_ASYNCHRONOUS_CONTROLS),
38	fMainTabView(NULL),
39	fGeneralPage(NULL),
40	fTeamsPage(NULL),
41	fThreadsPage(NULL),
42	fSchedulingPage(NULL),
43	fWaitObjectsPage(NULL),
44	fModel(NULL),
45	fModelLoader(NULL),
46	fSubWindowManager(NULL)
47{
48	fSubWindowManager = new SubWindowManager(this);
49
50	BGroupLayout* rootLayout = new BGroupLayout(B_VERTICAL);
51	SetLayout(rootLayout);
52
53	fMainTabView = new BTabView("main tab view");
54
55	BGroupLayoutBuilder(rootLayout)
56		.Add(fMainTabView);
57
58	fMainTabView->AddTab(fGeneralPage = new GeneralPage);
59	fMainTabView->AddTab(fTeamsPage = new TeamsPage(this));
60	fMainTabView->AddTab(fThreadsPage = new ThreadsPage(this));
61	fMainTabView->AddTab(fSchedulingPage = new SchedulingPage(this));
62	fMainTabView->AddTab(fWaitObjectsPage = new WaitObjectsPage(this));
63
64	// create a model loader, if we have a data source
65	if (dataSource != NULL)
66		fModelLoader = new ModelLoader(dataSource, BMessenger(this), NULL);
67}
68
69
70MainWindow::~MainWindow()
71{
72	if (fModelLoader != NULL)
73		fModelLoader->Delete();
74
75	if (fModel != NULL)
76		fModel->ReleaseReference();
77
78	fSubWindowManager->ReleaseReference();
79}
80
81
82void
83MainWindow::MessageReceived(BMessage* message)
84{
85	switch (message->what) {
86		case MSG_MODEL_LOADED_SUCCESSFULLY:
87		{
88printf("MSG_MODEL_LOADED_SUCCESSFULLY\n");
89			Model* model = fModelLoader->DetachModel();
90			fModelLoader->Delete();
91			fModelLoader = NULL;
92			_SetModel(model);
93			model->ReleaseReference();
94			break;
95		}
96
97		case MSG_MODEL_LOADED_FAILED:
98		case MSG_MODEL_LOADED_ABORTED:
99		{
100printf("MSG_MODEL_LOADED_FAILED/MSG_MODEL_LOADED_ABORTED\n");
101			fModelLoader->Delete();
102			fModelLoader = NULL;
103			// TODO: User feedback (in failed case)!
104			break;
105		}
106
107		default:
108			BWindow::MessageReceived(message);
109			break;
110	}
111}
112
113
114void
115MainWindow::Quit()
116{
117	if (fModelLoader != NULL)
118		fModelLoader->Abort(true);
119
120	fSubWindowManager->Broadcast(B_QUIT_REQUESTED);
121	be_app->PostMessage(MSG_WINDOW_QUIT);
122
123	BWindow::Quit();
124}
125
126
127void
128MainWindow::Show()
129{
130	BWindow::Show();
131
132	AutoLocker<MainWindow> locker;
133
134	if (fModelLoader == NULL)
135		return;
136
137	status_t error = fModelLoader->StartLoading();
138	if (error != B_OK) {
139		fModelLoader->Delete();
140		fModelLoader = NULL;
141		// TODO: User feedback!
142	}
143}
144
145
146void
147MainWindow::OpenTeamWindow(Model::Team* team)
148{
149	// TODO:...
150}
151
152
153void
154MainWindow::OpenThreadWindow(Model::Thread* thread)
155{
156	// create a sub window key
157	ObjectSubWindowKey* key = new(std::nothrow) ObjectSubWindowKey(thread);
158	if (key == NULL) {
159		// TODO: Report error!
160		return;
161	}
162	ObjectDeleter<ObjectSubWindowKey> keyDeleter(key);
163
164	AutoLocker<SubWindowManager> locker(fSubWindowManager);
165
166	// check whether the window already exists
167	ThreadWindow* window = dynamic_cast<ThreadWindow*>(
168		fSubWindowManager->LookupSubWindow(*key));
169	if (window != NULL) {
170		// window exists -- just bring it to front
171		locker.Unlock();
172		window->Lock();
173		window->Activate();
174		return;
175	}
176
177	// window doesn't exist yet -- create it
178	try {
179		window = new ThreadWindow(fSubWindowManager, fModel, thread);
180	} catch (std::bad_alloc&) {
181		// TODO: Report error!
182	}
183
184	if (!window->AddToSubWindowManager(key)) {
185		// TODO: Report error!
186		delete window;
187	}
188
189	keyDeleter.Detach();
190
191	window->Show();
192}
193
194
195void
196MainWindow::_SetModel(Model* model)
197{
198	if (fModel != NULL)
199		fModel->ReleaseReference();
200
201	fModel = model;
202
203	if (fModel != NULL)
204		fModel->AcquireReference();
205
206	fGeneralPage->SetModel(fModel);
207	fTeamsPage->SetModel(fModel);
208	fThreadsPage->SetModel(fModel);
209	fSchedulingPage->SetModel(fModel);
210	fWaitObjectsPage->SetModel(fModel);
211}
212