Source

headstak / StakViewController.m

/**
 headstak - a stack for your head
 
 Copyright (C) 2012 dreadtech.com
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 **/
//
//  HSController.m
//  headstak
//
//  Created by Veghead on 7/24/11.


#import "StakViewController.h"
#import "StakWindowController.h"
#import "StakDB.h"
#import "StakItem.h"
#import "StakView.h"
#import "StakItemView.h"
#import "StakPrefController.h"

NSObject *_stakLock;


@implementation StakViewController

- (id)init
{
    self = [super init];
    if (self) {
        _swc = [[StakWindowController alloc] init];
        [_swc setController:self];
        _db = [StakDB stackDB];
        [_db setTraceExecution:YES];
        [_db setLogsErrors:YES];
        [_db open];
        _stakHolder = [[NSMutableArray alloc] init];        
        [_db loadStakIntoHolder:_stakHolder];
        _stakLock = [[NSObject alloc] init];
    }
    return self;
}


- (void)flagsChanged:(NSEvent *)theEvent {
    NSLog(@"flags changed");
}


- (StakItem *)pushNewItemOfType:(NSUInteger)itemType {
    StakItem *item = [[StakItem alloc] initNewItemOfType:itemType inDb:[self db]];
    @synchronized(_stakLock) {
        [[self stakHolder] insertObject:item atIndex:0];
    }
    [[[self swc] stakView] addSubview:[item viewInStakView:[[self swc] stakView]]];
    [self layoutItemViews];
    return item;
}

- (StakItem *)popItem {
    StakItem *item = nil;
    @synchronized(_stakLock) {
        if ([[self stakHolder] count]) {
            item = [[self stakHolder] objectAtIndex:0];
            [item setPopTime:[NSDate date]];
            [item save];
            [[self stakHolder] removeObjectAtIndex:0];
            [[item viewInStakView:[[self swc] stakView]] removeFromSuperview];
            [self layoutItemViews];
        }
    }
    return item;
}


- (void)setStak:(NSMutableArray *)stak {
    @synchronized(_stakLock) {
        [self setStakHolder:stak];
    }
}

- (void)layoutItemViews {
    NSRect r = [[[self swc] stakView] frame];
    NSInteger yoffset = 0;
    NSMakeRect(r.origin.x, [[self stakHolder] count] * 40, r.size.width, r.size.height);
    for (StakItem *item in [self stakHolder]) {
        NSRect theFrame = [[item view] frame];
        theFrame.origin.y = yoffset;
        [[item view] setFrame:theFrame];
        yoffset += theFrame.size.height + 5;
    }
    [[[self swc]stakView] setNeedsDisplay:YES];
    return;
}

- (StakPrefController *)spc {
    if (!_spc) {
        _spc = [[StakPrefController alloc] initWithWindowNibName:@"StakPref"];
    }
    return _spc;
}

- (void)clearStakWarning {
    NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"All of your HeadStak history will be deleted. Are you sure?", nil)
                     defaultButton:NSLocalizedString(@"No", nil)
                   alternateButton:NSLocalizedString(@"Yes",nil)
                       otherButton:nil
         informativeTextWithFormat:@""];
    NSInteger result = [alert runModal];
    switch (result) {
        case NSAlertAlternateReturn:
            [self clearStak];
            break;
        default:
            break;
    }
}

- (void)clearStak {
    @synchronized(_stakLock) {
        while ([[self stakHolder] count]) {
            StakItem *item = [[self stakHolder] objectAtIndex:0];
            [[self stakHolder] removeObjectAtIndex:0];
            [[item viewInStakView:[[self swc] stakView]] removeFromSuperview];
        }
        [[self stakHolder] removeAllObjects];
    }
    [[self db] hardDeleteStak];
    [self layoutItemViews];
}

- (void)exportStakToURL:(NSURL *)exportFileURL {
    NSFileHandle *file;
    NSError *err;
    [NSApp activateIgnoringOtherApps:YES];
    [[NSFileManager defaultManager] createFileAtPath:[exportFileURL path] contents:nil attributes:nil];
    file = [NSFileHandle fileHandleForWritingToURL:exportFileURL
                                             error:&err];
    
    if (file == nil) {
        NSLog(@"Failed to open file with error %@", err);
        return;
    }
    
    [[self db] dumpStakToFileHandle:file];
    
    [file closeFile];
}

- (void)exportStakSheet {
    // Bring the app to the front, and close the stak if it's open.
    [NSApp activateIgnoringOtherApps:YES];
    [[self swc] close];
    
    NSSavePanel *exportPanel = [NSSavePanel savePanel];
    [exportPanel setAllowedFileTypes:[NSArray arrayWithObject:@"csv"]];
    NSArray *dirs = [NSFileManager.defaultManager URLsForDirectory:NSDocumentDirectory
                                                          inDomains:NSUserDomainMask];
    [exportPanel setDirectoryURL:dirs[0]];
    // Perform other setup
    // Use a completion handler -- this is a block which takes one argument
    // which corresponds to the button that was clicked
    [exportPanel beginWithCompletionHandler:^(NSInteger result){
        if (result == NSFileHandlingPanelOKButton) {
            
            NSLog(@"Got URL: %@", [exportPanel URL]);
            [self exportStakToURL:[exportPanel URL]];
            // Do what you need to do with the selected path
        }
    }];
}



@end