PageRenderTime 40ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/Controller.m

https://github.com/kek/khronos_time_tracker
Objective C | 2417 lines | 1504 code | 300 blank | 613 comment | 320 complexity | 3243d359c9a1355b13d2a497579db5ae MD5 | raw file
  1. #import "Controller.h"
  2. #import "CUPreferenceController.h"
  3. #import "CUPreferences.h"
  4. @implementation Controller
  5. //***Main Methods***
  6. + (void)initialize
  7. {
  8. [CUPreferences initializeDefaults];
  9. }
  10. - (void)dealloc
  11. {
  12. [preferences release];
  13. [preferencesController release];
  14. [main release];
  15. // Remove Notifications.
  16. NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
  17. [nc removeObserver:self];
  18. [super dealloc];
  19. }
  20. - (void)awakeFromNib
  21. {
  22. NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
  23. // Setup the Main Variable.
  24. if(!main)
  25. main = [NSBundle mainBundle];
  26. // Setup Preferences model.
  27. if(!preferences)
  28. preferences = [[CUPreferences init] alloc];
  29. firstLaunch = [preferences firstLaunch];
  30. // Attach Notifications
  31. // Get notifications for clock setting changes.
  32. [nc addObserver:self
  33. selector:@selector(handleClockSettingsChanged:)
  34. name:CUPreferencesTimeSettingsChangedNotification
  35. object:nil];
  36. // Get notifications for table changes.
  37. [nc addObserver:self
  38. selector:@selector(handleTableChanges:)
  39. name:CUPreferencesTableNotification
  40. object:nil];
  41. // Get notifications for Preferences Reset.
  42. [nc addObserver:self
  43. selector:@selector(handlePreferencesReset:)
  44. name:CUPreferencesResetNotification
  45. object:nil];
  46. // FIXME: Need to save the window size and placement (gdey)
  47. // [mainWindow setFrameOrigin:NSMakePoint(windowY, windowX)];
  48. // [mainWindow setContentSize:NSMakeSize(windowWidth, windowHeight)];
  49. [addSessionButton setEnabled:NO];
  50. [deleteSessionButton setEnabled:NO];
  51. [editSessionButton setEnabled:NO];
  52. [deleteJobButton setEnabled:NO];
  53. [editJobButton setEnabled:NO];
  54. if (firstLaunch) [mainWindow center];
  55. jobData = [[NSMutableArray alloc] init];
  56. tableActive = [NSImage imageNamed:@"jobActive"];
  57. tableInactive = [NSImage imageNamed:@"jobInactive"];
  58. tablePaused = [NSImage imageNamed:@"jobPause"];
  59. pauseYes = [NSImage imageNamed:@"stst_pause"];
  60. pauseNo = [NSImage imageNamed:@"stst_pause2"];
  61. startStopGray = [NSImage imageNamed:@"stst_null"];
  62. startStopGreen = [NSImage imageNamed:@"stst_start"];
  63. startStopRed = [NSImage imageNamed:@"stst_stop"];
  64. menuStartStopGray = [NSImage imageNamed:@"stst_nullMB"];
  65. menuStartStopRed = [NSImage imageNamed:@"stst_stopMB"];
  66. menuStartStopGreen = [NSImage imageNamed:@"stst_startMB"];
  67. menuPauseYes = [NSImage imageNamed:@"stst_playMB"];
  68. menuPauseNo = [NSImage imageNamed:@"stst_pause2MB"];
  69. menuPauseNull = [NSImage imageNamed:@"stst_nullPauseMB"];
  70. menuJobListIcon = [NSImage imageNamed:@"MBjobSelector3"];
  71. menuJobListAltIcon = [NSImage imageNamed:@"MBjobSelector3Alt"];
  72. updateTimer = [[NSTimer scheduledTimerWithTimeInterval:(1.0) target:self selector:@selector(updateLoop) userInfo:nil repeats:YES] retain];
  73. [[NSRunLoop currentRunLoop] addTimer:updateTimer forMode:NSEventTrackingRunLoopMode];
  74. [[NSRunLoop currentRunLoop] addTimer:updateTimer forMode:NSModalPanelRunLoopMode];
  75. saveTimer = 0;
  76. autoDeleteTime = 0;
  77. NSFileManager *fileManager = [NSFileManager defaultManager];
  78. if ([fileManager fileExistsAtPath:[@"~/Library/Application Support/Khronos/khronosData.khd" stringByExpandingTildeInPath]])
  79. [jobData setArray:[dataHandler createJobListFromFile:[@"~/Library/Application Support/Khronos/khronosData.khd" stringByExpandingTildeInPath]]];
  80. else if ([fileManager fileExistsAtPath:@"/Library/Application Support/KhronosHelp/khronosData.khd"])
  81. [jobData setArray:[dataHandler createJobListFromFile:@"/Library/Application Support/KhronosHelp/khronosData.khd"]];
  82. int i = 0;
  83. int count = [jobData count];
  84. while (i < count)
  85. {
  86. [self computeJobTime:i];
  87. i++;
  88. }
  89. if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_2)
  90. {
  91. lastJobSorter = [[NSSortDescriptor alloc] initWithKey:@"jobNumber" ascending:YES];
  92. lastSessionSorter = [[NSSortDescriptor alloc] initWithKey:@"sessionNumber" ascending:YES];
  93. lastJobSortAscending = YES;
  94. lastSessionSortAscending = YES;
  95. }
  96. printInfo = [NSPrintInfo sharedPrintInfo];
  97. [self buildStatusItem];
  98. [self updateMenuBarJobList];
  99. [self buildJobTable];
  100. [self buildSessionTable];
  101. [jobTable setTarget:self];
  102. [jobTable setDoubleAction:@selector(tableDoubleClick:)];
  103. [sessionTable setTarget:self];
  104. [sessionTable setDoubleAction:@selector(tableDoubleClick:)];
  105. [startStopField setStringValue:@""];
  106. [mainWindow makeKeyAndOrderFront:nil];
  107. }
  108. #pragma mark Preferences Notification Handlers
  109. -(void) handleTableChanges:(NSNotification *)note
  110. {
  111. NSLog(@"Recieved Notifications %@",note);
  112. NSDictionary *userInfo = [note userInfo];
  113. if([[userInfo objectForKey:CUPreferencesTableUserInfoTableName] isEqual:CUPreferencesProjectDisplay]) {
  114. NSLog(@"Updating the Project Table.");
  115. [self buildJobTable];
  116. }
  117. if([[userInfo objectForKey:CUPreferencesTableUserInfoTableName] isEqual:CUPreferencesSessionDisplay]) {
  118. NSLog(@"Updating the Session Table.");
  119. [self buildSessionTable];
  120. }
  121. if([[userInfo objectForKey:CUPreferencesTableUserInfoTableName] isEqual:CUPreferencesMenuDisplay]){
  122. NSLog(@"Updating the Menu Table");
  123. [self buildStatusItem];
  124. }
  125. }
  126. - (void) handleClockSettingsChanged:(NSNotification *)note
  127. {
  128. NSLog(@"Recieved Notification %@",note);
  129. [jobTable reloadData];
  130. [sessionTable reloadData];
  131. }
  132. - (void)handlePreferencesReset:(NSNotification *)note
  133. {
  134. [self buildJobTable];
  135. [self buildSessionTable];
  136. }
  137. - (void)applicationWillTerminate:(NSNotification *)notification
  138. {
  139. [self saveLoop];
  140. }
  141. - (void)createNewJob:(NSString *)name client:(NSString *)client rate:(double)rate
  142. {
  143. NSMutableDictionary *tempJob = [[NSMutableDictionary alloc] init];
  144. [tempJob setObject:[NSNumber numberWithInt:[self getHighestJobNumber]] forKey:@"jobNumber"];
  145. [tempJob setObject:@"No" forKey:@"jobActive"];
  146. [tempJob setObject:name forKey:@"jobName"];
  147. [tempJob setObject:client forKey:@"clientName"];
  148. cuDateTime *tempTimeLogged = [[cuDateTime alloc] initWithTimeString:@"0:00:00"];
  149. [tempJob setObject:tempTimeLogged forKey:@"jobTimeLogged"];
  150. [tempJob setObject:[NSNumber numberWithDouble:rate] forKey:@"hourlyRate"];
  151. [tempJob setObject:[NSNumber numberWithDouble:0] forKey:@"jobCharges"];
  152. NSMutableArray *tempSessionList = [[NSMutableArray alloc] init];
  153. [tempJob setObject:tempSessionList forKey:@"sessionList"];
  154. [jobData addObject:tempJob];
  155. }
  156. - (void)createNewSession:(cuDateTime *)startDateTime endDateTime:(cuDateTime *)endDateTime job:(int)whichJob active:(BOOL)active
  157. {
  158. NSMutableDictionary *tempSession = [[NSMutableDictionary alloc] init];
  159. [tempSession setObject:[NSNumber numberWithInt:[self getHighestSessionNumber:whichJob]] forKey:@"sessionNumber"];
  160. if (active) [tempSession setObject:@"Yes" forKey:@"sessionActive"];
  161. else [tempSession setObject:@"No" forKey:@"sessionActive"];
  162. [tempSession setObject:startDateTime forKey:@"startDateTime"];
  163. [tempSession setObject:endDateTime forKey:@"endDateTime"];
  164. cuDateTime *pauseTime = [[cuDateTime alloc] init];
  165. [tempSession setObject:pauseTime forKey:@"pauseTime"];
  166. [tempSession setObject:pauseTime forKey:@"tempPauseTime"];
  167. [[[jobData objectAtIndex:whichJob] objectForKey:@"sessionList"] addObject:tempSession];
  168. [self computeJobTime:whichJob];
  169. }
  170. - (void)computeJobTime:(int)job
  171. {
  172. cuDateTime *newTime = [[[cuDateTime alloc] init] autorelease];
  173. id sessionList = [[jobData objectAtIndex:job] objectForKey:@"sessionList"];
  174. cuDateTime *mathTime = [[cuDateTime alloc] init];
  175. cuDateTime *mathTimeTwo = [[cuDateTime alloc] init];
  176. cuDateTime *mathTimeThree = [[cuDateTime alloc] init];
  177. int i = 0;
  178. int count = [sessionList count];
  179. while (i < count)
  180. {
  181. [mathTime setValues:[[[[jobData objectAtIndex:job] objectForKey:@"sessionList"] objectAtIndex:i] objectForKey:@"endDateTime"]];
  182. [mathTimeTwo setValues:[[[[jobData objectAtIndex:job] objectForKey:@"sessionList"] objectAtIndex:i] objectForKey:@"startDateTime"]];
  183. [mathTimeThree setValues:[[[[jobData objectAtIndex:job] objectForKey:@"sessionList"] objectAtIndex:i] objectForKey:@"pauseTime"]];
  184. [newTime setValues:[newTime addInterval:[mathTimeTwo getTimeInterval:mathTime]]];
  185. [newTime setValues:[newTime subtractInterval:mathTimeThree]];
  186. i++;
  187. }
  188. [[jobData objectAtIndex:job] setObject:newTime forKey:@"jobTimeLogged"];
  189. [mathTime release];
  190. [mathTimeTwo release];
  191. [mathTimeThree release];
  192. }
  193. - (void)buildJobTable
  194. {
  195. NSArray *jobTableColumns = [jobTable tableColumns];
  196. int i = [jobTableColumns count];
  197. while (i > 0)
  198. {
  199. [jobTable removeTableColumn:[jobTableColumns objectAtIndex:i - 1]];
  200. i--;
  201. }
  202. //Add Columns
  203. [jobTable addTableColumn:[tableGenerator createJobActiveColumn:[main localizedStringForKey:@"ActiveHeader" value:@"..." table:@"ProjectTable"]]];
  204. if ([preferences displayForTable:CUPreferencesProjectDisplay column:CUPreferencesProjectDisplayNumber])
  205. [jobTable addTableColumn:[tableGenerator createJobNumberColumn:[main localizedStringForKey:@"NumberHeader" value:@"#" table:@"ProjectTable"]]];
  206. if ([preferences displayForTable:CUPreferencesProjectDisplay column:CUPreferencesProjectDisplayName])
  207. [jobTable addTableColumn:[tableGenerator createJobNameColumn:[main localizedStringForKey:@"NameHeader" value:@"Project" table:@"ProjectTable"]]];
  208. if ([preferences displayForTable:CUPreferencesProjectDisplay column:CUPreferencesProjectDisplayClient])
  209. [jobTable addTableColumn:[tableGenerator createJobClientColumn:[main localizedStringForKey:@"ClientHeader" value:@"Client" table:@"ProjectTable"]]];
  210. if ([preferences displayForTable:CUPreferencesProjectDisplay column:CUPreferencesProjectDisplayRate])
  211. [jobTable addTableColumn:[tableGenerator createJobHourlyRateColumn:[main localizedStringForKey:@"RateHeader" value:@"Rate" table:@"ProjectTable"]]];
  212. if ([preferences displayForTable:CUPreferencesProjectDisplay column:CUPreferencesProjectDisplayTime])
  213. [jobTable addTableColumn:[tableGenerator createJobTimeLoggedColumn:[main localizedStringForKey:@"TimeHeader" value:@"Time Logged" table:@"ProjectTable"]]];
  214. if([preferences displayForTable:CUPreferencesProjectDisplay column:CUPreferencesProjectDisplayCharges])
  215. [jobTable addTableColumn:[tableGenerator createJobChargesColumn:[main localizedStringForKey:@"ChargesHeader" value:@"Charges" table:@"ProjectTable"]]];
  216. [jobTable reloadData];
  217. }
  218. - (void)buildSessionTable
  219. {
  220. NSArray *sessionTableColumns = [sessionTable tableColumns];
  221. int i = [sessionTableColumns count];
  222. while (i > 0)
  223. {
  224. [sessionTable removeTableColumn:[sessionTableColumns objectAtIndex:i - 1]];
  225. i--;
  226. }
  227. //Add Columns
  228. [sessionTable addTableColumn:[tableGenerator createSessionActiveColumn:
  229. [main localizedStringForKey:@"ActiveHeader" value:@"..." table:@"SessionTable"]]];
  230. if ([preferences displayForTable:CUPreferencesSessionDisplay column:CUPreferencesSessionDisplayNumber])
  231. [sessionTable addTableColumn:[tableGenerator createSessionNumberColumn:
  232. [main localizedStringForKey:@"NumberHeader" value:@"#" table:@"SessionTable"]]];
  233. if ([preferences displayForTable:CUPreferencesSessionDisplay column:CUPreferencesSessionDisplayStartDate])
  234. [sessionTable addTableColumn:[tableGenerator createSessionSDateColumn:
  235. [main localizedStringForKey:@"StartDateHeader" value:@"Date" table:@"SessionTable"]]];
  236. if ([preferences displayForTable:CUPreferencesSessionDisplay column:CUPreferencesSessionDisplayStartTime])
  237. [sessionTable addTableColumn:[tableGenerator createSessionETimeColumn:
  238. [main localizedStringForKey:@"StartTimeHeader" value:@"Time" table:@"SessionTable"]]];
  239. if ([preferences displayForTable:CUPreferencesSessionDisplay column:CUPreferencesSessionDisplayEndDate])
  240. [sessionTable addTableColumn:[tableGenerator createSessionEDateColumn:
  241. [main localizedStringForKey:@"EndDateHeader" value:@"End Date" table:@"SessionTable"]]];
  242. if ([preferences displayForTable:CUPreferencesSessionDisplay column:CUPreferencesSessionDisplayEndTime])
  243. [sessionTable addTableColumn:[tableGenerator createSessionETimeColumn:
  244. [main localizedStringForKey:@"EndTimeHeader" value:@"End Time" table:@"SessionTable"]]];
  245. if ([preferences displayForTable:CUPreferencesSessionDisplay column:CUPreferencesSessionDisplayPauseTime])
  246. [sessionTable addTableColumn:[tableGenerator createSessionPauseTimeColumn:
  247. [main localizedStringForKey:@"PauseTimeHeader" value:@"Pauses" table:@"SessionTable"]]];
  248. if ([preferences displayForTable:CUPreferencesSessionDisplay column:CUPreferencesSessionDisplayTotalTime])
  249. [sessionTable addTableColumn:[tableGenerator createSessionTotalTimeColumn:
  250. [main localizedStringForKey:@"TotalTimeHeader" value:@"Total Time" table:@"SessionTable"]]];
  251. if ([preferences displayForTable:CUPreferencesSessionDisplay column:CUPreferencesSessionDisplayCharges])
  252. [sessionTable addTableColumn:[tableGenerator createSessionChargesColumn:
  253. [main localizedStringForKey:@"ChargesHeader" value:@"Charges" table:@"SessionTable"]]];
  254. if ([preferences displayForTable:CUPreferencesSessionDisplay column:CUPreferencesSessionDisplaySummary])
  255. [sessionTable addTableColumn:[tableGenerator createSessionSummaryColumn:
  256. [main localizedStringForKey:@"SummaryHeader" value:@"Summary" table:@"SessionTable"]]];
  257. [sessionTable reloadData];
  258. }
  259. - (void)buildPrintTable
  260. {
  261. NSArray *tableColumns = [printTable tableColumns];
  262. int i = [tableColumns count];
  263. while (i > 0)
  264. {
  265. [printTable removeTableColumn:[tableColumns objectAtIndex:i - 1]];
  266. i--;
  267. }
  268. if ([preferences displayForTable:CUPreferencesSessionDisplay column:CUPreferencesSessionDisplayNumber])
  269. [printTable addTableColumn:[tableGenerator createSessionNumberColumn:
  270. [main localizedStringForKey:@"NumberHeader" value:@"#" table:@"SessionTable"]]];
  271. if ([preferences displayForTable:CUPreferencesSessionDisplay column:CUPreferencesSessionDisplayStartDate])
  272. [printTable addTableColumn:[tableGenerator createSessionSDateColumn:
  273. [main localizedStringForKey:@"StartDateHeader" value:@"Date" table:@"SessionTable"]]];
  274. if ([preferences displayForTable:CUPreferencesSessionDisplay column:CUPreferencesSessionDisplayStartTime])
  275. [printTable addTableColumn:[tableGenerator createSessionETimeColumn:
  276. [main localizedStringForKey:@"StartTimeHeader" value:@"Time" table:@"SessionTable"]]];
  277. if ([preferences displayForTable:CUPreferencesSessionDisplay column:CUPreferencesSessionDisplayEndDate])
  278. [printTable addTableColumn:[tableGenerator createSessionEDateColumn:
  279. [main localizedStringForKey:@"EndDateHeader" value:@"End Date" table:@"SessionTable"]]];
  280. if ([preferences displayForTable:CUPreferencesSessionDisplay column:CUPreferencesSessionDisplayEndTime])
  281. [printTable addTableColumn:[tableGenerator createSessionETimeColumn:
  282. [main localizedStringForKey:@"EndTimeHeader" value:@"End Time" table:@"SessionTable"]]];
  283. if ([preferences displayForTable:CUPreferencesSessionDisplay column:CUPreferencesSessionDisplayPauseTime])
  284. [printTable addTableColumn:[tableGenerator createSessionPauseTimeColumn:
  285. [main localizedStringForKey:@"PauseTimeHeader" value:@"Pauses" table:@"SessionTable"]]];
  286. if ([preferences displayForTable:CUPreferencesSessionDisplay column:CUPreferencesSessionDisplayTotalTime])
  287. [printTable addTableColumn:[tableGenerator createSessionTotalTimeColumn:
  288. [main localizedStringForKey:@"TotalTimeHeader" value:@"Total Time" table:@"SessionTable"]]];
  289. if ([preferences displayForTable:CUPreferencesSessionDisplay column:CUPreferencesSessionDisplayCharges])
  290. [printTable addTableColumn:[tableGenerator createSessionChargesColumn:
  291. [main localizedStringForKey:@"ChargesHeader" value:@"Charges" table:@"SessionTable"]]];
  292. if ([preferences displayForTable:CUPreferencesSessionDisplay column:CUPreferencesSessionDisplaySummary])
  293. [printTable addTableColumn:[tableGenerator createSessionSummaryColumn:
  294. [main localizedStringForKey:@"SummaryHeader" value:@"Summary" table:@"SessionTable"]]];
  295. [printTable reloadData];
  296. }
  297. - (NSString *)formatterString
  298. {
  299. int time = [preferences updateTimeEvery];
  300. if (time == 0) return @"second";
  301. if (time == 15) return @"quarter";
  302. if (time == 30) return @"half";
  303. if (time == 60) return @"hour";
  304. return nil;
  305. }
  306. - (void)updatePrintWindowFields
  307. {
  308. [printJobName setStringValue:[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"jobName"]];
  309. [printClientName setStringValue:[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"clientName"]];
  310. NSMutableString *hourlyRateFormatted = [[NSMutableString alloc] init];
  311. [hourlyRateFormatted appendString:[preferences monetaryUnit]];
  312. [hourlyRateFormatted appendString:[[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"hourlyRate"] stringValue]];
  313. [printHourlyRate setStringValue:hourlyRateFormatted];
  314. cuDateTime *tempTimeLogged = [[cuDateTime alloc] init];
  315. [tempTimeLogged setValues:[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"jobTimeLogged"]];
  316. [printTotalTimeLogged setStringValue:[tempTimeLogged getTimeStringFor:[preferences updateTimeEvery]]];
  317. NSNumber *rate = [[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"hourlyRate"];
  318. NSString *formatterString = [self formatterString];
  319. NSMutableString *chargeNumberString = [[NSMutableString alloc] init];
  320. [chargeNumberString setString:[[NSNumber numberWithDouble:[tempTimeLogged calculateCharges:[rate doubleValue]
  321. format:formatterString]] stringValue]];
  322. [chargeNumberString setString:[self truncateChargeString:chargeNumberString]];
  323. NSMutableString *tempChargesString = [[NSMutableString alloc] init];
  324. [tempChargesString appendString:[preferences monetaryUnit]];
  325. [tempChargesString appendString:chargeNumberString];
  326. [printTotalCharges setStringValue:tempChargesString];
  327. [printWindow setContentSize:NSMakeSize(482, 235)];
  328. int i = 0;
  329. int count = [[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"] count];
  330. while (i < count)
  331. {
  332. [printWindow setContentSize:NSMakeSize(482, i * 19 + 235)];
  333. i++;
  334. }
  335. }
  336. - (void)buildStatusItem
  337. {
  338. [[NSStatusBar systemStatusBar] removeStatusItem:menuPauseButton];
  339. [[NSStatusBar systemStatusBar] removeStatusItem:menuStartStopButton];
  340. [[NSStatusBar systemStatusBar] removeStatusItem:jobPullDownMenu];
  341. [[NSStatusBar systemStatusBar] removeStatusItem:menuChargeDisplay];
  342. [[NSStatusBar systemStatusBar] removeStatusItem:menuTimeDisplay];
  343. if ([preferences displayForTable:CUPreferencesMenuDisplay column:CUPreferencesMenuDisplayRecrodingButton])
  344. {
  345. menuStartStopButton = [[[NSStatusBar systemStatusBar] statusItemWithLength:25] retain];
  346. [menuStartStopButton setHighlightMode:NO];
  347. [menuStartStopButton setImage:menuStartStopGray];
  348. [menuStartStopButton setTarget:self];
  349. [menuStartStopButton setAction:@selector(startStopRecording:)];
  350. [menuStartStopButton setEnabled:YES];
  351. }
  352. if ([preferences displayForTable:CUPreferencesMenuDisplay column:CUPreferencesMenuDisplayPauseButton])
  353. {
  354. menuPauseButton = [[[NSStatusBar systemStatusBar] statusItemWithLength:25] retain];
  355. [menuPauseButton setHighlightMode:NO];
  356. [menuPauseButton setImage:menuPauseNull];
  357. [menuPauseButton setTarget:self];
  358. [menuPauseButton setAction:@selector(pauseUnpause:)];
  359. [menuPauseButton setEnabled:YES];
  360. }
  361. if ([preferences displayForTable:CUPreferencesMenuDisplay column:CUPreferencesMenuDisplayProjectList]
  362. && floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_2)
  363. {
  364. jobPullDownMenu = [[[NSStatusBar systemStatusBar] statusItemWithLength:25] retain];
  365. [jobPullDownMenu setHighlightMode:YES];
  366. [jobPullDownMenu setImage:menuJobListIcon];
  367. [jobPullDownMenu setAlternateImage:menuJobListAltIcon];
  368. [jobPullDownMenu setMenu:menuJobList];
  369. [jobPullDownMenu setEnabled:YES];
  370. }
  371. if ([preferences displayForTable:CUPreferencesMenuDisplay column:CUPreferencesMenuDisplayTotalTime])
  372. {
  373. menuTimeDisplay = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength] retain];
  374. [menuTimeDisplay setHighlightMode:NO];
  375. [menuTimeDisplay setTitle:@""];
  376. [menuTimeDisplay setEnabled:YES];
  377. }
  378. if ([preferences displayForTable:CUPreferencesMenuDisplay column:CUPreferencesMenuDisplayCharges])
  379. {
  380. menuChargeDisplay = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength] retain];
  381. [menuChargeDisplay setHighlightMode:NO];
  382. [menuChargeDisplay setTitle:@""];
  383. [menuChargeDisplay setEnabled:YES];
  384. }
  385. }
  386. - (void)updateLoop
  387. {
  388. saveTimer++;
  389. if (saveTimer > [preferences autoSaveTime] * 60) [self saveLoop];
  390. int i = 0;
  391. int count = [jobData count];
  392. int j = 0;
  393. int sessionCount = 0;
  394. while (i < count)
  395. {
  396. if ([[[jobData objectAtIndex:i] objectForKey:@"jobActive"] isEqualTo:@"Yes"])
  397. {
  398. sessionCount = [[[jobData objectAtIndex:i] objectForKey:@"sessionList"] count];
  399. while (j < sessionCount)
  400. {
  401. if ([[[[[jobData objectAtIndex:i] objectForKey:@"sessionList"] objectAtIndex:j] objectForKey:@"sessionActive"] isEqualTo:@"Yes"])
  402. {
  403. [[[[jobData objectAtIndex:i] objectForKey:@"sessionList"] objectAtIndex:j]
  404. setObject:[[[cuDateTime alloc] initWithCurrentDateAndTime] autorelease] forKey:@"endDateTime"];
  405. }
  406. j++;
  407. }
  408. [self computeJobTime:i];
  409. [jobTable reloadData];
  410. [sessionTable reloadData];
  411. }
  412. if ([[[jobData objectAtIndex:i] objectForKey:@"jobActive"] isEqualTo:@"Paused"])
  413. {
  414. sessionCount = [[[jobData objectAtIndex:i] objectForKey:@"sessionList"] count];
  415. while (j < sessionCount)
  416. {
  417. if ([[[[[jobData objectAtIndex:i] objectForKey:@"sessionList"] objectAtIndex:j] objectForKey:@"sessionActive"] isEqualTo:@"Paused"])
  418. {
  419. [[[[jobData objectAtIndex:i] objectForKey:@"sessionList"] objectAtIndex:j]
  420. setObject:[[[cuDateTime alloc] initWithCurrentDateAndTime] autorelease] forKey:@"pauseStop"];
  421. cuDateTime *tempStartTime = [[cuDateTime alloc] init];
  422. [tempStartTime setValues:[[[[jobData objectAtIndex:i] objectForKey:@"sessionList"] objectAtIndex:j]
  423. objectForKey:@"pauseStart"]];
  424. cuDateTime *tempEndTime = [[cuDateTime alloc] init];
  425. [tempEndTime setValues:[[[[jobData objectAtIndex:i] objectForKey:@"sessionList"] objectAtIndex:j]
  426. objectForKey:@"pauseStop"]];
  427. [[[[jobData objectAtIndex:i] objectForKey:@"sessionList"] objectAtIndex:j]
  428. setObject:[tempStartTime getTimeInterval:tempEndTime] forKey:@"tempPauseTime"];
  429. [tempStartTime release];
  430. [tempEndTime release];
  431. }
  432. j++;
  433. }
  434. [self computeJobTime:i];
  435. [jobTable reloadData];
  436. [sessionTable reloadData];
  437. }
  438. j = 0;
  439. i++;
  440. }
  441. [self updateMenuBarData];
  442. }
  443. - (void)updateMenuBarData
  444. {
  445. if ([jobTable selectedRow] != -1)
  446. {
  447. id tempMenuTime = [[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"jobTimeLogged"];
  448. if ([preferences displayForTable:CUPreferencesMenuDisplay column:CUPreferencesMenuDisplayTotalTime])
  449. {
  450. [menuTimeDisplay setTitle:[tempMenuTime getTimeStringFor:[preferences updateTimeEvery]]];
  451. }
  452. if ([preferences displayForTable:CUPreferencesMenuDisplay column:CUPreferencesMenuDisplayCharges])
  453. {
  454. NSNumber *rate = [[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"hourlyRate"];
  455. NSString *formatterString = [self formatterString];
  456. NSMutableString *chargeNumberString = [[[NSMutableString alloc] init] autorelease];
  457. [chargeNumberString setString:[[NSNumber numberWithDouble:[tempMenuTime calculateCharges:[rate doubleValue]
  458. format:formatterString]] stringValue]];
  459. [chargeNumberString setString:[self truncateChargeString:chargeNumberString]];
  460. NSMutableString *tempChargesString = [[[NSMutableString alloc] init] autorelease];
  461. [tempChargesString appendString:[preferences monetaryUnit]];
  462. [tempChargesString appendString:chargeNumberString];
  463. [menuChargeDisplay setTitle:tempChargesString];
  464. }
  465. int i = [menuJobList numberOfItems] - 1;
  466. while (i >= 0)
  467. {
  468. [[menuJobList itemAtIndex:i] setState:NSOffState];
  469. i--;
  470. }
  471. [[menuJobList itemAtIndex:[jobTable selectedRow]] setState:NSOnState];
  472. }
  473. else
  474. {
  475. [menuTimeDisplay setTitle:@""];
  476. [menuChargeDisplay setTitle:@""];
  477. int i = [menuJobList numberOfItems] - 1;
  478. while (i >= 0)
  479. {
  480. [[menuJobList itemAtIndex:i] setState:NSOffState];
  481. i--;
  482. }
  483. }
  484. }
  485. - (void)updateMenuBarJobList
  486. {
  487. int i = [menuJobList numberOfItems] - 1;
  488. while (i >= 0)
  489. {
  490. [menuJobList removeItemAtIndex:i];
  491. i--;
  492. }
  493. int j = [jobData count] - 1;
  494. while (j >= 0)
  495. {
  496. [self addJobToMenuList:[[jobData objectAtIndex:j] objectForKey:@"jobName"]];
  497. j--;
  498. }
  499. }
  500. - (void)updateMenuBarButtons
  501. {
  502. if ([jobTable selectedRow] == -1)
  503. {
  504. [menuStartStopButton setImage:menuStartStopGray];
  505. [menuPauseButton setImage:menuPauseNull];
  506. }
  507. else
  508. {
  509. if ([[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"jobActive"] isEqualTo:@"Yes"])
  510. {
  511. [menuStartStopButton setImage:menuStartStopRed];
  512. [menuPauseButton setImage:menuPauseNo];
  513. }
  514. else if ([[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"jobActive"] isEqualTo:@"No"])
  515. {
  516. [menuStartStopButton setImage:menuStartStopGreen];
  517. [menuPauseButton setImage:menuPauseNull];
  518. }
  519. else if ([[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"jobActive"] isEqualTo:@"Paused"])
  520. {
  521. [menuStartStopButton setImage:menuStartStopRed];
  522. [menuPauseButton setImage:menuPauseYes];
  523. }
  524. }
  525. }
  526. - (void)addJobToMenuList:(NSString *)jobName
  527. {
  528. NSMenuItem *tempMenuItem = [[NSMenuItem alloc] initWithTitle:jobName action:@selector(jobMenuListSelectionChanged:) keyEquivalent:@""];
  529. [tempMenuItem setTarget:self];
  530. [menuJobList insertItem:tempMenuItem atIndex:0];
  531. }
  532. - (void)jobMenuListSelectionChanged:(id)sender
  533. {
  534. if ([sender state] == NSOffState)
  535. {
  536. [sender setState:NSOnState];
  537. [jobTable selectRowIndexes:[NSIndexSet indexSetWithIndex:[menuJobList indexOfItem:sender]] byExtendingSelection:YES];
  538. }
  539. }
  540. - (void)saveLoop
  541. {
  542. saveTimer = 0;
  543. [dataHandler saveJobListToFile:jobData];
  544. }
  545. - (int)getHighestJobNumber
  546. {
  547. if ([jobData count] == 0) return 1;
  548. else
  549. {
  550. int testInt = 2;
  551. int i = 0;
  552. int count = [jobData count];
  553. while (i < count)
  554. {
  555. if ([[[jobData objectAtIndex:i] objectForKey:@"jobNumber"] intValue] >= testInt)
  556. testInt = [[[jobData objectAtIndex:i] objectForKey:@"jobNumber"] intValue] + 1;
  557. i++;
  558. }
  559. return testInt;
  560. }
  561. }
  562. - (int)getHighestSessionNumber:(int)whichJob
  563. {
  564. id sessionList = [[jobData objectAtIndex:whichJob] objectForKey:@"sessionList"];
  565. if ([sessionList count] == 0) return 1;
  566. else
  567. {
  568. int testInt = 2;
  569. int i = 0;
  570. int count = [sessionList count];
  571. while (i < count)
  572. {
  573. if ([[[sessionList objectAtIndex:i] objectForKey:@"sessionNumber"] intValue] >= testInt)
  574. testInt = [[[sessionList objectAtIndex:i] objectForKey:@"sessionNumber"] intValue] + 1;
  575. i++;
  576. }
  577. return testInt;
  578. }
  579. }
  580. - (NSString *)truncateChargeString:(NSString *)originalString
  581. {
  582. NSMutableString *tempString = [[[NSMutableString alloc] init] autorelease];
  583. [tempString setString:originalString];
  584. int i = 0;
  585. int count = [tempString length];
  586. int periodLocation = -1;
  587. while (i < count)
  588. {
  589. if ([tempString characterAtIndex:i] == '.') periodLocation = i;
  590. i++;
  591. }
  592. if (periodLocation == 0) [tempString insertString:@"0" atIndex:0];
  593. if (count - periodLocation > 2 && periodLocation != -1) [tempString deleteCharactersInRange:NSMakeRange(periodLocation + 3, count - periodLocation - 3)];
  594. if (count - periodLocation == 2 && periodLocation != -1) [tempString appendString:@"0"];
  595. return tempString;
  596. }
  597. //***TableView Methods***
  598. - (int)numberOfRowsInTableView:(NSTableView *)tableView
  599. {
  600. if (tableView == jobTable)
  601. return [jobData count];
  602. else if ([jobTable selectedRow] != -1)
  603. return [[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"] count];
  604. else
  605. return 0;
  606. }
  607. - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)rowIndex
  608. {
  609. id theRow;
  610. id theValue = nil;
  611. if (tableView == jobTable)
  612. {
  613. theRow = [jobData objectAtIndex:rowIndex];
  614. if ([[tableColumn identifier] isEqualTo:@"jobActive"])
  615. {
  616. if ([[theRow objectForKey:@"jobActive"] isEqualTo:@"No"]) theValue = tableInactive;
  617. else if ([[theRow objectForKey:@"jobActive"] isEqualTo:@"Yes"]) theValue = tableActive;
  618. else if ([[theRow objectForKey:@"jobActive"] isEqualTo:@"Paused"]) theValue = tablePaused;
  619. }
  620. else if ([[tableColumn identifier] isEqualTo:@"hourlyRate"])
  621. {
  622. NSMutableString *hourlyRateString = [[[NSMutableString alloc] init] autorelease];
  623. [hourlyRateString appendString:[preferences monetaryUnit]];
  624. [hourlyRateString appendString:[[[jobData objectAtIndex:rowIndex] objectForKey:@"hourlyRate"] stringValue]];
  625. [hourlyRateString appendString:[textHourSuffix stringValue]];
  626. theValue = hourlyRateString;
  627. }
  628. else if ([[tableColumn identifier] isEqualTo:@"jobTimeLogged"] || [[tableColumn identifier] isEqualTo:@"jobCharges"])
  629. {
  630. cuDateTime *tempTimeLogged = [[[cuDateTime alloc] init] autorelease];
  631. [tempTimeLogged setValues:[[jobData objectAtIndex:rowIndex] objectForKey:@"jobTimeLogged"]];
  632. if ([[tableColumn identifier] isEqualTo:@"jobTimeLogged"])
  633. {
  634. theValue = [tempTimeLogged getTimeStringFor:[preferences updateTimeEvery]];
  635. }
  636. else
  637. {
  638. NSNumber *rate = [[jobData objectAtIndex:rowIndex] objectForKey:@"hourlyRate"];
  639. NSString *formatterString = [self formatterString];
  640. NSMutableString *chargeNumberString = [[[NSMutableString alloc] init] autorelease];
  641. [chargeNumberString setString:[[NSNumber numberWithDouble:[tempTimeLogged calculateCharges:[rate doubleValue]
  642. format:formatterString]] stringValue]];
  643. [chargeNumberString setString:[self truncateChargeString:chargeNumberString]];
  644. NSMutableString *tempChargesString = [[[NSMutableString alloc] init] autorelease];
  645. [tempChargesString appendString:[preferences monetaryUnit]];
  646. [tempChargesString appendString:chargeNumberString];
  647. theValue = tempChargesString;
  648. }
  649. }
  650. else theValue = [theRow objectForKey:[tableColumn identifier]];
  651. }
  652. else if ([jobTable selectedRow] != -1)
  653. {
  654. if (rowIndex < [[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"] count]){
  655. theRow = [[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"] objectAtIndex:rowIndex];
  656. if ([[tableColumn identifier] isEqualTo:@"sessionActive"])
  657. {
  658. if ([[theRow objectForKey:@"sessionActive"] isEqualTo:@"No"]) theValue = tableInactive;
  659. else if ([[theRow objectForKey:@"sessionActive"] isEqualTo:@"Yes"]) theValue = tableActive;
  660. else if ([[theRow objectForKey:@"sessionActive"] isEqualTo:@"Paused"]) theValue = tablePaused;
  661. }
  662. else if ([[tableColumn identifier] isEqualTo:@"startDate"])
  663. {
  664. theValue = [[theRow objectForKey:@"startDateTime"] getDateString];
  665. }
  666. else if ([[tableColumn identifier] isEqualTo:@"startTime"])
  667. {
  668. if ([preferences is24HourClock]) theValue = [[theRow objectForKey:@"startDateTime"] getTimeString];
  669. else theValue = [[theRow objectForKey:@"startDateTime"] getTwelveHourTimeString];
  670. }
  671. else if ([[tableColumn identifier] isEqualTo:@"endDate"])
  672. {
  673. theValue = [[theRow objectForKey:@"endDateTime"] getDateString];
  674. }
  675. else if ([[tableColumn identifier] isEqualTo:@"endTime"])
  676. {
  677. if ([preferences is24HourClock]) theValue = [[theRow objectForKey:@"endDateTime"] getTimeString];
  678. else theValue = [[theRow objectForKey:@"endDateTime"] getTwelveHourTimeString];
  679. }
  680. else if ([[tableColumn identifier] isEqualTo:@"totalTime"] || [[tableColumn identifier] isEqualTo:@"sessionCharges"])
  681. {
  682. cuDateTime *tempInterval = [[[cuDateTime alloc] init] autorelease];
  683. [tempInterval setValues:[[theRow objectForKey:@"startDateTime"] getTimeInterval:[theRow objectForKey:@"endDateTime"]]];
  684. [tempInterval setValues:[tempInterval subtractInterval:[theRow objectForKey:@"pauseTime"]]];
  685. NSString *formatterString = [self formatterString];
  686. if ([[tableColumn identifier] isEqualTo:@"totalTime"])
  687. {
  688. if ([formatterString isEqualTo:@"second"]) theValue = [tempInterval getTimeString];
  689. else if ([formatterString isEqualTo:@"minute"]) theValue = [tempInterval getTimeString:NO];
  690. else theValue = [tempInterval getFormattedTimeString:formatterString];
  691. }
  692. else if ([[tableColumn identifier] isEqualTo:@"sessionCharges"])
  693. {
  694. NSNumber *rate = [[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"hourlyRate"];
  695. NSMutableString *chargeNumberString = [[[NSMutableString alloc] init] autorelease];
  696. [chargeNumberString setString:[[NSNumber numberWithDouble:[tempInterval calculateCharges:[rate doubleValue]
  697. format:formatterString]] stringValue]];
  698. [chargeNumberString setString:[self truncateChargeString:chargeNumberString]];
  699. NSMutableString *tempChargesString = [[[NSMutableString alloc] init] autorelease];
  700. [tempChargesString appendString:[preferences monetaryUnit]];
  701. [tempChargesString appendString:chargeNumberString];
  702. theValue = tempChargesString;
  703. }
  704. }
  705. else if ([[tableColumn identifier] isEqualTo:@"pauseTime"])
  706. {
  707. cuDateTime *tempPauseTime = [[[cuDateTime alloc] init] autorelease];
  708. [tempPauseTime setValues:[theRow objectForKey:@"pauseTime"]];
  709. [tempPauseTime setValues:[tempPauseTime addInterval:[theRow objectForKey:@"tempPauseTime"]]];
  710. theValue = [tempPauseTime getTimeString];
  711. }
  712. else theValue = [theRow objectForKey:[tableColumn identifier]];
  713. }}
  714. return theValue;
  715. }
  716. - (void)tableView:(NSTableView *)tableView mouseDownInHeaderOfTableColumn:(NSTableColumn *)tableColumn
  717. {
  718. if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_2)
  719. {
  720. if (tableView == jobTable)
  721. {
  722. NSSortDescriptor *newSorter = [[NSSortDescriptor alloc] initWithKey:[tableColumn identifier] ascending:lastJobSortAscending];
  723. NSMutableArray *sortDescriptors = [[NSMutableArray alloc] init];
  724. [sortDescriptors addObject:newSorter];
  725. [sortDescriptors addObject:lastJobSorter];
  726. [jobData setArray:[jobData sortedArrayUsingDescriptors:sortDescriptors]];
  727. lastJobSortAscending = !lastJobSortAscending;
  728. if (![[lastJobSorter key] isEqualTo:[tableColumn identifier]])
  729. lastJobSorter = [[NSSortDescriptor alloc] initWithKey:[tableColumn identifier] ascending:lastJobSortAscending];
  730. [jobTable reloadData];
  731. [sessionTable reloadData];
  732. [self updateMenuBarJobList];
  733. }
  734. if (tableView == sessionTable && [jobTable selectedRow] != -1)
  735. {
  736. NSSortDescriptor *newSorter = [[NSSortDescriptor alloc] initWithKey:[tableColumn identifier] ascending:lastJobSortAscending];
  737. NSMutableArray *sortDescriptors = [[NSMutableArray alloc] init];
  738. [sortDescriptors addObject:newSorter];
  739. [sortDescriptors addObject:lastSessionSorter];
  740. [[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"] setArray:[[[jobData objectAtIndex:[jobTable selectedRow]]
  741. objectForKey:@"sessionList"] sortedArrayUsingDescriptors:sortDescriptors]];
  742. lastSessionSortAscending = !lastSessionSortAscending;
  743. if (![[lastSessionSorter key] isEqualTo:[tableColumn identifier]])
  744. lastSessionSorter = [[NSSortDescriptor alloc] initWithKey:[tableColumn identifier] ascending:lastSessionSortAscending];
  745. [jobTable reloadData];
  746. [sessionTable reloadData];
  747. }
  748. }
  749. }
  750. - (void)tableViewSelectionDidChange:(NSNotification *)notification
  751. {
  752. if ([notification object] == jobTable)
  753. {
  754. if ([jobTable selectedRow] != -1)
  755. {
  756. [addSessionButton setEnabled:YES]; [deleteJobButton setEnabled:YES]; [editJobButton setEnabled:YES];
  757. if ([[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"jobActive"] isEqualTo:@"No"])
  758. {
  759. [pauseButton setImage:nil];
  760. [pauseButton setAlternateImage:nil];
  761. [startStopButton setImage:startStopGreen];
  762. [startStopButton setAlternateImage:startStopGreen];
  763. [self updateMenuBarButtons];
  764. [startStopField setStringValue:[textStartRecording stringValue]];
  765. }
  766. else if ([[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"jobActive"] isEqualTo:@"Yes"])
  767. {
  768. [pauseButton setImage:pauseNo];
  769. [pauseButton setAlternateImage:pauseNo];
  770. [startStopButton setImage:startStopRed];
  771. [startStopButton setAlternateImage:startStopRed];
  772. [self updateMenuBarButtons];
  773. [startStopField setStringValue:[textStopRecording stringValue]];
  774. }
  775. else if ([[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"jobActive"] isEqualTo:@"Paused"])
  776. {
  777. [startStopButton setImage:startStopRed];
  778. [startStopButton setAlternateImage:startStopRed];
  779. [pauseButton setImage:pauseYes];
  780. [pauseButton setAlternateImage:pauseYes];
  781. [self updateMenuBarButtons];
  782. [startStopField setStringValue:[textStopRecording stringValue]];
  783. }
  784. [self updateMenuBarData];
  785. }
  786. else
  787. {
  788. [addSessionButton setEnabled:NO]; [deleteJobButton setEnabled:NO]; [editJobButton setEnabled:NO];
  789. [startStopButton setImage:startStopGray];
  790. [startStopButton setAlternateImage:startStopGray];
  791. [pauseButton setImage:nil];
  792. [pauseButton setAlternateImage:nil];
  793. [self updateMenuBarButtons];
  794. [menuChargeDisplay setTitle:@""];
  795. [menuTimeDisplay setTitle:@""];
  796. int i = [menuJobList numberOfItems] - 1;
  797. while (i >= 0)
  798. {
  799. [[menuJobList itemAtIndex:i] setState:NSOffState];
  800. i--;
  801. }
  802. [startStopField setStringValue:@""];
  803. }
  804. [sessionTable reloadData];
  805. }
  806. else if ([notification object] == sessionTable)
  807. {
  808. if ([sessionTable selectedRow] == -1)
  809. {
  810. [deleteSessionButton setEnabled:NO]; [editSessionButton setEnabled:NO];
  811. }
  812. else
  813. {
  814. [deleteSessionButton setEnabled:YES]; [editSessionButton setEnabled:YES];
  815. }
  816. }
  817. }
  818. - (void)tableDoubleClick:(NSTableView *)tableView
  819. {
  820. if (tableView == jobTable) [self editJob];
  821. else [self editSession];
  822. }
  823. - (void)tableView:(NSTableView *)tableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)tableColumn row:(int)rowIndex
  824. {
  825. if (tableView == sessionTable)
  826. [[[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"] objectAtIndex:rowIndex] setObject:anObject forKey:@"sessionSummary"];
  827. }
  828. - (void)tableView:(NSTableView *)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn row:(int)row
  829. {
  830. if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_2)
  831. {
  832. if (![[tableColumn identifier] isEqualTo:@"jobActive"] && ![[tableColumn identifier] isEqualTo:@"sessionActive"])
  833. {
  834. [cell setDrawsBackground:YES];
  835. if (row % 2) [cell setBackgroundColor:[NSColor whiteColor]];
  836. else [cell setBackgroundColor:[NSColor colorWithCalibratedRed:0.9 green:0.9 blue:0.9 alpha:1.0]];
  837. [tableView setIntercellSpacing:NSMakeSize(0, 0)];
  838. }
  839. }
  840. }
  841. //***Buttons***
  842. //Main Window
  843. - (IBAction)startStopRecording:(id)sender
  844. {
  845. if ([jobTable selectedRow] != -1)
  846. {
  847. if ([[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"jobActive"] isEqualTo:@"No"])
  848. {
  849. [[jobData objectAtIndex:[jobTable selectedRow]] setObject:@"Yes" forKey:@"jobActive"];
  850. cuDateTime *newStart = [[[cuDateTime alloc] initWithCurrentDateAndTime] autorelease];
  851. cuDateTime *newEnd = [[[cuDateTime alloc] initWithCurrentDateAndTime] autorelease];
  852. [self createNewSession:newStart endDateTime:newEnd job:[jobTable selectedRow] active:YES];
  853. [startStopButton setImage:startStopRed];
  854. [startStopButton setAlternateImage:startStopRed];
  855. [pauseButton setImage:pauseNo];
  856. [pauseButton setAlternateImage:pauseNo];
  857. [self updateMenuBarButtons];
  858. [startStopField setStringValue:[textStopRecording stringValue]];
  859. [jobTable reloadData];
  860. [sessionTable reloadData];
  861. }
  862. else if ([[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"jobActive"] isEqualTo:@"Yes"] ||
  863. [[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"jobActive"] isEqualTo:@"Paused"])
  864. {
  865. [[jobData objectAtIndex:[jobTable selectedRow]] setObject:@"No" forKey:@"jobActive"];
  866. int count = [[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"] count];
  867. [[[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"] objectAtIndex:count - 1]
  868. setObject:@"No" forKey:@"sessionActive"];
  869. [startStopButton setImage:startStopGreen];
  870. [startStopButton setAlternateImage:startStopGreen];
  871. [pauseButton setImage:nil];
  872. [pauseButton setAlternateImage:nil];
  873. [self updateMenuBarButtons];
  874. [startStopField setStringValue:[textStartRecording stringValue]];
  875. cuDateTime *tempStart = [[[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"] objectAtIndex:count - 1] objectForKey:@"startDateTime"];
  876. cuDateTime *tempEnd = [[[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"] objectAtIndex:count - 1] objectForKey:@"endDateTime"];
  877. // TODO: Should this autoSaveTime and not autoDeleteSettings?
  878. if ([[tempStart getTimeInterval:tempEnd] getHour] < 1 && [[tempStart getTimeInterval:tempEnd] getMinute] < [preferences autoDeleteSettings])
  879. {
  880. [[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"] removeObjectAtIndex:count - 1];
  881. [self computeJobTime:[jobTable selectedRow]];
  882. [self updateMenuBarData];
  883. }
  884. [jobTable reloadData];
  885. [sessionTable reloadData];
  886. }
  887. }
  888. }
  889. - (IBAction)pauseUnpause:(id)sender;
  890. {
  891. if ([jobTable selectedRow] != -1 && ![[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"jobActive"] isEqualTo:@"No"])
  892. {
  893. int i = 0;
  894. int count = [[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"] count];
  895. if ([[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"jobActive"] isEqualTo:@"Yes"])
  896. {
  897. [[jobData objectAtIndex:[jobTable selectedRow]] setObject:@"Paused" forKey:@"jobActive"];
  898. while (i < count)
  899. {
  900. if ([[[[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"] objectAtIndex:i]
  901. objectForKey:@"sessionActive"] isEqualTo:@"Yes"])
  902. {
  903. [[[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"] objectAtIndex:i]
  904. setObject:@"Paused" forKey:@"sessionActive"];
  905. [[[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"] objectAtIndex:i]
  906. setObject:[[cuDateTime alloc] initWithCurrentDateAndTime] forKey:@"pauseStart"];
  907. [[[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"]
  908. objectAtIndex:i] setObject:[[[cuDateTime alloc] initWithCurrentDateAndTime] autorelease] forKey:@"pauseStop"];
  909. }
  910. i++;
  911. }
  912. [pauseButton setImage:pauseYes];
  913. [pauseButton setAlternateImage:pauseYes];
  914. [self updateMenuBarButtons];
  915. [jobTable reloadData];
  916. [sessionTable reloadData];
  917. }
  918. else if ([[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"jobActive"] isEqualTo:@"Paused"])
  919. {
  920. [[jobData objectAtIndex:[jobTable selectedRow]] setObject:@"Yes" forKey:@"jobActive"];
  921. while (i < count)
  922. {
  923. if ([[[[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"] objectAtIndex:i]
  924. objectForKey:@"sessionActive"] isEqualTo:@"Paused"])
  925. {
  926. [[[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"] objectAtIndex:i]
  927. setObject:@"Yes" forKey:@"sessionActive"];
  928. cuDateTime *tempInterval = [[cuDateTime alloc] init];
  929. [tempInterval setValues:[[[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"] objectAtIndex:i]
  930. objectForKey:@"pauseTime"]];
  931. cuDateTime *tempIntervalTwo = [[cuDateTime alloc] init];
  932. [tempIntervalTwo setValues:[[[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"] objectAtIndex:i]
  933. objectForKey:@"tempPauseTime"]];
  934. [[[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"]
  935. objectAtIndex:i] setObject:[[[cuDateTime alloc] init] autorelease] forKey:@"pauseStop"];
  936. [[[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"]
  937. objectAtIndex:i] setObject:[[[cuDateTime alloc] init] autorelease] forKey:@"pauseStart"];
  938. [[[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"] objectAtIndex:i]
  939. setObject:[tempIntervalTwo addInterval:tempInterval] forKey:@"pauseTime"];
  940. [tempInterval release];
  941. [tempIntervalTwo release];
  942. }
  943. i++;
  944. }
  945. [pauseButton setImage:pauseNo];
  946. [pauseButton setAlternateImage:pauseNo];
  947. [self updateMenuBarButtons];
  948. [jobTable reloadData];
  949. [sessionTable reloadData];
  950. }
  951. }
  952. }
  953. - (IBAction)addJobButton:(id)sender
  954. {
  955. [NSApp beginSheet:addJobPanel modalForWindow:mainWindow modalDelegate:self didEndSelector:NULL contextInfo:nil];
  956. }
  957. - (IBAction)deleteJobButton:(id)sender
  958. {
  959. if ([preferences askDeleteProject])
  960. {
  961. int i = NSRunAlertPanel([textDeleteJobShort stringValue], [textDeleteJobLong stringValue], @"Delete Project", @"Cancel", nil);
  962. if (i == NSOKButton)
  963. {
  964. [jobData removeObjectAtIndex:[jobTable selectedRow]];
  965. [jobTable reloadData];
  966. [sessionTable reloadData];
  967. [self updateMenuBarJobList];
  968. }
  969. }
  970. else
  971. {
  972. [jobData removeObjectAtIndex:[jobTable selectedRow]];
  973. [jobTable reloadData];
  974. [sessionTable reloadData];
  975. [self updateMenuBarJobList];
  976. }
  977. }
  978. - (IBAction)editJobButton:(id)sender
  979. {
  980. [self editJob];
  981. }
  982. - (void)editJob
  983. {
  984. [editJobJobName setStringValue:[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"jobName"]];
  985. [editJobClient setStringValue:[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"clientName"]];
  986. [editJobHourlyRate setStringValue:[[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"hourlyRate"] stringValue]];
  987. [NSApp beginSheet:editJobPanel modalForWindow:mainWindow modalDelegate:self didEndSelector:NULL contextInfo:nil];
  988. }
  989. //Drawer
  990. - (IBAction)addSessionButton:(id)sender
  991. {
  992. [NSApp beginSheet:addSessionPanel modalForWindow:mainWindow modalDelegate:self didEndSelector:NULL contextInfo:nil];
  993. }
  994. - (IBAction)deleteSessionButton:(id)sender
  995. {
  996. if ([preferences askDeleteSession])
  997. {
  998. int i = NSRunAlertPanel([textDeleteSessionShort stringValue], [textDeleteSessionLong stringValue], @"Delete Session", @"Cancel", nil);
  999. if (i == NSOKButton)
  1000. {
  1001. [[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"] removeObjectAtIndex:[sessionTable selectedRow]];
  1002. [self computeJobTime:[jobTable selectedRow]];
  1003. [jobTable reloadData];
  1004. [self updateMenuBarData];
  1005. [sessionTable reloadData];
  1006. }
  1007. }
  1008. else
  1009. {
  1010. [[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"] removeObjectAtIndex:[sessionTable selectedRow]];
  1011. [self computeJobTime:[jobTable selectedRow]];
  1012. [jobTable reloadData];
  1013. [self updateMenuBarData];
  1014. [sessionTable reloadData];
  1015. }
  1016. }
  1017. - (IBAction)editSessionButton:(id)sender
  1018. {
  1019. [self editSession];
  1020. }
  1021. - (void)editSession
  1022. {
  1023. [editSessionStartDate setStringValue:[[[[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"]
  1024. objectAtIndex:[sessionTable selectedRow]] objectForKey:@"startDateTime"] getDateString]];
  1025. [editSessionStartTime setStringValue:[[[[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"]
  1026. objectAtIndex:[sessionTable selectedRow]] objectForKey:@"startDateTime"] getTimeString]];
  1027. [editSessionEndDate setStringValue:[[[[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"]
  1028. objectAtIndex:[sessionTable selectedRow]] objectForKey:@"endDateTime"] getDateString]];
  1029. [editSessionEndTime setStringValue:[[[[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"]
  1030. objectAtIndex:[sessionTable selectedRow]] objectForKey:@"endDateTime"] getTimeString]];
  1031. [NSApp beginSheet:editSessionPanel modalForWindow:mainWindow modalDelegate:self didEndSelector:NULL contextInfo:nil];
  1032. }
  1033. //AddJobPanel
  1034. - (IBAction)addJobCancel:(id)sender
  1035. {
  1036. [addJobPanel orderOut:nil];
  1037. [NSApp endSheet:addJobPanel];
  1038. [addJobClient setStringValue:@""];
  1039. [addJobJobName setStringValue:@""];
  1040. [addJobHourlyRate setStringValue:@""]; // TODO: we could set this based on some default $(cstuart 2007-07-03)
  1041. }
  1042. - (IBAction)addJobSave:(id)sender
  1043. {
  1044. NSMutableString *jobName = [[NSMutableString alloc] init];
  1045. NSMutableString *clientName = [[NSMutableString alloc] init];
  1046. [jobName setString:[addJobJobName stringValue]];
  1047. [clientName setString:[addJobClient stringValue]];
  1048. int i = [jobName length] - 1;
  1049. while (i > 0)
  1050. {
  1051. if ([jobName characterAtIndex:i] == '\n' || [jobName characterAtIndex:i] == '\t' || [jobName characterAtIndex:i] == '\\')
  1052. [jobName deleteCharactersInRange:NSMakeRange(i, 1)];
  1053. i--;
  1054. }
  1055. i = [clientName length] - 1;
  1056. while (i > 0)
  1057. {
  1058. if ([clientName characterAtIndex:i] == '\n' || [clientName characterAtIndex:i] == '\t' || [clientName characterAtIndex:i] == '\\')
  1059. [clientName deleteCharactersInRange:NSMakeRange(i, 1)];
  1060. i--;
  1061. }
  1062. [self createNewJob:jobName client:clientName rate:[addJobHourlyRate doubleValue]];
  1063. [jobTable reloadData];
  1064. [self updateMenuBarJobList];
  1065. [addJobPanel orderOut:nil];
  1066. [NSApp endSheet:addJobPanel];
  1067. [addJobClient setStringValue:@""];
  1068. [addJobJobName setStringValue:@""];
  1069. [addJobHourlyRate setStringValue:@""];
  1070. }
  1071. //EditJobPanel
  1072. - (IBAction)editJobCancel:(id)sender
  1073. {
  1074. [editJobPanel orderOut:nil];
  1075. [NSApp endSheet:editJobPanel];
  1076. [editJobClient setStringValue:@""];
  1077. [editJobJobName setStringValue:@""];
  1078. [editJobHourlyRate setStringValue:@""];
  1079. }
  1080. - (IBAction)editJobSave:(id)sender
  1081. {
  1082. if ([[editJobHourlyRate stringValue] length] != 0)
  1083. {
  1084. NSMutableString *jobName = [[NSMutableString alloc] init];
  1085. NSMutableString *clientName = [[NSMutableString alloc] init];
  1086. [jobName setString:[editJobJobName stringValue]];
  1087. [clientName setString:[editJobClient stringValue]];
  1088. int i = [jobName length] - 1;
  1089. while (i > 0)
  1090. {
  1091. if ([jobName characterAtIndex:i] == '\n' || [jobName characterAtIndex:i] == '\t' || [jobName characterAtIndex:i] == '\\')
  1092. [jobName deleteCharactersInRange:NSMakeRange(i, 1)];
  1093. i--;
  1094. }
  1095. i = [clientName length] - 1;
  1096. while (i > 0)
  1097. {
  1098. if ([clientName characterAtIndex:i] == '\n' || [clientName characterAtIndex:i] == '\t' || [clientName characterAtIndex:i] == '\\')
  1099. [clientName deleteCharactersInRange:NSMakeRange(i, 1)];
  1100. i--;
  1101. }
  1102. [[jobData objectAtIndex:[jobTable selectedRow]] setObject:jobName forKey:@"jobName"];
  1103. [[jobData objectAtIndex:[jobTable selectedRow]] setObject:clientName forKey:@"clientName"];
  1104. [[jobData objectAtIndex:[jobTable selectedRow]] setObject:[NSNumber numberWithDouble:[editJobHourlyRate doubleValue]] forKey:@"hourlyRate"];
  1105. [self computeJobTime:[jobTable selectedRow]];
  1106. [jobTable reloadData];
  1107. [sessionTable reloadData];
  1108. [self updateMenuBarJobList];
  1109. [editJobPanel orderOut:nil];
  1110. [NSApp endSheet:editJobPanel];
  1111. [editJobClient setStringValue:@""];
  1112. [editJobJobName setStringValue:@""];
  1113. [editJobHourlyRate setStringValue:@""];
  1114. }
  1115. else {NSBeep(); [editJobHourlyRate selectText:self];}
  1116. }
  1117. //AddSessionPanel
  1118. - (IBAction)addSessionCancel:(id)sender
  1119. {
  1120. [addSessionPanel orderOut:nil];
  1121. [NSApp endSheet:addSessionPanel];
  1122. [addSessionEndDate setStringValue:@""];
  1123. [addSessionEndTime setStringValue:@""];
  1124. [addSessionStartDate setStringValue:@""];
  1125. [addSessionStartTime setStringValue:@""];
  1126. }
  1127. - (IBAction)addSessionSave:(id)sender
  1128. {
  1129. int startTimeFormat = 0;
  1130. int endTimeFormat = 0;
  1131. NSCalendarDate *theDate = [NSCalendarDate calendarDate];
  1132. NSCalendarDate *tomorrowsDate = [NSCalendarDate calendarDate];
  1133. NSCalendarDate *yesterdaysDate = [NSCalendarDate calendarDate];
  1134. tomorrowsDate = [tomorrowsDate dateByAddingYears:0 months:0 days:1 hours:0 minutes:0 seconds:0];
  1135. yesterdaysDate = [yesterdaysDate dateByAddingYears:0 months:0 days:-1 hours:0 minutes:0 seconds:0];
  1136. if ([[[addSessionStartDate stringValue] lowercaseString] isEqualTo:@"today"])
  1137. {
  1138. NSMutableString *builtStartDate = [[[NSMutableString alloc] init] autorelease];
  1139. [builtStartDate appendString:[[NSNumber numberWithInt:[theDate monthOfYear]] stringValue]];
  1140. [builtStartDate appendString:@"/"];
  1141. [builtStartDate appendString:[[NSNumber numberWithInt:[theDate dayOfMonth]] stringValue]];
  1142. [builtStartDate appendString:@"/"];
  1143. [builtStartDate appendString:[[NSNumber numberWithInt:[theDate yearOfCommonEra]] stringValue]];
  1144. [addSessionStartDate setStringValue:builtStartDate];
  1145. }
  1146. if ([[[addSessionEndDate stringValue] lowercaseString] isEqualTo:@"today"])
  1147. {
  1148. NSMutableString *builtEndDate = [[[NSMutableString alloc] init] autorelease];
  1149. [builtEndDate appendString:[[NSNumber numberWithInt:[theDate monthOfYear]] stringValue]];
  1150. [builtEndDate appendString:@"/"];
  1151. [builtEndDate appendString:[[NSNumber numberWithInt:[theDate dayOfMonth]] stringValue]];
  1152. [builtEndDate appendString:@"/"];
  1153. [builtEndDate appendString:[[NSNumber numberWithInt:[theDate yearOfCommonEra]] stringValue]];
  1154. [addSessionEndDate setStringValue:builtEndDate];
  1155. }
  1156. if ([[[addSessionStartDate stringValue] lowercaseString] isEqualTo:@"yesterday"])
  1157. {
  1158. NSMutableString *builtStartDate = [[[NSMutableString alloc] init] autorelease];
  1159. [builtStartDate appendString:[[NSNumber numberWithInt:[yesterdaysDate monthOfYear]] stringValue]];
  1160. [builtStartDate appendString:@"/"];
  1161. [builtStartDate appendString:[[NSNumber numberWithInt:[yesterdaysDate dayOfMonth]] stringValue]];
  1162. [builtStartDate appendString:@"/"];
  1163. [builtStartDate appendString:[[NSNumber numberWithInt:[yesterdaysDate yearOfCommonEra]] stringValue]];
  1164. [addSessionStartDate setStringValue:builtStartDate];
  1165. }
  1166. if ([[[addSessionEndDate stringValue] lowercaseString] isEqualTo:@"yesterday"])
  1167. {
  1168. NSMutableString *builtEndDate = [[[NSMutableString alloc] init] autorelease];
  1169. [builtEndDate appendString:[[NSNumber numberWithInt:[yesterdaysDate monthOfYear]] stringValue]];
  1170. [builtEndDate appendString:@"/"];
  1171. [builtEndDate appendString:[[NSNumber numberWithInt:[yesterdaysDate dayOfMonth]] stringValue]];
  1172. [builtEndDate appendString:@"/"];
  1173. [builtEndDate appendString:[[NSNumber numberWithInt:[yesterdaysDate yearOfCommonEra]] stringValue]];
  1174. [addSessionEndDate setStringValue:builtEndDate];
  1175. }
  1176. if ([[[addSessionStartDate stringValue] lowercaseString] isEqualTo:@"tomorrow"])
  1177. {
  1178. NSMutableString *builtStartDate = [[[NSMutableString alloc] init] autorelease];
  1179. [builtStartDate appendString:[[NSNumber numberWithInt:[tomorrowsDate monthOfYear]] stringValue]];
  1180. [builtStartDate appendString:@"/"];
  1181. [builtStartDate appendString:[[NSNumber numberWithInt:[tomorrowsDate dayOfMonth]] stringValue]];
  1182. [builtStartDate appendString:@"/"];
  1183. [builtStartDate appendString:[[NSNumber numberWithInt:[tomorrowsDate yearOfCommonEra]] stringValue]];
  1184. [addSessionStartDate setStringValue:builtStartDate];
  1185. }
  1186. if ([[[addSessionEndDate stringValue] lowercaseString] isEqualTo:@"tomorrow"])
  1187. {
  1188. NSMutableString *builtEndDate = [[[NSMutableString alloc] init] autorelease];
  1189. [builtEndDate appendString:[[NSNumber numberWithInt:[tomorrowsDate monthOfYear]] stringValue]];
  1190. [builtEndDate appendString:@"/"];
  1191. [builtEndDate appendString:[[NSNumber numberWithInt:[tomorrowsDate dayOfMonth]] stringValue]];
  1192. [builtEndDate appendString:@"/"];
  1193. [builtEndDate appendString:[[NSNumber numberWithInt:[tomorrowsDate yearOfCommonEra]] stringValue]];
  1194. [addSessionEndDate setStringValue:builtEndDate];
  1195. }
  1196. if ([[[addSessionStartTime stringValue] lowercaseString] isEqualTo:@"now"])
  1197. [addSessionStartTime setStringValue:[[[[cuDateTime alloc] initWithCurrentDateAndTime] autorelease] getTimeString]];
  1198. if ([[[addSessionEndTime stringValue] lowercaseString] isEqualTo:@"now"])
  1199. [addSessionEndTime setStringValue:[[[[cuDateTime alloc] initWithCurrentDateAndTime] autorelease] getTimeString]];
  1200. if ([cuDateTime checkStringForTime:[addSessionStartTime stringValue]]) startTimeFormat = 1;
  1201. if ([cuDateTime checkStringForTime:[addSessionEndTime stringValue]]) endTimeFormat = 1;
  1202. if ([cuDateTime checkStringForTwelveHourTime:[addSessionStartTime stringValue]]) startTimeFormat = 2;
  1203. if ([cuDateTime checkStringForTwelveHourTime:[addSessionEndTime stringValue]]) endTimeFormat = 2;
  1204. if ([cuDateTime checkStringForTimeNoSeconds:[addSessionStartTime stringValue]]) startTimeFormat = 3;
  1205. if ([cuDateTime checkStringForTimeNoSeconds:[addSessionEndTime stringValue]]) endTimeFormat = 3;
  1206. if ([cuDateTime checkStringForTwelveHourTimeNoSeconds:[addSessionStartTime stringValue]]) startTimeFormat = 4;
  1207. if ([cuDateTime checkStringForTwelveHourTimeNoSeconds:[addSessionEndTime stringValue]]) endTimeFormat = 4;
  1208. if ([cuDateTime checkStringForDate:[addSessionStartDate stringValue]])
  1209. {
  1210. if (startTimeFormat != 0)
  1211. {
  1212. if ([cuDateTime checkStringForDate:[addSessionEndDate stringValue]])
  1213. {
  1214. if (endTimeFormat != 0)
  1215. {
  1216. cuDateTime *tempEndDateTime = [[cuDateTime alloc] initWithStrings:[addSessionEndDate stringValue] time:[addSessionEndTime stringValue]
  1217. timeFormat:endTimeFormat];
  1218. cuDateTime *tempStartDateTime = [[cuDateTime alloc] initWithStrings:[addSessionStartDate stringValue] time:[addSessionStartTime stringValue]
  1219. timeFormat:startTimeFormat];
  1220. if ([tempStartDateTime compare:tempEndDateTime] == NSOrderedDescending)
  1221. {
  1222. [self createNewSession:tempStartDateTime endDateTime:tempEndDateTime job:[jobTable selectedRow] active:NO];
  1223. [self computeJobTime:[jobTable selectedRow]];
  1224. [jobTable reloadData];
  1225. [sessionTable reloadData];
  1226. [addSessionPanel orderOut:nil];
  1227. [NSApp endSheet:addSessionPanel];
  1228. [addSessionEndDate setStringValue:@""];
  1229. [addSessionEndTime setStringValue:@""];
  1230. [addSessionStartDate setStringValue:@""];
  1231. [addSessionStartTime setStringValue:@""];
  1232. }
  1233. else NSRunAlertPanel([textBah stringValue], [textEndLater stringValue], @"OK", nil, nil);
  1234. }
  1235. else {NSBeep(); [addSessionEndTime selectText:self];}
  1236. }
  1237. else {NSBeep(); [addSessionEndDate selectText:self];}
  1238. }
  1239. else {NSBeep(); [addSessionStartTime selectText:self];}
  1240. }
  1241. else {NSBeep(); [addSessionStartDate selectText:self];}
  1242. }
  1243. //EditSessionPanel
  1244. - (IBAction)editSessionCancel:(id)sender
  1245. {
  1246. [editSessionPanel orderOut:nil];
  1247. [NSApp endSheet:editSessionPanel];
  1248. [editSessionEndDate setStringValue:@""];
  1249. [editSessionEndTime setStringValue:@""];
  1250. [editSessionStartDate setStringValue:@""];
  1251. [editSessionStartTime setStringValue:@""];
  1252. }
  1253. - (IBAction)editSessionSave:(id)sender
  1254. {
  1255. int startTimeFormat = 0;
  1256. int endTimeFormat = 0;
  1257. if ([cuDateTime checkStringForTime:[editSessionStartTime stringValue]]) startTimeFormat = 1;
  1258. if ([cuDateTime checkStringForTime:[editSessionEndTime stringValue]]) endTimeFormat = 1;
  1259. if ([cuDateTime checkStringForTwelveHourTime:[editSessionStartTime stringValue]]) startTimeFormat = 2;
  1260. if ([cuDateTime checkStringForTwelveHourTime:[editSessionEndTime stringValue]]) endTimeFormat = 2;
  1261. if ([cuDateTime checkStringForTimeNoSeconds:[editSessionStartTime stringValue]]) startTimeFormat = 3;
  1262. if ([cuDateTime checkStringForTimeNoSeconds:[editSessionEndTime stringValue]]) endTimeFormat = 3;
  1263. if ([cuDateTime checkStringForTwelveHourTimeNoSeconds:[editSessionStartTime stringValue]]) startTimeFormat = 4;
  1264. if ([cuDateTime checkStringForTwelveHourTimeNoSeconds:[editSessionEndTime stringValue]]) endTimeFormat = 4;
  1265. NSCalendarDate *theDate = [NSCalendarDate calendarDate];
  1266. NSCalendarDate *tomorrowsDate = [NSCalendarDate calendarDate];
  1267. NSCalendarDate *yesterdaysDate = [NSCalendarDate calendarDate];
  1268. tomorrowsDate = [tomorrowsDate dateByAddingYears:0 months:0 days:1 hours:0 minutes:0 seconds:0];
  1269. yesterdaysDate = [yesterdaysDate dateByAddingYears:0 months:0 days:-1 hours:0 minutes:0 seconds:0];
  1270. if ([[[editSessionStartDate stringValue] lowercaseString] isEqualTo:@"today"])
  1271. {
  1272. NSMutableString *builtStartDate = [[[NSMutableString alloc] init] autorelease];
  1273. [builtStartDate appendString:[[NSNumber numberWithInt:[theDate monthOfYear]] stringValue]];
  1274. [builtStartDate appendString:@"/"];
  1275. [builtStartDate appendString:[[NSNumber numberWithInt:[theDate dayOfMonth]] stringValue]];
  1276. [builtStartDate appendString:@"/"];
  1277. [builtStartDate appendString:[[NSNumber numberWithInt:[theDate yearOfCommonEra]] stringValue]];
  1278. [editSessionStartDate setStringValue:builtStartDate];
  1279. }
  1280. if ([[[editSessionEndDate stringValue] lowercaseString] isEqualTo:@"today"])
  1281. {
  1282. NSMutableString *builtEndDate = [[[NSMutableString alloc] init] autorelease];
  1283. [builtEndDate appendString:[[NSNumber numberWithInt:[theDate monthOfYear]] stringValue]];
  1284. [builtEndDate appendString:@"/"];
  1285. [builtEndDate appendString:[[NSNumber numberWithInt:[theDate dayOfMonth]] stringValue]];
  1286. [builtEndDate appendString:@"/"];
  1287. [builtEndDate appendString:[[NSNumber numberWithInt:[theDate yearOfCommonEra]] stringValue]];
  1288. [editSessionEndDate setStringValue:builtEndDate];
  1289. }
  1290. if ([[[editSessionStartDate stringValue] lowercaseString] isEqualTo:@"yesterday"])
  1291. {
  1292. NSMutableString *builtStartDate = [[[NSMutableString alloc] init] autorelease];
  1293. [builtStartDate appendString:[[NSNumber numberWithInt:[yesterdaysDate monthOfYear]] stringValue]];
  1294. [builtStartDate appendString:@"/"];
  1295. [builtStartDate appendString:[[NSNumber numberWithInt:[yesterdaysDate dayOfMonth]] stringValue]];
  1296. [builtStartDate appendString:@"/"];
  1297. [builtStartDate appendString:[[NSNumber numberWithInt:[yesterdaysDate yearOfCommonEra]] stringValue]];
  1298. [editSessionStartDate setStringValue:builtStartDate];
  1299. }
  1300. if ([[[editSessionEndDate stringValue] lowercaseString] isEqualTo:@"yesterday"])
  1301. {
  1302. NSMutableString *builtEndDate = [[[NSMutableString alloc] init] autorelease];
  1303. [builtEndDate appendString:[[NSNumber numberWithInt:[yesterdaysDate monthOfYear]] stringValue]];
  1304. [builtEndDate appendString:@"/"];
  1305. [builtEndDate appendString:[[NSNumber numberWithInt:[yesterdaysDate dayOfMonth]] stringValue]];
  1306. [builtEndDate appendString:@"/"];
  1307. [builtEndDate appendString:[[NSNumber numberWithInt:[yesterdaysDate yearOfCommonEra]] stringValue]];
  1308. [editSessionEndDate setStringValue:builtEndDate];
  1309. }
  1310. if ([[[editSessionStartDate stringValue] lowercaseString] isEqualTo:@"tomorrow"])
  1311. {
  1312. NSMutableString *builtStartDate = [[[NSMutableString alloc] init] autorelease];
  1313. [builtStartDate appendString:[[NSNumber numberWithInt:[tomorrowsDate monthOfYear]] stringValue]];
  1314. [builtStartDate appendString:@"/"];
  1315. [builtStartDate appendString:[[NSNumber numberWithInt:[tomorrowsDate dayOfMonth]] stringValue]];
  1316. [builtStartDate appendString:@"/"];
  1317. [builtStartDate appendString:[[NSNumber numberWithInt:[tomorrowsDate yearOfCommonEra]] stringValue]];
  1318. [editSessionStartDate setStringValue:builtStartDate];
  1319. }
  1320. if ([[[editSessionEndDate stringValue] lowercaseString] isEqualTo:@"tomorrow"])
  1321. {
  1322. NSMutableString *builtEndDate = [[[NSMutableString alloc] init] autorelease];
  1323. [builtEndDate appendString:[[NSNumber numberWithInt:[tomorrowsDate monthOfYear]] stringValue]];
  1324. [builtEndDate appendString:@"/"];
  1325. [builtEndDate appendString:[[NSNumber numberWithInt:[tomorrowsDate dayOfMonth]] stringValue]];
  1326. [builtEndDate appendString:@"/"];
  1327. [builtEndDate appendString:[[NSNumber numberWithInt:[tomorrowsDate yearOfCommonEra]] stringValue]];
  1328. [editSessionEndDate setStringValue:builtEndDate];
  1329. }
  1330. if ([[[editSessionStartTime stringValue] lowercaseString] isEqualTo:@"now"])
  1331. [editSessionStartTime setStringValue:[[[[cuDateTime alloc] initWithCurrentDateAndTime] autorelease] getTimeString]];
  1332. if ([[[editSessionEndTime stringValue] lowercaseString] isEqualTo:@"now"])
  1333. [editSessionEndTime setStringValue:[[[[cuDateTime alloc] initWithCurrentDateAndTime] autorelease] getTimeString]];
  1334. if ([cuDateTime checkStringForDate:[editSessionStartDate stringValue]])
  1335. {
  1336. if (startTimeFormat != 0)
  1337. {
  1338. if ([cuDateTime checkStringForDate:[editSessionEndDate stringValue]])
  1339. {
  1340. if (endTimeFormat != 0)
  1341. {
  1342. cuDateTime *tempStartDateTime = [[cuDateTime alloc] initWithStrings:[editSessionStartDate stringValue]
  1343. time:[editSessionStartTime stringValue] timeFormat:startTimeFormat];
  1344. cuDateTime *tempEndDateTime = [[cuDateTime alloc] initWithStrings:[editSessionEndDate stringValue]
  1345. time:[editSessionEndTime stringValue] timeFormat:endTimeFormat];
  1346. if ([tempStartDateTime compare:tempEndDateTime] == NSOrderedDescending)
  1347. {
  1348. [[[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"] objectAtIndex:[sessionTable selectedRow]]
  1349. setObject:tempStartDateTime forKey:@"startDateTime"];
  1350. [[[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"sessionList"] objectAtIndex:[sessionTable selectedRow]]
  1351. setObject:tempEndDateTime forKey:@"endDateTime"];
  1352. [self computeJobTime:[jobTable selectedRow]];
  1353. [jobTable reloadData];
  1354. [sessionTable reloadData];
  1355. [editSessionPanel orderOut:nil];
  1356. [NSApp endSheet:editSessionPanel];
  1357. [editSessionEndDate setStringValue:@""];
  1358. [editSessionEndTime setStringValue:@""];
  1359. [editSessionStartDate setStringValue:@""];
  1360. [editSessionStartTime setStringValue:@""];
  1361. }
  1362. else NSRunAlertPanel([textBah stringValue], [textEndLater stringValue], @"OK", nil, nil);
  1363. }
  1364. else {NSBeep(); [editSessionEndTime selectText:self];}
  1365. }
  1366. else {NSBeep(); [editSessionEndDate selectText:self];}
  1367. }
  1368. else {NSBeep(); [editSessionStartTime selectText:self];}
  1369. }
  1370. else {NSBeep(); [editSessionStartDate selectText:self];}
  1371. }
  1372. //***MenuItems***
  1373. - (IBAction)menuPauseAllJobs:(id)sender
  1374. {
  1375. int i = 0;
  1376. int j = 0;
  1377. int sessionCount = 0;
  1378. int count = [jobData count];
  1379. while (i < count)
  1380. {
  1381. if ([[[jobData objectAtIndex:i] objectForKey:@"jobActive"] isEqualTo:@"Yes"])
  1382. {
  1383. [[jobData objectAtIndex:i] setObject:@"Paused" forKey:@"jobActive"];
  1384. sessionCount = [[[jobData objectAtIndex:i] objectForKey:@"sessionList"] count];
  1385. while (j < sessionCount)
  1386. {
  1387. if ([[[[[jobData objectAtIndex:i] objectForKey:@"sessionList"] objectAtIndex:j] objectForKey:@"sessionActive"] isEqualTo:@"Yes"])
  1388. {
  1389. [[[[jobData objectAtIndex:i] objectForKey:@"sessionList"] objectAtIndex:j] setObject:@"Paused" forKey:@"sessionActive"];
  1390. [[[[jobData objectAtIndex:i]objectForKey:@"sessionList"] objectAtIndex:j]
  1391. setObject:[[cuDateTime alloc] initWithCurrentDateAndTime] forKey:@"pauseStart"];
  1392. [[[[jobData objectAtIndex:i]objectForKey:@"sessionList"] objectAtIndex:j]
  1393. setObject:[[cuDateTime alloc] initWithCurrentDateAndTime] forKey:@"pauseStop"];
  1394. }
  1395. j++;
  1396. }
  1397. }
  1398. i++;
  1399. j = 0;
  1400. }
  1401. if ([jobTable selectedRow] != -1)
  1402. {
  1403. if ([[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"jobActive"] isEqualTo:@"Paused"])
  1404. {
  1405. [pauseButton setImage:pauseYes];
  1406. [pauseButton setAlternateImage:pauseYes];
  1407. [startStopButton setImage:startStopRed];
  1408. [startStopButton setAlternateImage:startStopRed];
  1409. }
  1410. }
  1411. [jobTable reloadData];
  1412. [sessionTable reloadData];
  1413. }
  1414. - (IBAction)menuAddData:(id)sender
  1415. {
  1416. NSMutableArray *tempData = [[NSMutableArray alloc] init];
  1417. [tempData setArray:[dataHandler importData:jobData text:[textSelectFile stringValue]]];
  1418. [jobData setArray:tempData];
  1419. int i = 0;
  1420. int count = [jobData count];
  1421. while (i < count)
  1422. {
  1423. [self computeJobTime:i];
  1424. i++;
  1425. }
  1426. [self updateMenuBarJobList];
  1427. [jobTable reloadData];
  1428. [sessionTable reloadData];
  1429. }
  1430. - (IBAction)menuBlatantAd:(id)sender
  1431. {
  1432. NSWorkspace *workSpace = [NSWorkspace sharedWorkspace];
  1433. [workSpace openURL:[NSURL URLWithString:@"mailto:khronos@enure.net?subject=Suggestion"]];
  1434. }
  1435. - (IBAction)menuDisplayHelp:(id)sender
  1436. {
  1437. NSWorkspace *workSpace = [NSWorkspace sharedWorkspace];
  1438. [workSpace openFile:@"/Library/Application Support/KhronosHelp/index.html" withApplication:@"Safari"];
  1439. }
  1440. - (IBAction)menuDonate:(id)sender // FIXME $(cstuart 2007-07-03)
  1441. {
  1442. NSWorkspace *workSpace = [NSWorkspace sharedWorkspace];
  1443. [workSpace openURL:[NSURL URLWithString:@"http://khronos.enure.net/"]];
  1444. }
  1445. - (IBAction)menuExport:(id)sender
  1446. {
  1447. [self saveLoop];
  1448. [dataHandler exportData:jobData text:[textExportTo stringValue]];
  1449. }
  1450. - (IBAction)menuOpenWindow:(id)sender
  1451. {
  1452. [mainWindow makeKeyAndOrderFront:nil];
  1453. }
  1454. - (IBAction)showPagePanel:(id)sender
  1455. {
  1456. printInfo = [NSPrintInfo sharedPrintInfo];
  1457. NSPageLayout *pageLayout = [NSPageLayout pageLayout];
  1458. [pageLayout runModalWithPrintInfo:(NSPrintInfo *)printInfo];
  1459. }
  1460. - (IBAction)menuPrintInvoice:(id)sender
  1461. {
  1462. if ([jobTable selectedRow] != -1)
  1463. {
  1464. [self buildPrintTable];
  1465. [self updatePrintWindowFields];
  1466. NSPrintOperation *printOperation;
  1467. printOperation = [NSPrintOperation printOperationWithView:[printWindow contentView] printInfo:printInfo];
  1468. [printOperation setShowPanels:YES];
  1469. [printOperation runOperation];
  1470. }
  1471. else
  1472. {
  1473. NSRunAlertPanel([textBah stringValue], [textSelectJob stringValue], @"OK", nil, nil);
  1474. }
  1475. }
  1476. - (IBAction)menuHTML:(id)sender
  1477. {
  1478. /* FIXME: Disabling HTML output till we find a better way. (gdey)
  1479. if ([jobTable selectedRow] != -1)
  1480. {
  1481. NSSavePanel *savePanel = [NSSavePanel savePanel];
  1482. [savePanel setTitle:[textExportTo stringValue]];
  1483. int i = [savePanel runModal];
  1484. if (i == NSOKButton)
  1485. {
  1486. NSMutableString *compiledString = [[[NSMutableString alloc] init] autorelease];
  1487. cuDateTime *tempTimeLogged = [[[cuDateTime alloc] init] autorelease];
  1488. [tempTimeLogged setValues:[[jobData objectAtIndex:[jobTable selectedRow]] objectForKey:@"jobTimeLogged"]];
  1489. NSMutableString *dataPath = [[[NSMutableString alloc] init] autorelease];
  1490. [dataPath setString:[savePanel filename]];
  1491. [compiledString setString:[self generateHTMLForJob:[jobTable selectedRow]]];
  1492. [dataPath appendString:@".html"];
  1493. [compiledString writeToFile:dataPath atomically:NO];
  1494. }
  1495. }
  1496. else NSRunAlertPanel([textBah stringValue], [textSelectJob stringValue], @"OK", nil, nil);
  1497. */
  1498. }
  1499. - (IBAction)menuHTMLAll:(id)sender
  1500. {
  1501. /* Disabling HTML Output till I find a better way. (gdey)
  1502. NSSavePanel *savePanel = [NSSavePanel savePanel];
  1503. [savePanel setTitle:[textExportTo stringValue]];
  1504. int i = [savePanel runModal];
  1505. if (i == NSOKButton)
  1506. {
  1507. NSMutableString *dataPath = [[[NSMutableString alloc] init] autorelease];
  1508. [dataPath setString:[savePanel filename]];
  1509. NSFileManager *fileManager = [NSFileManager defaultManager];
  1510. [fileManager createDirectoryAtPath:dataPath attributes:nil];
  1511. NSMutableString *fileToSave = [[[NSMutableString alloc] init] autorelease];
  1512. int i = 0;
  1513. int count = [jobData count];
  1514. while (i < count)
  1515. {
  1516. [fileToSave setString:dataPath];
  1517. [fileToSave appendString:@"/"];
  1518. [fileToSave appendString:[[[jobData objectAtIndex:i] objectForKey:@"jobNumber"] stringValue]];
  1519. [fileToSave appendString:@".html"];
  1520. [[self generateHTMLForJob:i] writeToFile:fileToSave atomically:NO];
  1521. i++;
  1522. }
  1523. [dataPath appendString:@"/"];
  1524. [dataPath appendString:@"index.html"];
  1525. [[self generateIndexHTML] writeToFile:dataPath atomically:NO];
  1526. }
  1527. */
  1528. }
  1529. - (NSString *)generateIndexHTML
  1530. {
  1531. /* FIXME: Use Webkit to generate HTML or something else. (gdey)
  1532. NSMutableString *compiledString = [[[NSMutableString alloc] init] autorelease];
  1533. [compiledString appendString:@"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"];
  1534. [compiledString appendString:@"\n\n"];
  1535. [compiledString appendString:@"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">"];
  1536. [compiledString appendString:@"\n\n"];
  1537. [compiledString appendString:@"<head>"];
  1538. [compiledString appendString:@"\n\n"];
  1539. [compiledString appendString:@"<title>"];
  1540. [compiledString appendString:[preferences invoiceIndexTitle]];
  1541. [compiledString appendString:@"</title>"];
  1542. [compiledString appendString:@"\n\n"];
  1543. [compiledString appendString:@"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />"];
  1544. [compiledString appendString:@"\n\n"];
  1545. [compiledString appendString:@"<style type=\"text/css\" media=\"all\">\n\n"];
  1546. [compiledString appendString:@"body"];
  1547. [compiledString appendString:@"\n{\n\t"];
  1548. if ([prefsInvoiceSize intValue] == 1) [compiledString appendString:@"font: 9pt/13pt "];
  1549. if ([prefsInvoiceSize intValue] == 2) [compiledString appendString:@"font: 10pt/13pt "];
  1550. if ([prefsInvoiceSize intValue] == 3) [compiledString appendString:@"font: 11pt/14pt "];
  1551. if ([prefsInvoiceSize intValue] == 4) [compiledString appendString:@"font: 12pt/15pt "];
  1552. if ([prefsInvoiceSize intValue] == 5) [compiledString appendString:@"font: 13pt/16pt "];
  1553. if ([prefsInvoiceBodyFont indexOfSelectedItem] == 0) [compiledString appendString:@"georgia, \"times new roman\", sans-serif;\n"];
  1554. if ([prefsInvoiceBodyFont indexOfSelectedItem] == 1) [compiledString appendString:@"helvetica, arial, serif;\n"];
  1555. if ([prefsInvoiceBodyFont indexOfSelectedItem] == 2) [compiledString appendString:@"\"lucida grande\", serif;\n"];
  1556. if ([prefsInvoiceBodyFont indexOfSelectedItem] == 3) [compiledString appendString:@"palatino, \"times new roman\", sans-serif;\n"];
  1557. if ([prefsInvoiceBodyFont indexOfSelectedItem] == 4) [compiledString appendString:@"verdana, tahoma, serif;\n"];
  1558. [compiledString appendString:@"\n\t"];
  1559. [compiledString appendString:@"color: #111;"];
  1560. [compiledString appendString:@"\n\t"];
  1561. [compiledString appendString:@"margin: 5%;"];
  1562. [compiledString appendString:@"\n\t"];
  1563. [compiledString appendString:@"background-color: white;"];
  1564. [compiledString appendString:@"\n}\n\n"];
  1565. [compiledString appendString:@".session td, th"];
  1566. [compiledString appendString:@"\n{\n\t"];
  1567. [compiledString appendString:@"border-bottom: 1px solid #ccc;"];
  1568. [compiledString appendString:@"\n\t"];
  1569. [compiledString appendString:@"padding: 2px 12px;"];
  1570. [compiledString appendString:@"\n}\n\n"];
  1571. [compiledString appendString:@"h2 { "];
  1572. if ([prefsInvoiceSize intValue] == 1) [compiledString appendString:@"font: 16pt/22pt "];
  1573. if ([prefsInvoiceSize intValue] == 2) [compiledString appendString:@"font: 17pt/23pt "];
  1574. if ([prefsInvoiceSize intValue] == 3) [compiledString appendString:@"font: 18pt/24pt "];
  1575. if ([prefsInvoiceSize intValue] == 4) [compiledString appendString:@"font: 19pt/25pt "];
  1576. if ([prefsInvoiceSize intValue] == 5) [compiledString appendString:@"font: 20pt/26pt "];
  1577. if ([prefsInvoiceHeaderFont indexOfSelectedItem] == 0) [compiledString appendString:@"georgia, \"times new roman\", sans-serif;}\n"];
  1578. if ([prefsInvoiceHeaderFont indexOfSelectedItem] == 1) [compiledString appendString:@"helvetica, arial, serif;}\n"];
  1579. if ([prefsInvoiceHeaderFont indexOfSelectedItem] == 2) [compiledString appendString:@"\"lucida grande\", serif;}\n"];
  1580. if ([prefsInvoiceHeaderFont indexOfSelectedItem] == 3) [compiledString appendString:@"palatino, \"times new roman\", sans-serif;}\n"];
  1581. if ([prefsInvoiceHeaderFont indexOfSelectedItem] == 4) [compiledString appendString:@"verdana, tahoma, serif;}\n"];
  1582. [compiledString appendString:@"table, td, th { text-align: left; }\n"];
  1583. [compiledString appendString:@"th { font-weight: bold; }\n"];
  1584. [compiledString appendString:@"table.session { margin: 10px 0 40px; }\n"];
  1585. [compiledString appendString:@"#dent { margin: 15px; }\n\n"];
  1586. [compiledString appendString:@"a:link, a:visited { color: #111; font-weight: bold; text-decoration: none; border-bottom: 1px dotted #333; }\n"];
  1587. [compiledString appendString:@"a:visited { color: #555; }\n"];
  1588. [compiledString appendString:@"a:hover { border-bottom: 1px dotted #000; color: black;}\n\n</style>\n\n</head>\n\n<body>\n\n"];
  1589. [compiledString appendString:@"<h2>"];
  1590. [compiledString appendString:[prefsInvoiceIndexHeader stringValue]];
  1591. [compiledString appendString:@"</h2>\n\n"];
  1592. [compiledString appendString:@"<div id=\"dent\">\n\n\t"];
  1593. [compiledString appendString:@"<p>"];
  1594. [compiledString appendString:[prefsInvoiceIndexLink stringValue]];
  1595. [compiledString appendString:@"</p>\n\n\t"];
  1596. int i = 0;
  1597. int count = [jobData count];
  1598. if (count > 0)
  1599. {
  1600. [compiledString appendString:@"<table class=\"session\">\n\t\t<tr>"];
  1601. if ([prefsJobDisplayNumber state])
  1602. {
  1603. [compiledString appendString:@"<th>"];
  1604. [compiledString appendString:[textJobNumber stringValue]];
  1605. [compiledString appendString:@"</th>"];
  1606. }
  1607. [compiledString appendString:@"<th>"];
  1608. [compiledString appendString:[textJobName stringValue]];
  1609. [compiledString appendString:@"</th>"];
  1610. if ([prefsJobDisplayClient state])
  1611. {
  1612. [compiledString appendString:@"<th>"];
  1613. [compiledString appendString:[textClientName stringValue]];
  1614. [compiledString appendString:@"</th>"];
  1615. }
  1616. if ([prefsJobDisplayRate state])
  1617. {
  1618. [compiledString appendString:@"<th>"];
  1619. [compiledString appendString:[textRate stringValue]];
  1620. [compiledString appendString:@"</th>"];
  1621. }
  1622. if ([prefsJobDisplayTime state])
  1623. {
  1624. [compiledString appendString:@"<th>"];
  1625. [compiledString appendString:[textTimeLogged stringValue]];
  1626. [compiledString appendString:@"</th>"];
  1627. }
  1628. if ([prefsJobDisplayCharges state])
  1629. {
  1630. [compiledString appendString:@"<th>"];
  1631. [compiledString appendString:[textCharges stringValue]];
  1632. [compiledString appendString:@"</th>"];
  1633. }
  1634. [compiledString appendString:@"</tr>\n\t\t"];
  1635. }
  1636. NSMutableString *hourlyRateString = [[[NSMutableString alloc] init] autorelease];
  1637. id theJob;
  1638. cuDateTime *tempTimeLogged = [[[cuDateTime alloc] init] autorelease];
  1639. NSMutableString *chargeNumberString = [[[NSMutableString alloc] init] autorelease];
  1640. NSMutableString *tempChargesString = [[[NSMutableString alloc] init] autorelease];
  1641. NSNumber *rate;
  1642. NSString *formatterString = @"second";
  1643. if ([prefsUpdateEveryRadio selectedRow] == 1) formatterString = @"minute";
  1644. if ([prefsUpdateEveryRadio selectedRow] == 2) formatterString = @"quarter";
  1645. if ([prefsUpdateEveryRadio selectedRow] == 3) formatterString = @"half";
  1646. if ([prefsUpdateEveryRadio selectedRow] == 4) formatterString = @"hour";
  1647. while (i < count)
  1648. {
  1649. theJob = [jobData objectAtIndex:i];
  1650. [hourlyRateString setString:@""];
  1651. [tempTimeLogged setValues:[[jobData objectAtIndex:i] objectForKey:@"jobTimeLogged"]];
  1652. [chargeNumberString setString:@""];
  1653. [tempChargesString setString:@""];
  1654. rate = [[jobData objectAtIndex:i] objectForKey:@"hourlyRate"];
  1655. [compiledString appendString:@"<tr>"];
  1656. if ([prefsJobDisplayNumber state])
  1657. {
  1658. [compiledString appendString:@"<td>"];
  1659. [compiledString appendString:[[theJob objectForKey:@"jobNumber"] stringValue]];
  1660. [compiledString appendString:@"</td>\t"];
  1661. }
  1662. [compiledString appendString:@"<td>"];
  1663. [compiledString appendString:@"<a href=\""];
  1664. [compiledString appendString:[[theJob objectForKey:@"jobNumber"] stringValue]];
  1665. [compiledString appendString:@".html\""];
  1666. [compiledString appendString:@" title=\"View the invoice for "];
  1667. [compiledString appendString:[theJob objectForKey:@"jobName"]];
  1668. [compiledString appendString:@"\">"];
  1669. [compiledString appendString:[theJob objectForKey:@"jobName"]];
  1670. [compiledString appendString:@"</a></td>\t"];
  1671. if ([prefsJobDisplayClient state])
  1672. {
  1673. [compiledString appendString:@"<td>"];
  1674. [compiledString appendString:[theJob objectForKey:@"clientName"]];
  1675. [compiledString appendString:@"</td>\t"];
  1676. }
  1677. if ([prefsJobDisplayRate state])
  1678. {
  1679. [compiledString appendString:@"<td>"];
  1680. [hourlyRateString appendString:[prefsMonetaryUnit stringValue]];
  1681. [hourlyRateString appendString:[[[jobData objectAtIndex:i] objectForKey:@"hourlyRate"] stringValue]];
  1682. [hourlyRateString appendString:[textHourSuffix stringValue]];
  1683. [compiledString appendString:hourlyRateString];
  1684. [compiledString appendString:@"</td>\t"];
  1685. }
  1686. if ([prefsJobDisplayTime state])
  1687. {
  1688. [compiledString appendString:@"<td>"];
  1689. if ([prefsUpdateEveryRadio selectedRow] == 0) [compiledString appendString:[tempTimeLogged getTimeString]];
  1690. if ([prefsUpdateEveryRadio selectedRow] == 1) [compiledString appendString:[tempTimeLogged getTimeString:NO]];
  1691. if ([prefsUpdateEveryRadio selectedRow] == 2) [compiledString appendString:[tempTimeLogged getFormattedTimeString:@"quarter"]];
  1692. if ([prefsUpdateEveryRadio selectedRow] == 3) [compiledString appendString:[tempTimeLogged getFormattedTimeString:@"half"]];
  1693. if ([prefsUpdateEveryRadio selectedRow] == 4) [compiledString appendString:[tempTimeLogged getFormattedTimeString:@"hour"]];
  1694. [compiledString appendString:@"</td>\t"];
  1695. }
  1696. if ([prefsJobDisplayCharges state])
  1697. {
  1698. [compiledString appendString:@"<td>"];
  1699. [chargeNumberString setString:[[NSNumber numberWithDouble:[tempTimeLogged calculateCharges:[rate doubleValue]
  1700. format:formatterString]] stringValue]];
  1701. [chargeNumberString setString:[self truncateChargeString:chargeNumberString]];
  1702. [tempChargesString appendString:[prefsMonetaryUnit stringValue]];
  1703. [tempChargesString appendString:chargeNumberString];
  1704. [compiledString appendString:tempChargesString];
  1705. [compiledString appendString:@"</td>\t"];
  1706. }
  1707. [compiledString appendString:@"</tr>\n\t\t"];
  1708. i++;
  1709. }
  1710. if (count > 0) [compiledString appendString:@"</table>"];
  1711. [compiledString appendString:@"</div>\n\n</body>\n\n</html>\n\n"];
  1712. return compiledString;
  1713. */
  1714. return @"";
  1715. }
  1716. - (NSString *)generateHTMLForJob:(int)jobNumber
  1717. {
  1718. /* FIXME: Use Webkit to generate HTML or something else. (gdey)
  1719. NSMutableString *compiledString = [[[NSMutableString alloc] init] autorelease];
  1720. cuDateTime *tempTimeLogged = [[[cuDateTime alloc] init] autorelease];
  1721. [tempTimeLogged setValues:[[jobData objectAtIndex:jobNumber] objectForKey:@"jobTimeLogged"]];
  1722. [compiledString appendString:@"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"];
  1723. [compiledString appendString:@"\n\n"];
  1724. [compiledString appendString:@"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">"];
  1725. [compiledString appendString:@"\n\n"];
  1726. [compiledString appendString:@"<head>"];
  1727. [compiledString appendString:@"\n\n"];
  1728. [compiledString appendString:@"<title>"];
  1729. [compiledString appendString:[prefsInvoiceTitle stringValue]];
  1730. [compiledString appendString:@"</title>"];
  1731. [compiledString appendString:@"\n\n"];
  1732. [compiledString appendString:@"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />"];
  1733. [compiledString appendString:@"\n\n"];
  1734. [compiledString appendString:@"<style type=\"text/css\" media=\"all\">"];
  1735. [compiledString appendString:@"body"];
  1736. [compiledString appendString:@"\n{\n\t"];
  1737. if ([prefsInvoiceSize intValue] == 1) [compiledString appendString:@"font: 9pt/13pt "];
  1738. if ([prefsInvoiceSize intValue] == 2) [compiledString appendString:@"font: 10pt/13pt "];
  1739. if ([prefsInvoiceSize intValue] == 3) [compiledString appendString:@"font: 11pt/14pt "];
  1740. if ([prefsInvoiceSize intValue] == 4) [compiledString appendString:@"font: 12pt/15pt "];
  1741. if ([prefsInvoiceSize intValue] == 5) [compiledString appendString:@"font: 13pt/16pt "];
  1742. if ([prefsInvoiceBodyFont indexOfSelectedItem] == 0) [compiledString appendString:@"georgia, \"times new roman\", sans-serif;\n"];
  1743. if ([prefsInvoiceBodyFont indexOfSelectedItem] == 1) [compiledString appendString:@"helvetica, arial, serif;\n"];
  1744. if ([prefsInvoiceBodyFont indexOfSelectedItem] == 2) [compiledString appendString:@"\"lucida grande\", serif;\n"];
  1745. if ([prefsInvoiceBodyFont indexOfSelectedItem] == 3) [compiledString appendString:@"palatino, \"times new roman\", sans-serif;\n"];
  1746. if ([prefsInvoiceBodyFont indexOfSelectedItem] == 4) [compiledString appendString:@"verdana, tahoma, serif;\n"];
  1747. [compiledString appendString:@"\n\t"];
  1748. [compiledString appendString:@"color: #111;"];
  1749. [compiledString appendString:@"\n\t"];
  1750. [compiledString appendString:@"margin: 5%;"];
  1751. [compiledString appendString:@"\n\t"];
  1752. [compiledString appendString:@"background-color: white;"];
  1753. [compiledString appendString:@"\n}\n\n"];
  1754. [compiledString appendString:@".session td, th"];
  1755. [compiledString appendString:@"\n{\n\t"];
  1756. [compiledString appendString:@"border-bottom: 1px solid #ccc;"];
  1757. [compiledString appendString:@"\n\t"];
  1758. [compiledString appendString:@"padding: 2px 12px;"];
  1759. [compiledString appendString:@"\n}\n\n"];
  1760. [compiledString appendString:@"h2 { "];
  1761. if ([prefsInvoiceSize intValue] == 1) [compiledString appendString:@"font: 16pt/22pt "];
  1762. if ([prefsInvoiceSize intValue] == 2) [compiledString appendString:@"font: 17pt/23pt "];
  1763. if ([prefsInvoiceSize intValue] == 3) [compiledString appendString:@"font: 18pt/24pt "];
  1764. if ([prefsInvoiceSize intValue] == 4) [compiledString appendString:@"font: 19pt/25pt "];
  1765. if ([prefsInvoiceSize intValue] == 5) [compiledString appendString:@"font: 20pt/26pt "];
  1766. if ([prefsInvoiceHeaderFont indexOfSelectedItem] == 0) [compiledString appendString:@"georgia, \"times new roman\", sans-serif;}\n"];
  1767. if ([prefsInvoiceHeaderFont indexOfSelectedItem] == 1) [compiledString appendString:@"helvetica, arial, serif;}\n"];
  1768. if ([prefsInvoiceHeaderFont indexOfSelectedItem] == 2) [compiledString appendString:@"\"lucida grande\", serif;}\n"];
  1769. if ([prefsInvoiceHeaderFont indexOfSelectedItem] == 3) [compiledString appendString:@"palatino, \"times new roman\", sans-serif;}\n"];
  1770. if ([prefsInvoiceHeaderFont indexOfSelectedItem] == 4) [compiledString appendString:@"verdana, tahoma, serif;}\n"];
  1771. [compiledString appendString:@"table, td, th { text-align: left; }\n"];
  1772. [compiledString appendString:@"th { font-weight: bold; }\n"];
  1773. [compiledString appendString:@"table.session { margin: 10px 0 40px; }\n"];
  1774. [compiledString appendString:@"#dent { margin: 15px; }\n\n"];
  1775. [compiledString appendString:@"</style>\n\n</head>\n\n<body>\n\n"];
  1776. [compiledString appendString:@"<h2>"];
  1777. [compiledString appendString:[prefsInvoiceHeader stringValue]];
  1778. [compiledString appendString:@"</h2>\n\n"];
  1779. [compiledString appendString:@"<div id=\"dent\">\n\n\t"];
  1780. //start job table
  1781. [compiledString appendString:@"<table class=\"job\">\n\t\t"];
  1782. [compiledString appendString:@"<tr><td>"];
  1783. [compiledString appendString:[textJobName stringValue]];
  1784. [compiledString appendString:@":</td>\t\t<td><b>"];
  1785. [compiledString appendString:[[jobData objectAtIndex:jobNumber] objectForKey:@"jobName"]];
  1786. [compiledString appendString:@"</b></td></tr>\n\t\t"];
  1787. [compiledString appendString:@"<tr><td>"];
  1788. [compiledString appendString:[textClientName stringValue]];
  1789. [compiledString appendString:@":</td>\t\t<td><b>"];
  1790. [compiledString appendString:[[jobData objectAtIndex:jobNumber] objectForKey:@"clientName"]];
  1791. [compiledString appendString:@"</b></td></tr>\n\t\t"];
  1792. [compiledString appendString:@"<tr><td>"];
  1793. [compiledString appendString:[textRate stringValue]];
  1794. [compiledString appendString:@":</td>\t\t<td><b>"];
  1795. NSMutableString *hourlyRateString = [[[NSMutableString alloc] init] autorelease];
  1796. [hourlyRateString appendString:[prefsMonetaryUnit stringValue]];
  1797. [hourlyRateString appendString:[[[jobData objectAtIndex:jobNumber] objectForKey:@"hourlyRate"] stringValue]];
  1798. [hourlyRateString appendString:[textHourSuffix stringValue]];
  1799. [compiledString appendString:hourlyRateString];
  1800. [compiledString appendString:@"</b></td></tr>\n\t\t"];
  1801. [compiledString appendString:@"<tr><td>"];
  1802. [compiledString appendString:[textTimeLogged stringValue]];
  1803. [compiledString appendString:@":</td>\t\t<td><b>"];
  1804. if ([prefsUpdateEveryRadio selectedRow] == 0) [compiledString appendString:[tempTimeLogged getTimeString]];
  1805. if ([prefsUpdateEveryRadio selectedRow] == 1) [compiledString appendString:[tempTimeLogged getTimeString:NO]];
  1806. if ([prefsUpdateEveryRadio selectedRow] == 2) [compiledString appendString:[tempTimeLogged getFormattedTimeString:@"quarter"]];
  1807. if ([prefsUpdateEveryRadio selectedRow] == 3) [compiledString appendString:[tempTimeLogged getFormattedTimeString:@"half"]];
  1808. if ([prefsUpdateEveryRadio selectedRow] == 4) [compiledString appendString:[tempTimeLogged getFormattedTimeString:@"hour"]];
  1809. [compiledString appendString:@"</b></td></tr>\n\t\t"];
  1810. [compiledString appendString:@"<tr><td>"];
  1811. [compiledString appendString:[textTotalDue stringValue]];
  1812. [compiledString appendString:@":</td>\t\t<td><b>"];
  1813. NSNumber *rate = [[jobData objectAtIndex:jobNumber] objectForKey:@"hourlyRate"];
  1814. NSString *formatterString = @"second";
  1815. if ([prefsUpdateEveryRadio selectedRow] == 1) formatterString = @"minute";
  1816. if ([prefsUpdateEveryRadio selectedRow] == 2) formatterString = @"quarter";
  1817. if ([prefsUpdateEveryRadio selectedRow] == 3) formatterString = @"half";
  1818. if ([prefsUpdateEveryRadio selectedRow] == 4) formatterString = @"hour";
  1819. NSMutableString *chargeNumberString = [[[NSMutableString alloc] init] autorelease];
  1820. [chargeNumberString setString:[[NSNumber numberWithDouble:[tempTimeLogged calculateCharges:[rate doubleValue]
  1821. format:formatterString]] stringValue]];
  1822. [chargeNumberString setString:[self truncateChargeString:chargeNumberString]];
  1823. NSMutableString *tempChargesString = [[[NSMutableString alloc] init] autorelease];
  1824. [tempChargesString appendString:[prefsMonetaryUnit stringValue]];
  1825. [tempChargesString appendString:chargeNumberString];
  1826. [compiledString appendString:tempChargesString];
  1827. [compiledString appendString:@"</table>\n\n"];
  1828. //jobtable ended
  1829. int i = 0;
  1830. int count = [[[jobData objectAtIndex:jobNumber] objectForKey:@"sessionList"] count];
  1831. if (count > 0)
  1832. {
  1833. [compiledString appendString:@"<table class=\"session\">\n\t\t<tr>"];
  1834. if ([prefsSessionDisplayNumber state])
  1835. {
  1836. [compiledString appendString:@"<th>"];
  1837. [compiledString appendString:[textSessionNumber stringValue]];
  1838. [compiledString appendString:@"</th>"];
  1839. }
  1840. if ([prefsSessionDisplaySDate state])
  1841. {
  1842. [compiledString appendString:@"<th>"];
  1843. [compiledString appendString:[textSessionDate stringValue]];
  1844. [compiledString appendString:@"</th>"];
  1845. }
  1846. if ([prefsSessionDisplaySTime state])
  1847. {
  1848. [compiledString appendString:@"<th>"];
  1849. [compiledString appendString:[textSessionStart stringValue]];
  1850. [compiledString appendString:@"</th>"];
  1851. }
  1852. if ([prefsSessionDisplayEDate state])
  1853. {
  1854. [compiledString appendString:@"<th>"];
  1855. [compiledString appendString:[textSessionEndDate stringValue]];
  1856. [compiledString appendString:@"</th>"];
  1857. }
  1858. if ([prefsSessionDisplayETime state])
  1859. {
  1860. [compiledString appendString:@"<th>"];
  1861. [compiledString appendString:[textSessionEnd stringValue]];
  1862. [compiledString appendString:@"</th>"];
  1863. }
  1864. if ([prefsSessionDisplayPause state])
  1865. {
  1866. [compiledString appendString:@"<th>"];
  1867. [compiledString appendString:[textPauses stringValue]];
  1868. [compiledString appendString:@"</th>"];
  1869. }
  1870. if ([prefsSessionDisplayTotalTime state])
  1871. {
  1872. [compiledString appendString:@"<th>"];
  1873. [compiledString appendString:[textSessionTime stringValue]];
  1874. [compiledString appendString:@"</th>"];
  1875. }
  1876. if ([prefsSessionDisplayCharges state])
  1877. {
  1878. [compiledString appendString:@"<th>"];
  1879. [compiledString appendString:[textSessionCharges stringValue]];
  1880. [compiledString appendString:@"</th>"];
  1881. }
  1882. if ([prefsSessionDisplaySummary state])
  1883. {
  1884. [compiledString appendString:@"<th>"];
  1885. [compiledString appendString:[textSessionSummary stringValue]];
  1886. [compiledString appendString:@"</th>"];
  1887. }
  1888. [compiledString appendString:@"</tr>"];
  1889. }
  1890. cuDateTime *tempInterval = [[[cuDateTime alloc] init] autorelease];
  1891. NSMutableString *tempSessionChargeNumberString = [[[NSMutableString alloc] init] autorelease];
  1892. NSMutableString *tempSessionChargesString = [[[NSMutableString alloc] init] autorelease];
  1893. while (i < count)
  1894. {
  1895. [compiledString appendString:@"\n\t\t<tr>"];
  1896. id theSession = [[[jobData objectAtIndex:jobNumber] objectForKey:@"sessionList"] objectAtIndex:i];
  1897. [tempInterval setValues:[[theSession objectForKey:@"startDateTime"] getTimeInterval:[theSession objectForKey:@"endDateTime"]]];
  1898. [tempInterval setValues:[tempInterval subtractInterval:[theSession objectForKey:@"pauseTime"]]];
  1899. [tempSessionChargeNumberString setString:[[NSNumber numberWithDouble:[tempInterval calculateCharges:[rate doubleValue]
  1900. format:formatterString]] stringValue]];
  1901. [tempSessionChargeNumberString setString:[self truncateChargeString:tempSessionChargeNumberString]];
  1902. [tempSessionChargesString appendString:[prefsMonetaryUnit stringValue]];
  1903. [tempSessionChargesString appendString:tempSessionChargeNumberString];
  1904. if ([prefsSessionDisplayNumber state])
  1905. {
  1906. [compiledString appendString:@"<td>"];
  1907. [compiledString appendString:[[theSession objectForKey:@"sessionNumber"] stringValue]];
  1908. [compiledString appendString:@"</td>\t"];
  1909. }
  1910. if ([prefsSessionDisplaySDate state])
  1911. {
  1912. [compiledString appendString:@"<td>"];
  1913. [compiledString appendString:[[theSession objectForKey:@"startDateTime"] getDateString]];
  1914. [compiledString appendString:@"</td>\t"];
  1915. }
  1916. if ([prefsSessionDisplaySTime state])
  1917. {
  1918. [compiledString appendString:@"<td>"];
  1919. if ([formatterString isEqualTo:@"second"]) [compiledString appendString:[[theSession objectForKey:@"startDateTime"] getTimeString]];
  1920. else if ([formatterString isEqualTo:@"minute"]) [compiledString appendString:[[theSession objectForKey:@"startDateTime"] getTimeString:NO]];
  1921. else [compiledString appendString:[[theSession objectForKey:@"startDateTime"] getFormattedTimeString:formatterString]];
  1922. [compiledString appendString:@"</td>\t"];
  1923. }
  1924. if ([prefsSessionDisplayEDate state])
  1925. {
  1926. [compiledString appendString:@"<td>"];
  1927. [compiledString appendString:[[theSession objectForKey:@"endDateTime"] getDateString]];
  1928. [compiledString appendString:@"</td>\t"];
  1929. }
  1930. if ([prefsSessionDisplayETime state])
  1931. {
  1932. [compiledString appendString:@"<td>"];
  1933. if ([formatterString isEqualTo:@"second"]) [compiledString appendString:[[theSession objectForKey:@"endDateTime"] getTimeString]];
  1934. else if ([formatterString isEqualTo:@"minute"]) [compiledString appendString:[[theSession objectForKey:@"endDateTime"] getTimeString:NO]];
  1935. else [compiledString appendString:[[theSession objectForKey:@"endDateTime"] getFormattedTimeString:formatterString]];
  1936. [compiledString appendString:@"</td>\t"];
  1937. }
  1938. if ([prefsSessionDisplayPause state])
  1939. {
  1940. [compiledString appendString:@"<td>"];
  1941. cuDateTime *tempPauseTime = [[[cuDateTime alloc] init] autorelease];
  1942. [tempPauseTime setValues:[theSession objectForKey:@"pauseTime"]];
  1943. [tempPauseTime setValues:[tempPauseTime addInterval:[theSession objectForKey:@"tempPauseTime"]]];
  1944. [compiledString appendString:[tempPauseTime getTimeString]];
  1945. [compiledString appendString:@"</td>\t"];
  1946. }
  1947. if ([prefsSessionDisplayTotalTime state])
  1948. {
  1949. [compiledString appendString:@"<td>"];
  1950. if ([formatterString isEqualTo:@"second"]) [compiledString appendString:[tempInterval getTimeString]];
  1951. else if ([formatterString isEqualTo:@"minute"]) [compiledString appendString:[tempInterval getTimeString:NO]];
  1952. else [compiledString appendString:[tempInterval getFormattedTimeString:formatterString]];
  1953. [compiledString appendString:@"</td>\t"];
  1954. }
  1955. if ([prefsSessionDisplayCharges state])
  1956. {
  1957. [compiledString appendString:@"<td>"];
  1958. [compiledString appendString:tempSessionChargesString];
  1959. [tempSessionChargesString setString:@""];
  1960. [compiledString appendString:@"</td>\t"];
  1961. }
  1962. if ([prefsSessionDisplaySummary state])
  1963. {
  1964. [compiledString appendString:@"<td>"];
  1965. [compiledString appendString:[theSession objectForKey:@"sessionSummary"]];
  1966. [compiledString appendString:@"</td>\t"];
  1967. }
  1968. [compiledString appendString:@"</tr>"];
  1969. i++;
  1970. }
  1971. if (count > 0) [compiledString appendString:@"</table>"];
  1972. [compiledString appendString:@"</div>\n\n</body>\n\n</html>\n\n"];
  1973. return compiledString;
  1974. */
  1975. return @"";
  1976. }
  1977. - (IBAction)menuSave:(id)sender
  1978. {
  1979. [self saveLoop];
  1980. }
  1981. - (IBAction)menuSendEmail:(id)sender
  1982. {
  1983. NSWorkspace *workSpace = [NSWorkspace sharedWorkspace];
  1984. [workSpace openURL:[NSURL URLWithString:@"mailto:khronos@enure.net"]];
  1985. }
  1986. - (IBAction)menuVisitWebsite:(id)sender
  1987. {
  1988. NSWorkspace *workSpace = [NSWorkspace sharedWorkspace];
  1989. [workSpace openURL:[NSURL URLWithString:@"http://khronos.enure.net/"]];
  1990. }
  1991. - (IBAction)menuCheckForUpdates:(id)sender
  1992. {
  1993. NSString *versionString = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://khronos.enure.net/version.html"]]; // FIXME: This isn't working $(cstuart)
  1994. if ([versionString length] < 1 || [versionString length] > 5)
  1995. {
  1996. NSRunAlertPanel([textArr stringValue], [textProblemConnect stringValue], @"OK", nil, nil);
  1997. }
  1998. else if ([versionString doubleValue] > 1.22)
  1999. {
  2000. NSRunAlertPanel([textRejoice stringValue], [textNewVersion stringValue], @"OK", nil, nil);
  2001. }
  2002. else if ([versionString doubleValue] == 1.22)
  2003. {
  2004. NSRunAlertPanel([textYeargh stringValue], [textUpToDate stringValue], @"OK", nil, nil);
  2005. }
  2006. }
  2007. /***** Preferences *****/
  2008. - (IBAction)showPreferencesPanel:(id)sender
  2009. {
  2010. // Is perferencesController nil?
  2011. if(!preferencesController) {
  2012. preferencesController = [[CUPreferenceController alloc] init];
  2013. }
  2014. [preferencesController showWindow:self];
  2015. }
  2016. @end