1/*
2 * Copyright 2007-2010, Axel D��rfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include "ProgressWindow.h"
8
9#include <stdio.h>
10#include <string.h>
11
12#include <Autolock.h>
13#include <Catalog.h>
14#include <Locale.h>
15#include <MessageRunner.h>
16#include <Screen.h>
17#include <StatusBar.h>
18
19#include "ShowImageConstants.h"
20
21
22static const uint32 kMsgShow = 'show';
23
24#undef B_TRANSLATION_CONTEXT
25#define B_TRANSLATION_CONTEXT "ProgressWindow"
26
27
28ProgressWindow::ProgressWindow()
29	:
30	BWindow(BRect(0, 0, 250, 100), B_TRANSLATE("Progress monitor"),
31		B_MODAL_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,// B_FLOATING_APP_WINDOW_FEEL,
32		// TODO: a bug in the app_server prevents an initial floating-app feel
33		// to work correctly; the window will then not be visible for the first
34		// image, even though it's later set to normal feel in that case.
35		B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS),
36	fRunner(NULL)
37{
38	BRect rect = Bounds();
39
40	BView* view = new BView(rect, NULL, B_FOLLOW_ALL, B_WILL_DRAW);
41	view->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
42	AddChild(view);
43
44	rect = view->Bounds().InsetByCopy(5, 5);
45	fStatusBar = new BStatusBar(rect, "status", NULL, NULL);
46	float width, height;
47	fStatusBar->GetPreferredSize(&width, &height);
48	fStatusBar->ResizeTo(rect.Width(), height);
49	fStatusBar->SetResizingMode(B_FOLLOW_TOP | B_FOLLOW_LEFT_RIGHT);
50	view->AddChild(fStatusBar);
51
52	ResizeTo(Bounds().Width(), height + 9);
53
54	Run();
55}
56
57
58ProgressWindow::~ProgressWindow()
59{
60	delete fRunner;
61}
62
63
64void
65ProgressWindow::Start(BWindow* referenceWindow, bool center)
66{
67	BAutolock _(this);
68
69	BScreen screen(referenceWindow);
70	if (!center) {
71		BMessage settings;
72		GetDecoratorSettings(&settings);
73
74		int32 borderWidth;
75		if (settings.FindInt32("border width", &borderWidth) != B_OK)
76			borderWidth = 5;
77
78		MoveTo(screen.Frame().left + borderWidth,
79			screen.Frame().bottom - Bounds().Height() - borderWidth);
80	} else
81		CenterIn(screen.Frame());
82
83	SetFeel(referenceWindow->IsHidden()
84		? B_NORMAL_WINDOW_FEEL : B_FLOATING_APP_WINDOW_FEEL);
85
86	fRetrievedUpdate = false;
87	fRetrievedShow = false;
88	delete fRunner;
89
90	BMessage show(kMsgShow);
91	fRunner = new BMessageRunner(this, &show, 1000000, 1);
92}
93
94
95void
96ProgressWindow::Stop()
97{
98	BAutolock _(this);
99
100	delete fRunner;
101	fRunner = NULL;
102
103	if (!IsHidden())
104		Hide();
105}
106
107
108void
109ProgressWindow::MessageReceived(BMessage* message)
110{
111	switch (message->what) {
112		case kMsgShow:
113			if (fRetrievedUpdate && IsHidden()) {
114				Show();
115				Minimize(false);
116			}
117
118			fRetrievedShow = true;
119			break;
120
121		case kMsgProgressUpdate:
122			float percent;
123			if (message->FindFloat("percent", &percent) == B_OK)
124				fStatusBar->Update(percent - fStatusBar->CurrentValue());
125
126			const char* text;
127			if (message->FindString("message", &text) == B_OK)
128				fStatusBar->SetText(text);
129
130			fRetrievedUpdate = true;
131
132			if (fRetrievedShow && IsHidden()) {
133				Show();
134				Minimize(false);
135			}
136			break;
137
138		default:
139			BWindow::MessageReceived(message);
140	}
141}
142
143