1/*
2 * Copyright (c) 2007-2010, Haiku, Inc.
3 * Distributed under the terms of the MIT license.
4 *
5 * Author:
6 *		Łukasz 'Sil2100' Zemczak <sil2100@vexillium.org>
7 */
8
9
10#include "PackageTextViewer.h"
11
12#include <Button.h>
13#include <Catalog.h>
14#include <Locale.h>
15#include <ScrollView.h>
16
17#include <GroupLayout.h>
18#include <GroupLayoutBuilder.h>
19
20
21enum {
22	P_MSG_ACCEPT = 'pmac',
23	P_MSG_DECLINE
24};
25
26#undef B_TRANSLATION_CONTEXT
27#define B_TRANSLATION_CONTEXT "PackageTextViewer"
28
29
30PackageTextViewer::PackageTextViewer(const char *text, bool disclaimer)
31	:
32	BWindow(BRect(125, 125, 675, 475), B_TRANSLATE("Disclaimer"),
33		B_MODAL_WINDOW, B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_NOT_CLOSABLE),
34	fValue(0)
35{
36	_InitView(text, disclaimer);
37}
38
39
40PackageTextViewer::~PackageTextViewer()
41{
42}
43
44
45int32
46PackageTextViewer::Go()
47{
48	// Since this class can be thought of as a modified BAlert window, no use
49	// to reinvent a well fledged wheel. This concept has been borrowed from
50	// the current BAlert implementation
51	fSemaphore = create_sem(0, "TextViewer");
52	if (fSemaphore < B_OK) {
53		Quit();
54		return B_ERROR;
55	}
56
57	BWindow *parent =
58		dynamic_cast<BWindow *>(BLooper::LooperForThread(find_thread(NULL)));
59	Show();
60
61	if (parent) {
62		status_t ret;
63		for (;;) {
64			do {
65				ret = acquire_sem_etc(fSemaphore, 1, B_RELATIVE_TIMEOUT, 50000);
66			} while (ret == B_INTERRUPTED);
67
68			if (ret == B_BAD_SEM_ID)
69				break;
70			parent->UpdateIfNeeded();
71		}
72	}
73	else {
74		// Since there are no spinlocks, wait until the semaphore is free
75		while (acquire_sem(fSemaphore) == B_INTERRUPTED) {
76		}
77	}
78
79	int32 value = fValue;
80	if (Lock())
81		Quit();
82
83	return value;
84}
85
86
87void
88PackageTextViewer::MessageReceived(BMessage *msg)
89{
90	if (msg->what == P_MSG_ACCEPT) {
91		if (fSemaphore >= B_OK) {
92			fValue = 1;
93			delete_sem(fSemaphore);
94			fSemaphore = -1;
95		}
96	} else if (msg->what == P_MSG_DECLINE) {
97		if (fSemaphore >= B_OK) {
98			fValue = 0;
99			delete_sem(fSemaphore);
100			fSemaphore = -1;
101		}
102	} else
103		BWindow::MessageReceived(msg);
104}
105
106
107// #pragma mark -
108
109
110void
111PackageTextViewer::_InitView(const char *text, bool disclaimer)
112{
113	fBackground = new BView(Bounds(), "background_view", 0, 0);
114	fBackground->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
115
116	BRect bounds;
117	BRect rect = Bounds();
118	if (disclaimer) {
119		BButton *button = new BButton(BRect(0, 0, 1, 1), "accept",
120			B_TRANSLATE("Accept"), new BMessage(P_MSG_ACCEPT));
121		button->ResizeToPreferred();
122
123		bounds = button->Bounds();
124		rect.top = rect.bottom - bounds.bottom - 5.0f;
125		rect.left = rect.right - bounds.right - 5.0f;
126		rect.bottom = bounds.bottom;
127		rect.right = bounds.right;
128		button->MoveTo(rect.LeftTop());
129		button->MakeDefault(true);
130		fBackground->AddChild(button);
131
132		button = new BButton(BRect(0, 0, 1, 1), "decline",
133			B_TRANSLATE("Decline"),	new BMessage(P_MSG_DECLINE));
134		button->ResizeToPreferred();
135
136		bounds = button->Bounds();
137		rect.left -= bounds.right + 7.0f;
138		button->MoveTo(rect.LeftTop());
139		fBackground->AddChild(button);
140	} else {
141		BButton *button = new BButton(BRect(0, 0, 1, 1), "accept",
142			B_TRANSLATE("Continue"), new BMessage(P_MSG_ACCEPT));
143		button->ResizeToPreferred();
144
145		bounds = button->Bounds();
146		rect.top = rect.bottom - bounds.bottom - 5.0f;
147		rect.left = rect.right - bounds.right - 5.0f;
148		rect.bottom = bounds.bottom;
149		rect.right = bounds.right;
150		button->MoveTo(rect.LeftTop());
151		button->MakeDefault(true);
152		fBackground->AddChild(button);
153	}
154
155	bounds = Bounds().InsetBySelf(5.0f, 5.0f);
156	bounds.bottom = rect.top - 6.0f;
157	bounds.right -= B_V_SCROLL_BAR_WIDTH;
158
159	fText = new BTextView(bounds, "text_view", BRect(0, 0, bounds.Width(),
160		bounds.Height()), B_FOLLOW_NONE, B_WILL_DRAW);
161	fText->MakeEditable(false);
162	fText->MakeSelectable(true);
163	fText->SetText(text);
164
165	BScrollView *scroll = new BScrollView("scroll_view", fText,
166		B_FOLLOW_LEFT | B_FOLLOW_TOP, 0, false, true);
167
168	fBackground->AddChild(scroll);
169
170	AddChild(fBackground);
171}
172
173
174/*void
175PackageTextViewer::_InitView(const char *text, bool disclaimer)
176{
177	SetLayout(new BGroupLayout(B_HORIZONTAL));
178
179	fText = new BTextView(BRect(0, 0, 1, 1), "text_view", BRect(0, 0, 1, 1),
180			B_FOLLOW_NONE, B_WILL_DRAW | B_SUPPORTS_LAYOUT);
181	fText->MakeEditable(false);
182	fText->MakeSelectable(true);
183	BScrollView *scroll = new BScrollView("scroll_view", fText,
184			B_FOLLOW_LEFT | B_FOLLOW_TOP, 0, false, true);
185
186	if (disclaimer) {
187		BButton *accept = new BButton("accept", B_TRANSLATE("Accept"),
188				new BMessage(P_MSG_ACCEPT));
189
190		BButton *decline = new BButton("decline", B_TRANSLATE("Decline"),
191				new BMessage(P_MSG_DECLINE));
192
193		fBackground = BGroupLayoutBuilder(B_VERTICAL)
194			.Add(scroll)
195			.AddGroup(B_HORIZONTAL, 5.0f)
196				.AddGlue()
197				.Add(accept)
198				.Add(decline)
199			.End();
200	}
201	else {
202		BButton *button = new BButton("accept", B_TRANSLATE("Continue"),
203				new BMessage(P_MSG_ACCEPT));
204
205		fBackground = BGroupLayoutBuilder(B_VERTICAL)
206			.Add(scroll)
207			.AddGroup(B_HORIZONTAL, 5.0f)
208				.AddGlue()
209				.Add(button)
210			.End();
211	}
212
213	AddChild(fBackground);
214
215	fBackground->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
216	fText->SetText(text);
217}*/
218
219