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. 5 * 6 * Authors: 7 * Pier Luigi Fiorini, pierluigi.fiorini@gmail.com 8 * Brian Hill, supernova@tycho.email 9 */ 10 11 #include <stdio.h> 12 #include <stdlib.h> 13 14 #include <vector> 15 16 #include <Alert.h> 17 #include <Box.h> 18 #include <Button.h> 19 #include <Catalog.h> 20 #include <Directory.h> 21 #include <File.h> 22 #include <FindDirectory.h> 23 #include <Font.h> 24 #include <LayoutBuilder.h> 25 #include <Node.h> 26 #include <Path.h> 27 #include <Query.h> 28 #include <Roster.h> 29 #include <String.h> 30 #include <SymLink.h> 31 #include <Volume.h> 32 #include <VolumeRoster.h> 33 34 #include <notification/Notifications.h> 35 36 #include "GeneralView.h" 37 #include "NotificationsConstants.h" 38 #include "SettingsHost.h" 39 40 #undef B_TRANSLATION_CONTEXT 41 #define B_TRANSLATION_CONTEXT "GeneralView" 42 43 const uint32 kToggleNotifications = '_TSR'; 44 const uint32 kWidthChanged = '_WIC'; 45 const uint32 kTimeoutChanged = '_TIC'; 46 const uint32 kServerChangeTriggered = '_SCT'; 47 const BString kSampleMessageID("NotificationsSample"); 48 49 50 GeneralView::GeneralView(SettingsHost* host) 51 : 52 SettingsPane("general", host) 53 { 54 // Notification server 55 fNotificationBox = new BCheckBox("server", 56 B_TRANSLATE("Enable notifications"), 57 new BMessage(kToggleNotifications)); 58 BBox* box = new BBox("box"); 59 box->SetLabel(fNotificationBox); 60 61 // Window width 62 int32 minWidth = int32(kMinimumWidth / kWidthStep); 63 int32 maxWidth = int32(kMaximumWidth / kWidthStep); 64 fWidthSlider = new BSlider("width", B_TRANSLATE("Window width:"), 65 new BMessage(kWidthChanged), minWidth, maxWidth, B_HORIZONTAL); 66 fWidthSlider->SetHashMarks(B_HASH_MARKS_BOTTOM); 67 fWidthSlider->SetHashMarkCount(maxWidth - minWidth + 1); 68 BString minWidthLabel; 69 minWidthLabel << int32(kMinimumWidth); 70 BString maxWidthLabel; 71 maxWidthLabel << int32(kMaximumWidth); 72 fWidthSlider->SetLimitLabels( 73 B_TRANSLATE_COMMENT(minWidthLabel.String(), "Slider low text"), 74 B_TRANSLATE_COMMENT(maxWidthLabel.String(), "Slider high text")); 75 76 // Display time 77 fDurationSlider = new BSlider("duration", B_TRANSLATE("Duration:"), 78 new BMessage(kTimeoutChanged), kMinimumTimeout, kMaximumTimeout, 79 B_HORIZONTAL); 80 fDurationSlider->SetHashMarks(B_HASH_MARKS_BOTTOM); 81 fDurationSlider->SetHashMarkCount(kMaximumTimeout - kMinimumTimeout + 1); 82 BString minLabel; 83 minLabel << kMinimumTimeout; 84 BString maxLabel; 85 maxLabel << kMaximumTimeout; 86 fDurationSlider->SetLimitLabels( 87 B_TRANSLATE_COMMENT(minLabel.String(), "Slider low text"), 88 B_TRANSLATE_COMMENT(maxLabel.String(), "Slider high text")); 89 90 box->AddChild(BLayoutBuilder::Group<>(B_VERTICAL) 91 .SetInsets(B_USE_DEFAULT_SPACING) 92 .Add(fWidthSlider) 93 .Add(fDurationSlider) 94 .AddGlue() 95 .View()); 96 97 BLayoutBuilder::Group<>(this, B_VERTICAL) 98 .SetInsets(B_USE_WINDOW_SPACING) 99 .Add(box) 100 .End(); 101 } 102 103 104 void 105 GeneralView::AttachedToWindow() 106 { 107 BView::AttachedToWindow(); 108 fNotificationBox->SetTarget(this); 109 fWidthSlider->SetTarget(this); 110 fDurationSlider->SetTarget(this); 111 } 112 113 114 void 115 GeneralView::MessageReceived(BMessage* msg) 116 { 117 switch (msg->what) { 118 case kToggleNotifications: 119 { 120 SettingsPane::SettingsChanged(false); 121 _EnableControls(); 122 break; 123 } 124 case kWidthChanged: { 125 int32 value = fWidthSlider->Value() * 50; 126 _SetWidthLabel(value); 127 SettingsPane::SettingsChanged(true); 128 break; 129 } 130 case kTimeoutChanged: 131 { 132 int32 value = fDurationSlider->Value(); 133 _SetTimeoutLabel(value); 134 SettingsPane::SettingsChanged(true); 135 break; 136 } 137 default: 138 BView::MessageReceived(msg); 139 break; 140 } 141 } 142 143 144 status_t 145 GeneralView::Load(BMessage& settings) 146 { 147 bool autoStart = settings.GetBool(kAutoStartName, true); 148 fNotificationBox->SetValue(autoStart ? B_CONTROL_ON : B_CONTROL_OFF); 149 150 if (settings.FindFloat(kWidthName, &fOriginalWidth) != B_OK 151 || fOriginalWidth > kMaximumWidth 152 || fOriginalWidth < kMinimumWidth) 153 fOriginalWidth = kDefaultWidth; 154 155 if (settings.FindInt32(kTimeoutName, &fOriginalTimeout) != B_OK 156 || fOriginalTimeout > kMaximumTimeout 157 || fOriginalTimeout < kMinimumTimeout) 158 fOriginalTimeout = kDefaultTimeout; 159 // TODO need to save again if values outside of expected range 160 int32 setting; 161 if (settings.FindInt32(kIconSizeName, &setting) != B_OK) 162 fOriginalIconSize = kDefaultIconSize; 163 else 164 fOriginalIconSize = (icon_size)setting; 165 166 _EnableControls(); 167 168 return Revert(); 169 } 170 171 172 status_t 173 GeneralView::Save(BMessage& settings) 174 { 175 bool autoStart = (fNotificationBox->Value() == B_CONTROL_ON); 176 settings.AddBool(kAutoStartName, autoStart); 177 178 int32 timeout = fDurationSlider->Value(); 179 settings.AddInt32(kTimeoutName, timeout); 180 181 float width = fWidthSlider->Value() * 50; 182 settings.AddFloat(kWidthName, width); 183 184 icon_size iconSize = B_LARGE_ICON; 185 settings.AddInt32(kIconSizeName, (int32)iconSize); 186 187 return B_OK; 188 } 189 190 191 status_t 192 GeneralView::Revert() 193 { 194 fDurationSlider->SetValue(fOriginalTimeout); 195 _SetTimeoutLabel(fOriginalTimeout); 196 197 fWidthSlider->SetValue(fOriginalWidth / 50); 198 _SetWidthLabel(fOriginalWidth); 199 200 return B_OK; 201 } 202 203 204 bool 205 GeneralView::RevertPossible() 206 { 207 int32 timeout = fDurationSlider->Value(); 208 if (fOriginalTimeout != timeout) 209 return true; 210 211 int32 width = fWidthSlider->Value() * 50; 212 if (fOriginalWidth != width) 213 return true; 214 215 return false; 216 } 217 218 219 status_t 220 GeneralView::Defaults() 221 { 222 fDurationSlider->SetValue(kDefaultTimeout); 223 _SetTimeoutLabel(kDefaultTimeout); 224 225 fWidthSlider->SetValue(kDefaultWidth / 50); 226 _SetWidthLabel(kDefaultWidth); 227 228 return B_OK; 229 } 230 231 232 bool 233 GeneralView::DefaultsPossible() 234 { 235 int32 timeout = fDurationSlider->Value(); 236 if (kDefaultTimeout != timeout) 237 return true; 238 239 int32 width = fWidthSlider->Value() * 50; 240 if (kDefaultWidth != width) 241 return true; 242 243 return false; 244 } 245 246 247 bool 248 GeneralView::UseDefaultRevertButtons() 249 { 250 return true; 251 } 252 253 254 void 255 GeneralView::_EnableControls() 256 { 257 bool enabled = fNotificationBox->Value() == B_CONTROL_ON; 258 fWidthSlider->SetEnabled(enabled); 259 fDurationSlider->SetEnabled(enabled); 260 } 261 262 263 void 264 GeneralView::_SetTimeoutLabel(int32 value) 265 { 266 BString label(B_TRANSLATE("Timeout:")); 267 label.Append(" "); 268 label << value; 269 label.Append(" ").Append(B_TRANSLATE("seconds")); 270 fDurationSlider->SetLabel(label.String()); 271 } 272 273 274 void 275 GeneralView::_SetWidthLabel(int32 value) 276 { 277 BString label(B_TRANSLATE("Width:")); 278 label.Append(" "); 279 label << value; 280 label.Append(" ").Append(B_TRANSLATE("pixels")); 281 fWidthSlider->SetLabel(label.String()); 282 } 283 284 285 bool 286 GeneralView::_IsServerRunning() 287 { 288 return be_roster->IsRunning(kNotificationServerSignature); 289 } 290