1/* emacs buffer mode hint -*- objc -*- */
2
3#import "PreferencesController.h"
4#import "HourFormatter.h"
5#import "ConfigManager.h"
6#import "AlarmManager.h"
7#import "AlarmBackend.h"
8#import "defines.h"
9
10@implementation PreferencesController
11- (id)init
12{
13  self = [super init];
14  if (self) {
15    if (![NSBundle loadNibNamed:@"Preferences" owner:self])
16      return nil;
17
18    _sm = [StoreManager globalManager];
19    HourFormatter *formatter = [[[HourFormatter alloc] init] autorelease];
20    [[dayStartText cell] setFormatter:formatter];
21    [[dayEndText cell] setFormatter:formatter];
22    [[minStepText cell] setFormatter:formatter];
23    [[refreshIntervalText cell] setFormatter:formatter];
24    RETAIN(globalPreferences);
25    RETAIN(storePreferences);
26    RETAIN(storeFactory);
27    RETAIN(uiPreferences);
28    RETAIN(alarmPreferences);
29    [self selectItem:itemPopUp];
30    [panel setFrameAutosaveName:@"preferencesPanel"];
31    /* FIXME : could we call setupDefaultStore directly ? */
32    [[NSNotificationCenter defaultCenter] addObserver:self
33					  selector:@selector(storeStateChanged:)
34					  name:SAStatusChangedForStore
35					  object:nil];
36    [[NSNotificationCenter defaultCenter] addObserver:self
37 					  selector:@selector(storeStateChanged:)
38 					  name:SAEnabledStatusChangedForStore
39					  object:nil];
40  }
41  return self;
42}
43
44- (void)dealloc
45{
46  RELEASE(globalPreferences);
47  RELEASE(storePreferences);
48  RELEASE(storeFactory);
49  RELEASE(uiPreferences);
50  RELEASE(alarmPreferences);
51  [super dealloc];
52}
53
54- (void)setupDefaultStore
55{
56  NSString *defaultStore = [[ConfigManager globalConfig] objectForKey:ST_DEFAULT];
57  NSEnumerator *list = [_sm storeEnumerator];
58  id <AgendaStore> aStore;
59
60  [defaultStorePopUp removeAllItems];
61  while ((aStore = [list nextObject])) {
62    if ([aStore writable] && [aStore enabled])
63      [defaultStorePopUp addItemWithTitle:[aStore description]];
64  }
65  if ([defaultStorePopUp numberOfItems] > 0) {
66    if ([defaultStorePopUp itemWithTitle:defaultStore])
67      [defaultStorePopUp selectItemWithTitle:defaultStore];
68    else {
69      [defaultStorePopUp selectItemAtIndex:0];
70      [self selectDefaultStore:self];
71    }
72  }
73}
74
75- (void)setupStores
76{
77  NSEnumerator *list;
78  id <AgendaStore> aStore;
79
80  [self setupDefaultStore];
81  list = [_sm storeEnumerator];
82  [storePopUp removeAllItems];
83  while ((aStore = [list nextObject]))
84    [storePopUp addItemWithTitle:[aStore description]];
85  [storePopUp selectItemAtIndex:0];
86  [self selectStore:self];
87}
88
89- (void)storeStateChanged:(NSNotification *)notification
90{
91  [self setupDefaultStore];
92  [self selectStore:nil];
93}
94
95- (void)showPreferences
96{
97  ConfigManager *config = [ConfigManager globalConfig];
98  NSEnumerator *backends;
99  int start = [config integerForKey:FIRST_HOUR];
100  int end = [config integerForKey:LAST_HOUR];
101  int step = [config integerForKey:MIN_STEP];
102  Class backend;
103  NSString *name;
104
105  [dayStart setIntValue:start*3600];
106  [dayEnd setIntValue:end*3600];
107  [dayStartText setIntValue:start*3600];
108  [dayEndText setIntValue:end*3600];
109  [minStep setIntValue:step * 60];
110  [minStepText setIntValue:step * 60];
111  [showTooltip setState:[config integerForKey:TOOLTIP]];
112  [showDateAppIcon setState:[config integerForKey:APPICON_DATE]];
113  [showTimeAppIcon setState:[config integerForKey:APPICON_TIME]];
114
115  [alarmEnabled setState:[[AlarmManager globalManager] alarmsEnabled]];
116  [alarmBackendPopUp removeAllItems];
117  backends = [[AlarmManager backends] objectEnumerator];
118  while ((backend = [backends nextObject]))
119    [alarmBackendPopUp addItemWithTitle:[[backend class] backendName]];
120
121  name = [[AlarmManager globalManager] defaultBackendName];
122  if ([alarmBackendPopUp itemWithTitle:name])
123    [alarmBackendPopUp selectItemWithTitle:name];
124
125  [self setupStores];
126  [storeClass removeAllItems];
127  backends = [[StoreManager backends] objectEnumerator];
128  while ((backend = [backends nextObject]))
129    if ([backend isUserInstanciable])
130      [storeClass addItemWithTitle:[backend storeTypeName]];
131  [storeClass selectItemAtIndex:0];
132  [createButton setEnabled:NO];
133  [panel makeKeyAndOrderFront:self];
134}
135
136
137- (void)periodicSetupForStore:(id)store
138{
139  if ([store conformsToProtocol:@protocol(PeriodicRefresh)]) {
140    [storeRefresh setEnabled:YES];
141    [storeRefresh setState:[store periodicRefresh]];
142    [refreshInterval setEnabled:[store periodicRefresh]];
143    [refreshIntervalText setEnabled:[store periodicRefresh]];
144    [refreshIntervalText setIntValue:[store refreshInterval]];
145    [refreshInterval setIntValue:[store refreshInterval]];
146  } else {
147    [storeRefresh setEnabled:NO];
148    [storeRefresh setState:NO];
149    [refreshInterval setEnabled:NO];
150    [refreshIntervalText setEnabled:NO];
151    [refreshIntervalText setIntValue:0];
152    [refreshInterval setIntValue:0];
153  }
154}
155
156- (void)selectStore:(id)sender
157{
158  id <AgendaStore> store = [_sm storeForName:[storePopUp titleOfSelectedItem]];
159  [storeColor setColor:[store eventColor]];
160  [storeTextColor setColor:[store textColor]];
161  [storeDisplay setState:[store displayed]];
162  [storeWritable setState:[store writable]];
163  [storeEnabled setState:[store enabled]];
164  if ([[defaultStorePopUp titleOfSelectedItem] isEqual:[store description]])
165    [removeButton setEnabled:NO];
166  else
167    [removeButton setEnabled:YES];
168  [self periodicSetupForStore:store];
169}
170
171- (void)changeColor:(id)sender
172{
173  NSColor *rgb = [[storeColor color] colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
174  id <AgendaStore> store = [_sm storeForName:[storePopUp titleOfSelectedItem]];
175  [store setEventColor:rgb];
176}
177
178- (void)changeTextColor:(id)sender
179{
180  NSColor *rgb = [[storeTextColor color] colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
181  id <AgendaStore> store = [_sm storeForName:[storePopUp titleOfSelectedItem]];
182  [store setTextColor:rgb];
183}
184
185- (void)changeStart:(id)sender
186{
187  int value = [dayStart intValue] / 3600;
188  if (value != [[ConfigManager globalConfig] integerForKey:FIRST_HOUR]) {
189    [dayStartText setIntValue:value * 3600];
190    [[ConfigManager globalConfig] setInteger:value forKey:FIRST_HOUR];
191  }
192}
193
194- (void)changeEnd:(id)sender
195{
196  int value = [dayEnd intValue] / 3600;
197  if (value != [[ConfigManager globalConfig] integerForKey:LAST_HOUR]) {
198    [dayEndText setIntValue:value * 3600];
199    [[ConfigManager globalConfig] setInteger:value forKey:LAST_HOUR];
200  }
201}
202
203- (void)changeStep:(id)sender
204{
205  int value = [minStep intValue] / 60;
206  if (value != [[ConfigManager globalConfig] integerForKey:MIN_STEP]) {
207    [minStepText setIntValue:value * 60];
208    [[ConfigManager globalConfig] setInteger:value forKey:MIN_STEP];
209  }
210}
211
212- (void)changeInterval:(id)sender
213{
214  int value = [refreshInterval intValue];
215  id <PeriodicRefresh> store = (id <PeriodicRefresh>)[_sm storeForName:[storePopUp titleOfSelectedItem]];
216  [store setRefreshInterval:value];
217  [refreshIntervalText setIntValue:value];
218  [refreshInterval setIntValue:value];
219}
220
221- (void)selectDefaultStore:(id)sender
222{
223  [_sm setDefaultStore:[defaultStorePopUp titleOfSelectedItem]];
224  [self selectStore:nil];
225}
226
227- (void)toggleDisplay:(id)sender
228{
229  id <AgendaStore> store = [_sm storeForName:[storePopUp titleOfSelectedItem]];
230  [store setDisplayed:[storeDisplay state]];
231}
232
233- (void)toggleWritable:(id)sender
234{
235  id <AgendaStore> store = [_sm storeForName:[storePopUp titleOfSelectedItem]];
236  [store setWritable:[storeWritable state]];
237}
238
239- (void)toggleRefresh:(id)sender
240{
241  id <PeriodicRefresh> store = (id <PeriodicRefresh>)[_sm storeForName:[storePopUp titleOfSelectedItem]];
242  [store setPeriodicRefresh:[storeRefresh state]];
243  [self periodicSetupForStore:store];
244}
245
246- (void)toggleEnabled:(id)sender
247{
248  id <AgendaStore> store = [_sm storeForName:[storePopUp titleOfSelectedItem]];
249  [store setEnabled:[storeEnabled state]];
250}
251
252- (void)toggleTooltip:(id)sender
253{
254  [[ConfigManager globalConfig] setInteger:[showTooltip state] forKey:TOOLTIP];
255}
256
257- (void)toggleShowDate:(id)sender
258{
259  [[ConfigManager globalConfig] setInteger:[showDateAppIcon state] forKey:APPICON_DATE];
260}
261
262- (void)toggleShowTime:(id)sender
263{
264  [[ConfigManager globalConfig] setInteger:[showTimeAppIcon state] forKey:APPICON_TIME];
265}
266
267- (void)toggleAlarms:(id)sender
268{
269  [[AlarmManager globalManager] setAlarmsEnabled:[alarmEnabled state]];
270}
271
272- (void)selectAlarmBackend:(id)sender
273{
274  [[AlarmManager globalManager] setDefaultBackend:[alarmBackendPopUp titleOfSelectedItem]];
275}
276
277/* We only allow the removal of non-default stores */
278- (void)removeStore:(id)sender
279{
280  id <AgendaStore> store = [_sm storeForName:[storePopUp titleOfSelectedItem]];
281  ConfigManager *config = [ConfigManager globalConfig];
282  NSMutableArray *storeArray = [NSMutableArray arrayWithArray:[config objectForKey:STORES]];
283
284  [storeArray removeObject:[store description]];
285  [config setObject:storeArray forKey:STORES];
286  [config removeObjectForKey:[store description]];
287  [_sm removeStoreNamed:[store description]];
288  /* FIXME : This could be done by registering STORES key */
289  [self setupStores];
290}
291
292- (void)createStore:(id)sender
293{
294  ConfigManager *config = [ConfigManager globalConfig];
295  NSMutableArray *storeArray = [NSMutableArray arrayWithArray:[config objectForKey:STORES]];
296  Class backend;
297
298  backend = [StoreManager backendForName:[storeClass titleOfSelectedItem]];
299  if (backend && [backend registerWithName:[storeName stringValue]]) {
300    [_sm addStoreNamed:[storeName stringValue]];
301    [storeArray addObject:[storeName stringValue]];
302    [config setObject:storeArray forKey:STORES];
303    [self setupStores];
304  }
305  [storeName setStringValue:@""];
306  [createButton setEnabled:NO];
307}
308
309- (void)setContent:(id)content
310{
311  id old = [slot contentView];
312
313  if (old == content)
314    return;
315  [slot setContentView: content];
316  [itemPopUp setNextKeyView:[slot contentView]];
317}
318
319
320- (void)selectItem:(id)sender
321{
322  switch ([sender indexOfSelectedItem]) {
323  case 0:
324    [self setContent:globalPreferences];
325    break;
326  case 1:
327    [self setContent:storePreferences];
328    break;
329  case 2:
330    [self setContent:storeFactory];
331    break;
332  case 3:
333    [self setContent:uiPreferences];
334    break;
335  case 4:
336    [self setContent:alarmPreferences];
337    break;
338  }
339}
340
341- (void)controlTextDidChange:(NSNotification *)notification
342{
343  if ([notification object] == storeName) {
344    if ([_sm storeForName:[storeName stringValue]] || ![[storeName stringValue] length])
345      [createButton setEnabled:NO];
346    else
347      [createButton setEnabled:YES];
348  }
349}
350@end
351