2 * Copyright 2010-2017, Haiku, Inc. All Rights Reserved.
3 * Copyright 2009, Pier Luigi Fiorini.
4 * Distributed under the terms of the MIT License.
7 * Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
8 * Brian Hill, supernova@tycho.email
15 #include <ColumnListView.h>
16 #include <ColumnTypes.h>
17 #include <Directory.h>
18 #include <FindDirectory.h>
19 #include <LayoutBuilder.h>
20 #include <Notification.h>
22 #include <TextControl.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
)
43 fSignature(signature
),
46 SetField(new BStringField(fName
.String()), kAppNameIndex
);
47 BString text
= fAllowed
? B_TRANSLATE("Allowed") : B_TRANSLATE("Muted");
48 SetField(new BStringField(text
.String()), kAppEnabledIndex
);
53 AppRow::SetAllowed(bool allowed
)
56 RefreshEnabledField();
61 AppRow::RefreshEnabledField()
63 BStringField
* field
= (BStringField
*)GetField(kAppEnabledIndex
);
64 BString text
= fAllowed
? B_TRANSLATE("Allowed") : B_TRANSLATE("Muted");
65 field
->SetString(text
.String());
70 NotificationsView::NotificationsView(SettingsHost
* host
)
72 SettingsPane("apps", host
),
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 "
102 new BMessage(kMuteChanged
));
105 BLayoutBuilder::Group
<>(this, B_VERTICAL
)
106 .AddGroup(B_HORIZONTAL
)
108 .AddGroup(B_VERTICAL
)
115 .SetInsets(B_USE_WINDOW_SPACING
, B_USE_WINDOW_SPACING
,
116 B_USE_WINDOW_SPACING
, B_USE_DEFAULT_SPACING
);
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
));
125 fPanelFilter
= new AppRefFilter();
126 fAddAppPanel
= new BFilePanel(B_OPEN_PANEL
, NULL
, NULL
, B_FILE_NODE
, false,
131 NotificationsView::~NotificationsView()
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();
152 NotificationsView::MessageReceived(BMessage
* msg
)
155 case kApplicationSelected
:
158 _ClearItemSettings();
159 _UpdateSelectedItem();
160 _RecallItemSettings();
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
);
174 case kAddApplication
:
176 BMessage
addmsg(kAddApplicationRef
);
177 fAddAppPanel
->SetMessage(&addmsg
);
178 fAddAppPanel
->Show();
181 case kAddApplicationRef
:
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
];
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",
199 BAlert
* alert
= new BAlert("", text
.String(),
200 B_TRANSLATE("OK"), NULL
, NULL
, B_WIDTH_AS_USUAL
,
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();
215 //fApplications->InvalidateRow(row);
216 // TODO redraw row properly
217 Window()->PostMessage(kApply
);
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
,
230 case kRemoveApplication
:
233 appusage_t::iterator it
= fAppFilters
.find(fSelectedRow
->Signature());
234 if (it
!= fAppFilters
.end()) {
236 fAppFilters
.erase(it
);
238 fApplications
->RemoveRow(fSelectedRow
);
241 _ClearItemSettings();
242 _UpdateSelectedItem();
243 _RecallItemSettings();
244 Window()->PostMessage(kApply
);
249 BView::MessageReceived(msg
);
256 NotificationsView::Load(BMessage
& settings
)
261 if (settings
.GetInfo("app_usage", &type
, &count
) != B_OK
)
265 appusage_t::iterator auIt
;
266 for (auIt
= fAppFilters
.begin(); auIt
!= fAppFilters
.end(); auIt
++)
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();
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
);
296 NotificationsView::_ClearItemSettings()
298 fMuteAll
->SetValue(B_CONTROL_OFF
);
303 NotificationsView::_UpdateSelectedItem()
305 fSelectedRow
= dynamic_cast<AppRow
*>(fApplications
->CurrentSelection());
311 NotificationsView::_RecallItemSettings()
314 if(fSelectedRow
== NULL
)
316 fMuteAll
->SetValue(B_CONTROL_OFF
);
317 fMuteAll
->SetEnabled(false);
318 fRemoveButton
->SetEnabled(false);
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()));
330 NotificationsView::Revert()
337 NotificationsView::RevertPossible()
344 NotificationsView::Defaults()
351 NotificationsView::DefaultsPossible()
358 NotificationsView::UseDefaultRevertButtons()
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
);