libroot/posix/stdio: Remove unused portions.
[haiku.git] / src / preferences / notifications / NotificationsView.cpp
bloba0183e5c5ce0c8af74da21f20ce152cbdd97cf75
1 /*
2 * Copyright 2010-2017, Haiku, Inc. All Rights Reserved.
3 * Copyright 2009, Pier Luigi Fiorini.
4 * Distributed under the terms of the MIT License.
6 * Authors:
7 * Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
8 * Brian Hill, supernova@tycho.email
9 */
11 #include <Alert.h>
12 #include <Button.h>
13 #include <Catalog.h>
14 #include <CheckBox.h>
15 #include <ColumnListView.h>
16 #include <ColumnTypes.h>
17 #include <Directory.h>
18 #include <FindDirectory.h>
19 #include <LayoutBuilder.h>
20 #include <Notification.h>
21 #include <Path.h>
22 #include <TextControl.h>
23 #include <Window.h>
25 #include <notification/Notifications.h>
26 #include <notification/NotificationReceived.h>
28 #include "NotificationsConstants.h"
29 #include "NotificationsView.h"
31 #undef B_TRANSLATION_CONTEXT
32 #define B_TRANSLATION_CONTEXT "NotificationView"
34 // Applications column indexes
35 const int32 kAppNameIndex = 0;
36 const int32 kAppEnabledIndex = 1;
39 AppRow::AppRow(const char* name, const char* signature, bool allowed)
41 BRow(),
42 fName(name),
43 fSignature(signature),
44 fAllowed(allowed)
46 SetField(new BStringField(fName.String()), kAppNameIndex);
47 BString text = fAllowed ? B_TRANSLATE("Allowed") : B_TRANSLATE("Muted");
48 SetField(new BStringField(text.String()), kAppEnabledIndex);
52 void
53 AppRow::SetAllowed(bool allowed)
55 fAllowed = allowed;
56 RefreshEnabledField();
60 void
61 AppRow::RefreshEnabledField()
63 BStringField* field = (BStringField*)GetField(kAppEnabledIndex);
64 BString text = fAllowed ? B_TRANSLATE("Allowed") : B_TRANSLATE("Muted");
65 field->SetString(text.String());
66 Invalidate();
70 NotificationsView::NotificationsView(SettingsHost* host)
72 SettingsPane("apps", host),
73 fSelectedRow(NULL)
75 // Applications list
76 fApplications = new BColumnListView(B_TRANSLATE("Applications"),
77 0, B_FANCY_BORDER, false);
78 fApplications->SetSelectionMode(B_SINGLE_SELECTION_LIST);
79 fApplications->SetSelectionMessage(new BMessage(kApplicationSelected));
81 float colWidth = be_plain_font->StringWidth(B_TRANSLATE("Application"))
82 + (kCLVTitlePadding * 2);
83 fAppCol = new BStringColumn(B_TRANSLATE("Application"), colWidth * 2,
84 colWidth, colWidth * 4, B_TRUNCATE_END, B_ALIGN_LEFT);
85 fApplications->AddColumn(fAppCol, kAppNameIndex);
87 colWidth = be_plain_font->StringWidth(B_TRANSLATE("Status"))
88 + (kCLVTitlePadding * 2);
89 fAppEnabledCol = new BStringColumn(B_TRANSLATE("Status"), colWidth * 1.5,
90 colWidth, colWidth * 3, B_TRUNCATE_END, B_ALIGN_LEFT);
91 fApplications->AddColumn(fAppEnabledCol, kAppEnabledIndex);
92 fApplications->SetSortColumn(fAppCol, true, true);
94 fAddButton = new BButton("add_app", B_TRANSLATE("Add" B_UTF8_ELLIPSIS),
95 new BMessage(kAddApplication));
96 fRemoveButton = new BButton("add_app", B_TRANSLATE("Remove"),
97 new BMessage(kRemoveApplication));
98 fRemoveButton->SetEnabled(false);
100 fMuteAll = new BCheckBox("block", B_TRANSLATE("Mute notifications from "
101 "this application"),
102 new BMessage(kMuteChanged));
104 // Add views
105 BLayoutBuilder::Group<>(this, B_VERTICAL)
106 .AddGroup(B_HORIZONTAL)
107 .Add(fApplications)
108 .AddGroup(B_VERTICAL)
109 .Add(fAddButton)
110 .Add(fRemoveButton)
111 .AddGlue()
112 .End()
113 .End()
114 .Add(fMuteAll)
115 .SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING,
116 B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING);
118 // Set button sizes
119 float maxButtonWidth = std::max(fAddButton->PreferredSize().Width(),
120 fRemoveButton->PreferredSize().Width());
121 fAddButton->SetExplicitMaxSize(BSize(maxButtonWidth, B_SIZE_UNSET));
122 fRemoveButton->SetExplicitMaxSize(BSize(maxButtonWidth, B_SIZE_UNSET));
124 // File Panel
125 fPanelFilter = new AppRefFilter();
126 fAddAppPanel = new BFilePanel(B_OPEN_PANEL, NULL, NULL, B_FILE_NODE, false,
127 NULL, fPanelFilter);
131 NotificationsView::~NotificationsView()
133 delete fAddAppPanel;
134 delete fPanelFilter;
138 void
139 NotificationsView::AttachedToWindow()
141 fApplications->SetTarget(this);
142 fApplications->SetInvocationMessage(new BMessage(kApplicationSelected));
143 fAddButton->SetTarget(this);
144 fRemoveButton->SetTarget(this);
145 fMuteAll->SetTarget(this);
146 fAddAppPanel->SetTarget(this);
147 _RecallItemSettings();
151 void
152 NotificationsView::MessageReceived(BMessage* msg)
154 switch (msg->what) {
155 case kApplicationSelected:
157 Window()->Lock();
158 _ClearItemSettings();
159 _UpdateSelectedItem();
160 _RecallItemSettings();
161 Window()->Unlock();
162 break;
164 case kMuteChanged:
166 bool allowed = fMuteAll->Value() == B_CONTROL_OFF;
167 fSelectedRow->SetAllowed(allowed);
168 appusage_t::iterator it = fAppFilters.find(fSelectedRow->Signature());
169 if (it != fAppFilters.end())
170 it->second->SetAllowed(allowed);
171 Window()->PostMessage(kApply);
172 break;
174 case kAddApplication:
176 BMessage addmsg(kAddApplicationRef);
177 fAddAppPanel->SetMessage(&addmsg);
178 fAddAppPanel->Show();
179 break;
181 case kAddApplicationRef:
183 entry_ref srcRef;
184 msg->FindRef("refs", &srcRef);
185 BEntry srcEntry(&srcRef, true);
186 BPath path(&srcEntry);
187 BNode node(&srcEntry);
188 char *buf = new char[B_ATTR_NAME_LENGTH];
189 ssize_t size;
190 if ( (size = node.ReadAttr("BEOS:APP_SIG", 0, 0, buf,
191 B_ATTR_NAME_LENGTH)) > 0 )
193 // Search for already existing app
194 appusage_t::iterator it = fAppFilters.find(buf);
195 if (it != fAppFilters.end()) {
196 BString text(path.Leaf());
197 text.Append(B_TRANSLATE_COMMENT(" is already listed",
198 "Alert message"));
199 BAlert* alert = new BAlert("", text.String(),
200 B_TRANSLATE("OK"), NULL, NULL, B_WIDTH_AS_USUAL,
201 B_WARNING_ALERT);
202 alert->Go(NULL);
203 } else {
204 AppUsage* appUsage = new AppUsage(path.Leaf(), buf, true);
205 fAppFilters[appUsage->Signature()] = appUsage;
206 AppRow* row = new AppRow(appUsage->AppName(),
207 appUsage->Signature(), appUsage->Allowed());
208 fApplications->AddRow(row);
209 fApplications->DeselectAll();
210 fApplications->AddToSelection(row);
211 fApplications->ScrollTo(row);
212 _UpdateSelectedItem();
213 _RecallItemSettings();
214 //row->Invalidate();
215 //fApplications->InvalidateRow(row);
216 // TODO redraw row properly
217 Window()->PostMessage(kApply);
219 } else {
220 BAlert* alert = new BAlert("",
221 B_TRANSLATE_COMMENT("Application does not have "
222 "a valid signature", "Alert message"),
223 B_TRANSLATE("OK"), NULL, NULL, B_WIDTH_AS_USUAL,
224 B_WARNING_ALERT);
225 alert->Go(NULL);
227 delete[] buf;
228 break;
230 case kRemoveApplication:
232 if (fSelectedRow) {
233 appusage_t::iterator it = fAppFilters.find(fSelectedRow->Signature());
234 if (it != fAppFilters.end()) {
235 delete it->second;
236 fAppFilters.erase(it);
238 fApplications->RemoveRow(fSelectedRow);
239 delete fSelectedRow;
240 fSelectedRow = NULL;
241 _ClearItemSettings();
242 _UpdateSelectedItem();
243 _RecallItemSettings();
244 Window()->PostMessage(kApply);
246 break;
248 default:
249 BView::MessageReceived(msg);
250 break;
255 status_t
256 NotificationsView::Load(BMessage& settings)
258 type_code type;
259 int32 count = 0;
261 if (settings.GetInfo("app_usage", &type, &count) != B_OK)
262 return B_ERROR;
264 // Clean filters
265 appusage_t::iterator auIt;
266 for (auIt = fAppFilters.begin(); auIt != fAppFilters.end(); auIt++)
267 delete auIt->second;
268 fAppFilters.clear();
270 // Add new filters
271 for (int32 i = 0; i < count; i++) {
272 AppUsage* app = new AppUsage();
273 settings.FindFlat("app_usage", i, app);
274 fAppFilters[app->Signature()] = app;
277 // Load the applications list
278 _PopulateApplications();
280 return B_OK;
284 status_t
285 NotificationsView::Save(BMessage& storage)
287 appusage_t::iterator fIt;
288 for (fIt = fAppFilters.begin(); fIt != fAppFilters.end(); fIt++)
289 storage.AddFlat("app_usage", fIt->second);
291 return B_OK;
295 void
296 NotificationsView::_ClearItemSettings()
298 fMuteAll->SetValue(B_CONTROL_OFF);
302 void
303 NotificationsView::_UpdateSelectedItem()
305 fSelectedRow = dynamic_cast<AppRow*>(fApplications->CurrentSelection());
310 void
311 NotificationsView::_RecallItemSettings()
313 // No selected item
314 if(fSelectedRow == NULL)
316 fMuteAll->SetValue(B_CONTROL_OFF);
317 fMuteAll->SetEnabled(false);
318 fRemoveButton->SetEnabled(false);
319 } else {
320 fMuteAll->SetEnabled(true);
321 fRemoveButton->SetEnabled(true);
322 appusage_t::iterator it = fAppFilters.find(fSelectedRow->Signature());
323 if (it != fAppFilters.end())
324 fMuteAll->SetValue(!(it->second->Allowed()));
329 status_t
330 NotificationsView::Revert()
332 return B_OK;
336 bool
337 NotificationsView::RevertPossible()
339 return false;
343 status_t
344 NotificationsView::Defaults()
346 return B_OK;
350 bool
351 NotificationsView::DefaultsPossible()
353 return false;
357 bool
358 NotificationsView::UseDefaultRevertButtons()
360 return false;
364 void
365 NotificationsView::_PopulateApplications()
367 fApplications->Clear();
369 appusage_t::iterator it;
370 for (it = fAppFilters.begin(); it != fAppFilters.end(); ++it) {
371 AppUsage* appUsage = it->second;
372 AppRow* row = new AppRow(appUsage->AppName(),
373 appUsage->Signature(), appUsage->Allowed());
374 fApplications->AddRow(row);