OSDN Git Service

import jp-0.9.3
[handbrake-jp/handbrake-jp.git] / macosx / HBOutputPanelController.m
1 /**
2  * @file
3  * @date 18.5.2007
4  *
5  * Implementation of class HBOutputPanelController.
6  */
7
8 #import "HBOutputPanelController.h"
9 #import "HBOutputRedirect.h"
10
11 /// Maximum amount of characters that can be shown in the view.
12 // Original value used by cleaner
13 //#define TextStorageUpperSizeLimit 20000
14 // lets use this higher value for now for better gui debugging
15 #define TextStorageUpperSizeLimit 40000
16
17 /// When old output is removed, this is the amount of characters that will be
18 /// left in outputTextStorage.
19 // Original value used by cleaner
20 //#define TextStorageLowerSizeLimit 15000
21 // lets use this higher value for now for better gui debugging
22 #define TextStorageLowerSizeLimit 35000
23
24 @implementation HBOutputPanelController
25
26 /**
27  * Initializes the object, creates outputTextStorage and starts redirection of stderr.
28  */
29 - (id)init
30 {
31     if( (self = [super initWithWindowNibName:@"OutputPanel"]) )
32     {
33         /* NSWindowController likes to lazily load its window nib. Since this
34          * controller tries to touch the outlets before accessing the window, we
35          * need to force it to load immadiately by invoking its accessor.
36          *
37          * If/when we switch to using bindings, this can probably go away.
38          */
39         [self window];
40
41         /* We initialize the outputTextStorage object for the activity window */
42         outputTextStorage = [[NSTextStorage alloc] init];
43
44         /* We declare the default NSFileManager into fileManager */
45         NSFileManager * fileManager = [NSFileManager defaultManager];
46         /* Establish the log file location to write to */
47         /* We are initially using a .txt file as opposed to a .log file since it will open by
48          * default with the users text editor instead of the .log default Console.app, should
49          * create less confusion for less experienced users when we ask them to paste the log for support
50          */
51         outputLogFile = @"~/Library/Application Support/HandBrake/HandBrake-activitylog.txt";
52         outputLogFile = [[outputLogFile stringByExpandingTildeInPath]retain];
53
54         /* We check for an existing output log file here */
55         if( [fileManager fileExistsAtPath:outputLogFile] == 0 )
56         {
57             /* if not, then we create a new blank one */
58             [fileManager createFileAtPath:outputLogFile contents:nil attributes:nil];
59         }
60         /* We overwrite the existing output log with the date for starters the output log to start fresh with the new session */
61         /* Use the current date and time for the new output log header */
62         NSString *startOutputLogString = [NSString stringWithFormat: NSLocalizedStringFromTable(@"HandBrake Activity Log for Session (Cleared): %@\n\n", @"OutputPanel", @""), [[NSDate  date] descriptionWithCalendarFormat:nil timeZone:nil locale:nil]];
63         [startOutputLogString writeToFile:outputLogFile atomically:YES encoding:NSUTF8StringEncoding error:NULL];
64
65         [[HBOutputRedirect stderrRedirect] addListener:self];
66         [[HBOutputRedirect stdoutRedirect] addListener:self];
67
68         [self setWindowFrameAutosaveName:@"OutputPanelFrame"];
69         [[textView layoutManager] replaceTextStorage:outputTextStorage];
70         [[textView enclosingScrollView] setLineScroll:10];
71         [[textView enclosingScrollView] setPageScroll:20];
72         
73         encodeLogOn = NO;
74     }
75     return self;
76 }
77
78 /**
79  * Stops redirection of stderr and releases resources.
80  */
81 - (void)dealloc
82 {
83     [[HBOutputRedirect stderrRedirect] removeListener:self];
84     [[HBOutputRedirect stdoutRedirect] removeListener:self];
85     [outputTextStorage release];
86     [super dealloc];
87 }
88
89 /**
90  * Loads output panel from OutputPanel.nib and shows it.
91  */
92 - (IBAction)showOutputPanel:(id)sender
93 {
94     [textView scrollRangeToVisible:NSMakeRange([outputTextStorage length], 0)];
95     [self showWindow:sender];
96
97     [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"OutputPanelIsOpen"];
98 }
99
100 - (void) startEncodeLog:(NSString *) logPath
101 {
102     encodeLogOn = YES;
103     NSString *outputFileForEncode = logPath ;
104     /* Since the destination path matches the extension of the output file, replace the
105      * output movie extension and replace it with ".txt"
106      */
107     NSFileManager * fileManager = [NSFileManager defaultManager];
108     /* Establish the log file location to write to */
109     /* We are initially using a .txt file as opposed to a .log file since it will open by
110      * default with the users text editor instead of the .log default Console.app, should
111      * create less confusion for less experienced users when we ask them to paste the log for support
112      */
113     /* We need to get the current time in YY-MM-DD HH-MM-SS format to put at the beginning of the name of the log file */
114     time_t _now = time( NULL );
115     struct tm * now  = localtime( &_now );
116     NSString *dateForLogTitle = [NSString stringWithFormat:@"%02d-%02d-%02d %02d-%02d-%02d",now->tm_year + 1900, now->tm_mon, now->tm_mday,now->tm_hour, now->tm_min, now->tm_sec]; 
117     
118     /* Assemble the new log file name as YY-MM-DD HH-MM-SS mymoviename.txt */
119     NSString *outputDateFileName = [NSString stringWithFormat:@"%@ %@.txt",dateForLogTitle,[[outputFileForEncode lastPathComponent] stringByDeletingPathExtension]];
120     if ([[NSUserDefaults standardUserDefaults] boolForKey:@"EncodeLogLocation"]) // if we are putting it in the same directory with the movie
121     {
122         
123         outputLogFileForEncode = [[NSString stringWithFormat:@"%@/%@",[outputFileForEncode stringByDeletingLastPathComponent],outputDateFileName] retain];
124     }
125     else // if we are putting it in the default ~/Libraries/Application Support/HandBrake/EncodeLogs logs directory
126     {
127         NSString *libraryDir = [NSSearchPathForDirectoriesInDomains( NSLibraryDirectory,
128                                                                     NSUserDomainMask,
129                                                                     YES ) objectAtIndex:0];
130         NSString *encodeLogDirectory = [[[libraryDir stringByAppendingPathComponent:@"Application Support"] stringByAppendingPathComponent:@"HandBrake"] stringByAppendingPathComponent:@"EncodeLogs"];
131         if( ![[NSFileManager defaultManager] fileExistsAtPath:encodeLogDirectory] )
132         {
133             [[NSFileManager defaultManager] createDirectoryAtPath:encodeLogDirectory
134                                                        attributes:nil];
135         }
136         outputLogFileForEncode = [[NSString stringWithFormat:@"%@/%@",encodeLogDirectory,outputDateFileName] retain];   
137     }
138     [fileManager createFileAtPath:outputLogFileForEncode contents:nil attributes:nil];
139     
140     /* Similar to the regular activity log, we print a header containing the date and time of the encode as well as what directory it was encoded to */
141     NSString *versionStringFull = [[NSString stringWithFormat: NSLocalizedStringFromTable(@"Handbrake Version: %@", @"OutputPanel", @""), [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleGetInfoString"]] stringByAppendingString: [NSString stringWithFormat: @" (%@)\n\n", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]]];
142     NSString *startOutputLogString = [NSString stringWithFormat: NSLocalizedStringFromTable(@"HandBrake Activity Log for %@: %@\n%@", @"OutputPanel", @""),outputFileForEncode, [[NSDate  date] descriptionWithCalendarFormat:nil timeZone:nil locale:nil],versionStringFull];
143     [startOutputLogString writeToFile:outputLogFileForEncode atomically:YES encoding:NSUTF8StringEncoding error:NULL];
144
145
146 }
147
148 - (void) endEncodeLog
149 {
150     encodeLogOn = NO;
151 }
152
153 /**
154  * Displays text received from HBOutputRedirect in the text view.
155  */
156 - (void)stderrRedirect:(NSString *)text
157 {
158         
159     NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:text];
160         /* Actually write the libhb output to the text view (outputTextStorage) */
161     [outputTextStorage appendAttributedString:attributedString];
162     [attributedString release];
163     
164         /* remove text from outputTextStorage as defined by TextStorageUpperSizeLimit and TextStorageLowerSizeLimit */
165     if ([outputTextStorage length] > TextStorageUpperSizeLimit)
166                 [outputTextStorage deleteCharactersInRange:NSMakeRange(0, [outputTextStorage length] - TextStorageLowerSizeLimit)];
167     
168     [textView scrollRangeToVisible:NSMakeRange([outputTextStorage length], 0)];
169     
170     /* We use a c function to write to the log file without reading it into memory 
171         * as it should be faster and easier on memory than using cocoa's writeToFile
172         * thanks ritsuka !!*/
173     FILE *f = fopen([outputLogFile UTF8String], "a");
174     fprintf(f, "%s", [text UTF8String]);
175     fclose(f);
176     
177     if (encodeLogOn == YES && outputLogFileForEncode != nil)
178     {
179     FILE *e = fopen([outputLogFileForEncode UTF8String], "a");
180     fprintf(e, "%s", [text UTF8String]);
181     fclose(e);
182     }
183     /* Below uses Objective-C to write to the file, though it is slow and uses
184         * more memory than the c function above. For now, leaving this in here
185         * just in case and commented out.
186     */
187     /* Put the new incoming string from libhb into an nsstring for appending to our log file */
188     //NSString *newOutputString = [[NSString alloc] initWithString:text];
189     /*get the current log file and put it into an NSString */
190     /* HACK ALERT: must be a way to do it without reading the whole log into memory 
191         Performance note: could batch write to the log, but want to get each line as it comes out of
192         libhb in case of a crash or freeze so we see exactly what the last thing was before crash*/
193     //NSString *currentOutputLogString = [[NSString alloc]initWithContentsOfFile:outputLogFile encoding:NSUTF8StringEncoding error:NULL];
194     
195     /* Append the new libhb output string to the existing log file string */
196     //currentOutputLogString = [currentOutputLogString stringByAppendingString:newOutputString];
197     /* Save the new modified log file string back to disk */
198     //[currentOutputLogString writeToFile:outputLogFile atomically:YES encoding:NSUTF8StringEncoding error:NULL];
199     /* Release the new libhb output string */
200     //[newOutputString release];
201 }
202 - (void)stdoutRedirect:(NSString *)text { [self stderrRedirect:text]; }
203
204 /**
205  * Clears the output window.
206  */
207 - (IBAction)clearOutput:(id)sender
208 {
209         [outputTextStorage deleteCharactersInRange:NSMakeRange(0, [outputTextStorage length])];
210     /* We want to rewrite the app version info to the top of the activity window so it is always present */
211     NSString *versionStringFull = [[NSString stringWithFormat: NSLocalizedStringFromTable(@"Handbrake Version: %@", @"OutputPanel", @""), [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleGetInfoString"]] stringByAppendingString: [NSString stringWithFormat: @" (%@)", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]]];
212     time_t _now = time( NULL );
213     struct tm * now  = localtime( &_now );
214     fprintf(stderr, "[%02d:%02d:%02d] macgui: %s\n", now->tm_hour, now->tm_min, now->tm_sec, [versionStringFull UTF8String]);
215     
216 }
217
218 /**
219  * Copies all text in the output window to pasteboard.
220  */
221 - (IBAction)copyAllOutputToPasteboard:(id)sender
222 {
223         NSPasteboard *pboard = [NSPasteboard generalPasteboard];
224         [pboard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
225         [pboard setString:[outputTextStorage string] forType:NSStringPboardType];
226     
227 }
228
229 /**
230  * Opens the activity log txt file in users default editor.
231  */
232 - (IBAction)openActivityLogFile:(id)sender
233 {
234     /* Opens the activity window log file in the users default text editor */
235     NSAppleScript *myScript = [[NSAppleScript alloc] initWithSource: [NSString stringWithFormat: @"%@%@%@", NSLocalizedStringFromTable(@"tell application \"Finder\" to open (POSIX file \"", @"OutputPanel", @""), outputLogFile, @"\")"]];
236     [myScript executeAndReturnError: nil];
237     [myScript release];
238 }
239
240 /**
241  * Opens the activity log txt file in users default editor.
242  */
243 - (IBAction)openEncodeLogDirectory:(id)sender
244 {
245     /* Opens the activity window log file in the users default text editor */
246     NSString *libraryDir = [NSSearchPathForDirectoriesInDomains( NSLibraryDirectory,
247                                                                 NSUserDomainMask,
248                                                                 YES ) objectAtIndex:0];
249     NSString *encodeLogDirectory = [[[libraryDir stringByAppendingPathComponent:@"Application Support"] stringByAppendingPathComponent:@"HandBrake"] stringByAppendingPathComponent:@"EncodeLogs"];
250     if( ![[NSFileManager defaultManager] fileExistsAtPath:encodeLogDirectory] )
251     {
252         [[NSFileManager defaultManager] createDirectoryAtPath:encodeLogDirectory
253                                                    attributes:nil];
254     }
255     
256     NSAppleScript *myScript = [[NSAppleScript alloc] initWithSource: [NSString stringWithFormat: @"%@%@%@", NSLocalizedStringFromTable(@"tell application \"Finder\" to open (POSIX file \"", @"OutputPanel", @""), encodeLogDirectory, @"\")"]];
257     [myScript executeAndReturnError: nil];
258     [myScript release];
259 }
260
261 - (IBAction)clearActivityLogFile:(id)sender
262 {
263     /* We overwrite the existing output log with the new date and time header */
264         /* Use the current date and time for the new output log header */
265         NSString *startOutputLogString = [NSString stringWithFormat: NSLocalizedStringFromTable(@"HandBrake Activity Log for Session Starting: %@\n\n", @"OutputPanel", @""), [[NSDate  date] descriptionWithCalendarFormat:nil timeZone:nil locale:nil]];
266         [startOutputLogString writeToFile:outputLogFile atomically:NO encoding:NSUTF8StringEncoding error:NULL];
267         
268         /* We want to rewrite the app version info to the top of the activity window so it is always present */
269         NSString *versionStringFull = [[NSString stringWithFormat: NSLocalizedStringFromTable(@"macgui: Handbrake Version: %@", @"OutputPanel", @""), [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleGetInfoString"]] stringByAppendingString: [NSString stringWithFormat: @" (%@)", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]]];
270         [versionStringFull writeToFile:outputLogFile atomically:NO encoding:NSUTF8StringEncoding error:NULL];
271         
272 }
273
274 - (void)windowWillClose:(NSNotification *)aNotification
275 {
276     [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"OutputPanelIsOpen"];
277 }
278
279
280 @end