更新情報
広告
PRサイト
関連サイト

ファイルを保存する場所を選べる様にする

バージョン1.2.2でファイルを保存する場所を選べる様にしましたので、これの説明をします。

インターフェイスファイルの変更

ユーザが選択したパスを表示するテキストフィールドを追加するので、そのアウトレットを追加します。

パスを覚えておく変数ですが、固定ではなく書き換えられないといけないのでNSStringをNSMutableStringに変更します。

またユーザが保存場所を選ぶ時にボタンを押すので、それを受けるアクションを追加します。

RepeatingMotifSaverView.h
@class  RepeatingMotif;

@interface RepeatingMotifSaverView : ScreenSaverView 
{
    IBOutlet id     optionWindow;
    IBOutlet id     randomizer,generator;
    IBOutlet id     optionWindowTabView;
    IBOutlet id     creditTextView;
    IBOutlet id     directoryText;
    
    BOOL            fixToLayerMax,saveToFile,enableSaveToFile;
    BOOL            preview;
    BOOL            saveMarkedOnly,marked,playClick;
    int             counter,transition,hold,layerMax;
    int             selectedIndex;

    NSImage             *image;
    NSMutableString     *directory;
    NSMutableArray      *masterMotifs,*repeatingMotifs;
    RepeatingMotif      *repeatingMotif;
}

- (IBAction)closeOptionWindow:(id)sender;
- (IBAction)selectDirectoryToSaveFile:(id)sender;

@end


デフォルトデータベースから読み込んで初期化する

これまでは初期化メソッドで、ファイルを保存するパスをある決まった場所に設定していましたが、これをデフォルトデータベースから読み込む処理に変更します。

RepeatingMotifSaverView.m
- (id)initWithFrame:(NSRect)frame isPreview:(BOOL)isPreview
{
    self = [super initWithFrame:frame isPreview:isPreview];
    if(self)
    {
        ScreenSaverDefaults *ssd = [ScreenSaverDefaults
            defaultsForModuleWithName:RMSModuleName];
        NSFileManager   *fileManager = [NSFileManager defaultManager];
        NSArray         *paths = NSSearchPathForDirectoriesInDomains(
            NSLibraryDirectory, NSUserDomainMask, YES);
        
        [self setAnimationTimeInterval:1/10.0];
        [NSBundle loadNibNamed:RMSResourceName owner:self];
        transition      = [ssd integerForKey:@"transition"];
        hold            = [ssd integerForKey:@"hold"];
        layerMax        = [ssd integerForKey:@"layerMax"];
        fixToLayerMax   = [ssd boolForKey:@"fixToLayerMax"];
        selectedIndex   = [ssd integerForKey:@"selectedIndex"];
        saveToFile      = [ssd boolForKey:@"saveToFile"];
        saveMarkedOnly  = [ssd boolForKey:@"saveMarkedOnly"];
        playClick       = [ssd boolForKey:@"playClick"];

        enableSaveToFile = YES;
        preview = isPreview;
        masterMotifs = repeatingMotifs = nil;
        repeatingMotif = nil;

        directory = [[NSString stringWithFormat:@"%@/%@",
            [paths objectAtIndex:0], RMSDirectoryName] retain];
        directory = [[NSMutableString alloc]
            initWithString:[ssd stringForKey:@"directory"]];
        
        if(![fileManager fileExistsAtPath:directory])
            [fileManager createDirectoryAtPath:directory
                                    attributes:nil];
    }
    return self;
}

なお、初回は読み込もうにも何もありませんので"UserDefaults.plist"にデフォルトの場所を追加しておく必要があります。

UserDefaults.plist
	<key>directory</key>
	<string>~/Library/Repeating Motif Saver</string>

アクションを追加する

インターフェイスファイルで追加したアクションを実装します。やっている事はオープンパネルを用意して、それにオプションを設定し、runModalで実行しているだけです。OKならパスを保存する変数とテキストフィールドを更新します。

このアクションが呼び出される時は、スクリーンセーバの設定をシステム環境設定のウィンドウにぶら下がっているシートで行なっている訳ですから、モーダルダイアログで処理を実行するしかありません。

オープンパネルの設定は、

  • ファイル選択:不可
  • 複数選択:不可
  • ディレクトリ選択:可
  • ディレクトリ作成:可

です。

RepeatingMotifSaverView.m
- (void)selectDirectoryToSaveFile:(id)sender
{
    int         result;
    NSOpenPanel *openPanel = [NSOpenPanel openPanel];
    
    [openPanel setCanChooseFiles:NO];
    [openPanel setAllowsMultipleSelection:NO];
    [openPanel setCanChooseDirectories:YES];
    [openPanel setCanCreateDirectories:YES];
    result = [openPanel runModal];
    
    if(result == NSFileHandlingPanelOKButton)
    {
        [directory setString:[openPanel directory]];
        [directoryText setStringValue:directory];
    }
}


シート表示前の処理

シートを表示する前に、現在選択されているパスをテキストフィールドにセットする処理を追加します。

RepeatingMotifSaverView.m
- (NSWindow *)configureSheet
{
    [NSBundle loadNibNamed:RMSResourceName owner:self];
    [optionWindowTabView selectTabViewItemAtIndex:selectedIndex];

    NSBundle    *bundle = [NSBundle bundleForClass:[self class]];
    NSAttributedString  *creditsString =
        [[NSAttributedString alloc]
             initWithPath:[bundle pathForResource:@"Credits"
                                           ofType:@"rtf"]
       documentAttributes:nil];
    [[creditTextView textStorage] setAttributedString:creditsString];
    [creditsString release];
    [creditTextView setBackgroundColor:
        [NSColor windowBackgroundColor]];
    [directoryText setStringValue:directory];

    return optionWindow;
}

シート表示後の処理

シートを閉じるときに、選択されたパスをデフォルトデータベースに書き込む処理を追加します。

RepeatingMotifSaverView.m
- (void)closeOptionWindow:(id)sender
{
    ScreenSaverDefaults *ssd = [ScreenSaverDefaults
            defaultsForModuleWithName:RMSModuleName];
    
    [ssd setInteger:transition      forKey:@"transition"];
    [ssd setInteger:hold            forKey:@"hold"];
    [ssd setInteger:layerMax        forKey:@"layerMax"];
    [ssd setBool:fixToLayerMax      forKey:@"fixToLayerMax"];
    [ssd setInteger:selectedIndex   forKey:@"selectedIndex"];
    [ssd setBool:saveToFile         forKey:@"saveToFile"];

    [ssd setBool:saveMarkedOnly     forKey:@"saveMarkedOnly"];
    [ssd setBool:playClick          forKey:@"playClick"];
    
    [ssd setObject:directory        forKey:@"directory"];

    [randomizer writeToDefaults];
    [ssd synchronize];

    [NSApp endSheet:optionWindow];
}

Interface Builderでの作業

後はInterface Builderでテキストフィールドとボタンを追加し、アウトレットとアクションを接続すれば完成です。見えないですが、ボタンの左側にテキストフィールドを追加してあります。

部品が色々と増えてきたので、タブを一つ増やして保存に関する設定を独立させました。

ちなみにテキストフィールドの設定では、Line BreakingをTruncate Headにしています。パスが長い場合、末尾が省略されてしまうよりも先頭が省略された方がよいという判断です。

addSaveDirectory


ページの先頭へ戻る