diff --git a/.gitignore b/.gitignore index 9904951885..8806b30123 100644 --- a/.gitignore +++ b/.gitignore @@ -40,6 +40,8 @@ # profile - REMOVED temporarily (on double-checking, this seems incorrect; I can't find it in OS X docs?) #profile +# Help indexes +Vienna/**/*.helpindex #### # Xcode temporary files that should never be committed diff --git a/.travis.yml b/.travis.yml index 33522c7b89..53f0b8fe3d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,16 @@ -osx_image: xcode7.1 language: objective-c -before_install: -# - brew update -# - brew upgrade xctool -# - gem install cocoapods +osx_image: xcode8.3 xcode_workspace: Vienna.xcworkspace xcode_scheme: Vienna -before_script: make clean -script: make development + +script: xcodebuild -workspace "$TRAVIS_XCODE_WORKSPACE" -scheme "$TRAVIS_XCODE_SCHEME" test | xcpretty + notifications: - slack: - secure: KaYeG8xgiCCROn0yBrDj0xMI5f1LECVgqJalp+2APy2AdQzHmYQdysiy6c1xNL1//kW3TPAakopgpBwpQ6YTVBfI9F/n9SCvMEwHKKZVT1kwqYJDNwGKXy1tXJKQfhI2x6bs2+HJOgOTLhU+otrDlYyZWEel56q/NzNVx0dwHFs= + webhooks: + urls: + on_failure: always + on_start: never + +# for container-based infrastructure +sudo: false +cache: cocoapods diff --git a/3rdparty/BJRVerticallyCenteredTextFieldCell/BJRVerticallyCenteredTextFieldCell.m b/3rdparty/BJRVerticallyCenteredTextFieldCell/BJRVerticallyCenteredTextFieldCell.m index be9cb731cb..24d3e151f7 100644 --- a/3rdparty/BJRVerticallyCenteredTextFieldCell/BJRVerticallyCenteredTextFieldCell.m +++ b/3rdparty/BJRVerticallyCenteredTextFieldCell/BJRVerticallyCenteredTextFieldCell.m @@ -12,18 +12,17 @@ @implementation BJRVerticallyCenteredTextFieldCell // Deal ourselves with drawing the text inside the cell -(void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView { - NSAttributedString *attrString = self.attributedStringValue; - /* if your values can be attributed strings, make them white when selected */ if (self.isHighlighted && self.backgroundStyle==NSBackgroundStyleDark) { - NSMutableAttributedString *whiteString = [attrString.mutableCopy autorelease]; + NSMutableAttributedString *whiteString = self.attributedStringValue.mutableCopy; [whiteString addAttribute: NSForegroundColorAttributeName value: [NSColor whiteColor] range: NSMakeRange(0, whiteString.length) ]; - attrString = whiteString; + self.attributedStringValue = whiteString; } - [attrString drawWithRect: [self titleRectForBounds:cellFrame] + // Do the actual drawing + [self.attributedStringValue drawWithRect: [self titleRectForBounds:cellFrame] options: NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingDisableScreenFontSubstitution]; } @@ -32,8 +31,7 @@ - (NSRect)titleRectForBounds:(NSRect)theRect { NSRect titleFrame = [super titleRectForBounds:theRect]; /* find out how big the rendered text will be */ - NSAttributedString *attrString = self.attributedStringValue; - NSRect textRect = [attrString boundingRectWithSize: titleFrame.size + NSRect textRect = [self.attributedStringValue boundingRectWithSize: titleFrame.size options: NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingDisableScreenFontSubstitution]; CGFloat tHeight = textRect.size.height; diff --git a/3rdparty/DSClickableURLTextField/DSClickableURLTextField.h b/3rdparty/DSClickableURLTextField/DSClickableURLTextField.h index c1d3d7ae50..d41724e981 100644 --- a/3rdparty/DSClickableURLTextField/DSClickableURLTextField.h +++ b/3rdparty/DSClickableURLTextField/DSClickableURLTextField.h @@ -58,8 +58,7 @@ BOOL canCopyURLs; } -- (void)setCanCopyURLs:(BOOL)aFlag; -- (BOOL)canCopyURLs; +@property (nonatomic) BOOL canCopyURLs; @end diff --git a/3rdparty/DSClickableURLTextField/DSClickableURLTextField.m b/3rdparty/DSClickableURLTextField/DSClickableURLTextField.m index db1a394020..27ce17f7ee 100644 --- a/3rdparty/DSClickableURLTextField/DSClickableURLTextField.m +++ b/3rdparty/DSClickableURLTextField/DSClickableURLTextField.m @@ -55,7 +55,7 @@ @implementation DSClickableURLTextField /* Set the text field to be non-editable and non-selectable. */ -- (id)initWithCoder:(NSCoder *)coder +- (instancetype)initWithCoder:(NSCoder *)coder { if ( (self = [super initWithCoder:coder]) ) { [self setEditable:NO]; @@ -68,7 +68,7 @@ - (id)initWithCoder:(NSCoder *)coder /* Set the text field to be non-editable and non-selectable. */ -- (id)initWithFrame:(NSRect)frameRect +- (instancetype)initWithFrame:(NSRect)frameRect { if ( (self = [super initWithFrame:frameRect]) ) { [self setEditable:NO]; @@ -79,13 +79,6 @@ - (id)initWithFrame:(NSRect)frameRect return self; } -- (void)dealloc -{ - [clickedURL release]; - [URLStorage release]; - - [super dealloc]; -} /* Enforces that the text field be non-editable and non-selectable. Probably not needed, but I always @@ -100,14 +93,14 @@ - (void)awakeFromNib - (void)setAttributedStringValue:(NSAttributedString *)aStr { [URLStorage setAttributedString:aStr]; - [[self window] invalidateCursorRectsForView:self]; - [super setAttributedStringValue:aStr]; + [self.window invalidateCursorRectsForView:self]; + super.attributedStringValue = aStr; } - (void)setStringValue:(NSString *)aStr { - NSAttributedString *attrString = [[[NSAttributedString alloc] initWithString:aStr attributes:nil] autorelease]; - [self setAttributedStringValue:attrString]; + NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:aStr attributes:nil]; + self.attributedStringValue = attrString; } - (void)setCanCopyURLs:(BOOL)aFlag @@ -122,28 +115,28 @@ - (BOOL)canCopyURLs - (void)resetCursorRects { - if ( [[self attributedStringValue] length] == 0 ) { + if ( self.attributedStringValue.length == 0 ) { [super resetCursorRects]; return; } - NSRect cellBounds = [[self cell] drawingRectForBounds:[self bounds]]; + NSRect cellBounds = [self.cell drawingRectForBounds:self.bounds]; if ( URLStorage == nil ) { - BOOL cellWraps = ![[self cell] isScrollable]; + BOOL cellWraps = !self.cell.scrollable; NSSize containerSize = NSMakeSize( cellWraps ? cellBounds.size.width : MAXFLOAT, cellWraps ? MAXFLOAT : cellBounds.size.height ); - URLContainer = [[[NSTextContainer alloc] initWithContainerSize:containerSize] autorelease]; - URLManager = [[[NSLayoutManager alloc] init] autorelease]; + URLContainer = [[NSTextContainer alloc] initWithContainerSize:containerSize]; + URLManager = [[NSLayoutManager alloc] init]; URLStorage = [[NSTextStorage alloc] init]; [URLStorage addLayoutManager:URLManager]; [URLManager addTextContainer:URLContainer]; - [URLContainer setLineFragmentPadding:2.f]; + URLContainer.lineFragmentPadding = 2.f; - [URLStorage setAttributedString:[self attributedStringValue]]; + [URLStorage setAttributedString:self.attributedStringValue]; } - NSUInteger myLength = [URLStorage length]; + NSUInteger myLength = URLStorage.length; NSRange returnRange = { NSNotFound, 0 }, stringRange = { 0, myLength }, glyphRange = { NSNotFound, 0 }; NSCursor *pointingCursor = nil; @@ -157,7 +150,7 @@ - (void)resetCursorRects /* Moved out of the while and for loops as there's no need to recalculate it every time through */ - NSRect superVisRect = [self convertRect:[[self superview] visibleRect] fromView:[self superview]]; + NSRect superVisRect = [self convertRect:self.superview.visibleRect fromView:self.superview]; while ( stringRange.location < myLength ) { id aVal = [URLStorage attribute:NSLinkAttributeName atIndex:stringRange.location longestEffectiveRange:&returnRange inRange:stringRange]; @@ -186,10 +179,10 @@ - (void)resetCursorRects - (NSURL*)urlAtMouse:(NSEvent *)mouseEvent { NSURL* urlAtMouse = nil; - NSPoint mousePoint = [self convertPoint:[mouseEvent locationInWindow] fromView:nil]; - NSRect cellBounds = [[self cell] drawingRectForBounds:[self bounds]]; + NSPoint mousePoint = [self convertPoint:mouseEvent.locationInWindow fromView:nil]; + NSRect cellBounds = [self.cell drawingRectForBounds:self.bounds]; - if ( ([URLStorage length] > 0 ) && [self mouse:mousePoint inRect:cellBounds] ) { + if ( (URLStorage.length > 0 ) && [self mouse:mousePoint inRect:cellBounds] ) { id aVal = nil; NSRange returnRange = { NSNotFound, 0 }, glyphRange = { NSNotFound, 0 }; NSRectArray linkRect = NULL; @@ -197,7 +190,7 @@ - (NSURL*)urlAtMouse:(NSEvent *)mouseEvent NSUInteger charIndex = [URLManager characterIndexForGlyphAtIndex:glyphIndex]; NSUInteger numRects = 0, j = 0; - aVal = [URLStorage attribute:NSLinkAttributeName atIndex:charIndex longestEffectiveRange:&returnRange inRange:NSMakeRange(charIndex, [URLStorage length] - charIndex)]; + aVal = [URLStorage attribute:NSLinkAttributeName atIndex:charIndex longestEffectiveRange:&returnRange inRange:NSMakeRange(charIndex, URLStorage.length - charIndex)]; if ( (aVal != nil) ) { glyphRange = [URLManager glyphRangeForCharacterRange:returnRange actualCharacterRange:nil]; linkRect = [URLManager rectArrayForGlyphRange:glyphRange withinSelectedGlyphRange:glyphRange inTextContainer:URLContainer rectCount:&numRects]; @@ -226,10 +219,10 @@ - (NSMenu *)menuForEvent:(NSEvent *)aEvent NSURL *anURL = [self urlAtMouse:aEvent]; if ( anURL != nil ) { - NSMenu *aMenu = [[[NSMenu alloc] initWithTitle:@"Copy URL"] autorelease]; - NSMenuItem *anItem = [[[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Copy URL", @"Copy URL") action:@selector(copyURL:) keyEquivalent:@""] autorelease]; - [anItem setTarget:self]; - [anItem setRepresentedObject:anURL]; + NSMenu *aMenu = [[NSMenu alloc] initWithTitle:@"Copy URL"]; + NSMenuItem *anItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Copy URL", @"Copy URL") action:@selector(copyURL:) keyEquivalent:@""]; + anItem.target = self; + anItem.representedObject = anURL; [aMenu addItem:anItem]; return aMenu; @@ -243,9 +236,9 @@ - (void)copyURL:(id)sender NSPasteboard *copyBoard = [NSPasteboard pasteboardWithName:NSGeneralPboard]; NSURL *copyURL = [sender representedObject]; - [copyBoard declareTypes:[NSArray arrayWithObjects:NSURLPboardType, NSStringPboardType, nil] owner:nil]; + [copyBoard declareTypes:@[NSURLPboardType, NSStringPboardType] owner:nil]; [copyURL writeToPasteboard:copyBoard]; - [copyBoard setString:[copyURL absoluteString] forType:NSStringPboardType]; + [copyBoard setString:copyURL.absoluteString forType:NSStringPboardType]; } - (void)mouseDown:(NSEvent *)mouseEvent @@ -256,8 +249,7 @@ - (void)mouseDown:(NSEvent *)mouseEvent /* Remember which URL was clicked originally, so we don't end up opening the wrong URL accidentally. */ - [clickedURL release]; - clickedURL = [[self urlAtMouse:mouseEvent] retain]; + clickedURL = [self urlAtMouse:mouseEvent]; } - (void)mouseUp:(NSEvent *)mouseEvent @@ -265,10 +257,9 @@ - (void)mouseUp:(NSEvent *)mouseEvent NSURL* urlAtMouse = [self urlAtMouse:mouseEvent]; if ( (urlAtMouse != nil) && [urlAtMouse isEqualTo:clickedURL] ) { // check if delegate wants to open the URL itself, if not, let the workspace open the URL - if ( ([self delegate] == nil) || ![[self delegate] respondsToSelector:@selector(textField:openURL:)] || ![(id)[self delegate] textField:self openURL:urlAtMouse] ) + if ( (self.delegate == nil) || ![self.delegate respondsToSelector:@selector(textField:openURL:)] || ![(id)self.delegate textField:self openURL:urlAtMouse] ) [[NSWorkspace sharedWorkspace] openURL:urlAtMouse]; } - [clickedURL release]; clickedURL = nil; [super mouseUp:mouseEvent]; } diff --git a/3rdparty/DisclosableView/Info-DisclosableView.plist b/3rdparty/DisclosableView/Info-DisclosableView.plist index e8aeabbcf7..2d76c26412 100644 --- a/3rdparty/DisclosableView/Info-DisclosableView.plist +++ b/3rdparty/DisclosableView/Info-DisclosableView.plist @@ -1,5 +1,5 @@ - + CFBundleDevelopmentRegion @@ -11,7 +11,7 @@ CFBundleIconFile CFBundleIdentifier - com.snoize.DisclosableView + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/3rdparty/DisclosableView/SNDisclosableView.h b/3rdparty/DisclosableView/SNDisclosableView.h index d01a6b2747..d3967b4dfa 100644 --- a/3rdparty/DisclosableView/SNDisclosableView.h +++ b/3rdparty/DisclosableView/SNDisclosableView.h @@ -24,11 +24,9 @@ NSSize sizeBeforeHidden; } -- (BOOL)isShown; -- (void)setShown:(BOOL)value; +@property (nonatomic, getter=isShown) BOOL shown; -- (float)hiddenHeight; -- (void)setHiddenHeight:(float)value; +@property (nonatomic) float hiddenHeight; // Actions - (IBAction)toggleDisclosure:(id)sender; diff --git a/3rdparty/DisclosableView/SNDisclosableView.m b/3rdparty/DisclosableView/SNDisclosableView.m index 8949aee995..165f91cd4e 100644 --- a/3rdparty/DisclosableView/SNDisclosableView.m +++ b/3rdparty/DisclosableView/SNDisclosableView.m @@ -30,44 +30,38 @@ @implementation SNDisclosableView const float kDefaultHiddenHeight = 0.0; -- (id)initWithFrame:(NSRect)frameRect; +- (instancetype)initWithFrame:(NSRect)frameRect; { if (!(self = [super initWithFrame:frameRect])) return nil; isShown = YES; - originalHeight = [self frame].size.height; + originalHeight = self.frame.size.height; hiddenHeight = kDefaultHiddenHeight; return self; } -- (id)initWithCoder:(NSCoder *)aDecoder; +- (instancetype)initWithCoder:(NSCoder *)aDecoder; { if (!(self = [super initWithCoder:aDecoder])) return nil; isShown = YES; - originalHeight = [self frame].size.height; + originalHeight = self.frame.size.height; hiddenHeight = kDefaultHiddenHeight; [aDecoder decodeValueOfObjCType:@encode(typeof(hiddenHeight)) at:&hiddenHeight]; return self; } -- (void)dealloc; -{ - [hiddenSubviews release]; - - [super dealloc]; -} - (void)awakeFromNib; { - if ([[self superclass] instancesRespondToSelector:@selector(awakeFromNib)]) + if ([self.superclass instancesRespondToSelector:@selector(awakeFromNib)]) [super awakeFromNib]; - if ([self autoresizingMask] & NSViewHeightSizable) + if (self.autoresizingMask & NSViewHeightSizable) NSLog(@"Warning: SNDisclosableView: You probably don't want this view to be resizeable vertically. I suggest turning that off in the inspector in IB."); } @@ -115,7 +109,7 @@ - (void)setHiddenHeight:(float)value; - (IBAction)toggleDisclosure:(id)sender; { - [self setShown:!isShown]; + self.shown = !isShown; } - (IBAction)hide:(id)sender; @@ -125,7 +119,7 @@ - (IBAction)hide:(id)sender; if (!isShown) return; - keyLoopView = [self nextKeyView]; + keyLoopView = self.nextKeyView; if ([keyLoopView isDescendantOf:self]) { // We need to remove our subviews (which will be hidden) from the key loop. @@ -134,7 +128,7 @@ - (IBAction)hide:(id)sender; // Find the last view in the key loop which is one of our descendants. nonretainedLastChildKeyView = keyLoopView; - while ((keyLoopView = [nonretainedLastChildKeyView nextKeyView])) { + while ((keyLoopView = nonretainedLastChildKeyView.nextKeyView)) { if ([keyLoopView isDescendantOf:self]) nonretainedLastChildKeyView = keyLoopView; else @@ -143,7 +137,7 @@ - (IBAction)hide:(id)sender; // Set our nextKeyView to its nextKeyView, and set its nextKeyView to nil. // (If we don't do the last step, when we restore the key loop later, it will be missing views in the backwards direction.) - [self setNextKeyView:keyLoopView]; + self.nextKeyView = keyLoopView; [nonretainedLastChildKeyView setNextKeyView:nil]; } else { nonretainedOriginalNextKeyView = nil; @@ -152,7 +146,7 @@ - (IBAction)hide:(id)sender; // Remember our current size. // When showing, we will use this to resize the subviews properly. // (The window width may change while the subviews are hidden.) - sizeBeforeHidden = [self frame].size; + sizeBeforeHidden = self.frame.size; // Now shrink the window, causing this view to shrink and our subviews to be obscured. // Also remove the subviews from the view hierarchy. @@ -176,7 +170,7 @@ - (IBAction)show:(id)sender; // Then tell our subviews to resize themselves, according to their normal autoresize masks. // (This may cause their widths to change, if the window was resized horizontally while the subviews were out of the view hierarchy.) // Then set our frame size back so we are hidden again. - NSSize hiddenSize = [self frame].size; + NSSize hiddenSize = self.frame.size; [self setFrameSize:NSMakeSize(hiddenSize.width, originalHeight)]; [self resizeSubviewsWithOldSize:sizeBeforeHidden]; [self setFrameSize:hiddenSize]; @@ -185,8 +179,8 @@ - (IBAction)show:(id)sender; if (nonretainedOriginalNextKeyView) { // Restore the key loop to its old configuration. - [nonretainedLastChildKeyView setNextKeyView:[self nextKeyView]]; - [self setNextKeyView:nonretainedOriginalNextKeyView]; + nonretainedLastChildKeyView.nextKeyView = self.nextKeyView; + self.nextKeyView = nonretainedOriginalNextKeyView; } isShown = YES; @@ -205,10 +199,10 @@ - (void)removeSubviews; NSAssert(hiddenSubviews == nil, @"-[SNDisclosableView removeSubviews]: should have no hidden subviews yet"); - hiddenSubviews = [[NSArray alloc] initWithArray:[self subviews]]; - subviewIndex = [hiddenSubviews count]; + hiddenSubviews = [[NSArray alloc] initWithArray:self.subviews]; + subviewIndex = hiddenSubviews.count; while (subviewIndex--) - [[hiddenSubviews objectAtIndex:subviewIndex] removeFromSuperview]; + [hiddenSubviews[subviewIndex] removeFromSuperview]; } - (void)restoreSubviews; @@ -217,11 +211,10 @@ - (void)restoreSubviews; NSAssert(hiddenSubviews != nil, @"-[SNDisclosableView restoreSubviews]: hiddenSubviews array is nil"); - subviewIndex = [hiddenSubviews count]; + subviewIndex = hiddenSubviews.count; while (subviewIndex--) - [self addSubview:[hiddenSubviews objectAtIndex:subviewIndex]]; + [self addSubview:hiddenSubviews[subviewIndex]]; - [hiddenSubviews release]; hiddenSubviews = nil; } @@ -251,48 +244,48 @@ - (void)changeWindowHeightBy:(float)amount; NSRect newWindowFrame; NSSize newWindowMinOrMaxSize; - window = [self window]; + window = self.window; // Compute the window's new frame. - newWindowFrame = [window frame]; + newWindowFrame = window.frame; newWindowFrame.origin.y -= amount; newWindowFrame.size.height += amount; // If we're growing a visible window, will AppKit constrain it? It might not fit on the screen. - if ([window isVisible] && amount > 0) { - NSRect constrainedNewWindowFrame = [window constrainFrameRect:newWindowFrame toScreen:[window screen]]; + if (window.visible && amount > 0) { + NSRect constrainedNewWindowFrame = [window constrainFrameRect:newWindowFrame toScreen:window.screen]; if (constrainedNewWindowFrame.size.height < newWindowFrame.size.height) { // We can't actually make the window that size. Something will have to give. // Shrink to a height such that, when we grow later on, the window will fit. float shrunkenHeight = constrainedNewWindowFrame.size.height - amount; - NSRect immediateNewFrame = [window frame]; + NSRect immediateNewFrame = window.frame; immediateNewFrame.origin.y += (immediateNewFrame.size.height - shrunkenHeight); immediateNewFrame.size.height = shrunkenHeight; [window setFrame:immediateNewFrame display:YES animate:YES]; // Have to recompute based on the new frame... - newWindowFrame = [window frame]; + newWindowFrame = window.frame; newWindowFrame.origin.y -= amount; newWindowFrame.size.height += amount; } } // Now that we're in a configuration where we can change the window's size how we want, start with our current frame. - ourFrame = [self frame]; + ourFrame = self.frame; // Adjust the autoresize masks of the window's subviews, remembering the original masks. - windowSubviews = [[window contentView] subviews]; + windowSubviews = window.contentView.subviews; windowSubviewMasks = [NSMutableArray array]; for (NSView* windowSubview in windowSubviews) { - NSUInteger mask = [windowSubview autoresizingMask]; - [windowSubviewMasks addObject:[NSNumber numberWithUnsignedInteger:mask]]; + NSUInteger mask = windowSubview.autoresizingMask; + [windowSubviewMasks addObject:@(mask)]; if (windowSubview == self) { // This is us. Make us stick to the top and bottom of the window, and resize vertically. mask |= NSViewHeightSizable; mask &= ~NSViewMaxYMargin; mask &= ~NSViewMinYMargin; - } else if (NSMaxY([windowSubview frame]) < NSMaxY(ourFrame)) { + } else if (NSMaxY(windowSubview.frame) < NSMaxY(ourFrame)) { // This subview is below us. Make it stick to the bottom of the window. // It should not change height. mask &= ~NSViewHeightSizable; @@ -306,46 +299,46 @@ - (void)changeWindowHeightBy:(float)amount; mask |= NSViewMinYMargin; } - [windowSubview setAutoresizingMask:mask]; + windowSubview.autoresizingMask = mask; } // Adjust the autoresize masks of our subviews, remembering the original masks. - ourSubviews = [self subviews]; + ourSubviews = self.subviews; ourSubviewMasks = [NSMutableArray array]; for (NSView* ourSubview in ourSubviews) { - NSUInteger mask = [ourSubview autoresizingMask]; - [ourSubviewMasks addObject:[NSNumber numberWithUnsignedInt:mask]]; + NSAutoresizingMaskOptions mask = ourSubview.autoresizingMask; + [ourSubviewMasks addObject:@((NSUInteger)mask)]; // Don't change height, and stick to the top of the view. mask &= ~NSViewHeightSizable; mask &= ~NSViewMaxYMargin; mask |= NSViewMinYMargin; - [ourSubview setAutoresizingMask:mask]; + ourSubview.autoresizingMask = mask; } // Finally we can resize the window. - if ([window isVisible]) { - BOOL didPreserve = [window preservesContentDuringLiveResize]; + if (window.visible) { + BOOL didPreserve = window.preservesContentDuringLiveResize; [window setPreservesContentDuringLiveResize:NO]; [window setFrame:newWindowFrame display:YES animate:YES]; - [window setPreservesContentDuringLiveResize:didPreserve]; + window.preservesContentDuringLiveResize = didPreserve; } else { [window setFrame:newWindowFrame display:NO]; } // Adjust the window's min and max sizes to make sense. - newWindowMinOrMaxSize = [window minSize]; + newWindowMinOrMaxSize = window.minSize; newWindowMinOrMaxSize.height += amount; - [window setMinSize:newWindowMinOrMaxSize]; + window.minSize = newWindowMinOrMaxSize; - newWindowMinOrMaxSize = [window maxSize]; + newWindowMinOrMaxSize = window.maxSize; // If there is no max size set (height of 0), don't change it. if (newWindowMinOrMaxSize.height > 0) { newWindowMinOrMaxSize.height += amount; - [window setMaxSize:newWindowMinOrMaxSize]; + window.maxSize = newWindowMinOrMaxSize; } // Restore the saved autoresize masks. @@ -357,9 +350,9 @@ - (void)restoreAutoresizeMasks:(NSArray *)masks toViews:(NSArray *)views; { NSUInteger count, index; - count = [masks count]; + count = masks.count; for (index = 0; index < count; index++) - [(NSView*)[views objectAtIndex:index] setAutoresizingMask:[[masks objectAtIndex:index] unsignedIntValue]]; + ((NSView*)views[index]).autoresizingMask = [masks[index] unsignedIntValue]; } @end diff --git a/3rdparty/DisclosableView/SNDisclosureButton.m b/3rdparty/DisclosableView/SNDisclosureButton.m index 1454dccf61..cc79817292 100644 --- a/3rdparty/DisclosableView/SNDisclosureButton.m +++ b/3rdparty/DisclosableView/SNDisclosureButton.m @@ -23,7 +23,7 @@ - (NSImage *)imageNamed:(NSString *)imageName; @implementation SNDisclosureButton -- (id)initWithFrame:(NSRect)frame +- (instancetype)initWithFrame:(NSRect)frame { if (!(self = [super initWithFrame:frame])) return nil; @@ -51,16 +51,16 @@ - (void)configureDisclosureButton // Something is wrong with the linker and constant NSStrings can cause a crash to happen later on. char* imageName = "SNDisclosureArrowDown"; char* altImageName = "SNDisclosureArrowRight"; - NSString* imageNameStr = [NSString stringWithUTF8String:imageName]; - NSString* altImageNameStr = [NSString stringWithUTF8String:altImageName]; + NSString* imageNameStr = @(imageName); + NSString* altImageNameStr = @(altImageName); if ((image = [self imageNamed:imageNameStr])) - [self setImage:image]; + self.image = image; if ((image = [self imageNamed:altImageNameStr])) - [self setAlternateImage:image]; + self.alternateImage = image; - [[self cell] setHighlightsBy:NSPushInCellMask]; + ((NSButtonCell *)self.cell).highlightsBy = NSPushInCellMask; } - (NSImage *)imageNamed:(NSString *)imageName @@ -72,7 +72,7 @@ - (NSImage *)imageNamed:(NSString *)imageName bundle = [NSBundle bundleForClass:[self class]]; imagePath = [bundle pathForImageResource:imageName]; if (imagePath) { - image = [[[NSImage alloc] initByReferencingFile:imagePath] autorelease]; + image = [[NSImage alloc] initByReferencingFile:imagePath]; if (!image) NSLog(@"SNDisclosureButton: couldn't read image: %@", imagePath); } else { diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMAdiumTabStyle.h b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMAdiumTabStyle.h index 8d82cb41eb..68f8bfa045 100644 --- a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMAdiumTabStyle.h +++ b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMAdiumTabStyle.h @@ -26,14 +26,14 @@ BOOL _drawsRight; } +- (instancetype)init __attribute((objc_designated_initializer)); + - (void)loadImages; -- (BOOL)drawsUnified; -- (void)setDrawsUnified:(BOOL)value; -- (BOOL)drawsRight; -- (void)setDrawsRight:(BOOL)value; +@property (NS_NONATOMIC_IOSONLY) BOOL drawsUnified; +@property (NS_NONATOMIC_IOSONLY) BOOL drawsRight; - (void)encodeWithCoder:(NSCoder *)aCoder; -- (id)initWithCoder:(NSCoder *)aDecoder; +- (instancetype)initWithCoder:(NSCoder *)aDecoder __attribute((objc_designated_initializer)); @end diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMAquaTabStyle.h b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMAquaTabStyle.h index f4e54f6a38..f23aaa14a7 100644 --- a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMAquaTabStyle.h +++ b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMAquaTabStyle.h @@ -30,6 +30,6 @@ - (void)loadImages; - (void)encodeWithCoder:(NSCoder *)aCoder; -- (id)initWithCoder:(NSCoder *)aDecoder; +- (instancetype)initWithCoder:(NSCoder *)aDecoder; @end diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMMetalTabStyle.h b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMMetalTabStyle.h index 3e26edda5e..1d10e6b6fb 100644 --- a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMMetalTabStyle.h +++ b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMMetalTabStyle.h @@ -24,6 +24,6 @@ } - (void)encodeWithCoder:(NSCoder *)aCoder; -- (id)initWithCoder:(NSCoder *)aDecoder; +- (instancetype)initWithCoder:(NSCoder *)aDecoder; @end diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMOverflowPopUpButton.h b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMOverflowPopUpButton.h index f96dafa3f6..e76c18904e 100644 --- a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMOverflowPopUpButton.h +++ b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMOverflowPopUpButton.h @@ -18,11 +18,12 @@ CGFloat _animationValue; } +- (instancetype)initWithFrame:(NSRect)frameRect pullsDown:(BOOL)flag __attribute((objc_designated_initializer)); + //alternate image display -- (BOOL)animatingAlternateImage; -- (void)setAnimatingAlternateImage:(BOOL)flag; +@property (NS_NONATOMIC_IOSONLY) BOOL animatingAlternateImage; // archiving - (void)encodeWithCoder:(NSCoder *)aCoder; -- (id)initWithCoder:(NSCoder *)aDecoder; +- (instancetype)initWithCoder:(NSCoder *)aDecoder __attribute((objc_designated_initializer)); @end diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMRolloverButton.h b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMRolloverButton.h index 76d069de24..df793a19e2 100644 --- a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMRolloverButton.h +++ b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMRolloverButton.h @@ -13,7 +13,7 @@ NSImage *_usualImage; } -@property (retain) NSImage *usualImage; -@property (retain) NSImage *rolloverImage; +@property (strong) NSImage *usualImage; +@property (strong) NSImage *rolloverImage; @end \ No newline at end of file diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabBarCell.h b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabBarCell.h index cc55cadd80..cca84b39c9 100644 --- a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabBarCell.h +++ b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabBarCell.h @@ -53,34 +53,29 @@ typedef enum PSMTabBarCellTrackingAreaType : NSUInteger @property (assign) BOOL hasIcon; @property (assign) BOOL hasLargeImage; @property (assign) NSInteger count; -@property (retain) NSColor *countColor; +@property (strong) NSColor *countColor; @property (assign) BOOL isPlaceholder; @property (assign) BOOL isEdited; @property (assign) BOOL closeButtonPressed; #pragma mark Creation/Destruction -- (id)init; -- (id)initPlaceholderWithFrame:(NSRect) frame expanded:(BOOL) value inTabBarControl:(PSMTabBarControl *)tabBarControl; +- (instancetype)init; +- (instancetype)initPlaceholderWithFrame:(NSRect) frame expanded:(BOOL) value inTabBarControl:(PSMTabBarControl *)tabBarControl; - (void)dealloc; #pragma mark Accessors -//- (PSMTabBarControl *)controlView; -//- (void)setControlView:(PSMTabBarControl *)newControl; -- (CGFloat)width; -- (NSRect)frame; -- (void)setFrame:(NSRect)rect; -- (NSSize)attributedStringSize; -- (NSAttributedString *)attributedStringValue; -- (NSAttributedString *)attributedObjectCountStringValue; -- (NSProgressIndicator *)indicator; -- (BOOL)isInOverflowMenu; -- (void)setIsInOverflowMenu:(BOOL)value; -- (BOOL)closeButtonOver; -- (void)setCloseButtonOver:(BOOL)value; -- (void)setCloseButtonSuppressed:(BOOL)suppress; -- (BOOL)isCloseButtonSuppressed; -- (NSInteger)currentStep; -- (void)setCurrentStep:(NSInteger)value; +- (PSMTabBarControl *)controlView; +- (void)setControlView:(PSMTabBarControl *)newControl; +@property (NS_NONATOMIC_IOSONLY, readonly) CGFloat width; +@property (NS_NONATOMIC_IOSONLY) NSRect frame; +@property (NS_NONATOMIC_IOSONLY, readonly) NSSize attributedStringSize; +@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSAttributedString *attributedStringValue; +@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSAttributedString *attributedObjectCountStringValue; +@property (NS_NONATOMIC_IOSONLY, readonly, strong) NSProgressIndicator *indicator; +@property (NS_NONATOMIC_IOSONLY) BOOL isInOverflowMenu; +@property (NS_NONATOMIC_IOSONLY) BOOL closeButtonOver; +@property (NS_NONATOMIC_IOSONLY, getter=isCloseButtonSuppressed) BOOL closeButtonSuppressed; +@property (NS_NONATOMIC_IOSONLY) NSInteger currentStep; #pragma mark Providing Images - (NSImage *)closeButtonImageOfType:(PSMCloseButtonImageType)type; @@ -91,19 +86,19 @@ typedef enum PSMTabBarCellTrackingAreaType : NSUInteger - (NSRect)iconRectForBounds:(NSRect)theRect; - (NSRect)largeImageRectForBounds:(NSRect)theRect; - (NSRect)indicatorRectForBounds:(NSRect)theRect; -- (NSSize)objectCounterSize; +@property (NS_NONATOMIC_IOSONLY, readonly) NSSize objectCounterSize; - (NSRect)objectCounterRectForBounds:(NSRect)theRect; - (NSRect)closeButtonRectForBounds:(NSRect)theRect; -- (CGFloat)minimumWidthOfCell; -- (CGFloat)desiredWidthOfCell; +@property (NS_NONATOMIC_IOSONLY, readonly) CGFloat minimumWidthOfCell; +@property (NS_NONATOMIC_IOSONLY, readonly) CGFloat desiredWidthOfCell; #pragma mark Image Scaling - (NSSize)scaleImageWithSize:(NSSize)imageSize toFitInSize:(NSSize)canvasSize scalingType:(NSImageScaling)scalingType; #pragma mark Drawing -- (BOOL)shouldDrawCloseButton; -- (BOOL)shouldDrawObjectCounter; +@property (NS_NONATOMIC_IOSONLY, readonly) BOOL shouldDrawCloseButton; +@property (NS_NONATOMIC_IOSONLY, readonly) BOOL shouldDrawObjectCounter; - (void)drawWithFrame:(NSRect) cellFrame inTabBarControl:(PSMTabBarControl *)tabBarControl; - (void)drawInteriorWithFrame:(NSRect)cellFrame inTabBarControl:(PSMTabBarControl *)tabBarControl; - (void)drawLargeImageWithFrame:(NSRect)frame inTabBarControl:(PSMTabBarControl *)tabBarControl; @@ -119,24 +114,24 @@ typedef enum PSMTabBarCellTrackingAreaType : NSUInteger - (void)mouseExited:(NSEvent *)theEvent; #pragma mark Drag Support -- (NSRect)draggingRect; -- (NSImage *)dragImage; +@property (NS_NONATOMIC_IOSONLY, readonly) NSRect draggingRect; +@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSImage *dragImage; #pragma mark Archiving - (void)encodeWithCoder:(NSCoder *)aCoder; -- (id)initWithCoder:(NSCoder *)aDecoder; +- (instancetype)initWithCoder:(NSCoder *)aDecoder; @end @interface PSMTabBarControl (CellAccessors) -- (id)style; +@property (NS_NONATOMIC_IOSONLY, readonly, strong) id style; @end @interface NSObject (IdentifierAccesors) -- (NSImage *)largeImage; +@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSImage *largeImage; @end diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabBarControl.h b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabBarControl.h index c855263b8c..199e078b5b 100644 --- a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabBarControl.h +++ b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabBarControl.h @@ -64,7 +64,7 @@ typedef enum PSMTabStateMask : NSInteger { @protocol PSMTabBarControlDelegate; -@interface PSMTabBarControl : NSControl { +@interface PSMTabBarControl : NSControl { // control basics NSMutableArray *_cells; // the cells that draw the tabs @@ -126,10 +126,10 @@ typedef enum PSMTabStateMask : NSInteger { #pragma mark Control Characteristics + (NSBundle *)bundle; -- (CGFloat)availableCellWidth; -- (CGFloat)availableCellHeight; -- (NSRect)genericCellRect; -- (BOOL)isWindowActive; +@property (NS_NONATOMIC_IOSONLY, readonly) CGFloat availableCellWidth; +@property (NS_NONATOMIC_IOSONLY, readonly) CGFloat availableCellHeight; +@property (NS_NONATOMIC_IOSONLY, readonly) NSRect genericCellRect; +@property (NS_NONATOMIC_IOSONLY, getter=isWindowActive, readonly) BOOL windowActive; #pragma mark Style Class Registry @@ -141,7 +141,7 @@ typedef enum PSMTabStateMask : NSInteger { #pragma mark Cell Management (KVC Compliant) -- (NSArray *)cells; +@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSArray *cells; - (void)addCell:(PSMTabBarCell *)aCell; - (void)insertCell:(PSMTabBarCell *)aCell atIndex:(NSUInteger)index; - (void)removeCellAtIndex:(NSUInteger)index; @@ -149,87 +149,66 @@ typedef enum PSMTabStateMask : NSInteger { #pragma mark Control Configuration -- (PSMTabBarOrientation)orientation; -- (void)setOrientation:(PSMTabBarOrientation)value; -- (BOOL)canCloseOnlyTab; -- (void)setCanCloseOnlyTab:(BOOL)value; -- (BOOL)disableTabClose; -- (void)setDisableTabClose:(BOOL)value; -- (id)style; -- (void)setStyle:(id )newStyle; -- (NSString *)styleName; +@property (NS_NONATOMIC_IOSONLY) PSMTabBarOrientation orientation; +@property (NS_NONATOMIC_IOSONLY) BOOL canCloseOnlyTab; +@property (NS_NONATOMIC_IOSONLY) BOOL disableTabClose; +@property (NS_NONATOMIC_IOSONLY, strong) id style; +@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSString *styleName; - (void)setStyleNamed:(NSString *)name; -- (BOOL)hideForSingleTab; -- (void)setHideForSingleTab:(BOOL)value; -- (BOOL)showAddTabButton; -- (void)setShowAddTabButton:(BOOL)value; -- (NSInteger)cellMinWidth; -- (void)setCellMinWidth:(NSInteger)value; -- (NSInteger)cellMaxWidth; -- (void)setCellMaxWidth:(NSInteger)value; -- (NSInteger)cellOptimumWidth; -- (void)setCellOptimumWidth:(NSInteger)value; -- (BOOL)sizeCellsToFit; -- (void)setSizeCellsToFit:(BOOL)value; -- (BOOL)useOverflowMenu; -- (void)setUseOverflowMenu:(BOOL)value; -- (BOOL)allowsBackgroundTabClosing; -- (void)setAllowsBackgroundTabClosing:(BOOL)value; -- (BOOL)allowsResizing; -- (void)setAllowsResizing:(BOOL)value; -- (BOOL)selectsTabsOnMouseDown; -- (void)setSelectsTabsOnMouseDown:(BOOL)value; -- (BOOL)automaticallyAnimates; -- (void)setAutomaticallyAnimates:(BOOL)value; -- (BOOL)alwaysShowActiveTab; -- (void)setAlwaysShowActiveTab:(BOOL)value; -- (BOOL)allowsScrubbing; -- (void)setAllowsScrubbing:(BOOL)value; -- (PSMTabBarTearOffStyle)tearOffStyle; -- (void)setTearOffStyle:(PSMTabBarTearOffStyle)tearOffStyle; -- (CGFloat)heightOfTabCells; +@property (NS_NONATOMIC_IOSONLY) BOOL hideForSingleTab; +@property (NS_NONATOMIC_IOSONLY) BOOL showAddTabButton; +@property (NS_NONATOMIC_IOSONLY) NSInteger cellMinWidth; +@property (NS_NONATOMIC_IOSONLY) NSInteger cellMaxWidth; +@property (NS_NONATOMIC_IOSONLY) NSInteger cellOptimumWidth; +@property (NS_NONATOMIC_IOSONLY) BOOL sizeCellsToFit; +@property (NS_NONATOMIC_IOSONLY) BOOL useOverflowMenu; +@property (NS_NONATOMIC_IOSONLY) BOOL allowsBackgroundTabClosing; +@property (NS_NONATOMIC_IOSONLY) BOOL allowsResizing; +@property (NS_NONATOMIC_IOSONLY) BOOL selectsTabsOnMouseDown; +@property (NS_NONATOMIC_IOSONLY) BOOL automaticallyAnimates; +@property (NS_NONATOMIC_IOSONLY) BOOL alwaysShowActiveTab; +@property (NS_NONATOMIC_IOSONLY) BOOL allowsScrubbing; +@property (NS_NONATOMIC_IOSONLY) PSMTabBarTearOffStyle tearOffStyle; +@property (NS_NONATOMIC_IOSONLY, readonly) CGFloat heightOfTabCells; #pragma mark Accessors -- (NSTabView *)tabView; -- (void)setTabView:(NSTabView *)view; -- (id)delegate; -- (void)setDelegate:(id)object; -- (id)partnerView; -- (void)setPartnerView:(id)view; +@property (NS_NONATOMIC_IOSONLY, strong) NSTabView *tabView; +@property (NS_NONATOMIC_IOSONLY, assign) id delegate; +@property (NS_NONATOMIC_IOSONLY, strong) id partnerView; #pragma mark - #pragma mark Determining Sizes -- (NSSize)addTabButtonSize; -- (NSRect)addTabButtonRect; -- (NSSize)overflowButtonSize; -- (NSRect)overflowButtonRect; +@property (NS_NONATOMIC_IOSONLY, readonly) NSSize addTabButtonSize; +@property (NS_NONATOMIC_IOSONLY, readonly) NSRect addTabButtonRect; +@property (NS_NONATOMIC_IOSONLY, readonly) NSSize overflowButtonSize; +@property (NS_NONATOMIC_IOSONLY, readonly) NSRect overflowButtonRect; #pragma mark - #pragma mark Determining Margins -- (CGFloat)rightMargin; -- (CGFloat)leftMargin; -- (CGFloat)topMargin; -- (CGFloat)bottomMargin; +@property (NS_NONATOMIC_IOSONLY, readonly) CGFloat rightMargin; +@property (NS_NONATOMIC_IOSONLY, readonly) CGFloat leftMargin; +@property (NS_NONATOMIC_IOSONLY, readonly) CGFloat topMargin; +@property (NS_NONATOMIC_IOSONLY, readonly) CGFloat bottomMargin; #pragma mark The Buttons -- (PSMRolloverButton *)addTabButton; -- (PSMOverflowPopUpButton *)overflowPopUpButton; +@property (NS_NONATOMIC_IOSONLY, readonly, strong) PSMRolloverButton *addTabButton; +@property (NS_NONATOMIC_IOSONLY, readonly, strong) PSMOverflowPopUpButton *overflowPopUpButton; #pragma mark Tab Information -- (NSMutableArray *)representedTabViewItems; -- (NSUInteger)numberOfVisibleTabs; -- (PSMTabBarCell *)lastVisibleTab; +@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSMutableArray *representedTabViewItems; +@property (NS_NONATOMIC_IOSONLY, readonly) NSUInteger numberOfVisibleTabs; +@property (NS_NONATOMIC_IOSONLY, readonly, copy) PSMTabBarCell *lastVisibleTab; #pragma mark Special Effects - (void)hideTabBar:(BOOL) hide animate:(BOOL)animate; -- (BOOL)isTabBarHidden; -- (BOOL)isAnimating; +@property (NS_NONATOMIC_IOSONLY, getter=isTabBarHidden, readonly) BOOL tabBarHidden; +@property (NS_NONATOMIC_IOSONLY, getter=isAnimating, readonly) BOOL animating; // internal bindings methods also used by the tab drag assistant - (void)bindPropertiesForCell:(PSMTabBarCell *)cell andTabViewItem:(NSTabViewItem *)item; diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabBarController.h b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabBarController.h index 23177bf6b9..15d7f108bc 100644 --- a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabBarController.h +++ b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabBarController.h @@ -17,9 +17,9 @@ NSMenu *_overflowMenu; } -- (id)initWithTabBarControl:(PSMTabBarControl *)control; +- (instancetype)initWithTabBarControl:(PSMTabBarControl *)control __attribute((objc_designated_initializer)); -- (NSMenu *)overflowMenu; +@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSMenu *overflowMenu; - (NSRect)cellFrameAtIndex:(NSInteger)index; - (void)setSelectedCell:(PSMTabBarCell *)cell; diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabDragAssistant.h b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabDragAssistant.h index 79bb830856..c5c3a3a413 100644 --- a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabDragAssistant.h +++ b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabDragAssistant.h @@ -44,20 +44,13 @@ + (PSMTabDragAssistant *)sharedDragAssistant; // Accessors -- (PSMTabBarControl *)sourceTabBar; -- (void)setSourceTabBar:(PSMTabBarControl *)tabBar; -- (PSMTabBarControl *)destinationTabBar; -- (void)setDestinationTabBar:(PSMTabBarControl *)tabBar; -- (PSMTabBarCell *)draggedCell; -- (void)setDraggedCell:(PSMTabBarCell *)cell; -- (NSInteger)draggedCellIndex; -- (void)setDraggedCellIndex:(NSInteger)value; -- (BOOL)isDragging; -- (void)setIsDragging:(BOOL)value; -- (NSPoint)currentMouseLoc; -- (void)setCurrentMouseLoc:(NSPoint)point; -- (PSMTabBarCell *)targetCell; -- (void)setTargetCell:(PSMTabBarCell *)cell; +@property (NS_NONATOMIC_IOSONLY, strong) PSMTabBarControl *sourceTabBar; +@property (NS_NONATOMIC_IOSONLY, strong) PSMTabBarControl *destinationTabBar; +@property (NS_NONATOMIC_IOSONLY, copy) PSMTabBarCell *draggedCell; +@property (NS_NONATOMIC_IOSONLY) NSInteger draggedCellIndex; +@property (NS_NONATOMIC_IOSONLY) BOOL isDragging; +@property (NS_NONATOMIC_IOSONLY) NSPoint currentMouseLoc; +@property (NS_NONATOMIC_IOSONLY, copy) PSMTabBarCell *targetCell; // Functionality - (void)startDraggingCell:(PSMTabBarCell *)cell fromTabBarControl:(PSMTabBarControl *)tabBarControl withMouseDownEvent:(NSEvent *)event; @@ -86,5 +79,5 @@ void CGContextCopyWindowCaptureContentsToRect(void *grafport, CGRect rect, NSInt OSStatus CGSSetWindowTransform(NSInteger cid, NSInteger wid, CGAffineTransform transform); @interface NSApplication (CoreGraphicsUndocumented) -- (NSInteger)contextID; +@property (NS_NONATOMIC_IOSONLY, readonly) NSInteger contextID; @end diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabDragView.h b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabDragView.h index f8018d290e..f232ab6335 100644 --- a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabDragView.h +++ b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabDragView.h @@ -14,8 +14,6 @@ CGFloat _alpha; } - (void)setFadeValue:(CGFloat)value; -- (NSImage *)image; -- (void)setImage:(NSImage *)image; -- (NSImage *)alternateImage; -- (void)setAlternateImage:(NSImage *)image; +@property (NS_NONATOMIC_IOSONLY, copy) NSImage *image; +@property (NS_NONATOMIC_IOSONLY, copy) NSImage *alternateImage; @end diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabDragWindow.h b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabDragWindow.h index 04cde248c6..51c7745f1f 100644 --- a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabDragWindow.h +++ b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabDragWindow.h @@ -15,6 +15,6 @@ } + (PSMTabDragWindow *)dragWindowWithImage:(NSImage *)image styleMask:(NSUInteger)styleMask; -- (id)initWithImage:(NSImage *)image styleMask:(NSUInteger)styleMask; -- (PSMTabDragView *)dragView; +- (instancetype)initWithImage:(NSImage *)image styleMask:(NSUInteger)styleMask __attribute((objc_designated_initializer)); +@property (NS_NONATOMIC_IOSONLY, readonly, strong) PSMTabDragView *dragView; @end diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabDragWindowController.h b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabDragWindowController.h index 5948207f29..0bb82ab6bf 100644 --- a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabDragWindowController.h +++ b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabDragWindowController.h @@ -23,11 +23,13 @@ BOOL _showingAlternate; NSRect _originalWindowFrame; } -- (id)initWithImage:(NSImage *)image styleMask:(NSUInteger) styleMask tearOffStyle:(PSMTabBarTearOffStyle)tearOffStyle; -- (NSImage *)image; -- (NSImage *)alternateImage; -- (void)setAlternateImage:(NSImage *)image; -- (BOOL)isAnimating; +- (instancetype)initWithWindow:(NSWindow *)window __attribute((objc_designated_initializer)); +- (instancetype)initWithCoder:(NSCoder *)coder __attribute((objc_designated_initializer)); +- (instancetype)initWithImage:(NSImage *)image styleMask:(NSUInteger) styleMask tearOffStyle:(PSMTabBarTearOffStyle)tearOffStyle __attribute((objc_designated_initializer)); + +@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSImage *image; +@property (NS_NONATOMIC_IOSONLY, copy) NSImage *alternateImage; +@property (NS_NONATOMIC_IOSONLY, getter=isAnimating, readonly) BOOL animating; - (void)switchImages; @end diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabStyle.h b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabStyle.h index 8ca1e60a39..e40209cba4 100644 --- a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabStyle.h +++ b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTabStyle.h @@ -40,7 +40,7 @@ // cell values - (NSAttributedString *)attributedObjectCountStringValueForTabCell:(PSMTabBarCell *)cell; -- (NSAttributedString *)attributedStringValueForTabCell:(PSMTabBarCell *)cell; +- (NSAttributedString *)attributedStringValueForTabCell:(PSMTabBarCell *)cell inTabBarControl:(PSMTabBarControl *)tabBarControl; // Constraints - (CGFloat)minimumWidthOfTabCell:(PSMTabBarCell *)cell; diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTexturedMetalTabStyle.h b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTexturedMetalTabStyle.h new file mode 100644 index 0000000000..1d411eb137 --- /dev/null +++ b/3rdparty/PSMTabBarControl.framework/Versions/A/Headers/PSMTexturedMetalTabStyle.h @@ -0,0 +1,30 @@ +// +// PSMTexturedMetalTabStyle.h +// PSMTabBarControl +// +// Created by Christopher Cahoon on 5/8/2014. +// Based on PSMMetalTabStyle.h +// Created by John Pannell on 2/17/06. +// Copyright 2006 Positive Spin Media. All rights reserved. + +#import +#import "PSMTabStyle.h" + +@interface PSMTexturedMetalTabStyle : NSObject { + NSImage *metalCloseButton; + NSImage *metalCloseButtonDown; + NSImage *metalCloseButtonOver; + NSImage *metalCloseDirtyButton; + NSImage *metalCloseDirtyButtonDown; + NSImage *metalCloseDirtyButtonOver; + NSImage *_addTabButtonImage; + NSImage *_addTabButtonPressedImage; + NSImage *_addTabButtonRolloverImage; + + NSDictionary *_objectCountStringAttributes; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder; +- (instancetype)initWithCoder:(NSCoder *)aDecoder; + +@end diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/PSMTabBarControl b/3rdparty/PSMTabBarControl.framework/Versions/A/PSMTabBarControl index 95b839ce44..c8c947d456 100755 Binary files a/3rdparty/PSMTabBarControl.framework/Versions/A/PSMTabBarControl and b/3rdparty/PSMTabBarControl.framework/Versions/A/PSMTabBarControl differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_ActiveTabClose.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_ActiveTabClose.tiff new file mode 100644 index 0000000000..706fde73da Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_ActiveTabClose.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_ActiveTabClosePressed.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_ActiveTabClosePressed.tiff new file mode 100644 index 0000000000..c5739b695f Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_ActiveTabClosePressed.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_ActiveTabCloseRollover.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_ActiveTabCloseRollover.tiff new file mode 100644 index 0000000000..396c4b796e Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_ActiveTabCloseRollover.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_ActiveTabFill.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_ActiveTabFill.tiff new file mode 100644 index 0000000000..fe5b0c6e91 Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_ActiveTabFill.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_ActiveTabLeftCap.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_ActiveTabLeftCap.tiff new file mode 100644 index 0000000000..650e6619f1 Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_ActiveTabLeftCap.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_ActiveTabRightCap.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_ActiveTabRightCap.tiff new file mode 100644 index 0000000000..b344832aff Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_ActiveTabRightCap.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_AddTabButton.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_AddTabButton.tiff new file mode 100644 index 0000000000..c4299a3b29 Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_AddTabButton.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_AddTabButtonPushed.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_AddTabButtonPushed.tiff new file mode 100644 index 0000000000..5a0980c880 Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_AddTabButtonPushed.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_AddTabButtonRollover.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_AddTabButtonRollover.tiff new file mode 100644 index 0000000000..733dd28ab1 Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_AddTabButtonRollover.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_AddTabButtonRollover_Pressed.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_AddTabButtonRollover_Pressed.tiff new file mode 100644 index 0000000000..95c93e5205 Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_AddTabButtonRollover_Pressed.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_InactiveTabBG.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_InactiveTabBG.tiff new file mode 100644 index 0000000000..9311ef65a4 Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_InactiveTabBG.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_InactiveTabClose.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_InactiveTabClose.tiff new file mode 100644 index 0000000000..877930c4f4 Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_InactiveTabClose.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_InactiveTabClosePressed.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_InactiveTabClosePressed.tiff new file mode 100644 index 0000000000..11928c51bb Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_InactiveTabClosePressed.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_InactiveTabCloseRollover.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_InactiveTabCloseRollover.tiff new file mode 100644 index 0000000000..a1251aa3bf Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_InactiveTabCloseRollover.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_InactiveTabLeftCap.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_InactiveTabLeftCap.tiff new file mode 100644 index 0000000000..87133d1d05 Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_InactiveTabLeftCap.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_InactiveTabRightCap.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_InactiveTabRightCap.tiff new file mode 100644 index 0000000000..fd3a63a796 Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_InactiveTabRightCap.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_Pulled_ActiveTabCenterFill.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_Pulled_ActiveTabCenterFill.tiff new file mode 100644 index 0000000000..9e29455d92 Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_Pulled_ActiveTabCenterFill.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_Pulled_ActiveTabLeftCap.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_Pulled_ActiveTabLeftCap.tiff new file mode 100644 index 0000000000..e776d79259 Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_Pulled_ActiveTabLeftCap.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_Pulled_ActiveTabRightCap.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_Pulled_ActiveTabRightCap.tiff new file mode 100644 index 0000000000..c1d2ade699 Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/ActiveWindow_Pulled_ActiveTabRightCap.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/AquaTabClose_Front.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/AquaTabClose_Front.tiff index 7d9b2cea77..6e560c80fc 100644 Binary files a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/AquaTabClose_Front.tiff and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/AquaTabClose_Front.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/AquaTabClose_Front_Pressed.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/AquaTabClose_Front_Pressed.tiff index 09555c4296..ec14bbe3ea 100644 Binary files a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/AquaTabClose_Front_Pressed.tiff and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/AquaTabClose_Front_Pressed.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/AquaTabClose_Front_Rollover.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/AquaTabClose_Front_Rollover.tiff index 862a58e4fe..06334c5f39 100644 Binary files a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/AquaTabClose_Front_Rollover.tiff and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/AquaTabClose_Front_Rollover.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/AquaTabNew.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/AquaTabNew.tiff index 2b9b079037..a09df11e9a 100644 Binary files a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/AquaTabNew.tiff and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/AquaTabNew.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/AquaTabNewPressed.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/AquaTabNewPressed.tiff index 4e9d082869..b131f7962a 100644 Binary files a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/AquaTabNewPressed.tiff and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/AquaTabNewPressed.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/AquaTabNewRollover.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/AquaTabNewRollover.tiff index 0aa9012dfa..cf875a80cc 100644 Binary files a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/AquaTabNewRollover.tiff and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/AquaTabNewRollover.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_ActiveTabClose.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_ActiveTabClose.tiff new file mode 100644 index 0000000000..4f48565fc2 Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_ActiveTabClose.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_ActiveTabClosePressed.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_ActiveTabClosePressed.tiff new file mode 100644 index 0000000000..455a0563e8 Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_ActiveTabClosePressed.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_ActiveTabCloseRollover.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_ActiveTabCloseRollover.tiff new file mode 100644 index 0000000000..640781abad Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_ActiveTabCloseRollover.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_ActiveTabFill.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_ActiveTabFill.tiff new file mode 100644 index 0000000000..e7a7b16ee1 Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_ActiveTabFill.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_ActiveTabLeftCap.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_ActiveTabLeftCap.tiff new file mode 100644 index 0000000000..c948ed2673 Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_ActiveTabLeftCap.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_ActiveTabRightCap.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_ActiveTabRightCap.tiff new file mode 100644 index 0000000000..1e2dfc09ba Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_ActiveTabRightCap.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_AddTabButton.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_AddTabButton.tiff new file mode 100644 index 0000000000..075dd5324c Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_AddTabButton.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_InactiveTabBG.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_InactiveTabBG.tiff new file mode 100644 index 0000000000..2fed2e471a Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_InactiveTabBG.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_InactiveTabClose.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_InactiveTabClose.tiff new file mode 100644 index 0000000000..842751f60f Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_InactiveTabClose.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_InactiveTabClosePressed.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_InactiveTabClosePressed.tiff new file mode 100644 index 0000000000..64c9bb415e Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_InactiveTabClosePressed.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_InactiveTabCloseRollover.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_InactiveTabCloseRollover.tiff new file mode 100644 index 0000000000..578f35ef05 Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_InactiveTabCloseRollover.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_InactiveTabLeftCap.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_InactiveTabLeftCap.tiff new file mode 100644 index 0000000000..b58eb628cc Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_InactiveTabLeftCap.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_InactiveTabRightCap.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_InactiveTabRightCap.tiff new file mode 100644 index 0000000000..6aa366f299 Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/InactiveWindow_InactiveTabRightCap.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/Info.plist b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/Info.plist index 38939eaf91..57e992b489 100644 --- a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/Info.plist +++ b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/Info.plist @@ -3,7 +3,7 @@ BuildMachineOSBuild - 13E28 + 15A263e CFBundleDevelopmentRegion English CFBundleExecutable @@ -23,16 +23,16 @@ DTCompiler com.apple.compilers.llvm.clang.1_0 DTPlatformBuild - 5B1008 + 6E35b DTPlatformVersion GM DTSDKBuild - 13C64 + 14D125 DTSDKName - macosx10.9 + macosx10.10 DTXcode - 0511 + 0640 DTXcodeBuild - 5B1008 + 6E35b diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Dirty.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Dirty.tiff index ab3c036d85..20a47259fc 100644 Binary files a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Dirty.tiff and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Dirty.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Dirty_Pressed.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Dirty_Pressed.tiff index 06ee14d17f..4a7b947bf5 100644 Binary files a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Dirty_Pressed.tiff and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Dirty_Pressed.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Dirty_Pressed_Textured.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Dirty_Pressed_Textured.tiff new file mode 100644 index 0000000000..00248b0b11 Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Dirty_Pressed_Textured.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Dirty_Rollover.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Dirty_Rollover.tiff index 1d5d472db6..6dec5f09d3 100644 Binary files a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Dirty_Rollover.tiff and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Dirty_Rollover.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Dirty_Rollover_Textured.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Dirty_Rollover_Textured.tiff new file mode 100644 index 0000000000..d3d928e88d Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Dirty_Rollover_Textured.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Dirty_Textured.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Dirty_Textured.tiff new file mode 100644 index 0000000000..3708df94fe Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Dirty_Textured.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Front.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Front.tiff index 5fd4a3b0ea..e2bb7c1f63 100644 Binary files a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Front.tiff and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Front.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Front_Pressed.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Front_Pressed.tiff index 58a4cd6835..86bcf6eb84 100644 Binary files a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Front_Pressed.tiff and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Front_Pressed.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Front_Pressed_Textured.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Front_Pressed_Textured.tiff new file mode 100644 index 0000000000..98cc8b2f86 Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Front_Pressed_Textured.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Front_Rollover.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Front_Rollover.tiff index b959e8a974..5e751e0a74 100644 Binary files a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Front_Rollover.tiff and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Front_Rollover.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Front_Rollover_Textured.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Front_Rollover_Textured.tiff new file mode 100644 index 0000000000..b387fde979 Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Front_Rollover_Textured.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Front_Textured.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Front_Textured.tiff new file mode 100644 index 0000000000..d19faaf7e7 Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabClose_Front_Textured.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabNewMetalPressed_Textured.png b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabNewMetalPressed_Textured.png new file mode 100644 index 0000000000..18118ec363 Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabNewMetalPressed_Textured.png differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabNewMetalRollover_Textured.png b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabNewMetalRollover_Textured.png new file mode 100644 index 0000000000..b13081649a Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabNewMetalRollover_Textured.png differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabNewMetal_Textured.png b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabNewMetal_Textured.png new file mode 100644 index 0000000000..be02d7083d Binary files /dev/null and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/TabNewMetal_Textured.png differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/overflowImage.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/overflowImage.tiff index f3c9bfe4aa..54c1e675f9 100644 Binary files a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/overflowImage.tiff and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/overflowImage.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/overflowImagePressed.tiff b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/overflowImagePressed.tiff index edce7a9e88..b69720ba97 100644 Binary files a/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/overflowImagePressed.tiff and b/3rdparty/PSMTabBarControl.framework/Versions/A/Resources/overflowImagePressed.tiff differ diff --git a/3rdparty/PSMTabBarControl.framework/Versions/A/_CodeSignature/CodeResources b/3rdparty/PSMTabBarControl.framework/Versions/A/_CodeSignature/CodeResources index 5c06e0a6cd..92bc509107 100644 --- a/3rdparty/PSMTabBarControl.framework/Versions/A/_CodeSignature/CodeResources +++ b/3rdparty/PSMTabBarControl.framework/Versions/A/_CodeSignature/CodeResources @@ -4,6 +4,82 @@ files + Resources/ActiveWindow_ActiveTabClose.tiff + + mgLbsbnw38C4LQ8RDPs6aiubJ1s= + + Resources/ActiveWindow_ActiveTabClosePressed.tiff + + HWlFIi1vA611a/WWXGLuiK8TrVo= + + Resources/ActiveWindow_ActiveTabCloseRollover.tiff + + XhH6lPBfQzAVkaz0RguDF51jK9I= + + Resources/ActiveWindow_ActiveTabFill.tiff + + Xg10zlVSO5Q7etGQZ/51nGb1Kgw= + + Resources/ActiveWindow_ActiveTabLeftCap.tiff + + VVRFgl1oJFk7R447PIjdsycvBPQ= + + Resources/ActiveWindow_ActiveTabRightCap.tiff + + qSOASuVAMGx2BDch0sHpjZPFOKQ= + + Resources/ActiveWindow_AddTabButton.tiff + + Q/BADN0ZSVuSJv/JH8h5vGBjhPI= + + Resources/ActiveWindow_AddTabButtonPushed.tiff + + 1ujk25sVmWEU1Q6Cit/KfReSa6g= + + Resources/ActiveWindow_AddTabButtonRollover.tiff + + xnPILYljSq0L2QjkvzbSk05KSAs= + + Resources/ActiveWindow_AddTabButtonRollover_Pressed.tiff + + DJlzcMpEltHFGLLY9DFEif4V4CY= + + Resources/ActiveWindow_InactiveTabBG.tiff + + iRhRXx5j+2EQ7RM3GX3xOH2qqwc= + + Resources/ActiveWindow_InactiveTabClose.tiff + + zwpkGzin3vwVYz8mGfb98i+g65w= + + Resources/ActiveWindow_InactiveTabClosePressed.tiff + + L/wy106Z6JY1M9K8Uv4R2Xi4FN8= + + Resources/ActiveWindow_InactiveTabCloseRollover.tiff + + b0qfTeK6237YoSV1Jay3JhgDN8s= + + Resources/ActiveWindow_InactiveTabLeftCap.tiff + + QNJHEhD4RdrUuo2krqHREeLm7j8= + + Resources/ActiveWindow_InactiveTabRightCap.tiff + + fsdm5by/FrDQraKG8O2egYIneFQ= + + Resources/ActiveWindow_Pulled_ActiveTabCenterFill.tiff + + qhtPEn42oKZ2qLKpQ/Ym2+M+1BE= + + Resources/ActiveWindow_Pulled_ActiveTabLeftCap.tiff + + Iky6hYeE8ManZgJAm+JFePoPVBc= + + Resources/ActiveWindow_Pulled_ActiveTabRightCap.tiff + + Wng5DYlXe4mT0BTk97vKejBHYxg= + Resources/AdiumGradient.png pUGdMseoiA31TVjrgOM/5bZRUXY= @@ -22,27 +98,27 @@ Resources/AquaTabClose_Front.tiff - pV4HZY4wy6yimmSnjuJtkLbL9nQ= + BornexboGdaD9jCSGkdIYa759qk= Resources/AquaTabClose_Front_Pressed.tiff - 3BLGaFfwcyUXeybltEVqwG0pwvw= + QTJ9/tl6HveMf1bEvrXT+Szcqw8= Resources/AquaTabClose_Front_Rollover.tiff - R1Sz/63pL33ZQfpM3znOAUd6ddc= + XoIs4Y/RGclvp2PuJ4BTBgox5+Q= Resources/AquaTabNew.tiff - MSbb4qtahZcUNM6mqmBa90/910A= + +ZvIjbEkXBBdXpY+Ynn9FNuJMl4= Resources/AquaTabNewPressed.tiff - WMH+dKcr94reUC9p4wo1NDmyWaM= + af5TzUVpx94q5TAHXWPA0FGpENA= Resources/AquaTabNewRollover.tiff - MclsWCWNc/IKnjX0Ld0la4oosOY= + hZryPfBz6UFsn2PAg82nNBItPOc= Resources/AquaTabsBackground.png @@ -68,33 +144,109 @@ XNRM9R8anBn3LUQMVaf4GdwJzQM= + Resources/InactiveWindow_ActiveTabClose.tiff + + xfNBHYq4dfB48P2JXeiaATf2lx8= + + Resources/InactiveWindow_ActiveTabClosePressed.tiff + + nWT0TkRVXX0uGOz/uwcjDPXiyhU= + + Resources/InactiveWindow_ActiveTabCloseRollover.tiff + + YQ4q6yqrrND5iGGHoqLBk4HGPig= + + Resources/InactiveWindow_ActiveTabFill.tiff + + /GWFN1J5jVMMmIv6zbGiI7pg+fs= + + Resources/InactiveWindow_ActiveTabLeftCap.tiff + + nLZ2/PzZna9V0PN0DwOIYKSn+/M= + + Resources/InactiveWindow_ActiveTabRightCap.tiff + + DmJ7v8gD4zAbboO1Vx/Y/FOzUPM= + + Resources/InactiveWindow_AddTabButton.tiff + + Gzpp/m0DqvsVGWaU0EVQR94gHj8= + + Resources/InactiveWindow_InactiveTabBG.tiff + + uwk/xmr+K2jwDAc9KI2eOyGnJ6c= + + Resources/InactiveWindow_InactiveTabClose.tiff + + /63gZNRLlHitBzTCUa14XA42JT0= + + Resources/InactiveWindow_InactiveTabClosePressed.tiff + + fg1xAdub+8vMmKvq/6AlhujEQx0= + + Resources/InactiveWindow_InactiveTabCloseRollover.tiff + + 8hLTflXXVvo6LFfBr1O/ujYV8pM= + + Resources/InactiveWindow_InactiveTabLeftCap.tiff + + GpAaKypVK3VWNmNhMHmYeffuPrk= + + Resources/InactiveWindow_InactiveTabRightCap.tiff + + qHpGIDEMr6k267LEzaCYHAvocOQ= + Resources/Info.plist - Nn8GuQCaT8wJze7RSjJT3GPsz5c= + YFepEAp5R8lR21IRKGRiSAGklaM= Resources/TabClose_Dirty.tiff - H17jtiPs3gQgzhvQ4RRv6qfDlUI= + nYzOZiK+8rGoSlJIZBUsCfZcEvI= Resources/TabClose_Dirty_Pressed.tiff - EM5/8RIsnN7pLj+9iWFKTsGAWk0= + EMQkaDP2nhftv/7JrZoKYRuaIHc= + + Resources/TabClose_Dirty_Pressed_Textured.tiff + + IgIxz2LdWThhnVUOx1SiLOrEdWo= Resources/TabClose_Dirty_Rollover.tiff - Nlx7crhp1hq/LeKPH3d/sDXcEcQ= + GmetDVxgoHbeSd3StJxq7+gQz6A= + + Resources/TabClose_Dirty_Rollover_Textured.tiff + + kLVo9VO2WuBmjFiI/0ZgfsQDHEc= + + Resources/TabClose_Dirty_Textured.tiff + + 4Gp3k9UrA74gr2JU+fu1IOoEkwc= Resources/TabClose_Front.tiff - C0/Z60E1cx7zX7NLrWi/VVHYGcY= + dXgSElA/n9mPDoaeid0ES/Sz0MQ= Resources/TabClose_Front_Pressed.tiff - V0TT1wIgLTwcJABUKga2u3BYE2g= + zY7vJhRXaLhwk0jotkdwjepZQ10= + + Resources/TabClose_Front_Pressed_Textured.tiff + + IGBCPBpVkjQKfASCIKnfaCsfQts= Resources/TabClose_Front_Rollover.tiff - lrJN2LbqGL4rpzH3nTNpadHFrPc= + OhyfYu/bgjiRdP4KAVc64NU3ENY= + + Resources/TabClose_Front_Rollover_Textured.tiff + + ylcJs3/myBKfwfE8+ENNKFqvNxo= + + Resources/TabClose_Front_Textured.tiff + + r2aVlM2MVXUc/hgFRtaefoVYZnw= Resources/TabNewMetal.png @@ -104,17 +256,29 @@ Dws9oYWvi8Rvj0EtIWWm9iTlqdM= + Resources/TabNewMetalPressed_Textured.png + + Dws9oYWvi8Rvj0EtIWWm9iTlqdM= + Resources/TabNewMetalRollover.png A52pLQscBe2Z0igvKBBlWtc4AGs= + Resources/TabNewMetalRollover_Textured.png + + ydveK2t2Z/eh3WfZpdkW85U4dj8= + + Resources/TabNewMetal_Textured.png + + Wvi4d3JJ+/hsAP7FKZnyHlEVWqQ= + Resources/overflowImage.tiff - e3DByDQFXGW6ugJLEaGKoTPY5ZQ= + 74y4QUxnoQ6oxCAsdvrr3qkzGqc= Resources/overflowImagePressed.tiff - b1uovP8GFaBxSRWjHJEGGv9qx1g= + zNN2u+tNZcL+SGl7UsLZWp1Ligk= Resources/pi.png @@ -129,11 +293,11 @@ Headers/PSMAdiumTabStyle.h - Is43FAwp/MSlAiq1MvS78DuayLc= + YvJEb/dOS1CsUhM0MbEO7fMfjaY= Headers/PSMAquaTabStyle.h - H3rOCJAKCAxUyWqXmcNO5OVB9kQ= + 7EQKZpSDJRu/l2a6yhZ8TNjuVYU= Headers/PSMCardTabStyle.h @@ -145,11 +309,11 @@ Headers/PSMMetalTabStyle.h - foZA+2KBsi2rW1HWYuHBdk5TIZo= + JrQiaq6tsKpkAFLS2HjlECCqrfA= Headers/PSMOverflowPopUpButton.h - spW/EUALwzm9p8MCr0KieD620d0= + tA8na9zJIb4QOighAoF4OoaY8g4= Headers/PSMProgressIndicator.h @@ -157,44 +321,124 @@ Headers/PSMRolloverButton.h - mJE41QoTaTCg6KD03YraNMOZ6BY= + jofC4m3aHY/tBSzvrI8hMzyyZsE= Headers/PSMTabBarCell.h - D5r6C0Kk5FUSFKFnu2XidzsyKYg= + hOc5ndOGLbE2xVeKKnIAOv8pnnw= Headers/PSMTabBarControl.h - bKPwidlLIrt/0dU3J1+CLiCw6Pw= + yVDbIVvn/8m5ne3bwv9RiH6lsXc= Headers/PSMTabBarController.h - TnmMZg4lDu2oA0QwfEHTRkILZnA= + fG7cq3jCW7NnPlXzaQ8q85l8h7I= Headers/PSMTabDragAssistant.h - OfSEGvBym/ZaJbEleRYsuatvAys= + iWDdv78UW7n9zGE+ZuK4lJwEj5s= Headers/PSMTabDragView.h - vCpS2s0s/dSnVmRt3Ea2zazT6Zg= + fqEjab3FgSH/Q8Z0nGPhR0YMnys= Headers/PSMTabDragWindow.h - SYeaJlIEt32BgMrYf/Y42m5W+YM= + wy16zCF90U7v7we4UDJUUlT6+Ho= Headers/PSMTabDragWindowController.h - HBNAibOLNXAxpXqTsz+FyjkTlZU= + CxlaOgMOM+5jh6gusJjxwswV0Bs= Headers/PSMTabStyle.h - 22xYyn8F/19Zm2idoKq3P7DkLHg= + qrJkXTWK04cYk7n6OQc9ercym9E= + + Headers/PSMTexturedMetalTabStyle.h + + toBapp02SWnb0m9II8HBJcpk2Ig= Headers/PSMUnifiedTabStyle.h t96fB1PXbcNe3bkFmvJhAsQZPvM= + Resources/ActiveWindow_ActiveTabClose.tiff + + mgLbsbnw38C4LQ8RDPs6aiubJ1s= + + Resources/ActiveWindow_ActiveTabClosePressed.tiff + + HWlFIi1vA611a/WWXGLuiK8TrVo= + + Resources/ActiveWindow_ActiveTabCloseRollover.tiff + + XhH6lPBfQzAVkaz0RguDF51jK9I= + + Resources/ActiveWindow_ActiveTabFill.tiff + + Xg10zlVSO5Q7etGQZ/51nGb1Kgw= + + Resources/ActiveWindow_ActiveTabLeftCap.tiff + + VVRFgl1oJFk7R447PIjdsycvBPQ= + + Resources/ActiveWindow_ActiveTabRightCap.tiff + + qSOASuVAMGx2BDch0sHpjZPFOKQ= + + Resources/ActiveWindow_AddTabButton.tiff + + Q/BADN0ZSVuSJv/JH8h5vGBjhPI= + + Resources/ActiveWindow_AddTabButtonPushed.tiff + + 1ujk25sVmWEU1Q6Cit/KfReSa6g= + + Resources/ActiveWindow_AddTabButtonRollover.tiff + + xnPILYljSq0L2QjkvzbSk05KSAs= + + Resources/ActiveWindow_AddTabButtonRollover_Pressed.tiff + + DJlzcMpEltHFGLLY9DFEif4V4CY= + + Resources/ActiveWindow_InactiveTabBG.tiff + + iRhRXx5j+2EQ7RM3GX3xOH2qqwc= + + Resources/ActiveWindow_InactiveTabClose.tiff + + zwpkGzin3vwVYz8mGfb98i+g65w= + + Resources/ActiveWindow_InactiveTabClosePressed.tiff + + L/wy106Z6JY1M9K8Uv4R2Xi4FN8= + + Resources/ActiveWindow_InactiveTabCloseRollover.tiff + + b0qfTeK6237YoSV1Jay3JhgDN8s= + + Resources/ActiveWindow_InactiveTabLeftCap.tiff + + QNJHEhD4RdrUuo2krqHREeLm7j8= + + Resources/ActiveWindow_InactiveTabRightCap.tiff + + fsdm5by/FrDQraKG8O2egYIneFQ= + + Resources/ActiveWindow_Pulled_ActiveTabCenterFill.tiff + + qhtPEn42oKZ2qLKpQ/Ym2+M+1BE= + + Resources/ActiveWindow_Pulled_ActiveTabLeftCap.tiff + + Iky6hYeE8ManZgJAm+JFePoPVBc= + + Resources/ActiveWindow_Pulled_ActiveTabRightCap.tiff + + Wng5DYlXe4mT0BTk97vKejBHYxg= + Resources/AdiumGradient.png pUGdMseoiA31TVjrgOM/5bZRUXY= @@ -213,27 +457,27 @@ Resources/AquaTabClose_Front.tiff - pV4HZY4wy6yimmSnjuJtkLbL9nQ= + BornexboGdaD9jCSGkdIYa759qk= Resources/AquaTabClose_Front_Pressed.tiff - 3BLGaFfwcyUXeybltEVqwG0pwvw= + QTJ9/tl6HveMf1bEvrXT+Szcqw8= Resources/AquaTabClose_Front_Rollover.tiff - R1Sz/63pL33ZQfpM3znOAUd6ddc= + XoIs4Y/RGclvp2PuJ4BTBgox5+Q= Resources/AquaTabNew.tiff - MSbb4qtahZcUNM6mqmBa90/910A= + +ZvIjbEkXBBdXpY+Ynn9FNuJMl4= Resources/AquaTabNewPressed.tiff - WMH+dKcr94reUC9p4wo1NDmyWaM= + af5TzUVpx94q5TAHXWPA0FGpENA= Resources/AquaTabNewRollover.tiff - MclsWCWNc/IKnjX0Ld0la4oosOY= + hZryPfBz6UFsn2PAg82nNBItPOc= Resources/AquaTabsBackground.png @@ -259,33 +503,109 @@ XNRM9R8anBn3LUQMVaf4GdwJzQM= + Resources/InactiveWindow_ActiveTabClose.tiff + + xfNBHYq4dfB48P2JXeiaATf2lx8= + + Resources/InactiveWindow_ActiveTabClosePressed.tiff + + nWT0TkRVXX0uGOz/uwcjDPXiyhU= + + Resources/InactiveWindow_ActiveTabCloseRollover.tiff + + YQ4q6yqrrND5iGGHoqLBk4HGPig= + + Resources/InactiveWindow_ActiveTabFill.tiff + + /GWFN1J5jVMMmIv6zbGiI7pg+fs= + + Resources/InactiveWindow_ActiveTabLeftCap.tiff + + nLZ2/PzZna9V0PN0DwOIYKSn+/M= + + Resources/InactiveWindow_ActiveTabRightCap.tiff + + DmJ7v8gD4zAbboO1Vx/Y/FOzUPM= + + Resources/InactiveWindow_AddTabButton.tiff + + Gzpp/m0DqvsVGWaU0EVQR94gHj8= + + Resources/InactiveWindow_InactiveTabBG.tiff + + uwk/xmr+K2jwDAc9KI2eOyGnJ6c= + + Resources/InactiveWindow_InactiveTabClose.tiff + + /63gZNRLlHitBzTCUa14XA42JT0= + + Resources/InactiveWindow_InactiveTabClosePressed.tiff + + fg1xAdub+8vMmKvq/6AlhujEQx0= + + Resources/InactiveWindow_InactiveTabCloseRollover.tiff + + 8hLTflXXVvo6LFfBr1O/ujYV8pM= + + Resources/InactiveWindow_InactiveTabLeftCap.tiff + + GpAaKypVK3VWNmNhMHmYeffuPrk= + + Resources/InactiveWindow_InactiveTabRightCap.tiff + + qHpGIDEMr6k267LEzaCYHAvocOQ= + Resources/Info.plist - Nn8GuQCaT8wJze7RSjJT3GPsz5c= + YFepEAp5R8lR21IRKGRiSAGklaM= Resources/TabClose_Dirty.tiff - H17jtiPs3gQgzhvQ4RRv6qfDlUI= + nYzOZiK+8rGoSlJIZBUsCfZcEvI= Resources/TabClose_Dirty_Pressed.tiff - EM5/8RIsnN7pLj+9iWFKTsGAWk0= + EMQkaDP2nhftv/7JrZoKYRuaIHc= + + Resources/TabClose_Dirty_Pressed_Textured.tiff + + IgIxz2LdWThhnVUOx1SiLOrEdWo= Resources/TabClose_Dirty_Rollover.tiff - Nlx7crhp1hq/LeKPH3d/sDXcEcQ= + GmetDVxgoHbeSd3StJxq7+gQz6A= + + Resources/TabClose_Dirty_Rollover_Textured.tiff + + kLVo9VO2WuBmjFiI/0ZgfsQDHEc= + + Resources/TabClose_Dirty_Textured.tiff + + 4Gp3k9UrA74gr2JU+fu1IOoEkwc= Resources/TabClose_Front.tiff - C0/Z60E1cx7zX7NLrWi/VVHYGcY= + dXgSElA/n9mPDoaeid0ES/Sz0MQ= Resources/TabClose_Front_Pressed.tiff - V0TT1wIgLTwcJABUKga2u3BYE2g= + zY7vJhRXaLhwk0jotkdwjepZQ10= + + Resources/TabClose_Front_Pressed_Textured.tiff + + IGBCPBpVkjQKfASCIKnfaCsfQts= Resources/TabClose_Front_Rollover.tiff - lrJN2LbqGL4rpzH3nTNpadHFrPc= + OhyfYu/bgjiRdP4KAVc64NU3ENY= + + Resources/TabClose_Front_Rollover_Textured.tiff + + ylcJs3/myBKfwfE8+ENNKFqvNxo= + + Resources/TabClose_Front_Textured.tiff + + r2aVlM2MVXUc/hgFRtaefoVYZnw= Resources/TabNewMetal.png @@ -295,17 +615,29 @@ Dws9oYWvi8Rvj0EtIWWm9iTlqdM= + Resources/TabNewMetalPressed_Textured.png + + Dws9oYWvi8Rvj0EtIWWm9iTlqdM= + Resources/TabNewMetalRollover.png A52pLQscBe2Z0igvKBBlWtc4AGs= + Resources/TabNewMetalRollover_Textured.png + + ydveK2t2Z/eh3WfZpdkW85U4dj8= + + Resources/TabNewMetal_Textured.png + + Wvi4d3JJ+/hsAP7FKZnyHlEVWqQ= + Resources/overflowImage.tiff - e3DByDQFXGW6ugJLEaGKoTPY5ZQ= + 74y4QUxnoQ6oxCAsdvrr3qkzGqc= Resources/overflowImagePressed.tiff - b1uovP8GFaBxSRWjHJEGGv9qx1g= + zNN2u+tNZcL+SGl7UsLZWp1Ligk= Resources/pi.png diff --git a/3rdparty/Sparkle.framework/Versions/A/Headers/SUAppcast.h b/3rdparty/Sparkle.framework/Versions/A/Headers/SUAppcast.h deleted file mode 100644 index 171148a4d1..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Headers/SUAppcast.h +++ /dev/null @@ -1,33 +0,0 @@ -// -// SUAppcast.h -// Sparkle -// -// Created by Andy Matuschak on 3/12/06. -// Copyright 2006 Andy Matuschak. All rights reserved. -// - -#ifndef SUAPPCAST_H -#define SUAPPCAST_H - -@class SUAppcastItem; -@interface SUAppcast : NSObject { - NSArray *items; - NSString *userAgentString; - id delegate; - NSMutableData *incrementalData; -} - -- (void)fetchAppcastFromURL:(NSURL *)url; -- (void)setDelegate:delegate; -- (void)setUserAgentString:(NSString *)userAgentString; - -- (NSArray *)items; - -@end - -@interface NSObject (SUAppcastDelegate) -- (void)appcastDidFinishLoading:(SUAppcast *)appcast; -- (void)appcast:(SUAppcast *)appcast failedToLoadWithError:(NSError *)error; -@end - -#endif diff --git a/3rdparty/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h b/3rdparty/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h deleted file mode 100644 index 7f1ca65c08..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h +++ /dev/null @@ -1,47 +0,0 @@ -// -// SUAppcastItem.h -// Sparkle -// -// Created by Andy Matuschak on 3/12/06. -// Copyright 2006 Andy Matuschak. All rights reserved. -// - -#ifndef SUAPPCASTITEM_H -#define SUAPPCASTITEM_H - -@interface SUAppcastItem : NSObject { - NSString *title; - NSDate *date; - NSString *itemDescription; - - NSURL *releaseNotesURL; - - NSString *DSASignature; - NSString *minimumSystemVersion; - - NSURL *fileURL; - NSString *versionString; - NSString *displayVersionString; - - NSDictionary *propertiesDictionary; -} - -// Initializes with data from a dictionary provided by the RSS class. -- initWithDictionary:(NSDictionary *)dict; - -- (NSString *)title; -- (NSString *)versionString; -- (NSString *)displayVersionString; -- (NSDate *)date; -- (NSString *)itemDescription; -- (NSURL *)releaseNotesURL; -- (NSURL *)fileURL; -- (NSString *)DSASignature; -- (NSString *)minimumSystemVersion; - -// Returns the dictionary provided in initWithDictionary; this might be useful later for extensions. -- (NSDictionary *)propertiesDictionary; - -@end - -#endif diff --git a/3rdparty/Sparkle.framework/Versions/A/Headers/SUUpdater.h b/3rdparty/Sparkle.framework/Versions/A/Headers/SUUpdater.h deleted file mode 100644 index e78c4d3532..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Headers/SUUpdater.h +++ /dev/null @@ -1,118 +0,0 @@ -// -// SUUpdater.h -// Sparkle -// -// Created by Andy Matuschak on 1/4/06. -// Copyright 2006 Andy Matuschak. All rights reserved. -// - -#ifndef SUUPDATER_H -#define SUUPDATER_H - -#import - -@class SUUpdateDriver, SUAppcastItem, SUHost, SUAppcast; -@interface SUUpdater : NSObject { - NSTimer *checkTimer; - SUUpdateDriver *driver; - - SUHost *host; - IBOutlet id delegate; -} - -+ (SUUpdater *)sharedUpdater; -+ (SUUpdater *)updaterForBundle:(NSBundle *)bundle; -- (NSBundle *)hostBundle; - -- (void)setDelegate:(id)delegate; -- delegate; - -- (void)setAutomaticallyChecksForUpdates:(BOOL)automaticallyChecks; -- (BOOL)automaticallyChecksForUpdates; - -- (void)setUpdateCheckInterval:(NSTimeInterval)interval; -- (NSTimeInterval)updateCheckInterval; - -- (void)setFeedURL:(NSURL *)feedURL; -- (NSURL *)feedURL; - -- (void)setSendsSystemProfile:(BOOL)sendsSystemProfile; -- (BOOL)sendsSystemProfile; - -- (void)setAutomaticallyDownloadsUpdates:(BOOL)automaticallyDownloadsUpdates; -- (BOOL)automaticallyDownloadsUpdates; - -// This IBAction is meant for a main menu item. Hook up any menu item to this action, -// and Sparkle will check for updates and report back its findings verbosely. -- (IBAction)checkForUpdates:sender; - -// This kicks off an update meant to be programmatically initiated. That is, it will display no UI unless it actually finds an update, -// in which case it proceeds as usual. If the fully automated updating is turned on, however, this will invoke that behavior, and if an -// update is found, it will be downloaded and prepped for installation. -- (void)checkForUpdatesInBackground; - -// Date of last update check. Returns null if no check has been performed. -- (NSDate*)lastUpdateCheckDate; - -// This begins a "probing" check for updates which will not actually offer to update to that version. The delegate methods, though, -// (up to updater:didFindValidUpdate: and updaterDidNotFindUpdate:), are called, so you can use that information in your UI. -- (void)checkForUpdateInformation; - -// Call this to appropriately schedule or cancel the update checking timer according to the preferences for time interval and automatic checks. This call does not change the date of the next check, but only the internal NSTimer. -- (void)resetUpdateCycle; - -- (BOOL)updateInProgress; -@end - -@interface NSObject (SUUpdaterDelegateInformalProtocol) -// This method allows you to add extra parameters to the appcast URL, potentially based on whether or not Sparkle will also be sending along the system profile. This method should return an array of dictionaries with keys: "key", "value", "displayKey", "displayValue", the latter two being specifically for display to the user. -- (NSArray *)feedParametersForUpdater:(SUUpdater *)updater sendingSystemProfile:(BOOL)sendingProfile; - -// Use this to override the default behavior for Sparkle prompting the user about automatic update checks. -- (BOOL)updaterShouldPromptForPermissionToCheckForUpdates:(SUUpdater *)bundle; - -// Implement this if you want to do some special handling with the appcast once it finishes loading. -- (void)updater:(SUUpdater *)updater didFinishLoadingAppcast:(SUAppcast *)appcast; - -// If you're using special logic or extensions in your appcast, implement this to use your own logic for finding -// a valid update, if any, in the given appcast. -- (SUAppcastItem *)bestValidUpdateInAppcast:(SUAppcast *)appcast forUpdater:(SUUpdater *)bundle; - -// Sent when a valid update is found by the update driver. -- (void)updater:(SUUpdater *)updater didFindValidUpdate:(SUAppcastItem *)update; - -// Sent when a valid update is not found. -- (void)updaterDidNotFindUpdate:(SUUpdater *)update; - -// Sent immediately before installing the specified update. -- (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)update; - -// Return YES to delay the relaunch until you do some processing; invoke the given NSInvocation to continue. -- (BOOL)updater:(SUUpdater *)updater shouldPostponeRelaunchForUpdate:(SUAppcastItem *)update untilInvoking:(NSInvocation *)invocation; - -// Called immediately before relaunching. -- (void)updaterWillRelaunchApplication:(SUUpdater *)updater; - -// This method allows you to provide a custom version comparator. -// If you don't implement this method or return nil, the standard version comparator will be used. -- (id )versionComparatorForUpdater:(SUUpdater *)updater; - -// Returns the path which is used to relaunch the client after the update is installed. By default, the path of the host bundle. -- (NSString *)pathToRelaunchForUpdater:(SUUpdater *)updater; - -@end - -// Define some minimum intervals to avoid DOS-like checking attacks. These are in seconds. -#ifdef DEBUG -#define SU_MIN_CHECK_INTERVAL 60 -#else -#define SU_MIN_CHECK_INTERVAL 60*60 -#endif - -#ifdef DEBUG -#define SU_DEFAULT_CHECK_INTERVAL 60 -#else -#define SU_DEFAULT_CHECK_INTERVAL 60*60*24 -#endif - -#endif diff --git a/3rdparty/Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h b/3rdparty/Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h deleted file mode 100644 index 3d11ae8734..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// SUVersionComparisonProtocol.h -// Sparkle -// -// Created by Andy Matuschak on 12/21/07. -// Copyright 2007 Andy Matuschak. All rights reserved. -// - -#ifndef SUVERSIONCOMPARISONPROTOCOL_H -#define SUVERSIONCOMPARISONPROTOCOL_H - -/*! - @protocol - @abstract Implement this protocol to provide version comparison facilities for Sparkle. -*/ -@protocol SUVersionComparison - -/*! - @method - @abstract An abstract method to compare two version strings. - @discussion Should return NSOrderedAscending if b > a, NSOrderedDescending if b < a, and NSOrderedSame if they are equivalent. -*/ -- (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB; - -@end - -#endif diff --git a/3rdparty/Sparkle.framework/Versions/A/Headers/Sparkle.h b/3rdparty/Sparkle.framework/Versions/A/Headers/Sparkle.h deleted file mode 100644 index 08dd577758..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Headers/Sparkle.h +++ /dev/null @@ -1,21 +0,0 @@ -// -// Sparkle.h -// Sparkle -// -// Created by Andy Matuschak on 3/16/06. (Modified by CDHW on 23/12/07) -// Copyright 2006 Andy Matuschak. All rights reserved. -// - -#ifndef SPARKLE_H -#define SPARKLE_H - -// This list should include the shared headers. It doesn't matter if some of them aren't shared (unless -// there are name-space collisions) so we can list all of them to start with: - -#import - -#import -#import -#import - -#endif diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/Info.plist b/3rdparty/Sparkle.framework/Versions/A/Resources/Info.plist deleted file mode 100644 index c7f277d047..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/Info.plist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - Sparkle - CFBundleIdentifier - org.andymatuschak.Sparkle - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - Sparkle - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.5 Beta 6 - CFBundleSignature - ???? - CFBundleVersion - 313 - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/License.txt b/3rdparty/Sparkle.framework/Versions/A/Resources/License.txt deleted file mode 100644 index 20466c417f..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/License.txt +++ /dev/null @@ -1,7 +0,0 @@ -Copyright (c) 2006 Andy Matuschak - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/SUModelTranslation.plist b/3rdparty/Sparkle.framework/Versions/A/Resources/SUModelTranslation.plist deleted file mode 100644 index 92ef9471eb..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/SUModelTranslation.plist +++ /dev/null @@ -1,174 +0,0 @@ - - - - - ADP2,1 - Developer Transition Kit - MacBook1,1 - MacBook (Core Duo) - MacBook2,1 - MacBook (Core 2 Duo) - MacBook4,1 - MacBook (Core 2 Duo Feb 2008) - MacBookAir1,1 - MacBook Air (January 2008) - MacBookPro1,1 - MacBook Pro Core Duo (15-inch) - MacBookPro1,2 - MacBook Pro Core Duo (17-inch) - MacBookPro2,1 - MacBook Pro Core 2 Duo (17-inch) - MacBookPro2,2 - MacBook Pro Core 2 Duo (15-inch) - MacBookPro3,1 - MacBook Pro Core 2 Duo (15-inch LED, Core 2 Duo) - MacBookPro3,2 - MacBook Pro Core 2 Duo (17-inch HD, Core 2 Duo) - MacBookPro4,1 - MacBook Pro (Core 2 Duo Feb 2008) - MacPro1,1 - Mac Pro (four-core) - MacPro2,1 - Mac Pro (eight-core) - MacPro3,1 - Mac Pro (January 2008 4- or 8- core "Harpertown") - Macmini1,1 - Mac Mini (Core Solo/Duo) - PowerBook1,1 - PowerBook G3 - PowerBook2,1 - iBook G3 - PowerBook2,2 - iBook G3 (FireWire) - PowerBook2,3 - iBook G3 - PowerBook2,4 - iBook G3 - PowerBook3,1 - PowerBook G3 (FireWire) - PowerBook3,2 - PowerBook G4 - PowerBook3,3 - PowerBook G4 (Gigabit Ethernet) - PowerBook3,4 - PowerBook G4 (DVI) - PowerBook3,5 - PowerBook G4 (1GHz / 867MHz) - PowerBook4,1 - iBook G3 (Dual USB, Late 2001) - PowerBook4,2 - iBook G3 (16MB VRAM) - PowerBook4,3 - iBook G3 Opaque 16MB VRAM, 32MB VRAM, Early 2003) - PowerBook5,1 - PowerBook G4 (17 inch) - PowerBook5,2 - PowerBook G4 (15 inch FW 800) - PowerBook5,3 - PowerBook G4 (17-inch 1.33GHz) - PowerBook5,4 - PowerBook G4 (15 inch 1.5/1.33GHz) - PowerBook5,5 - PowerBook G4 (17-inch 1.5GHz) - PowerBook5,6 - PowerBook G4 (15 inch 1.67GHz/1.5GHz) - PowerBook5,7 - PowerBook G4 (17-inch 1.67GHz) - PowerBook5,8 - PowerBook G4 (Double layer SD, 15 inch) - PowerBook5,9 - PowerBook G4 (Double layer SD, 17 inch) - PowerBook6,1 - PowerBook G4 (12 inch) - PowerBook6,2 - PowerBook G4 (12 inch, DVI) - PowerBook6,3 - iBook G4 - PowerBook6,4 - PowerBook G4 (12 inch 1.33GHz) - PowerBook6,5 - iBook G4 (Early-Late 2004) - PowerBook6,7 - iBook G4 (Mid 2005) - PowerBook6,8 - PowerBook G4 (12 inch 1.5GHz) - PowerMac1,1 - Power Macintosh G3 (Blue & White) - PowerMac1,2 - Power Macintosh G4 (PCI Graphics) - PowerMac10,1 - Mac Mini G4 - PowerMac10,2 - Mac Mini (Late 2005) - PowerMac11,2 - Power Macintosh G5 (Late 2005) - PowerMac12,1 - iMac G5 (iSight) - PowerMac2,1 - iMac G3 (Slot-loading CD-ROM) - PowerMac2,2 - iMac G3 (Summer 2000) - PowerMac3,1 - Power Macintosh G4 (AGP Graphics) - PowerMac3,2 - Power Macintosh G4 (AGP Graphics) - PowerMac3,3 - Power Macintosh G4 (Gigabit Ethernet) - PowerMac3,4 - Power Macintosh G4 (Digital Audio) - PowerMac3,5 - Power Macintosh G4 (Quick Silver) - PowerMac3,6 - Power Macintosh G4 (Mirrored Drive Door) - PowerMac4,1 - iMac G3 (Early/Summer 2001) - PowerMac4,2 - iMac G4 (Flat Panel) - PowerMac4,4 - eMac - PowerMac4,5 - iMac G4 (17-inch Flat Panel) - PowerMac5,1 - Power Macintosh G4 Cube - PowerMac6,1 - iMac G4 (USB 2.0) - PowerMac6,3 - iMac G4 (20-inch Flat Panel) - PowerMac6,4 - eMac (USB 2.0, 2005) - PowerMac7,2 - Power Macintosh G5 - PowerMac7,3 - Power Macintosh G5 - PowerMac8,1 - iMac G5 - PowerMac8,2 - iMac G5 (Ambient Light Sensor) - PowerMac9,1 - Power Macintosh G5 (Late 2005) - RackMac1,1 - Xserve G4 - RackMac1,2 - Xserve G4 (slot-loading, cluster node) - RackMac3,1 - Xserve G5 - Xserve1,1 - Xserve (Intel Xeon) - Xserve2,1 - Xserve (January 2008 quad-core) - iMac1,1 - iMac G3 (Rev A-D) - iMac4,1 - iMac (Core Duo) - iMac4,2 - iMac for Education (17-inch, Core Duo) - iMac5,1 - iMac (Core 2 Duo, 17 or 20 inch, SuperDrive) - iMac5,2 - iMac (Core 2 Duo, 17 inch, Combo Drive) - iMac6,1 - iMac (Core 2 Duo, 24 inch, SuperDrive) - iMac8,1 - iMac (April 2008) - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/SUStatus.nib/classes.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/SUStatus.nib/classes.nib deleted file mode 100644 index 22f13f8b62..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/SUStatus.nib/classes.nib +++ /dev/null @@ -1,56 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - CLASS - NSApplication - LANGUAGE - ObjC - SUPERCLASS - NSResponder - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - CLASS - SUStatusController - LANGUAGE - ObjC - OUTLETS - - actionButton - NSButton - progressBar - NSProgressIndicator - - SUPERCLASS - SUWindowController - - - IBVersion - 1 - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/SUStatus.nib/info.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/SUStatus.nib/info.nib deleted file mode 100644 index a9ac8673c0..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/SUStatus.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 670 - IBLastKnownRelativeProjectPath - Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 10A96 - targetFramework - IBCocoaFramework - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/SUStatus.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/SUStatus.nib/keyedobjects.nib deleted file mode 100644 index 4f1d598179..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/SUStatus.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/classes.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/classes.nib deleted file mode 100644 index 4b1ab30e5b..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,50 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - doNotInstall - id - installLater - id - installNow - id - - CLASS - SUAutomaticUpdateAlert - LANGUAGE - ObjC - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/info.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/info.nib deleted file mode 100644 index 2e04cfa03c..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 667 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 9D34 - targetFramework - IBCocoaFramework - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index 6b926302ea..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/classes.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/classes.nib deleted file mode 100644 index 994d4c368f..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,67 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - CLASS - NSApplication - LANGUAGE - ObjC - SUPERCLASS - NSResponder - - - ACTIONS - - installUpdate - id - remindMeLater - id - skipThisVersion - id - - CLASS - SUUpdateAlert - LANGUAGE - ObjC - OUTLETS - - delegate - id - description - NSTextField - releaseNotesView - WebView - - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/info.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/info.nib deleted file mode 100644 index 2e04cfa03c..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 667 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 9D34 - targetFramework - IBCocoaFramework - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index b4353d2f7c..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/designable.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/designable.nib deleted file mode 100644 index cfeb220efc..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/designable.nib +++ /dev/null @@ -1,938 +0,0 @@ - - - - 1050 - 10K549 - 1938 - 1038.36 - 461.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 1938 - - - NSUserDefaultsController - NSScroller - NSArrayController - NSButton - NSScrollView - NSImageView - NSTextFieldCell - NSButtonCell - NSImageCell - NSTableView - NSCustomView - NSCustomObject - NSView - NSWindowTemplate - NSTextField - NSTableColumn - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - SUUpdatePermissionPrompt - - - FirstResponder - - - NSApplication - - - 1 - 2 - {{83, 492}, {438, 168}} - 1886912512 - - - NSWindow - - - View - - {213, 107} - - - 256 - - - - 257 - {{256, 12}, {168, 32}} - - 1 - YES - - -2080244224 - 134217728 - Check Automatically - - LucidaGrande - 13 - 1044 - - - 1 - -2038284033 - 1 - - - DQ - 200 - 25 - - - - - 257 - {{134, 12}, {122, 32}} - - YES - - 67239424 - 134217728 - Don't Check - - - -2038284033 - 1 - - - Gw - 200 - 25 - - - - - 264 - {{104, 114}, {315, 34}} - - YES - - 67239424 - 272629760 - Check for updates automatically? - - LucidaGrande-Bold - 13 - 2072 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - - - - 266 - {{104, 81}, {315, 42}} - - YES - - 67239424 - 272629760 - DO NOT LOCALIZE - - LucidaGrande - 11 - 3100 - - - - - - - - - 264 - {{104, 53}, {278, 18}} - - YES - - -2080244224 - 163840 - Include anonymous system profile - - - 1211912703 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - - - - 264 - - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple PNG pasteboard type - NSFilenamesPboardType - NeXT Encapsulated PostScript v1.2 pasteboard type - NeXT TIFF v4.0 pasteboard type - - {{23, 84}, {64, 64}} - - YES - - 130560 - 33554432 - - NSImage - NSApplicationIcon - - 0 - 1 - 0 - YES - - YES - - - - 265 - {{80, 50}, {27, 26}} - - YES - - 67239424 - 134250496 - - - - -1194573569 - 133 - - - 200 - 25 - - - - {438, 168} - - {{0, 0}, {1680, 1028}} - {213, 129} - {1e+13, 1e+13} - - - - visibleKey - visibleValue - displayValue - displayKey - - - YES - YES - YES - YES - YES - - - - 266 - - - - 274 - - - - 2304 - - - - 4352 - {356, 162} - - YES - - - 256 - {{346, 0}, {12, 17}} - - - - 128 - 40 - 1000 - - 75628096 - 2048 - - - - 3 - MC4zMzMzMzI5OQA - - - 6 - System - headerTextColor - - - - - 69336577 - 131072 - Text Cell - - - - 6 - System - textBackgroundColor - - 3 - MQA - - - - - 3 - YES - - - - 167 - 40 - 1000 - - 75628096 - 2048 - - - - - - - 69336577 - 131072 - Text Cell - - - - - - 3 - YES - - - - 3 - 2 - - - 6 - System - gridColor - - 3 - MC41AA - - - 14 - -759169024 - - - 4 - 15 - 0 - NO - 0 - - - {{1, 1}, {356, 162}} - - - - - 6 - System - controlBackgroundColor - - - 4 - - - - -2147483392 - {{-22, 1}, {11, 125}} - - 256 - - _doScroller: - 0.78125 - - - - -2147483392 - {{-100, -100}, {345, 11}} - - 257 - - _doScroller: - 0.99047619104385376 - - - {{4, 5}, {358, 164}} - - - 530 - - - - AAAAAAAAAABBgAAAQYAAAA - - - - 266 - {{1, 177}, {361, 70}} - - YES - - 67239424 - 272629760 - QW5vbnltb3VzIHN5c3RlbSBwcm9maWxlIGluZm9ybWF0aW9uIGlzIHVzZWQgdG8gaGVscCB1cyBwbGFu -IGZ1dHVyZSBkZXZlbG9wbWVudCB3b3JrLiBQbGVhc2UgY29udGFjdCB1cyBpZiB5b3UgaGF2ZSBhbnkg -cXVlc3Rpb25zIGFib3V0IHRoaXMuCgpUaGlzIGlzIHRoZSBpbmZvcm1hdGlvbiB0aGF0IHdvdWxkIGJl -IHNlbnQ6A - - - - - - - - {365, 254} - NSView - NSResponder - - - - SUIncludeProfile - SUSendProfileInfo - - YES - - - - - - - finishPrompt: - - - - 144 - - - - descriptionTextField - - - - 133 - - - - window - - - - 126 - - - - finishPrompt: - - - - 145 - - - - moreInfoView - - - - 127 - - - - toggleMoreInfo: - - - - 131 - - - - moreInfoButton - - - - 132 - - - - contentArray: systemProfileInformationArray - - - - - - contentArray: systemProfileInformationArray - contentArray - systemProfileInformationArray - 2 - - - 25 - - - - value: promptDescription - - - - - - value: promptDescription - value - promptDescription - 2 - - - 161 - - - - hidden: shouldAskAboutProfile - - - - - - hidden: shouldAskAboutProfile - hidden - shouldAskAboutProfile - - NSValueTransformerName - NSNegateBoolean - - 2 - - - 143 - - - - value: shouldSendProfile - - - - - - value: shouldSendProfile - value - shouldSendProfile - - - - - 2 - - - 148 - - - - value: icon - - - - - - value: icon - value - icon - 2 - - - 130 - - - - value: arrangedObjects.displayKey - - - - - - value: arrangedObjects.displayKey - value - arrangedObjects.displayKey - 2 - - - 174 - - - - value: arrangedObjects.displayValue - - - - - - value: arrangedObjects.displayValue - value - arrangedObjects.displayValue - 2 - - - 173 - - - - hidden: shouldAskAboutProfile - - - - - - hidden: shouldAskAboutProfile - hidden - shouldAskAboutProfile - - NSValueTransformerName - NSNegateBoolean - - 2 - - - 139 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 5 - - - - - - Profile Info - - - 6 - - - - - - - - - - - - - - 13 - - - - - - - - 14 - - - - - - - - 32 - - - - - - - - 33 - - - - - - - - 34 - - - - - - - - 37 - - - - - - - - 71 - - - - - - - - 24 - - - Array Controller - - - 39 - - - - - - - MoreInfoView - - - 40 - - - - - - - - - - 41 - - - - - - - - - 42 - - - - - - - - 43 - - - - - 44 - - - - - - - - 45 - - - - - 46 - - - - - - - - 49 - - - User Defaults Controller - - - 176 - - - - - 177 - - - - - 178 - - - - - 179 - - - - - 180 - - - - - 181 - - - - - 182 - - - - - 183 - - - - - 184 - - - - - 185 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 185 - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - YES - 3 - - {128, 128} - {15, 15} - - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib deleted file mode 100644 index 86c796189c..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings b/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings deleted file mode 100644 index 6a99f23e60..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/classes.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/classes.nib deleted file mode 100644 index 4b1ab30e5b..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,50 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - doNotInstall - id - installLater - id - installNow - id - - CLASS - SUAutomaticUpdateAlert - LANGUAGE - ObjC - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/info.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/info.nib deleted file mode 100644 index ab36d31037..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 658 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 9C7010 - targetFramework - IBCocoaFramework - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index 7630390c89..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/classes.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/classes.nib deleted file mode 100644 index 994d4c368f..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,67 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - CLASS - NSApplication - LANGUAGE - ObjC - SUPERCLASS - NSResponder - - - ACTIONS - - installUpdate - id - remindMeLater - id - skipThisVersion - id - - CLASS - SUUpdateAlert - LANGUAGE - ObjC - OUTLETS - - delegate - id - description - NSTextField - releaseNotesView - WebView - - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/info.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/info.nib deleted file mode 100644 index 2fb8a83726..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 670 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 18 - - IBSystem Version - 10A96 - targetFramework - IBCocoaFramework - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index e7e7497db4..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/classes.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/classes.nib deleted file mode 100644 index 5220a221f4..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/classes.nib +++ /dev/null @@ -1,59 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - finishPrompt - id - toggleMoreInfo - id - - CLASS - SUUpdatePermissionPrompt - LANGUAGE - ObjC - OUTLETS - - delegate - id - descriptionTextField - NSTextField - moreInfoButton - NSButton - moreInfoView - NSView - - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/info.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/info.nib deleted file mode 100644 index b1cd28eddc..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/info.nib +++ /dev/null @@ -1,21 +0,0 @@ - - - - - IBFramework Version - 670 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - 41 - - IBSystem Version - 10A96 - targetFramework - IBCocoaFramework - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib deleted file mode 100644 index e8dc5b8802..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings b/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings deleted file mode 100644 index 16e0787b46..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/classes.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/classes.nib deleted file mode 100644 index 4b1ab30e5b..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,50 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - doNotInstall - id - installLater - id - installNow - id - - CLASS - SUAutomaticUpdateAlert - LANGUAGE - ObjC - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/info.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/info.nib deleted file mode 100644 index 2e04cfa03c..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 667 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 9D34 - targetFramework - IBCocoaFramework - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index 6b2f938f90..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/classes.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/classes.nib deleted file mode 100644 index 994d4c368f..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,67 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - CLASS - NSApplication - LANGUAGE - ObjC - SUPERCLASS - NSResponder - - - ACTIONS - - installUpdate - id - remindMeLater - id - skipThisVersion - id - - CLASS - SUUpdateAlert - LANGUAGE - ObjC - OUTLETS - - delegate - id - description - NSTextField - releaseNotesView - WebView - - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/info.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/info.nib deleted file mode 100644 index 2e04cfa03c..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 667 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 9D34 - targetFramework - IBCocoaFramework - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index c9b1e7d883..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/designable.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/designable.nib deleted file mode 100644 index ed4f0279cd..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/designable.nib +++ /dev/null @@ -1,938 +0,0 @@ - - - - 1050 - 10K549 - 1938 - 1038.36 - 461.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 1938 - - - NSUserDefaultsController - NSScroller - NSArrayController - NSButton - NSScrollView - NSImageView - NSTextFieldCell - NSButtonCell - NSImageCell - NSTableView - NSCustomView - NSCustomObject - NSView - NSWindowTemplate - NSTextField - NSTableColumn - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - SUUpdatePermissionPrompt - - - FirstResponder - - - NSApplication - - - 1 - 2 - {{83, 492}, {438, 168}} - 1886912512 - - - NSWindow - - - View - - {213, 107} - - - 256 - - - - 257 - {{255, 12}, {169, 32}} - - 1 - YES - - -2080244224 - 134217728 - Check Automatically - - LucidaGrande - 13 - 1044 - - - 1 - -2038284033 - 1 - - - DQ - 200 - 25 - - - - - 257 - {{138, 12}, {117, 32}} - - YES - - 67239424 - 134217728 - Don't Check - - - -2038284033 - 1 - - - Gw - 200 - 25 - - - - - 264 - {{104, 114}, {289, 34}} - - YES - - 67239424 - 272629760 - Check for updates automatically? - - LucidaGrande-Bold - 13 - 2072 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - - - - 266 - {{104, 81}, {315, 42}} - - YES - - 67239424 - 272629760 - DO NOT LOCALIZE - - LucidaGrande - 11 - 3100 - - - - - - - - - 264 - {{104, 53}, {278, 18}} - - YES - - -2080244224 - 163840 - Include anonymous system profile - - - 1211912703 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - - - - 264 - - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple PNG pasteboard type - NSFilenamesPboardType - NeXT Encapsulated PostScript v1.2 pasteboard type - NeXT TIFF v4.0 pasteboard type - - {{23, 84}, {64, 64}} - - YES - - 130560 - 33554432 - - NSImage - NSApplicationIcon - - 0 - 1 - 0 - YES - - YES - - - - 265 - {{80, 50}, {27, 26}} - - YES - - 67239424 - 134250496 - - - - -1194573569 - 133 - - - 200 - 25 - - - - {438, 168} - - {{0, 0}, {1280, 778}} - {213, 129} - {1e+13, 1e+13} - - - - visibleKey - visibleValue - displayValue - displayKey - - - YES - YES - YES - YES - YES - - - - 266 - - - - 274 - - - - 2304 - - - - 4352 - {353, 113} - - YES - - - 256 - {{346, 0}, {12, 17}} - - - - 128 - 40 - 1000 - - 75628096 - 2048 - - - - 3 - MC4zMzMzMzI5OQA - - - 6 - System - headerTextColor - - - - - 69336577 - 131072 - Text Cell - - - - 6 - System - textBackgroundColor - - 3 - MQA - - - - - 3 - YES - - - - 219 - 40 - 1000 - - 75628096 - 2048 - - - - - - - 69336577 - 131072 - Text Cell - - - - - - 3 - YES - - - - 3 - 2 - - - 6 - System - gridColor - - 3 - MC41AA - - - 14 - -759169024 - - - 4 - 15 - 0 - NO - 0 - - - {{1, 1}, {353, 113}} - - - - - 6 - System - controlBackgroundColor - - - 4 - - - - -2147483392 - {{-22, 1}, {11, 125}} - - 256 - - _doScroller: - 0.78125 - - - - -2147483392 - {{-100, -100}, {345, 11}} - - 257 - - _doScroller: - 0.99047619104385376 - - - {{4, 5}, {355, 115}} - - - 530 - - - - AAAAAAAAAABBgAAAQYAAAA - - - - 266 - {{1, 128}, {358, 70}} - - YES - - 67239424 - 272629760 - QW5vbnltb3VzIHN5c3RlbSBwcm9maWxlIGluZm9ybWF0aW9uIGlzIHVzZWQgdG8gaGVscCB1cyBwbGFu -IGZ1dHVyZSBkZXZlbG9wbWVudCB3b3JrLiBQbGVhc2UgY29udGFjdCB1cyBpZiB5b3UgaGF2ZSBhbnkg -cXVlc3Rpb25zIGFib3V0IHRoaXMuCgpUaGlzIGlzIHRoZSBpbmZvcm1hdGlvbiB0aGF0IHdvdWxkIGJl -IHNlbnQ6A - - - - - - - - {362, 205} - NSView - NSResponder - - - - SUIncludeProfile - SUSendProfileInfo - - YES - - - - - - - finishPrompt: - - - - 144 - - - - descriptionTextField - - - - 133 - - - - window - - - - 126 - - - - finishPrompt: - - - - 145 - - - - moreInfoView - - - - 127 - - - - toggleMoreInfo: - - - - 131 - - - - moreInfoButton - - - - 132 - - - - contentArray: systemProfileInformationArray - - - - - - contentArray: systemProfileInformationArray - contentArray - systemProfileInformationArray - 2 - - - 25 - - - - value: promptDescription - - - - - - value: promptDescription - value - promptDescription - 2 - - - 161 - - - - hidden: shouldAskAboutProfile - - - - - - hidden: shouldAskAboutProfile - hidden - shouldAskAboutProfile - - NSValueTransformerName - NSNegateBoolean - - 2 - - - 143 - - - - value: shouldSendProfile - - - - - - value: shouldSendProfile - value - shouldSendProfile - - - - - 2 - - - 148 - - - - value: icon - - - - - - value: icon - value - icon - 2 - - - 130 - - - - value: arrangedObjects.displayKey - - - - - - value: arrangedObjects.displayKey - value - arrangedObjects.displayKey - 2 - - - 174 - - - - value: arrangedObjects.displayValue - - - - - - value: arrangedObjects.displayValue - value - arrangedObjects.displayValue - 2 - - - 173 - - - - hidden: shouldAskAboutProfile - - - - - - hidden: shouldAskAboutProfile - hidden - shouldAskAboutProfile - - NSValueTransformerName - NSNegateBoolean - - 2 - - - 139 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 5 - - - - - - Profile Info - - - 6 - - - - - - - - - - - - - - 13 - - - - - - - - 14 - - - - - - - - 32 - - - - - - - - 33 - - - - - - - - 34 - - - - - - - - 37 - - - - - - - - 71 - - - - - - - - 24 - - - Array Controller - - - 39 - - - - - - - MoreInfoView - - - 40 - - - - - - - - - - 41 - - - - - - - - - 42 - - - - - - - - 43 - - - - - 44 - - - - - - - - 45 - - - - - 46 - - - - - - - - 49 - - - User Defaults Controller - - - 176 - - - - - 177 - - - - - 178 - - - - - 179 - - - - - 180 - - - - - 181 - - - - - 182 - - - - - 183 - - - - - 184 - - - - - 185 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 185 - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - YES - 3 - - {128, 128} - {15, 15} - - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib deleted file mode 100644 index 15a08e627e..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings b/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings deleted file mode 100644 index 8274b5e2a7..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/classes.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/classes.nib deleted file mode 100644 index 4b1ab30e5b..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,50 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - doNotInstall - id - installLater - id - installNow - id - - CLASS - SUAutomaticUpdateAlert - LANGUAGE - ObjC - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/info.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/info.nib deleted file mode 100644 index 33a60200f9..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/info.nib +++ /dev/null @@ -1,16 +0,0 @@ - - - - - IBFramework Version - 629 - IBOldestOS - 5 - IBOpenObjects - - IBSystem Version - 9D34 - targetFramework - IBCocoaFramework - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index 4cd529a56b..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/classes.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/classes.nib deleted file mode 100644 index 994d4c368f..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,67 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - CLASS - NSApplication - LANGUAGE - ObjC - SUPERCLASS - NSResponder - - - ACTIONS - - installUpdate - id - remindMeLater - id - skipThisVersion - id - - CLASS - SUUpdateAlert - LANGUAGE - ObjC - OUTLETS - - delegate - id - description - NSTextField - releaseNotesView - WebView - - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/info.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/info.nib deleted file mode 100644 index d2586ea20e..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/info.nib +++ /dev/null @@ -1,16 +0,0 @@ - - - - - IBFramework Version - 629 - IBOldestOS - 5 - IBOpenObjects - - IBSystem Version - 9E17 - targetFramework - IBCocoaFramework - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index 65dfc95e3c..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/designable.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/designable.nib deleted file mode 100644 index dc4328c47c..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/designable.nib +++ /dev/null @@ -1,938 +0,0 @@ - - - - 1050 - 10K549 - 1938 - 1038.36 - 461.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 1938 - - - NSUserDefaultsController - NSScroller - NSArrayController - NSButton - NSScrollView - NSImageView - NSTextFieldCell - NSButtonCell - NSImageCell - NSTableView - NSCustomView - NSCustomObject - NSView - NSWindowTemplate - NSTextField - NSTableColumn - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - SUUpdatePermissionPrompt - - - FirstResponder - - - NSApplication - - - 1 - 2 - {{115, 815}, {438, 168}} - 1886912512 - - - NSWindow - - - View - - {213, 107} - - - 256 - - - - 257 - {{362, 12}, {62, 32}} - - 1 - YES - - -2080244224 - 134217728 - Check Automatically - - LucidaGrande - 13 - 1044 - - - 1 - -2038284033 - 1 - - - DQ - 200 - 25 - - - - - 257 - {{296, 12}, {66, 32}} - - YES - - 67239424 - 134217728 - Don't Check - - - -2038284033 - 1 - - - Gw - 200 - 25 - - - - - 264 - {{104, 114}, {326, 34}} - - YES - - 67239424 - 272629760 - Check for updates automatically? - - LucidaGrande-Bold - 13 - 2072 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - - - - 266 - {{104, 81}, {315, 42}} - - YES - - 67239424 - 272629760 - DO NOT LOCALIZE - - LucidaGrande - 11 - 3100 - - - - - - - - - 264 - {{104, 53}, {294, 18}} - - YES - - -2080244224 - 163840 - Include anonymous system profile - - - 1211912703 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - - - - 264 - - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple PNG pasteboard type - NSFilenamesPboardType - NeXT Encapsulated PostScript v1.2 pasteboard type - NeXT TIFF v4.0 pasteboard type - - {{23, 84}, {64, 64}} - - YES - - 130560 - 33554432 - - NSImage - NSApplicationIcon - - 0 - 1 - 0 - YES - - YES - - - - 265 - {{80, 50}, {27, 26}} - - YES - - 67239424 - 134250496 - - - - -1194573569 - 133 - - - 200 - 25 - - - - {438, 168} - - {{0, 0}, {1600, 1178}} - {213, 129} - {1e+13, 1e+13} - - - - visibleKey - visibleValue - displayValue - displayKey - - - YES - YES - YES - YES - YES - - - - 266 - - - - 274 - - - - 2304 - - - - 4352 - {356, 162} - - YES - - - 256 - {{346, 0}, {12, 17}} - - - - 128 - 40 - 1000 - - 75628096 - 2048 - - - - 3 - MC4zMzMzMzI5OQA - - - 6 - System - headerTextColor - - - - - 69336577 - 131072 - Text Cell - - - - 6 - System - textBackgroundColor - - 3 - MQA - - - - - 3 - YES - - - - 167 - 40 - 1000 - - 75628096 - 2048 - - - - - - - 69336577 - 131072 - Text Cell - - - - - - 3 - YES - - - - 3 - 2 - - - 6 - System - gridColor - - 3 - MC41AA - - - 14 - -759169024 - - - 4 - 15 - 0 - NO - 0 - - - {{1, 1}, {356, 162}} - - - - - 6 - System - controlBackgroundColor - - - 4 - - - - -2147483392 - {{-22, 1}, {11, 125}} - - 256 - - _doScroller: - 0.78125 - - - - -2147483392 - {{-100, -100}, {345, 11}} - - 257 - - _doScroller: - 0.99047619104385376 - - - {{4, 5}, {358, 164}} - - - 530 - - - - AAAAAAAAAABBgAAAQYAAAA - - - - 266 - {{1, 177}, {361, 70}} - - YES - - 67239424 - 272629760 - QW5vbnltb3VzIHN5c3RlbSBwcm9maWxlIGluZm9ybWF0aW9uIGlzIHVzZWQgdG8gaGVscCB1cyBwbGFu -IGZ1dHVyZSBkZXZlbG9wbWVudCB3b3JrLiBQbGVhc2UgY29udGFjdCB1cyBpZiB5b3UgaGF2ZSBhbnkg -cXVlc3Rpb25zIGFib3V0IHRoaXMuCgpUaGlzIGlzIHRoZSBpbmZvcm1hdGlvbiB0aGF0IHdvdWxkIGJl -IHNlbnQ6A - - - - - - - - {365, 254} - NSView - NSResponder - - - - SUIncludeProfile - SUSendProfileInfo - - YES - - - - - - - finishPrompt: - - - - 144 - - - - descriptionTextField - - - - 133 - - - - window - - - - 126 - - - - finishPrompt: - - - - 145 - - - - moreInfoView - - - - 127 - - - - toggleMoreInfo: - - - - 131 - - - - moreInfoButton - - - - 132 - - - - contentArray: systemProfileInformationArray - - - - - - contentArray: systemProfileInformationArray - contentArray - systemProfileInformationArray - 2 - - - 25 - - - - value: promptDescription - - - - - - value: promptDescription - value - promptDescription - 2 - - - 161 - - - - hidden: shouldAskAboutProfile - - - - - - hidden: shouldAskAboutProfile - hidden - shouldAskAboutProfile - - NSValueTransformerName - NSNegateBoolean - - 2 - - - 143 - - - - value: shouldSendProfile - - - - - - value: shouldSendProfile - value - shouldSendProfile - - - - - 2 - - - 148 - - - - value: icon - - - - - - value: icon - value - icon - 2 - - - 130 - - - - value: arrangedObjects.displayKey - - - - - - value: arrangedObjects.displayKey - value - arrangedObjects.displayKey - 2 - - - 174 - - - - value: arrangedObjects.displayValue - - - - - - value: arrangedObjects.displayValue - value - arrangedObjects.displayValue - 2 - - - 173 - - - - hidden: shouldAskAboutProfile - - - - - - hidden: shouldAskAboutProfile - hidden - shouldAskAboutProfile - - NSValueTransformerName - NSNegateBoolean - - 2 - - - 139 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 5 - - - - - - Profile Info - - - 6 - - - - - - - - - - - - - - 13 - - - - - - - - 14 - - - - - - - - 32 - - - - - - - - 33 - - - - - - - - 34 - - - - - - - - 37 - - - - - - - - 71 - - - - - - - - 24 - - - Array Controller - - - 39 - - - - - - - MoreInfoView - - - 40 - - - - - - - - - - 41 - - - - - - - - - 42 - - - - - - - - 43 - - - - - 44 - - - - - - - - 45 - - - - - 46 - - - - - - - - 49 - - - User Defaults Controller - - - 176 - - - - - 177 - - - - - 178 - - - - - 179 - - - - - 180 - - - - - 181 - - - - - 182 - - - - - 183 - - - - - 184 - - - - - 185 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 185 - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - YES - 3 - - {128, 128} - {15, 15} - - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib deleted file mode 100644 index c28fbb1e1f..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings b/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings deleted file mode 100644 index 98211ebc8b..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/classes.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/classes.nib deleted file mode 100644 index 4b1ab30e5b..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,50 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - doNotInstall - id - installLater - id - installNow - id - - CLASS - SUAutomaticUpdateAlert - LANGUAGE - ObjC - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/info.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/info.nib deleted file mode 100644 index 2e04cfa03c..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 667 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 9D34 - targetFramework - IBCocoaFramework - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index 15ba8f4c8e..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/classes.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/classes.nib deleted file mode 100644 index 994d4c368f..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,67 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - CLASS - NSApplication - LANGUAGE - ObjC - SUPERCLASS - NSResponder - - - ACTIONS - - installUpdate - id - remindMeLater - id - skipThisVersion - id - - CLASS - SUUpdateAlert - LANGUAGE - ObjC - OUTLETS - - delegate - id - description - NSTextField - releaseNotesView - WebView - - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/info.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/info.nib deleted file mode 100644 index 2e04cfa03c..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 667 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 9D34 - targetFramework - IBCocoaFramework - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index 2984064502..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/designable.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/designable.nib deleted file mode 100644 index 8bc975dddc..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/designable.nib +++ /dev/null @@ -1,938 +0,0 @@ - - - - 1050 - 10K549 - 1938 - 1038.36 - 461.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 1938 - - - NSUserDefaultsController - NSScroller - NSArrayController - NSButton - NSScrollView - NSImageView - NSTextFieldCell - NSButtonCell - NSImageCell - NSTableView - NSCustomView - NSCustomObject - NSView - NSWindowTemplate - NSTextField - NSTableColumn - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - SUUpdatePermissionPrompt - - - FirstResponder - - - NSApplication - - - 1 - 2 - {{83, 493}, {485, 167}} - 1886912512 - - - NSWindow - - - View - - {213, 107} - - - 256 - - - - 257 - {{257, 12}, {214, 32}} - - 1 - YES - - -2080244224 - 134217728 - Check Automatically - - LucidaGrande - 13 - 1044 - - - 1 - -2038284033 - 1 - - - DQ - 200 - 25 - - - - - 257 - {{119, 12}, {138, 32}} - - YES - - 67239424 - 134217728 - Don't Check - - - -2038284033 - 1 - - - Gw - 200 - 25 - - - - - 264 - {{104, 113}, {362, 34}} - - YES - - 67239424 - 272629760 - Check for updates automatically? - - LucidaGrande-Bold - 13 - 2072 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - - - - 266 - {{104, 63}, {362, 42}} - - YES - - 67239424 - 272629760 - DO NOT LOCALIZE - - LucidaGrande - 11 - 3100 - - - - - - - - - 264 - {{104, 52}, {278, 18}} - - YES - - -2080244224 - 163840 - Include anonymous system profile - - - 1211912703 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - - - - 264 - - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple PNG pasteboard type - NSFilenamesPboardType - NeXT Encapsulated PostScript v1.2 pasteboard type - NeXT TIFF v4.0 pasteboard type - - {{23, 83}, {64, 64}} - - YES - - 130560 - 33554432 - - NSImage - NSApplicationIcon - - 0 - 1 - 0 - YES - - YES - - - - 265 - {{79, 49}, {27, 26}} - - YES - - 67239424 - 134250496 - - - - -1194573569 - 133 - - - 200 - 25 - - - - {485, 167} - - {{0, 0}, {1680, 1028}} - {213, 129} - {1e+13, 1e+13} - - - - visibleKey - visibleValue - displayValue - displayKey - - - YES - YES - YES - YES - YES - - - - 266 - - - - 274 - - - - 2304 - - - - 4352 - {353, 113} - - YES - - - 256 - {{346, 0}, {12, 17}} - - - - 128 - 40 - 1000 - - 75628096 - 2048 - - - - 3 - MC4zMzMzMzI5OQA - - - 6 - System - headerTextColor - - - - - 69336577 - 131072 - Text Cell - - - - 6 - System - textBackgroundColor - - 3 - MQA - - - - - 3 - YES - - - - 219 - 40 - 1000 - - 75628096 - 2048 - - - - - - - 69336577 - 131072 - Text Cell - - - - - - 3 - YES - - - - 3 - 2 - - - 6 - System - gridColor - - 3 - MC41AA - - - 14 - -759169024 - - - 4 - 15 - 0 - NO - 0 - - - {{1, 1}, {353, 113}} - - - - - 6 - System - controlBackgroundColor - - - 4 - - - - -2147483392 - {{-22, 1}, {11, 125}} - - 256 - - _doScroller: - 0.78125 - - - - -2147483392 - {{-100, -100}, {345, 11}} - - 257 - - _doScroller: - 0.99047619104385376 - - - {{4, 5}, {355, 115}} - - - 530 - - - - AAAAAAAAAABBgAAAQYAAAA - - - - 266 - {{1, 128}, {358, 70}} - - YES - - 67239424 - 272629760 - QW5vbnltb3VzIHN5c3RlbSBwcm9maWxlIGluZm9ybWF0aW9uIGlzIHVzZWQgdG8gaGVscCB1cyBwbGFu -IGZ1dHVyZSBkZXZlbG9wbWVudCB3b3JrLiBQbGVhc2UgY29udGFjdCB1cyBpZiB5b3UgaGF2ZSBhbnkg -cXVlc3Rpb25zIGFib3V0IHRoaXMuCgpUaGlzIGlzIHRoZSBpbmZvcm1hdGlvbiB0aGF0IHdvdWxkIGJl -IHNlbnQ6A - - - - - - - - {362, 205} - NSView - NSResponder - - - - SUIncludeProfile - SUSendProfileInfo - - YES - - - - - - - finishPrompt: - - - - 144 - - - - descriptionTextField - - - - 133 - - - - window - - - - 126 - - - - finishPrompt: - - - - 145 - - - - moreInfoView - - - - 127 - - - - toggleMoreInfo: - - - - 131 - - - - moreInfoButton - - - - 132 - - - - contentArray: systemProfileInformationArray - - - - - - contentArray: systemProfileInformationArray - contentArray - systemProfileInformationArray - 2 - - - 25 - - - - value: promptDescription - - - - - - value: promptDescription - value - promptDescription - 2 - - - 161 - - - - hidden: shouldAskAboutProfile - - - - - - hidden: shouldAskAboutProfile - hidden - shouldAskAboutProfile - - NSValueTransformerName - NSNegateBoolean - - 2 - - - 143 - - - - value: shouldSendProfile - - - - - - value: shouldSendProfile - value - shouldSendProfile - - - - - 2 - - - 148 - - - - value: icon - - - - - - value: icon - value - icon - 2 - - - 130 - - - - value: arrangedObjects.displayKey - - - - - - value: arrangedObjects.displayKey - value - arrangedObjects.displayKey - 2 - - - 174 - - - - value: arrangedObjects.displayValue - - - - - - value: arrangedObjects.displayValue - value - arrangedObjects.displayValue - 2 - - - 173 - - - - hidden: shouldAskAboutProfile - - - - - - hidden: shouldAskAboutProfile - hidden - shouldAskAboutProfile - - NSValueTransformerName - NSNegateBoolean - - 2 - - - 139 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 5 - - - - - - Profile Info - - - 6 - - - - - - - - - - - - - - 13 - - - - - - - - 14 - - - - - - - - 32 - - - - - - - - 33 - - - - - - - - 34 - - - - - - - - 37 - - - - - - - - 71 - - - - - - - - 24 - - - Array Controller - - - 39 - - - - - - - MoreInfoView - - - 40 - - - - - - - - - - 41 - - - - - - - - - 42 - - - - - - - - 43 - - - - - 44 - - - - - - - - 45 - - - - - 46 - - - - - - - - 49 - - - User Defaults Controller - - - 176 - - - - - 177 - - - - - 178 - - - - - 179 - - - - - 180 - - - - - 181 - - - - - 182 - - - - - 183 - - - - - 184 - - - - - 185 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 185 - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - YES - 3 - - {128, 128} - {15, 15} - - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib deleted file mode 100644 index 3576ff07ee..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings b/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings deleted file mode 100644 index c611f147f7..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/classes.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/classes.nib deleted file mode 100644 index 4b1ab30e5b..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,50 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - doNotInstall - id - installLater - id - installNow - id - - CLASS - SUAutomaticUpdateAlert - LANGUAGE - ObjC - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/info.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/info.nib deleted file mode 100644 index 3f09790835..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/info.nib +++ /dev/null @@ -1,18 +0,0 @@ - - - - - IBFramework Version - 629 - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 9D34 - targetFramework - IBCocoaFramework - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index aa38f86ba2..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/classes.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/classes.nib deleted file mode 100644 index 994d4c368f..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,67 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - CLASS - NSApplication - LANGUAGE - ObjC - SUPERCLASS - NSResponder - - - ACTIONS - - installUpdate - id - remindMeLater - id - skipThisVersion - id - - CLASS - SUUpdateAlert - LANGUAGE - ObjC - OUTLETS - - delegate - id - description - NSTextField - releaseNotesView - WebView - - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/info.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/info.nib deleted file mode 100644 index d2586ea20e..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/info.nib +++ /dev/null @@ -1,16 +0,0 @@ - - - - - IBFramework Version - 629 - IBOldestOS - 5 - IBOpenObjects - - IBSystem Version - 9E17 - targetFramework - IBCocoaFramework - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index c82d3581bf..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/designable.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/designable.nib deleted file mode 100644 index 088cfa274a..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/designable.nib +++ /dev/null @@ -1,938 +0,0 @@ - - - - 1050 - 10K549 - 1938 - 1038.36 - 461.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 1938 - - - NSUserDefaultsController - NSScroller - NSArrayController - NSButton - NSScrollView - NSImageView - NSTextFieldCell - NSButtonCell - NSImageCell - NSTableView - NSCustomView - NSCustomObject - NSView - NSWindowTemplate - NSTextField - NSTableColumn - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - SUUpdatePermissionPrompt - - - FirstResponder - - - NSApplication - - - 1 - 2 - {{83, 492}, {438, 168}} - 1886912512 - - - NSWindow - - - View - - {213, 107} - - - 256 - - - - 257 - {{255, 12}, {169, 32}} - - 1 - YES - - -2080244224 - 134217728 - Zoek automatisch - - LucidaGrande - 13 - 1044 - - - 1 - -2038284033 - 1 - - - DQ - 200 - 25 - - - - - 257 - {{138, 12}, {117, 32}} - - YES - - 67239424 - 134217728 - Niet zoeken - - - -2038284033 - 1 - - - Gw - 200 - 25 - - - - - 264 - {{104, 114}, {289, 34}} - - YES - - 67239424 - 272629760 - Automatisch zoeken naar nieuwe versies? - - LucidaGrande-Bold - 13 - 2072 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - - - - 266 - {{104, 81}, {315, 42}} - - YES - - 67239424 - 272629760 - DO NOT LOCALIZE - - LucidaGrande - 11 - 3100 - - - - - - - - - 264 - {{104, 53}, {278, 18}} - - YES - - -2080244224 - 163840 - Voeg anoniem systeemprofiel toe - - - 1211912703 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - - - - 264 - - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple PNG pasteboard type - NSFilenamesPboardType - NeXT Encapsulated PostScript v1.2 pasteboard type - NeXT TIFF v4.0 pasteboard type - - {{23, 84}, {64, 64}} - - YES - - 130560 - 33554432 - - NSImage - NSApplicationIcon - - 0 - 1 - 0 - YES - - YES - - - - 265 - {{80, 50}, {27, 26}} - - YES - - 67239424 - 134250496 - - - - -1194573569 - 133 - - - 200 - 25 - - - - {438, 168} - - {{0, 0}, {1280, 778}} - {213, 129} - {1e+13, 1e+13} - - - - visibleKey - visibleValue - displayValue - displayKey - - - YES - YES - YES - YES - YES - - - - 266 - - - - 274 - - - - 2304 - - - - 4352 - {353, 113} - - YES - - - 256 - {{346, 0}, {12, 17}} - - - - 128 - 40 - 1000 - - 75628096 - 2048 - - - - 3 - MC4zMzMzMzI5OQA - - - 6 - System - headerTextColor - - - - - 69336577 - 131072 - Text Cell - - - - 6 - System - textBackgroundColor - - 3 - MQA - - - - - 3 - YES - - - - 219 - 40 - 1000 - - 75628096 - 2048 - - - - - - - 69336577 - 131072 - Text Cell - - - - - - 3 - YES - - - - 3 - 2 - - - 6 - System - gridColor - - 3 - MC41AA - - - 14 - -759169024 - - - 4 - 15 - 0 - NO - 0 - - - {{1, 1}, {353, 113}} - - - - - 6 - System - controlBackgroundColor - - - 4 - - - - -2147483392 - {{-22, 1}, {11, 125}} - - 256 - - _doScroller: - 0.78125 - - - - -2147483392 - {{-100, -100}, {345, 11}} - - 257 - - _doScroller: - 0.99047619104385376 - - - {{4, 5}, {355, 115}} - - - 530 - - - - AAAAAAAAAABBgAAAQYAAAA - - - - 266 - {{1, 128}, {358, 70}} - - YES - - 67239424 - 272629760 - QW5vbmllbWUgc3lzdGVlbXByb2ZpZWwtaW5mb3JtYXRpZSB3b3JkdCBnZWJydWlrdCBvbSBvbnMgdGUg -aGVscGVuIG1ldCBoZXQgcGxhbm5lbiB2YW4gdG9la29tc3RpZ2Ugb250d2lra2VsaW5nZW4uIEFscyB1 -IGhpZXJvdmVyIHZyYWdlbiBoZWVmdCwga3VudCB1IGNvbnRhY3QgbWV0IG9ucyBvcG5lbWVuLgoKRGV6 -ZSBpbmZvcm1hdGllIHphbCB3b3JkZW4gdmVyem9uZGVuOg - - - - - - - - {362, 205} - NSView - NSResponder - - - - SUIncludeProfile - SUSendProfileInfo - - YES - - - - - - - finishPrompt: - - - - 144 - - - - descriptionTextField - - - - 133 - - - - window - - - - 126 - - - - finishPrompt: - - - - 145 - - - - moreInfoView - - - - 127 - - - - toggleMoreInfo: - - - - 131 - - - - moreInfoButton - - - - 132 - - - - contentArray: systemProfileInformationArray - - - - - - contentArray: systemProfileInformationArray - contentArray - systemProfileInformationArray - 2 - - - 25 - - - - value: promptDescription - - - - - - value: promptDescription - value - promptDescription - 2 - - - 161 - - - - hidden: shouldAskAboutProfile - - - - - - hidden: shouldAskAboutProfile - hidden - shouldAskAboutProfile - - NSValueTransformerName - NSNegateBoolean - - 2 - - - 143 - - - - value: shouldSendProfile - - - - - - value: shouldSendProfile - value - shouldSendProfile - - - - - 2 - - - 148 - - - - value: icon - - - - - - value: icon - value - icon - 2 - - - 130 - - - - value: arrangedObjects.displayKey - - - - - - value: arrangedObjects.displayKey - value - arrangedObjects.displayKey - 2 - - - 174 - - - - value: arrangedObjects.displayValue - - - - - - value: arrangedObjects.displayValue - value - arrangedObjects.displayValue - 2 - - - 173 - - - - hidden: shouldAskAboutProfile - - - - - - hidden: shouldAskAboutProfile - hidden - shouldAskAboutProfile - - NSValueTransformerName - NSNegateBoolean - - 2 - - - 139 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 5 - - - - - - Profile Info - - - 6 - - - - - - - - - - - - - - 13 - - - - - - - - 14 - - - - - - - - 32 - - - - - - - - 33 - - - - - - - - 34 - - - - - - - - 37 - - - - - - - - 71 - - - - - - - - 24 - - - Array Controller - - - 39 - - - - - - - MoreInfoView - - - 40 - - - - - - - - - - 41 - - - - - - - - - 42 - - - - - - - - 43 - - - - - 44 - - - - - - - - 45 - - - - - 46 - - - - - - - - 49 - - - User Defaults Controller - - - 176 - - - - - 177 - - - - - 178 - - - - - 179 - - - - - 180 - - - - - 181 - - - - - 182 - - - - - 183 - - - - - 184 - - - - - 185 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 185 - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - YES - 3 - - {128, 128} - {15, 15} - - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib deleted file mode 100644 index 5f76399485..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings b/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings deleted file mode 100644 index 67cf535ee8..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/relaunch b/3rdparty/Sparkle.framework/Versions/A/Resources/relaunch deleted file mode 100755 index e7b96d6146..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/relaunch and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/classes.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/classes.nib deleted file mode 100644 index 4b1ab30e5b..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,50 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - doNotInstall - id - installLater - id - installNow - id - - CLASS - SUAutomaticUpdateAlert - LANGUAGE - ObjC - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/info.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/info.nib deleted file mode 100644 index 2b3d425766..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 670 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 9E17 - targetFramework - IBCocoaFramework - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index 1d4655c593..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/classes.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/classes.nib deleted file mode 100644 index 994d4c368f..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,67 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - CLASS - NSApplication - LANGUAGE - ObjC - SUPERCLASS - NSResponder - - - ACTIONS - - installUpdate - id - remindMeLater - id - skipThisVersion - id - - CLASS - SUUpdateAlert - LANGUAGE - ObjC - OUTLETS - - delegate - id - description - NSTextField - releaseNotesView - WebView - - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/info.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/info.nib deleted file mode 100644 index 2b3d425766..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 670 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 9E17 - targetFramework - IBCocoaFramework - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index 103b1cf847..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/designable.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/designable.nib deleted file mode 100644 index dabbf60a80..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/designable.nib +++ /dev/null @@ -1,938 +0,0 @@ - - - - 1050 - 10K549 - 1938 - 1038.36 - 461.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 1938 - - - NSUserDefaultsController - NSScroller - NSArrayController - NSButton - NSScrollView - NSImageView - NSTextFieldCell - NSButtonCell - NSImageCell - NSTableView - NSCustomView - NSCustomObject - NSView - NSWindowTemplate - NSTextField - NSTableColumn - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - SUUpdatePermissionPrompt - - - FirstResponder - - - NSApplication - - - 1 - 2 - {{83, 492}, {470, 168}} - 1886912512 - - - NSWindow - - - View - - {213, 107} - - - 256 - - - - 257 - {{255, 12}, {201, 32}} - - 1 - YES - - -2080244224 - 134217728 - Check Automatically - - LucidaGrande - 13 - 1044 - - - 1 - -2038284033 - 1 - - - DQ - 200 - 25 - - - - - 257 - {{138, 12}, {117, 32}} - - YES - - 67239424 - 134217728 - Don't Check - - - -2038284033 - 1 - - - Gw - 200 - 25 - - - - - 264 - {{104, 114}, {289, 34}} - - YES - - 67239424 - 272629760 - Check for updates automatically? - - LucidaGrande-Bold - 13 - 2072 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - - - - 266 - {{104, 81}, {315, 42}} - - YES - - 67239424 - 272629760 - DO NOT LOCALIZE - - LucidaGrande - 11 - 3100 - - - - - - - - - 264 - {{104, 53}, {278, 18}} - - YES - - -2080244224 - 163840 - Include anonymous system profile - - - 1211912703 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - - - - 264 - - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple PNG pasteboard type - NSFilenamesPboardType - NeXT Encapsulated PostScript v1.2 pasteboard type - NeXT TIFF v4.0 pasteboard type - - {{23, 84}, {64, 64}} - - YES - - 130560 - 33554432 - - NSImage - NSApplicationIcon - - 0 - 1 - 0 - YES - - YES - - - - 265 - {{80, 50}, {27, 26}} - - YES - - 67239424 - 134250496 - - - - -1194573569 - 133 - - - 200 - 25 - - - - {470, 168} - - {{0, 0}, {1440, 878}} - {213, 129} - {1e+13, 1e+13} - - - - visibleKey - visibleValue - displayValue - displayKey - - - YES - YES - YES - YES - YES - - - - 266 - - - - 274 - - - - 2304 - - - - 4352 - {353, 113} - - YES - - - 256 - {{346, 0}, {12, 17}} - - - - 128 - 40 - 1000 - - 75628096 - 2048 - - - - 3 - MC4zMzMzMzI5OQA - - - 6 - System - headerTextColor - - - - - 69336577 - 131072 - Text Cell - - - - 6 - System - textBackgroundColor - - 3 - MQA - - - - - 3 - YES - - - - 219 - 40 - 1000 - - 75628096 - 2048 - - - - - - - 69336577 - 131072 - Text Cell - - - - - - 3 - YES - - - - 3 - 2 - - - 6 - System - gridColor - - 3 - MC41AA - - - 14 - -759169024 - - - 4 - 15 - 0 - NO - 0 - - - {{1, 1}, {353, 113}} - - - - - 6 - System - controlBackgroundColor - - - 4 - - - - -2147483392 - {{-22, 1}, {11, 125}} - - 256 - - _doScroller: - 0.78125 - - - - -2147483392 - {{-100, -100}, {345, 11}} - - 257 - - _doScroller: - 0.99047619104385376 - - - {{4, 5}, {355, 115}} - - - 530 - - - - AAAAAAAAAABBgAAAQYAAAA - - - - 266 - {{1, 128}, {358, 70}} - - YES - - 67239424 - 272629760 - QW5vbnltb3VzIHN5c3RlbSBwcm9maWxlIGluZm9ybWF0aW9uIGlzIHVzZWQgdG8gaGVscCB1cyBwbGFu -IGZ1dHVyZSBkZXZlbG9wbWVudCB3b3JrLiBQbGVhc2UgY29udGFjdCB1cyBpZiB5b3UgaGF2ZSBhbnkg -cXVlc3Rpb25zIGFib3V0IHRoaXMuCgpUaGlzIGlzIHRoZSBpbmZvcm1hdGlvbiB0aGF0IHdvdWxkIGJl -IHNlbnQ6A - - - - - - - - {362, 205} - NSView - NSResponder - - - - SUIncludeProfile - SUSendProfileInfo - - YES - - - - - - - finishPrompt: - - - - 144 - - - - descriptionTextField - - - - 133 - - - - window - - - - 126 - - - - finishPrompt: - - - - 145 - - - - moreInfoView - - - - 127 - - - - toggleMoreInfo: - - - - 131 - - - - moreInfoButton - - - - 132 - - - - contentArray: systemProfileInformationArray - - - - - - contentArray: systemProfileInformationArray - contentArray - systemProfileInformationArray - 2 - - - 25 - - - - value: promptDescription - - - - - - value: promptDescription - value - promptDescription - 2 - - - 161 - - - - hidden: shouldAskAboutProfile - - - - - - hidden: shouldAskAboutProfile - hidden - shouldAskAboutProfile - - NSValueTransformerName - NSNegateBoolean - - 2 - - - 143 - - - - value: shouldSendProfile - - - - - - value: shouldSendProfile - value - shouldSendProfile - - - - - 2 - - - 148 - - - - value: icon - - - - - - value: icon - value - icon - 2 - - - 130 - - - - value: arrangedObjects.displayKey - - - - - - value: arrangedObjects.displayKey - value - arrangedObjects.displayKey - 2 - - - 174 - - - - value: arrangedObjects.displayValue - - - - - - value: arrangedObjects.displayValue - value - arrangedObjects.displayValue - 2 - - - 173 - - - - hidden: shouldAskAboutProfile - - - - - - hidden: shouldAskAboutProfile - hidden - shouldAskAboutProfile - - NSValueTransformerName - NSNegateBoolean - - 2 - - - 139 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 5 - - - - - - Profile Info - - - 6 - - - - - - - - - - - - - - 13 - - - - - - - - 14 - - - - - - - - 32 - - - - - - - - 33 - - - - - - - - 34 - - - - - - - - 37 - - - - - - - - 71 - - - - - - - - 24 - - - Array Controller - - - 39 - - - - - - - MoreInfoView - - - 40 - - - - - - - - - - 41 - - - - - - - - - 42 - - - - - - - - 43 - - - - - 44 - - - - - - - - 45 - - - - - 46 - - - - - - - - 49 - - - User Defaults Controller - - - 176 - - - - - 177 - - - - - 178 - - - - - 179 - - - - - 180 - - - - - 181 - - - - - 182 - - - - - 183 - - - - - 184 - - - - - 185 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 185 - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - YES - 3 - - {128, 128} - {15, 15} - - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib deleted file mode 100644 index b83a9f6d0f..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings b/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings deleted file mode 100644 index f3ff9d86cb..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/classes.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/classes.nib deleted file mode 100644 index 4b1ab30e5b..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,50 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - doNotInstall - id - installLater - id - installNow - id - - CLASS - SUAutomaticUpdateAlert - LANGUAGE - ObjC - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/info.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/info.nib deleted file mode 100644 index c5a067e891..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 670 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 10A96 - targetFramework - IBCocoaFramework - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index 53cb91a9b3..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/classes.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/classes.nib deleted file mode 100644 index 018710af88..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,39 +0,0 @@ -{ - IBClasses = ( - { - CLASS = FirstResponder; - LANGUAGE = ObjC; - SUPERCLASS = NSObject; - }, - { - CLASS = NSApplication; - LANGUAGE = ObjC; - SUPERCLASS = NSResponder; - }, - { - CLASS = NSObject; - LANGUAGE = ObjC; - }, - { - ACTIONS = { - installUpdate = id; - remindMeLater = id; - skipThisVersion = id; - }; - CLASS = SUUpdateAlert; - LANGUAGE = ObjC; - OUTLETS = { - delegate = id; - description = NSTextField; - releaseNotesView = WebView; - }; - SUPERCLASS = SUWindowController; - }, - { - CLASS = SUWindowController; - LANGUAGE = ObjC; - SUPERCLASS = NSWindowController; - } - ); - IBVersion = 1; -} \ No newline at end of file diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/info.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/info.nib deleted file mode 100644 index 6b787d4b9e..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/info.nib +++ /dev/null @@ -1,18 +0,0 @@ - - - - - IBDocumentLocation - 69 14 356 240 0 0 1280 778 - IBFramework Version - 489.0 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBSystem Version - 9D34 - targetFramework - IBCocoaFramework - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index 7e6d490e72..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/designable.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/designable.nib deleted file mode 100644 index 9855b8530c..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/designable.nib +++ /dev/null @@ -1,938 +0,0 @@ - - - - 1050 - 10K549 - 1938 - 1038.36 - 461.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 1938 - - - NSUserDefaultsController - NSScroller - NSArrayController - NSButton - NSScrollView - NSImageView - NSTextFieldCell - NSButtonCell - NSImageCell - NSTableView - NSCustomView - NSCustomObject - NSView - NSWindowTemplate - NSTextField - NSTableColumn - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - SUUpdatePermissionPrompt - - - FirstResponder - - - NSApplication - - - 1 - 2 - {{83, 492}, {438, 168}} - 1886912512 - - - NSWindow - - - View - - {213, 107} - - - 256 - - - - 257 - {{255, 12}, {169, 32}} - - 1 - YES - - -2080244224 - 134217728 - Check Automatically - - LucidaGrande - 13 - 1044 - - - 1 - -2038284033 - 1 - - - DQ - 200 - 25 - - - - - 257 - {{138, 12}, {117, 32}} - - YES - - 67239424 - 134217728 - Don't Check - - - -2038284033 - 1 - - - Gw - 200 - 25 - - - - - 264 - {{104, 114}, {289, 34}} - - YES - - 67239424 - 272629760 - Check for updates automatically? - - LucidaGrande-Bold - 13 - 2072 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - - - - 266 - {{104, 81}, {315, 42}} - - YES - - 67239424 - 272629760 - DO NOT LOCALIZE - - LucidaGrande - 11 - 3100 - - - - - - - - - 264 - {{104, 53}, {278, 18}} - - YES - - -2080244224 - 163840 - Include anonymous system profile - - - 1211912703 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - - - - 264 - - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple PNG pasteboard type - NSFilenamesPboardType - NeXT Encapsulated PostScript v1.2 pasteboard type - NeXT TIFF v4.0 pasteboard type - - {{23, 84}, {64, 64}} - - YES - - 130560 - 33554432 - - NSImage - NSApplicationIcon - - 0 - 1 - 0 - YES - - YES - - - - 265 - {{80, 50}, {27, 26}} - - YES - - 67239424 - 134250496 - - - - -1194573569 - 133 - - - 200 - 25 - - - - {438, 168} - - {{0, 0}, {1280, 778}} - {213, 129} - {1e+13, 1e+13} - - - - visibleKey - visibleValue - displayValue - displayKey - - - YES - YES - YES - YES - YES - - - - 266 - - - - 274 - - - - 2304 - - - - 4352 - {353, 113} - - YES - - - 256 - {{346, 0}, {12, 17}} - - - - 128 - 40 - 1000 - - 75628096 - 2048 - - - - 3 - MC4zMzMzMzI5OQA - - - 6 - System - headerTextColor - - - - - 69336577 - 131072 - Text Cell - - - - 6 - System - textBackgroundColor - - 3 - MQA - - - - - 3 - YES - - - - 219 - 40 - 1000 - - 75628096 - 2048 - - - - - - - 69336577 - 131072 - Text Cell - - - - - - 3 - YES - - - - 3 - 2 - - - 6 - System - gridColor - - 3 - MC41AA - - - 14 - -759169024 - - - 4 - 15 - 0 - NO - 0 - - - {{1, 1}, {353, 113}} - - - - - 6 - System - controlBackgroundColor - - - 4 - - - - -2147483392 - {{-22, 1}, {11, 125}} - - 256 - - _doScroller: - 0.78125 - - - - -2147483392 - {{-100, -100}, {345, 11}} - - 257 - - _doScroller: - 0.99047619104385376 - - - {{4, 5}, {355, 115}} - - - 530 - - - - AAAAAAAAAABBgAAAQYAAAA - - - - 266 - {{1, 128}, {358, 70}} - - YES - - 67239424 - 272629760 - QW5vbnltb3VzIHN5c3RlbSBwcm9maWxlIGluZm9ybWF0aW9uIGlzIHVzZWQgdG8gaGVscCB1cyBwbGFu -IGZ1dHVyZSBkZXZlbG9wbWVudCB3b3JrLiBQbGVhc2UgY29udGFjdCB1cyBpZiB5b3UgaGF2ZSBhbnkg -cXVlc3Rpb25zIGFib3V0IHRoaXMuCgpUaGlzIGlzIHRoZSBpbmZvcm1hdGlvbiB0aGF0IHdvdWxkIGJl -IHNlbnQ6A - - - - - - - - {362, 205} - NSView - NSResponder - - - - SUIncludeProfile - SUSendProfileInfo - - YES - - - - - - - finishPrompt: - - - - 144 - - - - descriptionTextField - - - - 133 - - - - window - - - - 126 - - - - finishPrompt: - - - - 145 - - - - moreInfoView - - - - 127 - - - - toggleMoreInfo: - - - - 131 - - - - moreInfoButton - - - - 132 - - - - contentArray: systemProfileInformationArray - - - - - - contentArray: systemProfileInformationArray - contentArray - systemProfileInformationArray - 2 - - - 25 - - - - value: promptDescription - - - - - - value: promptDescription - value - promptDescription - 2 - - - 161 - - - - hidden: shouldAskAboutProfile - - - - - - hidden: shouldAskAboutProfile - hidden - shouldAskAboutProfile - - NSValueTransformerName - NSNegateBoolean - - 2 - - - 143 - - - - value: shouldSendProfile - - - - - - value: shouldSendProfile - value - shouldSendProfile - - - - - 2 - - - 148 - - - - value: icon - - - - - - value: icon - value - icon - 2 - - - 130 - - - - value: arrangedObjects.displayKey - - - - - - value: arrangedObjects.displayKey - value - arrangedObjects.displayKey - 2 - - - 174 - - - - value: arrangedObjects.displayValue - - - - - - value: arrangedObjects.displayValue - value - arrangedObjects.displayValue - 2 - - - 173 - - - - hidden: shouldAskAboutProfile - - - - - - hidden: shouldAskAboutProfile - hidden - shouldAskAboutProfile - - NSValueTransformerName - NSNegateBoolean - - 2 - - - 139 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 5 - - - - - - Profile Info - - - 6 - - - - - - - - - - - - - - 13 - - - - - - - - 14 - - - - - - - - 32 - - - - - - - - 33 - - - - - - - - 34 - - - - - - - - 37 - - - - - - - - 71 - - - - - - - - 24 - - - Array Controller - - - 39 - - - - - - - MoreInfoView - - - 40 - - - - - - - - - - 41 - - - - - - - - - 42 - - - - - - - - 43 - - - - - 44 - - - - - - - - 45 - - - - - 46 - - - - - - - - 49 - - - User Defaults Controller - - - 176 - - - - - 177 - - - - - 178 - - - - - 179 - - - - - 180 - - - - - 181 - - - - - 182 - - - - - 183 - - - - - 184 - - - - - 185 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 185 - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - YES - 3 - - {128, 128} - {15, 15} - - - diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib b/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib deleted file mode 100644 index de0eb01d45..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings b/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings deleted file mode 100644 index 6b7a8f9514..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/Sparkle b/3rdparty/Sparkle.framework/Versions/A/Sparkle deleted file mode 100755 index 01a1b6e153..0000000000 Binary files a/3rdparty/Sparkle.framework/Versions/A/Sparkle and /dev/null differ diff --git a/3rdparty/Sparkle.framework/Versions/A/_CodeSignature/CodeResources b/3rdparty/Sparkle.framework/Versions/A/_CodeSignature/CodeResources deleted file mode 100644 index 35fbfc04fc..0000000000 --- a/3rdparty/Sparkle.framework/Versions/A/_CodeSignature/CodeResources +++ /dev/null @@ -1,1501 +0,0 @@ - - - - - files - - Resources/.DS_Store - - fZMQMWS9Hey1tZ+uCH7kcDlOe8I= - - Resources/Info.plist - - 2KZZnvs131X2HjPfoTFQdYT699k= - - Resources/License.txt - - f40cXuVVnuf3g7G1GozSCjejrFg= - - Resources/SUModelTranslation.plist - - J+hS/hOT7J63xTlo1JfeiGKN16Y= - - Resources/SUStatus.nib/classes.nib - - E9PmX1yxpGyLaVQkdNToi0rPfJY= - - Resources/SUStatus.nib/info.nib - - RohKdDM18eYVLdl6eiwXsfbutsU= - - Resources/SUStatus.nib/keyedobjects.nib - - 4cJaELQIS+8QDuNZVUkhmR1vJKo= - - Resources/de.lproj/SUAutomaticUpdateAlert.nib/classes.nib - - hash - - eCVJGWtx+UcI8Hu71flvxtvgVzE= - - optional - - - Resources/de.lproj/SUAutomaticUpdateAlert.nib/info.nib - - hash - - b2xsUcn4Ewa33cs42mDm6R/jxdc= - - optional - - - Resources/de.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib - - hash - - WGIElKEgBO5S3mDhF3VpoBEWjYg= - - optional - - - Resources/de.lproj/SUUpdateAlert.nib/classes.nib - - hash - - DSysr1qbrIY274sl6EUFIIAuOEk= - - optional - - - Resources/de.lproj/SUUpdateAlert.nib/info.nib - - hash - - b2xsUcn4Ewa33cs42mDm6R/jxdc= - - optional - - - Resources/de.lproj/SUUpdateAlert.nib/keyedobjects.nib - - hash - - Rrnx7U6c+2Vd1z8EGkG6/qnof7M= - - optional - - - Resources/de.lproj/SUUpdatePermissionPrompt.nib/designable.nib - - hash - - xdiYRRh3CBqJrwIUfSeXBXGvvcg= - - optional - - - Resources/de.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib - - hash - - xw0wQnx4V/RLNvjI4pU7M4nPQ78= - - optional - - - Resources/de.lproj/Sparkle.strings - - hash - - 4gF2PLDb7I5GWNcGgFBGTWUKG94= - - optional - - - Resources/en.lproj/SUAutomaticUpdateAlert.nib/classes.nib - - hash - - eCVJGWtx+UcI8Hu71flvxtvgVzE= - - optional - - - Resources/en.lproj/SUAutomaticUpdateAlert.nib/info.nib - - hash - - URy6e49Z98udTexmjqrYDDFE/jc= - - optional - - - Resources/en.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib - - hash - - uEdeiNJ3l2cMnPOQylswL9pSGFE= - - optional - - - Resources/en.lproj/SUUpdateAlert.nib/classes.nib - - hash - - DSysr1qbrIY274sl6EUFIIAuOEk= - - optional - - - Resources/en.lproj/SUUpdateAlert.nib/info.nib - - hash - - tgY7nR3ct6T03jE49to6xi09hfo= - - optional - - - Resources/en.lproj/SUUpdateAlert.nib/keyedobjects.nib - - hash - - MlN+cmJMyF0izlUhvwYhSMBQvng= - - optional - - - Resources/en.lproj/SUUpdatePermissionPrompt.nib/classes.nib - - hash - - uN2CqrTzPsoUX+FiD4k0Eccq38w= - - optional - - - Resources/en.lproj/SUUpdatePermissionPrompt.nib/info.nib - - hash - - vfQzCgQzTCMLhfMkPu+C7hE3t6Y= - - optional - - - Resources/en.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib - - hash - - +D+TWYizPHgwwkJY7mFcPE4xpAY= - - optional - - - Resources/en.lproj/Sparkle.strings - - hash - - lEgRTi1i1xBvF2q8uJW9qYipJx0= - - optional - - - Resources/es.lproj/SUAutomaticUpdateAlert.nib/classes.nib - - hash - - eCVJGWtx+UcI8Hu71flvxtvgVzE= - - optional - - - Resources/es.lproj/SUAutomaticUpdateAlert.nib/info.nib - - hash - - b2xsUcn4Ewa33cs42mDm6R/jxdc= - - optional - - - Resources/es.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib - - hash - - dav4I4nFKZYH1WV3ABxQKJ+jlfs= - - optional - - - Resources/es.lproj/SUUpdateAlert.nib/classes.nib - - hash - - DSysr1qbrIY274sl6EUFIIAuOEk= - - optional - - - Resources/es.lproj/SUUpdateAlert.nib/info.nib - - hash - - b2xsUcn4Ewa33cs42mDm6R/jxdc= - - optional - - - Resources/es.lproj/SUUpdateAlert.nib/keyedobjects.nib - - hash - - eU5DJWjn3FJDxh+t/fCRofb4hx8= - - optional - - - Resources/es.lproj/SUUpdatePermissionPrompt.nib/designable.nib - - hash - - g7qDYTw7/uFTHV8i8o6UFzICIR0= - - optional - - - Resources/es.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib - - hash - - dHakhl6SDCO0SfpnXfK4iPe9QVg= - - optional - - - Resources/es.lproj/Sparkle.strings - - hash - - x8UbbuWGE53sWlxcl4/jMU1vjGo= - - optional - - - Resources/fr.lproj/SUAutomaticUpdateAlert.nib/classes.nib - - hash - - eCVJGWtx+UcI8Hu71flvxtvgVzE= - - optional - - - Resources/fr.lproj/SUAutomaticUpdateAlert.nib/info.nib - - hash - - yzWCwzlPagYQMejgy/nDl3N99gM= - - optional - - - Resources/fr.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib - - hash - - Ddw2foe4dllG1U9sG8xpe54wduM= - - optional - - - Resources/fr.lproj/SUUpdateAlert.nib/classes.nib - - hash - - DSysr1qbrIY274sl6EUFIIAuOEk= - - optional - - - Resources/fr.lproj/SUUpdateAlert.nib/info.nib - - hash - - 9nzv0cfBmCeE/sLurelv2iTji9I= - - optional - - - Resources/fr.lproj/SUUpdateAlert.nib/keyedobjects.nib - - hash - - 17MWBX4mUKlszpZTvi5SvVb05Mc= - - optional - - - Resources/fr.lproj/SUUpdatePermissionPrompt.nib/designable.nib - - hash - - O8R8eaB9nKgpUOXL8Kw/woGweJ4= - - optional - - - Resources/fr.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib - - hash - - xtd4t/YMX+1wqeQtVHtawTLTR0E= - - optional - - - Resources/fr.lproj/Sparkle.strings - - hash - - ubKChRIMd5eQxsh/Xmhx9Rr2jiM= - - optional - - - Resources/it.lproj/SUAutomaticUpdateAlert.nib/classes.nib - - hash - - eCVJGWtx+UcI8Hu71flvxtvgVzE= - - optional - - - Resources/it.lproj/SUAutomaticUpdateAlert.nib/info.nib - - hash - - b2xsUcn4Ewa33cs42mDm6R/jxdc= - - optional - - - Resources/it.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib - - hash - - 95aXqlE3edk49yr3crIJ04gRnjc= - - optional - - - Resources/it.lproj/SUUpdateAlert.nib/classes.nib - - hash - - DSysr1qbrIY274sl6EUFIIAuOEk= - - optional - - - Resources/it.lproj/SUUpdateAlert.nib/info.nib - - hash - - b2xsUcn4Ewa33cs42mDm6R/jxdc= - - optional - - - Resources/it.lproj/SUUpdateAlert.nib/keyedobjects.nib - - hash - - b6n+yozLZbapENSaeccx1jx7Pgg= - - optional - - - Resources/it.lproj/SUUpdatePermissionPrompt.nib/designable.nib - - hash - - VC7Xns5S4+dBTXIM5WqQODl9CtY= - - optional - - - Resources/it.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib - - hash - - bLmbk4yeRN5aaa2BJ27rAsqw5VM= - - optional - - - Resources/it.lproj/Sparkle.strings - - hash - - vosLAb6yuQRbIGdsbKYicAPItQk= - - optional - - - Resources/nl.lproj/SUAutomaticUpdateAlert.nib/classes.nib - - hash - - eCVJGWtx+UcI8Hu71flvxtvgVzE= - - optional - - - Resources/nl.lproj/SUAutomaticUpdateAlert.nib/info.nib - - hash - - Mq9/S7PJEVyb286IgPcWmNoY794= - - optional - - - Resources/nl.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib - - hash - - QRERl1grslx1samBrxI01aUuiBE= - - optional - - - Resources/nl.lproj/SUUpdateAlert.nib/classes.nib - - hash - - DSysr1qbrIY274sl6EUFIIAuOEk= - - optional - - - Resources/nl.lproj/SUUpdateAlert.nib/info.nib - - hash - - 9nzv0cfBmCeE/sLurelv2iTji9I= - - optional - - - Resources/nl.lproj/SUUpdateAlert.nib/keyedobjects.nib - - hash - - DMkSvVxJc3WrEWGUVR63zYTBuj4= - - optional - - - Resources/nl.lproj/SUUpdatePermissionPrompt.nib/designable.nib - - hash - - k7vM2UA0CLncsmfSLtd7rdb9v2Y= - - optional - - - Resources/nl.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib - - hash - - 9gVBJ6KcG2DfaFH+kecAy9wSQ9M= - - optional - - - Resources/nl.lproj/Sparkle.strings - - hash - - 8zXWnDesb+lxXInSicqB5RP4p70= - - optional - - - Resources/relaunch - - A7AmbGg8d/XsDJjJ4XsB5cHNPJU= - - Resources/ru.lproj/SUAutomaticUpdateAlert.nib/classes.nib - - hash - - eCVJGWtx+UcI8Hu71flvxtvgVzE= - - optional - - - Resources/ru.lproj/SUAutomaticUpdateAlert.nib/info.nib - - hash - - CUAMWQRQzI/Ft86mZz5/9f0pUTs= - - optional - - - Resources/ru.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib - - hash - - sdqtO/hKuzOjTTWhkHUM43w373M= - - optional - - - Resources/ru.lproj/SUUpdateAlert.nib/classes.nib - - hash - - DSysr1qbrIY274sl6EUFIIAuOEk= - - optional - - - Resources/ru.lproj/SUUpdateAlert.nib/info.nib - - hash - - CUAMWQRQzI/Ft86mZz5/9f0pUTs= - - optional - - - Resources/ru.lproj/SUUpdateAlert.nib/keyedobjects.nib - - hash - - pk8L81vCTrXhGcUcX5/U7nN5Q60= - - optional - - - Resources/ru.lproj/SUUpdatePermissionPrompt.nib/designable.nib - - hash - - uO5bjc0hszbWQcNjRzGHY0FVdBk= - - optional - - - Resources/ru.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib - - hash - - S/QanJJVr+xp0l7mStEhsMtTbWI= - - optional - - - Resources/ru.lproj/Sparkle.strings - - hash - - /QxybcYWViK0p5154ukMmh7paX8= - - optional - - - Resources/sv.lproj/SUAutomaticUpdateAlert.nib/classes.nib - - hash - - eCVJGWtx+UcI8Hu71flvxtvgVzE= - - optional - - - Resources/sv.lproj/SUAutomaticUpdateAlert.nib/info.nib - - hash - - lFPl1p6hk112tZcAcMOKKftCKTs= - - optional - - - Resources/sv.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib - - hash - - j6ej7LvbruqyL19n+CJ/LqOAex8= - - optional - - - Resources/sv.lproj/SUUpdateAlert.nib/classes.nib - - hash - - qQ6PIjh69iK9ashN3tVFY0+UZR4= - - optional - - - Resources/sv.lproj/SUUpdateAlert.nib/info.nib - - hash - - qYOP9Ui1hwCq2WgR+srwa5eZ/JY= - - optional - - - Resources/sv.lproj/SUUpdateAlert.nib/keyedobjects.nib - - hash - - 1PaVgihYxeUULBWyA2ITU57/XKA= - - optional - - - Resources/sv.lproj/SUUpdatePermissionPrompt.nib/designable.nib - - hash - - GnZzJPLi8/lHv307pP+40tsIClI= - - optional - - - Resources/sv.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib - - hash - - QydYmlum8Jz70oJEq9GrjGSbfb8= - - optional - - - Resources/sv.lproj/Sparkle.strings - - hash - - Iv99/40jzTjFk/mdhbOsTKWisRw= - - optional - - - - files2 - - Headers/SUAppcast.h - - sK4fFNgpMFmYlCSo5MDjkwxnWJ4= - - Headers/SUAppcastItem.h - - lfDGo/f9EK5jbfU7tsSR/ReMQ3A= - - Headers/SUUpdater.h - - fsrUv4c7pbfNwOSX1AKit6RtkjE= - - Headers/SUVersionComparisonProtocol.h - - t4vJvGPOmzfxcGgqHUbbYtZ8AWo= - - Headers/Sparkle.h - - L7ZMguRipF7+oO6qLCVLvu+EMCk= - - Resources/Info.plist - - 2KZZnvs131X2HjPfoTFQdYT699k= - - Resources/License.txt - - f40cXuVVnuf3g7G1GozSCjejrFg= - - Resources/SUModelTranslation.plist - - J+hS/hOT7J63xTlo1JfeiGKN16Y= - - Resources/SUStatus.nib/classes.nib - - E9PmX1yxpGyLaVQkdNToi0rPfJY= - - Resources/SUStatus.nib/info.nib - - RohKdDM18eYVLdl6eiwXsfbutsU= - - Resources/SUStatus.nib/keyedobjects.nib - - 4cJaELQIS+8QDuNZVUkhmR1vJKo= - - Resources/de.lproj/SUAutomaticUpdateAlert.nib/classes.nib - - hash - - eCVJGWtx+UcI8Hu71flvxtvgVzE= - - optional - - - Resources/de.lproj/SUAutomaticUpdateAlert.nib/info.nib - - hash - - b2xsUcn4Ewa33cs42mDm6R/jxdc= - - optional - - - Resources/de.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib - - hash - - WGIElKEgBO5S3mDhF3VpoBEWjYg= - - optional - - - Resources/de.lproj/SUUpdateAlert.nib/classes.nib - - hash - - DSysr1qbrIY274sl6EUFIIAuOEk= - - optional - - - Resources/de.lproj/SUUpdateAlert.nib/info.nib - - hash - - b2xsUcn4Ewa33cs42mDm6R/jxdc= - - optional - - - Resources/de.lproj/SUUpdateAlert.nib/keyedobjects.nib - - hash - - Rrnx7U6c+2Vd1z8EGkG6/qnof7M= - - optional - - - Resources/de.lproj/SUUpdatePermissionPrompt.nib/designable.nib - - hash - - xdiYRRh3CBqJrwIUfSeXBXGvvcg= - - optional - - - Resources/de.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib - - hash - - xw0wQnx4V/RLNvjI4pU7M4nPQ78= - - optional - - - Resources/de.lproj/Sparkle.strings - - hash - - 4gF2PLDb7I5GWNcGgFBGTWUKG94= - - optional - - - Resources/en.lproj/SUAutomaticUpdateAlert.nib/classes.nib - - hash - - eCVJGWtx+UcI8Hu71flvxtvgVzE= - - optional - - - Resources/en.lproj/SUAutomaticUpdateAlert.nib/info.nib - - hash - - URy6e49Z98udTexmjqrYDDFE/jc= - - optional - - - Resources/en.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib - - hash - - uEdeiNJ3l2cMnPOQylswL9pSGFE= - - optional - - - Resources/en.lproj/SUUpdateAlert.nib/classes.nib - - hash - - DSysr1qbrIY274sl6EUFIIAuOEk= - - optional - - - Resources/en.lproj/SUUpdateAlert.nib/info.nib - - hash - - tgY7nR3ct6T03jE49to6xi09hfo= - - optional - - - Resources/en.lproj/SUUpdateAlert.nib/keyedobjects.nib - - hash - - MlN+cmJMyF0izlUhvwYhSMBQvng= - - optional - - - Resources/en.lproj/SUUpdatePermissionPrompt.nib/classes.nib - - hash - - uN2CqrTzPsoUX+FiD4k0Eccq38w= - - optional - - - Resources/en.lproj/SUUpdatePermissionPrompt.nib/info.nib - - hash - - vfQzCgQzTCMLhfMkPu+C7hE3t6Y= - - optional - - - Resources/en.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib - - hash - - +D+TWYizPHgwwkJY7mFcPE4xpAY= - - optional - - - Resources/en.lproj/Sparkle.strings - - hash - - lEgRTi1i1xBvF2q8uJW9qYipJx0= - - optional - - - Resources/es.lproj/SUAutomaticUpdateAlert.nib/classes.nib - - hash - - eCVJGWtx+UcI8Hu71flvxtvgVzE= - - optional - - - Resources/es.lproj/SUAutomaticUpdateAlert.nib/info.nib - - hash - - b2xsUcn4Ewa33cs42mDm6R/jxdc= - - optional - - - Resources/es.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib - - hash - - dav4I4nFKZYH1WV3ABxQKJ+jlfs= - - optional - - - Resources/es.lproj/SUUpdateAlert.nib/classes.nib - - hash - - DSysr1qbrIY274sl6EUFIIAuOEk= - - optional - - - Resources/es.lproj/SUUpdateAlert.nib/info.nib - - hash - - b2xsUcn4Ewa33cs42mDm6R/jxdc= - - optional - - - Resources/es.lproj/SUUpdateAlert.nib/keyedobjects.nib - - hash - - eU5DJWjn3FJDxh+t/fCRofb4hx8= - - optional - - - Resources/es.lproj/SUUpdatePermissionPrompt.nib/designable.nib - - hash - - g7qDYTw7/uFTHV8i8o6UFzICIR0= - - optional - - - Resources/es.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib - - hash - - dHakhl6SDCO0SfpnXfK4iPe9QVg= - - optional - - - Resources/es.lproj/Sparkle.strings - - hash - - x8UbbuWGE53sWlxcl4/jMU1vjGo= - - optional - - - Resources/fr.lproj/SUAutomaticUpdateAlert.nib/classes.nib - - hash - - eCVJGWtx+UcI8Hu71flvxtvgVzE= - - optional - - - Resources/fr.lproj/SUAutomaticUpdateAlert.nib/info.nib - - hash - - yzWCwzlPagYQMejgy/nDl3N99gM= - - optional - - - Resources/fr.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib - - hash - - Ddw2foe4dllG1U9sG8xpe54wduM= - - optional - - - Resources/fr.lproj/SUUpdateAlert.nib/classes.nib - - hash - - DSysr1qbrIY274sl6EUFIIAuOEk= - - optional - - - Resources/fr.lproj/SUUpdateAlert.nib/info.nib - - hash - - 9nzv0cfBmCeE/sLurelv2iTji9I= - - optional - - - Resources/fr.lproj/SUUpdateAlert.nib/keyedobjects.nib - - hash - - 17MWBX4mUKlszpZTvi5SvVb05Mc= - - optional - - - Resources/fr.lproj/SUUpdatePermissionPrompt.nib/designable.nib - - hash - - O8R8eaB9nKgpUOXL8Kw/woGweJ4= - - optional - - - Resources/fr.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib - - hash - - xtd4t/YMX+1wqeQtVHtawTLTR0E= - - optional - - - Resources/fr.lproj/Sparkle.strings - - hash - - ubKChRIMd5eQxsh/Xmhx9Rr2jiM= - - optional - - - Resources/it.lproj/SUAutomaticUpdateAlert.nib/classes.nib - - hash - - eCVJGWtx+UcI8Hu71flvxtvgVzE= - - optional - - - Resources/it.lproj/SUAutomaticUpdateAlert.nib/info.nib - - hash - - b2xsUcn4Ewa33cs42mDm6R/jxdc= - - optional - - - Resources/it.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib - - hash - - 95aXqlE3edk49yr3crIJ04gRnjc= - - optional - - - Resources/it.lproj/SUUpdateAlert.nib/classes.nib - - hash - - DSysr1qbrIY274sl6EUFIIAuOEk= - - optional - - - Resources/it.lproj/SUUpdateAlert.nib/info.nib - - hash - - b2xsUcn4Ewa33cs42mDm6R/jxdc= - - optional - - - Resources/it.lproj/SUUpdateAlert.nib/keyedobjects.nib - - hash - - b6n+yozLZbapENSaeccx1jx7Pgg= - - optional - - - Resources/it.lproj/SUUpdatePermissionPrompt.nib/designable.nib - - hash - - VC7Xns5S4+dBTXIM5WqQODl9CtY= - - optional - - - Resources/it.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib - - hash - - bLmbk4yeRN5aaa2BJ27rAsqw5VM= - - optional - - - Resources/it.lproj/Sparkle.strings - - hash - - vosLAb6yuQRbIGdsbKYicAPItQk= - - optional - - - Resources/nl.lproj/SUAutomaticUpdateAlert.nib/classes.nib - - hash - - eCVJGWtx+UcI8Hu71flvxtvgVzE= - - optional - - - Resources/nl.lproj/SUAutomaticUpdateAlert.nib/info.nib - - hash - - Mq9/S7PJEVyb286IgPcWmNoY794= - - optional - - - Resources/nl.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib - - hash - - QRERl1grslx1samBrxI01aUuiBE= - - optional - - - Resources/nl.lproj/SUUpdateAlert.nib/classes.nib - - hash - - DSysr1qbrIY274sl6EUFIIAuOEk= - - optional - - - Resources/nl.lproj/SUUpdateAlert.nib/info.nib - - hash - - 9nzv0cfBmCeE/sLurelv2iTji9I= - - optional - - - Resources/nl.lproj/SUUpdateAlert.nib/keyedobjects.nib - - hash - - DMkSvVxJc3WrEWGUVR63zYTBuj4= - - optional - - - Resources/nl.lproj/SUUpdatePermissionPrompt.nib/designable.nib - - hash - - k7vM2UA0CLncsmfSLtd7rdb9v2Y= - - optional - - - Resources/nl.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib - - hash - - 9gVBJ6KcG2DfaFH+kecAy9wSQ9M= - - optional - - - Resources/nl.lproj/Sparkle.strings - - hash - - 8zXWnDesb+lxXInSicqB5RP4p70= - - optional - - - Resources/relaunch - - A7AmbGg8d/XsDJjJ4XsB5cHNPJU= - - Resources/ru.lproj/SUAutomaticUpdateAlert.nib/classes.nib - - hash - - eCVJGWtx+UcI8Hu71flvxtvgVzE= - - optional - - - Resources/ru.lproj/SUAutomaticUpdateAlert.nib/info.nib - - hash - - CUAMWQRQzI/Ft86mZz5/9f0pUTs= - - optional - - - Resources/ru.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib - - hash - - sdqtO/hKuzOjTTWhkHUM43w373M= - - optional - - - Resources/ru.lproj/SUUpdateAlert.nib/classes.nib - - hash - - DSysr1qbrIY274sl6EUFIIAuOEk= - - optional - - - Resources/ru.lproj/SUUpdateAlert.nib/info.nib - - hash - - CUAMWQRQzI/Ft86mZz5/9f0pUTs= - - optional - - - Resources/ru.lproj/SUUpdateAlert.nib/keyedobjects.nib - - hash - - pk8L81vCTrXhGcUcX5/U7nN5Q60= - - optional - - - Resources/ru.lproj/SUUpdatePermissionPrompt.nib/designable.nib - - hash - - uO5bjc0hszbWQcNjRzGHY0FVdBk= - - optional - - - Resources/ru.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib - - hash - - S/QanJJVr+xp0l7mStEhsMtTbWI= - - optional - - - Resources/ru.lproj/Sparkle.strings - - hash - - /QxybcYWViK0p5154ukMmh7paX8= - - optional - - - Resources/sv.lproj/SUAutomaticUpdateAlert.nib/classes.nib - - hash - - eCVJGWtx+UcI8Hu71flvxtvgVzE= - - optional - - - Resources/sv.lproj/SUAutomaticUpdateAlert.nib/info.nib - - hash - - lFPl1p6hk112tZcAcMOKKftCKTs= - - optional - - - Resources/sv.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib - - hash - - j6ej7LvbruqyL19n+CJ/LqOAex8= - - optional - - - Resources/sv.lproj/SUUpdateAlert.nib/classes.nib - - hash - - qQ6PIjh69iK9ashN3tVFY0+UZR4= - - optional - - - Resources/sv.lproj/SUUpdateAlert.nib/info.nib - - hash - - qYOP9Ui1hwCq2WgR+srwa5eZ/JY= - - optional - - - Resources/sv.lproj/SUUpdateAlert.nib/keyedobjects.nib - - hash - - 1PaVgihYxeUULBWyA2ITU57/XKA= - - optional - - - Resources/sv.lproj/SUUpdatePermissionPrompt.nib/designable.nib - - hash - - GnZzJPLi8/lHv307pP+40tsIClI= - - optional - - - Resources/sv.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib - - hash - - QydYmlum8Jz70oJEq9GrjGSbfb8= - - optional - - - Resources/sv.lproj/Sparkle.strings - - hash - - Iv99/40jzTjFk/mdhbOsTKWisRw= - - optional - - - - rules - - ^Resources/ - - ^Resources/.*\.lproj/ - - optional - - weight - 1000 - - ^Resources/.*\.lproj/locversion.plist$ - - omit - - weight - 1100 - - ^version.plist$ - - - rules2 - - .*\.dSYM($|/) - - weight - 11 - - ^(.*/)?\.DS_Store$ - - omit - - weight - 2000 - - ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ - - nested - - weight - 10 - - ^.* - - ^Info\.plist$ - - omit - - weight - 20 - - ^PkgInfo$ - - omit - - weight - 20 - - ^Resources/ - - weight - 20 - - ^Resources/.*\.lproj/ - - optional - - weight - 1000 - - ^Resources/.*\.lproj/locversion.plist$ - - omit - - weight - 1100 - - ^[^/]+$ - - nested - - weight - 10 - - ^embedded\.provisionprofile$ - - weight - 20 - - ^version\.plist$ - - weight - 20 - - - - diff --git a/3rdparty/VTPG/VTPG_Common.h b/3rdparty/VTPG/VTPG_Common.h index aae8fe1d10..6a037b7465 100644 --- a/3rdparty/VTPG/VTPG_Common.h +++ b/3rdparty/VTPG/VTPG_Common.h @@ -2,6 +2,8 @@ // Copyright (c) 2008-2010, Vincent Gable. // vincent.gable@gmail.com +@import Foundation; + //based off of http://www.dribin.org/dave/blog/archives/2008/09/22/convert_to_nsstring/ NSString * VTPG_DDToStringFromTypeAndValue(const char * typeCode, void * value); @@ -34,6 +36,6 @@ NSString * VTPG_DDToStringFromTypeAndValue(const char * typeCode, void * value); // http://www.wilshipley.com/blog/2005/10/pimp-my-code-interlude-free-code.html static inline BOOL IsEmpty(id thing) { return thing == nil || - ([thing respondsToSelector:@selector(length)] && [(NSData *)thing length] == 0) || - ([thing respondsToSelector:@selector(count)] && [(NSArray *)thing count] == 0); + ([thing respondsToSelector:@selector(length)] && ((NSData *)thing).length == 0) || + ([thing respondsToSelector:@selector(count)] && ((NSArray *)thing).count == 0); } diff --git a/3rdparty/VTPG/VTPG_Common.m b/3rdparty/VTPG/VTPG_Common.m index 6f2eac9644..c0f0668037 100644 --- a/3rdparty/VTPG/VTPG_Common.m +++ b/3rdparty/VTPG/VTPG_Common.m @@ -5,8 +5,11 @@ //based off http://www.dribin.org/dave/blog/archives/2008/09/22/convert_to_nsstring/ // static BOOL TypeCodeIsCharArray(const char *typeCode){ - int lastCharOffset = strlen(typeCode) - 1; - int secondToLastCharOffset = lastCharOffset - 1 ; + size_t len = strlen(typeCode); + if(len <= 2) + return NO; + size_t lastCharOffset = len - 1; + size_t secondToLastCharOffset = lastCharOffset - 1 ; BOOL isCharArray = typeCode[0] == '[' && typeCode[secondToLastCharOffset] == 'c' && typeCode[lastCharOffset] == ']'; @@ -70,7 +73,11 @@ static BOOL TypeCodeIsCharArray(const char *typeCode){ IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(unsigned long long,@"%llu"); IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(float,@"%f"); IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(double,@"%f"); - IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(id,@"%@"); +#if __has_feature(objc_arc) + IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(__unsafe_unretained id,@"%@"); +#else /* not __has_feature(objc_arc) */ + IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(id,@"%@"); +#endif IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(short,@"%hi"); IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(unsigned short,@"%hu"); IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(int,@"%i"); diff --git a/3rdparty/autorevision/AUTHORS.txt b/3rdparty/autorevision/AUTHORS.txt index 61bf4d5eac..c700c19a2f 100644 --- a/3rdparty/autorevision/AUTHORS.txt +++ b/3rdparty/autorevision/AUTHORS.txt @@ -1,7 +1,16 @@ dak180 Eric S. Raymond -Dmitry Marakasov -Mike Swanson Paul Wise +Mike Swanson +Dmitry Marakasov +Vlad +Dennis Biringer +allevo +Jérôme Pouiller Joel C. Salomon yuanchuan +vagrant +Robert Wenner +Qiuwen Lu +Qiuwen Lu +Hironori Ichimiya diff --git a/3rdparty/autorevision/COPYING.md b/3rdparty/autorevision/COPYING.md index 01def0fa27..d62fce7645 100644 --- a/3rdparty/autorevision/COPYING.md +++ b/3rdparty/autorevision/COPYING.md @@ -1,4 +1,4 @@ -Copyright (c) 2012 - 2014 dak180 and contributors. +Copyright (c) 2012 - 2016 dak180 and contributors. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/3rdparty/autorevision/NEWS b/3rdparty/autorevision/NEWS index ddee5c3c4f..dc8ac6ac83 100644 --- a/3rdparty/autorevision/NEWS +++ b/3rdparty/autorevision/NEWS @@ -1,6 +1,58 @@ autorevision history -1.9 @ 2014-5-23 +1.18 @ 2016-11-22: + Fix some bashisms in the make file. + Get the short hash from git rather than assuming its length. + +1.17 @ 2016-11-18: + Fix out of repo operation. + Bring back the irc channel. + Add a script to sanity check out of repo operation. + +1.16 @ 2016-11-15: + Try to eliminate stray error output. + Allow the VCS_EXTRA symbol to be renamed. + Add an C# output. + Add an CMake output. + +1.15 @ 2016-08-08: + Add support for action stamps. + Add support for plain c/c++ source output. + Activate mq as needed for hg. + Add an .editorconfig file. + +1.14 @ 2016-02-22: + Fix PHP output. + Use constants array in PHP output. + Make sure that the cache file gets outputted where expected. + Add an example for use with waf. + +1.13 @ 2015-07-31: + Make the man page more reproducible. + Make sure VCS_WS_MODIFIED is not empty for svn. + Remove sql output until such time as it can be completed. + Add some missing example files. + +1.12 @ 2015-03-16 + Use --xml for svn when we care about the output. + New site: https://autorevision.github.io/ + Handle older svn detection more gracefully. + +1.11 @ 2015-02-20 + Added scheme, clojure, rpm, and sql outputs. + Added hpp, matlab, and octave outputs. + Reorder types in help and asciidoc to be more alphabetical. + Try using md5sum when md5 is not available when making tarballs. + Fix a typo in the svn driver. + +1.10a @ 2014-10-24 + Emergency bug fix. + +1.10 @ 2014-10-23 + Cover the case of split repository heads. + Add initial Swift output support. + +1.9 @ 2014-05-23 Add a logo. Only update the cache file when there are changes. New dependency `cmp`. diff --git a/3rdparty/autorevision/README.md b/3rdparty/autorevision/README.md index 506f695d59..9fb0bd5a67 100644 --- a/3rdparty/autorevision/README.md +++ b/3rdparty/autorevision/README.md @@ -9,6 +9,6 @@ Emitted information includes the ID of the most recent commit, its branch, its d There is support for reading and writing a cache file so autorevision will remain useful during a build from an unpacked distribution tarball. -See the [manual page](http://www.catb.org/esr/autorevision/autorevision.html), included in the distribution, for invocation details. +See the [manual page](./autorevision.asciidoc), included in the distribution, for invocation details. You can check out examples of the different output that autorevision can produce in [examples](https://github.com/Autorevision/autorevision/tree/master/examples). diff --git a/3rdparty/autorevision/autorevision b/3rdparty/autorevision/autorevision index f2950a8404..b0e92ef4d0 100755 --- a/3rdparty/autorevision/autorevision +++ b/3rdparty/autorevision/autorevision @@ -1,7 +1,7 @@ #!/bin/sh -# Copyright (c) 2012 - 2014 dak180 and contributors. See -# http://opensource.org/licenses/mit-license.php or the included +# Copyright (c) 2012 - 2016 dak180 and contributors. See +# https://opensource.org/licenses/mit-license.php or the included # COPYING.md for licence terms. # # autorevision - extracts metadata about the head version from your @@ -9,32 +9,44 @@ # Usage message. arUsage() { - cat > "/dev/stderr" << EOF -usage: ./autorevision {-t output-type | -s symbol} [-o cache-file [-f] ] [-V] + tee >&2 << EOF +usage: autorevision {-t output-type | -s symbol} [-o cache-file [-f] ] [-e name] [-U] [-V] Options include: -t output-type = specify output type -s symbol = specify symbol output -o cache-file = specify cache file location -f = force the use of cache data + -e name = set a different output name for VCS_EXTRA -U = check for untracked files in svn -V = emit version and exit -? = help message -The folowing are valid output types: +The following are valid output types: + c = C/C++ file + clojure = clojure file + cmake = CMake script file + csharp = CSharp properties file h = Header for use with c/c++ - xcode = Header useful for populating info.plist files - sh = Bash sytax - py = Python file - pl = Perl file - lua = Lua file - php = PHP file + hpp = Alternate C++ header strings with namespace ini = INI file - js = javascript file - json = JSON file java = Java file javaprop = Java properties file - tex = (La)TeX file + js = javascript file + json = JSON file + lua = Lua file m4 = m4 file + matlab = matlab file + octave = octave file + php = PHP file + pl = Perl file + py = Python file + rpm = rpm file + scheme = scheme file + sh = Bash sytax + swift = Swift file + tex = (La)TeX file + xcode = Header useful for populating info.plist files + The following are valid symbols: VCS_TYPE @@ -49,14 +61,14 @@ The following are valid symbols: VCS_FULL_HASH VCS_SHORT_HASH VCS_WC_MODIFIED + VCS_ACTION_STAMP EOF exit 1 } # Config -ARVERSION="1.9" -TARGETFILE="/dev/stdout" -while getopts ":t:o:s:VfU" OPTION; do +ARVERSION="1.17" +while getopts ":t:o:s:e:VfU" OPTION; do case "${OPTION}" in t) AFILETYPE="${OPTARG}" @@ -70,6 +82,9 @@ while getopts ":t:o:s:VfU" OPTION; do s) VAROUT="${OPTARG}" ;; + e) + EXTRA_NAME="${OPTARG}" + ;; U) UNTRACKEDFILES="1" ;; @@ -94,6 +109,10 @@ elif [ -z "${VAROUT}" ] && [ -z "${AFILETYPE}" ]; then elif [ -z "${CACHEFILE}" ] && [ "${CACHEFORCE}" = "1" ]; then # If -f is specified without -o: arUsage +elif [ ! -f "${CACHEFILE}" ] && [ "${CACHEFORCE}" = "1" ]; then + # If we are forced to use the cache but it does not exist. + echo "error: Cache forced but no cache found." 1>&2 + exit 1 fi # Make sure that the path we are given is one we can source @@ -102,54 +121,60 @@ if [ ! -z "${CACHEFILE}" ] && ! echo "${CACHEFILE}" | grep -q '^\.*/'; then CACHEFILE="./${CACHEFILE}" fi +GENERATED_HEADER="Generated by autorevision - do not hand-hack!" +: "${EXTRA_NAME:="VCS_EXTRA"}" # Functions to extract data from different repo types. # For git repos +# shellcheck disable=SC2039,SC2164,SC2155 gitRepo() { + local oldPath="${PWD}" + cd "$(git rev-parse --show-toplevel)" VCS_TYPE="git" VCS_BASENAME="$(basename "${PWD}")" - VCS_UUID="$(git rev-list --max-parents=0 --date-order --reverse HEAD 2>/dev/null | sed -n 1p)" + local currentRev="$(git rev-parse HEAD)" + + VCS_UUID="$(git rev-list --max-parents=0 --date-order --reverse "${currentRev}" 2>/dev/null | sed -n 1p)" if [ -z "${VCS_UUID}" ]; then - VCS_UUID="$(git rev-list --topo-order HEAD | tail -n 1)" + VCS_UUID="$(git rev-list --topo-order "${currentRev}" | tail -n 1)" fi - # Is the working copy clean? + # Is the working copy clean? test -z "$(git status --untracked-files=normal --porcelain)" VCS_WC_MODIFIED="${?}" # Enumeration of changesets - VCS_NUM="$(git rev-list --count HEAD 2>/dev/null)" + VCS_NUM="$(git rev-list --count "${currentRev}" 2>/dev/null)" if [ -z "${VCS_NUM}" ]; then echo "warning: Counting the number of revisions may be slower due to an outdated git version less than 1.7.2.3. If something breaks, please update it." 1>&2 VCS_NUM="$(git rev-list HEAD | wc -l)" fi # This may be a git-svn remote. If so, report the Subversion revision. - if [ -z "$(git config svn-remote.svn.url 2>/dev/null)" ] - then + if [ -z "$(git config svn-remote.svn.url 2>/dev/null)" ]; then # The full revision hash - VCS_FULL_HASH="$(git rev-parse HEAD)" + VCS_FULL_HASH="$(git rev-parse "${currentRev}")" # The short hash - VCS_SHORT_HASH="$(echo "${VCS_FULL_HASH}" | cut -b 1-7)" + VCS_SHORT_HASH="$(git rev-parse --short "${currentRev}")" else # The git-svn revision number - VCS_FULL_HASH="$(git svn find-rev HEAD)" + VCS_FULL_HASH="$(git svn find-rev "${currentRev}")" VCS_SHORT_HASH="${VCS_FULL_HASH}" fi # Current branch - VCS_BRANCH="$(git rev-parse --symbolic-full-name --verify "$(git name-rev --name-only --no-undefined HEAD 2>/dev/null)" 2>/dev/null | sed -e 's:refs/heads/::' | sed -e 's:refs/::')" + VCS_BRANCH="$(git rev-parse --symbolic-full-name --verify "$(git name-rev --name-only --no-undefined "${currentRev}" 2>/dev/null)" 2>/dev/null | sed -e 's:refs/heads/::' | sed -e 's:refs/::')" # Cache the description - local DESCRIPTION="$(git describe --long --tags 2>/dev/null)" + local DESCRIPTION="$(git describe --long --tags "${currentRev}" 2>/dev/null)" # Current or last tag ancestor (empty if no tags) - VCS_TAG="$(echo "${DESCRIPTION}" | sed -e "s:-g${VCS_SHORT_HASH}\$::" | sed -e 's:-[0-9]*$::')" + VCS_TAG="$(echo "${DESCRIPTION}" | sed -e "s:-g${VCS_SHORT_HASH}\$::" -e 's:-[0-9]*$::')" # Distance to last tag or an alias of VCS_NUM if there is no tag if [ ! -z "${DESCRIPTION}" ]; then @@ -159,11 +184,28 @@ gitRepo() { fi # Date of the current commit - VCS_DATE="$(git log -1 --pretty=format:%ci | sed -e 's: :T:' | sed -e 's: ::')" + VCS_DATE="$(TZ=UTC git show -s --date=iso-strict-local --pretty=format:%ad "${currentRev}" 2>/dev/null | sed -e 's|+00:00|Z|')" + if [ -z "${VCS_DATE}" ]; then + echo "warning: Action stamps require git version 2.7+." 1>&2 + VCS_DATE="$(git log -1 --pretty=format:%ci "${currentRev}" | sed -e 's: :T:' -e 's: ::' -e 's|+00:00|Z|')" + local ASdis="1" + fi + + # Action Stamp + if [ -z "${ASdis}" ]; then + VCS_ACTION_STAMP="${VCS_DATE}!$(git show -s --pretty=format:%cE "${currentRev}")" + else + VCS_ACTION_STAMP="" + fi + + cd "${oldPath}" } # For hg repos +# shellcheck disable=SC2039,SC2164 hgRepo() { + local oldPath="${PWD}" + cd "$(hg root)" VCS_TYPE="hg" @@ -194,7 +236,7 @@ hgRepo() { fi # Current or last tag ancestor (excluding auto tags, empty if no tags) - VCS_TAG="$(hg log -r "${VCS_NUM}" -l 1 --template '{latesttag}\n' 2>/dev/null | sed -e 's:qtip::' -e 's:tip::' -e 's:qbase::' -e 's:qparent::' -e "s:$(hg --config 'extensions.color=' --color never qtop 2>/dev/null)::" | cut -d ' ' -f 1)" + VCS_TAG="$(hg log -r "${VCS_NUM}" -l 1 --template '{latesttag}\n' 2>/dev/null | sed -e 's:qtip::' -e 's:tip::' -e 's:qbase::' -e 's:qparent::' -e "s:$(hg --config 'extensions.color=' --config 'extensions.mq=' --color never qtop 2>/dev/null)::" | cut -d ' ' -f 1)" # Distance to last tag or an alias of VCS_NUM if there is no tag if [ ! -z "${VCS_TAG}" ]; then @@ -204,11 +246,19 @@ hgRepo() { fi # Date of the current commit - VCS_DATE="$(hg log -r "${VCS_NUM}" -l 1 --template '{date|isodatesec}\n' 2>/dev/null | sed -e 's: :T:' | sed -e 's: ::')" + VCS_DATE="$(hg log -r "${VCS_NUM}" -l 1 --template '{date|isodatesec}\n' 2>/dev/null | sed -e 's: :T:' -e 's: ::' -e 's|+00:00|Z|')" + + # Action Stamp + VCS_ACTION_STAMP="$(TZ=UTC hg log -r "${VCS_NUM}" -l 1 --template '{date|localdate|rfc3339date}\n' 2>/dev/null | sed -e 's|+00:00|Z|')!$(hg log -r "${VCS_NUM}" -l 1 --template '{author|email}\n' 2>/dev/null)" + + cd "${oldPath}" } # For bzr repos +# shellcheck disable=SC2039,SC2164 bzrRepo() { + local oldPath="${PWD}" + cd "$(bzr root)" VCS_TYPE="bzr" @@ -245,11 +295,20 @@ bzrRepo() { fi # Date of the current commit - VCS_DATE="$(bzr version-info --custom --template='{date}\n' | sed -e 's: :T:' | sed -e 's: ::')" + VCS_DATE="$(bzr version-info --custom --template='{date}\n' | sed -e 's: :T:' -e 's: ::')" + + # Action Stamp + # Currently unimplemented because more investigation is needed. + VCS_ACTION_STAMP="" + + cd "${oldPath}" } # For svn repos +# shellcheck disable=SC2039,SC2164,SC2155 svnRepo() { + local oldPath="${PWD}" + VCS_TYPE="svn" case "${PWD}" in @@ -258,7 +317,7 @@ svnRepo() { while [ "$(basename "${fn}")" != 'trunk' ] && [ "$(basename "${fn}")" != 'branches' ] && [ "$(basename "${fn}")" != 'tags' ] && [ "$(basename "${fn}")" != '/' ]; do local fn="$(dirname "${fn}")" done - fn="$(dirname "${fn}")" + local fn="$(dirname "${fn}")" if [ "${fn}" = '/' ]; then VCS_BASENAME="$(basename "${PWD}")" else @@ -268,7 +327,7 @@ svnRepo() { *) VCS_BASENAME="$(basename "${PWD}")" ;; esac - VCS_UUID="$(svn info | sed -n -e 's:Repository UUID\: ::p')" + VCS_UUID="$(svn info --xml | sed -n -e 's:::' -e 's:::p')" # Cache svnversion output local SVNVERSION="$(svnversion)" @@ -287,6 +346,8 @@ svnRepo() { else VCS_WC_MODIFIED="1" fi + else + VCS_WC_MODIFIED="0" fi ;; esac @@ -304,7 +365,7 @@ svnRepo() { case "${PWD}" in /*trunk*|/*branches*|/*tags*) local lastbase="" - loacl fn="${PWD}" + local fn="${PWD}" while : do base="$(basename "${fn}")" @@ -325,22 +386,103 @@ svnRepo() { *) VCS_BRANCH="" ;; esac - # Current or last tag ancestor (empty if no tags). But "current tag" - # can't be extracted reliably because Subversion doesn't have tags the - # way other VCSes do. + # Current or last tag ancestor (empty if no tags). But "current + # tag" can't be extracted reliably because Subversion doesn't + # have tags the way other VCSes do. VCS_TAG="" VCS_TICK="" # Date of the current commit - VCS_DATE="$(svn info | sed -n -e 's:Last Changed Date\: ::p' | sed 's: (.*)::' | sed -e 's: :T:' | sed -e 's: ::')" + VCS_DATE="$(svn info --xml | sed -n -e 's:::' -e 's:::p')" + + # Action Stamp + VCS_ACTION_STAMP="${VCS_DATE}!$(svn log --xml -l 1 -r "${VCS_SHORT_HASH}" | sed -n -e 's:::' -e 's:::p')" + + cd "${oldPath}" } # Functions to output data in different formats. +# For bash output +# First in list because it is used by autorevision +shOutput() { + tee << EOF +# ${GENERATED_HEADER} + +VCS_TYPE="${VCS_TYPE}" +VCS_BASENAME="${VCS_BASENAME}" +VCS_UUID="${VCS_UUID}" +VCS_NUM="${VCS_NUM}" +VCS_DATE="${VCS_DATE}" +VCS_BRANCH="${VCS_BRANCH}" +VCS_TAG="${VCS_TAG}" +VCS_TICK="${VCS_TICK}" +${EXTRA_NAME}="${VCS_EXTRA}" + +VCS_ACTION_STAMP="${VCS_ACTION_STAMP}" +VCS_FULL_HASH="${VCS_FULL_HASH}" +VCS_SHORT_HASH="${VCS_SHORT_HASH}" + +VCS_WC_MODIFIED="${VCS_WC_MODIFIED}" + +# end +EOF +} + +# For source C output +cOutput() { + tee << EOF +/* ${GENERATED_HEADER} */ + +const char *VCS_TYPE = "${VCS_TYPE}"; +const char *VCS_BASENAME = "${VCS_BASENAME}"; +const char *VCS_UUID = "${VCS_UUID}"; +const int VCS_NUM = ${VCS_NUM}; +const char *VCS_DATE = "${VCS_DATE}"; +const char *VCS_BRANCH = "${VCS_BRANCH}"; +const char *VCS_TAG = "${VCS_TAG}"; +const int VCS_TICK = ${VCS_TICK}; +const char *${EXTRA_NAME} = "${VCS_EXTRA}"; + +const char *VCS_ACTION_STAMP = "${VCS_ACTION_STAMP}"; +const char *VCS_FULL_HASH = "${VCS_FULL_HASH}"; +const char *VCS_SHORT_HASH = "${VCS_SHORT_HASH}"; + +const int VCS_WC_MODIFIED = ${VCS_WC_MODIFIED}; + +/* end */ +EOF +} + +# For Cmake output +cmakeOutput() { + tee << EOF +# ${GENERATED_HEADER} + +set(VCS_TYPE ${VCS_TYPE}) +set(VCS_BASENAME ${VCS_BASENAME}) +set(VCS_UUID ${VCS_UUID}) +set(VCS_NUM ${VCS_NUM}) +set(VCS_DATE ${VCS_DATE}) +set(VCS_BRANCH ${VCS_BRANCH}) +set(VCS_TAG ${VCS_TAG}) +set(VCS_TICK ${VCS_TICK}) +set(${EXTRA_NAME} ${VCS_EXTRA}) + +set(VCS_ACTION_STAMP ${VCS_ACTION_STAMP}) +set(VCS_FULL_HASH ${VCS_FULL_HASH}) +set(VCS_SHORT_HASH ${VCS_SHORT_HASH}) + +set(VCS_WC_MODIFIED ${VCS_WC_MODIFIED}) + +# end +EOF +} + # For header output hOutput() { - cat > "${TARGETFILE}" << EOF -/* Generated by autorevision - do not hand-hack! */ + tee << EOF +/* ${GENERATED_HEADER} */ #ifndef AUTOREVISION_H #define AUTOREVISION_H @@ -352,8 +494,9 @@ hOutput() { #define VCS_BRANCH "${VCS_BRANCH}" #define VCS_TAG "${VCS_TAG}" #define VCS_TICK ${VCS_TICK} -#define VCS_EXTRA "${VCS_EXTRA}" +#define ${EXTRA_NAME} "${VCS_EXTRA}" +#define VCS_ACTION_STAMP "${VCS_ACTION_STAMP}" #define VCS_FULL_HASH "${VCS_FULL_HASH}" #define VCS_SHORT_HASH "${VCS_SHORT_HASH}" @@ -367,8 +510,8 @@ EOF # A header output for use with xcode to populate info.plist strings xcodeOutput() { - cat > "${TARGETFILE}" << EOF -/* Generated by autorevision - do not hand-hack! */ + tee << EOF +/* ${GENERATED_HEADER} */ #ifndef AUTOREVISION_H #define AUTOREVISION_H @@ -380,8 +523,9 @@ xcodeOutput() { #define VCS_BRANCH ${VCS_BRANCH} #define VCS_TAG ${VCS_TAG} #define VCS_TICK ${VCS_TICK} -#define VCS_EXTRA ${VCS_EXTRA} +#define ${EXTRA_NAME} ${VCS_EXTRA} +#define VCS_ACTION_STAMP ${VCS_ACTION_STAMP} #define VCS_FULL_HASH ${VCS_FULL_HASH} #define VCS_SHORT_HASH ${VCS_SHORT_HASH} @@ -393,27 +537,55 @@ xcodeOutput() { EOF } -# For bash output -shOutput() { - cat > "${TARGETFILE}" << EOF -# Generated by autorevision - do not hand-hack! +# For Swift output +swiftOutput() { + case "${VCS_WC_MODIFIED}" in + 0) VCS_WC_MODIFIED="false" ;; + 1) VCS_WC_MODIFIED="true" ;; + esac + # For values that may not exist depending on the type of repo we + # have read from, set them to `nil` when they are empty. + if [ -z "${VCS_UUID}" ]; then + VCS_UUID="nil" + else + VCS_UUID="\"${VCS_UUID}\"" + fi + if [ -z "${VCS_TAG}" ]; then + VCS_TAG="nil" + else + VCS_TAG="\"${VCS_TAG}\"" + fi + : "${VCS_TICK:="nil"}" + if [ -z "${VCS_EXTRA}" ]; then + VCS_EXTRA="nil" + else + VCS_EXTRA="\"${VCS_EXTRA}\"" + fi + if [ -z "${VCS_ACTION_STAMP}" ]; then + VCS_ACTION_STAMP="nil" + else + VCS_ACTION_STAMP="\"${VCS_ACTION_STAMP}\"" + fi + tee << EOF +/* ${GENERATED_HEADER} */ -VCS_TYPE="${VCS_TYPE}" -VCS_BASENAME="${VCS_BASENAME}" -VCS_UUID="${VCS_UUID}" -VCS_NUM=${VCS_NUM} -VCS_DATE="${VCS_DATE}" -VCS_BRANCH="${VCS_BRANCH}" -VCS_TAG="${VCS_TAG}" -VCS_TICK=${VCS_TICK} -VCS_EXTRA="${VCS_EXTRA}" +let VCS_TYPE = "${VCS_TYPE}" +let VCS_BASENAME = "${VCS_BASENAME}" +let VCS_UUID: String? = ${VCS_UUID} +let VCS_NUM: Int = ${VCS_NUM} +let VCS_DATE = "${VCS_DATE}" +let VCS_BRANCH: String = "${VCS_BRANCH}" +let VCS_TAG: String? = ${VCS_TAG} +let VCS_TICK: Int? = ${VCS_TICK} +let ${EXTRA_NAME}: String? = ${VCS_EXTRA} -VCS_FULL_HASH="${VCS_FULL_HASH}" -VCS_SHORT_HASH="${VCS_SHORT_HASH}" +let VCS_ACTION_STAMP: String? = ${VCS_ACTION_STAMP} +let VCS_FULL_HASH: String = "${VCS_FULL_HASH}" +let VCS_SHORT_HASH: String = "${VCS_SHORT_HASH}" -VCS_WC_MODIFIED=${VCS_WC_MODIFIED} +let VCS_WC_MODIFIED: Bool = ${VCS_WC_MODIFIED} -# end +/* end */ EOF } @@ -423,8 +595,8 @@ pyOutput() { 0) VCS_WC_MODIFIED="False" ;; 1) VCS_WC_MODIFIED="True" ;; esac - cat > "${TARGETFILE}" << EOF -# Generated by autorevision - do not hand-hack! + tee << EOF +# ${GENERATED_HEADER} VCS_TYPE = "${VCS_TYPE}" VCS_BASENAME = "${VCS_BASENAME}" @@ -434,8 +606,9 @@ VCS_DATE = "${VCS_DATE}" VCS_BRANCH = "${VCS_BRANCH}" VCS_TAG = "${VCS_TAG}" VCS_TICK = ${VCS_TICK} -VCS_EXTRA = "${VCS_EXTRA}" +${EXTRA_NAME} = "${VCS_EXTRA}" +VCS_ACTION_STAMP = "${VCS_ACTION_STAMP}" VCS_FULL_HASH = "${VCS_FULL_HASH}" VCS_SHORT_HASH = "${VCS_SHORT_HASH}" @@ -447,25 +620,27 @@ EOF # For Perl output plOutput() { - cat << EOF -# Generated by autorevision - do not hand-hack! + tee << EOF +# ${GENERATED_HEADER} -\$VCS_TYPE = "${VCS_TYPE}"; -\$VCS_BASENAME = "${VCS_BASENAME}" -\$VCS_UUID = "${VCS_UUID}" +\$VCS_TYPE = '${VCS_TYPE}'; +\$VCS_BASENAME = '${VCS_BASENAME}'; +\$VCS_UUID = '${VCS_UUID}'; \$VCS_NUM = ${VCS_NUM}; -\$VCS_DATE = "${VCS_DATE}"; -\$VCS_BRANCH = "${VCS_BRANCH}"; -\$VCS_TAG = "${VCS_TAG}"; +\$VCS_DATE = '${VCS_DATE}'; +\$VCS_BRANCH = '${VCS_BRANCH}'; +\$VCS_TAG = '${VCS_TAG}'; \$VCS_TICK = ${VCS_TICK}; -\$VCS_EXTRA = "${VCS_EXTRA}"; +\$${EXTRA_NAME} = '${VCS_EXTRA}'; -\$VCS_FULL_HASH = "${VCS_FULL_HASH}"; -\$VCS_SHORT_HASH = "${VCS_SHORT_HASH}"; +\$VCS_ACTION_STAMP = '${VCS_ACTION_STAMP}'; +\$VCS_FULL_HASH = '${VCS_FULL_HASH}'; +\$VCS_SHORT_HASH = '${VCS_SHORT_HASH}'; \$VCS_WC_MODIFIED = ${VCS_WC_MODIFIED}; # end +1; EOF } @@ -475,8 +650,8 @@ luaOutput() { 0) VCS_WC_MODIFIED="false" ;; 1) VCS_WC_MODIFIED="true" ;; esac - cat > "${TARGETFILE}" << EOF --- Generated by autorevision - do not hand-hack! + tee << EOF +-- ${GENERATED_HEADER} VCS_TYPE = "${VCS_TYPE}" VCS_BASENAME = "${VCS_BASENAME}" @@ -486,8 +661,9 @@ VCS_DATE = "${VCS_DATE}" VCS_BRANCH = "${VCS_BRANCH}" VCS_TAG = "${VCS_TAG}" VCS_TICK = ${VCS_TICK} -VCS_EXTRA = "${VCS_EXTRA}" +${EXTRA_NAME} = "${VCS_EXTRA}" +VCS_ACTION_STAMP = "${VCS_ACTION_STAMP}" VCS_FULL_HASH = "${VCS_FULL_HASH}" VCS_SHORT_HASH = "${VCS_SHORT_HASH}" @@ -503,24 +679,25 @@ phpOutput() { 0) VCS_WC_MODIFIED="false" ;; 1) VCS_WC_MODIFIED="true" ;; esac - cat > "${TARGETFILE}" << EOF + tee << EOF "${VCS_TYPE}", + "VCS_BASENAME" => "${VCS_BASENAME}", + "VCS_UUID" => "${VCS_UUID}", + "VCS_NUM" => ${VCS_NUM}, + "VCS_DATE" => "${VCS_DATE}", + "VCS_BRANCH" => "${VCS_BRANCH}", + "VCS_TAG" => "${VCS_TAG}", + "VCS_TICK" => ${VCS_TICK}, + "${EXTRA_NAME}" => "${VCS_EXTRA}", + "VCS_ACTION_STAMP" => "${VCS_ACTION_STAMP}", + "VCS_FULL_HASH" => "${VCS_FULL_HASH}", + "VCS_SHORT_HASH" => "${VCS_SHORT_HASH}", + "VCS_WC_MODIFIED" => ${VCS_WC_MODIFIED} +); # end ?> @@ -533,8 +710,8 @@ iniOutput() { 0) VCS_WC_MODIFIED="false" ;; 1) VCS_WC_MODIFIED="true" ;; esac - cat > "${TARGETFILE}" << EOF -; Generated by autorevision - do not hand-hack! + tee << EOF +; ${GENERATED_HEADER} [VCS] VCS_TYPE = "${VCS_TYPE}" VCS_BASENAME = "${VCS_BASENAME}" @@ -544,7 +721,8 @@ VCS_DATE = "${VCS_DATE}" VCS_BRANCH = "${VCS_BRANCH}" VCS_TAG = "${VCS_TAG}" VCS_TICK = ${VCS_TICK} -VCS_EXTRA = "${VCS_EXTRA}" +${EXTRA_NAME} = "${VCS_EXTRA}" +VCS_ACTION_STAMP = "${VCS_ACTION_STAMP}" VCS_FULL_HASH = "${VCS_FULL_HASH}" VCS_SHORT_HASH = "${VCS_SHORT_HASH}" VCS_WC_MODIFIED = ${VCS_WC_MODIFIED} @@ -558,8 +736,8 @@ jsOutput() { 1) VCS_WC_MODIFIED="true" ;; 0) VCS_WC_MODIFIED="false" ;; esac - cat > "${TARGETFILE}" << EOF -/** Generated by autorevision - do not hand-hack! */ + tee << EOF +/** ${GENERATED_HEADER} */ var autorevision = { VCS_TYPE: "${VCS_TYPE}", @@ -570,8 +748,9 @@ var autorevision = { VCS_BRANCH: "${VCS_BRANCH}", VCS_TAG: "${VCS_TAG}", VCS_TICK: ${VCS_TICK}, - VCS_EXTRA: "${VCS_EXTRA}", + ${EXTRA_NAME}: "${VCS_EXTRA}", + VCS_ACTION_STAMP: "${VCS_ACTION_STAMP}", VCS_FULL_HASH: "${VCS_FULL_HASH}", VCS_SHORT_HASH: "${VCS_SHORT_HASH}", @@ -593,8 +772,9 @@ jsonOutput() { 1) VCS_WC_MODIFIED="true" ;; 0) VCS_WC_MODIFIED="false" ;; esac - cat > "${TARGETFILE}" << EOF + tee << EOF { + "_comment": "${GENERATED_HEADER}", "VCS_TYPE": "${VCS_TYPE}", "VCS_BASENAME": "${VCS_BASENAME}", "VCS_UUID": "${VCS_UUID}", @@ -603,8 +783,9 @@ jsonOutput() { "VCS_BRANCH":"${VCS_BRANCH}", "VCS_TAG": "${VCS_TAG}", "VCS_TICK": ${VCS_TICK}, - "VCS_EXTRA": "${VCS_EXTRA}", + "${EXTRA_NAME}": "${VCS_EXTRA}", + "VCS_ACTION_STAMP": "${VCS_ACTION_STAMP}", "VCS_FULL_HASH": "${VCS_FULL_HASH}", "VCS_SHORT_HASH": "${VCS_SHORT_HASH}", @@ -619,8 +800,8 @@ javaOutput() { 1) VCS_WC_MODIFIED="true" ;; 0) VCS_WC_MODIFIED="false" ;; esac - cat > "${TARGETFILE}" << EOF -/* Generated by autorevision - do not hand-hack! */ + tee << EOF +/* ${GENERATED_HEADER} */ public class autorevision { public static final String VCS_TYPE = "${VCS_TYPE}"; @@ -631,8 +812,9 @@ public class autorevision { public static final String VCS_BRANCH = "${VCS_BRANCH}"; public static final String VCS_TAG = "${VCS_TAG}"; public static final long VCS_TICK = ${VCS_TICK}; - public static final String VCS_EXTRA = "${VCS_EXTRA}"; + public static final String ${EXTRA_NAME} = "${VCS_EXTRA}"; + public static final String VCS_ACTION_STAMP = "${VCS_ACTION_STAMP}"; public static final String VCS_FULL_HASH = "${VCS_FULL_HASH}"; public static final String VCS_SHORT_HASH = "${VCS_SHORT_HASH}"; @@ -641,14 +823,47 @@ public class autorevision { EOF } +csharpOutput() { + case "${VCS_WC_MODIFIED}" in + 1) VCS_WC_MODIFIED="true" ;; + 0) VCS_WC_MODIFIED="false" ;; + esac + if [ "${EXTRA_NAME}" = "VCS_EXTRA" ]; then + EXTRA_NAME="VcsExtra" + fi + tee << EOF +/* ${GENERATED_HEADER} */ + +namespace AutoRevision +{ + public class VersionInfo + { + public static string VcsType = "${VCS_TYPE}"; + public static string VcsBasename = "${VCS_BASENAME}"; + public static string VcsUuid = "${VCS_UUID}"; + public static string VcsNum = "${VCS_NUM}"; + public static string VcsDate = "${VCS_DATE}"; + public static string VcsBranch = "${VCS_DATE}"; + public static string VcsTag = "${VCS_TAG}"; + public static string VcsTick = "${VCS_TICK}"; + public static string ${EXTRA_NAME} = "${VCS_EXTRA}"; + public static string VcsActionStamp = "${VCS_ACTION_STAMP}"; + public static string VcsFullHash = "${VCS_FULL_HASH}"; + public static string VcsShortHash = "${VCS_SHORT_HASH}"; + public static string VcsWcModified = "${VCS_WC_MODIFIED}"; + } +} +EOF +} + # For Java properties output javapropOutput() { case "${VCS_WC_MODIFIED}" in 1) VCS_WC_MODIFIED="true" ;; 0) VCS_WC_MODIFIED="false" ;; esac - cat > "${TARGETFILE}" << EOF -# Generated by autorevision - do not hand-hack! + tee << EOF +# ${GENERATED_HEADER} VCS_TYPE=${VCS_TYPE} VCS_BASENAME=${VCS_BASENAME} @@ -658,8 +873,9 @@ VCS_DATE=${VCS_DATE} VCS_BRANCH=${VCS_BRANCH} VCS_TAG=${VCS_TAG} VCS_TICK=${VCS_TICK} -VCS_EXTRA=${VCS_EXTRA} +${EXTRA_NAME}=${VCS_EXTRA} +VCS_ACTION_STAMP=${VCS_ACTION_STAMP} VCS_FULL_HASH=${VCS_FULL_HASH} VCS_SHORT_HASH=${VCS_SHORT_HASH} @@ -669,7 +885,8 @@ EOF # For m4 output m4Output() { - cat > "${TARGETFILE}" << EOF + tee << EOF +dnl ${GENERATED_HEADER} define(\`VCS_TYPE', \`${VCS_TYPE}')dnl define(\`VCS_BASENAME', \`${VCS_BASENAME}')dnl define(\`VCS_UUID', \`${VCS_UUID}')dnl @@ -678,7 +895,8 @@ define(\`VCS_DATE', \`${VCS_DATE}')dnl define(\`VCS_BRANCH', \`${VCS_BRANCH}')dnl define(\`VCS_TAG', \`${VCS_TAG}')dnl define(\`VCS_TICK', \`${VCS_TICK}')dnl -define(\`VCS_EXTRA', \`${VCS_EXTRA}')dnl +define(\`${EXTRA_NAME}', \`${VCS_EXTRA}')dnl +define(\`VCS_ACTIONSTAMP', \`${VCS_ACTION_STAMP}')dnl define(\`VCS_FULLHASH', \`${VCS_FULL_HASH}')dnl define(\`VCS_SHORTHASH', \`${VCS_SHORT_HASH}')dnl define(\`VCS_WC_MODIFIED', \`${VCS_WC_MODIFIED}')dnl @@ -691,8 +909,11 @@ texOutput() { 0) VCS_WC_MODIFIED="false" ;; 1) VCS_WC_MODIFIED="true" ;; esac - cat > "${TARGETFILE}" << EOF -% Generated by autorevision - do not hand-hack! + if [ "${EXTRA_NAME}" = "VCS_EXTRA" ]; then + EXTRA_NAME="vcsExtra" + fi + tee << EOF +% ${GENERATED_HEADER} \def \vcsType {${VCS_TYPE}} \def \vcsBasename {${VCS_BASENAME}} \def \vcsUUID {${VCS_UUID}} @@ -701,7 +922,8 @@ texOutput() { \def \vcsBranch {${VCS_BRANCH}} \def \vcsTag {${VCS_TAG}} \def \vcsTick {${VCS_TICK}} -\def \vcsExtra {${VCS_EXTRA}} +\def \\${EXTRA_NAME} {${VCS_EXTRA}} +\def \vcsACTIONSTAMP {${VCS_ACTION_STAMP}} \def \vcsFullHash {${VCS_FULL_HASH}} \def \vcsShortHash {${VCS_SHORT_HASH}} \def \vcsWCModified {${VCS_WC_MODIFIED}} @@ -709,16 +931,185 @@ texOutput() { EOF } +# For scheme output +schemeOutput() { + case "${VCS_WC_MODIFIED}" in + 0) VCS_WC_MODIFIED="#f" ;; + 1) VCS_WC_MODIFIED="#t" ;; + esac + tee << EOF +;; ${GENERATED_HEADER} +(define VCS_TYPE "${VCS_TYPE}") +(define VCS_BASENAME "${VCS_BASENAME}") +(define VCS_UUID "${VCS_UUID}") +(define VCS_NUM ${VCS_NUM}) +(define VCS_DATE "${VCS_DATE}") +(define VCS_BRANCH "${VCS_BRANCH}") +(define VCS_TAG "${VCS_TAG}") +(define VCS_TICK ${VCS_TICK}) +(define ${EXTRA_NAME} "${VCS_EXTRA}") + +(define VCS_ACTION_STAMP "${VCS_ACTION_STAMP}") +(define VCS_FULL_HASH "${VCS_FULL_HASH}") +(define VCS_SHORT_HASH "${VCS_SHORT_HASH}") + +(define VCS_WC_MODIFIED ${VCS_WC_MODIFIED}) +;; end +EOF +} + +# For clojure output +clojureOutput() { + case "${VCS_WC_MODIFIED}" in + 0) VCS_WC_MODIFIED="false" ;; + 1) VCS_WC_MODIFIED="true" ;; + esac + tee << EOF +;; ${GENERATED_HEADER} +(def VCS_TYPE "${VCS_TYPE}") +(def VCS_BASENAME "${VCS_BASENAME}") +(def VCS_UUID "${VCS_UUID}") +(def VCS_NUM ${VCS_NUM}) +(def VCS_DATE "${VCS_DATE}") +(def VCS_BRANCH "${VCS_BRANCH}") +(def VCS_TAG "${VCS_TAG}") +(def VCS_TICK ${VCS_TICK}) +(def ${EXTRA_NAME} "${VCS_EXTRA}") + +(def VCS_ACTION_STAMP "${VCS_ACTION_STAMP}") +(def VCS_FULL_HASH "${VCS_FULL_HASH}") +(def VCS_SHORT_HASH "${VCS_SHORT_HASH}") + +(def VCS_WC_MODIFIED ${VCS_WC_MODIFIED}) +;; end +EOF +} + +# For rpm spec file output +rpmOutput() { + tee << EOF +# ${GENERATED_HEADER} +$([ "${VCS_TYPE}" ] && echo "%define vcs_type ${VCS_TYPE}") +$([ "${VCS_BASENAME}" ] && echo "%define vcs_basename ${VCS_BASENAME}") +$([ "${VCS_UUID}" ] && echo "%define vcs_uuid ${VCS_UUID}") +$([ "${VCS_NUM}" ] && echo "%define vcs_num ${VCS_NUM}") +$([ "${VCS_DATE}" ] && echo "%define vcs_date ${VCS_DATE}") +$([ "${VCS_BRANCH}" ] && echo "%define vcs_branch ${VCS_BRANCH}") +$([ "${VCS_TAG}" ] && echo "%define vcs_tag ${VCS_TAG}") +$([ "${VCS_TICK}" ] && echo "%define vcs_tick ${VCS_TICK}") +$([ "${VCS_EXTRA}" ] && echo "%define ${EXTRA_NAME} ${VCS_EXTRA}") + +$([ "${VCS_ACTION_STAMP}" ] && echo "%define vcs_action_stamp ${VCS_ACTION_STAMP}") +$([ "${VCS_FULL_HASH}" ] && echo "%define vcs_full_hash ${VCS_FULL_HASH}") +$([ "${VCS_SHORT_HASH}" ] && echo "%define vcs_short_hash ${VCS_SHORT_HASH}") + +$([ "${VCS_WC_MODIFIED}" ] && echo "%define vcs_wc_modified ${VCS_WC_MODIFIED}") +# end +EOF +} + +# For C++ Header output +# shellcheck disable=SC2155,SC2039 +hppOutput() { + local NAMESPACE="$(echo "${VCS_BASENAME}" | sed -e 's:_::g' | tr '[:lower:]' '[:upper:]')" + tee << EOF +/* ${GENERATED_HEADER} */ + +#ifndef ${NAMESPACE}_AUTOREVISION_H +#define ${NAMESPACE}_AUTOREVISION_H + +#include + +namespace $(echo "${NAMESPACE}" | tr '[:upper:]' '[:lower:]') +{ + const std::string VCS_TYPE = "${VCS_TYPE}"; + const std::string VCS_BASENAME = "${VCS_BASENAME}"; + const std::string VCS_UUID = "${VCS_UUID}"; + const int VCS_NUM = ${VCS_NUM}; + const std::string VCS_DATE = "${VCS_DATE}"; + const std::string VCS_BRANCH = "${VCS_BRANCH}"; + const std::string VCS_TAG = "${VCS_TAG}"; + const int VCS_TICK = ${VCS_TICK}; + const std::string ${EXTRA_NAME} = "${VCS_EXTRA}"; + + const std::string VCS_ACTION_STAMP = "${VCS_ACTION_STAMP}"; + const std::string VCS_FULL_HASH = "${VCS_FULL_HASH}"; + const std::string VCS_SHORT_HASH = "${VCS_SHORT_HASH}"; + + const int VCS_WC_MODIFIED = ${VCS_WC_MODIFIED}; +} + +#endif + +/* end */ +EOF +} + +# For Matlab output +matlabOutput() { + case "${VCS_WC_MODIFIED}" in + 0) VCS_WC_MODIFIED="FALSE" ;; + 1) VCS_WC_MODIFIED="TRUE" ;; + esac + tee << EOF +% ${GENERATED_HEADER} + +VCS_TYPE = '${VCS_TYPE}'; +VCS_BASENAME = '${VCS_BASENAME}'; +VCS_UUID = '${VCS_UUID}'; +VCS_NUM = ${VCS_NUM}; +VCS_DATE = '${VCS_DATE}'; +VCS_BRANCH = '${VCS_BRANCH}'; +VCS_TAG = '${VCS_TAG}'; +VCS_TICK = ${VCS_TICK}; +${EXTRA_NAME} = '${VCS_EXTRA}'; + +VCS_ACTION_STAMP = '${VCS_ACTION_STAMP}'; +VCS_FULL_HASH = '${VCS_FULL_HASH}'; +VCS_SHORT_HASH = '${VCS_SHORT_HASH}'; + +VCS_WC_MODIFIED = ${VCS_WC_MODIFIED}; + +% end +EOF +} + +# For Octave output +octaveOutput() { + tee << EOF +% ${GENERATED_HEADER} + +VCS_TYPE = '${VCS_TYPE}'; +VCS_BASENAME = '${VCS_BASENAME}'; +VCS_UUID = '${VCS_UUID}'; +VCS_NUM = ${VCS_NUM}; +VCS_DATE = '${VCS_DATE}'; +VCS_BRANCH = '${VCS_BRANCH}'; +VCS_TAG = '${VCS_TAG}'; +VCS_TICK = ${VCS_TICK}; +${EXTRA_NAME} = '${VCS_EXTRA}'; + +VCS_ACTION_STAMP = '${VCS_ACTION_STAMP}'; +VCS_FULL_HASH = '${VCS_FULL_HASH}'; +VCS_SHORT_HASH = '${VCS_SHORT_HASH}'; + +VCS_WC_MODIFIED = ${VCS_WC_MODIFIED}; + +% end +EOF +} # Helper functions # Count path segments +# shellcheck disable=SC2039 pathSegment() { local pathz="${1}" local depth="0" if [ ! -z "${pathz}" ]; then - while [ ! "${pathz}" = "/" ] && [ ! "${pathz}" = "." ]; do + # Continue until we are at / or there are no path separators left. + while [ ! "${pathz}" = "/" ] && [ ! "${pathz}" = "$(echo "${pathz}" | sed -e 's:/::')" ]; do pathz="$(dirname "${pathz}")" depth="$((depth+1))" done @@ -727,6 +1118,7 @@ pathSegment() { } # Largest of four numbers +# shellcheck disable=SC2039 multiCompare() { local larger="${1}" local numA="${2}" @@ -740,41 +1132,58 @@ multiCompare() { } # Test for repositories +# shellcheck disable=SC2155,SC2039 repoTest() { REPONUM="0" - if [ ! -z "$(git rev-parse HEAD 2>/dev/null)" ]; then - local gitPath="$(git rev-parse --show-toplevel)" + if command -v git > /dev/null 2>&1; then + local gitPath="$(git rev-parse --show-toplevel 2>/dev/null)" local gitDepth="$(pathSegment "${gitPath}")" - REPONUM="$((REPONUM+1))" + if [ ! -z "${gitPath}" ]; then + REPONUM="$((REPONUM+1))" + fi else local gitDepth="0" fi - if [ ! -z "$(hg root 2>/dev/null)" ]; then + if command -v hg > /dev/null 2>&1; then local hgPath="$(hg root 2>/dev/null)" local hgDepth="$(pathSegment "${hgPath}")" - REPONUM="$((REPONUM+1))" + if [ ! -z "${hgPath}" ]; then + REPONUM="$((REPONUM+1))" + fi else local hgDepth="0" fi - if [ ! -z "$(bzr root 2>/dev/null)" ]; then + if command -v bzr > /dev/null 2>&1; then local bzrPath="$(bzr root 2>/dev/null)" local bzrDepth="$(pathSegment "${bzrPath}")" - REPONUM="$((REPONUM+1))" + if [ ! -z "${bzrPath}" ]; then + REPONUM="$((REPONUM+1))" + fi else local bzrDepth="0" fi - if [ ! -z "$(svn info 2>/dev/null)" ]; then - local stringz="Working Copy Root Path: " - local svnPath="$(svn info | grep "${stringz}" | tr -d "${stringz}")" - local svnDepth="$(pathSegment "${svnPath}")" - REPONUM="$((REPONUM+1))" + if command -v svn > /dev/null 2>&1; then + local stringz="" + local stringx="" + local svnPath="$(svn info --xml 2>/dev/null | sed -n -e "s:${stringz}::" -e "s:${stringx}::p")" + # An old enough svn will not be able give us a path; default + # to 1 for that case. + if [ ! -z "${svnPath}" ]; then + local svnDepth="$(pathSegment "${svnPath}")" + REPONUM="$((REPONUM+1))" + elif [ -z "${svnPath}" ] && [ -d ".svn" ]; then + local svnDepth="1" + REPONUM="$((REPONUM+1))" + else + local svnDepth="0" + fi else local svnDepth="0" fi # Do not do more work then we have to. if [ "${REPONUM}" = "0" ]; then - return + return 0 fi # Figure out which repo is the deepest and use it. @@ -793,14 +1202,13 @@ repoTest() { # Detect which repos we are in and gather data. +# shellcheck source=/dev/null if [ -f "${CACHEFILE}" ] && [ "${CACHEFORCE}" = "1" ]; then # When requested only read from the cache to populate our symbols. . "${CACHEFILE}" else # If a value is not set through the environment set VCS_EXTRA to nothing. - if [ -z "${VCS_EXTRA}" ]; then - VCS_EXTRA="" - fi + : "${VCS_EXTRA:=""}" repoTest if [ -f "${CACHEFILE}" ] && [ "${REPONUM}" = "0" ]; then @@ -837,6 +1245,8 @@ if [ ! -z "${VAROUT}" ]; then echo "${VCS_SHORT_HASH}" elif [ "${VAROUT}" = "VCS_WC_MODIFIED" ]; then echo "${VCS_WC_MODIFIED}" + elif [ "${VAROUT}" = "VCS_ACTION_STAMP" ]; then + echo "${VCS_ACTION_STAMP}" else echo "error: Not a valid output symbol." 1>&2 exit 1 @@ -846,10 +1256,14 @@ fi # Detect requested output type and use it. if [ ! -z "${AFILETYPE}" ]; then - if [ "${AFILETYPE}" = "h" ]; then + if [ "${AFILETYPE}" = "c" ]; then + cOutput + elif [ "${AFILETYPE}" = "h" ]; then hOutput elif [ "${AFILETYPE}" = "xcode" ]; then xcodeOutput + elif [ "${AFILETYPE}" = "swift" ]; then + swiftOutput elif [ "${AFILETYPE}" = "sh" ]; then shOutput elif [ "${AFILETYPE}" = "py" ] || [ "${AFILETYPE}" = "python" ]; then @@ -870,10 +1284,26 @@ if [ ! -z "${AFILETYPE}" ]; then javaOutput elif [ "${AFILETYPE}" = "javaprop" ]; then javapropOutput + elif [ "${AFILETYPE}" = "csharp" ]; then + csharpOutput elif [ "${AFILETYPE}" = "tex" ]; then texOutput elif [ "${AFILETYPE}" = "m4" ]; then m4Output + elif [ "${AFILETYPE}" = "scheme" ]; then + schemeOutput + elif [ "${AFILETYPE}" = "clojure" ]; then + clojureOutput + elif [ "${AFILETYPE}" = "rpm" ]; then + rpmOutput + elif [ "${AFILETYPE}" = "hpp" ]; then + hppOutput + elif [ "${AFILETYPE}" = "matlab" ]; then + matlabOutput + elif [ "${AFILETYPE}" = "octave" ]; then + octaveOutput + elif [ "${AFILETYPE}" = "cmake" ]; then + cmakeOutput else echo "error: Not a valid output type." 1>&2 exit 1 @@ -883,8 +1313,8 @@ fi # If requested, make a cache file. if [ ! -z "${CACHEFILE}" ] && [ ! "${CACHEFORCE}" = "1" ]; then - TARGETFILE="${CACHEFILE}.tmp" - shOutput + EXTRA_NAME="VCS_EXTRA" + shOutput > "${CACHEFILE}.tmp" # Check to see if there have been any actual changes. if [ ! -f "${CACHEFILE}" ]; then diff --git a/3rdparty/autorevision/autorevision.asciidoc b/3rdparty/autorevision/autorevision.asciidoc index 14fd0186e5..05caca881d 100644 --- a/3rdparty/autorevision/autorevision.asciidoc +++ b/3rdparty/autorevision/autorevision.asciidoc @@ -1,23 +1,25 @@ = AUTOREVISION(1) = -:doctype: manpage -:br: {empty} + == NAME == autorevision - extract current-revision metadata from version-control repositories == SYNOPSIS == -*`autorevision`* {*`-t`* `` | *`-s`* ``} [*`-o`* `` [*`-f`*] ] [*`-U`*] [*`-V`*] +*autorevision* *-t* [*-o* [*-f*] ] [*-e* ] [*-U*] + +*autorevision* *-s* [*-o* [*-f*] ] [*-e* ] [*-U*] + +*autorevision* *-V* == DESCRIPTION == Extracts metadata about the head revision from your repository. This program is meant to be used by project build systems to extract -properties that can be used in software version strings. It can emit -source files containing variable and macro definitions suitable for -use with C, C++, Java, sh, Python, Perl, Mac info.plist and other -types of files (see below for the full list). +properties that can be used in version strings. It can emit source +files containing variable and macro definitions suitable for use with +C, C++, Java, Mac info.plist, sh, Python, Perl and many other types of +files (see below for the full list). -The generated source is written to standard output. +The generated source is written to the standard output. This program can normally be called from anywhere within a repository copy. Under bzr the copy must be of a branch, not a full multibranch @@ -27,8 +29,8 @@ checkout, not the repository itself. If you specify a cache file, then when *autorevision* is run where no repository can be recognized, the values from the cache file will be used instead. If a repository can be recognized, the cache is -rewritten. This feature makes it possible for your build to run -from an unpacked tarball that includes the cache file. +rewritten. This feature makes it possible for your build to run from +an unpacked tarball that includes the cache file. === Valid Repository Types === @@ -42,39 +44,30 @@ from an unpacked tarball that includes the cache file. === Valid Output Types === -*h*:: -A header file suitable for C/C++. - -*xcode*:: -A header like output for use with xcode to populate info.plist strings. +*clojure*:: +A clojure source file setting clojure variables. -*sh*:: -A text file suitable for including from a bash script. Will work with -Ruby. +*c*:: +A C/C++ source file. + +`autorevision_declr.h` in the contribs dir is provided for use with +this output. -*py*:: -A Python source file setting Python variables (*`python`* is an -acceptable synonym). +*cmake*:: +A cmake script file. -*pl*:: -A Perl source file setting Perl variables (*`perl`* is an acceptable -synonym). +*csharp*:: +C# file with Autorevision class -*lua*:: -A lua source file setting lua variables. +*h*:: +A header file suitable for C/C++. -*php*:: -A PHP source file setting PHP variables. +*hpp*:: +Alternate C++ header file with namespace. Namespace is assigned +from VCS_BASENAME. *ini*:: A ini source file setting ini variables. -*js*:: -A javascript source file setting javascript variables. - -*json*:: -A JSON format file. - *java*:: A Java source file setting class properties. @@ -82,14 +75,57 @@ A Java source file setting class properties. A Java properties file (like ini); useful when META-INF is readable in Java. -*tex*:: -A TeX source file defining TeX macros. Note that the symbols are given -different names since the underscore has a special meaning in TeX. -For example, VCS_SHORT_HASH is renamed to \vcsShortHash. +*js*:: +A javascript source file setting javascript variables. + +*json*:: +A JSON format file. + +*lua*:: +A lua source file setting lua variables. *m4*:: An m4 source file defining m4 macros. +*matlab*:: +Matlab output. + +*octave*:: +Octave output. + +*php*:: +A PHP source file setting PHP variables. + +*pl*:: +A Perl source file setting Perl variables (*`perl`* is an acceptable +synonym). + +*py*:: +A Python source file setting Python variables (*`python`* is an +acceptable synonym). + +*rpm*:: +A RPM spec file format setting spec file macros. + +*scheme*:: +A scheme source file setting scheme variables. + +*sh*:: +A text file suitable for including from a bash script. Will work with +Ruby. + +*swift*:: +A Swift source file setting Swift global constants. + +Unless set *VCS_EXTRA* and any symbols that are missing because of +repository support are set to `nil`. + +*tex*:: +A TeX source file defining TeX macros. Note that the symbols are +given different names since the underscore has a special meaning in +TeX. For example, VCS_SHORT_HASH is renamed to \vcsShortHash. + +*xcode*:: +A header like output for use with xcode to populate info.plist strings. === Valid Symbol Names === @@ -99,8 +135,8 @@ The repository type - "git", "hg", "bzr", or "svn". *VCS_BASENAME*:: The basename of the directory root. For most VCSes this will simply be the basename of the repository root directory. For Subversion, -*autorevision* will navigate up though trunk, branches, and tags -directories to find the actual root. +*autorevision* will attempt to navigate up though trunk, branches, and +tags directories to find the actual root. *VCS_NUM*:: A count of revisions between the current one and the initial @@ -108,7 +144,8 @@ one; useful for reporting build numbers. *VCS_UUID*:: A universally unique identifier, generated from the root commit in git -and hg; for svn it uses the supplied UUID.{br} +and hg; for svn it uses the supplied UUID. + +For git we choose the oldest commit if there is more than one. + Not currently implemented for bzr. *VCS_DATE*:: @@ -117,77 +154,91 @@ format, including seconds. *VCS_BRANCH*:: The name of the branch of the commit graph that was selected when -autoversion was run. Under Subversion this will normally be either -'trunk' or the basename of some branch or tag subdirectory, depending -on where *autoversion* was run. Under git, this will normally be the -shortname of the current branch (the asterisked line in the output of -of "git branch") except that when the branch doesn't have a shortname -it will be a full refspec. Under hg the feature that is called -'branches' is actually a sort of graph coloring (multiple heads can -have the same branch name) so this variable is filled with the current -bookmark if it exists, with the current branch name as a fallback.{br} +autoversion was run. + +Under git, this will normally be the shortname of the current branch +(the asterisked line in the output of "git branch") except that +when the branch doesn't have a shortname it will be a full +refspec. + +Under hg the feature that is called 'branches' is actually a sort of +graph coloring (multiple heads can have the same branch name) so this +symbol is filled with the current bookmark if it exists, with the +current branch name as a fallback. + +Under Subversion this will normally be either 'trunk' or the basename +of some branch or tag subdirectory, depending on where *autoversion* +was run. + Under bzr, this is the nick of the branch you are on. *VCS_TAG*:: -The name of the most recent tag ancestral to the current commit.{br} +The name of the most recent tag ancestral to the current commit. + Empty under Subversion. *VCS_TICK*:: A count of commits since most recent tag ancestral to the current -commit or an alias of *VCS_NUM* if there are no prior tags.{br} +commit or an alias of *VCS_NUM* if there are no prior tags. + Empty under Subversion. *VCS_EXTRA*:: A symbol set aside specifically to be set by the user through the environment or via scripts. +*VCS_ACTION_STAMP*:: +An "action stamp" consists of an RFC3339 timestamp in Zulu time, +followed by an exclamation point, followed by an RFC822 address +(technically, an "addr-spec" as defined in 6.1). + +For svn the second part is simply the author name. + +Not currently implemented for bzr. + *VCS_FULL_HASH*:: A full unique identifier for the current revision. *VCS_SHORT_HASH*:: -A shortened version of VCS_FULL_HASH, but VCS_FULL_HASH if it cannot be -shortened. +A shortened version of *VCS_FULL_HASH*, but *VCS_FULL_HASH* if it +cannot be shortened. *VCS_WC_MODIFIED*:: Set to `1` if the current working directory has been modified and `0` -if not. 'Untracked files are not ignored; see *`-U`* for details.' If -the output language is interpreted and has native Boolean literals, -true will mean modified and false unmodified. The C/C++ output is left -as numeric so the preprocessor can test it. +if not. If the output language has native Boolean literals, true will +mean modified and false unmodified. The C/C++ output is left as +numeric so the preprocessor can test it. + +'Untracked files are not ignored; see *`-U`* for details.' == OPTIONS == *-t* '':: -Sets the output type. It is required unless *`-s`* is specified; both +Sets the output type. It is required unless *`-s`* is specified; both *`-t`* and *`-s`* cannot be used in the same invocation. *-s* '':: Changes the reporting behavior; instead of emitting a symbol file to -stdout, only the value of that individual symbol will be reported. It +stdout, only the value of that individual symbol will be reported. It is required unless *`-t`* is specified; both *`-t`* and *`-s`* cannot be used in the same invocation. *-o* '':: Sets the name of the cache file. +*-e* '':: +Sets the output name of *VCS_EXTRA* + +Defaults to `VCS_EXTRA`. + *-f*:: -Forces the use cache data even when in a repo; useful if you want to -preprocess the data before final output. +Forces the use of cache data even when in a repo; useful for speeding +up subsequent runs if more than one output format is needed. *-U*:: Causes untracked files to be checked when determining if the working copy is modified 'for Subversion only'. While this is the -default behavior for all other repository types it is off by default +default behavior for all other repository types, it is off by default for Subversion because of speed concerns. *-V*:: Emits the autorevision version and exits. == BUGS == -The bzr extractor is not very well tested as yet. +The bzr extractor is not very well tested. When a git repo is actually a git-svn remote, this tool tries to do -the right thing and return a Subversion revision. The bug is that the +the right thing and return a Subversion revision. The bug is that the detector code for this case is somewhat unreliable; you will get the hash instead if your configuration doesn't use svn-remote.svn.url. @@ -201,12 +252,13 @@ unintended behavior. Development of autorevision is carried out at https://github.com/Autorevision/autorevision -Tarballs and HTML rendered docs are also hosted at -http://www.catb.org/esr/autorevision/ +HTML rendered docs and usage examples can be found at +https://autorevision.github.io/ == AUTHORS == dak180 : concept, bash/C/C++/XCode/PHP/ini -support, git and hg extraction.{br} +support, git and hg extraction. + Eric S. Raymond : Python/Perl/lua/m4 support, svn and -bzr extraction, git-svn support, CLI design, man page. +bzr extraction, git-svn support, CLI design, man page. + +See AUTHORS.txt for a full list in order of number of contributions. diff --git a/Acknowledgements.rtf b/Acknowledgements.rtf deleted file mode 100644 index 23c48d47f1..0000000000 --- a/Acknowledgements.rtf +++ /dev/null @@ -1,223 +0,0 @@ -{\rtf1\ansi\ansicpg1252\cocoartf1343\cocoasubrtf160 -\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 LucidaGrande;\f1\fswiss\fcharset0 Helvetica;\f2\froman\fcharset0 Times-Roman; -} -{\colortbl;\red255\green255\blue255;\red0\green137\blue255;} -\paperw12240\paperh15840\vieww25400\viewh14520\viewkind0 -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720 - -\f0\b\fs28 \cf0 Acknowledgments\ -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720 - -\b0\fs24 \cf0 Portions of this software may utilize the following copyrighted material, the use of which is hereby acknowledged.\ -\ - -\b Vienna Development Team\ - -\f1\b0\fs22 Steve Palmer\ -Michael Str\'f6ck\ -Jeffrey Johnson\ -\pard\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\tx4800\tx5280\tx5760\tx6240\tx6720\tx7200\tx7680\tx8160\tx8640\tx9120\tx9600\tx10080\tx10560\tx11040\tx11520\tx12000\tx12480\tx12960\tx13440\tx13920\tx14400\tx14880\tx15360\tx15840\tx16320\tx16800\tx17280\tx17760\tx18240\tx18720\tx19200\tx19680\tx20160\tx20640\tx21120\tx21600\tx22080\tx22560\tx23040\tx23520\tx24000\tx24480\tx24960\tx25440\tx25920\tx26400\tx26880\tx27360\tx27840\tx28320\tx28800\tx29280\tx29760\tx30240\tx30720\tx31200\tx31680\tx32160\tx32640\tx33120\tx33600\tx34080\tx34560\tx35040\tx35520\tx36000\tx36480\tx36960\tx37440\tx37920\tx38400\tx38880\tx39360\tx39840\tx40320\tx40800\tx41280\tx41760\tx42240\tx42720\tx43200\tx43680\tx44160\tx44640\tx45120\tx45600\tx46080\tx46560\tx47040\tx47520\tx48000\pardirnatural -\cf0 Salvatore Ansani\ -Barijaona Ramaholimihaso\ -Echelon9\ -Joshua Pore\ -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720 - -\f0\b\fs24 \cf0 \ -With Contributions From\ - -\f1\b0\fs22 Evan Schoenberg\ -David V. Kocher\ -Yann Bizeul\ -Hwang Hi\ -\pard\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\tx4800\tx5280\tx5760\tx6240\tx6720\tx7200\tx7680\tx8160\tx8640\tx9120\tx9600\tx10080\tx10560\tx11040\tx11520\tx12000\tx12480\tx12960\tx13440\tx13920\tx14400\tx14880\tx15360\tx15840\tx16320\tx16800\tx17280\tx17760\tx18240\tx18720\tx19200\tx19680\tx20160\tx20640\tx21120\tx21600\tx22080\tx22560\tx23040\tx23520\tx24000\tx24480\tx24960\tx25440\tx25920\tx26400\tx26880\tx27360\tx27840\tx28320\tx28800\tx29280\tx29760\tx30240\tx30720\tx31200\tx31680\tx32160\tx32640\tx33120\tx33600\tx34080\tx34560\tx35040\tx35520\tx36000\tx36480\tx36960\tx37440\tx37920\tx38400\tx38880\tx39360\tx39840\tx40320\tx40800\tx41280\tx41760\tx42240\tx42720\tx43200\tx43680\tx44160\tx44640\tx45120\tx45600\tx46080\tx46560\tx47040\tx47520\tx48000\pardirnatural -\cf0 Les Orchard\ -Darren Kulp\ -Brandon Booth\ -Philipp Antoni\ -Curtis Faith\ -Adam Hartford\ -Andrew Herron\ -dak180\ -Emiliano Necciari\ -Boris Du\'9aek\ -bavarious\ -Daniel Cotton\ -Dmitry Wolf\ -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720 - -\f0\b\fs24 \cf0 \ -Application Icon\ - -\f1\b0\fs22 Nick Daz\'e9 designed the Vienna 3 icon and contributed to many visual improvements.\ - -\f0\b\fs24 \ -Graphics\ - -\f1\b0\fs22 Thanks to Brandon Booth for the General and Appearance preference icons.\ -Thanks also due to Philipp Antoni for the UI improvements in 2.2.\ -"Add to Safari reading list" icon originally authored from Emey87 - {\field{\*\fldinst{HYPERLINK "http://emey87.deviantart.com/"}}{\fldrslt http://emey87.deviantart.com/}}, used under a Creative Commons Attribution-No Derivative Works 3.0 Unported license.\ -Monochrome status bar icon: Font Awesome by Dave Gandy - {\field{\*\fldinst{HYPERLINK "http://fontawesome.io/"}}{\fldrslt http://fontawesome.io/}}, used under a SIL Open Font License (OFL) 1.1 license.\ - -\f0\b\fs24 \ -Localisations\ - -\f1\b0\fs22 Grateful thanks are due to the following people who volunteered localised versions of Vienna:\ -\ -Basque - Aitor Zubizarreta\ -Brazilian Portuguese - Helv\'e9cio Mafra and Adriano Marcondes Machado\ -Czech - Jakub Formanek and Boris Du\'9aek\ -Danish - David Munch\ -Dutch - Martijn van Exel, Peter van Peursem and Konstruktionist\ -French - Cyril Gautrias\ -German - Jan Kampling, Michael Str\'f6ck and biphuhn\ -Italian - Marcello Teodori\ -Japanese - Daisuke Okada\ -Korean - Lee Seung Koo\ -Portuguese - Rui Carlos A. Gon\'e7alves\ -Spanish - Carlos Morales and Juan Pablo Atienza Martinez\ -Simplified Chinese - Arsen Liang\ -Swedish - Christoffer Larsson and Peter Vendleg\'e5rd\ -Traditional Chinese - Weizhong Yang and Jack M.H. Lin\ -Turkish - Emrah Omuris\ -Russian - Taras "sacrat" Brizitsky\ -Ukrainian - Andriy Kachalo\ - -\f0\fs24 \ -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720 -{\field{\*\fldinst{HYPERLINK "http://growl.info"}}{\fldrslt -\b \cf0 Evan Schoenberg -\b0 (Growl application bridge)}}\ -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720 - -\f1\fs22 \cf0 Copyright (c) The Growl Project, 2004 \ -All rights reserved.\ -\ -Redistribution and use in source and binary forms, with or without modification,\ -are permitted provided that the following conditions are met:\ -\ -1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\ -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\ -3. Neither the name of Growl nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\ -\ -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -\f0\fs24 \ -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720 - -\fs20 \cf0 \ -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\tx7280\tx7840\tx8400\tx8960\tx9520\tx10080\tx10640\tx11200\tx11760\tx12320\tx12880\tx13440\tx14000\tx14560\tx15120\tx15680\tx16240\tx16800\tx17360\tx17920\tx18480\tx19040\tx19600\tx20160\tx20720\tx21280\tx21840\tx22400\tx22960\tx23520\tx24080\tx24640\tx25200\tx25760\tx26320\tx26880\tx27440\tx28000\tx28560\tx29120\tx29680\tx30240\tx30800\tx31360\tx31920\tx32480\tx33040\tx33600\tx34160\tx34720\tx35280\tx35840\tx36400\tx36960\tx37520\tx38080\tx38640\tx39200\tx39760\tx40320\tx40880\tx41440\tx42000\tx42560\tx43120\tx43680\tx44240\tx44800\tx45360\tx45920\tx46480\tx47040\tx47600\tx48160\tx48720\tx49280\tx49840\tx50400\tx50960\tx51520\tx52080\tx52640\tx53200\tx53760\tx54320\tx54880\tx55440\tx56000 -{\field{\*\fldinst{HYPERLINK "https://github.com/ccgus/fmdb"}}{\fldrslt -\b\fs24 \cf0 \CocoaLigature0 August "Gus" Mueller, Flying Meat Inc. -\b0 (\CocoaLigature1 FMDatabase Library)}} -\f1\b\fs24 \ -\pard\pardeftab720 - -\b0\fs22 \cf0 Copyright (c) 2008 Flying Meat Inc.\ -\ -Permission is hereby granted, free of charge, to any person obtaining a copy\ -of this software and associated documentation files (the "Software"), to deal\ -in the Software without restriction, including without limitation the rights\ -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ -copies of the Software, and to permit persons to whom the Software is\ -furnished to do so, subject to the following conditions:\ -\ -The above copyright notice and this permission notice shall be included in\ -all copies or substantial portions of the Software.\ -\ -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\ -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\ -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\ -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\ -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\ -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\ -THE SOFTWARE.\ -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural -\cf0 --- \ -English non-authoritative interpretation of the license: \ -\pard\pardeftab720 -\cf0 In short, this is the MIT License.\ -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720 - -\f0\fs24 \cf0 \ -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\tx7280\tx7840\tx8400\tx8960\tx9520\tx10080\tx10640\tx11200\tx11760\tx12320\tx12880\tx13440\tx14000\tx14560\tx15120\tx15680\tx16240\tx16800\tx17360\tx17920\tx18480\tx19040\tx19600\tx20160\tx20720\tx21280\tx21840\tx22400\tx22960\tx23520\tx24080\tx24640\tx25200\tx25760\tx26320\tx26880\tx27440\tx28000\tx28560\tx29120\tx29680\tx30240\tx30800\tx31360\tx31920\tx32480\tx33040\tx33600\tx34160\tx34720\tx35280\tx35840\tx36400\tx36960\tx37520\tx38080\tx38640\tx39200\tx39760\tx40320\tx40880\tx41440\tx42000\tx42560\tx43120\tx43680\tx44240\tx44800\tx45360\tx45920\tx46480\tx47040\tx47600\tx48160\tx48720\tx49280\tx49840\tx50400\tx50960\tx51520\tx52080\tx52640\tx53200\tx53760\tx54320\tx54880\tx55440\tx56000\pardirnatural -{\field{\*\fldinst{HYPERLINK "http://www.sqlite.org"}}{\fldrslt -\b \cf0 D. Richard Hipp -\b0 (SQLite)}}\ -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\sa320 - -\f1\fs22 \cf0 The original author of SQLite has dedicated the code to the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute the original SQLite code, either in source code form or as a compiled binary, for any purpose, commerical or non-commerical, and by any means.\ -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\tx7280\tx7840\tx8400\tx8960\tx9520\tx10080\tx10640\tx11200\tx11760\tx12320\tx12880\tx13440\tx14000\tx14560\tx15120\tx15680\tx16240\tx16800\tx17360\tx17920\tx18480\tx19040\tx19600\tx20160\tx20720\tx21280\tx21840\tx22400\tx22960\tx23520\tx24080\tx24640\tx25200\tx25760\tx26320\tx26880\tx27440\tx28000\tx28560\tx29120\tx29680\tx30240\tx30800\tx31360\tx31920\tx32480\tx33040\tx33600\tx34160\tx34720\tx35280\tx35840\tx36400\tx36960\tx37520\tx38080\tx38640\tx39200\tx39760\tx40320\tx40880\tx41440\tx42000\tx42560\tx43120\tx43680\tx44240\tx44800\tx45360\tx45920\tx46480\tx47040\tx47600\tx48160\tx48720\tx49280\tx49840\tx50400\tx50960\tx51520\tx52080\tx52640\tx53200\tx53760\tx54320\tx54880\tx55440\tx56000\pardirnatural -{\field{\*\fldinst{HYPERLINK "http://snoize.com/"}}{\fldrslt -\b\fs24 \cf0 \CocoaLigature0 Kurt Revis -\b0 (DisclosableView)}} -\b\fs24 \CocoaLigature0 \ -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\tx7280\tx7840\tx8400\tx8960\tx9520\tx10080\tx10640\tx11200\tx11760\tx12320\tx12880\tx13440\tx14000\tx14560\tx15120\tx15680\tx16240\tx16800\tx17360\tx17920\tx18480\tx19040\tx19600\tx20160\tx20720\tx21280\tx21840\tx22400\tx22960\tx23520\tx24080\tx24640\tx25200\tx25760\tx26320\tx26880\tx27440\tx28000\tx28560\tx29120\tx29680\tx30240\tx30800\tx31360\tx31920\tx32480\tx33040\tx33600\tx34160\tx34720\tx35280\tx35840\tx36400\tx36960\tx37520\tx38080\tx38640\tx39200\tx39760\tx40320\tx40880\tx41440\tx42000\tx42560\tx43120\tx43680\tx44240\tx44800\tx45360\tx45920\tx46480\tx47040\tx47600\tx48160\tx48720\tx49280\tx49840\tx50400\tx50960\tx51520\tx52080\tx52640\tx53200\tx53760\tx54320\tx54880\tx55440\tx56000\pardirnatural - -\b0\fs22 \cf0 Copyright (c) 2002, Kurt Revis. All rights reserved.\ -\ -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\ -\ - * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\ - * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\ - * Neither the name of Snoize nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\ -\ -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\ -\ -\pard\pardeftab720 -{\field{\*\fldinst{HYPERLINK "http://alexgorbatchev.com/"}}{\fldrslt -\b\fs26 \cf2 \CocoaLigature1 Alex Gorbatchev -\b0 (SyntaxHighlighter)\ -}}\pard\pardeftab720 -\cf0 \CocoaLigature1 Copyright (c) 2003, 2004 Jim Weirich & Alex Gorbatchev\ -\ -Permission is hereby granted, free of charge, to any person obtaining\ -a copy of this software and associated documentation files (the\ -"Software"), to deal in the Software without restriction, including\ -without limitation the rights to use, copy, modify, merge, publish,\ -distribute, sublicense, and/or sell copies of the Software, and to\ -permit persons to whom the Software is furnished to do so, subject to\ -the following conditions:\ -\ -The above copyright notice and this permission notice shall be\ -included in all copies or substantial portions of the Software.\ -\ -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\ -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\ -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\ -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\ -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\ -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\ -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.{\field{\*\fldinst{HYPERLINK "http://alexgorbatchev.com/"}}{\fldrslt -\f2\fs24 \cf2 }} -\f2\fs24 \cf2 \ -\pard\tx529\pardeftab529\pardirnatural - -\f1\fs22 \cf0 \CocoaLigature0 \ -{\field{\*\fldinst{HYPERLINK "https://github.com/shpakovski/MASPreferences"}}{\fldrslt -\b\fs26 Vadim Shpakovski -\b0 (MASPreferences)}}\ -MASPreferences is licensed under the 2-clause BSD license.\ -\ -Copyright (c) 2011-2014, Vadim Shpakovski\ -All rights reserved.\ -\ -Redistribution and use in source and binary forms, with or without\ -modification, are permitted provided that the following conditions are met:\ -\ -1. Redistributions of source code must retain the above copyright notice, this\ - list of conditions and the following disclaimer.\ -\ -2. Redistributions in binary form must reproduce the above copyright notice,\ - this list of conditions and the following disclaimer in the documentation\ - and/or other materials provided with the distribution.\ -\ -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\ -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\ -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\ -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR\ -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\ -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\ -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\ -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\ -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\ -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.} \ No newline at end of file diff --git a/CHANGES b/CHANGES index 4c00433a3a..c37c822652 100644 --- a/CHANGES +++ b/CHANGES @@ -8,23 +8,230 @@ most recent build should be at the top of this file. Thanks! -3.0.9 +3.1.16 +------ +- Fix article selection after an article is deleted from within the 'Unread Articles' folder +- Fix bugs related to multithreading +- Fix handling of impossibility of creating the database +- Corrected changelog text at version 3.1.15 + +3.1.15 +------ +- Fix article list not scrolling to top when selecting a folder +- Fix 'Skip Folder' not selecting the first unread article in the next folder with unread articles + +3.1.14 +------ +- Fix article pane not updating on article deletion from the 'Unread Articles' folder + +3.1.13 +------ +- Fixes related to searching and smart folders +- Fix for selection of first article when jumping on next feed +- Better fix for unwanted reload of the article currently being read during sync + +3.1.12 +------ +- Fix crashes induced by some URLs +- Fix crash on macOS 10.13 High Sierra related to Activity window +- Fix unwanted reload of the article currently being read during sync +- Fix selection of current article on change of sort criterion/order +- Fix bug where Vienna doesn't quit when you press ‘Quit Vienna’ in the Database Upgrade window +- Truncate long text items with an ellipsis + +3.1.11 +------ +- Fix deleting article from smart folder or filtered folder +- Fix selection of last unread article with Next Unread command +- Update FMDB to 2.7.2 + +3.1.10 +------ +- Fix access to Get Info window +- Fix CoreAnimation related problems + +3.1.9 ----- +- Change the website to vienna-rss.com as the old domain name (vienna-rss.org) could not be renewed. Perform a minor database evolution to update this. +- Add a plug-in supporting wallabag.it +- Show acknowledgements in "About" dialog box +- Fix del.icio.us URL +- Fix an issue with icon +- Change status bar icons to scalable pdfs +- Remove textures in some windows, change some .nib to .xib +- Refactor things (window preferences code, delegates, organization of help files …) +- Modernize build architecture (Xcode 8.2, update pods) + +3.1.8 +----- +- Fixed an External XML Entity (XXE) vulnerability which allowed servers to steal the content of files on the machine running Vienna +- Fix incorrect escaping of OPML export +- Fix font preferences not working +- Fix error on unread articles count with OpenReader feeds +- Fix articles' list during feed refreshes when the current selection is a smart or group folder + +3.1.7 +----- +- Fix incorrect escaping of some feeds + +3.1.6 +----- +- Add support for delta feeds (RFC3229+feed) +- Database performance improvements +- Fix 'N' key to not scan fresher articles from same folder, except for smart folders +- Fix 'B' key to always go to first unread article +- Fix retrieving article text of some feeds +- Fix some macOS Sierra glitches +- Fix status message after tasks like marking OpenReader articles read +- Fixes to Danish and Russian translations, thanks to David Munch and Rinat Shaikhutdinov + +3.1.6 Release Candidate 2 +------------------------- +- New set of default feeds, thanks to Jesse Claven and Ricky Morse +- Fix infinite loop on ‘Skip Folder’ command when no unread articles were left +- Fix relative URLs, like in images's `srcset` attributes +- New developer tests, thanks to György Tóth +- Code refactoring / cleanup + +3.1.6 Release Candidate 1 +------------------------- +- When the user selects a folder, loading articles from database occurs on a separate thread +- Fix again the 'N' key not selecting last unread article or not wrapping to the first unread article +- Keep currently selected article on refresh of a group or smart folder +- Fix article selection in Unified layout +- Fix "Last Refresh filter" +- Fix an exception on opening the General preferences window +- Fix an assertion failure +- Code refactoring +- Reorganized tests + +3.1.5 +----- +- Fix syncing with FeedHQ +- Avoid unwanted eviction from cache +- Fix enclosure “Open” button when the enclosure URL has a query part +- Ensures the article pane displays selected article when switching from Unified to Horizontal or Vertical layout + +3.1.5 Release Candidate 2 +------------------------- +- Fix 'N' key breakage when a single unread article remained below current folder selection +- Fix 'N' key not wrapping to the first unread article under certain circumstances +- Force images to scale correctly +- Try to fix an assertion failure on balancing start/stop animations + +3.1.5 Release Candidate 1 +------------------------- +- Fix visual issue on marking read all articles in a group folder +- Fix deleting articles from a group folder +- Fix restoring Open Reader article from Trash +- Fix back and forward in Horizontal and Vertical layouts (invoked by < and > keys) +- Fix sort indicator in Horizontal and Vertical layouts +- Scrolls to top of list when selecting a folder +- Fix a rare occurence of crash in Preferences folder + +3.1.4 +----- +- Fix extreme slowness on marking a series of articles deleted +- Improve selection of next unread article and article list update +- Fix selection of default RSS reader application in preferences window +- In General preferences, use localized names for download folder and RSS readers' app names +- Fixed a problem preventing window from appearing at launch in certain settings + +3.1.4 Release Candidate 2 +------------------------- +- Improved detection of feeds URL +- Align selection behavior on selecting or skipping folders with 3.0.9's +- Fix handling of some addresses in internal browser's address field +- Improved German translation + +3.1.4 Release Candidate 1 +------------------------- +- Refactored code +- Make sure that unread / starred statuses are in sync between Vienna and the Open Reader server[^314-1] +- When opening current article in browser, respect what is set in user's preferences on marking it read +- Fix validation button of “New Group Folder…” dialog +- Fix features in Downloads and Activity windows +- Handle images directly embedded in HTML code +- Make sure we have a keyboard responder after switching layout +- Default folder sorting is manual +- Fix various crashes +- Other bugfixes + +[^314-1]: If you have deleted articles, you might have to reset the unread / starred statuses of these older articles from the web interface of your Open Reader server. + +3.1.3 +----- +- Fix some crashes +- Fix empty article list displayed by some feeds +- Prevent unwanted updates of user interface while refreshing Open Reader feeds +- E-mailing a link now occurs in foreground + +3.1.2 +----- +- More crash fixes +- Fix Vienna forgetting current folder/feed after termination and relaunch +- Restore mechanism required by some plugins, especially "Add to Safari reading list" +- Conversion to modern Ojective-C + +3.1.1 +----- +- Fix some crashes +- Fix deadlocks on OS X 10.8 +- Fix the sort functionality in Activity Window + +3.1.0 +----- +- Add search field in subscriptions tree +- In Atom feeds, prefer the ‘content’ item over the ’summary’ one +- Fix articles reappearing in a feed after being marked for deletion +- Improved memory management +- Fix broken Download window features +- Security : update Sparkle autoupdate framework with latest version and use a secure URL +- Fix some crashes + + +3.1.0 Beta 5 +------------ - Fix problem w/ subscribing to some feeds -- Improve handling of feeds having duplicate GUIDs -- Fix some styles to limit maximum image size -- Improve the ad blocking feature of the Feedlight styles -- Display articles of any newly added folder -- If adding existing feed, focus it - Better handling of legal/illegal characters in URL strings - Fix enclosure download when the URL string contains a query +- If adding existing feed, focus it +- Keep order of folders and groups on OPML export +- Fix some styles to limit maximum image size +- Improve the ad blocking feature of the Feedlight styles - Recognize a few more file extensions to be directly downloaded - Fix some crashes -3.0.8 ------ +3.1.0 Beta 4 +------------ +- Fix a crash +- Ensure current article remains visible when changing layout +- Display articles of any newly added folder +- Some code refactoring + +3.1.0 Beta 3 +------------ +- Improved handling of feeds having duplicate GUIDs +- Fixed rendering of feeds having XHTML bodies +- Handle feeds having illegal characters +- Allow concurrent drawings in unified layout +- Converted code to use Automatic Reference Count +- Improved cache mechanism for articles (using NSCache) +- Compiled with XCode 7 GM under OS X El Capitan GM + +3.1.0 Beta 2 +------------ - Fix unwanted scrolls in Unified layout +3.1.0 Beta 1 +------------ +### ! OS X 10.8 or better only ! +- Replace our "in house" database queue with FMDatabaseQueue and reorganize access +- Use view based NSTableView for unified layout (instead of PXListView) +- Replace JSONKit with NSJSONSerialization +- Replace XMLParser with NSXMLDocument/NSXMLNode +- Replace other deprecated functions / Miscellaneous refactoring + 3.0.7 ----- - More consistent response to keyboard shortcuts when the user switches to primary tab diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..996f4bf3b9 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,19 @@ +# Contributing to Vienna + +## Writing code + +The current version of Vienna requires Xcode 7 and Mac OS X 10.11 SDK. We will be officially moving to Xcode 8 and macOS Sierra SDK once it has been released. Currently the Unit Tests require Xcode 8 and Swift 3. + +Vienna uses [cocoapods](http://cocoapods.org) for managing dependencies. When building, make sure to always open the Xcode workspace `Viennna.xcworkspace` instead of a project file. + +You should have a basic knowledge of Git and read this [advice on workflow](https://github.com/ViennaRSS/vienna-rss/wiki/Good-manners-with-Git). + +As a starting point, search for any [issues with the *help-wanted* label](https://github.com/ViennaRSS/vienna-rss/issues?q=is%3Aopen+is%3Aissue+label%3Ahelp-wanted). + +Please let us know what you are working on by posting an issue on Vienna's github and assigning it to yourself. + +## Code style guidelines + +For Objective-C code, please try to follow the [Spotify Objective-C Coding Style](https://github.com/spotify/ios-style). + +For Swift code, please try to follow the [GitHub Swift Style Guide](https://github.com/github/swift-style-guide). diff --git a/Credits.rtf b/Credits.rtf new file mode 100644 index 0000000000..bc2c86469c --- /dev/null +++ b/Credits.rtf @@ -0,0 +1,290 @@ +{\rtf1\ansi\ansicpg1252\cocoartf1504\cocoasubrtf810 +{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +{\*\expandedcolortbl;;} +{\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid1} +{\list\listtemplateid2\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid101\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid2} +{\list\listtemplateid3\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{decimal\}.}{\leveltext\leveltemplateid201\'02\'00.;}{\levelnumbers\'01;}\fi-360\li720\lin720 }{\listname ;}\listid3} +{\list\listtemplateid4\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{decimal\}.}{\leveltext\leveltemplateid301\'02\'00.;}{\levelnumbers\'01;}\fi-360\li720\lin720 }{\listname ;}\listid4}} +{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}{\listoverride\listid3\listoverridecount0\ls3}{\listoverride\listid4\listoverridecount0\ls4}} +\vieww10900\viewh8400\viewkind0 +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 + +\f0\fs22 \cf0 Portions of this software may utilize the following copyrighted material, the use of which is hereby acknowledged.\ +\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 + +\b \cf0 Vienna development team +\b0 \ +\ + \'95 Steve Palmer\ + \'95 Michael Str\'f6ck\ + \'95 Jeffrey Johnson\ + \'95 Salvatore Ansani\ + \'95 Barijaona Ramaholimihaso\ + \'95 Echelon9\ + \'95 Joshua Pore\ +\ + +\b Contributors +\b0 \ +\ + \'95 Evan Schoenberg\ + \'95 David V. Kocher\ + \'95 Yann Bizeul\ + \'95 Hwang Hi\ + \'95 Les Orchard\ + \'95 Darren Kulp\ + \'95 Brandon Booth\ + \'95 Philipp Antoni\ + \'95 Curtis Faith\ + \'95 Adam Hartford\ + \'95 Andrew Herron\ + \'95 dak180\ + \'95 Emiliano Necciari\ + \'95 Boris Du\'9aek\ + \'95 bavarious\ + \'95 Daniel Cotton\ + \'95 Dmitry Wolf\ + \'95 Gy\'f6rgy T\'f3th\ +\ + +\b Graphics +\b0 \ +\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li425\fi-426\pardirnatural\partightenfactor0 +\cf0 \'95 Nick Daz\'e9, for the Vienna 3 icon and many visual improvements.\ + \'95 Brandon Booth, for the General and Appearance preference icons.\ + \'95 Philipp Antoni, for the UI improvements in 2.2.\ + \'95 "Add to Safari reading list" icon originally authored from {\field{\*\fldinst{HYPERLINK "https://emey87.deviantart.com"}}{\fldrslt Emey87}}, used under a Creative Commons Attribution-No Derivative Works 3.0 Unported license.\ + \'95 Monochrome status bar icon: Font Awesome by {\field{\*\fldinst{HYPERLINK "https://fontawesome.io"}}{\fldrslt Dave Gand}}, used under a SIL Open Font License (OFL) 1.1 license.\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 + +\b \cf0 Localizations +\b0 \ +\ +Basque\ +\pard\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li424\fi-425\pardirnatural\partightenfactor0 +\cf0 Aitor Zubizarreta\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Simplified Chinese\ +\pard\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li424\fi-425\pardirnatural\partightenfactor0 +\cf0 Arsen Liang\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Traditional Chinese\ +\pard\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li424\fi-425\pardirnatural\partightenfactor0 +\cf0 Weizhong Yang and Jack M.H. Lin\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Czech\ +\pard\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li424\fi-425\pardirnatural\partightenfactor0 +\cf0 Jakub Formanek and Boris Du\'9aek\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Danish\ +\pard\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li424\fi-425\pardirnatural\partightenfactor0 +\cf0 David Munch\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Dutch\ +\pard\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li424\fi-425\pardirnatural\partightenfactor0 +\cf0 Martijn van Exel, Peter van Peursem and Konstruktionist\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +French\ +\pard\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li424\fi-425\pardirnatural\partightenfactor0 +\cf0 Cyril Gautrias\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +German\ +\pard\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li424\fi-425\pardirnatural\partightenfactor0 +\cf0 Jan Kampling, Michael Str\'f6ck and biphuhn\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Italian\ +\pard\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li424\fi-425\pardirnatural\partightenfactor0 +\cf0 Marcello Teodori\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Japanese\ +\pard\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li424\fi-425\pardirnatural\partightenfactor0 +\cf0 Daisuke Okada\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Korean\ +\pard\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li424\fi-425\pardirnatural\partightenfactor0 +\cf0 Lee Seung Koo\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Portuguese\ +\pard\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li424\fi-425\pardirnatural\partightenfactor0 +\cf0 Rui Carlos A. Gon\'e7alves\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Brazilian Portuguese\ +\pard\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li424\fi-425\pardirnatural\partightenfactor0 +\cf0 Helv\'e9cio Mafra and Adriano Marcondes Machado\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Spanish\ +\pard\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li424\fi-425\pardirnatural\partightenfactor0 +\cf0 Carlos Morales and Juan Pablo Atienza Martinez\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Swedish\ +\pard\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li424\fi-425\pardirnatural\partightenfactor0 +\cf0 Christoffer Larsson and Peter Vendleg\'e5rd\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Turkish\ +\pard\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li424\fi-425\pardirnatural\partightenfactor0 +\cf0 Emrah Omuris\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Russian\ +\pard\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li424\fi-425\pardirnatural\partightenfactor0 +\cf0 Taras "sacrat" Brizitsky\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +Ukrainian\ +\pard\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li424\fi-425\pardirnatural\partightenfactor0 +\cf0 Andriy Kachalo\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 + +\b \cf0 ASIHTTPRequest +\b0 \ +Copyright (c) 2007-2011, All-Seeing Interactive. All rights reserved.\ +\ +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li425\fi-426\pardirnatural\partightenfactor0 +\ls1\ilvl0\cf0 {\listtext \'95 }Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\ +{\listtext \'95 }Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\ +{\listtext \'95 }Neither the name of the All-Seeing Interactive nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +THIS SOFTWARE IS PROVIDED BY All-Seeing Interactive ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL All-Seeing Interactive BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\ +\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 + +\b \cf0 CDEvents +\b0 \ +Copyright (c) 2010, 2011 Aron Cedercrantz\ +\ +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\ +\ +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\ +\ +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\ +\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 + +\b \cf0 DisclosableView +\b0 \ +Copyright (c) 2002, Kurt Revis. All rights reserved.\ +\ +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li425\fi-426\pardirnatural\partightenfactor0 +\ls2\ilvl0\cf0 {\listtext \'95 }Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\ +{\listtext \'95 }Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\ +{\listtext \'95 }Neither the name of Snoize nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\ +\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 + +\b \cf0 FMDatabase Library +\b0 \ +Copyright (c) 2008, August "Gus" Mueller, Flying Meat Inc.\ +\ +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\ +\ +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\ +\ +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\ +\ +English non-authoritative interpretation of the license: \ +In short, this is the MIT License.\ +\ + +\b Growl application bridge +\b0 \ +Copyright (c) 2004, Evan Schoenberg, The Growl Project. All rights reserved.\ +\ +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\ +\pard\tx189\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li427\fi-428\pardirnatural\partightenfactor0 +\ls3\ilvl0\cf0 {\listtext 1. }Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\ +{\listtext 2. }Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\ +{\listtext 3. }Neither the name of Growl nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\ +\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 + +\b \cf0 MASPreferences +\b0 \ +MASPreferences is licensed under the 2-clause BSD license.\ +\ +Copyright (c) 2011-2014, Vadim Shpakovski. All rights reserved.\ +\ +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\ +\ +\pard\tx189\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\li427\fi-428\pardirnatural\partightenfactor0 +\ls4\ilvl0\cf0 {\listtext 1. }Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\ +{\listtext 2. }Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 +\cf0 \ +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\ +\ +\pard\tx185\tx427\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0 + +\b \cf0 OCMock +\b0 \ +Copyright (c) 2004-2016 Erik Doernenburg and contributors\ +\ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use these files except in compliance with the License. You may obtain a copy of the License at\ +http://www.apache.org/licenses/LICENSE-2.0\ +\ +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\ +\ + +\b Sparkle +\b0 \ +Copyright (c) 2006-2013 Andy Matuschak.\ +Copyright (c) 2009-2013 Elgato Systems GmbH.\ +Copyright (c) 2011-2014 Kornel Lesi\uc0\u324 ski.\ +Copyright (c) 2015-2017 Mayur Pawashe.\ +Copyright (c) 2014 C.W. Betts.\ +Copyright (c) 2014 Petroules Corporation.\ +Copyright (c) 2014 Big Nerd Ranch.\ +All rights reserved.\ +\ +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\ +\ +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\ +\ +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\ +\ + +\b SQLite +\b0 \ +D. Richard Hipp\ +The original author of SQLite has dedicated the code to the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute the original SQLite code, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means.\ +\ + +\b SyntaxHighlighter +\b0 \ +Copyright (c) 2003, 2004 Jim Weirich & Alex Gorbatchev\ +\ +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\ +\ +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\ +\ +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.} \ No newline at end of file diff --git a/DatabaseSchema.doc b/DatabaseSchema.doc old mode 100755 new mode 100644 diff --git a/Interfaces/ActivityViewer.nib/designable.nib b/Interfaces/ActivityViewer.nib/designable.nib deleted file mode 100644 index 20eee2f368..0000000000 --- a/Interfaces/ActivityViewer.nib/designable.nib +++ /dev/null @@ -1,714 +0,0 @@ - - - - 1060 - 13A598 - 3084 - 1265 - 695.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSCustomObject - NSScrollView - NSScroller - NSSplitView - NSTableColumn - NSTableHeaderView - NSTableView - NSTextFieldCell - NSTextView - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - ActivityViewer - - - FirstResponder - - - NSApplication - - - 27 - 2 - {{150, 449}, {646, 563}} - -260571136 - Activity Window - NSPanel - - View - - - {213, 113} - - - 256 - - - - 274 - - - - 256 - - - - 2304 - - - - 256 - {644, 346} - - - YES - NO - YES - - - 256 - {644, 17} - - - - - - - -2147483392 - {{-26, 0}, {16, 17}} - - - - 19 - 10 - 1000 - - 75497536 - 2048 - - - LucidaGrande - 11 - 3100 - - - 6 - System - headerColor - - 3 - MQA - - - - 6 - System - headerTextColor - - 3 - MAA - - - - - 337641536 - 2048 - - - - 6 - System - controlBackgroundColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - - - YES - - - - name - 309 - 40 - 1000 - - 75497536 - 2048 - Source - - - 3 - MC4zMzMzMzI5ODU2AA - - - - - 337641536 - 2048 - - - - - - 3 - YES - - - name - YES - caseInsensitiveCompare: - - - - status - 306.66162109375 - 40.66162109375 - 1000 - - 75497536 - 2048 - Status - - - - - - 337641536 - 2048 - - - - - - 3 - YES - - - status - YES - caseInsensitiveCompare: - - - - 3 - 2 - - - 6 - System - gridColor - - 3 - MC41AA - - - 14 - 1388314624 - - - 4 - 15 - 0 - YES - 0 - 1 - - - {{1, 17}, {644, 346}} - - - - - 4 - - - - -2147483392 - {{-30, 17}, {15, 331}} - - - NO - - _doScroller: - 0.98947370052337646 - - - - -2147483392 - {{1, -30}, {629, 15}} - - - NO - 1 - - _doScroller: - 0.92228740453720093 - - - - 2304 - - - - {{1, 0}, {644, 17}} - - - - - 4 - - - {646, 364} - - - 133682 - - - - - QSAAAEEgAABBgAAAQYAAAA - 0.25 - 4 - 1 - - - - 256 - - - - 2304 - - - - 2322 - {644, 190} - - - - - - - - - - - - - - 38 - - - - 644 - 1 - - - 67119969 - 0 - - - - - 6 - System - selectedTextBackgroundColor - - - - 6 - System - selectedTextColor - - - - - - - 1 - MCAwIDEAA - - - - - - 1 - - 6 - {644, 10000000} - - - - {{1, 1}, {644, 190}} - - - - - - {4, 5} - - 12582912 - - - - - - TU0AKgAAAHCAFUqgBVKsAAAAwdVQUqwaEQeIRGJRGFlYqwWLQ+JxuOQpVRmEx2RROKwOQyOUQSPyaUym -SxqWyKXyeYxyZzWbSuJTScRCbz2Nz+gRKhUOfTqeUai0OSxiWTiBQSHSGFquGwekxyAgAAAOAQAAAwAA -AAEAEAAAAQEAAwAAAAEAEAAAAQIAAwAAAAIACAAIAQMAAwAAAAEABQAAAQYAAwAAAAEAAQAAAREABAAA -AAEAAAAIARIAAwAAAAEAAQAAARUAAwAAAAEAAgAAARYAAwAAAAEAEAAAARcABAAAAAEAAABnARwAAwAA -AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA - - - - - - 3 - MCAwAA - - - - 4 - - - - 256 - {{629, 1}, {16, 190}} - - - NO - - _doScroller: - 1 - - - - -2147483392 - {{-100, -100}, {87, 18}} - - - NO - 1 - - _doScroller: - 1 - 0.94565218687057495 - - - {{0, 373}, {646, 192}} - - - 133138 - - - - 0.25 - 4 - 1 - - - {{0, -2}, {646, 565}} - - - - - {646, 563} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - activityViewer - YES - - - - - - - activityWindow - - - - 11 - - - - window - - - - 15 - - - - activityTable - - - - 22 - - - - activityDetail - - - - 37 - - - - splitView - - - - 38 - - - - delegate - - - - 14 - - - - delegate - - - - 24 - - - - dataSource - - - - 32 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 8 - - - - - - Panel - - - 7 - - - - - - - - 36 - - - - - - - - - 16 - - - - - - - - - - - 17 - - - - - - - - - - 18 - - - - - - - - 19 - - - - - - - - 33 - - - - - - - - 34 - - - - - - - - - - 35 - - - - - 40 - - - - - 41 - - - - - 42 - - - - - 43 - - - - - 44 - - - - - 45 - - - - - 46 - - - - - 47 - - - - - -3 - - - Application - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - ExtendedTableView - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - ThinSplitView - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{278, 148}, {646, 563}} - - - - - - 47 - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - diff --git a/Interfaces/ActivityViewer.nib/keyedobjects.nib b/Interfaces/ActivityViewer.nib/keyedobjects.nib deleted file mode 100644 index 882151c2b0..0000000000 Binary files a/Interfaces/ActivityViewer.nib/keyedobjects.nib and /dev/null differ diff --git a/Interfaces/ActivityViewer.xib b/Interfaces/ActivityViewer.xib new file mode 100644 index 0000000000..7089491fca --- /dev/null +++ b/Interfaces/ActivityViewer.xib @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Interfaces/BrowserPane.nib/designable.nib b/Interfaces/BrowserPane.nib/designable.nib deleted file mode 100644 index 09e29ecc21..0000000000 --- a/Interfaces/BrowserPane.nib/designable.nib +++ /dev/null @@ -1,979 +0,0 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - 3084 - 2053 - - - NSBox - NSButton - NSButtonCell - NSCustomObject - NSCustomView - NSImageCell - NSImageView - NSTextField - NSTextFieldCell - WebView - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.WebKitIBPlugin - - - PluginDependencyRecalculationVersion - - - - - BrowserPaneTemplate - - - FirstResponder - - - NSApplication - - - - 286 - - - - 274 - - - - 274 - - - - 298 - - - - 10 - - {{0, -2}, {833, 5}} - - - - YES - {0, 0} - - 67108864 - 0 - Box - - LucidaGrande - 13 - 1044 - - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - 3 - 2 - 0 - NO - - - - -2147483383 - - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple PNG pasteboard type - NSFilenamesPboardType - NeXT Encapsulated PostScript v1.2 pasteboard type - NeXT TIFF v4.0 pasteboard type - - {{771, 6}, {16, 16}} - - - - YES - - 134217728 - 33554432 - - NSImage - lockedPage - - 0 - 0 - 0 - NO - - NO - YES - - - - 10 - - {{0, -4}, {833, 5}} - - - - YES - 0.82394367456436157 - {0, 0} - - 67108864 - 0 - Box - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - 3 - 2 - 0 - NO - - - - 268 - {{36, 4}, {27, 21}} - - - - YES - - 67108864 - 134217728 - - - LucidaGrande - 10 - 2843 - - - 138674176 - 6 - - NSImage - browserNextButton - - - - - - 200 - 25 - - NO - - - - 268 - {{63, 4}, {29, 21}} - - - - YES - - 67108864 - 134217728 - - - - 141836288 - 2 - - NSImage - browserRefreshButton - - - - 200 - 25 - - NO - - - - 268 - {{7, 4}, {29, 21}} - - - - YES - - 67108864 - 0 - - - - 141819904 - 6 - - NSImage - browserPreviousButton - - - - 200 - 25 - - NO - - - - 265 - {{794, 4}, {31, 21}} - - - - YES - - 67108864 - 134217728 - - - LucidaGrande - 10 - 16 - - - 138690560 - 2 - - NSImage - browserRSSButton - - - - 400 - 75 - - NO - - - - 268 - {{103, 7}, {14, 14}} - - - - YES - - 67108864 - 134217728 - - - - -2041823232 - 6 - - NSImage - webpage.tiff - - - - 400 - 75 - - NO - - - - 266 - {{99, 3}, {689, 22}} - - - - YES - - -1804599231 - 268469248 - - - - YES - - - 6 - System - textColor - - 3 - MAA - - - - NO - - - {{0, 544}, {833, 29}} - - - - GradientView - NSView - - - - 286 - - Apple HTML pasteboard type - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple URL pasteboard type - Apple Web Archive pasteboard type - NSColor pasteboard type - NSFilenamesPboardType - NSStringPboardType - NeXT RTFD pasteboard type - NeXT Rich Text Format v1.0 pasteboard type - NeXT TIFF v4.0 pasteboard type - WebURLsWithTitlesPboardType - public.png - public.url - public.url-name - - {831, 544} - - - - - - - - - - - - - - YES - YES - - - {{1, 1}, {831, 573}} - - - - - - {833, 575} - - - - {0, 0} - - 67108864 - 0 - Title - - LucidaGrande - 11 - 16 - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - - 1 - 3 - 0 - NO - - - {833, 575} - - - - BrowserPane - NSView - - - - - - - browserPane - - - - 16 - - - - webPane - - - - 10 - - - - addressField - - - - 13 - - - - boxFrame - - - - 19 - - - - handleAddress: - - - - 22 - - - - handleReload: - - - - 26 - - - - handleGoBack: - - - - 27 - - - - handleGoForward: - - - - 28 - - - - refreshButton - - - - 31 - - - - backButton - - - - 32 - - - - forwardButton - - - - 33 - - - - lockIconImage - - - - 35 - - - - iconImage - - - - 42 - - - - rssPageButton - - - - 52 - - - - handleRSSPage: - - - - 53 - - - - nextKeyView - - - - 21 - - - - selectText: - - - - 41 - - - - enabled: canGoBack - - - - - - enabled: canGoBack - enabled - canGoBack - 2 - - - 36 - - - - enabled: canGoForward - - - - - - enabled: canGoForward - enabled - canGoForward - 2 - - - 37 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 5 - - - - - - BrowserPaneView - - - 17 - - - - - - - - - -3 - - - Application - - - 48 - - - - - - - - - - - - - - - - 9 - - - - - 8 - - - - - - - - 55 - - - - - 50 - - - - - - - - 61 - - - - - 24 - - - - - - - - 57 - - - - - 62 - - - - - 23 - - - - - - - - 56 - - - - - 25 - - - - - - - - 58 - - - - - 34 - - - - - - - - 59 - - - - - 40 - - - - - - - - 60 - - - - - 63 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - BrowserPaneButton - com.apple.InterfaceBuilder.CocoaPlugin - BrowserPaneButton - com.apple.InterfaceBuilder.CocoaPlugin - BrowserPaneButton - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - BrowserPaneButton - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - SSTextField - com.apple.InterfaceBuilder.CocoaPlugin - TabbedWebView - com.apple.WebKitIBPlugin - - - - - - 64 - - - - - BrowserPane - NSView - - id - id - id - id - id - - - - handleAddress: - id - - - handleGoBack: - id - - - handleGoForward: - id - - - handleRSSPage: - id - - - handleReload: - id - - - - SSTextField - NSButton - NSBox - NSButton - NSButton - NSImageView - NSButton - NSButton - NSView - TabbedWebView - - - - addressField - SSTextField - - - backButton - NSButton - - - boxFrame - NSBox - - - forwardButton - NSButton - - - iconImage - NSButton - - - lockIconImage - NSImageView - - - refreshButton - NSButton - - - rssPageButton - NSButton - - - viewwwer - NSView - - - webPane - TabbedWebView - - - - IBProjectSource - ./Classes/BrowserPane.h - - - - BrowserPaneButton - NSButton - - IBProjectSource - ./Classes/BrowserPaneButton.h - - - - BrowserPaneTemplate - NSWindowController - - browserPane - BrowserPane - - - browserPane - - browserPane - BrowserPane - - - - IBProjectSource - ./Classes/BrowserPaneTemplate.h - - - - GradientView - NSView - - IBProjectSource - ./Classes/GradientView.h - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - SSTextField - NSTextField - - IBProjectSource - ./Classes/SSTextField.h - - - - TabbedWebView - WebView - - IBProjectSource - ./Classes/TabbedWebView.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {27, 21} - {29, 21} - {31, 21} - {29, 21} - {16, 16} - {128, 128} - - - diff --git a/Interfaces/BrowserPane.nib/keyedobjects.nib b/Interfaces/BrowserPane.nib/keyedobjects.nib deleted file mode 100644 index bbed43f1e0..0000000000 Binary files a/Interfaces/BrowserPane.nib/keyedobjects.nib and /dev/null differ diff --git a/Interfaces/BrowserPane.xib b/Interfaces/BrowserPane.xib new file mode 100644 index 0000000000..403e662f49 --- /dev/null +++ b/Interfaces/BrowserPane.xib @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Interfaces/Downloads.nib/designable.nib b/Interfaces/Downloads.nib/designable.nib deleted file mode 100644 index 07806aa21e..0000000000 --- a/Interfaces/Downloads.nib/designable.nib +++ /dev/null @@ -1,523 +0,0 @@ - - - - 1050 - 14B25 - 6254 - 1343.16 - 755.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 6254 - - - NSBox - NSButton - NSButtonCell - NSCustomObject - NSScrollView - NSScroller - NSTableColumn - NSTableView - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - DownloadWindow - - - FirstResponder - - - NSApplication - - - 4367 - 2 - {{827, 444}, {315, 412}} - 1886912512 - Downloads (Do not localise) - NSWindow - - View - - - {213, 107} - - - 256 - - - - 274 - - - - 2322 - - - - 256 - {315, 386} - - YES - NO - YES - - - 256 - {{299, 0}, {16, 17}} - - - - listColumn - 312 - 8 - 1000 - - 75497536 - 2048 - - - YES - 11 - 3100 - - - 3 - MC4zMzMzMzI5ODU2AA - - - 6 - System - headerTextColor - - 3 - MAA - - - - - 337641536 - 2048 - - YES - 13 - 1044 - - - - 6 - System - controlBackgroundColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - - - 1 - YES - - - - 3 - 2 - - 3 - MQA - - - 6 - System - gridColor - - 3 - MC41AA - - - 38 - 314572800 - - - 4 - 15 - 0 - YES - 0 - 1 - - - {{1, 1}, {315, 386}} - - - - - 4 - YES - - - - -2147483392 - {{-30, 1}, {15, 388}} - - NO - _doScroller: - - - _doScroller: - 0.93250000476837158 - - - - -2147483392 - {{-100, -100}, {298, 15}} - - NO - _doScroller: - - 1 - - _doScroller: - 0.9496644139289856 - - - {{-1, 25}, {317, 388}} - - - 133650 - - - - AAAAAAAAAABCIAAAQiAAAA - 0.25 - 4 - 1 - - - - 256 - {{5, 2}, {57, 20}} - - YES - - 67108864 - 134348800 - Clear - - - -2038022144 - 32 - - LucidaGrande - 11 - 16 - - - - 400 - 75 - - NO - - - - 258 - - {{0, 21}, {315, 5}} - - YES - 0.5 - - - - - - YES - - - {0, 0} - - 67108864 - 0 - Box - - - 6 - System - textBackgroundColor - - - - 6 - System - labelColor - - - - 3 - 2 - 0 - NO - - - - 258 - - {{0, 22}, {315, 5}} - - YES - 0.19014084339141846 - {0, 0} - - 67108864 - 0 - Box - - - - - 3 - 2 - 0 - NO - - - {315, 412} - - {{0, 0}, {1920, 1057}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - - - - table - - - - 11 - - - - clearList: - - - - 14 - - - - clearButton - - - - 15 - - - - downloadWindow - - - - 20 - - - - window - - - - 21 - - - - dataSource - - - - 18 - - - - delegate - - - - 19 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 5 - - - - - - Window - - - 6 - - - - - - - - - - - 7 - - - - - - - - - - 8 - - - - - - - - 9 - - - - - - - - 13 - - - - - - - - 23 - - - - - 24 - - - - - 25 - - - - - 26 - - - - - -3 - - - Application - - - 28 - - - - - 29 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{247, 234}, {315, 412}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - ExtendedTableView - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 29 - - - 0 - IBCocoaFramework - NO - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - diff --git a/Interfaces/Downloads.nib/keyedobjects.nib b/Interfaces/Downloads.nib/keyedobjects.nib deleted file mode 100644 index 4ac8629232..0000000000 Binary files a/Interfaces/Downloads.nib/keyedobjects.nib and /dev/null differ diff --git a/Interfaces/Downloads.xib b/Interfaces/Downloads.xib new file mode 100644 index 0000000000..089f45ffa2 --- /dev/null +++ b/Interfaces/Downloads.xib @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Interfaces/MainMenu.nib/designable.nib b/Interfaces/MainMenu.nib/designable.nib deleted file mode 100644 index f95d67151f..0000000000 --- a/Interfaces/MainMenu.nib/designable.nib +++ /dev/null @@ -1,1258 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Cg - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -CA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -CA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Filter by: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Interfaces/MainMenu.nib/keyedobjects.nib b/Interfaces/MainMenu.nib/keyedobjects.nib deleted file mode 100644 index a6682f0eb1..0000000000 Binary files a/Interfaces/MainMenu.nib/keyedobjects.nib and /dev/null differ diff --git a/Interfaces/MainMenu.xib b/Interfaces/MainMenu.xib new file mode 100644 index 0000000000..f9f02a1108 --- /dev/null +++ b/Interfaces/MainMenu.xib @@ -0,0 +1,1272 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Cg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +CA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +CA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Filter by: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Interfaces/Preferences/de.lproj/AdvancedPreferencesView.strings b/Interfaces/Preferences/de.lproj/AdvancedPreferencesView.strings index 7f6eb5762c..0cc7f901e7 100644 Binary files a/Interfaces/Preferences/de.lproj/AdvancedPreferencesView.strings and b/Interfaces/Preferences/de.lproj/AdvancedPreferencesView.strings differ diff --git a/Interfaces/Preferences/de.lproj/AdvancedPreferencesView.xib b/Interfaces/Preferences/de.lproj/AdvancedPreferencesView.xib index 7eded54e92..0e0fa1a873 100644 --- a/Interfaces/Preferences/de.lproj/AdvancedPreferencesView.xib +++ b/Interfaces/Preferences/de.lproj/AdvancedPreferencesView.xib @@ -1,8 +1,8 @@ - + - + @@ -16,7 +16,7 @@ - + @@ -70,7 +70,7 @@ - + diff --git a/Interfaces/Preferences/de.lproj/GeneralPreferencesView.strings b/Interfaces/Preferences/de.lproj/GeneralPreferencesView.strings index 7a06a74edd..47cfe6fa2f 100644 Binary files a/Interfaces/Preferences/de.lproj/GeneralPreferencesView.strings and b/Interfaces/Preferences/de.lproj/GeneralPreferencesView.strings differ diff --git a/Interfaces/Preferences/de.lproj/GeneralPreferencesView.xib b/Interfaces/Preferences/de.lproj/GeneralPreferencesView.xib index 10858e1bb5..20826cd586 100644 --- a/Interfaces/Preferences/de.lproj/GeneralPreferencesView.xib +++ b/Interfaces/Preferences/de.lproj/GeneralPreferencesView.xib @@ -1,7 +1,8 @@ - + - + + @@ -83,7 +84,7 @@ + + + + + + + + + + + + + + + diff --git a/lproj/cs.lproj/GroupFolder.nib/keyedobjects.nib b/lproj/cs.lproj/GroupFolder.nib/keyedobjects.nib index 19589ab4e3..5bcd5be24f 100644 Binary files a/lproj/cs.lproj/GroupFolder.nib/keyedobjects.nib and b/lproj/cs.lproj/GroupFolder.nib/keyedobjects.nib differ diff --git a/lproj/cs.lproj/InfoPlist.strings b/lproj/cs.lproj/InfoPlist.strings deleted file mode 100644 index 4494f2ab03..0000000000 --- a/lproj/cs.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ -NSHumanReadableCopyright = "Copyright 2004-2015 přispěvatelé. Seznam přispěvatelů naleznete v nabídce Nápověda."; diff --git a/lproj/cs.lproj/Localizable.strings b/lproj/cs.lproj/Localizable.strings index 7170bdc6e6..e9ed2e0bda 100644 --- a/lproj/cs.lproj/Localizable.strings +++ b/lproj/cs.lproj/Localizable.strings @@ -450,3 +450,9 @@ /*Added in 3.0.5 */ "Redirection attempt treated as temporary for safety concern" = "Redirection attempt treated as temporary for safety concern"; + +/*Added in 3.0.7 */ +"No articles in feed" = "No articles in feed"; + +/*Added in 3.1.2 */ +"Filter folders" = "Search for folders"; diff --git a/lproj/cs.lproj/RSSFeed.nib/designable.nib b/lproj/cs.lproj/RSSFeed.nib/designable.nib index 62229a14de..ea09f00a3b 100644 --- a/lproj/cs.lproj/RSSFeed.nib/designable.nib +++ b/lproj/cs.lproj/RSSFeed.nib/designable.nib @@ -1,1037 +1,216 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSMenu - NSMenuItem - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSUserDefaultsController - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - RSSFeed - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{165, 318}, {426, 291}} - 1886912512 - Zdroj RSS - NSPanel - - View - - - {426, 267} - - - 256 - - - - 256 - {{210, 13}, {101, 32}} - - - - YES - - 67108864 - 134217728 - Zrušit - - LucidaGrande - 13 - 1044 - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{311, 13}, {101, 32}} - - - 100 - YES - - 67108864 - 134217728 - Odebírat - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{20, 189}, {42, 17}} - - - - YES - - 67108864 - 71303168 - Zdroj: - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 256 - {{64, 183}, {210, 26}} - - - - YES - - -2080374720 - 1024 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - URL - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - 100 - - - YES - - - OtherViews - - - - - - 3 - YES - YES - 1 - - NO - - - - 256 - {{20, 258}, {389, 17}} - - - - YES - - 67108864 - 4194304 - Vytvořit nové odebírání - - LucidaGrande-Bold - 13 - 2072 - - - - - - NO - - - - 256 - {{20, 216}, {386, 34}} - - - - YES - - 67108864 - 4194304 - Níže zadejte adresu novinek, které chcete odebírat, nebo vyberte ze seznamu zdroj novinek a zadejte jméno uživatele dané služby. - - LucidaGrande - 10 - 2843 - - - - - - NO - - - - 256 - {{23, 84}, {386, 62}} - - - - YES - - -1805647871 - 4325376 - - - LucidaGrande - 11 - 3100 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 256 - {{283, 183}, {21, 24}} - - - - YES - - 67108864 - 134217728 - - - - -2038284288 - 33 - - - - - - 200 - 25 - - NO - - - - 256 - {{21, 154}, {389, 17}} - - - - YES - - 67108864 - 4194304 - URL: - - - - - - NO - - - - 268 - {{21, 46}, {185, 18}} - - - - YES - - -2080374784 - 0 - Subscribe in Open Reader - - - 1211912448 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - NO - - - {426, 291} - - - - - {{0, 0}, {1280, 778}} - {426, 289} - {10000000000000, 10000000000000} - YES - - - 3 - 2 - {{167, 255}, {423, 163}} - 1886912512 - Zdroj RSS - NSPanel - - View - - - {423, 163} - - - 256 - - - - 256 - {{318, 12}, {91, 32}} - - 100 - YES - - 67108864 - 134217728 - Uložit - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{227, 12}, {91, 32}} - - - YES - - 67108864 - 134217728 - Zrušit - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{20, 60}, {383, 62}} - - - YES - - -1805647871 - 4325376 - - - - YES - - - - NO - - - - 256 - {{17, 130}, {389, 17}} - - - YES - - 67108864 - 4194304 - Upravit odebírání - - - - - - NO - - - {{1, 9}, {423, 163}} - - - {{0, 0}, {1280, 778}} - {423, 185} - {10000000000000, 10000000000000} - YES - - - YES - - - - - - - window - - - - 14 - - - - doSubscribe: - - - - 37 - - - - feedSource - - - - 46 - - - - subscribeButton - - - - 48 - - - - doSave: - - - - 57 - - - - editRSSFeedWindow - - - - 61 - - - - newRSSFeedWindow - - - - 62 - - - - editFeedURL - - - - 69 - - - - saveButton - - - - 70 - - - - editCancelButton - - - - 74 - - - - subscribeCancelButton - - - - 76 - - - - doEditCancel: - - - - 77 - - - - doSubscribeCancel: - - - - 78 - - - - doLinkSourceChanged: - - - - 89 - - - - feedURL - - - - 91 - - - - doShowSiteHomePage: - - - - 93 - - - - siteHomePageButton - - - - 94 - - - - linkTitle - - - - 99 - - - - doGoogleOption: - - - - 118 - - - - googleOptionButton - - - - 119 - - - - value: googleOptionButton - - - - - - value: googleOptionButton - value - googleOptionButton - 2 - - - 117 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - NewRSSFeed - - - 5 - - - - - - - - - - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 40 - - - - - - - - 43 - - - - - - - - 64 - - - - - - - - 65 - - - - - - - - 90 - - - - - - - - 92 - - - - - - - - 97 - - - - - - - - 49 - - - - - - EditRSSFeed - - - 50 - - - - - - - - - - - 53 - - - - - - - - 54 - - - - - - - - 55 - - - - - - - - 67 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - 107 - - - - - 108 - - - - - 109 - - - - - 110 - - - - - 111 - - - - - 112 - - - - - 113 - - - - - 114 - - - - - 44 - - - - - - - - 45 - - - - - -3 - - - Application - - - 115 - - - - - - - - 116 - - - - - 120 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{1012, 565}, {429, 297}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 122 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - {15, 15} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Níže zadejte adresu novinek, které chcete odebírat, nebo vyberte ze seznamu zdroj novinek a zadejte jméno uživatele dané služby. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/cs.lproj/RSSFeed.nib/keyedobjects.nib b/lproj/cs.lproj/RSSFeed.nib/keyedobjects.nib index 198dd357dc..af579e3f4a 100644 Binary files a/lproj/cs.lproj/RSSFeed.nib/keyedobjects.nib and b/lproj/cs.lproj/RSSFeed.nib/keyedobjects.nib differ diff --git a/lproj/cs.lproj/SearchFolder.nib/designable.nib b/lproj/cs.lproj/SearchFolder.nib/designable.nib index 77902600c9..c7a243c6b6 100644 --- a/lproj/cs.lproj/SearchFolder.nib/designable.nib +++ b/lproj/cs.lproj/SearchFolder.nib/designable.nib @@ -1,1590 +1,263 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSBox - NSButton - NSButtonCell - NSCustomObject - NSCustomView - NSMenu - NSMenuItem - NSNumberFormatter - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - SmartFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{133, 455}, {647, 186}} - 1886912512 - - NSPanel - - View - - - {213, 107} - - - 256 - - - - 268 - {{17, 150}, {164, 17}} - - YES - - 67108864 - 4194304 - Jméno dynamické složky: - - LucidaGrande - 13 - 1044 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 268 - {{186, 148}, {206, 22}} - - YES - - -1804599231 - 4195328 - - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{547, 12}, {86, 32}} - - YES - - 67108864 - 134217728 - Uložit - - - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{461, 12}, {86, 32}} - - YES - - 67108864 - 134217728 - Zrušit - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 274 - - - - 274 - - - - 274 - {{12, 6}, {584, 38}} - - - NSView - - NSResponder - - - {{2, 2}, {609, 50}} - - - - {{17, 56}, {613, 54}} - - {0, 0} - - 67108864 - 0 - - - LucidaGrande - 11 - 3100 - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 3 - 0 - 0 - NO - - - - 268 - {{17, 118}, {202, 17}} - - YES - - 67108864 - 4194304 - Zobrazit příspěvky odpovídající - - - - - - NO - - - - 268 - {{221, 112}, {120, 26}} - - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - Nic - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - 268 - {{343, 118}, {287, 17}} - - YES - - 67108864 - 272629760 - následujícím shodám: - - - - - - NO - - - {647, 186} - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - 256 - - - - 256 - {{-1, 0}, {150, 26}} - - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Zde budou textová pole - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - 256 - {{513, -3}, {32, 31}} - - - YES - - 67108864 - 134479872 - - - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{302, 3}, {183, 22}} - - - YES - - -1804599231 - 4195328 - - - - YES - - - - NO - - - - 256 - {{541, -3}, {32, 31}} - - - YES - - 67108864 - 134479872 - + - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{151, 0}, {135, 26}} - - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Zde budou operátory - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{299, 0}, {100, 26}} - - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - - - 400 - 75 - - - Nic - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{302, 4}, {126, 22}} - - - YES - - -1804599231 - 4195328 - - - - - - - - - NaN - - - - 0 - - - . - - , - - - - - 0 - 2 - NO - YES - 1 - P0IPAAAAAAAAAAAAAAAAAA - - - 0 - 1 - NO - YES - 1 - AQAAAAAAAAAAAAAAAAAAAA - - -0 - 0 - - - 0 - -0 - - - - - - - - - . - , - NO - NO - YES - - - YES - - - - NO - - - - -2147483392 - {{299, 0}, {189, 26}} - - - 1008 - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Item2 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - Item3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{299, 0}, {189, 26}} - - - 1004 - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Item1 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - Item2 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - Item3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - -1 - 3 - YES - YES - 1 - - NO - - - {572, 28} - - - - NSView - - NSResponder - - - - - - - cancelButton - - - - 40 - - - - saveButton - - - - 41 - - - - searchCriteriaView - - - - 43 - - - - removeCriteriaButton - - - - 44 - - - - addCriteriaButton - - - - 45 - - - - fieldNamePopup - - - - 46 - - - - operatorPopup - - - - 47 - - - - valueField - - - - 49 - - - - window - - - - 50 - - - - addNewCriteria: - - - - 51 - - - - doCancel: - - - - 52 - - - - doSave: - - - - 53 - - - - searchWindow - - - - 54 - - - - removeCurrentCriteria: - - - - 57 - - - - fieldChanged: - - - - 59 - - - - flagValueField - - - - 65 - - - - numberValueField - - - - 70 - - - - folderValueField - - - - 78 - - - - criteriaConditionPopup - - - - 85 - - - - dateValueField - - - - 91 - - - - smartFolderName - - - - 92 - - - - searchCriteriaSuperview - - - - 42 - - - - nextKeyView - - - - 72 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - Search Folder - - - 5 - - - - - - - - - - - - - - - 7 - - - - - - - - 8 - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 37 - - - - - - - - 58 - - - - - - - - 79 - - - - - - - - 84 - - - - - - - - 26 - - - - - - - - - - - - - - SearchCriteriaView - - - 27 - - - - - - - - 29 - - - - - - - - 30 - - - - - - - - 31 - - - - - - - - 35 - - - - - - - - 61 - - - - - - - - 69 - - - - - - - - 73 - - - - - - - - 86 - - - - - - - - 94 - - - - - 95 - - - - - 96 - - - - - 97 - - - - - 98 - - - - - 99 - - - - - - - - 100 - - - - - 101 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - - - - 107 - - - - - - - - 108 - - - - - - - - 109 - - - - - - - - 71 - - - - - 80 - - - - - - - - 82 - - - - - 32 - - - - - - - - 33 - - - - - 34 - - - - - - - - 56 - - - - - 64 - - - - - - - - 62 - - - - - 74 - - - - - - - - - 76 - - - - - 75 - - - - - 87 - - - - - - - - - - 90 - - - - - 89 - - - - - 88 - - - - - -3 - - - Application - - - 36 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 109 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - SmartFolder - NSWindowController - - id - id - id - id - id - - - - addNewCriteria: - id - - - doCancel: - id - - - doSave: - id - - - fieldChanged: - id - - - removeCurrentCriteria: - id - - - - NSButton - NSButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSTextField - NSPopUpButton - NSButton - NSButton - NSView - NSView - NSWindow - NSTextField - NSTextField - - - - addCriteriaButton - NSButton - - - cancelButton - NSButton - - - criteriaConditionPopup - NSPopUpButton - - - dateValueField - NSPopUpButton - - - fieldNamePopup - NSPopUpButton - - - flagValueField - NSPopUpButton - - - folderValueField - NSPopUpButton - - - numberValueField - NSTextField - - - operatorPopup - NSPopUpButton - - - removeCriteriaButton - NSButton - - - saveButton - NSButton - - - searchCriteriaSuperview - NSView - - - searchCriteriaView - NSView - - - searchWindow - NSWindow - - - smartFolderName - NSTextField - - - valueField - NSTextField - - - - IBProjectSource - ./Classes/SmartFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/cs.lproj/SearchFolder.nib/keyedobjects.nib b/lproj/cs.lproj/SearchFolder.nib/keyedobjects.nib index 45097b1718..0356217353 100644 Binary files a/lproj/cs.lproj/SearchFolder.nib/keyedobjects.nib and b/lproj/cs.lproj/SearchFolder.nib/keyedobjects.nib differ diff --git a/lproj/cs.lproj/Vienna Help/advanced.html b/lproj/cs.lproj/Vienna Help/advanced.html deleted file mode 100644 index 3a189b180f..0000000000 --- a/lproj/cs.lproj/Vienna Help/advanced.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - Advanced Settings - - - -  Advanced Settings -

The Advanced section of the Preferences provides options to change very specific settings in Vienna that are -not essential for normal use but may resolve some issues as advised by the support forum. This page details the -advanced settings and their function. -

-

Enable JavaScript in internal browser

-

Enables or disables support for JavaScript scripting in the Vienna internal browser. By default this is enabled. By -turning this setting off, JavaScript code on web pages will not be allowed to run. This may resolve problems with pages -that use scripting to pop up windows or other unexpected behaviour but turning the setting off may also cause some web -pages to appear incomplete or fail to function correctly.

- - diff --git a/lproj/cs.lproj/Vienna Help/faq.html b/lproj/cs.lproj/Vienna Help/faq.html deleted file mode 100644 index 1d1fd51d0e..0000000000 --- a/lproj/cs.lproj/Vienna Help/faq.html +++ /dev/null @@ -1,191 +0,0 @@ - - - - - How Do I? - - - -  How Do I? -

Below are some of the more common questions asked about Vienna while it was being pre-release tested. -See the Official Vienna FAQ Page for these -and the latest hints and tips for using Vienna. -

- -

Where do I get the -Vienna source code?

-

See the Development page for -instructions for getting the source code for Vienna. The source code is -freely available if you're interested in learning how Vienna works, if -you want to build your own copy of Vienna from scratch on your own -machine or if you want to borrow portions for inclusion in your own -project. The source is provided under the -Apache 2.0 -license.

-

I found -a problem with Vienna. How do I report it?

-

Post a message over in the -Support forum and somebody will -investigate. Provide as much information about the problem as you can -including: the build of Vienna (obtained from the About Vienna panel), -repro steps and what you expected to happen. There is a sticky note in -the forum with tips on how to write a good bug report.

- -

Make sure you're always running the most recent build of Vienna. The -Check for Updates command will report if there's a newer build available -than the one you have.

-

Fixes for bugs take priority over new features so if your problem is -confirmed to be a bug with high impact and no simple workaround then -I'll look at making a fix available as soon as reasonably possible.

-

How do I create my own -styles?

-

See the Custom Styles page for -instructions.

-

How do I create my own -scripts?

- -

Vienna's scripts are written using AppleScript. See the - -Apple resource page for more details.

-

One way to get started is to download one of the existing scripts -from the Vienna Downloads page and view -it in the AppleScript editor.

- -

To submit your own script, send it to -steve@opencommunity.co.uk -and after it has been reviewed, it will be made available on the -Downloads page.

-

- -How can I see what happened when my subscriptions are refreshed?

-

Open the Activity Window from the Window menu. The activity window -shows all subscriptions and the status of the last time they were -refreshed in that session. The bottom of the activity window shows more -details include the HTTP headers and may be useful for debugging. (If -the details pane is not visible, grab the split bar at the bottom of the -Activity Window and drag it up to uncover the pane).

-

How do -I move my Vienna database to another folder?

- -

By default, your Vienna database is the messages.db file which is -located at ~/Library/Application Support/Vienna. You can move this to -another folder if you wish. The following steps show how:

-
    -
  1. Shut down Vienna.
  2. -
  3. Open a console window and enter:
    -
    -defaults write uk.co.opencommunity.vienna2 -"DefaultDatabase" '<path to new messages.db>'
    - -
    -where <path to new messages.db> is the name of the folder that -contains the messages.db file. The path itself should have the -messages.db filename at the end. For example:
    -
    -defaults write uk.co.opencommunity.vienna2 -"DefaultDatabase" '/Users/steve/mydata/messages.db'
    -
  4. - -
  5. Restart Vienna.
  6. -
-

- -One of my subscriptions reports "Error parsing XML data in feed". What -does this mean?

-

It means that Vienna got a feed back from the subscription that it -couldn't interpret. There are several reasons for this:

- -
    -
  1. The URL of the feed may not be pointing to an RSS or Atom feed -but to a web page. Check the URL of the offending feed carefully.
  2. -
  3. The feed itself may contain malformed XML. Some subscriptions -make a mistake in putting together the XML that makes up the feed -and Vienna cannot interpret malformed XML. Use the Validate Feed -command on the File menu to see if this is the case. Unfortunately -you cannot do much about this in Vienna except wait for the feed -itself to be corrected by the site.
  4. -
  5. The feed may be incomplete. If the refresh was interrupted then -the XML data will be incomplete and will appear malformed in Vienna. -A second refresh may correct this problem.
  6. -
-

If none of the above explain the problem, post a message on the -support forum with the URL of the feed exhibiting the problem.

-

- - -Is there a shortcut key for going to the next article, marking read, -etc?

-

Probably. There are single key equivalents for some of the menu -commands such as:

-

Spacebar - goes to the next unread article. If the current article is -several pages long, it will scroll through that article first. If you're -at the end of the current article it will then go to the next unread -article. By contrast the Next Unread command (Cmd+U) always goes -straight to the next unread article.

-

R - marks the current article read if it is unread, or unread if it -is read.

-

F - flags the current article if it isn't already flagged, or removes -the existing flag if it is not.

- -

Look in the Vienna Help file for more shortcuts.

- -

What do -the green dots mean in the list of articles?

-

The blue dots are for new articles, and the green dots are for updated articles: -articles whose text has changed since they were last downloaded.

- -

How do I use -Auto Expire and what does it do?

-

Auto-expire moves articles older than a certain number of days to the -Trash folder. It allows you to keep your folders manageable by only -retaining articles that are recent. The auto-expire runs both when -Vienna starts and after you have refreshed any subscriptions. To control -the age of articles to auto-expire, change the -"Move articles to Trash" option in Preferences.

-

Auto-expire will NOT remove unread or flagged articles. It assumes -that you haven't read these articles and thus leaves them alone.

-

How do I request -an enhancement in Vienna?

- -

Post a message over at the -support forum. All -requested enhancements are logged in the TODO file that is included with -the source code as a guidance for future developers.

- - diff --git a/lproj/cs.lproj/Vienna Help/index.html b/lproj/cs.lproj/Vienna Help/index.html deleted file mode 100644 index eb45f50f14..0000000000 --- a/lproj/cs.lproj/Vienna Help/index.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - Vienna Help - - - - - - - - - - -
-

-

Vienna Help

-
- - -

Introduction to Vienna

-

Learn how to get started with Vienna.

- -

Keyboard Shortcuts

-

Discover keyboard shortcuts for common commands

- -

How Do I?

-

Frequently Asked Questions, getting support and troubleshooting steps.

-
- - diff --git a/lproj/cs.lproj/Vienna Help/intro.html b/lproj/cs.lproj/Vienna Help/intro.html deleted file mode 100644 index 18eae3a50b..0000000000 --- a/lproj/cs.lproj/Vienna Help/intro.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - - Introduction to Vienna - - - -   -Introduction to Vienna -

Vienna is an application that allows you to read RSS or Atom news feeds on your Mac OS X computer. It automates the -job of retrieving news articles from all subscribed feeds and storing them in a local database for reading off-line. It -provides features that allow you to search feeds for keywords or phrases, tag articles with a flag for future reference -and organise related feeds together under groups. You can create smart folders that make it easy to dynamically retrieve -and view all articles in the database that match a search criteria. The built-in web browser allows you to go to the -articles web page or view links in the article directly in Vienna in separate tabs.

-

Vienna is designed to be simple and easy to use. A clean, uncluttered, interface maximises the space for articles and -just a few controls are needed to perform the most common actions in the user interface.

-Getting Started -

If this is the first time that you have used Vienna then it will have created a new database for you -and added some sample news subscriptions. So go ahead and press Command+R or choose Refresh All Subscriptions -from the File menu to grab the latest articles from those subscriptions.

-

Alternatively, subscribe to your own news feeds. There are various ways to find feeds. When browsing -the web, look out for the RSS feed icon or XML icons indicating that the page has a feed associated -with it. Alternatively almost all online blogging services such as LiveJournal or Blogger provide RSS feeds as -an alternative to reading the postings online.

-

If you know the user name of a blogger on LiveJournal, Blogger, MSN Spaces or Xanga then Vienna makes it easier -to subscribe to their news feed. Start by pressing Command+N or from the File menu, choose the New Subscription command. -In the "Create a new RSS subscription" panel, pick the blogging service from the drop down list and enter the -user name in the input field below. Then choose Subscribe and Vienna will add the subscription to the folder list. If -you are connected to the internet at the time, it will also immediately start collecting articles from the feed.

-

Normally you need to manually tell Vienna when to refresh all your subscriptions. However you can opt to ask Vienna -to automatically refresh at time intervals. In the General section of the Preferences, pick the desired time interval -from the drop down list next to 'Check for new articles'. Vienna needs to be running for it to automatically refresh -subscriptions.

-

To read articles, press the Spacebar to skip to the next unread article in any subscription. Each article is marked -as read automatically after a short delay. If you prefer to wait until you move to the next unread article before the -current one is marked read you can adjust the behaviour in the General tab of the Preferences. To mark an article as -unread again, choose the Mark Unread command from the Article menu or simply press the 'R' key.

-

Finally, you can view the article web page or any web page links in an article within Vienna. By default clicking -on a web link within Vienna will open the web page in a new tab. Vienna provides a lot of basic web browsing support -itself but there may be times when you will prefer to open links in your default web browser. If you prefer to view -all web pages outside of Vienna then enable the 'Open links in external browser' option in the General section of the -Preferences. However if you prefer to view the current link or page in your external browser, right click on the page -and choose the "Open Link in XXX" or "Open Page in XXX" option where XXX will be the name of your default browser.

-

Once you've got comfortable using Vienna, go ahead and explore the various options. You can change the style in -which the articles are displayed through the Style drop down list in the View menu. You can find many more custom -styles at the Downloads page on the Vienna web site along with custom scripts that allow you to integrate Vienna with -other applications on your machine. Or experiment with smart folders to organise articles according to criteria based -on the contents of each article. For example, you can easily set up a smart folder to group together all articles that -mention "Joss Whedon" and "Firefly" to find references to the Firefly cult series or the spin-off movie.

-

If you have any questions about Vienna or run into problems, head over to the -Support forum.

- - diff --git a/lproj/cs.lproj/Vienna Help/keyboard.html b/lproj/cs.lproj/Vienna Help/keyboard.html deleted file mode 100644 index a596a3dc0e..0000000000 --- a/lproj/cs.lproj/Vienna Help/keyboard.html +++ /dev/null @@ -1,224 +0,0 @@ - - - - - Keyboard Shortcuts - - - -  Keyboard Shortcuts -

You can use your keyboard to quickly accomplish many tasks in Vienna. To find the shortcuts for common commands, look in the menus -(or see the list at the bottom of this page). Many items in Vienna such as the folder pane and the article list pane also have contextual -menus. To see a contextual menu, press the Control key and click the item.

-

To do an action, press the shortcut keys indicated below.

- - - - - -
KeyAction
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Single Key Shortcuts -  
fSets the input focus to the search window.
rMarks the selected articles read.
sMarks the current folder read then skips to the next folder with unread articles.
kMarks the current folder read.
mFlags the selected articles.
<Displays the previous viewed article or web page.
>Displays the next viewed article or web page.
SpacebarMoves to the next unread article unless the current article has more text to scroll in which case it scrolls the current article up one page.
Enter/ReturnOpens the selected article's original web page.
Delete/BackspaceMoves the selected articles to the Trash folder. If this key is used in the Trash folder, the selected articles are permanently deleted.
General Shortcuts 
Alt-ClickOpen the clicked link, overriding your preference for opening links in external browser.
Command-NCreate a new subscription.
Shift-Command-FCreate a smart folder.
Shift-Command-EEdit the selected folder URL or edit a smart folder criteria.
Shift-Command-DDelete the selected folder.
Shift-Command-NRename the selected folder.
Command-RRefreshes all subscriptions.
Shift-Command-RRefresh only those subscriptions selected in the folder list.
Control-Command-SStops any active refresh.
Command-PPrint the selected articles.
Shift-Command-PBrings up the Page Setup panel.
Command-?Displays the Vienna help book.
Articles Shortcuts 
Alt-Enter/Alt-ReturnOpens the selected article's original web page, overriding your preference for opening links in external browser.
Command-UMoves to the next unread article.
Shift-Command-MFlags the selected articles.
Shift-Command-UMarks the selected articles read.
Shift-Command-SMarks the current folder read then skips to the next folder with unread articles.
Shift-Command-ORestores an article from the trash back to its original folder.
Shift-Command-KMarks all articles in the selected folders read.
Alt-Command-KMarks all articles in all folders read.
Window Shortcuts 
Command-WCloses the active tab window if one is open. Otherwise if no - tabs are open, this closes the Vienna window.
Alt-Command-WCloses all tab windows. Note that this command replaces the Close Tab - command on the File menu when the Alt key is held down.
Alt-Command-LeftDisplays the previous tab window.
Alt-Command-RightDisplays the next tab window.
Command-MMinimizes the Vienna window to the dock.
Command-0Displays the activity log viewer window.
Command-1Reopens the Vienna window if it was previously closed.
Command-2Displays the Downloads window.
Browser Window Shortcuts 
Alt-RReloads the current web page.
Command-PeriodCancels loading of the current web page.
Command-[/Command-LeftGoes back to the previous web page.
Command-]/Command-RightGoes forward to the next web page.
Command-FPuts the input focus in the search field. Entering some text here and - pressing Enter will search for that text on the current web page.
Command-GSearches for the next occurrence of the search text on the web page.
- - \ No newline at end of file diff --git a/lproj/da.lproj/AdvancedPreferencesView.nib/designable.nib b/lproj/da.lproj/AdvancedPreferencesView.nib/designable.nib new file mode 100644 index 0000000000..84977a2062 --- /dev/null +++ b/lproj/da.lproj/AdvancedPreferencesView.nib/designable.nib @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Indstillingerne her burde ikke skulle ændres til normal brug af Vienna. Referer til hjælpefilen for detaljerne for hver indstilling. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/da.lproj/AdvancedPreferencesView.nib/keyedobjects.nib b/lproj/da.lproj/AdvancedPreferencesView.nib/keyedobjects.nib new file mode 100644 index 0000000000..fe0fecaa96 Binary files /dev/null and b/lproj/da.lproj/AdvancedPreferencesView.nib/keyedobjects.nib differ diff --git a/lproj/da.lproj/AppearancePreferencesView.nib/designable.nib b/lproj/da.lproj/AppearancePreferencesView.nib/designable.nib new file mode 100644 index 0000000000..11f5d8491a --- /dev/null +++ b/lproj/da.lproj/AppearancePreferencesView.nib/designable.nib @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Artikelliste skrifttype: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/da.lproj/AppearancePreferencesView.nib/keyedobjects.nib b/lproj/da.lproj/AppearancePreferencesView.nib/keyedobjects.nib new file mode 100644 index 0000000000..3014ae49e5 Binary files /dev/null and b/lproj/da.lproj/AppearancePreferencesView.nib/keyedobjects.nib differ diff --git a/lproj/da.lproj/EmptyTrashWarning.nib/designable.nib b/lproj/da.lproj/EmptyTrashWarning.nib/designable.nib index 9145637639..1334f1ea2e 100644 --- a/lproj/da.lproj/EmptyTrashWarning.nib/designable.nib +++ b/lproj/da.lproj/EmptyTrashWarning.nib/designable.nib @@ -1,419 +1,81 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - EmptyTrashWarning - - - FirstResponder - - - NSApplication - - - 1 - 2 - {{274, 642}, {361, 152}} - 1886912512 - Empty Trash - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{228, 12}, {119, 32}} - - - YES - - -2080374784 - 134217728 - Empty Trash - - LucidaGrande - 13 - 1044 - - - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{61, 12}, {167, 32}} - - - YES - - -2080374784 - 134217728 - Don't Empty Trash - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{17, 82}, {327, 50}} - - - YES - - 67108928 - 272630784 - VGhlcmUgYXJlIGRlbGV0ZWQgYXJ0aWNsZXMgaW4gdGhlIHRyYXNoLgpXb3VsZCB5b3UgbGlrZSB0byBl -bXB0eSB0aGUgdHJhc2ggYmVmb3JlIHF1aXR0aW5nPw - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 256 - {{18, 58}, {223, 18}} - - - YES - - 67108864 - 0 - Do not show this warning again - - - 1211912448 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - NO - - - {361, 152} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - - - - doNotShowWarningAgain - - - - 12 - - - - doNotEmptyTrash: - - - - 13 - - - - emptyTrash: - - - - 14 - - - - window - - - - 15 - - - - initialFirstResponder - - - - 11 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 5 - - - - - - Window - - - 6 - - - - - - - - - - - 7 - - - - - - - - 8 - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 17 - - - - - 18 - - - - - 19 - - - - - 20 - - - - - -3 - - - Application - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 20 - - - - - EmptyTrashWarning - NSWindowController - - id - id - - - - doNotEmptyTrash: - id - - - emptyTrash: - id - - - - doNotShowWarningAgain - NSButton - - - doNotShowWarningAgain - - doNotShowWarningAgain - NSButton - - - - IBProjectSource - ./Classes/EmptyTrashWarning.h - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - NSSwitch - {15, 15} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Der er slettede artikler i Papirkurven. +Vil du tømme Papirkurven før du afslutter? + + + + + + + + + + + + + + + diff --git a/lproj/da.lproj/EmptyTrashWarning.nib/keyedobjects.nib b/lproj/da.lproj/EmptyTrashWarning.nib/keyedobjects.nib index d14831483a..3076cd7a5e 100644 Binary files a/lproj/da.lproj/EmptyTrashWarning.nib/keyedobjects.nib and b/lproj/da.lproj/EmptyTrashWarning.nib/keyedobjects.nib differ diff --git a/lproj/da.lproj/EmptyTrashWarning.strings b/lproj/da.lproj/EmptyTrashWarning.strings index c4640b023b..95a94dc02f 100644 Binary files a/lproj/da.lproj/EmptyTrashWarning.strings and b/lproj/da.lproj/EmptyTrashWarning.strings differ diff --git a/lproj/da.lproj/FeedCredentials.nib/designable.nib b/lproj/da.lproj/FeedCredentials.nib/designable.nib index c997ae7f44..1058bd5f88 100644 --- a/lproj/da.lproj/FeedCredentials.nib/designable.nib +++ b/lproj/da.lproj/FeedCredentials.nib/designable.nib @@ -1,8 +1,8 @@ - + - - + + @@ -17,8 +17,8 @@ - - + + @@ -51,8 +51,8 @@ - - + + @@ -60,8 +60,8 @@ - - + + @@ -69,8 +69,8 @@ - - + + @@ -81,8 +81,8 @@ - - + + @@ -133,4 +133,4 @@ Gw - \ No newline at end of file + diff --git a/lproj/da.lproj/FeedCredentials.nib/keyedobjects.nib b/lproj/da.lproj/FeedCredentials.nib/keyedobjects.nib index 96fceacfba..d30baa2f8c 100644 Binary files a/lproj/da.lproj/FeedCredentials.nib/keyedobjects.nib and b/lproj/da.lproj/FeedCredentials.nib/keyedobjects.nib differ diff --git a/lproj/da.lproj/FeedCredentials.strings b/lproj/da.lproj/FeedCredentials.strings index f922e128a4..d5e69367fe 100644 Binary files a/lproj/da.lproj/FeedCredentials.strings and b/lproj/da.lproj/FeedCredentials.strings differ diff --git a/lproj/da.lproj/GeneralPreferencesView.nib/designable.nib b/lproj/da.lproj/GeneralPreferencesView.nib/designable.nib new file mode 100644 index 0000000000..6bb570bf8a --- /dev/null +++ b/lproj/da.lproj/GeneralPreferencesView.nib/designable.nib @@ -0,0 +1,321 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/da.lproj/GeneralPreferencesView.nib/keyedobjects.nib b/lproj/da.lproj/GeneralPreferencesView.nib/keyedobjects.nib new file mode 100644 index 0000000000..1b454d304d Binary files /dev/null and b/lproj/da.lproj/GeneralPreferencesView.nib/keyedobjects.nib differ diff --git a/lproj/da.lproj/GroupFolder.nib/designable.nib b/lproj/da.lproj/GroupFolder.nib/designable.nib index f0b157af91..33fd2b16c7 100644 --- a/lproj/da.lproj/GroupFolder.nib/designable.nib +++ b/lproj/da.lproj/GroupFolder.nib/designable.nib @@ -1,502 +1,91 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - NewGroupFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{502, 622}, {388, 149}} - 1886912512 - - Panel - - - NSPanel - - - View - - - {213, 107} - - - 256 - - - - 260 - {{17, 112}, {354, 17}} - - - YES - - 67108864 - 4194304 - Ny gruppemappe - - LucidaGrande-Bold - 13 - 2072 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 258 - {{20, 60}, {348, 22}} - - - YES - - -1804599231 - 272630784 - - - LucidaGrande - 13 - 1044 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{285, 12}, {89, 32}} - - - 100 - YES - - 67108864 - 134217728 - Gem - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{203, 12}, {82, 32}} - - - YES - - 67108864 - 134217728 - Afbryd - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 268 - {{17, 90}, {353, 14}} - - - YES - - 67108864 - 4194304 - SW5kdGFzdCBncnVwcGVtYXBwZSBuYXZuZXQ6Cg - - LucidaGrande - 11 - 3100 - - - - - - NO - - - {388, 149} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - - - - newGroupFolderWindow - - - - 18 - - - - doCancel: - - - - 25 - - - - doSave: - - - - 26 - - - - folderName - - - - 27 - - - - cancelButton - - - - 28 - - - - saveButton - - - - 29 - - - - window - - - - 30 - - - - nextKeyView - - - - 24 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 5 - - - - - - GroupFolder - - - 6 - - - - - - - - - - - - 19 - - - - - - - - 20 - - - - - - - - 21 - - - - - - - - 22 - - - - - - - - 23 - - - - - - - - 32 - - - - - 33 - - - - - 34 - - - - - 35 - - - - - 36 - - - - - -3 - - - Application - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 36 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - NewGroupFolder - NSWindowController - - id - id - - - - doCancel: - id - - - doSave: - id - - - - NSButton - NSTextField - NSWindow - NSButton - - - - cancelButton - NSButton - - - folderName - NSTextField - - - newGroupFolderWindow - NSWindow - - - saveButton - NSButton - - - - IBProjectSource - ./Classes/NewGroupFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Indtast navn på gruppemappe: + + + + + + + + + + diff --git a/lproj/da.lproj/GroupFolder.nib/keyedobjects.nib b/lproj/da.lproj/GroupFolder.nib/keyedobjects.nib index 081f80a13f..4f4c3d2f43 100644 Binary files a/lproj/da.lproj/GroupFolder.nib/keyedobjects.nib and b/lproj/da.lproj/GroupFolder.nib/keyedobjects.nib differ diff --git a/lproj/da.lproj/GroupFolder.strings b/lproj/da.lproj/GroupFolder.strings index 645b139b9d..799e40e30a 100644 Binary files a/lproj/da.lproj/GroupFolder.strings and b/lproj/da.lproj/GroupFolder.strings differ diff --git a/lproj/da.lproj/InfoPlist.strings b/lproj/da.lproj/InfoPlist.strings deleted file mode 100644 index f7c8a6838b..0000000000 --- a/lproj/da.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ -NSHumanReadableCopyright = "Copyright 2004-2015 bidragsydere. Se Hjælp/Tak til for en liste over bidragsydere."; diff --git a/lproj/da.lproj/InfoWindow.nib/designable.nib b/lproj/da.lproj/InfoWindow.nib/designable.nib index 524d260ec3..89282eac3a 100644 --- a/lproj/da.lproj/InfoWindow.nib/designable.nib +++ b/lproj/da.lproj/InfoWindow.nib/designable.nib @@ -1,2633 +1,367 @@ - - - - 1060 - 13E28 - 940 - 1265.21 - 698.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 940 - - - YES - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - YES - - InfoWindow - - - FirstResponder - - - NSApplication - - - 7 - 2 - {{100, 100}, {270, 505}} - 1886912512 - Vindue - - NSWindow - - - View - - - {1.7976931348623157e+308, 1.7976931348623157e+308} - {270, 461} - - - 256 - - YES - - - 270 - {{43, 478}, {220, 17}} - - YES - - 69206081 - 272632320 - (Mappenavn) - - .LucidaGrandeUI-Bold - 13 - 2064 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - 1 - - - - 268 - {{43, 461}, {98, 14}} - - YES - - 67108864 - 272629760 - Sidst opdateret: - - .LucidaGrandeUI - 11 - 3088 - - - - - 6 - System - disabledControlTextColor - - 3 - MC4zMzMzMzMzMzMzAA - - - - NO - 1 - - - - 270 - {{130, 461}, {133, 14}} - - YES - - 67108928 - 272632320 - (Sidste opdateringsdato) - - - - - - NO - 1 - - - - 268 - - YES - - YES - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple PNG pasteboard type - NSFilenamesPboardType - NeXT Encapsulated PostScript v1.2 pasteboard type - NeXT TIFF v4.0 pasteboard type - - - {{15, 474}, {16, 16}} - - YES - - 0 - 33554432 - 0 - 0 - 0 - NO - - NO - YES - - - - 266 - - YES - - - 274 - {{10, 23}, {240, 58}} - - YES - - -1805647871 - 272760832 - - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - 1 - - - - 257 - {{140, -6}, {110, 28}} - - YES - - 67108864 - 134348800 - Valider - - - -2038284288 - 1 - - - - - - 200 - 25 - - NO - - - {{5, 139}, {250, 81}} - - SNDisclosableView - - - - 268 - {{5, 228}, {80, 18}} - - YES - - 67108864 - 0 - Feed URL: - - .LucidaGrandeUI - 13 - 1040 - - - -935575552 - 6 - - - 200 - 25 - - NO - - - - 266 - - YES - - - 256 - {{0, 61}, {69, 13}} - - YES - - 67108864 - 272629760 - Brugernavn: - - .LucidaGrandeUI - 10 - 2832 - - - - - - NO - 1 - - - - 256 - {{0, 39}, {69, 13}} - - YES - - 67108864 - 272629760 - S29kZW9yZDoKA - - - - - - NO - 1 - - - - 258 - {{72, 59}, {163, 19}} - - YES - - -1804599231 - 272761856 - - - - YES - - - - NO - 1 - - - - 258 - {{72, 36}, {163, 19}} - - YES - - -1804599231 - 272761856 - - - - YES - - - - NO - 1 - - - - 256 - {{86, 4}, {154, 28}} - - YES - - 67108864 - 134348800 - Opdater autorisering - - - -2038284288 - 1 - - LucidaGrande - 11 - 16 - - - - - - 200 - 25 - - NO - - - {{15, 22}, {235, 78}} - - SNDisclosableView - - - - 268 - {{5, 108}, {114, 18}} - - YES - - 67108864 - 0 - Autorisering: - - - -935575552 - 6 - - - 200 - 25 - - NO - - - - 266 - - YES - - - 256 - {{1, 63}, {62, 14}} - - YES - - 67108864 - 71434240 - Størrelse: - - - - - - NO - 1 - - - - 256 - {{17, 45}, {46, 14}} - - YES - - 67108864 - 71434240 - VWzDpnN0Ogo - - - - - - NO - 1 - - - - 256 - {{66, 63}, {80, 14}} - - YES - - 67108864 - 272629760 - Cg - - - - - - NO - 1 - - - - 256 - {{66, 45}, {80, 14}} - - YES - - 67108864 - 272629760 - Cg - - - - - - NO - 1 - - - - 256 - {{66, 21}, {113, 18}} - - YES - - 67108864 - 131072 - Abonneret - - - 1211912448 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - NO - - - - 256 - {{66, 0}, {156, 18}} - - YES - - 67108864 - 131072 - Load Full HTML Articles - - - 1211912448 - 2 - - - - 200 - 25 - - NO - - - {{15, 260}, {240, 77}} - - SNDisclosableView - - - - 268 - {{5, 345}, {80, 18}} - - YES - - 67108864 - 0 - Generelt: - - - -935575552 - 6 - - - 200 - 25 - - NO - - - - 266 - - YES - - - 274 - {{11, 0}, {242, 58}} - - YES - - 67108864 - 272629760 - - - - - - - NO - 1 - - - {{5, 369}, {250, 58}} - - SNDisclosableView - - - - 268 - {{5, 435}, {94, 18}} - - YES - - 67108864 - 0 - Beskrivelse: - - - -935575552 - 6 - - - 200 - 25 - - NO - - - - 258 - {{0, 453}, {270, 5}} - - {0, 0} - - 67108864 - 0 - Boks - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - 3 - 2 - 0 - NO - - - - 258 - {{0, 363}, {270, 5}} - - {0, 0} - - 67108864 - 0 - Boks - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - 3 - 2 - 0 - NO - - - - 258 - {{0, 249}, {270, 5}} - - {0, 0} - - 67108864 - 0 - Boks - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - 3 - 2 - 0 - NO - - - - 258 - {{0, 129}, {270, 5}} - - {0, 0} - - 67108864 - 0 - Boks - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - 3 - 2 - 0 - NO - - - {270, 505} - - {{0, 0}, {1920, 1178}} - {270, 483} - {1.7976931348623157e+308, 1.7976931348623157e+308} - YES - - - - - YES - - - window - - - - 14 - - - - toggleDisclosure: - - - - 39 - - - - urlField - - - - 40 - - - - folderName - - - - 41 - - - - folderImage - - - - 42 - - - - lastRefreshDate - - - - 43 - - - - toggleDisclosure: - - - - 46 - - - - username - - - - 55 - - - - password - - - - 56 - - - - nextKeyView - - - - 58 - - - - validateURL: - - - - 63 - - - - toggleDisclosure: - - - - 66 - - - - folderSize - - - - 71 - - - - folderUnread - - - - 72 - - - - isSubscribed - - - - 77 - - - - toggleDisclosure: - - - - 80 - - - - folderDescription - - - - 82 - - - - initialFirstResponder - - - - 83 - - - - nextKeyView - - - - 86 - - - - nextKeyView - - - - 87 - - - - urlFieldChanged: - - - - 88 - - - - subscribedChanged: - - - - 89 - - - - validateButton - - - - 90 - - - - nextKeyView - - - - 92 - - - - nextKeyView - - - - 93 - - - - authenticationChanged: - - - - 94 - - - - loadFullHTML - - - - 129 - - - - loadFullHTMLChanged: - - - - 130 - - - - nextKeyView - - - - 131 - - - - nextKeyView - - - - 132 - - - - - YES - - 0 - - YES - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 5 - - - YES - - - - Info Window - - - 6 - - - YES - - - - - - - - - - - - - - - - - - - - - 32 - - - YES - - - - - - 33 - - - YES - - - - - - 34 - - - YES - - - - - - 35 - - - YES - - - - - - 36 - - - YES - - - - - - - 37 - - - YES - - - - - - 62 - - - YES - - - - - - 38 - - - YES - - - - - - 44 - - - YES - - - - - - - - - - 51 - - - YES - - - - - - 52 - - - YES - - - - - - 53 - - - YES - - - - - - 54 - - - YES - - - - - - 91 - - - YES - - - - - - 45 - - - YES - - - - - - 64 - - - YES - - - - - - - - - - - 67 - - - YES - - - - - - 68 - - - YES - - - - - - 69 - - - YES - - - - - - 70 - - - YES - - - - - - 76 - - - YES - - - - - - 65 - - - YES - - - - - - 78 - - - YES - - - - - - 81 - - - YES - - - - - - 79 - - - YES - - - - - - 95 - - - YES - - - 256 - {{2, 2}, {125, 1}} - - - - - - 96 - - - - - 97 - - - YES - - - 256 - {{2, 2}, {125, 1}} - - - - - - 98 - - - - - 99 - - - YES - - - 256 - {{2, 2}, {125, 1}} - - - - - - 100 - - - - - 101 - - - YES - - - 256 - {{2, 2}, {125, 1}} - - - - - - 102 - - - - - 104 - - - - - 105 - - - - - 106 - - - - - 107 - - - - - 108 - - - - - 109 - - - - - 110 - - - - - 111 - - - - - 112 - - - - - 113 - - - - - 114 - - - - - 115 - - - - - 116 - - - - - 117 - - - - - 118 - - - - - 119 - - - - - 120 - - - - - 121 - - - - - 122 - - - - - 123 - - - - - 124 - - - - - -3 - - - Application - - - 125 - - - YES - - - - - - 126 - - - - - - - YES - - YES - -3.IBPluginDependency - 100.IBPluginDependency - 100.ImportedFromIB2 - 101.IBPluginDependency - 101.ImportedFromIB2 - 102.IBPluginDependency - 102.ImportedFromIB2 - 104.IBPluginDependency - 105.IBPluginDependency - 106.IBPluginDependency - 107.IBPluginDependency - 108.IBPluginDependency - 109.IBPluginDependency - 110.IBPluginDependency - 111.IBPluginDependency - 112.IBPluginDependency - 113.IBPluginDependency - 114.IBPluginDependency - 115.IBPluginDependency - 116.IBPluginDependency - 117.IBPluginDependency - 118.IBPluginDependency - 119.IBPluginDependency - 120.IBPluginDependency - 121.IBPluginDependency - 122.IBPluginDependency - 123.IBPluginDependency - 124.IBPluginDependency - 125.IBPluginDependency - 125.ImportedFromIB2 - 126.IBPluginDependency - 32.IBPluginDependency - 32.ImportedFromIB2 - 33.IBPluginDependency - 33.ImportedFromIB2 - 34.IBPluginDependency - 34.ImportedFromIB2 - 35.IBPluginDependency - 35.ImportedFromIB2 - 36.IBAttributePlaceholdersKey - 36.IBPluginDependency - 36.ImportedFromIB2 - 37.IBPluginDependency - 37.ImportedFromIB2 - 38.CustomClassName - 38.IBPluginDependency - 38.ImportedFromIB2 - 44.IBAttributePlaceholdersKey - 44.IBPluginDependency - 44.ImportedFromIB2 - 45.CustomClassName - 45.IBPluginDependency - 45.ImportedFromIB2 - 5.IBEditorWindowLastContentRect - 5.IBPluginDependency - 5.IBViewEditorWindowController.showingBoundsRectangles - 5.IBWindowTemplateEditedContentRect - 5.ImportedFromIB2 - 5.windowTemplate.hasMinSize - 5.windowTemplate.maxSize - 5.windowTemplate.minSize - 51.IBPluginDependency - 51.ImportedFromIB2 - 52.IBPluginDependency - 52.ImportedFromIB2 - 53.IBPluginDependency - 53.ImportedFromIB2 - 54.CustomClassName - 54.IBPluginDependency - 54.ImportedFromIB2 - 6.IBPluginDependency - 6.ImportedFromIB2 - 62.IBPluginDependency - 62.ImportedFromIB2 - 64.IBAttributePlaceholdersKey - 64.IBPluginDependency - 64.ImportedFromIB2 - 65.CustomClassName - 65.IBPluginDependency - 65.ImportedFromIB2 - 67.IBPluginDependency - 67.ImportedFromIB2 - 68.IBPluginDependency - 68.ImportedFromIB2 - 69.IBPluginDependency - 69.ImportedFromIB2 - 70.IBPluginDependency - 70.ImportedFromIB2 - 76.IBPluginDependency - 76.ImportedFromIB2 - 78.IBAttributePlaceholdersKey - 78.IBPluginDependency - 78.ImportedFromIB2 - 79.CustomClassName - 79.IBPluginDependency - 79.ImportedFromIB2 - 81.IBPluginDependency - 81.ImportedFromIB2 - 91.IBPluginDependency - 91.ImportedFromIB2 - 95.IBPluginDependency - 95.ImportedFromIB2 - 96.IBPluginDependency - 96.ImportedFromIB2 - 97.IBPluginDependency - 97.ImportedFromIB2 - 98.IBPluginDependency - 98.ImportedFromIB2 - 99.IBPluginDependency - 99.ImportedFromIB2 - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - - IBUserDefinedRuntimeAttributesPlaceholderName - - IBUserDefinedRuntimeAttributesPlaceholderName - - - YES - - com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.number - isShown - - - - com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.number - hiddenHeight - - YES - - - - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - SNDisclosureButton - com.apple.InterfaceBuilder.CocoaPlugin - - - IBUserDefinedRuntimeAttributesPlaceholderName - - IBUserDefinedRuntimeAttributesPlaceholderName - - - YES - - com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.number - isShown - - - - com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.number - hiddenHeight - - YES - - - - - com.apple.InterfaceBuilder.CocoaPlugin - - SNDisclosureButton - com.apple.InterfaceBuilder.CocoaPlugin - - {{683, 211}, {270, 505}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{683, 211}, {270, 505}} - - - {3.40282e+38, 3.40282e+38} - {270, 461} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - NSSecureTextField - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - - IBUserDefinedRuntimeAttributesPlaceholderName - - IBUserDefinedRuntimeAttributesPlaceholderName - - - YES - - com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.number - isShown - - - - com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.number - hiddenHeight - - YES - - - - - com.apple.InterfaceBuilder.CocoaPlugin - - SNDisclosureButton - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - - IBUserDefinedRuntimeAttributesPlaceholderName - - IBUserDefinedRuntimeAttributesPlaceholderName - - - YES - - com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.number - isShown - - - - com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.number - hiddenHeight - - YES - - - - - com.apple.InterfaceBuilder.CocoaPlugin - - SNDisclosureButton - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - - - - YES - - - YES - - - - - YES - - - YES - - - - 132 - - - - YES - - FirstResponder - NSObject - - IBUserSource - - - - - InfoWindow - NSWindowController - - YES - - YES - authenticationChanged: - loadFullHTMLChanged: - subscribedChanged: - urlFieldChanged: - validateURL: - - - YES - id - id - id - id - id - - - - YES - - YES - authenticationChanged: - loadFullHTMLChanged: - subscribedChanged: - urlFieldChanged: - validateURL: - - - YES - - authenticationChanged: - id - - - loadFullHTMLChanged: - id - - - subscribedChanged: - id - - - urlFieldChanged: - id - - - validateURL: - id - - - - - YES - - YES - folderDescription - folderImage - folderName - folderSize - folderUnread - isSubscribed - lastRefreshDate - loadFullHTML - password - urlField - username - validateButton - - - YES - NSTextField - NSImageView - NSTextField - NSTextField - NSTextField - NSButton - NSTextField - NSButton - NSSecureTextField - NSTextField - NSTextField - NSButton - - - - YES - - YES - folderDescription - folderImage - folderName - folderSize - folderUnread - isSubscribed - lastRefreshDate - loadFullHTML - password - urlField - username - validateButton - - - YES - - folderDescription - NSTextField - - - folderImage - NSImageView - - - folderName - NSTextField - - - folderSize - NSTextField - - - folderUnread - NSTextField - - - isSubscribed - NSButton - - - lastRefreshDate - NSTextField - - - loadFullHTML - NSButton - - - password - NSSecureTextField - - - urlField - NSTextField - - - username - NSTextField - - - validateButton - NSButton - - - - - IBProjectSource - src/InfoWindow.h - - - - InfoWindow - NSWindowController - - IBUserSource - - - - - NSObject - - IBProjectSource - 3rdparty/DSClickableURLTextField/DSClickableURLTextField.h - - - - NSObject - - IBProjectSource - src/FolderView.h - - - - NSObject - - IBProjectSource - src/TableViewExtensions.h - - - - NSObject - - IBProjectSource - src/ViewExtensions.h - - - - NSView - - - - NSWindow - - IBProjectSource - src/SquareWindow.h - - - - SNDisclosableView - NSView - - YES - - YES - hide: - show: - toggleDisclosure: - - - YES - id - id - id - - - - YES - - YES - hide: - show: - toggleDisclosure: - - - YES - - hide: - id - - - show: - id - - - toggleDisclosure: - id - - - - - IBProjectSource - 3rdparty/DisclosableView/SNDisclosableView.h - - - - SNDisclosureButton - NSButton - - IBProjectSource - 3rdparty/DisclosableView/SNDisclosureButton.h - - - - - YES - - NSActionCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSActionCell.h - - - - NSApplication - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSApplication.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSApplicationScripting.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSColorPanel.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSHelpManager.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSPageLayout.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSUserInterfaceItemSearching.h - - - - NSApplication - - IBFrameworkSource - PSMTabBarControl.framework/Headers/PSMTabDragAssistant.h - - - - NSBox - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSBox.h - - - - NSButton - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSButton.h - - - - NSButtonCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSButtonCell.h - - - - NSCell - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSCell.h - - - - NSControl - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSControl.h - - - - NSFormatter - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFormatter.h - - - - NSImageCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSImageCell.h - - - - NSImageView - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSImageView.h - - - - NSMenu - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenu.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSAccessibility.h - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDictionaryController.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDragging.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontManager.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontPanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSKeyValueBinding.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSNibLoading.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSOutlineView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSPasteboard.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSSavePanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTableView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSToolbarItem.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSView.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObjectScripting.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSPortCoder.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptObjectSpecifiers.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptWhoseTests.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLConnection.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLDownload.h - - - - NSObject - - IBFrameworkSource - PSMTabBarControl.framework/Headers/PSMTabBarCell.h - - - - NSObject - - IBFrameworkSource - Sparkle.framework/Headers/SUAppcast.h - - - - NSObject - - IBFrameworkSource - Sparkle.framework/Headers/SUUpdater.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebDownload.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebEditingDelegate.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebFrameLoadDelegate.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebJavaPlugIn.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebPlugin.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebPluginContainer.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebPolicyDelegate.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebResourceLoadDelegate.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebScriptObject.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebUIDelegate.h - - - - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSInterfaceStyle.h - - - - NSResponder - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSResponder.h - - - - NSSecureTextField - NSTextField - - IBFrameworkSource - AppKit.framework/Headers/NSSecureTextField.h - - - - NSTextField - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSTextField.h - - - - NSTextFieldCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSTextFieldCell.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSClipView.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItem.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSRulerView.h - - - - NSView - NSResponder - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSDrawer.h - - - - NSWindow - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSWindow.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSWindowScripting.h - - - - NSWindowController - NSResponder - - showWindow: - id - - - showWindow: - - showWindow: - id - - - - IBFrameworkSource - AppKit.framework/Headers/NSWindowController.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - ../Vienna.xcodeproj - 3 - - NSSwitch - {15, 15} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Kodeord: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Cg + + + + + + + + + + + +Cg + + + + + + + + + + + Ulæst: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/da.lproj/InfoWindow.nib/keyedobjects.nib b/lproj/da.lproj/InfoWindow.nib/keyedobjects.nib index 95cbacf475..b0e5f0d15a 100644 Binary files a/lproj/da.lproj/InfoWindow.nib/keyedobjects.nib and b/lproj/da.lproj/InfoWindow.nib/keyedobjects.nib differ diff --git a/lproj/da.lproj/InfoWindow.strings b/lproj/da.lproj/InfoWindow.strings index 509b4ec88a..fcb893b927 100644 Binary files a/lproj/da.lproj/InfoWindow.strings and b/lproj/da.lproj/InfoWindow.strings differ diff --git a/lproj/da.lproj/KnownSyncServers.plist b/lproj/da.lproj/KnownSyncServers.plist index aad6d6d42b..2db18b7768 100644 --- a/lproj/da.lproj/KnownSyncServers.plist +++ b/lproj/da.lproj/KnownSyncServers.plist @@ -1,5 +1,5 @@ - + BazQux @@ -7,35 +7,35 @@ Address www.bazqux.com Hint - Enter the info you set in BazQux's 'Mobile login' settings + Indtast informationerne du har i BazQux's 'Mobile login'-indstillinger FeedHQ Address feedhq.org Hint - Enter email address and password associated to your FeedHQ account + Indtast emailadresse og kodeord associeret med din FeedHQ konto InoReader Address www.inoreader.com Hint - Enter username and password associated to your InoReader account + Indtast emailadresse og kodeord associeret med din InoReader konto TheOldReader Address theoldreader.com Hint - Enter username and password defined in Settings/General section of theoldreader.com + Indtast emailadressen og kodeord defineret i Settings/General sektionen af theoldreader.com Andet Address Hint - Enter server's address and your credentials for this server + Indtast serverens adresse og dine oplysninger for den pågældende server diff --git a/lproj/da.lproj/Localizable.strings b/lproj/da.lproj/Localizable.strings index 825a0addd1..468bf8271f 100644 Binary files a/lproj/da.lproj/Localizable.strings and b/lproj/da.lproj/Localizable.strings differ diff --git a/lproj/da.lproj/RSSFeed.nib/designable.nib b/lproj/da.lproj/RSSFeed.nib/designable.nib index 8ebc824ef1..e5fe87d44c 100644 --- a/lproj/da.lproj/RSSFeed.nib/designable.nib +++ b/lproj/da.lproj/RSSFeed.nib/designable.nib @@ -1,1001 +1,220 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSMenu - NSMenuItem - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSUserDefaultsController - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - RSSFeed - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{165, 318}, {426, 289}} - 1886912512 - RSS-Feed - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{208, 9}, {102, 32}} - - - YES - - 67108864 - 134217728 - Afbryd - - LucidaGrande - 13 - 1044 - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{310, 9}, {102, 32}} - - - 100 - YES - - 67108864 - 134217728 - Abonner - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{20, 188}, {75, 17}} - - - YES - - 67108864 - 4194304 - S2lsZGU6Cg - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 256 - {{99, 181}, {175, 26}} - - - YES - - -2080374720 - 1024 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - URL - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - 100 - - - YES - - AndreOversigter - - - - - 3 - YES - YES - 1 - - NO - - - - 256 - {{20, 255}, {389, 17}} - - - YES - - 67108864 - 4194304 - TGF2IG55dCBhYm9ubmVtZW50Cg - - LucidaGrande-Bold - 13 - 2072 - - - - - - NO - - - - 256 - {{20, 213}, {378, 34}} - - - YES - - 67108864 - 4194304 - Indtast henvisningen for nyhedsfeedet forneden. Eller vælg fra kildelisten for at indtaste et genvejsnavn for nyhedsfeedet udgivet af kilden. - - LucidaGrande - 10 - 2843 - - - - - - NO - - - - 256 - {{23, 82}, {386, 62}} - - - YES - - -1805647871 - 4325376 - - - LucidaGrande - 11 - 3100 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 256 - {{283, 181}, {21, 24}} - - - YES - - 67108864 - 134217728 - - - - -2038284288 - 33 - - - - - - 200 - 25 - - NO - - - - 256 - {{20, 152}, {270, 17}} - - - YES - - 67108864 - 4194304 - URL: - - - - - - NO - - - - 268 - {{21, 44}, {185, 18}} - - - YES - - -2080374784 - 0 - Subscribe in Open Reader - - - 1211912448 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - NO - - - {426, 289} - - - - {{0, 0}, {1280, 778}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - 3 - 2 - {{305, 336}, {423, 167}} - 1886912512 - RSS-Feed - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{307, 12}, {102, 32}} - - 100 - YES - - 67108864 - 134217728 - Gem - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{205, 12}, {102, 32}} - - - YES - - 67108864 - 134217728 - Afbryd - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{20, 60}, {383, 62}} - - - YES - - -1805647871 - 4325376 - - - - YES - - - - NO - - - - 256 - {{17, 130}, {389, 17}} - - - YES - - 67108864 - 4194304 - Rediger abonnement - - - - - - NO - - - {{1, 9}, {423, 167}} - - - {{0, 0}, {1280, 778}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - YES - - - - - - - window - - - - 14 - - - - doSubscribe: - - - - 37 - - - - feedSource - - - - 46 - - - - subscribeButton - - - - 48 - - - - doSave: - - - - 57 - - - - editRSSFeedWindow - - - - 61 - - - - newRSSFeedWindow - - - - 62 - - - - editFeedURL - - - - 69 - - - - saveButton - - - - 70 - - - - editCancelButton - - - - 74 - - - - subscribeCancelButton - - - - 76 - - - - doEditCancel: - - - - 77 - - - - doSubscribeCancel: - - - - 78 - - - - doLinkSourceChanged: - - - - 89 - - - - feedURL - - - - 91 - - - - doShowSiteHomePage: - - - - 93 - - - - siteHomePageButton - - - - 94 - - - - linkTitle - - - - 99 - - - - doGoogleOption: - - - - 118 - - - - googleOptionButton - - - - 119 - - - - value: googleOptionButton - - - - - - value: googleOptionButton - value - googleOptionButton - 2 - - - 117 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - NewRSSFeed - - - 5 - - - - - - - - - - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 40 - - - - - - - - 43 - - - - - - - - 64 - - - - - - - - 65 - - - - - - - - 90 - - - - - - - - 92 - - - - - - - - 97 - - - - - - - - 49 - - - - - - EditRSSFeed - - - 50 - - - - - - - - - - - 53 - - - - - - - - 54 - - - - - - - - 55 - - - - - - - - 67 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - 107 - - - - - 108 - - - - - 109 - - - - - 110 - - - - - 111 - - - - - 112 - - - - - 113 - - - - - 114 - - - - - 44 - - - - - - - - 45 - - - - - -3 - - - Application - - - 115 - - - - - - - - 116 - - - - - 120 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{1012, 565}, {429, 297}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 122 - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - {15, 15} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Kilde: + + + + + + + + + + + + + + + + + + + + + + + + + + + Lav nyt abonnement + + + + + + + + + + + Indtast henvisningen for nyhedsfeedet forneden. Eller vælg fra kildelisten for at indtaste et genvejsnavn for nyhedsfeedet udgivet af kilden. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/da.lproj/RSSFeed.nib/keyedobjects.nib b/lproj/da.lproj/RSSFeed.nib/keyedobjects.nib index b1eab0a151..0ba4109b03 100644 Binary files a/lproj/da.lproj/RSSFeed.nib/keyedobjects.nib and b/lproj/da.lproj/RSSFeed.nib/keyedobjects.nib differ diff --git a/lproj/da.lproj/RSSFeed.strings b/lproj/da.lproj/RSSFeed.strings index aa2a3b17e4..9d7c471a39 100644 Binary files a/lproj/da.lproj/RSSFeed.strings and b/lproj/da.lproj/RSSFeed.strings differ diff --git a/lproj/da.lproj/SearchFolder.nib/designable.nib b/lproj/da.lproj/SearchFolder.nib/designable.nib index 454a696ddc..79ac5af4af 100644 --- a/lproj/da.lproj/SearchFolder.nib/designable.nib +++ b/lproj/da.lproj/SearchFolder.nib/designable.nib @@ -1,1573 +1,265 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSBox - NSButton - NSButtonCell - NSCustomObject - NSCustomView - NSMenu - NSMenuItem - NSNumberFormatter - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - SmartFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{118, 515}, {647, 186}} - 1886912512 - - NSPanel - - View - - - {213, 107} - - - 256 - - - - 268 - {{17, 150}, {133, 17}} - - - YES - - 67108864 - 4194304 - U21hcnRtYXBwZSBuYXZuOgo - - LucidaGrande - 13 - 1044 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 268 - {{155, 147}, {178, 22}} - - - YES - - -1804599231 - 4195328 - - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{555, 12}, {78, 32}} - - - YES - - 67108864 - 134217728 - Gem - - - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{475, 12}, {82, 32}} - - - YES - - 67108864 - 134217728 - Afbryd - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 274 - - - - 274 - - - - 274 - {{12, 6}, {584, 38}} - - - - NSView - - NSResponder - - - {{2, 2}, {609, 50}} - - - - - {{17, 56}, {613, 54}} - - - {0, 0} - - 67108864 - 0 - - - LucidaGrande - 11 - 3100 - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 3 - 0 - 0 - NO - - - - 268 - {{17, 118}, {182, 17}} - - - YES - - 67108864 - 4194304 - Vis alle artikler som matcher - - - - - - NO - - - - 268 - {{196, 112}, {80, 26}} - - - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - Intet - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - - - YES - - AndreOversigter - - - - - 3 - YES - YES - 1 - - NO - - - - 268 - {{279, 118}, {301, 17}} - - - YES - - 67108864 - 272629760 - under følgende forhold: - - - - - - NO - - - {647, 186} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - 256 - - - - 256 - {{-3, 0}, {135, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Felt navne her - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - AndreOversigter - - - - - 3 - YES - YES - 1 - - NO - - - - 256 - {{513, -3}, {32, 31}} - - YES - - 67108864 - 134479872 - - - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{302, 3}, {183, 22}} - - YES - - -1804599231 - 4195328 - - - - YES - - - - NO - - - - 256 - {{541, -3}, {32, 31}} - - YES - - 67108864 - 134479872 - + - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{151, 0}, {135, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Operatorer her - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - AndreOversigter - - - - - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{299, 0}, {100, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - - - 400 - 75 - - - Intet - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - AndreOversigter - - - - - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{302, 4}, {126, 22}} - - YES - - -1804599231 - 4195328 - - - - - - - - - NaN - - - - 0 - - - . - - , - - - - - 0 - 2 - NO - YES - 1 - P0IPAAAAAAAAAAAAAAAAAA - - - 0 - 1 - NO - YES - 1 - AQAAAAAAAAAAAAAAAAAAAA - - -0 - 0 - - - 0 - -0 - - - - - - - - - . - , - NO - NO - YES - - - YES - - - - NO - - - - -2147483392 - {{299, 0}, {189, 26}} - - 1008 - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Emne2 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - AndreOversigter - - - - - Emne3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{299, 0}, {189, 26}} - - 1004 - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Emne1 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - AndreOversigter - - - - - Emne2 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - Emne3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - 3 - YES - YES - 1 - - NO - - - {572, 28} - - NSView - - NSResponder - - - - - - - cancelButton - - - - 40 - - - - saveButton - - - - 41 - - - - searchCriteriaView - - - - 43 - - - - removeCriteriaButton - - - - 44 - - - - addCriteriaButton - - - - 45 - - - - fieldNamePopup - - - - 46 - - - - operatorPopup - - - - 47 - - - - valueField - - - - 49 - - - - window - - - - 50 - - - - addNewCriteria: - - - - 51 - - - - doCancel: - - - - 52 - - - - doSave: - - - - 53 - - - - searchWindow - - - - 54 - - - - removeCurrentCriteria: - - - - 57 - - - - fieldChanged: - - - - 59 - - - - flagValueField - - - - 65 - - - - numberValueField - - - - 70 - - - - folderValueField - - - - 78 - - - - criteriaConditionPopup - - - - 85 - - - - dateValueField - - - - 91 - - - - smartFolderName - - - - 92 - - - - searchCriteriaSuperview - - - - 42 - - - - nextKeyView - - - - 72 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - Search Folder - - - 5 - - - - - - - - - - - - - - - 7 - - - - - - - - 8 - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 37 - - - - - - - - 58 - - - - - - - - 79 - - - - - - - - 84 - - - - - - - - 26 - - - - - - - - - - - - - - SearchCriteriaView - - - 27 - - - - - - - - 29 - - - - - - - - 30 - - - - - - - - 31 - - - - - - - - 35 - - - - - - - - 61 - - - - - - - - 69 - - - - - - - - 73 - - - - - - - - 86 - - - - - - - - 94 - - - - - 95 - - - - - 96 - - - - - 97 - - - - - 98 - - - - - 99 - - - - - - - - 100 - - - - - 101 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - - - - 107 - - - - - - - - 108 - - - - - - - - 109 - - - - - - - - 71 - - - - - 80 - - - - - - - - 82 - - - - - 32 - - - - - - - - 33 - - - - - 34 - - - - - - - - 56 - - - - - 64 - - - - - - - - 62 - - - - - 74 - - - - - - - - - 76 - - - - - 75 - - - - - 87 - - - - - - - - - - 90 - - - - - 89 - - - - - 88 - - - - - -3 - - - Application - - - 36 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 109 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - SmartFolder - NSWindowController - - id - id - id - id - id - - - - addNewCriteria: - id - - - doCancel: - id - - - doSave: - id - - - fieldChanged: - id - - - removeCurrentCriteria: - id - - - - NSButton - NSButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSTextField - NSPopUpButton - NSButton - NSButton - NSView - NSView - NSWindow - NSTextField - NSTextField - - - - addCriteriaButton - NSButton - - - cancelButton - NSButton - - - criteriaConditionPopup - NSPopUpButton - - - dateValueField - NSPopUpButton - - - fieldNamePopup - NSPopUpButton - - - flagValueField - NSPopUpButton - - - folderValueField - NSPopUpButton - - - numberValueField - NSTextField - - - operatorPopup - NSPopUpButton - - - removeCriteriaButton - NSButton - - - saveButton - NSButton - - - searchCriteriaSuperview - NSView - - - searchCriteriaView - NSView - - - searchWindow - NSWindow - - - smartFolderName - NSTextField - - - valueField - NSTextField - - - - IBProjectSource - ./Classes/SmartFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Smartmappenavn: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/da.lproj/SearchFolder.nib/keyedobjects.nib b/lproj/da.lproj/SearchFolder.nib/keyedobjects.nib index ff6764ba4d..1a61a9a869 100644 Binary files a/lproj/da.lproj/SearchFolder.nib/keyedobjects.nib and b/lproj/da.lproj/SearchFolder.nib/keyedobjects.nib differ diff --git a/lproj/da.lproj/SearchFolder.strings b/lproj/da.lproj/SearchFolder.strings index c9d25918ec..e07e9224ea 100644 Binary files a/lproj/da.lproj/SearchFolder.strings and b/lproj/da.lproj/SearchFolder.strings differ diff --git a/lproj/da.lproj/SyncingPreferencesView.nib/designable.nib b/lproj/da.lproj/SyncingPreferencesView.nib/designable.nib new file mode 100644 index 0000000000..929daee43f --- /dev/null +++ b/lproj/da.lproj/SyncingPreferencesView.nib/designable.nib @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/da.lproj/SyncingPreferencesView.nib/keyedobjects.nib b/lproj/da.lproj/SyncingPreferencesView.nib/keyedobjects.nib new file mode 100644 index 0000000000..74a87552b6 Binary files /dev/null and b/lproj/da.lproj/SyncingPreferencesView.nib/keyedobjects.nib differ diff --git a/lproj/da.lproj/Vienna Help/advanced.html b/lproj/da.lproj/Vienna Help/advanced.html deleted file mode 100644 index bfa468fc1b..0000000000 --- a/lproj/da.lproj/Vienna Help/advanced.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - Avancerede indstillinger - - - -  Avancerede indstillinger -

Sektionen for avancerede instillinerg giver mulighed for at ændre meget specifikke indstillinger i Vienna som ikke er essentielle for normal brug, men som kan klare nogle problemer som kan være bragt op på support-forummet. Denne sider detajlerer de avancerede indstillinger og deres funktioner. -

-

Aktiver JavaScript i den interne browser

-

Aktiverer eller slår understøttelse for JavaScript skripts fra i Viennas interne browser. Som standard er dette slået til. Ved at slå denne instilling fra, vil JavaScript kode på hjemmesider ikke få tilladelse til at køre. Dette kan klare problemer med nogle sider som bruger skripter til pop-up-vinduer eller andet utilset adfærd, men slår man det fra kan det få nogle hjemmesider til at fremstå med fejl eller ligefrem få dem til at fungere ukorrekt. -

- - diff --git a/lproj/da.lproj/Vienna Help/faq.html b/lproj/da.lproj/Vienna Help/faq.html deleted file mode 100644 index a5bd478c01..0000000000 --- a/lproj/da.lproj/Vienna Help/faq.html +++ /dev/null @@ -1,191 +0,0 @@ - - - - - How Do I? - - - -  How Do I? -

Below are some of the more common questions asked about Vienna while it was being pre-release tested. -See the Official Vienna FAQ Page for these -and the latest hints and tips for using Vienna. -

- -

Where do I get the -Vienna source code?

-

See the Development page for -instructions for getting the source code for Vienna. The source code is -freely available if you're interested in learning how Vienna works, if -you want to build your own copy of Vienna from scratch on your own -machine or if you want to borrow portions for inclusion in your own -project. The source is provided under the -Apache 2.0 -license.

-

I found -a problem with Vienna. How do I report it?

-

Post a message over in the -Support forum and somebody will -investigate. Provide as much information about the problem as you can -including: the build of Vienna (obtained from the About Vienna panel), -repro steps and what you expected to happen. There is a sticky note in -the forum with tips on how to write a good bug report.

- -

Make sure you're always running the most recent build of Vienna. The -Check for Updates command will report if there's a newer build available -than the one you have.

-

Fixes for bugs take priority over new features so if your problem is -confirmed to be a bug with high impact and no simple workaround then -I'll look at making a fix available as soon as reasonably possible.

-

How do I create my own -styles?

-

See the Custom Styles page for -instructions.

-

How do I create my own -scripts?

- -

Vienna's scripts are written using AppleScript. See the - -Apple resource page for more details.

-

One way to get started is to download one of the existing scripts -from the Vienna Downloads page and view -it in the AppleScript editor.

- -

To submit your own script, send it to -steve@opencommunity.co.uk -and after it has been reviewed, it will be made available on the -Downloads page.

-

- -How can I see what happened when my subscriptions are refreshed?

-

Open the Activity Window from the Window menu. The activity window -shows all subscriptions and the status of the last time they were -refreshed in that session. The bottom of the activity window shows more -details include the HTTP headers and may be useful for debugging. (If -the details pane is not visible, grab the split bar at the bottom of the -Activity Window and drag it up to uncover the pane).

-

How do -I move my Vienna database to another folder?

- -

By default, your Vienna database is the messages.db file which is -located at ~/Library/Application Support/Vienna. You can move this to -another folder if you wish. The following steps show how:

-
    -
  1. Shut down Vienna.
  2. -
  3. Open a console window and enter:
    -
    -defaults write uk.co.opencommunity.vienna2 -"DefaultDatabase" '<path to new messages.db>'
    - -
    -where <path to new messages.db> is the name of the folder that -contains the messages.db file. The path itself should have the -messages.db filename at the end. For example:
    -
    -defaults write uk.co.opencommunity.vienna2 -"DefaultDatabase" '/Users/steve/mydata/messages.db'
    -
  4. - -
  5. Restart Vienna.
  6. -
-

- -One of my subscriptions reports "Error parsing XML data in feed". What -does this mean?

-

It means that Vienna got a feed back from the subscription that it -couldn't interpret. There are several reasons for this:

- -
    -
  1. The URL of the feed may not be pointing to an RSS or Atom feed -but to a web page. Check the URL of the offending feed carefully.
  2. -
  3. The feed itself may contain malformed XML. Some subscriptions -make a mistake in putting together the XML that makes up the feed -and Vienna cannot interpret malformed XML. Use the Validate Feed -command on the File menu to see if this is the case. Unfortunately -you cannot do much about this in Vienna except wait for the feed -itself to be corrected by the site.
  4. -
  5. The feed may be incomplete. If the refresh was interrupted then -the XML data will be incomplete and will appear malformed in Vienna. -A second refresh may correct this problem.
  6. -
-

If none of the above explain the problem, post a message on the -support forum with the URL of the feed exhibiting the problem.

-

- - -Is there a shortcut key for going to the next article, marking read, -etc?

-

Probably. There are single key equivalents for some of the menu -commands such as:

-

Spacebar - goes to the next unread article. If the current article is -several pages long, it will scroll through that article first. If you're -at the end of the current article it will then go to the next unread -article. By contrast the Next Unread command (Cmd+U) always goes -straight to the next unread article.

-

R - marks the current article read if it is unread, or unread if it -is read.

-

F - flags the current article if it isn't already flagged, or removes -the existing flag if it is not.

- -

Look in the Vienna Help file for more shortcuts.

- -

What do -the green dots mean in the list of articles?

-

The blue dots are for new articles, and the green dots are for updated articles: -articles whose text has changed since they were last downloaded.

- -

How do I use -Auto Expire and what does it do?

-

Auto-expire moves articles older than a certain number of days to the -Trash folder. It allows you to keep your folders manageable by only -retaining articles that are recent. The auto-expire runs both when -Vienna starts and after you have refreshed any subscriptions. To control -the age of articles to auto-expire, change the -"Move articles to Trash" option in Preferences.

-

Auto-expire will NOT remove unread or flagged articles. It assumes -that you haven't read these articles and thus leaves them alone.

-

How do I request -an enhancement in Vienna?

- -

Post a message over at the -support forum. All -requested enhancements are logged in the TODO file that is included with -the source code as a guidance for future developers.

- - diff --git a/lproj/da.lproj/Vienna Help/helpstyle.css b/lproj/da.lproj/Vienna Help/helpstyle.css deleted file mode 100644 index d02689f72e..0000000000 --- a/lproj/da.lproj/Vienna Help/helpstyle.css +++ /dev/null @@ -1,39 +0,0 @@ -a { - color: #3366CC; - text-decoration: none; -} -.title { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 18pt; - color: #000000; -} -.header { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 12pt; - color: #000000; -} -li { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 100; - font-size: 9pt; - color: #000000; -} -h2 { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 400; - font-size: 10pt; - color: #000000; -} -p { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 100; - font-size: 9pt; - color: #000000; -} -tr { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-size: 9pt; - color: #000000; -} \ No newline at end of file diff --git a/lproj/da.lproj/Vienna Help/images/Small-Vienna-Logo.jpg b/lproj/da.lproj/Vienna Help/images/Small-Vienna-Logo.jpg deleted file mode 100644 index 41035b4f11..0000000000 Binary files a/lproj/da.lproj/Vienna Help/images/Small-Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/da.lproj/Vienna Help/images/Vertical-Line.jpg b/lproj/da.lproj/Vienna Help/images/Vertical-Line.jpg deleted file mode 100644 index 011f1ce1e3..0000000000 Binary files a/lproj/da.lproj/Vienna Help/images/Vertical-Line.jpg and /dev/null differ diff --git a/lproj/da.lproj/Vienna Help/images/Vienna-Logo.jpg b/lproj/da.lproj/Vienna Help/images/Vienna-Logo.jpg deleted file mode 100644 index 13a6479bd4..0000000000 Binary files a/lproj/da.lproj/Vienna Help/images/Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/da.lproj/Vienna Help/images/rssfeed.gif b/lproj/da.lproj/Vienna Help/images/rssfeed.gif deleted file mode 100644 index 2dc8935119..0000000000 Binary files a/lproj/da.lproj/Vienna Help/images/rssfeed.gif and /dev/null differ diff --git a/lproj/da.lproj/Vienna Help/index.html b/lproj/da.lproj/Vienna Help/index.html deleted file mode 100644 index fa0f54f48b..0000000000 --- a/lproj/da.lproj/Vienna Help/index.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - Vienna hjælp - - - - - - - - - - -
-

-

Vienna hjælp

-
- - -

Introduktion til Vienna

-

Lær hvordan du starter med Vienna.

- -

Tastaturgenveje

-

Opdag tastaturgenveje for ofte brubte kommandoer

- -

Hvordan gør jeg?

-

Ofte stillede spørgsmål, få support og fejlsøgning

- -

Avancerede indstillinger

-

Explains the settings in the Advanced Preferences.

-
- - diff --git a/lproj/da.lproj/Vienna Help/intro.html b/lproj/da.lproj/Vienna Help/intro.html deleted file mode 100644 index 18eae3a50b..0000000000 --- a/lproj/da.lproj/Vienna Help/intro.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - - Introduction to Vienna - - - -   -Introduction to Vienna -

Vienna is an application that allows you to read RSS or Atom news feeds on your Mac OS X computer. It automates the -job of retrieving news articles from all subscribed feeds and storing them in a local database for reading off-line. It -provides features that allow you to search feeds for keywords or phrases, tag articles with a flag for future reference -and organise related feeds together under groups. You can create smart folders that make it easy to dynamically retrieve -and view all articles in the database that match a search criteria. The built-in web browser allows you to go to the -articles web page or view links in the article directly in Vienna in separate tabs.

-

Vienna is designed to be simple and easy to use. A clean, uncluttered, interface maximises the space for articles and -just a few controls are needed to perform the most common actions in the user interface.

-Getting Started -

If this is the first time that you have used Vienna then it will have created a new database for you -and added some sample news subscriptions. So go ahead and press Command+R or choose Refresh All Subscriptions -from the File menu to grab the latest articles from those subscriptions.

-

Alternatively, subscribe to your own news feeds. There are various ways to find feeds. When browsing -the web, look out for the RSS feed icon or XML icons indicating that the page has a feed associated -with it. Alternatively almost all online blogging services such as LiveJournal or Blogger provide RSS feeds as -an alternative to reading the postings online.

-

If you know the user name of a blogger on LiveJournal, Blogger, MSN Spaces or Xanga then Vienna makes it easier -to subscribe to their news feed. Start by pressing Command+N or from the File menu, choose the New Subscription command. -In the "Create a new RSS subscription" panel, pick the blogging service from the drop down list and enter the -user name in the input field below. Then choose Subscribe and Vienna will add the subscription to the folder list. If -you are connected to the internet at the time, it will also immediately start collecting articles from the feed.

-

Normally you need to manually tell Vienna when to refresh all your subscriptions. However you can opt to ask Vienna -to automatically refresh at time intervals. In the General section of the Preferences, pick the desired time interval -from the drop down list next to 'Check for new articles'. Vienna needs to be running for it to automatically refresh -subscriptions.

-

To read articles, press the Spacebar to skip to the next unread article in any subscription. Each article is marked -as read automatically after a short delay. If you prefer to wait until you move to the next unread article before the -current one is marked read you can adjust the behaviour in the General tab of the Preferences. To mark an article as -unread again, choose the Mark Unread command from the Article menu or simply press the 'R' key.

-

Finally, you can view the article web page or any web page links in an article within Vienna. By default clicking -on a web link within Vienna will open the web page in a new tab. Vienna provides a lot of basic web browsing support -itself but there may be times when you will prefer to open links in your default web browser. If you prefer to view -all web pages outside of Vienna then enable the 'Open links in external browser' option in the General section of the -Preferences. However if you prefer to view the current link or page in your external browser, right click on the page -and choose the "Open Link in XXX" or "Open Page in XXX" option where XXX will be the name of your default browser.

-

Once you've got comfortable using Vienna, go ahead and explore the various options. You can change the style in -which the articles are displayed through the Style drop down list in the View menu. You can find many more custom -styles at the Downloads page on the Vienna web site along with custom scripts that allow you to integrate Vienna with -other applications on your machine. Or experiment with smart folders to organise articles according to criteria based -on the contents of each article. For example, you can easily set up a smart folder to group together all articles that -mention "Joss Whedon" and "Firefly" to find references to the Firefly cult series or the spin-off movie.

-

If you have any questions about Vienna or run into problems, head over to the -Support forum.

- - diff --git a/lproj/da.lproj/Vienna Help/keyboard.html b/lproj/da.lproj/Vienna Help/keyboard.html deleted file mode 100644 index eca104daf9..0000000000 --- a/lproj/da.lproj/Vienna Help/keyboard.html +++ /dev/null @@ -1,422 +0,0 @@ - - - - - Tastaturgenveje - - - -  Tastaturgenveje -

Du kan bruge dit tastatur til hurtigt at klare mange funktioner i Vienna. For at finde genveje for ofte brugte kommandoer, kig da i menuerne (eller se listen i bunden af denne side). Mange emner i Vienna, såsom mappefanen og artikellistefanen, har også contextual menuer. For at se en contextualmenu, hold Kontrol-tasten nede og klik på et emne.

-

For at gøre en handling, tryk genvejstasterne indikeret nedenfor.

- - - - - - - -
-

Taster

-
-

Handling

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Enkelttastsgenveje

-
-

 

-
-

f

-
-

Sætter indputsfokuset til søgevinduet.

-
-

r

-
-

Markerer de valgte artikler som værende læst.

-
-

s

-
-

Markere den nuværende mappe som værende læst, og hopper derefter til den næste mappe med ulæste artikler.

-
-

k

-
-

Markerer den nuværende mappe som værende læst.

-
-

m

-
-

Sætter et mærke ved de valgte artikler.

-
-

<

-
-

Viser den sidst sete artikel eller hjemmeside.

-
-

>

-
-

Viser den efterfølgende sete artikel eller hjemmeside.

-
-

Spacebar

-
-

Hopper til den næste ulæste artikel medmindre den nuværende artikel har mere tekst at rulle i, hvilket i såfald medfører at den ruller den nuværende artikel én side op.

-
-

Enter/Return

-
-

Åbner den valgte artikels originale hjemmeside.

-
-

Delete/Backspace

-
-

Rykker de valgte artikler til Papirkurven. Hvis denne tast bruger i Papirkurven, vil de valgte artikler blive slettet permanent.

-
-

Generelle genveje

-
-

 

-
-

Alt-klik

-
-

Åbner den klikkede henvisning, og overgår dine indstillinger for åbning af henvisninger i ekstern browser.

-
-

Command-N

-
-

Laver et nyt abonnement.

-
-

Skift-Command-F

-
-

Lav en smartmappe.

-
-

Skift-Command-E

-
-

Rediger den valgte mappehenvisning eller rediger et smartmappekriterie.

-
-

Skift-Command-D

-
-

Slet den valgte mappe.

-
-

Skift-Command-N

-
-

Omdøb den valgte mappe.

-
-

Command-R

-
-

Opdater alle abonnementer.

-
-

Skift-Command-R

-
-

Opdater kun de valgte abonnementer i listen.

-
-

Control-Command-S

-
-

Stopper alle aktive opdateringer.

-
-

Command-P

-
-

Udskriv de valgte artikler.

-
-

Skift-Command-P

-
-

Viser sidelayoutpanelet.

-
-

Command-?

-
-

Viser Vienna hjælp-bogen.

-
-

Artikelgenveje

-
-

 

-
-

Alt-Enter/Alt-Return

-
-

Åbner den valgte artikel originale hjemmeside, og overgår dine indstillinger for åbning af henvisninger i ekstern browser.

-
-

Command-U

-
-

Hopper til den næste ulæste artikel.

-
-

Skift-Command-M

-
-

Mærker de valgte artikler.

-
-

Skift-Command-U

-
-

Markerer den valgte artikler som værende læst.

-
-

Skift-Command-S

-
-

Markerer den valgte mappe som værende læst, og hopper derefter til den næste mappe med ulæste artikler.

-
-

Skift-Command-O

-
-

Gendanner en artikel til dens originale mappe fra Papirkurven.

-
-

Skift-Command-K

-
-

Makerer alle artikler i de valgte mapper som værende læst.

-
-

Skift-Command-K

-
-

Markerer alle artikler i alle mapper som værende læst.

-
-

Vinduegenveje

-
-

 

-
-

Command-W

-
-

Lukker den aktive fane hvis der er en åben. Hvis ingen faner er åbne, lukkes Vienna-vinduet.

-
-

Alt-Command-W

-
-

Lukker alle fanevinduer. Noter at denne funktion erstatter Luk fane funktionen i Arkiv-menuen når Alt-tasten holdes nede.

-
-

Alt-Command-Left

-
-

Vis det foregående fanevindue.

-
-

Alt-Command-Right

-
-

Viser det næste fanevindue.

-
-

Command-M

-
-

Minimerer Vienna-vinduet til Docken.

-
-

Command-0

-
-

Viser aktivitetslogvinduet.

-
-

Command-1

-
-

Genåbner Vienna-vinduet hvis det tidligere var lukket.

-
-

Command-2

-
-

Viser vinduet med hentede filer.

-
-

Browservinduegenveje

-
-

 

-
-

Alt-R

-
-

Genindlæser den nuværende hjemmeside.

-
-

Command-Period

-
-

Stopper indlæsningen af den nuværende hjemmeside.

-
-

Command-[ eller Command-Left

-
-

Går tilbage til den foregående hjemmeside.

-
-

Command-] eller Command-Right

-
-

Går frem til den næste hjemmeside.

-
-

Command-F

-
-

Sætter indputsfokusset i søgefeltet. Indtast noget tekst her og tryk Enter for at søge i teksten på den nuværende hjemmeside.

-
-

Command-G

-
-

Søger efter den næste gang din søgte tekst fremgår i teksten på hjemmesiden.

-
- - diff --git a/lproj/de.lproj/GroupFolder.nib/designable.nib b/lproj/de.lproj/GroupFolder.nib/designable.nib index b67a4abc13..2587724998 100644 --- a/lproj/de.lproj/GroupFolder.nib/designable.nib +++ b/lproj/de.lproj/GroupFolder.nib/designable.nib @@ -1,507 +1,91 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - NewGroupFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{502, 622}, {388, 107}} - 1886912512 - - Panel - - - NSPanel - - - View - - - {213, 107} - - - 256 - - - - 260 - {{17, 112}, {354, 17}} - - - - YES - - 67108864 - 4194304 - Neuer Gruppenordner - - LucidaGrande-Bold - 13 - 2072 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 258 - {{20, 60}, {348, 22}} - - - - YES - - -1804599231 - 272630784 - - - LucidaGrande - 13 - 1044 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{285, 12}, {89, 32}} - - - 100 - YES - - 67108864 - 134217728 - Erstellen - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{188, 12}, {97, 32}} - - - - YES - - 67108864 - 134217728 - Abbrechen - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 268 - {{17, 90}, {353, 14}} - - - - YES - - 67108864 - 4194304 - R2ViZW4gU2llIGRlbiBOYW1lbiBkZXMgR3J1cHBlbm9yZG5lcnMgZWluOgo - - LucidaGrande - 11 - 3100 - - - - - - NO - - - {388, 107} - - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - - - - newGroupFolderWindow - - - - 18 - - - - doCancel: - - - - 25 - - - - doSave: - - - - 26 - - - - folderName - - - - 27 - - - - cancelButton - - - - 28 - - - - saveButton - - - - 29 - - - - window - - - - 30 - - - - nextKeyView - - - - 24 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 5 - - - - - - GroupFolder - - - 6 - - - - - - - - - - - - 19 - - - - - - - - 20 - - - - - - - - 21 - - - - - - - - 22 - - - - - - - - 23 - - - - - - - - 32 - - - - - 33 - - - - - 34 - - - - - 35 - - - - - 36 - - - - - -3 - - - Application - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 36 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - NewGroupFolder - NSWindowController - - id - id - - - - doCancel: - id - - - doSave: - id - - - - NSButton - NSTextField - NSWindow - NSButton - - - - cancelButton - NSButton - - - folderName - NSTextField - - - newGroupFolderWindow - NSWindow - - - saveButton - NSButton - - - - IBProjectSource - ./Classes/NewGroupFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Geben Sie den Namen des Gruppenordners ein: + + + + + + + + + + diff --git a/lproj/de.lproj/GroupFolder.nib/keyedobjects.nib b/lproj/de.lproj/GroupFolder.nib/keyedobjects.nib index e52bb2c2e1..2183e50d1d 100644 Binary files a/lproj/de.lproj/GroupFolder.nib/keyedobjects.nib and b/lproj/de.lproj/GroupFolder.nib/keyedobjects.nib differ diff --git a/lproj/de.lproj/InfoPlist.strings b/lproj/de.lproj/InfoPlist.strings deleted file mode 100644 index 9c7a273d2a..0000000000 --- a/lproj/de.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ -NSHumanReadableCopyright = "Copyright 2004-2015 Unterstützer. Schauen Sie unter Hilfe/Danksagungen für eine Liste der Unterstützer."; diff --git a/lproj/de.lproj/InfoWindow.nib/designable.nib b/lproj/de.lproj/InfoWindow.nib/designable.nib index ed24acc192..f56fd236f6 100644 --- a/lproj/de.lproj/InfoWindow.nib/designable.nib +++ b/lproj/de.lproj/InfoWindow.nib/designable.nib @@ -1,2652 +1,369 @@ - - - - 1060 - 13E28 - 940 - 1265.21 - 698.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 940 - - - YES - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - YES - - InfoWindow - - - FirstResponder - - - NSApplication - - - 7 - 2 - {{100, 100}, {313, 481}} - 1886912512 - Fenster - - NSWindow - - - View - - - {1.7976931348623157e+308, 1.7976931348623157e+308} - {270, 461} - - - 256 - - YES - - - 270 - {{43, 454}, {220, 17}} - - YES - - 69206081 - 272632320 - (Folder name) - - .LucidaGrandeUI-Bold - 13 - 2064 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - 1 - - - - 268 - {{43, 437}, {98, 14}} - - YES - - 67108864 - 272629760 - Letzte Aktualisierung: - - .LucidaGrandeUI - 11 - 3088 - - - - - 6 - System - disabledControlTextColor - - 3 - MC4zMzMzMzMzMzMzAA - - - - NO - 1 - - - - 270 - {{130, 437}, {133, 14}} - - YES - - 67108928 - 272632320 - (Last refresh date) - - - - - - NO - 1 - - - - 268 - - YES - - YES - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple PNG pasteboard type - NSFilenamesPboardType - NeXT Encapsulated PostScript v1.2 pasteboard type - NeXT TIFF v4.0 pasteboard type - - - {{16, 454}, {16, 16}} - - YES - - 0 - 33554432 - 0 - 0 - 0 - NO - - NO - YES - - - - 266 - - YES - - - 274 - {{8, 23}, {281, 58}} - - YES - - -1805647871 - 272760832 - - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - 1 - - - - 257 - {{184, -6}, {110, 28}} - - YES - - 67108864 - 134348800 - Überprüfen - - - -2038284288 - 1 - - - - - - 200 - 25 - - NO - - - {{8, 118}, {289, 81}} - - SNDisclosableView - - - - 268 - {{5, 209}, {151, 18}} - - YES - - 67108864 - 0 - Abonnementadresse: - - .LucidaGrandeUI - 13 - 1040 - - - -935575552 - 6 - - - 200 - 25 - - NO - - - - 266 - - YES - - - 256 - {{5, 61}, {81, 13}} - - YES - - 67108864 - 71303168 - Benutzername: - - .LucidaGrandeUI - 10 - 2832 - - - - - - NO - 1 - - - - 256 - {{26, 38}, {60, 13}} - - YES - - 67108864 - 71303168 - UGFzc3dvcnQ6Cg - - - - - - NO - 1 - - - - 258 - {{93, 59}, {196, 19}} - - YES - - -1804599231 - 272761856 - - - - YES - - - - NO - 1 - - - - 258 - {{93, 36}, {196, 19}} - - YES - - -1804599231 - 272761856 - - - - YES - - - - NO - 1 - - - - 256 - {{100, 4}, {194, 28}} - - YES - - 67108864 - 134348800 - Authentifizierung aktualisieren - - - -2038284288 - 1 - - LucidaGrande - 11 - 16 - - - - - - 200 - 25 - - NO - - - {{8, 6}, {289, 78}} - - SNDisclosableView - - - - 268 - {{5, 91}, {114, 18}} - - YES - - 67108864 - 0 - Authentication: - - - -935575552 - 6 - - - 200 - 25 - - NO - - - - 266 - - YES - - - 256 - {{8, 65}, {78, 14}} - - YES - - 67108864 - 71434240 - Artikelanzahl: - - - - - - NO - 1 - - - - 256 - {{21, 47}, {65, 14}} - - YES - - 67108864 - 71434240 - VW5nZWxlc2VuOgo - - - - - - NO - 1 - - - - 256 - {{90, 65}, {80, 14}} - - YES - - 67108864 - 272629760 - Cg - - - - - - NO - 1 - - - - 256 - {{90, 47}, {80, 14}} - - YES - - 67108864 - 272629760 - Cg - - - - - - NO - 1 - - - - 256 - {{90, 23}, {101, 18}} - - YES - - 67108864 - 131072 - Abonniert - - - 1211912448 - 2 - - NSSwitch - - - - 200 - 25 - - NO - - - - 256 - {{90, 3}, {194, 18}} - - YES - - 67108864 - 131072 - Ganze Webseite sofort anzeigen - - - 1211912448 - 2 - - - - 200 - 25 - - NO - - - {{8, 234}, {289, 79}} - - SNDisclosableView - - - - 268 - {{5, 320}, {80, 18}} - - YES - - 67108864 - 0 - Generell: - - - -935575552 - 6 - - - 200 - 25 - - NO - - - - 266 - - YES - - - 274 - {{5, 0}, {287, 58}} - - YES - - 67108864 - 272629760 - - - - - - - NO - 1 - - - {{8, 345}, {289, 58}} - - SNDisclosableView - - - - 268 - {{5, 410}, {94, 18}} - - YES - - 67108864 - 0 - Beschreibung: - - - -935575552 - 6 - - - 200 - 25 - - NO - - - - 258 - {{0, 429}, {270, 5}} - - {0, 0} - - 67108864 - 0 - Box - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - 3 - 2 - 0 - NO - - - - 258 - {{0, 339}, {313, 5}} - - {0, 0} - - 67108864 - 0 - Box - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - 3 - 2 - 0 - NO - - - - 258 - {{0, 228}, {313, 5}} - - {0, 0} - - 67108864 - 0 - Box - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - 3 - 2 - 0 - NO - - - - 258 - {{0, 108}, {313, 5}} - - {0, 0} - - 67108864 - 0 - Box - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - 3 - 2 - 0 - NO - - - {313, 481} - - {{0, 0}, {1920, 1178}} - {270, 483} - {1.7976931348623157e+308, 1.7976931348623157e+308} - YES - - - - - YES - - - window - - - - 14 - - - - toggleDisclosure: - - - - 39 - - - - urlField - - - - 40 - - - - folderName - - - - 41 - - - - folderImage - - - - 42 - - - - lastRefreshDate - - - - 43 - - - - toggleDisclosure: - - - - 46 - - - - username - - - - 55 - - - - password - - - - 56 - - - - nextKeyView - - - - 58 - - - - validateURL: - - - - 63 - - - - toggleDisclosure: - - - - 66 - - - - folderSize - - - - 71 - - - - folderUnread - - - - 72 - - - - isSubscribed - - - - 77 - - - - toggleDisclosure: - - - - 80 - - - - folderDescription - - - - 82 - - - - initialFirstResponder - - - - 83 - - - - nextKeyView - - - - 86 - - - - nextKeyView - - - - 87 - - - - urlFieldChanged: - - - - 88 - - - - subscribedChanged: - - - - 89 - - - - validateButton - - - - 90 - - - - nextKeyView - - - - 92 - - - - nextKeyView - - - - 93 - - - - authenticationChanged: - - - - 94 - - - - loadFullHTML - - - - 127 - - - - nextKeyView - - - - 128 - - - - nextKeyView - - - - 129 - - - - loadFullHTMLChanged: - - - - 130 - - - - - YES - - 0 - - YES - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 5 - - - YES - - - - Info Window - - - 6 - - - YES - - - - - - - - - - - - - - - - - - - - - 32 - - - YES - - - - - - 33 - - - YES - - - - - - 34 - - - YES - - - - - - 35 - - - YES - - - - - - 36 - - - YES - - - - - - - 37 - - - YES - - - - - - 62 - - - YES - - - - - - 38 - - - YES - - - - - - 44 - - - YES - - - - - - - - - - 51 - - - YES - - - - - - 52 - - - YES - - - - - - 53 - - - YES - - - - - - 54 - - - YES - - - - - - 91 - - - YES - - - - - - 45 - - - YES - - - - - - 64 - - - YES - - - - - - - - - - - 67 - - - YES - - - - - - 68 - - - YES - - - - - - 69 - - - YES - - - - - - 70 - - - YES - - - - - - 76 - - - YES - - - - - - 65 - - - YES - - - - - - 78 - - - YES - - - - - - 81 - - - YES - - - - - - 79 - - - YES - - - - - - 95 - - - YES - - - 256 - {{2, 2}, {125, 1}} - - - - - - 96 - - - - - 97 - - - YES - - - 256 - {{2, 2}, {125, 1}} - - - - - - 98 - - - - - 99 - - - YES - - - 256 - {{2, 2}, {125, 1}} - - - - - - 100 - - - - - 101 - - - YES - - - 256 - {{2, 2}, {125, 1}} - - - - - - 102 - - - - - 104 - - - - - 105 - - - - - 106 - - - - - 107 - - - - - 108 - - - - - 109 - - - - - 110 - - - - - 111 - - - - - 112 - - - - - 113 - - - - - 114 - - - - - 115 - - - - - 116 - - - - - 117 - - - - - 118 - - - - - 119 - - - - - 120 - - - - - 121 - - - - - 122 - - - - - 123 - - - - - 124 - - - - - -3 - - - Application - - - 125 - - - YES - - - - - - 126 - - - - - - - YES - - YES - -3.IBPluginDependency - 100.IBPluginDependency - 100.ImportedFromIB2 - 101.IBPluginDependency - 101.ImportedFromIB2 - 102.IBPluginDependency - 102.ImportedFromIB2 - 104.IBPluginDependency - 105.IBPluginDependency - 106.IBPluginDependency - 107.IBPluginDependency - 108.IBPluginDependency - 109.IBPluginDependency - 110.IBPluginDependency - 111.IBPluginDependency - 112.IBPluginDependency - 113.IBPluginDependency - 114.IBPluginDependency - 115.IBPluginDependency - 116.IBPluginDependency - 117.IBPluginDependency - 118.IBPluginDependency - 119.IBPluginDependency - 120.IBPluginDependency - 121.IBPluginDependency - 122.IBPluginDependency - 123.IBPluginDependency - 124.IBPluginDependency - 125.IBPluginDependency - 125.ImportedFromIB2 - 126.IBPluginDependency - 32.IBPluginDependency - 32.ImportedFromIB2 - 33.IBPluginDependency - 33.ImportedFromIB2 - 34.IBPluginDependency - 34.ImportedFromIB2 - 35.IBPluginDependency - 35.ImportedFromIB2 - 36.IBAttributePlaceholdersKey - 36.IBPluginDependency - 36.ImportedFromIB2 - 37.IBPluginDependency - 37.ImportedFromIB2 - 38.CustomClassName - 38.IBPluginDependency - 38.ImportedFromIB2 - 44.IBAttributePlaceholdersKey - 44.IBPluginDependency - 44.ImportedFromIB2 - 45.CustomClassName - 45.IBPluginDependency - 45.ImportedFromIB2 - 5.IBEditorWindowLastContentRect - 5.IBPluginDependency - 5.IBViewEditorWindowController.showingBoundsRectangles - 5.IBWindowTemplateEditedContentRect - 5.ImportedFromIB2 - 5.windowTemplate.hasMinSize - 5.windowTemplate.minSize - 51.IBPluginDependency - 51.ImportedFromIB2 - 52.IBPluginDependency - 52.ImportedFromIB2 - 53.IBPluginDependency - 53.ImportedFromIB2 - 54.CustomClassName - 54.IBPluginDependency - 54.ImportedFromIB2 - 6.IBPluginDependency - 6.IBUserGuides - 6.ImportedFromIB2 - 62.IBPluginDependency - 62.ImportedFromIB2 - 64.IBAttributePlaceholdersKey - 64.IBPluginDependency - 64.ImportedFromIB2 - 65.CustomClassName - 65.IBPluginDependency - 65.ImportedFromIB2 - 67.IBPluginDependency - 67.ImportedFromIB2 - 68.IBPluginDependency - 68.ImportedFromIB2 - 69.IBPluginDependency - 69.ImportedFromIB2 - 70.IBPluginDependency - 70.ImportedFromIB2 - 76.IBPluginDependency - 76.ImportedFromIB2 - 78.IBAttributePlaceholdersKey - 78.IBPluginDependency - 78.ImportedFromIB2 - 79.CustomClassName - 79.IBPluginDependency - 79.ImportedFromIB2 - 81.IBPluginDependency - 81.ImportedFromIB2 - 91.IBPluginDependency - 91.ImportedFromIB2 - 95.IBPluginDependency - 95.ImportedFromIB2 - 96.IBPluginDependency - 96.ImportedFromIB2 - 97.IBPluginDependency - 97.ImportedFromIB2 - 98.IBPluginDependency - 98.ImportedFromIB2 - 99.IBPluginDependency - 99.ImportedFromIB2 - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - - IBUserDefinedRuntimeAttributesPlaceholderName - - IBUserDefinedRuntimeAttributesPlaceholderName - - - YES - - com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.number - isShown - - - - com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.number - hiddenHeight - - YES - - - - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - SNDisclosureButton - com.apple.InterfaceBuilder.CocoaPlugin - - - IBUserDefinedRuntimeAttributesPlaceholderName - - IBUserDefinedRuntimeAttributesPlaceholderName - - - YES - - com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.number - isShown - - - - com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.number - hiddenHeight - - YES - - - - - com.apple.InterfaceBuilder.CocoaPlugin - - SNDisclosureButton - com.apple.InterfaceBuilder.CocoaPlugin - - {{379, 243}, {313, 481}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{379, 243}, {313, 481}} - - - {270, 461} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - NSSecureTextField - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - YES - - - 16 - 0 - - - - 16 - 1 - - - - 297 - 0 - - - - 101 - 0 - - - - 91 - 0 - - - - com.apple.InterfaceBuilder.CocoaPlugin - - - IBUserDefinedRuntimeAttributesPlaceholderName - - IBUserDefinedRuntimeAttributesPlaceholderName - - - YES - - com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.number - isShown - - - - com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.number - hiddenHeight - - YES - - - - - com.apple.InterfaceBuilder.CocoaPlugin - - SNDisclosureButton - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - - IBUserDefinedRuntimeAttributesPlaceholderName - - IBUserDefinedRuntimeAttributesPlaceholderName - - - YES - - com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.number - isShown - - - - com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.number - hiddenHeight - - YES - - - - - com.apple.InterfaceBuilder.CocoaPlugin - - SNDisclosureButton - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - - - - YES - - - YES - - - - - YES - - - YES - - - - 130 - - - - YES - - FirstResponder - NSObject - - IBUserSource - - - - - InfoWindow - NSWindowController - - YES - - YES - authenticationChanged: - loadFullHTMLChanged: - subscribedChanged: - urlFieldChanged: - validateURL: - - - YES - id - id - id - id - id - - - - YES - - YES - authenticationChanged: - loadFullHTMLChanged: - subscribedChanged: - urlFieldChanged: - validateURL: - - - YES - - authenticationChanged: - id - - - loadFullHTMLChanged: - id - - - subscribedChanged: - id - - - urlFieldChanged: - id - - - validateURL: - id - - - - - YES - - YES - folderDescription - folderImage - folderName - folderSize - folderUnread - isSubscribed - lastRefreshDate - loadFullHTML - password - urlField - username - validateButton - - - YES - NSTextField - NSImageView - NSTextField - NSTextField - NSTextField - NSButton - NSTextField - NSButton - NSSecureTextField - NSTextField - NSTextField - NSButton - - - - YES - - YES - folderDescription - folderImage - folderName - folderSize - folderUnread - isSubscribed - lastRefreshDate - loadFullHTML - password - urlField - username - validateButton - - - YES - - folderDescription - NSTextField - - - folderImage - NSImageView - - - folderName - NSTextField - - - folderSize - NSTextField - - - folderUnread - NSTextField - - - isSubscribed - NSButton - - - lastRefreshDate - NSTextField - - - loadFullHTML - NSButton - - - password - NSSecureTextField - - - urlField - NSTextField - - - username - NSTextField - - - validateButton - NSButton - - - - - IBProjectSource - src/InfoWindow.h - - - - InfoWindow - NSWindowController - - IBUserSource - - - - - NSObject - - IBProjectSource - 3rdparty/DSClickableURLTextField/DSClickableURLTextField.h - - - - NSObject - - IBProjectSource - src/FolderView.h - - - - NSObject - - IBProjectSource - src/TableViewExtensions.h - - - - NSObject - - IBProjectSource - src/ViewExtensions.h - - - - NSView - - - - NSWindow - - IBProjectSource - src/SquareWindow.h - - - - SNDisclosableView - NSView - - YES - - YES - hide: - show: - toggleDisclosure: - - - YES - id - id - id - - - - YES - - YES - hide: - show: - toggleDisclosure: - - - YES - - hide: - id - - - show: - id - - - toggleDisclosure: - id - - - - - IBProjectSource - 3rdparty/DisclosableView/SNDisclosableView.h - - - - SNDisclosureButton - NSButton - - IBProjectSource - 3rdparty/DisclosableView/SNDisclosureButton.h - - - - - YES - - NSActionCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSActionCell.h - - - - NSApplication - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSApplication.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSApplicationScripting.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSColorPanel.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSHelpManager.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSPageLayout.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSUserInterfaceItemSearching.h - - - - NSApplication - - IBFrameworkSource - PSMTabBarControl.framework/Headers/PSMTabDragAssistant.h - - - - NSBox - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSBox.h - - - - NSButton - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSButton.h - - - - NSButtonCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSButtonCell.h - - - - NSCell - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSCell.h - - - - NSControl - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSControl.h - - - - NSFormatter - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFormatter.h - - - - NSImageCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSImageCell.h - - - - NSImageView - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSImageView.h - - - - NSMenu - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenu.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSAccessibility.h - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDictionaryController.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDragging.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontManager.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontPanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSKeyValueBinding.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSNibLoading.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSOutlineView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSPasteboard.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSSavePanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTableView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSToolbarItem.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSView.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObjectScripting.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSPortCoder.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptObjectSpecifiers.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptWhoseTests.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLConnection.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLDownload.h - - - - NSObject - - IBFrameworkSource - PSMTabBarControl.framework/Headers/PSMTabBarCell.h - - - - NSObject - - IBFrameworkSource - Sparkle.framework/Headers/SUAppcast.h - - - - NSObject - - IBFrameworkSource - Sparkle.framework/Headers/SUUpdater.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebDownload.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebEditingDelegate.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebFrameLoadDelegate.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebJavaPlugIn.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebPlugin.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebPluginContainer.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebPolicyDelegate.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebResourceLoadDelegate.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebScriptObject.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebUIDelegate.h - - - - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSInterfaceStyle.h - - - - NSResponder - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSResponder.h - - - - NSSecureTextField - NSTextField - - IBFrameworkSource - AppKit.framework/Headers/NSSecureTextField.h - - - - NSTextField - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSTextField.h - - - - NSTextFieldCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSTextFieldCell.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSClipView.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItem.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSRulerView.h - - - - NSView - NSResponder - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSDrawer.h - - - - NSWindow - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSWindow.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSWindowScripting.h - - - - NSWindowController - NSResponder - - showWindow: - id - - - showWindow: - - showWindow: - id - - - - IBFrameworkSource - AppKit.framework/Headers/NSWindowController.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - ../Vienna.xcodeproj - 3 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Passwort: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Cg + + + + + + + + + + + +Cg + + + + + + + + + + + Ungelesen: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/de.lproj/InfoWindow.nib/keyedobjects.nib b/lproj/de.lproj/InfoWindow.nib/keyedobjects.nib index d89484fe01..a35d45a80e 100644 Binary files a/lproj/de.lproj/InfoWindow.nib/keyedobjects.nib and b/lproj/de.lproj/InfoWindow.nib/keyedobjects.nib differ diff --git a/lproj/de.lproj/InfoWindow.strings b/lproj/de.lproj/InfoWindow.strings index 404048d305..ae87ec06d2 100644 Binary files a/lproj/de.lproj/InfoWindow.strings and b/lproj/de.lproj/InfoWindow.strings differ diff --git a/lproj/de.lproj/KnownSyncServers.plist b/lproj/de.lproj/KnownSyncServers.plist index 0d53113b43..c5424f7870 100644 --- a/lproj/de.lproj/KnownSyncServers.plist +++ b/lproj/de.lproj/KnownSyncServers.plist @@ -1,5 +1,5 @@ - + BazQux @@ -7,7 +7,7 @@ Address www.bazqux.com Hint - Enter the info you set in BazQux's 'Mobile login' settings + Enter the info you set in BazQux's 'Mobile login' settings FeedHQ @@ -30,12 +30,12 @@ Hint Enter username and password defined in Settings/General section of theoldreader.com - Aüswählen + Auswählen Address Hint - Enter server's address and your credentials for this server + Geben Sie die Adresse und Anmeldedaten für diesen Server ein diff --git a/lproj/de.lproj/Localizable.strings b/lproj/de.lproj/Localizable.strings index 56c9bb9b87..63f3bf3e36 100644 --- a/lproj/de.lproj/Localizable.strings +++ b/lproj/de.lproj/Localizable.strings @@ -450,3 +450,9 @@ /*Added in 3.0.5 */ "Redirection attempt treated as temporary for safety concern" = "Redirection attempt treated as temporary for safety concern"; + +/*Added in 3.0.7 */ +"No articles in feed" = "No articles in feed"; + +/*Added in 3.1.2 */ +"Filter folders" = "Suche nach Ordnern"; diff --git a/lproj/de.lproj/RSSFeed.nib/designable.nib b/lproj/de.lproj/RSSFeed.nib/designable.nib index e5590db776..db28d1af71 100644 --- a/lproj/de.lproj/RSSFeed.nib/designable.nib +++ b/lproj/de.lproj/RSSFeed.nib/designable.nib @@ -1,1005 +1,217 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSMenu - NSMenuItem - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSUserDefaultsController - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - RSSFeed - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{165, 318}, {426, 297}} - 1886912512 - RSS Feed - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{194, 16}, {108, 32}} - - - YES - - 67108864 - 134217728 - Abbrechen - - LucidaGrande - 13 - 1044 - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{302, 17}, {113, 32}} - - - 100 - YES - - 67108864 - 134217728 - Abonnieren - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{20, 196}, {75, 17}} - - - YES - - 67108864 - 4194304 - Quelle: - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 256 - {{72, 191}, {175, 26}} - - - YES - - -2080374720 - 1024 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - Adresse - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - 100 - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - 256 - {{20, 263}, {389, 17}} - - - YES - - 67108864 - 4194304 - Ein neues Abonnement erstellen - - LucidaGrande-Bold - 13 - 2072 - - - - - - NO - - - - 256 - {{20, 221}, {378, 34}} - - - YES - - 67108864 - 4194304 - Geben Sie den Link für das Abonnement ein oder wählen Sie eine Quelle aus der Liste. - - LucidaGrande - 10 - 2843 - - - - - - NO - - - - 256 - {{23, 90}, {386, 62}} - - - YES - - -1805647871 - 4325376 - - - LucidaGrande - 11 - 3100 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 256 - {{257, 191}, {21, 24}} - - - YES - - 67108864 - 134217728 - - - - -2038284288 - 33 - - - - - - 200 - 25 - - NO - - - - 256 - {{20, 160}, {270, 17}} - - - YES - - 67108864 - 4194304 - Adresse: - - - - - - NO - - - - 268 - {{21, 52}, {199, 18}} - - - YES - - -2080374784 - 0 - Im Open Reader abonnieren - - - 1211912448 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - NO - - - {426, 297} - - - - {{0, 0}, {1280, 778}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - 3 - 2 - {{305, 336}, {423, 167}} - 1886912512 - RSS Feed - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{307, 12}, {102, 32}} - - 100 - YES - - 67108864 - 134217728 - Speichern - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{199, 12}, {108, 32}} - - - YES - - 67108864 - 134217728 - Abbrechen - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{20, 60}, {383, 62}} - - - YES - - -1805647871 - 4325376 - - - - YES - - - - NO - - - - 256 - {{17, 130}, {389, 17}} - - - YES - - 67108864 - 4194304 - QWJvbm5lbWVudCBiZWFyYmVpdGVuCg - - - - - - NO - - - {423, 167} - - - - {{0, 0}, {1280, 778}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - YES - - - - - - - window - - - - 14 - - - - doSubscribe: - - - - 37 - - - - feedSource - - - - 46 - - - - subscribeButton - - - - 48 - - - - doSave: - - - - 57 - - - - editRSSFeedWindow - - - - 61 - - - - newRSSFeedWindow - - - - 62 - - - - editFeedURL - - - - 69 - - - - saveButton - - - - 70 - - - - editCancelButton - - - - 74 - - - - subscribeCancelButton - - - - 76 - - - - doEditCancel: - - - - 77 - - - - doSubscribeCancel: - - - - 78 - - - - doLinkSourceChanged: - - - - 89 - - - - feedURL - - - - 91 - - - - doShowSiteHomePage: - - - - 93 - - - - siteHomePageButton - - - - 94 - - - - linkTitle - - - - 99 - - - - doGoogleOption: - - - - 118 - - - - googleOptionButton - - - - 119 - - - - value: googleOptionButton - - - - - - value: googleOptionButton - value - googleOptionButton - 2 - - - 117 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - NewRSSFeed - - - 5 - - - - - - - - - - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 40 - - - - - - - - 43 - - - - - - - - 64 - - - - - - - - 65 - - - - - - - - 90 - - - - - - - - 92 - - - - - - - - 97 - - - - - - - - 49 - - - - - - EditRSSFeed - - - 50 - - - - - - - - - - - 53 - - - - - - - - 54 - - - - - - - - 55 - - - - - - - - 67 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - 107 - - - - - 108 - - - - - 109 - - - - - 110 - - - - - 111 - - - - - 112 - - - - - 113 - - - - - 114 - - - - - 44 - - - - - - - - 45 - - - - - -3 - - - Application - - - 115 - - - - - - - - 116 - - - - - 120 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{1012, 565}, {429, 297}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 122 - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - {15, 15} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Abonnement bearbeiten + + + + + + + + + + + diff --git a/lproj/de.lproj/RSSFeed.nib/keyedobjects.nib b/lproj/de.lproj/RSSFeed.nib/keyedobjects.nib index c1358d06c7..f22fe9e614 100644 Binary files a/lproj/de.lproj/RSSFeed.nib/keyedobjects.nib and b/lproj/de.lproj/RSSFeed.nib/keyedobjects.nib differ diff --git a/lproj/de.lproj/SearchFolder.nib/designable.nib b/lproj/de.lproj/SearchFolder.nib/designable.nib index abfe0367ac..30595784cd 100644 --- a/lproj/de.lproj/SearchFolder.nib/designable.nib +++ b/lproj/de.lproj/SearchFolder.nib/designable.nib @@ -1,1600 +1,265 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSBox - NSButton - NSButtonCell - NSCustomObject - NSCustomView - NSMenu - NSMenuItem - NSNumberFormatter - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - SmartFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{234, 142}, {647, 186}} - 1886912512 - - NSPanel - - View - - - {213, 107} - - - 256 - - - - 268 - {{17, 150}, {213, 17}} - - - - YES - - 67108864 - 4194304 - TmFtZSBkZXMgaW50ZWxsaWdlbnRlbiBPcmRuZXJzOgo - - LucidaGrande - 13 - 1044 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 268 - {{235, 148}, {392, 22}} - - - - YES - - -1804599231 - 4195328 - - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{531, 12}, {102, 32}} - - - YES - - 67108864 - 134217728 - OK - - - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{429, 12}, {102, 32}} - - - - YES - - 67108864 - 134217728 - Abbrechen - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 274 - - - - 274 - - - - 274 - {{12, 6}, {584, 38}} - - - - - NSView - - NSResponder - - - {{2, 2}, {609, 50}} - - - - - - {{17, 56}, {613, 54}} - - - - {0, 0} - - 67108864 - 0 - - - LucidaGrande - 11 - 3100 - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 3 - 0 - 0 - NO - - - - 268 - {{17, 118}, {123, 17}} - - - - YES - - 67108864 - 4194304 - Enthält Artikel mit - - - - - - NO - - - - 268 - {{135, 112}, {85, 26}} - - - - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - keiner - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - 3 - YES - YES - 1 - - NO - - - - 268 - {{217, 118}, {301, 17}} - - - - YES - - 67108864 - 272629760 - der folgenden Eigenschaften - - - - - - NO - - - {647, 186} - - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - 256 - - - - 256 - {{-3, 0}, {135, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Field names go here - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - 256 - {{513, -3}, {32, 31}} - - YES - - 67108864 - 134479872 - - - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{302, 3}, {183, 22}} - - YES - - -1804599231 - 4195328 - - - - YES - - - - NO - - - - 256 - {{541, -3}, {32, 31}} - - YES - - 67108864 - 134479872 - + - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{151, 0}, {135, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Operators go here - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{299, 0}, {100, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - - - 400 - 75 - - - Nothing - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{302, 4}, {126, 22}} - - YES - - -1804599231 - 4195328 - - - - - - - - - NaN - - - - 0 - - - . - - , - - - - - 0 - 2 - NO - YES - 1 - P0IPAAAAAAAAAAAAAAAAAA - - - 0 - 1 - NO - YES - 1 - AQAAAAAAAAAAAAAAAAAAAA - - -0 - 0 - - - 0 - -0 - - - - - - - - - . - , - NO - NO - YES - - - YES - - - - NO - - - - -2147483392 - {{299, 0}, {189, 26}} - - 1008 - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Item2 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - Item3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{299, 0}, {189, 26}} - - 1004 - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Item1 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - Item2 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - Item3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - -1 - 3 - YES - YES - 1 - - NO - - - {572, 28} - - NSView - - NSResponder - - - - - - - cancelButton - - - - 40 - - - - saveButton - - - - 41 - - - - searchCriteriaView - - - - 43 - - - - removeCriteriaButton - - - - 44 - - - - addCriteriaButton - - - - 45 - - - - fieldNamePopup - - - - 46 - - - - operatorPopup - - - - 47 - - - - valueField - - - - 49 - - - - window - - - - 50 - - - - addNewCriteria: - - - - 51 - - - - doCancel: - - - - 52 - - - - doSave: - - - - 53 - - - - searchWindow - - - - 54 - - - - removeCurrentCriteria: - - - - 57 - - - - fieldChanged: - - - - 59 - - - - flagValueField - - - - 65 - - - - numberValueField - - - - 70 - - - - folderValueField - - - - 78 - - - - criteriaConditionPopup - - - - 85 - - - - dateValueField - - - - 91 - - - - smartFolderName - - - - 92 - - - - searchCriteriaSuperview - - - - 42 - - - - nextKeyView - - - - 72 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - Search Folder - - - 5 - - - - - - - - - - - - - - - 7 - - - - - - - - 8 - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 37 - - - - - - - - 58 - - - - - - - - 79 - - - - - - - - 84 - - - - - - - - 26 - - - - - - - - - - - - - - SearchCriteriaView - - - 27 - - - - - - - - 29 - - - - - - - - 30 - - - - - - - - 31 - - - - - - - - 35 - - - - - - - - 61 - - - - - - - - 69 - - - - - - - - 73 - - - - - - - - 86 - - - - - - - - 94 - - - - - 95 - - - - - 96 - - - - - 97 - - - - - 98 - - - - - 99 - - - - - - - - 100 - - - - - 101 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - - - - 107 - - - - - - - - 108 - - - - - - - - 109 - - - - - - - - 71 - - - - - 80 - - - - - - - - 82 - - - - - 32 - - - - - - - - 33 - - - - - 34 - - - - - - - - 56 - - - - - 64 - - - - - - - - 62 - - - - - 74 - - - - - - - - - 76 - - - - - 75 - - - - - 87 - - - - - - - - - - 90 - - - - - 89 - - - - - 88 - - - - - -3 - - - Application - - - 36 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 109 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - SmartFolder - NSWindowController - - id - id - id - id - id - - - - addNewCriteria: - id - - - doCancel: - id - - - doSave: - id - - - fieldChanged: - id - - - removeCurrentCriteria: - id - - - - NSButton - NSButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSTextField - NSPopUpButton - NSButton - NSButton - NSView - NSView - NSWindow - NSTextField - NSTextField - - - - addCriteriaButton - NSButton - - - cancelButton - NSButton - - - criteriaConditionPopup - NSPopUpButton - - - dateValueField - NSPopUpButton - - - fieldNamePopup - NSPopUpButton - - - flagValueField - NSPopUpButton - - - folderValueField - NSPopUpButton - - - numberValueField - NSTextField - - - operatorPopup - NSPopUpButton - - - removeCriteriaButton - NSButton - - - saveButton - NSButton - - - searchCriteriaSuperview - NSView - - - searchCriteriaView - NSView - - - searchWindow - NSWindow - - - smartFolderName - NSTextField - - - valueField - NSTextField - - - - IBProjectSource - ./Classes/SmartFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name des intelligenten Ordners: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/de.lproj/SearchFolder.nib/keyedobjects.nib b/lproj/de.lproj/SearchFolder.nib/keyedobjects.nib index 47f359bfe0..22694b21bc 100644 Binary files a/lproj/de.lproj/SearchFolder.nib/keyedobjects.nib and b/lproj/de.lproj/SearchFolder.nib/keyedobjects.nib differ diff --git a/lproj/de.lproj/Vienna Help/advanced.html b/lproj/de.lproj/Vienna Help/advanced.html deleted file mode 100644 index 75a7f3e728..0000000000 --- a/lproj/de.lproj/Vienna Help/advanced.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - Erweiterte Einstellingen - - - - - -  Erweiterte - Einstellungen - -

Der "Erweitert"-Abschnitt der Einstellungen ermöglicht das - Anpassen von spezifischen Optione die für den normalen Gebrauch - nicht notwendig sind, aber eventuelle Probleme beheben helfen - können. Dieser Abschnitt beschreibt die Optionen und ihre - Funktion.

- -

JavaScript im integrierten Browser aktivieren

- -

Aktiviert oder deaktiviert die JavaScript Unterstützung in - Viennas integriertem Web-Browser. Dieser Optione ist - standardmäßig aktiviert. Durch das Abschalten der Unterstützung - wird das Ausführen JavaScript vollständing unterbunden. Dies kann - zum Beispiel dabei helfen, Probleme mit Seiten zu beheben Dieser - durch Skripte Pop-Up Fenster öffnen oder sich sonst unerwartet - Verhalten. Allerdings können auch die Funktion und Anzeige - einiger Webseiten teilweise oder vollständig gestört werden.

- - diff --git a/lproj/de.lproj/Vienna Help/faq.rtfd/TXT.rtf b/lproj/de.lproj/Vienna Help/faq.rtfd/TXT.rtf deleted file mode 100644 index 57b5f51802..0000000000 --- a/lproj/de.lproj/Vienna Help/faq.rtfd/TXT.rtf +++ /dev/null @@ -1,14 +0,0 @@ -{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\froman\fcharset0 Times-Roman;} -{\colortbl;\red255\green255\blue255;\red0\green0\blue233;} -{\info -{\title Was tun?}}\vieww10800\viewh8400\viewkind0 -\deftab720 -\pard\pardeftab720 - -\f0\fs24 \cf0 \pard\pardeftab720 - -\f1 \cf0 \'a0\'a0Was tun?\ -\pard\pardeftab720\sa240 -\cf0 Schauen Sie auf der {\field{\*\fldinst{HYPERLINK "http://www.vienna-rss.org/vienna_faq.html"}}{\fldrslt \cf2 \ul \ulc2 offizelle Vienna Hilfe Seite}} f\'fcr die neusten Tipps und Tricks nach.\ -} \ No newline at end of file diff --git a/lproj/de.lproj/Vienna Help/helpstyle.css b/lproj/de.lproj/Vienna Help/helpstyle.css deleted file mode 100644 index 48a8dcebd1..0000000000 --- a/lproj/de.lproj/Vienna Help/helpstyle.css +++ /dev/null @@ -1,27 +0,0 @@ -a { - color: #3366CC; - text-decoration: none; -} -.title { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 18pt; - color: #000000; -} -.header { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 12pt; - color: #000000; -} -p { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 100; - font-size: 9pt; - color: #000000; -} -tr { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-size: 9pt; - color: #000000; -} \ No newline at end of file diff --git a/lproj/de.lproj/Vienna Help/images/Small-Vienna-Logo.jpg b/lproj/de.lproj/Vienna Help/images/Small-Vienna-Logo.jpg deleted file mode 100644 index 41035b4f11..0000000000 Binary files a/lproj/de.lproj/Vienna Help/images/Small-Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/de.lproj/Vienna Help/images/Vertical-Line.jpg b/lproj/de.lproj/Vienna Help/images/Vertical-Line.jpg deleted file mode 100644 index 011f1ce1e3..0000000000 Binary files a/lproj/de.lproj/Vienna Help/images/Vertical-Line.jpg and /dev/null differ diff --git a/lproj/de.lproj/Vienna Help/images/Vienna-Logo.jpg b/lproj/de.lproj/Vienna Help/images/Vienna-Logo.jpg deleted file mode 100644 index 13a6479bd4..0000000000 Binary files a/lproj/de.lproj/Vienna Help/images/Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/de.lproj/Vienna Help/index.html b/lproj/de.lproj/Vienna Help/index.html deleted file mode 100644 index a0fe6311fe..0000000000 --- a/lproj/de.lproj/Vienna Help/index.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - Vienna Hilfe - - - - - - - - - - -
-

-

Vienna Hilfe

-
- - -

Einleitung zu Vienna

-

Erste Schritte mit Vienna.

- -

Tastatur Kurzbefehle

-

Kurzbefehle für häufig verwendete Befehle

- -

Was tun?

-

Häufig gestellte Fragen, Support und Fehlerbeseitigung.

-
- - diff --git a/lproj/de.lproj/Vienna Help/intro.html b/lproj/de.lproj/Vienna Help/intro.html deleted file mode 100644 index 5c519814b7..0000000000 --- a/lproj/de.lproj/Vienna Help/intro.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - Einleitung zu Vienna - - - -  Einleitung zu Vienna -

Vienna ist ein Programm zum lesen und verwalten von RSS und Atom Feeds auf Mac OSX Computern. Es automatisiert Aufgaben -zum verwalten von Atikeln der abonnierten Feeds und speichert sie in einer lokalen Datenbank um die Artikel auch Offline -lesen zu können. Unterstützte Merkmale sind das Durchsuchen der Feeds nach Schlüsselwörtern und Phrasen, makieren ineressanter -Artikel und zusammenfassen von Feeds in Gruppen. Sie können intelligente Ordner erstellen, die Artikel mit den von ihnen -festgelegten Eigenschaften enthalten. Mit dem intekrierten Browser werden die Artikel Web-Seiten und Links direkt im Programm -in Tabs dargestelllt.

-

Vienna ist für eine einfache Nutzung konzipiert und besitzt eine optimierte Oberfläche für eine bessere Übersicht und -Kontrolle.

- - diff --git a/lproj/de.lproj/Vienna Help/keyboard.html b/lproj/de.lproj/Vienna Help/keyboard.html deleted file mode 100644 index 11391b41d8..0000000000 --- a/lproj/de.lproj/Vienna Help/keyboard.html +++ /dev/null @@ -1,190 +0,0 @@ - - - - - Tastatur-Kürzel - - - -  Tastatur-Kürzel -

Ein Großteil der Funktionen in Vienna können über die Tastatur ausgeführt werden. Die notwendigen Tastatür-Kürzel werden im -Menü neben dem jeweiligen Befehl angezeigt und werden im Folgenden beschrieben. Viele Bedienelemente in Vienna verfügen ausserdem -über Kontext-Menüs, die durch einen Rechtsklick beziehungsweise durch Klicken und halten von Steuerung aktiviert werden können. - -You can use your keyboard to quickly accomplish many tasks in Vienna. To find the shortcuts for common Befehls, look in the menus -(or see the list at the bottom of this page). Many items in Vienna such as the folder pane and the article list pane also have contextual -menus. To see a contextual menu, press the Steuerung key and click the item.

-

Um eine Funktion auszuführen, drücken sie die unten aufgeführten Tastenkombinationen.

- - - - - -
KeyAction
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Ein-Tasten-Kürzel -  
fLegt den Eingabefokus auf das Suchfeld.
rMarkiert die ausgewählten Artikel also gelesen.
sMarkiert den aktuellen Ordner als gelesen und springt zum nächstne.
mMarkiert die ausgewählten Artikel.
<Zeigt den vorigen Artikel oder die vorige Webseite.
>Zeigt den nächsten Artikel oder die nächste Webseite.
SpacebarSpringt zum nächsten ungelesen Artikel. Falls der momentane Artikel noch nicht bis zum Ende gescrollt ist, springt die Anzeige des momentanen Artikels um eine Seite.
Befehl-USpringt zum nächsten ungelesen Artikel.
EnterÖffnet die permanente Webadresse des momentanen Artikels.
LöschenVerschiebt die ausgewählten Artikel in den Papierkorb. Wenn die Taste im Papierkorb gedrückt wird, werden alle darin liegenden Artikel permanente gelöscht.
Allgemeine Tastatur-Kürzel 
Befehl-NEin neues Abonnement erstellen.
Befehl-TAlle Abonnements aktualisieren.
Shift-Befehl-TNur die ausgewählten Abonnements aktualisieren.
Befehl-Minusden momentanen Aktualisierungsvorgang abbrechen.
Befehl-PDie ausgewählten Artikel drucken.
Shift-Befehl-PSeite einrichten.
Befehl-?Aufrufen der Vienna-Hilfe.
Artikelbezogene Tastatur-Kürzel 
Shift-Befehl-MMarkiert die ausgewählten Artikel.
Shift-Befehl-RMarkiert die ausgewählten Artikel als gelesen.
Shift-Befehl-KMarkiert alle ausgewählten Artikel als gelesen.
Fensterbezogene Tastatur-Kürzel 
Befehl-WSchließt das aktuellen Tab. Falls kein Tab aktiv ist, wird das Hauptfenster geschlossen.
Alt-Befehl-WSchließt alle Tabs.
Steuerung-Befehl-Linke PfeiltasteSpringt zum vorigen Tab.
Steuerung-Befehl-Rechte PfeiltasteSpringt zum nächsten Tab.
Shift-Befehl-WSchließt das Hauptfenster und verschiebt Vienna in den Hintergrund. Das Fenster kann durch einen Klick auf Vienna's - Dock-Icon oder das Kürzel Befehl-1 wieder hergestellt werden.
Befehl-MMinimiert Vienna in das Dock.
Befehl-0Aktiviert die Aktivitätenanzeige.
Befehl-1Öffnet das Vienna Hauptfenster falls es zuvor geschlossen wurde.
Befehl-2Aktiviert das "Geladene Dateien"-Fenster.
Browserbezogene Tastatur-Kürzel 
Befehl-RAktualisiert die momentanen Webseite.
Befehl-PunktBricht das laden der aktuellen Webseite ab.
Befehl-[Springt zur vorigen Webseite.
Befehl-]Springt zur nächsten Webseite.
Befehl-FLegt den Eingabefokus auf das Suchfeld. Durch drücken von Enter wird auf der momentanen Webseite nach dem eingegebenen Begriff gesucht.
Befehl-GSucht bis zum nächsten Vorkommen des Suchbegriffes auf der Webseite.
- - \ No newline at end of file diff --git a/lproj/en.lproj/GroupFolder.nib/designable.nib b/lproj/en.lproj/GroupFolder.nib/designable.nib index f55ce48d13..82ddedbeaf 100644 --- a/lproj/en.lproj/GroupFolder.nib/designable.nib +++ b/lproj/en.lproj/GroupFolder.nib/designable.nib @@ -1,502 +1,91 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - NewGroupFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{502, 622}, {388, 149}} - 1886912512 - - Panel - - - NSPanel - - - View - - - {213, 107} - - - 256 - - - - 260 - {{17, 112}, {354, 17}} - - - YES - - 67108864 - 4194304 - New Group Folder - - LucidaGrande-Bold - 13 - 2072 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 258 - {{20, 60}, {348, 22}} - - - YES - - -1804599231 - 272630784 - - - LucidaGrande - 13 - 1044 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{285, 12}, {89, 32}} - - - 100 - YES - - 67108864 - 134217728 - Save - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{203, 12}, {82, 32}} - - - YES - - 67108864 - 134217728 - Cancel - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 268 - {{17, 90}, {353, 14}} - - - YES - - 67108864 - 4194304 - RW50ZXIgdGhlIGdyb3VwIGZvbGRlciBuYW1lOgo - - LucidaGrande - 11 - 3100 - - - - - - NO - - - {388, 149} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - - - - newGroupFolderWindow - - - - 18 - - - - doCancel: - - - - 25 - - - - doSave: - - - - 26 - - - - folderName - - - - 27 - - - - cancelButton - - - - 28 - - - - saveButton - - - - 29 - - - - window - - - - 30 - - - - nextKeyView - - - - 24 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 5 - - - - - - GroupFolder - - - 6 - - - - - - - - - - - - 19 - - - - - - - - 20 - - - - - - - - 21 - - - - - - - - 22 - - - - - - - - 23 - - - - - - - - 32 - - - - - 33 - - - - - 34 - - - - - 35 - - - - - 36 - - - - - -3 - - - Application - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 36 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - NewGroupFolder - NSWindowController - - id - id - - - - doCancel: - id - - - doSave: - id - - - - NSButton - NSTextField - NSWindow - NSButton - - - - cancelButton - NSButton - - - folderName - NSTextField - - - newGroupFolderWindow - NSWindow - - - saveButton - NSButton - - - - IBProjectSource - ./Classes/NewGroupFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Enter the group folder name: + + + + + + + + + + diff --git a/lproj/en.lproj/GroupFolder.nib/keyedobjects.nib b/lproj/en.lproj/GroupFolder.nib/keyedobjects.nib index 3f4597d11d..e78448d2aa 100644 Binary files a/lproj/en.lproj/GroupFolder.nib/keyedobjects.nib and b/lproj/en.lproj/GroupFolder.nib/keyedobjects.nib differ diff --git a/lproj/en.lproj/InfoPlist.strings b/lproj/en.lproj/InfoPlist.strings deleted file mode 100644 index 0097ee642a..0000000000 --- a/lproj/en.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ -NSHumanReadableCopyright = "Copyright 2004-2015 Contributors. See Help/Acknowledgements for list of contributors."; diff --git a/lproj/en.lproj/Localizable.strings b/lproj/en.lproj/Localizable.strings index ba68bd8bc9..b24fd14504 100644 --- a/lproj/en.lproj/Localizable.strings +++ b/lproj/en.lproj/Localizable.strings @@ -449,4 +449,10 @@ "RSS Icon not found!" = "RSS Icon not found!"; /*Added in 3.0.5 */ -"Redirection attempt treated as temporary for safety concern" = "Redirection attempt treated as temporary for safety concern"; \ No newline at end of file +"Redirection attempt treated as temporary for safety concern" = "Redirection attempt treated as temporary for safety concern"; + +/*Added in 3.0.7 */ +"No articles in feed" = "No articles in feed"; + +/*Added in 3.1.2 */ +"Filter folders" = "Search for folders"; diff --git a/lproj/en.lproj/RSSFeed.nib/designable.nib b/lproj/en.lproj/RSSFeed.nib/designable.nib index f4b065204b..8e09300c61 100644 --- a/lproj/en.lproj/RSSFeed.nib/designable.nib +++ b/lproj/en.lproj/RSSFeed.nib/designable.nib @@ -1,1004 +1,220 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSMenu - NSMenuItem - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSUserDefaultsController - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - NSObject - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{165, 318}, {429, 297}} - 1886912512 - RSS Feed - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{208, 9}, {102, 32}} - - - YES - - 67108864 - 134217728 - Cancel - - LucidaGrande - 13 - 1044 - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{310, 9}, {102, 32}} - - - 100 - YES - - 67108864 - 134217728 - Subscribe - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{20, 196}, {75, 17}} - - - YES - - 67108864 - 4194304 - U291cmNlOgo - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 256 - {{99, 189}, {175, 26}} - - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - URL - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - 100 - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - 256 - {{20, 263}, {389, 17}} - - - YES - - 67108864 - 4194304 - Q3JlYXRlIGEgbmV3IHN1YnNjcmlwdGlvbgo - - LucidaGrande-Bold - 13 - 2072 - - - - - - NO - - - - 256 - {{20, 221}, {378, 34}} - - - YES - - 67108864 - 4194304 - Enter the link for the news feed below. Or choose from the Source list to enter a shortcut name for the news feed provided by the source. - - LucidaGrande - 10 - 2843 - - - - - - NO - - - - 256 - {{23, 90}, {386, 62}} - - - YES - - -1805647871 - 4325376 - - - LucidaGrande - 11 - 3100 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 256 - {{283, 189}, {21, 24}} - - - YES - - 67108864 - 134217728 - - - - -2038284288 - 33 - - - - - - 200 - 25 - - NO - - - - 256 - {{20, 160}, {270, 17}} - - - YES - - 67108864 - 4194304 - URL: - - - - - - NO - - - - 268 - {{21, 52}, {185, 18}} - - - YES - - -2080374784 - 0 - Subscribe in Open Reader - - - 1211912448 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - NO - - - {429, 297} - - - - {{0, 0}, {1280, 778}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - 3 - 2 - {{305, 336}, {423, 167}} - 1886912512 - RSS Feed - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{307, 12}, {102, 32}} - - 100 - YES - - 67108864 - 134217728 - Save - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{205, 12}, {102, 32}} - - - YES - - 67108864 - 134217728 - Cancel - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{20, 60}, {383, 62}} - - - YES - - -1805647871 - 4325376 - - - - YES - - - - NO - - - - 256 - {{17, 130}, {389, 17}} - - - YES - - 67108864 - 4194304 - Edit subscription - - - - - - NO - - - {423, 167} - - - {{0, 0}, {1280, 778}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - YES - - - - - - - window - - - - 14 - - - - doSubscribe: - - - - 37 - - - - feedSource - - - - 46 - - - - subscribeButton - - - - 48 - - - - doSave: - - - - 57 - - - - editRSSFeedWindow - - - - 61 - - - - newRSSFeedWindow - - - - 62 - - - - editFeedURL - - - - 69 - - - - saveButton - - - - 70 - - - - editCancelButton - - - - 74 - - - - subscribeCancelButton - - - - 76 - - - - doEditCancel: - - - - 77 - - - - doSubscribeCancel: - - - - 78 - - - - doLinkSourceChanged: - - - - 89 - - - - feedURL - - - - 91 - - - - doShowSiteHomePage: - - - - 93 - - - - siteHomePageButton - - - - 94 - - - - linkTitle - - - - 99 - - - - doGoogleOption: - - - - 118 - - - - googleOptionButton - - - - 119 - - - - value: self.googleOptionButton - - - - - - value: self.googleOptionButton - value - self.googleOptionButton - 2 - - - 125 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - NewRSSFeed - - - 5 - - - - - - - - - - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 40 - - - - - - - - 43 - - - - - - - - 64 - - - - - - - - 65 - - - - - - - - 90 - - - - - - - - 92 - - - - - - - - 97 - - - - - - - - 49 - - - - - - EditRSSFeed - - - 50 - - - - - - - - - - - 53 - - - - - - - - 54 - - - - - - - - 55 - - - - - - - - 67 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - 107 - - - - - 108 - - - - - 109 - - - - - 110 - - - - - 111 - - - - - 112 - - - - - 113 - - - - - 114 - - - - - 44 - - - - - - - - 45 - - - - - -3 - - - Application - - - 115 - - - - - - - - 116 - - - - - 120 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{1012, 565}, {429, 297}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 138 - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - {15, 15} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Source: + + + + + + + + + + + + + + + + + + + + + + + + + + + Create a new subscription + + + + + + + + + + + Enter the link for the news feed below. Or choose from the Source list to enter a shortcut name for the news feed provided by the source. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/en.lproj/RSSFeed.nib/keyedobjects.nib b/lproj/en.lproj/RSSFeed.nib/keyedobjects.nib index 187b070885..40fada5a64 100644 Binary files a/lproj/en.lproj/RSSFeed.nib/keyedobjects.nib and b/lproj/en.lproj/RSSFeed.nib/keyedobjects.nib differ diff --git a/lproj/en.lproj/SearchFolder.nib/designable.nib b/lproj/en.lproj/SearchFolder.nib/designable.nib index b3544e81c7..b309881f70 100644 --- a/lproj/en.lproj/SearchFolder.nib/designable.nib +++ b/lproj/en.lproj/SearchFolder.nib/designable.nib @@ -1,1591 +1,265 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSBox - NSButton - NSButtonCell - NSCustomObject - NSCustomView - NSMenu - NSMenuItem - NSNumberFormatter - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - SmartFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{46, 594}, {647, 186}} - 1886912512 - - NSPanel - - View - - - {213, 107} - - - 256 - - - - 268 - {{17, 150}, {133, 17}} - - - YES - - 67108864 - 4194304 - U21hcnQgZm9sZGVyIG5hbWU6Cg - - LucidaGrande - 13 - 1044 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 268 - {{155, 147}, {178, 22}} - - - YES - - -1804599231 - 4195328 - - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{555, 12}, {78, 32}} - - - YES - - 67108864 - 134217728 - Save - - - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{475, 12}, {82, 32}} - - - YES - - 67108864 - 134217728 - Cancel - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 274 - - - - 274 - - - - 274 - {{12, 6}, {584, 38}} - - - - NSView - - NSResponder - - - {{2, 2}, {609, 50}} - - - - - {{17, 56}, {613, 54}} - - - {0, 0} - - 67108864 - 0 - - - LucidaGrande - 11 - 3100 - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 3 - 0 - 0 - NO - - - - 268 - {{17, 118}, {182, 17}} - - - YES - - 67108864 - 4194304 - Show all articles that match - - - - - - NO - - - - 268 - {{196, 112}, {80, 26}} - - - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - Nothing - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - 268 - {{279, 118}, {301, 17}} - - - YES - - 67108864 - 272629760 - of the following conditions: - - - - - - NO - - - {647, 186} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - 256 - - - - 256 - {{-3, 0}, {135, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Field names go here - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - 256 - {{513, -3}, {32, 31}} - - YES - - 67108864 - 134479872 - - - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{302, 3}, {183, 22}} - - YES - - -1804599231 - 4195328 - - - - YES - - - - NO - - - - 256 - {{541, -3}, {32, 31}} - - YES - - 67108864 - 134479872 - + - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{151, 0}, {135, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Operators go here - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{299, 0}, {100, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - - - 400 - 75 - - - Nothing - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{302, 4}, {126, 22}} - - YES - - -1804599231 - 4195328 - - - - - - - - - NaN - - - - 0 - - - . - - , - - - - - 0 - 2 - NO - YES - 1 - P0IPAAAAAAAAAAAAAAAAAA - - - 0 - 1 - NO - YES - 1 - AQAAAAAAAAAAAAAAAAAAAA - - -0 - 0 - - - 0 - -0 - - - - - - - - - . - , - NO - NO - YES - - - YES - - - - NO - - - - -2147483392 - {{299, 0}, {189, 26}} - - 1008 - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Item2 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - Item3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{299, 0}, {189, 26}} - - 1004 - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Item1 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - Item2 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - Item3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - -1 - 3 - YES - YES - 1 - - NO - - - {572, 28} - - NSView - - NSResponder - - - - - - - cancelButton - - - - 40 - - - - saveButton - - - - 41 - - - - searchCriteriaView - - - - 43 - - - - removeCriteriaButton - - - - 44 - - - - addCriteriaButton - - - - 45 - - - - fieldNamePopup - - - - 46 - - - - operatorPopup - - - - 47 - - - - valueField - - - - 49 - - - - window - - - - 50 - - - - addNewCriteria: - - - - 51 - - - - doCancel: - - - - 52 - - - - doSave: - - - - 53 - - - - searchWindow - - - - 54 - - - - removeCurrentCriteria: - - - - 57 - - - - fieldChanged: - - - - 59 - - - - flagValueField - - - - 65 - - - - numberValueField - - - - 70 - - - - folderValueField - - - - 78 - - - - criteriaConditionPopup - - - - 85 - - - - dateValueField - - - - 91 - - - - smartFolderName - - - - 92 - - - - searchCriteriaSuperview - - - - 42 - - - - nextKeyView - - - - 72 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - Search Folder - - - 5 - - - - - - - - - - - - - - - 7 - - - - - - - - 8 - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 37 - - - - - - - - 58 - - - - - - - - 79 - - - - - - - - 84 - - - - - - - - 26 - - - - - - - - - - - - - - SearchCriteriaView - - - 27 - - - - - - - - 29 - - - - - - - - 30 - - - - - - - - 31 - - - - - - - - 35 - - - - - - - - 61 - - - - - - - - 69 - - - - - - - - 73 - - - - - - - - 86 - - - - - - - - 94 - - - - - 95 - - - - - 96 - - - - - 97 - - - - - 98 - - - - - 99 - - - - - - - - 100 - - - - - 101 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - - - - 107 - - - - - - - - 108 - - - - - - - - 109 - - - - - - - - 71 - - - - - 80 - - - - - - - - 82 - - - - - 32 - - - - - - - - 33 - - - - - 34 - - - - - - - - 56 - - - - - 64 - - - - - - - - 62 - - - - - 74 - - - - - - - - - 76 - - - - - 75 - - - - - 87 - - - - - - - - - - 90 - - - - - 89 - - - - - 88 - - - - - -3 - - - Application - - - 36 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 109 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - SmartFolder - NSWindowController - - id - id - id - id - id - - - - addNewCriteria: - id - - - doCancel: - id - - - doSave: - id - - - fieldChanged: - id - - - removeCurrentCriteria: - id - - - - NSButton - NSButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSTextField - NSPopUpButton - NSButton - NSButton - NSView - NSView - NSWindow - NSTextField - NSTextField - - - - addCriteriaButton - NSButton - - - cancelButton - NSButton - - - criteriaConditionPopup - NSPopUpButton - - - dateValueField - NSPopUpButton - - - fieldNamePopup - NSPopUpButton - - - flagValueField - NSPopUpButton - - - folderValueField - NSPopUpButton - - - numberValueField - NSTextField - - - operatorPopup - NSPopUpButton - - - removeCriteriaButton - NSButton - - - saveButton - NSButton - - - searchCriteriaSuperview - NSView - - - searchCriteriaView - NSView - - - searchWindow - NSWindow - - - smartFolderName - NSTextField - - - valueField - NSTextField - - - - IBProjectSource - ./Classes/SmartFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Smart folder name: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/en.lproj/SearchFolder.nib/keyedobjects.nib b/lproj/en.lproj/SearchFolder.nib/keyedobjects.nib index b65da450ad..48fd073d30 100644 Binary files a/lproj/en.lproj/SearchFolder.nib/keyedobjects.nib and b/lproj/en.lproj/SearchFolder.nib/keyedobjects.nib differ diff --git a/lproj/en.lproj/Vienna Help/advanced.html b/lproj/en.lproj/Vienna Help/advanced.html deleted file mode 100644 index a11dd6f33f..0000000000 --- a/lproj/en.lproj/Vienna Help/advanced.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - Advanced Settings - - - -  Advanced Settings -

The Advanced section of the Preferences provides options to change very specific settings in Vienna that are -not essential for normal use but may resolve some issues as advised by the support forum. This page details the -advanced settings and their function. -

-

Enable JavaScript in internal browser

-

Enables or disables support for JavaScript scripting in the Vienna internal browser. By default this is enabled. By -turning this setting off, JavaScript code on web pages will not be allowed to run. This may resolve problems with pages -that use scripting to pop up windows or other unexpected behaviour but turning the setting off may also cause some web -pages to appear incomplete or fail to function correctly.

- - diff --git a/lproj/en.lproj/Vienna Help/faq.html b/lproj/en.lproj/Vienna Help/faq.html deleted file mode 100644 index 9ab7a8fa96..0000000000 --- a/lproj/en.lproj/Vienna Help/faq.html +++ /dev/null @@ -1,229 +0,0 @@ - - - - - How Do I? - - - -  How Do I? -

Below are some of the more common questions asked about Vienna while it was being pre-release tested. -See the Official Vienna FAQ Page for these -and the latest hints and tips for using Vienna. -

- -

I found -a problem with Vienna. How do I report it?

-

Post a message over in the -Support forum or in the issues list -and somebody will investigate. Provide as much information about the problem -as you can can: the build of Vienna (obtained from the About Vienna panel), -repro steps and what you expected to happen. There is a sticky note in -the forum with tips on how to write a good bug report.

- -

Make sure you're always running the most recent build of Vienna. The -Check for Updates command will report if there's a newer build available -than the one you have.

-

Fixes for bugs take priority over new features so if your problem is -confirmed to be a bug with high impact and no simple workaround then -we'll look at making a fix available as soon as reasonably possible.

- -

- -How can I see what happened when my subscriptions are refreshed?

-

Open the Activity Window from the Window menu. The activity window -shows all subscriptions and the status of the last time they were -refreshed in that session. The bottom of the activity window shows more -details include the HTTP headers and may be useful for debugging. (If -the details pane is not visible, grab the split bar at the bottom of the -Activity Window and drag it up to uncover the pane).

- -

- -How do I subscribe to a feed requiring user authentication?

- -

First, you need to understand that Open Reader services do not provide -authentication to a third party server. Vienna will need to have a direct -access to a server if it requires authentication. So, when you subscribe, make -sure the "Subscribe in Open Reader" checkbox is UNchecked.

- -

Then, it is important to know that there are two main methods that servers -use to authenticate an user who requests an XML feed :

-
    -
  • requiring a username and a password
  • -
  • or requiring a specific cookie
  • -
-

A difficulty lies in the fact that many servers will not explicitly state which -method they require.

- -

Requiring a username and a password is the most frequent method. It is also the most -transparent for the user. On first refresh, Vienna will present you with a dialog box -where you can enter the username and the password that has been provided to you.
-You can check that you have provided these credentials to Vienna (and update them if -necessary) through the 'Info' window associated to the feed (which you can access through -the 'Folder → Get Info…' menu or through the contextual menu you get when you right-click -on the feed in Vienna's left pane).
-Note that the password is securely stored in Apple's Keychain.

- -

For servers which require a cookie, the username and password must NOT be set in the -'Info' window. Both fields MUST be left blank.
-Instead, you will need to log in to the website through Safari or through a web browser -tab in Vienna.
-A problem is that you may need, from time to time, to re-log in again, because cookies can -expire. -

- -

How do -I move my Vienna database to another folder?

- -

By default, your Vienna database is the messages.db file which is -located at ~/Library/Application Support/Vienna. You can move this to -another folder if you wish. The following steps show how:

-
    -
  1. Shut down Vienna.
  2. -
  3. Open a console window and enter:
    -
    -defaults write uk.co.opencommunity.vienna2 -"DefaultDatabase" '<path to new messages.db>'
    - -
    -where <path to new messages.db> is the name of the folder that -contains the messages.db file. The path itself should have the -messages.db filename at the end. For example:
    -
    -defaults write uk.co.opencommunity.vienna2 -"DefaultDatabase" '/Users/steve/mydata/messages.db'
    -
  4. - -
  5. Restart Vienna.
  6. -
-

- -One of my subscriptions reports "Error parsing XML data in feed". What -does this mean?

-

It means that Vienna got a feed back from the subscription that it -couldn't interpret. There are several reasons for this:

- -
    -
  1. The URL of the feed may not be pointing to an RSS or Atom feed -but to a web page. Check the URL of the offending feed carefully.
  2. -
  3. The feed itself may contain malformed XML. Some subscriptions -make a mistake in putting together the XML that makes up the feed -and Vienna cannot interpret malformed XML. Use the Validate Feed -command on the File menu to see if this is the case. Unfortunately -you cannot do much about this in Vienna except wait for the feed -itself to be corrected by the site.
  4. -
  5. The feed may be incomplete. If the refresh was interrupted then -the XML data will be incomplete and will appear malformed in Vienna. -A second refresh may correct this problem.
  6. -
-

If none of the above explain the problem, post a message on the -support forum with the URL of the feed exhibiting the problem.

-

- - -Is there a shortcut key for going to the next article, marking read, -etc?

-

Probably. There are single key equivalents for some of the menu -commands such as:

-

Spacebar - goes to the next unread article. If the current article is -several pages long, it will scroll through that article first. If you're -at the end of the current article it will then go to the next unread -article. By contrast the Next Unread command (Cmd+U) always goes -straight to the next unread article.

-

R - marks the current article read if it is unread, or unread if it -is read.

-

F - flags the current article if it isn't already flagged, or removes -the existing flag if it is not.

- -

Look in the Vienna Help file for more shortcuts.

- -

What do -the green dots mean in the list of articles?

-

The blue dots are for new articles, and the green dots are for updated articles: -articles whose text has changed since they were last downloaded.

- -

How do I use -Auto Expire and what does it do?

-

Auto-expire moves articles older than a certain number of days to the -Trash folder. It allows you to keep your folders manageable by only -retaining articles that are recent. The auto-expire runs both when -Vienna starts and after you have refreshed any subscriptions. To control -the age of articles to auto-expire, change the -"Move articles to Trash" option in Preferences.

-

Auto-expire will NOT remove unread or flagged articles. It assumes -that you haven't read these articles and thus leaves them alone.

- -

How do I create my own styles?

-

See the Custom Styles page for -instructions.

- -

How do I create my own scripts?

- -

Vienna's scripts are written using AppleScript. See the - -Apple resource page for more details.

-

One way to get started is to download one of the existing scripts like -Cortig's original -Share with Papers plugin or -reefdog's Vienna to Yojimbo script -and view them in the AppleScript editor.

- -

To submit your own script, send it the support forum and after it has been reviewed, it will be made available on the -Downloads page.

- -

How do I request -an enhancement in Vienna?

- -

Post a message over at the -issues list.

- -

Where do I get the -Vienna source code?

-

See the Development page for -instructions for getting the source code for Vienna. The source code is -freely available if you're interested in learning how Vienna works, if -you want to build your own copy of Vienna from scratch on your own -machine or if you want to borrow portions for inclusion in your own -project. The source is provided under the -Apache 2.0 -license.

- - diff --git a/lproj/en.lproj/Vienna Help/helpstyle.css b/lproj/en.lproj/Vienna Help/helpstyle.css deleted file mode 100644 index d02689f72e..0000000000 --- a/lproj/en.lproj/Vienna Help/helpstyle.css +++ /dev/null @@ -1,39 +0,0 @@ -a { - color: #3366CC; - text-decoration: none; -} -.title { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 18pt; - color: #000000; -} -.header { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 12pt; - color: #000000; -} -li { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 100; - font-size: 9pt; - color: #000000; -} -h2 { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 400; - font-size: 10pt; - color: #000000; -} -p { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 100; - font-size: 9pt; - color: #000000; -} -tr { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-size: 9pt; - color: #000000; -} \ No newline at end of file diff --git a/lproj/en.lproj/Vienna Help/images/Small-Vienna-Logo.jpg b/lproj/en.lproj/Vienna Help/images/Small-Vienna-Logo.jpg deleted file mode 100644 index 41035b4f11..0000000000 Binary files a/lproj/en.lproj/Vienna Help/images/Small-Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/en.lproj/Vienna Help/images/Vertical-Line.jpg b/lproj/en.lproj/Vienna Help/images/Vertical-Line.jpg deleted file mode 100644 index 011f1ce1e3..0000000000 Binary files a/lproj/en.lproj/Vienna Help/images/Vertical-Line.jpg and /dev/null differ diff --git a/lproj/en.lproj/Vienna Help/images/Vienna-Logo.jpg b/lproj/en.lproj/Vienna Help/images/Vienna-Logo.jpg deleted file mode 100644 index 13a6479bd4..0000000000 Binary files a/lproj/en.lproj/Vienna Help/images/Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/en.lproj/Vienna Help/images/rssfeed.gif b/lproj/en.lproj/Vienna Help/images/rssfeed.gif deleted file mode 100644 index 2dc8935119..0000000000 Binary files a/lproj/en.lproj/Vienna Help/images/rssfeed.gif and /dev/null differ diff --git a/lproj/en.lproj/Vienna Help/index.html b/lproj/en.lproj/Vienna Help/index.html deleted file mode 100644 index fb7b03b57e..0000000000 --- a/lproj/en.lproj/Vienna Help/index.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - Vienna Help - - - - - - - - - - -
-

-

Vienna Help

-
- - -

Introduction to Vienna

-

Learn how to get started with Vienna.

- -

Keyboard Shortcuts

-

Discover keyboard shortcuts for common commands

- -

How Do I?

-

Frequently Asked Questions, getting support and troubleshooting steps.

- -

Advanced Settings

-

Explains the settings in the Advanced Preferences.

-
- - diff --git a/lproj/en.lproj/Vienna Help/intro.html b/lproj/en.lproj/Vienna Help/intro.html deleted file mode 100644 index ab744ef970..0000000000 --- a/lproj/en.lproj/Vienna Help/intro.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - Introduction to Vienna - - - -   -Introduction to Vienna -

Vienna is an application that allows you to read RSS or Atom news feeds on your Mac OS X computer. It automates the -job of retrieving news articles from all subscribed feeds and storing them in a local database for reading off-line. It -provides features that allow you to search feeds for keywords or phrases, tag articles with a flag for future reference -and organise related feeds together under groups. You can create smart folders that make it easy to dynamically retrieve -and view all articles in the database that match a search criteria. The built-in web browser allows you to go to the -articles web page or view links in the article directly in Vienna in separate tabs.

-

Vienna is designed to be simple and easy to use. A clean, uncluttered, interface maximises the space for articles and -just a few controls are needed to perform the most common actions in the user interface.

-Getting Started -

If this is the first time that you have used Vienna then it will have created a new database for you -and added some sample news subscriptions. So go ahead and press Command+R or choose Refresh All Subscriptions -from the File menu to grab the latest articles from those subscriptions.

-

Alternatively, subscribe to your own news feeds. There are various ways to find feeds. When browsing -the web, look out for the RSS feed icon or XML icons indicating that the page has a feed associated -with it. Alternatively almost all online blogging services such as LiveJournal or Blogger provide RSS feeds as -an alternative to reading the postings online.

-

If you know the user name of a blogger on LiveJournal, Blogger, MSN Spaces or Xanga then Vienna makes it easier -to subscribe to their news feed. Start by pressing Command+N or from the File menu, choose the New Subscription command. -In the "Create a new RSS subscription" panel, pick the blogging service from the drop down list and enter the -user name in the input field below. Then choose Subscribe and Vienna will add the subscription to the folder list. If -you are connected to the internet at the time, it will also immediately start collecting articles from the feed.

-

You can also use Vienna in relation with an account in an Open Reader server. Go into Preferences... / Syncing and tick the -"Sync with an Open Reader server" checkbox.
-Beforehand, think about which feeds you prefer reading through Open Reader and which you'll get through direct access. -Vienna will avoid creating duplicates between the two categories, but if you have feeds inside Open Reader -which Vienna already fetches directly, you will have discrepancies between your reading lists. -So, organize your feeds accordingly.
-You should take into account these elements :

-
    -
  • Open Reader feeds can be synchronized across multiple devices/applications supporting it
  • -
  • Open Reader does not support feeds requiring username/password
  • -
  • Fetching feeds directly avoids the Open Reader service as an intermediary between you and the publishing site; -for less "popular" feeds, you'll get articles sooner.
  • -
  • Generally, directly fetching feeds from their original website generates less network traffic. When the server signals there -is no new articles since last fetch, Vienna avoids an useless download.
  • -
-

Normally you need to manually tell Vienna when to refresh all your subscriptions. However you can opt to ask Vienna -to automatically refresh at time intervals. In the General section of the Preferences, pick the desired time interval -from the drop down list next to 'Check for new articles'. Vienna needs to be running for it to automatically refresh -subscriptions.

-

To read articles, press the Spacebar to skip to the next unread article in any subscription. Each article is marked -as read automatically after a short delay. If you prefer to wait until you move to the next unread article before the -current one is marked read you can adjust the behaviour in the General tab of the Preferences. To mark an article as -unread again, choose the Mark Unread command from the Article menu or simply press the 'R' key.

-

Finally, you can view the article web page or any web page links in an article within Vienna. By default clicking -on a web link within Vienna will open the web page in a new tab. Vienna provides a lot of basic web browsing support -itself but there may be times when you will prefer to open links in your default web browser. If you prefer to view -all web pages outside of Vienna then enable the 'Open links in external browser' option in the General section of the -Preferences. However if you prefer to view the current link or page in your external browser, right click on the page -and choose the "Open Link in XXX" or "Open Page in XXX" option where XXX will be the name of your default browser.

-

Once you've got comfortable using Vienna, go ahead and explore the various options. You can change the style in -which the articles are displayed through the Style drop down list in the View menu. You can find many more custom -styles at the Downloads page on the Vienna web site along with custom scripts that allow you to integrate Vienna with -other applications on your machine. Or experiment with smart folders to organise articles according to criteria based -on the contents of each article. For example, you can easily set up a smart folder to group together all articles that -mention "Joss Whedon" and "Firefly" to find references to the Firefly cult series or the spin-off movie.

-

If you have any questions about Vienna or run into problems, send an email to Vienna Help or head over to the -Support forum.

- - diff --git a/lproj/en.lproj/Vienna Help/keyboard.html b/lproj/en.lproj/Vienna Help/keyboard.html deleted file mode 100644 index 059ff5b04e..0000000000 --- a/lproj/en.lproj/Vienna Help/keyboard.html +++ /dev/null @@ -1,312 +0,0 @@ - - - - - Keyboard Shortcuts - - - -  Keyboard Shortcuts -

You can use your keyboard to quickly accomplish many tasks in Vienna. To find the shortcuts for common commands, look in the menus -(or see the list at the bottom of this page). Many items in Vienna such as the folder pane and the article list pane also have contextual -menus. To see a contextual menu, press the Control key and click the item.

-

To do an action, press the shortcut keys indicated below.

- - - - - -
KeyAction
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Single Key Shortcuts -  
bMoves to the first unread article.
fOpens the filter bar and puts the focus on the filter search field.
hPuts the focus on the search articles field.
kMarks the current folder read.
mToggles the selected articles flagged or unflagged.
nMoves to the next unread article.
rToggles the selected articles read and unread.
uToggles the selected articles read and unread.
sMarks the current folder read then skips to the next folder with unread articles.
< or ,Displays the previous viewed article or web page.
> or .Displays the next viewed article or web page.
LeftMoves the focus to the folder list if it is currently in the article list.
RightMoves the focus to the article list if it is currently in the folder list.
SpacebarMoves to the next unread article unless the current article has more text to scroll in which case it scrolls the current article up one page.
Enter/ReturnOpens the selected article's original web page.
Delete/BackspaceMoves the selected articles to the Trash folder. If this key is used in the Trash folder, the selected articles are permanently deleted.
General Shortcuts 
Alt-ClickOpen the clicked link, overriding your preference for opening links in external browser.
Shift-Command-BOpens the filter bar.
Command-NCreate a new subscription.
Shift-Command-FCreate a smart folder.
Shift-Command-EEdit the selected folder URL or edit a smart folder criteria.
Shift-Command-DDelete the selected folder.
Command-CCopies the selected text to the clipboard. If the focus is on an article, it copies the article details to the clipboard.
Command-HHides the Vienna main window.
Alt-Command-HHides all other application windows but keeps the Vienna main window visible.
Command-IDisplays the Info window for the selected folder.
Command-LPuts the focus on the address bar of the current tab. Or if no browser is open and has the focus, opens a new tab and puts the focus on the address bar.
Shift-Command-NRename the selected folder.
Command-RRefreshes all subscriptions.
Shift-Command-RRefresh only those subscriptions selected in the folder list.
Control-Command-SStops any active refresh.
Command-PPrint the selected articles.
Shift-Command-PBrings up the Page Setup panel.
Command-QExit Vienna.
Command-TOpens a new tab and puts the focus on the address bar.
Command-UMoves to the next unread article.
Command-ZUndoes the last action, if it can be undone.
Command-/Toggles the status bar on or off.
Command-+Increases the size of the text in the current article or web page.
Command--Decreases the size of the text in the current article or web page.
Command-,Opens the Vienna preferences panel.
Alt-Command-BackspaceEmpties the trash folder after prompting for confirmation.
Command-?Displays the Vienna help book.
Articles Shortcuts 
Alt-Enter/Alt-ReturnOpens the selected article's original web page, overriding your preference for opening links in external browser.
Shift-Command-ZRedo the last action, if it was previously undone.
Shift-Command-MFlags the selected articles.
Shift-Command-UMarks the selected articles read.
Alt-Command-SUses your default mail application to send a link to the current article by e-mail.
Shift-Command-SMarks the current folder read then skips to the next folder with unread articles.
Shift-Command-ORestores an article from the trash back to its original folder.
Shift-Command-KMarks all articles in the selected folders read.
Alt-Command-KMarks all articles in all folders read.
Window Shortcuts 
Command-WCloses the active tab window if one is open. Otherwise if no - tabs are open, this closes the Vienna window.
Alt-Command-WCloses all tab windows. Note that this command replaces the Close Tab - command on the File menu when the Alt key is held down.
Alt-Command-LeftDisplays the previous tab window.
Alt-Command-RightDisplays the next tab window.
Command-MMinimizes the Vienna window to the dock.
Command-0Displays the activity log viewer window.
Command-1Reopens the Vienna window if it was previously closed.
Command-2Displays the Downloads window.
Browser Window Shortcuts 
Alt-RReloads the current web page.
Command-PeriodCancels loading of the current web page.
Command-[/Command-LeftGoes back to the previous web page.
Command-]/Command-RightGoes forward to the next web page.
Command-FPuts the input focus in the search field. Entering some text here and - pressing Enter will search for that text on the current web page.
Command-GSearches for the next occurrence of the search text on the web page.
- - \ No newline at end of file diff --git a/lproj/es.lproj/EmptyTrashWarning.strings b/lproj/es.lproj/EmptyTrashWarning.strings old mode 100755 new mode 100644 diff --git a/lproj/es.lproj/FeedCredentials.strings b/lproj/es.lproj/FeedCredentials.strings old mode 100755 new mode 100644 diff --git a/lproj/es.lproj/InfoPlist.strings b/lproj/es.lproj/InfoPlist.strings deleted file mode 100755 index acb24200a2..0000000000 --- a/lproj/es.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ -NSHumanReadableCopyright = "Copyright 2004-2015 Colaboradores. Ayuda/Agradecimientos para ver la lista de colaboradores."; diff --git a/lproj/es.lproj/InfoWindow.nib/designable.nib b/lproj/es.lproj/InfoWindow.nib/designable.nib old mode 100755 new mode 100644 diff --git a/lproj/es.lproj/InfoWindow.nib/keyedobjects.nib b/lproj/es.lproj/InfoWindow.nib/keyedobjects.nib old mode 100755 new mode 100644 diff --git a/lproj/es.lproj/InfoWindow.strings b/lproj/es.lproj/InfoWindow.strings old mode 100755 new mode 100644 diff --git a/lproj/es.lproj/Localizable.strings b/lproj/es.lproj/Localizable.strings index dc6ef0633a..4a45d963ec 100644 --- a/lproj/es.lproj/Localizable.strings +++ b/lproj/es.lproj/Localizable.strings @@ -450,4 +450,10 @@ "RSS Icon not found!" = "¡Icono de la suscripción no encontrado!"; /*Added in 3.0.5 */ -"Redirection attempt treated as temporary for safety concern" = "Redirection attempt treated as temporary for safety concern"; \ No newline at end of file +"Redirection attempt treated as temporary for safety concern" = "Intento de redirección tratado como temporal por problemas de seguridad"; + +/*Added in 3.0.7 */ +"No articles in feed" = "No hay artículos en la fuente"; + +/*Added in 3.1.2 */ +"Filter folders" = "Filtrar carpetas"; diff --git a/lproj/es.lproj/RSSFeed.nib/designable.nib b/lproj/es.lproj/RSSFeed.nib/designable.nib old mode 100755 new mode 100644 diff --git a/lproj/es.lproj/RSSFeed.nib/keyedobjects.nib b/lproj/es.lproj/RSSFeed.nib/keyedobjects.nib old mode 100755 new mode 100644 diff --git a/lproj/es.lproj/RSSFeed.strings b/lproj/es.lproj/RSSFeed.strings old mode 100755 new mode 100644 diff --git a/lproj/es.lproj/SearchFolder.strings b/lproj/es.lproj/SearchFolder.strings old mode 100755 new mode 100644 diff --git a/lproj/es.lproj/Vienna Help/advanced.html b/lproj/es.lproj/Vienna Help/advanced.html deleted file mode 100644 index 5206a03a02..0000000000 --- a/lproj/es.lproj/Vienna Help/advanced.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - Preferencias avanzadas - - - - -  Preferencias - avanzadas -

La seccin Avanzado de las preferencias da al usuario la - posibilidad de cambiar algunos ajustes muy especficos de Vienna - que no son esenciales para el uso normal de la aplicacin pero - que podran resolver algunas incidencias tal y como se sugiere en - el foro de ayuda. Esta pgina detalla las preferencias avanzadas - y su funcin.

-

Habilitar el uso de JavaScript en el navegador - interno

-

Activa o desactiva el soporte para JavaScript en el navegador - integrado de Vienna. Javascript est activado por defecto. - Desactivndolo el cdigo programado por JavaScript no funcionar. - Este hecho podra ayudar a resolver algunas incidencias con - pginas que utilizan este tipo de cdigo -por ejemplo, ventanas - emergentes-. Sin embargo, tambin podra causar comportamientos - inesperados. Desactivar JavasScript tambin podra provocar que - algunas pginas apareciesen incompletas o no se mostrasen y/o - funcionasen tal y como se prevee.

- - diff --git a/lproj/es.lproj/Vienna Help/faq.html b/lproj/es.lproj/Vienna Help/faq.html deleted file mode 100644 index 4c500882d7..0000000000 --- a/lproj/es.lproj/Vienna Help/faq.html +++ /dev/null @@ -1,224 +0,0 @@ - - - - - - - Cmo puedo...? - - - - -  Cmo - puedo...? -

Le presentamos algunas de las preguntas ms frecuentes acerca - de Vienna. Consulte el F.A.Q. oficial - para obtener respuestas ms concretas y, obviamente, tambin los - ltimos consejos prcticos para el uso de Vienna.

- -

Dnde puedo conseguir el - cdigo de Vienna?

-

Consulte la pgina de - desarrollo para conocer la manera de obtener el cdigo de - Vienna. El cdigo est a libre disposicin de todo aquel que - quiera conocer cmo funciona Vienna. Tambin est disponible para - quien desee construir su propia copia de Vienna desde cero en su - propio ordenador o bien quiera incluir partes del cdigo en su - propio proyecto. El cdigo se distribuye bajo licencia Apache - 2.0.

-

He - apreciado un problema en Vienna. Cmo informo de ello?

-

Escriba en el foro de soporte y alguien investigar sobre - ello. Entregue tanta informacin como pueda acerca del problema. - No olvide especificar la versin de Vienna utilizada (se obtiene - en el men Acerca de Vienna), los pasos previos al error y lo que - esperaba que ocurriera.

-

Asegrese de que utiliza siempre la ltima versin de Vienna. - El men Comprobar si hay actualizaciones le informar en el caso - que existan versiones ms recientes que la que usted posee.

-

Tenga presente que solventar errores goza de mayor prioridad - que incluir nuevas caractersticas. En el que caso de que se - confirme que su problema es un error reconocido y generalizado se - intentar dar una solucin en un plazo razonable de tiempo.

-

Cmo puedo crear mis propios - estilos?

-

Consulte la pgina de - personalizacin de estilos para obtener las correspondientes - instrucciones.

-

Cmo puedo crear mis propios - scripts?

-

Los scripts de Vienna se escriben utilizando AppleScript. - Consulte la - pgina de recursos de Apple para obtener ms detalles acerca - de l y de su uso.

-

Una manera de comenzar es descargar uno de los scripts ya - existentes en la pgina de descargas - de Vienna y abrirlo con el editor de AppleScripts. Consulte - tambin la pgina de - scripts para obtener ms detalles de los scripts para Vienna - y ejemplos de lo que se puede conseguir.

-

Si desea presentar su propio script a la comunidad de usuarios - de la aplicacin, envelo a steve@opencommunity.co.uk - y una vez haya sido probado, se pondr a disposicin de todos en - la pgina de descargas.

-

- Cmo puedo comprobar si mis suscripciones se han - actualizado?

-

Abra la pgina de actividad del men Ventana. La ventana de - actividad muestra todas las suscripciones y la situacin que - tenan la ltima vez que fueron actualizadas durante la presente - sesin. La parte inferior de la ventana de actividad muestra ms - detalles. Entre stos se incluyen los encabezados HTTP, que - podran ser tiles para detectar y eliminar fallos. Si el panel - de actividades no est visible, puede hacerlo aparecer - arrastrando hacia la parte superior la barra inferior de la - ventana.

-

Cmo - puedo mover la base de datos de Vienna a otra carpeta?

-

Por defecto, la base de datos de Vienna es el archivo - messages.db que se encuentra en ~/Library/Application - Support/Vienna. Usted puede moverlo a la carpeta que desee. Los - pasos a realizar son los siguientes:

-
    -
  1. Salga de Vienna.
  2. -
  3. Abra una ventana de la consola e introduzca el siguiente - texto:
    -
    - defaults write - uk.co.opencommunity.vienna2 "DefaultDatabase" '<path to new - messages.db>'
    -
    - donde pone <path to new messages.db> es el nombre de la - nueva carpeta que contiene el archivo messages.db. La ruta debe - incluir el archivo messages.db al final. Un ejemplo:
    -
    - defaults write - uk.co.opencommunity.vienna2 "DefaultDatabase" - '/Users/steve/mydata/messages.db'
  4. -
  5. Reinicie Vienna.
  6. -
-

- Una de mis suscripciones muestra el mensaje Se ha producido un - error al procesar los datos XML de la fuente. Qu - significa?

-

Significa que Vienna ha obtenido una respuesta de la - suscripcin que no ha podido interpretar. Hay varias razones para - ello:

-
    -
  1. La URL de la suscripcin podra no redirigir a una fuente - RSS o Atom sino a una pgina web. Compruebe la direccin - URL.
  2. -
  3. La fuente de noticias podra contener XML incorrecto. - Algunas suscripciones cometen un error al unir el XML que - compone la fuente y por ello Vienna no puede interpretarlo. - Utilice el comando Validar la fuente para comprobar si es el - caso. Desafortunadamente no se puede hacer gran cosa ms que - esperar que se corrija desde la propia pgina.
  4. -
  5. La fuente de noticias podra estar incompleta. Si la - actualizacin ha sido interrumpida, probablemente el archivo - XML est incompleto y aparece como incorrecto para Vienna. Una - segunda actualizacin podra resolver el problema.
  6. -
-

Si ninguna de las posibilidades arriba mencionadas explica el - mensaje de error, escriba un mensaje en el foro de soporte, - incluyendo la direccin URL de la suscripcin que muestra el - problema.

-

- Hay alguna funcin rpida de teclado para pasar al siguiente - artculo, marcar como ledo, etc?

-

Probablemente. Existen algunas funciones rpidas de teclado - para algunos comandos del men. Algunos de ellos son:

-

Barra espaciadora - Dirige al siguiente artculo no ledo. Si - el artculo seleccionado tiene varias pginas, se desplazar - primero por el artculo. Sin embargo, el comando Siguiente - artculo no ledo (Comando-U) siempre se dirige directamente al - siguiente artculo no ledo.

-

R - Marca el artculo seleccionado como ledo si no lo est - todava, o bien como no ledo si es que ya ha sido ledo.

-

F - Marca con indicador el artculo seleccionado si no ha sido - marcado previamente, o bien elimina la marca si lo ha sido.

-

Consulte la ayuda de Vienna para obtener ms funciones rpidas - de teclado.

-

Cmo puedo - utilizar la auto-eliminacin de artculos y qu hace - exactamente?

-

La auto-eliminacin de artculos mueve a la papelera los - artculos que superan una determinada antigedad. Esto le permite - mantener de manera manejable las carpetas guardando nicamente - los artculos recientes. La auto-eliminacin de artculos - funciona tanto cuando se inicia Vienna como cuando se ha - actualizado cualquier suscripcin. Para especificar una nueva - fecha mxima de los artculos sujetos a la auto-eliminacin, - cambie la opcin Mover los artculos a la papelera en las - preferencias de la aplicacin.

-

La auto-eliminacin no eliminar artculos no ledos o con - indicador. Vienna entiende que ya que no ha ledo estos artculos - no desea eliminarlos todava .

-

Cmo puedo sugerir - una mejora para Vienna?

-

Escriba un mensaje en el foro de - soporte. Todas las mejoras son incluidas en un archivo - To-Do que se incluye en el cdigo como gua para futuros - desarrollos.

- - diff --git a/lproj/es.lproj/Vienna Help/helpstyle.css b/lproj/es.lproj/Vienna Help/helpstyle.css deleted file mode 100644 index d02689f72e..0000000000 --- a/lproj/es.lproj/Vienna Help/helpstyle.css +++ /dev/null @@ -1,39 +0,0 @@ -a { - color: #3366CC; - text-decoration: none; -} -.title { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 18pt; - color: #000000; -} -.header { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 12pt; - color: #000000; -} -li { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 100; - font-size: 9pt; - color: #000000; -} -h2 { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 400; - font-size: 10pt; - color: #000000; -} -p { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 100; - font-size: 9pt; - color: #000000; -} -tr { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-size: 9pt; - color: #000000; -} \ No newline at end of file diff --git a/lproj/es.lproj/Vienna Help/images/Small-Vienna-Logo.jpg b/lproj/es.lproj/Vienna Help/images/Small-Vienna-Logo.jpg deleted file mode 100644 index 41035b4f11..0000000000 Binary files a/lproj/es.lproj/Vienna Help/images/Small-Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/es.lproj/Vienna Help/images/Vertical-Line.jpg b/lproj/es.lproj/Vienna Help/images/Vertical-Line.jpg deleted file mode 100644 index 011f1ce1e3..0000000000 Binary files a/lproj/es.lproj/Vienna Help/images/Vertical-Line.jpg and /dev/null differ diff --git a/lproj/es.lproj/Vienna Help/images/Vienna-Logo.jpg b/lproj/es.lproj/Vienna Help/images/Vienna-Logo.jpg deleted file mode 100644 index 13a6479bd4..0000000000 Binary files a/lproj/es.lproj/Vienna Help/images/Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/es.lproj/Vienna Help/images/rssfeed.gif b/lproj/es.lproj/Vienna Help/images/rssfeed.gif deleted file mode 100644 index 2dc8935119..0000000000 Binary files a/lproj/es.lproj/Vienna Help/images/rssfeed.gif and /dev/null differ diff --git a/lproj/es.lproj/Vienna Help/index.html b/lproj/es.lproj/Vienna Help/index.html deleted file mode 100755 index 51c8349c0a..0000000000 --- a/lproj/es.lproj/Vienna Help/index.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - Ayuda de Vienna - - - - - - - - - - -
-

-

Ayuda de Vienna

-
-

Introduccin a Vienna

-

Aprenda como empezar con - Vienna.

-

Atajos de teclado

-

Descubra los atajos de teclado - para los comandos frecuentes.

-

Cmo hacer?

-

Preguntas frecuentes, obtener - soporte y pasos de resolucin de problemas.

-

Configuracin avanzada

-

Explica la configuracin en - las preferencias avanzadas.

-
- - diff --git a/lproj/es.lproj/Vienna Help/intro.html b/lproj/es.lproj/Vienna Help/intro.html deleted file mode 100644 index d34914be40..0000000000 --- a/lproj/es.lproj/Vienna Help/intro.html +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - - Introduccin a Vienna - - - - -   Introduccin a - Vienna -

Vienna es una aplicacin que le permite leer las fuentes de - noticias RSS o Atom en su ordenador con Mac OS X. Automatiza el - trabajo de conseguir artculos de noticias de todas las fuentes - suscritas y las guarda en una base de datos local, lo que permite - que los artculos tambin puedan ser ledos cuando no hay - disponible una conexin a la red. Asimismo incluye opciones de - bsqueda que le permiten buscar palabras o frases clave en los - artculos, marcar artculos con un indicador para tener - referencias u organizar las fuentes de artculos relacionadas en - grupos. Tambin puede crear carpetas inteligentes que obtienen y - muestran de manera fcil y dinmica los artculos en funcin de - un determinado criterio de bsqueda. El navegador integrado - - dotado con un sistema de pestaas - le permite ver los artculos - o enlaces de las pginas web desde el mismo Vienna.

-

Vienna est diseado para ofrecer una gran facilidad de uso. - Posee una interfaz limpia y sencilla que maximiza el espacio para - los artculos. Y apenas se necesitan unos pocos controles para - llevar a cabo las acciones ms frecuentes.

Primeros - pasos -

Si sta es la primera vez que utiliza Vienna se habr creado - automticamente una base de datos y aadido a ella algunas - suscripciones. Para actualizarlas pulse Comando-T o bien escoja - la opcin Actualizar todas las suscripciones que se encuentra en - el men Archivo.

-

Obviamente, puede suscribirse a todas las fuentes de noticias - que usted desee. Hay varias maneras de encontrar fuentes. Cuando - navegue por la web busque el - o el icono XML que indica que la pgina tiene una fuente de - noticias asociada a ella. Por lo general, prcticamente todos los - servicios de publicacin de blogs, por ejemplo LiveJournal o - Blogger/Blogspot, incluyen las fuentes RSS como altenativa a la - lectura de contenidos en la propia pgina.

-

Si conoce el nombre de un usuario de LiveJournal, - Blogger/Blogspot, MSN Spaces or Xanga, Vienna le proporciona una - fcil manera de suscribirse a esa fuente. Empiece pulsando - Comando-N o bien seleccionando la opcin Crear una nueva - suscripcin en el men Archivo. En el cuadro de dilogo Crear una - nueva suscripcin escoja el servicio de publicacin de blogs que - hay en la lista desplegable e introduzca el nombre de usuario en - el campo inferior. Pulse Suscribirse y Vienna aadir la - suscripcin a la lista de fuentes. Si en ese momento est - conectado a internet automticamente se iniciar la descarga de - los artculos disponibles en la fuente.

-

Es muy comn actualizar las suscripciones de manera manual. - Sin embargo, puede optar por la posibilidad de que Vienna lo haga - automticamente tras un determinado periodo de tiempo. Para ello, - dirjase a Preferencias y escoja el intervalo de tiempo deseado - en la opcin Comprobar si hay nuevos artculos. Tenga en cuenta - que Vienna necesita estar ejecutndose -ya sea en segundo plano- - para actualizar automticamente las suscripciones.

-

Al leer los artculos pulse la barra espaciadora y as saltar - al siguiente artculo no ledo de cualquier suscripcin. Cada - artculo recibe el estado de Ledo tras un breve lapso de tiempo. - Si prefiere esperar a leer un nuevo artculo para que que se - produzca este hecho dirjase a Preferencias. Para marcar de nuevo - como no ledo un artculo, simplemente pulse la tecla R o - seleccione la opcin Marcar como no ledo disponible en el men - Archivo.

-

Usted puede ver cualquier artculo o enlace con el propio - Vienna. Por defecto al seleccionar un enlace har que se abra una - nueva pestaa con el nuevo contenido. Vienna proporciona una - navegacin similar a los actuales navegadores, pero habr - ocasiones en las que prefiera hacerlo con su navegador preferido. - Si desea ver siempre en su navegador las pginas web, active en - Preferencias la opcin Abrir enlaces en un navegador externo. No - obstante, si nicamente desea visualizar el artculo seleccionado - en ese momento en un navegador externo, haga clic en el botn - derecho del ratn o pulse Comando a la vez que hace clic con el - mencionado ratn y elija la opcin Abrir pgina con XXX (XXX es - el nombre de su navegador por defecto).

-

Una vez se haya familiarizado a las caractersticas y uso de - Vienna puede explorar opciones ms avanzadas. Por ejemplo, puede - cambiar el estilo en el que se muestran los artculos gracias a - las diferentes posibilidades que se ofrecen en la lista - desplegable que encontrar en el men Ver. Tiene a su disposicin - ms estilos en la pgina de descargas de Vienna. All tambin - encontrar scripts que le permitirn ampliar las posibilidades de - uso de la aplicacin: podr hacer que Vienna se relacione de - manera ms directa con otras aplicaciones de su sistema. Otras - posibilidad de uso avanzado es la creacin de carpetas - inteligentes en funcin del contenido de los artculos. Una - muestra de ello podra ser el crear fcilmente una carpeta que - guarde todos los artculos que hagan referencia por ejemplo a U2 - y Bono. De este modo encontrar rpidamente informacin acerca de - la actividad del grupo o las campaas de sensibilizacin en las - que participa el cantante irlands.

-

Si tiene cualquier pregunta acerca de Vienna o no logra - resolver algn problema, dirjase al foro de - soporte.

- - diff --git a/lproj/es.lproj/Vienna Help/keyboard.html b/lproj/es.lproj/Vienna Help/keyboard.html deleted file mode 100644 index 17d81cdf4b..0000000000 --- a/lproj/es.lproj/Vienna Help/keyboard.html +++ /dev/null @@ -1,256 +0,0 @@ - - - - - - - Funciones rpidas de teclado - - - - -  Funciones rpidas de - teclado -

Puede utilizar su teclado para llevar a cabo rpidamente - muchas acciones en Vienna. Para encontrar las combinaciones de - teclas para las acciones ms frecuentes, consulte en los mens o - bien desplcese hacia el final de esta pgina. Recuerde que - muchos tems en Vienna disponen de men contextual. Para acceder - a ellos, pulse la tecla Control y haga clic sobre el tem - seleccionado.

-

Para llevar a cabo una accin, pulse las siguientes - combinaciones de teclado.

- - - - - -
TeclaAccin
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Funciones rpidas de teclado 
fDesplaza el cursor al cajn de bsqueda.
rMarca el artculo seleccionado como ledo.
sMarca todo el contenido de la carpeta seleccionada como - ledo y salta a la siguiente carpeta con artculos no - ledos.
kMarca la carpeta seleccionada como leda.
mMarca con indicador el artculo seleccionado.
<Muestra el artculo o pgina web previa.
>Muestra el siguiente artculo o pgina web.
Barra espaciadoraMuestra el siguiente artculo no ledo. En el caso de que - el artculo seleccionado disponga de ms de una pgina, se - mostrar la siguiente pgina del artculo.
Comando-UMuestra el siguiente artculo no ledo.
AceptarAbre la pgina original del artculo seleccionado.
SuprimirEnva el artculo seleccionado a la papelera. Si esta - funcin se utiliza dentro de la papelera, el artculo se - eliminar de manera permantente.
Funciones rpidas de teclado - generales 
Comando-NCrea una nueva suscripcin.
Shift-Comando-FCrea una nueva carpeta inteligente.
Shift-Comando-EEdita la direccin URL de la suscripcin seleccionada o - los criterios de una carpeta inteligente.
Shift-Comando-DElimina la carpeta seleccionada.
Shift-Comando-NRenombra la carpeta seleccionada.
Comando-RActualiza todas las suscripciones.
Shift-Comando-RActualiza nicamente las suscripciones - seleccionadas.
Comando-MinusCancela cualquier actualizacin que se est - produciendo.
Comando-PImprime el artculo seleccionado.
Shift-Comando-PMuestra la configuracin de pgina.
Shift-Comando-VValida la fuente de noticias.
Comando-?Muestra la ayuda de Vienna.
Funciones rpidas de teclado para artculos 
Shift-Comando-MMarca con indicador los artculos seleccionados.
Shift-Comando-UMarca como ledos los artculos seleccionados.
Shift-Comando-SMarca como leda la carpeta seleccionada y se desplaza a - la siguiente carpeta con artculos no ledos.
Shift-Comando-ORestaura un artculo desde la papelera a su carpeta - original.
Shift-Comando-KMarca como ledos todos los artculos de las carpetas - seleccionadas.
Alt-Comando-KMarca como ledos todos los artculos de todas las - carpetas.
Funciones rpidas de teclado para ventanas 
Comando-WCierra la pgina activa en el caso de que haya alguna. De - no haber ninguna, cierra la propia ventana principal de - Vienna.
Alt-Comando-WCierra todas las pestaas. Tenga en cuenta que que esta - accin sustituye al comamndo Cerrar pestaa del men - Archivo.
Control-Comando-IzquierdaMuestra la pestaa anterior.
Control-Comando-DerechaMuestra la pestaa siguiente.
Shift-Comando-WCierra la pantalla principal de Vienna pero deja a la - aplicacin ejecutndose en segundo plano. Puede acceder de - nuevo a la ventana principal haciendo clic en el icono de - Vienna o pulsando Comando-1.
Comando-MMinimiza la ventana de Vienna en el dock.
Comando-0Muestra la ventana de actividad.
Comando-1Muestra la ventana principal de Vienna.
Comando-2Muestra la ventana de descargas.
Funciones rpidas de teclas de ventana 
Alt-RActualiza la pgina web seleccionada.
Comando-PeriodCancela la carga de la pgina web seleccionada.
Comando-[/Comando-IzquierdaMuestra la anterior pgina web seleccionada.
Comando-]/Comando-DerechaMuestra la siguiente pgina web seleccionada.
Comando-FDesplaza el cursor al cajn de bsqueda. Escriba alguna - palabra y/o texto, pulse la tecla Aceptar y Vienna buscar en - la pgina web seleccionada su solicitud.
Comando-GBusca la siguiente acepcin del cajn de bsqueda en la - pgina web.
- - diff --git a/lproj/es.lproj/errorpage.html b/lproj/es.lproj/errorpage.html old mode 100755 new mode 100644 diff --git a/lproj/eus.lproj/GroupFolder.nib/designable.nib b/lproj/eus.lproj/GroupFolder.nib/designable.nib index 022fefa319..e9ced379e1 100644 --- a/lproj/eus.lproj/GroupFolder.nib/designable.nib +++ b/lproj/eus.lproj/GroupFolder.nib/designable.nib @@ -1,500 +1,91 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - NewGroupFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{502, 622}, {388, 149}} - 1886912512 - Panela - - NSPanel - - - View - - - {213, 107} - - - 256 - - - - 260 - {{17, 112}, {354, 17}} - - - YES - - 67108864 - 4194304 - Talde Berrirako Direktorioa - - LucidaGrande-Bold - 13 - 2072 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 258 - {{20, 60}, {348, 22}} - - - YES - - -1804599231 - 272630784 - - - LucidaGrande - 13 - 1044 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{285, 12}, {89, 32}} - - - 100 - YES - - 67108864 - 134217728 - Gorde - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{203, 12}, {82, 32}} - - - YES - - 67108864 - 134217728 - Ezeztatu - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 268 - {{17, 90}, {353, 14}} - - - YES - - 67108864 - 4194304 - U2FydHUgdGFsZGVhcmVuIGRpcmVrdG9yaW9hcmVuIGl6ZW5hOgo - - LucidaGrande - 11 - 3100 - - - - - - NO - - - {388, 149} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - - - - newGroupFolderWindow - - - - 18 - - - - doCancel: - - - - 25 - - - - doSave: - - - - 26 - - - - folderName - - - - 27 - - - - cancelButton - - - - 28 - - - - saveButton - - - - 29 - - - - window - - - - 30 - - - - nextKeyView - - - - 24 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 5 - - - - - - GroupFolder - - - 6 - - - - - - - - - - - - 19 - - - - - - - - 20 - - - - - - - - 21 - - - - - - - - 22 - - - - - - - - 23 - - - - - - - - 32 - - - - - 33 - - - - - 34 - - - - - 35 - - - - - 36 - - - - - -3 - - - Application - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 36 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - NewGroupFolder - NSWindowController - - id - id - - - - doCancel: - id - - - doSave: - id - - - - NSButton - NSTextField - NSWindow - NSButton - - - - cancelButton - NSButton - - - folderName - NSTextField - - - newGroupFolderWindow - NSWindow - - - saveButton - NSButton - - - - IBProjectSource - ./Classes/NewGroupFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Sartu taldearen direktorioaren izena: + + + + + + + + + + diff --git a/lproj/eus.lproj/GroupFolder.nib/keyedobjects.nib b/lproj/eus.lproj/GroupFolder.nib/keyedobjects.nib index 616469ca25..af5f0c9e3c 100644 Binary files a/lproj/eus.lproj/GroupFolder.nib/keyedobjects.nib and b/lproj/eus.lproj/GroupFolder.nib/keyedobjects.nib differ diff --git a/lproj/eus.lproj/InfoPlist.strings b/lproj/eus.lproj/InfoPlist.strings deleted file mode 100644 index 3f10778946..0000000000 --- a/lproj/eus.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ -NSHumanReadableCopyright = "Copyright 2004-2015 Laguntzaileak. Sartu Laguntza menuan Vienna-k jaso duen laguntzari buruz gehiago jakiteko."; diff --git a/lproj/eus.lproj/Localizable.strings b/lproj/eus.lproj/Localizable.strings index 48ac956d06..21dd0a3618 100644 --- a/lproj/eus.lproj/Localizable.strings +++ b/lproj/eus.lproj/Localizable.strings @@ -449,4 +449,10 @@ "RSS Icon not found!" = "RSS Icon not found!"; /*Added in 3.0.5 */ -"Redirection attempt treated as temporary for safety concern" = "Redirection attempt treated as temporary for safety concern"; \ No newline at end of file +"Redirection attempt treated as temporary for safety concern" = "Redirection attempt treated as temporary for safety concern"; + +/*Added in 3.0.7 */ +"No articles in feed" = "No articles in feed"; + +/*Added in 3.1.2 */ +"Filter folders" = "Search for folders"; diff --git a/lproj/eus.lproj/RSSFeed.nib/designable.nib b/lproj/eus.lproj/RSSFeed.nib/designable.nib index cd53e948de..b208ad3c19 100644 --- a/lproj/eus.lproj/RSSFeed.nib/designable.nib +++ b/lproj/eus.lproj/RSSFeed.nib/designable.nib @@ -1,1001 +1,219 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSMenu - NSMenuItem - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSUserDefaultsController - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - RSSFeed - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{165, 318}, {426, 294}} - 1886912512 - RSS Jarioa - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{208, 11}, {102, 32}} - - - YES - - 67108864 - 134217728 - Ezeztatu - - LucidaGrande - 13 - 1044 - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{310, 11}, {102, 32}} - - - 100 - YES - - 67108864 - 134217728 - Harpidetu - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{20, 193}, {75, 17}} - - - YES - - 67108864 - 4194304 - SXR1cnJpYToKA - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 256 - {{99, 186}, {175, 26}} - - - YES - - -2080374720 - 1024 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - URL - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - 100 - - - YES - - Bestelakoak - - - - - 3 - YES - YES - 1 - - NO - - - - 256 - {{20, 260}, {389, 17}} - - - YES - - 67108864 - 4194304 - SGFycGlkZXR6YSBiZXJyaSBiYXQgc29ydHUKA - - LucidaGrande-Bold - 13 - 2072 - - - - - - NO - - - - 256 - {{20, 218}, {378, 34}} - - - YES - - 67108864 - 4194304 - Sartu jarioaren URL helbidea behean, edota aukeratu bat iturrien listatik. - - LucidaGrande - 10 - 2843 - - - - - - NO - - - - 256 - {{23, 87}, {386, 62}} - - - YES - - -1805647871 - 4325376 - - - LucidaGrande - 11 - 3100 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 256 - {{283, 186}, {21, 24}} - - - YES - - 67108864 - 134217728 - - - - -2038284288 - 33 - - - - - - 200 - 25 - - NO - - - - 256 - {{20, 157}, {270, 17}} - - - YES - - 67108864 - 4194304 - URL: - - - - - - NO - - - - 268 - {{21, 49}, {185, 18}} - - - YES - - -2080374784 - 0 - Subscribe in Open Reader - - - 1211912448 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - NO - - - {426, 294} - - - - {{0, 0}, {1280, 778}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - 3 - 2 - {{305, 336}, {423, 167}} - 1886912512 - RSS Jarioa - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{307, 12}, {102, 32}} - - 100 - YES - - 67108864 - 134217728 - Gorde - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{205, 12}, {102, 32}} - - - YES - - 67108864 - 134217728 - Ezeztatu - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{20, 60}, {383, 62}} - - - YES - - -1805647871 - 4325376 - - - - YES - - - - NO - - - - 256 - {{17, 130}, {389, 17}} - - - YES - - 67108864 - 4194304 - Harpidetza editatu - - - - - - NO - - - {{1, 9}, {423, 167}} - - - {{0, 0}, {1280, 778}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - YES - - - - - - - window - - - - 14 - - - - doSubscribe: - - - - 37 - - - - feedSource - - - - 46 - - - - subscribeButton - - - - 48 - - - - doSave: - - - - 57 - - - - editRSSFeedWindow - - - - 61 - - - - newRSSFeedWindow - - - - 62 - - - - editFeedURL - - - - 69 - - - - saveButton - - - - 70 - - - - editCancelButton - - - - 74 - - - - subscribeCancelButton - - - - 76 - - - - doEditCancel: - - - - 77 - - - - doSubscribeCancel: - - - - 78 - - - - doLinkSourceChanged: - - - - 89 - - - - feedURL - - - - 91 - - - - doShowSiteHomePage: - - - - 93 - - - - siteHomePageButton - - - - 94 - - - - linkTitle - - - - 99 - - - - doGoogleOption: - - - - 118 - - - - googleOptionButton - - - - 119 - - - - value: googleOptionButton - - - - - - value: googleOptionButton - value - googleOptionButton - 2 - - - 117 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - NewRSSFeed - - - 5 - - - - - - - - - - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 40 - - - - - - - - 43 - - - - - - - - 64 - - - - - - - - 65 - - - - - - - - 90 - - - - - - - - 92 - - - - - - - - 97 - - - - - - - - 49 - - - - - - EditRSSFeed - - - 50 - - - - - - - - - - - 53 - - - - - - - - 54 - - - - - - - - 55 - - - - - - - - 67 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - 107 - - - - - 108 - - - - - 109 - - - - - 110 - - - - - 111 - - - - - 112 - - - - - 113 - - - - - 114 - - - - - 44 - - - - - - - - 45 - - - - - -3 - - - Application - - - 115 - - - - - - - - 116 - - - - - 120 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{1012, 565}, {429, 297}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 122 - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - {15, 15} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Iturria: + + + + + + + + + + + + + + + + + + + + + + + + + + + Harpidetza berri bat sortu + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/eus.lproj/RSSFeed.nib/keyedobjects.nib b/lproj/eus.lproj/RSSFeed.nib/keyedobjects.nib index ae611ddbb7..03775b8ba6 100644 Binary files a/lproj/eus.lproj/RSSFeed.nib/keyedobjects.nib and b/lproj/eus.lproj/RSSFeed.nib/keyedobjects.nib differ diff --git a/lproj/eus.lproj/SearchFolder.nib/designable.nib b/lproj/eus.lproj/SearchFolder.nib/designable.nib index bb2ba8a339..4234766bfc 100644 --- a/lproj/eus.lproj/SearchFolder.nib/designable.nib +++ b/lproj/eus.lproj/SearchFolder.nib/designable.nib @@ -1,1573 +1,265 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSBox - NSButton - NSButtonCell - NSCustomObject - NSCustomView - NSMenu - NSMenuItem - NSNumberFormatter - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - SmartFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{319, 551}, {647, 186}} - 1886912512 - - NSPanel - - View - - - {213, 107} - - - 256 - - - - 268 - {{17, 150}, {133, 17}} - - - YES - - 67108864 - 4194304 - RGlyZWt0b3JpbyBhZGltZW5kdWFyZW4gaXplbmE6Cg - - LucidaGrande - 13 - 1044 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 268 - {{155, 147}, {178, 22}} - - - YES - - -1804599231 - 4195328 - - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{555, 12}, {78, 32}} - - - YES - - 67108864 - 134217728 - Gorde - - - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{475, 12}, {82, 32}} - - - YES - - 67108864 - 134217728 - Ezeztatu - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 274 - - - - 274 - - - - 274 - {{12, 6}, {584, 38}} - - - - NSView - - NSResponder - - - {{2, 2}, {609, 50}} - - - - - {{17, 56}, {613, 54}} - - - {0, 0} - - 67108864 - 0 - - - LucidaGrande - 11 - 3100 - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 3 - 0 - 0 - NO - - - - 268 - {{17, 118}, {273, 17}} - - - YES - - 67108864 - 4194304 - Erakutsi zerikusia duten artikulu guztiak - - - - - - NO - - - - 268 - {{282, 112}, {80, 26}} - - - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - Ezer - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - - - YES - - Bestelakoak - - - - - 3 - YES - YES - 1 - - NO - - - - 268 - {{365, 118}, {166, 17}} - - - YES - - 67108864 - 272629760 - honako baldintzekin: - - - - - - NO - - - {647, 186} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - 256 - - - - 256 - {{-3, 0}, {135, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Fitxategi izenak hemen doaz - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - Bestelakoak - - - - - 3 - YES - YES - 1 - - NO - - - - 256 - {{513, -3}, {32, 31}} - - YES - - 67108864 - 134479872 - - - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{302, 3}, {183, 22}} - - YES - - -1804599231 - 4195328 - - - - YES - - - - NO - - - - 256 - {{541, -3}, {32, 31}} - - YES - - 67108864 - 134479872 - + - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{151, 0}, {135, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Operazioak hemen doaz - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - Bestelakoak - - - - - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{299, 0}, {100, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - - - 400 - 75 - - - Ezer - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - Bestelakoak - - - - - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{302, 4}, {126, 22}} - - YES - - -1804599231 - 4195328 - - - - - - - - - NaN - - - - 0 - - - . - - , - - - - - 0 - 2 - NO - YES - 1 - P0IPAAAAAAAAAAAAAAAAAA - - - 0 - 1 - NO - YES - 1 - AQAAAAAAAAAAAAAAAAAAAA - - -0 - 0 - - - 0 - -0 - - - - - - - - - . - , - NO - NO - YES - - - YES - - - - NO - - - - -2147483392 - {{299, 0}, {189, 26}} - - 1008 - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Item2 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - Bestelakoak - - - - - Item3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{299, 0}, {189, 26}} - - 1004 - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Item1 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - Bestelakoak - - - - - Item2 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - Item3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - 3 - YES - YES - 1 - - NO - - - {572, 28} - - NSView - - NSResponder - - - - - - - cancelButton - - - - 40 - - - - saveButton - - - - 41 - - - - searchCriteriaView - - - - 43 - - - - removeCriteriaButton - - - - 44 - - - - addCriteriaButton - - - - 45 - - - - fieldNamePopup - - - - 46 - - - - operatorPopup - - - - 47 - - - - valueField - - - - 49 - - - - window - - - - 50 - - - - addNewCriteria: - - - - 51 - - - - doCancel: - - - - 52 - - - - doSave: - - - - 53 - - - - searchWindow - - - - 54 - - - - removeCurrentCriteria: - - - - 57 - - - - fieldChanged: - - - - 59 - - - - flagValueField - - - - 65 - - - - numberValueField - - - - 70 - - - - folderValueField - - - - 78 - - - - criteriaConditionPopup - - - - 85 - - - - dateValueField - - - - 91 - - - - smartFolderName - - - - 92 - - - - searchCriteriaSuperview - - - - 42 - - - - nextKeyView - - - - 72 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - Search Folder - - - 5 - - - - - - - - - - - - - - - 7 - - - - - - - - 8 - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 37 - - - - - - - - 58 - - - - - - - - 79 - - - - - - - - 84 - - - - - - - - 26 - - - - - - - - - - - - - - SearchCriteriaView - - - 27 - - - - - - - - 29 - - - - - - - - 30 - - - - - - - - 31 - - - - - - - - 35 - - - - - - - - 61 - - - - - - - - 69 - - - - - - - - 73 - - - - - - - - 86 - - - - - - - - 94 - - - - - 95 - - - - - 96 - - - - - 97 - - - - - 98 - - - - - 99 - - - - - - - - 100 - - - - - 101 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - - - - 107 - - - - - - - - 108 - - - - - - - - 109 - - - - - - - - 71 - - - - - 80 - - - - - - - - 82 - - - - - 32 - - - - - - - - 33 - - - - - 34 - - - - - - - - 56 - - - - - 64 - - - - - - - - 62 - - - - - 74 - - - - - - - - - 76 - - - - - 75 - - - - - 87 - - - - - - - - - - 90 - - - - - 89 - - - - - 88 - - - - - -3 - - - Application - - - 36 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 109 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - SmartFolder - NSWindowController - - id - id - id - id - id - - - - addNewCriteria: - id - - - doCancel: - id - - - doSave: - id - - - fieldChanged: - id - - - removeCurrentCriteria: - id - - - - NSButton - NSButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSTextField - NSPopUpButton - NSButton - NSButton - NSView - NSView - NSWindow - NSTextField - NSTextField - - - - addCriteriaButton - NSButton - - - cancelButton - NSButton - - - criteriaConditionPopup - NSPopUpButton - - - dateValueField - NSPopUpButton - - - fieldNamePopup - NSPopUpButton - - - flagValueField - NSPopUpButton - - - folderValueField - NSPopUpButton - - - numberValueField - NSTextField - - - operatorPopup - NSPopUpButton - - - removeCriteriaButton - NSButton - - - saveButton - NSButton - - - searchCriteriaSuperview - NSView - - - searchCriteriaView - NSView - - - searchWindow - NSWindow - - - smartFolderName - NSTextField - - - valueField - NSTextField - - - - IBProjectSource - ./Classes/SmartFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Direktorio adimenduaren izena: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/eus.lproj/SearchFolder.nib/keyedobjects.nib b/lproj/eus.lproj/SearchFolder.nib/keyedobjects.nib index 619bf84817..85bc9e59a2 100644 Binary files a/lproj/eus.lproj/SearchFolder.nib/keyedobjects.nib and b/lproj/eus.lproj/SearchFolder.nib/keyedobjects.nib differ diff --git a/lproj/eus.lproj/Vienna Help/advanced.html b/lproj/eus.lproj/Vienna Help/advanced.html deleted file mode 100644 index fb9b248814..0000000000 --- a/lproj/eus.lproj/Vienna Help/advanced.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - Advanced Settings - - - - -  Advanced - Settings -

The Advanced section of the Preferences provides options to - change very specific settings in Vienna that are not essential - for normal use but may resolve some issues as advised by the - support forum. This page details the advanced settings and their - function.

-

Enable JavaScript in internal browser

-

Enables or disables support for JavaScript scripting in the - Vienna internal browser. By default this is enabled. By turning - this setting off, JavaScript code on web pages will not be - allowed to run. This may resolve problems with pages that use - scripting to pop up windows or other unexpected behaviour but - turning the setting off may also cause some web pages to appear - incomplete or fail to function correctly.

- - diff --git a/lproj/eus.lproj/Vienna Help/faq.html b/lproj/eus.lproj/Vienna Help/faq.html deleted file mode 100644 index 5bcc082cde..0000000000 --- a/lproj/eus.lproj/Vienna Help/faq.html +++ /dev/null @@ -1,216 +0,0 @@ - - - - - - - How Do I? - - - - -  How Do I? -

Below are some of the more common questions asked about Vienna - while it was being pre-release tested. See the Official Vienna FAQ - Page for these and the latest hints and tips for using - Vienna.

- -

Where do I get the Vienna - source code?

-

See the Development page - for instructions for getting the source code for Vienna. The - source code is freely available if you're interested in learning - how Vienna works, if you want to build your own copy of Vienna - from scratch on your own machine or if you want to borrow - portions for inclusion in your own project. The source is - provided under the Apache 2.0 - license.

-

I found a - problem with Vienna. How do I report it?

-

Post a message over in the Support - forum and somebody will investigate. Provide as much - information about the problem as you can including: the build of - Vienna (obtained from the About Vienna panel), repro steps and - what you expected to happen. There is a sticky note in the forum - with tips on how to write a good bug report.

-

Make sure you're always running the most recent build of - Vienna. The Check for Updates command will report if there's a - newer build available than the one you have.

-

Fixes for bugs take priority over new features so if your - problem is confirmed to be a bug with high impact and no simple - workaround then I'll look at making a fix available as soon as - reasonably possible.

-

How do I create my own - styles?

-

See the Custom Styles - page for instructions.

-

How do I create my own - scripts?

-

Vienna's scripts are written using AppleScript. See the - - Apple resource page for more details.

-

One way to get started is to download one of the existing - scripts from the Vienna Downloads - page and view it in the AppleScript editor.

-

To submit your own script, send it to steve@opencommunity.co.uk - and after it has been reviewed, it will be made available on the - Downloads page.

-

- How can I see what happened when my subscriptions are - refreshed?

-

Open the Activity Window from the Window menu. The activity - window shows all subscriptions and the status of the last time - they were refreshed in that session. The bottom of the activity - window shows more details include the HTTP headers and may be - useful for debugging. (If the details pane is not visible, grab - the split bar at the bottom of the Activity Window and drag it up - to uncover the pane).

-

How do I - move my Vienna database to another folder?

-

By default, your Vienna database is the messages.db file which - is located at ~/Library/Application Support/Vienna. You can move - this to another folder if you wish. The following steps show - how:

-
    -
  1. Shut down Vienna.
  2. -
  3. Open a console window and enter:
    -
    - defaults write - uk.co.opencommunity.vienna2 "DefaultDatabase" '<path to new - messages.db>'
    -
    - where <path to new messages.db> is the name of the folder - that contains the messages.db file. The path itself should have - the messages.db filename at the end. For example:
    -
    - defaults write - uk.co.opencommunity.vienna2 "DefaultDatabase" - '/Users/steve/mydata/messages.db'
  4. -
  5. Restart Vienna.
  6. -
-

- One of my subscriptions reports "Error parsing XML data in feed". - What does this mean?

-

It means that Vienna got a feed back from the subscription - that it couldn't interpret. There are several reasons for - this:

-
    -
  1. The URL of the feed may not be pointing to an RSS or Atom - feed but to a web page. Check the URL of the offending feed - carefully.
  2. -
  3. The feed itself may contain malformed XML. Some - subscriptions make a mistake in putting together the XML that - makes up the feed and Vienna cannot interpret malformed XML. - Use the Validate Feed command on the File menu to see if this - is the case. Unfortunately you cannot do much about this in - Vienna except wait for the feed itself to be corrected by the - site.
  4. -
  5. The feed may be incomplete. If the refresh was interrupted - then the XML data will be incomplete and will appear malformed - in Vienna. A second refresh may correct this problem.
  6. -
-

If none of the above explain the problem, post a message on - the support forum with the URL of the feed exhibiting the - problem.

-

- Is there a shortcut key for going to the next article, marking - read, etc?

-

Probably. There are single key equivalents for some of the - menu commands such as:

-

Spacebar - goes to the next unread article. If the current - article is several pages long, it will scroll through that - article first. If you're at the end of the current article it - will then go to the next unread article. By contrast the Next - Unread command (Cmd+U) always goes straight to the next unread - article.

-

R - marks the current article read if it is unread, or unread - if it is read.

-

F - flags the current article if it isn't already flagged, or - removes the existing flag if it is not.

-

Look in the Vienna Help file for more shortcuts.

-

What do - the green dots mean in the list of articles?

-

The blue dots are for new articles, and the green dots are for - updated articles: articles whose text has changed since they were - last downloaded.

-

How do I use Auto - Expire and what does it do?

-

Auto-expire moves articles older than a certain number of days - to the Trash folder. It allows you to keep your folders - manageable by only retaining articles that are recent. The - auto-expire runs both when Vienna starts and after you have - refreshed any subscriptions. To control the age of articles to - auto-expire, change the "Move articles to Trash" option in - Preferences.

-

Auto-expire will NOT remove unread or flagged articles. It - assumes that you haven't read these articles and thus leaves them - alone.

-

How do I request an - enhancement in Vienna?

-

Post a message over at the support - forum. All requested enhancements are logged in the TODO file - that is included with the source code as a guidance for future - developers.

- - diff --git a/lproj/eus.lproj/Vienna Help/helpstyle.css b/lproj/eus.lproj/Vienna Help/helpstyle.css deleted file mode 100644 index d02689f72e..0000000000 --- a/lproj/eus.lproj/Vienna Help/helpstyle.css +++ /dev/null @@ -1,39 +0,0 @@ -a { - color: #3366CC; - text-decoration: none; -} -.title { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 18pt; - color: #000000; -} -.header { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 12pt; - color: #000000; -} -li { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 100; - font-size: 9pt; - color: #000000; -} -h2 { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 400; - font-size: 10pt; - color: #000000; -} -p { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 100; - font-size: 9pt; - color: #000000; -} -tr { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-size: 9pt; - color: #000000; -} \ No newline at end of file diff --git a/lproj/eus.lproj/Vienna Help/images/Small-Vienna-Logo.jpg b/lproj/eus.lproj/Vienna Help/images/Small-Vienna-Logo.jpg deleted file mode 100644 index 41035b4f11..0000000000 Binary files a/lproj/eus.lproj/Vienna Help/images/Small-Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/eus.lproj/Vienna Help/images/Vertical-Line.jpg b/lproj/eus.lproj/Vienna Help/images/Vertical-Line.jpg deleted file mode 100644 index 011f1ce1e3..0000000000 Binary files a/lproj/eus.lproj/Vienna Help/images/Vertical-Line.jpg and /dev/null differ diff --git a/lproj/eus.lproj/Vienna Help/images/Vienna-Logo.jpg b/lproj/eus.lproj/Vienna Help/images/Vienna-Logo.jpg deleted file mode 100644 index 13a6479bd4..0000000000 Binary files a/lproj/eus.lproj/Vienna Help/images/Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/eus.lproj/Vienna Help/images/rssfeed.gif b/lproj/eus.lproj/Vienna Help/images/rssfeed.gif deleted file mode 100644 index 2dc8935119..0000000000 Binary files a/lproj/eus.lproj/Vienna Help/images/rssfeed.gif and /dev/null differ diff --git a/lproj/eus.lproj/Vienna Help/index.html b/lproj/eus.lproj/Vienna Help/index.html deleted file mode 100644 index a93a8e7d71..0000000000 --- a/lproj/eus.lproj/Vienna Help/index.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - Vienna Help - - - - - - - - - - -
-

-

Vienna Help

-
-

Introduction to Vienna

-

Learn how to get started with - Vienna.

-

Keyboard Shortcuts

-

Discover keyboard shortcuts - for common commands

-

How Do I?

-

Frequently Asked Questions, getting - support and troubleshooting steps.

-

Advanced Settings

-

Explains the settings in the - Advanced Preferences.

-
- - diff --git a/lproj/eus.lproj/Vienna Help/intro.html b/lproj/eus.lproj/Vienna Help/intro.html deleted file mode 100644 index 868b1d140e..0000000000 --- a/lproj/eus.lproj/Vienna Help/intro.html +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - Introduction to Vienna - - - - -   Introduction to - Vienna -

Vienna is an application that allows you to read RSS or Atom - news feeds on your Mac OS X computer. It automates the job of - retrieving news articles from all subscribed feeds and storing - them in a local database for reading off-line. It provides - features that allow you to search feeds for keywords or phrases, - tag articles with a flag for future reference and organise - related feeds together under groups. You can create smart folders - that make it easy to dynamically retrieve and view all articles - in the database that match a search criteria. The built-in web - browser allows you to go to the articles web page or view links - in the article directly in Vienna in separate tabs.

-

Vienna is designed to be simple and easy to use. A clean, - uncluttered, interface maximises the space for articles and just - a few controls are needed to perform the most common actions in - the user interface.

Getting Started -

If this is the first time that you have used Vienna then it - will have created a new database for you and added some sample - news subscriptions. So go ahead and press Command+R or choose - Refresh All Subscriptions from the File menu to grab the latest - articles from those subscriptions.

-

Alternatively, subscribe to your own news feeds. There are - various ways to find feeds. When browsing the web, look out for - the RSS feed icon or XML - icons indicating that the page has a feed associated with it. - Alternatively almost all online blogging services such as - LiveJournal or Blogger provide RSS feeds as an alternative to - reading the postings online.

-

If you know the user name of a blogger on LiveJournal, - Blogger, MSN Spaces or Xanga then Vienna makes it easier to - subscribe to their news feed. Start by pressing Command+N or from - the File menu, choose the New Subscription command. In the - "Create a new RSS subscription" panel, pick the blogging service - from the drop down list and enter the user name in the input - field below. Then choose Subscribe and Vienna will add the - subscription to the folder list. If you are connected to the - internet at the time, it will also immediately start collecting - articles from the feed.

-

Normally you need to manually tell Vienna when to refresh all - your subscriptions. However you can opt to ask Vienna to - automatically refresh at time intervals. In the General section - of the Preferences, pick the desired time interval from the drop - down list next to 'Check for new articles'. Vienna needs to be - running for it to automatically refresh subscriptions.

-

To read articles, press the Spacebar to skip to the next - unread article in any subscription. Each article is marked as - read automatically after a short delay. If you prefer to wait - until you move to the next unread article before the current one - is marked read you can adjust the behaviour in the General tab of - the Preferences. To mark an article as unread again, choose the - Mark Unread command from the Article menu or simply press the 'R' - key.

-

Finally, you can view the article web page or any web page - links in an article within Vienna. By default clicking on a web - link within Vienna will open the web page in a new tab. Vienna - provides a lot of basic web browsing support itself but there may - be times when you will prefer to open links in your default web - browser. If you prefer to view all web pages outside of Vienna - then enable the 'Open links in external browser' option in the - General section of the Preferences. However if you prefer to view - the current link or page in your external browser, right click on - the page and choose the "Open Link in XXX" or "Open Page in XXX" - option where XXX will be the name of your default browser.

-

Once you've got comfortable using Vienna, go ahead and explore - the various options. You can change the style in which the - articles are displayed through the Style drop down list in the - View menu. You can find many more custom styles at the Downloads page - on the Vienna web site along with custom scripts that allow you - to integrate Vienna with other applications on your machine. Or - experiment with smart folders to organise articles according to - criteria based on the contents of each article. For example, you - can easily set up a smart folder to group together all articles - that mention "Joss Whedon" and "Firefly" to find references to - the Firefly cult series or the spin-off movie.

-

If you have any questions about Vienna or run into problems, - head over to the Support - forum.

- - diff --git a/lproj/eus.lproj/Vienna Help/keyboard.html b/lproj/eus.lproj/Vienna Help/keyboard.html deleted file mode 100644 index 6ab921ea4d..0000000000 --- a/lproj/eus.lproj/Vienna Help/keyboard.html +++ /dev/null @@ -1,253 +0,0 @@ - - - - - - - Keyboard Shortcuts - - - - -  Keyboard - Shortcuts -

You can use your keyboard to quickly accomplish many tasks in - Vienna. To find the shortcuts for common commands, look in the - menus (or see the list at the bottom of this page). Many items in - Vienna such as the folder pane and the article list pane also - have contextual menus. To see a contextual menu, press the - Control key and click the item.

-

To do an action, press the shortcut keys indicated below.

- - - - - -
KeyAction
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Single Key Shortcuts 
fSets the input focus to the search window.
rMarks the selected articles read.
sMarks the current folder read then skips to the next - folder with unread articles.
kMarks the current folder read.
mFlags the selected articles.
nMoves to the next unread article.
<Displays the previous viewed article or web page.
>Displays the next viewed article or web page.
SpacebarMoves to the next unread article unless the current - article has more text to scroll in which case it scrolls the - current article up one page.
Enter/ReturnOpens the selected article's original web page.
Delete/BackspaceMoves the selected articles to the Trash folder. If this - key is used in the Trash folder, the selected articles are - permanently deleted.
General Shortcuts 
Alt-ClickOpen the clicked link, overriding your preference for - opening links in external browser.
Command-NCreate a new subscription.
Shift-Command-FCreate a smart folder.
Shift-Command-EEdit the selected folder URL or edit a smart folder - criteria.
Shift-Command-DDelete the selected folder.
Shift-Command-NRename the selected folder.
Command-RRefreshes all subscriptions.
Shift-Command-RRefresh only those subscriptions selected in the folder - list.
Control-Command-SStops any active refresh.
Command-PPrint the selected articles.
Shift-Command-PBrings up the Page Setup panel.
Command-?Displays the Vienna help book.
Articles Shortcuts 
Alt-Enter/Alt-ReturnOpens the selected article's original web page, - overriding your preference for opening links in external - browser.
Command-UMoves to the next unread article.
Shift-Command-MFlags the selected articles.
Shift-Command-UMarks the selected articles read.
Shift-Command-SMarks the current folder read then skips to the next - folder with unread articles.
Shift-Command-ORestores an article from the trash back to its original - folder.
Shift-Command-KMarks all articles in the selected folders read.
Alt-Command-KMarks all articles in all folders read.
Window Shortcuts 
Command-WCloses the active tab window if one is open. Otherwise if - no tabs are open, this closes the Vienna window.
Alt-Command-WCloses all tab windows. Note that this command replaces - the Close Tab command on the File menu when the Alt key is - held down.
Alt-Command-LeftDisplays the previous tab window.
Alt-Command-RightDisplays the next tab window.
Command-MMinimizes the Vienna window to the dock.
Command-0Displays the activity log viewer window.
Command-1Reopens the Vienna window if it was previously - closed.
Command-2Displays the Downloads window.
Browser Window Shortcuts 
Alt-RReloads the current web page.
Command-PeriodCancels loading of the current web page.
Command-[/Command-LeftGoes back to the previous web page.
Command-]/Command-RightGoes forward to the next web page.
Command-FPuts the input focus in the search field. Entering some - text here and pressing Enter will search for that text on the - current web page.
Command-GSearches for the next occurrence of the search text on - the web page.
- - diff --git a/lproj/fr.lproj/GroupFolder.nib/designable.nib b/lproj/fr.lproj/GroupFolder.nib/designable.nib index 983f72918c..1cfdbbcd3c 100644 --- a/lproj/fr.lproj/GroupFolder.nib/designable.nib +++ b/lproj/fr.lproj/GroupFolder.nib/designable.nib @@ -1,500 +1,91 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - NewGroupFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{195, 498}, {388, 107}} - 1886912512 - Panneau - - NSPanel - - - View - - - {213, 107} - - - 256 - - - - 260 - {{17, 112}, {354, 17}} - - - YES - - 67108864 - 4194304 - Nouveau groupe - - LucidaGrande-Bold - 13 - 2072 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 258 - {{20, 60}, {348, 22}} - - - YES - - -1804599231 - 272630784 - - - LucidaGrande - 13 - 1044 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{285, 12}, {89, 32}} - - - 100 - YES - - 67108864 - 134217728 - Créer - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{203, 12}, {82, 32}} - - - YES - - 67108864 - 134217728 - Annuler - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 268 - {{17, 90}, {353, 14}} - - - YES - - 67108864 - 4194304 - RW50cmVyIGxlIG5vbSBkdSBub3V2ZWF1IGdyb3VwZSA6Cg - - LucidaGrande - 11 - 3100 - - - - - - NO - - - {388, 107} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - - - - newGroupFolderWindow - - - - 18 - - - - doCancel: - - - - 25 - - - - doSave: - - - - 26 - - - - folderName - - - - 27 - - - - cancelButton - - - - 28 - - - - saveButton - - - - 29 - - - - window - - - - 30 - - - - nextKeyView - - - - 24 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 5 - - - - - - GroupFolder - - - 6 - - - - - - - - - - - - 19 - - - - - - - - 20 - - - - - - - - 21 - - - - - - - - 22 - - - - - - - - 23 - - - - - - - - 32 - - - - - 33 - - - - - 34 - - - - - 35 - - - - - 36 - - - - - -3 - - - Application - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 36 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - NewGroupFolder - NSWindowController - - id - id - - - - doCancel: - id - - - doSave: - id - - - - NSButton - NSTextField - NSWindow - NSButton - - - - cancelButton - NSButton - - - folderName - NSTextField - - - newGroupFolderWindow - NSWindow - - - saveButton - NSButton - - - - IBProjectSource - ./Classes/NewGroupFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Entrer le nom du nouveau groupe : + + + + + + + + + + diff --git a/lproj/fr.lproj/GroupFolder.nib/keyedobjects.nib b/lproj/fr.lproj/GroupFolder.nib/keyedobjects.nib index ca83a0765f..2e014e220f 100644 Binary files a/lproj/fr.lproj/GroupFolder.nib/keyedobjects.nib and b/lproj/fr.lproj/GroupFolder.nib/keyedobjects.nib differ diff --git a/lproj/fr.lproj/InfoPlist.strings b/lproj/fr.lproj/InfoPlist.strings deleted file mode 100644 index d3097928a0..0000000000 --- a/lproj/fr.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ -NSHumanReadableCopyright = "Copyright 2004-2015 Contributeurs. Voir Aide/Remerciements pour la liste des contributeurs."; diff --git a/lproj/fr.lproj/Localizable.strings b/lproj/fr.lproj/Localizable.strings index c753c8b816..7d85307674 100644 --- a/lproj/fr.lproj/Localizable.strings +++ b/lproj/fr.lproj/Localizable.strings @@ -449,4 +449,10 @@ "RSS Icon not found!" = "Icône RSS non trouvée !"; /*Added in 3.0.5 */ -"Redirection attempt treated as temporary for safety concern" = "Tentative de redirection traitée de façon temporaire par souci de prudence"; \ No newline at end of file +"Redirection attempt treated as temporary for safety concern" = "Tentative de redirection traitée de façon temporaire par souci de prudence"; + +/*Added in 3.0.7 */ +"No articles in feed" = "Aucun article dans le flux"; + +/*Added in 3.1.2 */ +"Filter folders" = "Rechercher dans les dossiers"; diff --git a/lproj/fr.lproj/RSSFeed.nib/designable.nib b/lproj/fr.lproj/RSSFeed.nib/designable.nib index 24e226395f..b190fa75fb 100644 --- a/lproj/fr.lproj/RSSFeed.nib/designable.nib +++ b/lproj/fr.lproj/RSSFeed.nib/designable.nib @@ -1,1220 +1,218 @@ - - - - 1050 - 14A386a - 6249 - 1343.14 - 755.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 6249 - - - NSButton - NSButtonCell - NSCustomObject - NSMenu - NSMenuItem - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSUserDefaultsController - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - RSSFeed - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{246, 140}, {426, 288}} - 1886912512 - Flux RSS - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{210, 9}, {102, 32}} - - - - YES - - 67108864 - 134217728 - Annuler - - YES - 13 - 1044 - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{312, 9}, {103, 32}} - - - 100 - YES - - 67108864 - 134217728 - S'abonner - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{20, 187}, {75, 17}} - - - - YES - - 67108864 - 4194304 - U291cmNlIDoKA - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - 1 - - - - 256 - {{99, 180}, {175, 26}} - - - - YES - - -2080374720 - 1024 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - URL - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - 100 - - - YES - - AutresVues - - - - - 3 - YES - YES - 1 - - NO - - - - 256 - {{20, 254}, {389, 17}} - - - - YES - - 67108864 - 4194304 - Créer un nouvel abonnement - - YES - 13 - 2072 - - - - - - NO - 1 - - - - 256 - {{20, 212}, {378, 34}} - - - - YES - - 67108864 - 4194304 - Entrer le lien pour le flux RSS, ou choisir un type de source à partir de la liste et entrer un nom pour obtenir le flux RSS associé. - - YES - 10 - 2843 - - - - - - NO - 1 - - - - 256 - {{23, 81}, {386, 62}} - - - - YES - - -1805647871 - 4325376 - - - YES - 11 - 3100 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - 1 - - - - 256 - {{283, 180}, {21, 24}} - - - - YES - - 67108864 - 134217728 - - - - -2038284288 - 33 - - - - - - 200 - 25 - - NO - - - - 256 - {{20, 151}, {270, 17}} - - - - YES - - 67108864 - 4194304 - URL : - - - - - - NO - 1 - - - - 268 - {{21, 43}, {292, 18}} - - - - YES - - -2080374784 - 0 - S'abonner à travers le serveur Open Reader - - - 1211912448 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - NO - - - {426, 288} - - - - - {{0, 0}, {1280, 778}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - 3 - 2 - {{305, 336}, {423, 167}} - 1886912512 - Flux RSS - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{307, 12}, {102, 32}} - - 100 - YES - - 67108864 - 134217728 - Modifier - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{205, 12}, {102, 32}} - - - YES - - 67108864 - 134217728 - Annuler - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{20, 60}, {383, 62}} - - - YES - - -1805647871 - 4325376 - - - - YES - - - - NO - 1 - - - - 256 - {{17, 130}, {389, 17}} - - - YES - - 67108864 - 4194304 - Éditer le lien de l'abonnement - - - - - - NO - 1 - - - {{1, 9}, {423, 167}} - - - {{0, 0}, {1280, 778}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - YES - - - - - - - window - - - - 14 - - - - doSubscribe: - - - - 37 - - - - feedSource - - - - 46 - - - - subscribeButton - - - - 48 - - - - doSave: - - - - 57 - - - - editRSSFeedWindow - - - - 61 - - - - newRSSFeedWindow - - - - 62 - - - - editFeedURL - - - - 69 - - - - saveButton - - - - 70 - - - - editCancelButton - - - - 74 - - - - subscribeCancelButton - - - - 76 - - - - doEditCancel: - - - - 77 - - - - doSubscribeCancel: - - - - 78 - - - - doLinkSourceChanged: - - - - 89 - - - - feedURL - - - - 91 - - - - doShowSiteHomePage: - - - - 93 - - - - siteHomePageButton - - - - 94 - - - - linkTitle - - - - 99 - - - - doGoogleOption: - - - - 118 - - - - googleOptionButton - - - - 119 - - - - value: googleOptionButton - - - - - - value: googleOptionButton - value - googleOptionButton - 2 - - - 117 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - NewRSSFeed - - - 5 - - - - - - - - - - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 40 - - - - - - - - 43 - - - - - - - - 64 - - - - - - - - 65 - - - - - - - - 90 - - - - - - - - 92 - - - - - - - - 97 - - - - - - - - 49 - - - - - - EditRSSFeed - - - 50 - - - - - - - - - - - 53 - - - - - - - - 54 - - - - - - - - 55 - - - - - - - - 67 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - 107 - - - - - 108 - - - - - 109 - - - - - 110 - - - - - 111 - - - - - 112 - - - - - 113 - - - - - 114 - - - - - 44 - - - - - - - - 45 - - - - - -3 - - - Application - - - 115 - - - - - - - - 116 - - - - - 120 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{1012, 565}, {429, 297}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 122 - - - - - NSObject - - deleteFolder: - id - - - deleteFolder: - - deleteFolder: - id - - - - IBProjectSource - ../src/FolderView.m - - - - NSObject - - deleteMessage: - id - - - deleteMessage: - - deleteMessage: - id - - - - IBProjectSource - ../src/MessageListView.m - - - - - - NSActionCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSActionCell.h - - - - NSApplication - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSApplication.h - - - - NSButton - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSButton.h - - - - NSButtonCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSButtonCell.h - - - - NSCell - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSCell.h - - - - NSControl - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSControl.h - - - - NSController - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSController.h - - - - NSFormatter - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFormatter.h - - - - NSMenu - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenu.h - - - - NSMenuItem - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItem.h - - - - NSMenuItemCell - NSButtonCell - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItemCell.h - - - - NSPanel - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSPanel.h - - - - NSPopUpButton - NSButton - - IBFrameworkSource - AppKit.framework/Headers/NSPopUpButton.h - - - - NSPopUpButtonCell - NSMenuItemCell - - IBFrameworkSource - AppKit.framework/Headers/NSPopUpButtonCell.h - - - - NSResponder - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSResponder.h - - - - NSTextField - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSTextField.h - - - - NSTextFieldCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSTextFieldCell.h - - - - NSUserDefaultsController - NSController - - IBFrameworkSource - AppKit.framework/Headers/NSUserDefaultsController.h - - - - NSView - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSView.h - - - - NSWindow - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSWindow.h - - - - - 0 - IBCocoaFramework - NO - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {12, 12} - {10, 2} - {15, 15} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Source : + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Entrer le lien pour le flux RSS, ou choisir un type de source à partir de la liste et entrer un nom pour obtenir le flux RSS associé. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/fr.lproj/RSSFeed.nib/keyedobjects.nib b/lproj/fr.lproj/RSSFeed.nib/keyedobjects.nib index 2cdc17fa47..02ba3c9c92 100644 Binary files a/lproj/fr.lproj/RSSFeed.nib/keyedobjects.nib and b/lproj/fr.lproj/RSSFeed.nib/keyedobjects.nib differ diff --git a/lproj/fr.lproj/SearchFolder.nib/designable.nib b/lproj/fr.lproj/SearchFolder.nib/designable.nib index e21827c473..3c1c26bfb1 100644 --- a/lproj/fr.lproj/SearchFolder.nib/designable.nib +++ b/lproj/fr.lproj/SearchFolder.nib/designable.nib @@ -1,1591 +1,263 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSBox - NSButton - NSButtonCell - NSCustomObject - NSCustomView - NSMenu - NSMenuItem - NSNumberFormatter - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - SmartFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{48, 158}, {647, 186}} - 1886912512 - - NSPanel - - View - - - {213, 107} - - - 256 - - - - 268 - {{17, 150}, {180, 17}} - - - YES - - 67108864 - 4194304 - Nom du dossier intelligent : - - LucidaGrande - 13 - 1044 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 268 - {{199, 148}, {178, 22}} - - - YES - - -1804599231 - 4195328 - - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{549, 12}, {84, 32}} - - - YES - - 67108864 - 134217728 - Valider - - - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{459, 12}, {90, 32}} - - - YES - - 67108864 - 134217728 - Annuler - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 274 - - - - 274 - - - - 274 - {{12, 6}, {584, 38}} - - - - NSView - - NSResponder - - - {{2, 2}, {609, 50}} - - - - - {{17, 56}, {613, 54}} - - - {0, 0} - - 67108864 - 0 - - - LucidaGrande - 11 - 3100 - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 3 - 0 - 0 - NO - - - - 268 - {{17, 118}, {209, 17}} - - - YES - - 67108864 - 4194304 - Montrer les articles qui satisfont - - - - - - NO - - - - 268 - {{228, 112}, {113, 26}} - - - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - chacune - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - 268 - {{343, 117}, {168, 17}} - - - YES - - 67108864 - 272629760 - des conditions suivantes : - - - - - - NO - - - {647, 186} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - 256 - - - - 256 - {{-3, 0}, {135, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Field names go here - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - 256 - {{513, -3}, {32, 31}} - - YES - - 67108864 - 134479872 - - - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{302, 3}, {183, 22}} - - YES - - -1804599231 - 4195328 - - - - YES - - - - NO - - - - 256 - {{541, -3}, {32, 31}} - - YES - - 67108864 - 134479872 - + - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{151, 0}, {135, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Operators go here - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{299, 0}, {100, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - - - 400 - 75 - - - chacune - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{302, 4}, {126, 22}} - - YES - - -1804599231 - 4195328 - - - - - - - - - NaN - - - - 0 - - - . - - , - - - - - 0 - 2 - NO - YES - 1 - P0IPAAAAAAAAAAAAAAAAAA - - - 0 - 1 - NO - YES - 1 - AQAAAAAAAAAAAAAAAAAAAA - - -0 - 0 - - - 0 - -0 - - - - - - - - - . - , - NO - NO - YES - - - YES - - - - NO - - - - -2147483392 - {{299, 0}, {189, 26}} - - 1008 - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Item2 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - Item3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{299, 0}, {189, 26}} - - 1004 - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Item3 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - Item1 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - Item2 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - {572, 28} - - NSView - - NSResponder - - - - - - - cancelButton - - - - 40 - - - - saveButton - - - - 41 - - - - searchCriteriaView - - - - 43 - - - - removeCriteriaButton - - - - 44 - - - - addCriteriaButton - - - - 45 - - - - fieldNamePopup - - - - 46 - - - - operatorPopup - - - - 47 - - - - valueField - - - - 49 - - - - window - - - - 50 - - - - addNewCriteria: - - - - 51 - - - - doCancel: - - - - 52 - - - - doSave: - - - - 53 - - - - searchWindow - - - - 54 - - - - removeCurrentCriteria: - - - - 57 - - - - fieldChanged: - - - - 59 - - - - flagValueField - - - - 65 - - - - numberValueField - - - - 70 - - - - folderValueField - - - - 78 - - - - criteriaConditionPopup - - - - 85 - - - - dateValueField - - - - 91 - - - - smartFolderName - - - - 92 - - - - searchCriteriaSuperview - - - - 42 - - - - nextKeyView - - - - 72 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - Search Folder - - - 5 - - - - - - - - - - - - - - - 7 - - - - - - - - 8 - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 37 - - - - - - - - 58 - - - - - - - - 79 - - - - - - - - 84 - - - - - - - - 26 - - - - - - - - - - - - - - SearchCriteriaView - - - 27 - - - - - - - - 29 - - - - - - - - 30 - - - - - - - - 31 - - - - - - - - 35 - - - - - - - - 61 - - - - - - - - 69 - - - - - - - - 73 - - - - - - - - 86 - - - - - - - - 94 - - - - - 95 - - - - - 96 - - - - - 97 - - - - - 98 - - - - - 99 - - - - - - - - 100 - - - - - 101 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - - - - 107 - - - - - - - - 108 - - - - - - - - 109 - - - - - - - - 71 - - - - - 80 - - - - - - - - 82 - - - - - 32 - - - - - - - - 33 - - - - - 34 - - - - - - - - 56 - - - - - 64 - - - - - - - - 62 - - - - - 74 - - - - - - - - - 76 - - - - - 75 - - - - - 87 - - - - - - - - - - 90 - - - - - 89 - - - - - 88 - - - - - -3 - - - Application - - - 36 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 109 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - SmartFolder - NSWindowController - - id - id - id - id - id - - - - addNewCriteria: - id - - - doCancel: - id - - - doSave: - id - - - fieldChanged: - id - - - removeCurrentCriteria: - id - - - - NSButton - NSButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSTextField - NSPopUpButton - NSButton - NSButton - NSView - NSView - NSWindow - NSTextField - NSTextField - - - - addCriteriaButton - NSButton - - - cancelButton - NSButton - - - criteriaConditionPopup - NSPopUpButton - - - dateValueField - NSPopUpButton - - - fieldNamePopup - NSPopUpButton - - - flagValueField - NSPopUpButton - - - folderValueField - NSPopUpButton - - - numberValueField - NSTextField - - - operatorPopup - NSPopUpButton - - - removeCriteriaButton - NSButton - - - saveButton - NSButton - - - searchCriteriaSuperview - NSView - - - searchCriteriaView - NSView - - - searchWindow - NSWindow - - - smartFolderName - NSTextField - - - valueField - NSTextField - - - - IBProjectSource - ./Classes/SmartFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/fr.lproj/SearchFolder.nib/keyedobjects.nib b/lproj/fr.lproj/SearchFolder.nib/keyedobjects.nib index 57a0147a81..c58064ffd2 100644 Binary files a/lproj/fr.lproj/SearchFolder.nib/keyedobjects.nib and b/lproj/fr.lproj/SearchFolder.nib/keyedobjects.nib differ diff --git a/lproj/fr.lproj/Vienna Help/advanced.html b/lproj/fr.lproj/Vienna Help/advanced.html deleted file mode 100644 index 1eb413828e..0000000000 --- a/lproj/fr.lproj/Vienna Help/advanced.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - Réglages avancés - - - - -  Réglages - Avancés -

Le panneau Advancé des Préférences proposes des options pour - changer des réglages très spécifiques de Vienna qui ne sont pas - essentiels pour une utilisation classique, mais qui peuvent - résoudre des problèmes comme ceux traités par le forum de - Support. Cette page détaille les réglages avancés et les - fonction.

-

Activer JavaScript dans le navigateur interne

-

Active ou désactive le support de script JavaScript dans le - navigateur interne de Vienna internal. Est activé par défaut. En - décochant ce réglage, le code JavaScript des pages Web ne sera - pas éxécuté. Cela peut résoudre des problèmes avec les pages qui - utilisent des scripts pour afficher des fenêtres ou d'autre - comportement inattendus, mais cela peut aussi rendre l'affichage - de page incomplet ou créer des disfonctionnement.

- - diff --git a/lproj/fr.lproj/Vienna Help/faq.html b/lproj/fr.lproj/Vienna Help/faq.html deleted file mode 100644 index ce10c808ae..0000000000 --- a/lproj/fr.lproj/Vienna Help/faq.html +++ /dev/null @@ -1,281 +0,0 @@ - - - - - - Comment faire ? - - - - -  Comment faire - ? -

Ci-dessous vous trouverez les questions les plus courantes à - propos de Vienna lors de sa phase de beta-test. Reportez-vous à - la page Official Vienna - FAQ (en anglais) pour les dernières astuces pour utiliser - Vienna.

- -

J'ai - rencontré un problème avec Vienna. Comment faire un rapport - ?

-

Postez un message dans le forum de - support ou dans la liste des - problèmes et quelqu'un analysera le problème. Fournissez - autant d'information que vous pouvez sur le problème, dont - notamment : la version du logiciel (disponible dans la fenêtre "À - propos"), les actions réalisées et ce à quoi vous vous attendiez. - Il y a une note dans le forum avec des instructions pour rédiger - un bon rapport de problème.

-

Assurez-vous que vous utilisez la version la plus récente de - Vienna. La commande de vérification de mise à jour vous informera - si une version plus récente que la votre existe.

-

La résolution des boggues est prioritaire sur l'ajout de - fonctionnalités, aussi si votre problème est bien un boggue ayant - un impact important et pas une simple amélioration, alors une - résolution du problème sera mise à disposition dès que - possible.

-

- Comment puis-je voir ce qui se passe quand les abonnements sont - rafraîchis ?

-

Ouvrez la fenêtre d'activité à partir du menu Fenêtre. la - fenêtre d'activité montre tous les abonnements et le statut de - leur dernière rafraîchissement dans la session. Le bas de la - fenêtre d'activité montre plus de détails et inclut les entêtes - HTTP qui peuvent être utiles pour débogguer. (Si le panneau de - détails n'est pas visible, découvrez-le en faisant glisser la - barre située en bas de la fenêtre).

-

Comment - puis je m'abonner à un flux exigeant une authentification de - l'utilisateur ?

-

Il est important de comprendre que les services de type Open - Reader ne permettent pas de s'authentifier auprès d'un service - tiers. Vienna devra accéder directement au serveur qui exige une - identification et une authentification de l'utilisateur.
- Quand vous vous abonnez, assurez vous que la case "S'abonner à - travers le serveur Open Reader" n'est PAS cochée.

-

Ensuite, il est utile de savoir qu'il y a deux principales - méthodes d'authentification des utilisateurs qui demandent un - flux, et ce selon les serveurs que l'on rencontre :

-
    -
  • certains serveurs exigent un nom d'utilisateur et le mot de - passe associé ;
  • -
  • d'autres serveurs exigent un cookie spécifique.
  • -
-

Le problème, c'est que beaucoup de serveurs n'indiquent pas - clairement quelle méthode ils mettent en oeuvre pour les flux - nécessitant une authentification.

-

La demande d'un nom d'utilisateur et du mot de passe associé - est la méthode la plus courante. C'est aussi celle qui est la - plus explicite vis-à-vis de l'utilisateur. Lors du premier - rafraîchissement du flux, Vienna vous présentera une boite de - dialogue où vous pourrez entrer le nom d'utilisateur et le mot de - passe.
- Vous pouvez vérifier que vous avez fourni un nom d'utilisateur et - un mot de passe – et les mettre à jour si nécessaire – à travers - la boite de dialogue "Infos" du flux. Vous accédez à cette boite - de dialogue à travers le menu "Dossier → Obtenir les infos…" ou - via le menu contextuel (clic droit) dans la liste des flux.
- Le mot de passe est stocké de manière sécurisée dans le Trousseau - d'accès.

-

Par contre, pour les serveurs qui exigent un cookie, le nom - d'utilisateur et le mot de passe ne doivent PAS apparaître dans - la boite de dialogue "Infos" du flux. Les deux champs DOIVENT - être laissés à blanc.
- Par contre, vous devrez être authentifiés auprès du site en vous - connectant via le web à travers le navigateur Safari ou à travers - un onglet de navigation dans Vienna.
- Comme les cookies peuvent expirer après un certain temps, vous - serez peut-être obligés de vous reconnecter de temps à - autres.

-

Comment - déplacer la base de données Vienna dans un autre dossier - ?

-

Par défaut, votre base de données Vienna est le fichier - messages.db placé dans ~/Library/Application Support/Vienna. vous - pouvez déplacer ce fichier dans le dossier de votre choix. Pour - cela, suivez les étapes ci-dessous :

-
    -
  1. Quitter Vienna.
  2. -
  3. Ouvrir une fenêtre de Terminal et taper :
    -
    - defaults write - uk.co.opencommunity.vienna2 "DefaultDatabase" - '<chemin_vers_messages.db>'
    -
    - où <chemin_vers_messages.db> est le nom complet du - fichier messages.db. Le chemin lui-même devrait contenir le nom - messages.db à la fin. Par exemple :
    -
    - defaults write - uk.co.opencommunity.vienna2 "DefaultDatabase" - '/Users/steve/mydata/messages.db'
  4. -
  5. Relancer Vienna.
  6. -
-

- Un de mes abonnements renvoie le message "Erreur de traitement - des données XML dans le flux". Qu'est ce que cela signifie - ?

-

Cela signifie que Vienna a reçu un retour de l'abonnement - qu'il ne sait pas interpréter. Il peut y avoir plusieurs raisons - à cela :

-
    -
  1. L'adresse URL du flux n'indique peut-être pas un flux RSS - ou Atom, mais une page Web. Vérifiez attentivement l'URL de - l'abonnement en question.
  2. -
  3. Le flux lui-même peut contenir un format XML incorrect. - Certains abonnements font des erreurs lors de l'assemblage des - données XML qui constituent le flux et Vienna ne sait pas - interpréter des flux XML incorrects. Utilisez la commande de - validation des flux à partir du menu Fichier pour identifier un - tel cas. Malheureusement, vous ne pourrez rien faire de plus - avec Vienna pour recevoir ce flux, si ce n'est attendre que le - flux soit corrigé par le site émetteur.
  4. -
  5. Le flux peut être incomplet. Si le rafraîchissement a été - interrompu, alors les données XML seront incomplètes et - apparaîtront malformées dans Vienna. Un nouveau - rafraîchissement devrait corriger ce problème.
  6. -
-

Si le problème n'est couvert par aucun des cas ci-dessus, - alors postez un message sur le forum de support en indiquant - l'URL concernée.

-

- Quels sont les raccourcis clavier pour passer à l'article - suivant, le marquer comme étant lu, etc. ?

-

Il existe des raccourcis à une touche pour quelques unes des - commandes des menus, par exemple :

-

Barre d'espace - affiche l'article suivant non lu. Si - l'article actuellement affiché est long de plusieurs pages, cette - commande affichera en priorité les pages suivantes. Elle - n'affichera l'article suivant que si la fin de l'article en cours - est déjà à l'écran. A l'inverse, la commande Cmd+U affichera - diretement l'article non lu suivant, même si l'article en cours - n'est pas lu entièrement.

-

R - Permute l'état lu / non lu pour l'article en cours.

-

F - Permute l'état du drapeau affiché / masqué pour l'article - en cours.

-

Lisez la page dédiées aux raccourcis pour une liste - complète.

-

Que - signifie le point vert dans la liste des articles ?

-

Les points bleus signalent les nouveaux articles, et les - points verts signalent les articles mis à jour : les articles - dont le contenu a changé depuis leur dernier téléchargement.

-

Comment utiliser - Auto Expire, et qu'est ce que cela fait ?

-

Auto-expire déplace les articles plus vieux qu'un certain - nombre de jours dans la corbeille. Cela permet d'obtenir des - dossiers gérables en conservant uniquement les articles les plus - récents. Cette fonction s'exécute à la fois au démarrage de - Vienna et après le rafraîchissement des abonnements. Dans les - préférences, modifiez le paramètre "Expirer les articles vieux - de" pour déterminer les articles à expurger.

-

Auto-expire n'effacera pas les articles non lus ou marqués - d'un drapeau.

-

Comment créer mes propres styles - ?

-

Voir la page Styles personnalisés - pour les instructions.

-

Comment créer mes propres - scripts ?

-

Le pilotage de Vienna par des scripts est possible en - utilisant AppleScript. Voir la page de ressources Apple - pour plus de détails.

-

Un moyen de débuter est de télécharger un des scripts - existants comme celui du plugin de - partage avec Papers écrit par Cortig ou le script de partage - de Vienna - vers Yojimbo écrit par reefdog et de les visualiser dans - l'éditeur d'AppleScript.

-

Pour soumettre vos propres scripts, envoyez-les dans le forum - de support, et après qu'ils sont revus, ils seront diffusés sur - la page de téléchargement.

-

Comment demander des - améliorations dans Vienna ?

-

Laisser un message sur la liste de - problèmes ou demandes (en anglais).

-

Où obtenir le code source - de Vienna ?

-

Voir la page de - développement contenant les instructions pour obtenir le code - source de Vienna. Le code source est disponible librement si vous - vous intéressez au fonctionnement de Vienna, si vous souhaitez - compiler votre propre copie de Vienna sur votre ordinateur ou si - vous souhaitez emprunter des portions de codes pour les inclures - dans votre propre projet. Le code source est diffusé sous la - licence - Apache 2.0.

- - diff --git a/lproj/fr.lproj/Vienna Help/helpstyle.css b/lproj/fr.lproj/Vienna Help/helpstyle.css deleted file mode 100644 index dac51403c2..0000000000 --- a/lproj/fr.lproj/Vienna Help/helpstyle.css +++ /dev/null @@ -1,39 +0,0 @@ -a { - color: #3366CC; - text-decoration: none; -} -.title { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 18pt; - color: #000000; -} -.header { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 12pt; - color: #000000; -} -li { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 100; - font-size: 9pt; - color: #000000; -} -h2 { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 400; - font-size: 10pt; - color: #000000; -} -p { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 100; - font-size: 9pt; - color: #000000; -} -tr { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-size: 9pt; - color: #000000; -} diff --git a/lproj/fr.lproj/Vienna Help/images/Small-Vienna-Logo.jpg b/lproj/fr.lproj/Vienna Help/images/Small-Vienna-Logo.jpg deleted file mode 100644 index 41035b4f11..0000000000 Binary files a/lproj/fr.lproj/Vienna Help/images/Small-Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/fr.lproj/Vienna Help/images/Vertical-Line.jpg b/lproj/fr.lproj/Vienna Help/images/Vertical-Line.jpg deleted file mode 100644 index 011f1ce1e3..0000000000 Binary files a/lproj/fr.lproj/Vienna Help/images/Vertical-Line.jpg and /dev/null differ diff --git a/lproj/fr.lproj/Vienna Help/images/Vienna-Logo.jpg b/lproj/fr.lproj/Vienna Help/images/Vienna-Logo.jpg deleted file mode 100644 index 13a6479bd4..0000000000 Binary files a/lproj/fr.lproj/Vienna Help/images/Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/fr.lproj/Vienna Help/images/rssfeed.gif b/lproj/fr.lproj/Vienna Help/images/rssfeed.gif deleted file mode 100644 index 2dc8935119..0000000000 Binary files a/lproj/fr.lproj/Vienna Help/images/rssfeed.gif and /dev/null differ diff --git a/lproj/fr.lproj/Vienna Help/index.html b/lproj/fr.lproj/Vienna Help/index.html deleted file mode 100755 index aa0e3b1652..0000000000 --- a/lproj/fr.lproj/Vienna Help/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - Aide Vienna - - - - - - - - - - -
-

-

Aide Vienna

-
-

Introduction à Vienna

-

Apprendre comment débuter avec - Vienna.

-

Raccourcis clavier

-

Découvrir les raccourcis - clavier pour les commandes courantes

-

Comment faire ?

-

Questions fréquemment posées, - obtenir du support, étapes de dépannage.

-

Réglages avancés

-

Explications des réglages de - l'onglet Advancés des Préférences.

-
- - diff --git a/lproj/fr.lproj/Vienna Help/intro.html b/lproj/fr.lproj/Vienna Help/intro.html deleted file mode 100755 index 5d605a0202..0000000000 --- a/lproj/fr.lproj/Vienna Help/intro.html +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - Introduction à Vienna - - - - -   Introduction à - Vienna -

Vienna est une application qui permet de lire des flux RSS ou - Atom sur les systèmes Mac OS X. Il automatise la récupération des - nouveaux articles pour tous les abonnements auxquels vous aurez - souscrit et les stocke dans une base de données locale pour une - lecture hors-ligne. Il fournit des fonctions permettant de - rechercher parmi les flux via des mots-clés ou des phrases, de - marquer des articles pour un référencement ultérieur et - d'organiser des flux ensemble à travers des groupes. Vous pouvez - créer des dossiers intelligents qui rendent aisé de retrouver et - consulter dynamiquement tous les articles de la base qui - satisfont des critères de sélection. Le navigateur internet - intégré permet d'afficher dans un onglet séparé, la page web des - articles ou les liens présents dans les articles.

-

Vienna est conçu pour être simple et facile à utiliser. Une - interface propre et dépouillée maximise l'espace pour les - articles, et seules quelques commandes sont nécessaires pour - effectuer les actions les plus courantes dans l'interface - utilisateur.

Pour démarrer -

Lors de la première utilisation de Vienna, il crée une base de - données et ajoute quelques abonnements d'exemple. Continuez ainsi - et pressez Commande+T ou choisissez "Rafraîchir les abonnements" - à partir du menu Fichier pour récupérer les derniers articles - pour ces abonnements.

-

Sinon, souscrivez à vos propres nouveaux flux. Il y a - différents moyens de trouver ces flux. En surfant sut le net, - repérez les icônes - ou XML indiquant qu'un flux est associé à la - page. De plus, presque tous les services de blogs tels que - LiveJournal ou Blogger fournissent des flux RSS comme alternative - à une lecture des publications en ligne.

-

Si vous connaissez le nom d'utilisateur d'un bloggueur inscrit - sur LiveJournal, Blogger, MSN Spaces ou Xanga alors Vienna - fournit un moyen aisé de souscrire à son flux. Pressez Commande+N - ou choisissez la commande "Nouvel abonnement..." à partir du menu - Fichier. Dans le panneau qui s'affiche, sélectionnez le service - de Blog dans la liste déroulante, et saisissez enfin le nom de - l'utilisateur dans le champ de texte en dessous. Confirmer par le - bouton "S'abonner" et Vienna ajoutera l'abonnement dans la liste - des dossiers. Si vous êtes connectés à Internet au même moment, - il commencera tout de suite à collecter les articles pour ce - flux.

-

Vous pouvez aussi utiliser Vienna en lien avec un compte de - serveur Open Reader. Allez dans Préférences... / Syncing et - activez la case "Synchroniser avec un serveur Open Reader".
- Au préalable, interrogez vous sur les flux que vous lirez à - travers Open Reader et ceux pour lesquels vous choisirez un accès - direct. Vienna évitera de créer des doublons entre les deux - catégories, mais si vous vous abonnez dans Open Reader à des flux - auxquels Vienna accède directement, vous aurez des incohérences - dans vos listes de lectures. Tenez en compte.
- Certains éléments sont à prendre en compte dans votre - organisation :

-
    -
  • Les flux Open Reader peuvent être synchronisés entre - différents appareils et différentes applications qui supportent - la synchronisation Open Reader
  • -
  • Open Reader ne permet pas d'accéder aux flux nécessitant un - nom d'utilisateur et un mot de passe
  • -
  • Accéder directement aux sites évite l'intermédiaire que - constitue un service Open Reader. Vous récupérerez souvent - l'information plus vite, notamment en ce qui concerne les sites - un peu moins "populaires".
  • -
  • Généralement, l'accès direct aux sites d'origine entraîne - moins de trafic réseau. Lorsque le serveur signale qu'il n'y a - pas de nouveaux articles depuis la dernière collecte, Vienna - évite un téléchargement inutile.
  • -
-

Normalement vous devez indiquer manuellement à Vienna de - rafraîchir les abonnements. Cependant, cela peut être automatisé - à intervalles réguliers. Pour cela, ouvrez la section "Générale" - du panneau de Préférences, sélectionnez l'intervalle de - rafraîchissement dans la liste déroulante en face du paramètre - 'Relever les nouveaux articles'. Vienna doit être lancé pour - pouvoir exécuter le rafraîchissement automatique.

-

Lors de la lecture des articles, pressez la barre d'espace - pour passer au prochain article non lu. Chaque article est marqué - comme étant lu automatiquement après un court délai. Si vous - préférez attendre de passer à l'article suivant pour marquer - l'article actuel comme étant lu, alors modifiez ce réglage dans - la section "Générale" des Préférences. Pour marquer à nouveau un - article comme étant non lu, choisissez la commande "Marquer comme - non lu" à partir du menu Message ou pressez simplement la touche - 'R'.

-

Finalement, vous pouvez visualiser dans Vienna la page web de - l'article ou n'importe quelle page dont le lien est contenu dans - un article. Vienna supporte beaucoup des fonctions élémentaires - d'un navigation internet. Par défaut, cliquer sur un lien dans - Vienna ouvrira la page web dans un nouvel onglet. Si vous - préférez visualiser toutes les pages web avec une autre - navigateur, alors dans la section "Générale" du panneau de - Préférences, activez l'option 'Ouvrir les liens dans un autre - navigateur'. Pour visualiser au cas par cas les liens pour les - pages dans un autre navigateur, choisissez dans le menu - contextuel de la page (bouton droit ou Crontrol-clic) la commande - "Ouvrir le lien dans XXX" ou "Ouvrir la page dans XXX" où XXX est - le nom de votre navigateur internet par défaut.

-

Dès que vous vous sentirez à l'aise avec Vienna, poursuivez et - explorez the différentes options. Vous pouvez changer l'apparence - d'affichage des articles en sélectionnant un Style dans la liste - du menu Affichage/Style. Vous trouverez beaucoup plus de styles - personnalisés sur la page de téléchargement du - site web de Vienna, ainsi que des scripts qui permettent - d'intégrer Vienna aux autres applications de votre ordinateur. - Vous pouvez expérimenter les dossiers intelligents pour organiser - les articles selon des critères fondés sur le contenu de chaque - article.

-

Si vous avez des questions au sujet de Vienna ou si vous - rencontrez des problèmes, envoyez un e-mail à Vienna Help ou - reportez-vous au forum de - support (en anglais).

- - diff --git a/lproj/fr.lproj/Vienna Help/keyboard.html b/lproj/fr.lproj/Vienna Help/keyboard.html deleted file mode 100644 index 18d7a02727..0000000000 --- a/lproj/fr.lproj/Vienna Help/keyboard.html +++ /dev/null @@ -1,364 +0,0 @@ - - - - - - Raccourcis clavier - - - - -  Raccourcis - clavier -

Dans Vienna vous pouvez utiliser votre clavier pour exécuter - rapidement beaucoup d'actions. Pour trouver les raccourcis - clavier pour les commandes courantes, regardez dans les menus (ou - parcourrez la liste en bas de cette page). Beaucoup d'objets dans - Vienna, tels que la liste des dossiers ou celle des articles - possèdent aussi un menu contextuel. Pour afficher un menu - contextuel, pressez la touche "Ctrl" et cliquez sur l'objet.

-

Pour réaliser une action, pressez les raccourcis indiqués - ci-dessous.

- - - - - -
Combinaison de - touchesAction
- - - - - -
Raccourci à une touche 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
fOuvrir la barre de recherche et sélectionne le champ de - recherche.
hSélectionne le champ de recherche.
kMarque tous les articles du dossier courant comme étant - lus.
mPermute l'état affiché/masqué du drapeau pour les - articles sélectionnés.
nVa à l'article non lu suivant.
r ou uPermute l'état lu/non lu pour les articles - sélectionnés.
sMarque tous les articles du dossier courant comme étant - lus et passe au prochain dossier contenant des articles non - lus.
<Affiche l'article ou la page web précédent.
>Affiche l'article ou la page web suivant.
GaucheSélectionne la liste des dossiers lorsque on se trouve - dans la liste des articles
Barre d'espacePasse au prochain article non lu, à moins qu'il reste du - texte à afficher pour l'article en cours ; dans ce cas, on - affiche la page de texte suivante.
Entrée ou ReturnOuvre la page web source de l'article sélectionné.
Suppr ou BackspaceDéplace les articles sélectionnés dans la corbeille. - Lorsque cette commande est utilisée à partir de la corbeille, - les articles sélectionnés sont définitivement détruits.
- - - - - -
Raccourcis généraux 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Alt-ClickOuvre la page originelle de l'article dans un onglet sans - tenir compte des préférences pour ouvrir les liens dans un - navigateur externe.
Shift-⌘-BAffiche la barre de filtre.
⌘-NCrée un nouvel abonnement.
Shift-⌘-GCrée un nouveau groupe.
Shift-⌘-FCrée un nouveau groupe intelligent.
Shift-⌘-EModifie l'adresse URL du dossier sélectionné ou modifie - les critères du dossier intelligent sélectionné.
Shift-⌘-DSupprime le groupe sélectionné.
⌘-CCopie le texte sélectionné dans le presse-papier. Si la - zone active est la liste des articles, copie l'intégralité de - l'article sélectionné.
⌘-HMasque Vienna.
Alt-⌘-HMasque toutes les applications sauf Vienna.
⌘-IAffiche la fenêtre d'information pour le dossier - sélectionné.
⌘-LSélectionne le champ d'adresse du navigateur de l'onglet - actuel ; ouvre un nouvel onglet avec un navigateur si - besoin.
Shift-⌘-NRenomme le dossier sélectionné.
⌘-RRafraîchit tous les abonnements.
Shift-⌘-RRafraîchit uniquement les abonnements sélectionnés dans - la liste des dossiers.
Ctrl-⌘-SStoppe tout rafraîchissement en cours.
⌘-PImprime les articles sélectionnés.
Shift-⌘-PAffiche la fenêtre de mise en page.
⌘-QQuitte Vienna.
⌘-TOuvre un nouvel onglet avec un navigateur et sélectionne - le champ d'adresse du navigateur.
⌘-UPasse au prochain article non lu.
⌘-ZAnnule l'action précédente si c'est possible.
⌘-+ (plus)Augmente la taille du texte dans la page WEB ou l'article - actif.
⌘-- (moins)Diminue la taille du texte dans la page WEB ou l'article - actif.
⌘-, (virgule)Affiche le panneau des préférences.
Alt-⌘-BackSpaceVide la corbeille après demande de confirmation.
⌘-?Affiche l'aide Vienna.
- - - - - -
Raccourcis Articles 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Alt-Entrée ou Alt-ReturnOuvre la page originelle de l'article dans un onglet sans - tenir compte des préférences pour ouvrir les liens dans un - navigateur externe.
Shift-⌘-ZRétablit la dernière action si elle vient juste d'être - annulée.
Shift-⌘-MMarque d'un drapeau les articles sélectionnés.
Shift-⌘-UMarque les articles sélectionnés comme étant lus.
Alt-⌘-SOuvre l'application de messagerie par défaut et crée un - courrier avec un lien vers l'article actuel.
Shift-⌘-SMarque tous les articles du dossier actuel comme étant - lus et passe au prochain dossier ayant des articles non - lus.
Shift-⌘-ORétablit un article de la corbeille dans son dossier - d'origine.
Shift-⌘-KMarque tous les articles des dossiers sélectionnés comme - étant lus.
Alt-⌘-KMarque tous les articles de tous les dossiers comme étant - lus.
- - - - - -
Raccourcis fenêtre 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
⌘-WFerme l'onglet actif si plusieurs sont ouverts ; sinon, - ferme la fenêtre Vienna.
Alt-⌘-WFerme tous les onglets autres que la liste des articles. - Note : cette commande remplace la commande "Fermer l'onglet" - dans le menu Fichier lorsque la touche Alt est pressée.
Alt-⌘-GaucheAffiche l'onglet précédent.
Alt-⌘-DroiteAffiche l'onglet suivant.
⌘-MRéduit la fenêtre principale ves le dock.
⌘-0Affiche la fenêtre l'activité.
⌘-1Réaffiche la fenêtre Vienna si celle-ci a été - préalablement fermée.
⌘-2Affiche la fenêtre de téléchargement.
- - - - - -
Racourcis du navigateur internet 
- - - - - - - - - - - - - - - - - - - - - - - - - -
Alt-RRecharge la page web active.
⌘-. (point)Arrête le chargement de la page web active.
⌘-[ ou ⌘-GaucheAffiche la page web précédente.
⌘-] ou ⌘-DroiteAffiche la page web suivante.
⌘-FAcitve le champ de recherche. Après validation par Enter, - le texte saisi sera recherché sur la page web active.
⌘-GRecherche l'occurrence suivante sur la page web - active.
- - diff --git a/lproj/gl.lproj/EmptyTrashWarning.strings b/lproj/gl.lproj/EmptyTrashWarning.strings new file mode 100644 index 0000000000..932f939403 --- /dev/null +++ b/lproj/gl.lproj/EmptyTrashWarning.strings @@ -0,0 +1,13 @@ + +/* NSButton (Do not show this warning again) : (oid:10) */ +"Do not show this warning again" = "Non amosar este aviso de novo"; + +/* NSButton (Don't Empty Trash) : (oid:8) */ +"Don't Empty Trash" = "Non baleirar a papeleira"; + +/* NSButton (Empty Trash) : (oid:7) */ +"Empty Trash" = "Tirar o lixo"; + +/* NSTextField (There are deleted articles in the trash. Would you like to empty the trash before quitting?) : (oid:9) */ +"There are deleted articles in the trash.\nWould you like to empty the trash before quitting?" = "Hai artigos eliminados na papeleira.\nQueres baleirala antes de saír??"; diff --git a/lproj/gl.lproj/FeedCredentials.strings b/lproj/gl.lproj/FeedCredentials.strings new file mode 100644 index 0000000000..cb8a1d0867 --- /dev/null +++ b/lproj/gl.lproj/FeedCredentials.strings @@ -0,0 +1,20 @@ +/* NSPanel () : (oid:5) */ +"" = ""; + +/* NSTextField (Access to %@ requires you to provide log in credentials) : (oid:10) */ +"Access to %@ requires you to provide log in credentials" = "O acceso a %@ precisa que proporciones os datos credenciais credenciales de inicio de sesión"; + +/* NSButton (Cancel) : (oid:8) */ +"Cancel" = "Cancelar"; + +/* NSButton (Log In) : (oid:14) */ +"Log In" = "Iniciar sesión"; + +/* NSTextField (Name:) : (oid:9) */ +"Name:" = "Nome:"; + +/* NSTextField (Password:) : (oid:13) */ +"Password:" = "Contrasinal:"; + +/* NSTextField (The user name and password you provide will be remembered for the next time you refresh this subscription.) : (oid:15) */ +"The user name and password you provide will be remembered for the next time you refresh this subscription." = "O nome de usuario e o contrasinal serán lembrados para a próxima vez que actualices esta subscrición."; diff --git a/lproj/gl.lproj/GroupFolder.strings b/lproj/gl.lproj/GroupFolder.strings new file mode 100644 index 0000000000..12b317458a --- /dev/null +++ b/lproj/gl.lproj/GroupFolder.strings @@ -0,0 +1,15 @@ +/* NSButton (Cancel) : (oid:22) */ +"Cancel" = "Cancelar"; + +/* NSTextField (Enter the group folder name: ) : (oid:23) */ +"Enter the group folder name:\n" = "Introduza o nome do cartafol do grupo:\n"; + +/* NSTextField (New Group Folder) : (oid:19) */ +"New Group Folder" = "Novo cartafol de grupo"; + +/* NSPanel (Panel) : (oid:5) */ +"Panel" = "Panel"; + +/* NSButton (Save) : (oid:21) */ +"Save" = "Gardar"; diff --git a/lproj/gl.lproj/InfoWindow.strings b/lproj/gl.lproj/InfoWindow.strings new file mode 100644 index 0000000000..a2bf3d87c4 --- /dev/null +++ b/lproj/gl.lproj/InfoWindow.strings @@ -0,0 +1,66 @@ + +/* Class = "NSWindow"; title = "Window"; ObjectID = "5"; */ +"5.title" = "Fiestra"; + +/* Class = "NSBox"; title = "Box"; ObjectID = "95"; */ +"95.title" = "Caixa"; + +/* Class = "NSBox"; title = "Box"; ObjectID = "97"; */ +"97.title" = "Caixa"; + +/* Class = "NSBox"; title = "Box"; ObjectID = "99"; */ +"99.title" = "Caixa"; + +/* Class = "NSBox"; title = "Box"; ObjectID = "101"; */ +"101.title" = "Caixa"; + +/* Class = "NSTextFieldCell"; title = "(Folder name)"; ObjectID = "104"; */ +"104.title" = "(Nome do cartafol)"; + +/* Class = "NSTextFieldCell"; title = "Last Refreshed:"; ObjectID = "105"; */ +"105.title" = "Última actualización:"; + +/* Class = "NSTextFieldCell"; title = "(Last refresh date)"; ObjectID = "106"; */ +"106.title" = "(Data da última actualización)"; + +/* Class = "NSButtonCell"; title = "Validate"; ObjectID = "109"; */ +"109.title" = "Validar"; + +/* Class = "NSButtonCell"; title = "Feed URL:"; ObjectID = "110"; */ +"110.title" = "URL da fonte:"; + +/* Class = "NSTextFieldCell"; title = "User name:"; ObjectID = "111"; */ +"111.title" = "Nome de usuario:"; + +/* Class = "NSTextFieldCell"; title = "Password:\n"; ObjectID = "112"; */ +"112.title" = "Contrasinal:\n"; + +/* Class = "NSButtonCell"; title = "Update Authentication"; ObjectID = "115"; */ +"115.title" = "Actualizar autenticación"; + +/* Class = "NSButtonCell"; title = "Authentication:"; ObjectID = "116"; */ +"116.title" = "Autenticación:"; + +/* Class = "NSTextFieldCell"; title = "Size:"; ObjectID = "117"; */ +"117.title" = "Tamaño:"; + +/* Class = "NSTextFieldCell"; title = "Unread:\n"; ObjectID = "118"; */ +"118.title" = "Non lidos:\n"; + +/* Class = "NSTextFieldCell"; title = "\n"; ObjectID = "119"; */ +"119.title" = "\n"; + +/* Class = "NSTextFieldCell"; title = "\n"; ObjectID = "120"; */ +"120.title" = "\n"; + +/* Class = "NSButtonCell"; title = "Subscribed"; ObjectID = "121"; */ +"121.title" = "Subscrito"; + +/* Class = "NSButtonCell"; title = "General:"; ObjectID = "122"; */ +"122.title" = "Xeral:"; + +/* Class = "NSButtonCell"; title = "Description:"; ObjectID = "124"; */ +"124.title" = "Descrición:"; + +/* Class = "NSButtonCell"; title = "Load Full HTML Articles"; ObjectID = "126"; */ +"126.title" = "Cargar artigos HTML completamente"; diff --git a/lproj/gl.lproj/Localizable.strings b/lproj/gl.lproj/Localizable.strings new file mode 100644 index 0000000000..3ecd77285d --- /dev/null +++ b/lproj/gl.lproj/Localizable.strings @@ -0,0 +1,459 @@ +"Mark Read" = "Marcar como lido"; +"Mark Unread" = "Marcar como non lido"; +"Mark Unflagged" = "Quitar marcas"; +"Articles" = "Artigos"; +"Folders" = "Cartafpñes"; +"Loading %@..." = "Cargando %@..."; +"Completed" = "Completado"; +"Refresh RSS feeds" = "Actualizar as subscricións"; +"Refresh All Subscriptions" = "Actualizar todas as subscricións"; +"Already subscribed title" = "Erro"; +"Already subscribed body" = "Xa está subscrito a esta fonte"; +"RSS Subscription Import Title" = "Importación completada"; +"%d subscriptions successfully imported" = "%d subscricións importadas correctamente"; +"RSS Subscription Export Title" = "Exportación completada"; +"%d subscriptions successfully exported" = "%d subscricións correctamente exportadas"; +"New unread articles retrieved" = "Recuperados novos artigos sen ler"; +"Growl refresh completed" = "Novos artigos recuperados"; +"New articles retrieved" = "Novos artigos recuperados"; +"(Untitled Feed)" = "(Fonte sen título)"; +"Open Link in Browser" = "Abrir a ligazón no navegador"; +"Copy Link to Clipboard" = "Copiar ligazón ao portapapeis"; +"Refresh completed" = "Actualización completada"; +"Retrieving articles" = "Recuperando artigos"; +"ClearButton" = "Borrar"; +"Read" = "Lido"; +"Flagged" = "Destacado"; +"Comments" = "Comentarios"; +"Parent" = "Pai"; +"Number" = "Número"; +"Subject" = "Asunto"; +"Folder" = "Cartafol"; +"Date" = "Data"; +"Author" = "Autor"; +"Text" = "Texto"; +"Headlines" = "Titulares"; +"Link" = "Ligazón"; +"Deleted" = "Eliminado"; +"GUID" = "GUID"; +"No" = "Non"; +"Yes" = "Si"; +"Version %@" = "Versión %@"; +"Refresh All" = "Actualizar todo"; +"Subscribe" = "Subscribirse"; +"Smart Folder" = "Cartafol intelixente"; +"Flag" = "Destacar"; +"Next Unread" = "Seguinte artigo sen ler"; +"Noon" = "Mediodía"; +"Midnight" = "Medianoite"; +"Today" = "Hoxe"; +"Yesterday" = "Onte"; +"Tomorrow" = "Mañá"; +"%@ at %@" = "%@ ás %@"; +"Quit" = "Saír"; +"Refresh cancelled" = "Actualización cancelada"; +"Additional actions for the selected folder" = "Accións adicionais para o cartafol seleccionado"; +"Create a new subscription" = "Crear nova subscrición"; +"Refresh all your subscriptions" = "Actualizar todas as subscricións"; +"New style title" = "Vienna instalou un novo estilo"; +"New style body" = "O estilo \"%@\" foi instalado no cartafol correspondente e engadido ao menú Estilos."; +"More Styles..." = "Máis estilos..."; +"Delete selected message" = "Estás seguro de eliminar permanentemente os artigos seleccionados?"; +"Delete selected message text" = "Esta operación non pode ser desfeita."; +"Cancel" = "Cancelar"; +"OK" = "Aceptar"; +"From" = "De"; +"To" = "Para"; +"(No title)" = "(Sen título)"; +"Refreshing folder images..." = "Actualizando as iconas dos cartafoles..."; +"Refreshing subscriptions..." = "Actualizando as subscricións..."; +"Authenticating with user name '%@'" = "Autenticando co nome de usuario \"%@\""; +"No new articles available" = "Non hai novos artigos dispoñibles"; +"%d new articles retrieved" = " Recuperados %d novos artigos"; +"HTTP code %d reported from server" = "Código HTTP %d notificado dende o servidor"; +"Headers:\n" = "Cabeceiras:\n"; +"Connection error (%d, %@):\n" = "Erro de conexión (%d, %@):\n"; +"\tDescription: %@\n" = "\tDescrición: %@\n"; +"\tSuggestion: %@\n" = "\tSuxerencia: %@\n"; +"\tCause: %@\n" = "\tMotivo: %@\n"; +"Article feed will be compressed" = "A fonte do artigo será comprimida"; +"Redirecting to %@" = "Redirixindo a %@"; +"Error: %@" = "Erro: %@"; +"Error" = "Erro"; +"Credentials Prompt" = "A subscrición a \"%@\" precisa dun nome de usuario e dun contrasinal."; +"%ld bytes received" = "%ld bytes recibidos"; +"Authentication failed for user '%@'" = "Produciuse un erro ao autenticar ao usuario \"%@\""; +"Error parsing XML data in feed" = "Erro ao analizar os datos XML da fonte"; +"Retrieving folder image" = "Recuperando a icona do cartafol"; +"Folder image retrieved from %@" = "Icona do cartafol recuperada de %@"; +"Contacting..." = "Conectando..."; +"Connect Running" = "Conexión iniciada"; +"Connect Running text" = "Desexas cancelar a conexión e saír de Vienna agora?"; +"Delete group folder" = "Eliminar cartafol de grupo"; +"Delete group folder text" = "Realmente queres eliminar o cartafol de grupo \"%@\" e todo o seu contido? Esta operación non se pode desfacer."; +"Delete smart folder" = "Eliminar cartafol intelixente"; +"Delete smart folder text" = "Realmente queres eliminar o cartafol intelixente \"%@\"? Esta operación non eliminará os artigos atopados actualmente pola busca."; +"Delete RSS feed text" = "¿Está seguro que desea cancelar la suscripción a \"%@\"? Esta operación eliminará todos los artículos almacenados."; +"Delete RSS feed" = "Eliminar subscrición"; +"Delete multiple folders text" = "Realmente queres eliminar todos os cartafoles seleccionados? Esta operación non se pode desfacer."; +"Delete multiple folders" = "Eliminar varios cartafoles"; +"Delete folder status" = "Eliminando cartafol \"%@\"..."; +"An error has occurred" = "Algo fallou."; +"Your software is up to date" = "A túa versión de Vienna está actualizada."; +"Please try again later" = "Por favor, téntao máis tarde."; +"An update is now available" = "Dispoñible unha actualización"; +"Update available text" = "A versión %@ de Vienna está dispoñible en:\n\n%@\n\nDesexas descargarla agora? Se non queres facelo agora, podes descargala noutro momento escollendo Comprobar Actualizacións outra vez."; +"any" = "algunha"; +"all" = "todas"; +"Open Scripts Folder" = "Abrir o cartafol de scripts"; +"Cannot create database folder" = "Sentímolo, mais Vienna non puido crear o cartafol da base de datos"; +"Cannot create database folder text" = "Vienna ha intentado crear la carpeta \"%@\" pero ha ocurrido un error. Compruebe los permisos de las carpetas de la ruta especificada."; +"Unrecognised database format title" = "O formato do arquivo da base de datos cambiou"; +"Unrecognised database format text" = "O formato do archivo da base de datos (%@) non é compatible con esta versión de Vienna. Elimine o arquivo ou cambie o seu nome e reinicie Vienna.\n"; +"Upgrade Title" = "Actualización da base de datos"; +"Upgrade Text" = "A base de datos existente precisa actualizarse para poder ser empregada con esta versión de Vienna. Si queres, podes crear unha nova baleira. De calquer modo, a base de datos actual será localizada en %@. Teña en conta que a nova base de datos non funcionará con versións anteriores de Vienna.\n\nNota: Para esta versións recoméndase iniciar unha nova base de datos.\n";/*no*/ +"New Database" = "Nova base de datos"; +"Upgrade" = "Actualizar"; +"Exit" = "Saír"; +"Search in %@" = "Procurar en %@"; +"Marked Articles" = "Artigos marcados"; +"Unread Articles" = "Artigos non lidos"; +"Today's Articles" = "Artigos de hoxe"; +"Trash" = "Lixo"; +"Select..." = "Seleccionar..."; +" (%d unread)" = " (%d non lidos)"; +"is" = "é"; +"is not" = "non é"; +"is after" = "é posterior a"; +"is before" = "é anterior a"; +"is on or after" = "é a partir de"; +"is on or before" = "é anterior a ou de"; +"contains" = "contén"; +"does not contain" = "non contén"; +"is less than" = "é menor que"; +"is greater than" = "é maior que"; +"is less than or equal to" = "é menor ou igual que"; +"is greater than or equal to" = "é maior ou igual que"; +"Cannot open export file message" = "Non se pode crear o arquivo de exportación"; +"Cannot open export file message text" = "Non se pode crear o arquivo de exportación especificado. Comprobe que non está bloqueado e que ningunha outra aplicación o está a empregar."; +"Source" = "Fonte"; +"Status" = "Estado"; +"Enter LiveJournal User name" = "Introduza o nome de usuario de LiveJournal"; +"Enter MSN Spaces User name" = "Introduza o nome de usuario de MSN Spaces"; +"Enter Blogspot User name" = "Introduza o nome de usuario de Blogspot"; +"Enter Xanga User name" = "Introduza o nome de usuario de Xanga"; +"Enter URL of RSS feed" = "Introduza a URL da fonte de novas"; +"Cannot rename folder" = "Non se puido renomear o cartafol"; +"A folder with that name already exists" = "Xa existe un cartafol con ese nome"; +"Recent Searches" = "Buscas recentes"; +"Recents" = "Recentes"; +"Clear" = "Baleirar as buscas recentes"; +"Search web page" = "Procurar páxina web"; +"Loading..." = "Cargando..."; +"Open Image in New Tab" = "Abrir imaxe nunha nova lapela"; +"Open Link in New Tab" = "Abrir ligazón nunha nova lapela"; +"Open Link in %@" = "Abrir ligazón en %@"; +"Open Page in %@" = "Abrir páxina en %@"; +"Copy Page Link to Clipboard" = "Copiar ligazón da páxina ao portapapeis"; +"%d unread articles" = "%d artigos sen ler"; +"More Scripts..." = "Máis scripts..."; +"Install Update" = "Instalar a actualización"; +"Do Not Install" = "Non instalar"; +"Replace smart folder title" = "Xa existe un cartafol chamado %@"; +"Replace smart folder text" = "Desexas reemplazar o cartafol intelixente polo criterio definido aquí?"; +"Replace" = "Reemprazar"; +"Never" = "Nunca"; +"After a Day" = "Despois dun día"; +"After 2 Days" = "Despois de 2 días"; +"After a Week" = "Despois dunha semana"; +"After 2 Weeks" = "Despois de 2 semanas"; +"After a Month" = "Despois dun mes"; +"Last Week" = "Última semana"; +"2 Weeks Ago" = "Hai 2 semanas"; +"A month" = "Un mes"; +"Activity Window" = "Xanela de actividade"; +"Error importing subscriptions body" = "Erro ao importar o arquivo especificado. O contido deste non está nun formato OPML XML válido."; +"Error importing subscriptions title" = "Error ao importar"; +"Rename" = "Renomear"; +"Mark All Read" = "Marcar todos como lidos"; +"Move Folders" = "Mover cartafoles"; +"Downloads" = "Descargas"; +"Invalid style title" = "O estilo %@ semella danado ou perdido."; +"Invalid style body" = "O estilo por defecto (Default) será empregado no seu lugar."; +"Downloads Running" = "Unha ou máis descargas en curso"; +"Downloads Running text" = "Se saes de Vienna agora, deteranse as descargas."; +"Mark All Subscriptions as Read" = "Marcar todas as subscricións como lidas"; +"Preferences" = "Preferencias"; +"General" = "Xeral"; +"Appearance" = "Apariencia"; +"Locate Title" = "Non se pode crear a base de datos de Vienna"; +"Locate Text" = "Non se pode crear a nova base de datos de Vienna en \"%@\" debido a que probablemente o cartafol está ubicado nun recurso compartido dunha rede remota e esta versión de Vienna non pode xestionar bases de datos remotas. Por favor, escolle un cartafol alternativo ubicado no seu equipo local.\n"; +"Empty Trash message" = "Realmente queres eliminar permanentemente as mensaxes do lixo?"; +"Empty Trash message text" = "Esta acción non pode ser desfeita."; +"Cannot open database" = "Vienna non puido abrir a base de datos"; +"Cannot open database text" = "Por algún motivo, o artigo da base de datos (%@) non se puido abrir. Pode estar danado ou inaccesible. Por favor, elimine ou cambie o nome do arquivo da base de datos e reinicie Vienna."; +"Vienna cannot open the file title" = "Vienna non pode abrir o arquivo."; +"Vienna cannot open the file body" = "Vienna non pode abrir o arquivo \"%@\" xa que foi movido desde que foi descargado."; +"Vienna cannot show the file title" = "Vienna non pode amosar o arquivo."; +"Vienna cannot show the file body" = "Vienna non pode amosar o arquivo \"%@\" xa que foi movido desde que foi descargado."; +"Empty" = "Baleirar"; +"Open" = "Abrir"; +"Show in Finder" = "Amosar no Finder"; +"Remove From List" = "Borrar da listaxe"; +"%.1f MB" = "%.1f MB"; +"%.1f KB" = "%.1f KB"; +"%.1f bytes" = "%.1f bytes"; +"%.1f of %.1f MB" = "%.1f de %.1f MB"; +"%.1f of %.1f KB" = "%.1f de %.1f KB"; +"%.1f of %.1f bytes" = "%.1f de %.1f bytes"; +"An error occurred when this feed was last refreshed" = "Produciuse un erro ao actualizar esta fonte"; +"Connecting to %@" = "Conectando con %@"; +"About Vienna" = "Acerca de Vienna"; +"Acknowledgements" = "Agradecemento"; +"Article" = "Artigo"; +"Back" = "Atrás"; +"Bring All to Front" = "Traer todo ao fronte"; +"Check Spelling" = "Comprobar ortografía"; +"Check Spelling as You Type" = "Comprobar ortografía namentres escribe"; +"Check for Updates" = "Procurar actualizacións"; +"Close All Tabs" = "Pechar todas as lapelas"; +"Close Tab" = "Pelas lapela"; +"Close Window" = "Pechar xanela"; +"Columns" = "Columnas"; +"Copy" = "Copiar"; +"Cut" = "Cortar"; +"Delete" = "Eliminar"; +"Delete Article" = "Eliminar artigo"; +"Delete…" = "Eliminar..."; +"Edit" = "Edición"; +"Edit…" = "Editar..."; +"Empty Trash" = "Baleirar o lixo"; +"Export Subscriptions…" = "Exportar subscricións..."; +"File" = "Arquivo"; +"Find" = "Procurar"; +"Find Next" = "Procurar seguinte"; +"Find Previous" = "Procurar anterior"; +"Find…" = "Procurar..."; +"Forward" = "Adiante"; +"Help" = "Axuda"; +"Hide Others" = "Ocultar outros"; +"Hide Vienna" = "Ocultar Vienna"; +"Import Subscriptions…" = "Importar subscricións..."; +"Jump to Selection" = "Ir á selección"; +"Main Window" = "Xanela principal"; +"MainMenu" = "Menú principal"; +"Mark All Articles as Read" = "Marcar todos os artigos como lidos"; +"Mark Flagged" = "Marcar como destacado"; +"Minimize" = "Minimizar"; +"New Group Folder…" = "Novo cartafol de grupo..."; +"New Smart Folder…" = "Novo cartafol intelixente..."; +"New Subscription…" = "Nova subscricións..."; +"Next Tab" = "Lapela seguinte"; +"Open Article Page" = "Abrir páxina do artigo"; +"Open Article Page in External Browser" = "Abrir páxina do artigo nun navegador externo"; +"Open Subscription Home Page" = "Abrir páxina da subscrición"; +"Open Subscription Home Page in External Browser" = "Abrir páxina da subscrición nun navegador externo"; +"Page Setup…" = "Configurar páxina…"; +"Paste" = "Pegar"; +"Preferences…" = "Preferencias..."; +"Previous Tab" = "Lapela anterior"; +"Print…" = "Imprimir..."; +"Quit Vienna" = "Saír de Vienna"; +"Redo" = "Refacer"; +"Refresh Selected Subscriptions" = "Actualizar subscricións seleccionadas"; +"Reload Page" = "Volver a cargar a páxina"; +"Rename…" = "Renomear..."; +"Restore Article" = "Restaurar artigo"; +"Select All" = "Seleccionar todo"; +"Services" = "Servizos"; +"Show All" = "Amosar todo"; +"Skip Folder" = "Omitir cartafol"; +"Sort By" = "Clasificar por"; +"Spelling" = "Ortografía"; +"Spelling…" = "Ortografía..."; +"Stop Refreshing" = "Cancelar actualización"; +"Stop Reloading Page" = "Deixar de recargar a páxina"; +"Style" = "Estilo"; +"Undo" = "Desfacer"; +"Use Selection for Find" = "Usar a selección para procurar"; +"Validate Feed" = "Validar fonte"; +"Vienna Help" = "Axuda de Vienna"; +"Vienna Web Site" = "Páxina web de Vienna"; +"View" = "Visualización"; +"Window" = "Xanela"; +"Zoom" = "Zoom"; +"Export all subscriptions" = "Exportar todas as subscricións"; +"Export selected subscriptions" = "Exportar subscricións seleccionadas"; +"Preserve group folders in exported file" = "Manter os cartafoles de grupo no arquivo exportado"; +"Open Frame" = "Abrir marco"; +"Open Image in %@" = "Abrir imaxe en %@"; +"Open Subscription Home Page in %@" = "Abrir páxina da subscrición en %@"; +"Open Article Page in %@" = "Abrir páxina do artigo en %@"; +"New Tab" = "Nova lapela"; +"External Browser" = "navegador externo"; + +/* Added in 2.1.0 */ +"Send Link" = "Enviar ligazón"; +"Send Links" = "Enviar ligazóns"; +"Increase Font Size" = "Aumentar o tamaño da fonte"; +"Decrease Font Size" = "Reducir o tamaño da fuente"; +"Enter the URL here" = "Introduza a URL aquí"; +"Refresh the current page" = "Actualizar a páxina actual"; +"Return to the previous page" = "Volver á páxina anterior"; +"Go forward to the next page" = "Avanzar á páxina seguinte"; +"Layout" = "Formato"; +"Reading Pane on Right" = "Panel de lectura na dereita"; +"Reading Pane at Bottom" = "Panel de lectura abaixo"; +"Filter By" = "Filtrar por"; +"Filter by:" = "Filtrar por:"; +"All" = "Todos"; +"All Articles" = "Todos os artigos"; +"Unread" = "Sen ler"; +"Last Refresh" = "Última actualización"; +"Feed URL updated to %@" = "URL da fonte actualizada a %@"; +"Filter articles" = "Filtrar artigos"; +"Feed has been removed by the server" = "A fonte foi eliminada polo servidor"; +"Mark all articles read" = "Marcar todos os artigos como lidos"; +"%@ Info" = "Información de %@"; +"%u articles" = "%u artigos"; +"%u unread" = "%u sen ler"; +"Keyboard Shortcuts" = "Atallos de teclado"; +"%@ (Filtered: %@)" = "%@ (Filtrado: %@)"; +"Get Info..." = "Obter información..."; +"Open Web Location..." = "Abrir ubicación..."; +"Refresh Folder Images" = "Actualizar as iconas dos cartafoles"; +"Report" = "Horizontal"; +"Condensed" = "Vertical"; +"Unified" = "Unificado"; +"Summary" = "Resumo"; +"Blog With..." = "Publicar nun blog con"; +"Blog with %@" = "Publicar nun Blog con %@"; +"Bigger Text" = "Aumentar o tamaño do texto"; +"Smaller Text" = "Reducir o tamaño do texto"; + +/* Added in 2.1.1 */ +"Advanced" = "Avanzado"; + +/* Added in 2.2.0 */ +"Import subscriptions from OPML file?" = "Importar subscricións dende o arquivo OPML?"; +"Do you really want to import the subscriptions from the specified OPML file?" = "Realmente desexa importar as subscricións do arquivo OPML especificado?"; +"Import" = "Importar"; +"HasEnclosure" = "Arquivo adxunto"; +"Enclosure" = "URL do adxunto"; +"Open New Tab" = "Abrir nova lapela"; +"Subscribe to the feed for this page" = "Subscribirse á fonte desta páxina"; +"Open Vienna" = "Abrir Vienna"; +"Download Enclosure" = "Descargar arquivo adxunto"; +"Download Enclosures" = "Descargar arquivos adxuntos"; +"Local File" = "Arquivo local"; +"Hide Status Bar" = "Ocultar barra de estado"; +"Show Status Bar" = "Amosar barra de estado"; +"Customize Toolbar..." = "Personalizar barra de ferramentas..."; +"Search Articles" = "Procurar artigos"; +"Progress" = "Progreso"; +"Delete all articles in the trash" = "Eliminar todos os artigos do papeleiro"; +"Unsubscribe" = "Cancelar subscricións"; +"Resubscribe" = "Volver a subscribirse á fonte"; +"Download" = "Descargar"; +"This article contains an enclosed file." = "Este artigo contén un arquivo adxunto."; +"Growl download completed" = "Descarga do arquivo correcta"; +"Growl download failed" = "Error ao descargar o arquivo"; +"Download completed" = "Descarga completada"; +"File %@ downloaded" = "Arquivo %@ descargado"; +"Download failed" = "Erro ao descargar"; +"File %@ failed to download" = "Erro ao descargar o arquivo %@"; +"Play" = "Reproducir"; +"Click the Play button to play this enclosure in iTunes." = "Faga clic no botón Reproducir para reproducir este arquivo adxunto en iTunes."; +"Click the Open button to open this file." = "Faga clic no botón Abrir para abrir este arquivo."; +"Filter displayed articles by matching text" = "Filtrar artigos amosados segundo o texto correspondiente"; +"Close the filter bar" = "Pechar barra de filtros"; +"Search all articles" = "Procurar todos os artigos"; +"Search Results" = "Resultados da procura"; +"Hide Filter Bar" = "Ocultar barra de filtros"; +"Show Filter Bar" = "Amosar barra de filtros"; +"Email a link to the current article or website" = "Enviar ligazón ao artigo ou páxina web actual"; +"Refresh" = "Actualizar"; +"Actions" = "Accións"; +"Get Info" = "Obter información"; +"See information about the selected subscription" = "Ver información acerca da subscricións seleccionada"; +"Display the list of available styles" = "Amosar a listaxe de estilos dispoñibles"; + +/* Added in 2.3.0 */ +"Order By" = "Ordenar por"; +"Manual" = "Manual"; +"Name" = "Nome"; + +/*Added in 2.4*/ +"Show XML Source" = "Amosar fonte XML"; +"Source of folder" = "Fonte do cartafol"; +"No feed source to display." = "Non hai código fonte para amosar."; +"Search current web page" = "Procurar na páxina web actual"; +"Search all articles or the current web page" = "Procurar en todos os artigos ou na páxina web actual"; +"Database Upgrade" = "Actualización da base de datos"; +"Vienna must upgrade its database to the latest version. This may take a minute or so. We apologize for the inconveninece." = "Vienna debe actualizar a súa base de datos á última versión. Isto pode tardar un minuto máis ou menos. Perdoa polo inconveniente."; +"Upgrade Database" = "Actualizar a base de datos"; + +/* Added in 2.5.0 */ +"Cannot create folder title" = "Non se pode crear o cartafol"; +"Cannot create folder body" = "O cartafol \"%@\" non puido ser creado."; + +/* Added in 2.6.0 */ +"Article load completed" = "Completouse a carga do artigo"; +"Loading HTML article..." = "Cargando artigos HTML..."; +"Ascending" = "Ascendente"; +"Descending" = "Descendente"; +"Use Current Style for Articles" = "Empregar estilo actual para os artigos"; +"Use Web Page for Articles" = "Empregar páxina web para artigos"; + +/* Added for Open Reader support */ +"Force Refresh Selected Subscriptions From Open Reader" = "Forzar a actualización das subscricións seleccionadas dende Open Reader"; +"Update Subscriptions From Open Reader" = "Actualizar as subscricións dende Open Reader"; +"Hide Toolbar" = "Ocultar a barra de ferramentas"; +"Delete Open Reader RSS feed text" = "Asegúrate de que o nome de usuario e o contrasinal precisos para acceder ao servidor de Open Reader foron inseridos correctamente nas preferencias de Vienna .\nComproba tamén o teu acceso a internet."; +"Delete Open Reader RSS feed" = "Eliminar subscrición de Open Reader"; + +/* Added in 3.0.0 */ +"Last 48 hours" = "Últimas 48 horas"; +"Unread or flagged" = "Non lido ou destacado"; +"Syncing" = "Sincronización"; +"Reindex Database" = "Volver a indexar a base de datos"; +"Other" = "Outro"; +"Authenticating on Open Reader" = "Autenticando en Open Reader"; +"Connecting to Open Reader server to retrieve %@" = "Conectando có servidor Open Reader para recuperar %@"; +"Retrieving folder image for Open Reader Feed" = "Recuperando a icona do cartafol para a fonte de Open Reader"; +"Fetching Open Reader Subscriptions..." = "Procurando subscricións de Open Reader..."; +"Open Reader Authentication Failed" = "Erro ao autenticar en Open Reader"; +"Open Reader Authentication Failed text" = "Asegúrate de que o nome de usuario e o contrasinal precisos para acceder ao servidor de Open Reader foron inseridos correctamente nas preferencias de Vienna.\nComproba tamén o teu acceso a internet."; + +/* Added in 3.0.1 */ +"Plugin installed" = "Plugin instalado"; +"A new plugin has been installed. It is now available from the menu and you can add it to the toolbar." = "Un novo plugin foi instalado. Agora está dispoñible no menú e pode engadilo á barra de ferramentas."; +"Error loading script '%@'" = "Erro ao cargar o script '%@'"; +"AppleScript Error in '%@' script" = "Erro de appleScript en script '%@'"; +"No thanks" = "Non, grazas"; +"Include anonymous system profile when checking for updates?" = "Incluir perfil anónimo do sistema ao procurar actualizacións?"; +"Include anonymous system profile when checking for updates text" = "Isto axuda ao desenrola de Viena ao informar de que versións de Mac OS X son máis populares entre os nosos usuarios."; +"Error: Feed not found!" = "Erro: Fonta non atopada!"; +"Loading" = "A cargar..."; +"Plugin could not be installed" = "O plugin non se puido instalar"; +"Vienna failed to install the plugin." = "Vienna fallou ao instalar o plugin."; +"Queue" = "Cola"; +"Forcing Refresh subscriptions..." = "A forzar a actualización de subscricións..."; +"Improper infinitely looping URL redirect to %@" = "Redirixir URL infinitamente cíclica a %@"; + +/* Added in 3.0.2 */ +"Close" = "Pechar"; +"Locate" = "Ubicar"; +"Error retrieving RSS feed:"="Erro recuperando subscrición"; +"Got HTTP status 304 - No news from last check" = "Recibido estado HTTP 304 - Non hai novas dende a última procura"; +"Error retrieving RSS Icon:" = "Erro recuperando a icona da subscrición:"; +"RSS Icon not found!" = "Icona da subscrición non atopada!"; + +/*Added in 3.0.5 */ +"Redirection attempt treated as temporary for safety concern" = "A tentiva de redirección foi tratada como temporal por seguridade"; + +/*Added in 3.0.7 */ +"No articles in feed" = "No articles in feed"; + +/*Added in 3.1.2 */ +"Filter folders" = "Search for folders"; diff --git a/lproj/it.lproj/GroupFolder.nib/designable.nib b/lproj/it.lproj/GroupFolder.nib/designable.nib index adf1085e80..0ad28d5c4a 100644 --- a/lproj/it.lproj/GroupFolder.nib/designable.nib +++ b/lproj/it.lproj/GroupFolder.nib/designable.nib @@ -1,500 +1,91 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - NewGroupFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{220, 592}, {409, 107}} - 1886912512 - Pannello - - NSPanel - - - View - - - {213, 107} - - - 256 - - - - 260 - {{17, 112}, {354, 17}} - - - YES - - 67108864 - 4194304 - Nuova Cartella Gruppo - - LucidaGrande-Bold - 13 - 2072 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 258 - {{20, 60}, {348, 22}} - - - YES - - -1804599231 - 272630784 - - - LucidaGrande - 13 - 1044 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{285, 12}, {89, 32}} - - - 100 - YES - - 67108864 - 134217728 - Registra - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{203, 12}, {82, 32}} - - - YES - - 67108864 - 134217728 - Annulla - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 268 - {{17, 90}, {353, 14}} - - - YES - - 67108864 - 4194304 - SW5zZXJpc2NpIGlsIG5vbWUgZGVsbGEgY2FydGVsbGEgZ3J1cHBvOgo - - LucidaGrande - 11 - 3100 - - - - - - NO - - - {409, 107} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - - - - newGroupFolderWindow - - - - 18 - - - - doCancel: - - - - 25 - - - - doSave: - - - - 26 - - - - folderName - - - - 27 - - - - cancelButton - - - - 28 - - - - saveButton - - - - 29 - - - - window - - - - 30 - - - - nextKeyView - - - - 24 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 5 - - - - - - GroupFolder - - - 6 - - - - - - - - - - - - 19 - - - - - - - - 20 - - - - - - - - 21 - - - - - - - - 22 - - - - - - - - 23 - - - - - - - - 32 - - - - - 33 - - - - - 34 - - - - - 35 - - - - - 36 - - - - - -3 - - - Application - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 36 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - NewGroupFolder - NSWindowController - - id - id - - - - doCancel: - id - - - doSave: - id - - - - NSButton - NSTextField - NSWindow - NSButton - - - - cancelButton - NSButton - - - folderName - NSTextField - - - newGroupFolderWindow - NSWindow - - - saveButton - NSButton - - - - IBProjectSource - ./Classes/NewGroupFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Inserisci il nome della cartella gruppo: + + + + + + + + + + diff --git a/lproj/it.lproj/GroupFolder.nib/keyedobjects.nib b/lproj/it.lproj/GroupFolder.nib/keyedobjects.nib index 7b070c9693..ff5731c828 100644 Binary files a/lproj/it.lproj/GroupFolder.nib/keyedobjects.nib and b/lproj/it.lproj/GroupFolder.nib/keyedobjects.nib differ diff --git a/lproj/it.lproj/InfoPlist.strings b/lproj/it.lproj/InfoPlist.strings deleted file mode 100644 index 04ac85bfd4..0000000000 --- a/lproj/it.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ -NSHumanReadableCopyright = "Copyright 2004-2015 Contributors. Vedi Aiuto/Riconoscimenti per l'elenco di quanti hanno contribuito."; diff --git a/lproj/it.lproj/Localizable.strings b/lproj/it.lproj/Localizable.strings index e65cb8ef22..2fc7d534e9 100644 --- a/lproj/it.lproj/Localizable.strings +++ b/lproj/it.lproj/Localizable.strings @@ -450,3 +450,9 @@ /*Added in 3.0.5 */ "Redirection attempt treated as temporary for safety concern" = "Redirection attempt treated as temporary for safety concern"; + +/*Added in 3.0.7 */ +"No articles in feed" = "No articles in feed"; + +/*Added in 3.1.2 */ +"Filter folders" = "Search for folders"; diff --git a/lproj/it.lproj/RSSFeed.nib/designable.nib b/lproj/it.lproj/RSSFeed.nib/designable.nib index ca935f2330..43ce72b7e8 100644 --- a/lproj/it.lproj/RSSFeed.nib/designable.nib +++ b/lproj/it.lproj/RSSFeed.nib/designable.nib @@ -1,1037 +1,220 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSMenu - NSMenuItem - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSUserDefaultsController - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - RSSFeed - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{309, 458}, {426, 283}} - 1886912512 - Feed RSS - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{208, 6}, {102, 32}} - - - - YES - - 67108864 - 134217728 - Annulla - - LucidaGrande - 13 - 1044 - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{310, 6}, {102, 32}} - - - 100 - YES - - 67108864 - 134217728 - Iscriviti - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{20, 182}, {75, 17}} - - - - YES - - 67108864 - 4194304 - U29yZ2VudGU6Cg - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 256 - {{99, 175}, {175, 26}} - - - - YES - - -2080374720 - 1024 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - URL - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - 100 - - - YES - - - OtherViews - - - - - - 3 - YES - YES - 1 - - NO - - - - 256 - {{20, 249}, {389, 17}} - - - - YES - - 67108864 - 4194304 - Q3JlYSB1bmEgbnVvdmEgaXNjcml6aW9uZSBSU1MKA - - LucidaGrande-Bold - 13 - 2072 - - - - - - NO - - - - 256 - {{20, 207}, {378, 34}} - - - - YES - - 67108864 - 4194304 - Inserisci il collegamento al feed RSS in basso. Oppure scegli dalla lista Sorgente ed inserisci il nome breve per il feed RSS fornito da tale sorgente. - - LucidaGrande - 10 - 2843 - - - - - - NO - - - - 256 - {{23, 76}, {386, 62}} - - - - YES - - -1805647871 - 4325376 - - - LucidaGrande - 11 - 3100 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 256 - {{283, 175}, {21, 24}} - - - - YES - - 67108864 - 134217728 - - - - -2038284288 - 33 - - - - - - 200 - 25 - - NO - - - - 256 - {{20, 146}, {270, 17}} - - - - YES - - 67108864 - 4194304 - URL: - - - - - - NO - - - - 268 - {{21, 38}, {185, 18}} - - - - YES - - -2080374784 - 0 - Subscribe in Open Reader - - - 1211912448 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - NO - - - {426, 283} - - - - - {{0, 0}, {1280, 778}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - 3 - 2 - {{10, 331}, {423, 167}} - 1886912512 - Feed RSS - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{307, 12}, {102, 32}} - - 100 - YES - - 67108864 - 134217728 - Registra - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{205, 12}, {102, 32}} - - - YES - - 67108864 - 134217728 - Annulla - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{20, 60}, {383, 62}} - - - YES - - -1805647871 - 4325376 - - - - YES - - - - NO - - - - 256 - {{17, 130}, {389, 17}} - - - YES - - 67108864 - 4194304 - Modifica iscrizione - - - - - - NO - - - {{1, 9}, {423, 167}} - - - {{0, 0}, {1280, 778}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - YES - - - - - - - window - - - - 14 - - - - doSubscribe: - - - - 37 - - - - feedSource - - - - 46 - - - - subscribeButton - - - - 48 - - - - doSave: - - - - 57 - - - - editRSSFeedWindow - - - - 61 - - - - newRSSFeedWindow - - - - 62 - - - - editFeedURL - - - - 69 - - - - saveButton - - - - 70 - - - - editCancelButton - - - - 74 - - - - subscribeCancelButton - - - - 76 - - - - doEditCancel: - - - - 77 - - - - doSubscribeCancel: - - - - 78 - - - - doLinkSourceChanged: - - - - 89 - - - - feedURL - - - - 91 - - - - doShowSiteHomePage: - - - - 93 - - - - siteHomePageButton - - - - 94 - - - - linkTitle - - - - 99 - - - - doGoogleOption: - - - - 118 - - - - googleOptionButton - - - - 119 - - - - value: googleOptionButton - - - - - - value: googleOptionButton - value - googleOptionButton - 2 - - - 117 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - NewRSSFeed - - - 5 - - - - - - - - - - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 40 - - - - - - - - 43 - - - - - - - - 64 - - - - - - - - 65 - - - - - - - - 90 - - - - - - - - 92 - - - - - - - - 97 - - - - - - - - 49 - - - - - - EditRSSFeed - - - 50 - - - - - - - - - - - 53 - - - - - - - - 54 - - - - - - - - 55 - - - - - - - - 67 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - 107 - - - - - 108 - - - - - 109 - - - - - 110 - - - - - 111 - - - - - 112 - - - - - 113 - - - - - 114 - - - - - 44 - - - - - - - - 45 - - - - - -3 - - - Application - - - 115 - - - - - - - - 116 - - - - - 120 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{1012, 565}, {429, 297}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 122 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - {15, 15} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Sorgente: + + + + + + + + + + + + + + + + + + + + + + + + + + + Crea una nuova iscrizione RSS + + + + + + + + + + + Inserisci il collegamento al feed RSS in basso. Oppure scegli dalla lista Sorgente ed inserisci il nome breve per il feed RSS fornito da tale sorgente. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/it.lproj/RSSFeed.nib/keyedobjects.nib b/lproj/it.lproj/RSSFeed.nib/keyedobjects.nib index 2b9b1e9ae1..4f6bbbc309 100644 Binary files a/lproj/it.lproj/RSSFeed.nib/keyedobjects.nib and b/lproj/it.lproj/RSSFeed.nib/keyedobjects.nib differ diff --git a/lproj/it.lproj/SearchFolder.nib/designable.nib b/lproj/it.lproj/SearchFolder.nib/designable.nib index 2b2618b681..ab16cbb497 100644 --- a/lproj/it.lproj/SearchFolder.nib/designable.nib +++ b/lproj/it.lproj/SearchFolder.nib/designable.nib @@ -1,1591 +1,265 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSBox - NSButton - NSButtonCell - NSCustomObject - NSCustomView - NSMenu - NSMenuItem - NSNumberFormatter - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - SmartFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{173, 606}, {647, 186}} - 1886912512 - - NSPanel - - View - - - {213, 107} - - - 256 - - - - 268 - {{17, 150}, {139, 17}} - - - YES - - 67108864 - 4194304 - Tm9tZSBjYXJ0ZWxsYSBzbWFydDoKA - - LucidaGrande - 13 - 1044 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 268 - {{161, 147}, {172, 22}} - - - YES - - -1804599231 - 4195328 - - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{542, 12}, {92, 32}} - - - YES - - 67108864 - 134217728 - Registra - - - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{457, 12}, {88, 32}} - - - YES - - 67108864 - 134217728 - Annulla - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 274 - - - - 274 - - - - 274 - {{12, 6}, {584, 38}} - - - - NSView - - NSResponder - - - {{2, 2}, {609, 50}} - - - - - {{17, 56}, {613, 54}} - - - {0, 0} - - 67108864 - 0 - - - LucidaGrande - 11 - 3100 - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 3 - 0 - 0 - NO - - - - 268 - {{17, 118}, {222, 17}} - - - YES - - 67108864 - 4194304 - Contiene articoli che rispondono a - - - - - - NO - - - - 268 - {{241, 112}, {203, 26}} - - - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - Nessuna - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - 268 - {{446, 118}, {63, 17}} - - - YES - - 67108864 - 272629760 - seguenti: - - - - - - NO - - - {647, 186} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - 256 - - - - 256 - {{-3, 0}, {153, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - I nomi dei campi vanno qui - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - 256 - {{513, -3}, {32, 31}} - - YES - - 67108864 - 134479872 - - - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{314, 3}, {183, 22}} - - YES - - -1804599231 - 4195328 - - - - YES - - - - NO - - - - 256 - {{541, -3}, {32, 31}} - - YES - - 67108864 - 134479872 - + - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{152, 0}, {157, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Gli operator vanno qui - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{317, 0}, {100, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - - - 400 - 75 - - - Nessuna - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{314, 3}, {126, 22}} - - YES - - -1804599231 - 4195328 - - - - - - - - - NaN - - - - 0 - - - . - - , - - - - - 0 - 2 - NO - YES - 1 - P0IPAAAAAAAAAAAAAAAAAA - - - 0 - 1 - NO - YES - 1 - AQAAAAAAAAAAAAAAAAAAAA - - -0 - 0 - - - 0 - -0 - - - - - - - - - . - , - NO - NO - YES - - - YES - - - - NO - - - - -2147483392 - {{311, 0}, {189, 26}} - - 1008 - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Item2 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - Item3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{311, 0}, {189, 26}} - - 1004 - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Item1 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - Item2 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - Item3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - -1 - 3 - YES - YES - 1 - - NO - - - {572, 28} - - NSView - - NSResponder - - - - - - - cancelButton - - - - 40 - - - - saveButton - - - - 41 - - - - searchCriteriaView - - - - 43 - - - - removeCriteriaButton - - - - 44 - - - - addCriteriaButton - - - - 45 - - - - fieldNamePopup - - - - 46 - - - - operatorPopup - - - - 47 - - - - valueField - - - - 49 - - - - window - - - - 50 - - - - addNewCriteria: - - - - 51 - - - - doCancel: - - - - 52 - - - - doSave: - - - - 53 - - - - searchWindow - - - - 54 - - - - removeCurrentCriteria: - - - - 57 - - - - fieldChanged: - - - - 59 - - - - flagValueField - - - - 65 - - - - numberValueField - - - - 70 - - - - folderValueField - - - - 78 - - - - criteriaConditionPopup - - - - 85 - - - - dateValueField - - - - 91 - - - - smartFolderName - - - - 92 - - - - searchCriteriaSuperview - - - - 42 - - - - nextKeyView - - - - 72 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - Search Folder - - - 5 - - - - - - - - - - - - - - - 7 - - - - - - - - 8 - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 37 - - - - - - - - 58 - - - - - - - - 79 - - - - - - - - 84 - - - - - - - - 26 - - - - - - - - - - - - - - SearchCriteriaView - - - 27 - - - - - - - - 29 - - - - - - - - 30 - - - - - - - - 31 - - - - - - - - 35 - - - - - - - - 61 - - - - - - - - 69 - - - - - - - - 73 - - - - - - - - 86 - - - - - - - - 94 - - - - - 95 - - - - - 96 - - - - - 97 - - - - - 98 - - - - - 99 - - - - - - - - 100 - - - - - 101 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - - - - 107 - - - - - - - - 108 - - - - - - - - 109 - - - - - - - - 71 - - - - - 80 - - - - - - - - 82 - - - - - 32 - - - - - - - - 33 - - - - - 34 - - - - - - - - 56 - - - - - 64 - - - - - - - - 62 - - - - - 74 - - - - - - - - - 76 - - - - - 75 - - - - - 87 - - - - - - - - - - 90 - - - - - 89 - - - - - 88 - - - - - -3 - - - Application - - - 36 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 109 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - SmartFolder - NSWindowController - - id - id - id - id - id - - - - addNewCriteria: - id - - - doCancel: - id - - - doSave: - id - - - fieldChanged: - id - - - removeCurrentCriteria: - id - - - - NSButton - NSButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSTextField - NSPopUpButton - NSButton - NSButton - NSView - NSView - NSWindow - NSTextField - NSTextField - - - - addCriteriaButton - NSButton - - - cancelButton - NSButton - - - criteriaConditionPopup - NSPopUpButton - - - dateValueField - NSPopUpButton - - - fieldNamePopup - NSPopUpButton - - - flagValueField - NSPopUpButton - - - folderValueField - NSPopUpButton - - - numberValueField - NSTextField - - - operatorPopup - NSPopUpButton - - - removeCriteriaButton - NSButton - - - saveButton - NSButton - - - searchCriteriaSuperview - NSView - - - searchCriteriaView - NSView - - - searchWindow - NSWindow - - - smartFolderName - NSTextField - - - valueField - NSTextField - - - - IBProjectSource - ./Classes/SmartFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Nome cartella smart: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/it.lproj/SearchFolder.nib/keyedobjects.nib b/lproj/it.lproj/SearchFolder.nib/keyedobjects.nib index 31c857dfeb..4e1ba1cd16 100644 Binary files a/lproj/it.lproj/SearchFolder.nib/keyedobjects.nib and b/lproj/it.lproj/SearchFolder.nib/keyedobjects.nib differ diff --git a/lproj/it.lproj/Vienna Help/advanced.html b/lproj/it.lproj/Vienna Help/advanced.html deleted file mode 100644 index fb9b248814..0000000000 --- a/lproj/it.lproj/Vienna Help/advanced.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - Advanced Settings - - - - -  Advanced - Settings -

The Advanced section of the Preferences provides options to - change very specific settings in Vienna that are not essential - for normal use but may resolve some issues as advised by the - support forum. This page details the advanced settings and their - function.

-

Enable JavaScript in internal browser

-

Enables or disables support for JavaScript scripting in the - Vienna internal browser. By default this is enabled. By turning - this setting off, JavaScript code on web pages will not be - allowed to run. This may resolve problems with pages that use - scripting to pop up windows or other unexpected behaviour but - turning the setting off may also cause some web pages to appear - incomplete or fail to function correctly.

- - diff --git a/lproj/it.lproj/Vienna Help/faq.html b/lproj/it.lproj/Vienna Help/faq.html deleted file mode 100644 index a2f416d887..0000000000 --- a/lproj/it.lproj/Vienna Help/faq.html +++ /dev/null @@ -1,220 +0,0 @@ - - - - - - - Come Faccio A? - - - - -  Come Faccio - A? -

Qui sotto ci sono alcune delle domande pi comuni che ci sono - state fatte su Vienna mentre veniva effettuato il test - pre-rilascio. Vai alla Pagina FAQ Ufficiale - di Vienna per questi e i pi recenti trucchi e suggerimenti - per usare Vienna.

- -

Dove ottengo il codice - sorgente di Vienna?

-

Vedi la pagina - Development per istruzioni su come ottenere il codice - sorgente di Vienna. Il codice sorgente liberamente disponibile - se sei interessato ad imparare come funziona Vienna, se vuoi - compilare una tua copia di Vienna da zero sulla tua macchina o se - vuoi prenderne una parte da includere nel tuo progetto. Il - sorgente viene fornito sottolicenza Apache - 2.0 .

-

Ho trovato - un problema in Vienna. Come lo segnalo?

-

Invia un messaggio nel forum Support e qualcuno investigher. - Fornisci quante pi informazioni puoi sul problema incluso: il - numero della build di Vienna (ottenuta dalla finestra - Informazioni su Vienna), i passi per riprodurlo e cosa ti aspetti - che accada.

-

Assicurati di avere in esecuzione sempre la build pi recente - di Vienna. Il comando Controlla Aggiornamenti segnaler se c' - una build pi recente disponibile rispetto a quella in tuo - possesso.

-

Le correzioni di problemi hanno priorit sulle nuove - funzionalit per cui sel il tuo problema viene confermato come - baco ad alto impatto e non c' un alternativa semplice di - funzionamento cercher di rendere disponibile una correzione non - appena ragionevolmente possibile.

-

Come faccio a creare i miei - stili?

-

Vedi la pagina Custom - Styles per istruzioni.

-

ome faccio a creare i miei - script?

<<p>Gli script di Vienna sono scritti - usando AppleScript. Vedi la - pagine risorse di Apple per ulteriori dettagli. -

Un modo per iniziare scaricare uno degli script esistenti - dalla pagina Vienna - Downloads e visualizzarlo nell'editor AppleScript. Dai uno - sguardo anche alla pagina - Scripts per ulteriori dettagli sul dizionario di scripting di - Vienna ed esempi di cosa puoi ottenere.

-

Per pubblicare il tuo script, invialo a steve@opencommunity.co.uk - e dopo esser stato controllato, sar reso disponibile sulla - pagina Downloads.

-

- Come posso vedere cosa successo quando sono state aggiornate le - mie iscrizioni?

-

Apri la Finestra Attivit dal menu Finestra. La finestra - attivit mostra tutte le iscrizioni e lo stato relativo - all'ultima volta che sono state aggiornate in quella sessione. In - fondo la fiestra attivit mostra ulteriori dettagli incluse le - intestazioni HTTP e pu essere utile per il debug. (Se il - pannello dettagli non visibile, prendi il separatore in fondo - alla Finestra Attivit e trascinalo sopra in modo da scoprire il - pannello).

-

Come - faccio a spostare il mio database di Vienna in un'altra - cartella?

-

Di default, il tuo database Vienna il file messages.db che - posizionato in ~/Libreria/Application Support/Vienna. Puoi - spostarlo in un'altra cartella se lo desideri. I passi seguenti - mostrano come:

-
    -
  1. Chiudi Vienna.
  2. -
  3. Apri una finestra del terminale ed inserisci:
    -
    - defaults write - uk.co.opencommunity.vienna2 "DefaultDatabase" '<percorso al - nuovo messages.db>'
    -
    - dove <percorso al nuovo messages.db> il nome della - cartella che contiene il file messages.db. Il percordo stesso - dovrebbe avere il nome file messages.db alla fine. Ad - esempio:
    -
    - defaults write - uk.co.opencommunity.vienna2 "DefaultDatabase" - '/Users/steve/mydata/messages.db'
  4. -
  5. Riavvia Vienna.
  6. -
-

- Una delle mie iscrizioni segnala "Errore nell'interpretazione dei - dati XML nel feed". Cosa significa?

-

Significa che Vienna ha ottenuto una risposta dall'iscrizione - che non riuscita ad interpretare. Ci sono diverse ragioni per - cui ci pu accadere:

-
    -
  1. La URL del feed potrebbe non puntare ad un feed RSS o Atom - ma ad una pagina web. Controlla la URL del feed che crea - problemi attentamente.
  2. -
  3. Il feed stesso potrebbe contenere XML malformato. Alcune - iscrizioni commettono un errore nel mettere insieme l'XML che - definisce il feed e Vienna non pu interpretare XML malformato. - Usa il comando Convalida Feed nel menu Archivio per vedere se - sei in questo caso. Sfortunatamente non puoi far molto per - questo in Vienna tranne attendere che il feed stesso venga - corretto dal sito.
  4. -
  5. Il feed potrebbe essere incompleto. Se l'aggiornamento - stato interrotto dopo i dati XML saranno incompleti ed - appariranno malformati in Vienna. Un secondo aggiornamento - potrebbe correggere questo problema.
  6. -
-

Se nessuna delle ragioni sopra indicate spiega il problema, - invia un messaggio sul forum di supporto con la URL del feed che - mostra tale problema.

-

- C' un'abbreviazione da tastiera per andare al prossimo articolo, - segnalarlo come letto, ecc.?

-

Probabilmente. Ci sono equivalenti a tasto singolo per alcuni - dei comandi del menu come:

-

Spazio - va al prossimo articolo da leggere. Se l'articolo - corrente lungo diverse pagine, andr avanti all'interno - dell'articolo per prima cosa. Se sei alla fine dell'articolo - corrente poi andr all'articolo successivo non letto. Per - contrasto il comando Successivo Non Letto (Cmd+U) va sempre - dritto all'articolo successivo non letto.

-

R - segnala l'articolo corrente come letto se non ancora - stato letto, o come non letto se gi stato letto.

-

F - segnala con contrassegno l'articolo corrente se non gi - con contrassegno, o rimuove il contrassegno esistente se gi lo - .

-

Cerca in Aiuto Vienna per ulteriori abbreviazioni.

-

Coma faccio ad - usare Scadenza Automatica e cosa fa?

-

Scadenza Automatica sposta gli articoli pi vecchi di un certo - numero di giorni nella cartella Cestino. Ti permette di mantenere - le tue cartelle gestibili trattenendo solo gli articoli che siano - recenti. La scadenza automatica viene eseguita sia all'avvio di - Vienna che dopo che tu abbia aggiornato qualsiasi iscrizione. Per - controllare la data degli articoli da far scadere - automaticamente, modifca l'opzione "Fai scadere articoli pi - vecchi di" nelle Preferenze.

-

Scadenza Automatica non eliminer articoli non letti o - segnalati con contrassegno. Assume che tu non abbia letto questi - articoli e cos li lascia l.

-

Come faccio a - richiedere un miglioramento in Vienna?

-

Invia un messaggio sul forum di - supporto. Tutti i miglioramenti richiesti sono registrati nel - file TODO incluso insieme al codice sorgente come guida per gli - sviluppatori futuri.

- - diff --git a/lproj/it.lproj/Vienna Help/helpstyle.css b/lproj/it.lproj/Vienna Help/helpstyle.css deleted file mode 100644 index 48a8dcebd1..0000000000 --- a/lproj/it.lproj/Vienna Help/helpstyle.css +++ /dev/null @@ -1,27 +0,0 @@ -a { - color: #3366CC; - text-decoration: none; -} -.title { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 18pt; - color: #000000; -} -.header { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 12pt; - color: #000000; -} -p { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 100; - font-size: 9pt; - color: #000000; -} -tr { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-size: 9pt; - color: #000000; -} \ No newline at end of file diff --git a/lproj/it.lproj/Vienna Help/images/Small-Vienna-Logo.jpg b/lproj/it.lproj/Vienna Help/images/Small-Vienna-Logo.jpg deleted file mode 100644 index 41035b4f11..0000000000 Binary files a/lproj/it.lproj/Vienna Help/images/Small-Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/it.lproj/Vienna Help/images/Vertical-Line.jpg b/lproj/it.lproj/Vienna Help/images/Vertical-Line.jpg deleted file mode 100644 index 011f1ce1e3..0000000000 Binary files a/lproj/it.lproj/Vienna Help/images/Vertical-Line.jpg and /dev/null differ diff --git a/lproj/it.lproj/Vienna Help/images/Vienna-Logo.jpg b/lproj/it.lproj/Vienna Help/images/Vienna-Logo.jpg deleted file mode 100644 index 13a6479bd4..0000000000 Binary files a/lproj/it.lproj/Vienna Help/images/Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/it.lproj/Vienna Help/index.html b/lproj/it.lproj/Vienna Help/index.html deleted file mode 100644 index dcf968e75a..0000000000 --- a/lproj/it.lproj/Vienna Help/index.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - Aiuto Vienna - - - - - - - - - - -
-

-

Aiuto Vienna

-
-

Introduzione a Vienna

-

Impara come iniziare ad usare - Vienna.

-

Abbreviazioni da Tastiera

-

Scopri le abbreviazioni da - tastiera per i comandi comuni

-

Come Faccio A

-

Domande Frequenti, come ottenere - supporto e passi da eseguire per la risoluzione dei - problemi.

-
- - diff --git a/lproj/it.lproj/Vienna Help/intro.html b/lproj/it.lproj/Vienna Help/intro.html deleted file mode 100644 index 8f28295c0a..0000000000 --- a/lproj/it.lproj/Vienna Help/intro.html +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - Introduzione a Vienna - - - - -   Introduzione a - Vienna -

Vienna un'applicazione che ti permette di leggere feed di - notizie in formato RSS o Atom sul tuo computer con Mac OSX. - Automatizza il compito di recuperare i nuovi articoli da tutti i - feed cui si iscritti e di memorizzarli in un database locale - per leggerli quando si off-line. Fornisce caratteristiche che - ti permettono di cercare nei feed per parole chiave o frasi, - segnalare gli articoli con contrassegno per riferimento futuro ed - organizzare insieme in gruppi i feed correlati. Puoi creare - cartelle smart che rendano semplice recuperare e visualizzare - tutti gli articoli nel database che soddisfino un dato criterio - di ricerca. Il browser interno ti permette di andare alla pagina - web degli articoli direttamente all'interno di Vienna su pannelli - separati.

-

Vienna progettato in modo da essere semplice e facile da - utilizzare. Un'interfaccia pulita e ordinata massimizza lo spazio - per gli articoli e solo pochi pulsanti sono necessari per - eseguire la maggior parte delle operazioni nell'interfaccia - utente.

Come Iniziare -

Se questa la prima volta che usi Vienna allora il programma - avr creato un nuovo database per te ad aggiunto alcune - iscrizioni e notizie di esempio. Vai allora avanti e premi - Comando+T o scegli Aggiorna Tutte le Iscrizioni dal menu Archivio - per ottenere gli ultimi articoli da queste iscrizioni.

-

Alternativamente, iscriviti ai tuoi feed di notizie personali. - Ci sono vari modi per trovare feed. Quando navighi sul web, cerca - la o le icone XML che - indicano che la pagina ha dei feed associati ad essa. - Alternativamente quasi tutti i servizi di blogging come - LiveJournal o Blogger forniscono feed RSS come alternativa alla - lettura degli articoli online.

-

Se conosci il nome utente di blogger su Splinder, LiveJournal, - Blogger, MSN Spaces o Xanga allora Vienna rende pi facile - iscriversi ai loro news feed. Inizia premendo Comando+N o scegli - il comando Nuova Iscrizione dal menu Archivio. Nella finestra - "Crea una nuova iscrizione RSS", scegli il servizio di blogging - dall'elenco a comparsa ed inserisci il nome utente nel campo di - testo sottostante. Poi scegli Iscriviti e Vienna aggiunger - l'iscrizione all'elenco cartelle. Se in quel momento eri connesso - ad internet, Vienna inizier anche immediatamente a raccogliere - gli articoli dal feed.

-

Normalmente devi dire manualmente a Vienna quando aggiornare - tutte le tue iscrizioni. Comunque puoi scegliere di chiedere a - Vienna di aggiornare automaticamente ad intervalli di tempo - regolari. Nella sezione Generale delle Preferenze, scegli - l'intervallo di tempo desiderato dall'elenco a comparsa vicino a - 'Controlla nuovi articoli'. Vienna deve essere in esecuzione - perch possa aggiornare automaticamente le iscrizioni.

-

Per leggere gli articoli, premi la Barra Spaziatrice per - passare all'articolo successivo non letto in ogni iscrizione. - Ogni articolo segnalato automaticamente come letto dopo un - breve periodo di tempo. Se preferisci aspettare fino a quando ti - sposti all'articolo successivo non letto prima che quello - corrente sia segnalato come letto, puoi impostare questo - comportamento nel pannello Generale delle Preferenze. Per - selezionare un articolo come non letto di nuovo, scegli il - comando Segnala come Non Letto dal menu Articolo o premi - semplicemente il tasto 'R'.

-

Infine puoi visualizzare la pagina web dell'articolo oppure - qualsiasi collegamento a pagine web in un articolo all'interno di - Vienna. Di default facendo clic su un collegamento web - all'interno di Vienna, il programma aprir la pagina web in un - nuovo pannello. Vienna fornisce un buon supporto per la - navigazione web di base ma ci saranno volte in cui preferirai - aprire i collegamenti nel tuo browser web di default. Se - preferisci visualizzare tutte le pagine web fuori da Vienna, - allora attiva l'opzione 'Apri collegamenti in un browser esterno' - nella sezione Generale delle Preferenze. Se comunque preferisci - visualizzare il collegamento o pagina corrente nel tuo browser - esterno, fai clic con il pulsante destro sulla pagina o scegli - l'opzione "Apri Collegamento in XXX" o "Apri Pagina in XXX" dove - XXX sar il nome del tuo browser di default.

-

Dopo esserti impratichito nell'usare Vienna, vai avanti ed - esplora la varie opzioni. Puoi modificare lo stile in cui gli - articoli sono visualizzati attraverso l'elenco a comparsa Stili - nel menu Vista. Puoi trovare molti altri stili personalizzati - nella pagina Downloads sul sito web di Vienna insieme a script - personalizzati che ti permettono di integrare Vienna con altre - applicazioni sulla tua macchina. Oppure fai esperimenti con le - cartelle smart per organizzare gli articoli secondo criteri - basati sui contenuti di ogni articolo. Ad esempio, puoi - facilmente impostare una cartella smart per raggruppare insieme - tutti gli articoli che menzionano "Joss Whedon" e "Firefly" per - trovare riferimenti alla serie di culto Firefly o al film tratto - da essa.

-

Se hai domande su Vienna o riscontri dei problemi, vai sul - forum - Support.

- - diff --git a/lproj/it.lproj/Vienna Help/keyboard.html b/lproj/it.lproj/Vienna Help/keyboard.html deleted file mode 100644 index 4e88ce8028..0000000000 --- a/lproj/it.lproj/Vienna Help/keyboard.html +++ /dev/null @@ -1,260 +0,0 @@ - - - - - - - Abbreviazioni da Tastiera - - - - -  Abbreviazioni da - Tastiera -

Puoi usare la tua tastiera per eseguire rapidamente diverse - operazioni in Vienna. Per trovare le abbreviazioni per i comandi - comuni, guarda nei menu (o vedi la lista in fondo a questa - pagina). Molti elementi di Vienna come l'area cartella e l'elenco - degli articoli hanno anche dei menu contestuali. Per vedere un - menu contestuale, premi il tasto Control e fai clic - sull'elemento.

-

Per eseguire un'azione, premi i tasti di abbreviazione sotto - indicati.

- - - - - -
TastoAzione
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Abbreviazioni a Tasto Singolo 
fImposta il focus dell'input sulla finestra di - ricerca.
rSegnala gli articoli selezionati come letti.
sSegnala la cartella corrente come letta poi passa alla - cartella successiva con articoli non letti.
kSegnala la cartella corrente come letta.
mSegnala con contrassegno gli articoli selezionati.
<Mostra l'articolo o pagina web vista in precedenza.
>Mostra l'articolo o pagina web vista - successivamente.
SpacebarVa all'articolo successivo non letto a meno che - l'articolo corrente non abbia altro testo da scorrere ed in - tal caso va su di una pagina all'interno dell'articolo - corrente.
Comando-UVa all'articolo successivo non letto.
Enter/ReturnApre l'articolo selezionato nella pagina web - originale.
Delete/BackspaceSposta gli articoli selezionati nella cartella Cestino. - Se questo tasto viene utilizzato nella cartella Cestino, gli - articoli selezionati saranno eliminati in modo - permanente.
Abbreviazioni Generali 
Comando-NCrea una nuova iscrizione.
Shift-Comando-FCrea una cartella smart.
Shift-Comando-EModifica la URL della cartella selezionata o modifica il - criterio di una cartella smart.
Shift-Comando-DElimina la cartella selezionata.
Shift-Comando-NRinomina la cartella selezionata.
Comando-RAggionta tutte le iscrizioni.
Shift-Comando-RAggiorna solo quelle iscrizioni che siano selezionate - nell'elenco cartelle.
Comando-MenoInterrompi ogni aggiornamento attivo.
Comando-PStampa gli articoli selezionati.
Shift-Comando-PAttiva la finestra Formato di stampa.
Shift-Comando-VConvalida il feed selezionato.
Comando-?Visualizza le pagine dell'aiuto di Vienna.
Abbreviazioni Articoli 
Shift-Comando-MSegnala con contrassegno gli articoli selezionati.
Shift-Comando-USegnala gli articoli selezionati come letti.
Shift-Comando-SSegnala la cartella corrente come letta poi passa alla - cartella successiva con articoli non letti.
Shift-Comando-ORipristina un articolo dal cestino riportandolo nella sua - cartella originale.
Shift-Comando-KSegnala tutti gli articoli nelle cartelle selezionate - come letti.
Alt-Comando-KSegnala tutti gli articoli in tutte le cartelle come - letti.
Abbreviazioni Finestra 
Comando-WChiude il pannello attivo se ce n' uno aperto. - Altrimenti se non ci sono pannelli aperti, chiude la finestra - di Vienna.
Alt-Comando-WChiude tutti i pannelli. Nota che questo comando - sostituisce il comando Chiudi Pannello nel menu Archivio - quando si tiene premuto il tasto Alt.
Control-Comando-Freccia SinistraVisualizza il pannello precedente.
Control-Comando-Freccia DestraVisualizza il pannello successivo.
Shift-Comando-WChiude la finestra di Vienna ma lascia Vienna in - esecuzione in background. Puoi riportare la finestra in vista - facendo clic sull'icon nel dock di Vienna o premendo - Comando-1.
Comando-MRidimenziona la finestra di Vienna nel dock.
Comando-0Visualizza la finestra con il visore resoconto - attivit.
Comando-1Riapre la finestra di Vienna se era stata chiusa - precedentemente.
Comando-2Visualizza la finestra Downloads.
Abbreviazioni Finestra Browser 
Alt-RRicarica la pagina web corrente.
Comando-PuntoAnnulla il caricamento della pagina web corrente.
Comando-[/Comando-sinistraVai indietro alla pagina web precedente.
Comando-]/Command-destraVai avanti alla pagina web successiva.
Comando-FImposta il focus sul campo di ricerca. Inserendo del - testo qui e premendo Enter, il programma cercher quel testo - nella pagina web corrente.
Comando-GRicerca la prossima occorrenza del testo cercato nella - pagina web.
- - diff --git a/lproj/ja.lproj/GroupFolder.nib/designable.nib b/lproj/ja.lproj/GroupFolder.nib/designable.nib index 797d4428e5..d374ea1b39 100644 --- a/lproj/ja.lproj/GroupFolder.nib/designable.nib +++ b/lproj/ja.lproj/GroupFolder.nib/designable.nib @@ -1,500 +1,91 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - NewGroupFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{270, 500}, {388, 107}} - 1886912512 - パネル - - NSPanel - - - View - - - {213, 107} - - - 256 - - - - 260 - {{17, 112}, {354, 17}} - - - YES - - 67108864 - 4194304 - 新規グループフォルダ - - LucidaGrande-Bold - 13 - 2072 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 258 - {{20, 60}, {348, 22}} - - - YES - - -1804599231 - 272630784 - - - LucidaGrande - 13 - 1044 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{285, 12}, {89, 32}} - - - 100 - YES - - 67108864 - 134217728 - 保存 - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{203, 12}, {82, 32}} - - - YES - - 67108864 - 134217728 - キャンセル - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 268 - {{17, 90}, {353, 14}} - - - YES - - 67108864 - 4194304 - 44Kw44Or44O844OX44OV44Kp44Or44OA5ZCN44KS5YWl5Yqb77yaCg - - LucidaGrande - 11 - 3100 - - - - - - NO - - - {388, 107} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - - - - newGroupFolderWindow - - - - 18 - - - - doCancel: - - - - 25 - - - - doSave: - - - - 26 - - - - folderName - - - - 27 - - - - cancelButton - - - - 28 - - - - saveButton - - - - 29 - - - - window - - - - 30 - - - - nextKeyView - - - - 24 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 5 - - - - - - GroupFolder - - - 6 - - - - - - - - - - - - 19 - - - - - - - - 20 - - - - - - - - 21 - - - - - - - - 22 - - - - - - - - 23 - - - - - - - - 32 - - - - - 33 - - - - - 34 - - - - - 35 - - - - - 36 - - - - - -3 - - - Application - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 36 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - NewGroupFolder - NSWindowController - - id - id - - - - doCancel: - id - - - doSave: - id - - - - NSButton - NSTextField - NSWindow - NSButton - - - - cancelButton - NSButton - - - folderName - NSTextField - - - newGroupFolderWindow - NSWindow - - - saveButton - NSButton - - - - IBProjectSource - ./Classes/NewGroupFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + グループフォルダ名を入力: + + + + + + + + + + diff --git a/lproj/ja.lproj/GroupFolder.nib/keyedobjects.nib b/lproj/ja.lproj/GroupFolder.nib/keyedobjects.nib index 8dc6886fe4..cd8de87779 100644 Binary files a/lproj/ja.lproj/GroupFolder.nib/keyedobjects.nib and b/lproj/ja.lproj/GroupFolder.nib/keyedobjects.nib differ diff --git a/lproj/ja.lproj/InfoPlist.strings b/lproj/ja.lproj/InfoPlist.strings deleted file mode 100644 index 412b84041a..0000000000 --- a/lproj/ja.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ -NSHumanReadableCopyright = "Copyright 2004-2015 貢献者 (貢献者のリストは、ヘルプ/謝辞 を参照ください)"; diff --git a/lproj/ja.lproj/Localizable.strings b/lproj/ja.lproj/Localizable.strings index 90da4ae5e7..675520e46e 100644 --- a/lproj/ja.lproj/Localizable.strings +++ b/lproj/ja.lproj/Localizable.strings @@ -450,3 +450,9 @@ /*Added in 3.0.5 */ "Redirection attempt treated as temporary for safety concern" = "Redirection attempt treated as temporary for safety concern"; + +/*Added in 3.0.7 */ +"No articles in feed" = "No articles in feed"; + +/*Added in 3.1.2 */ +"Filter folders" = "Search for folders"; diff --git a/lproj/ja.lproj/RSSFeed.nib/designable.nib b/lproj/ja.lproj/RSSFeed.nib/designable.nib index 9d695211b2..43b4cccbc4 100644 --- a/lproj/ja.lproj/RSSFeed.nib/designable.nib +++ b/lproj/ja.lproj/RSSFeed.nib/designable.nib @@ -1,1003 +1,219 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSMenu - NSMenuItem - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSUserDefaultsController - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - RSSFeed - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{165, 318}, {426, 290}} - 1886912512 - RSS フィード - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{208, 14}, {102, 32}} - - - YES - - 67108864 - 134217728 - キャンセル - - LucidaGrande - 13 - 1044 - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{310, 14}, {102, 32}} - - - 100 - YES - - 67108864 - 134217728 - 購読 - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{20, 189}, {75, 17}} - - - YES - - 67108864 - 4194304 - 44K944O844K577yaCg - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 256 - {{99, 182}, {175, 26}} - - - YES - - -2080374720 - 1024 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - URL - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - 100 - - - YES - - - OtherViews - - - - - - 3 - YES - YES - 1 - - NO - - - - 256 - {{20, 256}, {389, 17}} - - - YES - - 67108864 - 4194304 - 5paw6KaP6LO86Kqt44KS5L2c5oiQCg - - LucidaGrande-Bold - 13 - 2072 - - - - - - NO - - - - 256 - {{20, 214}, {378, 34}} - - - YES - - 67108864 - 4194304 - ニュースフィードへのリンクを入力してください。またはソースリストからニュースフィードのショートカット名を入力してください。 - - LucidaGrande - 10 - 2843 - - - - - - NO - - - - 256 - {{23, 83}, {386, 62}} - - - YES - - -1805647871 - 4325376 - - - LucidaGrande - 11 - 3100 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 256 - {{283, 182}, {21, 24}} - - - YES - - 67108864 - 134217728 - - - - -2038284288 - 33 - - - - - - 200 - 25 - - NO - - - - 256 - {{20, 153}, {270, 17}} - - - YES - - 67108864 - 4194304 - URL: - - - - - - NO - - - - 268 - {{21, 45}, {185, 18}} - - - YES - - -2080374784 - 0 - Subscribe in Open Reader - - - 1211912448 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - NO - - - {426, 290} - - - - {{0, 0}, {1280, 778}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - 3 - 2 - {{305, 336}, {423, 167}} - 1886912512 - RSS フィード - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{307, 12}, {102, 32}} - - 100 - YES - - 67108864 - 134217728 - 保存 - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{205, 12}, {102, 32}} - - - YES - - 67108864 - 134217728 - キャンセル - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{20, 60}, {383, 62}} - - - YES - - -1805647871 - 4325376 - - - - YES - - - - NO - - - - 256 - {{17, 130}, {389, 17}} - - - YES - - 67108864 - 4194304 - 購読を編集 - - - - - - NO - - - {{1, 9}, {423, 167}} - - - {{0, 0}, {1280, 778}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - YES - - - - - - - window - - - - 14 - - - - doSubscribe: - - - - 37 - - - - feedSource - - - - 46 - - - - subscribeButton - - - - 48 - - - - doSave: - - - - 57 - - - - editRSSFeedWindow - - - - 61 - - - - newRSSFeedWindow - - - - 62 - - - - editFeedURL - - - - 69 - - - - saveButton - - - - 70 - - - - editCancelButton - - - - 74 - - - - subscribeCancelButton - - - - 76 - - - - doEditCancel: - - - - 77 - - - - doSubscribeCancel: - - - - 78 - - - - doLinkSourceChanged: - - - - 89 - - - - feedURL - - - - 91 - - - - doShowSiteHomePage: - - - - 93 - - - - siteHomePageButton - - - - 94 - - - - linkTitle - - - - 99 - - - - doGoogleOption: - - - - 118 - - - - googleOptionButton - - - - 119 - - - - value: googleOptionButton - - - - - - value: googleOptionButton - value - googleOptionButton - 2 - - - 117 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - NewRSSFeed - - - 5 - - - - - - - - - - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 40 - - - - - - - - 43 - - - - - - - - 64 - - - - - - - - 65 - - - - - - - - 90 - - - - - - - - 92 - - - - - - - - 97 - - - - - - - - 49 - - - - - - EditRSSFeed - - - 50 - - - - - - - - - - - 53 - - - - - - - - 54 - - - - - - - - 55 - - - - - - - - 67 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - 107 - - - - - 108 - - - - - 109 - - - - - 110 - - - - - 111 - - - - - 112 - - - - - 113 - - - - - 114 - - - - - 44 - - - - - - - - 45 - - - - - -3 - - - Application - - - 115 - - - - - - - - 116 - - - - - 120 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{1012, 565}, {429, 297}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 122 - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - {15, 15} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ソース: + + + + + + + + + + + + + + + + + + + + + + + + + + + 新規購読を作成 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/ja.lproj/RSSFeed.nib/keyedobjects.nib b/lproj/ja.lproj/RSSFeed.nib/keyedobjects.nib index 5f03c49454..f969cb6913 100644 Binary files a/lproj/ja.lproj/RSSFeed.nib/keyedobjects.nib and b/lproj/ja.lproj/RSSFeed.nib/keyedobjects.nib differ diff --git a/lproj/ja.lproj/SearchFolder.nib/designable.nib b/lproj/ja.lproj/SearchFolder.nib/designable.nib index df4ddfa3c8..dfe3796904 100644 --- a/lproj/ja.lproj/SearchFolder.nib/designable.nib +++ b/lproj/ja.lproj/SearchFolder.nib/designable.nib @@ -1,1591 +1,265 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSBox - NSButton - NSButtonCell - NSCustomObject - NSCustomView - NSMenu - NSMenuItem - NSNumberFormatter - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - SmartFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{361, 578}, {647, 186}} - 1886912512 - - NSPanel - - View - - - {213, 107} - - - 256 - - - - 268 - {{17, 150}, {133, 17}} - - - YES - - 67108864 - 4194304 - 44K544Oe44O844OI44OV44Kp44Or44OA5ZCN77yaCg - - LucidaGrande - 13 - 1044 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 268 - {{155, 147}, {178, 22}} - - - YES - - -1804599231 - 4195328 - - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{555, 12}, {78, 32}} - - - YES - - 67108864 - 134217728 - 保存 - - - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{461, 12}, {94, 32}} - - - YES - - 67108864 - 134217728 - キャンセル - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 274 - - - - 274 - - - - 274 - {{12, 6}, {584, 38}} - - - - NSView - - NSResponder - - - {{2, 2}, {609, 50}} - - - - - {{17, 56}, {613, 54}} - - - {0, 0} - - 67108864 - 0 - - - LucidaGrande - 11 - 3100 - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 3 - 0 - 0 - NO - - - - 268 - {{17, 118}, {182, 17}} - - - YES - - 67108864 - 4194304 - 以下の条件の - - - - - - NO - - - - 268 - {{104, 112}, {80, 26}} - - - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - なし - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - 268 - {{187, 118}, {301, 17}} - - - YES - - 67108864 - 272629760 - に一致したすべての記事を表示: - - - - - - NO - - - {647, 186} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - 256 - - - - 256 - {{-3, 0}, {137, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - フィールド名 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - 256 - {{513, -3}, {32, 31}} - - YES - - 67108864 - 134479872 - - - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{302, 3}, {183, 22}} - - YES - - -1804599231 - 4195328 - - - - YES - - - - NO - - - - 256 - {{541, -3}, {32, 31}} - - YES - - 67108864 - 134479872 - + - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{151, 0}, {135, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - オペレータ - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{299, 0}, {100, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - - - 400 - 75 - - - なし - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{302, 4}, {126, 22}} - - YES - - -1804599231 - 4195328 - - - - - - - - - NaN - - - - 0 - - - . - - , - - - - - 0 - 2 - NO - YES - 1 - P0IPAAAAAAAAAAAAAAAAAA - - - 0 - 1 - NO - YES - 1 - AQAAAAAAAAAAAAAAAAAAAA - - -0 - 0 - - - 0 - -0 - - - - - - - - - . - , - NO - NO - YES - - - YES - - - - NO - - - - -2147483392 - {{299, 0}, {189, 26}} - - 1008 - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Item2 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - Item3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{299, 0}, {189, 26}} - - 1004 - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Item1 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - Item2 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - Item3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - -1 - 3 - YES - YES - 1 - - NO - - - {572, 28} - - NSView - - NSResponder - - - - - - - cancelButton - - - - 40 - - - - saveButton - - - - 41 - - - - searchCriteriaView - - - - 43 - - - - removeCriteriaButton - - - - 44 - - - - addCriteriaButton - - - - 45 - - - - fieldNamePopup - - - - 46 - - - - operatorPopup - - - - 47 - - - - valueField - - - - 49 - - - - window - - - - 50 - - - - addNewCriteria: - - - - 51 - - - - doCancel: - - - - 52 - - - - doSave: - - - - 53 - - - - searchWindow - - - - 54 - - - - removeCurrentCriteria: - - - - 57 - - - - fieldChanged: - - - - 59 - - - - flagValueField - - - - 65 - - - - numberValueField - - - - 70 - - - - folderValueField - - - - 78 - - - - criteriaConditionPopup - - - - 85 - - - - dateValueField - - - - 91 - - - - smartFolderName - - - - 92 - - - - searchCriteriaSuperview - - - - 42 - - - - nextKeyView - - - - 72 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - Search Folder - - - 5 - - - - - - - - - - - - - - - 7 - - - - - - - - 8 - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 37 - - - - - - - - 58 - - - - - - - - 79 - - - - - - - - 84 - - - - - - - - 26 - - - - - - - - - - - - - - SearchCriteriaView - - - 27 - - - - - - - - 29 - - - - - - - - 30 - - - - - - - - 31 - - - - - - - - 35 - - - - - - - - 61 - - - - - - - - 69 - - - - - - - - 73 - - - - - - - - 86 - - - - - - - - 94 - - - - - 95 - - - - - 96 - - - - - 97 - - - - - 98 - - - - - 99 - - - - - - - - 100 - - - - - 101 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - - - - 107 - - - - - - - - 108 - - - - - - - - 109 - - - - - - - - 71 - - - - - 80 - - - - - - - - 82 - - - - - 32 - - - - - - - - 33 - - - - - 34 - - - - - - - - 56 - - - - - 64 - - - - - - - - 62 - - - - - 74 - - - - - - - - - 76 - - - - - 75 - - - - - 87 - - - - - - - - - - 90 - - - - - 89 - - - - - 88 - - - - - -3 - - - Application - - - 36 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 109 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - SmartFolder - NSWindowController - - id - id - id - id - id - - - - addNewCriteria: - id - - - doCancel: - id - - - doSave: - id - - - fieldChanged: - id - - - removeCurrentCriteria: - id - - - - NSButton - NSButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSTextField - NSPopUpButton - NSButton - NSButton - NSView - NSView - NSWindow - NSTextField - NSTextField - - - - addCriteriaButton - NSButton - - - cancelButton - NSButton - - - criteriaConditionPopup - NSPopUpButton - - - dateValueField - NSPopUpButton - - - fieldNamePopup - NSPopUpButton - - - flagValueField - NSPopUpButton - - - folderValueField - NSPopUpButton - - - numberValueField - NSTextField - - - operatorPopup - NSPopUpButton - - - removeCriteriaButton - NSButton - - - saveButton - NSButton - - - searchCriteriaSuperview - NSView - - - searchCriteriaView - NSView - - - searchWindow - NSWindow - - - smartFolderName - NSTextField - - - valueField - NSTextField - - - - IBProjectSource - ./Classes/SmartFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + スマートフォルダ名: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/ja.lproj/SearchFolder.nib/keyedobjects.nib b/lproj/ja.lproj/SearchFolder.nib/keyedobjects.nib index 1c060620f3..6ec0e8a97a 100644 Binary files a/lproj/ja.lproj/SearchFolder.nib/keyedobjects.nib and b/lproj/ja.lproj/SearchFolder.nib/keyedobjects.nib differ diff --git a/lproj/ja.lproj/Vienna Help/advanced.html b/lproj/ja.lproj/Vienna Help/advanced.html deleted file mode 100644 index fb9b248814..0000000000 --- a/lproj/ja.lproj/Vienna Help/advanced.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - Advanced Settings - - - - -  Advanced - Settings -

The Advanced section of the Preferences provides options to - change very specific settings in Vienna that are not essential - for normal use but may resolve some issues as advised by the - support forum. This page details the advanced settings and their - function.

-

Enable JavaScript in internal browser

-

Enables or disables support for JavaScript scripting in the - Vienna internal browser. By default this is enabled. By turning - this setting off, JavaScript code on web pages will not be - allowed to run. This may resolve problems with pages that use - scripting to pop up windows or other unexpected behaviour but - turning the setting off may also cause some web pages to appear - incomplete or fail to function correctly.

- - diff --git a/lproj/ja.lproj/Vienna Help/faq.html b/lproj/ja.lproj/Vienna Help/faq.html deleted file mode 100644 index 8532ac8e96..0000000000 --- a/lproj/ja.lproj/Vienna Help/faq.html +++ /dev/null @@ -1,208 +0,0 @@ - - - - - - - How Do I? - - - - -  How Do I? -

Below are some of the more common questions asked about Vienna - while it was being pre-release tested. See the Official Vienna FAQ - Page for these and the latest hints and tips for using - Vienna.

- -

Where do I get the Vienna - source code?

-

See the Development page - for instructions for getting the source code for Vienna. The - source code is freely available if you're interested in learning - how Vienna works, if you want to build your own copy of Vienna - from scratch on your own machine or if you want to borrow - portions for inclusion in your own project. The source is - provided under the Apache 2.0 - license.

-

I found a - problem with Vienna. How do I report it?

-

Post a message over in the Support forum and somebody will - investigate. Provide as much information about the problem as you - can including: the build of Vienna (obtained from the About - Vienna panel), repro steps and what you expected to happen.

-

Make sure you're always running the most recent build of - Vienna. The Check for Updates command will report if there's a - newer build available than the one you have.

-

Fixes for bugs take priority over new features so if your - problem is confirmed to be a bug with high impact and no simple - workaround then I'll look at making a fix available as soon as - reasonably possible.

-

How do I create my own - styles?

-

See the Custom Styles - page for instructions.

-

How do I create my own - scripts?

-

Vienna's scripts are written using AppleScript. See the - - Apple resource page for more details.

-

One way to get started is to download one of the existing - scripts from the Vienna Downloads - page and view it in the AppleScript editor. Also take a look - at the Scripts - page for more details of the Vienna scripting dictionary and - examples of what you can accomplish.

-

To submit your own script, send it to steve@opencommunity.co.uk - and after it has been reviewed, it will be made available on the - Downloads page.

-

- How can I see what happened when my subscriptions are - refreshed?

-

Open the Activity Window from the Window menu. The activity - window shows all subscriptions and the status of the last time - they were refreshed in that session. The bottom of the activity - window shows more details include the HTTP headers and may be - useful for debugging. (If the details pane is not visible, grab - the split bar at the bottom of the Activity Window and drag it up - to uncover the pane).

-

How do I - move my Vienna database to another folder?

-

By default, your Vienna database is the messages.db file which - is located at ~/Library/Application Support/Vienna. You can move - this to another folder if you wish. The following steps show - how:

-
    -
  1. Shut down Vienna.
  2. -
  3. Open a console window and enter:
    -
    - defaults write - uk.co.opencommunity.vienna2 "DefaultDatabase" '<path to new - messages.db>'
    -
    - where <path to new messages.db> is the name of the folder - that contains the messages.db file. The path itself should have - the messages.db filename at the end. For example:
    -
    - defaults write - uk.co.opencommunity.vienna2 "DefaultDatabase" - '/Users/steve/mydata/messages.db'
  4. -
  5. Restart Vienna.
  6. -
-

- One of my subscriptions reports "Error parsing XML data in feed". - What does this mean?

-

It means that Vienna got a feed back from the subscription - that it couldn't interpret. There are several reasons for - this:

-
    -
  1. The URL of the feed may not be pointing to an RSS or Atom - feed but to a web page. Check the URL of the offending feed - carefully.
  2. -
  3. The feed itself may contain malformed XML. Some - subscriptions make a mistake in putting together the XML that - makes up the feed and Vienna cannot interpret malformed XML. - Use the Validate Feed command on the File menu to see if this - is the case. Unfortunately you cannot do much about this in - Vienna except wait for the feed itself to be corrected by the - site.
  4. -
  5. The feed may be incomplete. If the refresh was interrupted - then the XML data will be incomplete and will appear malformed - in Vienna. A second refresh may correct this problem.
  6. -
-

If none of the above explain the problem, post a message on - the support forum with the URL of the feed exhibiting the - problem.

-

- Is there a shortcut key for going to the next article, marking - read, etc?

-

Probably. There are single key equivalents for some of the - menu commands such as:

-

Spacebar - goes to the next unread article. If the current - article is several pages long, it will scroll through that - article first. If you're at the end of the current article it - will then go to the next unread article. By contrast the Next - Unread command (Cmd+U) always goes straight to the next unread - article.

-

R - marks the current article read if it is unread, or unread - if it is read.

-

F - flags the current article if it isn't already flagged, or - removes the existing flag if it is not.

-

Look in the Vienna Help file for more shortcuts.

-

How do I use Auto - Expire and what does it do?

-

Auto-expire moves articles older than a certain number of days - to the Trash folder. It allows you to keep your folders - manageable by only retaining articles that are recent. The - auto-expire runs both when Vienna starts and after you have - refreshed any subscriptions. To control the age of articles to - auto-expire, change the "Expire articles older than" option in - Preferences.

-

Auto-expire will NOT remove unread or flagged articles. It - assumes that you haven't read these articles and thus leaves them - alone.

-

How do I request an - enhancement in Vienna?

-

Post a message over at the support - forum. All requested enhancements are logged in the TODO file - that is included with the source code as a guidance for future - developers.

- - diff --git a/lproj/ja.lproj/Vienna Help/helpstyle.css b/lproj/ja.lproj/Vienna Help/helpstyle.css deleted file mode 100644 index d02689f72e..0000000000 --- a/lproj/ja.lproj/Vienna Help/helpstyle.css +++ /dev/null @@ -1,39 +0,0 @@ -a { - color: #3366CC; - text-decoration: none; -} -.title { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 18pt; - color: #000000; -} -.header { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 12pt; - color: #000000; -} -li { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 100; - font-size: 9pt; - color: #000000; -} -h2 { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 400; - font-size: 10pt; - color: #000000; -} -p { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 100; - font-size: 9pt; - color: #000000; -} -tr { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-size: 9pt; - color: #000000; -} \ No newline at end of file diff --git a/lproj/ja.lproj/Vienna Help/images/Small-Vienna-Logo.jpg b/lproj/ja.lproj/Vienna Help/images/Small-Vienna-Logo.jpg deleted file mode 100644 index 41035b4f11..0000000000 Binary files a/lproj/ja.lproj/Vienna Help/images/Small-Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/ja.lproj/Vienna Help/images/Vertical-Line.jpg b/lproj/ja.lproj/Vienna Help/images/Vertical-Line.jpg deleted file mode 100644 index 011f1ce1e3..0000000000 Binary files a/lproj/ja.lproj/Vienna Help/images/Vertical-Line.jpg and /dev/null differ diff --git a/lproj/ja.lproj/Vienna Help/images/Vienna-Logo.jpg b/lproj/ja.lproj/Vienna Help/images/Vienna-Logo.jpg deleted file mode 100644 index 13a6479bd4..0000000000 Binary files a/lproj/ja.lproj/Vienna Help/images/Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/ja.lproj/Vienna Help/images/rssfeed.gif b/lproj/ja.lproj/Vienna Help/images/rssfeed.gif deleted file mode 100644 index 2dc8935119..0000000000 Binary files a/lproj/ja.lproj/Vienna Help/images/rssfeed.gif and /dev/null differ diff --git a/lproj/ja.lproj/Vienna Help/index.html b/lproj/ja.lproj/Vienna Help/index.html deleted file mode 100644 index 00c223fc12..0000000000 --- a/lproj/ja.lproj/Vienna Help/index.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - Vienna Help - - - - - - - - - - -
-

-

Vienna Help

-
-

Introduction to Vienna

-

Learn how to get started with - Vienna.

-

Keyboard Shortcuts

-

Discover keyboard shortcuts - for common commands

-

How Do I?

-

Frequently Asked Questions, getting - support and troubleshooting steps.

-
- - diff --git a/lproj/ja.lproj/Vienna Help/intro.html b/lproj/ja.lproj/Vienna Help/intro.html deleted file mode 100644 index 8837ebedf8..0000000000 --- a/lproj/ja.lproj/Vienna Help/intro.html +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - - Introduction to Vienna - - - - -   Introduction to - Vienna -

Vienna is an application that allows you to read RSS or Atom - news feeds on your Mac OSX computer. It automates the job of - retrieving news articles from all subscribed feeds and storing - them in a local database for reading off-line. It provides - features that allow you to search feeds for keywords or phrases, - tag articles with a flag for future reference and organise - related feeds together under groups. You can create smart folders - that make it easy to dynamically retrieve and view all articles - in the database that match a search criteria. The built-in web - browser allows you to go to the articles web page or view links - in the article directly in Vienna in separate tabs.

-

Vienna is designed to be simple and easy to use. A clean, - uncluttered, interface maximises the space for articles and just - a few controls are needed to perform the most common actions in - the user interface.

Getting Started -

If this is the first time that you have used Vienna then it - will have created a new database for you and added some sample - news subscriptions. So go ahead and press Command+T or choose - Refresh All Subscriptions from the File menu to grab the latest - articles from those subscriptions.

-

Alternatively, subscribe to your own news feeds. There are - various ways to find feeds. When browsing the web, look out for - the or XML icons - indicating that the page has a feed associated with it. - Alternatively almost all online blogging services such as - LiveJournal or Blogger provide RSS feeds as an alternative to - reading the postings online.

-

If you know the user name of a blogger on LiveJournal, - Blogger, MSN Spaces or Xanga then Vienna makes it easier to - subscribe to their news feed. Start by pressing Command+N or from - the File menu, choose the New Subscription command. In the - "Create a new RSS subscription" panel, pick the blogging service - from the drop down list and enter the user name in the input - field below. Then choose Subscribe and Vienna will add the - subscription to the folder list. If you are connected to the - internet at the time, it will also immediately start collecting - articles from the feed.

-

Normally you need to manually tell Vienna when to refresh all - your subscriptions. However you can opt to ask Vienna to - automatically refresh at time intervals. In the General section - of the Preferences, pick the desired time interval from the drop - down list next to 'Check for new articles'. Vienna needs to be - running for it to automatically refresh subscriptions.

-

To read articles, press the Spacebar to skip to the next - unread article in any subscription. Each article is marked as - read automatically after a short delay. If you prefer to wait - until you move to the next unread article before the current one - is marked read you can adjust the behaviour in the General tab of - the Preferences. To mark an article as unread again, choose the - Mark Unread command from the Article menu or simply press the 'R' - key.

-

Finally, you can view the article web page or any web page - links in an article within Vienna. By default clicking on a web - link within Vienna will open the web page in a new tab. Vienna - provides a lot of basic web browsing support itself but there may - be times when you will prefer to open links in your default web - browser. If you prefer to view all web pages outside of Vienna - then enable the 'Open links in external browser' option in the - General section of the Preferences. However if you prefer to view - the current link or page in your external browser, right click on - the page and choose the "Open Link in XXX" or "Open Page in XXX" - option where XXX will be the name of your default browser.

-

Once you've got comfortable using Vienna, go ahead and explore - the various options. You can change the style in which the - articles are displayed through the Style drop down list in the - View menu. You can find many more custom styles at the Downloads - page on the Vienna web site along with custom scripts that allow - you to integrate Vienna with other applications on your machine. - Or experiment with smart folders to organise articles according - to criteria based on the contents of each article. For example, - you can easily set up a smart folder to group together all - articles that mention "Joss Whedon" and "Firefly" to find - references to the Firefly cult series or the spin-off movie.

-

If you have any questions about Vienna or run into problems, - head over to the Support - forum.

- - diff --git a/lproj/ja.lproj/Vienna Help/keyboard.html b/lproj/ja.lproj/Vienna Help/keyboard.html deleted file mode 100644 index fd95d46952..0000000000 --- a/lproj/ja.lproj/Vienna Help/keyboard.html +++ /dev/null @@ -1,248 +0,0 @@ - - - - - - - Keyboard Shortcuts - - - - -  Keyboard - Shortcuts -

You can use your keyboard to quickly accomplish many tasks in - Vienna. To find the shortcuts for common commands, look in the - menus (or see the list at the bottom of this page). Many items in - Vienna such as the folder pane and the article list pane also - have contextual menus. To see a contextual menu, press the - Control key and click the item.

-

To do an action, press the shortcut keys indicated below.

- - - - - -
KeyAction
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Single Key Shortcuts 
fSets the input focus to the search window.
rMarks the selected articles read.
sMarks the current folder read then skips to the next - folder with unread articles.
kMarks the current folder read.
mFlags the selected articles.
<Displays the previous viewed article or web page.
>Displays the next viewed article or web page.
SpacebarMoves to the next unread article unless the current - article has more text to scroll in which case it scrolls the - current article up one page.
Command-UMoves to the next unread article.
Enter/ReturnOpens the selected article's original web page.
Delete/BackspaceMoves the selected articles to the Trash folder. If this - key is used in the Trash folder, the selected articles are - permanently deleted.
General Shortcuts 
Command-NCreate a new subscription.
Shift-Command-FCreate a smart folder.
Shift-Command-EEdit the selected folder URL or edit a smart folder - criteria.
Shift-Command-DDelete the selected folder.
Shift-Command-NRename the selected folder.
Command-RRefreshes all subscriptions.
Shift-Command-RRefresh only those subscriptions selected in the folder - list.
Command-MinusStops any active refresh.
Command-PPrint the selected articles.
Shift-Command-PBrings up the Page Setup panel.
Shift-Command-VValidate the selected feed.
Command-?Displays the Vienna help book.
Articles Shortcuts 
Shift-Command-MFlags the selected articles.
Shift-Command-UMarks the selected articles read.
Shift-Command-SMarks the current folder read then skips to the next - folder with unread articles.
Shift-Command-ORestores an article from the trash back to its original - folder.
Shift-Command-KMarks all articles in the selected folders read.
Alt-Command-KMarks all articles in all folders read.
Window Shortcuts 
Command-WCloses the active tab window if one is open. Otherwise if - no tabs are open, this closes the Vienna window.
Alt-Command-WCloses all tab windows. Note that this command replaces - the Close Tab command on the File menu when the Alt key is - held down.
Control-Command-LeftDisplays the previous tab window.
Control-Command-RightDisplays the next tab window.
Shift-Command-WCloses the Vienna window but leaves Vienna running in the - background. You can bring the window back by clicking on the - Vienna dock icon or pressing Command-1.
Command-MMinimizes the Vienna window to the dock.
Command-0Displays the activity log viewer window.
Command-1Reopens the Vienna window if it was previously - closed.
Command-2Displays the Downloads window.
Browser Window Shortcuts 
Alt-RReloads the current web page.
Command-PeriodCancels loading of the current web page.
Command-[/Command-LeftGoes back to the previous web page.
Command-]/Command-RightGoes forward to the next web page.
Command-FPuts the input focus in the search field. Entering some - text here and pressing Enter will search for that text on the - current web page.
Command-GSearches for the next occurrence of the search text on - the web page.
- - diff --git a/lproj/ko.lproj/GroupFolder.nib/designable.nib b/lproj/ko.lproj/GroupFolder.nib/designable.nib index fa4fc075d8..dd8f9402d7 100644 --- a/lproj/ko.lproj/GroupFolder.nib/designable.nib +++ b/lproj/ko.lproj/GroupFolder.nib/designable.nib @@ -1,502 +1,89 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - NewGroupFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{502, 622}, {388, 149}} - 1886912512 - - Panel - - - NSPanel - - - View - - - {213, 107} - - - 256 - - - - 260 - {{17, 112}, {354, 17}} - - - YES - - 67108864 - 4194304 - 새 그룹 폴더 추가 - - LucidaGrande-Bold - 13 - 2072 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 258 - {{20, 60}, {348, 22}} - - - YES - - -1804599231 - 272630784 - - - LucidaGrande - 13 - 1044 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{287, 12}, {87, 32}} - - - 100 - YES - - 67108864 - 134217728 - 추가 - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{200, 12}, {87, 32}} - - - YES - - 67108864 - 134217728 - 취소 - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 268 - {{17, 90}, {353, 14}} - - - YES - - 67108864 - 4194304 - 새 그룹 폴더의 이름을 입력하십시오: - - LucidaGrande - 11 - 3100 - - - - - - NO - - - {388, 149} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - - - - newGroupFolderWindow - - - - 18 - - - - doCancel: - - - - 25 - - - - doSave: - - - - 26 - - - - folderName - - - - 27 - - - - cancelButton - - - - 28 - - - - saveButton - - - - 29 - - - - window - - - - 30 - - - - nextKeyView - - - - 24 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 5 - - - - - - GroupFolder - - - 6 - - - - - - - - - - - - 19 - - - - - - - - 20 - - - - - - - - 21 - - - - - - - - 22 - - - - - - - - 23 - - - - - - - - 32 - - - - - 33 - - - - - 34 - - - - - 35 - - - - - 36 - - - - - -3 - - - Application - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 36 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - NewGroupFolder - NSWindowController - - id - id - - - - doCancel: - id - - - doSave: - id - - - - NSButton - NSTextField - NSWindow - NSButton - - - - cancelButton - NSButton - - - folderName - NSTextField - - - newGroupFolderWindow - NSWindow - - - saveButton - NSButton - - - - IBProjectSource - ./Classes/NewGroupFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/ko.lproj/GroupFolder.nib/keyedobjects.nib b/lproj/ko.lproj/GroupFolder.nib/keyedobjects.nib index 9ee25272a0..fc35329911 100644 Binary files a/lproj/ko.lproj/GroupFolder.nib/keyedobjects.nib and b/lproj/ko.lproj/GroupFolder.nib/keyedobjects.nib differ diff --git a/lproj/ko.lproj/InfoPlist.strings b/lproj/ko.lproj/InfoPlist.strings deleted file mode 100644 index 0097ee642a..0000000000 --- a/lproj/ko.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ -NSHumanReadableCopyright = "Copyright 2004-2015 Contributors. See Help/Acknowledgements for list of contributors."; diff --git a/lproj/ko.lproj/Localizable.strings b/lproj/ko.lproj/Localizable.strings index 862fe18d32..6c38ee2af8 100644 --- a/lproj/ko.lproj/Localizable.strings +++ b/lproj/ko.lproj/Localizable.strings @@ -450,3 +450,9 @@ /*Added in 3.0.5 */ "Redirection attempt treated as temporary for safety concern" = "Redirection attempt treated as temporary for safety concern"; + +/*Added in 3.0.7 */ +"No articles in feed" = "No articles in feed"; + +/*Added in 3.1.2 */ +"Filter folders" = "Search for folders"; diff --git a/lproj/ko.lproj/RSSFeed.nib/designable.nib b/lproj/ko.lproj/RSSFeed.nib/designable.nib index e661df2044..cf63b56b64 100644 --- a/lproj/ko.lproj/RSSFeed.nib/designable.nib +++ b/lproj/ko.lproj/RSSFeed.nib/designable.nib @@ -1,1007 +1,217 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSMenu - NSMenuItem - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSUserDefaultsController - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - RSSFeed - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{165, 318}, {426, 295}} - 1886912512 - RSS Feed - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{208, 15}, {102, 32}} - - - YES - - 67108864 - 134217728 - 취소 - - AppleSDGothicNeo-Regular - 13 - 16 - - - -2038284288 - 1 - - LucidaGrande - 13 - 1044 - - - Gw - 200 - 25 - - NO - - - - 256 - {{310, 15}, {102, 32}} - - - 100 - YES - - 67108864 - 134217728 - 구독하기 - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{20, 194}, {75, 17}} - - - YES - - 67108864 - 4194304 - 추가 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 256 - {{99, 187}, {175, 26}} - - - YES - - -2080374720 - 1024 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - URL - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - 100 - - - YES - - - OtherViews - - - - - - 3 - YES - YES - 1 - - NO - - - - 256 - {{20, 261}, {389, 17}} - - - YES - - 67108864 - 4194304 - Q3JlYXRlIGEgbmV3IHN1YnNjcmlwdGlvbgo - - LucidaGrande-Bold - 13 - 2072 - - - - - - NO - - - - 256 - {{20, 219}, {378, 34}} - - - YES - - 67108864 - 4194304 - 새 구독 추가 - - LucidaGrande - 10 - 2843 - - - - - - NO - - - - 256 - {{23, 88}, {386, 62}} - - - YES - - -1805647871 - 4325376 - - - LucidaGrande - 11 - 3100 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 256 - {{283, 187}, {21, 24}} - - - YES - - 67108864 - 134217728 - - - - -2038284288 - 33 - - - - - - 200 - 25 - - NO - - - - 256 - {{20, 158}, {270, 17}} - - - YES - - 67108864 - 4194304 - URL: - - - - - - NO - - - - 268 - {{21, 50}, {185, 18}} - - - YES - - -2080374784 - 0 - Subscribe in Open Reader - - - 1211912448 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - NO - - - {426, 295} - - - - {{0, 0}, {1280, 778}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - 3 - 2 - {{305, 336}, {423, 167}} - 1886912512 - RSS Feed - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{307, 12}, {102, 32}} - - 100 - YES - - 67108864 - 134217728 - URL: - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{205, 12}, {102, 32}} - - - YES - - 67108864 - 134217728 - 저장 - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{20, 60}, {383, 62}} - - - YES - - -1805647871 - 4325376 - - - - YES - - - - NO - - - - 256 - {{17, 130}, {389, 17}} - - - YES - - 67108864 - 4194304 - Edit subscription - - - - - - NO - - - {{1, 9}, {423, 167}} - - - {{0, 0}, {1280, 778}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - YES - - - - - - - window - - - - 14 - - - - doSubscribe: - - - - 37 - - - - feedSource - - - - 46 - - - - subscribeButton - - - - 48 - - - - doSave: - - - - 57 - - - - editRSSFeedWindow - - - - 61 - - - - newRSSFeedWindow - - - - 62 - - - - editFeedURL - - - - 69 - - - - saveButton - - - - 70 - - - - editCancelButton - - - - 74 - - - - subscribeCancelButton - - - - 76 - - - - doEditCancel: - - - - 77 - - - - doSubscribeCancel: - - - - 78 - - - - doLinkSourceChanged: - - - - 89 - - - - feedURL - - - - 91 - - - - doShowSiteHomePage: - - - - 93 - - - - siteHomePageButton - - - - 94 - - - - linkTitle - - - - 99 - - - - doGoogleOption: - - - - 118 - - - - googleOptionButton - - - - 119 - - - - value: googleOptionButton - - - - - - value: googleOptionButton - value - googleOptionButton - 2 - - - 117 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - NewRSSFeed - - - 5 - - - - - - - - - - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 40 - - - - - - - - 43 - - - - - - - - 64 - - - - - - - - 65 - - - - - - - - 90 - - - - - - - - 92 - - - - - - - - 97 - - - - - - - - 49 - - - - - - EditRSSFeed - - - 50 - - - - - - - - - - - 53 - - - - - - - - 54 - - - - - - - - 55 - - - - - - - - 67 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - 107 - - - - - 108 - - - - - 109 - - - - - 110 - - - - - 111 - - - - - 112 - - - - - 113 - - - - - 114 - - - - - 44 - - - - - - - - 45 - - - - - -3 - - - Application - - - 115 - - - - - - - - 116 - - - - - 120 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{1012, 565}, {429, 297}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 122 - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - {15, 15} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create a new subscription + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/ko.lproj/RSSFeed.nib/keyedobjects.nib b/lproj/ko.lproj/RSSFeed.nib/keyedobjects.nib index 894a0ead0a..c79d92cab6 100644 Binary files a/lproj/ko.lproj/RSSFeed.nib/keyedobjects.nib and b/lproj/ko.lproj/RSSFeed.nib/keyedobjects.nib differ diff --git a/lproj/ko.lproj/SearchFolder.nib/designable.nib b/lproj/ko.lproj/SearchFolder.nib/designable.nib index ce0968966f..c771771c6f 100644 --- a/lproj/ko.lproj/SearchFolder.nib/designable.nib +++ b/lproj/ko.lproj/SearchFolder.nib/designable.nib @@ -1,1591 +1,263 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSBox - NSButton - NSButtonCell - NSCustomObject - NSCustomView - NSMenu - NSMenuItem - NSNumberFormatter - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - SmartFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{486, 670}, {647, 186}} - 1886912512 - - NSPanel - - View - - - {213, 107} - - - 256 - - - - 268 - {{17, 150}, {108, 17}} - - - YES - - 67108864 - 4194304 - 스마트 폴더 이름: - - LucidaGrande - 13 - 1044 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 268 - {{130, 147}, {300, 22}} - - - YES - - -1804599231 - 4195328 - - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{546, 12}, {87, 32}} - - - YES - - 67108864 - 134217728 - 저장 - - - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{459, 12}, {87, 32}} - - - YES - - 67108864 - 134217728 - 취소 - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 274 - - - - 274 - - - - 274 - {{12, 6}, {584, 38}} - - - - NSView - - NSResponder - - - {{2, 2}, {609, 50}} - - - - - {{17, 56}, {613, 54}} - - - {0, 0} - - 67108864 - 0 - - - LucidaGrande - 11 - 3100 - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 3 - 0 - 0 - NO - - - - 268 - {{17, 118}, {43, 17}} - - - YES - - 67108864 - 4194304 - 다음의 - - - - - - NO - - - - 268 - {{62, 112}, {80, 26}} - - - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - Nothing - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - 268 - {{144, 118}, {194, 17}} - - - YES - - 67108864 - 272629760 - 조건에 일치하는 모든 기사 항목: - - - - - - NO - - - {647, 186} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - 256 - - - - 256 - {{-3, 0}, {126, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Field names go here - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - 256 - {{513, -3}, {32, 31}} - - YES - - 67108864 - 134479872 - - - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{316, 3}, {183, 22}} - - YES - - -1804599231 - 4195328 - - - - YES - - - - NO - - - - 256 - {{541, -3}, {32, 31}} - - YES - - 67108864 - 134479872 - + - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{125, 0}, {186, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Operators go here - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{313, 0}, {189, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - - - 400 - 75 - - - Nothing - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{316, 4}, {183, 22}} - - YES - - -1804599231 - 4195328 - - - - - - - - - NaN - - - - 0 - - - . - - , - - - - - 0 - 2 - NO - YES - 1 - P0IPAAAAAAAAAAAAAAAAAA - - - 0 - 1 - NO - YES - 1 - AQAAAAAAAAAAAAAAAAAAAA - - -0 - 0 - - - 0 - -0 - - - - - - - - - . - , - NO - NO - YES - - - YES - - - - NO - - - - -2147483392 - {{313, 0}, {189, 26}} - - 1008 - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Item2 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - Item3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{313, 0}, {189, 26}} - - 1004 - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Item1 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - Item2 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - Item3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - -1 - 3 - YES - YES - 1 - - NO - - - {572, 28} - - NSView - - NSResponder - - - - - - - cancelButton - - - - 40 - - - - saveButton - - - - 41 - - - - searchCriteriaView - - - - 43 - - - - removeCriteriaButton - - - - 44 - - - - addCriteriaButton - - - - 45 - - - - fieldNamePopup - - - - 46 - - - - operatorPopup - - - - 47 - - - - valueField - - - - 49 - - - - window - - - - 50 - - - - addNewCriteria: - - - - 51 - - - - doCancel: - - - - 52 - - - - doSave: - - - - 53 - - - - searchWindow - - - - 54 - - - - removeCurrentCriteria: - - - - 57 - - - - fieldChanged: - - - - 59 - - - - flagValueField - - - - 65 - - - - numberValueField - - - - 70 - - - - folderValueField - - - - 78 - - - - criteriaConditionPopup - - - - 85 - - - - dateValueField - - - - 91 - - - - smartFolderName - - - - 92 - - - - searchCriteriaSuperview - - - - 42 - - - - nextKeyView - - - - 72 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - Search Folder - - - 5 - - - - - - - - - - - - - - - 7 - - - - - - - - 8 - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 37 - - - - - - - - 58 - - - - - - - - 79 - - - - - - - - 84 - - - - - - - - 26 - - - - - - - - - - - - - - SearchCriteriaView - - - 27 - - - - - - - - 29 - - - - - - - - 30 - - - - - - - - 31 - - - - - - - - 35 - - - - - - - - 61 - - - - - - - - 69 - - - - - - - - 73 - - - - - - - - 86 - - - - - - - - 94 - - - - - 95 - - - - - 96 - - - - - 97 - - - - - 98 - - - - - 99 - - - - - - - - 100 - - - - - 101 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - - - - 107 - - - - - - - - 108 - - - - - - - - 109 - - - - - - - - 71 - - - - - 80 - - - - - - - - 82 - - - - - 32 - - - - - - - - 33 - - - - - 34 - - - - - - - - 56 - - - - - 64 - - - - - - - - 62 - - - - - 74 - - - - - - - - - 76 - - - - - 75 - - - - - 87 - - - - - - - - - - 90 - - - - - 89 - - - - - 88 - - - - - -3 - - - Application - - - 36 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 109 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - SmartFolder - NSWindowController - - id - id - id - id - id - - - - addNewCriteria: - id - - - doCancel: - id - - - doSave: - id - - - fieldChanged: - id - - - removeCurrentCriteria: - id - - - - NSButton - NSButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSTextField - NSPopUpButton - NSButton - NSButton - NSView - NSView - NSWindow - NSTextField - NSTextField - - - - addCriteriaButton - NSButton - - - cancelButton - NSButton - - - criteriaConditionPopup - NSPopUpButton - - - dateValueField - NSPopUpButton - - - fieldNamePopup - NSPopUpButton - - - flagValueField - NSPopUpButton - - - folderValueField - NSPopUpButton - - - numberValueField - NSTextField - - - operatorPopup - NSPopUpButton - - - removeCriteriaButton - NSButton - - - saveButton - NSButton - - - searchCriteriaSuperview - NSView - - - searchCriteriaView - NSView - - - searchWindow - NSWindow - - - smartFolderName - NSTextField - - - valueField - NSTextField - - - - IBProjectSource - ./Classes/SmartFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/ko.lproj/SearchFolder.nib/keyedobjects.nib b/lproj/ko.lproj/SearchFolder.nib/keyedobjects.nib index 25622df3d7..98afec4f57 100644 Binary files a/lproj/ko.lproj/SearchFolder.nib/keyedobjects.nib and b/lproj/ko.lproj/SearchFolder.nib/keyedobjects.nib differ diff --git a/lproj/ko.lproj/Vienna Help/advanced.html b/lproj/ko.lproj/Vienna Help/advanced.html deleted file mode 100644 index fb9b248814..0000000000 --- a/lproj/ko.lproj/Vienna Help/advanced.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - Advanced Settings - - - - -  Advanced - Settings -

The Advanced section of the Preferences provides options to - change very specific settings in Vienna that are not essential - for normal use but may resolve some issues as advised by the - support forum. This page details the advanced settings and their - function.

-

Enable JavaScript in internal browser

-

Enables or disables support for JavaScript scripting in the - Vienna internal browser. By default this is enabled. By turning - this setting off, JavaScript code on web pages will not be - allowed to run. This may resolve problems with pages that use - scripting to pop up windows or other unexpected behaviour but - turning the setting off may also cause some web pages to appear - incomplete or fail to function correctly.

- - diff --git a/lproj/ko.lproj/Vienna Help/faq.html b/lproj/ko.lproj/Vienna Help/faq.html deleted file mode 100644 index 8532ac8e96..0000000000 --- a/lproj/ko.lproj/Vienna Help/faq.html +++ /dev/null @@ -1,208 +0,0 @@ - - - - - - - How Do I? - - - - -  How Do I? -

Below are some of the more common questions asked about Vienna - while it was being pre-release tested. See the Official Vienna FAQ - Page for these and the latest hints and tips for using - Vienna.

- -

Where do I get the Vienna - source code?

-

See the Development page - for instructions for getting the source code for Vienna. The - source code is freely available if you're interested in learning - how Vienna works, if you want to build your own copy of Vienna - from scratch on your own machine or if you want to borrow - portions for inclusion in your own project. The source is - provided under the Apache 2.0 - license.

-

I found a - problem with Vienna. How do I report it?

-

Post a message over in the Support forum and somebody will - investigate. Provide as much information about the problem as you - can including: the build of Vienna (obtained from the About - Vienna panel), repro steps and what you expected to happen.

-

Make sure you're always running the most recent build of - Vienna. The Check for Updates command will report if there's a - newer build available than the one you have.

-

Fixes for bugs take priority over new features so if your - problem is confirmed to be a bug with high impact and no simple - workaround then I'll look at making a fix available as soon as - reasonably possible.

-

How do I create my own - styles?

-

See the Custom Styles - page for instructions.

-

How do I create my own - scripts?

-

Vienna's scripts are written using AppleScript. See the - - Apple resource page for more details.

-

One way to get started is to download one of the existing - scripts from the Vienna Downloads - page and view it in the AppleScript editor. Also take a look - at the Scripts - page for more details of the Vienna scripting dictionary and - examples of what you can accomplish.

-

To submit your own script, send it to steve@opencommunity.co.uk - and after it has been reviewed, it will be made available on the - Downloads page.

-

- How can I see what happened when my subscriptions are - refreshed?

-

Open the Activity Window from the Window menu. The activity - window shows all subscriptions and the status of the last time - they were refreshed in that session. The bottom of the activity - window shows more details include the HTTP headers and may be - useful for debugging. (If the details pane is not visible, grab - the split bar at the bottom of the Activity Window and drag it up - to uncover the pane).

-

How do I - move my Vienna database to another folder?

-

By default, your Vienna database is the messages.db file which - is located at ~/Library/Application Support/Vienna. You can move - this to another folder if you wish. The following steps show - how:

-
    -
  1. Shut down Vienna.
  2. -
  3. Open a console window and enter:
    -
    - defaults write - uk.co.opencommunity.vienna2 "DefaultDatabase" '<path to new - messages.db>'
    -
    - where <path to new messages.db> is the name of the folder - that contains the messages.db file. The path itself should have - the messages.db filename at the end. For example:
    -
    - defaults write - uk.co.opencommunity.vienna2 "DefaultDatabase" - '/Users/steve/mydata/messages.db'
  4. -
  5. Restart Vienna.
  6. -
-

- One of my subscriptions reports "Error parsing XML data in feed". - What does this mean?

-

It means that Vienna got a feed back from the subscription - that it couldn't interpret. There are several reasons for - this:

-
    -
  1. The URL of the feed may not be pointing to an RSS or Atom - feed but to a web page. Check the URL of the offending feed - carefully.
  2. -
  3. The feed itself may contain malformed XML. Some - subscriptions make a mistake in putting together the XML that - makes up the feed and Vienna cannot interpret malformed XML. - Use the Validate Feed command on the File menu to see if this - is the case. Unfortunately you cannot do much about this in - Vienna except wait for the feed itself to be corrected by the - site.
  4. -
  5. The feed may be incomplete. If the refresh was interrupted - then the XML data will be incomplete and will appear malformed - in Vienna. A second refresh may correct this problem.
  6. -
-

If none of the above explain the problem, post a message on - the support forum with the URL of the feed exhibiting the - problem.

-

- Is there a shortcut key for going to the next article, marking - read, etc?

-

Probably. There are single key equivalents for some of the - menu commands such as:

-

Spacebar - goes to the next unread article. If the current - article is several pages long, it will scroll through that - article first. If you're at the end of the current article it - will then go to the next unread article. By contrast the Next - Unread command (Cmd+U) always goes straight to the next unread - article.

-

R - marks the current article read if it is unread, or unread - if it is read.

-

F - flags the current article if it isn't already flagged, or - removes the existing flag if it is not.

-

Look in the Vienna Help file for more shortcuts.

-

How do I use Auto - Expire and what does it do?

-

Auto-expire moves articles older than a certain number of days - to the Trash folder. It allows you to keep your folders - manageable by only retaining articles that are recent. The - auto-expire runs both when Vienna starts and after you have - refreshed any subscriptions. To control the age of articles to - auto-expire, change the "Expire articles older than" option in - Preferences.

-

Auto-expire will NOT remove unread or flagged articles. It - assumes that you haven't read these articles and thus leaves them - alone.

-

How do I request an - enhancement in Vienna?

-

Post a message over at the support - forum. All requested enhancements are logged in the TODO file - that is included with the source code as a guidance for future - developers.

- - diff --git a/lproj/ko.lproj/Vienna Help/helpstyle.css b/lproj/ko.lproj/Vienna Help/helpstyle.css deleted file mode 100644 index d02689f72e..0000000000 --- a/lproj/ko.lproj/Vienna Help/helpstyle.css +++ /dev/null @@ -1,39 +0,0 @@ -a { - color: #3366CC; - text-decoration: none; -} -.title { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 18pt; - color: #000000; -} -.header { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 12pt; - color: #000000; -} -li { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 100; - font-size: 9pt; - color: #000000; -} -h2 { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 400; - font-size: 10pt; - color: #000000; -} -p { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 100; - font-size: 9pt; - color: #000000; -} -tr { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-size: 9pt; - color: #000000; -} \ No newline at end of file diff --git a/lproj/ko.lproj/Vienna Help/images/Small-Vienna-Logo.jpg b/lproj/ko.lproj/Vienna Help/images/Small-Vienna-Logo.jpg deleted file mode 100644 index 41035b4f11..0000000000 Binary files a/lproj/ko.lproj/Vienna Help/images/Small-Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/ko.lproj/Vienna Help/images/Vertical-Line.jpg b/lproj/ko.lproj/Vienna Help/images/Vertical-Line.jpg deleted file mode 100644 index 011f1ce1e3..0000000000 Binary files a/lproj/ko.lproj/Vienna Help/images/Vertical-Line.jpg and /dev/null differ diff --git a/lproj/ko.lproj/Vienna Help/images/Vienna-Logo.jpg b/lproj/ko.lproj/Vienna Help/images/Vienna-Logo.jpg deleted file mode 100644 index 13a6479bd4..0000000000 Binary files a/lproj/ko.lproj/Vienna Help/images/Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/ko.lproj/Vienna Help/images/rssfeed.gif b/lproj/ko.lproj/Vienna Help/images/rssfeed.gif deleted file mode 100644 index 2dc8935119..0000000000 Binary files a/lproj/ko.lproj/Vienna Help/images/rssfeed.gif and /dev/null differ diff --git a/lproj/ko.lproj/Vienna Help/index.html b/lproj/ko.lproj/Vienna Help/index.html deleted file mode 100644 index 00c223fc12..0000000000 --- a/lproj/ko.lproj/Vienna Help/index.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - Vienna Help - - - - - - - - - - -
-

-

Vienna Help

-
-

Introduction to Vienna

-

Learn how to get started with - Vienna.

-

Keyboard Shortcuts

-

Discover keyboard shortcuts - for common commands

-

How Do I?

-

Frequently Asked Questions, getting - support and troubleshooting steps.

-
- - diff --git a/lproj/ko.lproj/Vienna Help/intro.html b/lproj/ko.lproj/Vienna Help/intro.html deleted file mode 100644 index 5194b44378..0000000000 --- a/lproj/ko.lproj/Vienna Help/intro.html +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - - Introduction to Vienna - - - - -   Introduction to - Vienna -

Vienna is an application that allows you to read RSS or Atom - news feeds on your Mac OSX computer. It automates the job of - retrieving news articles from all subscribed feeds and storing - them in a local database for reading off-line. It provides - features that allow you to search feeds for keywords or phrases, - tag articles with a flag for future reference and organise - related feeds together under groups. You can create smart folders - that make it easy to dynamically retrieve and view all articles - in the database that match a search criteria. The built-in web - browser allows you to go to the articles web page or view links - in the article directly in Vienna in separate tabs.

-

Vienna is designed to be simple and easy to use. A clean, - uncluttered, interface maximises the space for articles and just - a few controls are needed to perform the most common actions in - the user interface.

Getting Started -

If this is the first time that you have used Vienna then it - will have created a new database for you and added some sample - news subscriptions. So go ahead and press Command+T or choose - Refresh All Subscriptions from the File menu to grab the latest - articles from those subscriptions.

-

Alternatively, subscribe to your own news feeds. There are - various ways to find feeds. When browsing the web, look out for - the RSS feed icon or XML - icons indicating that the page has a feed associated with it. - Alternatively almost all online blogging services such as - LiveJournal or Blogger provide RSS feeds as an alternative to - reading the postings online.

-

If you know the user name of a blogger on LiveJournal, - Blogger, MSN Spaces or Xanga then Vienna makes it easier to - subscribe to their news feed. Start by pressing Command+N or from - the File menu, choose the New Subscription command. In the - "Create a new RSS subscription" panel, pick the blogging service - from the drop down list and enter the user name in the input - field below. Then choose Subscribe and Vienna will add the - subscription to the folder list. If you are connected to the - internet at the time, it will also immediately start collecting - articles from the feed.

-

Normally you need to manually tell Vienna when to refresh all - your subscriptions. However you can opt to ask Vienna to - automatically refresh at time intervals. In the General section - of the Preferences, pick the desired time interval from the drop - down list next to 'Check for new articles'. Vienna needs to be - running for it to automatically refresh subscriptions.

-

To read articles, press the Spacebar to skip to the next - unread article in any subscription. Each article is marked as - read automatically after a short delay. If you prefer to wait - until you move to the next unread article before the current one - is marked read you can adjust the behaviour in the General tab of - the Preferences. To mark an article as unread again, choose the - Mark Unread command from the Article menu or simply press the 'R' - key.

-

Finally, you can view the article web page or any web page - links in an article within Vienna. By default clicking on a web - link within Vienna will open the web page in a new tab. Vienna - provides a lot of basic web browsing support itself but there may - be times when you will prefer to open links in your default web - browser. If you prefer to view all web pages outside of Vienna - then enable the 'Open links in external browser' option in the - General section of the Preferences. However if you prefer to view - the current link or page in your external browser, right click on - the page and choose the "Open Link in XXX" or "Open Page in XXX" - option where XXX will be the name of your default browser.

-

Once you've got comfortable using Vienna, go ahead and explore - the various options. You can change the style in which the - articles are displayed through the Style drop down list in the - View menu. You can find many more custom styles at the Downloads - page on the Vienna web site along with custom scripts that allow - you to integrate Vienna with other applications on your machine. - Or experiment with smart folders to organise articles according - to criteria based on the contents of each article. For example, - you can easily set up a smart folder to group together all - articles that mention "Joss Whedon" and "Firefly" to find - references to the Firefly cult series or the spin-off movie.

-

If you have any questions about Vienna or run into problems, - head over to the Support - forum.

- - diff --git a/lproj/ko.lproj/Vienna Help/keyboard.html b/lproj/ko.lproj/Vienna Help/keyboard.html deleted file mode 100644 index dfce63f716..0000000000 --- a/lproj/ko.lproj/Vienna Help/keyboard.html +++ /dev/null @@ -1,259 +0,0 @@ - - - - - - - Keyboard Shortcuts - - - - -  Keyboard - Shortcuts -

You can use your keyboard to quickly accomplish many tasks in - Vienna. To find the shortcuts for common commands, look in the - menus (or see the list at the bottom of this page). Many items in - Vienna such as the folder pane and the article list pane also - have contextual menus. To see a contextual menu, press the - Control key and click the item.

-

To do an action, press the shortcut keys indicated below.

- - - - - -
KeyAction
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Single Key Shortcuts 
fSets the input focus to the search window.
rMarks the selected articles read.
sMarks the current folder read then skips to the next - folder with unread articles.
kMarks the current folder read.
mFlags the selected articles.
<Displays the previous viewed article or web page.
>Displays the next viewed article or web page.
SpacebarMoves to the next unread article unless the current - article has more text to scroll in which case it scrolls the - current article up one page.
Enter/ReturnOpens the selected article's original web page.
Delete/BackspaceMoves the selected articles to the Trash folder. If this - key is used in the Trash folder, the selected articles are - permanently deleted.
General Shortcuts 
Alt-ClickOpen the clicked link, overriding your preference for - opening links in external browser.
Command-NCreate a new subscription.
Shift-Command-FCreate a smart folder.
Shift-Command-EEdit the selected folder URL or edit a smart folder - criteria.
Shift-Command-DDelete the selected folder.
Shift-Command-NRename the selected folder.
Command-RRefreshes all subscriptions.
Shift-Command-RRefresh only those subscriptions selected in the folder - list.
Command-MinusStops any active refresh.
Command-PPrint the selected articles.
Shift-Command-PBrings up the Page Setup panel.
Shift-Command-VValidate the selected feed.
Command-?Displays the Vienna help book.
Articles Shortcuts 
Alt-Enter/Alt-ReturnOpens the selected article's original web page, - overriding your preference for opening links in external - browser.
Command-UMoves to the next unread article.
Shift-Command-MFlags the selected articles.
Shift-Command-UMarks the selected articles read.
Shift-Command-SMarks the current folder read then skips to the next - folder with unread articles.
Shift-Command-ORestores an article from the trash back to its original - folder.
Shift-Command-KMarks all articles in the selected folders read.
Alt-Command-KMarks all articles in all folders read.
Window Shortcuts 
Command-WCloses the active tab window if one is open. Otherwise if - no tabs are open, this closes the Vienna window.
Alt-Command-WCloses all tab windows. Note that this command replaces - the Close Tab command on the File menu when the Alt key is - held down.
Control-Command-LeftDisplays the previous tab window.
Control-Command-RightDisplays the next tab window.
Shift-Command-WCloses the Vienna window but leaves Vienna running in the - background. You can bring the window back by clicking on the - Vienna dock icon or pressing Command-1.
Command-MMinimizes the Vienna window to the dock.
Command-0Displays the activity log viewer window.
Command-1Reopens the Vienna window if it was previously - closed.
Command-2Displays the Downloads window.
Browser Window Shortcuts 
Alt-RReloads the current web page.
Command-PeriodCancels loading of the current web page.
Command-[/Command-LeftGoes back to the previous web page.
Command-]/Command-RightGoes forward to the next web page.
Command-FPuts the input focus in the search field. Entering some - text here and pressing Enter will search for that text on the - current web page.
Command-GSearches for the next occurrence of the search text on - the web page.
- - diff --git a/lproj/nl.lproj/FeedCredentials.strings b/lproj/nl.lproj/FeedCredentials.strings old mode 100755 new mode 100644 diff --git a/lproj/nl.lproj/GroupFolder.nib/designable.nib b/lproj/nl.lproj/GroupFolder.nib/designable.nib index 1cc01eb6df..4c14f92bda 100644 --- a/lproj/nl.lproj/GroupFolder.nib/designable.nib +++ b/lproj/nl.lproj/GroupFolder.nib/designable.nib @@ -1,500 +1,91 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - NewGroupFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{765, 602}, {388, 107}} - 1886912512 - Paneel - - NSPanel - - - View - - - {213, 107} - - - 256 - - - - 260 - {{17, 112}, {354, 17}} - - - YES - - 67108864 - 4194304 - Nieuwe groep-map - - LucidaGrande-Bold - 13 - 2072 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 258 - {{20, 60}, {348, 22}} - - - YES - - -1804599231 - 272630784 - - - LucidaGrande - 13 - 1044 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{285, 12}, {89, 32}} - - - 100 - YES - - 67108864 - 134217728 - Bewaar - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{190, 12}, {95, 32}} - - - YES - - 67108864 - 134217728 - Annuleer - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 268 - {{17, 90}, {353, 14}} - - - YES - - 67108864 - 4194304 - R2VlZiBkZSBuYWFtIHZhbiBkZSBncm9lcC1tYXA6Cg - - LucidaGrande - 11 - 3100 - - - - - - NO - - - {388, 107} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - - - - newGroupFolderWindow - - - - 18 - - - - doCancel: - - - - 25 - - - - doSave: - - - - 26 - - - - folderName - - - - 27 - - - - cancelButton - - - - 28 - - - - saveButton - - - - 29 - - - - window - - - - 30 - - - - nextKeyView - - - - 24 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 5 - - - - - - GroupFolder - - - 6 - - - - - - - - - - - - 19 - - - - - - - - 20 - - - - - - - - 21 - - - - - - - - 22 - - - - - - - - 23 - - - - - - - - 32 - - - - - 33 - - - - - 34 - - - - - 35 - - - - - 36 - - - - - -3 - - - Application - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 36 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - NewGroupFolder - NSWindowController - - id - id - - - - doCancel: - id - - - doSave: - id - - - - NSButton - NSTextField - NSWindow - NSButton - - - - cancelButton - NSButton - - - folderName - NSTextField - - - newGroupFolderWindow - NSWindow - - - saveButton - NSButton - - - - IBProjectSource - ./Classes/NewGroupFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Geef de naam van de groep-map: + + + + + + + + + + diff --git a/lproj/nl.lproj/GroupFolder.nib/keyedobjects.nib b/lproj/nl.lproj/GroupFolder.nib/keyedobjects.nib index b2f2f0ea4e..3ffabe2d39 100644 Binary files a/lproj/nl.lproj/GroupFolder.nib/keyedobjects.nib and b/lproj/nl.lproj/GroupFolder.nib/keyedobjects.nib differ diff --git a/lproj/nl.lproj/GroupFolder.strings b/lproj/nl.lproj/GroupFolder.strings old mode 100755 new mode 100644 diff --git a/lproj/nl.lproj/InfoPlist.strings b/lproj/nl.lproj/InfoPlist.strings deleted file mode 100644 index 8a60ee27f3..0000000000 --- a/lproj/nl.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ -NSHumanReadableCopyright = "Copyright 2004-2015 Medewerkers. Zie Help/Dankwoord voor een lijst van medewerkers."; diff --git a/lproj/nl.lproj/InfoWindow.strings b/lproj/nl.lproj/InfoWindow.strings old mode 100755 new mode 100644 diff --git a/lproj/nl.lproj/Localizable.strings b/lproj/nl.lproj/Localizable.strings index 51a5be7aca..7116203d1f 100644 --- a/lproj/nl.lproj/Localizable.strings +++ b/lproj/nl.lproj/Localizable.strings @@ -450,3 +450,9 @@ /*Added in 3.0.5 */ "Redirection attempt treated as temporary for safety concern" = "Redirection attempt treated as temporary for safety concern"; + +/*Added in 3.0.7 */ +"No articles in feed" = "No articles in feed"; + +/*Added in 3.1.2 */ +"Filter folders" = "Search for folders"; diff --git a/lproj/nl.lproj/RSSFeed.nib/designable.nib b/lproj/nl.lproj/RSSFeed.nib/designable.nib index f2ad360e56..e90ad398a6 100644 --- a/lproj/nl.lproj/RSSFeed.nib/designable.nib +++ b/lproj/nl.lproj/RSSFeed.nib/designable.nib @@ -1,1004 +1,216 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSMenu - NSMenuItem - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSUserDefaultsController - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - RSSFeed - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{165, 318}, {426, 294}} - 1886912512 - RSS-feed - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{208, 12}, {102, 32}} - - - YES - - 67108864 - 134217728 - Annuleer - - LucidaGrande - 13 - 1044 - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{310, 12}, {102, 32}} - - - 100 - YES - - 67108864 - 134217728 - Abonneer - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{20, 193}, {75, 17}} - - - YES - - 67108864 - 4194304 - Bron: - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 256 - {{99, 186}, {175, 26}} - - - YES - - -2080374720 - 1024 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - URL - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - 100 - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - 256 - {{20, 260}, {389, 17}} - - - YES - - 67108864 - 4194304 - Neem een nieuw abonnement - - LucidaGrande-Bold - 13 - 2072 - - - - - - NO - - - - 256 - {{20, 218}, {378, 34}} - - - YES - - 67108864 - 4194304 - Geef hieronder de koppeling voor het abonnement op, of kies een door de uitgever aangegeven koppeling op uit het menu hieronder. - - LucidaGrande - 10 - 2843 - - - - - - NO - - - - 256 - {{23, 87}, {386, 62}} - - - YES - - -1805647871 - 4325376 - - - LucidaGrande - 11 - 3100 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 256 - {{283, 186}, {21, 24}} - - - YES - - 67108864 - 134217728 - - - - -2038284288 - 33 - - - - - - 200 - 25 - - NO - - - - 256 - {{20, 157}, {270, 17}} - - - YES - - 67108864 - 4194304 - URL: - - - - - - NO - - - - 268 - {{21, 49}, {185, 18}} - - - YES - - -2080374784 - 0 - Abonneer in Open Reader - - - 1211912448 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - NO - - - {426, 294} - - - - {{0, 0}, {1280, 778}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - 3 - 2 - {{305, 336}, {423, 167}} - 1886912512 - RSS-feed - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{307, 12}, {102, 32}} - - 100 - YES - - 67108864 - 134217728 - Bewaar - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{205, 12}, {102, 32}} - - - YES - - 67108864 - 134217728 - Annuleer - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{20, 60}, {383, 62}} - - - YES - - -1805647871 - 4325376 - - - - YES - - - - NO - - - - 256 - {{17, 130}, {389, 17}} - - - YES - - 67108864 - 4194304 - Bewerk abonnement - - - - - - NO - - - {{1, 9}, {423, 167}} - - - {{0, 0}, {1280, 778}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - YES - - - - - - - window - - - - 14 - - - - doSubscribe: - - - - 37 - - - - feedSource - - - - 46 - - - - subscribeButton - - - - 48 - - - - doSave: - - - - 57 - - - - editRSSFeedWindow - - - - 61 - - - - newRSSFeedWindow - - - - 62 - - - - editFeedURL - - - - 69 - - - - saveButton - - - - 70 - - - - editCancelButton - - - - 74 - - - - subscribeCancelButton - - - - 76 - - - - doEditCancel: - - - - 77 - - - - doSubscribeCancel: - - - - 78 - - - - doLinkSourceChanged: - - - - 89 - - - - feedURL - - - - 91 - - - - doShowSiteHomePage: - - - - 93 - - - - siteHomePageButton - - - - 94 - - - - linkTitle - - - - 99 - - - - doGoogleOption: - - - - 118 - - - - googleOptionButton - - - - 119 - - - - value: googleOptionButton - - - - - - value: googleOptionButton - value - googleOptionButton - 2 - - - 117 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - NewRSSFeed - - - 5 - - - - - - - - - - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 40 - - - - - - - - 43 - - - - - - - - 64 - - - - - - - - 65 - - - - - - - - 90 - - - - - - - - 92 - - - - - - - - 97 - - - - - - - - 49 - - - - - - EditRSSFeed - - - 50 - - - - - - - - - - - 53 - - - - - - - - 54 - - - - - - - - 55 - - - - - - - - 67 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - 107 - - - - - 108 - - - - - 109 - - - - - 110 - - - - - 111 - - - - - 112 - - - - - 113 - - - - - 114 - - - - - 44 - - - - - - - - 45 - - - - - -3 - - - Application - - - 115 - - - - - - - - 116 - - - - - 120 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{1012, 565}, {429, 297}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 122 - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - {15, 15} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Geef hieronder de koppeling voor het abonnement op, of kies een door de uitgever aangegeven koppeling op uit het menu hieronder. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/nl.lproj/RSSFeed.nib/keyedobjects.nib b/lproj/nl.lproj/RSSFeed.nib/keyedobjects.nib index da30cf1fc3..23c357a7ab 100644 Binary files a/lproj/nl.lproj/RSSFeed.nib/keyedobjects.nib and b/lproj/nl.lproj/RSSFeed.nib/keyedobjects.nib differ diff --git a/lproj/nl.lproj/RSSFeed.strings b/lproj/nl.lproj/RSSFeed.strings old mode 100755 new mode 100644 diff --git a/lproj/nl.lproj/SearchFolder.nib/designable.nib b/lproj/nl.lproj/SearchFolder.nib/designable.nib index 7839bdc675..fe9679c94b 100644 --- a/lproj/nl.lproj/SearchFolder.nib/designable.nib +++ b/lproj/nl.lproj/SearchFolder.nib/designable.nib @@ -1,1585 +1,265 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSBox - NSButton - NSButtonCell - NSCustomObject - NSCustomView - NSMenu - NSMenuItem - NSNumberFormatter - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - SmartFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{319, 601}, {647, 186}} - 1886912512 - - NSPanel - - View - - - {213, 107} - - - 256 - - - - 268 - {{19, 150}, {162, 17}} - - - YES - - 67108864 - 4194304 - Naam voor slimme map: - - LucidaGrande - 13 - 1044 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 268 - {{184, 148}, {178, 22}} - - - YES - - -1804599231 - 4195328 - - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{548, 12}, {85, 32}} - - - YES - - 67108864 - 134217728 - Bewaar - - - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{451, 12}, {97, 32}} - - - YES - - 67108864 - 134217728 - Annuleer - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 274 - - - - 274 - - - - 274 - {{12, 6}, {584, 38}} - - - - NSView - - NSResponder - - - {{2, 2}, {609, 50}} - - - - - {{17, 56}, {613, 54}} - - - {0, 0} - - 67108864 - 0 - - - LucidaGrande - 11 - 3100 - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 3 - 0 - 0 - NO - - - - 268 - {{17, 116}, {230, 18}} - - - YES - - 67108864 - 4194304 - VG9vbiBkZSBhcnRpa2VsZW4gZGllIHZvbGRvZW4gYWFuOgo - - - - - - NO - - - - 268 - {{241, 112}, {123, 26}} - - - YES - - -2080374720 - 2048 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - Niets - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - 268 - {{366, 117}, {257, 17}} - - - YES - - 67108864 - 272629760 - van de volgende voorwaarden: - - - - - - NO - - - {647, 186} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - 256 - - - - 256 - {135, 26} - - YES - - -2080374720 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Veldnamen komen hier - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - 3 - YES - YES - 1 - - NO - - - - 256 - {{513, -3}, {32, 31}} - - YES - - 67108864 - 134479872 - - - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{302, 3}, {183, 22}} - - YES - - -1804599231 - 4195328 - - - - YES - - - - NO - - - - 256 - {{541, -3}, {32, 31}} - - YES - - 67108864 - 134479872 - + - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{151, 0}, {135, 26}} - - YES - - -2080374720 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Operators go here - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{299, 0}, {100, 26}} - - YES - - -2080374720 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Niets - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{302, 4}, {126, 22}} - - YES - - -1804599231 - 4195328 - - - - - - - - - NaN - - - - 0 - - - . - - , - - - - - 0 - 2 - NO - YES - 1 - P0IPAAAAAAAAAAAAAAAAAA - - - 0 - 1 - NO - YES - 1 - AQAAAAAAAAAAAAAAAAAAAA - - -0 - 0 - - - 0 - -0 - - - - - - - - - . - , - NO - NO - YES - - - YES - - - - NO - - - - -2147483392 - {{299, 0}, {189, 26}} - - 1008 - YES - - -2080374720 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Item2 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - Item3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{299, 0}, {189, 26}} - - 1004 - YES - - -2080374720 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Item1 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - Item2 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - Item3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - 3 - YES - YES - 1 - - NO - - - {572, 28} - - NSView - - NSResponder - - - - - - - cancelButton - - - - 40 - - - - saveButton - - - - 41 - - - - searchCriteriaView - - - - 43 - - - - removeCriteriaButton - - - - 44 - - - - addCriteriaButton - - - - 45 - - - - fieldNamePopup - - - - 46 - - - - operatorPopup - - - - 47 - - - - valueField - - - - 49 - - - - window - - - - 50 - - - - addNewCriteria: - - - - 51 - - - - doCancel: - - - - 52 - - - - doSave: - - - - 53 - - - - searchWindow - - - - 54 - - - - removeCurrentCriteria: - - - - 57 - - - - fieldChanged: - - - - 59 - - - - flagValueField - - - - 65 - - - - numberValueField - - - - 70 - - - - folderValueField - - - - 78 - - - - criteriaConditionPopup - - - - 85 - - - - dateValueField - - - - 91 - - - - smartFolderName - - - - 92 - - - - searchCriteriaSuperview - - - - 42 - - - - nextKeyView - - - - 72 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - Search Folder - - - 5 - - - - - - - - - - - - - - - 7 - - - - - - - - 8 - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 37 - - - - - - - - 58 - - - - - - - - 79 - - - - - - - - 84 - - - - - - - - 26 - - - - - - - - - - - - - - SearchCriteriaView - - - 27 - - - - - - - - 29 - - - - - - - - 30 - - - - - - - - 31 - - - - - - - - 35 - - - - - - - - 61 - - - - - - - - 69 - - - - - - - - 73 - - - - - - - - 86 - - - - - - - - 94 - - - - - 95 - - - - - 96 - - - - - 97 - - - - - 98 - - - - - 99 - - - - - - - - 100 - - - - - 101 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - - - - 107 - - - - - - - - 108 - - - - - - - - 109 - - - - - - - - 71 - - - - - 80 - - - - - - - - 82 - - - - - 32 - - - - - - - - 33 - - - - - 34 - - - - - - - - 56 - - - - - 64 - - - - - - - - 62 - - - - - 74 - - - - - - - - - 76 - - - - - 75 - - - - - 87 - - - - - - - - - - 90 - - - - - 89 - - - - - 88 - - - - - -3 - - - Application - - - 36 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 109 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - SmartFolder - NSWindowController - - id - id - id - id - id - - - - addNewCriteria: - id - - - doCancel: - id - - - doSave: - id - - - fieldChanged: - id - - - removeCurrentCriteria: - id - - - - NSButton - NSButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSTextField - NSPopUpButton - NSButton - NSButton - NSView - NSView - NSWindow - NSTextField - NSTextField - - - - addCriteriaButton - NSButton - - - cancelButton - NSButton - - - criteriaConditionPopup - NSPopUpButton - - - dateValueField - NSPopUpButton - - - fieldNamePopup - NSPopUpButton - - - flagValueField - NSPopUpButton - - - folderValueField - NSPopUpButton - - - numberValueField - NSTextField - - - operatorPopup - NSPopUpButton - - - removeCriteriaButton - NSButton - - - saveButton - NSButton - - - searchCriteriaSuperview - NSView - - - searchCriteriaView - NSView - - - searchWindow - NSWindow - - - smartFolderName - NSTextField - - - valueField - NSTextField - - - - IBProjectSource - ./Classes/SmartFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Toon de artikelen die voldoen aan: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/nl.lproj/SearchFolder.nib/keyedobjects.nib b/lproj/nl.lproj/SearchFolder.nib/keyedobjects.nib index 08d2410480..498c6b171e 100644 Binary files a/lproj/nl.lproj/SearchFolder.nib/keyedobjects.nib and b/lproj/nl.lproj/SearchFolder.nib/keyedobjects.nib differ diff --git a/lproj/nl.lproj/SearchFolder.strings b/lproj/nl.lproj/SearchFolder.strings old mode 100755 new mode 100644 diff --git a/lproj/nl.lproj/Vienna Help/advanced.html b/lproj/nl.lproj/Vienna Help/advanced.html deleted file mode 100644 index de2cc77692..0000000000 --- a/lproj/nl.lproj/Vienna Help/advanced.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - Geavanceerde voorkeuren - - - - -  Geavanceerde - voorkeuren -

De "Geavanceerd" sectie van de Voorkeuren geeft de - mogelijkheid om specifieke opties van Vienna te wijzigen die niet - essentieel zijn voor het normale gebruik, maar bepaalde problemen - kan oplossen zoals geadviseerd door het support forum. Deze - pagina geeft uitleg over die mogelijkheden.

-

Activeer JavaScript in interne browser

-

Schakelt ondersteuning voor JavaScript scripts in de interne - browser van Vienna aan of uit. Standaard is dit ingeschakeld. - Door dit uit te schakelen kan JavaScript code op webpagina's niet - uitgevoerd worden. Dit kan problemen oplossen zoals pop-up - vensters of ander ongewenst c.q. onverwacht gedrag. Echter dit - kan er ook toe leiden dat webpagina's niet volledig laden of niet - werken, danwel onvolledig werken.

- - diff --git a/lproj/nl.lproj/Vienna Help/faq.html b/lproj/nl.lproj/Vienna Help/faq.html deleted file mode 100644 index c48a76f657..0000000000 --- a/lproj/nl.lproj/Vienna Help/faq.html +++ /dev/null @@ -1,215 +0,0 @@ - - - - - - How Do I? - - - - -  Hoe kan ik? -

Hier zijn een aantal vragen die naar voren kwamen tijdens de - ontwikkeling van Vienna in de test-fase. Kijk hiervoor op - Official Vienna - FAQ Page en de laatste hints en tips voor Vienna.

- -

Waar kan ik de Vienna - broncode vinden?

-

Kijk op de Development pagina - voor instructies om de broncode van Vienna te krijgen. De - broncode is vrij beschikbaar om in te kijken als u geïnteresseerd - bent hoe Vienna werkt, als u zelf een kopie van Vienna wilt - compileren of om in een ander project delen ervan te gebruiken. - De broncode wordt aangeboden onder de Apache 2.0 - license.

-

Ik heb een - probleem gevonden in Vienna. Hoe kan ik dit melden?

-

Plaats een bericht in het Support - forum of in de issues list - (beide Engels-talig) en iemand zal het onderzoeken. Geef - zoveel informatie over het probleem als u kan, inclusief: de - 'build' van Vienna (te vinden in het Vienna → Over Vienna - venster), hoe de fout te reproduceren en wat u verwachte dat er - zou gebeuren. Er is een sticky note in het forum met tips hoe u - een goed bug rapport schrijft.

-

Zorg ervoor dat u altijd de laatste versie van Vienna - gebruikt. Het Vienna → Zoek naar updates menu zal - rapporteren of er een nieuwere versie is dan degene die u - gebruikt.

-

Hoe creëer ik mijn eigen - stijlen?

-

Kijk op de Custom Styles page - voor instructies.

-

Hoe kan ik mijn eigen scripts - maken?

-

Vienna's scripts zijn geschreven in AppleScript. Kijk op - Apple resource - page voor meer informatie.

-

Om te beginnen kan u een bestaand script downladen zoals - Cortig's - original Share with Papers plugin of reefdog's - Vienna to Yojimbo script en dit bekijken in AppleScript - editor.

-

Heeft u een script dat u wilt aanmelden, stuur dit naar - steve@opencommunity.co.uk - en nadat het is bekeken, zal het beschikbaar komen op de - Downloads pagina.

-

- Hoe kan ik zien wat er gebeurt als mijn abonnementen worden - bijgewerkt?

-

Selecteer Venster → Activiteitenoverzicht. Het venster - toont alle abonnementen en hun status van de laatste bijwerking. - Onderin staan gedetailleerde gegevens en deze kunnen bruikbaar - zijn voor het oplossen van problemen. (Als de details niet - zichtbaar zijn, pak dan de splitter onder in het venster en sleep - deze omhoog om dit paneel te tonen).

-

Hoe kan - ik mijn Vienna database verplaatsen naar een andere map?

-

De Vienna database heet messages.db en is normaliter te vinden - in ~/Library/Application Support/Vienna. U kan deze op een - andere plaats bewaren. Volg deze stappen:

-
    -
  1. Stop Vienna.
  2. -
  3. Open een Terminal venster en typ:
    -
    - defaults write - uk.co.opencommunity.vienna2 "DefaultDatabase" '<pad naar - nieuwe messages.db>'
    -
    - waar <pad naar nieuwe messages.db> de padnaam naar de map - is die de messages.db gaat bevatten. De padnaam moet de - messages.db bestandsnaam aan het einde bevatten. - Bijvoorbeeld:
    -
    - defaults write - uk.co.opencommunity.vienna2 "DefaultDatabase" - '/Users/steve/mydata/messages.db'
  4. -
  5. Start Vienna.
  6. -
-

- Een van mijn abonnementen meldt "Error parsing XML data in feed". - Wat betekent dit?

-

Dit betekent dat Vienna van een feed uit de abonnementen data - kreeg waar het niet mee uit de voeten kan. Hier kunnen meerdere - redenen voor zijn:

-
    -
  1. De URL van de feed wijst niet naar een RSS of Atom feed - maar naar een webpagina. Controleer de URL van de betreffende - feed zorgvuldig.
  2. -
  3. De feed zelf kan non valide XML bevatten. Kies Map → - Toon info… en vervolgens Valideer om te zien of dit het - geval is. Helaas kunt u in Vienna niets doen om dit op te - lossen, behalve wachten tot de site de feed corrigeert.
  4. -
  5. De feed kan incompleet zijn. Als het bijwerken werd - onderbroken dan kan de XML data incompleet zijn en verminkt - lijken voor Vienna. Een tweede keer bijwerken kan dit probleem - oplossen.
  6. -
-

Als het bovenstaande uw probleem niet verklaart, plaats dan - een bericht op het support forum met de problematische feed - URL.

-

- Is er een toetscombinatie om naar het volgende artikel te gaan, - artikelen te markeren, etc?

-

Waarschijnlijk. Er zijn enkeltoets equivalenten voor sommige - menu commando's zoals:

-

Spatiebalk - ga naar het volgende ongelezen artikel. - Als het huidige artikel enkele pagina's lang is, dan wordt er - eerst door dat artikel geschoven. Aan het einde van het artikel - zal dan naar het volgende ongelezen artikel gegaan worden. Dit in - tegenstelling tot het Volgende ongelezen menu - (toetscombinatie ⌘U) dat altijd direct naar het volgende - ongelezen artikel gaat.

-

R - markeert het huidige artikel als gelezen als het - ongelezen is en vice versa.

-

F - markeert het huidige artikel met een vlag als het - die nog niet heeft, of verwijderd deze als die wel aanwezig - is.

-

Kijk in het Vienna help bestand voor meer - toetscombinaties.

-

Welke - betekenis hebben de groene bolletjes in de artikel - lijst?

-

Blauwe bolletjes zijn voor nieuwe artikelen, en de groene voor - bijgewerkte artikelen: artikelen waarvan de tekst gewijzigd is - sinds ze voor het laatst zijn gedownload.

-

Hoe gebruik ik - Auto Expiratie en wat doet het?

-

Auto-expiratie verplaatst artikelen die ouder zijn dan x dagen - naar de prullenmand. Hierdoor kunt u uw mappen handelbaar houden - door alleen recente artikelen te bewaren. Dit is actief bij het - starten van Vienna en na het bijwerken van abonnementen. Ga naar - Voorkeuren → Algemeen en pas daar de Verplaats - artikelen naar prullenmand optie aan.

-

Auto-expire verwijderd GEEN ongelezen of gemarkeerde - artikelen. Het gaat ervan uit dat u die nog niet gelezen heeft en - laat ze daarom met rust.

-

Hoe vraag ik om een - verbetering aan Vienna?

-

Plaats een bericht in de issues - list.

- - diff --git a/lproj/nl.lproj/Vienna Help/helpstyle.css b/lproj/nl.lproj/Vienna Help/helpstyle.css deleted file mode 100644 index d02689f72e..0000000000 --- a/lproj/nl.lproj/Vienna Help/helpstyle.css +++ /dev/null @@ -1,39 +0,0 @@ -a { - color: #3366CC; - text-decoration: none; -} -.title { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 18pt; - color: #000000; -} -.header { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 12pt; - color: #000000; -} -li { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 100; - font-size: 9pt; - color: #000000; -} -h2 { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 400; - font-size: 10pt; - color: #000000; -} -p { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 100; - font-size: 9pt; - color: #000000; -} -tr { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-size: 9pt; - color: #000000; -} \ No newline at end of file diff --git a/lproj/nl.lproj/Vienna Help/images/Small-Vienna-Logo.jpg b/lproj/nl.lproj/Vienna Help/images/Small-Vienna-Logo.jpg deleted file mode 100644 index 41035b4f11..0000000000 Binary files a/lproj/nl.lproj/Vienna Help/images/Small-Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/nl.lproj/Vienna Help/images/Vertical-Line.jpg b/lproj/nl.lproj/Vienna Help/images/Vertical-Line.jpg deleted file mode 100644 index 011f1ce1e3..0000000000 Binary files a/lproj/nl.lproj/Vienna Help/images/Vertical-Line.jpg and /dev/null differ diff --git a/lproj/nl.lproj/Vienna Help/images/Vienna-Logo.jpg b/lproj/nl.lproj/Vienna Help/images/Vienna-Logo.jpg deleted file mode 100644 index 13a6479bd4..0000000000 Binary files a/lproj/nl.lproj/Vienna Help/images/Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/nl.lproj/Vienna Help/images/rssfeed.gif b/lproj/nl.lproj/Vienna Help/images/rssfeed.gif deleted file mode 100644 index 2dc8935119..0000000000 Binary files a/lproj/nl.lproj/Vienna Help/images/rssfeed.gif and /dev/null differ diff --git a/lproj/nl.lproj/Vienna Help/index.html b/lproj/nl.lproj/Vienna Help/index.html deleted file mode 100644 index 4e70d27ec1..0000000000 --- a/lproj/nl.lproj/Vienna Help/index.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - Vienna Help - - - - - - - - - - -
-

-

Vienna Help

-
-

Inleiding voor Vienna

-

De eerste stappen met - Vienna.

-

Toetscombinaties

-

Ontdek toetscombinaties voor - veelgebruikte commando's

-

Hoe kan ik?

-

Veelgestelde vragen, ondersteuning - verkrijgen en problemen oplossen.

-
- - diff --git a/lproj/nl.lproj/Vienna Help/intro.html b/lproj/nl.lproj/Vienna Help/intro.html deleted file mode 100644 index 0f33129a28..0000000000 --- a/lproj/nl.lproj/Vienna Help/intro.html +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - Introduction to Vienna - - - - -   Inleiding -

Vienna is een programma waarmee u RSS en Atom feeds kunt lezen - op uw Mac OS X computer. Het automatiseert het ophalen van nieuwe - artikelen van uw abonnementen en bewaart deze in een lokale - database zodat u hen ook offline kan lezen. U kunt artikelen - doorzoeken op sleutelwoorden, markeren voor later en feeds - organiseren in mappen. U kunt slimme mappen aanmaken die het - eenvoudig maken om automatisch artikelen bij elkaar te groeperen - gebaseerd op zoekcriteria. De ingebouwde webbrowser geeft u de - mogelijkheid om de webpagina's van de artikelen te bekijken of om - links te volgen in aparte tabbladen.

-

Vienna is ontworpen met als doel eenvoud. Veel ruimte voor uw - nieuws en een simpele bediening.

Beginnen met Vienna -

Als dit de eerste keer is dat u Vienna gebruikt dan wordt er - een database gecreëerd en een aantal standaard abonnmementen - toegevoegd. Kies Archief → Werk alle abonnementen bij uit - het menu of ⌘R om de meest recente artikelen op te - halen.

-

Abonneer u op uw eigen feeds. Er zijn diverse manieren om - feeds te vinden. Tijdens het web browsen ziet u of XML iconen die aangeven dat de - webpagina een RSS-feed heeft. Bijna alle online blog diensten - zoals Blogger of LiveJournal hebben RSS feeds.

-

Indien u de gebruikersnaam van een blogger op LiveJournal, - Blogger, MSN Spaces of Xanga kent, dan maakt Vienna het eenvoudig - om een abonnement te nemen op hun feed. Begin door ⌘N in - te toetsen of door Archief → Nieuw abonnement... te - kiezen. In het Neem een nieuw abonnement venster, kies de - blog dienst uit de Bron lijst en voer de gebruikersnaam - in. Kies dan Abonneer en Vienna voegt het abonnement toe - aan de lijst. Als u verbonden bent met het internet worden direct - de artikelen van de feed binnen gehaald.

-

U kan Vienna ook gebruiken in combinatie met een Open Reader - account. Kies Vienna → Voorkeuren → Synchroniseren en vink - Synchroniseer met Open Reader aan.
- Bedenk vooraf welke feeds u via Open Reader wil lezen en welke u - direct wil benaderen. Vienna voorkomt duplicaten tussen de twee, - maar als u feeds in Open Reader heeft die Vienna al direct - ophaalt dan onstaan er onderlinge afwijkingen in uw lees lijsten. - Houd hier rekening mee bij het organiseren van uw feeds.
- Houd de volgende dingen in de gaten:

-
    -
  • Open Reader feeds kunnen synchroniseren tussen meerdere - programma's en apparaten die dit ondersteunen
  • -
  • Open Reader ondersteunt geen feeds die een gebruikersnaam - en wachtwoord vereisen
  • -
  • Feeds direct ophalen vermijdt Google als tussenpersoon. - Voor minder 'populaire' feeds krijgt u sneller artikelen - binnen.
  • -
  • In het algemeen geldt dat feeds direct ophalen van de - originele website minder netwerkverkeer oplevert. Als de server - geen nieuwe artikelen heeft sinds de laatste bijwerking, dan - voorkomt Vienna een nodeloze download.
  • -
-

Normaal moet u in Vienna handmatig uw abonnementen bijwerken. - U kan dit ook automatisch laten doen met een tijd-interval. In de - Algemeen sectie van de Voorkeuren selecteert u de - gewenste interval uit de lijst Zoek naar nieuwe artikelen. - Vienna moet actief zijn om automatisch de abonnementen bij te - werken.

-

Tijdens het lezen drukt u de spatiebalk in om naar een volgend - ongelezen artikel te gaan. Ieder artikel wordt als gelezen - gemarkeerd na een korte vertraging. Als u liever heeft dat dit - gebeurt als u naar het volgende artikel gaat, dan kan u dit - aanpassen in Voorkeuren → Algemeen. Om een artikel als - ongelezen te markeren kies Artikel → Markeer als ongelezen - of druk eenvoudigweg de R toets in.

-

Tenslotte, u kunt de webpagina van een artikel of een - koppeling uit het artikel bekijken in Vienna. Op een koppeling - klikken opent de webpagina in de interne browser in een nieuwe - tab. Als u de voorkeur heeft om alle webpagina's in uw standaard - webbrowser te bekijken selecteer dan in Voorkeuren → - Algemeen de optie Open koppeling in externe browser. - Als u rechts-klikt in een artikel of webpagina dan kunt u die - bekijken in uw standaard ingestelde externe browser, u ziet dan - in het contextuele menu de optie Open koppeling in xxx of - Open pagina in xxx waar xxx vervangen wordt door de naam - van uw standaard browser.

-

Ontdek nog meer mogelijkheden van Vienna. U kunt de stilering - van de artikelen veranderen door Weergave → Stijl te - kiezen. Veel meer stijlen zijn te vinden op de Downloads pagina van - de Vienna website samen met scripts waarmee u Vienna kan - integreren met andere programma's op uw computer. Of - experimenteer met slimme mappen om uw artikelen te organiseren - volgens de door u opgegeven criteria omtrent de inhoud van die - artikelen.

-

Indien u vragen heeft over Vienna of problemen ondervind, - stuur dan een email naar Vienna Help of - ga naar het Support - forum.

- - diff --git a/lproj/nl.lproj/Vienna Help/keyboard.html b/lproj/nl.lproj/Vienna Help/keyboard.html deleted file mode 100644 index f389007e4c..0000000000 --- a/lproj/nl.lproj/Vienna Help/keyboard.html +++ /dev/null @@ -1,351 +0,0 @@ - - - - - - Keyboard Shortcuts - - - - -  Toetscombinaties -

U kunt met uw toetsenbord snel veel taken uitvoeren in Vienna. - U vindt de combinaties door in de menus te kijken en in de - onderstaande lijst. Vele items in Vienna hebben ook een - contextueel menu. Om een contextueel menu te openen klikt u op - een item terwijl u de Control toets ingedrukt houd.

-

Om een commando uit te voeren, druk de onderstaande toetsen - in.

-

Toets legenda

-

⌦ = Delete, ⌫ = Backspace, - ⌅ = Enter, ↩ = Return, ⌥ = Alt, - ⇧ = Shift, ⌘ = Command, - ⌃ = Control

- - - - - -
Toets(en)Actie
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Enkelvoudige toetsen 
bGa naar het eerste ongelezen artikel.
fActiveer het zoek venster.
hPlaats de cursor in het 'Zoek in artikelen' veld.
kMarkeer de huidige map als gelezen.
mSchakel de geselecteerde artikelen tussen ⚑ markering aan - of uit.
nGa naar het volgende ongelezen artikel.
rSchakel de geselecteerde artikelen tussen gelezen en - ongelezen.
uSchakel de geselecteerde artikelen tussen gelezen en - ongelezen.
sMarkeer de huidige map als gelezen en springt naar de - volgende map met ongelezen artikelen.
<  of  ,Toon het vorige bekeken artikel of webpagina.
>  of  .Toon het volgende bekeken artikel of webpagina.
SpatiebalkGa naar het volgende ongelezen artikel, tenzij er meer - tekst in het huidige artikel is dan schuift de volgende - pagina in beeld.
⌅  of  ↩Open de webpagina van het geselecteerde artikel.
⌦  of  ⌫Verplaats geselecteerde artikelen naar de prullenmand. - Als deze toets wordt gebruikt in de prullenmand, dan worden - de artikelen definitief verwijderd.
Algemeen 
⌥KlikOpen de geklikte koppeling, en negeer de - voorkeurinstelling voor openen in externe browser.
⇧⌘BOpen de filterbalk.
⌘NMaak een nieuw abonnement aan.
⇧⌘FMaak een slimme map.
⇧⌘EBewerk de URL voor de geselecteerde map of bewerk slimme - map criteria.
⇧⌘DVerwijder de geselecteerde map.
⌘CKopieer de geselecteerde tekst naar het klembord. Als de - focus op een artikel ligt, dan worden de artikel details - gekopieerd.
⌘HVerberg het Vienna venster.
⌥⌘HVerberg alle vensters, behalve die van Vienna.
⌘IToon het Info venster voor de geselecteerde map.
⌘LPlaats de cursor in de adresbalk van de huidige tab. - Indien er geen browser geopend is, dan wordt er een nieuwe - tab geopend en de cursor in de adresbalk geplaatst.
⇧⌘NWijzig de naam van de geselecteerde map.
⌘RWerk alle abonnementen bij.
⇧⌘RWerk alleen de geselecteerde abonnementen bij.
⌃⌘SStop bijwerken abonnementen.
⌘PDruk geselecteerde artikelen af.
⇧⌘PToon het Pagina-instelling venster.
⌘QStop Vienna.
⌘TOpen een nieuwe tab en plaats de cursor in de - adresbalk.
⌘UGa naar het volgende ongelezen artikel.
⌘ZHerstel de laatste actie indien mogelijk.
⌘/Toon/verberg de status balk.
⌘+Maak de tekst groter in huidige artikel of - webpagina.
⌘-Maak de tekst kleiner in huidige artikel of - webpagina.
⌘,Open het Voorkeuren venster.
⌥⌘⌫Leeg de prullenmand en vraag om bevestiging.
⌘?Toon het Vienna Help bestand, (Mac OS X 10.5 en later, - activeer de zoek functie in het Help bestand).
Artikelen 
⌥⌅  of  ⌥↩Open de webpagina van het artikel en negeer de - voorkeurinstelling voor openen in externe browser.
⇧⌘ZDoe de laatse actie opnieuw als die was hersteld.
⇧⌘MMarkeer de geselecteerde artikelen met een ⚑ en plaatst - het in de map Gemarkeerde artikelen.
⇧⌘UMarkeer geselecteerde artikel als gelezen.
⌥⌘SStuur een email met een koppeling naar het huidige - artikel.
⇧⌘SMarkeer de huidige map als gelezen en ga naar de volgende - map met ongelezen artikelen.
⇧⌘OHaal artikel uit prullenmand en zet terug in originele - map.
⇧⌘KMarkeer alle artikelen in geselecteerde map als - gelezen.
⌥⌘KMarkeer alle artikelen in alle mappen als gelezen.
Vensters 
⌘WSluit de actieve tab als er een open is. Indien dat niet - het geval is, dan sluit het Vienna venster.
⌥⌘WSluit alle tab vensters. Opmerking: Dit commando vervangt - de Sluit tab in het Archief menu als de alt (⌥) - toets is ingedrukt.
⇧⌘WSluit het Vienna venster maar laat Vienna in de - achtergrond werken. U kan het venster weer openen door op het - Vienna icoon in de Dock te klikken of door ⌘1 in te - toetsen.
⌥⌘←Toon het vorige tab venster.
⌥⌘→Toon het volgende tab venster.
⌘MMinimaliseer het Vienna venster naar de Dock.
⌘0Toon het Activiteitenoverzicht log venster.
⌘1Open het Vienna venster indien het was gesloten.
⌘2Toon het Downloads venster.
Browser venster 
⌥RVervers de huidige webpagina.
⌘.Annuleer het laden van de huidige webpagina.
⌘[  of  ⌘←Ga naar de vorige webpagina.
⌘]  of  ⌘→Ga naar de volgende webpagina.
⌘FActiveer het zoek veld in de knoppenbalk. Voer hier tekst - in en druk op Enter en er wordt gezocht in de huidige - webpagina.
⌘GKijk of de zoekterm voorkomt verderop in de - webpagina.
- - diff --git a/lproj/pt.lproj/GroupFolder.nib/designable.nib b/lproj/pt.lproj/GroupFolder.nib/designable.nib index 14c425c7bd..c9800f8944 100644 --- a/lproj/pt.lproj/GroupFolder.nib/designable.nib +++ b/lproj/pt.lproj/GroupFolder.nib/designable.nib @@ -1,500 +1,91 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - NewGroupFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{502, 622}, {388, 149}} - 1886912512 - Painel - - NSPanel - - - View - - - {213, 107} - - - 256 - - - - 260 - {{17, 112}, {354, 17}} - - - YES - - 67108864 - 4194304 - Nova pasta de grupo - - LucidaGrande-Bold - 13 - 2072 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 258 - {{20, 60}, {348, 22}} - - - YES - - -1804599231 - 272630784 - - - LucidaGrande - 13 - 1044 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{285, 12}, {89, 32}} - - - 100 - YES - - 67108864 - 134217728 - Guardar - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{203, 12}, {82, 32}} - - - YES - - 67108864 - 134217728 - Cancelar - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 268 - {{17, 90}, {353, 14}} - - - YES - - 67108864 - 4194304 - SW50cm9kdXphIG8gbm9tZSBkYSBub3ZhIHBhc3RhIGRlIGdydXBvOgo - - LucidaGrande - 11 - 3100 - - - - - - NO - - - {388, 149} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - - - - newGroupFolderWindow - - - - 18 - - - - doCancel: - - - - 25 - - - - doSave: - - - - 26 - - - - folderName - - - - 27 - - - - cancelButton - - - - 28 - - - - saveButton - - - - 29 - - - - window - - - - 30 - - - - nextKeyView - - - - 24 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 5 - - - - - - GroupFolder - - - 6 - - - - - - - - - - - - 19 - - - - - - - - 20 - - - - - - - - 21 - - - - - - - - 22 - - - - - - - - 23 - - - - - - - - 32 - - - - - 33 - - - - - 34 - - - - - 35 - - - - - 36 - - - - - -3 - - - Application - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 36 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - NewGroupFolder - NSWindowController - - id - id - - - - doCancel: - id - - - doSave: - id - - - - NSButton - NSTextField - NSWindow - NSButton - - - - cancelButton - NSButton - - - folderName - NSTextField - - - newGroupFolderWindow - NSWindow - - - saveButton - NSButton - - - - IBProjectSource - ./Classes/NewGroupFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Introduza o nome da nova pasta de grupo: + + + + + + + + + + diff --git a/lproj/pt.lproj/GroupFolder.nib/keyedobjects.nib b/lproj/pt.lproj/GroupFolder.nib/keyedobjects.nib index 8d8729e210..1a6bb4cc3c 100644 Binary files a/lproj/pt.lproj/GroupFolder.nib/keyedobjects.nib and b/lproj/pt.lproj/GroupFolder.nib/keyedobjects.nib differ diff --git a/lproj/pt.lproj/InfoPlist.strings b/lproj/pt.lproj/InfoPlist.strings deleted file mode 100644 index d940c0e05c..0000000000 --- a/lproj/pt.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ -NSHumanReadableCopyright = "Copyright 2004-2015 Colaboradores. Ver Ajuda/Agradecimentos para a lista de colaboradores."; diff --git a/lproj/pt.lproj/Localizable.strings b/lproj/pt.lproj/Localizable.strings index 2e24685ef2..3751ea3481 100644 --- a/lproj/pt.lproj/Localizable.strings +++ b/lproj/pt.lproj/Localizable.strings @@ -450,3 +450,9 @@ /*Added in 3.0.5 */ "Redirection attempt treated as temporary for safety concern" = "Redirection attempt treated as temporary for safety concern"; + +/*Added in 3.0.7 */ +"No articles in feed" = "No articles in feed"; + +/*Added in 3.1.2 */ +"Filter folders" = "Search for folders"; diff --git a/lproj/pt.lproj/RSSFeed.nib/designable.nib b/lproj/pt.lproj/RSSFeed.nib/designable.nib index ff902d8acc..f0bb6dca19 100644 --- a/lproj/pt.lproj/RSSFeed.nib/designable.nib +++ b/lproj/pt.lproj/RSSFeed.nib/designable.nib @@ -1,1003 +1,220 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSMenu - NSMenuItem - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSUserDefaultsController - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - RSSFeed - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{165, 318}, {426, 304}} - 1886912512 - Fonte RSS - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{208, 18}, {102, 32}} - - - YES - - 67108864 - 134217728 - Cancelar - - LucidaGrande - 13 - 1044 - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{310, 18}, {102, 32}} - - - 100 - YES - - 67108864 - 134217728 - Subscrever - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{20, 203}, {75, 17}} - - - YES - - 67108864 - 4194304 - T3JpZ2VtOgo - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 256 - {{99, 196}, {175, 26}} - - - YES - - -2080374720 - 1024 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - URL - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - 100 - - - YES - - - OtherViews - - - - - - 3 - YES - YES - 1 - - NO - - - - 256 - {{20, 270}, {389, 17}} - - - YES - - 67108864 - 4194304 - Q3JpYXIgdW1hIG5vdmEgc3Vic2NyacOnw6NvCg - - LucidaGrande-Bold - 13 - 2072 - - - - - - NO - - - - 256 - {{20, 228}, {378, 34}} - - - YES - - 67108864 - 4194304 - Introduza o link para a nova fonte em baixo. Ou escolha na lista de Origens e intriduza um atalho para a fontes disponibilizadas pela origem. - - LucidaGrande - 10 - 2843 - - - - - - NO - - - - 256 - {{23, 97}, {386, 62}} - - - YES - - -1805647871 - 4325376 - - - LucidaGrande - 11 - 3100 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 256 - {{283, 196}, {21, 24}} - - - YES - - 67108864 - 134217728 - - - - -2038284288 - 33 - - - - - - 200 - 25 - - NO - - - - 256 - {{20, 167}, {270, 17}} - - - YES - - 67108864 - 4194304 - URL: - - - - - - NO - - - - 268 - {{21, 59}, {185, 18}} - - - YES - - -2080374784 - 0 - Subscribe in Open Reader - - - 1211912448 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - NO - - - {426, 304} - - - - {{0, 0}, {1280, 778}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - 3 - 2 - {{305, 336}, {423, 167}} - 1886912512 - Fonte RSS - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{307, 12}, {102, 32}} - - 100 - YES - - 67108864 - 134217728 - Guardar - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{205, 12}, {102, 32}} - - - YES - - 67108864 - 134217728 - Cancelar - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{20, 60}, {383, 62}} - - - YES - - -1805647871 - 4325376 - - - - YES - - - - NO - - - - 256 - {{17, 130}, {389, 17}} - - - YES - - 67108864 - 4194304 - Editar subscrição - - - - - - NO - - - {{1, 9}, {423, 167}} - - - {{0, 0}, {1280, 778}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - YES - - - - - - - window - - - - 14 - - - - doSubscribe: - - - - 37 - - - - feedSource - - - - 46 - - - - subscribeButton - - - - 48 - - - - doSave: - - - - 57 - - - - editRSSFeedWindow - - - - 61 - - - - newRSSFeedWindow - - - - 62 - - - - editFeedURL - - - - 69 - - - - saveButton - - - - 70 - - - - editCancelButton - - - - 74 - - - - subscribeCancelButton - - - - 76 - - - - doEditCancel: - - - - 77 - - - - doSubscribeCancel: - - - - 78 - - - - doLinkSourceChanged: - - - - 89 - - - - feedURL - - - - 91 - - - - doShowSiteHomePage: - - - - 93 - - - - siteHomePageButton - - - - 94 - - - - linkTitle - - - - 99 - - - - doGoogleOption: - - - - 118 - - - - googleOptionButton - - - - 119 - - - - value: googleOptionButton - - - - - - value: googleOptionButton - value - googleOptionButton - 2 - - - 117 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - NewRSSFeed - - - 5 - - - - - - - - - - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 40 - - - - - - - - 43 - - - - - - - - 64 - - - - - - - - 65 - - - - - - - - 90 - - - - - - - - 92 - - - - - - - - 97 - - - - - - - - 49 - - - - - - EditRSSFeed - - - 50 - - - - - - - - - - - 53 - - - - - - - - 54 - - - - - - - - 55 - - - - - - - - 67 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - 107 - - - - - 108 - - - - - 109 - - - - - 110 - - - - - 111 - - - - - 112 - - - - - 113 - - - - - 114 - - - - - 44 - - - - - - - - 45 - - - - - -3 - - - Application - - - 115 - - - - - - - - 116 - - - - - 120 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{1012, 565}, {429, 297}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 122 - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - {15, 15} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Origem: + + + + + + + + + + + + + + + + + + + + + + + + + + + Criar uma nova subscrição + + + + + + + + + + + Introduza o link para a nova fonte em baixo. Ou escolha na lista de Origens e intriduza um atalho para a fontes disponibilizadas pela origem. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/pt.lproj/RSSFeed.nib/keyedobjects.nib b/lproj/pt.lproj/RSSFeed.nib/keyedobjects.nib index 9811bfa38a..bc4060719d 100644 Binary files a/lproj/pt.lproj/RSSFeed.nib/keyedobjects.nib and b/lproj/pt.lproj/RSSFeed.nib/keyedobjects.nib differ diff --git a/lproj/pt.lproj/SearchFolder.nib/designable.nib b/lproj/pt.lproj/SearchFolder.nib/designable.nib index 03af88d581..8a4c54aada 100644 --- a/lproj/pt.lproj/SearchFolder.nib/designable.nib +++ b/lproj/pt.lproj/SearchFolder.nib/designable.nib @@ -1,1591 +1,265 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSBox - NSButton - NSButtonCell - NSCustomObject - NSCustomView - NSMenu - NSMenuItem - NSNumberFormatter - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - SmartFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{46, 594}, {647, 186}} - 1886912512 - - NSPanel - - View - - - {213, 107} - - - 256 - - - - 268 - {{17, 150}, {182, 17}} - - - YES - - 67108864 - 4194304 - Tm9tZSBkYSBwYXN0YSBpbnRlbGlnZW50ZToKA - - LucidaGrande - 13 - 1044 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 268 - {{199, 144}, {178, 22}} - - - YES - - -1804599231 - 4195328 - - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{555, 12}, {78, 32}} - - - YES - - 67108864 - 134217728 - Guardar - - - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{475, 12}, {82, 32}} - - - YES - - 67108864 - 134217728 - Cancelar - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 274 - - - - 274 - - - - 274 - {{12, 6}, {584, 38}} - - - - NSView - - NSResponder - - - {{2, 2}, {609, 50}} - - - - - {{17, 56}, {613, 54}} - - - {0, 0} - - 67108864 - 0 - - - LucidaGrande - 11 - 3100 - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 3 - 0 - 0 - NO - - - - 268 - {{17, 116}, {297, 17}} - - - YES - - 67108864 - 4194304 - Mostrar todos os artigos que combinam com - - - - - - NO - - - - 268 - {{308, 110}, {112, 26}} - - - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - Nenhuma - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - 268 - {{422, 116}, {176, 17}} - - - YES - - 67108864 - 272629760 - das seguintes condições: - - - - - - NO - - - {647, 186} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - 256 - - - - 256 - {{-3, 0}, {135, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Nome do campo aqui - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - 256 - {{513, -3}, {32, 31}} - - YES - - 67108864 - 134479872 - - - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{302, 3}, {183, 22}} - - YES - - -1804599231 - 4195328 - - - - YES - - - - NO - - - - 256 - {{541, -3}, {32, 31}} - - YES - - 67108864 - 134479872 - + - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{151, 0}, {135, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Operadores aqui - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{299, 0}, {100, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - - - 400 - 75 - - - Nenhuma - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{302, 4}, {126, 22}} - - YES - - -1804599231 - 4195328 - - - - - - - - - NaN - - - - 0 - - - . - - , - - - - - 0 - 2 - NO - YES - 1 - P0IPAAAAAAAAAAAAAAAAAA - - - 0 - 1 - NO - YES - 1 - AQAAAAAAAAAAAAAAAAAAAA - - -0 - 0 - - - 0 - -0 - - - - - - - - - . - , - NO - NO - YES - - - YES - - - - NO - - - - -2147483392 - {{299, 0}, {189, 26}} - - 1008 - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Item2 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - Item3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{299, 0}, {189, 26}} - - 1004 - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Item1 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - Item2 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - Item3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - -1 - 3 - YES - YES - 1 - - NO - - - {572, 28} - - NSView - - NSResponder - - - - - - - cancelButton - - - - 40 - - - - saveButton - - - - 41 - - - - searchCriteriaView - - - - 43 - - - - removeCriteriaButton - - - - 44 - - - - addCriteriaButton - - - - 45 - - - - fieldNamePopup - - - - 46 - - - - operatorPopup - - - - 47 - - - - valueField - - - - 49 - - - - window - - - - 50 - - - - addNewCriteria: - - - - 51 - - - - doCancel: - - - - 52 - - - - doSave: - - - - 53 - - - - searchWindow - - - - 54 - - - - removeCurrentCriteria: - - - - 57 - - - - fieldChanged: - - - - 59 - - - - flagValueField - - - - 65 - - - - numberValueField - - - - 70 - - - - folderValueField - - - - 78 - - - - criteriaConditionPopup - - - - 85 - - - - dateValueField - - - - 91 - - - - smartFolderName - - - - 92 - - - - searchCriteriaSuperview - - - - 42 - - - - nextKeyView - - - - 72 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - Search Folder - - - 5 - - - - - - - - - - - - - - - 7 - - - - - - - - 8 - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 37 - - - - - - - - 58 - - - - - - - - 79 - - - - - - - - 84 - - - - - - - - 26 - - - - - - - - - - - - - - SearchCriteriaView - - - 27 - - - - - - - - 29 - - - - - - - - 30 - - - - - - - - 31 - - - - - - - - 35 - - - - - - - - 61 - - - - - - - - 69 - - - - - - - - 73 - - - - - - - - 86 - - - - - - - - 94 - - - - - 95 - - - - - 96 - - - - - 97 - - - - - 98 - - - - - 99 - - - - - - - - 100 - - - - - 101 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - - - - 107 - - - - - - - - 108 - - - - - - - - 109 - - - - - - - - 71 - - - - - 80 - - - - - - - - 82 - - - - - 32 - - - - - - - - 33 - - - - - 34 - - - - - - - - 56 - - - - - 64 - - - - - - - - 62 - - - - - 74 - - - - - - - - - 76 - - - - - 75 - - - - - 87 - - - - - - - - - - 90 - - - - - 89 - - - - - 88 - - - - - -3 - - - Application - - - 36 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 109 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - SmartFolder - NSWindowController - - id - id - id - id - id - - - - addNewCriteria: - id - - - doCancel: - id - - - doSave: - id - - - fieldChanged: - id - - - removeCurrentCriteria: - id - - - - NSButton - NSButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSTextField - NSPopUpButton - NSButton - NSButton - NSView - NSView - NSWindow - NSTextField - NSTextField - - - - addCriteriaButton - NSButton - - - cancelButton - NSButton - - - criteriaConditionPopup - NSPopUpButton - - - dateValueField - NSPopUpButton - - - fieldNamePopup - NSPopUpButton - - - flagValueField - NSPopUpButton - - - folderValueField - NSPopUpButton - - - numberValueField - NSTextField - - - operatorPopup - NSPopUpButton - - - removeCriteriaButton - NSButton - - - saveButton - NSButton - - - searchCriteriaSuperview - NSView - - - searchCriteriaView - NSView - - - searchWindow - NSWindow - - - smartFolderName - NSTextField - - - valueField - NSTextField - - - - IBProjectSource - ./Classes/SmartFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Nome da pasta inteligente: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/pt.lproj/SearchFolder.nib/keyedobjects.nib b/lproj/pt.lproj/SearchFolder.nib/keyedobjects.nib index 044dfabc26..3e028039ff 100644 Binary files a/lproj/pt.lproj/SearchFolder.nib/keyedobjects.nib and b/lproj/pt.lproj/SearchFolder.nib/keyedobjects.nib differ diff --git a/lproj/pt.lproj/Vienna Help/advanced.html b/lproj/pt.lproj/Vienna Help/advanced.html deleted file mode 100644 index fb9b248814..0000000000 --- a/lproj/pt.lproj/Vienna Help/advanced.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - Advanced Settings - - - - -  Advanced - Settings -

The Advanced section of the Preferences provides options to - change very specific settings in Vienna that are not essential - for normal use but may resolve some issues as advised by the - support forum. This page details the advanced settings and their - function.

-

Enable JavaScript in internal browser

-

Enables or disables support for JavaScript scripting in the - Vienna internal browser. By default this is enabled. By turning - this setting off, JavaScript code on web pages will not be - allowed to run. This may resolve problems with pages that use - scripting to pop up windows or other unexpected behaviour but - turning the setting off may also cause some web pages to appear - incomplete or fail to function correctly.

- - diff --git a/lproj/pt.lproj/Vienna Help/faq.html b/lproj/pt.lproj/Vienna Help/faq.html deleted file mode 100644 index 7af1e2e6d0..0000000000 --- a/lproj/pt.lproj/Vienna Help/faq.html +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - - How Do I? - - - - -  How Do I? -

Below are some of the more common questions asked about Vienna - while it was being pre-release tested. See the Official Vienna FAQ - Page for these and the latest hints and tips for using - Vienna.

- -

Where do I get the Vienna - source code?

-

See the Development page - for instructions for getting the source code for Vienna. The - source code is freely available if you're interested in learning - how Vienna works, if you want to build your own copy of Vienna - from scratch on your own machine or if you want to borrow - portions for inclusion in your own project. The source is - provided under the Apache 2.0 - license.

-

I found a - problem with Vienna. How do I report it?

-

Send an email to Vienna Help or - post a message over in the Support - forum and somebody will investigate. Provide as much - information about the problem as you can including: the build of - Vienna (obtained from the About Vienna panel), repro steps and - what you expected to happen. There is a sticky note in the forum - with tips on how to write a good bug report.

-

Make sure you're always running the most recent build of - Vienna. The Check for Updates command will report if there's a - newer build available than the one you have.

-

Fixes for bugs take priority over new features so if your - problem is confirmed to be a bug with high impact and no simple - workaround then I'll look at making a fix available as soon as - reasonably possible.

-

How do I create my own - styles?

-

See the Custom Styles - page for instructions.

-

How do I create my own - scripts?

-

Vienna's scripts are written using AppleScript. See the - - Apple resource page for more details.

-

One way to get started is to download one of the existing - scripts from the Vienna Downloads - page and view it in the AppleScript editor.

-

To submit your own script, send it to steve@opencommunity.co.uk - and after it has been reviewed, it will be made available on the - Downloads page.

-

- How can I see what happened when my subscriptions are - refreshed?

-

Open the Activity Window from the Window menu. The activity - window shows all subscriptions and the status of the last time - they were refreshed in that session. The bottom of the activity - window shows more details include the HTTP headers and may be - useful for debugging. (If the details pane is not visible, grab - the split bar at the bottom of the Activity Window and drag it up - to uncover the pane).

-

How do I - move my Vienna database to another folder?

-

By default, your Vienna database is the messages.db file which - is located at ~/Library/Application Support/Vienna. You can move - this to another folder if you wish. The following steps show - how:

-
    -
  1. Shut down Vienna.
  2. -
  3. Open a console window and enter:
    -
    - defaults write - uk.co.opencommunity.vienna2 "DefaultDatabase" '<path to new - messages.db>'
    -
    - where <path to new messages.db> is the name of the folder - that contains the messages.db file. The path itself should have - the messages.db filename at the end. For example:
    -
    - defaults write - uk.co.opencommunity.vienna2 "DefaultDatabase" - '/Users/steve/mydata/messages.db'
  4. -
  5. Restart Vienna.
  6. -
-

- One of my subscriptions reports "Error parsing XML data in feed". - What does this mean?

-

It means that Vienna got a feed back from the subscription - that it couldn't interpret. There are several reasons for - this:

-
    -
  1. The URL of the feed may not be pointing to an RSS or Atom - feed but to a web page. Check the URL of the offending feed - carefully.
  2. -
  3. The feed itself may contain malformed XML. Some - subscriptions make a mistake in putting together the XML that - makes up the feed and Vienna cannot interpret malformed XML. - Use the Validate Feed command on the File menu to see if this - is the case. Unfortunately you cannot do much about this in - Vienna except wait for the feed itself to be corrected by the - site.
  4. -
  5. The feed may be incomplete. If the refresh was interrupted - then the XML data will be incomplete and will appear malformed - in Vienna. A second refresh may correct this problem.
  6. -
-

If none of the above explain the problem, post a message on - the support forum with the URL of the feed exhibiting the - problem.

-

- Is there a shortcut key for going to the next article, marking - read, etc?

-

Probably. There are single key equivalents for some of the - menu commands such as:

-

Spacebar - goes to the next unread article. If the current - article is several pages long, it will scroll through that - article first. If you're at the end of the current article it - will then go to the next unread article. By contrast the Next - Unread command (Cmd+U) always goes straight to the next unread - article.

-

R - marks the current article read if it is unread, or unread - if it is read.

-

F - flags the current article if it isn't already flagged, or - removes the existing flag if it is not.

-

Look in the Vienna Help file for more shortcuts.

-

What do - the green dots mean in the list of articles?

-

The blue dots are for new articles, and the green dots are for - updated articles: articles whose text has changed since they were - last downloaded.

-

How do I use Auto - Expire and what does it do?

-

Auto-expire moves articles older than a certain number of days - to the Trash folder. It allows you to keep your folders - manageable by only retaining articles that are recent. The - auto-expire runs both when Vienna starts and after you have - refreshed any subscriptions. To control the age of articles to - auto-expire, change the "Move articles to Trash" option in - Preferences.

-

Auto-expire will NOT remove unread or flagged articles. It - assumes that you haven't read these articles and thus leaves them - alone.

-

How do I request an - enhancement in Vienna?

-

Post a message over at the support - forum. All requested enhancements are logged in the TODO file - that is included with the source code as a guidance for future - developers.

- - diff --git a/lproj/pt.lproj/Vienna Help/helpstyle.css b/lproj/pt.lproj/Vienna Help/helpstyle.css deleted file mode 100644 index d02689f72e..0000000000 --- a/lproj/pt.lproj/Vienna Help/helpstyle.css +++ /dev/null @@ -1,39 +0,0 @@ -a { - color: #3366CC; - text-decoration: none; -} -.title { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 18pt; - color: #000000; -} -.header { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 12pt; - color: #000000; -} -li { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 100; - font-size: 9pt; - color: #000000; -} -h2 { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 400; - font-size: 10pt; - color: #000000; -} -p { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 100; - font-size: 9pt; - color: #000000; -} -tr { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-size: 9pt; - color: #000000; -} \ No newline at end of file diff --git a/lproj/pt.lproj/Vienna Help/images/Small-Vienna-Logo.jpg b/lproj/pt.lproj/Vienna Help/images/Small-Vienna-Logo.jpg deleted file mode 100644 index 41035b4f11..0000000000 Binary files a/lproj/pt.lproj/Vienna Help/images/Small-Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/pt.lproj/Vienna Help/images/Vertical-Line.jpg b/lproj/pt.lproj/Vienna Help/images/Vertical-Line.jpg deleted file mode 100644 index 011f1ce1e3..0000000000 Binary files a/lproj/pt.lproj/Vienna Help/images/Vertical-Line.jpg and /dev/null differ diff --git a/lproj/pt.lproj/Vienna Help/images/Vienna-Logo.jpg b/lproj/pt.lproj/Vienna Help/images/Vienna-Logo.jpg deleted file mode 100644 index 13a6479bd4..0000000000 Binary files a/lproj/pt.lproj/Vienna Help/images/Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/pt.lproj/Vienna Help/images/rssfeed.gif b/lproj/pt.lproj/Vienna Help/images/rssfeed.gif deleted file mode 100644 index 2dc8935119..0000000000 Binary files a/lproj/pt.lproj/Vienna Help/images/rssfeed.gif and /dev/null differ diff --git a/lproj/pt.lproj/Vienna Help/index.html b/lproj/pt.lproj/Vienna Help/index.html deleted file mode 100644 index a93a8e7d71..0000000000 --- a/lproj/pt.lproj/Vienna Help/index.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - Vienna Help - - - - - - - - - - -
-

-

Vienna Help

-
-

Introduction to Vienna

-

Learn how to get started with - Vienna.

-

Keyboard Shortcuts

-

Discover keyboard shortcuts - for common commands

-

How Do I?

-

Frequently Asked Questions, getting - support and troubleshooting steps.

-

Advanced Settings

-

Explains the settings in the - Advanced Preferences.

-
- - diff --git a/lproj/pt.lproj/Vienna Help/intro.html b/lproj/pt.lproj/Vienna Help/intro.html deleted file mode 100644 index 47c19b355f..0000000000 --- a/lproj/pt.lproj/Vienna Help/intro.html +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - Introduction to Vienna - - - - -   Introduction to - Vienna -

Vienna is an application that allows you to read RSS or Atom - news feeds on your Mac OS X computer. It automates the job of - retrieving news articles from all subscribed feeds and storing - them in a local database for reading off-line. It provides - features that allow you to search feeds for keywords or phrases, - tag articles with a flag for future reference and organise - related feeds together under groups. You can create smart folders - that make it easy to dynamically retrieve and view all articles - in the database that match a search criteria. The built-in web - browser allows you to go to the articles web page or view links - in the article directly in Vienna in separate tabs.

-

Vienna is designed to be simple and easy to use. A clean, - uncluttered, interface maximises the space for articles and just - a few controls are needed to perform the most common actions in - the user interface.

Getting Started -

If this is the first time that you have used Vienna then it - will have created a new database for you and added some sample - news subscriptions. So go ahead and press Command+R or choose - Refresh All Subscriptions from the File menu to grab the latest - articles from those subscriptions.

-

Alternatively, subscribe to your own news feeds. There are - various ways to find feeds. When browsing the web, look out for - the RSS feed icon or XML - icons indicating that the page has a feed associated with it. - Alternatively almost all online blogging services such as - LiveJournal or Blogger provide RSS feeds as an alternative to - reading the postings online.

-

If you know the user name of a blogger on LiveJournal, - Blogger, MSN Spaces or Xanga then Vienna makes it easier to - subscribe to their news feed. Start by pressing Command+N or from - the File menu, choose the New Subscription command. In the - "Create a new RSS subscription" panel, pick the blogging service - from the drop down list and enter the user name in the input - field below. Then choose Subscribe and Vienna will add the - subscription to the folder list. If you are connected to the - internet at the time, it will also immediately start collecting - articles from the feed.

-

Normally you need to manually tell Vienna when to refresh all - your subscriptions. However you can opt to ask Vienna to - automatically refresh at time intervals. In the General section - of the Preferences, pick the desired time interval from the drop - down list next to 'Check for new articles'. Vienna needs to be - running for it to automatically refresh subscriptions.

-

To read articles, press the Spacebar to skip to the next - unread article in any subscription. Each article is marked as - read automatically after a short delay. If you prefer to wait - until you move to the next unread article before the current one - is marked read you can adjust the behaviour in the General tab of - the Preferences. To mark an article as unread again, choose the - Mark Unread command from the Article menu or simply press the 'R' - key.

-

Finally, you can view the article web page or any web page - links in an article within Vienna. By default clicking on a web - link within Vienna will open the web page in a new tab. Vienna - provides a lot of basic web browsing support itself but there may - be times when you will prefer to open links in your default web - browser. If you prefer to view all web pages outside of Vienna - then enable the 'Open links in external browser' option in the - General section of the Preferences. However if you prefer to view - the current link or page in your external browser, right click on - the page and choose the "Open Link in XXX" or "Open Page in XXX" - option where XXX will be the name of your default browser.

-

Once you've got comfortable using Vienna, go ahead and explore - the various options. You can change the style in which the - articles are displayed through the Style drop down list in the - View menu. You can find many more custom styles at the Downloads page - on the Vienna web site along with custom scripts that allow you - to integrate Vienna with other applications on your machine. Or - experiment with smart folders to organise articles according to - criteria based on the contents of each article. For example, you - can easily set up a smart folder to group together all articles - that mention "Joss Whedon" and "Firefly" to find references to - the Firefly cult series or the spin-off movie.

-

If you have any questions about Vienna or run into problems, - send an email to Vienna Help or - head over to the Support - forum.

- - diff --git a/lproj/pt.lproj/Vienna Help/keyboard.html b/lproj/pt.lproj/Vienna Help/keyboard.html deleted file mode 100644 index f1e7b3bede..0000000000 --- a/lproj/pt.lproj/Vienna Help/keyboard.html +++ /dev/null @@ -1,346 +0,0 @@ - - - - - - - Keyboard Shortcuts - - - - -  Keyboard - Shortcuts -

You can use your keyboard to quickly accomplish many tasks in - Vienna. To find the shortcuts for common commands, look in the - menus (or see the list at the bottom of this page). Many items in - Vienna such as the folder pane and the article list pane also - have contextual menus. To see a contextual menu, press the - Control key and click the item.

-

To do an action, press the shortcut keys indicated below.

- - - - - -
KeyAction
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Single Key Shortcuts 
fOpens the filter bar and puts the focus on the filter - search field.
hPuts the focus on the search articles field.
kMarks the current folder read.
mToggles the selected articles flagged or unflagged.
nMoves to the next unread article.
rToggles the selected articles read and unread.
uToggles the selected articles read and unread.
sMarks the current folder read then skips to the next - folder with unread articles.
<Displays the previous viewed article or web page.
>Displays the next viewed article or web page.
LeftMoves the focus to the folder list if it is currently in - the article list.
RightMoves the focus to the article list if it is currently in - the folder list.
SpacebarMoves to the next unread article unless the current - article has more text to scroll in which case it scrolls the - current article up one page.
Enter/ReturnOpens the selected article's original web page.
Delete/BackspaceMoves the selected articles to the Trash folder. If this - key is used in the Trash folder, the selected articles are - permanently deleted.
General Shortcuts 
Alt-ClickOpen the clicked link, overriding your preference for - opening links in external browser.
Shift-Command-BOpens the filter bar.
Command-NCreate a new subscription.
Shift-Command-FCreate a smart folder.
Shift-Command-EEdit the selected folder URL or edit a smart folder - criteria.
Shift-Command-DDelete the selected folder.
Command-CCopies the selected text to the clipboard. If the focus - is on an article, it copies the article details to the - clipboard.
Command-HHides the Vienna main window.
Alt-Command-HHides all other application windows but keeps the Vienna - main window visible.
Command-IDisplays the Info window for the selected folder.
Command-LPuts the focus on the address bar of the current tab. Or - if no browser is open and has the focus, opens a new tab and - puts the focus on the address bar.
Shift-Command-NRename the selected folder.
Command-RRefreshes all subscriptions.
Shift-Command-RRefresh only those subscriptions selected in the folder - list.
Control-Command-SStops any active refresh.
Command-PPrint the selected articles.
Shift-Command-PBrings up the Page Setup panel.
Command-QExit Vienna.
Command-TOpens a new tab and puts the focus on the address - bar.
Command-UMoves to the next unread article.
Command-ZUndoes the last action, if it can be undone.
Command-/Toggles the status bar on or off.
Command-+Increases the size of the text in the current article or - web page.
Command--Decreases the size of the text in the current article or - web page.
Command-,Opens the Vienna preferences panel.
Alt-Command-BackspaceEmpties the trash folder after prompting for - confirmation.
Command-?Displays the Vienna help book.
Articles Shortcuts 
Alt-Enter/Alt-ReturnOpens the selected article's original web page, - overriding your preference for opening links in external - browser.
Shift-Command-ZRedo the last action, if it was previously undone.
Shift-Command-MFlags the selected articles.
Shift-Command-UMarks the selected articles read.
Alt-Command-SUses your default mail application to send a link to the - current article by e-mail.
Shift-Command-SMarks the current folder read then skips to the next - folder with unread articles.
Shift-Command-ORestores an article from the trash back to its original - folder.
Shift-Command-KMarks all articles in the selected folders read.
Alt-Command-KMarks all articles in all folders read.
Window Shortcuts 
Command-WCloses the active tab window if one is open. Otherwise if - no tabs are open, this closes the Vienna window.
Alt-Command-WCloses all tab windows. Note that this command replaces - the Close Tab command on the File menu when the Alt key is - held down.
Alt-Command-LeftDisplays the previous tab window.
Alt-Command-RightDisplays the next tab window.
Command-MMinimizes the Vienna window to the dock.
Command-0Displays the activity log viewer window.
Command-1Reopens the Vienna window if it was previously - closed.
Command-2Displays the Downloads window.
Browser Window Shortcuts 
Alt-RReloads the current web page.
Command-PeriodCancels loading of the current web page.
Command-[/Command-LeftGoes back to the previous web page.
Command-]/Command-RightGoes forward to the next web page.
Command-FPuts the input focus in the search field. Entering some - text here and pressing Enter will search for that text on the - current web page.
Command-GSearches for the next occurrence of the search text on - the web page.
- - diff --git a/lproj/pt_BR.lproj/EmptyTrashWarning.strings b/lproj/pt_BR.lproj/EmptyTrashWarning.strings old mode 100755 new mode 100644 diff --git a/lproj/pt_BR.lproj/GroupFolder.nib/designable.nib b/lproj/pt_BR.lproj/GroupFolder.nib/designable.nib index e645af0a28..abeb07e0ec 100644 --- a/lproj/pt_BR.lproj/GroupFolder.nib/designable.nib +++ b/lproj/pt_BR.lproj/GroupFolder.nib/designable.nib @@ -1,500 +1,91 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - NewGroupFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{502, 622}, {388, 149}} - 1886912512 - Painel - - NSPanel - - - View - - - {213, 107} - - - 256 - - - - 260 - {{17, 112}, {354, 17}} - - - YES - - 67108864 - 4194304 - Nova pasta de grupo - - LucidaGrande-Bold - 13 - 2072 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 258 - {{20, 60}, {348, 22}} - - - YES - - -1804599231 - 272630784 - - - LucidaGrande - 13 - 1044 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{285, 12}, {89, 32}} - - - 100 - YES - - 67108864 - 134217728 - Salvar - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{203, 12}, {82, 32}} - - - YES - - 67108864 - 134217728 - Cancelar - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 268 - {{17, 90}, {353, 14}} - - - YES - - 67108864 - 4194304 - RW50cmUgbyBub21lIGRhIHBhc3RhIGRlIGdydXBvOgo - - LucidaGrande - 11 - 3100 - - - - - - NO - - - {388, 149} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - - - - newGroupFolderWindow - - - - 18 - - - - doCancel: - - - - 25 - - - - doSave: - - - - 26 - - - - folderName - - - - 27 - - - - cancelButton - - - - 28 - - - - saveButton - - - - 29 - - - - window - - - - 30 - - - - nextKeyView - - - - 24 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 5 - - - - - - GroupFolder - - - 6 - - - - - - - - - - - - 19 - - - - - - - - 20 - - - - - - - - 21 - - - - - - - - 22 - - - - - - - - 23 - - - - - - - - 32 - - - - - 33 - - - - - 34 - - - - - 35 - - - - - 36 - - - - - -3 - - - Application - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 36 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - NewGroupFolder - NSWindowController - - id - id - - - - doCancel: - id - - - doSave: - id - - - - NSButton - NSTextField - NSWindow - NSButton - - - - cancelButton - NSButton - - - folderName - NSTextField - - - newGroupFolderWindow - NSWindow - - - saveButton - NSButton - - - - IBProjectSource - ./Classes/NewGroupFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Entre o nome da pasta de grupo: + + + + + + + + + + diff --git a/lproj/pt_BR.lproj/GroupFolder.nib/keyedobjects.nib b/lproj/pt_BR.lproj/GroupFolder.nib/keyedobjects.nib index 569f8b3751..1146ee62ee 100644 Binary files a/lproj/pt_BR.lproj/GroupFolder.nib/keyedobjects.nib and b/lproj/pt_BR.lproj/GroupFolder.nib/keyedobjects.nib differ diff --git a/lproj/pt_BR.lproj/InfoPlist.strings b/lproj/pt_BR.lproj/InfoPlist.strings deleted file mode 100644 index a20a786d2e..0000000000 --- a/lproj/pt_BR.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ -NSHumanReadableCopyright = "Copyright 2004-2015 Contribuintes. Ver Ajuda/Agradecimentos para a lista de contribuintes."; diff --git a/lproj/pt_BR.lproj/Localizable.strings b/lproj/pt_BR.lproj/Localizable.strings index 84b437a71c..d38d65fa61 100644 --- a/lproj/pt_BR.lproj/Localizable.strings +++ b/lproj/pt_BR.lproj/Localizable.strings @@ -450,3 +450,9 @@ /*Added in 3.0.5 */ "Redirection attempt treated as temporary for safety concern" = "Redirection attempt treated as temporary for safety concern"; + +/*Added in 3.0.7 */ +"No articles in feed" = "No articles in feed"; + +/*Added in 3.1.2 */ +"Filter folders" = "Search for folders"; diff --git a/lproj/pt_BR.lproj/RSSFeed.nib/designable.nib b/lproj/pt_BR.lproj/RSSFeed.nib/designable.nib index 15ea8593a3..a6264d0980 100644 --- a/lproj/pt_BR.lproj/RSSFeed.nib/designable.nib +++ b/lproj/pt_BR.lproj/RSSFeed.nib/designable.nib @@ -1,1003 +1,221 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSMenu - NSMenuItem - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSUserDefaultsController - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - RSSFeed - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{165, 318}, {426, 289}} - 1886912512 - RSS - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{208, 9}, {102, 32}} - - - YES - - 67108864 - 134217728 - Cancelar - - LucidaGrande - 13 - 1044 - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{310, 9}, {102, 32}} - - - 100 - YES - - 67108864 - 134217728 - Assinar - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{20, 188}, {75, 17}} - - - YES - - 67108864 - 4194304 - T3JpZ2VtOgo - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 256 - {{99, 181}, {175, 26}} - - - YES - - -2080374720 - 1024 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - URL - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - 100 - - - YES - - - OtherViews - - - - - - 3 - YES - YES - 1 - - NO - - - - 256 - {{20, 255}, {389, 17}} - - - YES - - 67108864 - 4194304 - Q3JpYXIgbm92YSBhc3NpbmF0dXJhCg - - LucidaGrande-Bold - 13 - 2072 - - - - - - NO - - - - 256 - {{20, 213}, {378, 34}} - - - YES - - 67108864 - 4194304 - Entre o link das notícias abaixo. Ou escolha da lista de de Origens para entrar com um atalho para as notícias fornecidas pela origem. - - LucidaGrande - 10 - 2843 - - - - - - NO - - - - 256 - {{23, 82}, {386, 62}} - - - YES - - -1805647871 - 4325376 - - - LucidaGrande - 11 - 3100 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 256 - {{283, 181}, {21, 24}} - - - YES - - 67108864 - 134217728 - - - - -2038284288 - 33 - - - - - - 200 - 25 - - NO - - - - 256 - {{20, 152}, {270, 17}} - - - YES - - 67108864 - 4194304 - URL: - - - - - - NO - - - - 268 - {{21, 44}, {185, 18}} - - - YES - - -2080374784 - 0 - Subscribe in Open Reader - - - 1211912448 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - NO - - - {426, 289} - - - - {{0, 0}, {1280, 778}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - 3 - 2 - {{305, 336}, {423, 167}} - 1886912512 - RSS - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{307, 12}, {102, 32}} - - 100 - YES - - 67108864 - 134217728 - Salvar - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{205, 12}, {102, 32}} - - - YES - - 67108864 - 134217728 - Cancelar - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{20, 60}, {383, 62}} - - - YES - - -1805647871 - 4325376 - - - - YES - - - - NO - - - - 256 - {{17, 130}, {389, 17}} - - - YES - - 67108864 - 4194304 - Editar assinatura - - - - - - NO - - - {{1, 9}, {423, 167}} - - - {{0, 0}, {1280, 778}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - YES - - - - - - - window - - - - 14 - - - - doSubscribe: - - - - 37 - - - - feedSource - - - - 46 - - - - subscribeButton - - - - 48 - - - - doSave: - - - - 57 - - - - editRSSFeedWindow - - - - 61 - - - - newRSSFeedWindow - - - - 62 - - - - editFeedURL - - - - 69 - - - - saveButton - - - - 70 - - - - editCancelButton - - - - 74 - - - - subscribeCancelButton - - - - 76 - - - - doEditCancel: - - - - 77 - - - - doSubscribeCancel: - - - - 78 - - - - doLinkSourceChanged: - - - - 89 - - - - feedURL - - - - 91 - - - - doShowSiteHomePage: - - - - 93 - - - - siteHomePageButton - - - - 94 - - - - linkTitle - - - - 99 - - - - doGoogleOption: - - - - 118 - - - - googleOptionButton - - - - 119 - - - - value: googleOptionButton - - - - - - value: googleOptionButton - value - googleOptionButton - 2 - - - 117 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - NewRSSFeed - - - 5 - - - - - - - - - - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 40 - - - - - - - - 43 - - - - - - - - 64 - - - - - - - - 65 - - - - - - - - 90 - - - - - - - - 92 - - - - - - - - 97 - - - - - - - - 49 - - - - - - EditRSSFeed - - - 50 - - - - - - - - - - - 53 - - - - - - - - 54 - - - - - - - - 55 - - - - - - - - 67 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - 107 - - - - - 108 - - - - - 109 - - - - - 110 - - - - - 111 - - - - - 112 - - - - - 113 - - - - - 114 - - - - - 44 - - - - - - - - 45 - - - - - -3 - - - Application - - - 115 - - - - - - - - 116 - - - - - 120 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{1012, 565}, {429, 297}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 122 - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - {15, 15} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Origem: + + + + + + + + + + + + + + + + + + + + + + + + + + + Criar nova assinatura + + + + + + + + + + + Entre o link das notícias abaixo. Ou escolha da lista de de Origens para entrar com um atalho para as notícias fornecidas pela origem. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/pt_BR.lproj/RSSFeed.nib/keyedobjects.nib b/lproj/pt_BR.lproj/RSSFeed.nib/keyedobjects.nib index e9ff0d3d29..b9952a2da5 100644 Binary files a/lproj/pt_BR.lproj/RSSFeed.nib/keyedobjects.nib and b/lproj/pt_BR.lproj/RSSFeed.nib/keyedobjects.nib differ diff --git a/lproj/pt_BR.lproj/SearchFolder.nib/designable.nib b/lproj/pt_BR.lproj/SearchFolder.nib/designable.nib index 4faaca1151..b670e8cd4e 100644 --- a/lproj/pt_BR.lproj/SearchFolder.nib/designable.nib +++ b/lproj/pt_BR.lproj/SearchFolder.nib/designable.nib @@ -1,1585 +1,265 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSBox - NSButton - NSButtonCell - NSCustomObject - NSCustomView - NSMenu - NSMenuItem - NSNumberFormatter - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - SmartFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{235, 568}, {647, 186}} - 1886912512 - - NSPanel - - View - - - {213, 107} - - - 256 - - - - 268 - {{17, 150}, {246, 17}} - - - YES - - 67108864 - 4194304 - Tm9tZSBkYSBwYXN0YSBpbnRlbGlnZW50ZToKA - - LucidaGrande - 13 - 1044 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 268 - {{200, 148}, {178, 22}} - - - YES - - -1804599231 - 4195328 - - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{555, 12}, {78, 32}} - - - YES - - 67108864 - 134217728 - Salvar - - - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{475, 12}, {82, 32}} - - - YES - - 67108864 - 134217728 - Cancelar - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 274 - - - - 274 - - - - 274 - {{12, 6}, {584, 38}} - - - - NSView - - NSResponder - - - {{2, 2}, {609, 50}} - - - - - {{17, 56}, {613, 54}} - - - {0, 0} - - 67108864 - 0 - - - LucidaGrande - 11 - 3100 - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 3 - 0 - 0 - NO - - - - 268 - {{17, 118}, {267, 17}} - - - YES - - 67108864 - 4194304 - Mostrar todos os artigos que combinam - - - - - - NO - - - - 268 - {{286, 112}, {80, 26}} - - - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - Nada - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - 3 - YES - YES - 1 - - NO - - - - 268 - {{369, 118}, {210, 17}} - - - YES - - 67108864 - 272629760 - das seguintes condições: - - - - - - NO - - - {647, 186} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - 256 - - - - 256 - {{-3, 0}, {135, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Nomes de campos entram aqui - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - 3 - YES - YES - 1 - - NO - - - - 256 - {{513, -3}, {32, 31}} - - YES - - 67108864 - 134479872 - - - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{302, 3}, {183, 22}} - - YES - - -1804599231 - 4195328 - - - - YES - - - - NO - - - - 256 - {{541, -3}, {32, 31}} - - YES - - 67108864 - 134479872 - + - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{151, 0}, {135, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Operadores entram aqui - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{299, 0}, {100, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - - - 400 - 75 - - - Nada - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{302, 4}, {126, 22}} - - YES - - -1804599231 - 4195328 - - - - - - - - - NaN - - - - 0 - - - . - - , - - - - - 0 - 2 - NO - YES - 1 - P0IPAAAAAAAAAAAAAAAAAA - - - 0 - 1 - NO - YES - 1 - AQAAAAAAAAAAAAAAAAAAAA - - -0 - 0 - - - 0 - -0 - - - - - - - - - . - , - NO - NO - YES - - - YES - - - - NO - - - - -2147483392 - {{299, 0}, {189, 26}} - - 1008 - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Item2 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - Item3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{299, 0}, {189, 26}} - - 1004 - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Item1 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - Item2 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - Item3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - 3 - YES - YES - 1 - - NO - - - {572, 28} - - NSView - - NSResponder - - - - - - - cancelButton - - - - 40 - - - - saveButton - - - - 41 - - - - searchCriteriaView - - - - 43 - - - - removeCriteriaButton - - - - 44 - - - - addCriteriaButton - - - - 45 - - - - fieldNamePopup - - - - 46 - - - - operatorPopup - - - - 47 - - - - valueField - - - - 49 - - - - window - - - - 50 - - - - addNewCriteria: - - - - 51 - - - - doCancel: - - - - 52 - - - - doSave: - - - - 53 - - - - searchWindow - - - - 54 - - - - removeCurrentCriteria: - - - - 57 - - - - fieldChanged: - - - - 59 - - - - flagValueField - - - - 65 - - - - numberValueField - - - - 70 - - - - folderValueField - - - - 78 - - - - criteriaConditionPopup - - - - 85 - - - - dateValueField - - - - 91 - - - - smartFolderName - - - - 92 - - - - searchCriteriaSuperview - - - - 42 - - - - nextKeyView - - - - 72 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - Search Folder - - - 5 - - - - - - - - - - - - - - - 7 - - - - - - - - 8 - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 37 - - - - - - - - 58 - - - - - - - - 79 - - - - - - - - 84 - - - - - - - - 26 - - - - - - - - - - - - - - SearchCriteriaView - - - 27 - - - - - - - - 29 - - - - - - - - 30 - - - - - - - - 31 - - - - - - - - 35 - - - - - - - - 61 - - - - - - - - 69 - - - - - - - - 73 - - - - - - - - 86 - - - - - - - - 94 - - - - - 95 - - - - - 96 - - - - - 97 - - - - - 98 - - - - - 99 - - - - - - - - 100 - - - - - 101 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - - - - 107 - - - - - - - - 108 - - - - - - - - 109 - - - - - - - - 71 - - - - - 80 - - - - - - - - 82 - - - - - 32 - - - - - - - - 33 - - - - - 34 - - - - - - - - 56 - - - - - 64 - - - - - - - - 62 - - - - - 74 - - - - - - - - - 76 - - - - - 75 - - - - - 87 - - - - - - - - - - 90 - - - - - 89 - - - - - 88 - - - - - -3 - - - Application - - - 36 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 109 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - SmartFolder - NSWindowController - - id - id - id - id - id - - - - addNewCriteria: - id - - - doCancel: - id - - - doSave: - id - - - fieldChanged: - id - - - removeCurrentCriteria: - id - - - - NSButton - NSButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSTextField - NSPopUpButton - NSButton - NSButton - NSView - NSView - NSWindow - NSTextField - NSTextField - - - - addCriteriaButton - NSButton - - - cancelButton - NSButton - - - criteriaConditionPopup - NSPopUpButton - - - dateValueField - NSPopUpButton - - - fieldNamePopup - NSPopUpButton - - - flagValueField - NSPopUpButton - - - folderValueField - NSPopUpButton - - - numberValueField - NSTextField - - - operatorPopup - NSPopUpButton - - - removeCriteriaButton - NSButton - - - saveButton - NSButton - - - searchCriteriaSuperview - NSView - - - searchCriteriaView - NSView - - - searchWindow - NSWindow - - - smartFolderName - NSTextField - - - valueField - NSTextField - - - - IBProjectSource - ./Classes/SmartFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Nome da pasta inteligente: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/pt_BR.lproj/SearchFolder.nib/keyedobjects.nib b/lproj/pt_BR.lproj/SearchFolder.nib/keyedobjects.nib index f23132083f..699703be21 100644 Binary files a/lproj/pt_BR.lproj/SearchFolder.nib/keyedobjects.nib and b/lproj/pt_BR.lproj/SearchFolder.nib/keyedobjects.nib differ diff --git a/lproj/pt_BR.lproj/Vienna Help/advanced.html b/lproj/pt_BR.lproj/Vienna Help/advanced.html deleted file mode 100644 index fb9b248814..0000000000 --- a/lproj/pt_BR.lproj/Vienna Help/advanced.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - Advanced Settings - - - - -  Advanced - Settings -

The Advanced section of the Preferences provides options to - change very specific settings in Vienna that are not essential - for normal use but may resolve some issues as advised by the - support forum. This page details the advanced settings and their - function.

-

Enable JavaScript in internal browser

-

Enables or disables support for JavaScript scripting in the - Vienna internal browser. By default this is enabled. By turning - this setting off, JavaScript code on web pages will not be - allowed to run. This may resolve problems with pages that use - scripting to pop up windows or other unexpected behaviour but - turning the setting off may also cause some web pages to appear - incomplete or fail to function correctly.

- - diff --git a/lproj/pt_BR.lproj/Vienna Help/faq.html b/lproj/pt_BR.lproj/Vienna Help/faq.html deleted file mode 100644 index 8532ac8e96..0000000000 --- a/lproj/pt_BR.lproj/Vienna Help/faq.html +++ /dev/null @@ -1,208 +0,0 @@ - - - - - - - How Do I? - - - - -  How Do I? -

Below are some of the more common questions asked about Vienna - while it was being pre-release tested. See the Official Vienna FAQ - Page for these and the latest hints and tips for using - Vienna.

- -

Where do I get the Vienna - source code?

-

See the Development page - for instructions for getting the source code for Vienna. The - source code is freely available if you're interested in learning - how Vienna works, if you want to build your own copy of Vienna - from scratch on your own machine or if you want to borrow - portions for inclusion in your own project. The source is - provided under the Apache 2.0 - license.

-

I found a - problem with Vienna. How do I report it?

-

Post a message over in the Support forum and somebody will - investigate. Provide as much information about the problem as you - can including: the build of Vienna (obtained from the About - Vienna panel), repro steps and what you expected to happen.

-

Make sure you're always running the most recent build of - Vienna. The Check for Updates command will report if there's a - newer build available than the one you have.

-

Fixes for bugs take priority over new features so if your - problem is confirmed to be a bug with high impact and no simple - workaround then I'll look at making a fix available as soon as - reasonably possible.

-

How do I create my own - styles?

-

See the Custom Styles - page for instructions.

-

How do I create my own - scripts?

-

Vienna's scripts are written using AppleScript. See the - - Apple resource page for more details.

-

One way to get started is to download one of the existing - scripts from the Vienna Downloads - page and view it in the AppleScript editor. Also take a look - at the Scripts - page for more details of the Vienna scripting dictionary and - examples of what you can accomplish.

-

To submit your own script, send it to steve@opencommunity.co.uk - and after it has been reviewed, it will be made available on the - Downloads page.

-

- How can I see what happened when my subscriptions are - refreshed?

-

Open the Activity Window from the Window menu. The activity - window shows all subscriptions and the status of the last time - they were refreshed in that session. The bottom of the activity - window shows more details include the HTTP headers and may be - useful for debugging. (If the details pane is not visible, grab - the split bar at the bottom of the Activity Window and drag it up - to uncover the pane).

-

How do I - move my Vienna database to another folder?

-

By default, your Vienna database is the messages.db file which - is located at ~/Library/Application Support/Vienna. You can move - this to another folder if you wish. The following steps show - how:

-
    -
  1. Shut down Vienna.
  2. -
  3. Open a console window and enter:
    -
    - defaults write - uk.co.opencommunity.vienna2 "DefaultDatabase" '<path to new - messages.db>'
    -
    - where <path to new messages.db> is the name of the folder - that contains the messages.db file. The path itself should have - the messages.db filename at the end. For example:
    -
    - defaults write - uk.co.opencommunity.vienna2 "DefaultDatabase" - '/Users/steve/mydata/messages.db'
  4. -
  5. Restart Vienna.
  6. -
-

- One of my subscriptions reports "Error parsing XML data in feed". - What does this mean?

-

It means that Vienna got a feed back from the subscription - that it couldn't interpret. There are several reasons for - this:

-
    -
  1. The URL of the feed may not be pointing to an RSS or Atom - feed but to a web page. Check the URL of the offending feed - carefully.
  2. -
  3. The feed itself may contain malformed XML. Some - subscriptions make a mistake in putting together the XML that - makes up the feed and Vienna cannot interpret malformed XML. - Use the Validate Feed command on the File menu to see if this - is the case. Unfortunately you cannot do much about this in - Vienna except wait for the feed itself to be corrected by the - site.
  4. -
  5. The feed may be incomplete. If the refresh was interrupted - then the XML data will be incomplete and will appear malformed - in Vienna. A second refresh may correct this problem.
  6. -
-

If none of the above explain the problem, post a message on - the support forum with the URL of the feed exhibiting the - problem.

-

- Is there a shortcut key for going to the next article, marking - read, etc?

-

Probably. There are single key equivalents for some of the - menu commands such as:

-

Spacebar - goes to the next unread article. If the current - article is several pages long, it will scroll through that - article first. If you're at the end of the current article it - will then go to the next unread article. By contrast the Next - Unread command (Cmd+U) always goes straight to the next unread - article.

-

R - marks the current article read if it is unread, or unread - if it is read.

-

F - flags the current article if it isn't already flagged, or - removes the existing flag if it is not.

-

Look in the Vienna Help file for more shortcuts.

-

How do I use Auto - Expire and what does it do?

-

Auto-expire moves articles older than a certain number of days - to the Trash folder. It allows you to keep your folders - manageable by only retaining articles that are recent. The - auto-expire runs both when Vienna starts and after you have - refreshed any subscriptions. To control the age of articles to - auto-expire, change the "Expire articles older than" option in - Preferences.

-

Auto-expire will NOT remove unread or flagged articles. It - assumes that you haven't read these articles and thus leaves them - alone.

-

How do I request an - enhancement in Vienna?

-

Post a message over at the support - forum. All requested enhancements are logged in the TODO file - that is included with the source code as a guidance for future - developers.

- - diff --git a/lproj/pt_BR.lproj/Vienna Help/helpstyle.css b/lproj/pt_BR.lproj/Vienna Help/helpstyle.css deleted file mode 100644 index d02689f72e..0000000000 --- a/lproj/pt_BR.lproj/Vienna Help/helpstyle.css +++ /dev/null @@ -1,39 +0,0 @@ -a { - color: #3366CC; - text-decoration: none; -} -.title { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 18pt; - color: #000000; -} -.header { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 12pt; - color: #000000; -} -li { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 100; - font-size: 9pt; - color: #000000; -} -h2 { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 400; - font-size: 10pt; - color: #000000; -} -p { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 100; - font-size: 9pt; - color: #000000; -} -tr { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-size: 9pt; - color: #000000; -} \ No newline at end of file diff --git a/lproj/pt_BR.lproj/Vienna Help/images/Small-Vienna-Logo.jpg b/lproj/pt_BR.lproj/Vienna Help/images/Small-Vienna-Logo.jpg deleted file mode 100644 index 41035b4f11..0000000000 Binary files a/lproj/pt_BR.lproj/Vienna Help/images/Small-Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/pt_BR.lproj/Vienna Help/images/Vertical-Line.jpg b/lproj/pt_BR.lproj/Vienna Help/images/Vertical-Line.jpg deleted file mode 100644 index 011f1ce1e3..0000000000 Binary files a/lproj/pt_BR.lproj/Vienna Help/images/Vertical-Line.jpg and /dev/null differ diff --git a/lproj/pt_BR.lproj/Vienna Help/images/Vienna-Logo.jpg b/lproj/pt_BR.lproj/Vienna Help/images/Vienna-Logo.jpg deleted file mode 100644 index 13a6479bd4..0000000000 Binary files a/lproj/pt_BR.lproj/Vienna Help/images/Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/pt_BR.lproj/Vienna Help/images/rssfeed.gif b/lproj/pt_BR.lproj/Vienna Help/images/rssfeed.gif deleted file mode 100644 index 2dc8935119..0000000000 Binary files a/lproj/pt_BR.lproj/Vienna Help/images/rssfeed.gif and /dev/null differ diff --git a/lproj/pt_BR.lproj/Vienna Help/index.html b/lproj/pt_BR.lproj/Vienna Help/index.html deleted file mode 100644 index 00c223fc12..0000000000 --- a/lproj/pt_BR.lproj/Vienna Help/index.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - Vienna Help - - - - - - - - - - -
-

-

Vienna Help

-
-

Introduction to Vienna

-

Learn how to get started with - Vienna.

-

Keyboard Shortcuts

-

Discover keyboard shortcuts - for common commands

-

How Do I?

-

Frequently Asked Questions, getting - support and troubleshooting steps.

-
- - diff --git a/lproj/pt_BR.lproj/Vienna Help/intro.html b/lproj/pt_BR.lproj/Vienna Help/intro.html deleted file mode 100644 index 8837ebedf8..0000000000 --- a/lproj/pt_BR.lproj/Vienna Help/intro.html +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - - Introduction to Vienna - - - - -   Introduction to - Vienna -

Vienna is an application that allows you to read RSS or Atom - news feeds on your Mac OSX computer. It automates the job of - retrieving news articles from all subscribed feeds and storing - them in a local database for reading off-line. It provides - features that allow you to search feeds for keywords or phrases, - tag articles with a flag for future reference and organise - related feeds together under groups. You can create smart folders - that make it easy to dynamically retrieve and view all articles - in the database that match a search criteria. The built-in web - browser allows you to go to the articles web page or view links - in the article directly in Vienna in separate tabs.

-

Vienna is designed to be simple and easy to use. A clean, - uncluttered, interface maximises the space for articles and just - a few controls are needed to perform the most common actions in - the user interface.

Getting Started -

If this is the first time that you have used Vienna then it - will have created a new database for you and added some sample - news subscriptions. So go ahead and press Command+T or choose - Refresh All Subscriptions from the File menu to grab the latest - articles from those subscriptions.

-

Alternatively, subscribe to your own news feeds. There are - various ways to find feeds. When browsing the web, look out for - the or XML icons - indicating that the page has a feed associated with it. - Alternatively almost all online blogging services such as - LiveJournal or Blogger provide RSS feeds as an alternative to - reading the postings online.

-

If you know the user name of a blogger on LiveJournal, - Blogger, MSN Spaces or Xanga then Vienna makes it easier to - subscribe to their news feed. Start by pressing Command+N or from - the File menu, choose the New Subscription command. In the - "Create a new RSS subscription" panel, pick the blogging service - from the drop down list and enter the user name in the input - field below. Then choose Subscribe and Vienna will add the - subscription to the folder list. If you are connected to the - internet at the time, it will also immediately start collecting - articles from the feed.

-

Normally you need to manually tell Vienna when to refresh all - your subscriptions. However you can opt to ask Vienna to - automatically refresh at time intervals. In the General section - of the Preferences, pick the desired time interval from the drop - down list next to 'Check for new articles'. Vienna needs to be - running for it to automatically refresh subscriptions.

-

To read articles, press the Spacebar to skip to the next - unread article in any subscription. Each article is marked as - read automatically after a short delay. If you prefer to wait - until you move to the next unread article before the current one - is marked read you can adjust the behaviour in the General tab of - the Preferences. To mark an article as unread again, choose the - Mark Unread command from the Article menu or simply press the 'R' - key.

-

Finally, you can view the article web page or any web page - links in an article within Vienna. By default clicking on a web - link within Vienna will open the web page in a new tab. Vienna - provides a lot of basic web browsing support itself but there may - be times when you will prefer to open links in your default web - browser. If you prefer to view all web pages outside of Vienna - then enable the 'Open links in external browser' option in the - General section of the Preferences. However if you prefer to view - the current link or page in your external browser, right click on - the page and choose the "Open Link in XXX" or "Open Page in XXX" - option where XXX will be the name of your default browser.

-

Once you've got comfortable using Vienna, go ahead and explore - the various options. You can change the style in which the - articles are displayed through the Style drop down list in the - View menu. You can find many more custom styles at the Downloads - page on the Vienna web site along with custom scripts that allow - you to integrate Vienna with other applications on your machine. - Or experiment with smart folders to organise articles according - to criteria based on the contents of each article. For example, - you can easily set up a smart folder to group together all - articles that mention "Joss Whedon" and "Firefly" to find - references to the Firefly cult series or the spin-off movie.

-

If you have any questions about Vienna or run into problems, - head over to the Support - forum.

- - diff --git a/lproj/pt_BR.lproj/Vienna Help/keyboard.html b/lproj/pt_BR.lproj/Vienna Help/keyboard.html deleted file mode 100644 index fd95d46952..0000000000 --- a/lproj/pt_BR.lproj/Vienna Help/keyboard.html +++ /dev/null @@ -1,248 +0,0 @@ - - - - - - - Keyboard Shortcuts - - - - -  Keyboard - Shortcuts -

You can use your keyboard to quickly accomplish many tasks in - Vienna. To find the shortcuts for common commands, look in the - menus (or see the list at the bottom of this page). Many items in - Vienna such as the folder pane and the article list pane also - have contextual menus. To see a contextual menu, press the - Control key and click the item.

-

To do an action, press the shortcut keys indicated below.

- - - - - -
KeyAction
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Single Key Shortcuts 
fSets the input focus to the search window.
rMarks the selected articles read.
sMarks the current folder read then skips to the next - folder with unread articles.
kMarks the current folder read.
mFlags the selected articles.
<Displays the previous viewed article or web page.
>Displays the next viewed article or web page.
SpacebarMoves to the next unread article unless the current - article has more text to scroll in which case it scrolls the - current article up one page.
Command-UMoves to the next unread article.
Enter/ReturnOpens the selected article's original web page.
Delete/BackspaceMoves the selected articles to the Trash folder. If this - key is used in the Trash folder, the selected articles are - permanently deleted.
General Shortcuts 
Command-NCreate a new subscription.
Shift-Command-FCreate a smart folder.
Shift-Command-EEdit the selected folder URL or edit a smart folder - criteria.
Shift-Command-DDelete the selected folder.
Shift-Command-NRename the selected folder.
Command-RRefreshes all subscriptions.
Shift-Command-RRefresh only those subscriptions selected in the folder - list.
Command-MinusStops any active refresh.
Command-PPrint the selected articles.
Shift-Command-PBrings up the Page Setup panel.
Shift-Command-VValidate the selected feed.
Command-?Displays the Vienna help book.
Articles Shortcuts 
Shift-Command-MFlags the selected articles.
Shift-Command-UMarks the selected articles read.
Shift-Command-SMarks the current folder read then skips to the next - folder with unread articles.
Shift-Command-ORestores an article from the trash back to its original - folder.
Shift-Command-KMarks all articles in the selected folders read.
Alt-Command-KMarks all articles in all folders read.
Window Shortcuts 
Command-WCloses the active tab window if one is open. Otherwise if - no tabs are open, this closes the Vienna window.
Alt-Command-WCloses all tab windows. Note that this command replaces - the Close Tab command on the File menu when the Alt key is - held down.
Control-Command-LeftDisplays the previous tab window.
Control-Command-RightDisplays the next tab window.
Shift-Command-WCloses the Vienna window but leaves Vienna running in the - background. You can bring the window back by clicking on the - Vienna dock icon or pressing Command-1.
Command-MMinimizes the Vienna window to the dock.
Command-0Displays the activity log viewer window.
Command-1Reopens the Vienna window if it was previously - closed.
Command-2Displays the Downloads window.
Browser Window Shortcuts 
Alt-RReloads the current web page.
Command-PeriodCancels loading of the current web page.
Command-[/Command-LeftGoes back to the previous web page.
Command-]/Command-RightGoes forward to the next web page.
Command-FPuts the input focus in the search field. Entering some - text here and pressing Enter will search for that text on the - current web page.
Command-GSearches for the next occurrence of the search text on - the web page.
- - diff --git a/lproj/ru.lproj/EmptyTrashWarning.nib/designable.nib b/lproj/ru.lproj/EmptyTrashWarning.nib/designable.nib index b4b2d77916..35f03a88f1 100644 --- a/lproj/ru.lproj/EmptyTrashWarning.nib/designable.nib +++ b/lproj/ru.lproj/EmptyTrashWarning.nib/designable.nib @@ -1,420 +1,80 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - EmptyTrashWarning - - - FirstResponder - - - NSApplication - - - 1 - 2 - {{274, 642}, {361, 152}} - 1886912512 - Очистка Корзины - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{189, 12}, {158, 32}} - - - YES - - -2080374784 - 134217728 - Очистить Корзину - - LucidaGrande - 13 - 1044 - - - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{73, 12}, {116, 32}} - - - YES - - -2080374784 - 134217728 - Не очищать - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{17, 82}, {327, 50}} - - - YES - - 67108928 - 272630784 - 0JIg0JrQvtGA0LfQuNC90LUg0YPRgdGC0Ywg0YPQtNCw0LvQtdC90L3Ri9C1INGB0YLQsNGC0YzQuC4K -0J7Rh9C40YHRgtC40YLRjCDQmtC+0YDQt9C40L3RgyDQv9C10YDQtdC0INC30LDQstC10YDRiNC10L3Q -uNC10Lwg0YDQsNCx0L7RgtGLPw - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 256 - {{18, 58}, {269, 18}} - - - YES - - 67108864 - 0 - Больше не показывать это сообщение - - - 1211912448 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - NO - - - {361, 152} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - - - - doNotShowWarningAgain - - - - 12 - - - - doNotEmptyTrash: - - - - 13 - - - - emptyTrash: - - - - 14 - - - - window - - - - 15 - - - - initialFirstResponder - - - - 11 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 5 - - - - - - Window - - - 6 - - - - - - - - - - - 7 - - - - - - - - 8 - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 17 - - - - - 18 - - - - - 19 - - - - - 20 - - - - - -3 - - - Application - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 20 - - - - - EmptyTrashWarning - NSWindowController - - id - id - - - - doNotEmptyTrash: - id - - - emptyTrash: - id - - - - doNotShowWarningAgain - NSButton - - - doNotShowWarningAgain - - doNotShowWarningAgain - NSButton - - - - IBProjectSource - ./Classes/EmptyTrashWarning.h - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - NSSwitch - {15, 15} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + В Корзине есть удаленные статьи. +Очистить Корзину перед завершением работы? + + + + + + + + + + + + + diff --git a/lproj/ru.lproj/EmptyTrashWarning.nib/keyedobjects.nib b/lproj/ru.lproj/EmptyTrashWarning.nib/keyedobjects.nib index 2135745595..5af40810b8 100644 Binary files a/lproj/ru.lproj/EmptyTrashWarning.nib/keyedobjects.nib and b/lproj/ru.lproj/EmptyTrashWarning.nib/keyedobjects.nib differ diff --git a/lproj/ru.lproj/EmptyTrashWarning.strings b/lproj/ru.lproj/EmptyTrashWarning.strings index 92e5854ecb..fe758bfb91 100644 --- a/lproj/ru.lproj/EmptyTrashWarning.strings +++ b/lproj/ru.lproj/EmptyTrashWarning.strings @@ -1,13 +1,13 @@ /* NSButton (Do not show this warning again) : (oid:10) */ -"Do not show this warning again" = "Do not show this warning again"; +"Do not show this warning again" = "Больше не показывать это сообщение"; /* NSButton (Don't Empty Trash) : (oid:8) */ -"Don't Empty Trash" = "Don't Empty Trash"; +"Don't Empty Trash" = "Не очищать"; /* NSButton (Empty Trash) : (oid:7) */ -"Empty Trash" = "Empty Trash"; +"Empty Trash" = "Очистка Корзины"; /* NSTextField (There are deleted articles in the trash. Would you like to empty the trash before quitting?) : (oid:9) */ -"There are deleted articles in the trash.\nWould you like to empty the trash before quitting?" = "There are deleted articles in the trash.\nWould you like to empty the trash before quitting?"; +"There are deleted articles in the trash.\nWould you like to empty the trash before quitting?" = "В Корзине есть удаленные статьи.\nОчистить Корзину перед завершением работы?"; diff --git a/lproj/ru.lproj/FeedCredentials.nib/designable.nib b/lproj/ru.lproj/FeedCredentials.nib/designable.nib index dcac6396f0..4cc5bcf5d9 100644 --- a/lproj/ru.lproj/FeedCredentials.nib/designable.nib +++ b/lproj/ru.lproj/FeedCredentials.nib/designable.nib @@ -1,8 +1,8 @@ - + - - + + @@ -17,8 +17,8 @@ - - + + @@ -36,7 +36,7 @@ - + @@ -45,7 +45,7 @@ - + @@ -133,4 +133,4 @@ Gw - \ No newline at end of file + diff --git a/lproj/ru.lproj/FeedCredentials.nib/keyedobjects.nib b/lproj/ru.lproj/FeedCredentials.nib/keyedobjects.nib index ca1291d6b2..be854207ce 100644 Binary files a/lproj/ru.lproj/FeedCredentials.nib/keyedobjects.nib and b/lproj/ru.lproj/FeedCredentials.nib/keyedobjects.nib differ diff --git a/lproj/ru.lproj/FeedCredentials.strings b/lproj/ru.lproj/FeedCredentials.strings index 731f5feef2..48dbaf3768 100644 --- a/lproj/ru.lproj/FeedCredentials.strings +++ b/lproj/ru.lproj/FeedCredentials.strings @@ -2,19 +2,19 @@ "" = ""; /* NSTextField (Access to %@ requires you to provide log in credentials) : (oid:10) */ -"Access to %@ requires you to provide log in credentials" = "Access to %@ requires you to provide log in credentials"; +"Access to %@ requires you to provide log in credentials" = "Для доступа к %@ требуется указать имя пользователя и пароль"; /* NSButton (Cancel) : (oid:8) */ -"Cancel" = "Cancel"; +"Cancel" = "Отмена"; /* NSButton (Log In) : (oid:14) */ -"Log In" = "Log In"; +"Log In" = "Войти"; /* NSTextField (Name:) : (oid:9) */ -"Name:" = "Name:"; +"Name:" = "Имя:"; /* NSTextField (Password:) : (oid:13) */ -"Password:" = "Password:"; +"Password:" = "Пароль:"; /* NSTextField (The user name and password you provide will be remembered for the next time you refresh this subscription.) : (oid:15) */ -"The user name and password you provide will be remembered for the next time you refresh this subscription." = "The user name and password you provide will be remembered for the next time you refresh this subscription."; +"The user name and password you provide will be remembered for the next time you refresh this subscription." = "Имя пользователя и пароль будут сохранены, так что вам не придется вводить их повторно"; diff --git a/lproj/ru.lproj/GroupFolder.nib/designable.nib b/lproj/ru.lproj/GroupFolder.nib/designable.nib index 9677f5591f..434bbb6b16 100644 --- a/lproj/ru.lproj/GroupFolder.nib/designable.nib +++ b/lproj/ru.lproj/GroupFolder.nib/designable.nib @@ -1,500 +1,91 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - NewGroupFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{517, 338}, {535, 250}} - 1886912512 - Панель - - NSPanel - - - View - - - {213, 107} - - - 256 - - - - 260 - {{91, 160}, {354, 17}} - - - YES - - 67108864 - 4194304 - Новая Группа - - LucidaGrande-Bold - 13 - 2072 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 258 - {{106, 114}, {348, 22}} - - - YES - - -1804599231 - 272630784 - - - LucidaGrande - 13 - 1044 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{338, 60}, {110, 32}} - - - 100 - YES - - 67108864 - 134217728 - Сохранить - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{249, 60}, {89, 32}} - - - YES - - 67108864 - 134217728 - Отмена - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 268 - {{17, 191}, {353, 14}} - - - YES - - 67108864 - 4194304 - RW50ZXIgdGhlIGdyb3VwIGZvbGRlciBuYW1lOgo - - LucidaGrande - 11 - 3100 - - - - - - NO - - - {535, 250} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - - - - newGroupFolderWindow - - - - 18 - - - - doCancel: - - - - 25 - - - - doSave: - - - - 26 - - - - folderName - - - - 27 - - - - cancelButton - - - - 28 - - - - saveButton - - - - 29 - - - - window - - - - 30 - - - - nextKeyView - - - - 24 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 5 - - - - - - GroupFolder - - - 6 - - - - - - - - - - - - 19 - - - - - - - - 20 - - - - - - - - 21 - - - - - - - - 22 - - - - - - - - 23 - - - - - - - - 32 - - - - - 33 - - - - - 34 - - - - - 35 - - - - - 36 - - - - - -3 - - - Application - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 36 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - NewGroupFolder - NSWindowController - - id - id - - - - doCancel: - id - - - doSave: - id - - - - NSButton - NSTextField - NSWindow - NSButton - - - - cancelButton - NSButton - - - folderName - NSTextField - - - newGroupFolderWindow - NSWindow - - - saveButton - NSButton - - - - IBProjectSource - ./Classes/NewGroupFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Введите название группы: + + + + + + + + + + diff --git a/lproj/ru.lproj/GroupFolder.nib/keyedobjects.nib b/lproj/ru.lproj/GroupFolder.nib/keyedobjects.nib index 44aca342e0..62979a62e7 100644 Binary files a/lproj/ru.lproj/GroupFolder.nib/keyedobjects.nib and b/lproj/ru.lproj/GroupFolder.nib/keyedobjects.nib differ diff --git a/lproj/ru.lproj/GroupFolder.strings b/lproj/ru.lproj/GroupFolder.strings index 5d672739f2..40648978ca 100644 --- a/lproj/ru.lproj/GroupFolder.strings +++ b/lproj/ru.lproj/GroupFolder.strings @@ -1,16 +1,16 @@ /* NSButton (Cancel) : (oid:22) */ -"Cancel" = "Cancel"; +"Cancel" = "Отмена"; /* NSTextField (Enter the group folder name: ) : (oid:23) */ -"Enter the group folder name:\n" = "Enter the group folder name:\n"; +"Enter the group folder name:\n" = "Введите название группы:\n"; /* NSTextField (New Group Folder) : (oid:19) */ -"New Group Folder" = "New Group Folder"; +"New Group Folder" = "Новая группа"; /* NSPanel (Panel) : (oid:5) */ "Panel" = "Panel"; /* NSButton (Save) : (oid:21) */ -"Save" = "Save"; +"Save" = "Сохранить"; diff --git a/lproj/ru.lproj/InfoPlist.strings b/lproj/ru.lproj/InfoPlist.strings deleted file mode 100644 index 755c942e8d..0000000000 --- a/lproj/ru.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ -NSHumanReadableCopyright = "© 2004-2013 Участники проекта. Смотрите раздел Справка/Благодарности, чтобы узнать список участников."; diff --git a/lproj/ru.lproj/InfoWindow.nib/designable.nib b/lproj/ru.lproj/InfoWindow.nib/designable.nib index 85c5f1c2ac..9c6dede1d8 100644 --- a/lproj/ru.lproj/InfoWindow.nib/designable.nib +++ b/lproj/ru.lproj/InfoWindow.nib/designable.nib @@ -1,2633 +1,378 @@ - - - - 1060 - 13E28 - 940 - 1265.21 - 698.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 940 - - - YES - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - YES - - InfoWindow - - - FirstResponder - - - NSApplication - - - 7 - 2 - {{100, 100}, {270, 498}} - 1886912512 - Window - - NSWindow - - - View - - - {1.7976931348623157e+308, 1.7976931348623157e+308} - {270, 461} - - - 256 - - YES - - - 270 - {{43, 471}, {220, 17}} - - YES - - 69206081 - 272632320 - (Folder name) - - .LucidaGrandeUI-Bold - 13 - 2064 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - 1 - - - - 268 - {{43, 454}, {98, 14}} - - YES - - 67108864 - 272629760 - Last Refreshed: - - .LucidaGrandeUI - 11 - 3088 - - - - - 6 - System - disabledControlTextColor - - 3 - MC4zMzMzMzMzMzMzAA - - - - NO - 1 - - - - 270 - {{130, 454}, {133, 14}} - - YES - - 67108928 - 272632320 - (Last refresh date) - - - - - - NO - 1 - - - - 268 - - YES - - YES - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple PNG pasteboard type - NSFilenamesPboardType - NeXT Encapsulated PostScript v1.2 pasteboard type - NeXT TIFF v4.0 pasteboard type - - - {{15, 467}, {16, 16}} - - YES - - 0 - 33554432 - 0 - 0 - 0 - NO - - NO - YES - - - - 266 - - YES - - - 274 - {{10, 23}, {240, 58}} - - YES - - -1805647871 - 272760832 - - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - 1 - - - - 257 - {{140, -6}, {110, 28}} - - YES - - 67108864 - 134348800 - Validate - - - -2038284288 - 1 - - - - - - 200 - 25 - - NO - - - {{5, 125}, {250, 81}} - - SNDisclosableView - - - - 268 - {{5, 214}, {80, 18}} - - YES - - 67108864 - 0 - Feed URL: - - .LucidaGrandeUI - 13 - 1040 - - - -935575552 - 6 - - - 200 - 25 - - NO - - - - 266 - - YES - - - 256 - {{9, 61}, {60, 13}} - - YES - - 67108864 - 71303168 - User name: - - .LucidaGrandeUI - 10 - 2832 - - - - - - NO - 1 - - - - 256 - {{9, 39}, {60, 13}} - - YES - - 67108864 - 71303168 - UGFzc3dvcmQ6Cg - - - - - - NO - 1 - - - - 258 - {{72, 59}, {163, 19}} - - YES - - -1804599231 - 272761856 - - - - YES - - - - NO - 1 - - - - 258 - {{72, 36}, {163, 19}} - - YES - - -1804599231 - 272761856 - - - - YES - - - - NO - 1 - - - - 256 - {{86, 4}, {154, 28}} - - YES - - 67108864 - 134348800 - Update Authentication - - - -2038284288 - 1 - - LucidaGrande - 11 - 16 - - - - - - 200 - 25 - - NO - - - {{15, 8}, {235, 78}} - - SNDisclosableView - - - - 268 - {{5, 94}, {114, 18}} - - YES - - 67108864 - 0 - Authentication: - - - -935575552 - 6 - - - 200 - 25 - - NO - - - - 266 - - YES - - - 256 - {{17, 70}, {42, 14}} - - YES - - 67108864 - 71434240 - Size: - - - - - - NO - 1 - - - - 256 - {{17, 52}, {46, 14}} - - YES - - 67108864 - 71434240 - VW5yZWFkOgo - - - - - - NO - 1 - - - - 256 - {{66, 70}, {80, 14}} - - YES - - 67108864 - 272629760 - Cg - - - - - - NO - 1 - - - - 256 - {{66, 52}, {80, 14}} - - YES - - 67108864 - 272629760 - Cg - - - - - - NO - 1 - - - - 256 - {{66, 28}, {101, 18}} - - YES - - 67108864 - 131072 - Subscribed - - - 1211912448 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - NO - - - - 256 - {{66, 8}, {156, 18}} - - YES - - 67108864 - 131072 - Load Full HTML Articles - - - 1211912448 - 2 - - - - 200 - 25 - - NO - - - {{15, 246}, {240, 84}} - - SNDisclosableView - - - - 268 - {{5, 338}, {80, 18}} - - YES - - 67108864 - 0 - General: - - - -935575552 - 6 - - - 200 - 25 - - NO - - - - 266 - - YES - - - 274 - {{11, 0}, {242, 58}} - - YES - - 67108864 - 272629760 - - - - - - - NO - 1 - - - {{5, 362}, {250, 58}} - - SNDisclosableView - - - - 268 - {{5, 428}, {94, 18}} - - YES - - 67108864 - 0 - Description: - - - -935575552 - 6 - - - 200 - 25 - - NO - - - - 258 - {{0, 446}, {270, 5}} - - {0, 0} - - 67108864 - 0 - Box - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - 3 - 2 - 0 - NO - - - - 258 - {{0, 356}, {270, 5}} - - {0, 0} - - 67108864 - 0 - Box - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - 3 - 2 - 0 - NO - - - - 258 - {{0, 235}, {270, 5}} - - {0, 0} - - 67108864 - 0 - Box - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - 3 - 2 - 0 - NO - - - - 258 - {{0, 115}, {270, 5}} - - {0, 0} - - 67108864 - 0 - Box - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - 3 - 2 - 0 - NO - - - {270, 498} - - {{0, 0}, {1920, 1178}} - {270, 483} - {1.7976931348623157e+308, 1.7976931348623157e+308} - YES - - - - - YES - - - window - - - - 14 - - - - toggleDisclosure: - - - - 39 - - - - urlField - - - - 40 - - - - folderName - - - - 41 - - - - folderImage - - - - 42 - - - - lastRefreshDate - - - - 43 - - - - toggleDisclosure: - - - - 46 - - - - username - - - - 55 - - - - password - - - - 56 - - - - nextKeyView - - - - 58 - - - - validateURL: - - - - 63 - - - - toggleDisclosure: - - - - 66 - - - - folderSize - - - - 71 - - - - folderUnread - - - - 72 - - - - isSubscribed - - - - 77 - - - - toggleDisclosure: - - - - 80 - - - - folderDescription - - - - 82 - - - - initialFirstResponder - - - - 83 - - - - nextKeyView - - - - 86 - - - - nextKeyView - - - - 87 - - - - urlFieldChanged: - - - - 88 - - - - subscribedChanged: - - - - 89 - - - - validateButton - - - - 90 - - - - nextKeyView - - - - 92 - - - - nextKeyView - - - - 93 - - - - authenticationChanged: - - - - 94 - - - - loadFullHTML - - - - 129 - - - - loadFullHTMLChanged: - - - - 130 - - - - nextKeyView - - - - 131 - - - - nextKeyView - - - - 132 - - - - - YES - - 0 - - YES - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 5 - - - YES - - - - Info Window - - - 6 - - - YES - - - - - - - - - - - - - - - - - - - - - 32 - - - YES - - - - - - 33 - - - YES - - - - - - 34 - - - YES - - - - - - 35 - - - YES - - - - - - 36 - - - YES - - - - - - - 37 - - - YES - - - - - - 62 - - - YES - - - - - - 38 - - - YES - - - - - - 44 - - - YES - - - - - - - - - - 51 - - - YES - - - - - - 52 - - - YES - - - - - - 53 - - - YES - - - - - - 54 - - - YES - - - - - - 91 - - - YES - - - - - - 45 - - - YES - - - - - - 64 - - - YES - - - - - - - - - - - 67 - - - YES - - - - - - 68 - - - YES - - - - - - 69 - - - YES - - - - - - 70 - - - YES - - - - - - 76 - - - YES - - - - - - 65 - - - YES - - - - - - 78 - - - YES - - - - - - 81 - - - YES - - - - - - 79 - - - YES - - - - - - 95 - - - YES - - - 256 - {{2, 2}, {125, 1}} - - - - - - 96 - - - - - 97 - - - YES - - - 256 - {{2, 2}, {125, 1}} - - - - - - 98 - - - - - 99 - - - YES - - - 256 - {{2, 2}, {125, 1}} - - - - - - 100 - - - - - 101 - - - YES - - - 256 - {{2, 2}, {125, 1}} - - - - - - 102 - - - - - 104 - - - - - 105 - - - - - 106 - - - - - 107 - - - - - 108 - - - - - 109 - - - - - 110 - - - - - 111 - - - - - 112 - - - - - 113 - - - - - 114 - - - - - 115 - - - - - 116 - - - - - 117 - - - - - 118 - - - - - 119 - - - - - 120 - - - - - 121 - - - - - 122 - - - - - 123 - - - - - 124 - - - - - -3 - - - Application - - - 125 - - - YES - - - - - - 126 - - - - - - - YES - - YES - -3.IBPluginDependency - 100.IBPluginDependency - 100.ImportedFromIB2 - 101.IBPluginDependency - 101.ImportedFromIB2 - 102.IBPluginDependency - 102.ImportedFromIB2 - 104.IBPluginDependency - 105.IBPluginDependency - 106.IBPluginDependency - 107.IBPluginDependency - 108.IBPluginDependency - 109.IBPluginDependency - 110.IBPluginDependency - 111.IBPluginDependency - 112.IBPluginDependency - 113.IBPluginDependency - 114.IBPluginDependency - 115.IBPluginDependency - 116.IBPluginDependency - 117.IBPluginDependency - 118.IBPluginDependency - 119.IBPluginDependency - 120.IBPluginDependency - 121.IBPluginDependency - 122.IBPluginDependency - 123.IBPluginDependency - 124.IBPluginDependency - 125.IBPluginDependency - 125.ImportedFromIB2 - 126.IBPluginDependency - 32.IBPluginDependency - 32.ImportedFromIB2 - 33.IBPluginDependency - 33.ImportedFromIB2 - 34.IBPluginDependency - 34.ImportedFromIB2 - 35.IBPluginDependency - 35.ImportedFromIB2 - 36.IBAttributePlaceholdersKey - 36.IBPluginDependency - 36.ImportedFromIB2 - 37.IBPluginDependency - 37.ImportedFromIB2 - 38.CustomClassName - 38.IBPluginDependency - 38.ImportedFromIB2 - 44.IBAttributePlaceholdersKey - 44.IBPluginDependency - 44.ImportedFromIB2 - 45.CustomClassName - 45.IBPluginDependency - 45.ImportedFromIB2 - 5.IBEditorWindowLastContentRect - 5.IBPluginDependency - 5.IBViewEditorWindowController.showingBoundsRectangles - 5.IBWindowTemplateEditedContentRect - 5.ImportedFromIB2 - 5.windowTemplate.hasMinSize - 5.windowTemplate.maxSize - 5.windowTemplate.minSize - 51.IBPluginDependency - 51.ImportedFromIB2 - 52.IBPluginDependency - 52.ImportedFromIB2 - 53.IBPluginDependency - 53.ImportedFromIB2 - 54.CustomClassName - 54.IBPluginDependency - 54.ImportedFromIB2 - 6.IBPluginDependency - 6.ImportedFromIB2 - 62.IBPluginDependency - 62.ImportedFromIB2 - 64.IBAttributePlaceholdersKey - 64.IBPluginDependency - 64.ImportedFromIB2 - 65.CustomClassName - 65.IBPluginDependency - 65.ImportedFromIB2 - 67.IBPluginDependency - 67.ImportedFromIB2 - 68.IBPluginDependency - 68.ImportedFromIB2 - 69.IBPluginDependency - 69.ImportedFromIB2 - 70.IBPluginDependency - 70.ImportedFromIB2 - 76.IBPluginDependency - 76.ImportedFromIB2 - 78.IBAttributePlaceholdersKey - 78.IBPluginDependency - 78.ImportedFromIB2 - 79.CustomClassName - 79.IBPluginDependency - 79.ImportedFromIB2 - 81.IBPluginDependency - 81.ImportedFromIB2 - 91.IBPluginDependency - 91.ImportedFromIB2 - 95.IBPluginDependency - 95.ImportedFromIB2 - 96.IBPluginDependency - 96.ImportedFromIB2 - 97.IBPluginDependency - 97.ImportedFromIB2 - 98.IBPluginDependency - 98.ImportedFromIB2 - 99.IBPluginDependency - 99.ImportedFromIB2 - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - - IBUserDefinedRuntimeAttributesPlaceholderName - - IBUserDefinedRuntimeAttributesPlaceholderName - - - YES - - com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.number - isShown - - - - com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.number - hiddenHeight - - YES - - - - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - SNDisclosureButton - com.apple.InterfaceBuilder.CocoaPlugin - - - IBUserDefinedRuntimeAttributesPlaceholderName - - IBUserDefinedRuntimeAttributesPlaceholderName - - - YES - - com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.number - isShown - - - - com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.number - hiddenHeight - - YES - - - - - com.apple.InterfaceBuilder.CocoaPlugin - - SNDisclosureButton - com.apple.InterfaceBuilder.CocoaPlugin - - {{389, 226}, {270, 498}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{389, 226}, {270, 498}} - - - {3.40282e+38, 3.40282e+38} - {270, 461} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - NSSecureTextField - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - - IBUserDefinedRuntimeAttributesPlaceholderName - - IBUserDefinedRuntimeAttributesPlaceholderName - - - YES - - com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.number - isShown - - - - com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.number - hiddenHeight - - YES - - - - - com.apple.InterfaceBuilder.CocoaPlugin - - SNDisclosureButton - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - - IBUserDefinedRuntimeAttributesPlaceholderName - - IBUserDefinedRuntimeAttributesPlaceholderName - - - YES - - com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.number - isShown - - - - com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.number - hiddenHeight - - YES - - - - - com.apple.InterfaceBuilder.CocoaPlugin - - SNDisclosureButton - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - - - - YES - - - YES - - - - - YES - - - YES - - - - 132 - - - - YES - - FirstResponder - NSObject - - IBUserSource - - - - - InfoWindow - NSWindowController - - YES - - YES - authenticationChanged: - loadFullHTMLChanged: - subscribedChanged: - urlFieldChanged: - validateURL: - - - YES - id - id - id - id - id - - - - YES - - YES - authenticationChanged: - loadFullHTMLChanged: - subscribedChanged: - urlFieldChanged: - validateURL: - - - YES - - authenticationChanged: - id - - - loadFullHTMLChanged: - id - - - subscribedChanged: - id - - - urlFieldChanged: - id - - - validateURL: - id - - - - - YES - - YES - folderDescription - folderImage - folderName - folderSize - folderUnread - isSubscribed - lastRefreshDate - loadFullHTML - password - urlField - username - validateButton - - - YES - NSTextField - NSImageView - NSTextField - NSTextField - NSTextField - NSButton - NSTextField - NSButton - NSSecureTextField - NSTextField - NSTextField - NSButton - - - - YES - - YES - folderDescription - folderImage - folderName - folderSize - folderUnread - isSubscribed - lastRefreshDate - loadFullHTML - password - urlField - username - validateButton - - - YES - - folderDescription - NSTextField - - - folderImage - NSImageView - - - folderName - NSTextField - - - folderSize - NSTextField - - - folderUnread - NSTextField - - - isSubscribed - NSButton - - - lastRefreshDate - NSTextField - - - loadFullHTML - NSButton - - - password - NSSecureTextField - - - urlField - NSTextField - - - username - NSTextField - - - validateButton - NSButton - - - - - IBProjectSource - src/InfoWindow.h - - - - InfoWindow - NSWindowController - - IBUserSource - - - - - NSObject - - IBProjectSource - 3rdparty/DSClickableURLTextField/DSClickableURLTextField.h - - - - NSObject - - IBProjectSource - src/FolderView.h - - - - NSObject - - IBProjectSource - src/TableViewExtensions.h - - - - NSObject - - IBProjectSource - src/ViewExtensions.h - - - - NSView - - - - NSWindow - - IBProjectSource - src/SquareWindow.h - - - - SNDisclosableView - NSView - - YES - - YES - hide: - show: - toggleDisclosure: - - - YES - id - id - id - - - - YES - - YES - hide: - show: - toggleDisclosure: - - - YES - - hide: - id - - - show: - id - - - toggleDisclosure: - id - - - - - IBProjectSource - 3rdparty/DisclosableView/SNDisclosableView.h - - - - SNDisclosureButton - NSButton - - IBProjectSource - 3rdparty/DisclosableView/SNDisclosureButton.h - - - - - YES - - NSActionCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSActionCell.h - - - - NSApplication - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSApplication.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSApplicationScripting.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSColorPanel.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSHelpManager.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSPageLayout.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSUserInterfaceItemSearching.h - - - - NSApplication - - IBFrameworkSource - PSMTabBarControl.framework/Headers/PSMTabDragAssistant.h - - - - NSBox - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSBox.h - - - - NSButton - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSButton.h - - - - NSButtonCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSButtonCell.h - - - - NSCell - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSCell.h - - - - NSControl - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSControl.h - - - - NSFormatter - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFormatter.h - - - - NSImageCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSImageCell.h - - - - NSImageView - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSImageView.h - - - - NSMenu - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenu.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSAccessibility.h - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDictionaryController.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDragging.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontManager.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontPanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSKeyValueBinding.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSNibLoading.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSOutlineView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSPasteboard.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSSavePanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTableView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSToolbarItem.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSView.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObjectScripting.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSPortCoder.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptObjectSpecifiers.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptWhoseTests.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLConnection.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLDownload.h - - - - NSObject - - IBFrameworkSource - PSMTabBarControl.framework/Headers/PSMTabBarCell.h - - - - NSObject - - IBFrameworkSource - Sparkle.framework/Headers/SUAppcast.h - - - - NSObject - - IBFrameworkSource - Sparkle.framework/Headers/SUUpdater.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebDownload.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebEditingDelegate.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebFrameLoadDelegate.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebJavaPlugIn.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebPlugin.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebPluginContainer.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebPolicyDelegate.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebResourceLoadDelegate.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebScriptObject.h - - - - NSObject - - IBFrameworkSource - WebKit.framework/Headers/WebUIDelegate.h - - - - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSInterfaceStyle.h - - - - NSResponder - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSResponder.h - - - - NSSecureTextField - NSTextField - - IBFrameworkSource - AppKit.framework/Headers/NSSecureTextField.h - - - - NSTextField - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSTextField.h - - - - NSTextFieldCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSTextFieldCell.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSClipView.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItem.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSRulerView.h - - - - NSView - NSResponder - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSDrawer.h - - - - NSWindow - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSWindow.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSWindowScripting.h - - - - NSWindowController - NSResponder - - showWindow: - id - - - showWindow: - - showWindow: - id - - - - IBFrameworkSource - AppKit.framework/Headers/NSWindowController.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - ../../Vienna.xcodeproj - 3 - - NSSwitch - {15, 15} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Password: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Cg + + + + + + + + + + + +Cg + + + + + + + + + + + Unread: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/ru.lproj/InfoWindow.nib/keyedobjects.nib b/lproj/ru.lproj/InfoWindow.nib/keyedobjects.nib index ad117e6108..177509c9a7 100644 Binary files a/lproj/ru.lproj/InfoWindow.nib/keyedobjects.nib and b/lproj/ru.lproj/InfoWindow.nib/keyedobjects.nib differ diff --git a/lproj/ru.lproj/InfoWindow.strings b/lproj/ru.lproj/InfoWindow.strings index d4c71d23a9..668fea7c77 100644 --- a/lproj/ru.lproj/InfoWindow.strings +++ b/lproj/ru.lproj/InfoWindow.strings @@ -18,34 +18,34 @@ "104.title" = "(Folder name)"; /* Class = "NSTextFieldCell"; title = "Last Refreshed:"; ObjectID = "105"; */ -"105.title" = "Last Refreshed:"; +"105.title" = "Обновлена:"; /* Class = "NSTextFieldCell"; title = "(Last refresh date)"; ObjectID = "106"; */ "106.title" = "(Last refresh date)"; /* Class = "NSButtonCell"; title = "Validate"; ObjectID = "109"; */ -"109.title" = "Validate"; +"109.title" = "Проверить"; /* Class = "NSButtonCell"; title = "Feed URL:"; ObjectID = "110"; */ -"110.title" = "Feed URL:"; +"110.title" = "URL ленты:"; /* Class = "NSTextFieldCell"; title = "User name:"; ObjectID = "111"; */ -"111.title" = "User name:"; +"111.title" = "Имя:"; /* Class = "NSTextFieldCell"; title = "Password:\n"; ObjectID = "112"; */ -"112.title" = "Password:\n"; +"112.title" = "Пароль:\n"; /* Class = "NSButtonCell"; title = "Update Authentication"; ObjectID = "115"; */ -"115.title" = "Update Authentication"; +"115.title" = "Авторизироваться"; /* Class = "NSButtonCell"; title = "Authentication:"; ObjectID = "116"; */ -"116.title" = "Authentication:"; +"116.title" = "Авторизация:"; /* Class = "NSTextFieldCell"; title = "Size:"; ObjectID = "117"; */ -"117.title" = "Size:"; +"117.title" = "Статей:"; /* Class = "NSTextFieldCell"; title = "Unread:\n"; ObjectID = "118"; */ -"118.title" = "Unread:\n"; +"118.title" = "Новых:\n"; /* Class = "NSTextFieldCell"; title = "\n"; ObjectID = "119"; */ "119.title" = "\n"; @@ -54,13 +54,13 @@ "120.title" = "\n"; /* Class = "NSButtonCell"; title = "Subscribed"; ObjectID = "121"; */ -"121.title" = "Subscribed"; +"121.title" = "Подписка"; /* Class = "NSButtonCell"; title = "General:"; ObjectID = "122"; */ -"122.title" = "General:"; +"122.title" = "Общие:"; /* Class = "NSButtonCell"; title = "Description:"; ObjectID = "124"; */ -"124.title" = "Description:"; +"124.title" = "Описание:"; /* Class = "NSButtonCell"; title = "Load Full HTML Articles"; ObjectID = "126"; */ -"126.title" = "Load Full HTML Articles"; +"126.title" = "Загружать весь HTML-код"; diff --git a/lproj/ru.lproj/KnownSyncServers.plist b/lproj/ru.lproj/KnownSyncServers.plist index 7b5ee435f8..985752f511 100644 --- a/lproj/ru.lproj/KnownSyncServers.plist +++ b/lproj/ru.lproj/KnownSyncServers.plist @@ -1,5 +1,5 @@ - + BazQux @@ -7,35 +7,35 @@ Address www.bazqux.com Hint - Enter the info you set in BazQux's 'Mobile login' settings + Введите информацию из настроек BazQux's 'Mobile login' FeedHQ Address feedhq.org Hint - Enter email address and password associated to your FeedHQ account + Введите email и пароль от вашего аккаунта FeedHQ InoReader Address www.inoreader.com Hint - Enter username and password associated to your InoReader account + Введите имя пользователя и пароль от вашего аккаунта InoReader TheOldReader Address theoldreader.com Hint - Enter username and password defined in Settings/General section of theoldreader.com + Введите имя пользователя и пароль, указанные в разделе Settings/General ресурса theoldreader.com Иное Address Hint - Enter server's address and your credentials for this server + Введите адрес сервера и ваши учетные данные для этого сервера diff --git a/lproj/ru.lproj/Localizable.strings b/lproj/ru.lproj/Localizable.strings index f84a24ad27..3efa894f56 100644 --- a/lproj/ru.lproj/Localizable.strings +++ b/lproj/ru.lproj/Localizable.strings @@ -1,24 +1,24 @@ -"Mark Read" = "Отметить как Прочитанное"; -"Mark Unread" = "Снять Пометку о Прочтении"; +"Mark Read" = "Отметить как прочитанное"; +"Mark Unread" = "Снять отметку о прочтении"; "Mark Unflagged" = "Снять флаг"; "Articles" = "Статьи"; "Folders" = "Папки"; "Loading %@..." = "Загрузка %@..."; "Completed" = "Завершено"; "Refresh RSS feeds" = "Обновить подписки"; -"Refresh All Subscriptions" = "Обновить Все Подписки"; +"Refresh All Subscriptions" = "Обновить все подписки"; "Already subscribed title" = "Ошибка"; "Already subscribed body" = "Вы уже подписаны на данный канал"; -"RSS Subscription Import Title" = "Импортирование Завершено"; +"RSS Subscription Import Title" = "Импортирование завершено"; "%d subscriptions successfully imported" = "Успешно импортировано %d каналов"; -"RSS Subscription Export Title" = "Экспортирование Завершено"; +"RSS Subscription Export Title" = "Экспортирование завершено"; "%d subscriptions successfully exported" = "Успешно экспортировано %d каналов"; "New unread articles retrieved" = "Получено %d новых статей"; -"Growl refresh completed" = "Новые Статьи"; -"New articles retrieved" = "Новые Статьи"; +"Growl refresh completed" = "Новые статьи"; +"New articles retrieved" = "Новые статьи"; "(Untitled Feed)" = "без имени"; -"Open Link in Browser" = "Открыть Ссылку в Браузере"; -"Copy Link to Clipboard" = "Копировать Ссылку в Буфер Обмена"; +"Open Link in Browser" = "Открыть ссылку в браузере"; +"Copy Link to Clipboard" = "Копировать ссылку в буфер обмена"; "Refresh completed" = "Обновление завершено"; "Retrieving articles" = "Загружаю статьи"; "ClearButton" = "Очистить"; @@ -39,7 +39,7 @@ "No" = "Нет"; "Yes" = "Да"; "Version %@" = "Версия %@"; -"Refresh All" = "Обновить Все"; +"Refresh All" = "Обновить все"; "Subscribe" = "Подписаться"; "Smart Folder" = "Смарт-папка"; "Flag" = "Метка"; @@ -55,9 +55,9 @@ "Additional actions for the selected folder" = "Дополнительные действия для выбранной папки"; "Create a new subscription" = "Создать новую подписку"; "Refresh all your subscriptions" = "Обновить все подписки"; -"New style title" = "Vienna установила новый Стиль"; +"New style title" = "Vienna установила новый стиль"; "New style body" = "Стиль \"%@\" был установлен в папку стилей и добавлен в меню Стиль."; -"More Styles..." = "Больше Стилей..."; +"More Styles..." = "Больше стилей..."; "Delete selected message" = "Вы уверены, что хотите безвозвратно удалить выбранные статьи?"; "Delete selected message text" = "Это действие не может быть отменено."; "Cancel" = "Отмена"; @@ -105,20 +105,20 @@ "Update available text" = "Версия %@ программы Vienna доступна для загрузки с:\n\n%@\n\nЗагрузить ее сейчас? Ее так же можно будет загрузить позже, выбрав Проверить Обновления."; "any" = "любое"; "all" = "все"; -"Open Scripts Folder" = "Открыть Папку Скриптов"; +"Open Scripts Folder" = "Открыть папку скриптов"; "Cannot create database folder" = "Извините, но Vienna не смогла создать папку базы данных"; "Cannot create database folder text" = "Vienna попыталась создать папку \"%@\", но произошла ошибка. Проверьте разрешения для папок в указанном пути."; "Unrecognised database format title" = "Формат базы данных изменился"; "Unrecognised database format text" = "Формат базы данных (%@) не поддерживается текущей версией Vienna. Удалите или переименуйте этот файл и перезапустите программу.\n"; -"Upgrade Title" = "Обновление Базы"; +"Upgrade Title" = "Обновление базы"; "Upgrade Text" = "Существующая база данных должна быть обновлена для работы с данной версией Vienna. Или же вы можете создать новую, пустую базу данных. В любом случае ваша текущая база данных будет заархивирована в %@. Новые или обновленные базы НЕ БУДУТ работать с предыдущими версиями Vienna.\n\nЗаметка: для этого билда рекомендуется создать новую базу.\n"; -"New Database" = "Новая База Данных"; +"New Database" = "Новая база данных"; "Upgrade" = "Обновление"; "Exit" = "Выход"; -"Search in %@" = "Поиск в in %@"; -"Marked Articles" = "Отмеченные Статьи"; -"Unread Articles" = "Непрочитанные Статьи"; -"Today's Articles" = "Сегодняшние Статьи"; +"Search in %@" = "Поиск в %@"; +"Marked Articles" = "Отмеченные статьи"; +"Unread Articles" = "Непрочитанные статьи"; +"Today's Articles" = "Сегодняшние статьи"; "Trash" = "Корзина"; "Select..." = "Выбрать..."; " (%d unread)" = " (%d непрочитанных)"; @@ -145,53 +145,53 @@ "Enter URL of RSS feed" = "Введите URL новостного канала"; "Cannot rename folder" = "Невозможно переименовать папку"; "A folder with that name already exists" = "Папка с данным именем уже существует"; -"Recent Searches" = "История Поиска"; +"Recent Searches" = "История поиска"; "Recents" = "Журнал"; -"Clear" = "Очистить Историю Поиска"; +"Clear" = "Очистить историю поиска"; "Search web page" = "Поиск в сети"; "Loading..." = "Загрузка..."; -"Open Image in New Tab" = "Открыть Изображение в Новой Вкладке"; -"Open Link in New Tab" = "Открыть Ссылку в Новой Вкладке"; -"Open Link in %@" = "Открыть Ссылку в %@"; -"Open Page in %@" = "Открыть Страницу в %@"; -"Copy Page Link to Clipboard" = "Копировать Ссылку в Буфер Обмена"; +"Open Image in New Tab" = "Открыть изображение в новой вкладке"; +"Open Link in New Tab" = "Открыть ссылку в новой вкладке"; +"Open Link in %@" = "Открыть ссылку в %@"; +"Open Page in %@" = "Открыть страницу в %@"; +"Copy Page Link to Clipboard" = "Копировать ссылку в буфер обмена"; "%d unread articles" = "%d непрочитанных статей"; -"More Scripts..." = "Больше Скриптов..."; -"Install Update" = "Установить Обновление"; -"Do Not Install" = "Не Устанавливать"; +"More Scripts..." = "Больше скриптов..."; +"Install Update" = "Установить обновление"; +"Do Not Install" = "Не устанавливать"; "Replace smart folder title" = "Смарт-папка %@ уже существует"; "Replace smart folder text" = "Заменить существующую Смарт-папку новой?"; "Replace" = "Заменить"; "Never" = "Никогда"; -"After a Day" = "Через День"; -"After 2 Days" = "Через 2 Дня"; -"After a Week" = "Через Неделю"; -"After 2 Weeks" = "Через 2 Недели"; -"After a Month" = "Через Месяц"; -"Last Week" = "На Прошлой Неделе"; -"2 Weeks Ago" = "2 Недели Назад"; +"After a Day" = "Через день"; +"After 2 Days" = "Через 2 дня"; +"After a Week" = "Через неделю"; +"After 2 Weeks" = "Через 2 недели"; +"After a Month" = "Через месяц"; +"Last Week" = "На прошлой неделе"; +"2 Weeks Ago" = "2 недели назад"; "A month" = "Месяц"; -"Activity Window" = "Окно Действий"; +"Activity Window" = "Окно действий"; "Error importing subscriptions body" = "Невозможно импортировать указанный файл. Содержимое файла не является корректными данными формата OPML XML."; "Error importing subscriptions title" = "Ошибка импортирования"; "Rename" = "Переименовать"; -"Mark All Read" = "Отметить Все как Прочитанные"; -"Move Folders" = "Переместить Папки"; +"Mark All Read" = "Отметить все как прочитанные"; +"Move Folders" = "Переместить папки"; "Downloads" = "Загрузки"; "Invalid style title" = "Стиль %@ отсутствует или поврежден"; -"Invalid style body" = "Будет использован Стиль по умолчанию."; +"Invalid style body" = "Будет использован стиль по умолчанию."; "Downloads Running" = "Одна или более загрузок еще не завершена"; "Downloads Running text" = "Если вы сейчас выйдете из Vienna, все загрузки будут остановлены."; -"Mark All Subscriptions as Read" = "Отметить Все Подписки Как Прочитанные"; +"Mark All Subscriptions as Read" = "Отметить все подписки как прочитанные"; "Preferences" = "Настройки"; "General" = "Общие"; -"Appearance" = "Внешний Вид"; +"Appearance" = "Внешний вид"; "Locate Title" = "Невозможно создать базу данных Vienna"; "Locate Text" = "Новая база данных Vienna не может быть создана в \"%@\" из-за того, что папка, возможно, находится на удаленном сервере, а текущая версия Vienna не может работать с удаленными базами данных. Пожалуйста, выберите папку на своем компьютере.\n"; "Empty Trash message" = "Удалить все сообщения в Корзине?"; "Empty Trash message text" = "Данное действие невозможно отменить"; "Cannot open database" = "Извините, но Vienna не смогла открыть базу данных"; -"Cannot open database text" = "Файл базы данных (%@) не может быть открыт. Он может быть поврежден или недоступен. PleaseПожалуйста, удалите или переименуйте файл базы данных и перезапустите Vienna."; +"Cannot open database text" = "Файл базы данных (%@) не может быть открыт. Он может быть поврежден или недоступен. Пожалуйста, удалите или переименуйте файл базы данных и перезапустите Vienna."; "Vienna cannot open the file title" = "Vienna не может открыть этот файл."; "Vienna cannot open the file body" = "Vienna не может открыть файл \"%@\" потому что он был перемещен после загрузки."; "Vienna cannot show the file title" = "Vienna не может отобразить файл."; @@ -213,103 +213,103 @@ "Article" = "Статья"; "Back" = "Назад"; "Bring All to Front" = "Все окна – на передний план"; -"Check Spelling" = "Проверить Правописание"; -"Check Spelling as You Type" = "Проверять Правописание при Наборе Текста"; -"Check for Updates" = "Проверить Наличие Обновлений"; -"Close All Tabs" = "Закрыть Все Вкладки"; -"Close Tab" = "Закрыть Вкладку"; -"Close Window" = "Закрыть Окно"; +"Check Spelling" = "Проверить правописание"; +"Check Spelling as You Type" = "Проверять правописание при наборе текста"; +"Check for Updates" = "Проверить наличие обновлений"; +"Close All Tabs" = "Закрыть все вкладки"; +"Close Tab" = "Закрыть вкладку"; +"Close Window" = "Закрыть окно"; "Columns" = "Колонки"; "Copy" = "Копировать"; "Cut" = "Вырезать"; "Delete" = "Удалить"; -"Delete Article" = "Удалить Статью"; +"Delete Article" = "Удалить статью"; "Delete…" = "Удалить…"; "Edit" = "Правка"; "Edit…" = "Правка…"; "Empty Trash" = "Очистить Корзину"; -"Export Subscriptions…" = "Экспортировать Подписки…"; +"Export Subscriptions…" = "Экспортировать подписки…"; "File" = "Файл"; "Find" = "Найти"; -"Find Next" = "Следующее Совпадение"; -"Find Previous" = "Предыдущее Совпадение"; +"Find Next" = "Следующее совпадение"; +"Find Previous" = "Предыдущее совпадение"; "Find…" = "Найти…"; "Forward" = "Далее"; "Help" = "Справка"; -"Hide Others" = "Скрыть Другие"; +"Hide Others" = "Скрыть другие"; "Hide Vienna" = "Скрыть Vienna"; -"Import Subscriptions…" = "Импортировать Подписки…"; -"Jump to Selection" = "Перейти к Выбранному"; -"Main Window" = "Главное Окно"; -"MainMenu" = "Главное Меню"; -"Mark All Articles as Read" = "Отметить Все Статьи Как Прочитанные"; +"Import Subscriptions…" = "Импортировать подписки…"; +"Jump to Selection" = "Перейти к выбранному"; +"Main Window" = "Главное окно"; +"MainMenu" = "Главное меню"; +"Mark All Articles as Read" = "Отметить все статьи как прочитанные"; "Mark Flagged" = "Отметить"; "Minimize" = "Свернуть"; -"New Group Folder…" = "Новая Группа…"; +"New Group Folder…" = "Новая группа…"; "New Smart Folder…" = "Новая Смарт-папка…"; -"New Subscription…" = "Новая Подписка…"; -"Next Tab" = "Следующая Вкладка"; -"Open Article Page" = "Открыть Статью"; -"Open Article Page in External Browser" = "Открыть Статью во Внешнем Браузере"; -"Open Subscription Home Page" = "Открыть Страницу Подписки"; -"Open Subscription Home Page in External Browser" = "Открыть Страницу Подписки во Внешнем Браузере"; -"Page Setup…" = "Параметры Страницы…"; +"New Subscription…" = "Новая подписка…"; +"Next Tab" = "Следующая вкладка"; +"Open Article Page" = "Открыть статью"; +"Open Article Page in External Browser" = "Открыть статью во внешнем браузере"; +"Open Subscription Home Page" = "Открыть страницу подписки"; +"Open Subscription Home Page in External Browser" = "Открыть страницу подписки во внешнем браузере"; +"Page Setup…" = "Параметры страницы…"; "Paste" = "Вставить"; "Preferences…" = "Настройки…"; -"Previous Tab" = "Предыдущая Вкладка"; +"Previous Tab" = "Предыдущая вкладка"; "Print…" = "Напечатать…"; -"Quit Vienna" = "Завершать Работу Vienna"; +"Quit Vienna" = "Завершить работу Vienna"; "Redo" = "Повторить"; -"Refresh Selected Subscriptions" = "Обновить Выбранные Подписки"; -"Reload Page" = "Перезагрузить Страницу"; +"Refresh Selected Subscriptions" = "Обновить выбранные подписки"; +"Reload Page" = "Перезагрузить страницу"; "Rename…" = "Переименовать…"; -"Restore Article" = "Восстановить Статью"; -"Select All" = "Выбрать Все"; +"Restore Article" = "Восстановить статью"; +"Select All" = "Выбрать все"; "Services" = "Службы"; -"Show All" = "Отобразить Все"; -"Skip Folder" = "Пропустить Папку"; +"Show All" = "Отобразить все"; +"Skip Folder" = "Пропустить папку"; "Sort By" = "Сортировать по"; "Spelling" = "Правописание"; "Spelling…" = "Правописание…"; -"Stop Refreshing" = "Остановить Обновление"; -"Stop Reloading Page" = "Остановить Загрузку Страницы"; +"Stop Refreshing" = "Остановить обновление"; +"Stop Reloading Page" = "Остановить загрузку страницы"; "Style" = "Стиль"; "Undo" = "Отменить"; -"Use Selection for Find" = "Искать Выделенное"; -"Validate Feed" = "Проверить Канал"; +"Use Selection for Find" = "Искать выделенное"; +"Validate Feed" = "Проверить канал"; "Vienna Help" = "Справка Vienna"; -"Vienna Web Site" = "Сайт Программы Vienna"; +"Vienna Web Site" = "Сайт программы Vienna"; "View" = "Вид"; "Window" = "Окно"; "Zoom" = "Изменить масштаб"; "Export all subscriptions" = "Экспортировать все подписки"; "Export selected subscriptions" = "Экспортировать выбранные подписки"; "Preserve group folders in exported file" = "Сохранить группы в экспортируемом файле"; -"Open Frame" = "Открыть Фрейм"; -"Open Image in %@" = "Открыть Изображение в %@"; -"Open Subscription Home Page in %@" = "Открыть Страницу Подписки в %@"; -"Open Article Page in %@" = "Открыть Статью в %@"; -"New Tab" = "Новая Вкладка"; -"External Browser" = "Внешний Браузер"; +"Open Frame" = "Открыть фрейм"; +"Open Image in %@" = "Открыть изображение в %@"; +"Open Subscription Home Page in %@" = "Открыть страницу подписки в %@"; +"Open Article Page in %@" = "Открыть статью в %@"; +"New Tab" = "Новая вкладка"; +"External Browser" = "Внешний браузер"; /* Added in 2.1.0 */ -"Send Link" = "Отправить Ссылку"; -"Send Links" = "Отправить Ссылки"; -"Increase Font Size" = "Увеличить Размер Шрифта"; -"Decrease Font Size" = "Уменьшить Размер Шрифта"; +"Send Link" = "Отправить ссылку"; +"Send Links" = "Отправить ссылки"; +"Increase Font Size" = "Увеличить размер шрифта"; +"Decrease Font Size" = "Уменьшить размер шрифта"; "Enter the URL here" = "Введите URL"; "Refresh the current page" = "Обновить страницу"; "Return to the previous page" = "На предыдущую страницу"; "Go forward to the next page" = "На следующую страницу"; "Layout" = "Раскладка"; -"Reading Pane on Right" = "Панель Чтения Справа"; -"Reading Pane at Bottom" = "Панель Чтения Снизу"; +"Reading Pane on Right" = "Панель чтения справа"; +"Reading Pane at Bottom" = "Панель чтения снизу"; "Filter By" = "Показывать"; "Filter by:" = "Показывать:"; "All" = "Все"; -"All Articles" = "Все Статьи"; +"All Articles" = "Все статьи"; "Unread" = "Непрочитанное"; -"Last Refresh" = "С Последнего Обновления"; +"Last Refresh" = "С последнего обновления"; "Feed URL updated to %@" = "URL канала обновился до %@"; "Filter articles" = "Фильтровать статьи"; "Feed has been removed by the server" = "Канал был удален с сервера"; @@ -317,19 +317,19 @@ "%@ Info" = "%@ Сведения"; "%u articles" = "%u статей"; "%u unread" = "%u непрочитано"; -"Keyboard Shortcuts" = "Горячие Клавиши"; +"Keyboard Shortcuts" = "Горячие клавиши"; "%@ (Filtered: %@)" = "%@ (Фильтр: %@)"; "Get Info..." = "Сведения..."; -"Open Web Location..." = "Открыть Адрес Веб..."; -"Refresh Folder Images" = "Обновить Изображения Папки"; +"Open Web Location..." = "Открыть адрес веб..."; +"Refresh Folder Images" = "Обновить изображения папки"; "Report" = "Отчет"; "Condensed" = "Сжатая"; "Unified" = "Общая"; "Summary" = "Выводы"; -"Blog With..." = "Запись в Блог..."; -"Blog with %@" = "Запись в Блог %@"; -"Bigger Text" = "Увеличить Шрифт"; -"Smaller Text" = "Уменьшить Шрифт"; +"Blog With..." = "Запись в блог..."; +"Blog with %@" = "Запись в блог %@"; +"Bigger Text" = "Увеличить шрифт"; +"Smaller Text" = "Уменьшить шрифт"; /* Added in 2.1.1 */ "Advanced" = "Расширенные"; @@ -339,114 +339,120 @@ "Do you really want to import the subscriptions from the specified OPML file?" = "Действительно импортировать подписки из указанного файла OPML?"; "Import" = "Импорт"; "HasEnclosure" = "Вложения"; -"Enclosure" = "URL Вложения"; -"Open New Tab" = "Открыть Новую Вкладку"; +"Enclosure" = "URL вложения"; +"Open New Tab" = "Открыть новую вкладку"; "Subscribe to the feed for this page" = "Подписаться к каналу на данной странице"; "Open Vienna" = "Открыть Vienna"; -"Download Enclosure" = "Загрузить Вложение"; -"Download Enclosures" = "Загрузить Вложения"; -"Local File" = "Локальный Файл"; -"Hide Status Bar" = "Спрятать Строку Статуса"; -"Show Status Bar" = "Показать Строку Статуса"; -"Customize Toolbar..." = "Настроить Панель Инструментов"; -"Search Articles" = "Искать Статьи"; +"Download Enclosure" = "Загрузить вложение"; +"Download Enclosures" = "Загрузить вложения"; +"Local File" = "Локальный файл"; +"Hide Status Bar" = "Спрятать строку статуса"; +"Show Status Bar" = "Показать строку статуса"; +"Customize Toolbar..." = "Настроить панель инструментов"; +"Search Articles" = "Искать статьи"; "Progress" = "Прогресс"; "Delete all articles in the trash" = "Удалить все статьи в Корзине"; -"Unsubscribe" = "Unsubscribe from Feed"; -"Resubscribe" = "Resubscribe to Feed"; -"Download" = "Download"; -"This article contains an enclosed file." = "This article contains an enclosed file."; -"Growl download completed" = "File download successful"; -"Growl download failed" = "File download failed"; -"Download completed" = "Download completed"; -"File %@ downloaded" = "File %@ downloaded"; -"Download failed" = "Download failed"; -"File %@ failed to download" = "File %@ failed to download"; -"Play" = "Play"; -"Click the Play button to play this enclosure in iTunes." = "Click the Play button to play this enclosure in iTunes."; -"Click the Open button to open this file." = "Click the Open button to open this file."; -"Filter displayed articles by matching text" = "Filter displayed articles by matching text"; -"Close the filter bar" = "Close the filter bar"; -"Search all articles" = "Search all articles"; -"Search Results" = "Search Results"; -"Hide Filter Bar" = "Hide Filter Bar"; -"Show Filter Bar" = "Show Filter Bar"; -"Email a link to the current article or website" = "Email a link to the current article or website"; -"Refresh" = "Refresh"; -"Action" = "Action"; +"Unsubscribe" = "Отписаться от ленты"; +"Resubscribe" = "Возобновить подписку"; +"Download" = "Загрузка"; +"This article contains an enclosed file." = "Эта статья содержит вложенный файл."; +"Growl download completed" = "Загрузка файла успешно завершена"; +"Growl download failed" = "Ошибка загрузки файла"; +"Download completed" = "Загрузка завершена"; +"File %@ downloaded" = "Файл %@ загружен"; +"Download failed" = "Ошибка "; +"File %@ failed to download" = "Ошибка при загрузке файла %@"; +"Play" = "Воспроизведение"; +"Click the Play button to play this enclosure in iTunes." = "Нажмите кнопку Воспроизведение , для проигрывания в iTunes."; +"Click the Open button to open this file." = "Нажмите кнопку Открыть для открытия файла."; +"Filter displayed articles by matching text" = "Фильтр статей, совпадающих по тексту"; +"Close the filter bar" = "Закрыть панель фильтра"; +"Search all articles" = "Поиск в статьях"; +"Search Results" = "Результаты поиска"; +"Hide Filter Bar" = "Скрыть панель фильтра"; +"Show Filter Bar" = "Показать панель фильтра"; +"Email a link to the current article or website" = "Отправить ссылку на текущую статью или сайт"; +"Refresh" = "Обновить"; +"Action" = "Действие"; "Get Info" = "Сведения"; -"See information about the selected subscription" = "See information about the selected subscription"; -"Display the list of available styles" = "Display the list of available styles"; +"See information about the selected subscription" = "Просмотреть информацию о выбранной подписке"; +"Display the list of available styles" = "Показать список доступных стилей"; /* Added in 2.3.0 */ -"Order By" = "Order By"; -"Manual" = "Manual"; -"Name" = "Name"; +"Order By" = "Упорядочить подписки"; +"Manual" = "Вручную"; +"Name" = "По названию"; /*Added in 2.4*/ -"Show XML Source" = "Show XML Source"; -"Source of folder" = "Source of folder"; -"No feed source to display." = "No feed source to display."; -"Search current web page" = "Search current web page"; -"Search all articles or the current web page" = "Search all articles or the current web page"; -"Database Upgrade" = "Database Upgrade"; -"Vienna must upgrade its database to the latest version. This may take a minute or so. We apologize for the inconveninece." = "Vienna must upgrade its database to the latest version. This may take a minute or so. We apologize for the inconveninece."; -"Upgrade Database" = "Upgrade Database"; +"Show XML Source" = "Показать XML-код ленты"; +"Source of folder" = "Исходный код ленты"; +"No feed source to display." = "Исходный код для отображения не найден."; +"Search current web page" = "Поиск по текущей веб-странице"; +"Search all articles or the current web page" = "Поиск в статьях или по текущей веб-странице"; +"Database Upgrade" = "Обновление базы данных"; +"Vienna must upgrade its database to the latest version. This may take a minute or so. We apologize for the inconveninece." = "Vienna необходимо обновить свою базу данных до последней версии. Это может занять минуту или около того. Приносим свои извинения за доставленные неудобства."; +"Upgrade Database" = "Обновить базу данных"; /* Added in 2.5.0 */ -"Cannot create folder title" = "Cannot create folder"; -"Cannot create folder body" = "The \"%@\" folder cannot be created."; +"Cannot create folder title" = "Ошибка"; +"Cannot create folder body" = "Ошибка создания папки \"%@\"."; /* Added in 2.6.0 */ -"Article load completed" = "Article load completed"; -"Loading HTML article..." = "Loading HTML article..."; -"Ascending" = "Ascending"; -"Descending" = "Descending"; -"Use Current Style for Articles" = "Use Current Style for Articles"; -"Use Web Page for Articles" = "Use Web Page for Articles"; +"Article load completed" = "Загрузка статьи завершена"; +"Loading HTML article..." = "Загрузка HTML статьи..."; +"Ascending" = "По возрастанию"; +"Descending" = "По убыванию"; +"Use Current Style for Articles" = "Использовать текущий стиль для статьи"; +"Use Web Page for Articles" = "Использовать веб-страницу статьи"; /* Added for Open Reader support */ -"Force Refresh Selected Subscriptions From Open Reader" = "Force Refresh Selected Subscriptions From Open Reader"; -"Update Subscriptions From Open Reader" = "Update Subscriptions From Open Reader"; -"Delete Open Reader RSS feed text" = "Unsubscribing from an Open Reader RSS feed will also remove your locally cached articles."; -"Delete Open Reader RSS feed" = "Delete Open Reader RSS feed"; +"Force Refresh Selected Subscriptions From Open Reader" = "Принудительно обновить выбранные подписки из Open Reader"; +"Update Subscriptions From Open Reader" = "Обновить подписки из Open Reader"; +"Delete Open Reader RSS feed text" = "Отписывание от RSS-ленты из Open Reader, приведет к удалению статей, сохраненных локально."; +"Delete Open Reader RSS feed" = "Удалить RSS-ленту из Open Reader"; /* Added in 3.0.0 */ -"Last 48 hours" = "Last 48 hours"; -"Unread or flagged" = "Unread or flagged"; -"Syncing" = "Syncing"; -"Reindex Database" = "Reindex Database"; +"Last 48 hours" = "Последние 48 часов"; +"Unread or flagged" = "Непрочитанные или отмеченные"; +"Syncing" = "Синхронизации"; +"Reindex Database" = "Проиндексировать базу данных"; "Other" = "Иное"; -"Authenticating on Open Reader" = "Authenticating on Open Reader"; -"Connecting to Open Reader server to retrieve %@" = "Connecting to Open Reader server to retrieve %@"; -"Retrieving folder image for Open Reader Feed" = "Retrieving folder image for Open Reader Feed"; -"Fetching Open Reader Subscriptions..." = "Fetching Open Reader Subscriptions..."; -"Open Reader Authentication Failed" = "Open Reader Authentication Failed"; -"Open Reader Authentication Failed text" = "Make sure the username and password needed to access the Open Reader server are correctly set in Vienna's preferences.\nAlso check your network access."; +"Authenticating on Open Reader" = "Авторизация в Open Reader"; +"Connecting to Open Reader server to retrieve %@" = "Соединение с сервером Open Reader для получения %@"; +"Retrieving folder image for Open Reader Feed" = "Получение иконки для Open Reader подписки"; +"Fetching Open Reader Subscriptions..." = "Открытие Open Reader подписки..."; +"Open Reader Authentication Failed" = "В авторизации в Open Reader отказано"; +"Open Reader Authentication Failed text" = "Убедитесь, что в настройках Vienna указаны правильные имя пользователя и пароль для доступа к серверу Open Reader.\nТакже проверьте сетевое соединение."; /* Added in 3.0.1 */ -"Plugin installed" = "Plugin installed"; -"A new plugin has been installed. It is now available from the menu and you can add it to the toolbar." = "A new plugin has been installed. It is now available from the menu and you can add it to the toolbar."; -"Error loading script '%@'" = "Error loading script '%@'"; -"AppleScript Error in '%@' script" = "AppleScript Error in '%@' script"; -"No thanks" = "No thanks"; -"Include anonymous system profile when checking for updates?" = "Include anonymous system profile when checking for updates?"; -"Include anonymous system profile when checking for updates text" = "This helps Vienna development by letting us know what versions of Mac OS X are most popular amongst our users."; -"Error: Feed not found!" = "Error: Feed not found!"; -"Loading" = "Loading"; -"Plugin could not be installed" = "Plugin could not be installed"; -"Vienna failed to install the plugin." = "Vienna failed to install the plugin."; -"Queue" = "Queue"; -"Forcing Refresh subscriptions..." = "Forcing Refresh subscriptions..."; -"Improper infinitely looping URL redirect to %@" = "Improper infinitely looping URL redirect to %@"; +"Plugin installed" = "Плагин установлен"; +"A new plugin has been installed. It is now available from the menu and you can add it to the toolbar." = "Новый плагин успешно установлен. Теперь он доступен из меню, а также можно добавить его на панель инструментов."; +"Error loading script '%@'" = "Ошибка загрузки скрипта '%@'"; +"AppleScript Error in '%@' script" = "Ошибка AppleScript в скрипте '%@'"; +"No thanks" = "Нет, спасибо"; +"Include anonymous system profile when checking for updates?" = "Добавить анонимную информацию о системе при проверке обновлений?"; +"Include anonymous system profile when checking for updates text" = "Знание наиболее популярных версий Mac OS X среди наших пользователей, помогает дальнейшей разработке и развитию Vienna."; +"Error: Feed not found!" = "Ошибка: Лента не найдена!"; +"Loading" = "Загрузка"; +"Plugin could not be installed" = "Плагин не может быть установлен"; +"Vienna failed to install the plugin." = "Vienna не удалось установить плагин."; +"Queue" = "Очередь"; +"Forcing Refresh subscriptions..." = "Принудительное обновление подписок..."; +"Improper infinitely looping URL redirect to %@" = "Бесконечное перенаправление URL по адресу %@"; /* Added in 3.0.2 */ -"Close" = "Close"; -"Locate" = "Locate"; -"Error retrieving RSS feed:"="Error retrieving RSS feed:"; -"Got HTTP status 304 - No news from last check" = "Got HTTP status 304 - No news from last check"; -"Error retrieving RSS Icon:" = "Error retrieving RSS Icon:"; -"RSS Icon not found!" = "RSS Icon not found!"; +"Close" = "Закрыть"; +"Locate" = "Найти"; +"Error retrieving RSS feed:"="Ошибка запроса RSS-ленты:"; +"Got HTTP status 304 - No news from last check" = "Получен HTTP-код 304 - Нет новостей с момента последней проверки"; +"Error retrieving RSS Icon:" = "Ошибка получения иконки RSS:"; +"RSS Icon not found!" = "Иконка RSS не найдена!"; /*Added in 3.0.5 */ -"Redirection attempt treated as temporary for safety concern" = "Redirection attempt treated as temporary for safety concern"; +"Redirection attempt treated as temporary for safety concern" = "Зафиксирована попытка перенаправления"; + +/*Added in 3.0.7 */ +"No articles in feed" = "В ленте нет статей"; + +/*Added in 3.1.2 */ +"Filter folders" = "Поиск по подпискам"; diff --git a/lproj/ru.lproj/RSSFeed.nib/designable.nib b/lproj/ru.lproj/RSSFeed.nib/designable.nib index 60d1a866f2..0b3d4d7843 100644 --- a/lproj/ru.lproj/RSSFeed.nib/designable.nib +++ b/lproj/ru.lproj/RSSFeed.nib/designable.nib @@ -1,1003 +1,217 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSButton - NSButtonCell - NSCustomObject - NSMenu - NSMenuItem - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSUserDefaultsController - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - RSSFeed - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{165, 318}, {426, 289}} - 1886912512 - Канал RSS - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{190, 8}, {102, 32}} - - - YES - - 67108864 - 134217728 - Отмена - - LucidaGrande - 13 - 1044 - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{292, 8}, {123, 32}} - - - 100 - YES - - 67108864 - 134217728 - Подписаться - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{16, 188}, {75, 17}} - - - YES - - 67108864 - 71303168 - 0JjRgdGC0L7Rh9C90LjQujoKA - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 256 - {{95, 181}, {175, 26}} - - - YES - - -2080374720 - 1024 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - URL - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - 100 - - - YES - - - OtherViews - - - - - - 3 - YES - YES - 1 - - NO - - - - 256 - {{20, 255}, {389, 17}} - - - YES - - 67108864 - 4194304 - Создание новой подписки - - LucidaGrande-Bold - 13 - 2072 - - - - - - NO - - - - 256 - {{20, 213}, {378, 34}} - - - YES - - 67108864 - 4194304 - Введите ссылку на канал новостей или выберите канал из списка Источник для добавления ссылки с заданного источника. - - LucidaGrande - 10 - 2843 - - - - - - NO - - - - 256 - {{23, 82}, {386, 62}} - - - YES - - -1805647871 - 4325376 - - - LucidaGrande - 11 - 3100 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 256 - {{279, 181}, {21, 24}} - - - YES - - 67108864 - 134217728 - - - - -2038284288 - 33 - - - - - - 200 - 25 - - NO - - - - 256 - {{20, 152}, {270, 17}} - - - YES - - 67108864 - 4194304 - URL: - - - - - - NO - - - - 268 - {{21, 44}, {185, 18}} - - - YES - - -2080374784 - 0 - Subscribe in Open Reader - - - 1211912448 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - NO - - - {426, 289} - - - - {{0, 0}, {1280, 778}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - 3 - 2 - {{236, 362}, {423, 167}} - 1886912512 - Канал RSS - NSPanel - - View - - - {213, 107} - - - 256 - - - - 256 - {{299, 12}, {110, 32}} - - 100 - YES - - 67108864 - 134217728 - Сохранить - - - 100 - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 256 - {{197, 12}, {102, 32}} - - - YES - - 67108864 - 134217728 - Отмена - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 256 - {{20, 60}, {383, 62}} - - - YES - - -1805647871 - 4325376 - - - - YES - - - - NO - - - - 256 - {{17, 130}, {389, 17}} - - - YES - - 67108864 - 4194304 - Изменение подписки - - - - - - NO - - - {{1, 9}, {423, 167}} - - - {{0, 0}, {1280, 778}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - YES - - - - - - - window - - - - 14 - - - - doSubscribe: - - - - 37 - - - - feedSource - - - - 46 - - - - subscribeButton - - - - 48 - - - - doSave: - - - - 57 - - - - editRSSFeedWindow - - - - 61 - - - - newRSSFeedWindow - - - - 62 - - - - editFeedURL - - - - 69 - - - - saveButton - - - - 70 - - - - editCancelButton - - - - 74 - - - - subscribeCancelButton - - - - 76 - - - - doEditCancel: - - - - 77 - - - - doSubscribeCancel: - - - - 78 - - - - doLinkSourceChanged: - - - - 89 - - - - feedURL - - - - 91 - - - - doShowSiteHomePage: - - - - 93 - - - - siteHomePageButton - - - - 94 - - - - linkTitle - - - - 99 - - - - doGoogleOption: - - - - 118 - - - - googleOptionButton - - - - 119 - - - - value: googleOptionButton - - - - - - value: googleOptionButton - value - googleOptionButton - 2 - - - 117 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - NewRSSFeed - - - 5 - - - - - - - - - - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 40 - - - - - - - - 43 - - - - - - - - 64 - - - - - - - - 65 - - - - - - - - 90 - - - - - - - - 92 - - - - - - - - 97 - - - - - - - - 49 - - - - - - EditRSSFeed - - - 50 - - - - - - - - - - - 53 - - - - - - - - 54 - - - - - - - - 55 - - - - - - - - 67 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - 107 - - - - - 108 - - - - - 109 - - - - - 110 - - - - - 111 - - - - - 112 - - - - - 113 - - - - - 114 - - - - - 44 - - - - - - - - 45 - - - - - -3 - - - Application - - - 115 - - - - - - - - 116 - - - - - 120 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{1012, 565}, {429, 297}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 122 - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - {15, 15} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Источник: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/ru.lproj/RSSFeed.nib/keyedobjects.nib b/lproj/ru.lproj/RSSFeed.nib/keyedobjects.nib index 85c08a3fa3..dcb7d90ed3 100644 Binary files a/lproj/ru.lproj/RSSFeed.nib/keyedobjects.nib and b/lproj/ru.lproj/RSSFeed.nib/keyedobjects.nib differ diff --git a/lproj/ru.lproj/RSSFeed.strings b/lproj/ru.lproj/RSSFeed.strings index 561e0c3736..22a1f31794 100644 --- a/lproj/ru.lproj/RSSFeed.strings +++ b/lproj/ru.lproj/RSSFeed.strings @@ -1,33 +1,33 @@ /* NSButton (Cancel) : (oid:54) */ -"Cancel" = "Cancel"; +"Cancel" = "Отмена"; /* NSTextField (Create a new subscription ) : (oid:64) */ -"Create a new subscription\n" = "Create a new subscription\n"; +"Create a new subscription\n" = "Создание новой подписки\n"; /* NSTextField (Edit subscription) : (oid:67) */ -"Edit subscription" = "Edit subscription"; +"Edit subscription" = "Изменение подписки"; /* NSTextField (Enter the link for the news feed below. Or choose from the Source list to enter a shortcut name for the news feed provided by the source.) : (oid:65) */ -"Enter the link for the news feed below. Or choose from the Source list to enter a shortcut name for the news feed provided by the source." = "Enter the link for the news feed below. Or choose from the Source list to enter a shortcut name for the news feed provided by the source."; +"Enter the link for the news feed below. Or choose from the Source list to enter a shortcut name for the news feed provided by the source." = "Введите ссылку на канал новостей или выберите канал из списка Источник для добавления ссылки с заданного источника."; /* NSMenu : (oid:44) */ "OtherViews" = "OtherViews"; /* NSPanel (RSS Feed) : (oid:49) */ -"RSS Feed" = "RSS Feed"; +"RSS Feed" = "RSS лента"; /* NSButton (Save) : (oid:53) */ -"Save" = "Save"; +"Save" = "Сохранить"; /* NSTextField (Source: ) : (oid:40) */ -"Source:\n" = "Source:\n"; +"Source:\n" = "Источник:\n"; /* NSButton (Subscribe) : (oid:10) */ -"Subscribe" = "Subscribe"; +"Subscribe" = "Подписаться"; /* NSMenuItem : (oid:45) */ "URL" = "URL"; diff --git a/lproj/ru.lproj/RSSSources.plist b/lproj/ru.lproj/RSSSources.plist index dd28b36dfe..517c6e6809 100644 --- a/lproj/ru.lproj/RSSSources.plist +++ b/lproj/ru.lproj/RSSSources.plist @@ -1,5 +1,5 @@ - + Local File diff --git a/lproj/ru.lproj/SearchFolder.nib/designable.nib b/lproj/ru.lproj/SearchFolder.nib/designable.nib index fb5fd96fc7..94b4085640 100644 --- a/lproj/ru.lproj/SearchFolder.nib/designable.nib +++ b/lproj/ru.lproj/SearchFolder.nib/designable.nib @@ -1,1591 +1,266 @@ - - - - 1050 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSBox - NSButton - NSButtonCell - NSCustomObject - NSCustomView - NSMenu - NSMenuItem - NSNumberFormatter - NSPopUpButton - NSPopUpButtonCell - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - SmartFolder - - - FirstResponder - - - NSApplication - - - 3 - 2 - {{394, 527}, {647, 186}} - 1886912512 - - NSPanel - - View - - - {213, 107} - - - 256 - - - - 268 - {{17, 150}, {176, 17}} - - - YES - - 67108864 - 4194304 - 0JjQvNGPINC90L7QstC+0Lkg0YHQvNCw0YDRgi3Qv9Cw0L/QutC4Ogo - - LucidaGrande - 13 - 1044 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - NO - - - - 268 - {{198, 147}, {178, 22}} - - - YES - - -1804599231 - 4195328 - - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - NO - - - - 289 - {{523, 12}, {110, 32}} - - - YES - - 67108864 - 134217728 - Сохранить - - - -2038284288 - 1 - - - DQ - 200 - 25 - - NO - - - - 289 - {{444, 12}, {79, 32}} - - - YES - - 67108864 - 134217728 - Отмена - - - -2038284288 - 1 - - - Gw - 200 - 25 - - NO - - - - 274 - - - - 274 - - - - 274 - {{12, 6}, {584, 38}} - - - - NSView - - NSResponder - - - {{2, 2}, {609, 50}} - - - - - {{17, 56}, {613, 54}} - - - {0, 0} - - 67108864 - 0 - - - LucidaGrande - 11 - 3100 - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 3 - 0 - 0 - NO - - - - 268 - {{17, 118}, {248, 17}} - - - YES - - 67108864 - 4194304 - Показывать статьи, соответстующие - - - - - - NO - - - - 268 - {{261, 112}, {118, 26}} - - - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - Ни одному - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - 268 - {{386, 118}, {301, 17}} - - - YES - - 67108864 - 272629760 - из следующих условий: - - - - - - NO - - - {647, 186} - - - - {{0, 0}, {1920, 1058}} - {213, 129} - {10000000000000, 10000000000000} - YES - - - - 256 - - - - 256 - {{-3, 0}, {147, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Названия полей - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - 256 - {{513, -3}, {32, 31}} - - YES - - 67108864 - 134479872 - - - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{302, 3}, {183, 22}} - - YES - - -1804599231 - 4195328 - - - - YES - - - - NO - - - - 256 - {{541, -3}, {32, 31}} - - YES - - 67108864 - 134479872 - + - - - -2037645312 - 7 - - - - - 200 - 25 - - NO - - - - 256 - {{151, 0}, {135, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Операторы - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{299, 0}, {100, 26}} - - YES - - -2076180416 - 1024 - - - 109199360 - 1 - - - - - - - - 400 - 75 - - - Nothing - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{302, 4}, {126, 22}} - - YES - - -1804599231 - 4195328 - - - - - - - - - NaN - - - - 0 - - - . - - , - - - - - 0 - 2 - NO - YES - 1 - P0IPAAAAAAAAAAAAAAAAAA - - - 0 - 1 - NO - YES - 1 - AQAAAAAAAAAAAAAAAAAAAA - - -0 - 0 - - - 0 - -0 - - - - - - - - - . - , - NO - NO - YES - - - YES - - - - NO - - - - -2147483392 - {{299, 0}, {189, 26}} - - 1008 - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Item2 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - Item3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - -1 - 3 - YES - YES - 1 - - NO - - - - -2147483392 - {{294, 0}, {194, 26}} - - 1004 - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - - - - 400 - 75 - - - Item1 - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - - - - Item2 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - Item3 - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - -1 - 3 - YES - YES - 1 - - NO - - - {572, 28} - - NSView - - NSResponder - - - - - - - cancelButton - - - - 40 - - - - saveButton - - - - 41 - - - - searchCriteriaView - - - - 43 - - - - removeCriteriaButton - - - - 44 - - - - addCriteriaButton - - - - 45 - - - - fieldNamePopup - - - - 46 - - - - operatorPopup - - - - 47 - - - - valueField - - - - 49 - - - - window - - - - 50 - - - - addNewCriteria: - - - - 51 - - - - doCancel: - - - - 52 - - - - doSave: - - - - 53 - - - - searchWindow - - - - 54 - - - - removeCurrentCriteria: - - - - 57 - - - - fieldChanged: - - - - 59 - - - - flagValueField - - - - 65 - - - - numberValueField - - - - 70 - - - - folderValueField - - - - 78 - - - - criteriaConditionPopup - - - - 85 - - - - dateValueField - - - - 91 - - - - smartFolderName - - - - 92 - - - - searchCriteriaSuperview - - - - 42 - - - - nextKeyView - - - - 72 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 6 - - - - - - Search Folder - - - 5 - - - - - - - - - - - - - - - 7 - - - - - - - - 8 - - - - - - - - 9 - - - - - - - - 10 - - - - - - - - 37 - - - - - - - - 58 - - - - - - - - 79 - - - - - - - - 84 - - - - - - - - 26 - - - - - - - - - - - - - - SearchCriteriaView - - - 27 - - - - - - - - 29 - - - - - - - - 30 - - - - - - - - 31 - - - - - - - - 35 - - - - - - - - 61 - - - - - - - - 69 - - - - - - - - 73 - - - - - - - - 86 - - - - - - - - 94 - - - - - 95 - - - - - 96 - - - - - 97 - - - - - 98 - - - - - 99 - - - - - - - - 100 - - - - - 101 - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - - - 105 - - - - - - - - 106 - - - - - - - - 107 - - - - - - - - 108 - - - - - - - - 109 - - - - - - - - 71 - - - - - 80 - - - - - - - - 82 - - - - - 32 - - - - - - - - 33 - - - - - 34 - - - - - - - - 56 - - - - - 64 - - - - - - - - 62 - - - - - 74 - - - - - - - - - 76 - - - - - 75 - - - - - 87 - - - - - - - - - - 90 - - - - - 89 - - - - - 88 - - - - - -3 - - - Application - - - 36 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 109 - - - - - NSObject - - id - id - - - - deleteFolder: - id - - - deleteMessage: - id - - - - IBProjectSource - ./Classes/NSObject.h - - - - SmartFolder - NSWindowController - - id - id - id - id - id - - - - addNewCriteria: - id - - - doCancel: - id - - - doSave: - id - - - fieldChanged: - id - - - removeCurrentCriteria: - id - - - - NSButton - NSButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSPopUpButton - NSTextField - NSPopUpButton - NSButton - NSButton - NSView - NSView - NSWindow - NSTextField - NSTextField - - - - addCriteriaButton - NSButton - - - cancelButton - NSButton - - - criteriaConditionPopup - NSPopUpButton - - - dateValueField - NSPopUpButton - - - fieldNamePopup - NSPopUpButton - - - flagValueField - NSPopUpButton - - - folderValueField - NSPopUpButton - - - numberValueField - NSTextField - - - operatorPopup - NSPopUpButton - - - removeCriteriaButton - NSButton - - - saveButton - NSButton - - - searchCriteriaSuperview - NSView - - - searchCriteriaView - NSView - - - searchWindow - NSWindow - - - smartFolderName - NSTextField - - - valueField - NSTextField - - - - IBProjectSource - ./Classes/SmartFolder.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Имя новой смарт-папки: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lproj/ru.lproj/SearchFolder.nib/keyedobjects.nib b/lproj/ru.lproj/SearchFolder.nib/keyedobjects.nib index ac97c85cd1..9ea9d6b80c 100644 Binary files a/lproj/ru.lproj/SearchFolder.nib/keyedobjects.nib and b/lproj/ru.lproj/SearchFolder.nib/keyedobjects.nib differ diff --git a/lproj/ru.lproj/SearchFolder.strings b/lproj/ru.lproj/SearchFolder.strings index 2ee6d1dbf4..ee5be9d8fe 100644 --- a/lproj/ru.lproj/SearchFolder.strings +++ b/lproj/ru.lproj/SearchFolder.strings @@ -8,10 +8,10 @@ "-" = "-"; /* NSButton (Cancel) : (oid:10) */ -"Cancel" = "Cancel"; +"Cancel" = "Отмена"; /* NSMenuItem : (oid:33) */ -"Field names go here" = "Field names go here"; +"Field names go here" = "Название полей"; /* NSMenuItem : (oid:88) */ "Item1" = "Item1"; @@ -23,24 +23,24 @@ "Item3" = "Item3"; /* NSMenuItem : (oid:82) */ -"Nothing" = "Nothing"; +"Nothing" = "Ни одному"; /* NSMenuItem : (oid:56) */ -"Operators go here" = "Operators go here"; +"Operators go here" = "Операторы"; /* NSMenu : (oid:87) */ "OtherViews" = "OtherViews"; /* NSButton (Save) : (oid:9) */ -"Save" = "Save"; +"Save" = "Сохранить"; /* NSTextField (Show all articles that match) : (oid:58) */ -"Show all articles that match" = "Show all articles that match"; +"Show all articles that match" = "Показыывать статьи, соответствующие"; /* NSTextField (Smart folder name: ) : (oid:7) */ -"Smart folder name:\n" = "Smart folder name:\n"; +"Smart folder name:\n" = "Имя новой смарт-папки:\n"; /* NSTextField (of the following conditions:) : (oid:84) */ -"of the following conditions:" = "of the following conditions:"; +"of the following conditions:" = "из следующих условий:"; diff --git a/lproj/ru.lproj/Vienna Help/advanced.html b/lproj/ru.lproj/Vienna Help/advanced.html deleted file mode 100644 index fb9b248814..0000000000 --- a/lproj/ru.lproj/Vienna Help/advanced.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - Advanced Settings - - - - -  Advanced - Settings -

The Advanced section of the Preferences provides options to - change very specific settings in Vienna that are not essential - for normal use but may resolve some issues as advised by the - support forum. This page details the advanced settings and their - function.

-

Enable JavaScript in internal browser

-

Enables or disables support for JavaScript scripting in the - Vienna internal browser. By default this is enabled. By turning - this setting off, JavaScript code on web pages will not be - allowed to run. This may resolve problems with pages that use - scripting to pop up windows or other unexpected behaviour but - turning the setting off may also cause some web pages to appear - incomplete or fail to function correctly.

- - diff --git a/lproj/ru.lproj/Vienna Help/faq.html b/lproj/ru.lproj/Vienna Help/faq.html deleted file mode 100644 index 5bcc082cde..0000000000 --- a/lproj/ru.lproj/Vienna Help/faq.html +++ /dev/null @@ -1,216 +0,0 @@ - - - - - - - How Do I? - - - - -  How Do I? -

Below are some of the more common questions asked about Vienna - while it was being pre-release tested. See the Official Vienna FAQ - Page for these and the latest hints and tips for using - Vienna.

- -

Where do I get the Vienna - source code?

-

See the Development page - for instructions for getting the source code for Vienna. The - source code is freely available if you're interested in learning - how Vienna works, if you want to build your own copy of Vienna - from scratch on your own machine or if you want to borrow - portions for inclusion in your own project. The source is - provided under the Apache 2.0 - license.

-

I found a - problem with Vienna. How do I report it?

-

Post a message over in the Support - forum and somebody will investigate. Provide as much - information about the problem as you can including: the build of - Vienna (obtained from the About Vienna panel), repro steps and - what you expected to happen. There is a sticky note in the forum - with tips on how to write a good bug report.

-

Make sure you're always running the most recent build of - Vienna. The Check for Updates command will report if there's a - newer build available than the one you have.

-

Fixes for bugs take priority over new features so if your - problem is confirmed to be a bug with high impact and no simple - workaround then I'll look at making a fix available as soon as - reasonably possible.

-

How do I create my own - styles?

-

See the Custom Styles - page for instructions.

-

How do I create my own - scripts?

-

Vienna's scripts are written using AppleScript. See the - - Apple resource page for more details.

-

One way to get started is to download one of the existing - scripts from the Vienna Downloads - page and view it in the AppleScript editor.

-

To submit your own script, send it to steve@opencommunity.co.uk - and after it has been reviewed, it will be made available on the - Downloads page.

-

- How can I see what happened when my subscriptions are - refreshed?

-

Open the Activity Window from the Window menu. The activity - window shows all subscriptions and the status of the last time - they were refreshed in that session. The bottom of the activity - window shows more details include the HTTP headers and may be - useful for debugging. (If the details pane is not visible, grab - the split bar at the bottom of the Activity Window and drag it up - to uncover the pane).

-

How do I - move my Vienna database to another folder?

-

By default, your Vienna database is the messages.db file which - is located at ~/Library/Application Support/Vienna. You can move - this to another folder if you wish. The following steps show - how:

-
    -
  1. Shut down Vienna.
  2. -
  3. Open a console window and enter:
    -
    - defaults write - uk.co.opencommunity.vienna2 "DefaultDatabase" '<path to new - messages.db>'
    -
    - where <path to new messages.db> is the name of the folder - that contains the messages.db file. The path itself should have - the messages.db filename at the end. For example:
    -
    - defaults write - uk.co.opencommunity.vienna2 "DefaultDatabase" - '/Users/steve/mydata/messages.db'
  4. -
  5. Restart Vienna.
  6. -
-

- One of my subscriptions reports "Error parsing XML data in feed". - What does this mean?

-

It means that Vienna got a feed back from the subscription - that it couldn't interpret. There are several reasons for - this:

-
    -
  1. The URL of the feed may not be pointing to an RSS or Atom - feed but to a web page. Check the URL of the offending feed - carefully.
  2. -
  3. The feed itself may contain malformed XML. Some - subscriptions make a mistake in putting together the XML that - makes up the feed and Vienna cannot interpret malformed XML. - Use the Validate Feed command on the File menu to see if this - is the case. Unfortunately you cannot do much about this in - Vienna except wait for the feed itself to be corrected by the - site.
  4. -
  5. The feed may be incomplete. If the refresh was interrupted - then the XML data will be incomplete and will appear malformed - in Vienna. A second refresh may correct this problem.
  6. -
-

If none of the above explain the problem, post a message on - the support forum with the URL of the feed exhibiting the - problem.

-

- Is there a shortcut key for going to the next article, marking - read, etc?

-

Probably. There are single key equivalents for some of the - menu commands such as:

-

Spacebar - goes to the next unread article. If the current - article is several pages long, it will scroll through that - article first. If you're at the end of the current article it - will then go to the next unread article. By contrast the Next - Unread command (Cmd+U) always goes straight to the next unread - article.

-

R - marks the current article read if it is unread, or unread - if it is read.

-

F - flags the current article if it isn't already flagged, or - removes the existing flag if it is not.

-

Look in the Vienna Help file for more shortcuts.

-

What do - the green dots mean in the list of articles?

-

The blue dots are for new articles, and the green dots are for - updated articles: articles whose text has changed since they were - last downloaded.

-

How do I use Auto - Expire and what does it do?

-

Auto-expire moves articles older than a certain number of days - to the Trash folder. It allows you to keep your folders - manageable by only retaining articles that are recent. The - auto-expire runs both when Vienna starts and after you have - refreshed any subscriptions. To control the age of articles to - auto-expire, change the "Move articles to Trash" option in - Preferences.

-

Auto-expire will NOT remove unread or flagged articles. It - assumes that you haven't read these articles and thus leaves them - alone.

-

How do I request an - enhancement in Vienna?

-

Post a message over at the support - forum. All requested enhancements are logged in the TODO file - that is included with the source code as a guidance for future - developers.

- - diff --git a/lproj/ru.lproj/Vienna Help/helpstyle.css b/lproj/ru.lproj/Vienna Help/helpstyle.css deleted file mode 100644 index d02689f72e..0000000000 --- a/lproj/ru.lproj/Vienna Help/helpstyle.css +++ /dev/null @@ -1,39 +0,0 @@ -a { - color: #3366CC; - text-decoration: none; -} -.title { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 18pt; - color: #000000; -} -.header { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 700; - font-size: 12pt; - color: #000000; -} -li { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 100; - font-size: 9pt; - color: #000000; -} -h2 { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 400; - font-size: 10pt; - color: #000000; -} -p { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-weight: 100; - font-size: 9pt; - color: #000000; -} -tr { - font-family: "Lucida Grande", Arial, Helvetica, sans-serif; - font-size: 9pt; - color: #000000; -} \ No newline at end of file diff --git a/lproj/ru.lproj/Vienna Help/images/Small-Vienna-Logo.jpg b/lproj/ru.lproj/Vienna Help/images/Small-Vienna-Logo.jpg deleted file mode 100644 index 41035b4f11..0000000000 Binary files a/lproj/ru.lproj/Vienna Help/images/Small-Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/ru.lproj/Vienna Help/images/Vertical-Line.jpg b/lproj/ru.lproj/Vienna Help/images/Vertical-Line.jpg deleted file mode 100644 index 011f1ce1e3..0000000000 Binary files a/lproj/ru.lproj/Vienna Help/images/Vertical-Line.jpg and /dev/null differ diff --git a/lproj/ru.lproj/Vienna Help/images/Vienna-Logo.jpg b/lproj/ru.lproj/Vienna Help/images/Vienna-Logo.jpg deleted file mode 100644 index 13a6479bd4..0000000000 Binary files a/lproj/ru.lproj/Vienna Help/images/Vienna-Logo.jpg and /dev/null differ diff --git a/lproj/ru.lproj/Vienna Help/images/rssfeed.gif b/lproj/ru.lproj/Vienna Help/images/rssfeed.gif deleted file mode 100644 index 2dc8935119..0000000000 Binary files a/lproj/ru.lproj/Vienna Help/images/rssfeed.gif and /dev/null differ diff --git a/lproj/ru.lproj/Vienna Help/index.html b/lproj/ru.lproj/Vienna Help/index.html deleted file mode 100644 index a93a8e7d71..0000000000 --- a/lproj/ru.lproj/Vienna Help/index.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - Vienna Help - - - - - - - - - - -
-

-

Vienna Help

-
-

Introduction to Vienna

-

Learn how to get started with - Vienna.

-

Keyboard Shortcuts

-

Discover keyboard shortcuts - for common commands

-

How Do I?

-

Frequently Asked Questions, getting - support and troubleshooting steps.

-

Advanced Settings

-

Explains the settings in the - Advanced Preferences.

-
- - diff --git a/lproj/ru.lproj/Vienna Help/intro.html b/lproj/ru.lproj/Vienna Help/intro.html deleted file mode 100644 index 868b1d140e..0000000000 --- a/lproj/ru.lproj/Vienna Help/intro.html +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - Introduction to Vienna - - - - -   Introduction to - Vienna -

Vienna is an application that allows you to read RSS or Atom - news feeds on your Mac OS X computer. It automates the job of - retrieving news articles from all subscribed feeds and storing - them in a local database for reading off-line. It provides - features that allow you to search feeds for keywords or phrases, - tag articles with a flag for future reference and organise - related feeds together under groups. You can create smart folders - that make it easy to dynamically retrieve and view all articles - in the database that match a search criteria. The built-in web - browser allows you to go to the articles web page or view links - in the article directly in Vienna in separate tabs.

-

Vienna is designed to be simple and easy to use. A clean, - uncluttered, interface maximises the space for articles and just - a few controls are needed to perform the most common actions in - the user interface.

Getting Started -

If this is the first time that you have used Vienna then it - will have created a new database for you and added some sample - news subscriptions. So go ahead and press Command+R or choose - Refresh All Subscriptions from the File menu to grab the latest - articles from those subscriptions.

-

Alternatively, subscribe to your own news feeds. There are - various ways to find feeds. When browsing the web, look out for - the RSS feed icon or XML - icons indicating that the page has a feed associated with it. - Alternatively almost all online blogging services such as - LiveJournal or Blogger provide RSS feeds as an alternative to - reading the postings online.

-

If you know the user name of a blogger on LiveJournal, - Blogger, MSN Spaces or Xanga then Vienna makes it easier to - subscribe to their news feed. Start by pressing Command+N or from - the File menu, choose the New Subscription command. In the - "Create a new RSS subscription" panel, pick the blogging service - from the drop down list and enter the user name in the input - field below. Then choose Subscribe and Vienna will add the - subscription to the folder list. If you are connected to the - internet at the time, it will also immediately start collecting - articles from the feed.

-

Normally you need to manually tell Vienna when to refresh all - your subscriptions. However you can opt to ask Vienna to - automatically refresh at time intervals. In the General section - of the Preferences, pick the desired time interval from the drop - down list next to 'Check for new articles'. Vienna needs to be - running for it to automatically refresh subscriptions.

-

To read articles, press the Spacebar to skip to the next - unread article in any subscription. Each article is marked as - read automatically after a short delay. If you prefer to wait - until you move to the next unread article before the current one - is marked read you can adjust the behaviour in the General tab of - the Preferences. To mark an article as unread again, choose the - Mark Unread command from the Article menu or simply press the 'R' - key.

-

Finally, you can view the article web page or any web page - links in an article within Vienna. By default clicking on a web - link within Vienna will open the web page in a new tab. Vienna - provides a lot of basic web browsing support itself but there may - be times when you will prefer to open links in your default web - browser. If you prefer to view all web pages outside of Vienna - then enable the 'Open links in external browser' option in the - General section of the Preferences. However if you prefer to view - the current link or page in your external browser, right click on - the page and choose the "Open Link in XXX" or "Open Page in XXX" - option where XXX will be the name of your default browser.

-

Once you've got comfortable using Vienna, go ahead and explore - the various options. You can change the style in which the - articles are displayed through the Style drop down list in the - View menu. You can find many more custom styles at the Downloads page - on the Vienna web site along with custom scripts that allow you - to integrate Vienna with other applications on your machine. Or - experiment with smart folders to organise articles according to - criteria based on the contents of each article. For example, you - can easily set up a smart folder to group together all articles - that mention "Joss Whedon" and "Firefly" to find references to - the Firefly cult series or the spin-off movie.

-

If you have any questions about Vienna or run into problems, - head over to the Support - forum.

- - diff --git a/lproj/ru.lproj/Vienna Help/keyboard.html b/lproj/ru.lproj/Vienna Help/keyboard.html deleted file mode 100644 index 6ab921ea4d..0000000000 --- a/lproj/ru.lproj/Vienna Help/keyboard.html +++ /dev/null @@ -1,253 +0,0 @@ - - - - - - - Keyboard Shortcuts - - - - -  Keyboard - Shortcuts -

You can use your keyboard to quickly accomplish many tasks in - Vienna. To find the shortcuts for common commands, look in the - menus (or see the list at the bottom of this page). Many items in - Vienna such as the folder pane and the article list pane also - have contextual menus. To see a contextual menu, press the - Control key and click the item.

-

To do an action, press the shortcut keys indicated below.

- - - - - -
KeyAction
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Single Key Shortcuts 
fSets the input focus to the search window.
rMarks the selected articles read.
sMarks the current folder read then skips to the next - folder with unread articles.
kMarks the current folder read.
mFlags the selected articles.
nMoves to the next unread article.
<Displays the previous viewed article or web page.
>Displays the next viewed article or web page.
SpacebarMoves to the next unread article unless the current - article has more text to scroll in which case it scrolls the - current article up one page.
Enter/ReturnOpens the selected article's original web page.
Delete/BackspaceMoves the selected articles to the Trash folder. If this - key is used in the Trash folder, the selected articles are - permanently deleted.
General Shortcuts 
Alt-ClickOpen the clicked link, overriding your preference for - opening links in external browser.
Command-NCreate a new subscription.
Shift-Command-FCreate a smart folder.
Shift-Command-EEdit the selected folder URL or edit a smart folder - criteria.
Shift-Command-DDelete the selected folder.
Shift-Command-NRename the selected folder.
Command-RRefreshes all subscriptions.
Shift-Command-RRefresh only those subscriptions selected in the folder - list.
Control-Command-SStops any active refresh.
Command-PPrint the selected articles.
Shift-Command-PBrings up the Page Setup panel.
Command-?Displays the Vienna help book.
Articles Shortcuts 
Alt-Enter/Alt-ReturnOpens the selected article's original web page, - overriding your preference for opening links in external - browser.
Command-UMoves to the next unread article.
Shift-Command-MFlags the selected articles.
Shift-Command-UMarks the selected articles read.
Shift-Command-SMarks the current folder read then skips to the next - folder with unread articles.
Shift-Command-ORestores an article from the trash back to its original - folder.
Shift-Command-KMarks all articles in the selected folders read.
Alt-Command-KMarks all articles in all folders read.
Window Shortcuts 
Command-WCloses the active tab window if one is open. Otherwise if - no tabs are open, this closes the Vienna window.
Alt-Command-WCloses all tab windows. Note that this command replaces - the Close Tab command on the File menu when the Alt key is - held down.
Alt-Command-LeftDisplays the previous tab window.
Alt-Command-RightDisplays the next tab window.
Command-MMinimizes the Vienna window to the dock.
Command-0Displays the activity log viewer window.
Command-1Reopens the Vienna window if it was previously - closed.
Command-2Displays the Downloads window.
Browser Window Shortcuts 
Alt-RReloads the current web page.
Command-PeriodCancels loading of the current web page.
Command-[/Command-LeftGoes back to the previous web page.
Command-]/Command-RightGoes forward to the next web page.
Command-FPuts the input focus in the search field. Entering some - text here and pressing Enter will search for that text on the - current web page.
Command-GSearches for the next occurrence of the search text on - the web page.
- - diff --git a/lproj/ru.lproj/errorpage.html b/lproj/ru.lproj/errorpage.html index 7c249a3c92..1207425ee7 100644 --- a/lproj/ru.lproj/errorpage.html +++ b/lproj/ru.lproj/errorpage.html @@ -2,7 +2,7 @@ -An error has occured +Произошла ошибка + + + +

Version Notes

-

3.0.9

+

3.1.16

+ +
    +
  • Fix article selection after an article is deleted from within the 'Unread Articles' folder
  • +
  • Fix bugs related to multithreading
  • +
  • Fix handling of impossibility of creating the database
  • +
  • Corrected changelog text at version 3.1.15
  • +
+ +

3.1.15

    -
  • Fix problem w/ subscribing to some feeds
  • -
  • Improve handling of feeds having duplicate GUIDs
  • -
  • Fix some styles to limit maximum image size
  • -
  • Improve the ad blocking feature of the Feedlight styles
  • -
  • Display articles of any newly added folder
  • -
  • If adding existing feed, focus it
  • -
  • Better handling of legal/illegal characters in URL strings
  • -
  • Fix enclosure download when the URL string contains a query
  • -
  • Recognize a few more file extensions to be directly downloaded
  • -
  • Fix some crashes
  • +
  • Fix article list not scrolling to top when selecting a folder
  • +
  • Fix 'Skip Folder' not selecting the first unread article in the next folder with unread articles
+

3.1.14

+ +
    +
  • Fix article pane not updating on article deletion from the 'Unread Articles' folder
  • +
+ + + diff --git a/palettes/PSMTabBarControl.palette/Contents/Info.plist b/palettes/PSMTabBarControl.palette/Contents/Info.plist deleted file mode 100644 index d11b4b3e18..0000000000 --- a/palettes/PSMTabBarControl.palette/Contents/Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - PSMTabBarControl - CFBundleIdentifier - com.positivespinmedia.PSMTabBarControl - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - PSMTabBarControl - CFBundlePackageType - BNDL - CFBundleSignature - PSM1 - CFBundleVersion - 1.1 - - diff --git a/palettes/PSMTabBarControl.palette/Contents/MacOS/PSMTabBarControl b/palettes/PSMTabBarControl.palette/Contents/MacOS/PSMTabBarControl deleted file mode 100755 index 7273e3235b..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/MacOS/PSMTabBarControl and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabClose_Front.tif b/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabClose_Front.tif deleted file mode 100644 index a221ac7467..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabClose_Front.tif and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabClose_Front_Pressed.tif b/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabClose_Front_Pressed.tif deleted file mode 100644 index 104799dd60..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabClose_Front_Pressed.tif and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabClose_Front_Rollover.tif b/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabClose_Front_Rollover.tif deleted file mode 100644 index cd86fa5c21..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabClose_Front_Rollover.tif and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabNew.png b/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabNew.png deleted file mode 100644 index 843b3c386d..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabNew.png and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabNewPressed.png b/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabNewPressed.png deleted file mode 100644 index 469438d234..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabNewPressed.png and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabNewRollover.png b/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabNewRollover.png deleted file mode 100644 index f728511795..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabNewRollover.png and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabsBackground.png b/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabsBackground.png deleted file mode 100644 index 456ca6172d..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabsBackground.png and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabsDown.png b/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabsDown.png deleted file mode 100644 index 2db28ae1f4..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabsDown.png and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabsDownGraphite.png b/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabsDownGraphite.png deleted file mode 100644 index 787520e9fd..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabsDownGraphite.png and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabsDownNonKey.png b/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabsDownNonKey.png deleted file mode 100644 index 34a57ff639..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabsDownNonKey.png and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabsSeparator.png b/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabsSeparator.png deleted file mode 100644 index f7cc1d0f99..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabsSeparator.png and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabsSeparatorDown.png b/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabsSeparatorDown.png deleted file mode 100644 index 79dbf2a199..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/AquaTabsSeparatorDown.png and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/InfoPlist.strings b/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/InfoPlist.strings deleted file mode 100644 index 0bf04f0d2c..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/InfoPlist.strings and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/PSMTabBarControlInspector.nib/classes.nib b/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/PSMTabBarControlInspector.nib/classes.nib deleted file mode 100644 index 659b73a0ee..0000000000 --- a/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/PSMTabBarControlInspector.nib/classes.nib +++ /dev/null @@ -1,22 +0,0 @@ -{ - IBClasses = ( - {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, - { - CLASS = PSMTabBarControlInspector; - LANGUAGE = ObjC; - OUTLETS = { - "_allowsDragBetweenWindows" = NSButton; - "_canCloseOnlyTab" = NSButton; - "_cellMaxWidth" = NSTextField; - "_cellMinWidth" = NSTextField; - "_cellOptimumWidth" = NSTextField; - "_hideForSingleTab" = NSButton; - "_showAddTab" = NSButton; - "_sizeToFit" = NSButton; - "_stylePopUp" = NSPopUpButton; - }; - SUPERCLASS = IBInspector; - } - ); - IBVersion = 1; -} \ No newline at end of file diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/PSMTabBarControlInspector.nib/info.nib b/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/PSMTabBarControlInspector.nib/info.nib deleted file mode 100644 index bf503dd361..0000000000 --- a/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/PSMTabBarControlInspector.nib/info.nib +++ /dev/null @@ -1,16 +0,0 @@ - - - - - IBDocumentLocation - 83 72 356 240 0 0 1680 1028 - IBFramework Version - 446.1 - IBOpenObjects - - 3 - - IBSystem Version - 8I127 - - diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/PSMTabBarControlInspector.nib/keyedobjects.nib b/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/PSMTabBarControlInspector.nib/keyedobjects.nib deleted file mode 100644 index 2def97d1d3..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/PSMTabBarControlInspector.nib/keyedobjects.nib and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/PSMTabBarControlInspector.nib/objects.nib b/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/PSMTabBarControlInspector.nib/objects.nib deleted file mode 100644 index 9a89923a6c..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/PSMTabBarControlInspector.nib/objects.nib and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/PSMTabBarControlPalette.nib/classes.nib b/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/PSMTabBarControlPalette.nib/classes.nib deleted file mode 100644 index 4752228596..0000000000 --- a/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/PSMTabBarControlPalette.nib/classes.nib +++ /dev/null @@ -1,28 +0,0 @@ -{ - IBClasses = ( - {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, - {CLASS = PSMAquaTabStyle; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, - {CLASS = PSMMetalTabStyle; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, - {CLASS = PSMOverflowPopUpButton; LANGUAGE = ObjC; SUPERCLASS = NSPopUpButton; }, - { - CLASS = PSMProgressIndicator; - LANGUAGE = ObjC; - SUPERCLASS = NSProgressIndicator; - }, - {CLASS = PSMRolloverButton; LANGUAGE = ObjC; SUPERCLASS = NSButton; }, - {CLASS = PSMTabBarCell; LANGUAGE = ObjC; SUPERCLASS = NSActionCell; }, - { - CLASS = PSMTabBarControl; - LANGUAGE = ObjC; - OUTLETS = {delegate = id; partnerView = id; style = id; tabView = NSTabView; }; - SUPERCLASS = NSControl; - }, - { - CLASS = PSMTabBarControlPalette; - LANGUAGE = ObjC; - OUTLETS = {repImage = NSImageView; }; - SUPERCLASS = IBPalette; - } - ); - IBVersion = 1; -} \ No newline at end of file diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/PSMTabBarControlPalette.nib/info.nib b/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/PSMTabBarControlPalette.nib/info.nib deleted file mode 100644 index 866500bb2a..0000000000 --- a/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/PSMTabBarControlPalette.nib/info.nib +++ /dev/null @@ -1,16 +0,0 @@ - - - - - IBDocumentLocation - 83 142 356 240 0 0 1680 1028 - IBFramework Version - 443.0 - IBOpenObjects - - 2 - - IBSystem Version - 8H14 - - diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/PSMTabBarControlPalette.nib/keyedobjects.nib b/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/PSMTabBarControlPalette.nib/keyedobjects.nib deleted file mode 100644 index 635e6d8d17..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/PSMTabBarControlPalette.nib/keyedobjects.nib and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/PSMTabBarControlPalette.nib/objects.nib b/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/PSMTabBarControlPalette.nib/objects.nib deleted file mode 100644 index c0988d7f17..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/English.lproj/PSMTabBarControlPalette.nib/objects.nib and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/PSMTabBarControl.ibclassdescription b/palettes/PSMTabBarControl.palette/Contents/Resources/PSMTabBarControl.ibclassdescription deleted file mode 100755 index 89959b3847..0000000000 --- a/palettes/PSMTabBarControl.palette/Contents/Resources/PSMTabBarControl.ibclassdescription +++ /dev/null @@ -1,7 +0,0 @@ -{ - PSMTabBarControl = { - SuperClass = NSControl; - Attributes = { - }; - }; -} \ No newline at end of file diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/TabClose_Front.tif b/palettes/PSMTabBarControl.palette/Contents/Resources/TabClose_Front.tif deleted file mode 100644 index abdea19f7a..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/TabClose_Front.tif and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/TabClose_Front_Pressed.tif b/palettes/PSMTabBarControl.palette/Contents/Resources/TabClose_Front_Pressed.tif deleted file mode 100644 index 125cf7e310..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/TabClose_Front_Pressed.tif and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/TabClose_Front_Rollover.tif b/palettes/PSMTabBarControl.palette/Contents/Resources/TabClose_Front_Rollover.tif deleted file mode 100644 index 3d2bcb6211..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/TabClose_Front_Rollover.tif and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/TabControlRep.tif b/palettes/PSMTabBarControl.palette/Contents/Resources/TabControlRep.tif deleted file mode 100644 index 6ad0f4042a..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/TabControlRep.tif and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/TabIcon.tif b/palettes/PSMTabBarControl.palette/Contents/Resources/TabIcon.tif deleted file mode 100644 index 55e08f117e..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/TabIcon.tif and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/TabNewMetal.png b/palettes/PSMTabBarControl.palette/Contents/Resources/TabNewMetal.png deleted file mode 100644 index 5b8301845a..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/TabNewMetal.png and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/TabNewMetalPressed.png b/palettes/PSMTabBarControl.palette/Contents/Resources/TabNewMetalPressed.png deleted file mode 100644 index b18f6d4cfe..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/TabNewMetalPressed.png and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/TabNewMetalRollover.png b/palettes/PSMTabBarControl.palette/Contents/Resources/TabNewMetalRollover.png deleted file mode 100644 index 083f00ae7d..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/TabNewMetalRollover.png and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/overflowImage.tiff b/palettes/PSMTabBarControl.palette/Contents/Resources/overflowImage.tiff deleted file mode 100755 index dc4b184e49..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/overflowImage.tiff and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/overflowImagePressed.tif b/palettes/PSMTabBarControl.palette/Contents/Resources/overflowImagePressed.tif deleted file mode 100755 index f6ad227df7..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/overflowImagePressed.tif and /dev/null differ diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/palette.table b/palettes/PSMTabBarControl.palette/Contents/Resources/palette.table deleted file mode 100644 index e3053e3d08..0000000000 --- a/palettes/PSMTabBarControl.palette/Contents/Resources/palette.table +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - Class PSMTabBarControlPalette - - - NibFile PSMTabBarControlPalette - - - Icon TabIcon.tif - - - ToolTips PSMTabBarControl - - - ExportClasses - - PSMTabBarControl - PSMTabBarCell - PSMAquaTabStyle - PSMMetalTabStyle - PSMRolloverButton - PSMProgressIndcator - PSMOverflowPopUpButton - - - - ExportImages - - TabControlRep.tif - TabIcon.tif - - - - ExportSounds - - - - - diff --git a/palettes/PSMTabBarControl.palette/Contents/Resources/pi.png b/palettes/PSMTabBarControl.palette/Contents/Resources/pi.png deleted file mode 100644 index e3ff079452..0000000000 Binary files a/palettes/PSMTabBarControl.palette/Contents/Resources/pi.png and /dev/null differ diff --git a/src/ActivityLog.h b/src/ActivityLog.h index fada44f5ff..234ebdbf0a 100644 --- a/src/ActivityLog.h +++ b/src/ActivityLog.h @@ -27,11 +27,9 @@ } // Accessor functions --(NSString *)name; --(NSString *)status; --(NSString *)details; --(void)setName:(NSString *)aName; --(void)setStatus:(NSString *)aStatus; +@property (nonatomic, copy) NSString *name; +@property (nonatomic, copy) NSString *status; +@property (nonatomic, readonly, copy) NSString *details; -(void)appendDetail:(NSString *)aString; -(void)clearDetails; @end @@ -42,7 +40,7 @@ // Accessor functions +(ActivityLog *)defaultLog; --(NSArray *)allItems; +@property (nonatomic, readonly, copy) NSArray *allItems; -(ActivityItem *)itemByName:(NSString *)theName; -(void)sortUsingDescriptors:(NSArray *)sortDescriptors; @end diff --git a/src/ActivityLog.m b/src/ActivityLog.m index 10c1d21862..e56640d3a3 100644 --- a/src/ActivityLog.m +++ b/src/ActivityLog.m @@ -21,19 +21,17 @@ #import "ActivityLog.h" #import "Database.h" -static ActivityLog * defaultActivityLog = nil; // Singleton object - @implementation ActivityItem /* init * Initialise a new ActivityItem object */ --(id)init +-(instancetype)init { if ((self = [super init]) != nil) { - [self setName:@""]; - [self setStatus:@""]; + self.name = @""; + self.status = @""; details = nil; } return self; @@ -60,8 +58,6 @@ -(NSString *)status */ -(void)setName:(NSString *)aName { - [aName retain]; - [name release]; name = aName; } @@ -70,10 +66,10 @@ -(void)setName:(NSString *)aName */ -(void)setStatus:(NSString *)aStatus { - [aStatus retain]; - [status release]; - status = aStatus; - [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_ActivityLogChange" object:self]; + dispatch_async(dispatch_get_main_queue(), ^{ + status = aStatus; + [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_ActivityLogChange" object:self]; + }); } /* clearDetails @@ -89,10 +85,13 @@ -(void)clearDetails */ -(void)appendDetail:(NSString *)aString { - if (details == nil) - details = [[NSMutableArray alloc] init]; - [details addObject:aString]; - [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_ActivityDetailChange" object:self]; + dispatch_async(dispatch_get_main_queue(), ^{ + if (details == nil) { + details = [[NSMutableArray alloc] init]; + } + [details addObject:aString]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_ActivityDetailChange" object:self]; + }); } /* details @@ -106,8 +105,7 @@ -(NSString *)details { for (NSString * aString in details) { - [detailString appendString:aString]; - [detailString appendString:@"\n"]; + [detailString appendFormat:@"%@\n", aString]; } } return detailString; @@ -121,21 +119,9 @@ -(NSString *)description return [NSString stringWithFormat:@"{'%@', '%@'}", name, status]; } -/* dealloc - * Clean up before we expire. - */ --(void)dealloc -{ - [details release]; - details=nil; - [status release]; - status=nil; - [name release]; - name=nil; - [super dealloc]; -} @end + @implementation ActivityLog /* defaultLog @@ -143,15 +129,19 @@ @implementation ActivityLog */ +(ActivityLog *)defaultLog { - if (defaultActivityLog == nil) + // Singleton + static ActivityLog * defaultActivityLog = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ defaultActivityLog = [[ActivityLog alloc] init]; + }); return defaultActivityLog; } /* init * Initialise a new log instance. */ --(id)init +-(instancetype)init { if ((self = [super init]) != nil) { @@ -166,8 +156,8 @@ -(id)init */ -(void)handleWillDeleteFolder:(NSNotification *)nc { - Folder * folder = [[Database sharedDatabase] folderFromID:[[nc object] intValue]]; - ActivityItem * item = [self itemByName:[folder name]]; + Folder * folder = [[Database sharedManager] folderFromID:[nc.object integerValue]]; + ActivityItem * item = [self itemByName:folder.name]; [log removeObject:item]; [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_ActivityLogChange" object:nil]; } @@ -177,14 +167,14 @@ -(void)handleWillDeleteFolder:(NSNotification *)nc * return, indexPointer is the index of the item or the index of the item just * where the status item should be if it was found. */ --(ActivityItem *)getStatus:(NSString *)name index:(int *)indexPointer +-(ActivityItem *)getStatus:(NSString *)name index:(NSInteger *)indexPointer { - int indexOfItem = 0; + NSInteger indexOfItem = 0; ActivityItem * item; for (item in log) { - if ([[item name] caseInsensitiveCompare:name] == NSOrderedSame) + if ([item.name caseInsensitiveCompare:name] == NSOrderedSame) break; ++indexOfItem; } @@ -199,16 +189,15 @@ -(ActivityItem *)getStatus:(NSString *)name index:(int *)indexPointer -(ActivityItem *)itemByName:(NSString *)theName { ActivityItem * item; - int insertionIndex; + NSInteger insertionIndex; if ((item = [self getStatus:theName index:&insertionIndex]) == nil) { item = [[ActivityItem alloc] init]; - [item setName:theName]; + item.name = theName; [log insertObject:item atIndex:insertionIndex]; - [item release]; - item = [log objectAtIndex:insertionIndex]; + item = log[insertionIndex]; } return item; } @@ -235,8 +224,5 @@ -(NSArray *)allItems -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - [log release]; - log=nil; - [super dealloc]; } @end diff --git a/src/ActivityViewer.m b/src/ActivityViewer.m index 7e9faa5e95..433460867d 100644 --- a/src/ActivityViewer.m +++ b/src/ActivityViewer.m @@ -29,11 +29,11 @@ @implementation ActivityViewer /* init * Just init the activity window. */ --(id)init +-(instancetype)init { if ((self = [super initWithWindowNibName:@"ActivityViewer"]) != nil) { - allItems = [[[ActivityLog defaultLog] allItems] retain]; + allItems = [ActivityLog defaultLog].allItems; } return self; } @@ -45,15 +45,15 @@ -(void)windowDidLoad { // Work around a Cocoa bug where the window positions aren't saved [self setShouldCascadeWindows:NO]; - [self setWindowFrameAutosaveName:@"activityViewer"]; - [activityWindow setDelegate:self]; + self.windowFrameAutosaveName = @"activityViewer"; + activityWindow.delegate = self; // Default font for the details view NSFont * detailsFont = [NSFont fontWithName:@"Monaco" size:11.0]; - [activityDetail setFont:detailsFont]; + activityDetail.font = detailsFont; // Handle double-click on an item - [activityTable setDoubleAction:@selector(handleDoubleClick:)]; + activityTable.doubleAction = @selector(handleDoubleClick:); // Set window title [activityWindow setTitle:NSLocalizedString(@"Activity Window", nil)]; @@ -62,7 +62,7 @@ -(void)windowDidLoad [activityTable localiseHeaderStrings]; // Restore the split position - [splitView setLayout:[[Preferences standardPreferences] objectForKey:@"SplitView3Positions"]]; + splitView.xlayout = [[Preferences standardPreferences] objectForKey:@"SplitView3Positions"]; // Set up to receive notifications when the activity log changes NSNotificationCenter * nc = [NSNotificationCenter defaultCenter]; @@ -76,7 +76,7 @@ -(void)windowDidLoad */ -(BOOL)windowShouldClose:(NSNotification *)notification { - [[Preferences standardPreferences] setObject:[splitView layout] forKey:@"SplitView3Positions"]; + [[Preferences standardPreferences] setObject:splitView.xlayout forKey:@"SplitView3Positions"]; return YES; } @@ -85,20 +85,20 @@ -(BOOL)windowShouldClose:(NSNotification *)notification */ -(IBAction)handleDoubleClick:(id)sender { - int selectedRow = [activityTable selectedRow]; + NSInteger selectedRow = activityTable.selectedRow; if (selectedRow >= 0) { - ActivityItem * selectedItem = [allItems objectAtIndex:selectedRow]; + ActivityItem * selectedItem = allItems[selectedRow]; // Name might be a URL if the feed has always been invalid. - Database * db = [Database sharedDatabase]; - Folder * folder = [db folderFromName:[selectedItem name]]; + Database * db = [Database sharedManager]; + Folder * folder = [db folderFromName:selectedItem.name]; if (folder == nil) - folder = [db folderFromFeedURL:[selectedItem name]]; + folder = [db folderFromFeedURL:selectedItem.name]; if (folder != nil) { AppController * controller = APPCONTROLLER; - [controller selectFolder:[folder itemId]]; + [controller selectFolder:folder.itemId]; } } } @@ -110,15 +110,15 @@ -(void)reloadTable { ActivityItem * selectedItem = nil; - int selectedRow = [activityTable selectedRow]; - if (selectedRow >= 0 && selectedRow < [allItems count]) - selectedItem = [allItems objectAtIndex:selectedRow]; + NSInteger selectedRow = activityTable.selectedRow; + if (selectedRow >= 0 && selectedRow < allItems.count) + selectedItem = allItems[selectedRow]; - [[ActivityLog defaultLog] sortUsingDescriptors:[activityTable sortDescriptors]]; + [[ActivityLog defaultLog] sortUsingDescriptors:activityTable.sortDescriptors]; [activityTable reloadData]; if (selectedItem == nil) - [activityDetail setString:@""]; + activityDetail.string = @""; else { NSUInteger rowToSelect = [allItems indexOfObject:selectedItem]; @@ -148,11 +148,11 @@ -(void)handleLogChange:(NSNotification *)nc */ -(void)handleDetailChange:(NSNotification *)nc { - ActivityItem * item = (ActivityItem *)[nc object]; - int selectedRow = [activityTable selectedRow]; + ActivityItem * item = (ActivityItem *)nc.object; + NSInteger selectedRow = activityTable.selectedRow; - if (selectedRow >= 0 && (item == [allItems objectAtIndex:selectedRow])) - [activityDetail setString:[item details]]; + if (selectedRow >= 0 && (item == allItems[selectedRow])) + activityDetail.string = item.details; } /* numberOfRowsInTableView [datasource] @@ -161,7 +161,7 @@ -(void)handleDetailChange:(NSNotification *)nc */ -(NSUInteger)numberOfRowsInTableView:(NSTableView *)aTableView { - return [allItems count]; + return allItems.count; } /* tableViewSelectionDidChange [delegate] @@ -170,11 +170,11 @@ -(NSUInteger)numberOfRowsInTableView:(NSTableView *)aTableView */ -(void)tableViewSelectionDidChange:(NSNotification *)aNotification { - int selectedRow = [activityTable selectedRow]; - if (selectedRow >= 0 && selectedRow < [allItems count]) + NSInteger selectedRow = activityTable.selectedRow; + if (selectedRow >= 0 && selectedRow < allItems.count) { - ActivityItem * item = [allItems objectAtIndex:selectedRow]; - [activityDetail setString:[item details]]; + ActivityItem * item = allItems[selectedRow]; + activityDetail.string = item.details; } } @@ -191,8 +191,16 @@ -(void)tableView:(NSTableView *)aTableView sortDescriptorsDidChange:(NSArray *)o */ -(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSUInteger)rowIndex { - ActivityItem * item = [allItems objectAtIndex:rowIndex]; - return ([aTableColumn identifier]) ? [item valueForKey:[aTableColumn identifier]] : @""; + NSString * identifier = aTableColumn.identifier; + if (identifier != nil && identifier.length > 0 ) + { + ActivityItem * item = allItems[rowIndex]; + return [item valueForKey:identifier]; + } + else + { + return @""; + } } /* dealloc @@ -202,8 +210,6 @@ -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; [activityWindow setDelegate:nil]; - [allItems release]; allItems=nil; - [super dealloc]; } @end diff --git a/src/AddressBarCell.h b/src/AddressBarCell.h index a569bd3382..af1f9cdd25 100644 --- a/src/AddressBarCell.h +++ b/src/AddressBarCell.h @@ -25,6 +25,5 @@ } // Accessor functions --(void)setHasSecureImage:(BOOL)flag; --(BOOL)hasSecureImage; +@property (nonatomic) BOOL hasSecureImage; @end \ No newline at end of file diff --git a/src/AddressBarCell.m b/src/AddressBarCell.m index 2a29416508..5bd94e098a 100644 --- a/src/AddressBarCell.m +++ b/src/AddressBarCell.m @@ -25,7 +25,7 @@ @implementation AddressBarCell /* initTextCell * Initialise a new TextFieldCell subclass. */ --(id)initTextCell:(NSString *)inStr +-(instancetype)initTextCell:(NSString *)inStr { if ((self = [super initTextCell:inStr]) != nil) { @@ -40,7 +40,7 @@ -(id)initTextCell:(NSString *)inStr -(void)setHasSecureImage:(BOOL)flag { hasSecureImage = flag; - [(NSControl*)[self controlView] calcSize]; + [(NSControl*)self.controlView calcSize]; } /* hasSecureImage @@ -57,7 +57,7 @@ -(BOOL)hasSecureImage */ -(NSRect)drawingRectForBounds:(NSRect)theRect { - const float imageSpace = 19.0; + const CGFloat imageSpace = 19.0; theRect.origin.x += imageSpace; theRect.size.width -= imageSpace; diff --git a/src/AppController.h b/src/AppController.h index 14d83f5874..29c8851308 100644 --- a/src/AppController.h +++ b/src/AppController.h @@ -28,35 +28,33 @@ #import "PopupButton.h" #import "PluginManager.h" #import +#import "CDEvents.h" -#define APPCONTROLLER (AppController *)[NSApp delegate] +#define APPCONTROLLER ((AppController *)[NSApp delegate]) +#define APP ((ViennaApp *)NSApp) -@class NewPreferencesController; @class FoldersTree; @class SmartFolder; @class NewSubscription; @class NewGroupFolder; @class WebPreferences; @class BrowserView; -@class ArticleListView; -@class UnifiedDisplayView; @class EmptyTrashWarning; @class ClickableProgressIndicator; @class SearchPanel; @class BJRWindowWithToolbar; +@class TreeFilterView; +@class ViennaSparkleDelegate; @interface AppController : NSObject { IBOutlet BJRWindowWithToolbar * mainWindow; IBOutlet ArticleController * articleController; - IBOutlet FoldersTree * foldersTree; IBOutlet NSSplitView * splitView1; IBOutlet NSView * exportSaveAccessory; IBOutlet NSView * searchView; IBOutlet NSSearchField * filterSearchField; IBOutlet NSPopUpButton * filterViewPopUp; - IBOutlet ArticleListView * mainArticleView; - IBOutlet UnifiedDisplayView * unifiedListView; IBOutlet NSView * articleFrame; IBOutlet BrowserView * browserView; IBOutlet NSButtonCell * exportAll; @@ -73,12 +71,13 @@ IBOutlet NSMenuItem * stylesMenu; IBOutlet NSMenuItem * filtersMenu; IBOutlet FilterView * filterView; + IBOutlet TreeFilterView *treeFilterView; + IBOutlet TreeFilterView *treeFilterSearchField; IBOutlet NSView * cosmeticStatusBarHighlightLine; IBOutlet NSTextField * currentFilterTextField; IBOutlet NSButton * filterIconInStatusBarButton; ActivityViewer * activityViewer; - NewPreferencesController * preferenceController; DownloadWindow * downloadWindow; SmartFolder * smartFolder; NewGroupFolder * groupFolder; @@ -91,28 +90,28 @@ NSMutableDictionary * scriptPathMappings; NSMenu * appDockMenu; NSStatusItem * appStatusItem; - int progressCount; + NSInteger progressCount; NSDictionary * standardURLs; NSTimer * checkTimer; - int lastCountOfUnread; + NSInteger lastCountOfUnread; BOOL isStatusBarVisible; NSString * persistedStatusText; NSMenuItem * scriptsMenuItem; BOOL didCompleteInitialisation; NSString * searchString; - NSWindowController *_preferencesWindowController; NewSubscription * _rssFeed; + CDEvents * _events; + ViennaSparkleDelegate * _sparkleDelegate; } -@property (nonatomic, readonly) NSWindowController *preferencesWindowController; -@property(nonatomic, retain) NewSubscription *rssFeed; +@property(nonatomic, strong) NewSubscription *rssFeed; +@property(nonatomic, strong) IBOutlet FoldersTree * foldersTree; // Menu action items -(IBAction)handleAbout:(id)sender; -(IBAction)exitVienna:(id)sender; -(IBAction)reindexDatabase:(id)sender; --(IBAction)showPreferencePanel:(id)sender; -(IBAction)deleteMessage:(id)sender; -(IBAction)deleteFolder:(id)sender; -(IBAction)searchUsingToolbarTextField:(id)sender; @@ -134,7 +133,6 @@ -(IBAction)newGroupFolder:(id)sender; -(IBAction)editFolder:(id)sender; -(IBAction)showXMLSource:(id)sender; --(IBAction)showAcknowledgements:(id)sender; -(IBAction)showViennaHomePage:(id)sender; -(IBAction)viewArticlePages:(id)sender; -(IBAction)viewArticlePagesInAlternateBrowser:(id)sender; @@ -184,6 +182,8 @@ -(IBAction)setFocusToSearchField:(id)sender; -(IBAction)localPerformFindPanelAction:(id)sender; -(IBAction)keepFoldersArranged:(id)sender; +-(IBAction)exportSubscriptions:(id)sender; +-(IBAction)importSubscriptions:(id)sender; // Public functions @@ -196,32 +196,29 @@ -(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger)flags; -(void)openURLInDefaultBrowser:(NSURL *)url; -(void)handleRSSLink:(NSString *)linkPath; --(void)selectFolder:(int)folderId; +-(void)selectFolder:(NSInteger)folderId; -(void)createNewSubscription:(NSString *)urlString underFolder:(NSInteger)parentId afterChild:(NSInteger)predecessorId; -(void)createNewGoogleReaderSubscription:(NSString *)url underFolder:(NSInteger)parentId withTitle:(NSString*)title afterChild:(NSInteger)predecessorId; -(void)markSelectedFoldersRead:(NSArray *)arrayOfFolders; -(void)doSafeInitialisation; -(void)clearUndoStack; --(NSString *)filterString; --(void)setFilterString:(NSString *)newFilterString; --(NSString *)searchString; --(void)setSearchString:(NSString *)newSearchString; --(Article *)selectedArticle; --(int)currentFolderId; --(BOOL)isConnecting; +@property (nonatomic, copy) NSString *filterString; +@property (nonatomic, copy) NSString *searchString; +@property (nonatomic, readonly, strong) Article *selectedArticle; +@property (nonatomic, readonly) NSInteger currentFolderId; +@property (nonatomic, getter=isConnecting, readonly) BOOL connecting; -(void)runAppleScript:(NSString *)scriptName; -(NSDictionary *)standardURLs; --(BrowserView *)browserView; --(NSArray *)folders; +@property (nonatomic, readonly, strong) BrowserView *browserView; +@property (nonatomic, readonly, copy) NSArray *folders; -(void)blogWithExternalEditor:(NSString *)externalEditorBundleIdentifier; -(void)toggleOptionKeyButtonStates; --(NSMenu *)folderMenu; +@property (nonatomic, readonly, copy) NSMenu *folderMenu; -(void)updateStatusBarFilterButtonVisibility; --(NSLayoutManager *)layoutManager; --(void)viewAnimationCompleted:(NSView *)theView withTag:(int)viewTag; +@property (nonatomic, readonly, strong) NSLayoutManager *layoutManager; +-(void)viewAnimationCompleted:(NSView *)theView withTag:(NSInteger)viewTag; -(void)growlNotify:(id)notifyContext title:(NSString *)title description:(NSString *)description notificationName:(NSString *)notificationName; -(void)performWebSearch:(SearchMethod *)searchMethod; -(void)performAllArticlesSearch; -(void)performWebPageSearch; -+(NSDate *)getDateFromString:(NSString *)dateString; @end diff --git a/src/AppController.m b/src/AppController.m index 280fcc1109..8124bde49e 100644 --- a/src/AppController.m +++ b/src/AppController.m @@ -20,22 +20,13 @@ #import "AppController.h" -#import "MASPreferencesWindowController.h" -#import "GeneralPreferencesViewController.h" -#import "AppearancePreferencesViewController.h" -#import "SyncingPreferencesViewController.h" -#import "AdvancedPreferencesViewController.h" - #import "FoldersTree.h" -#import "ArticleListView.h" -#import "UnifiedDisplayView.h" #import "Import.h" #import "Export.h" #import "RefreshManager.h" #import "ArrayExtensions.h" #import "StringExtensions.h" #import "SplitViewExtensions.h" -#import "SquareWindow.h" #import "ViewExtensions.h" #import "BrowserView.h" #import "SearchFolder.h" @@ -58,7 +49,7 @@ #import "ClickableProgressIndicator.h" #import "SearchPanel.h" #import "SearchMethod.h" -#import +#import "ViennaSparkleDelegate.h" #import #include #include @@ -70,10 +61,10 @@ #import "Database.h" #import "BJRWindowWithToolbar.h" #import "NSURL+Utils.h" - +#import "PreferencesWindowController.h" @interface AppController (Private) - -(NSMenu *)searchFieldMenu; + @property (nonatomic, readonly, copy) NSMenu *searchFieldMenu; -(void)installSleepHandler; -(void)installScriptsFolderWatcher; -(void)handleTabChange:(NSNotification *)nc; @@ -93,7 +84,7 @@ -(void)initSortMenu; -(void)initColumnsMenu; -(void)initScriptsMenu; -(void)initFiltersMenu; - -(NSMenu *)getStylesMenu; + @property (nonatomic, getter=getStylesMenu, readonly, copy) NSMenu *stylesMenu; -(void)startProgressIndicator; -(void)stopProgressIndicator; -(void)doEditFolder:(Folder *)folder; @@ -102,78 +93,51 @@ -(BOOL)installFilename:(NSString *)srcFile toPath:(NSString *)path; -(void)setStatusBarState:(BOOL)isVisible withAnimation:(BOOL)doAnimate; -(void)setFilterBarState:(BOOL)isVisible withAnimation:(BOOL)doAnimate; -(void)setPersistedFilterBarState:(BOOL)isVisible withAnimation:(BOOL)doAnimate; - -(void)doConfirmedDelete:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo; - -(void)doConfirmedEmptyTrash:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo; + -(void)doConfirmedDelete:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo; + -(void)doConfirmedEmptyTrash:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo; -(void)runAppleScript:(NSString *)scriptName; - -(NSString *)appName; + @property (nonatomic, readonly, copy) NSString *appName; -(void)sendBlogEvent:(NSString *)externalEditorBundleIdentifier title:(NSString *)title url:(NSString *)url body:(NSString *)body author:(NSString *)author guid:(NSString *)guid; - -(void)setLayout:(int)newLayout withRefresh:(BOOL)refreshFlag; + -(void)setLayout:(NSInteger)newLayout withRefresh:(BOOL)refreshFlag; -(void)updateAlternateMenuTitle; -(void)updateSearchPlaceholderAndSearchMethod; -(void)toggleOptionKeyButtonStates; - -(FoldersTree *)foldersTree; + @property (nonatomic, readonly, strong) FoldersTree *foldersTree; -(void)updateCloseCommands; - -(BOOL)isFilterBarVisible; - -(BOOL)isStatusBarVisible; - -(NSDictionary *)registrationDictionaryForGrowl; - -(NSTimer *)checkTimer; + @property (nonatomic, getter=isFilterBarVisible, readonly) BOOL filterBarVisible; + @property (nonatomic, getter=isStatusBarVisible, readonly) BOOL statusBarVisible; + @property (nonatomic, readonly, copy) NSDictionary *registrationDictionaryForGrowl; + @property (nonatomic, readonly, strong) NSTimer *checkTimer; -(ToolbarItem *)toolbarItemWithIdentifier:(NSString *)theIdentifier; -(void)searchArticlesWithString:(NSString *)searchString; -(void)sourceWindowWillClose:(NSNotification *)notification; -(IBAction)cancelAllRefreshesToolbar:(id)sender; @end +@interface AppController () + +@property (nonatomic) PreferencesWindowController *preferencesWindowController; + +@end + // Static constant strings that are typically never tweaked -static const int MA_Minimum_Folder_Pane_Width = 80; -static const int MA_Minimum_BrowserView_Pane_Width = 200; -static const int MA_StatusBarHeight = 23; +static const CGFloat MA_Minimum_Folder_Pane_Width = 80.0; +static const CGFloat MA_Minimum_BrowserView_Pane_Width = 200.0; +static const CGFloat MA_StatusBarHeight = 23.0; // Awake from sleep static io_connect_t root_port; static void MySleepCallBack(void * x, io_service_t y, natural_t messageType, void * messageArgument); -@implementation AppController { -} - -// C array of NSDateFormatter format strings. This is array is used only once to populate dateFormatterArray. -// Note: for every four-digit year entry, we need an earlier two-digit year entry so that NSDateFormatter parses -// two-digit years considering the two-digit-year start date. -static NSString * kDateFormats[] = { - //For the different date formats, see - //IMPORTANT hack : remove in these strings any colon [:] beginning from character # 20 (first char is #0) - // 2010-09-28T15:31:25Z and 2010-09-28T17:31:25+02:00 - @"yy-MM-dd'T'HH:mm:ssZZZ", @"yyyy-MM-dd'T'HH:mm:ssZZZ", - // 2010-09-28T15:31:25.815+02:00 - @"yy-MM-dd'T'HH:mm:ss.SSSZZZ", @"yyyy-MM-dd'T'HH:mm:ss.SSSZZZ", - // "Sat, 13 Dec 2008 18:45:15 EAT" and "Fri, 12 Dec 2008 18:45:15 -08:00" - @"EEE, dd MMM yy HH:mmss zzz", @"EEE, dd MMM yyyy HH:mmss zzz", - @"EEE, dd MMM yy HH:mmss ZZZ", @"EEE, dd MMM yyyy HH:mmss ZZZ", - @"EEE, dd MMM yy HH:mmss", @"EEE, dd MMM yyyy HH:mmss", - // Required by compatibility with older OS X versions - @"yy-MM-dd'T'HH:mm:ss'Z'", @"yyyy-MM-dd'T'HH:mm:ss'Z'", - @"yy-MM-dd'T'HH:mm:ss.SSS'Z'", @"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", - // Other exotic and non standard date formats - @"yy-MM-dd HH:mm:ss ZZZ", @"yyyy-MM-dd HH:mm:ss ZZZ", - @"yy-MM-dd HH:mm:ss zzz", @"yyyy-MM-dd HH:mm:ss zzz", - @"EEE dd MMM yy HH:mmss zzz", @"EEE dd MMM yyyy HH:mmss zzz", - @"EEE dd MMM yy HH:mmss ZZZ", @"EEE dd MMM yyyy HH:mmss ZZZ", - @"EEE dd MMM yy HH:mmss", @"EEE dd MMM yyyy HH:mmss", - @"EEEE dd MMMM yy", @"EEEE dd MMMM yyyy", -}; -static const size_t kNumberOfDateFormatters = sizeof(kDateFormats) / sizeof(kDateFormats[0]); -// C array of NSDateFormatter's : creating a NSDateFormatter is very expensive, so we create -// those we need early in the program launch and keep them in memory. -static NSDateFormatter * dateFormatterArray[kNumberOfDateFormatters]; - -static NSLock * dateFormatters_lock; -static NSLocale * enUSLocale; +@implementation AppController @synthesize rssFeed = _rssFeed; +@synthesize foldersTree; /* init * Class instance initialisation. */ --(id)init +-(instancetype)init { if ((self = [super init]) != nil) { @@ -197,40 +161,23 @@ -(id)init */ -(void)awakeFromNib { - -#if ( MAC_OS_X_VERSION_MAX_ALLOWED < 1070 && !defined(NSWindowCollectionBehaviorFullScreenPrimary) ) - enum { - NSWindowCollectionBehaviorFullScreenPrimary = (1 << 7) - }; -#endif - - //Enable FullScreen Support if we are on Lion 10.7.x - [mainWindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; - - Preferences * prefs = [Preferences standardPreferences]; - + // Restore the most recent layout - [self setLayout:[prefs layout] withRefresh:NO]; - + [self setLayout:prefs.layout withRefresh:NO]; + // Localise the menus - [self localiseMenus:[[NSApp mainMenu] itemArray]]; + [self localiseMenus:NSApp.mainMenu.itemArray]; // Set the delegates and title - [mainWindow setDelegate:self]; - [mainWindow setTitle:[self appName]]; - [[NSApplication sharedApplication] setDelegate:self]; - [mainWindow setMinSize: NSMakeSize(MA_Default_Main_Window_Min_Width, MA_Default_Main_Window_Min_Height)]; + mainWindow.title = self.appName; + [NSApplication sharedApplication].delegate = self; + mainWindow.minSize = NSMakeSize(MA_Default_Main_Window_Min_Width, MA_Default_Main_Window_Min_Height); // Initialise the plugin manager now that the UI is ready pluginManager = [[PluginManager alloc] init]; [pluginManager resetPlugins]; - // Retain views which might be removed from the toolbar and therefore released; - // we will need them if they are added back later. - [spinner retain]; - [searchField retain]; - // We need to register the handlers early to catch events fired on launch. NSAppleEventManager *em = [NSAppleEventManager sharedAppleEventManager]; [em setEventHandler:self @@ -241,6 +188,10 @@ -(void)awakeFromNib andSelector:@selector(getUrl:withReplyEvent:) forEventClass:'WWW!' // A particularly ancient AppleEvent that dates andEventID:'OURL']; // back to the Spyglass days. + + // Initialise delegate for Sparkle + _sparkleDelegate = [[ViennaSparkleDelegate alloc] init]; + [[SUUpdater sharedUpdater] setDelegate:_sparkleDelegate]; } /* applicationDidResignActive @@ -249,8 +200,8 @@ -(void)awakeFromNib -(void)applicationDidResignActive:(NSNotification *)aNotification { [foldersTree setOutlineViewBackgroundColor: [NSColor colorWithCalibratedRed:0.91 green:0.91 blue:0.91 alpha:1.00]]; - [statusText setTextColor:[NSColor colorWithCalibratedRed:0.43 green:0.43 blue:0.43 alpha:1.00]]; - [currentFilterTextField setTextColor:[NSColor colorWithCalibratedRed:0.43 green:0.43 blue:0.43 alpha:1.00]]; + statusText.textColor = [NSColor colorWithCalibratedRed:0.43 green:0.43 blue:0.43 alpha:1.00]; + currentFilterTextField.textColor = [NSColor colorWithCalibratedRed:0.43 green:0.43 blue:0.43 alpha:1.00]; [filterIconInStatusBarButton setEnabled:NO]; } @@ -260,8 +211,8 @@ -(void)applicationDidResignActive:(NSNotification *)aNotification -(void)applicationDidBecomeActive:(NSNotification *)notification { [foldersTree setOutlineViewBackgroundColor: [NSColor colorWithCalibratedRed:0.84 green:0.87 blue:0.90 alpha:1.00]]; - [statusText setTextColor:[NSColor blackColor]]; - [currentFilterTextField setTextColor:[NSColor blackColor]]; + statusText.textColor = [NSColor blackColor]; + currentFilterTextField.textColor = [NSColor blackColor]; [filterIconInStatusBarButton setEnabled:YES]; } @@ -274,17 +225,13 @@ -(void)doSafeInitialisation static BOOL doneSafeInit = NO; if (!doneSafeInit) { - [ASIHTTPRequest setDefaultUserAgentString:[NSString stringWithFormat:MA_DefaultUserAgentString, [[((ViennaApp *)NSApp) applicationVersion] firstWord]]]; + [ASIHTTPRequest setDefaultUserAgentString:[NSString stringWithFormat:MA_DefaultUserAgentString, ((ViennaApp *)NSApp).applicationVersion.firstWord]]; [foldersTree initialiseFoldersTree]; - [mainArticleView initialiseArticleView]; - [unifiedListView initTableView]; // If the statusbar is hidden, also hide the highlight line on its top and the filter button. - if (![self isStatusBarVisible]) + if (!self.statusBarVisible) { - if ([mainWindow respondsToSelector:@selector(setBottomCornerRounded:)]) - [mainWindow setBottomCornerRounded:NO]; [cosmeticStatusBarHighlightLine setHidden:YES]; [currentFilterTextField setHidden:YES]; [filterIconInStatusBarButton setHidden:YES]; @@ -292,26 +239,25 @@ -(void)doSafeInitialisation Preferences * prefs = [Preferences standardPreferences]; // Set the initial filter bar state - [self setFilterBarState:[prefs showFilterBar] withAnimation:NO]; - - // Make article list the first responder - [mainWindow makeFirstResponder:[[browserView primaryTabItemView] mainView]]; + [self setFilterBarState:prefs.showFilterBar withAnimation:NO]; // Select the folder and article from the last session - int previousFolderId = [prefs integerForKey:MAPref_CachedFolderID]; + NSInteger previousFolderId = [prefs integerForKey:MAPref_CachedFolderID]; NSString * previousArticleGuid = [prefs stringForKey:MAPref_CachedArticleGUID]; - if ([previousArticleGuid isBlank]) + if (previousArticleGuid.blank) previousArticleGuid = nil; - [[articleController mainArticleView] selectFolderAndArticle:previousFolderId guid:previousArticleGuid]; + [articleController selectFolderAndArticle:previousFolderId guid:previousArticleGuid]; + + [mainWindow makeFirstResponder:(previousArticleGuid != nil) ? [browserView primaryTabItemView].mainView : foldersTree.mainView]; - if ([prefs refreshOnStartup]) + if (prefs.refreshOnStartup) [self refreshAllSubscriptions:self]; // Start opening the old tabs once everything else has finished initializing and setting up NSArray * tabLinks = [prefs arrayForKey:MAPref_TabList]; for (NSString * tabLink in tabLinks) { - [self createNewTab:([tabLink length] ? [NSURL URLWithString:tabLink] : nil) inBackground:YES]; + [self createNewTab:(tabLink.length ? [NSURL URLWithString:tabLink] : nil) inBackground:YES]; } doneSafeInit = YES; @@ -328,24 +274,23 @@ -(void)doSafeInitialisation */ -(void)localiseMenus:(NSArray *)arrayOfMenus { - int count = [arrayOfMenus count]; - int index; + NSUInteger count = arrayOfMenus.count; - for (index = 0; index < count; ++index) + for (NSUInteger index = 0; index < count; ++index) { - NSMenuItem * menuItem = [arrayOfMenus objectAtIndex:index]; - if (menuItem != nil && ![menuItem isSeparatorItem]) + NSMenuItem * menuItem = arrayOfMenus[index]; + if (menuItem != nil && !menuItem.separatorItem) { NSString * localisedMenuTitle = NSLocalizedString([menuItem title], nil); - if ([menuItem submenu]) + if (menuItem.submenu) { - NSMenu * subMenu = [menuItem submenu]; + NSMenu * subMenu = menuItem.submenu; if (localisedMenuTitle != nil) - [subMenu setTitle:localisedMenuTitle]; - [self localiseMenus:[subMenu itemArray]]; + subMenu.title = localisedMenuTitle; + [self localiseMenus:subMenu.itemArray]; } if (localisedMenuTitle != nil) - [menuItem setTitle:localisedMenuTitle]; + menuItem.title = localisedMenuTitle; } } } @@ -369,33 +314,36 @@ static void MySleepCallBack(void * refCon, io_service_t service, natural_t messa if (messageType == kIOMessageSystemHasPoweredOn) { AppController * app = APPCONTROLLER; - Preferences * prefs = [Preferences standardPreferences]; - int frequency = [prefs refreshFrequency]; - if (frequency > 0) + if (app != nil) { - NSDate * lastRefresh = [prefs objectForKey:MAPref_LastRefreshDate]; - if ((lastRefresh == nil) || ([app checkTimer] == nil)) - [app handleCheckFrequencyChange:nil]; - else - { - // Wait at least 15 seconds after waking to avoid refresh errors. - NSTimeInterval interval = -[lastRefresh timeIntervalSinceNow]; - if (interval > frequency) - { - if ([[Preferences standardPreferences] syncGoogleReader]) - [[GoogleReader sharedManager] getToken]; - [NSTimer scheduledTimerWithTimeInterval:15.0 - target:app - selector:@selector(refreshOnTimer:) - userInfo:nil - repeats:NO]; - [app handleCheckFrequencyChange:nil]; - } - else - { - [[app checkTimer] setFireDate:[NSDate dateWithTimeIntervalSinceNow:15.0 + frequency - interval]]; - } - } + Preferences * prefs = [Preferences standardPreferences]; + NSInteger frequency = prefs.refreshFrequency; + if (frequency > 0) + { + NSDate * lastRefresh = [prefs objectForKey:MAPref_LastRefreshDate]; + if ((lastRefresh == nil) || (app.checkTimer == nil)) + [app handleCheckFrequencyChange:nil]; + else + { + // Wait at least 15 seconds after waking to avoid refresh errors. + NSTimeInterval interval = -lastRefresh.timeIntervalSinceNow; + if (interval > frequency) + { + if ([Preferences standardPreferences].syncGoogleReader) + [[GoogleReader sharedManager] getToken]; + [NSTimer scheduledTimerWithTimeInterval:15.0 + target:app + selector:@selector(refreshOnTimer:) + userInfo:nil + repeats:NO]; + [app handleCheckFrequencyChange:nil]; + } + else + { + app.checkTimer.fireDate = [NSDate dateWithTimeIntervalSinceNow:15.0 + frequency - interval]; + } + } + } } } else if (messageType == kIOMessageCanSystemSleep) @@ -421,30 +369,23 @@ -(void)installSleepHandler IONotificationPortRef notify; io_object_t anIterator; - root_port = IORegisterForSystemPower(self, ¬ify, MySleepCallBack, &anIterator); + root_port = IORegisterForSystemPower((__bridge void *)(self), ¬ify, MySleepCallBack, &anIterator); if (root_port != 0) CFRunLoopAddSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(notify), kCFRunLoopCommonModes); } -/* MyScriptsFolderWatcherCallBack - * This is the callback function which is invoked when the file system detects changes in the Scripts - * folder. We use this to trigger a refresh of the scripts menu. - */ -static void MyScriptsFolderWatcherCallBack(FNMessage message, OptionBits flags, void * refcon, FNSubscriptionRef subscription) -{ - AppController * app = (AppController *)refcon; - [app initScriptsMenu]; -} - /* installScriptsFolderWatcher * Install a handler to notify of changes in the scripts folder. + * The handler is a code block which triggers a refresh of the scripts menu */ -(void)installScriptsFolderWatcher { - NSString * path = [[Preferences standardPreferences] scriptsFolder]; - FNSubscriptionRef refCode; - - FNSubscribeByPath((const UInt8 *)[path UTF8String], MyScriptsFolderWatcherCallBack, self, kNilOptions, &refCode); + NSURL * path = [NSURL fileURLWithPath:[Preferences standardPreferences].scriptsFolder]; + _events = [[CDEvents alloc] initWithURLs:@[path] + block:^(CDEvents *watcher, CDEvent *event) { + // triggers a refresh of the scripts.menu + [self initScriptsMenu]; + }]; } /* layoutManager @@ -483,6 +424,7 @@ -(void)applicationDidFinishLaunching:(NSNotification *)aNot [nc addObserver:self selector:@selector(handleShowAppInStatusBar:) name:@"MA_Notify_ShowAppInStatusBarChanged" object:nil]; [nc addObserver:self selector:@selector(handleShowStatusBar:) name:@"MA_Notify_StatusBarChanged" object:nil]; [nc addObserver:self selector:@selector(handleShowFilterBar:) name:@"MA_Notify_FilterBarChanged" object:nil]; + [nc addObserver:self selector:@selector(showUnreadCountOnApplicationIconAndWindowTitle) name:@"MA_Notify_FoldersUpdated" object:nil]; //Open Reader Notifications [nc addObserver:self selector:@selector(handleGoogleAuthFailed:) name:@"MA_Notify_GoogleAuthFailed" object:nil]; @@ -490,33 +432,33 @@ -(void)applicationDidFinishLaunching:(NSNotification *)aNot [self setStatusMessage:nil persist:NO]; // Initialize the database - if ((db = [Database sharedDatabase]) == nil) + if ((db = [Database sharedManager]) == nil) { [NSApp terminate:nil]; return; } // Create the toolbar. - NSToolbar * toolbar = [[[NSToolbar alloc] initWithIdentifier:@"MA_Toolbar"] autorelease]; + NSToolbar * toolbar = [[NSToolbar alloc] initWithIdentifier:@"MA_Toolbar"]; // Set the appropriate toolbar options. We are the delegate, customization is allowed, // changes made by the user are automatically saved and we start in icon mode. - [toolbar setDelegate:self]; + toolbar.delegate = self; [toolbar setAllowsUserCustomization:YES]; [toolbar setAutosavesConfiguration:YES]; - [toolbar setDisplayMode:NSToolbarDisplayModeIconOnly]; + toolbar.displayMode = NSToolbarDisplayModeIconOnly; [toolbar setShowsBaselineSeparator:NO]; - [mainWindow setToolbar:toolbar]; + mainWindow.toolbar = toolbar; // Give the status bar and filter string an embossed look - [[statusText cell] setBackgroundStyle:NSBackgroundStyleRaised]; - [[currentFilterTextField cell] setBackgroundStyle:NSBackgroundStyleRaised]; - [currentFilterTextField setStringValue:@""]; + statusText.cell.backgroundStyle = NSBackgroundStyleRaised; + currentFilterTextField.cell.backgroundStyle = NSBackgroundStyleRaised; + currentFilterTextField.stringValue = @""; // Preload dictionary of standard URLs NSString * pathToPList = [[NSBundle mainBundle] pathForResource:@"StandardURLs.plist" ofType:@""]; if (pathToPList != nil) - standardURLs = [[NSDictionary dictionaryWithContentsOfFile:pathToPList] retain]; + standardURLs = [NSDictionary dictionaryWithContentsOfFile:pathToPList]; // Initialize the Sort By and Columns menu [self initSortMenu]; @@ -524,11 +466,11 @@ -(void)applicationDidFinishLaunching:(NSNotification *)aNot [self initFiltersMenu]; // Initialize the Styles menu. - [stylesMenu setSubmenu:[self getStylesMenu]]; + stylesMenu.submenu = self.stylesMenu; // Restore the splitview layout - [splitView1 setLayout:[[Preferences standardPreferences] objectForKey:@"SplitView1Positions"]]; - [splitView1 setDelegate:self]; + splitView1.xlayout = [[Preferences standardPreferences] objectForKey:@"SplitView1Positions"]; + splitView1.delegate = self; // Show the current unread count on the app icon [self showUnreadCountOnApplicationIconAndWindowTitle]; @@ -538,13 +480,13 @@ -(void)applicationDidFinishLaunching:(NSNotification *)aNot NSMenuItem * alternateItem = menuItemWithAction(@selector(viewSourceHomePageInAlternateBrowser:)); if (alternateItem != nil) { - [alternateItem setKeyEquivalentModifierMask:NSAlternateKeyMask]; + alternateItem.keyEquivalentModifierMask = NSAlternateKeyMask; [alternateItem setAlternate:YES]; } alternateItem = menuItemWithAction(@selector(viewArticlePagesInAlternateBrowser:)); if (alternateItem != nil) { - [alternateItem setKeyEquivalentModifierMask:NSAlternateKeyMask]; + alternateItem.keyEquivalentModifierMask = NSAlternateKeyMask; [alternateItem setAlternate:YES]; } [self updateAlternateMenuTitle]; @@ -552,34 +494,34 @@ -(void)applicationDidFinishLaunching:(NSNotification *)aNot // Create a menu for the search field // The menu title doesn't appear anywhere so we don't localise it. The titles of each // item is localised though. - [[searchField cell] setSearchMenuTemplate:[self searchFieldMenu]]; - [[filterSearchField cell] setSearchMenuTemplate:[self searchFieldMenu]]; + ((NSSearchFieldCell *)searchField.cell).searchMenuTemplate = self.searchFieldMenu; + ((NSSearchFieldCell *)filterSearchField.cell).searchMenuTemplate = self.searchFieldMenu; // Set the placeholder string for the global search field - SearchMethod * currentSearchMethod = [[Preferences standardPreferences] searchMethod]; - [[searchField cell] setPlaceholderString:NSLocalizedString([currentSearchMethod friendlyName], nil)]; + SearchMethod * currentSearchMethod = [Preferences standardPreferences].searchMethod; + [searchField.cell setPlaceholderString:NSLocalizedString([currentSearchMethod friendlyName], nil)]; // Add Scripts menu if we have any scripts if (!hasOSScriptsMenu()) [self initScriptsMenu]; // Show/hide the status bar based on the last session state - [self setStatusBarState:[prefs showStatusBar] withAnimation:NO]; + [self setStatusBarState:prefs.showStatusBar withAnimation:NO]; // Add the app to the status bar if needed. [self showAppInStatusBar]; // Growl initialization NSBundle *mainBundle = [NSBundle mainBundle]; - NSString *path = [[mainBundle privateFrameworksPath] stringByAppendingPathComponent:@"Growl.framework"]; + NSString *path = [mainBundle.privateFrameworksPath stringByAppendingPathComponent:@"Growl.framework"]; LOG_NS(@"path: %@", path); NSBundle *growlFramework = [NSBundle bundleWithPath:path]; if([growlFramework load]) { - NSDictionary *infoDictionary = [growlFramework infoDictionary]; + NSDictionary *infoDictionary = growlFramework.infoDictionary; LOG_NS(@"Using Growl.framework %@ (%@)", - [infoDictionary objectForKey:@"CFBundleShortVersionString"], - [infoDictionary objectForKey:(NSString *)kCFBundleVersionKey]); + infoDictionary[@"CFBundleShortVersionString"], + infoDictionary[(NSString *)kCFBundleVersionKey]); Class GAB = NSClassFromString(@"GrowlApplicationBridge"); if([GAB respondsToSelector:@selector(setGrowlDelegate:)]) @@ -602,11 +544,11 @@ -(void)applicationDidFinishLaunching:(NSNotification *)aNot [self showMainWindow:self]; // Hook up the key sequence properly now that all NIBs are loaded. - [[foldersTree mainView] setNextKeyView:[[browserView primaryTabItemView] mainView]]; + foldersTree.mainView.nextKeyView = [browserView primaryTabItemView].mainView; // Check if we have previously asked the user to send anonymous system profile if([[NSUserDefaults standardUserDefaults] objectForKey:MAPref_SendSystemProfileInfo] == nil) { - [self showSystemProfileInfoAlert]; + [_sparkleDelegate showSystemProfileInfoAlert]; } // Do safe initialisation. @@ -631,24 +573,15 @@ -(BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleW return YES; } -/* updaterWillRelaunchApplication - * This is a delegate for Sparkle.framwork - */ -- (void)updaterWillRelaunchApplication:(SUUpdater *)updater -{ - [[Preferences standardPreferences] handleUpdateRestart]; - -} - /* applicationShouldTerminate * This function is called when the user wants to close Vienna. First we check to see * if a connection or import is running and that all articles are saved. */ -(NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { - int returnCode; + NSInteger returnCode; - if ([[DownloadManager sharedInstance] activeDownloads] > 0) + if ([DownloadManager sharedInstance].activeDownloads > 0) { returnCode = NSRunAlertPanel(NSLocalizedString(@"Downloads Running", nil), NSLocalizedString(@"Downloads Running text", nil), @@ -656,11 +589,15 @@ -(NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender NSLocalizedString(@"Cancel", nil), nil); if (returnCode == NSAlertAlternateReturn) + { + [[NSNotificationCenter defaultCenter] removeObserver:self]; return NSTerminateCancel; + } } if (!didCompleteInitialisation) { + [[NSNotificationCenter defaultCenter] removeObserver:self]; return NSTerminateNow; } @@ -669,22 +606,21 @@ -(NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender case MA_EmptyTrash_None: break; case MA_EmptyTrash_WithoutWarning: - if (![db isTrashEmpty]) + if (!db.trashEmpty) { [db purgeDeletedArticles]; } break; case MA_EmptyTrash_WithWarning: - if (![db isTrashEmpty]) + if (!db.trashEmpty) { if (emptyTrashWarning == nil) emptyTrashWarning = [[EmptyTrashWarning alloc] init]; - if ([emptyTrashWarning shouldEmptyTrash]) + if (emptyTrashWarning.shouldEmptyTrash) { [db purgeDeletedArticles]; } - [emptyTrashWarning release]; emptyTrashWarning = nil; } break; @@ -713,15 +649,15 @@ -(void)applicationWillTerminate:(NSNotification *)aNotification { // Save the splitview layout Preferences * prefs = [Preferences standardPreferences]; - [prefs setObject:[splitView1 layout] forKey:@"SplitView1Positions"]; + [prefs setObject:splitView1.xlayout forKey:@"SplitView1Positions"]; // Close the activity window explicitly to force it to // save its split bar position to the preferences. - NSWindow * activityWindow = [activityViewer window]; + NSWindow * activityWindow = activityViewer.window; [activityWindow performClose:self]; // Put back the original app icon - [[NSApp dockTile] setBadgeLabel:nil]; + [NSApp.dockTile setBadgeLabel:nil]; // Save the open tabs [browserView saveOpenTabs]; @@ -733,6 +669,7 @@ -(void)applicationWillTerminate:(NSNotification *)aNotification // Finally save preferences [prefs savePreferences]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; } [db close]; } @@ -742,7 +679,7 @@ -(void)applicationWillTerminate:(NSNotification *)aNotification */ - (NSRect)splitView:(NSSplitView *)splitView effectiveRect:(NSRect)proposedEffectiveRect forDrawnRect:(NSRect)drawnRect ofDividerAtIndex:(NSInteger)dividerIndex { - if([splitView isVertical]) { + if(splitView.vertical) { drawnRect.origin.x -= 4; drawnRect.size.width += 6; return drawnRect; @@ -757,58 +694,58 @@ - (NSRect)splitView:(NSSplitView *)splitView effectiveRect:(NSRect)proposedEffec -(BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename { Preferences * prefs = [Preferences standardPreferences]; - if ([[filename pathExtension] isEqualToString:@"viennastyle"]) + if ([filename.pathExtension isEqualToString:@"viennastyle"]) { - NSString * styleName = [[filename lastPathComponent] stringByDeletingPathExtension]; - if (![self installFilename:filename toPath:[prefs stylesFolder]]) - [[Preferences standardPreferences] setDisplayStyle:styleName]; + NSString * styleName = filename.lastPathComponent.stringByDeletingPathExtension; + if (![self installFilename:filename toPath:prefs.stylesFolder]) + [Preferences standardPreferences].displayStyle = styleName; else { Preferences * prefs = [Preferences standardPreferences]; - [stylesMenu setSubmenu:[self getStylesMenu]]; - [[self toolbarItemWithIdentifier:@"Styles"] setPopup:@"stylesMenuButton" withMenu:[self getStylesMenu]]; - [prefs setDisplayStyle:styleName]; - if ([[prefs displayStyle] isEqualToString:styleName]) + stylesMenu.submenu = self.stylesMenu; + [[self toolbarItemWithIdentifier:@"Styles"] setPopup:@"stylesMenuButton" withMenu:self.stylesMenu]; + prefs.displayStyle = styleName; + if ([prefs.displayStyle isEqualToString:styleName]) runOKAlertPanel(NSLocalizedString(@"New style title", nil), NSLocalizedString(@"New style body", nil), styleName); } return YES; } - if ([[filename pathExtension] isEqualToString:@"viennaplugin"]) + if ([filename.pathExtension isEqualToString:@"viennaplugin"]) { - NSString * path = [prefs pluginsFolder]; + NSString * path = prefs.pluginsFolder; if ([self installFilename:filename toPath:path]) { runOKAlertPanel(NSLocalizedString(@"Plugin installed", nil), NSLocalizedString(@"A new plugin has been installed. It is now available from the menu and you can add it to the toolbar.", nil)); - NSString * fullPath = [path stringByAppendingPathComponent:[filename lastPathComponent]]; + NSString * fullPath = [path stringByAppendingPathComponent:filename.lastPathComponent]; [pluginManager loadPlugin:fullPath]; } return YES; } - if ([[filename pathExtension] isEqualToString:@"scpt"]) + if ([filename.pathExtension isEqualToString:@"scpt"]) { - if ([self installFilename:filename toPath:[prefs scriptsFolder]]) + if ([self installFilename:filename toPath:prefs.scriptsFolder]) { if (!hasOSScriptsMenu()) [self initScriptsMenu]; } return YES; } - if ([[filename pathExtension] isEqualToString:@"opml"]) + if ([filename.pathExtension isEqualToString:@"opml"]) { BOOL returnCode = NSRunAlertPanel(NSLocalizedString(@"Import subscriptions from OPML file?", nil), NSLocalizedString(@"Do you really want to import the subscriptions from the specified OPML file?", nil), NSLocalizedString(@"Import", nil), NSLocalizedString(@"Cancel", nil), nil); if (returnCode == NSAlertAlternateReturn) return NO; - [self importFromFile:filename]; + [Import importFromFile:filename]; return YES; } - if ([[filename pathExtension] isEqualToString:@"webloc"]) + if ([filename.pathExtension isEqualToString:@"webloc"]) { NSURL* url = [NSURL URLFromInetloc:filename]; - if (![mainWindow isVisible]) + if (!mainWindow.visible) [mainWindow makeKeyAndOrderFront:self]; - if (url != nil && ![db readOnly]) + if (url != nil && !db.readOnly) { - [self.rssFeed newSubscription:mainWindow underParent:[foldersTree groupParentSelection] initialURL:[url absoluteString]]; + [self.rssFeed newSubscription:mainWindow underParent:foldersTree.groupParentSelection initialURL:url.absoluteString]; return YES; } else @@ -824,7 +761,7 @@ -(BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename */ -(BOOL)installFilename:(NSString *)srcFile toPath:(NSString *)path { - NSString * fullPath = [path stringByAppendingPathComponent:[srcFile lastPathComponent]]; + NSString * fullPath = [path stringByAppendingPathComponent:srcFile.lastPathComponent]; // Make sure we actually have a destination folder. NSFileManager * fileManager = [NSFileManager defaultManager]; @@ -853,17 +790,14 @@ -(NSMenu *)searchFieldMenu NSMenuItem * item = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Recent Searches", nil) action:NULL keyEquivalent:@""]; [item setTag:NSSearchFieldRecentsTitleMenuItemTag]; [cellMenu insertItem:item atIndex:0]; - [item release]; item = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Recents", nil) action:NULL keyEquivalent:@""]; [item setTag:NSSearchFieldRecentsMenuItemTag]; [cellMenu insertItem:item atIndex:1]; - [item release]; item = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Clear", nil) action:NULL keyEquivalent:@""]; [item setTag:NSSearchFieldClearRecentsMenuItemTag]; [cellMenu insertItem:item atIndex:2]; - [item release]; SearchMethod * searchMethod; NSString * friendlyName; @@ -873,47 +807,45 @@ -(NSMenu *)searchFieldMenu // Add all built-in search methods to the menu. for (searchMethod in [SearchMethod builtInSearchMethods]) { - friendlyName = [searchMethod friendlyName]; + friendlyName = searchMethod.friendlyName; item = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(friendlyName, nil) action:@selector(setSearchMethod:) keyEquivalent:@""]; - [item setRepresentedObject: searchMethod]; + item.representedObject = searchMethod; // Is this the currently set search method? If yes, mark it as such. - if ( [friendlyName isEqualToString:[[[Preferences standardPreferences] searchMethod] friendlyName]] ) - [item setState:NSOnState]; + if ( [friendlyName isEqualToString:[Preferences standardPreferences].searchMethod.friendlyName] ) + item.state = NSOnState; [cellMenu addItem:item]; - [item release]; } // Add all available plugged-in search methods to the menu. - NSMutableArray * searchMethods = [NSMutableArray arrayWithArray:[pluginManager searchMethods]]; - if ([searchMethods count] > 0) + NSMutableArray * searchMethods = [NSMutableArray arrayWithArray:pluginManager.searchMethods]; + if (searchMethods.count > 0) { [cellMenu addItem: [NSMenuItem separatorItem]]; for (searchMethod in searchMethods) { - if (![searchMethod friendlyName]) + if (!searchMethod.friendlyName) continue; - item = [[NSMenuItem alloc] initWithTitle:[searchMethod friendlyName] action:@selector(setSearchMethod:) keyEquivalent:@""]; - [item setRepresentedObject: searchMethod]; + item = [[NSMenuItem alloc] initWithTitle:searchMethod.friendlyName action:@selector(setSearchMethod:) keyEquivalent:@""]; + item.representedObject = searchMethod; // Is this the currently set search method? If yes, mark it as such. - if ( [[searchMethod friendlyName] isEqualToString: [[[Preferences standardPreferences] searchMethod] friendlyName]] ) - [item setState:NSOnState]; + if ( [searchMethod.friendlyName isEqualToString: [Preferences standardPreferences].searchMethod.friendlyName] ) + item.state = NSOnState; [cellMenu addItem:item]; - [item release]; } } - [cellMenu setDelegate:self]; - return [cellMenu autorelease]; + cellMenu.delegate = self; + return cellMenu; } /* setSearchMethod */ -(void)setSearchMethod:(NSMenuItem *)sender { - [[Preferences standardPreferences] setSearchMethod: [sender representedObject]]; - [[searchField cell] setPlaceholderString:[sender title]]; + [Preferences standardPreferences].searchMethod = sender.representedObject; + ((NSSearchFieldCell *)searchField.cell).placeholderString = sender.title; } /* standardURLs @@ -947,7 +879,7 @@ -(CGFloat)splitView:(NSSplitView *)sender constrainMaxCoordinate:(CGFloat)propos { if (sender == splitView1 && offset == 0) { - NSRect mainFrame = [[splitView1 superview] frame]; + NSRect mainFrame = splitView1.superview.frame; return mainFrame.size.width - MA_Minimum_BrowserView_Pane_Width; } return proposedMax; @@ -958,12 +890,12 @@ -(CGFloat)splitView:(NSSplitView *)sender constrainMaxCoordinate:(CGFloat)propos */ -(void)splitView:(NSSplitView *)sender resizeSubviewsWithOldSize:(NSSize)oldSize { - CGFloat dividerThickness = [sender dividerThickness]; - id sv1 = [[sender subviews] objectAtIndex:0]; - id sv2 = [[sender subviews] objectAtIndex:1]; + CGFloat dividerThickness = sender.dividerThickness; + id sv1 = sender.subviews[0]; + id sv2 = sender.subviews[1]; NSRect leftFrame = [sv1 frame]; NSRect rightFrame = [sv2 frame]; - NSRect newFrame = [sender frame]; + NSRect newFrame = sender.frame; if (sender == splitView1) { @@ -984,7 +916,7 @@ -(void)splitView:(NSSplitView *)sender resizeSubviewsWithOldSize:(NSSize)oldSize */ -(NSMenu *)folderMenu { - NSMenu * folderMenu = [[[NSMenu alloc] init] autorelease]; + NSMenu * folderMenu = [[NSMenu alloc] init]; [folderMenu addItem:copyOfMenuItemWithAction(@selector(refreshSelectedSubscriptions:))]; [folderMenu addItem:[NSMenuItem separatorItem]]; [folderMenu addItem:copyOfMenuItemWithAction(@selector(editFolder:))]; @@ -995,7 +927,7 @@ -(NSMenu *)folderMenu [folderMenu addItem:[NSMenuItem separatorItem]]; [folderMenu addItem:copyOfMenuItemWithAction(@selector(viewSourceHomePage:))]; NSMenuItem * alternateItem = copyOfMenuItemWithAction(@selector(viewSourceHomePageInAlternateBrowser:)); - [alternateItem setKeyEquivalentModifierMask:NSAlternateKeyMask]; + alternateItem.keyEquivalentModifierMask = NSAlternateKeyMask; [alternateItem setAlternate:YES]; [folderMenu addItem:alternateItem]; [folderMenu addItem:copyOfMenuItemWithAction(@selector(getInfo:))]; @@ -1048,102 +980,31 @@ -(IBAction)unifiedLayout:(id)sender /* setLayout * Changes the layout of the panes. */ --(void)setLayout:(int)newLayout withRefresh:(BOOL)refreshFlag +-(void)setLayout:(NSInteger)newLayout withRefresh:(BOOL)refreshFlag { BOOL visibleFilterBar = NO; // Turn off the filter bar when switching layouts. This is simpler than // trying to graft it onto the new layout. - if ([self isFilterBarVisible]) + if (self.filterBarVisible) { visibleFilterBar = YES; [self setPersistedFilterBarState:NO withAnimation:NO]; } - switch (newLayout) - { - case MA_Layout_Report: - [browserView setPrimaryTabItemView:mainArticleView]; - if (refreshFlag) - [mainArticleView refreshFolder:MA_Refresh_RedrawList]; - [articleController setMainArticleView:mainArticleView]; - break; - - case MA_Layout_Condensed: - [browserView setPrimaryTabItemView:mainArticleView]; - if (refreshFlag) - [mainArticleView refreshFolder:MA_Refresh_RedrawList]; - [articleController setMainArticleView:mainArticleView]; - break; - - case MA_Layout_Unified: - [browserView setPrimaryTabItemView:unifiedListView]; - if (refreshFlag) - [unifiedListView refreshFolder:MA_Refresh_RedrawList]; - [mainWindow display]; - [articleController setMainArticleView:unifiedListView]; - break; - } - - [[Preferences standardPreferences] setLayout:newLayout]; + [articleController setLayout:newLayout]; + if (refreshFlag) + [articleController.mainArticleView refreshFolder:MA_Refresh_RedrawList]; + [browserView setPrimaryTabItemView:articleController.mainArticleView]; + foldersTree.mainView.nextKeyView = [browserView primaryTabItemView].mainView; + if (self.selectedArticle == nil) + [mainWindow makeFirstResponder:foldersTree.mainView]; + else + [mainWindow makeFirstResponder:[browserView primaryTabItemView].mainView]; //restore filter bar state if necessary if (visibleFilterBar) [self setPersistedFilterBarState:YES withAnimation:NO]; [self updateSearchPlaceholderAndSearchMethod]; - [[foldersTree mainView] setNextKeyView:[[browserView primaryTabItemView] mainView]]; -} - -+ (void) initialize -{ - // Initializes our multi-thread lock - dateFormatters_lock = [[NSLock alloc] init]; - - // Initializes the date formatters - enUSLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]; - - for (int i=0; i 20) - { - modifiedDateString = [dateString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; - modifiedDateString = [modifiedDateString - stringByReplacingOccurrencesOfString:@":" withString:@"" - options:0 range:NSMakeRange(20,modifiedDateString.length-20)]; - } - else - { - modifiedDateString = dateString; - } - - [dateFormatters_lock lock]; - for (int i=0; i= 0; --index) { - NSMenuItem * menuItem = [newDefaultMenu objectAtIndex:index]; - switch ([menuItem tag]) + NSMenuItem * menuItem = newDefaultMenu[index]; + switch (menuItem.tag) { case WebMenuItemTagOpenImageInNewWindow: imageURL = [element valueForKey:WebElementImageURLKey]; if (imageURL != nil) { [menuItem setTitle:NSLocalizedString(@"Open Image in New Tab", nil)]; - [menuItem setTarget:self]; - [menuItem setAction:@selector(openWebElementInNewTab:)]; - [menuItem setRepresentedObject:imageURL]; - [menuItem setTag:WebMenuItemTagOther]; - newMenuItem = [[NSMenuItem new] autorelease]; + menuItem.target = self; + menuItem.action = @selector(openWebElementInNewTab:); + menuItem.representedObject = imageURL; + menuItem.tag = WebMenuItemTagOther; + newMenuItem = [NSMenuItem new]; if (newMenuItem != nil) { - [newMenuItem setTitle:[NSString stringWithFormat:NSLocalizedString(@"Open Image in %@", nil), defaultBrowser]]; - [newMenuItem setTarget:self]; - [newMenuItem setAction:@selector(openWebElementInDefaultBrowser:)]; - [newMenuItem setRepresentedObject:imageURL]; - [newMenuItem setTag:WebMenuItemTagOther]; + newMenuItem.title = [NSString stringWithFormat:NSLocalizedString(@"Open Image in %@", nil), defaultBrowser]; + newMenuItem.target = self; + newMenuItem.action = @selector(openWebElementInDefaultBrowser:); + newMenuItem.representedObject = imageURL; + newMenuItem.tag = WebMenuItemTagOther; [newDefaultMenu insertObject:newMenuItem atIndex:index + 1]; } } @@ -1222,21 +1081,20 @@ -(NSArray *)contextMenuItemsForElement:(NSDictionary *)element defaultMenuItems: case WebMenuItemTagOpenLinkInNewWindow: [menuItem setTitle:NSLocalizedString(@"Open Link in New Tab", nil)]; - [menuItem setTarget:self]; - [menuItem setAction:@selector(openWebElementInNewTab:)]; - [menuItem setRepresentedObject:urlLink]; - [menuItem setTag:WebMenuItemTagOther]; + menuItem.target = self; + menuItem.action = @selector(openWebElementInNewTab:); + menuItem.representedObject = urlLink; + menuItem.tag = WebMenuItemTagOther; newMenuItem = [[NSMenuItem alloc] init]; if (newMenuItem != nil) { - [newMenuItem setTitle:[NSString stringWithFormat:NSLocalizedString(@"Open Link in %@", nil), defaultBrowser]]; - [newMenuItem setTarget:self]; - [newMenuItem setAction:@selector(openWebElementInDefaultBrowser:)]; - [newMenuItem setRepresentedObject:urlLink]; - [newMenuItem setTag:WebMenuItemTagOther]; + newMenuItem.title = [NSString stringWithFormat:NSLocalizedString(@"Open Link in %@", nil), defaultBrowser]; + newMenuItem.target = self; + newMenuItem.action = @selector(openWebElementInDefaultBrowser:); + newMenuItem.representedObject = urlLink; + newMenuItem.tag = WebMenuItemTagOther; [newDefaultMenu insertObject:newMenuItem atIndex:index + 1]; } - [newMenuItem release]; break; case WebMenuItemTagCopyLinkToClipboard: @@ -1251,44 +1109,50 @@ -(NSArray *)contextMenuItemsForElement:(NSDictionary *)element defaultMenuItems: [newDefaultMenu addObject:[NSMenuItem separatorItem]]; // Add command to open the current page in the external browser - newMenuItem = [[NSMenuItem new] autorelease]; + newMenuItem = [NSMenuItem new]; if (newMenuItem != nil) { - [newMenuItem setTitle:[NSString stringWithFormat:NSLocalizedString(@"Open Page in %@", nil), defaultBrowser]]; - [newMenuItem setTarget:self]; - [newMenuItem setAction:@selector(openPageInBrowser:)]; - [newMenuItem setTag:WebMenuItemTagOther]; + newMenuItem.title = [NSString stringWithFormat:NSLocalizedString(@"Open Page in %@", nil), defaultBrowser]; + newMenuItem.target = self; + newMenuItem.action = @selector(openPageInBrowser:); + newMenuItem.tag = WebMenuItemTagOther; [newDefaultMenu addObject:newMenuItem]; } // Add command to copy the URL of the current page to the clipboard - newMenuItem = [[NSMenuItem new] autorelease]; + newMenuItem = [NSMenuItem new]; if (newMenuItem != nil) { [newMenuItem setTitle:NSLocalizedString(@"Copy Page Link to Clipboard", nil)]; - [newMenuItem setTarget:self]; - [newMenuItem setAction:@selector(copyPageURLToClipboard:)]; - [newMenuItem setTag:WebMenuItemTagOther]; + newMenuItem.target = self; + newMenuItem.action = @selector(copyPageURLToClipboard:); + newMenuItem.tag = WebMenuItemTagOther; [newDefaultMenu addObject:newMenuItem]; } } - return [newDefaultMenu autorelease]; + return [newDefaultMenu copy]; } /** openURLsInDefaultBrowser * Open an array of URLs in whatever the user has registered as their * default system browser. */ -- (void)openURLsInDefaultBrowser:(NSArray *)urlArray { +- (void)openURLsInDefaultBrowser:(NSArray *)urlArray { Preferences * prefs = [Preferences standardPreferences]; - + BOOL openLinksInBackground = prefs.openLinksInBackground; + + if ([urlArray.firstObject.scheme isEqualToString:@"mailto"]) { + openLinksInBackground = NO; + } + // This line is a workaround for OS X bug rdar://4450641 - if ([prefs openLinksInBackground]) + if (openLinksInBackground) { [mainWindow orderFront:self]; + } // Launch in the foreground or background as needed - NSWorkspaceLaunchOptions lOptions = [prefs openLinksInBackground] ? (NSWorkspaceLaunchWithoutActivation | NSWorkspaceLaunchDefault) : (NSWorkspaceLaunchDefault | NSWorkspaceLaunchDefault); + NSWorkspaceLaunchOptions lOptions = openLinksInBackground ? (NSWorkspaceLaunchWithoutActivation | NSWorkspaceLaunchDefault) : (NSWorkspaceLaunchDefault | NSWorkspaceLaunchDefault); [[NSWorkspace sharedWorkspace] openURLs:urlArray withAppBundleIdentifier:NULL options:lOptions @@ -1302,7 +1166,7 @@ - (void)openURLsInDefaultBrowser:(NSArray *)urlArray { */ -(void)openURLInDefaultBrowser:(NSURL *)url { - [self openURLsInDefaultBrowser:[NSArray arrayWithObject:url]]; + [self openURLsInDefaultBrowser:@[url]]; } @@ -1311,19 +1175,19 @@ -(void)openURLInDefaultBrowser:(NSURL *)url */ -(IBAction)openPageInBrowser:(id)sender { - NSView * theView = [browserView activeTabItemView]; + NSView * theView = browserView.activeTabItemView; NSURL * url = nil; // Get the URL from the appropriate view. if ([theView isKindOfClass:[BrowserPane class]]) { BrowserPane * webPane = (BrowserPane *)theView; - url = [webPane url]; + url = webPane.url; } else if ([theView isKindOfClass:[ArticleListView class]]) { ArticleListView * articleListView = (ArticleListView *)theView; - url = [articleListView url]; + url = articleListView.url; } // If we have an URL then open it in the default browser. @@ -1336,28 +1200,28 @@ -(IBAction)openPageInBrowser:(id)sender */ -(IBAction)copyPageURLToClipboard:(id)sender { - NSView * theView = [browserView activeTabItemView]; + NSView * theView = browserView.activeTabItemView; NSURL * url = nil; // Get the URL from the appropriate view. if ([theView isKindOfClass:[BrowserPane class]]) { BrowserPane * webPane = (BrowserPane *)theView; - url = [webPane url]; + url = webPane.url; } else if ([theView isKindOfClass:[ArticleListView class]]) { ArticleListView * articleListView = (ArticleListView *)theView; - url = [articleListView url]; + url = articleListView.url; } // If we have an URL then copy it to the clipboard. if (url != nil) { NSPasteboard * pboard = [NSPasteboard generalPasteboard]; - [pboard declareTypes:[NSArray arrayWithObjects:NSStringPboardType, NSURLPboardType, nil] owner:self]; + [pboard declareTypes:@[NSStringPboardType, NSURLPboardType] owner:self]; [url writeToPasteboard:pboard]; - [pboard setString:[url description] forType:NSStringPboardType]; + [pboard setString:url.description forType:NSStringPboardType]; } } @@ -1371,15 +1235,12 @@ -(IBAction)openWebElementInNewTab:(id)sender NSMenuItem * item = (NSMenuItem *)sender; Preferences * prefs = [Preferences standardPreferences]; - BOOL openInBackground = [prefs openLinksInBackground]; - - /* As Safari does, 'shift' inverts this behavior. Use GetCurrentKeyModifiers() because [NSApp currentEvent] was created - * when the current event began, which may be when the contexual menu opened. - */ - if (((GetCurrentKeyModifiers() & (shiftKey | rightShiftKey)) != 0)) + BOOL openInBackground = prefs.openLinksInBackground; + if ([NSEvent modifierFlags] & NSEventModifierFlagShift) { openInBackground = !openInBackground; + } - [self createNewTab:[item representedObject] inBackground:openInBackground]; + [self createNewTab:item.representedObject inBackground:openInBackground]; } } @@ -1391,7 +1252,7 @@ -(IBAction)openWebElementInDefaultBrowser:(id)sender if ([sender isKindOfClass:[NSMenuItem class]]) { NSMenuItem * item = (NSMenuItem *)sender; - [self openURLInDefaultBrowser:[item representedObject]]; + [self openURLInDefaultBrowser:item.representedObject]; } } @@ -1401,12 +1262,12 @@ -(IBAction)openWebElementInDefaultBrowser:(id)sender */ -(IBAction)openWebLocation:(id)sender { - NSView * theView = [browserView activeTabItemView]; + NSView * theView = browserView.activeTabItemView; [self showMainWindow:self]; if (![theView isKindOfClass:[BrowserPane class]]) { [self createNewTab:nil inBackground:NO]; - theView = [browserView activeTabItemView]; + theView = browserView.activeTabItemView; } if ([theView isKindOfClass:[BrowserPane class]]) { @@ -1436,19 +1297,16 @@ -(void)openURLFromString:(NSString *)urlString inPreferredBrowser:(BOOL)openInPr -(void)openURLs:(NSArray *)urls inPreferredBrowser:(BOOL)openInPreferredBrowserFlag { Preferences * prefs = [Preferences standardPreferences]; - BOOL openURLInVienna = [prefs openLinksInVienna]; + BOOL openURLInVienna = prefs.openLinksInVienna; if (!openInPreferredBrowserFlag) openURLInVienna = (!openURLInVienna); if (openURLInVienna) { - BOOL openInBackground = [prefs openLinksInBackground]; - - /* As Safari does, 'shift' inverts this behavior. Use GetCurrentKeyModifiers() because [NSApp currentEvent] was created - * when the current event began, which may be when the contexual menu opened. - */ - if (((GetCurrentKeyModifiers() & (shiftKey | rightShiftKey)) != 0)) - openInBackground = !openInBackground; - + BOOL openInBackground = prefs.openLinksInBackground; + if ([NSEvent modifierFlags] & NSEventModifierFlagShift) { + openInBackground = !openInBackground; + } + for (NSURL * url in urls) [self createNewTab:url inBackground:openInBackground]; } @@ -1467,7 +1325,7 @@ -(void)openURL:(NSURL *)url inPreferredBrowser:(BOOL)openInPreferredBrowserFlag NSLog(@"Called openURL:inPreferredBrowser: with nil url."); return; } - [self openURLs:[NSArray arrayWithObject:url] inPreferredBrowser:openInPreferredBrowserFlag]; + [self openURLs:@[url] inPreferredBrowser:openInPreferredBrowserFlag]; } /* newTab @@ -1479,7 +1337,7 @@ -(IBAction)newTab:(id)sender [self createNewTab:nil inBackground:NO]; // Make the address bar first responder. - NSView * theView = [browserView activeTabItemView]; + NSView * theView = browserView.activeTabItemView; BrowserPane * browserPane = (BrowserPane *)theView; [browserPane activateAddressBar]; } @@ -1489,11 +1347,11 @@ -(IBAction)newTab:(id)sender */ -(IBAction)downloadEnclosure:(id)sender { - for (Article * currentArticle in [articleController markedArticleRange]) + for (Article * currentArticle in articleController.markedArticleRange) { - if ([currentArticle hasEnclosure]) + if (currentArticle.hasEnclosure) { - [[DownloadManager sharedInstance] downloadFileFromURL:[currentArticle enclosure]]; + [[DownloadManager sharedInstance] downloadFileFromURL:currentArticle.enclosure]; } } } @@ -1506,7 +1364,7 @@ -(void)createNewTab:(NSURL *)url inBackground:(BOOL)openInBackgroundFlag BrowserPaneTemplate * newBrowserTemplate = [[BrowserPaneTemplate alloc] init]; if (newBrowserTemplate) { - BrowserPane * newBrowserPane = [newBrowserTemplate mainView]; + BrowserPane * newBrowserPane = newBrowserTemplate.mainView; [browserView createNewTabWithView:newBrowserPane makeKey:!openInBackgroundFlag]; [newBrowserPane setController:self]; @@ -1515,7 +1373,6 @@ -(void)createNewTab:(NSURL *)url inBackground:(BOOL)openInBackgroundFlag else [browserView setTabItemViewTitle:newBrowserPane title:NSLocalizedString(@"New Tab", nil)]; - [newBrowserTemplate release]; } if (didCompleteInitialisation) [browserView performSelector:@selector(saveOpenTabs) withObject:nil afterDelay:3]; @@ -1543,9 +1400,83 @@ -(IBAction)showMainWindow:(id)sender */ -(IBAction)keepFoldersArranged:(id)sender { - [[Preferences standardPreferences] setFoldersTreeSortMethod:[sender tag]]; + [Preferences standardPreferences].foldersTreeSortMethod = [sender tag]; +} + + +/* exportSubscriptions + * Export the list of RSS subscriptions as an OPML file. + */ +-(IBAction)exportSubscriptions:(id)sender +{ + NSSavePanel * panel = [NSSavePanel savePanel]; + + // If multiple selections in the folder list, default to selected folders + // for simplicity. + if (foldersTree.countOfSelectedFolders > 1) + { + exportSelected.state = NSOnState; + exportAll.state = NSOffState; + } + else + { + exportSelected.state = NSOffState; + exportAll.state = NSOnState; + } + + // Localise the strings + [exportAll setTitle:NSLocalizedString(@"Export all subscriptions", nil)]; + [exportSelected setTitle:NSLocalizedString(@"Export selected subscriptions", nil)]; + [exportWithGroups setTitle:NSLocalizedString(@"Preserve group folders in exported file", nil)]; + + panel.accessoryView = exportSaveAccessory; + panel.allowedFileTypes = @[@"opml"]; + [panel beginSheetModalForWindow:mainWindow completionHandler:^(NSInteger returnCode) { + if (returnCode == NSOKButton) + { + [panel orderOut:self]; + + NSInteger countExported = [Export exportToFile:panel.URL.path fromFoldersTree:foldersTree selection:(exportSelected.state == NSOnState) withGroups:(exportWithGroups.state == NSOnState)]; + + if (countExported < 0) + { + NSBeginCriticalAlertSheet(NSLocalizedString(@"Cannot open export file message", nil), + NSLocalizedString(@"OK", nil), + nil, + nil, NSApp.mainWindow, self, + nil, nil, nil, + NSLocalizedString(@"Cannot open export file message text", nil)); + } + else + { + // Announce how many we successfully imported + NSRunAlertPanel(NSLocalizedString(@"RSS Subscription Export Title", nil), NSLocalizedString(@"%d subscriptions successfully exported", nil), NSLocalizedString(@"OK", nil), nil, nil, countExported); + } + } + }]; +} + + +/* importSubscriptions + * Import an OPML file which lists RSS feeds. + */ +-(IBAction)importSubscriptions:(id)sender +{ + NSOpenPanel * panel = [NSOpenPanel openPanel]; + [panel beginSheetModalForWindow:mainWindow + completionHandler: ^(NSInteger returnCode) { + + if (returnCode == NSOKButton) + { + [panel orderOut:self]; + [Import importFromFile:panel.URL.path]; + } + }]; + + //panel = nil; } + /* runAppleScript * Run an AppleScript script given a fully qualified path to the script. */ @@ -1557,17 +1488,16 @@ -(void)runAppleScript:(NSString *)scriptName NSAppleScript * appleScript = [[NSAppleScript alloc] initWithContentsOfURL:scriptURL error:&errorDictionary]; if (appleScript == nil) { - NSString * baseScriptName = [[scriptName lastPathComponent] stringByDeletingPathExtension]; + NSString * baseScriptName = scriptName.lastPathComponent.stringByDeletingPathExtension; runOKAlertPanel([NSString stringWithFormat:NSLocalizedString(@"Error loading script '%@'", nil), baseScriptName], [errorDictionary valueForKey:NSAppleScriptErrorMessage]); } else { NSAppleEventDescriptor * resultEvent = [appleScript executeAndReturnError:&errorDictionary]; - [appleScript release]; if (resultEvent == nil) { - NSString * baseScriptName = [[scriptName lastPathComponent] stringByDeletingPathExtension]; + NSString * baseScriptName = scriptName.lastPathComponent.stringByDeletingPathExtension; runOKAlertPanel([NSString stringWithFormat:NSLocalizedString(@"AppleScript Error in '%@' script", nil), baseScriptName], [errorDictionary valueForKey:NSAppleScriptErrorMessage]); } @@ -1581,17 +1511,17 @@ -(void)runAppleScript:(NSString *)scriptName */ -(BOOL)isFilterBarVisible { - return [filterView superview] != nil; + return filterView.superview != nil; } -(void)handleGoogleAuthFailed:(NSNotification *)nc { - if ([mainWindow isKeyWindow]) { - NSAlert *alert = [[[NSAlert alloc] init] autorelease]; + if (mainWindow.keyWindow) { + NSAlert *alert = [[NSAlert alloc] init]; [alert addButtonWithTitle:@"OK"]; [alert setMessageText:NSLocalizedString(@"Open Reader Authentication Failed",nil)]; - [alert setInformativeText:NSLocalizedString(@"Make sure the username and password needed to access the Open Reader server are correctly set in Vienna's preferences.\nAlso check your network access.",nil)]; - [alert setAlertStyle:NSWarningAlertStyle]; + [alert setInformativeText:NSLocalizedString(@"Open Reader Authentication Failed text",nil)]; + alert.alertStyle = NSWarningAlertStyle; [alert beginSheetModalForWindow:mainWindow modalDelegate:self didEndSelector:nil contextInfo:nil]; } } @@ -1609,8 +1539,8 @@ -(void)handleGoogleDownloadSubscriptions:(NSNotification *)nc { */ -(void)handleShowFilterBar:(NSNotification *)nc { - if ([browserView activeTabItemView] == [browserView primaryTabItemView]) - [self setFilterBarState:[[Preferences standardPreferences] showFilterBar] withAnimation:YES]; + if (browserView.activeTabItemView == [browserView primaryTabItemView]) + [self setFilterBarState:[Preferences standardPreferences].showFilterBar withAnimation:YES]; } /* showHideFilterBar @@ -1618,7 +1548,7 @@ -(void)handleShowFilterBar:(NSNotification *)nc */ -(IBAction)showHideFilterBar:(id)sender { - [self setPersistedFilterBarState:![self isFilterBarVisible] withAnimation:YES]; + [self setPersistedFilterBarState:!self.filterBarVisible withAnimation:YES]; } /* hideFilterBar @@ -1635,7 +1565,7 @@ -(IBAction)hideFilterBar:(id)sender -(void)setPersistedFilterBarState:(BOOL)isVisible withAnimation:(BOOL)doAnimate { [self setFilterBarState:isVisible withAnimation:doAnimate]; - [[Preferences standardPreferences] setShowFilterBar:isVisible]; + [Preferences standardPreferences].showFilterBar = isVisible; } /* setFilterBarState @@ -1645,65 +1575,65 @@ -(void)setPersistedFilterBarState:(BOOL)isVisible withAnimation:(BOOL)doAnimate */ -(void)setFilterBarState:(BOOL)isVisible withAnimation:(BOOL)doAnimate { - if (isVisible && ![self isFilterBarVisible]) + if (isVisible && !self.filterBarVisible) { - NSView * parentView = [[[articleController mainArticleView] subviews] objectAtIndex:0]; + NSView * parentView = articleController.mainArticleView.subviews[0]; NSRect filterBarRect; NSRect mainRect; - mainRect = [parentView bounds]; - filterBarRect = [filterView bounds]; + mainRect = parentView.bounds; + filterBarRect = filterView.bounds; filterBarRect.size.width = mainRect.size.width; filterBarRect.origin.y = mainRect.size.height - filterBarRect.size.height; mainRect.size.height -= filterBarRect.size.height; - [[parentView superview] addSubview:filterView]; - [filterView setFrame:filterBarRect]; + [parentView.superview addSubview:filterView]; + filterView.frame = filterBarRect; if (!doAnimate) - [parentView setFrame:mainRect]; + parentView.frame = mainRect; else [parentView resizeViewWithAnimation:mainRect withTag:MA_ViewTag_Filterbar]; [parentView display]; // Hook up the Tab ordering so Tab from the search field goes to the // article view. - [[foldersTree mainView] setNextKeyView:filterSearchField]; - [filterSearchField setNextKeyView:[[browserView primaryTabItemView] mainView]]; + foldersTree.mainView.nextKeyView = filterSearchField; + filterSearchField.nextKeyView = [browserView primaryTabItemView].mainView; // Set focus only if this was user initiated if (doAnimate) [mainWindow makeFirstResponder:filterSearchField]; } - if (!isVisible && [self isFilterBarVisible]) + if (!isVisible && self.filterBarVisible) { - NSView * parentView = [[[articleController mainArticleView] subviews] objectAtIndex:0]; + NSView * parentView = articleController.mainArticleView.subviews[0]; NSRect filterBarRect; NSRect mainRect; - mainRect = [parentView bounds]; - filterBarRect = [filterView bounds]; + mainRect = parentView.bounds; + filterBarRect = filterView.bounds; mainRect.size.height += filterBarRect.size.height; [filterView removeFromSuperview]; if (!doAnimate) - [parentView setFrame:mainRect]; + parentView.frame = mainRect; else [parentView resizeViewWithAnimation:mainRect withTag:MA_ViewTag_Filterbar]; [parentView display]; // Fix up the tab ordering - [[foldersTree mainView] setNextKeyView:[[browserView primaryTabItemView] mainView]]; + foldersTree.mainView.nextKeyView = [browserView primaryTabItemView].mainView; // Clear the filter, otherwise we end up with no way remove it! - [self setFilterString:@""]; + self.filterString = @""; if (doAnimate) { [self searchUsingFilterField:self]; // If the focus was originally on the filter bar then we should // move it to the message list - if ([mainWindow firstResponder] == mainWindow) - [mainWindow makeFirstResponder:[[browserView primaryTabItemView] mainView]]; + if (mainWindow.firstResponder == mainWindow) + [mainWindow makeFirstResponder:[browserView primaryTabItemView].mainView]; } } } @@ -1733,14 +1663,14 @@ -(void)growlNotify:(id)notifyContext title:(NSString *)title description:(NSStri -(void)growlNotificationWasClicked:(id)clickContext { NSDictionary * contextDict = (NSDictionary *)clickContext; - int contextValue = [[contextDict valueForKey:@"ContextType"] intValue]; + NSInteger contextValue = [[contextDict valueForKey:@"ContextType"] integerValue]; if (contextValue == MA_GrowlContext_RefreshCompleted) { [self openVienna:self]; Folder * unreadArticles = [db folderFromName:NSLocalizedString(@"Unread Articles", nil)]; if (unreadArticles != nil) - [foldersTree selectFolder:[unreadArticles itemId]]; + [foldersTree selectFolder:unreadArticles.itemId]; return; } @@ -1760,23 +1690,18 @@ -(void)growlNotificationWasClicked:(id)clickContext -(NSDictionary *)registrationDictionaryForGrowl { - NSDictionary *notificationsWithDescriptions = [NSDictionary dictionaryWithObjectsAndKeys: - @"Growl refresh completed", NSLocalizedString(@"Growl refresh completed", ""), - @"Growl download completed", NSLocalizedString(@"Growl download completed", ""), - @"Growl download failed", NSLocalizedString(@"Growl download failed", ""), - nil]; - - NSArray *allNotesArray = [notificationsWithDescriptions allKeys]; - NSMutableArray *defNotesArray = [allNotesArray mutableCopy]; + NSDictionary *notificationsWithDescriptions = @{NSLocalizedString(@"Growl refresh completed", ""): @"Growl refresh completed", + NSLocalizedString(@"Growl download completed", ""): @"Growl download completed", + NSLocalizedString(@"Growl download failed", ""): @"Growl download failed"}; + + NSArray *allNotesArray = notificationsWithDescriptions.allKeys; + NSArray *defNotesArray = [allNotesArray copy]; - NSDictionary *regDict = [NSDictionary dictionaryWithObjectsAndKeys: - [self appName], GROWL_APP_NAME, - allNotesArray, GROWL_NOTIFICATIONS_ALL, - defNotesArray, GROWL_NOTIFICATIONS_DEFAULT, - notificationsWithDescriptions, GROWL_NOTIFICATIONS_HUMAN_READABLE_NAMES, - nil]; + NSDictionary *regDict = @{GROWL_APP_NAME: self.appName, + GROWL_NOTIFICATIONS_ALL: allNotesArray, + GROWL_NOTIFICATIONS_DEFAULT: defNotesArray, + GROWL_NOTIFICATIONS_HUMAN_READABLE_NAMES: notificationsWithDescriptions}; - [defNotesArray release]; return regDict; } @@ -1786,28 +1711,27 @@ -(NSDictionary *)registrationDictionaryForGrowl */ -(void)initSortMenu { - NSMenu * sortSubmenu = [[[NSMenu alloc] initWithTitle:@"Sort By"] autorelease]; + NSMenu * sortSubmenu = [[NSMenu alloc] initWithTitle:@"Sort By"]; // Add the fields which are sortable to the menu. for (Field * field in [db arrayOfFields]) { // Filter out columns we don't sort on. Later we should have an attribute in the // field object itself based on which columns we can sort on. - if ([field tag] != MA_FieldID_Parent && - [field tag] != MA_FieldID_GUID && - [field tag] != MA_FieldID_Comments && - [field tag] != MA_FieldID_Deleted && - [field tag] != MA_FieldID_Headlines && - [field tag] != MA_FieldID_Summary && - [field tag] != MA_FieldID_Link && - [field tag] != MA_FieldID_Text && - [field tag] != MA_FieldID_EnclosureDownloaded && - [field tag] != MA_FieldID_Enclosure) + if (field.tag != MA_FieldID_Parent && + field.tag != MA_FieldID_GUID && + field.tag != MA_FieldID_Comments && + field.tag != MA_FieldID_Deleted && + field.tag != MA_FieldID_Headlines && + field.tag != MA_FieldID_Summary && + field.tag != MA_FieldID_Link && + field.tag != MA_FieldID_Text && + field.tag != MA_FieldID_EnclosureDownloaded && + field.tag != MA_FieldID_Enclosure) { - NSMenuItem * menuItem = [[NSMenuItem alloc] initWithTitle:[field displayName] action:@selector(doSortColumn:) keyEquivalent:@""]; - [menuItem setRepresentedObject:field]; + NSMenuItem * menuItem = [[NSMenuItem alloc] initWithTitle:field.displayName action:@selector(doSortColumn:) keyEquivalent:@""]; + menuItem.representedObject = field; [sortSubmenu addItem:menuItem]; - [menuItem release]; } } @@ -1816,16 +1740,14 @@ -(void)initSortMenu // Now add the ascending and descending menu items. NSMenuItem * menuItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Ascending", nil) action:@selector(doSortDirection:) keyEquivalent:@""]; - [menuItem setRepresentedObject:[NSNumber numberWithBool:YES]]; + menuItem.representedObject = @YES; [sortSubmenu addItem:menuItem]; - [menuItem release]; menuItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Descending", nil) action:@selector(doSortDirection:) keyEquivalent:@""]; - [menuItem setRepresentedObject:[NSNumber numberWithBool:NO]]; + menuItem.representedObject = @NO; [sortSubmenu addItem:menuItem]; - [menuItem release]; // Set the submenu - [sortByMenu setSubmenu:sortSubmenu]; + sortByMenu.submenu = sortSubmenu; } /* initColumnsMenu @@ -1833,27 +1755,26 @@ -(void)initSortMenu */ -(void)initColumnsMenu { - NSMenu * columnsSubMenu = [[[NSMenu alloc] initWithTitle:@"Columns"] autorelease]; + NSMenu * columnsSubMenu = [[NSMenu alloc] initWithTitle:@"Columns"]; for (Field * field in [db arrayOfFields]) { // Filter out columns we don't view in the article list. Later we should have an attribute in the // field object based on which columns are visible in the tableview. - if ([field tag] != MA_FieldID_Text && - [field tag] != MA_FieldID_GUID && - [field tag] != MA_FieldID_Comments && - [field tag] != MA_FieldID_Deleted && - [field tag] != MA_FieldID_Parent && - [field tag] != MA_FieldID_Headlines && - [field tag] != MA_FieldID_EnclosureDownloaded) + if (field.tag != MA_FieldID_Text && + field.tag != MA_FieldID_GUID && + field.tag != MA_FieldID_Comments && + field.tag != MA_FieldID_Deleted && + field.tag != MA_FieldID_Parent && + field.tag != MA_FieldID_Headlines && + field.tag != MA_FieldID_EnclosureDownloaded) { - NSMenuItem * menuItem = [[NSMenuItem alloc] initWithTitle:[field displayName] action:@selector(doViewColumn:) keyEquivalent:@""]; - [menuItem setRepresentedObject:field]; + NSMenuItem * menuItem = [[NSMenuItem alloc] initWithTitle:field.displayName action:@selector(doViewColumn:) keyEquivalent:@""]; + menuItem.representedObject = field; [columnsSubMenu addItem:menuItem]; - [menuItem release]; } } - [columnsMenu setSubmenu:columnsSubMenu]; + columnsMenu.submenu = columnsSubMenu; } /* initScriptsMenu @@ -1867,23 +1788,23 @@ -(void)initColumnsMenu -(void)initScriptsMenu { // Valid script file extensions - NSArray * exts = [NSArray arrayWithObjects:@"scpt", nil]; + NSArray * exts = @[@"scpt"]; // Dump the current mappings [scriptPathMappings removeAllObjects]; // Add scripts within the app resource - NSString * path = [[[NSBundle mainBundle] sharedSupportPath] stringByAppendingPathComponent:@"Scripts"]; + NSString * path = [[NSBundle mainBundle].sharedSupportPath stringByAppendingPathComponent:@"Scripts"]; loadMapFromPath(path, scriptPathMappings, NO, exts); // Add scripts that the user created and stored in the scripts folder - path = [[Preferences standardPreferences] scriptsFolder]; + path = [Preferences standardPreferences].scriptsFolder; loadMapFromPath(path, scriptPathMappings, NO, exts); // Add the contents of the scriptsPathMappings dictionary keys to the menu sorted // by key name. - NSArray * sortedMenuItems = [[scriptPathMappings allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; - int count = [sortedMenuItems count]; + NSArray * sortedMenuItems = [scriptPathMappings.allKeys sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; + NSInteger count = sortedMenuItems.count; // Insert the Scripts menu to the left of the Help menu only if // we actually have any scripts. @@ -1891,14 +1812,13 @@ -(void)initScriptsMenu { NSMenu * scriptsMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"Scripts"]; - int index; + NSInteger index; for (index = 0; index < count; ++index) { - NSMenuItem * menuItem = [[NSMenuItem alloc] initWithTitle:[sortedMenuItems objectAtIndex:index] + NSMenuItem * menuItem = [[NSMenuItem alloc] initWithTitle:sortedMenuItems[index] action:@selector(doSelectScript:) keyEquivalent:@""]; [scriptsMenu addItem:menuItem]; - [menuItem release]; } [scriptsMenu addItem:[NSMenuItem separatorItem]]; @@ -1906,28 +1826,24 @@ -(void)initScriptsMenu menuItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Open Scripts Folder", nil) action:@selector(doOpenScriptsFolder:) keyEquivalent:@""]; [scriptsMenu addItem:menuItem]; - [menuItem release]; menuItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"More Scripts...", nil) action:@selector(moreScripts:) keyEquivalent:@""]; [scriptsMenu addItem:menuItem]; - [menuItem release]; // If this is the first call to initScriptsMenu, create the scripts menu. Otherwise we just // update the one we have. if (scriptsMenuItem != nil) { - [[NSApp mainMenu] removeItem:scriptsMenuItem]; - [scriptsMenuItem release]; + [NSApp.mainMenu removeItem:scriptsMenuItem]; } scriptsMenuItem = [[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:@"Scripts" action:NULL keyEquivalent:@""]; - [scriptsMenuItem setImage:[NSImage imageNamed:@"scriptMenu.tiff"]]; + scriptsMenuItem.image = [NSImage imageNamed:@"scriptMenu.tiff"]; - int helpMenuIndex = [[NSApp mainMenu] numberOfItems] - 1; - [[NSApp mainMenu] insertItem:scriptsMenuItem atIndex:helpMenuIndex]; - [scriptsMenuItem setSubmenu:scriptsMenu]; + NSInteger helpMenuIndex = NSApp.mainMenu.numberOfItems - 1; + [NSApp.mainMenu insertItem:scriptsMenuItem atIndex:helpMenuIndex]; + scriptsMenuItem.submenu = scriptsMenu; - [scriptsMenu release]; } } @@ -1938,28 +1854,26 @@ -(void)initScriptsMenu */ -(NSMenu *)getStylesMenu { - NSMenu * stylesSubMenu = [[[NSMenu alloc] initWithTitle:@"Style"] autorelease]; + NSMenu * stylesSubMenu = [[NSMenu alloc] initWithTitle:@"Style"]; // Reinitialise the styles map NSDictionary * stylesMap = [ArticleView loadStylesMap]; // Add the contents of the stylesPathMappings dictionary keys to the menu sorted by key name. - NSArray * sortedMenuItems = [[stylesMap allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; - int count = [sortedMenuItems count]; - int index; + NSArray * sortedMenuItems = [stylesMap.allKeys sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; + NSInteger count = sortedMenuItems.count; + NSInteger index; for (index = 0; index < count; ++index) { - NSMenuItem * menuItem = [[NSMenuItem alloc] initWithTitle:[sortedMenuItems objectAtIndex:index] action:@selector(doSelectStyle:) keyEquivalent:@""]; + NSMenuItem * menuItem = [[NSMenuItem alloc] initWithTitle:sortedMenuItems[index] action:@selector(doSelectStyle:) keyEquivalent:@""]; [stylesSubMenu addItem:menuItem]; - [menuItem release]; } // Append a link to More Styles... [stylesSubMenu addItem:[NSMenuItem separatorItem]]; NSMenuItem * menuItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"More Styles...", nil) action:@selector(moreStyles:) keyEquivalent:@""]; [stylesSubMenu addItem:menuItem]; - [menuItem release]; return stylesSubMenu; } @@ -1970,38 +1884,36 @@ -(NSMenu *)getStylesMenu */ -(void)initFiltersMenu { - NSMenu * filterSubMenu = [[[NSMenu alloc] initWithTitle:@"Filter By"] autorelease]; - NSMenu * filterPopupMenu = [[[NSMenu alloc] initWithTitle:@""] autorelease]; + NSMenu * filterSubMenu = [[NSMenu alloc] initWithTitle:@"Filter By"]; + NSMenu * filterPopupMenu = [[NSMenu alloc] initWithTitle:@""]; NSArray * filtersArray = [ArticleFilter arrayOfFilters]; - int count = [filtersArray count]; - int index; + NSInteger count = filtersArray.count; + NSInteger index; for (index = 0; index < count; ++index) { - ArticleFilter * filter = [filtersArray objectAtIndex:index]; + ArticleFilter * filter = filtersArray[index]; NSMenuItem * menuItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString([filter name], nil) action:@selector(changeFiltering:) keyEquivalent:@""]; - [menuItem setTag:[filter tag]]; + menuItem.tag = filter.tag; [filterSubMenu addItem:menuItem]; - [menuItem release]; menuItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString([filter name], nil) action:@selector(changeFiltering:) keyEquivalent:@""]; - [menuItem setTag:[filter tag]]; + menuItem.tag = filter.tag; [filterPopupMenu addItem:menuItem]; - [menuItem release]; } // Add it to the Filters menu - [filtersMenu setSubmenu:filterSubMenu]; - [filterViewPopUp setMenu:filterPopupMenu]; + filtersMenu.submenu = filterSubMenu; + filterViewPopUp.menu = filterPopupMenu; // Sync the popup selection with user preferences - int indexOfDefaultItem = [filterViewPopUp indexOfItemWithTag:[[Preferences standardPreferences] filterMode]]; + NSInteger indexOfDefaultItem = [filterViewPopUp indexOfItemWithTag:[Preferences standardPreferences].filterMode]; if (indexOfDefaultItem != -1) { [filterViewPopUp selectItemAtIndex:indexOfDefaultItem]; - [currentFilterTextField setStringValue: [[filterViewPopUp itemAtIndex:indexOfDefaultItem] title]]; + currentFilterTextField.stringValue = [filterViewPopUp itemAtIndex:indexOfDefaultItem].title; } } @@ -2010,11 +1922,11 @@ -(void)initFiltersMenu */ -(void)updateNewArticlesNotification { - if (([[Preferences standardPreferences] newArticlesNotification] + if (([Preferences standardPreferences].newArticlesNotification & MA_NewArticlesNotification_Badge) == 0) { // Remove the badge if there was one. - [[NSApp dockTile] setBadgeLabel:nil]; + [NSApp.dockTile setBadgeLabel:nil]; } else { @@ -2028,8 +1940,8 @@ -(void)updateNewArticlesNotification */ -(void)showUnreadCountOnApplicationIconAndWindowTitle { - @synchronized([NSApp dockTile]) { - int currentCountOfUnread = [db countOfUnread]; + @synchronized(NSApp.dockTile) { + NSInteger currentCountOfUnread = db.countOfUnread; if (currentCountOfUnread == lastCountOfUnread) return; lastCountOfUnread = currentCountOfUnread; @@ -2040,20 +1952,20 @@ -(void)showUnreadCountOnApplicationIconAndWindowTitle // Don't show a count if there are no unread articles if (currentCountOfUnread <= 0) { - [[NSApp dockTile] setBadgeLabel:nil]; - [mainWindow setTitle:[self appName]]; + [NSApp.dockTile setBadgeLabel:nil]; + mainWindow.title = self.appName; return; } - [mainWindow setTitle:[NSString stringWithFormat:@"%@ (%i %@)", [self appName], currentCountOfUnread, NSLocalizedString(@"Unread", nil)]]; + mainWindow.title = [NSString stringWithFormat:@"%@ (%li %@)", self.appName, (long)currentCountOfUnread, NSLocalizedString(@"Unread", nil)]; // Exit now if we're not showing the unread count on the application icon - if (([[Preferences standardPreferences] newArticlesNotification] + if (([Preferences standardPreferences].newArticlesNotification & MA_NewArticlesNotification_Badge) ==0) return; - NSString * countdown = [NSString stringWithFormat:@"%i", currentCountOfUnread]; - [[NSApp dockTile] setBadgeLabel:countdown]; + NSString * countdown = [NSString stringWithFormat:@"%li", (long)currentCountOfUnread]; + NSApp.dockTile.badgeLabel = countdown; } // @synchronized } @@ -2063,11 +1975,11 @@ -(void)showUnreadCountOnApplicationIconAndWindowTitle */ -(IBAction)handleAbout:(id)sender { - NSDictionary * fileAttributes = [[NSBundle mainBundle] infoDictionary]; + NSDictionary * fileAttributes = [NSBundle mainBundle].infoDictionary; LOG_EXPR(fileAttributes); - NSString * version = [fileAttributes objectForKey:@"CFBundleShortVersionString"]; + NSString * version = fileAttributes[@"CFBundleShortVersionString"]; NSString * versionString = [NSString stringWithFormat:NSLocalizedString(@"Version %@", nil), version]; - NSDictionary * d = [NSDictionary dictionaryWithObjectsAndKeys:versionString, @"ApplicationVersion", @"", @"Version", nil, nil]; + NSDictionary * d = @{@"ApplicationVersion": versionString, @"Version": @""}; [NSApp activateIgnoringOtherApps:YES]; [NSApp orderFrontStandardAboutPanelWithOptions:d]; } @@ -2080,7 +1992,7 @@ -(IBAction)emptyTrash:(id)sender NSBeginCriticalAlertSheet(NSLocalizedString(@"Empty Trash message", nil), NSLocalizedString(@"Empty", nil), NSLocalizedString(@"Cancel", nil), - nil, [NSApp mainWindow], self, + nil, NSApp.mainWindow, self, @selector(doConfirmedEmptyTrash:returnCode:contextInfo:), nil, nil, NSLocalizedString(@"Empty Trash message text", nil)); } @@ -2089,7 +2001,7 @@ -(IBAction)emptyTrash:(id)sender * This function is called after the user has dismissed * the confirmation sheet. */ --(void)doConfirmedEmptyTrash:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo +-(void)doConfirmedEmptyTrash:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo { if (returnCode == NSAlertDefaultReturn) { @@ -2103,27 +2015,16 @@ -(void)doConfirmedEmptyTrash:(NSWindow *)sheet returnCode:(int)returnCode contex */ -(IBAction)keyboardShortcutsHelp:(id)sender { - GotoHelpPage((CFStringRef)@"keyboard.html", NULL); + NSString *helpBook = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleHelpBookName"]; + [[NSHelpManager sharedHelpManager] openHelpAnchor:@"KeyboardSection" inBook:helpBook]; } -/* showPreferencePanel - * Display the Preference Panel. - */ -/* --(IBAction)showPreferencePanel:(id)sender -{ - if (!preferenceController) - preferenceController = [[NewPreferencesController alloc] init]; - [NSApp activateIgnoringOtherApps:YES]; - [preferenceController showWindow:self]; -} */ - /* printDocument * Print the selected articles in the article window. */ -(IBAction)printDocument:(id)sender { - [[browserView activeTabItemView] printDocument:sender]; + [browserView.activeTabItemView printDocument:sender]; } /* folders @@ -2139,7 +2040,7 @@ -(NSArray *)folders */ -(NSString *)appName { - return [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]; + return [NSBundle mainBundle].infoDictionary[@"CFBundleName"]; } /* selectedArticle @@ -2147,22 +2048,22 @@ -(NSString *)appName */ -(Article *)selectedArticle { - return [articleController selectedArticle]; + return articleController.selectedArticle; } /* currentFolderId * Return the ID of the currently selected folder whose articles are shown in * the article window. */ --(int)currentFolderId +-(NSInteger)currentFolderId { - return [articleController currentFolderId]; + return articleController.currentFolderId; } /* selectFolder * Select the specified folder. */ --(void)selectFolder:(int)folderId +-(void)selectFolder:(NSInteger)folderId { [foldersTree selectFolder:folderId]; } @@ -2173,21 +2074,21 @@ -(void)selectFolder:(int)folderId */ -(void)updateCloseCommands { - if ([browserView countOfTabs] < 2 || ![mainWindow isKeyWindow]) + if (browserView.countOfTabs < 2 || !mainWindow.keyWindow) { - [closeTabItem setKeyEquivalent:@""]; - [closeAllTabsItem setKeyEquivalent:@""]; - [closeWindowItem setKeyEquivalent:@"w"]; - [closeWindowItem setKeyEquivalentModifierMask:NSCommandKeyMask]; + closeTabItem.keyEquivalent = @""; + closeAllTabsItem.keyEquivalent = @""; + closeWindowItem.keyEquivalent = @"w"; + closeWindowItem.keyEquivalentModifierMask = NSCommandKeyMask; } else { - [closeTabItem setKeyEquivalent:@"w"]; - [closeTabItem setKeyEquivalentModifierMask:NSCommandKeyMask]; - [closeAllTabsItem setKeyEquivalent:@"w"]; - [closeAllTabsItem setKeyEquivalentModifierMask:NSCommandKeyMask|NSAlternateKeyMask]; - [closeWindowItem setKeyEquivalent:@"W"]; - [closeWindowItem setKeyEquivalentModifierMask:NSCommandKeyMask]; + closeTabItem.keyEquivalent = @"w"; + closeTabItem.keyEquivalentModifierMask = NSCommandKeyMask; + closeAllTabsItem.keyEquivalent = @"w"; + closeAllTabsItem.keyEquivalentModifierMask = NSCommandKeyMask|NSAlternateKeyMask; + closeWindowItem.keyEquivalent = @"W"; + closeWindowItem.keyEquivalentModifierMask = NSCommandKeyMask; } } @@ -2197,9 +2098,9 @@ -(void)updateCloseCommands -(void)showAppInStatusBar { Preferences * prefs = [Preferences standardPreferences]; - if ([prefs showAppInStatusBar] && appStatusItem == nil) + if (prefs.showAppInStatusBar && appStatusItem == nil) { - appStatusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength] retain]; + appStatusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength]; [self setAppStatusBarIcon]; [appStatusItem setHighlightMode:YES]; @@ -2209,17 +2110,14 @@ -(void)showAppInStatusBar [statusBarMenu addItem:copyOfMenuItemWithAction(@selector(refreshAllSubscriptions:))]; [statusBarMenu addItem:copyOfMenuItemWithAction(@selector(markAllSubscriptionsRead:))]; [statusBarMenu addItem:[NSMenuItem separatorItem]]; - [statusBarMenu addItem:copyOfMenuItemWithAction(@selector(showPreferencePanel:))]; [statusBarMenu addItem:copyOfMenuItemWithAction(@selector(handleAbout:))]; [statusBarMenu addItem:[NSMenuItem separatorItem]]; [statusBarMenu addItem:copyOfMenuItemWithAction(@selector(exitVienna:))]; - [appStatusItem setMenu:statusBarMenu]; - [statusBarMenu release]; + appStatusItem.menu = statusBarMenu; } - else if (![prefs showAppInStatusBar] && appStatusItem != nil) + else if (!prefs.showAppInStatusBar && appStatusItem != nil) { [[NSStatusBar systemStatusBar] removeStatusItem:appStatusItem]; - [appStatusItem release]; appStatusItem = nil; } } @@ -2234,19 +2132,19 @@ -(void)setAppStatusBarIcon { if (lastCountOfUnread == 0) { - NSImage *statusBarImage = [NSImage imageNamed:@"statusBarIcon.png"]; + NSImage *statusBarImage = [NSImage imageNamed:@"statusBarIcon"]; [statusBarImage setTemplate:YES]; - [appStatusItem setImage:statusBarImage]; + appStatusItem.image = statusBarImage; [appStatusItem setTitle:nil]; } else { - NSImage *statusBarImage = [NSImage imageNamed:@"statusBarIconUnread.png"]; + NSImage *statusBarImage = [NSImage imageNamed:@"statusBarIconUnread"]; [statusBarImage setTemplate:YES]; - [appStatusItem setImage:statusBarImage]; - [appStatusItem setTitle:[NSString stringWithFormat:@"%u", lastCountOfUnread]]; + appStatusItem.image = statusBarImage; + appStatusItem.title = [NSString stringWithFormat:@"%ld", (long)lastCountOfUnread]; // Yosemite hack : need to insist for displaying correctly icon and text - [appStatusItem setImage:statusBarImage]; + appStatusItem.image = statusBarImage; } } } @@ -2257,7 +2155,7 @@ -(void)setAppStatusBarIcon */ -(void)handleRSSLink:(NSString *)linkPath { - [self createNewSubscription:linkPath underFolder:[foldersTree groupParentSelection] afterChild:-1]; + [self createNewSubscription:linkPath underFolder:foldersTree.groupParentSelection afterChild:-1]; } /* handleEditFolder @@ -2265,8 +2163,8 @@ -(void)handleRSSLink:(NSString *)linkPath */ -(void)handleEditFolder:(NSNotification *)nc { - TreeNode * node = (TreeNode *)[nc object]; - Folder * folder = [db folderFromID:[node nodeId]]; + TreeNode * node = (TreeNode *)nc.object; + Folder * folder = [db folderFromID:node.nodeId]; [self doEditFolder:folder]; } @@ -2275,7 +2173,7 @@ -(void)handleEditFolder:(NSNotification *)nc */ -(IBAction)editFolder:(id)sender { - Folder * folder = [db folderFromID:[foldersTree actualSelection]]; + Folder * folder = [db folderFromID:foldersTree.actualSelection]; [self doEditFolder:folder]; } @@ -2286,13 +2184,13 @@ -(void)doEditFolder:(Folder *)folder { if (IsRSSFolder(folder)) { - [self.rssFeed editSubscription:mainWindow folderId:[folder itemId]]; + [self.rssFeed editSubscription:mainWindow folderId:folder.itemId]; } else if (IsSmartFolder(folder)) { if (!smartFolder) smartFolder = [[SmartFolder alloc] initWithDatabase:db]; - [smartFolder loadCriteria:mainWindow folderId:[folder itemId]]; + [smartFolder loadCriteria:mainWindow folderId:folder.itemId]; } } @@ -2301,11 +2199,10 @@ -(void)doEditFolder:(Folder *)folder */ -(void)handleFolderSelection:(NSNotification *)nc { - TreeNode * node = (TreeNode *)[nc object]; - int newFolderId = [node nodeId]; + NSInteger newFolderId = ((TreeNode *)nc.object).nodeId; // We don't filter when we switch folders. - [self setFilterString:@""]; + self.filterString = @""; // Call through the controller to display the new folder. [articleController displayFolder:newFolderId]; @@ -2331,7 +2228,7 @@ -(void)handleReloadPreferences:(NSNotification *)nc { [self updateAlternateMenuTitle]; [foldersTree updateAlternateMenuTitle]; - [mainArticleView updateAlternateMenuTitle]; + [articleController updateAlternateMenuTitle]; [self updateNewArticlesNotification]; } @@ -2349,18 +2246,17 @@ -(void)handleShowAppInStatusBar:(NSNotification *)nc */ -(void)handleCheckFrequencyChange:(NSNotification *)nc { - int newFrequency = [[Preferences standardPreferences] refreshFrequency]; + NSInteger newFrequency = [Preferences standardPreferences].refreshFrequency; [checkTimer invalidate]; - [checkTimer release]; checkTimer = nil; if (newFrequency > 0) { - checkTimer = [[NSTimer scheduledTimerWithTimeInterval:newFrequency + checkTimer = [NSTimer scheduledTimerWithTimeInterval:newFrequency target:self selector:@selector(refreshOnTimer:) userInfo:nil - repeats:NO] retain]; + repeats:NO]; } } @@ -2378,11 +2274,11 @@ -(NSTimer *)checkTimer -(IBAction)doViewColumn:(id)sender; { NSMenuItem * menuItem = (NSMenuItem *)sender; - Field * field = [menuItem representedObject]; + Field * field = menuItem.representedObject; - [field setVisible:![field visible]]; - [mainArticleView updateVisibleColumns]; - [mainArticleView saveTableSettings]; + field.visible = !field.visible; + [articleController updateVisibleColumns]; + [articleController saveTableSettings]; } /* doSortColumn @@ -2391,10 +2287,10 @@ -(IBAction)doViewColumn:(id)sender; -(IBAction)doSortColumn:(id)sender { NSMenuItem * menuItem = (NSMenuItem *)sender; - Field * field = [menuItem representedObject]; + Field * field = menuItem.representedObject; NSAssert1(field, @"Somehow got a nil representedObject for Sort column sub-menu item '%@'", [menuItem title]); - [articleController sortByIdentifier:[field name]]; + [articleController sortByIdentifier:field.name]; } /* doSortDirection @@ -2403,10 +2299,10 @@ -(IBAction)doSortColumn:(id)sender -(IBAction)doSortDirection:(id)sender { NSMenuItem * menuItem = (NSMenuItem *)sender; - NSNumber * ascendingNumber = [menuItem representedObject]; + NSNumber * ascendingNumber = menuItem.representedObject; NSAssert1(ascendingNumber, @"Somehow got a nil representedObject for Sort direction sub-menu item '%@'", [menuItem title]); - BOOL ascending = [ascendingNumber boolValue]; + BOOL ascending = ascendingNumber.boolValue; [articleController sortAscending:ascending]; } @@ -2415,7 +2311,7 @@ -(IBAction)doSortDirection:(id)sender */ -(IBAction)doOpenScriptsFolder:(id)sender { - [[NSWorkspace sharedWorkspace] openFile:[[Preferences standardPreferences] scriptsFolder]]; + [[NSWorkspace sharedWorkspace] openFile:[Preferences standardPreferences].scriptsFolder]; } /* doSelectScript @@ -2424,7 +2320,7 @@ -(IBAction)doOpenScriptsFolder:(id)sender -(IBAction)doSelectScript:(id)sender { NSMenuItem * menuItem = (NSMenuItem *)sender; - NSString * scriptPath = [scriptPathMappings valueForKey:[menuItem title]]; + NSString * scriptPath = [scriptPathMappings valueForKey:menuItem.title]; if (scriptPath != nil) [self runAppleScript:scriptPath]; } @@ -2435,7 +2331,7 @@ -(IBAction)doSelectScript:(id)sender -(IBAction)doSelectStyle:(id)sender { NSMenuItem * menuItem = (NSMenuItem *)sender; - [[Preferences standardPreferences] setDisplayStyle:[menuItem title]]; + [Preferences standardPreferences].displayStyle = menuItem.title; } /* handleTabChange @@ -2443,18 +2339,18 @@ -(IBAction)doSelectStyle:(id)sender */ -(void)handleTabChange:(NSNotification *)nc { - NSView * newView = [nc object]; + NSView * newView = nc.object; if (newView == [browserView primaryTabItemView]) { - if ([self selectedArticle] == nil) - [mainWindow makeFirstResponder:[foldersTree mainView]]; + if (self.selectedArticle == nil) + [mainWindow makeFirstResponder:foldersTree.mainView]; else - [mainWindow makeFirstResponder:[[browserView primaryTabItemView] mainView]]; + [mainWindow makeFirstResponder:[browserView primaryTabItemView].mainView]; } else { BrowserPane * webPane = (BrowserPane *)newView; - [mainWindow makeFirstResponder:[webPane mainView]]; + [mainWindow makeFirstResponder:webPane.mainView]; } [self updateStatusBarFilterButtonVisibility]; [self updateSearchPlaceholderAndSearchMethod]; @@ -2474,8 +2370,8 @@ - (void)handleTabCountChange:(NSNotification *)nc */ -(void)handleFolderNameChange:(NSNotification *)nc { - int folderId = [(NSNumber *)[nc object] intValue]; - if (folderId == [articleController currentFolderId]) + NSInteger folderId = ((NSNumber *)nc.object).integerValue; + if (folderId == articleController.currentFolderId) [self updateSearchPlaceholderAndSearchMethod]; } @@ -2484,7 +2380,7 @@ -(void)handleFolderNameChange:(NSNotification *)nc */ -(void)handleRefreshStatusChange:(NSNotification *)nc { - if ([NSApp isRefreshing]) + if (self.connecting) { // Save the date/time of this refresh so we do the right thing when // we apply the filter. @@ -2492,7 +2388,7 @@ -(void)handleRefreshStatusChange:(NSNotification *)nc // Toggle the refresh button ToolbarItem * item = [self toolbarItemWithIdentifier:@"Refresh"]; - [item setAction:@selector(cancelAllRefreshesToolbar:)]; + item.action = @selector(cancelAllRefreshesToolbar:); [item setButtonImage:@"cancelRefreshButton"]; [self startProgressIndicator]; @@ -2501,28 +2397,28 @@ -(void)handleRefreshStatusChange:(NSNotification *)nc { // Run the auto-expire now Preferences * prefs = [Preferences standardPreferences]; - [db purgeArticlesOlderThanDays:[prefs autoExpireDuration]]; + [db purgeArticlesOlderThanDays:prefs.autoExpireDuration]; [self setStatusMessage:NSLocalizedString(@"Refresh completed", nil) persist:YES]; [self stopProgressIndicator]; // Toggle the refresh button ToolbarItem * item = [self toolbarItemWithIdentifier:@"Refresh"]; - [item setAction:@selector(refreshAllSubscriptions:)]; + item.action = @selector(refreshAllSubscriptions:); [item setButtonImage:@"refreshButton"]; [self showUnreadCountOnApplicationIconAndWindowTitle]; // Bounce the dock icon for 1 second if the bounce method has been selected. - int newUnread = [[RefreshManager sharedManager] countOfNewArticles] + [[GoogleReader sharedManager] countOfNewArticles]; - if (newUnread > 0 && (([prefs newArticlesNotification] & MA_NewArticlesNotification_Bounce) != 0)) + NSInteger newUnread = [RefreshManager sharedManager].countOfNewArticles + [GoogleReader sharedManager].countOfNewArticles; + if (newUnread > 0 && ((prefs.newArticlesNotification & MA_NewArticlesNotification_Bounce) != 0)) [NSApp requestUserAttention:NSInformationalRequest]; // Growl notification if (newUnread > 0) { NSMutableDictionary * contextDict = [NSMutableDictionary dictionary]; - [contextDict setValue:[NSNumber numberWithInt:MA_GrowlContext_RefreshCompleted] forKey:@"ContextType"]; + [contextDict setValue:@MA_GrowlContext_RefreshCompleted forKey:@"ContextType"]; [self growlNotify:contextDict title:NSLocalizedString(@"New articles retrieved", nil) @@ -2557,32 +2453,33 @@ -(IBAction)moreScripts:(id)sender */ -(void)viewArticlePages:(id)sender inPreferredBrowser:(BOOL)usePreferredBrowser { - NSArray * articleArray = [articleController markedArticleRange]; + NSArray * articleArray = articleController.markedArticleRange; Article * currentArticle; - if ([articleArray count] > 0) + if (articleArray.count > 0) { - NSMutableArray * articlesWithLinks = [NSMutableArray arrayWithCapacity:[articleArray count]]; - NSMutableArray * urls = [NSMutableArray arrayWithCapacity:[articleArray count]]; + NSMutableArray * articlesWithLinks = [NSMutableArray arrayWithCapacity:articleArray.count]; + NSMutableArray * urls = [NSMutableArray arrayWithCapacity:articleArray.count]; for (currentArticle in articleArray) { - if (currentArticle && ![[currentArticle link] isBlank]) + if (currentArticle && !currentArticle.link.blank) { [articlesWithLinks addObject:currentArticle]; - NSURL * theURL = [NSURL URLWithString:[currentArticle link]]; + NSURL * theURL = [NSURL URLWithString:currentArticle.link]; if (theURL == nil) { - theURL = cleanedUpAndEscapedUrlFromString([currentArticle link]); + theURL = cleanedUpAndEscapedUrlFromString(currentArticle.link); } [urls addObject:theURL]; } } [self openURLs:urls inPreferredBrowser:usePreferredBrowser]; - - if (![db readOnly]) + + if (([Preferences standardPreferences].markReadInterval > 0.0f) && !db.readOnly) { [articleController markReadByArray:articlesWithLinks readFlag:YES]; + } } } @@ -2609,7 +2506,7 @@ -(IBAction)viewArticlePagesInAlternateBrowser:(id)sender */ -(IBAction)goForward:(id)sender { - [[browserView activeTabItemView] handleGoForward:sender]; + [browserView.activeTabItemView handleGoForward:sender]; } /* goBack @@ -2618,7 +2515,7 @@ -(IBAction)goForward:(id)sender */ -(IBAction)goBack:(id)sender { - [[browserView activeTabItemView] handleGoBack:sender]; + [browserView.activeTabItemView handleGoBack:sender]; } /* localPerformFindPanelAction @@ -2633,8 +2530,8 @@ -(IBAction)localPerformFindPanelAction:(id)sender { case NSFindPanelActionSetFindString: [self setFocusToSearchField:self]; - [searchField setStringValue:[NSApp currentTextSelection]]; - [searchPanel setSearchString:[NSApp currentTextSelection]]; + searchField.stringValue = APP.currentTextSelection; + [searchPanel setSearchString:APP.currentTextSelection]; break; case NSFindPanelActionShowFindPanel: @@ -2642,7 +2539,7 @@ -(IBAction)localPerformFindPanelAction:(id)sender break; default: - [[browserView activeTabItemView] performFindPanelAction:[sender tag]]; + [browserView.activeTabItemView performFindPanelAction:[sender tag]]; break; } } @@ -2657,7 +2554,7 @@ -(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger)flags { if (keyChar >= '0' && keyChar <= '9' && (flags & NSControlKeyMask)) { - int layoutStyle = MA_Layout_Report + (keyChar - '0'); + NSInteger layoutStyle = MA_Layout_Report + (keyChar - '0'); [self setLayout:layoutStyle withRefresh:YES]; return YES; } @@ -2668,9 +2565,9 @@ -(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger)flags return NO; else { - if ([mainWindow firstResponder] == [[browserView primaryTabItemView] mainView]) + if (mainWindow.firstResponder == [browserView primaryTabItemView].mainView) { - [mainWindow makeFirstResponder:[foldersTree mainView]]; + [mainWindow makeFirstResponder:foldersTree.mainView]; return YES; } } @@ -2681,12 +2578,12 @@ -(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger)flags return NO; else { - if ([mainWindow firstResponder] == [foldersTree mainView]) + if (mainWindow.firstResponder == foldersTree.mainView) { [browserView setActiveTabToPrimaryTab]; - if ([self selectedArticle] == nil) - [articleController ensureSelectedArticle:NO]; - [mainWindow makeFirstResponder:([self selectedArticle] != nil) ? [[browserView primaryTabItemView] mainView] : [foldersTree mainView]]; + if (self.selectedArticle == nil) + [articleController ensureSelectedArticle]; + [mainWindow makeFirstResponder:(self.selectedArticle != nil) ? [browserView primaryTabItemView].mainView : foldersTree.mainView]; return YES; } } @@ -2694,12 +2591,12 @@ -(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger)flags case NSDeleteFunctionKey: case NSDeleteCharacter: - if ([mainWindow firstResponder] == [foldersTree mainView]) + if (mainWindow.firstResponder == foldersTree.mainView) { [self deleteFolder:self]; return YES; } - else if ([mainWindow firstResponder] == [mainArticleView mainView]) + else if (mainWindow.firstResponder == (articleController.mainArticleView).mainView) { [self deleteMessage:self]; return YES; @@ -2713,7 +2610,7 @@ -(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger)flags case 'f': case 'F': - if (![self isFilterBarVisible]) + if (!self.filterBarVisible) [self setPersistedFilterBarState:YES withAnimation:YES]; else [mainWindow makeFirstResponder:filterSearchField]; @@ -2763,7 +2660,7 @@ -(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger)flags case NSEnterCharacter: case NSCarriageReturnCharacter: - if ([mainWindow firstResponder] == [foldersTree mainView]) + if (mainWindow.firstResponder == foldersTree.mainView) { if (flags & NSAlternateKeyMask) [self viewSourceHomePageInAlternateBrowser:self]; @@ -2783,14 +2680,14 @@ -(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger)flags case ' ': //SPACE { - WebView * view = [[browserView activeTabItemView] webView]; - NSView * theView = [[[view mainFrame] frameView] documentView]; + WebView * view = browserView.activeTabItemView.webView; + NSView * theView = view.mainFrame.frameView.documentView; if (theView == nil) [self viewNextUnread:self]; else { - NSRect visibleRect = [theView visibleRect]; + NSRect visibleRect = theView.visibleRect; if (flags & NSShiftKeyMask) { if (visibleRect.origin.y < 2) @@ -2800,7 +2697,7 @@ -(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger)flags } else { - if (visibleRect.origin.y + visibleRect.size.height >= [theView frame].size.height - 2) + if (visibleRect.origin.y + visibleRect.size.height >= theView.frame.size.height - 2) [self viewNextUnread:self]; else [view scrollPageDown:self]; @@ -2821,15 +2718,15 @@ -(void)toggleOptionKeyButtonStates { ToolbarItem * item = [self toolbarItemWithIdentifier:@"Subscribe"]; - if (!([[NSApp currentEvent] modifierFlags] & NSAlternateKeyMask)) + if (!(NSApp.currentEvent.modifierFlags & NSAlternateKeyMask)) { [item setButtonImage:@"subscribeButton"]; - [item setAction:@selector(newSubscription:)]; + item.action = @selector(newSubscription:); } else { [item setButtonImage:@"smartFolderButton"]; - [item setAction:@selector(newSmartFolder:)]; + item.action = @selector(newSmartFolder:); } } @@ -2838,9 +2735,9 @@ -(void)toggleOptionKeyButtonStates */ -(ToolbarItem *)toolbarItemWithIdentifier:(NSString *)theIdentifier { - for (ToolbarItem * theItem in [[mainWindow toolbar] visibleItems]) + for (ToolbarItem * theItem in mainWindow.toolbar.visibleItems) { - if ([[theItem itemIdentifier] isEqualToString:theIdentifier]) + if ([theItem.itemIdentifier isEqualToString:theIdentifier]) return theItem; } return nil; @@ -2851,7 +2748,7 @@ -(ToolbarItem *)toolbarItemWithIdentifier:(NSString *)theIdentifier */ -(BOOL)isConnecting { - return [[RefreshManager sharedManager] isConnecting]; + return [RefreshManager sharedManager].connecting; } /* refreshOnTimer @@ -2868,8 +2765,8 @@ -(void)refreshOnTimer:(NSTimer *)aTimer */ -(void)markSelectedFoldersRead:(NSArray *)arrayOfFolders { - if (![db readOnly]) - [articleController markAllReadByArray:arrayOfFolders withUndo:YES withRefresh:YES]; + if (!db.readOnly) + [articleController markAllFoldersReadByArray:arrayOfFolders]; } /* createNewGoogleReaderSubscription @@ -2893,19 +2790,18 @@ -(void)createNewGoogleReaderSubscription:(NSString *)url underFolder:(NSInteger) } // Create then select the new folder. - __block NSInteger folderId; - [db doTransactionWithBlock:^(BOOL *rollback) { - folderId = [db addGoogleReaderFolder:title underParent:parentId afterChild:predecessorId subscriptionURL:url]; - }]; //end transaction block - - + NSInteger folderId = [db addGoogleReaderFolder:title + underParent:parentId + afterChild:predecessorId + subscriptionURL:url]; + if (folderId != -1) { // [foldersTree selectFolder:folderId]; // if (isAccessible(url)) //{ Folder * folder = [db folderFromID:folderId]; - [[RefreshManager sharedManager] refreshSubscriptionsAfterSubscribe:[NSArray arrayWithObject:folder] ignoringSubscriptionStatus:NO]; + [[RefreshManager sharedManager] refreshSubscriptionsAfterSubscribe:@[folder] ignoringSubscriptionStatus:NO]; //} } } @@ -2919,23 +2815,23 @@ -(void)createNewSubscription:(NSString *)urlString underFolder:(NSInteger)parent if ([urlString hasPrefix:@"feed://"]) urlString = [NSString stringWithFormat:@"http://%@", [urlString substringFromIndex:7]]; - urlString = [cleanedUpAndEscapedUrlFromString(urlString) absoluteString]; + urlString = cleanedUpAndEscapedUrlFromString(urlString).absoluteString; // If the folder already exists, just select it. Folder * folder = [db folderFromFeedURL:urlString]; if (folder != nil) { [browserView setActiveTabToPrimaryTab]; - [foldersTree selectFolder:[folder itemId]]; + [foldersTree selectFolder:folder.itemId]; return; } - // Create then select the new folder. - if ([[Preferences standardPreferences] syncGoogleReader] && [[Preferences standardPreferences] prefersGoogleNewSubscription]) + // Create the new folder. + if ([Preferences standardPreferences].syncGoogleReader && [Preferences standardPreferences].prefersGoogleNewSubscription) { //creates in Google GoogleReader * myGoogle = [GoogleReader sharedManager]; [myGoogle subscribeToFeed:urlString]; - NSString * folderName = [[db folderFromID:parentId] name]; + NSString * folderName = [db folderFromID:parentId].name; if (folderName != nil) [myGoogle setFolderName:folderName forFeed:urlString set:TRUE]; [myGoogle loadSubscriptions:nil]; @@ -2943,21 +2839,17 @@ -(void)createNewSubscription:(NSString *)urlString underFolder:(NSInteger)parent } else { //creates locally - __block NSInteger folderId; - [db doTransactionWithBlock:^(BOOL *rollback) { - folderId = [db addRSSFolder:[Database untitledFeedFolderName] underParent:parentId afterChild:predecessorId subscriptionURL:urlString]; - }]; //end transaction block + NSInteger folderId = [db addRSSFolder:[Database untitledFeedFolderName] + underParent:parentId + afterChild:predecessorId + subscriptionURL:urlString]; if (folderId != -1) { - [foldersTree selectFolder:folderId]; - if (isAccessible(urlString)) - { - Folder * folder = [db folderFromID:folderId]; - [[RefreshManager sharedManager] refreshSubscriptionsAfterSubscribe:[NSArray arrayWithObject:folder] ignoringSubscriptionStatus:NO]; - } else if ([urlString hasPrefix:@"file"]) { + if (isAccessible(urlString) || [urlString hasPrefix:@"file"]) + { Folder * folder = [db folderFromID:folderId]; - [[RefreshManager sharedManager] refreshSubscriptionsAfterSubscribe:[NSArray arrayWithObject:folder] ignoringSubscriptionStatus:NO]; + [[RefreshManager sharedManager] refreshSubscriptionsAfterSubscribe:@[folder] ignoringSubscriptionStatus:NO]; } } } @@ -2968,7 +2860,7 @@ -(void)createNewSubscription:(NSString *)urlString underFolder:(NSInteger)parent */ -(IBAction)newSubscription:(id)sender { - [self.rssFeed newSubscription:mainWindow underParent:[foldersTree groupParentSelection] initialURL:nil]; + [self.rssFeed newSubscription:mainWindow underParent:foldersTree.groupParentSelection initialURL:nil]; } /* newSmartFolder @@ -2978,7 +2870,7 @@ -(IBAction)newSmartFolder:(id)sender { if (!smartFolder) smartFolder = [[SmartFolder alloc] initWithDatabase:db]; - [smartFolder newCriteria:mainWindow underParent:[foldersTree groupParentSelection]]; + [smartFolder newCriteria:mainWindow underParent:foldersTree.groupParentSelection]; } /* newGroupFolder @@ -2988,7 +2880,7 @@ -(IBAction)newGroupFolder:(id)sender { if (!groupFolder) groupFolder = [[NewGroupFolder alloc] init]; - [groupFolder newGroupFolder:mainWindow underParent:[foldersTree groupParentSelection]]; + [groupFolder newGroupFolder:mainWindow underParent:foldersTree.groupParentSelection]; } /* restoreMessage @@ -2996,10 +2888,10 @@ -(IBAction)newGroupFolder:(id)sender */ -(IBAction)restoreMessage:(id)sender { - Folder * folder = [db folderFromID:[articleController currentFolderId]]; - if (IsTrashFolder(folder) && [self selectedArticle] != nil && ![db readOnly]) + Folder * folder = [db folderFromID:articleController.currentFolderId]; + if (IsTrashFolder(folder) && self.selectedArticle != nil && !db.readOnly) { - NSArray * articleArray = [articleController markedArticleRange]; + NSArray * articleArray = articleController.markedArticleRange; [articleController markDeletedByArray:articleArray deleteFlag:NO]; [self clearUndoStack]; } @@ -3011,12 +2903,12 @@ -(IBAction)restoreMessage:(id)sender */ -(IBAction)deleteMessage:(id)sender { - if ([self selectedArticle] != nil && ![db readOnly]) + if (self.selectedArticle != nil && !db.readOnly) { - Folder * folder = [db folderFromID:[articleController currentFolderId]]; + Folder * folder = [db folderFromID:articleController.currentFolderId]; if (!IsTrashFolder(folder)) { - NSArray * articleArray = [articleController markedArticleRange]; + NSArray * articleArray = articleController.markedArticleRange; [articleController markDeletedByArray:articleArray deleteFlag:YES]; } else @@ -3024,7 +2916,7 @@ -(IBAction)deleteMessage:(id)sender NSBeginCriticalAlertSheet(NSLocalizedString(@"Delete selected message", nil), NSLocalizedString(@"Delete", nil), NSLocalizedString(@"Cancel", nil), - nil, [NSApp mainWindow], self, + nil, NSApp.mainWindow, self, @selector(doConfirmedDelete:returnCode:contextInfo:), nil, nil, NSLocalizedString(@"Delete selected message text", nil)); } @@ -3035,11 +2927,11 @@ -(IBAction)deleteMessage:(id)sender * This function is called after the user has dismissed * the confirmation sheet. */ --(void)doConfirmedDelete:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo +-(void)doConfirmedDelete:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo { if (returnCode == NSAlertDefaultReturn) { - NSArray * articleArray = [articleController markedArticleRange]; + NSArray * articleArray = articleController.markedArticleRange; [articleController deleteArticlesByArray:articleArray]; // Blow away the undo stack here since undo actions may refer to @@ -3054,8 +2946,7 @@ -(void)doConfirmedDelete:(NSWindow *)sheet returnCode:(int)returnCode contextInf */ -(void)sourceWindowWillClose:(NSNotification *)notification { - XMLSourceWindow * sourceWindow = [notification object]; - [[sourceWindow retain] autorelease]; // Don't deallocate the object immediately + XMLSourceWindow * sourceWindow = notification.object; [sourceWindows removeObject:sourceWindow]; } @@ -3066,11 +2957,11 @@ -(void)sourceWindowWillClose:(NSNotification *)notification */ -(IBAction)showXMLSource:(id)sender { - for (Folder * folder in [foldersTree selectedFolders]) + for (Folder * folder in foldersTree.selectedFolders) { - if ([folder isRSSFolder]) + if (folder.RSSFolder) { - XMLSourceWindow * sourceWindow = [[[XMLSourceWindow alloc] initWithFolder:folder] autorelease]; + XMLSourceWindow * sourceWindow = [[XMLSourceWindow alloc] initWithFolder:folder]; if (sourceWindow != nil) { @@ -3093,7 +2984,7 @@ -(IBAction)showDownloadsWindow:(id)sender { if (downloadWindow == nil) downloadWindow = [[DownloadWindow alloc] init]; - [[downloadWindow window] makeKeyAndOrderFront:sender]; + [downloadWindow.window makeKeyAndOrderFront:sender]; } /* conditionalShowDownloadsWindow @@ -3103,8 +2994,8 @@ -(IBAction)conditionalShowDownloadsWindow:(id)sender { if (downloadWindow == nil) downloadWindow = [[DownloadWindow alloc] init]; - if (![[downloadWindow window] isVisible]) - [[downloadWindow window] makeKeyAndOrderFront:sender]; + if (!downloadWindow.window.visible) + [downloadWindow.window makeKeyAndOrderFront:sender]; } /* toggleActivityViewer @@ -3116,8 +3007,8 @@ -(IBAction)toggleActivityViewer:(id)sender activityViewer = [[ActivityViewer alloc] init]; if (activityViewer != nil) { - NSWindow * activityWindow = [activityViewer window]; - if (![activityWindow isVisible]) + NSWindow * activityWindow = activityViewer.window; + if (!activityWindow.visible) [activityViewer showWindow:self]; else [activityWindow performClose:self]; @@ -3130,9 +3021,15 @@ -(IBAction)toggleActivityViewer:(id)sender -(IBAction)viewFirstUnread:(id)sender { [browserView setActiveTabToPrimaryTab]; - if ([db countOfUnread] > 0) + if (db.countOfUnread > 0) + { + [mainWindow makeFirstResponder:[browserView primaryTabItemView].mainView]; [articleController displayFirstUnread]; - [mainWindow makeFirstResponder:([self selectedArticle] != nil) ? [[browserView primaryTabItemView] mainView] : [foldersTree mainView]]; + } + else + { + [mainWindow makeFirstResponder:(self.selectedArticle != nil) ? [browserView primaryTabItemView].mainView : foldersTree.mainView]; + } } /* viewNextUnread @@ -3141,9 +3038,15 @@ -(IBAction)viewFirstUnread:(id)sender -(IBAction)viewNextUnread:(id)sender { [browserView setActiveTabToPrimaryTab]; - if ([db countOfUnread] > 0) + if (db.countOfUnread > 0) + { + [mainWindow makeFirstResponder:[browserView primaryTabItemView].mainView]; [articleController displayNextUnread]; - [mainWindow makeFirstResponder:([self selectedArticle] != nil) ? [[browserView primaryTabItemView] mainView] : [foldersTree mainView]]; + } + else + { + [mainWindow makeFirstResponder:(self.selectedArticle != nil) ? [browserView primaryTabItemView].mainView : foldersTree.mainView]; + } } /* clearUndoStack @@ -3152,7 +3055,7 @@ -(IBAction)viewNextUnread:(id)sender */ -(void)clearUndoStack { - [[mainWindow undoManager] removeAllActions]; + [mainWindow.undoManager removeAllActions]; } /* skipFolder @@ -3161,10 +3064,13 @@ -(void)clearUndoStack */ -(IBAction)skipFolder:(id)sender { - if (![db readOnly]) + if (!db.readOnly) { - [articleController markAllReadByArray:[foldersTree selectedFolders] withUndo:YES withRefresh:YES]; - [self viewNextUnread:self]; + [articleController markAllFoldersReadByArray:foldersTree.selectedFolders]; + if (db.countOfUnread > 0) + { + [articleController displayNextFolderWithUnread]; + } } } @@ -3175,8 +3081,8 @@ -(IBAction)skipFolder:(id)sender */ -(IBAction)markAllRead:(id)sender { - if (![db readOnly]) - [articleController markAllReadByArray:[foldersTree selectedFolders] withUndo:YES withRefresh:YES]; + if (!db.readOnly) + [articleController markAllFoldersReadByArray:foldersTree.selectedFolders]; } /* markAllSubscriptionsRead @@ -3184,9 +3090,9 @@ -(IBAction)markAllRead:(id)sender */ -(IBAction)markAllSubscriptionsRead:(id)sender { - if (![db readOnly]) + if (!db.readOnly) { - [articleController markAllReadByArray:[foldersTree folders:0] withUndo:YES withRefresh:YES]; + [articleController markAllFoldersReadByArray:[foldersTree folders:0]]; } } @@ -3195,11 +3101,11 @@ -(IBAction)markAllSubscriptionsRead:(id)sender */ -(IBAction)markReadToggle:(id)sender { - Article * theArticle = [self selectedArticle]; - if (theArticle != nil && ![db readOnly]) + Article * theArticle = self.selectedArticle; + if (theArticle != nil && !db.readOnly) { - NSArray * articleArray = [articleController markedArticleRange]; - [articleController markReadByArray:articleArray readFlag:![theArticle isRead]]; + NSArray * articleArray = articleController.markedArticleRange; + [articleController markReadByArray:articleArray readFlag:!theArticle.read]; } } @@ -3208,10 +3114,10 @@ -(IBAction)markReadToggle:(id)sender */ -(IBAction)markRead:(id)sender { - Article * theArticle = [self selectedArticle]; - if (theArticle != nil && ![db readOnly]) + Article * theArticle = self.selectedArticle; + if (theArticle != nil && !db.readOnly) { - NSArray * articleArray = [articleController markedArticleRange]; + NSArray * articleArray = articleController.markedArticleRange; [articleController markReadByArray:articleArray readFlag:YES]; } } @@ -3221,10 +3127,10 @@ -(IBAction)markRead:(id)sender */ -(IBAction)markUnread:(id)sender { - Article * theArticle = [self selectedArticle]; - if (theArticle != nil && ![db readOnly]) + Article * theArticle = self.selectedArticle; + if (theArticle != nil && !db.readOnly) { - NSArray * articleArray = [articleController markedArticleRange]; + NSArray * articleArray = articleController.markedArticleRange; [articleController markReadByArray:articleArray readFlag:NO]; } } @@ -3234,11 +3140,11 @@ -(IBAction)markUnread:(id)sender */ -(IBAction)markFlagged:(id)sender { - Article * theArticle = [self selectedArticle]; - if (theArticle != nil && ![db readOnly]) + Article * theArticle = self.selectedArticle; + if (theArticle != nil && !db.readOnly) { - NSArray * articleArray = [articleController markedArticleRange]; - [articleController markFlaggedByArray:articleArray flagged:![theArticle isFlagged]]; + NSArray * articleArray = articleController.markedArticleRange; + [articleController markFlaggedByArray:articleArray flagged:!theArticle.flagged]; } } @@ -3247,15 +3153,7 @@ -(IBAction)markFlagged:(id)sender */ -(IBAction)renameFolder:(id)sender { - [foldersTree renameFolder:[foldersTree actualSelection]]; -} - -- (void)addFoldersIn:(Folder *)folder toArray:(NSMutableArray *)array -{ - [array addObject:folder]; - if (IsGroupFolder(folder)) - for (Folder * f in [db arrayOfFolders:[folder itemId]]) - [self addFoldersIn:f toArray:array]; + [foldersTree renameFolder:foldersTree.actualSelection]; } /* deleteFolder @@ -3263,8 +3161,8 @@ - (void)addFoldersIn:(Folder *)folder toArray:(NSMutableArray *)array */ -(IBAction)deleteFolder:(id)sender { - NSMutableArray * selectedFolders = [NSMutableArray arrayWithArray:[foldersTree selectedFolders]]; - NSUInteger count = [selectedFolders count]; + NSMutableArray * selectedFolders = [NSMutableArray arrayWithArray:foldersTree.selectedFolders]; + NSUInteger count = selectedFolders.count; NSUInteger index; // Show a different prompt depending on whether we're deleting one folder or a @@ -3275,27 +3173,27 @@ -(IBAction)deleteFolder:(id)sender if (count == 1) { - Folder * folder = [selectedFolders objectAtIndex:0]; + Folder * folder = selectedFolders[0]; if (IsSmartFolder(folder)) { - alertBody = [NSString stringWithFormat:NSLocalizedString(@"Delete smart folder text", nil), [folder name]]; + alertBody = [NSString stringWithFormat:NSLocalizedString(@"Delete smart folder text", nil), folder.name]; alertTitle = NSLocalizedString(@"Delete smart folder", nil); } else if (IsSearchFolder(folder)) needPrompt = NO; else if (IsRSSFolder(folder)) { - alertBody = [NSString stringWithFormat:NSLocalizedString(@"Delete RSS feed text", nil), [folder name]]; + alertBody = [NSString stringWithFormat:NSLocalizedString(@"Delete RSS feed text", nil), folder.name]; alertTitle = NSLocalizedString(@"Delete RSS feed", nil); } else if (IsGoogleReaderFolder(folder)) { - alertBody = [NSString stringWithFormat:NSLocalizedString(@"Delete Open Reader RSS feed text", nil), [folder name]]; + alertBody = [NSString stringWithFormat:NSLocalizedString(@"Delete Open Reader RSS feed text", nil), folder.name]; alertTitle = NSLocalizedString(@"Delete Open Reader RSS feed", nil); } else if (IsGroupFolder(folder)) { - alertBody = [NSString stringWithFormat:NSLocalizedString(@"Delete group folder text", nil), [folder name]]; + alertBody = [NSString stringWithFormat:NSLocalizedString(@"Delete group folder text", nil), folder.name]; alertTitle = NSLocalizedString(@"Delete group folder", nil); } else if (IsTrashFolder(folder)) @@ -3318,12 +3216,11 @@ -(IBAction)deleteFolder:(id)sender return; } - // End any editing - [self.rssFeed doEditCancel:nil]; + if (smartFolder != nil) [smartFolder doCancel:nil]; - if ([(NSControl *)[foldersTree mainView] abortEditing]) - [mainWindow makeFirstResponder:[foldersTree mainView]]; + if ([(NSControl *)foldersTree.mainView abortEditing]) + [mainWindow makeFirstResponder:foldersTree.mainView]; // Clear undo stack for this action @@ -3332,13 +3229,13 @@ -(IBAction)deleteFolder:(id)sender // Prompt for each folder for now for (index = 0; index < count; ++index) { - Folder * folder = [selectedFolders objectAtIndex:index]; + Folder * folder = selectedFolders[index]; // This little hack is so if we're deleting the folder currently being displayed // and there's more than one folder being deleted, we delete the folder currently // being displayed last so that the MA_Notify_FolderDeleted handlers that only // refresh the display if the current folder is being deleted only trips once. - if ([folder itemId] == [articleController currentFolderId] && index < count - 1) + if (folder.itemId == articleController.currentFolderId && index < count - 1) { [selectedFolders insertObject:folder atIndex:count]; ++count; @@ -3347,19 +3244,15 @@ -(IBAction)deleteFolder:(id)sender if (!IsTrashFolder(folder)) { // Create a status string - NSString * deleteStatusMsg = [NSString stringWithFormat:NSLocalizedString(@"Delete folder status", nil), [folder name]]; + NSString * deleteStatusMsg = [NSString stringWithFormat:NSLocalizedString(@"Delete folder status", nil), folder.name]; [self setStatusMessage:deleteStatusMsg persist:NO]; - // Fetch folders for unsubscribe - NSMutableArray * rssFolders = [NSMutableArray array]; - [self addFoldersIn:folder toArray:rssFolders]; - // Now call the database to delete the folder. - [db deleteFolder:[folder itemId]]; + [db deleteFolder:folder.itemId]; if (IsGoogleReaderFolder(folder)) { NSLog(@"Unsubscribe Open Reader folder"); - [[GoogleReader sharedManager] unsubscribeFromFeed:[folder feedURL]]; + [[GoogleReader sharedManager] unsubscribeFromFeed:folder.feedURL]; } } } @@ -3374,7 +3267,7 @@ -(IBAction)deleteFolder:(id)sender */ -(IBAction)getInfo:(id)sender { - int folderId = [foldersTree actualSelection]; + NSInteger folderId = foldersTree.actualSelection; if (folderId > 0) [[InfoWindowManager infoWindowManager] showInfoWindowForFolder:folderId]; } @@ -3384,27 +3277,25 @@ -(IBAction)getInfo:(id)sender */ -(IBAction)unsubscribeFeed:(id)sender { - NSMutableArray * selectedFolders = [NSMutableArray arrayWithArray:[foldersTree selectedFolders]]; - int count = [selectedFolders count]; - int index; + NSArray * selectedFolders = [NSArray arrayWithArray:foldersTree.selectedFolders]; + NSInteger count = selectedFolders.count; + NSInteger index; for (index = 0; index < count; ++index) { - Folder * folder = [selectedFolders objectAtIndex:index]; - int folderID = [folder itemId]; + Folder * folder = selectedFolders[index]; if (IsUnsubscribed(folder)) { // Currently unsubscribed, so re-subscribe locally - [[Database sharedDatabase] clearFolderFlag:folderID flagToClear:MA_FFlag_Unsubscribed]; + [[Database sharedManager] clearFlag:MA_FFlag_Unsubscribed forFolder:folder.itemId]; } else { // Currently subscribed, so unsubscribe locally - [[Database sharedDatabase] setFolderFlag:folderID flagToSet:MA_FFlag_Unsubscribed]; + [[Database sharedManager] setFlag:MA_FFlag_Unsubscribed forFolder:folder.itemId]; } - [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_FoldersUpdated" object:[NSNumber numberWithInt:folderID]]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_FoldersUpdated" + object:@(folder.itemId)]; } - - } /* setLoadFullHTMLFlag @@ -3413,26 +3304,26 @@ -(IBAction)unsubscribeFeed:(id)sender */ -(IBAction)setLoadFullHTMLFlag:(BOOL)loadFullHTMLPages { - NSMutableArray * selectedFolders = [NSMutableArray arrayWithArray:[foldersTree selectedFolders]]; - int count = [selectedFolders count]; - int index; + NSMutableArray * selectedFolders = [NSMutableArray arrayWithArray:foldersTree.selectedFolders]; + NSInteger count = selectedFolders.count; + NSInteger index; for (index = 0; index < count; ++index) { - Folder * folder = [selectedFolders objectAtIndex:index]; - int folderID = [folder itemId]; + Folder * folder = selectedFolders[index]; + NSInteger folderID = folder.itemId; if (loadFullHTMLPages) { [folder setFlag:MA_FFlag_LoadFullHTML]; - [[Database sharedDatabase] setFolderFlag:folderID flagToSet:MA_FFlag_LoadFullHTML]; + [[Database sharedManager] setFlag:MA_FFlag_LoadFullHTML forFolder:folderID]; } else { [folder clearFlag:MA_FFlag_LoadFullHTML]; - [[Database sharedDatabase] clearFolderFlag:folderID flagToClear:MA_FFlag_LoadFullHTML]; + [[Database sharedManager] clearFlag:MA_FFlag_LoadFullHTML forFolder:folderID]; } - [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_LoadFullHTMLChange" object:[NSNumber numberWithInt:folderID]]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_LoadFullHTMLChange" object:@(folderID)]; } } @@ -3457,10 +3348,10 @@ -(IBAction)useWebPageForArticles:(id)sender */ -(IBAction)viewSourceHomePage:(id)sender { - Article * thisArticle = [self selectedArticle]; - Folder * folder = (thisArticle) ? [db folderFromID:[thisArticle folderId]] : [db folderFromID:[foldersTree actualSelection]]; + Article * thisArticle = self.selectedArticle; + Folder * folder = (thisArticle) ? [db folderFromID:thisArticle.folderId] : [db folderFromID:foldersTree.actualSelection]; if (thisArticle || IsRSSFolder(folder) || IsGoogleReaderFolder(folder)) - [self openURLFromString:[folder homePage] inPreferredBrowser:YES]; + [self openURLFromString:folder.homePage inPreferredBrowser:YES]; } /* viewSourceHomePageInAlternateBrowser @@ -3468,10 +3359,10 @@ -(IBAction)viewSourceHomePage:(id)sender */ -(IBAction)viewSourceHomePageInAlternateBrowser:(id)sender { - Article * thisArticle = [self selectedArticle]; - Folder * folder = (thisArticle) ? [db folderFromID:[thisArticle folderId]] : [db folderFromID:[foldersTree actualSelection]]; + Article * thisArticle = self.selectedArticle; + Folder * folder = (thisArticle) ? [db folderFromID:thisArticle.folderId] : [db folderFromID:foldersTree.actualSelection]; if (thisArticle || IsRSSFolder(folder) || IsGoogleReaderFolder(folder)) - [self openURLFromString:[folder homePage] inPreferredBrowser:NO]; + [self openURLFromString:folder.homePage inPreferredBrowser:NO]; } /* showViennaHomePage @@ -3484,19 +3375,6 @@ -(IBAction)showViennaHomePage:(id)sender [self openURLInDefaultBrowser:[NSURL URLWithString:homePage]]; } -/* showAcknowledgements - * Display the acknowledgements document in a new tab. - */ --(IBAction)showAcknowledgements:(id)sender -{ - NSBundle *thisBundle = [NSBundle bundleForClass:[self class]]; - NSString * pathToAckFile = [thisBundle pathForResource:@"Acknowledgements" ofType:@"html"]; - if (pathToAckFile != nil) - { - [self createNewTab:[NSURL fileURLWithPath:pathToAckFile isDirectory:NO] inBackground:NO]; - } -} - #pragma mark Tabs /* previousTab @@ -3528,7 +3406,7 @@ -(IBAction)closeAllTabs:(id)sender */ -(IBAction)closeTab:(id)sender { - [browserView closeTabItemView:[browserView activeTabItemView]]; + [browserView closeTabItemView:browserView.activeTabItemView]; } /* reloadPage @@ -3536,7 +3414,7 @@ -(IBAction)closeTab:(id)sender */ -(IBAction)reloadPage:(id)sender { - NSView * theView = [browserView activeTabItemView]; + NSView * theView = browserView.activeTabItemView; if ([theView isKindOfClass:[BrowserPane class]]) [theView performSelector:@selector(handleReload:)]; } @@ -3546,7 +3424,7 @@ -(IBAction)reloadPage:(id)sender */ -(IBAction)stopReloadingPage:(id)sender { - NSView * theView = [browserView activeTabItemView]; + NSView * theView = browserView.activeTabItemView; if ([theView isKindOfClass:[BrowserPane class]]) [theView performSelector:@selector(handleStopLoading:)]; } @@ -3560,22 +3438,22 @@ -(void)updateAlternateMenuTitle { Preferences * prefs = [Preferences standardPreferences]; NSString * alternateLocation; - if ([prefs openLinksInVienna]) + if (prefs.openLinksInVienna) { alternateLocation = getDefaultBrowser(); if (alternateLocation == nil) alternateLocation = NSLocalizedString(@"External Browser", nil); } else - alternateLocation = [self appName]; + alternateLocation = self.appName; NSMenuItem * item = menuItemWithAction(@selector(viewSourceHomePageInAlternateBrowser:)); if (item != nil) { - [item setTitle:[NSString stringWithFormat:NSLocalizedString(@"Open Subscription Home Page in %@", nil), alternateLocation]]; + item.title = [NSString stringWithFormat:NSLocalizedString(@"Open Subscription Home Page in %@", nil), alternateLocation]; } item = menuItemWithAction(@selector(viewArticlePagesInAlternateBrowser:)); if (item != nil) - [item setTitle:[NSString stringWithFormat:NSLocalizedString(@"Open Article Page in %@", nil), alternateLocation]]; + item.title = [NSString stringWithFormat:NSLocalizedString(@"Open Article Page in %@", nil), alternateLocation]; } /* updateStatusBarFilterButtonVisibility @@ -3584,7 +3462,7 @@ -(void)updateAlternateMenuTitle -(void)updateStatusBarFilterButtonVisibility { - NSView * theView = [browserView activeTabItemView]; + NSView * theView = browserView.activeTabItemView; if ([theView isKindOfClass:[BrowserPane class]]) { [currentFilterTextField setHidden: YES]; @@ -3602,21 +3480,21 @@ -(void)updateStatusBarFilterButtonVisibility */ -(void)updateSearchPlaceholderAndSearchMethod { - NSView * theView = [browserView activeTabItemView]; + NSView * theView = browserView.activeTabItemView; Preferences * prefs = [Preferences standardPreferences]; // START of rather verbose implementation of switching between "Search all articles" and "Search current web page". if ([theView isKindOfClass:[BrowserPane class]]) { // If the current view is a browser view and "Search all articles" is the current SearchMethod, switch to "Search current webpage" - if ([[[prefs searchMethod] friendlyName] isEqualToString:[[SearchMethod searchAllArticlesMethod] friendlyName]]) + if ([prefs.searchMethod.friendlyName isEqualToString:[SearchMethod searchAllArticlesMethod].friendlyName]) { - for (NSMenuItem * menuItem in [[[searchField cell] searchMenuTemplate] itemArray]) + for (NSMenuItem * menuItem in ((NSSearchFieldCell *)searchField.cell).searchMenuTemplate.itemArray) { - if ([[[menuItem representedObject] friendlyName] isEqualToString:[[SearchMethod searchCurrentWebPageMethod] friendlyName]]) + if ([[menuItem.representedObject friendlyName] isEqualToString:[SearchMethod searchCurrentWebPageMethod].friendlyName]) { - [[searchField cell] setPlaceholderString:NSLocalizedString([[SearchMethod searchCurrentWebPageMethod] friendlyName], nil)]; - [[Preferences standardPreferences] setSearchMethod: [menuItem representedObject]]; + [searchField.cell setPlaceholderString:NSLocalizedString([[SearchMethod searchCurrentWebPageMethod] friendlyName], nil)]; + [Preferences standardPreferences].searchMethod = menuItem.representedObject; } } } @@ -3624,33 +3502,33 @@ -(void)updateSearchPlaceholderAndSearchMethod else { // If the current view is anything else "Search current webpage" is active, switch to "Search all articles". - if ([[[prefs searchMethod] friendlyName] isEqualToString:[[SearchMethod searchCurrentWebPageMethod] friendlyName]]) + if ([prefs.searchMethod.friendlyName isEqualToString:[SearchMethod searchCurrentWebPageMethod].friendlyName]) { - for (NSMenuItem * menuItem in [[[searchField cell] searchMenuTemplate] itemArray]) + for (NSMenuItem * menuItem in ((NSSearchFieldCell *)searchField.cell).searchMenuTemplate.itemArray) { - if ([[[menuItem representedObject] friendlyName] isEqualToString:[[SearchMethod searchAllArticlesMethod] friendlyName]]) + if ([[menuItem.representedObject friendlyName] isEqualToString:[SearchMethod searchAllArticlesMethod].friendlyName]) { - [[searchField cell] setPlaceholderString:NSLocalizedString([[SearchMethod searchAllArticlesMethod] friendlyName], nil)]; - [[Preferences standardPreferences] setSearchMethod: [menuItem representedObject]]; + [searchField.cell setPlaceholderString:NSLocalizedString([[SearchMethod searchAllArticlesMethod] friendlyName], nil)]; + [Preferences standardPreferences].searchMethod = menuItem.representedObject; } } } else { - [[searchField cell] setPlaceholderString:NSLocalizedString([[prefs searchMethod] friendlyName], nil)]; + [searchField.cell setPlaceholderString:NSLocalizedString([[prefs searchMethod] friendlyName], nil)]; } // END of switching between "Search all articles" and "Search current web page". } - if ([[Preferences standardPreferences] layout] == MA_Layout_Unified) + if ([Preferences standardPreferences].layout == MA_Layout_Unified) { - [[filterSearchField cell] setSendsWholeSearchString:YES]; - [[filterSearchField cell] setPlaceholderString:[articleController searchPlaceholderString]]; + [filterSearchField.cell setSendsWholeSearchString:YES]; + ((NSSearchFieldCell *)filterSearchField.cell).placeholderString = articleController.searchPlaceholderString; } else { - [[filterSearchField cell] setSendsWholeSearchString:NO]; - [[filterSearchField cell] setPlaceholderString:[articleController searchPlaceholderString]]; + [filterSearchField.cell setSendsWholeSearchString:NO]; + ((NSSearchFieldCell *)filterSearchField.cell).placeholderString = articleController.searchPlaceholderString; } } @@ -3661,7 +3539,7 @@ -(void)updateSearchPlaceholderAndSearchMethod */ -(IBAction)setFocusToSearchField:(id)sender { - if ([[mainWindow toolbar] isVisible] && [self toolbarItemWithIdentifier:@"SearchItem"] && [[mainWindow toolbar] displayMode] != NSToolbarDisplayModeLabelOnly) + if (mainWindow.toolbar.visible && [self toolbarItemWithIdentifier:@"SearchItem"] && mainWindow.toolbar.displayMode != NSToolbarDisplayModeLabelOnly) [mainWindow makeFirstResponder:searchField]; else { @@ -3677,8 +3555,6 @@ -(IBAction)setFocusToSearchField:(id)sender */ -(void)setSearchString:(NSString *)newSearchString { - [newSearchString retain]; - [searchString release]; searchString = newSearchString; } @@ -3687,7 +3563,7 @@ -(void)setSearchString:(NSString *)newSearchString */ -(NSString *)searchString { - return [[searchString retain] autorelease]; + return searchString; } @@ -3696,7 +3572,7 @@ -(NSString *)searchString */ -(void)setFilterString:(NSString *)newFilterString { - [filterSearchField setStringValue:newFilterString]; + filterSearchField.stringValue = newFilterString; } /* filterString @@ -3704,7 +3580,7 @@ -(void)setFilterString:(NSString *)newFilterString */ -(NSString *)filterString { - return [filterSearchField stringValue]; + return filterSearchField.stringValue; } /* searchUsingFilterField @@ -3712,7 +3588,13 @@ -(NSString *)filterString */ -(IBAction)searchUsingFilterField:(id)sender { - [[browserView activeTabItemView] performFindPanelAction:NSFindPanelActionNext]; + [browserView.activeTabItemView performFindPanelAction:NSFindPanelActionNext]; +} + +- (IBAction)searchUsingTreeFilter:(NSSearchField* )field +{ + NSString* f = field.stringValue; + [foldersTree setSearch:f]; } /* searchUsingToolbarTextField @@ -3720,9 +3602,12 @@ -(IBAction)searchUsingFilterField:(id)sender */ -(IBAction)searchUsingToolbarTextField:(id)sender { - [self setSearchString:[searchField stringValue]]; - SearchMethod * currentSearchMethod = [[Preferences standardPreferences] searchMethod]; - [self performSelector:[currentSearchMethod handler] withObject: currentSearchMethod]; + self.searchString = searchField.stringValue; + SearchMethod * currentSearchMethod = [Preferences standardPreferences].searchMethod; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + [self performSelector:currentSearchMethod.handler withObject: currentSearchMethod]; +#pragma clang diagnostic pop } /* performAllArticlesSearch @@ -3730,7 +3615,7 @@ -(IBAction)searchUsingToolbarTextField:(id)sender */ -(void)performAllArticlesSearch { - [self searchArticlesWithString:[searchField stringValue]]; + [self searchArticlesWithString:searchField.stringValue]; } /* performAllArticlesSearch @@ -3746,7 +3631,7 @@ -(void)performWebSearch:(SearchMethod *)searchMethod */ -(void)performWebPageSearch { - NSView * theView = [browserView activeTabItemView]; + NSView * theView = browserView.activeTabItemView; if ([theView isKindOfClass:[BrowserPane class]]) { [self setFocusToSearchField:self]; @@ -3761,13 +3646,13 @@ -(void)performWebPageSearch */ -(void)searchArticlesWithString:(NSString *)theSearchString { - if (![theSearchString isBlank]) + if (!theSearchString.blank) { [db setSearchString:theSearchString]; - if ([foldersTree actualSelection] != [db searchFolderId]) - [foldersTree selectFolder:[db searchFolderId]]; + if (foldersTree.actualSelection != db.searchFolderId) + [foldersTree selectFolder:db.searchFolderId]; else - [mainArticleView refreshFolder:MA_Refresh_ReloadFromDatabase]; + [articleController reloadArrayOfArticles]; } } @@ -3779,7 +3664,7 @@ -(void)searchArticlesWithString:(NSString *)theSearchString -(IBAction)refreshAllFolderIcons:(id)sender { LOG_EXPR([foldersTree folders:0]); - if (![self isConnecting]) + if (!self.connecting) [[RefreshManager sharedManager] refreshFolderIconCacheForSubscriptions:[foldersTree folders:0]]; } @@ -3788,49 +3673,18 @@ -(IBAction)refreshAllFolderIcons:(id)sender */ -(IBAction)refreshAllSubscriptions:(id)sender { - static int waitNumber = 20; - // Check the Open Reader status - if ([[Preferences standardPreferences] syncGoogleReader] && ![[GoogleReader sharedManager] isReady]) { - LLog(@"Waiting until Google Auth is done..."); - waitNumber-- ; - if (![sender isKindOfClass:[NSTimer class]]) { - LLog(@"Create a timer..."); - [[GoogleReader sharedManager] authenticate]; - [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(refreshAllSubscriptions:) userInfo:nil repeats:YES]; - } - // if we have tried for 1 minute, there is probably a serious problem with logging in... - // don't insist any further for now regarding Open Reader - if (waitNumber<=0) { - [[GoogleReader sharedManager] clearAuthentication]; - if ([sender isKindOfClass:[NSTimer class]]) { - [(NSTimer*)sender invalidate]; - sender = nil; - waitNumber = 20; - } - } - else - return; - } else { - [self setStatusMessage:nil persist:NO]; - if ([sender isKindOfClass:[NSTimer class]]) { - [(NSTimer*)sender invalidate]; - sender = nil; - waitNumber = 20; - } - } - // Reset the refresh timer [self handleCheckFrequencyChange:nil]; // Kick off an initial refresh - if (![self isConnecting]) + if (!self.connecting) [[RefreshManager sharedManager] refreshSubscriptionsAfterRefreshAll:[foldersTree folders:0] ignoringSubscriptionStatus:NO]; } -(IBAction)forceRefreshSelectedSubscriptions:(id)sender { NSLog(@"Force Refresh"); - [[RefreshManager sharedManager] forceRefreshSubscriptionForFolders:[foldersTree selectedFolders]]; + [[RefreshManager sharedManager] forceRefreshSubscriptionForFolders:foldersTree.selectedFolders]; } -(IBAction)updateRemoteSubscriptions:(id)sender { @@ -3844,7 +3698,7 @@ -(IBAction)updateRemoteSubscriptions:(id)sender { */ -(IBAction)refreshSelectedSubscriptions:(id)sender { - [[RefreshManager sharedManager] refreshSubscriptionsAfterRefresh:[foldersTree selectedFolders] ignoringSubscriptionStatus:YES]; + [[RefreshManager sharedManager] refreshSubscriptionsAfterRefresh:foldersTree.selectedFolders ignoringSubscriptionStatus:YES]; } /* cancelAllRefreshesToolbar @@ -3878,10 +3732,10 @@ -(IBAction)mailLinkToArticlePage:(id)sender Article * currentArticle; // If the active tab is a web view, mail the URL ... - NSView * theView = [browserView activeTabItemView]; + NSView * theView = browserView.activeTabItemView; if ([theView isKindOfClass:[BrowserPane class]]) { - NSString * viewLink = [theView viewLink]; + NSString * viewLink = theView.viewLink; if (viewLink != nil) { title = percentEscape([browserView tabItemViewTitle:theView]); @@ -3892,14 +3746,14 @@ -(IBAction)mailLinkToArticlePage:(id)sender else { // ... otherwise, iterate over the currently selected articles. - NSArray * articleArray = [articleController markedArticleRange]; - if ([articleArray count] > 0) + NSArray * articleArray = articleController.markedArticleRange; + if (articleArray.count > 0) { - if ([articleArray count] == 1) + if (articleArray.count == 1) { - currentArticle = [articleArray objectAtIndex:0]; - title = percentEscape([currentArticle title]); - link = percentEscape([currentArticle link]); + currentArticle = articleArray[0]; + title = percentEscape(currentArticle.title); + link = percentEscape(currentArticle.link); mailtoLink = [NSMutableString stringWithFormat: @"mailto:?subject=%@&body=%@", title, link]; } else @@ -3907,8 +3761,8 @@ -(IBAction)mailLinkToArticlePage:(id)sender mailtoLink = [NSMutableString stringWithFormat:@"mailto:?subject=&body="]; for (currentArticle in articleArray) { - title = percentEscape([currentArticle title]); - link = percentEscape([currentArticle link]); + title = percentEscape(currentArticle.title); + link = percentEscape(currentArticle.link); [mailtoLink appendFormat: @"%@%@%@%@%@", title, mailtoLineBreak, link, mailtoLineBreak, mailtoLineBreak]; } } @@ -3925,8 +3779,8 @@ -(IBAction)mailLinkToArticlePage:(id)sender */ -(IBAction)makeTextSmaller:(id)sender { - NSView * activeView = [browserView activeTabItemView]; - [[activeView webView] makeTextSmaller:sender]; + NSView * activeView = browserView.activeTabItemView; + [activeView.webView makeTextSmaller:sender]; } /* makeTextLarger @@ -3935,8 +3789,8 @@ -(IBAction)makeTextSmaller:(id)sender */ -(IBAction)makeTextLarger:(id)sender { - NSView * activeView = [browserView activeTabItemView]; - [[activeView webView] makeTextLarger:sender]; + NSView * activeView = browserView.activeTabItemView; + [activeView.webView makeTextLarger:sender]; } /* changeFiltering @@ -3945,8 +3799,8 @@ -(IBAction)makeTextLarger:(id)sender -(IBAction)changeFiltering:(id)sender { NSMenuItem * menuItem = (NSMenuItem *)sender; - [[Preferences standardPreferences] setFilterMode:[menuItem tag]]; - [currentFilterTextField setStringValue:[menuItem title]]; + [Preferences standardPreferences].filterMode = menuItem.tag; + currentFilterTextField.stringValue = menuItem.title; } #pragma mark Blogging @@ -3958,7 +3812,7 @@ -(IBAction)changeFiltering:(id)sender -(void)blogWithExternalEditor:(NSString *)externalEditorBundleIdentifier; { // Is our target application running? If not, we'll launch it. - if ([[NSRunningApplication runningApplicationsWithBundleIdentifier:externalEditorBundleIdentifier] count] == 0) + if ([NSRunningApplication runningApplicationsWithBundleIdentifier:externalEditorBundleIdentifier].count == 0) { [[NSWorkspace sharedWorkspace] launchAppWithBundleIdentifier:externalEditorBundleIdentifier options:NSWorkspaceLaunchWithoutActivation @@ -3967,14 +3821,14 @@ -(void)blogWithExternalEditor:(NSString *)externalEditorBundleIdentifier; } // If the active tab is a web view, blog the URL - NSView * theView = [browserView activeTabItemView]; + NSView * theView = browserView.activeTabItemView; if ([theView isKindOfClass:[BrowserPane class]]) - [self sendBlogEvent:externalEditorBundleIdentifier title:[browserView tabItemViewTitle:[browserView activeTabItemView]] url:[theView viewLink] body:[NSApp currentTextSelection] author:@"" guid:@""]; + [self sendBlogEvent:externalEditorBundleIdentifier title:[browserView tabItemViewTitle:browserView.activeTabItemView] url:theView.viewLink body:APP.currentTextSelection author:@"" guid:@""]; else { // Get the currently selected articles from the ArticleView and iterate over them. - for (Article * currentArticle in [articleController markedArticleRange]) - [self sendBlogEvent:externalEditorBundleIdentifier title:[currentArticle title] url:[currentArticle link] body:[NSApp currentTextSelection] author:[currentArticle author] guid:[currentArticle guid]]; + for (Article * currentArticle in articleController.markedArticleRange) + [self sendBlogEvent:externalEditorBundleIdentifier title:currentArticle.title url:currentArticle.link body:APP.currentTextSelection author:currentArticle.author guid:currentArticle.guid]; } } @@ -4013,9 +3867,9 @@ -(void)sendBlogEvent:(NSString *)externalEditorBundleIdentifier title:(NSString [event setDescriptor: eventRecord forKeyword:'----']; // Send our Apple Event. - OSStatus err = AESendMessage([event aeDesc], NULL, kAENoReply | kAEDontReconnect | kAENeverInteract | kAEDontRecord, kAEDefaultTimeout); + OSStatus err = AESendMessage(event.aeDesc, NULL, kAENoReply | kAEDontReconnect | kAENeverInteract | kAEDontRecord, kAEDefaultTimeout); if (err != noErr) - NSLog(@"Error sending Apple Event: %i", (int)err ); + NSLog(@"Error sending Apple Event: %li", (long)err ); } #pragma mark Progress Indicator @@ -4051,7 +3905,7 @@ -(void)stopProgressIndicator -(BOOL)isStatusBarVisible { Preferences * prefs = [Preferences standardPreferences]; - return [prefs showStatusBar]; + return prefs.showStatusBar; } /* handleShowStatusBar @@ -4059,7 +3913,7 @@ -(BOOL)isStatusBarVisible */ -(void)handleShowStatusBar:(NSNotification *)nc { - [self setStatusBarState:[[Preferences standardPreferences] showStatusBar] withAnimation:YES]; + [self setStatusBarState:[Preferences standardPreferences].showStatusBar withAnimation:YES]; } /* showHideStatusBar @@ -4067,10 +3921,10 @@ -(void)handleShowStatusBar:(NSNotification *)nc */ -(IBAction)showHideStatusBar:(id)sender { - BOOL newState = ![self isStatusBarVisible]; + BOOL newState = !self.statusBarVisible; [self setStatusBarState:newState withAnimation:YES]; - [[Preferences standardPreferences] setShowStatusBar:newState]; + [Preferences standardPreferences].showStatusBar = newState; } /* setStatusBarState @@ -4078,7 +3932,7 @@ -(IBAction)showHideStatusBar:(id)sender */ -(void)setStatusBarState:(BOOL)isVisible withAnimation:(BOOL)doAnimate { - NSRect viewSize = [splitView1 frame]; + NSRect viewSize = splitView1.frame; if (isStatusBarVisible && !isVisible) { viewSize.size.height += MA_StatusBarHeight; @@ -4093,8 +3947,8 @@ -(void)setStatusBarState:(BOOL)isVisible withAnimation:(BOOL)doAnimate { if (!doAnimate) { - [statusText setHidden:!isVisible]; - [splitView1 setFrame:viewSize]; + statusText.hidden = !isVisible; + splitView1.frame = viewSize; } else { @@ -4106,10 +3960,6 @@ -(void)setStatusBarState:(BOOL)isVisible withAnimation:(BOOL)doAnimate [currentFilterTextField setHidden:YES]; [filterIconInStatusBarButton setHidden:YES]; [cosmeticStatusBarHighlightLine setHidden:YES]; - if ([mainWindow respondsToSelector:@selector(setBottomCornerRounded:)]) - { - [mainWindow setBottomCornerRounded:NO]; - } } [splitView1 resizeViewWithAnimation:viewSize withTag:MA_ViewTag_Statusbar]; } @@ -4127,22 +3977,20 @@ -(void)setStatusMessage:(NSString *)newStatusText persist:(BOOL)persistenceFlag @synchronized(persistedStatusText){ if (persistenceFlag) { - [newStatusText retain]; - [persistedStatusText release]; persistedStatusText = newStatusText; } - if (newStatusText == nil || [newStatusText isBlank]) + if (newStatusText == nil || newStatusText.blank) newStatusText = persistedStatusText; - [statusText setStringValue:(newStatusText ? newStatusText : @"")]; + statusText.stringValue = (newStatusText ? newStatusText : @""); } } /* viewAnimationCompleted * Called when animation of the specified view completes. */ --(void)viewAnimationCompleted:(NSView *)theView withTag:(int)viewTag +-(void)viewAnimationCompleted:(NSView *)theView withTag:(NSInteger)viewTag { - if (viewTag == MA_ViewTag_Statusbar && [self isStatusBarVisible]) + if (viewTag == MA_ViewTag_Statusbar && self.statusBarVisible) { // When showing the status bar, show these controls AFTER // we have made the view visible. Again, looks cleaner. @@ -4150,13 +3998,9 @@ -(void)viewAnimationCompleted:(NSView *)theView withTag:(int)viewTag [currentFilterTextField setHidden:NO]; [filterIconInStatusBarButton setHidden:NO]; [cosmeticStatusBarHighlightLine setHidden:NO]; - if ([mainWindow respondsToSelector:@selector(setBottomCornerRounded:)]) - { - [mainWindow setBottomCornerRounded:YES]; - } return; } - if (viewTag == MA_ViewTag_Filterbar && [self isFilterBarVisible]) + if (viewTag == MA_ViewTag_Filterbar && self.filterBarVisible) { [filterView display]; return; @@ -4173,73 +4017,73 @@ -(void)viewAnimationCompleted:(NSView *)theView withTag:(int)viewTag */ -(BOOL)validateCommonToolbarAndMenuItems:(SEL)theAction validateFlag:(BOOL *)validateFlag { - BOOL isMainWindowVisible = [mainWindow isVisible]; - BOOL isAnyArticleView = [browserView activeTabItemView] == [browserView primaryTabItemView]; + BOOL isMainWindowVisible = mainWindow.visible; + BOOL isAnyArticleView = browserView.activeTabItemView == [browserView primaryTabItemView]; *validateFlag = NO; if (theAction == @selector(refreshAllSubscriptions:) || theAction == @selector(cancelAllRefreshesToolbar:)) { - *validateFlag = ![db readOnly]; + *validateFlag = !db.readOnly; return YES; } if (theAction == @selector(newSubscription:)) { - *validateFlag = ![db readOnly] && isMainWindowVisible; + *validateFlag = !db.readOnly && isMainWindowVisible; return YES; } if (theAction == @selector(newSmartFolder:)) { - *validateFlag = ![db readOnly] && isMainWindowVisible; + *validateFlag = !db.readOnly && isMainWindowVisible; return YES; } if (theAction == @selector(skipFolder:)) { - *validateFlag = ![db readOnly] && isAnyArticleView && isMainWindowVisible && [db countOfUnread] > 0; + *validateFlag = !db.readOnly && isAnyArticleView && isMainWindowVisible && db.countOfUnread > 0; return YES; } if (theAction == @selector(showXMLSource:)) { - Folder * folder = [db folderFromID:[foldersTree actualSelection]]; - *validateFlag = isMainWindowVisible && folder != nil && [folder hasFeedSource]; + Folder * folder = [db folderFromID:foldersTree.actualSelection]; + *validateFlag = isMainWindowVisible && folder != nil && folder.hasFeedSource; return YES; } if (theAction == @selector(getInfo:)) { - Folder * folder = [db folderFromID:[foldersTree actualSelection]]; + Folder * folder = [db folderFromID:foldersTree.actualSelection]; *validateFlag = (IsRSSFolder(folder) || IsGoogleReaderFolder(folder)) && isMainWindowVisible; return YES; } if (theAction == @selector(forceRefreshSelectedSubscriptions:)) { - Folder * folder = [db folderFromID:[foldersTree actualSelection]]; + Folder * folder = [db folderFromID:foldersTree.actualSelection]; *validateFlag = IsGoogleReaderFolder(folder); return YES; } if (theAction == @selector(viewNextUnread:)) { - *validateFlag = [db countOfUnread] > 0; + *validateFlag = db.countOfUnread > 0; return YES; } if (theAction == @selector(goBack:)) { - *validateFlag = [[browserView activeTabItemView] canGoBack] && isMainWindowVisible; + *validateFlag = browserView.activeTabItemView.canGoBack && isMainWindowVisible; return YES; } if (theAction == @selector(mailLinkToArticlePage:)) { - NSView * theView = [browserView activeTabItemView]; - Article * thisArticle = [self selectedArticle]; + NSView * theView = browserView.activeTabItemView; + Article * thisArticle = self.selectedArticle; if ([theView isKindOfClass:[BrowserPane class]]) - *validateFlag = ([theView viewLink] != nil); + *validateFlag = (theView.viewLink != nil); else *validateFlag = (thisArticle != nil && isMainWindowVisible); return NO; // Give the menu handler a chance too. } if (theAction == @selector(emptyTrash:)) { - *validateFlag = ![db readOnly]; + *validateFlag = !db.readOnly; return YES; } if (theAction == @selector(searchUsingToolbarTextField:)) @@ -4255,8 +4099,8 @@ -(BOOL)validateCommonToolbarAndMenuItems:(SEL)theAction validateFlag:(BOOL *)val -(BOOL)validateToolbarItem:(ToolbarItem *)toolbarItem { BOOL flag; - [self validateCommonToolbarAndMenuItems:[toolbarItem action] validateFlag:&flag]; - return (flag && ([NSApp isActive])); + [self validateCommonToolbarAndMenuItems:toolbarItem.action validateFlag:&flag]; + return (flag && (NSApp.active)); } /* validateMenuItem @@ -4265,10 +4109,10 @@ -(BOOL)validateToolbarItem:(ToolbarItem *)toolbarItem */ -(BOOL)validateMenuItem:(NSMenuItem *)menuItem { - SEL theAction = [menuItem action]; - BOOL isMainWindowVisible = [mainWindow isVisible]; - BOOL isAnyArticleView = [browserView activeTabItemView] == [browserView primaryTabItemView]; - BOOL isArticleView = [browserView activeTabItemView] == mainArticleView; + SEL theAction = menuItem.action; + BOOL isMainWindowVisible = mainWindow.visible; + BOOL isAnyArticleView = browserView.activeTabItemView == [browserView primaryTabItemView]; + BOOL isArticleView = browserView.activeTabItemView == articleController.mainArticleView; BOOL flag; if ([self validateCommonToolbarAndMenuItems:theAction validateFlag:&flag]) @@ -4281,25 +4125,25 @@ -(BOOL)validateMenuItem:(NSMenuItem *)menuItem return NO; if (isAnyArticleView) { - return [self selectedArticle] != nil; + return self.selectedArticle != nil; } else { - NSView * theView = [browserView activeTabItemView]; - return theView != nil && [theView isKindOfClass:[BrowserPane class]] && ![(BrowserPane *)theView isLoading]; + NSView * theView = browserView.activeTabItemView; + return theView != nil && [theView isKindOfClass:[BrowserPane class]] && !((BrowserPane *)theView).loading; } } else if (theAction == @selector(goForward:)) { - return [[browserView activeTabItemView] canGoForward] && isMainWindowVisible; + return browserView.activeTabItemView.canGoForward && isMainWindowVisible; } else if (theAction == @selector(newGroupFolder:)) { - return ![db readOnly] && isMainWindowVisible; + return !db.readOnly && isMainWindowVisible; } else if (theAction == @selector(showHideStatusBar:)) { - if ([self isStatusBarVisible]) + if (self.statusBarVisible) [menuItem setTitle:NSLocalizedString(@"Hide Status Bar", nil)]; else [menuItem setTitle:NSLocalizedString(@"Show Status Bar", nil)]; @@ -4307,7 +4151,7 @@ -(BOOL)validateMenuItem:(NSMenuItem *)menuItem } else if (theAction == @selector(showHideFilterBar:)) { - if ([self isFilterBarVisible]) + if (self.filterBarVisible) [menuItem setTitle:NSLocalizedString(@"Hide Filter Bar", nil)]; else [menuItem setTitle:NSLocalizedString(@"Show Filter Bar", nil)]; @@ -4315,46 +4159,46 @@ -(BOOL)validateMenuItem:(NSMenuItem *)menuItem } else if (theAction == @selector(makeTextLarger:)) { - return [[[browserView activeTabItemView] webView] canMakeTextLarger] && isMainWindowVisible; + return browserView.activeTabItemView.webView.canMakeTextLarger && isMainWindowVisible; } else if (theAction == @selector(makeTextSmaller:)) { - return [[[browserView activeTabItemView] webView] canMakeTextSmaller] && isMainWindowVisible; + return browserView.activeTabItemView.webView.canMakeTextSmaller && isMainWindowVisible; } else if (theAction == @selector(doViewColumn:)) { - Field * field = [menuItem representedObject]; - [menuItem setState:[field visible] ? NSOnState : NSOffState]; + Field * field = menuItem.representedObject; + menuItem.state = field.visible ? NSOnState : NSOffState; return isMainWindowVisible && isArticleView; } else if (theAction == @selector(doSelectStyle:)) { - NSString * styleName = [menuItem title]; - [menuItem setState:[styleName isEqualToString:[[Preferences standardPreferences] displayStyle]] ? NSOnState : NSOffState]; + NSString * styleName = menuItem.title; + menuItem.state = [styleName isEqualToString:[Preferences standardPreferences].displayStyle] ? NSOnState : NSOffState; return isMainWindowVisible && isAnyArticleView; } else if (theAction == @selector(doSortColumn:)) { - Field * field = [menuItem representedObject]; - if ([[field name] isEqualToString:[articleController sortColumnIdentifier]]) - [menuItem setState:NSOnState]; + Field * field = menuItem.representedObject; + if ([field.name isEqualToString:articleController.sortColumnIdentifier]) + menuItem.state = NSOnState; else - [menuItem setState:NSOffState]; + menuItem.state = NSOffState; return isMainWindowVisible && isAnyArticleView; } else if (theAction == @selector(doSortDirection:)) { - NSNumber * ascendingNumber = [menuItem representedObject]; - BOOL ascending = [ascendingNumber integerValue]; - if (ascending == [articleController sortIsAscending]) - [menuItem setState:NSOnState]; + NSNumber * ascendingNumber = menuItem.representedObject; + BOOL ascending = ascendingNumber.integerValue; + if (ascending == articleController.sortIsAscending) + menuItem.state = NSOnState; else - [menuItem setState:NSOffState]; + menuItem.state = NSOffState; return isMainWindowVisible && isAnyArticleView; } else if (theAction == @selector(unsubscribeFeed:)) { - Folder * folder = [db folderFromID:[foldersTree actualSelection]]; + Folder * folder = [db folderFromID:foldersTree.actualSelection]; if (folder) { if (IsUnsubscribed(folder)) @@ -4362,77 +4206,77 @@ -(BOOL)validateMenuItem:(NSMenuItem *)menuItem else [menuItem setTitle:NSLocalizedString(@"Unsubscribe", nil)]; } - return folder && (IsRSSFolder(folder) || IsGoogleReaderFolder(folder)) && ![db readOnly] && isMainWindowVisible; + return folder && (IsRSSFolder(folder) || IsGoogleReaderFolder(folder)) && !db.readOnly && isMainWindowVisible; } else if (theAction == @selector(useCurrentStyleForArticles:)) { - Folder * folder = [db folderFromID:[foldersTree actualSelection]]; - if (folder && (IsRSSFolder(folder) || IsGoogleReaderFolder(folder)) && ![folder loadsFullHTML]) - [menuItem setState:NSOnState]; + Folder * folder = [db folderFromID:foldersTree.actualSelection]; + if (folder && (IsRSSFolder(folder) || IsGoogleReaderFolder(folder)) && !folder.loadsFullHTML) + menuItem.state = NSOnState; else - [menuItem setState:NSOffState]; - return folder && (IsRSSFolder(folder) || IsGoogleReaderFolder(folder)) && ![db readOnly] && isMainWindowVisible; + menuItem.state = NSOffState; + return folder && (IsRSSFolder(folder) || IsGoogleReaderFolder(folder)) && !db.readOnly && isMainWindowVisible; } else if (theAction == @selector(useWebPageForArticles:)) { - Folder * folder = [db folderFromID:[foldersTree actualSelection]]; - if (folder && (IsRSSFolder(folder) || IsGoogleReaderFolder(folder)) && [folder loadsFullHTML]) - [menuItem setState:NSOnState]; + Folder * folder = [db folderFromID:foldersTree.actualSelection]; + if (folder && (IsRSSFolder(folder) || IsGoogleReaderFolder(folder)) && folder.loadsFullHTML) + menuItem.state = NSOnState; else - [menuItem setState:NSOffState]; - return folder && (IsRSSFolder(folder) || IsGoogleReaderFolder(folder)) && ![db readOnly] && isMainWindowVisible; + menuItem.state = NSOffState; + return folder && (IsRSSFolder(folder) || IsGoogleReaderFolder(folder)) && !db.readOnly && isMainWindowVisible; } else if (theAction == @selector(deleteFolder:)) { - Folder * folder = [db folderFromID:[foldersTree actualSelection]]; + Folder * folder = [db folderFromID:foldersTree.actualSelection]; if (IsSearchFolder(folder)) [menuItem setTitle:NSLocalizedString(@"Delete", nil)]; else [menuItem setTitle:NSLocalizedString(@"Delete…", nil)]; - return folder && !IsTrashFolder(folder) && ![db readOnly] && isMainWindowVisible; + return folder && !IsTrashFolder(folder) && !db.readOnly && isMainWindowVisible; } else if (theAction == @selector(refreshSelectedSubscriptions:)) { - Folder * folder = [db folderFromID:[foldersTree actualSelection]]; - return folder && (IsRSSFolder(folder) || IsGroupFolder(folder) || IsGoogleReaderFolder(folder)) && ![db readOnly]; + Folder * folder = [db folderFromID:foldersTree.actualSelection]; + return folder && (IsRSSFolder(folder) || IsGroupFolder(folder) || IsGoogleReaderFolder(folder)) && !db.readOnly; } else if (theAction == @selector(refreshAllFolderIcons:)) { - return ![self isConnecting] && ![db readOnly]; + return !self.connecting && !db.readOnly; } else if (theAction == @selector(renameFolder:)) { - Folder * folder = [db folderFromID:[foldersTree actualSelection]]; - return folder && ![db readOnly] && isMainWindowVisible; + Folder * folder = [db folderFromID:foldersTree.actualSelection]; + return folder && !db.readOnly && isMainWindowVisible; } else if (theAction == @selector(markAllRead:)) { - Folder * folder = [db folderFromID:[foldersTree actualSelection]]; - return folder && !IsTrashFolder(folder) && ![db readOnly] && isMainWindowVisible && [db countOfUnread] > 0; + Folder * folder = [db folderFromID:foldersTree.actualSelection]; + return folder && !IsTrashFolder(folder) && !db.readOnly && isMainWindowVisible && db.countOfUnread > 0; } else if (theAction == @selector(markAllSubscriptionsRead:)) { - return ![db readOnly] && isMainWindowVisible && [db countOfUnread] > 0; + return !db.readOnly && isMainWindowVisible && db.countOfUnread > 0; } else if (theAction == @selector(importSubscriptions:)) { - return ![db readOnly] && isMainWindowVisible; + return !db.readOnly && isMainWindowVisible; } else if (theAction == @selector(cancelAllRefreshes:)) { - return ![db readOnly] && [self isConnecting]; + return !db.readOnly && self.connecting; } else if ((theAction == @selector(viewSourceHomePage:)) || (theAction == @selector(viewSourceHomePageInAlternateBrowser:))) { - Article * thisArticle = [self selectedArticle]; - Folder * folder = (thisArticle) ? [db folderFromID:[thisArticle folderId]] : [db folderFromID:[foldersTree actualSelection]]; - return folder && (thisArticle || IsRSSFolder(folder) || IsGoogleReaderFolder(folder)) && ([folder homePage] && ![[folder homePage] isBlank] && isMainWindowVisible); + Article * thisArticle = self.selectedArticle; + Folder * folder = (thisArticle) ? [db folderFromID:thisArticle.folderId] : [db folderFromID:foldersTree.actualSelection]; + return folder && (thisArticle || IsRSSFolder(folder) || IsGoogleReaderFolder(folder)) && (folder.homePage && !folder.homePage.blank && isMainWindowVisible); } else if ((theAction == @selector(viewArticlePages:)) || (theAction == @selector(viewArticlePagesInAlternateBrowser:))) { - Article * thisArticle = [self selectedArticle]; + Article * thisArticle = self.selectedArticle; if (thisArticle != nil) - return ([thisArticle link] && ![[thisArticle link] isBlank] && isMainWindowVisible); + return (thisArticle.link && !thisArticle.link.blank && isMainWindowVisible); return NO; } else if (theAction == @selector(exportSubscriptions:)) @@ -4441,30 +4285,30 @@ -(BOOL)validateMenuItem:(NSMenuItem *)menuItem } else if (theAction == @selector(reindexDatabase:)) { - return ![self isConnecting] && ![db readOnly] && isMainWindowVisible; + return !self.connecting && !db.readOnly && isMainWindowVisible; } else if (theAction == @selector(editFolder:)) { - Folder * folder = [db folderFromID:[foldersTree actualSelection]]; - return folder && (IsSmartFolder(folder) || IsRSSFolder(folder)) && ![db readOnly] && isMainWindowVisible; + Folder * folder = [db folderFromID:foldersTree.actualSelection]; + return folder && (IsSmartFolder(folder) || IsRSSFolder(folder)) && !db.readOnly && isMainWindowVisible; } else if (theAction == @selector(restoreMessage:)) { - Folder * folder = [db folderFromID:[foldersTree actualSelection]]; - return IsTrashFolder(folder) && [self selectedArticle] != nil && ![db readOnly] && isMainWindowVisible; + Folder * folder = [db folderFromID:foldersTree.actualSelection]; + return IsTrashFolder(folder) && self.selectedArticle != nil && !db.readOnly && isMainWindowVisible; } else if (theAction == @selector(deleteMessage:)) { - Folder * folder = [db folderFromID:[foldersTree actualSelection]]; - return [self selectedArticle] != nil && ![db readOnly] && isMainWindowVisible &&!IsGoogleReaderFolder(folder); + Folder * folder = [db folderFromID:foldersTree.actualSelection]; + return self.selectedArticle != nil && !db.readOnly && isMainWindowVisible &&!IsGoogleReaderFolder(folder); } else if (theAction == @selector(previousTab:)) { - return isMainWindowVisible && [browserView countOfTabs] > 1; + return isMainWindowVisible && browserView.countOfTabs > 1; } else if (theAction == @selector(nextTab:)) { - return isMainWindowVisible && [browserView countOfTabs] > 1; + return isMainWindowVisible && browserView.countOfTabs > 1; } else if (theAction == @selector(closeTab:)) { @@ -4472,27 +4316,27 @@ -(BOOL)validateMenuItem:(NSMenuItem *)menuItem } else if (theAction == @selector(closeAllTabs:)) { - return isMainWindowVisible && [browserView countOfTabs] > 1; + return isMainWindowVisible && browserView.countOfTabs > 1; } else if (theAction == @selector(reloadPage:)) { - NSView * theView = [browserView activeTabItemView]; - return ([theView isKindOfClass:[BrowserPane class]]) && ![(BrowserPane *)theView isLoading]; + NSView * theView = browserView.activeTabItemView; + return ([theView isKindOfClass:[BrowserPane class]]) && !((BrowserPane *)theView).loading; } else if (theAction == @selector(stopReloadingPage:)) { - NSView * theView = [browserView activeTabItemView]; - return ([theView isKindOfClass:[BrowserPane class]]) && [(BrowserPane *)theView isLoading]; + NSView * theView = browserView.activeTabItemView; + return ([theView isKindOfClass:[BrowserPane class]]) && ((BrowserPane *)theView).loading; } else if (theAction == @selector(changeFiltering:)) { - [menuItem setState:([menuItem tag] == [[Preferences standardPreferences] filterMode]) ? NSOnState : NSOffState]; + menuItem.state = (menuItem.tag == [Preferences standardPreferences].filterMode) ? NSOnState : NSOffState; return isMainWindowVisible; } else if (theAction == @selector(keepFoldersArranged:)) { Preferences * prefs = [Preferences standardPreferences]; - [menuItem setState:([prefs foldersTreeSortMethod] == [menuItem tag]) ? NSOnState : NSOffState]; + menuItem.state = (prefs.foldersTreeSortMethod == menuItem.tag) ? NSOnState : NSOffState; return isMainWindowVisible; } else if (theAction == @selector(setFocusToSearchField:)) @@ -4502,46 +4346,46 @@ -(BOOL)validateMenuItem:(NSMenuItem *)menuItem else if (theAction == @selector(reportLayout:)) { Preferences * prefs = [Preferences standardPreferences]; - [menuItem setState:([prefs layout] == MA_Layout_Report) ? NSOnState : NSOffState]; + menuItem.state = (prefs.layout == MA_Layout_Report) ? NSOnState : NSOffState; return isMainWindowVisible; } else if (theAction == @selector(condensedLayout:)) { Preferences * prefs = [Preferences standardPreferences]; - [menuItem setState:([prefs layout] == MA_Layout_Condensed) ? NSOnState : NSOffState]; + menuItem.state = (prefs.layout == MA_Layout_Condensed) ? NSOnState : NSOffState; return isMainWindowVisible; } else if (theAction == @selector(unifiedLayout:)) { Preferences * prefs = [Preferences standardPreferences]; - [menuItem setState:([prefs layout] == MA_Layout_Unified) ? NSOnState : NSOffState]; + menuItem.state = (prefs.layout == MA_Layout_Unified) ? NSOnState : NSOffState; return isMainWindowVisible; } else if (theAction == @selector(markFlagged:)) { - Article * thisArticle = [self selectedArticle]; + Article * thisArticle = self.selectedArticle; if (thisArticle != nil) { - if ([thisArticle isFlagged]) + if (thisArticle.flagged) [menuItem setTitle:NSLocalizedString(@"Mark Unflagged", nil)]; else [menuItem setTitle:NSLocalizedString(@"Mark Flagged", nil)]; } - return (thisArticle != nil && ![db readOnly] && isMainWindowVisible); + return (thisArticle != nil && !db.readOnly && isMainWindowVisible); } else if (theAction == @selector(markRead:)) { - Article * thisArticle = [self selectedArticle]; - return (thisArticle != nil && ![db readOnly] && isMainWindowVisible); + Article * thisArticle = self.selectedArticle; + return (thisArticle != nil && !db.readOnly && isMainWindowVisible); } else if (theAction == @selector(markUnread:)) { - Article * thisArticle = [self selectedArticle]; - return (thisArticle != nil && ![db readOnly] && isMainWindowVisible); + Article * thisArticle = self.selectedArticle; + return (thisArticle != nil && !db.readOnly && isMainWindowVisible); } else if (theAction == @selector(mailLinkToArticlePage:)) { - if ([[articleController markedArticleRange] count] > 1) + if (articleController.markedArticleRange.count > 1) [menuItem setTitle:NSLocalizedString(@"Send Links", nil)]; else [menuItem setTitle:NSLocalizedString(@"Send Link", nil)]; @@ -4549,11 +4393,11 @@ -(BOOL)validateMenuItem:(NSMenuItem *)menuItem } else if (theAction == @selector(downloadEnclosure:)) { - if ([[articleController markedArticleRange] count] > 1) + if (articleController.markedArticleRange.count > 1) [menuItem setTitle:NSLocalizedString(@"Download Enclosures", nil)]; else [menuItem setTitle:NSLocalizedString(@"Download Enclosure", nil)]; - return ([[self selectedArticle] hasEnclosure] && isMainWindowVisible); + return (self.selectedArticle.hasEnclosure && isMainWindowVisible); } else if (theAction == @selector(newTab:)) { @@ -4562,10 +4406,10 @@ -(BOOL)validateMenuItem:(NSMenuItem *)menuItem else if (theAction == @selector(setSearchMethod:)) { Preferences * prefs = [Preferences standardPreferences]; - if ([[[prefs searchMethod] friendlyName] isEqualToString:[[menuItem representedObject] friendlyName]]) - [menuItem setState:NSOnState]; + if ([prefs.searchMethod.friendlyName isEqualToString:[menuItem.representedObject friendlyName]]) + menuItem.state = NSOnState; else - [menuItem setState:NSOffState]; + menuItem.state = NSOffState; return YES; } return YES; @@ -4583,86 +4427,86 @@ -(NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString * { [item setView:searchField]; [item setLabel:NSLocalizedString(@"Search Articles", nil)]; - [item setPaletteLabel:[item label]]; - [item setTarget:self]; - [item setAction:@selector(searchUsingToolbarTextField:)]; + item.paletteLabel = item.label; + item.target = self; + item.action = @selector(searchUsingToolbarTextField:); [item setToolTip:NSLocalizedString(@"Search Articles", nil)]; } else if ([itemIdentifier isEqualToString:@"Subscribe"]) { [item setLabel:NSLocalizedString(@"Subscribe", nil)]; - [item setPaletteLabel:[item label]]; + item.paletteLabel = item.label; [item setButtonImage:@"subscribeButton"]; - [item setTarget:self]; - [item setAction:@selector(newSubscription:)]; + item.target = self; + item.action = @selector(newSubscription:); [item setToolTip:NSLocalizedString(@"Create a new subscription", nil)]; } else if ([itemIdentifier isEqualToString:@"PreviousButton"]) { [item setLabel:NSLocalizedString(@"Back", nil)]; - [item setPaletteLabel:[item label]]; + item.paletteLabel = item.label; [item setButtonImage:@"previousButton"]; - [item setTarget:self]; - [item setAction:@selector(goBack:)]; + item.target = self; + item.action = @selector(goBack:); [item setToolTip:NSLocalizedString(@"Back", nil)]; } else if ([itemIdentifier isEqualToString:@"NextButton"]) { [item setLabel:NSLocalizedString(@"Next Unread", nil)]; - [item setPaletteLabel:[item label]]; + item.paletteLabel = item.label; [item setButtonImage:@"nextButton"]; - [item setTarget:self]; - [item setAction:@selector(viewNextUnread:)]; + item.target = self; + item.action = @selector(viewNextUnread:); [item setToolTip:NSLocalizedString(@"Next Unread", nil)]; } else if ([itemIdentifier isEqualToString:@"SkipFolder"]) { [item setLabel:NSLocalizedString(@"Skip Folder", nil)]; - [item setPaletteLabel:[item label]]; + item.paletteLabel = item.label; [item setButtonImage:@"skipFolderButton"]; - [item setTarget:self]; - [item setAction:@selector(skipFolder:)]; + item.target = self; + item.action = @selector(skipFolder:); [item setToolTip:NSLocalizedString(@"Skip Folder", nil)]; } else if ([itemIdentifier isEqualToString:@"Refresh"]) { [item setLabel:NSLocalizedString(@"Refresh", nil)]; - [item setPaletteLabel:[item label]]; + item.paletteLabel = item.label; [item setButtonImage:@"refreshButton"]; - [item setTarget:self]; - [item setAction:@selector(refreshAllSubscriptions:)]; + item.target = self; + item.action = @selector(refreshAllSubscriptions:); [item setToolTip:NSLocalizedString(@"Refresh all your subscriptions", nil)]; } else if ([itemIdentifier isEqualToString:@"MailLink"]) { [item setLabel:NSLocalizedString(@"Send Link", nil)]; - [item setPaletteLabel:[item label]]; + item.paletteLabel = item.label; [item setButtonImage:@"mailLinkButton"]; - [item setTarget:self]; - [item setAction:@selector(mailLinkToArticlePage:)]; + item.target = self; + item.action = @selector(mailLinkToArticlePage:); [item setToolTip:NSLocalizedString(@"Email a link to the current article or website", nil)]; } else if ([itemIdentifier isEqualToString:@"EmptyTrash"]) { [item setLabel:NSLocalizedString(@"Empty Trash", nil)]; - [item setPaletteLabel:[item label]]; + item.paletteLabel = item.label; [item setButtonImage:@"emptyTrashButton"]; - [item setTarget:self]; - [item setAction:@selector(emptyTrash:)]; + item.target = self; + item.action = @selector(emptyTrash:); [item setToolTip:NSLocalizedString(@"Delete all articles in the trash", nil)]; } else if ([itemIdentifier isEqualToString:@"GetInfo"]) { [item setLabel:NSLocalizedString(@"Get Info", nil)]; - [item setPaletteLabel:[item label]]; + item.paletteLabel = item.label; [item setButtonImage:@"getInfoButton"]; - [item setTarget:self]; - [item setAction:@selector(getInfo:)]; + item.target = self; + item.action = @selector(getInfo:); [item setToolTip:NSLocalizedString(@"See information about the selected subscription", nil)]; } else if ([itemIdentifier isEqualToString: @"Spinner"]) { - [item setLabel:@""]; + item.label = @""; [item setPaletteLabel:NSLocalizedString(@"Progress", nil)]; //Only have the spinner hide when stopped for the real window, not for the customization pane if (willBeInserted) @@ -4674,43 +4518,42 @@ -(NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString * [spinner setHidden:NO]; //Ensure the spinner has the proper state; it may be added while we're refreshing - if ([NSApp isRefreshing]) - [spinner startAnimation:self]; + if (self.connecting) + [self startProgressIndicator]; } else { - NSProgressIndicator *customizationPaletteSpinner = [[NSProgressIndicator alloc] initWithFrame:[spinner frame]]; - [customizationPaletteSpinner setControlSize:[spinner controlSize]]; - [customizationPaletteSpinner setControlTint:[spinner controlTint]]; - [customizationPaletteSpinner setIndeterminate:[spinner isIndeterminate]]; - [customizationPaletteSpinner setStyle:[spinner style]]; + NSProgressIndicator *customizationPaletteSpinner = [[NSProgressIndicator alloc] initWithFrame:spinner.frame]; + customizationPaletteSpinner.controlSize = spinner.controlSize; + customizationPaletteSpinner.controlTint = spinner.controlTint; + customizationPaletteSpinner.indeterminate = spinner.indeterminate; + customizationPaletteSpinner.style = spinner.style; [item setView:customizationPaletteSpinner]; - [customizationPaletteSpinner release]; } - [item setMinSize:NSMakeSize(NSWidth([spinner frame]), NSHeight([spinner frame]))]; - [item setMaxSize:NSMakeSize(NSWidth([spinner frame]), NSHeight([spinner frame]))]; + item.minSize = NSMakeSize(NSWidth(spinner.frame), NSHeight(spinner.frame)); + item.maxSize = NSMakeSize(NSWidth(spinner.frame), NSHeight(spinner.frame)); } else if ([itemIdentifier isEqualToString: @"Styles"]) { - [item setPopup:@"stylesMenuButton" withMenu:(willBeInserted ? [self getStylesMenu] : nil)]; + [item setPopup:@"stylesMenuButton" withMenu:(willBeInserted ? self.stylesMenu : nil)]; [item setLabel:NSLocalizedString(@"Style", nil)]; - [item setPaletteLabel:[item label]]; + item.paletteLabel = item.label; [item setToolTip:NSLocalizedString(@"Display the list of available styles", nil)]; } else if ([itemIdentifier isEqualToString: @"Action"]) { - [item setPopup:@"popupMenuButton" withMenu:(willBeInserted ? [self folderMenu] : nil)]; + [item setPopup:@"popupMenuButton" withMenu:(willBeInserted ? self.folderMenu : nil)]; [item setLabel:NSLocalizedString(@"Action", nil)]; - [item setPaletteLabel:[item label]]; + item.paletteLabel = item.label; [item setToolTip:NSLocalizedString(@"Additional actions for the selected folder", nil)]; } else { [pluginManager toolbarItem:item withIdentifier:itemIdentifier]; } - return [item autorelease]; + return item; } /* toolbarDefaultItemIdentifiers @@ -4719,15 +4562,14 @@ -(NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString * */ -(NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar { - return [NSArray arrayByExpandingAllArrayObjects: - @"Subscribe", + return [[@[@"Subscribe", @"SkipFolder", @"Action", - @"Refresh", - [pluginManager defaultToolbarItems], - NSToolbarFlexibleSpaceItemIdentifier, - @"SearchItem", - nil]; + @"Refresh"] + arrayByAddingObjectsFromArray:[pluginManager defaultToolbarItems]] + arrayByAddingObjectsFromArray:@[NSToolbarFlexibleSpaceItemIdentifier, + @"SearchItem"] + ]; } /* toolbarAllowedItemIdentifiers @@ -4736,8 +4578,7 @@ -(NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar */ -(NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar { - return [NSArray arrayByExpandingAllArrayObjects: - NSToolbarSeparatorItemIdentifier, + return [@[NSToolbarSeparatorItemIdentifier, NSToolbarSpaceItemIdentifier, NSToolbarFlexibleSpaceItemIdentifier, @"Refresh", @@ -4751,86 +4592,26 @@ -(NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar @"GetInfo", @"Styles", @"PreviousButton", - @"NextButton", - [pluginManager toolbarItems], - nil]; -} - -/*! showSystemProfileInfoAlert - * displays an alert asking the user to opt-in to sending anonymous system profile throug Sparkle - */ --(void)showSystemProfileInfoAlert { - NSAlert *alert = [[NSAlert alloc] init]; - [alert addButtonWithTitle:NSLocalizedString(@"OK", @"OK")]; - [alert addButtonWithTitle:NSLocalizedString(@"No thanks", @"No thanks")]; - [alert setMessageText:NSLocalizedString(@"Include anonymous system profile when checking for updates?", @"Include anonymous system profile when checking for updates?")]; - [alert setInformativeText:NSLocalizedString(@"Include anonymous system profile when checking for updates text", @"This helps Vienna development by letting us know what versions of Mac OS X are most popular amongst our users.")]; - [alert setAlertStyle:NSInformationalAlertStyle]; - int buttonClicked = alert.runModal; - NSLog(@"buttonClicked: %d", buttonClicked); - switch (buttonClicked) { - case NSAlertFirstButtonReturn: - /* Agreed to send system profile. Uses preferences to set value otherwise - the preference control is out of sync */ - [[Preferences standardPreferences] setSendSystemSpecs:YES]; - break; - case NSAlertSecondButtonReturn: - /* Declined to send system profile. Uses SUUpdater to set the value - otherwise it stays nil instead of being set to 0 */ - [[SUUpdater sharedUpdater] setSendsSystemProfile:NO]; - break; - default: - break; - } - [alert release]; + @"NextButton"] + arrayByAddingObjectsFromArray:pluginManager.toolbarItems + ]; } +#pragma mark Preferences -#pragma mark - MASPreferences - -- (NSWindowController *)preferencesWindowController -{ - if (_preferencesWindowController == nil) - { - NSViewController *generalViewController = [[GeneralPreferencesViewController alloc] init]; - NSViewController *appearanceViewController = [[AppearancePreferencesViewController alloc] init]; - NSViewController *syncingViewController = [[SyncingPreferencesViewController alloc] init]; - NSViewController *advancedViewController = [[AdvancedPreferencesViewController alloc] init]; - NSArray *controllers = [[NSArray alloc] initWithObjects:generalViewController, appearanceViewController, syncingViewController, advancedViewController, nil]; - - // To add a flexible space between General and Advanced preference panes insert [NSNull null]: - // NSArray *controllers = [[NSArray alloc] initWithObjects:generalViewController, [NSNull null], advancedViewController, nil]; - - [generalViewController release]; - [appearanceViewController release]; - [syncingViewController release]; - [advancedViewController release]; - - NSString *title = NSLocalizedString(@"Preferences", @"Common title for Preferences window"); - _preferencesWindowController = [[MASPreferencesWindowController alloc] initWithViewControllers:controllers title:title]; - [controllers release]; +- (PreferencesWindowController *)preferencesWindowController { + if (!_preferencesWindowController) { + _preferencesWindowController = [PreferencesWindowController new]; } + return _preferencesWindowController; } -#pragma mark - MASPreferences Actions - -- (IBAction)showPreferencePanel:(id)sender -{ - [self.preferencesWindowController showWindow:nil]; +- (IBAction)showPreferences:(id)sender { + [self.preferencesWindowController showWindow:self]; } -NSString *const kFocusedAdvancedControlIndex = @"FocusedAdvancedControlIndex"; - -- (NSInteger)focusedAdvancedControlIndex -{ - return [[NSUserDefaults standardUserDefaults] integerForKey:kFocusedAdvancedControlIndex]; -} - -- (void)setFocusedAdvancedControlIndex:(NSInteger)focusedAdvancedControlIndex -{ - [[NSUserDefaults standardUserDefaults] setInteger:focusedAdvancedControlIndex forKey:kFocusedAdvancedControlIndex]; -} +#pragma mark Dealloc /* dealloc * Clean up and release resources. @@ -4839,28 +4620,9 @@ -(void)dealloc { [mainWindow setDelegate:nil]; [splitView1 setDelegate:nil]; + [[SUUpdater sharedUpdater] setDelegate:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self]; - [pluginManager release]; - [scriptsMenuItem release]; - [standardURLs release]; - [downloadWindow release]; - [persistedStatusText release]; - [scriptPathMappings release]; - [smartFolder release]; - [groupFolder release]; - [preferenceController release]; - [activityViewer release]; - [checkTimer release]; - [appDockMenu release]; - [appStatusItem release]; - [db release]; - [spinner release]; - [searchField release]; - [sourceWindows release]; - [searchString release]; - [_preferencesWindowController release]; - [self.rssFeed release]; - - [super dealloc]; } + + @end diff --git a/src/ArrayExtensions.h b/src/ArrayExtensions.h index 3a83c005f2..1057be7704 100644 --- a/src/ArrayExtensions.h +++ b/src/ArrayExtensions.h @@ -22,5 +22,4 @@ @interface NSArray (ArrayExtensions) -(NSUInteger)indexOfStringInArray:(NSString *)theString; - +(NSArray *)arrayByExpandingAllArrayObjects:(id)id1, ...; @end diff --git a/src/ArrayExtensions.m b/src/ArrayExtensions.m index 657d23e158..55dbe2e98c 100644 --- a/src/ArrayExtensions.m +++ b/src/ArrayExtensions.m @@ -30,9 +30,9 @@ @implementation NSArray (ArrayExtensions) -(NSUInteger)indexOfStringInArray:(NSString *)theString { NSUInteger index = 0; - while (index < [self count]) + while (index < self.count) { - NSString * aString = [self objectAtIndex:index]; + NSString * aString = self[index]; NSAssert([aString isKindOfClass:[NSString class]], @"Not an NSString object in the array!"); if ([aString isEqualToString:theString]) return index; @@ -41,31 +41,4 @@ -(NSUInteger)indexOfStringInArray:(NSString *)theString return NSNotFound; } -/* arrayByExpandingAllArrayObjects - * Creates and returns an array containing all the objects in the list but also expanding - * any NSArray objects. Note that the expansion is NOT recursive - any arrays in the - * nested NSArray will not be expanded. Instead this function should be called on the - * nested arrays to expand those if desired. - */ -+(NSArray *)arrayByExpandingAllArrayObjects:(id)id1, ... -{ - NSMutableArray * newArray = [NSMutableArray arrayWithObject:id1]; - va_list arguments; - id obj; - - va_start(arguments, id1); - while ((obj = (id)va_arg(arguments, NSUInteger)) != 0) - { - if ([obj isKindOfClass:[NSArray class]]) - { - id innerObj; - - for (innerObj in obj) - [newArray addObject:innerObj]; - continue; - } - [newArray addObject:obj]; - } - return newArray; -} @end diff --git a/src/ArticleBaseView.h b/src/ArticleBaseView.h index f1822f483b..0ae28a0ddb 100644 --- a/src/ArticleBaseView.h +++ b/src/ArticleBaseView.h @@ -22,16 +22,14 @@ @class Article; @protocol ArticleBaseView - -(void)selectFolderWithFilter:(int)newFolderId; - -(void)selectFolderAndArticle:(int)folderId guid:(NSString *)guid; - -(void)refreshFolder:(int)refreshFlag; - -(Article *)selectedArticle; - -(NSArray *)markedArticleRange; + -(BOOL)selectFirstUnreadInFolder; + -(BOOL)viewNextUnreadInFolder; + -(void)scrollToArticle:(NSString *)guid; + -(void)refreshFolder:(NSInteger)refreshFlag; + @property (nonatomic, readonly, strong) Article *selectedArticle; + @property (nonatomic, readonly, copy) NSArray *markedArticleRange; -(void)saveTableSettings; - -(void)ensureSelectedArticle:(BOOL)singleSelection; - -(void)displayFirstUnread; - -(void)displayNextUnread; - -(void)refreshCurrentFolder; - -(void)handleRefreshArticle:(NSNotification *)nc; - -(void)refreshArticlePane; + -(void)ensureSelectedArticle; + -(void)startLoadIndicator; + -(void)stopLoadIndicator; @end diff --git a/src/ArticleCellView.h b/src/ArticleCellView.h old mode 100755 new mode 100644 index be032e93d5..0feaac5ee8 --- a/src/ArticleCellView.h +++ b/src/ArticleCellView.h @@ -1,6 +1,5 @@ // // ArticleCellView.h -// PXListView // // Adapted from PXListView by Alex Rozanski // Modified by Barijaona Ramaholimihaso @@ -8,25 +7,23 @@ #import -#import "PXListViewCell.h" #import "ArticleView.h" -@interface ArticleCellView : PXListViewCell +@interface ArticleCellView : NSTableCellView { AppController * controller; - ArticleView *articleView; - NSProgressIndicator * progressIndicator; BOOL inProgress; - int folderId; + NSInteger folderId; NSUInteger articleRow; + NSTableView *__weak _listView; } -@property (assign,readonly)ArticleView *articleView; +@property (readonly, strong)ArticleView *articleView; +@property (readonly, strong)NSProgressIndicator * progressIndicator; @property BOOL inProgress; -@property int folderId; +@property NSInteger folderId; @property NSUInteger articleRow; +@property (nonatomic, weak) NSTableView *listView; -// Public functions --(id)initWithReusableIdentifier: (NSString*)identifier inFrame:(NSRect)frameRect; @end diff --git a/src/ArticleCellView.m b/src/ArticleCellView.m index 1bbed1c618..a533a10dab 100644 --- a/src/ArticleCellView.m +++ b/src/ArticleCellView.m @@ -1,6 +1,5 @@ // // ArticleCellView.m -// PXListView // // Adapted from PXListView by Alex Rozanski // Modified by Barijaona Ramaholimihaso @@ -9,45 +8,45 @@ #import "ArticleCellView.h" #import "AppController.h" #import "BrowserView.h" -#import "PXListView.h" -#import "PXListView+Private.h" #define PROGRESS_INDICATOR_LEFT_MARGIN 8 #define PROGRESS_INDICATOR_DIMENSION_REGULAR 24 -#define DEFAULT_CELL_HEIGHT 150 +#define DEFAULT_CELL_HEIGHT 300 #define XPOS_IN_CELL 6 #define YPOS_IN_CELL 2 @implementation ArticleCellView +@synthesize listView = _listView; @synthesize articleView; +@synthesize progressIndicator; @synthesize inProgress, folderId, articleRow; #pragma mark - #pragma mark Init/Dealloc --(id)initWithReusableIdentifier: (NSString*)identifier inFrame:(NSRect)frameRect +-(instancetype)initWithFrame:(NSRect)frameRect { - if((self = [super initWithReusableIdentifier:identifier])) + if((self = [super initWithFrame:frameRect])) { controller = APPCONTROLLER; articleView= [[ArticleView alloc] initWithFrame:frameRect]; // Make the list view the frame load and UI delegate for the web view - [articleView setUIDelegate:[[controller browserView] primaryTabItemView]]; - [articleView setFrameLoadDelegate:[[controller browserView] primaryTabItemView]]; + articleView.UIDelegate = [controller.browserView primaryTabItemView]; + articleView.frameLoadDelegate = [controller.browserView primaryTabItemView]; // Notify the list view when the article view has finished loading SEL loadFinishedSelector = NSSelectorFromString(@"webViewLoadFinished:"); - [[NSNotificationCenter defaultCenter] addObserver:[[controller browserView] primaryTabItemView] selector:loadFinishedSelector name:WebViewProgressFinishedNotification object:articleView]; + [[NSNotificationCenter defaultCenter] addObserver:[controller.browserView primaryTabItemView] selector:loadFinishedSelector name:WebViewProgressFinishedNotification object:articleView]; [articleView setOpenLinksInNewBrowser:YES]; [articleView setController:controller]; - [[[articleView mainFrame] frameView] setAllowsScrolling:NO]; + [articleView.mainFrame.frameView setAllowsScrolling:NO]; // Make web preferences 16pt Arial to match Safari - [[articleView preferences] setStandardFontFamily:@"Arial"]; - [[articleView preferences] setDefaultFontSize:16]; + articleView.preferences.standardFontFamily = @"Arial"; + articleView.preferences.defaultFontSize = 16; // Enable caching - [[articleView preferences] setUsesPageCache:YES]; + [articleView.preferences setUsesPageCache:YES]; [articleView setMaintainsBackForwardList:NO]; [self setInProgress:NO]; progressIndicator = nil; @@ -57,50 +56,11 @@ -(id)initWithReusableIdentifier: (NSString*)identifier inFrame:(NSRect)frameRect -(void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:[[controller browserView] primaryTabItemView] name:WebViewProgressFinishedNotification object:articleView]; + [[NSNotificationCenter defaultCenter] removeObserver:[controller.browserView primaryTabItemView] name:WebViewProgressFinishedNotification object:articleView]; [articleView setUIDelegate:nil]; [articleView setFrameLoadDelegate:nil]; [articleView stopLoading:self]; - [articleView release], articleView=nil; - [progressIndicator release], progressIndicator=nil; - [super dealloc]; -} - -#pragma mark - -#pragma mark Reusing Cells - -- (void)prepareForReuse -{ - //calculate the frame - NSRect newWebViewRect = NSMakeRect(XPOS_IN_CELL, - YPOS_IN_CELL, - NSWidth([self frame]) - XPOS_IN_CELL, - DEFAULT_CELL_HEIGHT); - //set the new frame to the webview - [articleView stopLoading:self]; - [articleView setFrame:newWebViewRect]; - [self setInProgress:YES]; - [articleView clearHTML]; - [super prepareForReuse]; -} - -#pragma mark - -#pragma mark Interaction - -/* menuForEvent - * Called when the popup menu is opened on the table. - * We ensure that the item under the cursor is selected. - * Handle menu by moving the selection. - */ --(NSMenu *)menuForEvent:(NSEvent *)theEvent -{ - NSUInteger row = [self row]; - PXListView *listView = [self listView]; - NSUInteger currentSelectedRow = [listView selectedRow]; - if (row != currentSelectedRow) - [listView selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO]; - return ([[listView selectedRows] count] > 0 ? [self menu] : nil); } #pragma mark - @@ -109,34 +69,35 @@ -(NSMenu *)menuForEvent:(NSEvent *)theEvent -(void)drawRect:(NSRect)dirtyRect { [super drawRect:dirtyRect]; - if([self isSelected]) { + if([self.listView.selectedRowIndexes containsIndex:articleRow]) { [[NSColor selectedControlColor] set]; } else { [[NSColor controlColor] set]; } + [self layoutSubviews]; //Draw the border and background - NSBezierPath *roundedRect = [NSBezierPath bezierPathWithRect:[self bounds]]; + NSBezierPath *roundedRect = [NSBezierPath bezierPathWithRect:self.bounds]; [roundedRect fill]; //Progress indicator - if ([self inProgress]) + if (self.inProgress) { if (!progressIndicator) { // Allocate and initialize the spinning progress indicator. - NSRect progressRect = NSMakeRect(PROGRESS_INDICATOR_LEFT_MARGIN, NSHeight([self bounds]) - PROGRESS_INDICATOR_DIMENSION_REGULAR, + NSRect progressRect = NSMakeRect(PROGRESS_INDICATOR_LEFT_MARGIN, NSHeight(self.bounds) - PROGRESS_INDICATOR_DIMENSION_REGULAR, PROGRESS_INDICATOR_DIMENSION_REGULAR, PROGRESS_INDICATOR_DIMENSION_REGULAR); progressIndicator = [[NSProgressIndicator alloc] initWithFrame:progressRect]; - [progressIndicator setControlSize:NSRegularControlSize]; - [progressIndicator setStyle:NSProgressIndicatorSpinningStyle]; + progressIndicator.controlSize = NSRegularControlSize; + progressIndicator.style = NSProgressIndicatorSpinningStyle; [progressIndicator setDisplayedWhenStopped:NO]; } // Add the progress indicator as a subview of the cell if // it is not already one. - if ([progressIndicator superview] != self) + if (progressIndicator.superview != self) [self addSubview:progressIndicator]; // Start the animation. @@ -146,11 +107,10 @@ -(void)drawRect:(NSRect)dirtyRect { // Stop the animation and remove from the superview. [progressIndicator stopAnimation:self]; - [[progressIndicator superview] setNeedsDisplayInRect:[progressIndicator frame]]; + [progressIndicator.superview setNeedsDisplayInRect:progressIndicator.frame]; [progressIndicator removeFromSuperviewWithoutNeedingDisplay]; // Release the progress indicator. - [progressIndicator release]; progressIndicator = nil; } @@ -161,11 +121,10 @@ -(void)layoutSubviews //calculate the new frame NSRect newWebViewRect = NSMakeRect(XPOS_IN_CELL, YPOS_IN_CELL, - NSWidth([self frame]) - XPOS_IN_CELL, - NSHeight([self frame]) -YPOS_IN_CELL); + NSWidth(self.frame) - XPOS_IN_CELL, + NSHeight(self.frame) -YPOS_IN_CELL); //set the new frame to the webview - [articleView setFrame:newWebViewRect]; - [super layoutSubviews]; + articleView.frame = newWebViewRect; } - (BOOL)acceptsFirstResponder @@ -173,29 +132,6 @@ - (BOOL)acceptsFirstResponder return NO; }; -/* keyDown - * Here is where we handle special keys when this view - * has the focus so we can do custom things. - */ --(void)keyDown:(NSEvent *)theEvent -{ - [[[self listView] superview] keyDown:theEvent]; -} - -/* canMakeTextSmaller - */ --(IBAction)canMakeTextSmaller -{ - [articleView canMakeTextSmaller]; -} - -/* canMakeTextLarger - */ --(IBAction)canMakeTextLarger -{ - [articleView canMakeTextLarger]; -} - /* makeTextSmaller * Make webview text size smaller */ diff --git a/src/ArticleController.h b/src/ArticleController.h index 6e71f6abe9..a9dad9bda4 100644 --- a/src/ArticleController.h +++ b/src/ArticleController.h @@ -20,10 +20,12 @@ #import #import "FoldersTree.h" -#import "BacktrackArray.h" +#import "BackTrackArray.h" #import "BaseView.h" #import "ArticleBaseView.h" #import "ArticleView.h" +#import "ArticleListView.h" +#import "UnifiedDisplayView.h" /* ArticleController * The ArticleController contains the controlling logic for the article view that is @@ -37,56 +39,65 @@ { FoldersTree * foldersTree; + IBOutlet ArticleListView * articleListView; + IBOutlet UnifiedDisplayView * unifiedListView; NSView * mainArticleView; NSArray * currentArrayOfArticles; NSArray * folderArrayOfArticles; - int currentFolderId; + NSInteger currentFolderId; NSDictionary * articleSortSpecifiers; NSString * sortColumnIdentifier; BackTrackArray * backtrackArray; BOOL isBacktracking; + BOOL shouldPreserveSelectedArticle; Article * articleToPreserve; + NSString * guidOfArticleToSelect; + BOOL firstUnreadArticleRequired; + dispatch_queue_t queue; + NSInteger reloadArrayOfArticlesSemaphor; + BOOL requireSelectArticleAfterReload; } -@property (nonatomic, retain) IBOutlet FoldersTree * foldersTree; -@property (nonatomic, retain) NSView * mainArticleView; +@property (nonatomic, strong) IBOutlet FoldersTree * foldersTree; +@property (nonatomic, strong) NSView * mainArticleView; @property (nonatomic, copy) NSArray * currentArrayOfArticles; @property (nonatomic, copy) NSArray * folderArrayOfArticles; -@property (nonatomic, assign) NSDictionary * articleSortSpecifiers; -@property (nonatomic, assign) BackTrackArray * backtrackArray; +@property (nonatomic) NSDictionary * articleSortSpecifiers; +@property (nonatomic) BackTrackArray * backtrackArray; // Public functions -(NSView *)mainArticleView; --(void)setMainArticleView:(NSView *)newView; --(int)currentFolderId; --(Article *)selectedArticle; --(NSArray *)markedArticleRange; +-(void)setLayout:(NSInteger)newLayout; +@property (nonatomic, readonly) NSInteger currentFolderId; +@property (nonatomic, readonly, strong) Article *selectedArticle; +@property (nonatomic, readonly, copy) NSArray *markedArticleRange; +-(void)updateAlternateMenuTitle; +-(void)updateVisibleColumns; -(void)saveTableSettings; -(void)sortArticles; --(NSArray *)allArticles; +@property (nonatomic, readonly, copy) NSArray *allArticles; -(void)displayFirstUnread; -(void)displayNextUnread; --(NSString *)searchPlaceholderString; +-(void)displayNextFolderWithUnread; +@property (nonatomic, readonly, copy) NSString *searchPlaceholderString; -(void)reloadArrayOfArticles; --(void)refreshCurrentFolder; --(void)displayFolder:(int)newFolderId; +-(void)displayFolder:(NSInteger)newFolderId; -(void)refilterArrayOfArticles; --(NSString *)sortColumnIdentifier; --(BOOL)sortIsAscending; --(void)ensureSelectedArticle:(BOOL)singleSelection; +@property (nonatomic, readonly, copy) NSString *sortColumnIdentifier; +@property (nonatomic, readonly) BOOL sortIsAscending; +-(void)ensureSelectedArticle; -(void)sortByIdentifier:(NSString *)columnName; -(void)sortAscending:(BOOL)newAscending; --(BOOL)currentCacheContainsFolder:(int)folderId; -(void)deleteArticlesByArray:(NSArray *)articleArray; -(void)markReadByArray:(NSArray *)articleArray readFlag:(BOOL)readFlag; -(void)markAllReadByReferencesArray:(NSArray *)refArray readFlag:(BOOL)readFlag; --(void)markAllReadByArray:(NSArray *)folderArray withUndo:(BOOL)undoFlag withRefresh:(BOOL)refreshFlag; +-(void)markAllFoldersReadByArray:(NSArray *)folderArray; -(void)markDeletedByArray:(NSArray *)articleArray deleteFlag:(BOOL)deleteFlag; -(void)markFlaggedByArray:(NSArray *)articleArray flagged:(BOOL)flagged; +-(void)selectFolderAndArticle:(NSInteger)folderId guid:(NSString *)guid; -(void)addBacktrack:(NSString *)guid; -(void)goForward; -(void)goBack; --(BOOL)canGoForward; --(BOOL)canGoBack; --(void)setArticleToPreserve:(Article *)article; +@property (nonatomic, readonly) BOOL canGoForward; +@property (nonatomic, readonly) BOOL canGoBack; @end diff --git a/src/ArticleController.m b/src/ArticleController.m index 8f3308b325..b2ec382267 100644 --- a/src/ArticleController.m +++ b/src/ArticleController.m @@ -27,15 +27,8 @@ #import "ArticleRef.h" #import "StringExtensions.h" #import "GoogleReader.h" -#import "RefreshManager.h" - -// Private functions -@interface ArticleController (Private) - -(NSArray *)applyFilter:(NSArray *)unfilteredArray; - -(void)setSortColumnIdentifier:(NSString *)str; - -(NSArray *)wrappedMarkAllReadInArray:(NSArray *)folderArray withUndo:(BOOL)undoFlag; - -(void)innerMarkReadByArray:(NSArray *)articleArray readFlag:(BOOL)readFlag; -@end +#import "ArticleListView.h" +#import "UnifiedDisplayView.h" @implementation ArticleController @synthesize foldersTree, mainArticleView, currentArrayOfArticles, folderArrayOfArticles, articleSortSpecifiers, backtrackArray; @@ -43,103 +36,127 @@ @implementation ArticleController /* init * Initialise. */ --(id)init +-(instancetype)init { if ((self = [super init]) != nil) { isBacktracking = NO; currentFolderId = -1; articleToPreserve = nil; + guidOfArticleToSelect = nil; + firstUnreadArticleRequired = NO; // Set default values to generate article sort descriptors - articleSortSpecifiers = [[NSDictionary alloc] initWithObjectsAndKeys: - [NSDictionary dictionaryWithObjectsAndKeys: - @"containingFolder.name", @"key", - @"compare:", @"selector", - nil], MA_Field_Folder, - [NSDictionary dictionaryWithObjectsAndKeys: - @"isRead", @"key", - @"compare:", @"selector", - nil], MA_Field_Read, - [NSDictionary dictionaryWithObjectsAndKeys: - @"isFlagged", @"key", - @"compare:", @"selector", - nil], MA_Field_Flagged, - [NSDictionary dictionaryWithObjectsAndKeys: - @"hasComments", @"key", - @"compare:", @"selector", - nil], MA_Field_Comments, - [NSDictionary dictionaryWithObjectsAndKeys: - [@"articleData." stringByAppendingString:MA_Field_Date], @"key", - @"compare:", @"selector", - nil], MA_Field_Date, - [NSDictionary dictionaryWithObjectsAndKeys: - [@"articleData." stringByAppendingString:MA_Field_Author], @"key", - @"caseInsensitiveCompare:", @"selector", - nil], MA_Field_Author, - [NSDictionary dictionaryWithObjectsAndKeys: - [@"articleData." stringByAppendingString:MA_Field_Subject], @"key", - @"numericCompare:", @"selector", - nil], MA_Field_Headlines, - [NSDictionary dictionaryWithObjectsAndKeys: - [@"articleData." stringByAppendingString:MA_Field_Subject], @"key", - @"numericCompare:", @"selector", - nil], MA_Field_Subject, - [NSDictionary dictionaryWithObjectsAndKeys: - [@"articleData." stringByAppendingString:MA_Field_Link], @"key", - @"caseInsensitiveCompare:", @"selector", - nil], MA_Field_Link, - [NSDictionary dictionaryWithObjectsAndKeys: - [@"articleData." stringByAppendingString:MA_Field_Summary], @"key", - @"caseInsensitiveCompare:", @"selector", - nil], MA_Field_Summary, - [NSDictionary dictionaryWithObjectsAndKeys: - @"hasEnclosure", @"key", - @"compare:", @"selector", - nil], MA_Field_HasEnclosure, - [NSDictionary dictionaryWithObjectsAndKeys: - @"enclosure", @"key", - @"caseInsensitiveCompare:", @"selector", - nil], MA_Field_Enclosure, - nil]; + articleSortSpecifiers = @{ + MA_Field_Folder: @{ + @"key": @"containingFolder.name", + @"selector": @"compare:" + }, + MA_Field_Read: @{ + @"key": @"isRead", + @"selector": @"compare:" + }, + MA_Field_Flagged: @{ + @"key": @"isFlagged", + @"selector": @"compare:" + }, + MA_Field_Comments: @{ + @"key": @"hasComments", + @"selector": @"compare:" + }, + MA_Field_Date: @{ + @"key": [@"articleData." stringByAppendingString:MA_Field_Date], + @"selector": @"compare:" + }, + MA_Field_Author: @{ + @"key": [@"articleData." stringByAppendingString:MA_Field_Author], + @"selector": @"caseInsensitiveCompare:" + }, + MA_Field_Headlines: @{ + @"key": [@"articleData." stringByAppendingString:MA_Field_Subject], + @"selector": @"numericCompare:" + }, + MA_Field_Subject: @{ + @"key": [@"articleData." stringByAppendingString:MA_Field_Subject], + @"selector": @"numericCompare:" + }, + MA_Field_Link: @{ + @"key": [@"articleData." stringByAppendingString:MA_Field_Link], + @"selector": @"caseInsensitiveCompare:" + }, + MA_Field_Summary: @{ + @"key": [@"articleData." stringByAppendingString:MA_Field_Summary], + @"selector": @"caseInsensitiveCompare:" + }, + MA_Field_HasEnclosure: @{ + @"key": @"hasEnclosure", + @"selector": @"compare:" + }, + MA_Field_Enclosure: @{ + @"key": @"enclosure", + @"selector": @"caseInsensitiveCompare:" + }, + }; // Pre-set sort to what was saved in the preferences Preferences * prefs = [Preferences standardPreferences]; - NSArray * sortDescriptors = [prefs articleSortDescriptors]; - if ([sortDescriptors count] == 0) + NSArray * sortDescriptors = prefs.articleSortDescriptors; + if (sortDescriptors.count == 0) { - NSSortDescriptor * descriptor = [[[NSSortDescriptor alloc] initWithKey:[@"articleData." stringByAppendingString:MA_Field_Date] ascending:YES] autorelease]; - [prefs setArticleSortDescriptors:[NSArray arrayWithObject:descriptor]]; + NSSortDescriptor * descriptor = [[NSSortDescriptor alloc] initWithKey:[@"articleData." stringByAppendingString:MA_Field_Date] ascending:YES]; + prefs.articleSortDescriptors = @[descriptor]; [prefs setObject:MA_Field_Date forKey:MAPref_SortColumn]; } [self setSortColumnIdentifier:[prefs stringForKey:MAPref_SortColumn]]; // Create a backtrack array - backtrackArray = [[BackTrackArray alloc] initWithMaximum:[prefs backTrackQueueSize]]; + backtrackArray = [[BackTrackArray alloc] initWithMaximum:prefs.backTrackQueueSize]; // Register for notifications NSNotificationCenter * nc = [NSNotificationCenter defaultCenter]; [nc addObserver:self selector:@selector(handleFilterChange:) name:@"MA_Notify_FilteringChange" object:nil]; - [nc addObserver:self selector:@selector(handleFolderNameChange:) name:@"MA_Notify_FolderNameChanged" object:nil]; - [nc addObserver:self selector:@selector(handleFolderUpdate:) name:@"MA_Notify_FoldersUpdated" object:nil]; - [nc addObserver:self selector:@selector(handleFolderAdded:) name:@"MA_Notify_FolderAdded" object:nil]; - [nc addObserver:self selector:@selector(handleRefreshArticle:) name:@"MA_Notify_ArticleViewChange" object:nil]; - + [nc addObserver:self selector:@selector(handleArticleListContentChange:) name:@"MA_Notify_ArticleListContentChange" object:nil]; + [nc addObserver:self selector:@selector(handleArticleListStateChange:) name:@"MA_Notify_ArticleListStateChange" object:nil]; + + queue = dispatch_queue_create("uk.co.opencommunity.vienna2.displayRefresh", DISPATCH_QUEUE_SERIAL); + reloadArrayOfArticlesSemaphor = 0; + requireSelectArticleAfterReload = NO; } return self; } -/* refreshCurrentFolder +/* setLayout + * Changes the layout of the panes. */ --(void)refreshCurrentFolder +-(void)setLayout:(NSInteger)newLayout { - [mainArticleView refreshCurrentFolder]; -} + Article * currentSelectedArticle = self.selectedArticle; + switch (newLayout) + { + case MA_Layout_Report: + case MA_Layout_Condensed: + self.mainArticleView = articleListView; + break; + + case MA_Layout_Unified: + self.mainArticleView = unifiedListView; + break; + } + + [Preferences standardPreferences].layout = newLayout; + if (currentSelectedArticle != nil) + { + [self selectFolderAndArticle:currentFolderId guid:currentSelectedArticle.guid]; + [self ensureSelectedArticle]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_ArticleViewChange" object:nil]; + } + +} /* currentFolderId * Returns the ID of the current folder being displayed by the view. */ --(int)currentFolderId +-(NSInteger)currentFolderId { return currentFolderId; } @@ -150,7 +167,7 @@ -(int)currentFolderId */ -(NSArray *)markedArticleRange { - return [mainArticleView markedArticleRange]; + return mainArticleView.markedArticleRange; } /* saveTableSettings @@ -162,12 +179,36 @@ -(void)saveTableSettings [mainArticleView saveTableSettings]; } +/* updateAlternateMenuTitle + * Sets the approprate title for the alternate item in the contextual menu + */ + -(void)updateAlternateMenuTitle +{ + if (mainArticleView == articleListView) + { + [articleListView updateAlternateMenuTitle]; + } + else + { + [unifiedListView updateAlternateMenuTitle]; + } +} + +/* updateVisibleColumns + * For relevant layouts, adapt table settings + */ +-(void)updateVisibleColumns +{ + if (mainArticleView == articleListView) + [articleListView updateVisibleColumns]; +} + /* selectedArticle * Returns the currently selected article from the article list. */ -(Article *)selectedArticle { - return [mainArticleView selectedArticle]; + return mainArticleView.selectedArticle; } /* allArticles @@ -182,9 +223,13 @@ -(NSArray *)allArticles * Ensures that an article is selected in the list and that any selected * article is scrolled into view. */ --(void)ensureSelectedArticle:(BOOL)singleSelection +-(void)ensureSelectedArticle { - [mainArticleView ensureSelectedArticle:singleSelection]; + if (reloadArrayOfArticlesSemaphor <= 0) { + [mainArticleView ensureSelectedArticle]; + } else { + requireSelectArticleAfterReload = YES; + } } /* searchPlaceholderString @@ -195,8 +240,8 @@ -(NSString *)searchPlaceholderString if (currentFolderId == -1) return @""; - Folder * folder = [[Database sharedDatabase] folderFromID:currentFolderId]; - return [NSString stringWithFormat:NSLocalizedString(@"Search in %@", nil), [folder name]]; + Folder * folder = [[Database sharedManager] folderFromID:currentFolderId]; + return [NSString stringWithFormat:NSLocalizedString(@"Search in %@", nil), folder.name]; } /* sortColumnIdentifier @@ -212,8 +257,6 @@ -(NSString *)sortColumnIdentifier */ -(void)setSortColumnIdentifier:(NSString *)str { - [str retain]; - [sortColumnIdentifier release]; sortColumnIdentifier = str; } @@ -223,10 +266,10 @@ -(void)setSortColumnIdentifier:(NSString *)str -(void)sortByIdentifier:(NSString *)columnName { Preferences * prefs = [Preferences standardPreferences]; - NSMutableArray * descriptors = [NSMutableArray arrayWithArray:[prefs articleSortDescriptors]]; + NSMutableArray * descriptors = [NSMutableArray arrayWithArray:prefs.articleSortDescriptors]; if ([sortColumnIdentifier isEqualToString:columnName]) - [descriptors replaceObjectAtIndex:0 withObject:[[descriptors objectAtIndex:0] reversedSortDescriptor]]; + descriptors[0] = [descriptors[0] reversedSortDescriptor]; else { [self setSortColumnIdentifier:columnName]; @@ -239,13 +282,12 @@ -(void)sortByIdentifier:(NSString *)columnName sortDescriptor = [[NSSortDescriptor alloc] initWithKey:[specifier valueForKey:@"key"] ascending:YES selector:NSSelectorFromString([specifier valueForKey:@"selector"])]; else { - sortDescriptor = [[descriptors objectAtIndex:index] retain]; + sortDescriptor = descriptors[index]; [descriptors removeObjectAtIndex:index]; } [descriptors insertObject:sortDescriptor atIndex:0]; - [sortDescriptor release]; } - [prefs setArticleSortDescriptors:descriptors]; + prefs.articleSortDescriptors = descriptors; [mainArticleView refreshFolder:MA_Refresh_SortAndRedraw]; } @@ -255,9 +297,9 @@ -(void)sortByIdentifier:(NSString *)columnName -(BOOL)sortIsAscending { Preferences * prefs = [Preferences standardPreferences]; - NSMutableArray * descriptors = [NSMutableArray arrayWithArray:[prefs articleSortDescriptors]]; - NSSortDescriptor * sortDescriptor = [descriptors objectAtIndex:0]; - BOOL ascending = [sortDescriptor ascending]; + NSMutableArray * descriptors = [NSMutableArray arrayWithArray:prefs.articleSortDescriptors]; + NSSortDescriptor * sortDescriptor = descriptors[0]; + BOOL ascending = sortDescriptor.ascending; return ascending; } @@ -268,14 +310,14 @@ -(BOOL)sortIsAscending -(void)sortAscending:(BOOL)newAscending { Preferences * prefs = [Preferences standardPreferences]; - NSMutableArray * descriptors = [NSMutableArray arrayWithArray:[prefs articleSortDescriptors]]; - NSSortDescriptor * sortDescriptor = [descriptors objectAtIndex:0]; + NSMutableArray * descriptors = [NSMutableArray arrayWithArray:prefs.articleSortDescriptors]; + NSSortDescriptor * sortDescriptor = descriptors[0]; - BOOL existingAscending = [sortDescriptor ascending]; + BOOL existingAscending = sortDescriptor.ascending; if ( newAscending != existingAscending ) { - [descriptors replaceObjectAtIndex:0 withObject:[sortDescriptor reversedSortDescriptor]]; - [prefs setArticleSortDescriptors:descriptors]; + descriptors[0] = sortDescriptor.reversedSortDescriptor; + prefs.articleSortDescriptors = descriptors; [mainArticleView refreshFolder:MA_Refresh_SortAndRedraw]; } } @@ -287,9 +329,9 @@ -(void)sortArticles { NSArray * sortedArrayOfArticles; - sortedArrayOfArticles = [currentArrayOfArticles sortedArrayUsingDescriptors:[[Preferences standardPreferences] articleSortDescriptors]]; + sortedArrayOfArticles = [currentArrayOfArticles sortedArrayUsingDescriptors:[Preferences standardPreferences].articleSortDescriptors]; NSAssert([sortedArrayOfArticles count] == [currentArrayOfArticles count], @"Lost articles from currentArrayOfArticles during sort"); - [self setCurrentArrayOfArticles:sortedArrayOfArticles]; + self.currentArrayOfArticles = sortedArrayOfArticles; } /* displayFirstUnread @@ -298,7 +340,31 @@ -(void)sortArticles */ -(void)displayFirstUnread { - [mainArticleView displayFirstUnread]; + // mark current article read + Article * currentArticle = self.selectedArticle; + if (currentArticle != nil && !currentArticle.read) + { + [self markReadByArray:@[currentArticle] readFlag:YES]; + } + + // If there are any unread articles then select the first one in the + // first folder. + if ([Database sharedManager].countOfUnread > 0) + { + // Get the first folder with unread articles. + NSInteger firstFolderWithUnread = foldersTree.firstFolderWithUnread; + if (firstFolderWithUnread == currentFolderId) + { + [mainArticleView selectFirstUnreadInFolder]; + } + else + { + // Seed in order to select the first unread article. + firstUnreadArticleRequired = YES; + // Select the folder in the tree view. + [foldersTree selectFolder:firstFolderWithUnread]; + } + } } /* displayNextUnread @@ -307,22 +373,93 @@ -(void)displayFirstUnread */ -(void)displayNextUnread { - [mainArticleView displayNextUnread]; + // mark current article read + Article * currentArticle = self.selectedArticle; + if (currentArticle != nil && !currentArticle.read) + { + [self markReadByArray:@[currentArticle] readFlag:YES]; + } + + // If there are any unread articles then select the nexst one + if ([Database sharedManager].countOfUnread > 0) + { + // Search other articles in the same folder, starting from current position + if (![mainArticleView viewNextUnreadInFolder]) + { + // If nothing found and smart folder, search if we have other fresh articles from same folder + Folder * currentFolder = [[Database sharedManager] folderFromID:currentFolderId]; + if (IsSmartFolder(currentFolder) || IsTrashFolder(currentFolder) || IsSearchFolder(currentFolder)) + { + if (![mainArticleView selectFirstUnreadInFolder]) + { + [self displayNextFolderWithUnread]; + } + } + else + { + [self displayNextFolderWithUnread]; + } + } + } +} + +/* displayNextFolderWithUnread + * Instructs the current article view to display the next folder with unread articles + * in the database. + */ +-(void)displayNextFolderWithUnread +{ + NSInteger nextFolderWithUnread = [foldersTree nextFolderWithUnread:currentFolderId]; + if (nextFolderWithUnread != -1) + { + // Seed in order to select the first unread article. + firstUnreadArticleRequired = YES; + [foldersTree selectFolder:nextFolderWithUnread]; + } } /* displayFolder + * This is called after notification of folder selection change * Call the current article view to display the specified folder if it * is different from the current one. */ --(void)displayFolder:(int)newFolderId +-(void)displayFolder:(NSInteger)newFolderId { if (currentFolderId != newFolderId && newFolderId != 0) { - [[[Database sharedDatabase] folderFromID:currentFolderId] clearCache]; + // Clear all of the articles in the current folder. + // This will reset the scroller position and deselect all. + // Otherwise, the new folder might attempt to preserve selection. + // This can happen with smart folders, which have the same articles as other folders. + currentArrayOfArticles = @[]; + folderArrayOfArticles = @[]; + [mainArticleView refreshFolder:MA_Refresh_RedrawList]; + currentFolderId = newFolderId; [self reloadArrayOfArticles]; - [self sortArticles]; - [mainArticleView selectFolderWithFilter:newFolderId]; + } + +} + +/* selectFolderAndArticle + * Select a folder and select a specified article within the folder. + */ +-(void)selectFolderAndArticle:(NSInteger)folderId guid:(NSString *)guid +{ + // If we're in the right folder, select the article + if (folderId == currentFolderId) + { + if (guid != nil) { + [mainArticleView scrollToArticle:guid]; + } + } + else + { + // We seed guidOfArticleToSelect so that + // after notification of folder selection change has been processed, + // it will select the requisite article on our behalf. + guidOfArticleToSelect = guid; + [foldersTree selectFolder:folderId]; } } @@ -332,11 +469,76 @@ -(void)displayFolder:(int)newFolderId */ -(void)reloadArrayOfArticles { - - Folder * folder = [[Database sharedDatabase] folderFromID:currentFolderId]; - [self setFolderArrayOfArticles:[folder articlesWithFilter:[APPCONTROLLER filterString]]]; - - [self refilterArrayOfArticles]; + reloadArrayOfArticlesSemaphor++; + [mainArticleView startLoadIndicator]; + + [self getArticlesWithCompletionBlock:^(NSArray *resultArray) { + // when multiple refreshes where queued, we update folderArrayOfArticles only once + reloadArrayOfArticlesSemaphor--; + if (reloadArrayOfArticlesSemaphor <=0) + { + [mainArticleView stopLoadIndicator]; + self.folderArrayOfArticles = resultArray; + Article * article = self.selectedArticle; + + if (shouldPreserveSelectedArticle) + { + if (article != nil && article.read && !article.deleted) + { + articleToPreserve = article; + } + shouldPreserveSelectedArticle = NO; + } + + [mainArticleView refreshFolder:MA_Refresh_ReapplyFilter]; + + if (guidOfArticleToSelect != nil ) + { + [mainArticleView scrollToArticle:guidOfArticleToSelect]; + guidOfArticleToSelect = nil; + } + else if (firstUnreadArticleRequired) + { + [mainArticleView selectFirstUnreadInFolder]; + firstUnreadArticleRequired = NO; + } + + if (requireSelectArticleAfterReload) + { + [self ensureSelectedArticle]; + requireSelectArticleAfterReload = NO; + } + + // To avoid upsetting the current displayed article after a refresh, + // we check to see if the selected article is the same + // and if it has been updated + Article * currentArticle = self.selectedArticle; + if ( currentArticle == article && + [[Preferences standardPreferences] boolForKey:MAPref_CheckForUpdatedArticles] + && currentArticle.revised && !currentArticle.read ) + { + [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_ArticleViewChange" object:nil]; + } + } + }]; +} + +/* getArticlesWithCompletionBlock + * Launch articlesWithFilter on background queue and perform completion block + */ +- (void)getArticlesWithCompletionBlock:(void(^)(NSArray * resultArray))completionBlock { + Folder * folder = [[Database sharedManager] folderFromID:currentFolderId]; + NSString *filterString = APPCONTROLLER.filterString; + dispatch_async(queue, ^{ + NSArray * articleArray = [folder articlesWithFilter:filterString]; + + // call the completion block with the result when finished + if (completionBlock) { + dispatch_async(dispatch_get_main_queue(), ^{ + completionBlock(articleArray); + }); + } + }); } /* refilterArrayOfArticles @@ -344,7 +546,7 @@ -(void)reloadArrayOfArticles */ -(void)refilterArrayOfArticles { - [self setCurrentArrayOfArticles:[self applyFilter:folderArrayOfArticles]]; + self.currentArrayOfArticles = [self applyFilter:folderArrayOfArticles]; } /* applyFilter @@ -355,40 +557,30 @@ -(NSArray *)applyFilter:(NSArray *)unfilteredArray { NSMutableArray * filteredArray = [NSMutableArray arrayWithArray:unfilteredArray]; - NSString * guidOfArticleToPreserve = (articleToPreserve != nil) ? [articleToPreserve guid] : @""; - int folderIdOfArticleToPreserve = [articleToPreserve folderId]; - - ArticleFilter * filter = [ArticleFilter filterByTag:[[Preferences standardPreferences] filterMode]]; - SEL comparator = [filter comparator]; - int count = [filteredArray count]; - int index; + NSString * guidOfArticleToPreserve = articleToPreserve.guid; - for (index = count - 1; index >= 0; --index) + ArticleFilter * filter = [ArticleFilter filterByTag:[Preferences standardPreferences].filterMode]; + SEL comparator = filter.comparator; + for (NSInteger index = filteredArray.count - 1; index >= 0; --index) { - Article * article = [filteredArray objectAtIndex:index]; - if (([article folderId] == folderIdOfArticleToPreserve) && [[article guid] isEqualToString:guidOfArticleToPreserve]) - guidOfArticleToPreserve = @""; + Article * article = filteredArray[index]; + if (guidOfArticleToPreserve != nil + && article.folderId == articleToPreserve.folderId + && [article.guid isEqualToString:guidOfArticleToPreserve]) + { + guidOfArticleToPreserve = nil; + } else if ((comparator != nil) && !((BOOL)(NSInteger)[ArticleFilter performSelector:comparator withObject:article])) [filteredArray removeObjectAtIndex:index]; } - if (![guidOfArticleToPreserve isEqualToString:@""]) + if (guidOfArticleToPreserve != nil) { - Article * articleToAdd = nil; - Folder * folder = [[Database sharedDatabase] folderFromID:folderIdOfArticleToPreserve]; - if (folder != nil) - { - [folder clearCache]; - [folder articles]; - articleToAdd = [folder articleFromGuid:guidOfArticleToPreserve]; - } - if (articleToAdd == nil) - articleToAdd = articleToPreserve; - [filteredArray addObject:articleToAdd]; + [filteredArray addObject:articleToPreserve]; } - [self setArticleToPreserve:nil]; + articleToPreserve = nil; - return filteredArray; + return [filteredArray copy]; } /* markDeletedUndo @@ -414,7 +606,7 @@ -(void)markUndeletedUndo:(id)anObject -(void)markDeletedByArray:(NSArray *)articleArray deleteFlag:(BOOL)deleteFlag { // Set up to undo this action - NSUndoManager * undoManager = [[NSApp mainWindow] undoManager]; + NSUndoManager * undoManager = NSApp.mainWindow.undoManager; SEL markDeletedUndoAction = deleteFlag ? @selector(markDeletedUndo:) : @selector(markUndeletedUndo:); [undoManager registerUndoWithTarget:self selector:markDeletedUndoAction object:articleArray]; [undoManager setActionName:NSLocalizedString(@"Delete", nil)]; @@ -422,31 +614,59 @@ -(void)markDeletedByArray:(NSArray *)articleArray deleteFlag:(BOOL)deleteFlag // We will make a new copy of currentArrayOfArticles and folderArrayOfArticles with the selected articles removed. NSMutableArray * currentArrayCopy = [NSMutableArray arrayWithArray:currentArrayOfArticles]; NSMutableArray * folderArrayCopy = [NSMutableArray arrayWithArray:folderArrayOfArticles]; - __block BOOL needFolderRedraw = NO; __block BOOL needReload = NO; + NSString * guidToSelect = nil; + + // if we mark deleted, mark also read and unflagged + if (deleteFlag) { + [self innerMarkReadByRefsArray:articleArray readFlag:YES]; + [self innerMarkFlaggedByArray:articleArray flagged:NO]; + + Article * firstArticle = articleArray.firstObject; + if (firstArticle != nil) // Should always be true + { + // We want to select the next non-deleted article + NSUInteger articleIndex = [currentArrayOfArticles indexOfObject:firstArticle]; + if (articleIndex != NSNotFound) + { + NSUInteger count = currentArrayOfArticles.count; + for (NSUInteger i = articleIndex + 1; i < count; ++i) + { + Article * nextArticle = [currentArrayOfArticles objectAtIndex:i]; + if (![articleArray containsObject:nextArticle]) + { + guidToSelect = nextArticle.guid; + break; + } + } + + // Otherwise, we want to select the previous article. + if (guidToSelect == nil && articleIndex > 0) + { + Article * nextArticle = [currentArrayOfArticles objectAtIndex:articleIndex - 1]; + guidToSelect = nextArticle.guid; + } + + // Deselect all now, select article after refresh + [mainArticleView scrollToArticle:nil]; + } + } + } + // Iterate over every selected article in the table and set the deleted // flag on the article while simultaneously removing it from our copies - Database * db = [Database sharedDatabase]; - [db doTransactionWithBlock:^(BOOL *rollback) { for (Article * theArticle in articleArray) { - NSInteger folderId = [theArticle folderId]; - if (![theArticle isRead]) { - needFolderRedraw = YES; - if (deleteFlag && IsGoogleReaderFolder([db folderFromID:folderId])) { - [[GoogleReader sharedManager] markRead:[theArticle guid] readFlag:YES]; - } - } - [db markArticleDeleted:folderId guid:[theArticle guid] isDeleted:deleteFlag]; + [[Database sharedManager] markArticleDeleted:theArticle isDeleted:deleteFlag]; if (![currentArrayOfArticles containsObject:theArticle]) needReload = YES; - else if (deleteFlag && (currentFolderId != [db trashFolderId])) + else if (deleteFlag && (currentFolderId != [Database sharedManager].trashFolderId)) { [currentArrayCopy removeObject:theArticle]; [folderArrayCopy removeObject:theArticle]; } - else if (!deleteFlag && (currentFolderId == [db trashFolderId])) + else if (!deleteFlag && (currentFolderId == [Database sharedManager].trashFolderId)) { [currentArrayCopy removeObject:theArticle]; [folderArrayCopy removeObject:theArticle]; @@ -454,26 +674,26 @@ -(void)markDeletedByArray:(NSArray *)articleArray deleteFlag:(BOOL)deleteFlag else needReload = YES; } - }]; //end transaction block - [self setCurrentArrayOfArticles:currentArrayCopy]; - [self setFolderArrayOfArticles:folderArrayCopy]; + + self.currentArrayOfArticles = currentArrayCopy; + self.folderArrayOfArticles = folderArrayCopy; if (needReload) - [mainArticleView refreshFolder:MA_Refresh_ReloadFromDatabase]; + [self reloadArrayOfArticles]; else { [mainArticleView refreshFolder:MA_Refresh_RedrawList]; - if ([currentArrayOfArticles count] > 0u) - [mainArticleView ensureSelectedArticle:YES]; + if (currentArrayOfArticles.count > 0u) + { + if (guidToSelect != nil) + { + [mainArticleView scrollToArticle:guidToSelect]; + } + [mainArticleView ensureSelectedArticle]; + } else - [[NSApp mainWindow] makeFirstResponder:[foldersTree mainView]]; - } - - // If any of the articles we deleted were unread then the - // folder's unread count just changed. - if (needFolderRedraw) - { - [foldersTree updateFolder:currentFolderId recurseToParents:YES]; - [APPCONTROLLER showUnreadCountOnApplicationIconAndWindowTitle]; + { + [NSApp.mainWindow makeFirstResponder:foldersTree.mainView]; + } } } @@ -485,47 +705,64 @@ -(void)deleteArticlesByArray:(NSArray *)articleArray // Make a new copy of currentArrayOfArticles and folderArrayOfArticles with the selected article removed. NSMutableArray * currentArrayCopy = [NSMutableArray arrayWithArray:currentArrayOfArticles]; NSMutableArray * folderArrayCopy = [NSMutableArray arrayWithArray:folderArrayOfArticles]; - __block BOOL needFolderRedraw = NO; + [self innerMarkReadByRefsArray:articleArray readFlag:YES]; + + NSString * guidToSelect = nil; + Article * firstArticle = articleArray.firstObject; + if (firstArticle != nil) // Should always be true + { + // We want to select the next non-deleted article + NSUInteger articleIndex = [currentArrayOfArticles indexOfObject:firstArticle]; + if (articleIndex != NSNotFound) + { + NSUInteger count = currentArrayOfArticles.count; + for (NSUInteger i = articleIndex + 1; i < count; ++i) + { + Article * nextArticle = [currentArrayOfArticles objectAtIndex:i]; + if (![articleArray containsObject:nextArticle]) + { + guidToSelect = nextArticle.guid; + break; + } + } + + // Otherwise, we want to select the previous article. + if (guidToSelect == nil && articleIndex > 0) + { + Article * nextArticle = [currentArrayOfArticles objectAtIndex:articleIndex - 1]; + guidToSelect = nextArticle.guid; + } + + // Deselect all now, select article after refresh + [mainArticleView scrollToArticle:nil]; + } + } + // Iterate over every selected article in the table and remove it from // the database. - Database * db = [Database sharedDatabase]; - - [db doTransactionWithBlock:^(BOOL *rollback) { for (Article * theArticle in articleArray) { - NSInteger folderId = [theArticle folderId]; - if (![theArticle isRead]) { - needFolderRedraw = YES; - if (IsGoogleReaderFolder([db folderFromID:folderId])) { - [[GoogleReader sharedManager] markRead:[theArticle guid] readFlag:YES]; - } - } - if ([db deleteArticle:folderId guid:[theArticle guid]]) + if ([[Database sharedManager] deleteArticle:theArticle]) { [currentArrayCopy removeObject:theArticle]; [folderArrayCopy removeObject:theArticle]; } } - }]; //end transaction block - [self setCurrentArrayOfArticles:currentArrayCopy]; - [self setFolderArrayOfArticles:folderArrayCopy]; + self.currentArrayOfArticles = currentArrayCopy; + self.folderArrayOfArticles = folderArrayCopy; [mainArticleView refreshFolder:MA_Refresh_RedrawList]; - // If any of the articles we deleted were unread then the - // folder's unread count just changed. - if (needFolderRedraw) - [foldersTree updateFolder:currentFolderId recurseToParents:YES]; - // Ensure there's a valid selection - if ([currentArrayOfArticles count] > 0u) - [mainArticleView ensureSelectedArticle:YES]; - else - [[NSApp mainWindow] makeFirstResponder:[foldersTree mainView]]; - - // Read and/or unread count may have changed - if (needFolderRedraw) - [APPCONTROLLER showUnreadCountOnApplicationIconAndWindowTitle]; + if (currentArrayOfArticles.count > 0u) { + if (guidToSelect != nil) + { + [mainArticleView scrollToArticle:guidToSelect]; + } + [mainArticleView ensureSelectedArticle]; + } else { + [NSApp.mainWindow makeFirstResponder:foldersTree.mainView]; + } } /* markUnflagUndo @@ -548,27 +785,33 @@ -(void)markFlagUndo:(id)anObject * Mark the specified articles in articleArray as flagged. */ -(void)markFlaggedByArray:(NSArray *)articleArray flagged:(BOOL)flagged -{ - Database * db = [Database sharedDatabase]; - +{ // Set up to undo this action - NSUndoManager * undoManager = [[NSApp mainWindow] undoManager]; + NSUndoManager * undoManager = NSApp.mainWindow.undoManager; SEL markFlagUndoAction = flagged ? @selector(markUnflagUndo:) : @selector(markFlagUndo:); [undoManager registerUndoWithTarget:self selector:markFlagUndoAction object:articleArray]; [undoManager setActionName:NSLocalizedString(@"Flag", nil)]; - [db doTransactionWithBlock:^(BOOL *rollback) { + [self innerMarkFlaggedByArray:articleArray flagged:flagged]; + [mainArticleView refreshFolder:MA_Refresh_RedrawList]; +} + +/* innerMarkFlaggedByArray + * Marks all articles in the specified array flagged or unflagged. + */ +-(void)innerMarkFlaggedByArray:(NSArray *)articleArray flagged:(BOOL)flagged +{ for (Article * theArticle in articleArray) { - Folder *myFolder = [db folderFromID:[theArticle folderId]]; + Folder *myFolder = [[Database sharedManager] folderFromID:theArticle.folderId]; if (IsGoogleReaderFolder(myFolder)) { - [[GoogleReader sharedManager] markStarred:[theArticle guid] starredFlag:flagged]; + [[GoogleReader sharedManager] markStarred:theArticle starredFlag:flagged]; } - [db markArticleFlagged:[theArticle folderId] guid:[theArticle guid] isFlagged:flagged]; + [[Database sharedManager] markArticleFlagged:theArticle.folderId + guid:theArticle.guid + isFlagged:flagged]; [theArticle markFlagged:flagged]; } - }]; //end transaction block - [mainArticleView refreshFolder:MA_Refresh_RedrawList]; } /* markUnreadUndo @@ -593,20 +836,14 @@ -(void)markReadUndo:(id)anObject -(void)markReadByArray:(NSArray *)articleArray readFlag:(BOOL)readFlag { // Set up to undo this action - NSUndoManager * undoManager = [[NSApp mainWindow] undoManager]; + NSUndoManager * undoManager = NSApp.mainWindow.undoManager; SEL markReadUndoAction = readFlag ? @selector(markUnreadUndo:) : @selector(markReadUndo:); [undoManager registerUndoWithTarget:self selector:markReadUndoAction object:articleArray]; [undoManager setActionName:NSLocalizedString(@"Mark Read", nil)]; - Database * db = [Database sharedDatabase]; - [db doTransactionWithBlock:^(BOOL *rollback) { - [self innerMarkReadByArray:articleArray readFlag:readFlag]; - }]; //end transaction block + [self innerMarkReadByArray:articleArray readFlag:readFlag]; + [mainArticleView refreshFolder:MA_Refresh_RedrawList]; - - // The info bar has a count of unread articles so we need to - // update that. - [APPCONTROLLER showUnreadCountOnApplicationIconAndWindowTitle]; } /* innerMarkReadByArray @@ -614,24 +851,30 @@ -(void)markReadByArray:(NSArray *)articleArray readFlag:(BOOL)readFlag */ -(void)innerMarkReadByArray:(NSArray *)articleArray readFlag:(BOOL)readFlag { - Database * db = [Database sharedDatabase]; NSInteger lastFolderId = -1; for (Article * theArticle in articleArray) { - NSInteger folderId = [theArticle folderId]; - if (IsGoogleReaderFolder([db folderFromID:folderId]) && ([theArticle isRead] != readFlag)) { - [[GoogleReader sharedManager] markRead:[theArticle guid] readFlag:readFlag]; + NSInteger folderId = theArticle.folderId; + if (theArticle.read != readFlag) + { + if (IsGoogleReaderFolder([[Database sharedManager] folderFromID:folderId])) { + [[GoogleReader sharedManager] markRead:theArticle readFlag:readFlag]; + } else { + [[Database sharedManager] markArticleRead:folderId guid:theArticle.guid isRead:readFlag]; + [theArticle markRead:readFlag]; + if (folderId != lastFolderId && lastFolderId != -1) { + [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_FoldersUpdated" + object:@(lastFolderId)]; + } + lastFolderId = folderId; + } } - //FIX: article status should be "settato" from httprequest success block - [db markArticleRead:folderId guid:[theArticle guid] isRead:readFlag]; - [theArticle markRead:readFlag]; - if (folderId != lastFolderId && lastFolderId != -1) - [foldersTree updateFolder:lastFolderId recurseToParents:YES]; - lastFolderId = folderId; } - if (lastFolderId != -1) - [foldersTree updateFolder:lastFolderId recurseToParents:YES]; + if (lastFolderId != -1) { + [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_FoldersUpdated" + object:@(lastFolderId)]; + } } /* innerMarkReadByRefsArray @@ -639,23 +882,31 @@ -(void)innerMarkReadByArray:(NSArray *)articleArray readFlag:(BOOL)readFlag */ -(void)innerMarkReadByRefsArray:(NSArray *)articleArray readFlag:(BOOL)readFlag { - Database * db = [Database sharedDatabase]; + Database * db = [Database sharedManager]; NSInteger lastFolderId = -1; for (ArticleReference * articleRef in articleArray) { - NSInteger folderId = [articleRef folderId]; - if (IsGoogleReaderFolder([db folderFromID:folderId])){ - [[GoogleReader sharedManager] markRead:[articleRef guid] readFlag:readFlag]; + NSInteger folderId = articleRef.folderId; + Folder * folder = [db folderFromID:folderId]; + if (IsGoogleReaderFolder(folder)){ + Article * article = [folder articleFromGuid:articleRef.guid]; + if (article != nil) { + [[GoogleReader sharedManager] markRead:article readFlag:readFlag]; + } + } else { + [db markArticleRead:folderId guid:articleRef.guid isRead:readFlag]; + if (folderId != lastFolderId && lastFolderId != -1) { + [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_FoldersUpdated" + object:@(lastFolderId)]; + } + lastFolderId = folderId; } - //FIX: article status should be "settato" from httprequest success block - [db markArticleRead:folderId guid:[articleRef guid] isRead:readFlag]; - if (folderId != lastFolderId && lastFolderId != -1) - [foldersTree updateFolder:lastFolderId recurseToParents:YES]; - lastFolderId = folderId; } - if (lastFolderId != -1) - [foldersTree updateFolder:lastFolderId recurseToParents:YES]; + if (lastFolderId != -1) { + [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_FoldersUpdated" + object:@(lastFolderId)]; + } } /* markAllReadUndo @@ -674,96 +925,72 @@ -(void)markAllReadRedo:(id)anObject [self markAllReadByReferencesArray:(NSArray *)anObject readFlag:YES]; } -/* markAllReadByArray - * Given an array of folders, mark all the articles in those folders as read and - * return a reference array listing all the articles that were actually marked. +/* markAllFoldersReadByArray + * Given an array of folders, mark all the articles in those folders as read. */ --(void)markAllReadByArray:(NSArray *)folderArray withUndo:(BOOL)undoFlag withRefresh:(BOOL)refreshFlag +-(void)markAllFoldersReadByArray:(NSArray *)folderArray { - Database * db = [Database sharedDatabase]; - [db doTransactionWithBlock:^(BOOL *rollback) { - NSArray * refArray = [self wrappedMarkAllReadInArray:folderArray withUndo:undoFlag]; - if (refArray != nil && [refArray count] > 0) + NSArray * refArray = [self wrappedMarkAllFoldersReadInArray:folderArray]; + if (refArray != nil && refArray.count > 0) { - NSUndoManager * undoManager = [[NSApp mainWindow] undoManager]; + NSUndoManager * undoManager = NSApp.mainWindow.undoManager; [undoManager registerUndoWithTarget:self selector:@selector(markAllReadUndo:) object:refArray]; [undoManager setActionName:NSLocalizedString(@"Mark All Read", nil)]; } - - for (Article * theArticle in folderArrayOfArticles) - [theArticle markRead:YES]; - - }]; //end transaction block - - if (refreshFlag) - [mainArticleView refreshFolder:MA_Refresh_RedrawList]; - [APPCONTROLLER showUnreadCountOnApplicationIconAndWindowTitle]; + + // Smart and Search folders are not included in folderArray when you mark all subscriptions read, + // so we need to mark articles read if they're the current folder. + Folder * currentFolder = [[Database sharedManager] folderFromID:currentFolderId]; + if (currentFolder != nil && ![folderArray containsObject:currentFolder]) + { + for (Article * theArticle in folderArrayOfArticles) + [theArticle markRead:YES]; + } + + [mainArticleView refreshFolder:MA_Refresh_RedrawList]; } -/* wrappedMarkAllReadInArray +/* wrappedMarkAllFoldersReadInArray * Given an array of folders, mark all the articles in those folders as read and * return a reference array listing all the articles that were actually marked. */ --(NSArray *)wrappedMarkAllReadInArray:(NSArray *)folderArray withUndo:(BOOL)undoFlag +-(NSArray *)wrappedMarkAllFoldersReadInArray:(NSArray *)folderArray { NSMutableArray * refArray = [NSMutableArray array]; - Database * db = [Database sharedDatabase]; for (Folder * folder in folderArray) { - int folderId = [folder itemId]; - if (IsGroupFolder(folder) && undoFlag) + NSInteger folderId = folder.itemId; + if (IsGroupFolder(folder)) { - [refArray addObjectsFromArray:[self wrappedMarkAllReadInArray:[db arrayOfFolders:folderId] withUndo:undoFlag]]; + [refArray addObjectsFromArray:[self wrappedMarkAllFoldersReadInArray:[[Database sharedManager] arrayOfFolders:folderId]]]; } else if (IsRSSFolder(folder)) { - if (undoFlag) - [refArray addObjectsFromArray:[db arrayOfUnreadArticlesRefs:folderId]]; - if ([db markFolderRead:folderId]) - { - [foldersTree updateFolder:folderId recurseToParents:YES]; - + [refArray addObjectsFromArray:[folder arrayOfUnreadArticlesRefs]]; + if ([[Database sharedManager] markFolderRead:folderId]) { + [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_FoldersUpdated" + object:@(folderId)]; } } else if (IsGoogleReaderFolder(folder)) { - NSArray * articleArray = [db arrayOfUnreadArticlesRefs:folderId]; - if (undoFlag) - [refArray addObjectsFromArray:articleArray]; + NSArray * articleArray = [folder arrayOfUnreadArticlesRefs]; + [refArray addObjectsFromArray:articleArray]; [self innerMarkReadByRefsArray:articleArray readFlag:YES]; } else { // For smart folders, we only mark all read the current folder to // simplify things. - if (undoFlag && folderId == currentFolderId) + if (folderId == currentFolderId) { [refArray addObjectsFromArray:currentArrayOfArticles]; [self innerMarkReadByArray:currentArrayOfArticles readFlag:YES]; } } } - return refArray; -} - -/* currentCacheContainsFolder - * Scans the current article cache to determine if any article is a member of the specified - * folder and returns YES if so. - */ --(BOOL)currentCacheContainsFolder:(int)folderId -{ - int count = [currentArrayOfArticles count]; - int index = 0; - - while (index < count) - { - Article * anArticle = [currentArrayOfArticles objectAtIndex:index]; - if ([anArticle folderId] == folderId) - return YES; - ++index; - } - return NO; + return [refArray copy]; } /* markAllReadByReferencesArray @@ -771,49 +998,51 @@ -(BOOL)currentCacheContainsFolder:(int)folderId */ -(void)markAllReadByReferencesArray:(NSArray *)refArray readFlag:(BOOL)readFlag { - Database * db = [Database sharedDatabase]; - __block int lastFolderId = -1; + Database * dbManager = [Database sharedManager]; + __block NSInteger lastFolderId = -1; __block BOOL needRefilter = NO; // Set up to undo or redo this action - NSUndoManager * undoManager = [[NSApp mainWindow] undoManager]; + NSUndoManager * undoManager = NSApp.mainWindow.undoManager; SEL markAllReadUndoAction = readFlag ? @selector(markAllReadUndo:) : @selector(markAllReadRedo:); [undoManager registerUndoWithTarget:self selector:markAllReadUndoAction object:refArray]; [undoManager setActionName:NSLocalizedString(@"Mark All Read", nil)]; - [db doTransactionWithBlock:^(BOOL *rollback) { for (ArticleReference *ref in refArray) { - int folderId = [ref folderId]; - NSString * theGuid = [ref guid]; - if (IsGoogleReaderFolder([db folderFromID:folderId])) - [[GoogleReader sharedManager] markRead:theGuid readFlag:readFlag]; + NSInteger folderId = ref.folderId; + NSString * theGuid = ref.guid; + Folder * folder = [dbManager folderFromID:folderId]; + if (IsGoogleReaderFolder(folder)) { + Article * article = [folder articleFromGuid:theGuid]; + if (article != nil) { + [[GoogleReader sharedManager] markRead:article readFlag:readFlag]; + } + } else { + [dbManager markArticleRead:folderId guid:theGuid isRead:readFlag]; + if (folderId != lastFolderId && lastFolderId != -1) { + [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_FoldersUpdated" + object:@(lastFolderId)]; + } + lastFolderId = folderId; + } - [db markArticleRead:folderId guid:theGuid isRead:readFlag]; - if (folderId != lastFolderId && lastFolderId != -1) - { - [foldersTree updateFolder:lastFolderId recurseToParents:YES]; - if (lastFolderId == currentFolderId) - needRefilter = YES; + if (folderId == currentFolderId) { + needRefilter = YES; } - lastFolderId = folderId; } - }]; //end transaction block - if (lastFolderId != -1) - { - [foldersTree updateFolder:lastFolderId recurseToParents:YES]; - if (lastFolderId == currentFolderId) - needRefilter = YES; - if (!IsRSSFolder([db folderFromID:currentFolderId])&&!IsGoogleReaderFolder([db folderFromID:currentFolderId])) - [mainArticleView refreshFolder:MA_Refresh_ReloadFromDatabase]; - else if (needRefilter) - [mainArticleView refreshFolder:MA_Refresh_ReapplyFilter]; + if (lastFolderId != -1) { + [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_FoldersUpdated" + object:@(lastFolderId)]; + } + if (lastFolderId != -1 && !IsRSSFolder([dbManager folderFromID:currentFolderId]) + && !IsGoogleReaderFolder([dbManager folderFromID:currentFolderId])) { + [self reloadArrayOfArticles]; + } + else if (needRefilter) { + [mainArticleView refreshFolder:MA_Refresh_ReapplyFilter]; } - - // The info bar has a count of unread articles so we need to - // update that. - [APPCONTROLLER showUnreadCountOnApplicationIconAndWindowTitle]; } /* addBacktrack @@ -831,13 +1060,13 @@ -(void)addBacktrack:(NSString *)guid */ -(void)goForward { - int folderId; + NSInteger folderId; NSString * guid; if ([backtrackArray nextItemAtQueue:&folderId guidPointer:&guid]) { isBacktracking = YES; - [mainArticleView selectFolderAndArticle:folderId guid:guid]; + [self selectFolderAndArticle:folderId guid:guid]; isBacktracking = NO; } } @@ -847,13 +1076,13 @@ -(void)goForward */ -(void)goBack { - int folderId; + NSInteger folderId; NSString * guid; if ([backtrackArray previousItemAtQueue:&folderId guidPointer:&guid]) { isBacktracking = YES; - [mainArticleView selectFolderAndArticle:folderId guid:guid]; + [self selectFolderAndArticle:folderId guid:guid]; isBacktracking = NO; } } @@ -863,7 +1092,7 @@ -(void)goBack */ -(BOOL)canGoForward { - return ![backtrackArray isAtEndOfQueue]; + return !backtrackArray.atEndOfQueue; } /* canGoBack @@ -871,7 +1100,7 @@ -(BOOL)canGoForward */ -(BOOL)canGoBack { - return ![backtrackArray isAtStartOfQueue]; + return !backtrackArray.atStartOfQueue; } /* handleFilterChange @@ -885,69 +1114,37 @@ -(void)handleFilterChange:(NSNotification *)nc } } -/* handleFolderNameChange -* Some folder metadata changed. Update the article list header and the -* current article with a possible name change. +/* handleArticleListStateChange +* Called if a folder content has changed +* but we don't need to add new articles */ --(void)handleFolderNameChange:(NSNotification *)nc +-(void)handleArticleListStateChange:(NSNotification *)nc { - @synchronized(mainArticleView) - { - int folderId = [(NSNumber *)[nc object] intValue]; - if (folderId == currentFolderId) - [mainArticleView refreshArticlePane]; + NSInteger folderId = ((NSNumber *)nc.object).integerValue; + Folder * currentFolder = [[Database sharedManager] folderFromID:currentFolderId]; + if ( (folderId == currentFolderId) || (!IsRSSFolder(currentFolder) && !IsGoogleReaderFolder(currentFolder)) ) { + [mainArticleView refreshFolder:MA_Refresh_RedrawList]; } } -/* handleRefreshArticle -* Respond to the notification to refresh the current article pane. -*/ --(void)handleRefreshArticle:(NSNotification *)nc -{ - @synchronized(mainArticleView) - { - [mainArticleView handleRefreshArticle:nc]; - } -} - -/* handleFolderUpdate -* Called if a folder content has changed. -*/ --(void)handleFolderUpdate:(NSNotification *)nc -{ - @synchronized(mainArticleView) - { - int folderId = [(NSNumber *)[nc object] intValue]; - if (folderId != currentFolderId) - return; - - Folder * folder = [[Database sharedDatabase] folderFromID:folderId]; - if (IsSmartFolder(folder) || IsTrashFolder(folder)) - [mainArticleView refreshFolder:MA_Refresh_ReloadFromDatabase]; - } -} - -/* handleFolderAdded -* Called if a folder was added. -*/ --(void)handleFolderAdded:(NSNotification *)nc -{ - @synchronized(mainArticleView) - { - Folder * folder = (Folder *)[nc object]; - currentFolderId = [folder itemId]; - [mainArticleView selectFolderAndArticle:currentFolderId guid:nil]; - } -} - -/* setArticleToPreserve - * Sets the article to preserve when reloading the array of articles. +/* handleArticleListContentChange + * called after a refresh + * or any other event which may have added a removed an article + * to the current folder */ --(void)setArticleToPreserve:(Article *)article +-(void)handleArticleListContentChange:(NSNotification *)note { - [article retain]; - [articleToPreserve release]; - articleToPreserve = article; + // With automatic refresh and automatic mark read, + // the article you're current reading can disappear. + // For example, if you're reading in the Unread Articles smart folder. + // So make sure the keep this article around. + if ([[Preferences standardPreferences] refreshFrequency] > 0 + && [[Preferences standardPreferences] markReadInterval] > 0.0) + { + shouldPreserveSelectedArticle = YES; + } + + [self reloadArrayOfArticles]; } /* dealloc @@ -956,21 +1153,5 @@ -(void)setArticleToPreserve:(Article *)article -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - [mainArticleView release]; - mainArticleView=nil; - [backtrackArray release]; - backtrackArray=nil; - [sortColumnIdentifier release]; - sortColumnIdentifier=nil; - [folderArrayOfArticles release]; - folderArrayOfArticles=nil; - [currentArrayOfArticles release]; - currentArrayOfArticles=nil; - [articleSortSpecifiers release]; - articleSortSpecifiers=nil; - [articleToPreserve release]; - articleToPreserve=nil; - [foldersTree release]; - [super dealloc]; } @end diff --git a/src/ArticleFilter.h b/src/ArticleFilter.h index c8e39b7c09..f639b28757 100644 --- a/src/ArticleFilter.h +++ b/src/ArticleFilter.h @@ -29,7 +29,7 @@ // Public functions +(NSArray *)arrayOfFilters; +(ArticleFilter *)filterByTag:(NSInteger)theTag; --(NSString *)name; --(NSInteger)tag; --(SEL)comparator; +@property (nonatomic, readonly, copy) NSString *name; +@property (nonatomic, readonly) NSInteger tag; +@property (nonatomic, readonly) SEL comparator; @end diff --git a/src/ArticleFilter.m b/src/ArticleFilter.m index cf4bb8847a..e4db7e2ba4 100644 --- a/src/ArticleFilter.m +++ b/src/ArticleFilter.m @@ -38,7 +38,7 @@ @implementation ArticleFilter */ +(BOOL)unreadArticleFilterComparator:(Article *)theArticle { - return ![theArticle isRead]; + return !theArticle.read; } /* flaggedArticleFilterComparator @@ -46,7 +46,7 @@ +(BOOL)unreadArticleFilterComparator:(Article *)theArticle */ +(BOOL)flaggedArticleFilterComparator:(Article *)theArticle { - return [theArticle isFlagged]; + return theArticle.flagged; } /* todayFilterComparator @@ -54,7 +54,7 @@ +(BOOL)flaggedArticleFilterComparator:(Article *)theArticle */ +(BOOL)todayFilterComparator:(Article *)theArticle { - return ([[theArticle date] compare:[NSCalendarDate today]] != NSOrderedAscending); + return ([theArticle.date compare:[NSCalendarDate today]] != NSOrderedAscending); } /* lastRefreshFilterComparator @@ -62,7 +62,7 @@ +(BOOL)todayFilterComparator:(Article *)theArticle */ +(BOOL)lastRefreshFilterComparator:(Article *)theArticle { - return ([[theArticle createdDate] compare:[[Preferences standardPreferences] objectForKey:MAPref_LastRefreshDate]] != NSOrderedAscending); + return ([theArticle.createdDate compare:[[Preferences standardPreferences] objectForKey:MAPref_LastRefreshDate]] != NSOrderedAscending); } /* twoDaysFilterComparator @@ -70,7 +70,7 @@ +(BOOL)lastRefreshFilterComparator:(Article *)theArticle */ +(BOOL)twoDaysFilterComparator:(Article *)theArticle { - return ([[theArticle date] compare:[[NSCalendarDate date] dateByAddingTimeInterval:-172800]] != NSOrderedAscending); + return ([theArticle.date compare:[[NSCalendarDate date] dateByAddingTimeInterval:-172800]] != NSOrderedAscending); } /* unreadOrFlaggedArticleFilterComparator @@ -78,7 +78,7 @@ +(BOOL)twoDaysFilterComparator:(Article *)theArticle */ +(BOOL)unreadOrFlaggedArticleFilterComparator:(Article *)theArticle { - return ( ![theArticle isRead] || [theArticle isFlagged] ); + return ( !theArticle.read || theArticle.flagged ); } /* initalize @@ -117,10 +117,10 @@ +(NSArray *)arrayOfFilters +(ArticleFilter *)filterByTag:(NSInteger)theTag { NSInteger index; - for (index = 0; index < [_filterList count]; ++index) + for (index = 0; index < _filterList.count; ++index) { - ArticleFilter * filter = [_filterList objectAtIndex:index]; - if ([filter tag] == theTag) + ArticleFilter * filter = _filterList[index]; + if (filter.tag == theTag) return filter; } return nil; @@ -129,11 +129,11 @@ +(ArticleFilter *)filterByTag:(NSInteger)theTag /* initWithName * This is the designated initialiser for a new ArticleFilter object. */ --(id)initWithName:(NSString *)theName tag:(NSInteger)theTag comparator:(SEL)theComparator +-(instancetype)initWithName:(NSString *)theName tag:(NSInteger)theTag comparator:(SEL)theComparator { if ((self = [super init]) != nil) { - name = [theName retain]; + name = theName; tag = theTag; comparator = theComparator; } @@ -169,19 +169,10 @@ -(NSInteger)tag */ +(void)createFilter:(NSString *)name tag:(NSInteger)tag comparator:(SEL)comparator { - ArticleFilter * newFilter = [[[ArticleFilter alloc] initWithName:name tag:tag comparator:comparator] autorelease]; + ArticleFilter * newFilter = [[ArticleFilter alloc] initWithName:name tag:tag comparator:comparator]; if (_filterList == nil) _filterList = [[NSMutableArray alloc] init]; [_filterList addObject:newFilter]; } -/* dealloc - * Clean up behind us. - */ --(void)dealloc -{ - [name release]; - name=nil; - [super dealloc]; -} @end diff --git a/src/ArticleListView.h b/src/ArticleListView.h index 72c89e048a..0672dbee38 100644 --- a/src/ArticleListView.h +++ b/src/ArticleListView.h @@ -30,7 +30,6 @@ @class ArticleController; @class MessageListView; @class ArticleView; -@class FoldersTree; @interface ArticleListView : NSView { @@ -39,19 +38,15 @@ IBOutlet MessageListView * articleList; IBOutlet ArticleView * articleText; IBOutlet NSSplitView * splitView2; - IBOutlet FoldersTree * foldersTree; IBOutlet StdEnclosureView * stdEnclosureView; - int currentSelectedRow; - int tableLayout; + NSInteger tableLayout; BOOL isAppInitialising; BOOL isChangingOrientation; BOOL isInTableInit; BOOL blockSelectionHandler; - BOOL blockMarkRead; NSTimer * markReadTimer; - NSString * guidOfArticleToSelect; NSFont * articleListFont; NSFont * articleListUnreadFont; NSMutableDictionary * reportCellDict; @@ -68,17 +63,15 @@ BOOL isCurrentPageFullHTML; BOOL isLoadingHTMLArticle; NSError * lastError; + NSProgressIndicator * progressIndicator; } // Public functions --(void)initialiseArticleView; -(void)updateAlternateMenuTitle; -(void)updateVisibleColumns; -(void)saveTableSettings; --(int)tableLayout; --(NSArray *)markedArticleRange; --(BOOL)canDeleteMessageAtRow:(int)row; +-(BOOL)canDeleteMessageAtRow:(NSInteger)row; -(void)loadArticleLink:(NSString *) articleLink; --(NSURL *)url; +@property (nonatomic, readonly, copy) NSURL *url; -(void)webViewLoadFinished:(NSNotification *)notification; @end diff --git a/src/ArticleListView.m b/src/ArticleListView.m index f3c02dd535..c87d76f67b 100644 --- a/src/ArticleListView.m +++ b/src/ArticleListView.m @@ -28,13 +28,11 @@ #import "SplitViewExtensions.h" #import "MessageListView.h" #import "ArticleView.h" -#import "FoldersTree.h" #import "CalendarExtensions.h" #import "StringExtensions.h" #import "HelperFunctions.h" #import "ArticleRef.h" #import "ArticleFilter.h" -#import "XMLParser.h" #import "Field.h" #import #import "PopupButton.h" @@ -50,16 +48,14 @@ -(void)setTableViewFont; -(void)showSortDirection; -(void)selectArticleAfterReload; -(void)handleReadingPaneChange:(NSNotificationCenter *)nc; - -(BOOL)scrollToArticle:(NSString *)guid; - -(void)selectFirstUnreadInFolder; - -(BOOL)viewNextUnreadInCurrentFolder:(int)currentRow; + -(BOOL)viewNextUnreadInCurrentFolder:(NSInteger)currentRow; -(void)loadMinimumFontSize; -(void)markCurrentRead:(NSTimer *)aTimer; -(void)refreshImmediatelyArticleAtCurrentRow; -(void)refreshArticleAtCurrentRow; - -(void)makeRowSelectedAndVisible:(int)rowIndex; + -(void)makeRowSelectedAndVisible:(NSInteger)rowIndex; -(void)updateArticleListRowHeight; - -(void)setOrientation:(int)newLayout; + -(void)setOrientation:(NSInteger)newLayout; -(void)loadSplitSettingsForLayout; -(void)saveSplitSettingsForLayout; -(void)showEnclosureView; @@ -79,7 +75,7 @@ @implementation ArticleListView /* initWithFrame * Initialise our view. */ --(id)initWithFrame:(NSRect)frame +-(instancetype)initWithFrame:(NSRect)frame { self= [super initWithFrame:frame]; if (self) @@ -87,8 +83,6 @@ -(id)initWithFrame:(NSRect)frame isChangingOrientation = NO; isInTableInit = NO; blockSelectionHandler = NO; - blockMarkRead = NO; - guidOfArticleToSelect = nil; markReadTimer = nil; lastError = nil; isCurrentPageFullHTML = NO; @@ -108,22 +102,24 @@ -(void)awakeFromNib [nc addObserver:self selector:@selector(handleArticleListFontChange:) name:@"MA_Notify_ArticleListFontChange" object:nil]; [nc addObserver:self selector:@selector(handleReadingPaneChange:) name:@"MA_Notify_ReadingPaneChange" object:nil]; [nc addObserver:self selector:@selector(handleLoadFullHTMLChange:) name:@"MA_Notify_LoadFullHTMLChange" object:nil]; - [nc addObserver:self selector:@selector(handleArticleListStateChange:) name:@"MA_Notify_ArticleListStateChange" object:nil]; + [nc addObserver:self selector:@selector(handleRefreshArticle:) name:@"MA_Notify_ArticleViewChange" object:nil]; // Make us the frame load and UI delegate for the web view - [articleText setUIDelegate:self]; - [articleText setFrameLoadDelegate:self]; + articleText.UIDelegate = self; + articleText.frameLoadDelegate = self; [articleText setOpenLinksInNewBrowser:YES]; [articleText setController:controller]; // Make web preferences 16pt Arial to match Safari - [[articleText preferences] setStandardFontFamily:@"Arial"]; - [[articleText preferences] setDefaultFontSize:16]; + articleText.preferences.standardFontFamily = @"Arial"; + articleText.preferences.defaultFontSize = 16; // Disable caching - [[articleText preferences] setUsesPageCache:NO]; + [articleText.preferences setUsesPageCache:NO]; [articleText setMaintainsBackForwardList:NO]; - [[articleText backForwardList] setPageCacheSize:0]; + [articleText.backForwardList setPageCacheSize:0]; + + [self initialiseArticleView]; } /* initialiseArticleView @@ -140,7 +136,8 @@ -(void)initialiseArticleView // Create report and condensed view attribute dictionaries NSMutableParagraphStyle * style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; - [style setLineBreakMode:NSLineBreakByClipping]; + style.lineBreakMode = NSLineBreakByTruncatingTail; + style.tighteningFactorForTruncation = 0.0; reportCellDict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:style, NSParagraphStyleAttributeName, nil]; unreadReportCellDict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:style, NSParagraphStyleAttributeName, nil]; @@ -153,17 +150,16 @@ -(void)initialiseArticleView linkLineDict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:style, NSParagraphStyleAttributeName, [NSColor blueColor], NSForegroundColorAttributeName, nil]; bottomLineDict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:style, NSParagraphStyleAttributeName, [NSColor grayColor], NSForegroundColorAttributeName, nil]; - [style release]; // Set the reading pane orientation - [self setOrientation:[prefs layout]]; - [splitView2 setDelegate:self]; + [self setOrientation:prefs.layout]; + splitView2.delegate = self; // Initialise the article list view [self initTableView]; // Make sure we skip the column filter button in the Tab order - [articleList setNextKeyView:articleText]; + articleList.nextKeyView = articleText; // Done initialising isAppInitialising = NO; @@ -177,7 +173,7 @@ -(CGFloat)splitView:(NSSplitView *)sender constrainMinCoordinate:(CGFloat)propos { if (sender == splitView2) { - BOOL isVertical = [sender isVertical]; + BOOL isVertical = sender.vertical; if (isVertical) return (offset == 0) ? proposedMin + MA_Minimum_ArticleList_Pane_Width : proposedMin + MA_Minimum_Article_Pane_Dimension ; else @@ -195,7 +191,7 @@ -(CGFloat)splitView:(NSSplitView *)sender constrainMaxCoordinate:(CGFloat)propos { if (sender == splitView2) { - BOOL isVertical = [sender isVertical]; + BOOL isVertical = sender.vertical; if (isVertical) return (offset == 0) ? proposedMax - MA_Minimum_Article_Pane_Dimension : proposedMax - MA_Minimum_ArticleList_Pane_Width; else @@ -209,13 +205,13 @@ -(CGFloat)splitView:(NSSplitView *)sender constrainMaxCoordinate:(CGFloat)propos */ -(void)splitView:(NSSplitView *)sender resizeSubviewsWithOldSize:(NSSize)oldSize { - CGFloat dividerThickness = [sender dividerThickness]; - BOOL isVertical = [sender isVertical]; - id sv1 = [[sender subviews] objectAtIndex:0]; - id sv2 = [[sender subviews] objectAtIndex:1]; + CGFloat dividerThickness = sender.dividerThickness; + BOOL isVertical = sender.vertical; + id sv1 = sender.subviews[0]; + id sv2 = sender.subviews[1]; NSRect leftFrame = [sv1 frame]; NSRect rightFrame = [sv2 frame]; - NSRect newFrame = [sender frame]; + NSRect newFrame = sender.frame; if (sender == splitView2) { @@ -253,7 +249,7 @@ -(void)splitView:(NSSplitView *)sender resizeSubviewsWithOldSize:(NSSize)oldSize */ -(WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request { - [controller openURL:[request URL] inPreferredBrowser:YES]; + [controller openURL:request.URL inPreferredBrowser:YES]; // Change this to handle modifier key? // Is this covered by the webView policy? return nil; @@ -290,7 +286,7 @@ - (BOOL)webView:(WebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString */ -(void)webView:(WebView *)sender setStatusText:(NSString *)text { - if ([[controller browserView] activeTabItemView] == self) + if (controller.browserView.activeTabItemView == self) [controller setStatusMessage:text persist:NO]; } @@ -298,10 +294,10 @@ -(void)webView:(WebView *)sender setStatusText:(NSString *)text * Called from the webview when the user positions the mouse over an element. If it's a link * then echo the URL to the status bar like Safari does. */ --(void)webView:(WebView *)sender mouseDidMoveOverElement:(NSDictionary *)elementInformation modifierFlags:(NSUInteger )modifierFlags +-(void)webView:(WebView *)sender mouseDidMoveOverElement:(NSDictionary *)elementInformation modifierFlags:(NSUInteger)modifierFlags { NSURL * url = [elementInformation valueForKey:@"WebElementLinkURL"]; - [controller setStatusMessage:(url ? [url absoluteString] : @"") persist:NO]; + [controller setStatusMessage:(url ? url.absoluteString : @"") persist:NO]; } /* contextMenuItemsForElement @@ -326,26 +322,25 @@ -(NSArray *)webView:(WebView *)sender contextMenuItemsForElement:(NSDictionary * if (!isCurrentPageFullHTML) { NSMutableArray * newDefaultMenu = [[NSMutableArray alloc] init]; - int count = [defaultMenuItems count]; - int index; + NSInteger count = defaultMenuItems.count; + NSInteger index; // Copy over everything but the reload menu item, which we can't handle if // this is not a full HTML page since we don't have an URL. for (index = 0; index < count; index++) { - NSMenuItem * menuItem = [defaultMenuItems objectAtIndex:index]; - if ([menuItem tag] != WebMenuItemTagReload) + NSMenuItem * menuItem = defaultMenuItems[index]; + if (menuItem.tag != WebMenuItemTagReload) [newDefaultMenu addObject:menuItem]; } // If we still have some menu items then use that for the new default menu, otherwise // set the default items to nil as we may have removed all the items. - if ([newDefaultMenu count] > 0) - defaultMenuItems = [newDefaultMenu autorelease]; + if (newDefaultMenu.count > 0) + defaultMenuItems = newDefaultMenu; else { defaultMenuItems = nil; - [newDefaultMenu release]; } } @@ -361,31 +356,30 @@ -(void)initTableView Preferences * prefs = [Preferences standardPreferences]; // Variable initialization here - currentSelectedRow = -1; articleListFont = nil; articleListUnreadFont = nil; // Initialize the article columns from saved data NSArray * dataArray = [prefs arrayForKey:MAPref_ArticleListColumns]; - Database * db = [Database sharedDatabase]; + Database * db = [Database sharedManager]; Field * field; NSUInteger index; - for (index = 0; index < [dataArray count];) + for (index = 0; index < dataArray.count;) { NSString * name; - int width = 100; + NSInteger width = 100; BOOL visible = NO; - name = [dataArray objectAtIndex:index++]; - if (index < [dataArray count]) - visible = [[dataArray objectAtIndex:index++] intValue] == YES; - if (index < [dataArray count]) - width = [[dataArray objectAtIndex:index++] intValue]; + name = dataArray[index++]; + if (index < dataArray.count) + visible = [dataArray[index++] integerValue] == YES; + if (index < dataArray.count) + width = [dataArray[index++] integerValue]; field = [db fieldByName:name]; - [field setVisible:visible]; - [field setWidth:width]; + field.visible = visible; + field.width = width; } // Set the default fonts @@ -395,7 +389,7 @@ -(void)initTableView [self updateVisibleColumns]; // In condensed mode, the summary field takes up the whole space. - [articleList setColumnAutoresizingStyle:NSTableViewUniformColumnAutoresizingStyle]; + articleList.columnAutoresizingStyle = NSTableViewUniformColumnAutoresizingStyle; // Dynamically create the popup menu. This is one less thing to // explicitly localise in the NIB file. @@ -409,23 +403,22 @@ -(void)initTableView [articleListMenu addItem:[NSMenuItem separatorItem]]; [articleListMenu addItem:copyOfMenuItemWithAction(@selector(viewSourceHomePage:))]; NSMenuItem * alternateItem = copyOfMenuItemWithAction(@selector(viewSourceHomePageInAlternateBrowser:)); - [alternateItem setKeyEquivalentModifierMask:NSAlternateKeyMask]; + alternateItem.keyEquivalentModifierMask = NSAlternateKeyMask; [alternateItem setAlternate:YES]; [articleListMenu addItem:alternateItem]; [articleListMenu addItem:copyOfMenuItemWithAction(@selector(viewArticlePages:))]; alternateItem = copyOfMenuItemWithAction(@selector(viewArticlePagesInAlternateBrowser:)); - [alternateItem setKeyEquivalentModifierMask:NSAlternateKeyMask]; + alternateItem.keyEquivalentModifierMask = NSAlternateKeyMask; [alternateItem setAlternate:YES]; [articleListMenu addItem:alternateItem]; - [articleList setMenu:articleListMenu]; - [articleListMenu release]; + articleList.menu = articleListMenu; // Set the target for double-click actions - [articleList setDoubleAction:@selector(doubleClickRow:)]; - [articleList setAction:@selector(singleClickRow:)]; + articleList.doubleAction = @selector(doubleClickRow:); + articleList.action = @selector(singleClickRow:); [articleList setDelegate:self]; [articleList setDataSource:self]; - [articleList setTarget:self]; + articleList.target = self; [articleList accessibilitySetOverrideValue:NSLocalizedString(@"Articles", nil) forAttribute:NSAccessibilityDescriptionAttribute]; } @@ -437,25 +430,25 @@ -(void)initTableView */ -(IBAction)singleClickRow:(id)sender { - int row = [articleList clickedRow]; - int column = [articleList clickedColumn]; - NSArray * allArticles = [articleController allArticles]; + NSInteger row = articleList.clickedRow; + NSInteger column = articleList.clickedColumn; + NSArray * allArticles = articleController.allArticles; - if (row >= 0 && row < (int)[allArticles count]) + if (row >= 0 && row < (NSInteger)allArticles.count) { - NSArray * columns = [articleList tableColumns]; - if (column >= 0 && column < (int)[columns count]) + NSArray * columns = articleList.tableColumns; + if (column >= 0 && column < (NSInteger)columns.count) { - Article * theArticle = [allArticles objectAtIndex:row]; - NSString * columnName = [(NSTableColumn *)[columns objectAtIndex:column] identifier]; + Article * theArticle = allArticles[row]; + NSString * columnName = ((NSTableColumn *)columns[column]).identifier; if ([columnName isEqualToString:MA_Field_Read]) { - [articleController markReadByArray:[NSArray arrayWithObject:theArticle] readFlag:![theArticle isRead]]; + [articleController markReadByArray:@[theArticle] readFlag:!theArticle.read]; return; } if ([columnName isEqualToString:MA_Field_Flagged]) { - [articleController markFlaggedByArray:[NSArray arrayWithObject:theArticle] flagged:![theArticle isFlagged]]; + [articleController markFlaggedByArray:@[theArticle] flagged:!theArticle.flagged]; return; } if ([columnName isEqualToString:MA_Field_HasEnclosure]) @@ -473,10 +466,11 @@ -(IBAction)singleClickRow:(id)sender */ -(IBAction)doubleClickRow:(id)sender { - if (currentSelectedRow != -1 && [articleList clickedRow] != -1) + NSInteger clickedRow = articleList.clickedRow; + if (clickedRow != -1) { - Article * theArticle = [[articleController allArticles] objectAtIndex:currentSelectedRow]; - [controller openURLFromString:[theArticle link] inPreferredBrowser:YES]; + Article * theArticle = articleController.allArticles[clickedRow]; + [controller openURLFromString:theArticle.link inPreferredBrowser:YES]; } } @@ -488,8 +482,8 @@ -(void)updateAlternateMenuTitle { NSMenuItem * mainMenuItem; NSMenuItem * contextualMenuItem; - int index; - NSMenu * articleListMenu = [articleList menu]; + NSInteger index; + NSMenu * articleListMenu = articleList.menu; if (articleListMenu == nil) return; mainMenuItem = menuItemWithAction(@selector(viewSourceHomePageInAlternateBrowser:)); @@ -499,7 +493,7 @@ -(void)updateAlternateMenuTitle if (index >= 0) { contextualMenuItem = [articleListMenu itemAtIndex:index]; - [contextualMenuItem setTitle:[mainMenuItem title]]; + contextualMenuItem.title = mainMenuItem.title; } } mainMenuItem = menuItemWithAction(@selector(viewArticlePagesInAlternateBrowser:)); @@ -509,7 +503,7 @@ -(void)updateAlternateMenuTitle if (index >= 0) { contextualMenuItem = [articleListMenu itemAtIndex:index]; - [contextualMenuItem setTitle:[mainMenuItem title]]; + contextualMenuItem.title = mainMenuItem.title; } } } @@ -517,25 +511,12 @@ -(void)updateAlternateMenuTitle /* ensureSelectedArticle * Ensure that there is a selected article and that it is visible. */ --(void)ensureSelectedArticle:(BOOL)singleSelection +-(void)ensureSelectedArticle { - if (singleSelection) - { - int nextRow = [[articleList selectedRowIndexes] firstIndex]; - int articlesCount = [[articleController allArticles] count]; - - currentSelectedRow = -1; - if (nextRow < 0 || nextRow >= articlesCount) - nextRow = articlesCount - 1; - [self makeRowSelectedAndVisible:nextRow]; - } + if (articleList.selectedRow == -1) + [self makeRowSelectedAndVisible:0]; else - { - if ([articleList selectedRow] == -1) - [self makeRowSelectedAndVisible:0]; - else - [articleList scrollRowToVisible:[articleList selectedRow]]; - } + [articleList scrollRowToVisible:articleList.selectedRow]; } /* updateVisibleColumns @@ -544,12 +525,12 @@ -(void)ensureSelectedArticle:(BOOL)singleSelection */ -(void)updateVisibleColumns { - NSArray * fields = [[Database sharedDatabase] arrayOfFields]; - int count = [fields count]; - int index; + NSArray * fields = [[Database sharedManager] arrayOfFields]; + NSInteger count = fields.count; + NSInteger index; // Save current selection - NSIndexSet * selArray = [articleList selectedRowIndexes]; + NSIndexSet * selArray = articleList.selectedRowIndexes; // Mark we're doing an update of the tableview isInTableInit = YES; @@ -560,20 +541,20 @@ -(void)updateVisibleColumns // Create the new columns for (index = 0; index < count; ++index) { - Field * field = [fields objectAtIndex:index]; - NSString * identifier = [field name]; - int tag = [field tag]; + Field * field = fields[index]; + NSString * identifier = field.name; + NSInteger tag = field.tag; BOOL showField; // Handle which fields can be visible in the condensed (vertical) layout // versus the table (horizontal) layout if (tableLayout == MA_Layout_Report) - showField = [field visible] && tag != MA_FieldID_Headlines && tag != MA_FieldID_Comments; + showField = field.visible && tag != MA_FieldID_Headlines && tag != MA_FieldID_Comments; else { showField = NO; if (tag == MA_FieldID_Read || tag == MA_FieldID_Flagged || tag == MA_FieldID_HasEnclosure) - showField = [field visible]; + showField = field.visible; if (tag == MA_FieldID_Headlines) showField = YES; } @@ -581,12 +562,12 @@ -(void)updateVisibleColumns // hide old columns which shouldn't be visible anymore if ([articleList columnWithIdentifier:identifier]!=-1) { - NSArray *columns = [articleList tableColumns]; + NSArray *columns = articleList.tableColumns; - if(columns && [columns count] > 0) + if(columns && columns.count > 0) { - NSTableColumn *col = [columns objectAtIndex:[articleList columnWithIdentifier:identifier]]; - [col setHidden:!showField]; + NSTableColumn *col = columns[[articleList columnWithIdentifier:identifier]]; + col.hidden = !showField; } } // Add to the end only those columns that are visible @@ -599,42 +580,41 @@ -(void)updateVisibleColumns // in willDisplayCell:forTableColumn:row: where it sets the inProgress flag. // We need to use a different column for condensed layout vs. table layout. BOOL isProgressColumn = NO; - if (tableLayout == MA_Layout_Report && [[column identifier] isEqualToString:MA_Field_Subject]) + if (tableLayout == MA_Layout_Report && [column.identifier isEqualToString:MA_Field_Subject]) isProgressColumn = YES; - if (tableLayout == MA_Layout_Condensed && [[column identifier] isEqualToString:MA_Field_Headlines]) + if (tableLayout == MA_Layout_Condensed && [column.identifier isEqualToString:MA_Field_Headlines]) isProgressColumn = YES; if (isProgressColumn) { ProgressTextCell * progressCell; - progressCell = [[[ProgressTextCell alloc] init] autorelease]; - [column setDataCell:progressCell]; + progressCell = [[ProgressTextCell alloc] init]; + column.dataCell = progressCell; } else { BJRVerticallyCenteredTextFieldCell * cell; - cell = [[[BJRVerticallyCenteredTextFieldCell alloc] init] autorelease]; - [column setDataCell:cell]; + cell = [[BJRVerticallyCenteredTextFieldCell alloc] init]; + column.dataCell = cell; } BOOL isResizable = (tag != MA_FieldID_Read && tag != MA_FieldID_Flagged && tag != MA_FieldID_Comments && tag != MA_FieldID_HasEnclosure); - [column setResizingMask:(isResizable ? NSTableColumnUserResizingMask : NSTableColumnNoResizing)]; + column.resizingMask = (isResizable ? NSTableColumnUserResizingMask : NSTableColumnNoResizing); // the headline column is auto-resizable - [column setResizingMask:[column resizingMask] | ([[column identifier] isEqualToString:MA_Field_Headlines] ? NSTableColumnAutoresizingMask : 0)]; + column.resizingMask = column.resizingMask | ([column.identifier isEqualToString:MA_Field_Headlines] ? NSTableColumnAutoresizingMask : 0); // Set the header attributes. - NSTableHeaderCell * headerCell = [column headerCell]; - [headerCell setTitle:[field displayName]]; + NSTableHeaderCell * headerCell = column.headerCell; + headerCell.title = field.displayName; // Set the other column atributes. [column setEditable:NO]; - [column setMinWidth:10]; - [column setMaxWidth:2000]; - [column setWidth:[field width]]; + column.minWidth = 10; + column.maxWidth = 2000; + column.width = field.width; [articleList addTableColumn:column]; - [column release]; } } @@ -650,9 +630,9 @@ -(void)updateVisibleColumns [articleList selectRowIndexes:selArray byExtendingSelection:NO]; if (tableLayout == MA_Layout_Report) - [articleList setAutosaveName:@"Vienna3ReportLayoutColumns"]; + articleList.autosaveName = @"Vienna3ReportLayoutColumns"; else - [articleList setAutosaveName:@"Vienna3CondensedLayoutColumns"]; + articleList.autosaveName = @"Vienna3CondensedLayoutColumns"; [articleList setAutosaveTableColumns:YES]; // Done @@ -667,20 +647,20 @@ -(void)saveTableSettings Preferences * prefs = [Preferences standardPreferences]; // Remember the current folder and article - NSString * guid = (currentSelectedRow >= 0 && currentSelectedRow < [[articleController allArticles] count]) ? [[[articleController allArticles] objectAtIndex:currentSelectedRow] guid] : @""; - [prefs setInteger:[articleController currentFolderId] forKey:MAPref_CachedFolderID]; - [prefs setString:guid forKey:MAPref_CachedArticleGUID]; + NSString * guid = [self.selectedArticle guid]; + [prefs setInteger:articleController.currentFolderId forKey:MAPref_CachedFolderID]; + [prefs setString:(guid != nil ? guid : @"") forKey:MAPref_CachedArticleGUID]; // An array we need for the settings NSMutableArray * dataArray = [[NSMutableArray alloc] init]; // Create the new columns - for (Field * field in [[Database sharedDatabase] arrayOfFields]) + for (Field * field in [[Database sharedManager] arrayOfFields]) { - [dataArray addObject:[field name]]; - [dataArray addObject:[NSNumber numberWithBool:[field visible]]]; - [dataArray addObject:[NSNumber numberWithInt:[field width]]]; + [dataArray addObject:field.name]; + [dataArray addObject:@(field.visible)]; + [dataArray addObject:@(field.width)]; } // Save these to the preferences @@ -690,7 +670,6 @@ -(void)saveTableSettings [self saveSplitSettingsForLayout]; // We're done - [dataArray release]; } /* setTableViewFont @@ -699,24 +678,21 @@ -(void)saveTableSettings */ -(void)setTableViewFont { - [articleListFont release]; - [articleListUnreadFont release]; Preferences * prefs = [Preferences standardPreferences]; - articleListFont = [[NSFont fontWithName:[prefs articleListFont] size:[prefs articleListFontSize]] retain]; + articleListFont = [NSFont fontWithName:prefs.articleListFont size:prefs.articleListFontSize]; articleListUnreadFont = [prefs boolForKey:MAPref_ShowUnreadArticlesInBold] ? [[NSFontManager sharedFontManager] convertWeight:YES ofFont:articleListFont] : articleListFont; - [articleListUnreadFont retain]; - - [reportCellDict setObject:articleListFont forKey:NSFontAttributeName]; - [unreadReportCellDict setObject:articleListUnreadFont forKey:NSFontAttributeName]; - - [topLineDict setObject:articleListFont forKey:NSFontAttributeName]; - [unreadTopLineDict setObject:articleListUnreadFont forKey:NSFontAttributeName]; - [middleLineDict setObject:articleListFont forKey:NSFontAttributeName]; - [linkLineDict setObject:articleListFont forKey:NSFontAttributeName]; - [bottomLineDict setObject:articleListFont forKey:NSFontAttributeName]; - [selectionDict setObject:articleListFont forKey:NSFontAttributeName]; - [unreadTopLineSelectionDict setObject:articleListUnreadFont forKey:NSFontAttributeName]; + + reportCellDict[NSFontAttributeName] = articleListFont; + unreadReportCellDict[NSFontAttributeName] = articleListUnreadFont; + + topLineDict[NSFontAttributeName] = articleListFont; + unreadTopLineDict[NSFontAttributeName] = articleListUnreadFont; + middleLineDict[NSFontAttributeName] = articleListFont; + linkLineDict[NSFontAttributeName] = articleListFont; + bottomLineDict[NSFontAttributeName] = articleListFont; + selectionDict[NSFontAttributeName] = articleListFont; + unreadTopLineSelectionDict[NSFontAttributeName] = articleListUnreadFont; [self updateArticleListRowHeight]; } @@ -728,27 +704,27 @@ -(void)setTableViewFont */ -(void)updateArticleListRowHeight { - Database * db = [Database sharedDatabase]; - float height = [[APPCONTROLLER layoutManager] defaultLineHeightForFont:articleListFont]; - int numberOfRowsInCell; + Database * db = [Database sharedManager]; + CGFloat height = [APPCONTROLLER.layoutManager defaultLineHeightForFont:articleListFont]; + NSInteger numberOfRowsInCell; if (tableLayout == MA_Layout_Report) numberOfRowsInCell = 1; else { numberOfRowsInCell = 0; - if ([[db fieldByName:MA_Field_Subject] visible]) + if ([db fieldByName:MA_Field_Subject].visible) ++numberOfRowsInCell; - if ([[db fieldByName:MA_Field_Folder] visible] || [[db fieldByName:MA_Field_Date] visible] || [[db fieldByName:MA_Field_Author] visible]) + if ([db fieldByName:MA_Field_Folder].visible || [db fieldByName:MA_Field_Date].visible || [db fieldByName:MA_Field_Author].visible) ++numberOfRowsInCell; - if ([[db fieldByName:MA_Field_Link] visible]) + if ([db fieldByName:MA_Field_Link].visible) ++numberOfRowsInCell; - if ([[db fieldByName:MA_Field_Summary] visible]) + if ([db fieldByName:MA_Field_Summary].visible) ++numberOfRowsInCell; if (numberOfRowsInCell == 0) ++numberOfRowsInCell; } - [articleList setRowHeight:(height + 2.0f) * (float)numberOfRowsInCell]; + articleList.rowHeight = (height + 2.0f) * (CGFloat)numberOfRowsInCell; } /* showSortDirection @@ -756,14 +732,14 @@ -(void)updateArticleListRowHeight */ -(void)showSortDirection { - NSString * sortColumnIdentifier = [articleController sortColumnIdentifier]; + NSString * sortColumnIdentifier = articleController.sortColumnIdentifier; - for (NSTableColumn * column in [articleList tableColumns]) + for (NSTableColumn * column in articleList.tableColumns) { - if ([[column identifier] isEqualToString:sortColumnIdentifier]) + if ([column.identifier isEqualToString:sortColumnIdentifier]) { - NSString * imageName = ([[[[Preferences standardPreferences] articleSortDescriptors] objectAtIndex:0] ascending]) ? @"NSAscendingSortIndicator" : @"NSDescendingSortIndicator"; - [articleList setHighlightedTableColumn:column]; + NSString * imageName = ([[Preferences standardPreferences].articleSortDescriptors[0] ascending]) ? @"NSAscendingSortIndicator" : @"NSDescendingSortIndicator"; + articleList.highlightedTableColumn = column; [articleList setIndicatorImage:[NSImage imageNamed:imageName] inTableColumn:column]; } else @@ -775,25 +751,26 @@ -(void)showSortDirection } /* scrollToArticle - * Moves the selection to the specified article. Returns YES if we found the - * article, NO otherwise. + * Moves the selection to the specified article. */ --(BOOL)scrollToArticle:(NSString *)guid +-(void)scrollToArticle:(NSString *)guid { - int rowIndex = 0; - BOOL found = NO; - - for (Article * thisArticle in [articleController allArticles]) + if (guid != nil) { - if ([[thisArticle guid] isEqualToString:guid]) + NSInteger rowIndex = 0; + for (Article * thisArticle in articleController.allArticles) { - [self makeRowSelectedAndVisible:rowIndex]; - found = YES; - break; + if ([thisArticle.guid isEqualToString:guid]) + { + [self makeRowSelectedAndVisible:rowIndex]; + return; + } + ++rowIndex; } - ++rowIndex; } - return found; + + [articleList deselectAll:self]; + [self refreshArticleAtCurrentRow]; } /* mainView @@ -815,14 +792,9 @@ -(WebView *)webView /* canDeleteMessageAtRow * Returns YES if the message at the specified row can be deleted, otherwise NO. */ --(BOOL)canDeleteMessageAtRow:(int)row +-(BOOL)canDeleteMessageAtRow:(NSInteger)row { - if ((row >= 0) && (row < [[articleController allArticles] count])) - { - Article * article = [[articleController allArticles] objectAtIndex:row]; - return (article != nil) && ![[Database sharedDatabase] readOnly] && [[articleList window] isVisible]; - } - return NO; + return articleList.window.visible && (self.selectedArticle != nil) && ![Database sharedManager].readOnly; } /* canGoForward @@ -830,7 +802,7 @@ -(BOOL)canDeleteMessageAtRow:(int)row */ -(BOOL)canGoForward { - return [articleController canGoForward]; + return articleController.canGoForward; } /* canGoBack @@ -838,7 +810,7 @@ -(BOOL)canGoForward */ -(BOOL)canGoBack { - return [articleController canGoBack]; + return articleController.canGoBack; } /* handleGoForward @@ -847,7 +819,6 @@ -(BOOL)canGoBack -(IBAction)handleGoForward:(id)sender { [articleController goForward]; - [[NSApp mainWindow] makeFirstResponder:([self selectedArticle] != nil) ? articleList : [foldersTree mainView]]; } /* handleGoBack @@ -856,7 +827,6 @@ -(IBAction)handleGoForward:(id)sender -(IBAction)handleGoBack:(id)sender { [articleController goBack]; - [[NSApp mainWindow] makeFirstResponder:([self selectedArticle] != nil) ? articleList : [foldersTree mainView]]; } - (BOOL)acceptsFirstResponder @@ -868,7 +838,7 @@ - (BOOL)acceptsFirstResponder * Support special key codes. If we handle the key, return YES otherwise * return NO to allow the framework to pass it on for default processing. */ --(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger )flags +-(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger)flags { return [controller handleKeyDown:keyChar withFlags:flags]; } @@ -878,7 +848,8 @@ -(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger )flags */ -(Article *)selectedArticle { - return (currentSelectedRow >= 0 && currentSelectedRow < [[articleController allArticles] count]) ? [[articleController allArticles] objectAtIndex:currentSelectedRow] : nil; + NSInteger currentSelectedRow = articleList.selectedRow; + return (currentSelectedRow >= 0 && currentSelectedRow < articleController.allArticles.count) ? articleController.allArticles[currentSelectedRow] : nil; } /* printDocument @@ -894,8 +865,6 @@ -(void)printDocument:(id)sender */ -(void)setError:(NSError *)newError { - [newError retain]; - [lastError release]; lastError = newError; } @@ -905,26 +874,18 @@ -(void)setError:(NSError *)newError -(void)handleArticleListFontChange:(NSNotification *)note { [self setTableViewFont]; - if (self == [articleController mainArticleView]) + if (self == articleController.mainArticleView) { [articleList reloadData]; } } --(void)handleArticleListStateChange:(NSNotification *)note -{ - if (self == [articleController mainArticleView]) - { - [self refreshCurrentFolder]; - } -} - /* handleLoadFullHTMLChange * Called when the user changes the folder setting to load the article in full HTML. */ -(void)handleLoadFullHTMLChange:(NSNotification *)note { - if (self == [articleController mainArticleView]) + if (self == articleController.mainArticleView) [self refreshArticlePane]; } @@ -933,10 +894,10 @@ -(void)handleLoadFullHTMLChange:(NSNotification *)note */ -(void)handleReadingPaneChange:(NSNotificationCenter *)nc { - if (self == [articleController mainArticleView]) + if (self == articleController.mainArticleView) { [self saveSplitSettingsForLayout]; - [self setOrientation:[[Preferences standardPreferences] layout]]; + [self setOrientation:[Preferences standardPreferences].layout]; [self updateVisibleColumns]; [articleList reloadData]; } @@ -950,7 +911,7 @@ -(void)loadSplitSettingsForLayout NSString * splitPrefsName = (tableLayout == MA_Layout_Report) ? @"SplitView2ReportLayout" : @"SplitView2CondensedLayout"; - [splitView2 setLayout:[[Preferences standardPreferences] objectForKey:splitPrefsName]]; + splitView2.xlayout = [[Preferences standardPreferences] objectForKey:splitPrefsName]; } /* saveSplitSettingsForLayout @@ -961,136 +922,75 @@ -(void)saveSplitSettingsForLayout NSString * splitPrefsName = (tableLayout == MA_Layout_Report) ? @"SplitView2ReportLayout" : @"SplitView2CondensedLayout"; - [[Preferences standardPreferences] setObject:[splitView2 layout] forKey:splitPrefsName]; + [[Preferences standardPreferences] setObject:splitView2.xlayout forKey:splitPrefsName]; } /* setOrientation * Adjusts the article view orientation and updates the article list row * height to accommodate the summary view */ --(void)setOrientation:(int)newLayout +-(void)setOrientation:(NSInteger)newLayout { isChangingOrientation = YES; tableLayout = newLayout; - [splitView2 setVertical:(newLayout == MA_Layout_Condensed)]; + splitView2.vertical = (newLayout == MA_Layout_Condensed); [self loadSplitSettingsForLayout]; [splitView2 display]; isChangingOrientation = NO; } -/* tableLayout - * Returns the active table layout. - */ --(int)tableLayout -{ - return tableLayout; -} - /* makeRowSelectedAndVisible * Selects the specified row in the table and makes it visible by * scrolling it to the center of the table. */ --(void)makeRowSelectedAndVisible:(int)rowIndex +-(void)makeRowSelectedAndVisible:(NSInteger)rowIndex { - if ([[articleController allArticles] count] == 0u) + if (articleController.allArticles.count == 0u) { - currentSelectedRow = -1; [articleList deselectAll:self]; } - else if (rowIndex == currentSelectedRow) - [self refreshArticleAtCurrentRow]; - else + else if (rowIndex != [articleList selectedRow]) { [articleList selectRowIndexes:[NSIndexSet indexSetWithIndex:rowIndex] byExtendingSelection:NO]; - if (currentSelectedRow == -1 || blockSelectionHandler) - { - currentSelectedRow = rowIndex; - [self refreshImmediatelyArticleAtCurrentRow]; - } - int pageSize = [articleList rowsInRect:[articleList visibleRect]].length; - int lastRow = [articleList numberOfRows] - 1; - int visibleRow = currentSelectedRow + (pageSize / 2); + // make sure our current selection is visible + [articleList scrollRowToVisible:rowIndex]; + // then try to center it in the list + NSInteger pageSize = [articleList rowsInRect:articleList.visibleRect].length; + NSInteger lastRow = articleList.numberOfRows - 1; + NSInteger visibleRow = rowIndex + (pageSize / 2); if (visibleRow > lastRow) visibleRow = lastRow; - [articleList scrollRowToVisible:currentSelectedRow]; [articleList scrollRowToVisible:visibleRow]; } } -/* displayFirstUnread - * Locate the first unread article. +/* + * viewNextUnreadInFolder + * Search the following unread article in the current folder + * and select it if found */ --(void)displayFirstUnread +-(BOOL)viewNextUnreadInFolder { - // Mark the current article read. - [self markCurrentRead:nil]; - - // If there are any unread articles then select the first one in the - // first folder. - if ([[Database sharedDatabase] countOfUnread] > 0) - { - guidOfArticleToSelect = nil; - - // Get the first folder with unread articles. - int firstFolderWithUnread = [foldersTree firstFolderWithUnread]; - - // Select the folder in the tree view. - [foldersTree selectFolder:firstFolderWithUnread]; - - // Now select the first unread article. - [self selectFirstUnreadInFolder]; - } -} - -/* displayNextUnread - * Locate the next unread article from the current article onward. - */ --(void)displayNextUnread -{ - // Save the value of currentSelectedRow. - int currentRow = currentSelectedRow; - - // Mark the current article read. - [self markCurrentRead:nil]; - - // Scan the current folder from the selection forward. If nothing found, try - // other folders until we come back to ourselves. - if (([[Database sharedDatabase] countOfUnread] > 0) && (![self viewNextUnreadInCurrentFolder:currentRow])) - { - int nextFolderWithUnread = [foldersTree nextFolderWithUnread:[articleController currentFolderId]]; - if (nextFolderWithUnread != -1) - { - if (nextFolderWithUnread == [articleController currentFolderId]) - { - [self viewNextUnreadInCurrentFolder:-1]; - } - else - { - guidOfArticleToSelect = nil; - [foldersTree selectFolder:nextFolderWithUnread]; - [self selectFirstUnreadInFolder]; - } - } - } + return [self viewNextUnreadInCurrentFolder:([articleList selectedRow] + 1)]; } /* viewNextUnreadInCurrentFolder * Select the next unread article in the current folder after currentRow. */ --(BOOL)viewNextUnreadInCurrentFolder:(int)currentRow +-(BOOL)viewNextUnreadInCurrentFolder:(NSInteger)currentRow { if (currentRow < 0) currentRow = 0; - NSArray * allArticles = [articleController allArticles]; - int totalRows = [allArticles count]; + NSArray * allArticles = articleController.allArticles; + NSInteger totalRows = allArticles.count; Article * theArticle; while (currentRow < totalRows) { - theArticle = [allArticles objectAtIndex:currentRow]; - if (![theArticle isRead]) + theArticle = allArticles[currentRow]; + if (!theArticle.read) { [self makeRowSelectedAndVisible:currentRow]; return YES; @@ -1105,20 +1005,20 @@ -(BOOL)viewNextUnreadInCurrentFolder:(int)currentRow */ -(void)showEnclosureView { - if ([stdEnclosureView superview] == nil) + if (stdEnclosureView.superview == nil) { NSRect enclosureRect; NSRect mainRect; - mainRect = [articleText bounds]; - enclosureRect = [stdEnclosureView bounds]; + mainRect = articleText.bounds; + enclosureRect = stdEnclosureView.bounds; enclosureRect.size.width = mainRect.size.width; mainRect.size.height -= enclosureRect.size.height; mainRect.origin.y += enclosureRect.size.height; - [[articleText superview] addSubview:stdEnclosureView]; - [articleText setFrame:mainRect]; - [stdEnclosureView setFrame:enclosureRect]; + [articleText.superview addSubview:stdEnclosureView]; + articleText.frame = mainRect; + stdEnclosureView.frame = enclosureRect; } } @@ -1127,52 +1027,34 @@ -(void)showEnclosureView */ -(void)hideEnclosureView { - if ([stdEnclosureView superview] != nil) + if (stdEnclosureView.superview != nil) { NSRect enclosureRect; NSRect mainRect; - mainRect = [articleText bounds]; - enclosureRect = [stdEnclosureView bounds]; + mainRect = articleText.bounds; + enclosureRect = stdEnclosureView.bounds; mainRect.size.height += enclosureRect.size.height; [stdEnclosureView removeFromSuperview]; - [articleText setFrame:mainRect]; + articleText.frame = mainRect; } } /* selectFirstUnreadInFolder * Moves the selection to the first unread article in the current article list or the - * last article if the folder has no unread articles. + * first article if the folder has no unread articles. */ --(void)selectFirstUnreadInFolder +-(BOOL)selectFirstUnreadInFolder { - if (![self viewNextUnreadInCurrentFolder:-1]) + BOOL result = [self viewNextUnreadInCurrentFolder:-1]; + if (!result) { - int count = [[articleController allArticles] count]; + NSInteger count = articleController.allArticles.count; if (count > 0) - [self makeRowSelectedAndVisible:[[[[Preferences standardPreferences] articleSortDescriptors] objectAtIndex:0] ascending] ? 0 : count - 1]; - } -} - -/* selectFolderAndArticle - * Select a folder and select a specified article within the folder. - */ --(void)selectFolderAndArticle:(int)folderId guid:(NSString *)guid -{ - // If we're in the right folder, easy enough. - if (folderId == [articleController currentFolderId]) - [self scrollToArticle:guid]; - else - { - // Otherwise we force the folder to be selected and seed guidOfArticleToSelect - // so that after handleFolderSelection has been invoked, it will select the - // requisite article on our behalf. - currentSelectedRow = -1; - [guidOfArticleToSelect release]; - guidOfArticleToSelect = [guid retain]; - [foldersTree selectFolder:folderId]; + [self makeRowSelectedAndVisible:0]; } + return result; } /* viewLink @@ -1187,18 +1069,18 @@ -(NSString *)viewLink /* performFindPanelAction * Implement the search action. */ --(void)performFindPanelAction:(int)actionTag +-(void)performFindPanelAction:(NSInteger)actionTag { - [self refreshFolder:MA_Refresh_ReloadFromDatabase]; + [articleController reloadArrayOfArticles]; // This action is send continuously by the filter field, so make sure not the mark read while searching - if (currentSelectedRow < 0 && [[articleController allArticles] count] > 0 ) + if ([articleList selectedRow] < 0 && articleController.allArticles.count > 0 ) { BOOL shouldSelectArticle = YES; - if ([[Preferences standardPreferences] markReadInterval] > 0.0f) + if ([Preferences standardPreferences].markReadInterval > 0.0f) { - Article * article = [[articleController allArticles] objectAtIndex:0u]; - if (![article isRead]) + Article * article = articleController.allArticles[0u]; + if (!article.read) shouldSelectArticle = NO; } if (shouldSelectArticle) @@ -1206,94 +1088,59 @@ -(void)performFindPanelAction:(int)actionTag } } -/* refreshCurrentFolder - * Reload the current folder after a refresh. - */ --(void)refreshCurrentFolder -{ - // Preserve the article that the user might currently be reading. - Preferences * prefs = [Preferences standardPreferences]; - if (([prefs refreshFrequency] > 0) && - (currentSelectedRow >= 0 && currentSelectedRow < (int)[[articleController allArticles] count])) - { - Article * currentArticle = [[articleController allArticles] objectAtIndex:currentSelectedRow]; - if (![currentArticle isDeleted]) - [articleController setArticleToPreserve:currentArticle]; - } - - [self refreshFolder:MA_Refresh_ReloadFromDatabase]; -} - /* refreshFolder * Refreshes the current folder by applying the current sort or thread * logic and redrawing the article list. The selected article is preserved * and restored on completion of the refresh. */ --(void)refreshFolder:(int)refreshFlag +-(void)refreshFolder:(NSInteger)refreshFlag { - NSArray * allArticles = [articleController allArticles]; - NSString * guid = nil; + blockSelectionHandler = YES; + + Article * currentSelectedArticle = self.selectedArticle; + + switch (refreshFlag) + { + case MA_Refresh_RedrawList: + break; + case MA_Refresh_ReapplyFilter: + [articleController refilterArrayOfArticles]; + [articleController sortArticles]; + break; + case MA_Refresh_SortAndRedraw: + [articleController sortArticles]; + break; + } - [markReadTimer invalidate]; - [markReadTimer release]; - markReadTimer = nil; - - if (refreshFlag == MA_Refresh_SortAndRedraw) - blockSelectionHandler = blockMarkRead = YES; - if (currentSelectedRow >= 0 && currentSelectedRow < [allArticles count]) - guid = [[[allArticles objectAtIndex:currentSelectedRow] guid] retain]; - if (refreshFlag == MA_Refresh_ReloadFromDatabase) - [articleController reloadArrayOfArticles]; - else if (refreshFlag == MA_Refresh_ReapplyFilter) - [articleController refilterArrayOfArticles]; - if (refreshFlag != MA_Refresh_RedrawList) - [articleController sortArticles]; - [self showSortDirection]; [articleList reloadData]; - if (guid != nil) + [self scrollToArticle:currentSelectedArticle.guid]; + + blockSelectionHandler = NO; +} + +/* startLoadIndicator + * add the indicator of articles' data being loaded + */ +-(void)startLoadIndicator +{ + if (progressIndicator == nil) { - // To avoid upsetting the current displayed article after a refresh, we check to see if the selection has stayed - // the same and the GUID of the article at the selection is the same. - allArticles = [articleController allArticles]; - Article * currentArticle = (currentSelectedRow >= 0 && currentSelectedRow < (int)[allArticles count]) ? [allArticles objectAtIndex:currentSelectedRow] : nil; - BOOL isUnchanged = (currentArticle != nil) && [guid isEqualToString:[currentArticle guid]]; - if (!isUnchanged) - { - if (![self scrollToArticle:guid]) - { - currentSelectedRow = -1; - [articleList deselectAll:self]; - [self refreshArticlePane]; - } - } - else if (refreshFlag == MA_Refresh_ReloadFromDatabase && - [[Preferences standardPreferences] boolForKey:MAPref_CheckForUpdatedArticles] && - [currentArticle isRevised] && ![currentArticle isRead]) // The article may have been updated, so refresh the article pane. - [self refreshArticlePane]; + progressIndicator = [[NSProgressIndicator alloc] initWithFrame:articleList.visibleRect]; + progressIndicator.style = NSProgressIndicatorSpinningStyle; + progressIndicator.displayedWhenStopped = NO; + [articleList addSubview:progressIndicator]; } - else - currentSelectedRow = -1; - if ((refreshFlag == MA_Refresh_ReapplyFilter || refreshFlag == MA_Refresh_ReloadFromDatabase) && (currentSelectedRow == -1) && ([[NSApp mainWindow] firstResponder] == articleList)) - [[NSApp mainWindow] makeFirstResponder:[foldersTree mainView]]; - else if (refreshFlag == MA_Refresh_SortAndRedraw) - blockSelectionHandler = blockMarkRead = NO; - [guid release]; + [progressIndicator startAnimation:self]; } -/* selectArticleAfterReload - * Sets the selection in the article list after the list is reloaded. The value of guidOfArticleToSelect - * is either MA_Select_None, meaning no selection, MA_Select_Unread meaning select the first unread - * article from the beginning (after sorting is applied) or it is the ID of a specific article to be - * selected. +/* stopLoadIndicator + * remove the indicator of articles loading */ --(void)selectArticleAfterReload +-(void)stopLoadIndicator { - if (guidOfArticleToSelect == nil) - [self selectFirstUnreadInFolder]; - else - [self scrollToArticle:guidOfArticleToSelect]; - [guidOfArticleToSelect release]; - guidOfArticleToSelect = nil; + [progressIndicator stopAnimation:self]; + [progressIndicator removeFromSuperviewWithoutNeedingDisplay]; + progressIndicator = nil; } /* menuWillAppear @@ -1302,36 +1149,17 @@ -(void)selectArticleAfterReload */ -(void)tableView:(ExtendedTableView *)tableView menuWillAppear:(NSEvent *)theEvent { - int row = [articleList rowAtPoint:[articleList convertPoint:[theEvent locationInWindow] fromView:nil]]; + NSInteger row = [articleList rowAtPoint:[articleList convertPoint:theEvent.locationInWindow fromView:nil]]; if (row >= 0) { // Select the row under the cursor if it isn't already selected - if ([articleList numberOfSelectedRows] <= 1) + if (articleList.numberOfSelectedRows <= 1) { - blockSelectionHandler = YES; [articleList selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO]; - currentSelectedRow = row; - [self refreshArticleAtCurrentRow]; - blockSelectionHandler = NO; } } } -/* selectFolderWithFilter - * Switches to the specified folder and displays articles filtered by whatever is in - * the search field. - */ --(void)selectFolderWithFilter:(int)newFolderId -{ - [articleList deselectAll:self]; - currentSelectedRow = -1; - [articleList reloadData]; - if (guidOfArticleToSelect == nil) - [articleList scrollRowToVisible:0]; - else - [self selectArticleAfterReload]; -} - /* refreshImmediatelyArticleAtCurrentRow * Refreshes the article at the current selected row. */ @@ -1339,24 +1167,16 @@ -(void)refreshImmediatelyArticleAtCurrentRow { [self refreshArticlePane]; - // If we mark read after an interval, start the timer here. - if (currentSelectedRow >= 0 && currentSelectedRow < [[articleController allArticles] count]) - { - Article * theArticle = [[articleController allArticles] objectAtIndex:currentSelectedRow]; - if (![theArticle isRead] && !blockMarkRead) - { - [markReadTimer invalidate]; - [markReadTimer release]; - markReadTimer = nil; - - float interval = [[Preferences standardPreferences] markReadInterval]; - if (interval > 0 && !isAppInitialising) - markReadTimer = [[NSTimer scheduledTimerWithTimeInterval:(double)interval - target:self - selector:@selector(markCurrentRead:) - userInfo:nil - repeats:NO] retain]; - } + Article * theArticle = self.selectedArticle; + if (theArticle != nil && !theArticle.read) + { + CGFloat interval = [Preferences standardPreferences].markReadInterval; + if (interval > 0 && !isAppInitialising) + markReadTimer = [NSTimer scheduledTimerWithTimeInterval:(double)interval + target:self + selector:@selector(markCurrentRead:) + userInfo:nil + repeats:NO]; } } @@ -1365,20 +1185,18 @@ -(void)refreshImmediatelyArticleAtCurrentRow */ -(void)refreshArticleAtCurrentRow { - if (currentSelectedRow < 0) + Article * article = self.selectedArticle; + if (article == nil) { [articleText clearHTML]; [self hideEnclosureView]; } else { - NSArray * allArticles = [articleController allArticles]; - NSAssert(currentSelectedRow < (int)[allArticles count], @"Out of range row index received"); - [self refreshImmediatelyArticleAtCurrentRow]; // Add this to the backtrack list - NSString * guid = [[allArticles objectAtIndex:currentSelectedRow] guid]; + NSString * guid = [article guid]; [articleController addBacktrack:guid]; } } @@ -1388,7 +1206,7 @@ -(void)refreshArticleAtCurrentRow */ -(void)handleRefreshArticle:(NSNotification *)nc { - if (!isAppInitialising) + if (self == articleController.mainArticleView && !isAppInitialising) [self refreshArticlePane]; } @@ -1400,7 +1218,6 @@ -(void)clearCurrentURL // If we already have an URL release it. if (currentURL) { - [currentURL release]; currentURL = nil; } } @@ -1418,7 +1235,7 @@ -(void)loadArticleLink:(NSString *) articleLink isLoadingHTMLArticle = YES; // Load the actual link. - [articleText setMainFrameURL:articleLink]; + articleText.mainFrameURL = articleLink; // Clear the current URL. [self clearCurrentURL]; @@ -1446,9 +1263,9 @@ -(NSURL *)url */ -(void)refreshArticlePane { - NSArray * msgArray = [self markedArticleRange]; + NSArray * msgArray = self.markedArticleRange; - if ([msgArray count] == 0) + if (msgArray.count == 0) { // Clear the current URL. [self clearCurrentURL]; @@ -1461,9 +1278,9 @@ -(void)refreshArticlePane } else { - Article * firstArticle = [msgArray objectAtIndex:0]; - Folder * folder = [[Database sharedDatabase] folderFromID:[firstArticle folderId]]; - if ([folder loadsFullHTML] && [msgArray count] == 1) + Article * firstArticle = msgArray[0]; + Folder * folder = [[Database sharedManager] folderFromID:firstArticle.folderId]; + if (folder.loadsFullHTML && msgArray.count == 1) { // Remember we have a full HTML page so we can setup the context menus // appropriately. @@ -1477,7 +1294,7 @@ -(void)refreshArticlePane // performSelector:withObject:afterDelay: here so that this link load gets // queued up into the event loop, otherwise the WebView class won't draw the // clearing of the HTML before this new link gets loaded. - [self performSelector: @selector(loadArticleLink:) withObject:[firstArticle link] afterDelay:0.0]; + [self performSelector: @selector(loadArticleLink:) withObject:firstArticle.link afterDelay:0.0]; } else { @@ -1495,23 +1312,23 @@ -(void)refreshArticlePane isLoadingHTMLArticle = NO; // Set the article to the HTML from the RSS feed. - [articleText setHTML:htmlText withBase:SafeString([folder feedURL])]; + [articleText setHTML:htmlText]; } } // Show the enclosure view if just one article is selected and it has an // enclosure. - if ([msgArray count] != 1) + if (msgArray.count != 1) [self hideEnclosureView]; else { - Article * oneArticle = [msgArray objectAtIndex:0]; - if (![oneArticle hasEnclosure]) + Article * oneArticle = msgArray[0]; + if (!oneArticle.hasEnclosure) [self hideEnclosureView]; else { [self showEnclosureView]; - [stdEnclosureView setEnclosureFile:[oneArticle enclosure]]; + [stdEnclosureView setEnclosureFile:oneArticle.enclosure]; } } } @@ -1521,12 +1338,10 @@ -(void)refreshArticlePane */ -(void)markCurrentRead:(NSTimer *)aTimer { - NSArray * allArticles = [articleController allArticles]; - if (currentSelectedRow >=0 && currentSelectedRow < (int)[allArticles count] && ![[Database sharedDatabase] readOnly]) + Article * theArticle = self.selectedArticle; + if (theArticle != nil && !theArticle.read && ![Database sharedManager].readOnly) { - Article * theArticle = [allArticles objectAtIndex:currentSelectedRow]; - if (![theArticle isRead]) - [articleController markReadByArray:[NSArray arrayWithObject:theArticle] readFlag:YES]; + [articleController markReadByArray:@[theArticle] readFlag:YES]; } } @@ -1536,7 +1351,7 @@ -(void)markCurrentRead:(NSTimer *)aTimer */ -(NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView { - return [[articleController allArticles] count]; + return articleController.allArticles.count; } /* objectValueForTableColumn [datasource] @@ -1545,36 +1360,36 @@ -(NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView */ -(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex { - Database * db = [Database sharedDatabase]; - NSArray * allArticles = [articleController allArticles]; + Database * db = [Database sharedManager]; + NSArray * allArticles = articleController.allArticles; Article * theArticle; - if(rowIndex < 0 || rowIndex >= [allArticles count]) + if(rowIndex < 0 || rowIndex >= allArticles.count) return nil; - theArticle = [allArticles objectAtIndex:rowIndex]; - NSString * identifier = [aTableColumn identifier]; + theArticle = allArticles[rowIndex]; + NSString * identifier = aTableColumn.identifier; if ([identifier isEqualToString:MA_Field_Read]) { - if (![theArticle isRead]) - return ([theArticle isRevised]) ? [NSImage imageNamed:@"revised.tiff"] : [NSImage imageNamed:@"unread.tiff"]; + if (!theArticle.read) + return (theArticle.revised) ? [NSImage imageNamed:@"revised.tiff"] : [NSImage imageNamed:@"unread.tiff"]; return [NSImage imageNamed:@"alphaPixel.tiff"]; } if ([identifier isEqualToString:MA_Field_Flagged]) { - if ([theArticle isFlagged]) + if (theArticle.flagged) return [NSImage imageNamed:@"flagged.tiff"]; return [NSImage imageNamed:@"alphaPixel.tiff"]; } if ([identifier isEqualToString:MA_Field_Comments]) { - if ([theArticle hasComments]) + if (theArticle.hasComments) return [NSImage imageNamed:@"comments.tiff"]; return [NSImage imageNamed:@"alphaPixel.tiff"]; } if ([identifier isEqualToString:MA_Field_HasEnclosure]) { - if ([theArticle hasEnclosure]) + if (theArticle.hasEnclosure) return [NSImage imageNamed:@"enclosure.tiff"]; return [NSImage imageNamed:@"alphaPixel.tiff"]; } @@ -1582,39 +1397,39 @@ -(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColum NSMutableAttributedString * theAttributedString; if ([identifier isEqualToString:MA_Field_Headlines]) { - theAttributedString = [[NSMutableAttributedString alloc] init]; - BOOL isSelectedRow = [aTableView isRowSelected:rowIndex] && ([[NSApp mainWindow] firstResponder] == aTableView); + theAttributedString = [[NSMutableAttributedString alloc] initWithString:@""]; + BOOL isSelectedRow = [aTableView isRowSelected:rowIndex] && (NSApp.mainWindow.firstResponder == aTableView); - if ([[db fieldByName:MA_Field_Subject] visible]) + if ([db fieldByName:MA_Field_Subject].visible) { NSDictionary * topLineDictPtr; - if ([theArticle isRead]) + if (theArticle.read) topLineDictPtr = (isSelectedRow ? selectionDict : topLineDict); else topLineDictPtr = (isSelectedRow ? unreadTopLineSelectionDict : unreadTopLineDict); - NSString * topString = [NSString stringWithFormat:@"%@", [theArticle title]]; + NSString * topString = [NSString stringWithFormat:@"%@", theArticle.title]; NSMutableAttributedString * topAttributedString = [[NSMutableAttributedString alloc] initWithString:topString attributes:topLineDictPtr]; - [topAttributedString fixFontAttributeInRange:NSMakeRange(0u, [topAttributedString length])]; - [theAttributedString appendAttributedString:[topAttributedString autorelease]]; + [topAttributedString fixFontAttributeInRange:NSMakeRange(0u, topAttributedString.length)]; + [theAttributedString appendAttributedString:topAttributedString]; } // Add the summary line that appears below the title. - if ([[db fieldByName:MA_Field_Summary] visible]) + if ([db fieldByName:MA_Field_Summary].visible) { - NSString * summaryString = [theArticle summary]; - int maxSummaryLength = MIN([summaryString length], 150); + NSString * summaryString = theArticle.summary; + NSInteger maxSummaryLength = MIN([summaryString length], 150); NSString * middleString = [NSString stringWithFormat:@"\n%@", [summaryString substringToIndex:maxSummaryLength]]; NSDictionary * middleLineDictPtr = (isSelectedRow ? selectionDict : middleLineDict); NSMutableAttributedString * middleAttributedString = [[NSMutableAttributedString alloc] initWithString:middleString attributes:middleLineDictPtr]; - [middleAttributedString fixFontAttributeInRange:NSMakeRange(0u, [middleAttributedString length])]; - [theAttributedString appendAttributedString:[middleAttributedString autorelease]]; + [middleAttributedString fixFontAttributeInRange:NSMakeRange(0u, middleAttributedString.length)]; + [theAttributedString appendAttributedString:middleAttributedString]; } // Add the link line that appears below the summary and title. - if ([[db fieldByName:MA_Field_Link] visible]) + if ([db fieldByName:MA_Field_Link].visible) { - NSString * articleLink = [theArticle link]; + NSString * articleLink = theArticle.link; if (articleLink != nil) { NSString * linkString = [NSString stringWithFormat:@"\n%@", articleLink]; @@ -1622,12 +1437,12 @@ -(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColum NSURL * articleURL = [NSURL URLWithString:articleLink]; if (articleURL != nil) { - linkLineDictPtr = [[linkLineDictPtr mutableCopy] autorelease]; - [linkLineDictPtr setObject:articleURL forKey:NSLinkAttributeName]; + linkLineDictPtr = [linkLineDictPtr mutableCopy]; + linkLineDictPtr[NSLinkAttributeName] = articleURL; } NSMutableAttributedString * linkAttributedString = [[NSMutableAttributedString alloc] initWithString:linkString attributes:linkLineDictPtr]; - [linkAttributedString fixFontAttributeInRange:NSMakeRange(0u, [linkAttributedString length])]; - [theAttributedString appendAttributedString:[linkAttributedString autorelease]]; + [linkAttributedString fixFontAttributeInRange:NSMakeRange(0u, linkAttributedString.length)]; + [theAttributedString appendAttributedString:linkAttributedString]; } } @@ -1636,73 +1451,73 @@ -(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColum NSMutableString * summaryString = [NSMutableString stringWithString:@""]; NSString * delimiter = @""; - if ([[db fieldByName:MA_Field_Folder] visible]) + if ([db fieldByName:MA_Field_Folder].visible) { - Folder * folder = [db folderFromID:[theArticle folderId]]; - [summaryString appendString:[folder name]]; + Folder * folder = [db folderFromID:theArticle.folderId]; + [summaryString appendFormat:@"%@", folder.name]; delimiter = @" - "; } - if ([[db fieldByName:MA_Field_Date] visible]) + if ([db fieldByName:MA_Field_Date].visible) { - NSCalendarDate * anDate = [[theArticle date] dateWithCalendarFormat:nil timeZone:nil]; - [summaryString appendFormat:@"%@%@", delimiter,[anDate friendlyDescription]]; + NSCalendarDate * anDate = [theArticle.date dateWithCalendarFormat:nil timeZone:nil]; + [summaryString appendFormat:@"%@%@", delimiter,anDate.friendlyDescription]; delimiter = @" - "; } - if ([[db fieldByName:MA_Field_Author] visible]) + if ([db fieldByName:MA_Field_Author].visible) { - if (![[theArticle author] isBlank]) - [summaryString appendFormat:@"%@%@", delimiter, [theArticle author]]; + if (!theArticle.author.blank) + [summaryString appendFormat:@"%@%@", delimiter, theArticle.author]; } if (![summaryString isEqualToString:@""]) summaryString = [NSMutableString stringWithFormat:@"\n%@", summaryString]; NSMutableAttributedString * summaryAttributedString = [[NSMutableAttributedString alloc] initWithString:summaryString attributes:bottomLineDictPtr]; - [summaryAttributedString fixFontAttributeInRange:NSMakeRange(0u, [summaryAttributedString length])]; - [theAttributedString appendAttributedString:[summaryAttributedString autorelease]]; - return [theAttributedString autorelease]; + [summaryAttributedString fixFontAttributeInRange:NSMakeRange(0u, summaryAttributedString.length)]; + [theAttributedString appendAttributedString:summaryAttributedString]; + return theAttributedString; } NSString * cellString; if ([identifier isEqualToString:MA_Field_Date]) { - NSDate * date = [theArticle date]; + NSDate * date = theArticle.date; NSCalendarDate * calDate = [date dateWithCalendarFormat:nil timeZone:nil]; - cellString = [calDate friendlyDescription]; + cellString = calDate.friendlyDescription; } else if ([identifier isEqualToString:MA_Field_Folder]) { - Folder * folder = [db folderFromID:[theArticle folderId]]; - cellString = [folder name]; + Folder * folder = [db folderFromID:theArticle.folderId]; + cellString = folder.name; } else if ([identifier isEqualToString:MA_Field_Author]) { - cellString = [theArticle author]; + cellString = theArticle.author; } else if ([identifier isEqualToString:MA_Field_Link]) { - cellString = [theArticle link]; + cellString = theArticle.link; } else if ([identifier isEqualToString:MA_Field_Subject]) { - cellString = [theArticle title]; + cellString = theArticle.title; } else if ([identifier isEqualToString:MA_Field_Summary]) { - cellString = [theArticle summary]; + cellString = theArticle.summary; } else if ([identifier isEqualToString:MA_Field_Enclosure]) { - cellString = [theArticle enclosure]; + cellString = theArticle.enclosure; } else { - cellString = nil; + cellString = @""; [NSException raise:@"ArticleListView unknown table column identifier exception" format:@"Unknown table column identifier: %@", identifier]; } - theAttributedString = [[NSMutableAttributedString alloc] initWithString:cellString attributes:([theArticle isRead] ? reportCellDict : unreadReportCellDict)]; - [theAttributedString fixFontAttributeInRange:NSMakeRange(0u, [theAttributedString length])]; - return [theAttributedString autorelease]; + theAttributedString = [[NSMutableAttributedString alloc] initWithString:SafeString(cellString) attributes:(theArticle.read ? reportCellDict : unreadReportCellDict)]; + [theAttributedString fixFontAttributeInRange:NSMakeRange(0u, theAttributedString.length)]; + return theAttributedString; } /* tableViewSelectionDidChange [delegate] @@ -1710,9 +1525,11 @@ -(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColum */ -(void)tableViewSelectionDidChange:(NSNotification *)aNotification { + [markReadTimer invalidate]; + markReadTimer = nil; + if (!blockSelectionHandler) { - currentSelectedRow = [articleList selectedRow]; [self refreshArticleAtCurrentRow]; } } @@ -1722,8 +1539,9 @@ -(void)tableViewSelectionDidChange:(NSNotification *)aNotification */ -(void)tableView:(NSTableView *)tableView didClickTableColumn:(NSTableColumn *)tableColumn { - NSString * columnName = [tableColumn identifier]; + NSString * columnName = tableColumn.identifier; [articleController sortByIdentifier:columnName]; + [self showSortDirection]; } /* tableViewColumnDidResize @@ -1734,13 +1552,13 @@ -(void)tableViewColumnDidResize:(NSNotification *)notification { if (!isInTableInit && !isAppInitialising && !isChangingOrientation) { - NSTableColumn * tableColumn = [[notification userInfo] objectForKey:@"NSTableColumn"]; - Field * field = [[Database sharedDatabase] fieldByName:[tableColumn identifier]]; - int oldWidth = [[[notification userInfo] objectForKey:@"NSOldWidth"] intValue]; + NSTableColumn * tableColumn = notification.userInfo[@"NSTableColumn"]; + Field * field = [[Database sharedManager] fieldByName:tableColumn.identifier]; + NSInteger oldWidth = [notification.userInfo[@"NSOldWidth"] integerValue]; - if (oldWidth != [tableColumn width]) + if (oldWidth != tableColumn.width) { - [field setWidth:[tableColumn width]]; + field.width = tableColumn.width; [self saveTableSettings]; } } @@ -1761,7 +1579,7 @@ -(BOOL)tableView:(NSTableView *)tv writeRows:(NSArray *)rows toPasteboard:(NSPas */ -(void)tableView:(NSTableView *)tv willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex { - NSString * columnIdentifer = [tableColumn identifier]; + NSString * columnIdentifer = tableColumn.identifier; BOOL isProgressColumn = NO; // We need to use a different column for condensed layout vs. table layout. @@ -1778,7 +1596,7 @@ -(void)tableView:(NSTableView *)tv willDisplayCell:(id)cell forTableColumn:(NSTa // displayed and removed as needed. if ([realCell respondsToSelector:@selector(setInProgress:forRow:)]) { - if (rowIndex == currentSelectedRow && isLoadingHTMLArticle) + if (rowIndex == [tv selectedRow] && isLoadingHTMLArticle) [realCell setInProgress:YES forRow:rowIndex]; else [realCell setInProgress:NO forRow:rowIndex]; @@ -1798,14 +1616,14 @@ -(BOOL)copyTableSelection:(NSArray *)rows toPasteboard:(NSPasteboard *)pboard NSMutableArray * arrayOfTitles = [[NSMutableArray alloc] init]; NSMutableString * fullHTMLText = [[NSMutableString alloc] init]; NSMutableString * fullPlainText = [[NSMutableString alloc] init]; - Database * db = [Database sharedDatabase]; - int count = [rows count]; - int index; + Database * db = [Database sharedManager]; + NSInteger count = rows.count; + NSInteger index; // Set up the pasteboard - [pboard declareTypes:[NSArray arrayWithObjects:MA_PBoardType_RSSItem, @"WebURLsWithTitlesPboardType", NSStringPboardType, NSHTMLPboardType, nil] owner:self]; + [pboard declareTypes:@[MA_PBoardType_RSSItem, @"WebURLsWithTitlesPboardType", NSStringPboardType, NSHTMLPboardType] owner:self]; if (count == 1) - [pboard addTypes:[NSArray arrayWithObjects:MA_PBoardType_url, MA_PBoardType_urln, NSURLPboardType, nil] owner:self]; + [pboard addTypes:@[MA_PBoardType_url, MA_PBoardType_urln, NSURLPboardType] owner:self]; // Open the HTML string [fullHTMLText appendString:@""]; @@ -1813,12 +1631,12 @@ -(BOOL)copyTableSelection:(NSArray *)rows toPasteboard:(NSPasteboard *)pboard // Get all the articles that are being dragged for (index = 0; index < count; ++index) { - int msgIndex = [[rows objectAtIndex:index] intValue]; - Article * thisArticle = [[articleController allArticles] objectAtIndex:msgIndex]; - Folder * folder = [db folderFromID:[thisArticle folderId]]; - NSString * msgText = [thisArticle body]; - NSString * msgTitle = [thisArticle title]; - NSString * msgLink = [thisArticle link]; + NSInteger msgIndex = [rows[index] integerValue]; + Article * thisArticle = articleController.allArticles[msgIndex]; + Folder * folder = [db folderFromID:thisArticle.folderId]; + NSString * msgText = thisArticle.body; + NSString * msgTitle = thisArticle.title; + NSString * msgLink = thisArticle.link; [arrayOfURLs addObject:msgLink]; [arrayOfTitles addObject:msgTitle]; @@ -1827,9 +1645,9 @@ -(BOOL)copyTableSelection:(NSArray *)rows toPasteboard:(NSPasteboard *)pboard [articleDict setValue:msgTitle forKey:@"rssItemTitle"]; [articleDict setValue:msgLink forKey:@"rssItemLink"]; [articleDict setValue:msgText forKey:@"rssItemDescription"]; - [articleDict setValue:[folder name] forKey:@"sourceName"]; - [articleDict setValue:[folder homePage] forKey:@"sourceHomeURL"]; - [articleDict setValue:[folder feedURL] forKey:@"sourceRSSURL"]; + [articleDict setValue:folder.name forKey:@"sourceName"]; + [articleDict setValue:folder.homePage forKey:@"sourceHomeURL"]; + [articleDict setValue:folder.feedURL forKey:@"sourceRSSURL"]; [arrayOfArticles addObject:articleDict]; // Plain text @@ -1853,15 +1671,10 @@ -(BOOL)copyTableSelection:(NSArray *)rows toPasteboard:(NSPasteboard *)pboard // Put string on the pasteboard for external drops. [pboard setPropertyList:arrayOfArticles forType:MA_PBoardType_RSSItem]; - [pboard setPropertyList:[NSArray arrayWithObjects:arrayOfURLs, arrayOfTitles, nil] forType:@"WebURLsWithTitlesPboardType"]; + [pboard setPropertyList:@[arrayOfURLs, arrayOfTitles] forType:@"WebURLsWithTitlesPboardType"]; [pboard setString:fullPlainText forType:NSStringPboardType]; - [pboard setString:[fullHTMLText stringByEscapingExtendedCharacters] forType:NSHTMLPboardType]; + [pboard setString:fullHTMLText.stringByEscapingExtendedCharacters forType:NSHTMLPboardType]; - [arrayOfArticles release]; - [arrayOfURLs release]; - [arrayOfTitles release]; - [fullHTMLText release]; - [fullPlainText release]; return YES; } @@ -1871,19 +1684,19 @@ -(BOOL)copyTableSelection:(NSArray *)rows toPasteboard:(NSPasteboard *)pboard -(NSArray *)markedArticleRange { NSMutableArray * articleArray = nil; - if ([articleList numberOfSelectedRows] > 0) + if (articleList.numberOfSelectedRows > 0) { - NSIndexSet * rowIndexes = [articleList selectedRowIndexes]; - NSUInteger rowIndex = [rowIndexes firstIndex]; + NSIndexSet * rowIndexes = articleList.selectedRowIndexes; + NSUInteger rowIndex = rowIndexes.firstIndex; - articleArray = [NSMutableArray arrayWithCapacity:[rowIndexes count]]; + articleArray = [NSMutableArray arrayWithCapacity:rowIndexes.count]; while (rowIndex != NSNotFound) { - [articleArray addObject:[[articleController allArticles] objectAtIndex:rowIndex]]; + [articleArray addObject:articleController.allArticles[rowIndex]]; rowIndex = [rowIndexes indexGreaterThanIndex:rowIndex]; } } - return articleArray; + return [articleArray copy]; } /* didStartProvisionalLoadForFrame @@ -1891,7 +1704,7 @@ -(NSArray *)markedArticleRange */ -(void)webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)frame { - if (frame == [articleText mainFrame]) + if (frame == articleText.mainFrame) { [self setError:nil]; [controller setStatusMessage:NSLocalizedString( isLoadingHTMLArticle ? @"Loading HTML article..." : @"", nil) persist:YES]; @@ -1912,10 +1725,9 @@ -(void)webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame */ -(void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { - if (frame == [articleText mainFrame]) + if (frame == articleText.mainFrame) { - [self handleError:error withDataSource: [frame provisionalDataSource]]; - [self endMainFrameLoad]; + [self handleError:error withDataSource: frame.provisionalDataSource]; } } @@ -1924,11 +1736,11 @@ -(void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)erro */ -(void)webView:(WebView *)sender didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { - if (frame == [articleText mainFrame]) + if (frame == articleText.mainFrame) { - // Not really an error. A plugin is grabbing the URL and will handle it by itself. - if (!([[error domain] isEqualToString:WebKitErrorDomain] && [error code] == WebKitErrorPlugInWillHandleLoad)) - [self handleError:error withDataSource:[frame dataSource]]; + // Not really errors. Load is cancelled or a plugin is grabbing the URL and will handle it by itself. + if (!([error.domain isEqualToString:WebKitErrorDomain] && (error.code == NSURLErrorCancelled || error.code == WebKitErrorPlugInWillHandleLoad))) + [self handleError:error withDataSource:frame.dataSource]; [self endMainFrameLoad]; } } @@ -1939,14 +1751,14 @@ -(void)handleError:(NSError *)error withDataSource:(WebDataSource *)dataSource [self setError:error]; // Load the localized verion of the error page - WebFrame * frame = [articleText mainFrame]; + WebFrame * frame = articleText.mainFrame; NSString * pathToErrorPage = [[NSBundle bundleForClass:[self class]] pathForResource:@"errorpage" ofType:@"html"]; if (pathToErrorPage != nil) { NSString *errorMessage = [NSString stringWithContentsOfFile:pathToErrorPage encoding:NSUTF8StringEncoding error:NULL]; - errorMessage = [errorMessage stringByReplacingOccurrencesOfString: @"$ErrorInformation" withString: [error localizedDescription]]; + errorMessage = [errorMessage stringByReplacingOccurrencesOfString: @"$ErrorInformation" withString: error.localizedDescription]; if (errorMessage != nil) - [frame loadAlternateHTMLString:errorMessage baseURL:[NSURL fileURLWithPath:pathToErrorPage isDirectory:NO] forUnreachableURL:[[dataSource request] URL]]; + [frame loadAlternateHTMLString:errorMessage baseURL:[NSURL fileURLWithPath:pathToErrorPage isDirectory:NO] forUnreachableURL:dataSource.request.URL]; } } @@ -1970,7 +1782,7 @@ -(void)endMainFrameLoad */ -(void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame { - if (frame == [articleText mainFrame]) + if (frame == articleText.mainFrame) [self endMainFrameLoad]; } @@ -1988,36 +1800,5 @@ -(void)dealloc [articleText setFrameLoadDelegate:nil]; [splitView2 setDelegate:nil]; [articleList setDelegate:nil]; - [markReadTimer release]; - markReadTimer=nil; - [articleListFont release]; - articleListFont=nil; - [articleListUnreadFont release]; - articleListUnreadFont=nil; - [reportCellDict release]; - reportCellDict=nil; - [unreadReportCellDict release]; - unreadReportCellDict=nil; - [guidOfArticleToSelect release]; - guidOfArticleToSelect=nil; - [unreadTopLineSelectionDict release]; - unreadTopLineSelectionDict=nil; - [selectionDict release]; - selectionDict=nil; - [unreadTopLineDict release]; - unreadTopLineDict=nil; - [topLineDict release]; - topLineDict=nil; - [middleLineDict release]; - middleLineDict=nil; - [linkLineDict release]; - linkLineDict=nil; - [bottomLineDict release]; - bottomLineDict=nil; - [lastError release]; - lastError=nil; - [currentURL release]; - currentURL=nil; - [super dealloc]; } @end diff --git a/src/ArticleRef.h b/src/ArticleRef.h index 360589d036..e5680f4c6d 100644 --- a/src/ArticleRef.h +++ b/src/ArticleRef.h @@ -24,14 +24,14 @@ @interface ArticleReference : NSObject { NSString * guid; - int folderId; + NSInteger folderId; } // Public functions +(ArticleReference *)makeReference:(Article *)anArticle; -+(ArticleReference *)makeReferenceFromGUID:(NSString *)aGuid inFolder:(int)folderId; ++(ArticleReference *)makeReferenceFromGUID:(NSString *)aGuid inFolder:(NSInteger)folderId; // Accessors --(NSString *)guid; --(int)folderId; +@property (nonatomic, readonly, copy) NSString *guid; +@property (nonatomic, readonly) NSInteger folderId; @end diff --git a/src/ArticleRef.m b/src/ArticleRef.m index 1ce9d1117b..f135da7c6a 100644 --- a/src/ArticleRef.m +++ b/src/ArticleRef.m @@ -24,11 +24,11 @@ @implementation ArticleReference /* initWithReference */ --(id)initWithReference:(NSString *)aGuid inFolder:(int)aFolderId +-(instancetype)initWithReference:(NSString *)aGuid inFolder:(NSInteger)aFolderId { if ((self = [super init]) != nil) { - guid = [aGuid retain]; + guid = aGuid; folderId = aFolderId; } return self; @@ -39,15 +39,15 @@ -(id)initWithReference:(NSString *)aGuid inFolder:(int)aFolderId */ +(ArticleReference *)makeReference:(Article *)anArticle { - return [[[ArticleReference alloc] initWithReference:[anArticle guid] inFolder:[anArticle folderId]] autorelease]; + return [[ArticleReference alloc] initWithReference:anArticle.guid inFolder:anArticle.folderId]; } /* makeReferenceFromGUID * Create a new ArticleReference using the information in the specified article. */ -+(ArticleReference *)makeReferenceFromGUID:(NSString *)aGuid inFolder:(int)folderId ++(ArticleReference *)makeReferenceFromGUID:(NSString *)aGuid inFolder:(NSInteger)folderId { - return [[[ArticleReference alloc] initWithReference:aGuid inFolder:folderId] autorelease]; + return [[ArticleReference alloc] initWithReference:aGuid inFolder:folderId]; } /* guid @@ -61,7 +61,7 @@ -(NSString *)guid /* folderId * Return the reference folder ID. */ --(int)folderId +-(NSInteger)folderId { return folderId; } @@ -71,16 +71,7 @@ -(int)folderId */ -(NSString *)description { - return [NSString stringWithFormat:@"%@ in folder %d", guid, folderId]; + return [NSString stringWithFormat:@"%@ in folder %ld", guid, (long)folderId]; } -/* dealloc - * Clean up behind ourselves. - */ --(void)dealloc -{ - [guid release]; - guid=nil; - [super dealloc]; -} @end diff --git a/src/ArticleView.h b/src/ArticleView.h index 55f584165e..90943dd368 100644 --- a/src/ArticleView.h +++ b/src/ArticleView.h @@ -32,7 +32,7 @@ +(NSDictionary *)stylesMap; +(NSDictionary *)loadStylesMap; -(void)clearHTML; --(void)setHTML:(NSString *)htmlText withBase:(NSString *)urlString; +-(void)setHTML:(NSString *)htmlText; -(NSString *)articleTextFromArray:(NSArray *)msgArray; -(void)keyDown:(NSEvent *)theEvent; @end diff --git a/src/ArticleView.m b/src/ArticleView.m index 31de1552f9..7203fe7fa0 100644 --- a/src/ArticleView.m +++ b/src/ArticleView.m @@ -40,7 +40,7 @@ @implementation ArticleView /* initWithFrame * The designated instance initialiser. */ --(id)initWithFrame:(NSRect)frameRect +-(instancetype)initWithFrame:(NSRect)frameRect { if ((self = [super initWithFrame:frameRect]) != nil) { @@ -48,7 +48,7 @@ -(id)initWithFrame:(NSRect)frameRect htmlTemplate = nil; cssStylesheet = nil; jsScript = nil; - currentHTML = nil; + currentHTML = @""; // Set up to be notified when style changes NSNotificationCenter * nc = [NSNotificationCenter defaultCenter]; @@ -57,9 +57,9 @@ -(id)initWithFrame:(NSRect)frameRect // Select the user's current style or revert back to the // default style otherwise. Preferences * prefs = [Preferences standardPreferences]; - [self initForStyle:[prefs displayStyle]]; + [self initForStyle:prefs.displayStyle]; // enlarge / reduce the text size according to user's setting - [self setTextSizeMultiplier:[prefs textSizeMultiplier]]; + self.textSizeMultiplier = prefs.textSizeMultiplier; } return self; } @@ -70,8 +70,8 @@ -(id)initWithFrame:(NSRect)frameRect -(void)handleStyleChange:(NSNotificationCenter *)nc { Preferences * prefs = [Preferences standardPreferences]; - [self initForStyle:[prefs displayStyle]]; - [self setTextSizeMultiplier:[prefs textSizeMultiplier]]; + [self initForStyle:prefs.displayStyle]; + self.textSizeMultiplier = prefs.textSizeMultiplier; } /* performDragOperation @@ -98,10 +98,10 @@ +(NSDictionary *)loadStylesMap if (stylePathMappings == nil) stylePathMappings = [[NSMutableDictionary alloc] init]; - NSString * path = [[[NSBundle mainBundle] sharedSupportPath] stringByAppendingPathComponent:@"Styles"]; + NSString * path = [[NSBundle mainBundle].sharedSupportPath stringByAppendingPathComponent:@"Styles"]; loadMapFromPath(path, stylePathMappings, YES, nil); - path = [[Preferences standardPreferences] stylesFolder]; + path = [Preferences standardPreferences].stylesFolder; loadMapFromPath(path, stylePathMappings, YES, nil); return stylePathMappings; @@ -116,29 +116,26 @@ -(BOOL)initForStyle:(NSString *)styleName if (stylePathMappings == nil) [ArticleView loadStylesMap]; - NSString * path = [stylePathMappings objectForKey:styleName]; + NSString * path = stylePathMappings[styleName]; if (path != nil) { NSString * filePath = [path stringByAppendingPathComponent:@"template.html"]; NSString * templateString = [NSString stringWithContentsOfFile:filePath usedEncoding:NULL error:NULL]; // Sanity check the file. Obviously anything bigger than 0 bytes but smaller than a valid template // format is a problem but we'll worry about that later. There's only so much rope we can give. - if (templateString != nil && [templateString length] > 0u) + if (templateString != nil && templateString.length > 0u) { - [htmlTemplate release]; - [cssStylesheet release]; - [jsScript release]; - htmlTemplate = [templateString retain]; - cssStylesheet = [[@"file://localhost" stringByAppendingString:[path stringByAppendingPathComponent:@"stylesheet.css"]] retain]; + htmlTemplate = templateString; + cssStylesheet = [[@"file://localhost" stringByAppendingString:[path stringByAppendingPathComponent:@"stylesheet.css"]] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSString * javaScriptPath = [path stringByAppendingPathComponent:@"script.js"]; if ([[NSFileManager defaultManager] fileExistsAtPath:javaScriptPath]) - jsScript = [[@"file://localhost" stringByAppendingString:javaScriptPath] retain]; + jsScript = [[@"file://localhost" stringByAppendingString:javaScriptPath] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; else jsScript = nil; // Make sure the template is valid - NSString * firstLine = [[htmlTemplate firstNonBlankLine] lowercaseString]; + NSString * firstLine = htmlTemplate.firstNonBlankLine.lowercaseString; if (![firstLine hasPrefix:@""] && ![firstLine hasPrefix:@""]; + NSMutableString * htmlText = [[NSMutableString alloc] initWithString:@""]; + // the link for the first article will be the base URL for resolving relative URLs + [htmlText appendString:@""]; if (cssStylesheet != nil) { [htmlText appendString:@""]; + [htmlText appendString:@"\">"]; } if (jsScript != nil) { [htmlText appendString:@""]; + [htmlText appendString:@"\">"]; } [htmlText appendString:@""]; [htmlText appendString:@""]; - for (index = 0; index < [msgArray count]; ++index) + for (index = 0; index < msgArray.count; ++index) { - Article * theArticle = [msgArray objectAtIndex:index]; + Article * theArticle = msgArray[index]; // Load the selected HTML template for the current view style and plug in the current // article values and style sheet setting. NSMutableString * htmlArticle; if (htmlTemplate == nil) { - NSMutableString * articleBody = [NSMutableString stringWithString:[theArticle body]]; + NSMutableString * articleBody = [NSMutableString stringWithString:SafeString(theArticle.body)]; [articleBody fixupRelativeImgTags:SafeString([theArticle link])]; [articleBody fixupRelativeIframeTags:SafeString([theArticle link])]; [articleBody fixupRelativeAnchorTags:SafeString([theArticle link])]; @@ -209,7 +210,7 @@ -(NSString *)articleTextFromArray:(NSArray *)msgArray // Handle conditional tag expansion. Sections in and // are stripped out if all the tags inside are blank. - while(![scanner isAtEnd]) + while(!scanner.atEnd) { if ([scanner scanUpToString:@"" intoString:&commentTag] && commentTag != nil) { - commentTag = [commentTag trim]; + commentTag = commentTag.trim; if ([commentTag isEqualToString:@"cond:noblank"]) stripIfEmpty = YES; if ([commentTag isEqualToString:@"end"]) @@ -234,10 +235,9 @@ -(NSString *)articleTextFromArray:(NSArray *)msgArray if (index > 0) [htmlText appendString:@"

"]; [htmlText appendString:htmlArticle]; - [htmlArticle release]; } [htmlText appendString:@""]; - return [htmlText autorelease]; + return htmlText; } /* clearHTML @@ -245,21 +245,13 @@ -(NSString *)articleTextFromArray:(NSArray *)msgArray */ -(void)clearHTML { - // Reset current html string. - if (currentHTML != nil) - [currentHTML release]; - currentHTML = [[NSString alloc] initWithString: @""]; - - // Load a blank HTML page. - NSString * htmlText = @""; - [[self mainFrame] loadHTMLString:htmlText - baseURL:[NSURL URLWithString:@""]]; + [self setHTML:@""]; } /* setHTML * Loads the web view with the specified HTML text. */ --(void)setHTML:(NSString *)htmlText withBase:(NSString *)urlString +-(void)setHTML:(NSString *)htmlText { // If the current HTML is the same as the new HTML then we don't need to // do anything here. This will stop the view from spurious redraws of the same @@ -268,15 +260,9 @@ -(void)setHTML:(NSString *)htmlText withBase:(NSString *)urlString return; // Remember the current html string. - if (currentHTML != nil) - [currentHTML release]; - currentHTML = [[NSString alloc] initWithString: htmlText]; - - // Replace feed:// with http:// if necessary - if ([urlString hasPrefix:@"feed://"]) - urlString = [NSString stringWithFormat:@"http://%@", [urlString substringFromIndex:7]]; + currentHTML = [htmlText copy]; - [[self mainFrame] loadHTMLString:htmlText + [self.mainFrame loadHTMLString:currentHTML baseURL:[NSURL URLWithString:@"/"]]; } @@ -286,14 +272,14 @@ -(void)setHTML:(NSString *)htmlText withBase:(NSString *)urlString */ -(void)keyDown:(NSEvent *)theEvent { - if ([[theEvent characters] length] == 1) + if (theEvent.characters.length == 1) { - unichar keyChar = [[theEvent characters] characterAtIndex:0]; - if ([APPCONTROLLER handleKeyDown:keyChar withFlags:[theEvent modifierFlags]]) + unichar keyChar = [theEvent.characters characterAtIndex:0]; + if ([APPCONTROLLER handleKeyDown:keyChar withFlags:theEvent.modifierFlags]) return; //Don't go back or forward in article view. - if (([theEvent modifierFlags] & NSCommandKeyMask) && + if ((theEvent.modifierFlags & NSCommandKeyMask) && ((keyChar == NSLeftArrowFunctionKey) || (keyChar == NSRightArrowFunctionKey))) return; } @@ -306,8 +292,8 @@ -(void)keyDown:(NSEvent *)theEvent */ -(void)swipeWithEvent:(NSEvent *)event { - CGFloat deltaX = [event deltaX]; - CGFloat deltaY = [event deltaY]; + CGFloat deltaX = event.deltaX; + CGFloat deltaY = event.deltaY; /* Check which is more likely to be what the user wanted: horizontal or vertical swipe? * Thankfully, that's all the checking we need to do as built-in swipe detection is very solid. */ @@ -341,7 +327,7 @@ -(void)swipeWithEvent:(NSEvent *)event -(IBAction)makeTextSmaller:(id)sender { [super makeTextSmaller:sender]; - [[Preferences standardPreferences] setTextSizeMultiplier:[self textSizeMultiplier]]; + [Preferences standardPreferences].textSizeMultiplier = self.textSizeMultiplier; } /* makeTextLarger @@ -349,7 +335,7 @@ -(IBAction)makeTextSmaller:(id)sender -(IBAction)makeTextLarger:(id)sender { [super makeTextLarger:sender]; - [[Preferences standardPreferences] setTextSizeMultiplier:[self textSizeMultiplier]]; + [Preferences standardPreferences].textSizeMultiplier = self.textSizeMultiplier; } #pragma mark - @@ -361,9 +347,9 @@ -(IBAction)makeTextLarger:(id)sender */ -(void)webView:(WebView *)sender decidePolicyForNewWindowAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request newFrameName:(NSString *)frameName decisionListener:(id)listener { - int navType = [[actionInformation valueForKey:WebActionNavigationTypeKey] intValue]; - if ((navType == WebNavigationTypeLinkClicked) && ([[Preferences standardPreferences] openLinksInBackground] || ![[Preferences standardPreferences] openLinksInVienna])) - [[NSApp mainWindow] makeFirstResponder:[[[APPCONTROLLER browserView] primaryTabItemView] mainView]]; + NSInteger navType = [[actionInformation valueForKey:WebActionNavigationTypeKey] integerValue]; + if ((navType == WebNavigationTypeLinkClicked) && ([Preferences standardPreferences].openLinksInBackground || ![Preferences standardPreferences].openLinksInVienna)) + [NSApp.mainWindow makeFirstResponder:[APPCONTROLLER.browserView primaryTabItemView].mainView]; [super webView:sender decidePolicyForNewWindowAction:actionInformation request:request newFrameName:frameName decisionListener:listener]; } @@ -375,19 +361,19 @@ -(void)webView:(WebView *)sender decidePolicyForNewWindowAction:(NSDictionary *) */ -(void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener { - if ([[request URL] fragment] != nil) + if (request.URL.fragment != nil) { - NSURL * feedURL = [[[[self mainFrame] dataSource] initialRequest] URL]; - if ((feedURL != nil) && [[feedURL scheme] isEqualToString:[[request URL] scheme]] && [[feedURL host] isEqualToString:[[request URL] host]] && [[feedURL path] isEqualToString:[[request URL] path]]) + NSURL * feedURL = self.mainFrame.dataSource.initialRequest.URL; + if ((feedURL != nil) && [feedURL.scheme isEqualToString:request.URL.scheme] && [feedURL.host isEqualToString:request.URL.host] && [feedURL.path isEqualToString:request.URL.path]) { [listener use]; return; } } - int navType = [[actionInformation valueForKey:WebActionNavigationTypeKey] intValue]; - if ((navType == WebNavigationTypeLinkClicked) && ([[Preferences standardPreferences] openLinksInBackground] || ![[Preferences standardPreferences] openLinksInVienna])) - [[NSApp mainWindow] makeFirstResponder:[[[APPCONTROLLER browserView] primaryTabItemView] mainView]]; + NSInteger navType = [[actionInformation valueForKey:WebActionNavigationTypeKey] integerValue]; + if ((navType == WebNavigationTypeLinkClicked) && ([Preferences standardPreferences].openLinksInBackground || ![Preferences standardPreferences].openLinksInVienna)) + [NSApp.mainWindow makeFirstResponder:[APPCONTROLLER.browserView primaryTabItemView].mainView]; [super webView:sender decidePolicyForNavigationAction:actionInformation request:request frame:frame decisionListener:listener]; } @@ -398,14 +384,5 @@ -(void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary * -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - [cssStylesheet release]; - cssStylesheet=nil; - [htmlTemplate release]; - htmlTemplate=nil; - [currentHTML release]; - currentHTML=nil; - [jsScript release]; - jsScript=nil; - [super dealloc]; } @end diff --git a/src/BJRWindowWithToolbar.h b/src/BJRWindowWithToolbar.h old mode 100755 new mode 100644 diff --git a/src/BJRWindowWithToolbar.m b/src/BJRWindowWithToolbar.m index 8134e2582c..348e89a816 100644 --- a/src/BJRWindowWithToolbar.m +++ b/src/BJRWindowWithToolbar.m @@ -30,7 +30,7 @@ -(BOOL)validateUserInterfaceItem:(id )anItem id itemObject = (id)anItem; if ( [itemObject action] == @selector(toggleToolbarShown:) && [itemObject respondsToSelector:@selector(setTitle:)] ) { - if ([[self toolbar] isVisible]) + if (self.toolbar.visible) [itemObject setTitle:[[NSBundle bundleWithIdentifier:@"com.apple.AppKit"] localizedStringForKey:@"Hide Toolbar" value:@"" table:@"Toolbar"]]; else [itemObject setTitle:[[NSBundle bundleWithIdentifier:@"com.apple.AppKit"] localizedStringForKey:@"Show Toolbar" value:@"" table:@"Toolbar"]]; diff --git a/src/BackTrackArray.h b/src/BackTrackArray.h index e5060c3f5c..9cfcffd08d 100644 --- a/src/BackTrackArray.h +++ b/src/BackTrackArray.h @@ -23,14 +23,14 @@ @interface BackTrackArray : NSObject { NSMutableArray * array; NSUInteger maxItems; - int queueIndex; + NSInteger queueIndex; } // Accessor functions --(id)initWithMaximum:(NSUInteger )theMax; --(BOOL)isAtStartOfQueue; --(BOOL)isAtEndOfQueue; --(void)addToQueue:(int)folderId guid:(NSString *)guid; --(BOOL)nextItemAtQueue:(int *)folderId guidPointer:(NSString **)guidPtr; --(BOOL)previousItemAtQueue:(int *)folderId guidPointer:(NSString **)guidPtr; +-(instancetype)initWithMaximum:(NSUInteger)theMax /*NS_DESIGNATED_INITIALIZER*/; +@property (nonatomic, getter=isAtStartOfQueue, readonly) BOOL atStartOfQueue; +@property (nonatomic, getter=isAtEndOfQueue, readonly) BOOL atEndOfQueue; +-(void)addToQueue:(NSInteger)folderId guid:(NSString *)guid; +-(BOOL)nextItemAtQueue:(NSInteger *)folderId guidPointer:(NSString **)guidPtr; +-(BOOL)previousItemAtQueue:(NSInteger *)folderId guidPointer:(NSString **)guidPtr; @end diff --git a/src/BackTrackArray.m b/src/BackTrackArray.m index 716a4b14af..99eca4001a 100644 --- a/src/BackTrackArray.m +++ b/src/BackTrackArray.m @@ -27,7 +27,7 @@ @implementation BackTrackArray * Initialises a new BackTrackArray with the specified maximum number of * items. */ --(id)initWithMaximum:(NSUInteger )theMax +-(instancetype)initWithMaximum:(NSUInteger)theMax { if ((self = [super init]) != nil) { @@ -51,20 +51,20 @@ -(BOOL)isAtStartOfQueue */ -(BOOL)isAtEndOfQueue { - return queueIndex >= (int)[array count] - 1; + return queueIndex >= (NSInteger)array.count - 1; } /* previousItemAtQueue * Removes an item from the tail of the queue as long as the queue is not * empty and returns the backtrack data. */ --(BOOL)previousItemAtQueue:(int *)folderId guidPointer:(NSString **)guidPointer +-(BOOL)previousItemAtQueue:(NSInteger *)folderId guidPointer:(NSString **)guidPointer { if (queueIndex > 0) { - ArticleReference * item = [array objectAtIndex:--queueIndex]; - *folderId = [item folderId]; - *guidPointer = [item guid]; + ArticleReference * item = array[--queueIndex]; + *folderId = item.folderId; + *guidPointer = item.guid; return YES; } return NO; @@ -74,13 +74,13 @@ -(BOOL)previousItemAtQueue:(int *)folderId guidPointer:(NSString **)guidPointer * Removes an item from the tail of the queue as long as the queue is not * empty and returns the backtrack data. */ --(BOOL)nextItemAtQueue:(int *)folderId guidPointer:(NSString **)guidPointer +-(BOOL)nextItemAtQueue:(NSInteger *)folderId guidPointer:(NSString **)guidPointer { - if (queueIndex < (int)[array count] - 1) + if (queueIndex < (NSInteger)array.count - 1) { - ArticleReference * item = [array objectAtIndex:++queueIndex]; - *folderId = [item folderId]; - *guidPointer = [item guid]; + ArticleReference * item = array[++queueIndex]; + *folderId = item.folderId; + *guidPointer = item.guid; return YES; } return NO; @@ -95,32 +95,23 @@ -(BOOL)nextItemAtQueue:(int *)folderId guidPointer:(NSString **)guidPointer * new 'head' position. This produces the expected results when tracking * from the new item inserted back to the most recent item. */ --(void)addToQueue:(int)folderId guid:(NSString *)guid +-(void)addToQueue:(NSInteger)folderId guid:(NSString *)guid { - while (queueIndex + 1 < (int)[array count]) + while (queueIndex + 1 < (NSInteger)array.count) [array removeObjectAtIndex:queueIndex + 1]; - if ([array count] == maxItems) + if (array.count == maxItems) { [array removeObjectAtIndex:0]; --queueIndex; } - if ([array count] > 0) + if (array.count > 0) { - ArticleReference * item = [array objectAtIndex:[array count] - 1]; - if ([[item guid] isEqualToString:guid] && [item folderId] == folderId) + ArticleReference * item = array[array.count - 1]; + if ([item.guid isEqualToString:guid] && item.folderId == folderId) return; } [array addObject:[ArticleReference makeReferenceFromGUID:guid inFolder:folderId]]; ++queueIndex; } -/* dealloc - * Clean up and release resources. - */ --(void)dealloc -{ - [array release]; - array=nil; - [super dealloc]; -} @end diff --git a/src/BaseView.h b/src/BaseView.h index 48d36c7334..a0ce935ebc 100644 --- a/src/BaseView.h +++ b/src/BaseView.h @@ -21,17 +21,17 @@ @class WebView; @protocol BaseView @required - -(void)performFindPanelAction:(int)tag; + -(void)performFindPanelAction:(NSInteger)tag; -(void)printDocument:(id)sender; -(IBAction)handleGoForward:(id)sender; -(IBAction)handleGoBack:(id)sender; - -(BOOL)canGoForward; - -(BOOL)canGoBack; - -(NSString *)viewLink; - -(NSView *)mainView; - -(WebView *)webView; - -(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger )flags; + @property (nonatomic, readonly) BOOL canGoForward; + @property (nonatomic, readonly) BOOL canGoBack; + @property (nonatomic, readonly, copy) NSString *viewLink; + @property (nonatomic, readonly, strong) NSView *mainView; + @property (nonatomic, readonly, strong) WebView *webView; + -(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger)flags; @optional - -(NSString *)viewTitle; + @property (nonatomic, readonly, copy) NSString *viewTitle; @end diff --git a/src/BezierPathExtensions.h b/src/BezierPathExtensions.h index 71f977e13b..c7ad17048c 100644 --- a/src/BezierPathExtensions.h +++ b/src/BezierPathExtensions.h @@ -21,5 +21,5 @@ #import @interface NSBezierPath (BezierPathExtensions) - +(NSBezierPath *)bezierPathWithRoundRectInRect:(NSRect)aRect radius:(float)radius; + +(NSBezierPath *)bezierPathWithRoundRectInRect:(NSRect)aRect radius:(CGFloat)radius; @end diff --git a/src/BezierPathExtensions.m b/src/BezierPathExtensions.m index 09478359cc..e654ba5836 100644 --- a/src/BezierPathExtensions.m +++ b/src/BezierPathExtensions.m @@ -25,7 +25,7 @@ @implementation NSBezierPath (BezierPathExtensions) /* bezierPathWithRoundRectInRect * Create a rectangluar bezier path with rounded corners. Radius is the radius of the corners. */ -+(NSBezierPath *)bezierPathWithRoundRectInRect:(NSRect)aRect radius:(float)radius ++(NSBezierPath *)bezierPathWithRoundRectInRect:(NSRect)aRect radius:(CGFloat)radius { NSBezierPath * path = [NSBezierPath bezierPath]; radius = MIN(radius, 0.5f * MIN(NSWidth(aRect), NSHeight(aRect))); diff --git a/src/BitlyAPIHelper.h b/src/BitlyAPIHelper.h index 8000e1c81e..460999e2a3 100644 --- a/src/BitlyAPIHelper.h +++ b/src/BitlyAPIHelper.h @@ -17,6 +17,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // +#import @interface BitlyAPIHelper : NSObject { diff --git a/src/BitlyAPIHelper.m b/src/BitlyAPIHelper.m index 7fd0611967..c3e931b474 100644 --- a/src/BitlyAPIHelper.m +++ b/src/BitlyAPIHelper.m @@ -19,7 +19,6 @@ // #import "BitlyAPIHelper.h" -#import "XMLParser.h" #import "HelperFunctions.h" // bit.ly defaults to delivering results via JSON, but we want to use XML here, that's why whe use &format=xml @@ -45,34 +44,41 @@ - (NSString*)shortenURL: (NSString*)longURL { // The next few lines incrementally build the request... NSString * requestURLString = [NSString stringWithFormat:BitlyApiBaseUrl, @"shorten", login, apiKey]; - longURL = [cleanedUpAndEscapedUrlFromString(longURL) absoluteString]; + longURL = cleanedUpAndEscapedUrlFromString(longURL).absoluteString; NSString * parameters = [NSString stringWithFormat:@"longUrl=%@", longURL]; requestURLString = [requestURLString stringByAppendingString:parameters]; NSURL *finishedRequestURL = [NSURL URLWithString:requestURLString]; - NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:finishedRequestURL]; + NSURLRequest *request = [[NSURLRequest alloc] initWithURL:finishedRequestURL]; // ... which is then finally sent to bit.ly's servers. NSHTTPURLResponse* urlResponse = nil; - NSError *error = [[[NSError alloc] init] autorelease]; + NSError *error = nil; NSData * data = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&error]; // If the response is OK, use Vienna's XML parser stuff to get the data we need. - if ([urlResponse statusCode] >= 200 && [urlResponse statusCode] < 300) + if (urlResponse.statusCode >= 200 && urlResponse.statusCode < 300) { //TODO: Robust error-handling. - XMLParser * responseParser = [[XMLParser alloc] init]; - [responseParser setData:data]; - - XMLParser * subtree; - if ((subtree = [responseParser treeByPath:@"bitly/results/nodeKeyVal/shortUrl"]) != nil) - { - [responseParser release]; - [request release]; - return [subtree valueOfElement]; - } - [responseParser release]; + NSError *error = nil; + NSXMLDocument *bitlyResponse = [[NSXMLDocument alloc] initWithData:data options:NSXMLNodeOptionsNone error:&error]; + if (error) { + // TODO: Present error-message to the user? + NSLog(@"URL shortening with bit.ly failed: %@", error); + return nil; + } + + error = nil; + NSXMLNode *shortUrlNode = [bitlyResponse nodesForXPath:@".//bitly/results/nodeKeyVal/shortUrl" error:&error].firstObject; + + if (error) { + // TODO: Present error-message to the user? + NSLog(@"Processing xml xpath from bit.ly failed: %@", error); + return nil; + } else { + return shortUrlNode.stringValue; + } + } - [request release]; // TODO: Present error-message to the user? NSLog(@"URL shortening with bit.ly failed!"); NSBeep(); diff --git a/src/BrowserPane.h b/src/BrowserPane.h index 444dbf12c5..26fd3ab0ed 100644 --- a/src/BrowserPane.h +++ b/src/BrowserPane.h @@ -52,11 +52,11 @@ BOOL isLocalFile; BOOL isLoading; BOOL openURLInBackground; - NSString * rssPageURL; + BOOL hasRSSlink; NSString * viewTitle; } -@property (nonatomic, retain) IBOutlet TabbedWebView * webPane; +@property (nonatomic, strong) IBOutlet TabbedWebView * webPane; // Action functions -(IBAction)handleGoForward:(id)sender; @@ -68,12 +68,11 @@ // Accessor functions -(void)setController:(AppController *)theController; -(void)loadURL:(NSURL *)url inBackground:(BOOL)openInBackgroundFlag; --(NSURL *)url; --(void)setViewTitle:(NSString *)newTitle; --(NSString *)viewTitle; --(BOOL)isLoading; --(BOOL)canGoBack; --(BOOL)canGoForward; +@property (nonatomic, readonly, copy) NSURL *url; +@property (nonatomic, copy) NSString *viewTitle; +@property (nonatomic, getter=isLoading, readonly) BOOL loading; +@property (nonatomic, readonly) BOOL canGoBack; +@property (nonatomic, readonly) BOOL canGoForward; -(void)handleStopLoading:(id)sender; -(void)activateAddressBar; @end \ No newline at end of file diff --git a/src/BrowserPane.m b/src/BrowserPane.m index 1e6038e221..562158285b 100644 --- a/src/BrowserPane.m +++ b/src/BrowserPane.m @@ -28,6 +28,7 @@ #import "AddressBarCell.h" #import #import "RichXMLParser.h" +#import "SubscriptionModel.h" @implementation BrowserPaneButtonCell @@ -71,12 +72,10 @@ @implementation BrowserPane + (void)load { - @autoreleasepool { - if (self == [BrowserPane class]) { - //These are synonyms - [self exposeBinding:@"isLoading"]; - [self exposeBinding:@"isProcessing"]; - } + if (self == [BrowserPane class]) { + //These are synonyms + [self exposeBinding:@"isLoading"]; + [self exposeBinding:@"isProcessing"]; } } @@ -95,7 +94,7 @@ + (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key /* initWithFrame * Initialise our view. */ --(id)initWithFrame:(NSRect)frame +-(instancetype)initWithFrame:(NSRect)frame { self = [super initWithFrame:frame]; if (self) @@ -109,7 +108,7 @@ -(id)initWithFrame:(NSRect)frame openURLInBackground = NO; pageFilename = nil; lastError = nil; - rssPageURL = nil; + hasRSSlink = NO; } return self; } @@ -121,43 +120,43 @@ -(void)awakeFromNib { // Create our webview [webPane initTabbedWebView]; - [webPane setUIDelegate:self]; - [webPane setFrameLoadDelegate:self]; + webPane.UIDelegate = self; + webPane.frameLoadDelegate = self; // Make web preferences 16pt Arial to match Safari - [[webPane preferences] setStandardFontFamily:@"Arial"]; - [[webPane preferences] setDefaultFontSize:16]; + webPane.preferences.standardFontFamily = @"Arial"; + webPane.preferences.defaultFontSize = 16; // Use an AddressBarCell for the address field which allows space for the // web page image and an optional lock icon for secure pages. - AddressBarCell * cell = [[[AddressBarCell alloc] init] autorelease]; + AddressBarCell * cell = [[AddressBarCell alloc] init]; [cell setEditable:YES]; [cell setDrawsBackground:YES]; [cell setBordered:YES]; [cell setBezeled:YES]; [cell setScrollable:YES]; - [cell setTarget:self]; - [cell setAction:@selector(handleAddress:)]; - [cell setFont:[NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]]; - [addressField setCell:cell]; + cell.target = self; + cell.action = @selector(handleAddress:); + cell.font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]; + addressField.cell = cell; // Initialise address field - [addressField setStringValue:@""]; + addressField.stringValue = @""; // The RSS page button is hidden by default [self showRssPageButton:NO]; // Set tooltips [addressField setToolTip:NSLocalizedString(@"Enter the URL here", nil)]; - [[addressField cell] accessibilitySetOverrideValue:NSLocalizedString(@"Enter the URL here", nil) forAttribute:NSAccessibilityTitleAttribute]; + [addressField.cell accessibilitySetOverrideValue:NSLocalizedString(@"Enter the URL here", nil) forAttribute:NSAccessibilityTitleAttribute]; [refreshButton setToolTip:NSLocalizedString(@"Refresh the current page", nil)]; - [[refreshButton cell] accessibilitySetOverrideValue:NSLocalizedString(@"Refresh the current page", nil) forAttribute:NSAccessibilityTitleAttribute]; + [refreshButton.cell accessibilitySetOverrideValue:NSLocalizedString(@"Refresh the current page", nil) forAttribute:NSAccessibilityTitleAttribute]; [backButton setToolTip:NSLocalizedString(@"Return to the previous page", nil)]; - [[backButton cell] accessibilitySetOverrideValue:NSLocalizedString(@"Return to the previous page", nil) forAttribute:NSAccessibilityTitleAttribute]; + [backButton.cell accessibilitySetOverrideValue:NSLocalizedString(@"Return to the previous page", nil) forAttribute:NSAccessibilityTitleAttribute]; [forwardButton setToolTip:NSLocalizedString(@"Go forward to the next page", nil)]; - [[forwardButton cell] accessibilitySetOverrideValue:NSLocalizedString(@"Go forward to the next page", nil) forAttribute:NSAccessibilityTitleAttribute]; + [forwardButton.cell accessibilitySetOverrideValue:NSLocalizedString(@"Go forward to the next page", nil) forAttribute:NSAccessibilityTitleAttribute]; [rssPageButton setToolTip:NSLocalizedString(@"Subscribe to the feed for this page", nil)]; - [[rssPageButton cell] accessibilitySetOverrideValue:NSLocalizedString(@"Subscribe to the feed for this page", nil) forAttribute:NSAccessibilityTitleAttribute]; + [rssPageButton.cell accessibilitySetOverrideValue:NSLocalizedString(@"Subscribe to the feed for this page", nil) forAttribute:NSAccessibilityTitleAttribute]; } /* setController @@ -174,9 +173,9 @@ -(void)setController:(AppController *)theController */ -(NSString *)viewLink { - if ([[[self.webPane mainFrame] dataSource] unreachableURL]) - return [[[[self.webPane mainFrame] dataSource] unreachableURL] absoluteString]; - return [[self url] absoluteString]; + if ((self.webPane).mainFrame.dataSource.unreachableURL) + return (self.webPane).mainFrame.dataSource.unreachableURL.absoluteString; + return self.url.absoluteString; } /* showRssPageButton @@ -185,7 +184,7 @@ -(NSString *)viewLink // TODO : associate a menu when there are multiple feeds -(void)showRssPageButton:(BOOL)showButton { - [rssPageButton setEnabled:showButton]; + rssPageButton.enabled = showButton; } /* setError @@ -193,8 +192,6 @@ -(void)showRssPageButton:(BOOL)showButton */ -(void)setError:(NSError *)newError { - [newError retain]; - [lastError release]; lastError = newError; } @@ -203,14 +200,16 @@ -(void)setError:(NSError *)newError */ -(IBAction)handleAddress:(id)sender { - NSString * theURL = [addressField stringValue]; - // If no '.' appears in the string, wrap it with 'www' and 'com' - if (![theURL hasCharacter:'.']) - theURL = [NSString stringWithFormat:@"www.%@.com", theURL]; - - // If no schema, prefix http:// - if ([theURL rangeOfString:@"://"].location == NSNotFound) + NSString * theURL = addressField.stringValue; + if ([NSURL URLWithString:theURL].scheme == nil) + { + // If no '.' appears in the string, wrap it with 'www' and 'com' + if (![theURL hasCharacter:'.']) + { + theURL = [NSString stringWithFormat:@"www.%@.com", theURL]; + } theURL = [NSString stringWithFormat:@"http://%@", theURL]; + } // cleanUpUrl is a hack to handle Internationalized Domain Names. WebKit handles them automatically, so we tap into that. NSURL *urlToLoad = cleanedUpAndEscapedUrlFromString(theURL); @@ -222,8 +221,6 @@ -(IBAction)handleAddress:(id)sender -(void)setViewTitle:(NSString *) newTitle { - [newTitle retain]; - [viewTitle release]; viewTitle = newTitle; } @@ -232,7 +229,7 @@ -(void)setViewTitle:(NSString *) newTitle */ -(void)activateAddressBar { - [[NSApp mainWindow] makeFirstResponder:addressField]; + [NSApp.mainWindow makeFirstResponder:addressField]; } /* loadURL @@ -240,23 +237,20 @@ -(void)activateAddressBar */ -(void)loadURL:(NSURL *)url inBackground:(BOOL)openInBackgroundFlag { - [self setViewTitle:@""]; + self.viewTitle = @""; openURLInBackground = openInBackgroundFlag; - isLocalFile = [url isFileURL]; + isLocalFile = url.fileURL; - [pageFilename release]; - pageFilename = [[[[url path] lastPathComponent] stringByDeletingPathExtension] retain]; + pageFilename = url.path.lastPathComponent.stringByDeletingPathExtension; - [addressField setStringValue:[url absoluteString]]; - [self retain]; - if ([self.webPane isLoading]) + addressField.stringValue = url.absoluteString; + if ((self.webPane).loading) { [self willChangeValueForKey:@"isLoading"]; [self.webPane stopLoading:self]; [self didChangeValueForKey:@"isLoading"]; } - [[self.webPane mainFrame] loadRequest:[NSURLRequest requestWithURL:url]]; - [self release]; + [(self.webPane).mainFrame loadRequest:[NSURLRequest requestWithURL:url]]; } /* setStatusText @@ -265,7 +259,7 @@ -(void)loadURL:(NSURL *)url inBackground:(BOOL)openInBackgroundFlag */ -(void)webView:(WebView *)sender setStatusText:(NSString *)text { - if ([[controller browserView] activeTabItemView] == self) + if (controller.browserView.activeTabItemView == self) [controller setStatusMessage:text persist:NO]; } @@ -273,10 +267,10 @@ -(void)webView:(WebView *)sender setStatusText:(NSString *)text * Called from the webview when the user positions the mouse over an element. If it's a link * then echo the URL to the status bar like Safari does. */ --(void)webView:(WebView *)sender mouseDidMoveOverElement:(NSDictionary *)elementInformation modifierFlags:(NSUInteger )modifierFlags +-(void)webView:(WebView *)sender mouseDidMoveOverElement:(NSDictionary *)elementInformation modifierFlags:(NSUInteger)modifierFlags { NSURL * url = [elementInformation valueForKey:@"WebElementLinkURL"]; - [controller setStatusMessage:(url ? [url absoluteString] : @"") persist:NO]; + [controller setStatusMessage:(url ? url.absoluteString : @"") persist:NO]; } /* didStartProvisionalLoadForFrame @@ -284,13 +278,12 @@ -(void)webView:(WebView *)sender mouseDidMoveOverElement:(NSDictionary *)element */ -(void)webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)frame { - if (frame == [self.webPane mainFrame]) + if (frame == (self.webPane).mainFrame) { - [[controller browserView] setTabItemViewTitle:self title:NSLocalizedString(@"Loading...", nil)]; + [controller.browserView setTabItemViewTitle:self title:NSLocalizedString(@"Loading...", nil)]; [self showRssPageButton:NO]; [self setError:nil]; - [self setViewTitle:@""]; - [self retain]; + self.viewTitle = @""; } } @@ -300,7 +293,7 @@ -(void)webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)fra */ -(void)webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame { - if (frame == [self.webPane mainFrame]) + if (frame == (self.webPane).mainFrame) { if (!isLoading) { @@ -310,29 +303,29 @@ -(void)webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame } if (!openURLInBackground) - [[sender window] makeFirstResponder:sender]; + [sender.window makeFirstResponder:sender]; // Show or hide the lock icon depending on whether this is a secure // web page. Also shade the address bar a nice light yellow colour as // Camino does. - NSURL * theURL = [[[frame dataSource] request] URL]; - if ([[theURL scheme] isEqualToString:@"https"]) + NSURL * theURL = frame.dataSource.request.URL; + if ([theURL.scheme isEqualToString:@"https"]) { - [[addressField cell] setHasSecureImage:YES]; - [addressField setBackgroundColor:[NSColor colorWithDeviceRed:1.0 green:1.0 blue:0.777 alpha:1.0]]; + [addressField.cell setHasSecureImage:YES]; + addressField.backgroundColor = [NSColor colorWithDeviceRed:1.0 green:1.0 blue:0.777 alpha:1.0]; [lockIconImage setHidden:NO]; } else { - [[addressField cell] setHasSecureImage:NO]; - [addressField setBackgroundColor:[NSColor whiteColor]]; + [addressField.cell setHasSecureImage:NO]; + addressField.backgroundColor = [NSColor whiteColor]; [lockIconImage setHidden:YES]; } - if (![[frame dataSource] unreachableURL]) - [addressField setStringValue:[theURL absoluteString]]; + if (!frame.dataSource.unreachableURL) + addressField.stringValue = theURL.absoluteString; else - [addressField setStringValue:[[[frame dataSource] unreachableURL] absoluteString]]; + addressField.stringValue = frame.dataSource.unreachableURL.absoluteString; } } @@ -342,29 +335,29 @@ -(void)webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame */ -(void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { - if (frame == [self.webPane mainFrame]) + if (frame == (self.webPane).mainFrame) { // Was this a feed redirect? If so, this isn't an error: - if (![self.webPane isFeedRedirect] && ![self.webPane isDownload]) + if (!(self.webPane).feedRedirect && !(self.webPane).download) { [self setError:error]; // Use a warning sign as favicon - [iconImage setImage:[NSImage imageNamed:@"folderError.tiff"]]; + iconImage.image = [NSImage imageNamed:@"folderError.tiff"]; // Load the localized verion of the error page NSString * pathToErrorPage = [[NSBundle bundleForClass:[self class]] pathForResource:@"errorpage" ofType:@"html"]; if (pathToErrorPage != nil) { NSString *errorMessage = [NSString stringWithContentsOfFile:pathToErrorPage encoding:NSUTF8StringEncoding error:NULL]; - errorMessage = [errorMessage stringByReplacingOccurrencesOfString: @"$ErrorInformation" withString: [error localizedDescription]]; + errorMessage = [errorMessage stringByReplacingOccurrencesOfString: @"$ErrorInformation" withString: error.localizedDescription]; if (errorMessage != nil) { - [frame loadAlternateHTMLString:errorMessage baseURL:[NSURL fileURLWithPath:pathToErrorPage isDirectory:NO] forUnreachableURL:[[[frame provisionalDataSource] request] URL]]; + [frame loadAlternateHTMLString:errorMessage baseURL:[NSURL fileURLWithPath:pathToErrorPage isDirectory:NO] forUnreachableURL:frame.provisionalDataSource.request.URL]; } - NSString *unreachableURL = [[[frame provisionalDataSource] unreachableURL] absoluteString]; + NSString *unreachableURL = frame.provisionalDataSource.unreachableURL.absoluteString; if (unreachableURL != nil) - [addressField setStringValue: [[[frame provisionalDataSource] unreachableURL] absoluteString]]; + addressField.stringValue = frame.provisionalDataSource.unreachableURL.absoluteString; } } [self endFrameLoad]; @@ -381,7 +374,7 @@ -(void)endFrameLoad if ([viewTitle isEqualToString:@""]) { if (lastError == nil) - [[controller browserView] setTabItemViewTitle:self title:pageFilename]; + [controller.browserView setTabItemViewTitle:self title:pageFilename]; } [self willChangeValueForKey:@"isLoading"]; @@ -389,7 +382,6 @@ -(void)endFrameLoad [self didChangeValueForKey:@"isLoading"]; openURLInBackground = NO; - [self release]; } /* didFailLoadWithError @@ -397,26 +389,25 @@ -(void)endFrameLoad */ -(void)webView:(WebView *)sender didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { - if (frame == [self.webPane mainFrame]) + if (frame == (self.webPane).mainFrame) { - // Not really an error. A plugin is grabbing the URL and will handle it - // by itself. - if (!([[error domain] isEqualToString:WebKitErrorDomain] && [error code] == WebKitErrorPlugInWillHandleLoad)) + // Not really errors. Load is cancelled or a plugin is grabbing the URL and will handle it by itself. + if (!([error.domain isEqualToString:WebKitErrorDomain] && (error.code == NSURLErrorCancelled || error.code == WebKitErrorPlugInWillHandleLoad))) { [self setError:error]; // Use a warning sign as favicon - [iconImage setImage:[NSImage imageNamed:@"folderError.tiff"]]; + iconImage.image = [NSImage imageNamed:@"folderError.tiff"]; // Load the localized verion of the error page NSString * pathToErrorPage = [[NSBundle bundleForClass:[self class]] pathForResource:@"errorpage" ofType:@"html"]; if (pathToErrorPage != nil) { NSString *errorMessage = [NSString stringWithContentsOfFile:pathToErrorPage encoding:NSUTF8StringEncoding error:NULL]; - errorMessage = [errorMessage stringByReplacingOccurrencesOfString: @"$ErrorInformation" withString: [error localizedDescription]]; + errorMessage = [errorMessage stringByReplacingOccurrencesOfString: @"$ErrorInformation" withString: error.localizedDescription]; if (errorMessage != nil) { - [frame loadAlternateHTMLString:errorMessage baseURL:[NSURL fileURLWithPath:pathToErrorPage isDirectory:NO] forUnreachableURL:[[[frame dataSource] request] URL]]; + [frame loadAlternateHTMLString:errorMessage baseURL:[NSURL fileURLWithPath:pathToErrorPage isDirectory:NO] forUnreachableURL:frame.dataSource.request.URL]; } } } @@ -429,20 +420,16 @@ -(void)webView:(WebView *)sender didFailLoadWithError:(NSError *)error forFrame: */ -(void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame { - if (frame == [self.webPane mainFrame]) + if (frame == (self.webPane).mainFrame) { // Once the frame is loaded, trawl the source for possible links to RSS // pages. - NSData * webSrc = [[frame dataSource] data]; + NSData * webSrc = frame.dataSource.data; NSMutableArray * arrayOfLinks = [NSMutableArray array]; if ([RichXMLParser extractFeeds:webSrc toArray:arrayOfLinks]) { - [rssPageURL release]; - rssPageURL = [arrayOfLinks objectAtIndex:0]; - if (![rssPageURL hasPrefix:@"http:"] && ![rssPageURL hasPrefix:@"https:"]) - rssPageURL = [[NSURL URLWithString:rssPageURL relativeToURL:[self url]] absoluteString]; - [rssPageURL retain]; + hasRSSlink = YES; [self showRssPageButton:YES]; } [self endFrameLoad]; @@ -454,10 +441,10 @@ -(void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame */ -(void)webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame { - if (frame == [self.webPane mainFrame]) + if (frame == (self.webPane).mainFrame) { - [[controller browserView] setTabItemViewTitle:self title:title]; - [self setViewTitle:title]; + [controller.browserView setTabItemViewTitle:self title:title]; + self.viewTitle = title; } } @@ -466,10 +453,10 @@ -(void)webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(Web */ -(void)webView:(WebView *)sender didReceiveIcon:(NSImage *)image forFrame:(WebFrame *)frame { - if (frame == [self.webPane mainFrame]) + if (frame == (self.webPane).mainFrame) { - [image setSize:NSMakeSize(14, 14)]; - [iconImage setImage:image]; + image.size = NSMakeSize(14, 14); + iconImage.image = image; } } @@ -483,7 +470,7 @@ -(WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)r // Change this to handle modifier key? // Is this covered by the webView policy? { - [controller openURL:[request URL] inPreferredBrowser:YES]; + [controller openURL:request.URL inPreferredBrowser:YES]; return nil; } else @@ -491,9 +478,9 @@ -(WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)r // open a new tab and return its main webview { [controller newTab:nil]; - NSView * theView = [[controller browserView] activeTabItemView]; + NSView * theView = controller.browserView.activeTabItemView; BrowserPane * browserPane = (BrowserPane *)theView; - return [browserPane webPane]; + return browserPane.webPane; } } @@ -535,7 +522,7 @@ - (void)webView:(WebView *)sender runOpenPanelForFileButtonWithResultListener:(i if ( [openDlg runModal] == NSOKButton ) { - NSArray* files = [[openDlg URLs]valueForKey:@"relativePath"]; + NSArray* files = [openDlg.URLs valueForKey:@"relativePath"]; [resultListener chooseFilenames:files]; } } @@ -553,7 +540,7 @@ -(void)webView:(WebView *)sender setFrame:(NSRect)frame -(void)webViewClose:(WebView *)sender { [self handleStopLoading:self]; - [[controller browserView] closeTabItemView:self]; + [controller.browserView closeTabItemView:self]; } /* contextMenuItemsForElement @@ -600,22 +587,22 @@ -(WebView *)webView * Implement the search action. Search the web page for the specified * text. */ --(void)performFindPanelAction:(int)actionTag +-(void)performFindPanelAction:(NSInteger)actionTag { switch (actionTag) { case NSFindPanelActionSetFindString: { - [self.webPane searchFor:[controller searchString] direction:YES caseSensitive:NO wrap:YES]; + [self.webPane searchFor:controller.searchString direction:YES caseSensitive:NO wrap:YES]; break; } case NSFindPanelActionNext: - [self.webPane searchFor:[controller searchString] direction:YES caseSensitive:NO wrap:YES]; + [self.webPane searchFor:controller.searchString direction:YES caseSensitive:NO wrap:YES]; break; case NSFindPanelActionPrevious: - [self.webPane searchFor:[controller searchString] direction:NO caseSensitive:NO wrap:YES]; + [self.webPane searchFor:controller.searchString direction:NO caseSensitive:NO wrap:YES]; break; } } @@ -626,14 +613,14 @@ -(void)performFindPanelAction:(int)actionTag -(NSURL *)url { NSURL * theURL = nil; - WebDataSource * dataSource = [[self.webPane mainFrame] dataSource]; + WebDataSource * dataSource = (self.webPane).mainFrame.dataSource; if (dataSource != nil) { - theURL = [[dataSource request] URL]; + theURL = dataSource.request.URL; } else { - NSString * urlString = [addressField stringValue]; + NSString * urlString = addressField.stringValue; if (urlString != nil) theURL = [NSURL URLWithString:urlString]; } @@ -650,7 +637,7 @@ -(NSString *)viewTitle */ -(BOOL)canGoForward { - return [self.webPane canGoForward]; + return (self.webPane).canGoForward; } /* canGoBack @@ -658,7 +645,7 @@ -(BOOL)canGoForward */ -(BOOL)canGoBack { - return [self.webPane canGoBack]; + return (self.webPane).canGoBack; } /* handleGoForward @@ -682,8 +669,8 @@ -(IBAction)handleGoBack:(id)sender */ -(void)swipeWithEvent:(NSEvent *)event { - CGFloat deltaX = [event deltaX]; - CGFloat deltaY = [event deltaY]; + CGFloat deltaX = event.deltaX; + CGFloat deltaY = event.deltaY; // If the horizontal component of the swipe is larger, the user wants to go back or forward... if (fabs(deltaX) > fabs(deltaY)) @@ -714,7 +701,7 @@ -(void)swipeWithEvent:(NSEvent *)event */ -(IBAction)handleReload:(id)sender { - if ([[self.webPane mainFrame] dataSource] != nil) + if ((self.webPane).mainFrame.dataSource != nil) [self.webPane reload:self]; else [self handleAddress:self]; @@ -730,7 +717,7 @@ -(void)handleStopLoading:(id)sender [self.webPane setUIDelegate:nil]; [self.webPane stopLoading:self]; [self didChangeValueForKey:@"isLoading"]; - [[self.webPane mainFrame] loadHTMLString:@"" baseURL:nil]; + [(self.webPane).mainFrame loadHTMLString:@"" baseURL:nil]; } /* handleRSSPage @@ -738,17 +725,19 @@ -(void)handleStopLoading:(id)sender */ -(IBAction)handleRSSPage:(id)sender { - if (rssPageURL != nil) + if (hasRSSlink) { - Folder * currentFolder = [NSApp currentFolder]; - int currentFolderId = [currentFolder itemId]; - int parentFolderId = [currentFolder parentId]; - if ([currentFolder firstChildId] > 0) + Folder * currentFolder = APP.currentFolder; + NSInteger currentFolderId = currentFolder.itemId; + NSInteger parentFolderId = currentFolder.parentId; + if (currentFolder.firstChildId > 0) { parentFolderId = currentFolderId; currentFolderId = 0; } - [APPCONTROLLER createNewSubscription:rssPageURL underFolder:parentFolderId afterChild:currentFolderId]; + SubscriptionModel *subscription = [[SubscriptionModel alloc] init]; + NSString * verifiedURLString = [subscription verifiedFeedURLFromURL:self.url].absoluteString; + [APPCONTROLLER createNewSubscription:verifiedURLString underFolder:parentFolderId afterChild:currentFolderId]; } } @@ -765,14 +754,14 @@ -(BOOL)isLoading */ -(BOOL)isProcessing { - return [self isLoading]; + return self.loading; } /* handleKeyDown [delegate] * Support special key codes. If we handle the key, return YES otherwise * return NO to allow the framework to pass it on for default processing. */ --(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger )flags +-(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger)flags { return NO; } @@ -782,20 +771,9 @@ -(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger )flags */ -(void)dealloc { - [viewTitle release]; - viewTitle=nil; - [rssPageURL release]; - rssPageURL=nil; [self handleStopLoading:nil]; [webPane setFrameLoadDelegate:nil]; [webPane setUIDelegate:nil]; [webPane close]; - [lastError release]; - lastError=nil; - [pageFilename release]; - pageFilename=nil; - [webPane release]; - webPane = nil; - [super dealloc]; } @end diff --git a/src/BrowserPaneTemplate.h b/src/BrowserPaneTemplate.h index df99144f1f..6520286519 100644 --- a/src/BrowserPaneTemplate.h +++ b/src/BrowserPaneTemplate.h @@ -24,5 +24,7 @@ IBOutlet BrowserPane * browserPane; } --(BrowserPane *)mainView; +@property(strong) NSArray * topObjects; + +@property (nonatomic, readonly, strong) BrowserPane *mainView; @end diff --git a/src/BrowserPaneTemplate.m b/src/BrowserPaneTemplate.m index 04cb4d60f2..b05f2c9958 100644 --- a/src/BrowserPaneTemplate.m +++ b/src/BrowserPaneTemplate.m @@ -21,10 +21,14 @@ @implementation BrowserPaneTemplate --(id)init +-(instancetype)init { if ((self = [super init]) != nil) - [NSBundle loadNibNamed:@"BrowserPane" owner:self]; + { + NSArray * objects; + [[NSBundle bundleForClass:[self class]] loadNibNamed:@"BrowserPane" owner:self topLevelObjects:&objects]; + self.topObjects = objects; + } return self; } @@ -33,11 +37,4 @@ -(BrowserPane *)mainView return browserPane; } --(void)dealloc -{ - [browserPane release]; - browserPane=nil; - [super dealloc]; -} - @end diff --git a/src/BrowserView.h b/src/BrowserView.h index 037639507d..f31b80d379 100644 --- a/src/BrowserView.h +++ b/src/BrowserView.h @@ -27,7 +27,6 @@ @interface BrowserView : NSView { NSView * primaryTabItemView; - IBOutlet NSTabView * tabView; IBOutlet PSMTabBarControl * tabBarControl; } @@ -35,12 +34,12 @@ -(void)setPrimaryTabItemView:(NSView *)newPrimaryTabItemView; -(void)setTabItemViewTitle:(NSView *)tabView title:(NSString *)newTitle; -(NSString *)tabItemViewTitle:(NSView *)tabView; --(NSView *)activeTabItemView; +@property (nonatomic, readonly, strong) NSView *activeTabItemView; -(NSView *)primaryTabItemView; -(void)setActiveTabToPrimaryTab; -(void)closeTabItemView:(NSView *)theTab; -(void)closeAllTabs; --(int)countOfTabs; +@property (nonatomic, readonly) NSInteger countOfTabs; -(void)createNewTabWithView:(NSView *)newTabView makeKey:(BOOL)keyIt; -(void)showTabItemView:(NSView *)theTabView; -(void)showPreviousTab; diff --git a/src/BrowserView.m b/src/BrowserView.m index 485c51013a..4e3d41fd86 100644 --- a/src/BrowserView.m +++ b/src/BrowserView.m @@ -22,6 +22,7 @@ #import "Preferences.h" #import "Constants.h" #import +#import #import "AppController.h" @interface NSTabView (BrowserViewAdditions) @@ -40,11 +41,17 @@ -(NSTabViewItem *)tabViewItemWithIdentifier:(id)identifier } @end +@interface BrowserView () + +@property (weak, nonatomic) IBOutlet NSTabView *tabView; + +@end + @implementation BrowserView -(void)awakeFromNib { - [[tabView tabViewItemAtIndex:0] setLabel:NSLocalizedString(@"Articles", nil)]; + [[self.tabView tabViewItemAtIndex:0] setLabel:NSLocalizedString(@"Articles", nil)]; //Metal is the default [tabBarControl setStyleNamed:@"Unified"]; @@ -53,12 +60,12 @@ -(void)awakeFromNib [tabBarControl setUseOverflowMenu:YES]; [tabBarControl setAllowsBackgroundTabClosing:YES]; [tabBarControl setAutomaticallyAnimates:NO]; - [tabBarControl setCellMinWidth:60]; - [tabBarControl setCellMaxWidth:350]; + tabBarControl.cellMinWidth = 60.0; + tabBarControl.cellMaxWidth = 350.0; [tabBarControl setShowAddTabButton:YES]; - [[tabBarControl addTabButton] setTarget:[NSApp delegate]]; - [[tabBarControl addTabButton] setAction:@selector(newTab:)]; + tabBarControl.addTabButton.target = NSApp.delegate; + tabBarControl.addTabButton.action = @selector(newTab:); } /* stringForToolTip @@ -68,7 +75,7 @@ -(void)awakeFromNib */ -(NSString *)view:(NSView *)view stringForToolTip:(NSToolTipTag)tag point:(NSPoint)point userData:(void *)userData { - return [[tabView tabViewItemWithIdentifier:(NSView *)userData] label]; + return [self.tabView tabViewItemWithIdentifier:(__bridge NSView *)userData].label; } /* setPrimaryTabItemView @@ -77,23 +84,21 @@ -(NSString *)view:(NSView *)view stringForToolTip:(NSToolTipTag)tag point:(NSPoi */ -(void)setPrimaryTabItemView:(NSView *)newPrimaryTabItemView { - [newPrimaryTabItemView retain]; NSTabViewItem * item; if (primaryTabItemView == nil) { // This should only be called on launch - item = [tabView tabViewItemAtIndex:0]; + item = [self.tabView tabViewItemAtIndex:0]; } else { - item = [tabView tabViewItemWithIdentifier:primaryTabItemView]; + item = [self.tabView tabViewItemWithIdentifier:primaryTabItemView]; } - [item setIdentifier:newPrimaryTabItemView]; - [item setView:newPrimaryTabItemView]; + item.identifier = newPrimaryTabItemView; + item.view = newPrimaryTabItemView; - [primaryTabItemView release]; primaryTabItemView = newPrimaryTabItemView; [primaryTabItemView setNeedsDisplay:YES]; @@ -105,7 +110,7 @@ -(void)setPrimaryTabItemView:(NSView *)activeTabItemView { - return [[tabView selectedTabViewItem] identifier]; + return self.tabView.selectedTabViewItem.identifier; } /* setActiveTabToPrimaryTab @@ -131,9 +136,8 @@ -(void)setActiveTabToPrimaryTab -(void)createNewTabWithView:(NSView *)newTabView makeKey:(BOOL)keyIt { NSTabViewItem *tabViewItem = [[NSTabViewItem alloc] initWithIdentifier:newTabView]; - [tabViewItem setView:newTabView]; - [tabView addTabViewItem:tabViewItem]; - [tabViewItem release]; + tabViewItem.view = newTabView; + [self.tabView addTabViewItem:tabViewItem]; if (keyIt) [self showTabItemView:newTabView]; } @@ -143,7 +147,7 @@ -(void)createNewTabWithView:(NSView *)newTabView makeKey:(BOOL)keyIt */ -(void)setTabItemViewTitle:(NSView *)inTabView title:(NSString *)newTitle { - [[tabView tabViewItemWithIdentifier:inTabView] setLabel:newTitle]; + [self.tabView tabViewItemWithIdentifier:inTabView].label = newTitle; } /* tabTitle @@ -151,7 +155,7 @@ -(void)setTabItemViewTitle:(NSView *)inTabView title:(NSString *)newTitle */ -(NSString *)tabItemViewTitle:(NSView *)tabItemView { - return [[tabView tabViewItemWithIdentifier:tabItemView] label]; + return [self.tabView tabViewItemWithIdentifier:tabItemView].label; } /* closeAllTabs @@ -159,13 +163,13 @@ -(NSString *)tabItemViewTitle:(NSView *)tabItemView */ -(void)closeAllTabs { - int count = [tabView numberOfTabViewItems]; - int i; + NSInteger count = self.tabView.numberOfTabViewItems; + NSInteger i; for ((i = (count - 1)); i >= 0; i--) { - NSTabViewItem * item = [tabView tabViewItemAtIndex:i]; - if ([item identifier] != primaryTabItemView) + NSTabViewItem * item = [self.tabView tabViewItemAtIndex:i]; + if (item.identifier != primaryTabItemView) { - [tabView removeTabViewItem:item]; + [self.tabView removeTabViewItem:item]; } } } @@ -177,28 +181,28 @@ -(void)closeAllTabs -(void)closeTabItemView:(NSView *)tabItemView { if (tabItemView != primaryTabItemView) { - NSTabViewItem *tabViewItem = [tabView tabViewItemWithIdentifier:tabItemView]; - int oldIndex = [tabView indexOfTabViewItem:tabViewItem]; + NSTabViewItem *tabViewItem = [self.tabView tabViewItemWithIdentifier:tabItemView]; + NSInteger oldIndex = [self.tabView indexOfTabViewItem:tabViewItem]; - if ([tabView numberOfTabViewItems] > (oldIndex + 1)) { - [tabView selectTabViewItemAtIndex:(oldIndex + 1)]; + if (self.tabView.numberOfTabViewItems > (oldIndex + 1)) { + [self.tabView selectTabViewItemAtIndex:(oldIndex + 1)]; } - [tabView removeTabViewItem:tabViewItem]; + [self.tabView removeTabViewItem:tabViewItem]; } } - (BOOL)tabView:(NSTabView *)inTabView shouldCloseTabViewItem:(NSTabViewItem *)tabViewItem { - if ([tabViewItem identifier] == primaryTabItemView) + if (tabViewItem.identifier == primaryTabItemView) { return NO; } else { - int oldIndex = [tabView indexOfTabViewItem:tabViewItem]; - if ([tabView numberOfTabViewItems] > (oldIndex + 1)) { - [tabView selectTabViewItemAtIndex:(oldIndex + 1)]; + NSInteger oldIndex = [self.tabView indexOfTabViewItem:tabViewItem]; + if (self.tabView.numberOfTabViewItems > (oldIndex + 1)) { + [self.tabView selectTabViewItemAtIndex:(oldIndex + 1)]; } return YES; @@ -208,9 +212,9 @@ - (BOOL)tabView:(NSTabView *)inTabView shouldCloseTabViewItem:(NSTabViewItem *)t /* countOfTabs * Returns the total number of tabs. */ --(int)countOfTabs +-(NSInteger)countOfTabs { - return [tabView numberOfTabViewItems]; + return self.tabView.numberOfTabViewItems; } /* showTabVew @@ -218,8 +222,8 @@ -(int)countOfTabs */ -(void)showTabItemView:(NSView *)theTabView { - if ([tabView tabViewItemWithIdentifier:theTabView]) { - [tabView selectTabViewItemWithIdentifier:theTabView]; + if ([self.tabView tabViewItemWithIdentifier:theTabView]) { + [self.tabView selectTabViewItemWithIdentifier:theTabView]; } } @@ -229,10 +233,10 @@ -(void)showTabItemView:(NSView *)theTabView */ -(void)showPreviousTab { - if ([tabView indexOfTabViewItem:[tabView selectedTabViewItem]] == 0) - [tabView selectLastTabViewItem:self]; + if ([self.tabView indexOfTabViewItem:self.tabView.selectedTabViewItem] == 0) + [self.tabView selectLastTabViewItem:self]; else - [tabView selectPreviousTabViewItem:self]; + [self.tabView selectPreviousTabViewItem:self]; } /* showNextTab @@ -241,10 +245,10 @@ -(void)showPreviousTab */ -(void)showNextTab { - if ([tabView indexOfTabViewItem:[tabView selectedTabViewItem]] == ([tabView numberOfTabViewItems] - 1)) - [tabView selectFirstTabViewItem:self]; + if ([self.tabView indexOfTabViewItem:self.tabView.selectedTabViewItem] == (self.tabView.numberOfTabViewItems - 1)) + [self.tabView selectFirstTabViewItem:self]; else - [tabView selectNextTabViewItem:self]; + [self.tabView selectNextTabViewItem:self]; } /* didSelectTabViewItem @@ -252,7 +256,7 @@ -(void)showNextTab */ -(void)tabView:(NSTabView *)inTabView didSelectTabViewItem:(NSTabViewItem *)inTabViewItem { - [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_TabChanged" object:[inTabViewItem identifier]]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_TabChanged" object:inTabViewItem.identifier]; } - (void)tabViewDidChangeNumberOfTabViewItems:(NSTabView *)tabView @@ -266,7 +270,7 @@ - (void)tabViewDidChangeNumberOfTabViewItems:(NSTabView *)tabView */ -(BOOL)tabView:(NSTabView *)aTabView disableTabCloseForTabViewItem:(NSTabViewItem *)tabViewItem { - return ([tabViewItem identifier] == primaryTabItemView); + return (tabViewItem.identifier == primaryTabItemView); } /* tabView:shouldDragTabViewItem:fromTabBar: @@ -307,12 +311,12 @@ - (BOOL)tabView:(NSTabView *)aTabView shouldAllowTabViewItem:(NSTabViewItem *)ta */ -(void)saveOpenTabs { - NSMutableArray *tabLinks = [NSMutableArray arrayWithCapacity:[self countOfTabs]]; + NSMutableArray *tabLinks = [NSMutableArray arrayWithCapacity:self.countOfTabs]; - for (NSTabViewItem * tabViewItem in [tabView tabViewItems]) + for (NSTabViewItem * tabViewItem in self.tabView.tabViewItems) { - NSView * theView = [tabViewItem identifier]; - NSString * tabLink = [theView viewLink]; + NSView * theView = tabViewItem.identifier; + NSString * tabLink = theView.viewLink; if (tabLink != nil) [tabLinks addObject:tabLink]; } @@ -328,12 +332,5 @@ -(void)saveOpenTabs -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - [tabBarControl release]; - tabBarControl=nil; - [primaryTabItemView release]; - primaryTabItemView=nil; - [tabView release]; - tabView=nil; - [super dealloc]; } @end diff --git a/src/CalendarExtensions.h b/src/CalendarExtensions.h index 8c1da7d288..fec3a51f1e 100644 --- a/src/CalendarExtensions.h +++ b/src/CalendarExtensions.h @@ -22,6 +22,6 @@ @interface NSCalendarDate (CalendarExtensions) +(NSCalendarDate *)today; - -(NSString *)friendlyDescription; + @property (nonatomic, readonly, copy) NSString *friendlyDescription; @end diff --git a/src/CalendarExtensions.m b/src/CalendarExtensions.m index 91434a05ef..80f5b1f81a 100644 --- a/src/CalendarExtensions.m +++ b/src/CalendarExtensions.m @@ -55,8 +55,8 @@ -(NSString *)friendlyDescription // Note: NSUserDefaults provide built-in localized names for today, yesterday // and tomorrow. We don't use them because the initial letter isn't capitalized // and it's tough to make assumptions about how to capitalize a localized string. - int todayNum = [[NSCalendarDate calendarDate] dayOfCommonEra]; - int myNum = [self dayOfCommonEra]; + NSInteger todayNum = [[NSCalendarDate calendarDate] dayOfCommonEra]; + NSInteger myNum = [self dayOfCommonEra]; if (myNum == todayNum) { diff --git a/src/ClickableProgressIndicator.m b/src/ClickableProgressIndicator.m index 6c605d8afb..f0fc082887 100644 --- a/src/ClickableProgressIndicator.m +++ b/src/ClickableProgressIndicator.m @@ -20,7 +20,12 @@ - (void)setAction:(SEL)inAction - (void)mouseDown:(NSEvent *)inEvent { if (target && action) - [target performSelector:action withObject:self]; + { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + [target performSelector:action withObject:self]; +#pragma clang diagnostic pop + } else [super mouseDown:inEvent]; } diff --git a/src/Constants.h b/src/Constants.h index bd9053e29f..128b084bc1 100644 --- a/src/Constants.h +++ b/src/Constants.h @@ -18,6 +18,8 @@ // limitations under the License. // +@import Foundation; + extern NSString * MA_DefaultStyleName; extern NSString * MA_DefaultUserAgentString; extern NSString * MA_BrowserUserAgentString; @@ -85,8 +87,8 @@ extern float MA_Default_Read_Interval; extern NSInteger MA_Default_MinimumFontSize; extern NSInteger MA_Default_AutoExpireDuration; extern NSInteger MA_Default_Check_Frequency; -extern float MA_Default_Main_Window_Min_Width; -extern float MA_Default_Main_Window_Min_Height; +extern CGFloat MA_Default_Main_Window_Min_Width; +extern CGFloat MA_Default_Main_Window_Min_Height; extern NSInteger MA_Default_ConcurrentDownloads; extern NSString * MA_PBoardType_RSSItem; @@ -112,7 +114,6 @@ extern NSString * MA_PBoardType_urln; // Refresh folder options #define MA_Refresh_RedrawList 0 #define MA_Refresh_ReapplyFilter 1 -#define MA_Refresh_ReloadFromDatabase 2 #define MA_Refresh_SortAndRedraw 3 // Growl contexts @@ -124,20 +125,20 @@ extern NSString * MA_PBoardType_urln; #define MA_ViewTag_Filterbar 1 #define MA_ViewTag_Statusbar 2 -const AEKeyword EditDataItemAppleEventClass; -const AEKeyword EditDataItemAppleEventID; -const AEKeyword DataItemTitle; -const AEKeyword DataItemDescription; -const AEKeyword DataItemSummary; -const AEKeyword DataItemLink; -const AEKeyword DataItemPermalink; -const AEKeyword DataItemSubject; -const AEKeyword DataItemCreator; -const AEKeyword DataItemCommentsURL; -const AEKeyword DataItemGUID; -const AEKeyword DataItemSourceName; -const AEKeyword DataItemSourceHomeURL; -const AEKeyword DataItemSourceFeedURL; +extern AEKeyword EditDataItemAppleEventClass; +extern AEKeyword EditDataItemAppleEventID; +extern AEKeyword DataItemTitle; +extern AEKeyword DataItemDescription; +extern AEKeyword DataItemSummary; +extern AEKeyword DataItemLink; +extern AEKeyword DataItemPermalink; +extern AEKeyword DataItemSubject; +extern AEKeyword DataItemCreator; +extern AEKeyword DataItemCommentsURL; +extern AEKeyword DataItemGUID; +extern AEKeyword DataItemSourceName; +extern AEKeyword DataItemSourceHomeURL; +extern AEKeyword DataItemSourceFeedURL; // Layout styles #define MA_Layout_Report 1 @@ -154,7 +155,7 @@ const AEKeyword DataItemSourceFeedURL; #define MA_EmptyTrash_WithWarning 2 // Sync types -typedef enum { +typedef NS_ENUM(unsigned int, SyncTypes) { MA_Sync_Subscribe, MA_Sync_Unsubscribe, MA_Sync_Delete, @@ -166,6 +167,6 @@ typedef enum { MA_Sync_Mark_Unread, MA_Sync_Mark_Flagged, MA_Sync_Mark_Unflagged -} SyncTypes; +}; //extern NSString * MA_Sync_FolderSeparator; diff --git a/src/Constants.m b/src/Constants.m index c277bcad67..3cd3f87c5c 100644 --- a/src/Constants.m +++ b/src/Constants.m @@ -18,6 +18,8 @@ // limitations under the License. // +@import Foundation; + NSString * MA_DefaultUserAgentString = @"Mozilla/5.0 Vienna/%@"; NSString * MA_BrowserUserAgentString = @"Vienna/%@ Version/%@ Safari/%@"; @@ -84,8 +86,8 @@ const float MA_Default_Read_Interval = 0.5; const NSInteger MA_Default_AutoExpireDuration = 0; const NSInteger MA_Default_Check_Frequency = 10800; -const float MA_Default_Main_Window_Min_Width = 700.0; -const float MA_Default_Main_Window_Min_Height = 350.0; +const CGFloat MA_Default_Main_Window_Min_Width = 700.0; +const CGFloat MA_Default_Main_Window_Min_Height = 350.0; const NSInteger MA_Default_ConcurrentDownloads = 10; // Constants for External Weblog Editor Interface according to http://ranchero.com/netnewswire/developers/externalinterface.php diff --git a/src/Criteria.h b/src/Criteria.h index 3a2ab00c36..9a8314b9d9 100644 --- a/src/Criteria.h +++ b/src/Criteria.h @@ -22,7 +22,7 @@ /* Enum of valid criteria operators */ -typedef enum { +typedef NS_ENUM(NSUInteger, CriteriaOperator) { MA_CritOper_Is = 1, MA_CritOper_IsNot, MA_CritOper_IsLessThan, @@ -37,13 +37,13 @@ typedef enum { MA_CritOper_IsOnOrAfter, MA_CritOper_Under, MA_CritOper_NotUnder -} CriteriaOperator; +} ; -typedef enum { +typedef NS_ENUM(NSUInteger, CriteriaCondition) { MA_CritCondition_All = 0, MA_CritCondition_Any, MA_CritCondition_Invalid -} CriteriaCondition; +}; @interface Criteria : NSObject { NSString * field; @@ -52,16 +52,13 @@ typedef enum { } // Public functions --(id)initWithField:(NSString *)newField withOperator:(CriteriaOperator)newOperator withValue:(NSString *)newValue; +-(instancetype)initWithField:(NSString *)newField withOperator:(CriteriaOperator)newOperator withValue:(NSString *)newValue NS_DESIGNATED_INITIALIZER; +(NSString *)stringFromOperator:(CriteriaOperator)operator; +(CriteriaOperator)operatorFromString:(NSString *)string; +(NSArray *)arrayOfOperators; --(void)setField:(NSString *)newField; --(void)setOperator:(CriteriaOperator)newOperator; --(void)setValue:(NSString *)newValue; --(NSString *)field; --(NSString *)value; --(CriteriaOperator)operator; +@property (nonatomic, copy) NSString *field; +@property (nonatomic, copy) NSString *value; +@property (nonatomic) CriteriaOperator operator; @end @interface CriteriaTree : NSObject { @@ -70,12 +67,11 @@ typedef enum { } // Public functions --(id)initWithString:(NSString *)string; --(NSEnumerator *)criteriaEnumerator; +-(instancetype)initWithString:(NSString *)string NS_DESIGNATED_INITIALIZER; +@property (nonatomic, readonly, strong) NSEnumerator *criteriaEnumerator; -(void)addCriteria:(Criteria *)newCriteria; --(NSString *)string; --(CriteriaCondition)condition; --(void)setCondition:(CriteriaCondition)newCondition; +@property (nonatomic, readonly, copy) NSString *string; +@property (nonatomic) CriteriaCondition condition; +(CriteriaCondition)conditionFromString:(NSString *)string; +(NSString *)conditionToString:(CriteriaCondition)condition; @end diff --git a/src/Criteria.m b/src/Criteria.m index 0f3d6e2b0a..1e3ebf898e 100644 --- a/src/Criteria.m +++ b/src/Criteria.m @@ -19,14 +19,13 @@ // #import "Criteria.h" -#import "XMLParser.h" @implementation Criteria /* init * Initialise an empty Criteria. */ --(id)init +-(instancetype)init { return [self initWithField:@"" withOperator:0 withValue:@""]; } @@ -34,13 +33,13 @@ -(id)init /* initWithField * Initalises a new Criteria with the specified values. */ --(id)initWithField:(NSString *)newField withOperator:(CriteriaOperator)newOperator withValue:(NSString *)newValue +-(instancetype)initWithField:(NSString *)newField withOperator:(CriteriaOperator)newOperator withValue:(NSString *)newValue { if ((self = [super init]) != nil) { - [self setField:newField]; - [self setOperator:newOperator]; - [self setValue:newValue]; + self.field = newField; + self.operator = newOperator; + self.value = newValue; } return self; } @@ -82,9 +81,9 @@ +(CriteriaOperator)operatorFromString:(NSString *)string NSArray * operatorArray = [Criteria arrayOfOperators]; NSUInteger index; - for (index = 0; index < [operatorArray count]; ++index) + for (index = 0; index < operatorArray.count; ++index) { - CriteriaOperator op = [[operatorArray objectAtIndex:index] intValue]; + CriteriaOperator op = [operatorArray[index] integerValue]; if ([string isEqualToString:[Criteria stringFromOperator:op]]) return op; } @@ -96,22 +95,22 @@ +(CriteriaOperator)operatorFromString:(NSString *)string */ +(NSArray *)arrayOfOperators { - return [NSArray arrayWithObjects: - [NSNumber numberWithInt:MA_CritOper_Is], - [NSNumber numberWithInt:MA_CritOper_IsNot], - [NSNumber numberWithInt:MA_CritOper_IsAfter], - [NSNumber numberWithInt:MA_CritOper_IsBefore], - [NSNumber numberWithInt:MA_CritOper_IsOnOrAfter], - [NSNumber numberWithInt:MA_CritOper_IsOnOrBefore], - [NSNumber numberWithInt:MA_CritOper_Contains], - [NSNumber numberWithInt:MA_CritOper_NotContains], - [NSNumber numberWithInt:MA_CritOper_IsLessThan], - [NSNumber numberWithInt:MA_CritOper_IsLessThanOrEqual], - [NSNumber numberWithInt:MA_CritOper_IsGreaterThan], - [NSNumber numberWithInt:MA_CritOper_IsGreaterThanOrEqual], - [NSNumber numberWithInt:MA_CritOper_Under], - [NSNumber numberWithInt:MA_CritOper_NotUnder], - nil]; + return @[ + @(MA_CritOper_Is), + @(MA_CritOper_IsNot), + @(MA_CritOper_IsAfter), + @(MA_CritOper_IsBefore), + @(MA_CritOper_IsOnOrAfter), + @(MA_CritOper_IsOnOrBefore), + @(MA_CritOper_Contains), + @(MA_CritOper_NotContains), + @(MA_CritOper_IsLessThan), + @(MA_CritOper_IsLessThanOrEqual), + @(MA_CritOper_IsGreaterThan), + @(MA_CritOper_IsGreaterThanOrEqual), + @(MA_CritOper_Under), + @(MA_CritOper_NotUnder) + ]; } /* setField @@ -119,8 +118,6 @@ +(NSArray *)arrayOfOperators */ -(void)setField:(NSString *)newField { - [newField retain]; - [field release]; field = newField; } @@ -143,8 +140,6 @@ -(void)setOperator:(CriteriaOperator)newOperator */ -(void)setValue:(NSString *)newValue { - [newValue retain]; - [value release]; value = newValue; } @@ -172,25 +167,15 @@ -(NSString *)value return value; } -/* dealloc - * Clean up and release resources. - */ --(void)dealloc -{ - [value release]; - value=nil; - [field release]; - field=nil; - [super dealloc]; -} @end + @implementation CriteriaTree /* init * Initialise an empty CriteriaTree */ --(id)init +-(instancetype)init { return [self initWithString:@""]; } @@ -199,44 +184,41 @@ -(id)init * Initialises an criteria tree object with the specified string. The caller is responsible for * releasing the tree. */ --(id)initWithString:(NSString *)string +-(instancetype)initWithString:(NSString *)string { if ((self = [super init]) != nil) { criteriaTree = [[NSMutableArray alloc] init]; condition = MA_CritCondition_All; - const char * utf8String = [string UTF8String]; - NSData * data = [NSData dataWithBytes:utf8String length:strlen(utf8String)]; - XMLParser * xmlTree = [[XMLParser alloc] init]; - if ([data length] > 0 && [xmlTree setData:data]) + NSError *error = nil; + NSXMLDocument *criteriaTreeDoc = [[NSXMLDocument alloc] + initWithXMLString:string + options:NSXMLNodeOptionsNone + error:&error]; + + if (!error) { - XMLParser * criteriaGroup = [xmlTree treeByName:@"criteriagroup"]; - int index = 0; - - // For backward compatibility, the absence of the condition attribute - // assumes that we're matching ALL conditions. - condition = [CriteriaTree conditionFromString:[criteriaGroup valueOfAttribute:@"condition"]]; - if (condition == MA_CritCondition_Invalid) - condition = MA_CritCondition_All; - - if (criteriaGroup != nil) - while (index < [criteriaGroup countOfChildren]) - { - XMLParser * subTree = [criteriaGroup treeByIndex:index]; - NSString * fieldName = [subTree valueOfAttribute:@"field"]; - NSString * operator = [[subTree treeByName:@"operator"] valueOfElement]; - NSString * value = [[subTree treeByName:@"value"] valueOfElement]; - - Criteria * newCriteria = [[Criteria alloc] init]; - [newCriteria setField:fieldName]; - [newCriteria setOperator:[operator intValue]]; - [newCriteria setValue:value]; - [self addCriteria:newCriteria]; - [newCriteria release]; - ++index; - } - } - [xmlTree release]; + NSArray *criteriaArray = [criteriaTreeDoc.rootElement elementsForName:@"criteria"]; + condition = [CriteriaTree conditionFromString:[criteriaTreeDoc.rootElement attributeForName:@"condition"].stringValue]; + if (condition == MA_CritCondition_Invalid) { + // For backward compatibility, the absence of the condition attribute + // assumes that we're matching ALL conditions. + condition = MA_CritCondition_All; + } + + for (NSXMLElement *criteriaElement in criteriaArray) { + NSString *fieldname = [criteriaElement attributeForName:@"field"].stringValue; + NSString *operator = [criteriaElement elementsForName:@"operator"].firstObject.stringValue; + NSString *value = [criteriaElement elementsForName:@"value"].firstObject.stringValue; + + Criteria *newCriteria = [[Criteria alloc] + initWithField:fieldname + withOperator:operator.integerValue + withValue:value]; + [self addCriteria:newCriteria]; + + } + } } return self; } @@ -250,9 +232,9 @@ +(CriteriaCondition)conditionFromString:(NSString *)string { if (string != nil) { - if ([[string lowercaseString] isEqualToString:@"any"]) + if ([string.lowercaseString isEqualToString:@"any"]) return MA_CritCondition_Any; - if ([[string lowercaseString] isEqualToString:@"all"]) + if ([string.lowercaseString isEqualToString:@"all"]) return MA_CritCondition_All; } return MA_CritCondition_Invalid; @@ -311,33 +293,35 @@ -(void)addCriteria:(Criteria *)newCriteria */ -(NSString *)string { - XMLParser * newTree = [[XMLParser alloc] initWithEmptyTree]; - NSDictionary * conditionDict = [NSDictionary dictionaryWithObject:[CriteriaTree conditionToString:condition] forKey:@"condition"]; - XMLParser * groupTree = [newTree addTree:@"criteriagroup" withAttributes:conditionDict]; - NSUInteger index; - - for (index = 0; index < [criteriaTree count]; ++index) - { - Criteria * criteria = [criteriaTree objectAtIndex:index]; - NSDictionary * criteriaDict = [NSDictionary dictionaryWithObject:[criteria field] forKey:@"field"]; - XMLParser * oneCriteriaTree = [groupTree addTree:@"criteria" withAttributes:criteriaDict]; - - [oneCriteriaTree addTree:@"operator" withElement:[NSString stringWithFormat:@"%d", [criteria operator]]]; - [oneCriteriaTree addTree:@"value" withElement:[criteria value]]; - } - - NSString * criteriaString = [newTree xmlForTree]; - [newTree release]; - return criteriaString; + NSXMLDocument *criteriaDoc = [NSXMLDocument document]; + [criteriaDoc setStandalone:YES]; + criteriaDoc.characterEncoding = @"UTF-8"; + criteriaDoc.version = @"1.0"; + + NSDictionary * conditionDict = @{@"condition": [CriteriaTree conditionToString:condition]}; + NSXMLElement *criteriaGroup = [[NSXMLElement alloc] initWithName:@"criteriagroup"]; + [criteriaGroup setAttributesWithDictionary:conditionDict]; + + for (Criteria *criteria in criteriaTree) { + NSDictionary * criteriaDict = @{@"field": criteria.field}; + NSXMLElement *criteriaElement = [[NSXMLElement alloc] initWithName:@"criteria"]; + [criteriaElement setAttributesWithDictionary:criteriaDict]; + NSXMLElement *operatorElement = [[NSXMLElement alloc] + initWithName:@"operator" + stringValue:[NSString stringWithFormat: + @"%lu", (unsigned long)criteria.operator]]; + NSXMLElement *valueElement = [[NSXMLElement alloc] + initWithName:@"value" + stringValue:criteria.value]; + + [criteriaGroup addChild:criteriaElement]; + [criteriaElement addChild:operatorElement]; + [criteriaElement addChild:valueElement]; + + } + [criteriaDoc addChild:criteriaGroup]; + + return criteriaDoc.XMLString; } -/* dealloc - * Clean up and release resources. - */ --(void)dealloc -{ - [criteriaTree release]; - criteriaTree=nil; - [super dealloc]; -} @end diff --git a/src/Database.h b/src/Database.h index ec3b110cb9..db2802b315 100644 --- a/src/Database.h +++ b/src/Database.h @@ -19,66 +19,42 @@ // #import -#import "FMDatabase.h" +#import "FMDB.h" #import "Folder.h" #import "Field.h" #import "Criteria.h" @interface Database : NSObject { - FMDatabase * sqlDatabase; BOOL initializedfoldersDict; BOOL initializedSmartfoldersDict; BOOL readOnly; - int databaseVersion; - int countOfUnread; - NSThread * mainThread; - BOOL inTransaction; + NSInteger countOfUnread; NSString * searchString; NSMutableArray * fieldsOrdered; NSMutableDictionary * fieldsByName; NSMutableDictionary * fieldsByTitle; NSMutableDictionary * foldersDict; NSMutableDictionary * smartfoldersDict; - dispatch_queue_t _transactionQueue; - dispatch_queue_t _execQueue; Folder * trashFolder; Folder * searchFolder; + FMDatabaseQueue *databaseQueue; } -@property(nonatomic, retain) Folder * trashFolder; -@property(nonatomic, retain) Folder * searchFolder; +@property(nonatomic, strong) Folder * trashFolder; +@property(nonatomic, strong) Folder * searchFolder; +@property(nonatomic, strong) FMDatabaseQueue * databaseQueue; // General database functions -+(Database *)sharedDatabase; --(BOOL)initDatabase:(NSString *)databaseFileName; +- (instancetype)initWithDatabaseAtPath:(NSString *)dbPath /*NS_DESIGNATED_INITIALIZER*/; ++(instancetype)sharedManager; -(void)syncLastUpdate; --(NSInteger)databaseVersion; -(void)compactDatabase; -(void)reindexDatabase; --(NSInteger)countOfUnread; --(BOOL)readOnly; +@property (nonatomic, readonly) NSInteger countOfUnread; +@property (nonatomic, readonly) NSInteger databaseVersion; +@property (nonatomic, readonly) BOOL readOnly; -(void)close; -/* - * Submits a transaction block - * An easy way to wrap things up in a transaction can be done like this: - [db doTransactionWithBlock:^(BOOL *rollback) { - ... - [db ...]; - ... - - if (whoopsSomethingWrongHappened) { - *rollback = YES; - return; // leave the block - } - // etc… - - ... - - }]; -*/ -- (void)doTransactionWithBlock:(void (^)(BOOL *rollback))block; - // Fields functions -(void)addField:(NSString *)name type:(NSInteger)type tag:(NSInteger)tag sqlField:(NSString *)sqlField visible:(BOOL)visible width:(NSInteger)width; -(NSArray *)arrayOfFields; @@ -86,9 +62,9 @@ // Folder functions -(void)initFolderArray; --(NSInteger)firstFolderId; --(NSInteger)trashFolderId; --(NSInteger)searchFolderId; +@property (nonatomic, readonly) NSInteger firstFolderId; +@property (nonatomic, readonly) NSInteger trashFolderId; +@property (nonatomic, readonly) NSInteger searchFolderId; -(NSArray *)arrayOfAllFolders; -(NSArray *)arrayOfFolders:(NSInteger)parentId; -(Folder *)folderFromID:(NSInteger)wantedId; @@ -96,22 +72,23 @@ -(Folder *)folderFromName:(NSString *)wantedName; -(NSInteger)addFolder:(NSInteger)parentId afterChild:(NSInteger)predecessorId folderName:(NSString *)name type:(NSInteger)type canAppendIndex:(BOOL)canAppendIndex; -(BOOL)deleteFolder:(NSInteger)folderId; --(BOOL)setFolderName:(NSInteger)folderId newName:(NSString *)newName; --(BOOL)setFolderDescription:(NSInteger)folderId newDescription:(NSString *)newDescription; --(BOOL)setFolderHomePage:(NSInteger)folderId newHomePage:(NSString *)newLink; --(BOOL)setFolderFeedURL:(NSInteger)folderId newFeedURL:(NSString *)newFeedURL; +-(BOOL)setName:(NSString *)newName forFolder:(NSInteger)folderId; +-(BOOL)setDescription:(NSString *)newDescription forFolder:(NSInteger)folderId; +-(BOOL)setHomePage:(NSString *)homePageURL forFolder:(NSInteger)folderId; +-(BOOL)setFeedURL:(NSString *)feed_url forFolder:(NSInteger)folderId; -(BOOL)setFolderUsername:(NSInteger)folderId newUsername:(NSString *)name; -(void)purgeDeletedArticles; -(void)purgeArticlesOlderThanDays:(NSUInteger)daysToKeep; -(BOOL)markFolderRead:(NSInteger)folderId; --(void)clearFolderFlag:(NSInteger)folderId flagToClear:(NSUInteger)flag; --(void)setFolderFlag:(NSInteger)folderId flagToSet:(NSUInteger)flag; +-(void)clearFlag:(NSUInteger)flag forFolder:(NSInteger)folderId; +-(void)setFlag:(NSUInteger)flag forFolder:(NSInteger)folderId; -(void)setFolderUnreadCount:(Folder *)folder adjustment:(NSUInteger)adjustment; --(void)setFolderLastUpdate:(NSInteger)folderId lastUpdate:(NSDate *)lastUpdate; --(void)setFolderLastUpdateString:(NSInteger)folderId lastUpdateString:(NSString *)lastUpdateString; +-(void)setLastUpdate:(NSDate *)lastUpdate forFolder:(NSInteger)folderId; +-(void)setLastUpdateString:(NSString *)lastUpdateString forFolder:(NSInteger)folderId; -(BOOL)setParent:(NSInteger)newParentID forFolder:(NSInteger)folderId; -(BOOL)setFirstChild:(NSInteger)childId forFolder:(NSInteger)folderId; -(BOOL)setNextSibling:(NSUInteger)nextSiblingId forFolder:(NSInteger)folderId; +-(NSArray *)minimalCacheForFolder:(NSInteger)folderId; -(void)handleAutoSortFoldersTreeChange:(NSNotification *)notification; // RSS folder functions @@ -127,20 +104,21 @@ // Smart folder functions -(void)initSmartfoldersDict; -(NSInteger)addSmartFolder:(NSString *)folderName underParent:(NSInteger)parentId withQuery:(CriteriaTree *)criteriaTree; --(BOOL)updateSearchFolder:(NSInteger)folderId withFolder:(NSString *)folderName withQuery:(CriteriaTree *)criteriaTree; +-(void)updateSearchFolder:(NSInteger)folderId withFolder:(NSString *)folderName withQuery:(CriteriaTree *)criteriaTree; -(CriteriaTree *)searchStringForSmartFolder:(NSInteger)folderId; -(NSString *)criteriaToSQL:(CriteriaTree *)criteriaTree; // Article functions --(BOOL)createArticle:(NSInteger)folderID article:(Article *)article guidHistory:(NSArray *)guidHistory; --(BOOL)deleteArticle:(NSInteger)folderId guid:(NSString *)guid; +-(BOOL)addArticle:(Article *)article toFolder:(NSInteger)folderID; +-(BOOL)updateArticle:(Article *)existingArticle ofFolder:(NSInteger)folderID withArticle:(Article *)article; +-(BOOL)deleteArticle:(Article *)article; -(NSArray *)arrayOfUnreadArticlesRefs:(NSInteger)folderId; -(NSArray *)arrayOfArticles:(NSInteger)folderId filterString:(NSString *)filterString; -(void)markArticleRead:(NSInteger)folderId guid:(NSString *)guid isRead:(BOOL)isRead; -(void)markArticleFlagged:(NSInteger)folderId guid:(NSString *)guid isFlagged:(BOOL)isFlagged; --(void)markArticleDeleted:(NSInteger)folderId guid:(NSString *)guid isDeleted:(BOOL)isDeleted; +-(void)markArticleDeleted:(Article *)article isDeleted:(BOOL)isDeleted; -(void)markUnreadArticlesFromFolder:(Folder *)folder guidArray:(NSArray *)guidArray; -(void)markStarredArticlesFromFolder:(Folder *)folder guidArray:(NSArray *)guidArray; --(BOOL)isTrashEmpty; +@property (nonatomic, getter=isTrashEmpty, readonly) BOOL trashEmpty; -(NSArray *)guidHistoryForFolderId:(NSInteger)folderId; @end diff --git a/src/Database.m b/src/Database.m index 78f23ca6a5..7f712e9b39 100644 --- a/src/Database.m +++ b/src/Database.m @@ -28,440 +28,273 @@ #import "NSNotificationAdditions.h" #import "RefreshManager.h" #import "Debug.h" +#import "VNADatabaseMigration.h" // Private scope flags #define MA_Scope_Inclusive 1 #define MA_Scope_SubFolders 2 // Private functions -@interface Database (Private) - -(NSString *)relocateLockedDatabase:(NSString *)path; - -(void)setDatabaseVersion:(NSInteger)newVersion; - -(BOOL)initArticleArray:(Folder *)folder; - -(CriteriaTree *)criteriaForFolder:(NSInteger)folderId; - -(NSArray *)arrayOfSubFolders:(Folder *)folder; - -(NSString *)sqlScopeForFolder:(Folder *)folder flags:(NSInteger)scopeFlags; - -(void)createInitialSmartFolder:(NSString *)folderName withCriteria:(Criteria *)criteria; - -(NSInteger)createFolderOnDatabase:(NSString *)name underParent:(NSInteger)parentId withType:(NSInteger)type; - -(NSInteger)executeSQL:(NSString *)sqlStatement; - -(NSInteger)executeSQLWithFormat:(NSString *)sqlStatement, ...; +@interface Database () + +@property (nonatomic, readonly) BOOL setupInitialDatabase; +- (void)initaliseFields; +-(NSString *)relocateLockedDatabase:(NSString *)path; +-(CriteriaTree *)criteriaForFolder:(NSInteger)folderId; +-(NSArray *)arrayOfSubFolders:(Folder *)folder; +-(NSString *)sqlScopeForFolder:(Folder *)folder flags:(NSInteger)scopeFlags; +-(void)createInitialSmartFolder:(NSString *)folderName withCriteria:(Criteria *)criteria; +-(NSInteger)createFolderOnDatabase:(NSString *)name underParent:(NSInteger)parentId withType:(NSInteger)type; ++(NSString *)databasePath; @end // The current database version number const NSInteger MA_Min_Supported_DB_Version = 12; -const NSInteger MA_Current_DB_Version = 18; +const NSInteger MA_Current_DB_Version = 19; -// There's just one database and we manage access to it through a -// singleton object. -static Database * _sharedDatabase = nil; @implementation Database @synthesize trashFolder, searchFolder; - -/* init - * General object initialization. - */ --(id)init -{ - if ((self = [super init]) != nil) - { - inTransaction = NO; - sqlDatabase = NULL; - initializedfoldersDict = NO; - initializedSmartfoldersDict = NO; - countOfUnread = 0; - trashFolder = nil; - searchFolder = nil; - searchString = @""; - smartfoldersDict = [[NSMutableDictionary alloc] init]; - foldersDict = [[NSMutableDictionary alloc] init]; - _transactionQueue = dispatch_queue_create("uk.co.opencommunity.vienna2.database-transaction", NULL); - _execQueue = dispatch_queue_create("uk.co.opencommunity.vienna2.database-access", NULL); - } - return self; -} - -/* sharedDatabase - * Returns the single instance of the refresh manager. - */ -+(Database *)sharedDatabase -{ - if (!_sharedDatabase) - { - _sharedDatabase = [[Database alloc] init]; - if (![_sharedDatabase initDatabase:[[Preferences standardPreferences] defaultDatabase]]) +@synthesize databaseQueue; + + + +/*! + * initialise the Database object with a specific path + * + * @param dbPath the path to the database we want to initialise + * + * @return an initialised Database object + */ +- (instancetype)initWithDatabaseAtPath:(NSString *)dbPath +{ + self = [super init]; + if (self) { + initializedfoldersDict = NO; + initializedSmartfoldersDict = NO; + countOfUnread = 0; + trashFolder = nil; + searchFolder = nil; + searchString = @""; + smartfoldersDict = [[NSMutableDictionary alloc] init]; + foldersDict = [[NSMutableDictionary alloc] init]; + [self initaliseFields]; + databaseQueue = [FMDatabaseQueue databaseQueueWithPath:dbPath]; + // If we did not succeed getting read/write+create status, + // then we need to prompt the user for a different location. + if (databaseQueue == nil) { + dbPath = [self relocateLockedDatabase:dbPath]; + if (dbPath != nil) + databaseQueue = [FMDatabaseQueue databaseQueueWithPath:dbPath]; + } + if (![self initialiseDatabase]) { - [_sharedDatabase release]; - _sharedDatabase = nil; + self = nil; } - } - return _sharedDatabase; -} - -+ (NSString*)prepareStringForQuery:(NSString*)inString -{ - NSMutableString* string; - NSRange range = NSMakeRange( 0, [inString length]); - NSRange subRange; - - if([inString respondsToSelector:@selector(stringValue)]) { - inString = [(id)inString stringValue]; } - if((NSNull*)inString == [NSNull null]) { - inString = nil; - } - if(inString == nil) return nil; // just don't try. - - subRange = [inString rangeOfString:@"'" options:NSLiteralSearch range:range]; - if( subRange.location == NSNotFound ) - return inString; - - string = [NSMutableString stringWithString:inString]; - for( ; subRange.location != NSNotFound && range.length > 0; ) - { - subRange = [string rangeOfString:@"'" options:NSLiteralSearch range:range]; - if( subRange.location != NSNotFound ) - [string replaceCharactersInRange:subRange withString:@"''"]; - - range.location = subRange.location + 2; - range.length = ( [string length] < range.location ) ? 0 : ( [string length] - range.location ); - } - - return string; + return self; } -/* initDatabase - * Initalizes the database. The database is first checked to ensure it exists - * and, if not, it is created with all the tables. - */ --(BOOL)initDatabase:(NSString *)databaseFileName -{ - // Don't allow nested opens - if (sqlDatabase) - return NO; - // Fully expand the path and make sure it exists because if the - // database file itself doesn't exist, we want to create it and - // we can't create it on a non-existent path. - NSFileManager * fileManager = [NSFileManager defaultManager]; - NSString * qualifiedDatabaseFileName = [databaseFileName stringByExpandingTildeInPath]; - NSString * databaseFolder = [qualifiedDatabaseFileName stringByDeletingLastPathComponent]; - BOOL isDir; +/* sharedManager + * Returns the single instance of the database manager. + */ ++ (instancetype)sharedManager { + static id sharedMyManager = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedMyManager = [[Database alloc] initWithDatabaseAtPath:[Database databasePath]]; + }); + + return sharedMyManager; +} - - if (![fileManager fileExistsAtPath:databaseFolder isDirectory:&isDir]) - { - NSError *error; - if (![fileManager createDirectoryAtPath:databaseFolder withIntermediateDirectories:YES attributes:NULL error:&error]) - { - NSRunAlertPanel(NSLocalizedString(@"Cannot create database folder", nil), - [NSString stringWithFormat:NSLocalizedString(@"Cannot create database folder text: %@", nil), error], - NSLocalizedString(@"Close", nil), @"", @"", - databaseFolder); - [error release]; - return NO; - } - } - - // Open the database at the well known location - sqlDatabase = [[FMDatabase alloc] initWithPath:qualifiedDatabaseFileName]; - if (!sqlDatabase || ![sqlDatabase open]) - { - NSRunAlertPanel(NSLocalizedString(@"Cannot open database", nil), - NSLocalizedString(@"Cannot open database text", nil), - NSLocalizedString(@"Close", nil), @"", @"", - qualifiedDatabaseFileName); - [sqlDatabase release]; - return NO; - } - // Get the info table. If it doesn't exist then the database is new - FMResultSet * results = [sqlDatabase executeQuery:@"select version from info"]; - databaseVersion = 0; - if ([results next]) - { - NSString * versionString = [results stringForColumn:@"version"]; - databaseVersion = [versionString intValue]; - } - [results close]; +/*! + * Initialise the Vienna database. Create the initial database if + * necessary, otherwise migrate to the correct version if it is out of date + * + * @return YES if the database is at the correct version and good to go + */ +- (BOOL)initialiseDatabase { + NSInteger databaseVersion = self.databaseVersion; + LLog(@"database version: %ld", databaseVersion); + + if (databaseVersion >= MA_Current_DB_Version) { + // Most common case, so it is first + // Nothing to do here + return YES; + } else if (databaseVersion >= MA_Min_Supported_DB_Version) { + NSAlert * alert = [[NSAlert alloc] init]; + [alert setMessageText:NSLocalizedString(@"Database Upgrade", nil)]; + [alert setInformativeText:NSLocalizedString(@"Vienna must upgrade its database to the latest version. This may take a minute or so. We apologize for the inconveninece.", nil)]; + [alert addButtonWithTitle:NSLocalizedString(@"Upgrade Database", nil)]; + [alert addButtonWithTitle:NSLocalizedString(@"Quit Vienna", nil)]; + NSInteger modalReturn = [alert runModal]; + if (modalReturn == NSAlertSecondButtonReturn) + { + return NO; + } - // Trap unsupported databases - if (databaseVersion > 0 && databaseVersion < MA_Min_Supported_DB_Version) - { - NSRunAlertPanel(NSLocalizedString(@"Unrecognised database format", nil), - NSLocalizedString(@"Unrecognised database format text", nil), - NSLocalizedString(@"Close", nil), @"", @"", - qualifiedDatabaseFileName); + // Backup the database before any upgrade + NSString * backupDatabaseFileName = [[Database databasePath] stringByAppendingPathExtension:@"bak"]; + [[NSFileManager defaultManager] copyItemAtPath:[Database databasePath] toPath:backupDatabaseFileName error:nil]; + + [databaseQueue inDatabase:^(FMDatabase *db) { + // Migrate the database to the newest version + // TODO: move this into transaction so we can rollback on failure + [VNADatabaseMigration migrateDatabase:db fromVersion:databaseVersion]; + }]; + + // Confirm the database is now at the correct version + if (self.databaseVersion == MA_Current_DB_Version) { + return YES; + } else { + return NO; + } + } else if ((databaseVersion > 0) && (databaseVersion < MA_Min_Supported_DB_Version)) { + // database version is too old or schema not supported + // TODO: help text for the user to fix the issue + NSRunAlertPanel(NSLocalizedString(@"Unrecognised database format", nil), + NSLocalizedString(@"Unrecognised database format text", nil), + NSLocalizedString(@"Close", nil), @"", @"", + databaseQueue.path); + return NO; + } else if (databaseVersion == 0) { + // database is fresh + return self.setupInitialDatabase; + } + + return NO; +} + +/*! + * sets up an inital Vienna database at the given path + * + * @param dbPath The path to create the database at + * + * @return True on succes + */ +- (BOOL)setupInitialDatabase { + __block BOOL success = NO; + [databaseQueue inDatabase:^(FMDatabase *db) { + success = [self createTablesOnDatabase:db]; + }]; + if(!success) { return NO; } - - // Create the tables when the database is empty. - if (databaseVersion == 0) - { - // Create the tables. We use the first table as a test whether we can actually - // write to the specified location. If not then we need to prompt the user for - // a different location. - NSInteger resultCode; - while ((resultCode = [self executeSQL:@"create table info (version, last_opened, first_folder, folder_sort)"]) != SQLITE_OK) - { - if (resultCode != SQLITE_LOCKED) - return NO; - - // Database was opened but table was locked. - NSString * newPath = [self relocateLockedDatabase:qualifiedDatabaseFileName]; - if (newPath == nil) - return NO; - qualifiedDatabaseFileName = newPath; - } - - [self doTransactionWithBlock:^(BOOL *rollback) { - - [self executeSQL:@"create table folders (folder_id integer primary key, parent_id, foldername, unread_count, last_update, type, flags, next_sibling, first_child)"]; - [self executeSQL:@"create table messages (message_id, folder_id, parent_id, read_flag, marked_flag, deleted_flag, title, sender, link, createddate, date, text, revised_flag, enclosuredownloaded_flag, hasenclosure_flag, enclosure)"]; - [self executeSQL:@"create table smart_folders (folder_id, search_string)"]; - [self executeSQL:@"create table rss_folders (folder_id, feed_url, username, last_update_string, description, home_page, bloglines_id)"]; - [self executeSQL:@"create table rss_guids (message_id, folder_id)"]; - [self executeSQL:@"create index messages_folder_idx on messages (folder_id)"]; - [self executeSQL:@"create index messages_message_idx on messages (message_id)"]; - [self executeSQL:@"create index rss_guids_idx on rss_guids (folder_id)"]; - - // Create a criteria to find all marked articles - Criteria * markedCriteria = [[Criteria alloc] initWithField:MA_Field_Flagged withOperator:MA_CritOper_Is withValue:@"Yes"]; - [self createInitialSmartFolder:NSLocalizedString(@"Marked Articles", nil) withCriteria:markedCriteria]; - [markedCriteria release]; - - // Create a criteria to show all unread articles - Criteria * unreadCriteria = [[Criteria alloc] initWithField:MA_Field_Read withOperator:MA_CritOper_Is withValue:@"No"]; - [self createInitialSmartFolder:NSLocalizedString(@"Unread Articles", nil) withCriteria:unreadCriteria]; - [unreadCriteria release]; - - // Create a criteria to show all articles received today - Criteria * todayCriteria = [[Criteria alloc] initWithField:MA_Field_Date withOperator:MA_CritOper_Is withValue:@"today"]; - [self createInitialSmartFolder:NSLocalizedString(@"Today's Articles", nil) withCriteria:todayCriteria]; - [todayCriteria release]; - + + // Create a criteria to find all marked articles + Criteria * markedCriteria = [[Criteria alloc] initWithField:MA_Field_Flagged withOperator:MA_CritOper_Is withValue:@"Yes"]; + [self createInitialSmartFolder:NSLocalizedString(@"Marked Articles", nil) withCriteria:markedCriteria]; + + // Create a criteria to show all unread articles + Criteria * unreadCriteria = [[Criteria alloc] initWithField:MA_Field_Read withOperator:MA_CritOper_Is withValue:@"No"]; + [self createInitialSmartFolder:NSLocalizedString(@"Unread Articles", nil) withCriteria:unreadCriteria]; + + // Create a criteria to show all articles received today + Criteria * todayCriteria = [[Criteria alloc] initWithField:MA_Field_Date withOperator:MA_CritOper_Is withValue:@"today"]; + [self createInitialSmartFolder:NSLocalizedString(@"Today's Articles", nil) withCriteria:todayCriteria]; + + [databaseQueue inDatabase:^(FMDatabase *db) { // Create the trash folder - [self executeSQLWithFormat:@"insert into folders (parent_id, foldername, unread_count, last_update, type, flags, next_sibling, first_child) values (-1, '%@', 0, 0, %d, 0, 0, 0)", - NSLocalizedString(@"Trash", nil), - MA_Trash_Folder]; - + [db executeUpdate:@"insert into folders (parent_id, foldername, unread_count, last_update, type, flags, next_sibling, first_child) values (-1, ?, 0, 0, ?, 0, 0, 0)", + NSLocalizedString(@"Trash", nil), @(MA_Trash_Folder)]; + // Set the initial version - databaseVersion = MA_Current_DB_Version; - [self executeSQLWithFormat:@"insert into info (version, first_folder, folder_sort) values (%d, 0, %d)", databaseVersion, MA_FolderSort_Manual]; + [db setUserVersion:(uint32_t)MA_Current_DB_Version]; + + // Set the default sort order and write it to both the db and the prefs + [db executeUpdate:@"insert into info (first_folder, folder_sort) values (0, ?)", @(MA_FolderSort_Manual)]; [[Preferences standardPreferences] setFoldersTreeSortMethod:MA_FolderSort_Manual]; - - // Set the initial folder order - [self initFolderArray]; - NSInteger folderId = 0; - NSInteger previousSibling = 0; - NSArray * allFolders = [foldersDict allKeys]; - NSUInteger count = [allFolders count]; - NSUInteger index; - for (index = 0u; index < count; ++index) - { - previousSibling = folderId; - folderId = [[allFolders objectAtIndex:index] intValue]; - if (index == 0u) - [self setFirstChild:folderId forFolder:MA_Root_Folder]; - else - [self setNextSibling:folderId forFolder:previousSibling]; - } - - // If we have a DemoFeeds.plist in the resources then use it to create some initial demo - // RSS feeds. - NSBundle *thisBundle = [NSBundle bundleForClass:[self class]]; - NSString * pathToPList = [thisBundle pathForResource:@"DemoFeeds.plist" ofType:@""]; - if (pathToPList != nil) - { - NSDictionary * demoFeedsDict = [NSDictionary dictionaryWithContentsOfFile:pathToPList]; - if (demoFeedsDict) - { - for (NSString * feedName in demoFeedsDict) - { - NSDictionary * itemDict = [demoFeedsDict objectForKey:feedName]; - NSString * feedURL = [itemDict valueForKey:@"URL"]; - if (feedURL != nil && feedName != nil) - previousSibling = [self addRSSFolder:feedName underParent:MA_Root_Folder afterChild:previousSibling subscriptionURL:feedURL]; - } - } - } - - }]; //end transaction block - } - else if (databaseVersion < MA_Current_DB_Version) - { - NSAlert * alert = [[NSAlert alloc] init]; - [alert setMessageText:NSLocalizedString(@"Database Upgrade", nil)]; - [alert setInformativeText:NSLocalizedString(@"Vienna must upgrade its database to the latest version. This may take a minute or so. We apologize for the inconveninece.", nil)]; - [alert addButtonWithTitle:NSLocalizedString(@"Upgrade Database", nil)]; - [alert addButtonWithTitle:NSLocalizedString(@"Quit Vienna", nil)]; - NSInteger modalReturn = [alert runModal]; - [alert release]; - if (modalReturn == NSAlertSecondButtonReturn) - { - return NO; - } - - // Backup the database before any upgrade - NSString * backupDatabaseFileName = [qualifiedDatabaseFileName stringByAppendingPathExtension:@"bak"]; - [[NSFileManager defaultManager] copyItemAtPath:qualifiedDatabaseFileName toPath:backupDatabaseFileName error:nil]; - } - - // Upgrade to rev 13. - // Add createddate field to the messages table and initialise it to a date in the past. - // Create an index on the message_id column. - if (databaseVersion < 13) - { - [self doTransactionWithBlock:^(BOOL *rollback) { - - [self executeSQL:@"alter table messages add column createddate"]; - [self executeSQLWithFormat:@"update messages set createddate=%f", [[NSDate distantPast] timeIntervalSince1970]]; - [self executeSQL:@"create index messages_message_idx on messages (message_id)"]; + }]; + + // Set the initial folder order + [self initFolderArray]; + NSInteger folderId = 0; + NSInteger previousSibling = 0; + NSArray * allFolders = foldersDict.allKeys; + NSUInteger count = allFolders.count; + NSUInteger index; + for (index = 0u; index < count; ++index) + { + previousSibling = folderId; + folderId = [allFolders[index] integerValue]; + if (index == 0u) + [self setFirstChild:folderId forFolder:MA_Root_Folder]; + else + [self setNextSibling:folderId forFolder:previousSibling]; + } + + // If we have a DemoFeeds.plist in the resources then use it to create some initial demo + // RSS feeds. + NSBundle *thisBundle = [NSBundle bundleForClass:[self class]]; + NSString * pathToPList = [thisBundle pathForResource:@"DemoFeeds.plist" ofType:@""]; + if (pathToPList != nil) + { + NSDictionary * demoFeedsDict = [NSDictionary dictionaryWithContentsOfFile:pathToPList]; + if (demoFeedsDict) + { + for (NSString * feedName in demoFeedsDict) + { + NSDictionary * itemDict = demoFeedsDict[feedName]; + NSString * feedURL = [itemDict valueForKey:@"URL"]; + if (feedURL != nil && feedName != nil) + previousSibling = [self addRSSFolder:feedName underParent:MA_Root_Folder afterChild:previousSibling subscriptionURL:feedURL]; + } + } + } + return YES; +} - }]; //end transaction block - NSLog(@"Updated database schema to version %d.", databaseVersion); - } - - // Upgrade to rev 14. - // Add next_sibling and next_child columns to folders table and first_folder column to info table to allow for manual sorting. - // Initialize all values to 0. The correct values will be set by -[FoldersTree setManualSortOrderForNode:]. - // Make sure that all parent_id values are integers rather than strings, because previous versions of setParent:forFolder: - // set them as strings. - if (databaseVersion < 14) - { - [self doTransactionWithBlock:^(BOOL *rollback) { - - [self executeSQL:@"alter table info add column first_folder"]; - [self executeSQL:@"update info set first_folder=0"]; - - [self executeSQL:@"alter table folders add column next_sibling"]; - [self executeSQL:@"update folders set next_sibling=0"]; - - [self executeSQL:@"alter table folders add column first_child"]; - [self executeSQL:@"update folders set first_child=0"]; - - [[Preferences standardPreferences] setFoldersTreeSortMethod:MA_FolderSort_ByName]; - - FMResultSet * results = [sqlDatabase executeQuery:@"select folder_id, parent_id from folders"]; - while([results next]) - { - NSInteger folderId = [[results stringForColumn:@"folder_id"] intValue]; - NSInteger parentId = [[results stringForColumn:@"parent_id"] intValue]; - [self executeSQLWithFormat:@"update folders set parent_id=%ld where folder_id=%ld", parentId, folderId]; - } - [results close]; - - }]; //end transaction block - NSLog(@"Updated database schema to version %d.", databaseVersion); - } - - // Upgrade to rev 15. - // Move the folders tree sort method preference to the database, so that it can survive deletion of the preferences file. - // Do not disturb the manual sort order, if it exists. - if (databaseVersion < 15) - { - [self doTransactionWithBlock:^(BOOL *rollback) { - - [self executeSQL:@"alter table info add column folder_sort"]; - - NSInteger oldFoldersTreeSortMethod = [[Preferences standardPreferences] foldersTreeSortMethod]; - [self executeSQLWithFormat:@"update info set folder_sort=%d", oldFoldersTreeSortMethod]; - }]; //end transaction block - NSLog(@"Updated database schema to version %d.", databaseVersion); - } - - // Upgrade to rev 16. - // Add revised_flag to messages table, and initialize all values to 0. - if (databaseVersion < 16) - { - [self doTransactionWithBlock:^(BOOL *rollback) { - - [self executeSQL:@"alter table messages add column revised_flag"]; - [self executeSQL:@"update messages set revised_flag=0"]; - - // Set the new version - [self setDatabaseVersion:16]; - }]; //end transaction block - } - - - // Upgrade to rev 17. - // Add hasenclosure_flag, enclosuredownloaded_flag and enclosure to messages table, and initialize stuff. - if (databaseVersion < 17) - { - [self doTransactionWithBlock:^(BOOL *rollback) { - - [self executeSQL:@"alter table messages add column hasenclosure_flag"]; - [self executeSQL:@"update messages set hasenclosure_flag=0"]; - [self executeSQL:@"alter table messages add column enclosure"]; - [self executeSQL:@"update messages set enclosure=''"]; - [self executeSQL:@"alter table messages add column enclosuredownloaded_flag"]; - [self executeSQL:@"update messages set enclosuredownloaded_flag=0"]; - - // Set the new version - [self setDatabaseVersion:17]; - }]; //end transaction block - } - - // Upgrade to rev 18. - // Add table all message guids. - if (databaseVersion < 18) - { - [self doTransactionWithBlock:^(BOOL *rollback) { - - [self executeSQL:@"create table rss_guids as select message_id, folder_id from messages"]; - [self executeSQL:@"create index rss_guids_idx on rss_guids (folder_id)"]; - - // Set the new version - [self setDatabaseVersion:18]; - }]; //end transaction block - } - - // Read the folders tree sort method from the database. - // Make sure that the folders tree is not yet registered to receive notifications at this point. - __block NSInteger newFoldersTreeSortMethod = MA_FolderSort_ByName; - dispatch_sync(_execQueue, ^() { - FMResultSet * sortResults = [sqlDatabase executeQuery:@"select folder_sort from info"]; - if ([sortResults next]) - { - newFoldersTreeSortMethod = [[sortResults stringForColumn:@"folder_sort"] intValue]; - } - [sortResults close]; - }); +-(BOOL)createTablesOnDatabase:(FMDatabase *)db { + // Create the tables. We use the first table as a test whether we can + // setup at the specified location + [db executeUpdate:@"create table info (version, last_opened, first_folder, folder_sort)"]; + if ([db hadError]) { + return NO; + } + [db executeUpdate:@"create table folders (folder_id integer primary key, parent_id, foldername, unread_count, last_update, type, flags, next_sibling, first_child)"]; + [db executeUpdate:@"create table messages (message_id, folder_id, parent_id, read_flag, marked_flag, deleted_flag, title, sender, link, createddate, date, text, revised_flag, enclosuredownloaded_flag, hasenclosure_flag, enclosure)"]; + [db executeUpdate:@"create table smart_folders (folder_id, search_string)"]; + [db executeUpdate:@"create table rss_folders (folder_id, feed_url, username, last_update_string, description, home_page, bloglines_id)"]; + [db executeUpdate:@"create table rss_guids (message_id, folder_id)"]; + [db executeUpdate:@"create index messages_folder_idx on messages (folder_id)"]; + [db executeUpdate:@"create index messages_message_idx on messages (message_id)"]; + [db executeUpdate:@"create index rss_guids_idx on rss_guids (folder_id)"]; + if ([db hadError]) { + return NO; + } + return YES; +} - [[Preferences standardPreferences] setFoldersTreeSortMethod:newFoldersTreeSortMethod]; - - // Register for notifications of change in folders tree sort method. - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleAutoSortFoldersTreeChange:) name:@"MA_Notify_AutoSortFoldersTreeChange" object:nil]; - - // Initial check if the database is read-only - [self syncLastUpdate]; - - // Create fields - fieldsByName = [[NSMutableDictionary alloc] init]; - fieldsOrdered = [[NSMutableArray alloc] init]; - - [self addField:MA_Field_Read type:MA_FieldType_Flag tag:MA_FieldID_Read sqlField:@"read_flag" visible:YES width:17]; - [self addField:MA_Field_Flagged type:MA_FieldType_Flag tag:MA_FieldID_Flagged sqlField:@"marked_flag" visible:YES width:17]; - [self addField:MA_Field_HasEnclosure type:MA_FieldType_Flag tag:MA_FieldID_HasEnclosure sqlField:@"hasenclosure_flag" visible:YES width:17]; - [self addField:MA_Field_Deleted type:MA_FieldType_Flag tag:MA_FieldID_Deleted sqlField:@"deleted_flag" visible:NO width:15]; - [self addField:MA_Field_Comments type:MA_FieldType_Integer tag:MA_FieldID_Comments sqlField:@"comment_flag" visible:NO width:15]; - [self addField:MA_Field_GUID type:MA_FieldType_Integer tag:MA_FieldID_GUID sqlField:@"message_id" visible:NO width:72]; - [self addField:MA_Field_Subject type:MA_FieldType_String tag:MA_FieldID_Subject sqlField:@"title" visible:YES width:472]; - [self addField:MA_Field_Folder type:MA_FieldType_Folder tag:MA_FieldID_Folder sqlField:@"folder_id" visible:NO width:130]; - [self addField:MA_Field_Date type:MA_FieldType_Date tag:MA_FieldID_Date sqlField:@"date" visible:YES width:152]; - [self addField:MA_Field_Parent type:MA_FieldType_Integer tag:MA_FieldID_Parent sqlField:@"parent_id" visible:NO width:72]; - [self addField:MA_Field_Author type:MA_FieldType_String tag:MA_FieldID_Author sqlField:@"sender" visible:YES width:138]; - [self addField:MA_Field_Link type:MA_FieldType_String tag:MA_FieldID_Link sqlField:@"link" visible:NO width:138]; - [self addField:MA_Field_Text type:MA_FieldType_String tag:MA_FieldID_Text sqlField:@"text" visible:NO width:152]; - [self addField:MA_Field_Summary type:MA_FieldType_String tag:MA_FieldID_Summary sqlField:@"summary" visible:NO width:152]; - [self addField:MA_Field_Headlines type:MA_FieldType_String tag:MA_FieldID_Headlines sqlField:@"" visible:NO width:100]; - [self addField:MA_Field_Enclosure type:MA_FieldType_String tag:MA_FieldID_Enclosure sqlField:@"enclosure" visible:NO width:100]; - [self addField:MA_Field_EnclosureDownloaded type:MA_FieldType_Flag tag:MA_FieldID_EnclosureDownloaded sqlField:@"enclosuredownloaded_flag" visible:NO width:100]; - - return YES; +/*! + * Initialise the mappings between the names of + * the database fields and the model fields + */ +-(void)initaliseFields { + fieldsByName = [[NSMutableDictionary alloc] init]; + fieldsOrdered = [[NSMutableArray alloc] init]; + + [self addField:MA_Field_Read type:MA_FieldType_Flag tag:MA_FieldID_Read sqlField:@"read_flag" visible:YES width:17]; + [self addField:MA_Field_Flagged type:MA_FieldType_Flag tag:MA_FieldID_Flagged sqlField:@"marked_flag" visible:YES width:17]; + [self addField:MA_Field_HasEnclosure type:MA_FieldType_Flag tag:MA_FieldID_HasEnclosure sqlField:@"hasenclosure_flag" visible:YES width:17]; + [self addField:MA_Field_Deleted type:MA_FieldType_Flag tag:MA_FieldID_Deleted sqlField:@"deleted_flag" visible:NO width:15]; + [self addField:MA_Field_Comments type:MA_FieldType_Integer tag:MA_FieldID_Comments sqlField:@"comment_flag" visible:NO width:15]; + [self addField:MA_Field_GUID type:MA_FieldType_Integer tag:MA_FieldID_GUID sqlField:@"message_id" visible:NO width:72]; + [self addField:MA_Field_Subject type:MA_FieldType_String tag:MA_FieldID_Subject sqlField:@"title" visible:YES width:472]; + [self addField:MA_Field_Folder type:MA_FieldType_Folder tag:MA_FieldID_Folder sqlField:@"folder_id" visible:NO width:130]; + [self addField:MA_Field_Date type:MA_FieldType_Date tag:MA_FieldID_Date sqlField:@"date" visible:YES width:152]; + [self addField:MA_Field_Parent type:MA_FieldType_Integer tag:MA_FieldID_Parent sqlField:@"parent_id" visible:NO width:72]; + [self addField:MA_Field_Author type:MA_FieldType_String tag:MA_FieldID_Author sqlField:@"sender" visible:YES width:138]; + [self addField:MA_Field_Link type:MA_FieldType_String tag:MA_FieldID_Link sqlField:@"link" visible:NO width:138]; + [self addField:MA_Field_Text type:MA_FieldType_String tag:MA_FieldID_Text sqlField:@"text" visible:NO width:152]; + [self addField:MA_Field_Summary type:MA_FieldType_String tag:MA_FieldID_Summary sqlField:@"summary" visible:NO width:152]; + [self addField:MA_Field_Headlines type:MA_FieldType_String tag:MA_FieldID_Headlines sqlField:@"" visible:NO width:100]; + [self addField:MA_Field_Enclosure type:MA_FieldType_String tag:MA_FieldID_Enclosure sqlField:@"enclosure" visible:NO width:100]; + [self addField:MA_Field_EnclosureDownloaded type:MA_FieldType_Flag tag:MA_FieldID_EnclosureDownloaded sqlField:@"enclosuredownloaded_flag" visible:NO width:100]; } /* relocateLockedDatabase @@ -470,7 +303,8 @@ -(BOOL)initDatabase:(NSString *)databaseFileName */ -(NSString *)relocateLockedDatabase:(NSString *)path { - NSString * errorTitle = NSLocalizedString(@"Locate Title", nil); + FMDatabase *sqlDatabase = [FMDatabase databaseWithPath:[Database databasePath]]; + NSString * errorTitle = NSLocalizedString(@"Locate Title", nil); NSString * errorText = NSLocalizedString(@"Locate Text", nil); NSInteger option = NSRunAlertPanel(errorTitle, errorText, NSLocalizedString(@"Locate", nil), NSLocalizedString(@"Exit", nil), nil, path); if (option == 0) @@ -483,7 +317,6 @@ -(NSString *)relocateLockedDatabase:(NSString *)path if (sqlDatabase != nil) { [sqlDatabase close]; - [sqlDatabase release]; sqlDatabase = nil; [[NSFileManager defaultManager] removeItemAtPath:path error:nil]; } @@ -496,8 +329,8 @@ -(NSString *)relocateLockedDatabase:(NSString *)path return nil; // Make the new database name. - NSString * databaseName = [path lastPathComponent]; - NSString * newPath = [[[[openPanel URLs] objectAtIndex:0] path] stringByAppendingPathComponent:databaseName]; + NSString * databaseName = path.lastPathComponent; + NSString * newPath = [openPanel.URLs[0].path stringByAppendingPathComponent:databaseName]; // And try to open it. sqlDatabase = [[FMDatabase alloc] initWithPath:newPath]; @@ -507,16 +340,17 @@ -(NSString *)relocateLockedDatabase:(NSString *)path NSLocalizedString(@"Cannot open database text", nil), NSLocalizedString(@"Close", nil), @"", @"", newPath); - [sqlDatabase release]; sqlDatabase = nil; return nil; } // Save this to the preferences [[Preferences standardPreferences] setDefaultDatabase:newPath]; + [sqlDatabase close]; return newPath; } - return nil; + [sqlDatabase close]; + return nil; } /* createInitialSmartFolder @@ -532,52 +366,13 @@ -(void)createInitialSmartFolder:(NSString *)folderName withCriteria:(Criteria *) CriteriaTree * criteriaTree = [[CriteriaTree alloc] init]; [criteriaTree addCriteria:criteria]; - NSString * preparedCriteriaString = [Database prepareStringForQuery:[criteriaTree string]]; - [self executeSQLWithFormat:@"insert into smart_folders (folder_id, search_string) values (%lld, '%@')", [sqlDatabase lastInsertRowId], preparedCriteriaString]; - [criteriaTree release]; + __weak NSString * preparedCriteriaString = criteriaTree.string; + [databaseQueue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"insert into smart_folders (folder_id, search_string) values (?, ?)", @([db lastInsertRowId]), preparedCriteriaString]; + }]; } } -/* executeSQL - * Executes the specified SQL statement and discards the result. Should be used for - * SQL statements that do not return results. - * Returns an error code. - */ --(NSInteger)executeSQL:(NSString *)sqlStatement -{ - -// In debug mode, log the execution duration in the console -#ifdef DEBUG - NSDate *start = [NSDate date]; -#endif - __block int errorCode; - dispatch_sync(_execQueue, ^() { - [sqlDatabase executeUpdate:sqlStatement withArgumentsInArray:nil]; - errorCode = [sqlDatabase lastErrorCode]; - }); -#ifdef DEBUG - NSLog(@"Query (%f secs): %@", [[NSDate date] timeIntervalSinceDate:start], sqlStatement); -#endif - return errorCode; -} - -/* executeSQLWithFormat - * Formats and executes the specified SQL statement and discards the result. Should be used for - * SQL statements that do not return results. - * Returns an error code. - */ --(NSInteger)executeSQLWithFormat:(NSString *)sqlStatement, ... -{ - va_list arguments; - va_start(arguments, sqlStatement); - int errorCode; - NSString * query = [[NSString alloc] initWithFormat:sqlStatement arguments:arguments]; - errorCode = [self executeSQL:query]; - [query release]; - va_end(arguments); - return errorCode; -} - /* syncLastUpdate * Call this function to update the field in the info table which contains the last_updated * date. This is basically auditing data and is only called when the database is first opened @@ -585,8 +380,17 @@ -(NSInteger)executeSQLWithFormat:(NSString *)sqlStatement, ... */ -(void)syncLastUpdate { - NSInteger result = [self executeSQLWithFormat:@"update info set last_opened='%@'", [NSDate date]]; - readOnly = (result != SQLITE_OK); + __block BOOL success; + + [databaseQueue inDatabase:^(FMDatabase *db) { + success = [db executeUpdate:@"update info set last_opened=?", [NSDate date]]; + + }]; + if (success) { + readOnly = NO; + } else { + readOnly = YES; + } } /* countOfUnread @@ -603,16 +407,16 @@ -(NSInteger)countOfUnread */ -(void)addField:(NSString *)name type:(NSInteger)type tag:(NSInteger)tag sqlField:(NSString *)sqlField visible:(BOOL)visible width:(NSInteger)width { - Field * field = [[Field new] autorelease]; + Field * field = [Field new]; if (field != nil) { - [field setName:name]; + field.name = name; [field setDisplayName:NSLocalizedString(name, nil)]; - [field setType:type]; - [field setTag:tag]; - [field setVisible:visible]; - [field setWidth:width]; - [field setSqlField:sqlField]; + field.type = type; + field.tag = tag; + field.visible = visible; + field.width = width; + field.sqlField = sqlField; [fieldsOrdered addObject:field]; [fieldsByName setValue:field forKey:name]; } @@ -635,22 +439,35 @@ -(Field *)fieldByName:(NSString *)name return [fieldsByName valueForKey:name]; } -/* databaseVersion - * Return the database version. +/*! + * Get the current database version from the database + * This method fetches the version information from both + * the SQLite PRAGMA user_version and the legacy Vienna info + * table, returning the highest version number. + * + * @return the current database version */ -(NSInteger)databaseVersion { - return databaseVersion; -} + __block NSInteger dbVersion = 0; + + // FMDatabaseQueue *queue = [[Database sharedManager] databaseQueue]; + [databaseQueue inDatabase:^(FMDatabase *db) { + FMResultSet * results = [db executeQuery:@"select version from info"]; + dbVersion = 0; + if ([results next]) + { + dbVersion = [results intForColumn:@"version"]; + } + [results close]; + + // compare the SQLite PRAGMA user_version to the legacy version number + if ([db userVersion] > dbVersion) { + dbVersion = [db userVersion]; + } + }]; -/* setDatabaseVersion - * Sets the version stamp in the database. - */ --(void)setDatabaseVersion:(NSInteger)newVersion -{ - [self executeSQLWithFormat:@"update info set version=%ld", newVersion]; - databaseVersion = newVersion; - NSLog(@"Updated database schema to version %d.", databaseVersion); + return dbVersion; } /* readOnly @@ -661,63 +478,17 @@ -(BOOL)readOnly return readOnly; } -/* beginTransaction - * Starts a SQL transaction. - */ --(void)beginTransaction -{ - NSAssert(!inTransaction, @"Whoops! Already in a transaction. You cannot nest transactions"); - [sqlDatabase beginTransaction]; - inTransaction = YES; -} - -/* commitTransaction - * Commits a SQL transaction. - */ --(void)commitTransaction -{ - NSAssert(inTransaction, @"Whoops! Commit while not in a transaction. Someone forgot to call beginTransaction first"); - [sqlDatabase commit]; - inTransaction = NO; -} - -/* rollbackTransaction - * Rollbacks a SQL transaction. - */ --(void)rollbackTransaction -{ - NSAssert(inTransaction, @"Whoops! Rollback while not in a transaction. Someone forgot to call beginTransaction first"); - [sqlDatabase rollback]; - inTransaction = NO; -} - -/* doTransactionWithBlock - * Submits a transaction block - */ -- (void)doTransactionWithBlock:(void (^)(BOOL *rollback))block { - dispatch_sync(_transactionQueue, ^() { - @autoreleasepool { - @synchronized(self) { - BOOL shouldRollback = NO; - [self beginTransaction]; - block(&shouldRollback); - if (shouldRollback) { - [self rollbackTransaction]; - } else { - [self commitTransaction]; - } - } - } - }); //block for dispatch_sync -} /* compactDatabase * Compact the database using the vacuum command. */ -(void)compactDatabase { - if (!readOnly) - [self executeSQL:@"vacuum"]; + if (!readOnly) { + [databaseQueue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"vacuum"]; + }]; + } } /* reindexDatabase @@ -725,14 +496,20 @@ -(void)compactDatabase */ -(void)reindexDatabase { - if (!readOnly) - [self executeSQL:@"reindex"]; + if (!readOnly) { + [databaseQueue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"reindex"]; + }]; + } } -/* clearFolderFlag - * Clears the specified flag for the folder. +/** + * Clears a specified flag for the specified folder + * + * @param flag the flag to clear + * @param folderId the folder to clear the flag from */ --(void)clearFolderFlag:(NSInteger)folderId flagToClear:(NSUInteger)flag +-(void)clearFlag:(NSUInteger)flag forFolder:(NSInteger)folderId { // Exit now if we're read-only if (readOnly) @@ -742,136 +519,191 @@ -(void)clearFolderFlag:(NSInteger)folderId flagToClear:(NSUInteger)flag if (folder != nil) { [folder clearFlag:flag]; - [self executeSQLWithFormat:@"update folders set flags=%d where folder_id=%d", [folder flags], folderId]; + FMDatabaseQueue *queue = databaseQueue; + [queue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"update folders set flags=? where folder_id=?", @(folder.flags), @(folderId)]; + }]; } } -/* setFolderFlag - * Sets the specified flag for the folder. + +/** + * Sets the specified flag for the folder. + * + * @param flag flag to set + * @param folderId folder to set the flag for */ --(void)setFolderFlag:(NSInteger)folderId flagToSet:(NSUInteger)flag +-(void)setFlag:(NSUInteger)flag forFolder:(NSInteger)folderId { // Exit now if we're read-only - if (readOnly) + if (readOnly) { return; - + } + Folder * folder = [self folderFromID:folderId]; if (folder != nil) { [folder setFlag:flag]; - [self executeSQLWithFormat:@"update folders set flags=%lu where folder_id=%ld", [folder flags], folderId]; + FMDatabaseQueue *queue = databaseQueue; + [queue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"update folders set flags=? where folder_id=?", @(folder.flags), @(folderId)]; + }]; } } -/* setFolderLastUpdate - * Sets the date when the folder was last updated. +/** + * Sets the date when the folder was last updated. + * + * @param lastUpdate The date of the last update + * @param folderId The ID of the folder being updated */ --(void)setFolderLastUpdate:(NSInteger)folderId lastUpdate:(NSDate *)lastUpdate +-(void)setLastUpdate:(NSDate *)lastUpdate forFolder:(NSInteger)folderId { // Exit now if we're read-only - if (readOnly) + if (readOnly) { return; - + } // If no change to last update, do nothing Folder * folder = [self folderFromID:folderId]; if (folder != nil && (IsRSSFolder(folder) || IsGoogleReaderFolder(folder))) { - if ([[folder lastUpdate] isEqualToDate:lastUpdate]) + if ([folder.lastUpdate isEqualToDate:lastUpdate]) { return; - - [folder setLastUpdate:lastUpdate]; - NSTimeInterval interval = [lastUpdate timeIntervalSince1970]; - [self executeSQLWithFormat:@"update folders set last_update=%f where folder_id=%ld", interval, folderId]; + } + folder.lastUpdate = lastUpdate; + NSTimeInterval interval = lastUpdate.timeIntervalSince1970; + FMDatabaseQueue *queue = databaseQueue; + [queue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"update folders set last_update=? where folder_id=?", @(interval), @(folderId)]; + }]; } } -/* setFolderLastUpdateString - * Sets the last update string for the folder. + +/** + * Sets the last update string for the folder. + * + * @param lastUpdateString The new last update string + * @param folderId The ID of the folder being updated */ --(void)setFolderLastUpdateString:(NSInteger)folderId lastUpdateString:(NSString *)lastUpdateString +-(void)setLastUpdateString:(NSString *)lastUpdateString forFolder:(NSInteger)folderId { // Exit now if we're read-only - if (readOnly) + if (readOnly) { return; - + } // If no change to last update string, do nothing Folder * folder = [self folderFromID:folderId]; if (folder != nil && (IsRSSFolder(folder) || IsGoogleReaderFolder(folder))) { - if ([[folder lastUpdateString] isEqualToString:lastUpdateString]) + if ([folder.lastUpdateString isEqualToString:lastUpdateString]) return; - [folder setLastUpdateString:lastUpdateString]; - [self executeSQLWithFormat:@"update rss_folders set last_update_string='%@' where folder_id=%ld", [folder lastUpdateString], folderId]; + folder.lastUpdateString = lastUpdateString; + FMDatabaseQueue *queue = databaseQueue; + [queue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"update rss_folders set last_update_string=? where folder_id=?", + folder.lastUpdateString, @(folderId)]; + }]; } } -/* setFolderFeedURL - * Change the URL of the feed on the specified RSS folder subscription. +/** + * Change the URL of the feed on the specified RSS folder subscription. + * + * @param feed_url the URL to set the folder's feed to + * @param folderId the ID of the folder whose URL we are changing + * + * @return YES on success */ --(BOOL)setFolderFeedURL:(NSInteger)folderId newFeedURL:(NSString *)url +-(BOOL)setFeedURL:(NSString *)feed_url forFolder:(NSInteger)folderId { // Exit now if we're read-only - if (readOnly) + if (readOnly) { return NO; + } Folder * folder = [self folderFromID:folderId]; - if (folder != nil && ![[folder feedURL] isEqualToString:url]) + if (folder != nil && ![folder.feedURL isEqualToString:feed_url]) { - NSString * preparedURL = [Database prepareStringForQuery:url]; - [folder setFeedURL:url]; - [self executeSQLWithFormat:@"update rss_folders set feed_url='%@' where folder_id=%ld", preparedURL, (long)folderId]; + folder.feedURL = feed_url; + FMDatabaseQueue *queue = databaseQueue; + [queue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"update rss_folders set feed_url=? where folder_id=?", feed_url, @(folderId)]; + }]; } return YES; } - --(NSInteger)addGoogleReaderFolder:(NSString *)feedName underParent:(NSInteger)parentId afterChild:(NSInteger)predecessorId subscriptionURL:(NSString *)url { +/*! + * Add a Google Reader RSS Feed folder and return the ID of the new folder. + * + * @param feedName The name of the RSS folder + * @param parentId The parent folder ID + * @param predecessorId The predecessor folder ID + * @param feed_url The URL of the RSS Feed folder + * + * @return The ID of the new folder + */ +-(NSInteger)addGoogleReaderFolder:(NSString *)feedName underParent:(NSInteger)parentId afterChild:(NSInteger)predecessorId subscriptionURL:(NSString *)feed_url { NSInteger folderId = [self addFolder:parentId afterChild:predecessorId folderName:feedName type:MA_GoogleReader_Folder canAppendIndex:YES]; //TODO: optimization using unique add function for addRSSFolder if (folderId != -1) { - NSString * preparedURL = [Database prepareStringForQuery:url]; - NSString *preparedName = [Database prepareStringForQuery:feedName]; - NSInteger results = [self executeSQLWithFormat: - @"insert into rss_folders (folder_id, description, username, home_page, last_update_string, feed_url, bloglines_id) " - "values (%ld, '%@', '', '', '', '%@', %d)", - (long)folderId, - preparedName, - preparedURL, - 0]; - if (results != SQLITE_OK) - return -1; + FMDatabaseQueue *queue = databaseQueue; + __block BOOL success; + [queue inDatabase:^(FMDatabase *db) { + success = [db executeUpdate:@"insert into rss_folders (folder_id, description, username, home_page, last_update_string, feed_url, bloglines_id) values (?, ?, '', '', '', ?, 0)", + @(folderId), + feedName, // description + // username + // home_page + // last_update_string + feed_url]; + }]; + if (!success) { + return -1; + } // Add this new folder to our internal cache Folder * folder = [self folderFromID:folderId]; - [folder setFeedURL:url]; + folder.feedURL = feed_url; } return folderId; } -/* addRSSFolder - * Add an RSS Feed folder and return the ID of the new folder. +/*! + * Add a RSS Feed folder and return the ID of the new folder. + * + * @param feedName The name of the RSS folder + * @param parentId The parent folder ID + * @param predecessorId The predecessor folder ID + * @param feed_url The URL of the RSS Feed folder + * + * @return The ID of the new folder */ --(NSInteger)addRSSFolder:(NSString *)feedName underParent:(NSInteger)parentId afterChild:(NSInteger)predecessorId subscriptionURL:(NSString *)url +-(NSInteger)addRSSFolder:(NSString *)feedName underParent:(NSInteger)parentId afterChild:(NSInteger)predecessorId subscriptionURL:(NSString *)feed_url { NSInteger folderId = [self addFolder:parentId afterChild:predecessorId folderName:feedName type:MA_RSS_Folder canAppendIndex:YES]; if (folderId != -1) { - NSString * preparedURL = [Database prepareStringForQuery:url]; - NSInteger results = [self executeSQLWithFormat: - @"insert into rss_folders (folder_id, description, username, home_page, last_update_string, feed_url, bloglines_id) " - "values (%ld, '', '', '', '', '%@', %d)", - (long)folderId, - preparedURL, - 0]; - if (results != SQLITE_OK) - return -1; + FMDatabaseQueue *queue = databaseQueue; + __block BOOL success; + [queue inDatabase:^(FMDatabase *db) { + success = [db executeUpdate:@"insert into rss_folders (folder_id, description, username, home_page, last_update_string, feed_url, bloglines_id) " + "values (?, '', '', '', '', ?, 0)", + @(folderId), + feed_url]; + }]; + if (!success) { + return -1; + } + // Add this new folder to our internal cache Folder * folder = [self folderFromID:folderId]; - [folder setFeedURL:url]; + folder.feedURL = feed_url; } return folderId; } @@ -897,7 +729,7 @@ -(NSInteger)addFolder:(NSInteger)parentId afterChild:(NSInteger)predId folderNam { folder = [self folderFromName:name]; if (folder) - return [folder itemId]; + return folder.itemId; } else { @@ -907,41 +739,44 @@ -(NSInteger)addFolder:(NSInteger)parentId afterChild:(NSInteger)predId folderNam NSUInteger index = 1; while (([self folderFromName:name]) != nil) - name = [NSString stringWithFormat:@"%@ (%li)", oldName, (unsigned long)index++]; + name = [NSString stringWithFormat:@"%@ (%lu)", oldName, (unsigned long)index++]; } NSInteger nextSibling = 0; - BOOL manualSort = [[Preferences standardPreferences] foldersTreeSortMethod] == MA_FolderSort_Manual; + BOOL manualSort = [Preferences standardPreferences].foldersTreeSortMethod == MA_FolderSort_Manual; if (manualSort) { if (predecessorId > 0) { Folder * predecessor = [self folderFromID:predecessorId]; if (predecessor != nil) - nextSibling = [predecessor nextSiblingId]; + nextSibling = predecessor.nextSiblingId; else predecessorId = 0; } if (predecessorId < 0) { - dispatch_sync(_execQueue, ^() { - FMResultSet * siblings = [sqlDatabase executeQueryWithFormat:@"select folder_id from folders where parent_id=%ld and next_sibling=0", (long)parentId]; - if([siblings next]) - predecessorId = [[siblings stringForColumn:@"folder_id"] intValue]; - else - predecessorId = 0; + FMDatabaseQueue *queue = databaseQueue; + + [queue inDatabase:^(FMDatabase *db) { + FMResultSet * siblings = [db executeQuery:@"SELECT folder_id from folders where parent_id=? and next_sibling=0", @(parentId)]; + if([siblings next]) { + predecessorId = [siblings intForColumn:@"folder_id"]; + } else { + predecessorId = 0; + } [siblings close]; - }); + }]; } if (predecessorId == 0) { if (parentId == MA_Root_Folder) - nextSibling = [self firstFolderId]; + nextSibling = self.firstFolderId; else { Folder * parent = [self folderFromID:parentId]; if (parent != nil) - nextSibling = [parent firstChildId]; + nextSibling = parent.firstChildId; } } } @@ -953,10 +788,10 @@ -(NSInteger)addFolder:(NSInteger)parentId afterChild:(NSInteger)predId folderNam // Add this new folder to our internal cache. If this is an RSS or Open Reader // folder, mark it so that somewhere down the line we'll request the // image for the folder. - folder = [[[Folder alloc] initWithId:newItemId parentId:parentId name:name type:type] autorelease]; + folder = [[Folder alloc] initWithId:newItemId parentId:parentId name:name type:type]; if ((type == MA_RSS_Folder)||(type == MA_GoogleReader_Folder)) [folder setFlag:MA_FFlag_CheckForImage]; - [foldersDict setObject:folder forKey:[NSNumber numberWithInt:newItemId]]; + foldersDict[@(newItemId)] = folder; if (manualSort) { @@ -981,39 +816,41 @@ -(NSInteger)addFolder:(NSInteger)parentId afterChild:(NSInteger)predId folderNam */ -(NSInteger)createFolderOnDatabase:(NSString *)name underParent:(NSInteger)parentId withType:(NSInteger)type { - NSString * preparedName = [Database prepareStringForQuery:name]; - NSInteger newItemId = -1; + FMDatabaseQueue *queue = databaseQueue; + + __block NSInteger newItemId = -1; NSInteger flags = 0; NSInteger nextSibling = 0; NSInteger firstChild = 0; // For new folders, last update is set to before now NSDate * lastUpdate = [NSDate distantPast]; - NSTimeInterval interval = [lastUpdate timeIntervalSince1970]; + NSTimeInterval interval = lastUpdate.timeIntervalSince1970; // Require an image check if we're a subscription folder - if ((type == MA_RSS_Folder) || (type == MA_GoogleReader_Folder)) + if ((type == MA_RSS_Folder) || (type == MA_GoogleReader_Folder)) { flags = MA_FFlag_CheckForImage; - + } // Create the folder in the database. One thing to watch out for here that has // bit me before. When adding new fields to the folders table, remember to init // the field here even if its just to an empty value. - NSInteger results = [self executeSQLWithFormat: - @"insert into folders (foldername, parent_id, unread_count, last_update, type, flags, next_sibling, first_child) values('%@', %ld, 0, %f, %ld, %ld, %ld, %ld)", - preparedName, - (long)parentId, - interval, - (long)type, - (long)flags, - (long)nextSibling, - (long)firstChild]; - - // Quick way of getting the last autoincrement primary key value (the folder_id). - if (results == SQLITE_OK) - { - newItemId = [sqlDatabase lastInsertRowId]; - } + [queue inDatabase:^(FMDatabase *db) { + BOOL success = [db executeUpdate: + @"insert into folders (foldername, parent_id, unread_count, last_update, type, flags, next_sibling, first_child) values(?, ?, 0, ?, ?, ?, ?, ?)", + name, + @(parentId), + // unread_count = 0 + @(interval), + @(type), + @(flags), + @(nextSibling), + @(firstChild)]; + // Quick way of getting the last autoincrement primary key value (the folder_id). + if (success) { + newItemId = [db lastInsertRowId]; + } + }]; return newItemId; } @@ -1026,41 +863,47 @@ +(NSString *)untitledFeedFolderName } /* wrappedDeleteFolder - * Delete the specified folder. This function should be called from within a - * transaction wrapper since it can be very SQL intensive. + * Delete the specified folder. This function can be very SQL intensive. */ -(BOOL)wrappedDeleteFolder:(NSInteger)folderId { - NSArray * arrayOfChildFolders = [self arrayOfFolders:folderId]; - Folder * folder; + NSArray * arrayOfChildFolders = [self arrayOfFolders:folderId]; + Folder * folder; + FMDatabaseQueue *queue = databaseQueue; // Recurse and delete child folders - for (folder in arrayOfChildFolders) - [self wrappedDeleteFolder:[folder itemId]]; + for (folder in arrayOfChildFolders) { + [self wrappedDeleteFolder:folder.itemId]; + } // Adjust unread counts on parents folder = [self folderFromID:folderId]; - NSInteger adjustment = -[folder unreadCount]; - while ([folder parentId] != MA_Root_Folder) + NSInteger adjustment = -folder.unreadCount; + while (folder.parentId != MA_Root_Folder) { - folder = [self folderFromID:[folder parentId]]; - [folder setChildUnreadCount:[folder childUnreadCount] + adjustment]; + folder = [self folderFromID:folder.parentId]; + folder.childUnreadCount = folder.childUnreadCount + adjustment; } // Delete all articles in this folder then delete ourselves. folder = [self folderFromID:folderId]; - countOfUnread -= [folder unreadCount]; - if (IsSmartFolder(folder)) - [self executeSQLWithFormat:@"delete from smart_folders where folder_id=%ld", folderId]; + countOfUnread -= folder.unreadCount; + if (IsSmartFolder(folder)) { + [queue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"delete from smart_folders where folder_id=?", @(folderId)]; + }]; + } // If this is an RSS feed, delete from the feeds // and delete raw feed source if (IsRSSFolder(folder) || IsGoogleReaderFolder(folder)) { - [self executeSQLWithFormat:@"delete from rss_folders where folder_id=%ld", folderId]; - [self executeSQLWithFormat:@"delete from rss_guids where folder_id=%ld", folderId]; + [queue inTransaction:^(FMDatabase *db, BOOL * rollback) { + [db executeUpdate:@"delete from rss_folders where folder_id=?", @(folderId)]; + [db executeUpdate:@"delete from rss_guids where folder_id=?", @(folderId)]; + }]; - NSString * feedSourceFilePath = [folder feedSourceFilePath]; + NSString * feedSourceFilePath = folder.feedSourceFilePath; if (feedSourceFilePath != nil) { BOOL isDirectory = YES; @@ -1084,34 +927,36 @@ -(BOOL)wrappedDeleteFolder:(NSInteger)folderId } // Update the sort order if necessary - if ([[Preferences standardPreferences] foldersTreeSortMethod] == MA_FolderSort_Manual) + if ([Preferences standardPreferences].foldersTreeSortMethod == MA_FolderSort_Manual) { __block NSInteger previousSibling = -999; - dispatch_sync(_execQueue, ^() { - FMResultSet * results = [sqlDatabase executeQueryWithFormat:@"select folder_id from folders where parent_id=%ld and next_sibling=%ld", (long)[folder parentId], (long)folderId]; + [queue inDatabase:^(FMDatabase *db) { + FMResultSet * results = [db executeQuery:@"SELECT folder_id from folders where parent_id=? and next_sibling=?", @(folder.parentId), @(folderId)]; if ([results next]) { - previousSibling = [[results stringForColumn:@"folder_id"] intValue]; + previousSibling = [results intForColumn:@"folder_id"]; } [results close]; - }); + }]; if (previousSibling != -999) - [self setNextSibling:[folder nextSiblingId] forFolder:previousSibling]; + [self setNextSibling:folder.nextSiblingId forFolder:previousSibling]; else - [self setFirstChild:[folder nextSiblingId] forFolder:[folder parentId]]; + [self setFirstChild:folder.nextSiblingId forFolder:folder.parentId]; } // For a smart folder, the next line is a no-op but it helpfully takes care of the case where a // normal folder had it's type grobbed to MA_Smart_Folder. - [self executeSQLWithFormat:@"delete from messages where folder_id=%ld", folderId]; - [self executeSQLWithFormat:@"delete from folders where folder_id=%ld", folderId]; + [queue inTransaction:^(FMDatabase *db, BOOL *rollback) { + [db executeUpdate:@"delete from messages where folder_id=?", @(folderId)]; + [db executeUpdate:@"delete from folders where folder_id=?", @(folderId)]; + }]; // Remove from the folders array. Do this after we send the notification // so that the notification handlers don't fail if they try to dereference the // folder. - [foldersDict removeObjectForKey:[NSNumber numberWithInt:folderId]]; + [foldersDict removeObjectForKey:@(folderId)]; return YES; } @@ -1125,7 +970,7 @@ -(BOOL)deleteFolder:(NSInteger)folderId NSArray * arrayOfChildFolders; NSNumber * numFolder; Folder * folder; - __block BOOL result; + BOOL result; // Exit now if we're read-only if (readOnly) @@ -1137,39 +982,45 @@ -(BOOL)deleteFolder:(NSInteger)folderId return NO; arrayOfChildFolders = [self arrayOfSubFolders:folder]; - arrayOfFolderIds = [NSMutableArray arrayWithCapacity:[arrayOfChildFolders count]]; + arrayOfFolderIds = [NSMutableArray arrayWithCapacity:arrayOfChildFolders.count]; // Send the pre-delete notification before we start the transaction so that the handlers can // safely do any database access. for (folder in arrayOfChildFolders) { - numFolder = [NSNumber numberWithInt:[folder itemId]]; + numFolder = @(folder.itemId); [arrayOfFolderIds addObject:numFolder]; [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_WillDeleteFolder" object:numFolder]; } // Now do the deletion. - [self doTransactionWithBlock:^(BOOL *rollback) { result = [self wrappedDeleteFolder:folderId]; - }]; //end transaction block // Send the post-delete notification after we're finished. Note that the folder actually corresponding to // each numFolder won't exist any more and the handlers need to be aware of this. - for (numFolder in arrayOfFolderIds) + for (numFolder in arrayOfFolderIds) { [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_FolderDeleted" object:numFolder]; + } return result; } -/* setFolderName - * Renames the specified folder. + +/** + * Renames the specified folder. + * + * @param newName the name name for the folder + * @param folderId the ID of the folder to rename + * + * @return YES on success */ --(BOOL)setFolderName:(NSInteger)folderId newName:(NSString *)newName +-(BOOL)setName:(NSString *)newName forFolder:(NSInteger)folderId { // Exit now if we're read-only - if (readOnly) + if (readOnly) { return NO; - + } + // Find our folder element. Folder * folder = [self folderFromID:folderId]; if (!folder) @@ -1177,61 +1028,83 @@ -(BOOL)setFolderName:(NSInteger)folderId newName:(NSString *)newName // Do nothing if the name hasn't changed. Otherwise it is wasted // effort, basically. - if ([[folder name] isEqualToString:newName]) + if ([folder.name isEqualToString:newName]) { return NO; + } - [folder setName:newName]; + folder.name = newName; // Rename in the database - NSString * preparedNewName = [Database prepareStringForQuery:newName]; - [self executeSQLWithFormat:@"update folders set foldername='%@' where folder_id=%ld", preparedNewName, folderId]; + FMDatabaseQueue *queue = databaseQueue; + [queue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"update folders set foldername=? where folder_id=?", newName, @(folderId)]; + }]; // Send a notification that the folder has changed. It is the responsibility of the // notifiee that they work out that the name is the part that has changed. - [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_FolderNameChanged" object:[NSNumber numberWithInt:folderId]]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_FolderNameChanged" object:@(folderId)]; return YES; } -/* setFolderDescription - * Sets the folder description both in the internal structure and in the folder_description table. + +/** + * Sets the folder description both in the internal structure and in the folder_description table. + * + * @param newDescription The new description for the folder + * @param folderId The ID of the folder + * + * @return YES on success */ --(BOOL)setFolderDescription:(NSInteger)folderId newDescription:(NSString *)newDescription +-(BOOL)setDescription:(NSString *)newDescription forFolder:(NSInteger)folderId { // Exit now if we're read-only - if (readOnly) + if (readOnly) { return NO; - + } // Find our folder element. Folder * folder = [self folderFromID:folderId]; - if (!folder) + if (!folder) { return NO; + } // Do nothing if the description hasn't changed. Otherwise it is wasted // effort, basically. - if ([[folder feedDescription] isEqualToString:newDescription]) + if ([folder.feedDescription isEqualToString:newDescription]) { return NO; + } - [folder setFeedDescription:newDescription]; + folder.feedDescription = newDescription; // Add a new description or update the one we have - NSString * preparedNewDescription = [Database prepareStringForQuery:newDescription]; - [self executeSQLWithFormat:@"update rss_folders set description='%@' where folder_id=%ld", preparedNewDescription, (long)folderId]; + FMDatabaseQueue *queue = databaseQueue; + [queue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"update rss_folders set description=? where folder_id=?", + newDescription, @(folderId)]; + }]; // Send a notification that the folder has changed. It is the responsibility of the // notifiee that they work out that the description is the part that has changed. - [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_FolderDescriptionChanged" object:[NSNumber numberWithInt:folderId]]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_FolderDescriptionChanged" + object:@(folderId)]; return YES; } -/* setFolderHomePage - * Sets the folder's associated URL link in both in the internal structure and in the folder_description table. + +/** + * Sets the folder's associated home page URL link in both in the internal + * structure and in the folder_description table. + * + * @param homePageURL The home page URL + * @param folderId The ID of the folder getting updated + * + * @return YES on success */ --(BOOL)setFolderHomePage:(NSInteger)folderId newHomePage:(NSString *)newHomePage +-(BOOL)setHomePage:(NSString *)homePageURL forFolder:(NSInteger)folderId; { // Exit now if we're read-only - if (readOnly) + if (readOnly) { return NO; - + } // Find our folder element. Folder * folder = [self folderFromID:folderId]; if (!folder) @@ -1239,18 +1112,24 @@ -(BOOL)setFolderHomePage:(NSInteger)folderId newHomePage:(NSString *)newHomePage // Do nothing if the link hasn't changed. Otherwise it is wasted // effort, basically. - if ([[folder homePage] isEqualToString:newHomePage]||newHomePage==nil) + if ([folder.homePage isEqualToString:homePageURL] || homePageURL==nil) { return NO; + } - [folder setHomePage:newHomePage]; + folder.homePage = homePageURL; // Add a new link or update the one we have - NSString * preparedNewLink = [Database prepareStringForQuery:newHomePage]; - [self executeSQLWithFormat:@"update rss_folders set home_page='%@' where folder_id=%ld", preparedNewLink, (long)folderId]; + FMDatabaseQueue *queue = databaseQueue; + [queue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"update rss_folders set home_page=? where folder_id=?", + homePageURL, @(folderId)]; + }]; + // Send a notification that the folder has changed. It is the responsibility of the // notifiee that they work out that the link is the part that has changed. - [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_FolderHomePageChanged" object:[NSNumber numberWithInt:folderId]]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_FolderHomePageChanged" + object:@(folderId)]; return YES; } @@ -1260,24 +1139,25 @@ -(BOOL)setFolderHomePage:(NSInteger)folderId newHomePage:(NSString *)newHomePage -(BOOL)setFolderUsername:(NSInteger)folderId newUsername:(NSString *)name { // Exit now if we're read-only - if (readOnly) - return NO; + if (readOnly) return NO; // Find our folder element. Folder * folder = [self folderFromID:folderId]; - if (!folder) - return NO; + if (!folder) return NO; // Do nothing if the link hasn't changed. Otherwise it is wasted // effort, basically. - if ([[folder username] isEqualToString:name]) - return NO; + if ([folder.username isEqualToString:name]) return NO; - [folder setUsername:name]; + folder.username = name; // Add a new link or update the one we have - NSString * preparedName = [Database prepareStringForQuery:name]; - [self executeSQLWithFormat:@"update rss_folders set username='%@' where folder_id=%ld", preparedName, (long)folderId]; + FMDatabaseQueue *queue = databaseQueue; + [queue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"update rss_folders set username=? where folder_id=?", + name, @(folderId)]; + }]; + return YES; } @@ -1287,11 +1167,12 @@ -(BOOL)setFolderUsername:(NSInteger)folderId newUsername:(NSString *)name -(BOOL)setParent:(NSInteger)newParentID forFolder:(NSInteger)folderId { // Exit now if we're read-only - if (readOnly) + if (readOnly) { return NO; + } Folder * folder = [self folderFromID:folderId]; - if ([folder parentId] == newParentID) + if (folder.parentId == newParentID) return NO; // Sanity check. Make sure we're not reparenting to our @@ -1299,24 +1180,24 @@ -(BOOL)setParent:(NSInteger)newParentID forFolder:(NSInteger)folderId Folder * parentFolder = [self folderFromID:newParentID]; while (parentFolder != nil) { - if ([parentFolder itemId] == folderId) + if (parentFolder.itemId == folderId) return NO; - parentFolder = [self folderFromID:[parentFolder parentId]]; + parentFolder = [self folderFromID:parentFolder.parentId]; } // Adjust the child unread count for the old parent. NSInteger adjustment = 0; if (IsRSSFolder(folder) || IsGoogleReaderFolder(folder)) - adjustment = [folder unreadCount]; - else if ([folder isGroupFolder]) - adjustment = [folder childUnreadCount]; + adjustment = folder.unreadCount; + else if (folder.groupFolder) + adjustment = folder.childUnreadCount; if (adjustment > 0) { - parentFolder = [self folderFromID:[folder parentId]]; + parentFolder = [self folderFromID:folder.parentId]; while (parentFolder != nil) { - [parentFolder setChildUnreadCount:[parentFolder childUnreadCount] - adjustment]; - parentFolder = [self folderFromID:[parentFolder parentId]]; + parentFolder.childUnreadCount = parentFolder.childUnreadCount - adjustment; + parentFolder = [self folderFromID:parentFolder.parentId]; } } @@ -1330,13 +1211,17 @@ -(BOOL)setParent:(NSInteger)newParentID forFolder:(NSInteger)folderId parentFolder = [self folderFromID:newParentID]; while (parentFolder != nil) { - [parentFolder setChildUnreadCount:[parentFolder childUnreadCount] + adjustment]; - parentFolder = [self folderFromID:[parentFolder parentId]]; + parentFolder.childUnreadCount = parentFolder.childUnreadCount + adjustment; + parentFolder = [self folderFromID:parentFolder.parentId]; } } // Update the database now - [self executeSQLWithFormat:@"update folders set parent_id=%ld where folder_id=%ld", newParentID, folderId]; + FMDatabaseQueue *queue = databaseQueue; + [queue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"update folders set parent_id=? where folder_id=?", + @(newParentID), @(folderId)]; + }]; return YES; } @@ -1346,12 +1231,17 @@ -(BOOL)setParent:(NSInteger)newParentID forFolder:(NSInteger)folderId -(BOOL)setFirstChild:(NSInteger)childId forFolder:(NSInteger)folderId { // Exit now if we're read-only - if (readOnly) + if (readOnly) { return NO; + } + FMDatabaseQueue *queue = databaseQueue; + if (folderId == MA_Root_Folder) { - [self executeSQLWithFormat:@"update info set first_folder=%ld", childId]; + [queue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"update info set first_folder=?", @(childId)]; + }]; } else { @@ -1359,9 +1249,11 @@ -(BOOL)setFirstChild:(NSInteger)childId forFolder:(NSInteger)folderId if (folder == nil) return NO; - [folder setFirstChildId:childId]; - - [self executeSQLWithFormat:@"update folders set first_child=%ld where folder_id=%ld", childId, folderId]; + folder.firstChildId = childId; + [queue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"update folders set first_child=? where folder_id=?", + @(childId), @(folderId)]; + }]; } return YES; @@ -1373,16 +1265,22 @@ -(BOOL)setFirstChild:(NSInteger)childId forFolder:(NSInteger)folderId -(BOOL)setNextSibling:(NSUInteger)nextSiblingId forFolder:(NSInteger)folderId { // Exit now if we're read-only - if (readOnly) + if (readOnly) { return NO; - + } + Folder * folder = [self folderFromID:folderId]; if (folder == nil) return NO; - [folder setNextSiblingId:nextSiblingId]; + folder.nextSiblingId = nextSiblingId; - [self executeSQLWithFormat:@"update folders set next_sibling=%lu where folder_id=%ld", nextSiblingId, folderId]; + FMDatabaseQueue *queue = databaseQueue; + [queue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"update folders set next_sibling=? where folder_id=?", + @(nextSiblingId), @(folderId)]; + }]; + return YES; } @@ -1392,14 +1290,16 @@ -(BOOL)setNextSibling:(NSUInteger)nextSiblingId forFolder:(NSInteger)folderId -(NSInteger)firstFolderId { __block NSInteger folderId = 0; - dispatch_sync(_execQueue, ^() { - FMResultSet * results = [sqlDatabase executeQuery:@"select first_folder from info"]; - if ([results next]) - { - folderId = [[results stringForColumn:@"first_folder"] intValue]; - } - [results close]; - }); + FMDatabaseQueue *queue = databaseQueue; + [queue inDatabase:^(FMDatabase *db) { + FMResultSet * results = [db executeQuery:@"select first_folder from info"]; + if ([results next]) + { + folderId = [results intForColumn:@"first_folder"]; + } + [results close]; + }]; + return folderId; } @@ -1408,7 +1308,7 @@ -(NSInteger)firstFolderId */ -(NSInteger)trashFolderId { - return [trashFolder itemId]; + return trashFolder.itemId; } /* searchFolderId; @@ -1417,38 +1317,43 @@ -(NSInteger)trashFolderId */ -(NSInteger)searchFolderId { - if ([self searchFolder] == nil) + if (self.searchFolder == nil) { NSInteger folderId = [self addFolder:MA_Root_Folder afterChild:0 folderName: NSLocalizedString(@"Search Results", nil) type:MA_Search_Folder canAppendIndex:YES]; - [self setSearchFolder:[self folderFromID:folderId]]; + self.searchFolder = [self folderFromID:folderId]; } - return [[self searchFolder] itemId]; + return (self.searchFolder).itemId; } /* folderFromID - * Retrieve a Folder given it's ID. + * Retrieve a Folder given its ID. */ -(Folder *)folderFromID:(NSInteger)wantedId { - return [foldersDict objectForKey:[NSNumber numberWithInt:wantedId]]; + return foldersDict[@(wantedId)]; } /* folderFromName - * Retrieve a Folder given it's name. + * Retrieve a Folder given its name. */ -(Folder *)folderFromName:(NSString *)wantedName { Folder * folder; for (folder in [foldersDict objectEnumerator]) { - if ([[folder name] isEqualToString:wantedName]) + if ([folder.name isEqualToString:wantedName]) break; } return folder; } -/* folderFromFeedURL - * Returns the RSSFolder that is subscribed to the specified feed URL. + +/*! + * folderFromFeedURL + * + * @param wantedFeedURL The feed URL the folder is wanted for + * + * @return An RSSFolder that is subscribed to the specified feed URL. */ -(Folder *)folderFromFeedURL:(NSString *)wantedFeedURL; { @@ -1456,7 +1361,7 @@ -(Folder *)folderFromFeedURL:(NSString *)wantedFeedURL; for (folder in [foldersDict objectEnumerator]) { - if ([[folder feedURL] isEqualToString:wantedFeedURL]) + if ([folder.feedURL isEqualToString:wantedFeedURL]) break; } return folder; @@ -1468,201 +1373,196 @@ -(Folder *)folderFromFeedURL:(NSString *)wantedFeedURL; */ -(void)handleAutoSortFoldersTreeChange:(NSNotification *)notification { - if (!readOnly) - [self executeSQLWithFormat:@"update info set folder_sort=%d", [[Preferences standardPreferences] foldersTreeSortMethod]]; + if (!readOnly) { + [databaseQueue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"update info set folder_sort=?", @([Preferences standardPreferences].foldersTreeSortMethod)]; + }]; + } } -/* createArticle - * Adds or updates an article in the specified folder. Returns YES if the - * article was added or updated or NO if we couldn't add the article for +/* addArticle + * Adds an article in the specified folder. Returns YES if the + * article was added or NO if we couldn't add the article for * some reason. */ --(BOOL)createArticle:(NSInteger)folderID article:(Article *)article guidHistory:(NSArray *)guidHistory +-(BOOL)addArticle:(Article *)article toFolder:(NSInteger)folderID { - // Exit now if we're read-only + FMDatabaseQueue *queue = databaseQueue; + + // Exit now if we're read-only if (readOnly) return NO; - - // Make sure the folder ID is valid. We need it to decipher - // some info before we add the article. - Folder * folder = [self folderFromID:folderID]; - if (folder != nil) - { - // Prime the article cache - [self initArticleArray:folder]; - - // Extract the article data from the dictionary. - NSString * articleBody = [article body]; - NSString * articleTitle = [article title]; - NSDate * articleDate = [article date]; - NSString * articleLink = [[article link] trim]; - NSString * userName = [[article author] trim]; - NSString * articleEnclosure = [[article enclosure] trim]; - NSString * articleGuid = [article guid]; - NSInteger parentId = [article parentId]; - BOOL marked_flag = [article isFlagged]; - BOOL read_flag = [article isRead]; - BOOL revised_flag = [article isRevised]; - BOOL deleted_flag = [article isDeleted]; - BOOL hasenclosure_flag = [article hasEnclosure]; - - // We always set the created date ourselves - [article setCreatedDate:[NSDate date]]; - - // Set some defaults - if (articleDate == nil) - articleDate = [NSDate date]; - if (userName == nil) - userName = @""; - - // Parse off the title - if (articleTitle == nil || [articleTitle isBlank]) - articleTitle = [[NSString stringByRemovingHTML:articleBody] firstNonBlankLine]; - - // Save date as time intervals - NSTimeInterval interval = [articleDate timeIntervalSince1970]; - NSTimeInterval createdInterval = [[article createdDate] timeIntervalSince1970]; - - // Does this article already exist? - Article * existingArticle = [folder articleFromGuid:articleGuid]; - // We're going to ignore the problem of feeds re-using guids, which is very naughty! Bad feed! - - // Fix title and article body so they're acceptable to SQL - NSString * preparedArticleTitle = [Database prepareStringForQuery:articleTitle]; - NSString * preparedArticleText = [Database prepareStringForQuery:articleBody]; - NSString * preparedArticleLink = [Database prepareStringForQuery:articleLink]; - NSString * preparedUserName = [Database prepareStringForQuery:userName]; - NSString * preparedArticleGuid = [Database prepareStringForQuery:articleGuid]; - NSString * preparedEnclosure = [Database prepareStringForQuery:articleEnclosure]; - - // Unread count adjustment factor - NSInteger adjustment = 0; - - if (existingArticle == nil && [guidHistory containsObject:articleGuid]) - { - return NO; // Article has been deleted and removed from database, so ignore - } - else if (existingArticle == nil) - { - - NSInteger results = [self executeSQLWithFormat: - @"insert into messages (message_id, parent_id, folder_id, sender, link, date, createddate, read_flag, marked_flag, deleted_flag, title, text, revised_flag, enclosure, hasenclosure_flag) " - @"values('%@', %ld, %ld, '%@', '%@', %f, %f, %d, %d, %d, '%@', '%@', %d, '%@', %d)", - preparedArticleGuid, - (long)parentId, - (long)folderID, - preparedUserName, - preparedArticleLink, - interval, - createdInterval, - read_flag, - marked_flag, - deleted_flag, - preparedArticleTitle, - preparedArticleText, - revised_flag, - preparedEnclosure, - hasenclosure_flag]; - if (results != SQLITE_OK) - return NO; - [self executeSQLWithFormat:@"insert into rss_guids (message_id, folder_id) values ('%@', %ld)", preparedArticleGuid, folderID]; - - // Add the article to the folder - [article setStatus:MA_MsgStatus_New]; - [folder addArticleToCache:article]; - - // Update folder unread count - if (!read_flag) - adjustment = 1; - } - else if ([existingArticle isDeleted]) - { - return NO; - } - else if (![[Preferences standardPreferences] boolForKey:MAPref_CheckForUpdatedArticles]) - { - return NO; - } - else - { - // The article is revised if either the title or the body has changed. - - NSString * existingTitle = [existingArticle title]; - BOOL isArticleRevised = ![existingTitle isEqualToString:articleTitle]; - - if (!isArticleRevised) - { - __block NSString * existingBody = [existingArticle body]; - // If the folder is not displayed, then the article text has not been loaded yet. - if (existingBody == nil) - { - dispatch_sync(_execQueue, ^() { - FMResultSet * results = [sqlDatabase executeQueryWithFormat:@"select text from messages where folder_id=%ld and message_id=%@", (long)folderID, articleGuid]; - if ([results next]) - { - existingBody = [results stringForColumn:@"text"]; - } - else - existingBody = @""; - [results close]; - }); - } - - isArticleRevised = ![existingBody isEqualToString:articleBody]; - } - - if (isArticleRevised) - { - // Only pre-existing articles should be marked as revised. - // New articles created during the current refresh should not be marked as revised, - // even if there are multiple versions of the new article in the feed. - revised_flag = [existingArticle isRevised]; - if (!revised_flag && ([existingArticle status] == MA_MsgStatus_Empty)) - revised_flag = YES; - - NSInteger results = [self executeSQLWithFormat:@"update messages set parent_id=%ld, sender='%@', link='%@', date=%f, " - @"read_flag=0, title='%@', text='%@', revised_flag=%d where folder_id=%ld and message_id='%@'", - (long)parentId, - preparedUserName, - preparedArticleLink, - interval, - preparedArticleTitle, - preparedArticleText, - revised_flag, - (long)folderID, - preparedArticleGuid]; - if (results != SQLITE_OK) - return NO; - - [existingArticle setTitle:articleTitle]; - [existingArticle setBody:articleBody]; - [existingArticle markRevised:revised_flag]; - - // Update folder unread count if necessary - if ([existingArticle isRead]) - { - adjustment = 1; - [article setStatus:MA_MsgStatus_New]; - [existingArticle markRead:NO]; - } - else - [article setStatus:MA_MsgStatus_Updated]; - } - else - { - return NO; - } - } - - // Fix unread count on parent folders - if (adjustment != 0) - { - countOfUnread += adjustment; - [self setFolderUnreadCount:folder adjustment:adjustment]; - } - return YES; - } - return NO; + + // Extract the article data from the dictionary. + NSString * articleBody = article.body; + NSString * articleTitle = article.title; + NSDate * articleDate = article.date; + NSString * articleLink = article.link.trim; + NSString * userName = article.author.trim; + NSString * articleEnclosure = article.enclosure.trim; + NSString * articleGuid = article.guid; + NSInteger parentId = article.parentId; + BOOL marked_flag = article.flagged; + BOOL read_flag = article.read; + BOOL revised_flag = article.revised; + BOOL deleted_flag = article.deleted; + BOOL hasenclosure_flag = article.hasEnclosure; + + // We always set the created date ourselves + article.createdDate = [NSDate date]; + + // Set some defaults + if (articleDate == nil) + articleDate = [NSDate date]; + if (userName == nil) + userName = @""; + + // Parse off the title + if (articleTitle == nil || articleTitle.blank) + articleTitle = [NSString stringByRemovingHTML:articleBody].firstNonBlankLine; + + // Dates are stored as time intervals + NSTimeInterval interval = articleDate.timeIntervalSince1970; + NSTimeInterval createdInterval = article.createdDate.timeIntervalSince1970; + + __block BOOL success; + [queue inTransaction:^(FMDatabase *db, BOOL *rollback) { + success = [db executeUpdate:@"insert into messages (message_id, parent_id, folder_id, sender, link, date, createddate, read_flag, marked_flag, deleted_flag, title, text, revised_flag, enclosure, hasenclosure_flag) " + @"values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + articleGuid, + @(parentId), + @(folderID), + userName, + articleLink, + @(interval), + @(createdInterval), + @(read_flag), + @(marked_flag), + @(deleted_flag), + articleTitle, + articleBody, + @(revised_flag), + articleEnclosure, + @(hasenclosure_flag)]; + if (!success) { + NSLog(@"error = %@", [db lastErrorMessage]); + *rollback = YES; + return; + } + + success = [db executeUpdate:@"insert into rss_guids (message_id, folder_id) values (?, ?)", articleGuid, @(folderID)]; + if (!success) { + NSLog(@"error = %@", [db lastErrorMessage]); + *rollback = YES; + return; + } + + }]; + return (success); +} + +/* updateArticle + * Updates an article in the specified folder. Returns YES if the + * article was updated or NO if we couldn't update the article for + * some reason. + */ +-(BOOL)updateArticle:(Article *)existingArticle ofFolder:(NSInteger)folderID withArticle:(Article *)article +{ + // Exit now if we're read-only + if (readOnly) + return NO; + + FMDatabaseQueue *queue = databaseQueue; + + // Extract the data from the new state of article + NSString * articleBody = article.body; + NSString * articleTitle = article.title; + NSDate * articleDate = article.date; + NSString * articleLink = article.link.trim; + NSString * userName = article.author.trim; + NSString * articleGuid = article.guid; + NSInteger parentId = article.parentId; + BOOL revised_flag = article.revised; + + // Set some defaults + if (articleDate == nil) + articleDate = existingArticle.date; + if (userName == nil) + userName = @""; + + // Parse off the title + if (articleTitle == nil || articleTitle.blank) + articleTitle = [NSString stringByRemovingHTML:articleBody].firstNonBlankLine; + + // Dates are stored as time intervals + NSTimeInterval interval = articleDate.timeIntervalSince1970; + + // The article is revised if either the title or the body has changed. + + NSString * existingTitle = existingArticle.title; + BOOL isArticleRevised = ![existingTitle isEqualToString:articleTitle]; + if (!isArticleRevised) + { + __block NSString * existingBody = existingArticle.body; + // the article text may not have been loaded yet, for instance if the folder is not displayed + if (existingBody == nil) + { + [queue inDatabase:^(FMDatabase *db) { + FMResultSet * results = [db executeQuery:@"select text from messages where folder_id=? and message_id=?", + @(folderID), articleGuid]; + if ([results next]) { + existingBody = [results stringForColumn:@"text"]; + } else { + existingBody = @""; + } + [results close]; + }]; + } + isArticleRevised = ![existingBody isEqualToString:articleBody]; + } + + if (isArticleRevised) + { + // Articles preexisting in database should be marked as revised. + // New articles created during the current refresh should not be marked as revised, + // even if there are multiple versions of the new article in the feed. + if (existingArticle.revised || (existingArticle.status == ArticleStatusEmpty)) + revised_flag = YES; + + __block BOOL success; + [queue inDatabase:^(FMDatabase *db) { + success = [db executeUpdate:@"update messages set parent_id=?, sender=?, link=?, date=?, " + @"read_flag=0, title=?, text=?, revised_flag=? where folder_id=? and message_id=?", + @(parentId), + userName, + articleLink, + @(interval), + articleTitle, + articleBody, + @(revised_flag), + @(folderID), + articleGuid]; + + }]; + + if (!success) + return NO; + else + { + // update the existing article in memory + existingArticle.title = articleTitle; + existingArticle.body = articleBody; + [existingArticle markRevised:revised_flag]; + existingArticle.parentId = parentId; + existingArticle.author = userName; + existingArticle.link = articleLink; + return YES; + } + } + else + { + return NO; + } } /* purgeArticlesOlderThanDays @@ -1675,10 +1575,12 @@ -(void)purgeArticlesOlderThanDays:(NSUInteger)daysToKeep { NSInteger dayDelta = (daysToKeep % 1000); NSInteger monthDelta = (daysToKeep / 1000); - NSTimeInterval timeDiff = [[[NSCalendarDate calendarDate] dateByAddingYears:0 months:-monthDelta days:-dayDelta hours:0 minutes:0 seconds:0] timeIntervalSince1970]; - - [self executeSQLWithFormat:@"update messages set deleted_flag=1 where deleted_flag=0 and marked_flag=0 and read_flag=1 and date < %f", timeDiff]; - } + NSTimeInterval timeDiff = [[NSCalendarDate calendarDate] dateByAddingYears:0 months:-monthDelta days:-dayDelta hours:0 minutes:0 seconds:0].timeIntervalSince1970; + + [databaseQueue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"update messages set deleted_flag=1 where deleted_flag=0 and marked_flag=0 and read_flag=1 and date < ?", @(timeDiff)]; + }]; + } } /* purgeDeletedArticles @@ -1687,44 +1589,53 @@ -(void)purgeArticlesOlderThanDays:(NSUInteger)daysToKeep */ -(void)purgeDeletedArticles { - NSInteger results = [self executeSQL:@"delete from messages where deleted_flag=1"]; - if (results == SQLITE_OK) + __block BOOL success; + [databaseQueue inDatabase:^(FMDatabase *db) { + success = [db executeUpdate:@"delete from messages where deleted_flag=1"]; + }]; + + if (success) { [self compactDatabase]; - [trashFolder clearCache]; + for (Folder * folder in [foldersDict objectEnumerator]) + [folder clearCache]; - [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_FoldersUpdated" object:[NSNumber numberWithInt:[self trashFolderId]]]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_FoldersUpdated" object:@(self.trashFolderId)]; } } /* deleteArticle * Permanently deletes a article from the specified folder */ --(BOOL)deleteArticle:(NSInteger)folderId guid:(NSString *)guid +-(BOOL)deleteArticle:(Article *)article { + NSInteger folderId = article.folderId; + NSString * guid = article.guid; Folder * folder = [self folderFromID:folderId]; if (folder != nil) { - // Prime the article cache - [self initArticleArray:folder]; + FMDatabaseQueue *queue = databaseQueue; + __block BOOL success; + [queue inDatabase:^(FMDatabase *db) { + success = [db executeUpdate:@"delete from messages where folder_id=? and message_id=?", + @(folderId), guid]; + }]; - Article * article = [folder articleFromGuid:guid]; - if (article != nil) - { - NSString * preparedGuid = [Database prepareStringForQuery:guid]; - - NSInteger results = [self executeSQLWithFormat:@"delete from messages where folder_id=%ld and message_id='%@'", (long)folderId, preparedGuid]; - if (results == SQLITE_OK) + if (success) + { + if (!article.read) + { + [self setFolderUnreadCount:folder adjustment:-1]; + } + if ([folder countOfCachedArticles] > 0) { - if (![article isRead]) - { - [self setFolderUnreadCount:folder adjustment:-1]; - --countOfUnread; - } + // If we're in a smart folder, the cached article may be different. + Article * cachedArticle = [folder articleFromGuid:guid]; + [cachedArticle markDeleted:YES]; [folder removeArticleFromCache:guid]; - return YES; } - } + return YES; + } } return NO; } @@ -1736,22 +1647,22 @@ -(void)initSmartfoldersDict { if (!initializedSmartfoldersDict) { - // Make sure we have a database. - NSAssert(sqlDatabase, @"Database not assigned for this item"); + FMDatabaseQueue *queue = databaseQueue; + // Make sure we have a database queue. + NSAssert(queue, @"Database queue not assigned for this item"); - dispatch_sync(_execQueue, ^() { - FMResultSet * results = [sqlDatabase executeQuery:@"select folder_id, search_string from smart_folders"]; + [queue inDatabase:^(FMDatabase *db) { + FMResultSet * results = [db executeQuery:@"select folder_id, search_string from smart_folders"]; while([results next]) { - NSInteger folderId = [[results stringForColumnIndex:0] intValue]; + NSInteger folderId = [results stringForColumnIndex:0].integerValue; NSString * search_string = [results stringForColumnIndex:1]; CriteriaTree * criteriaTree = [[CriteriaTree alloc] initWithString:search_string]; - [smartfoldersDict setObject:criteriaTree forKey:[NSNumber numberWithInt:folderId]]; - [criteriaTree release]; + smartfoldersDict[@(folderId)] = criteriaTree; } [results close]; - }); + }]; initializedSmartfoldersDict = YES; } } @@ -1763,7 +1674,7 @@ -(void)initSmartfoldersDict -(CriteriaTree *)searchStringForSmartFolder:(NSInteger)folderId { [self initSmartfoldersDict]; - return [smartfoldersDict objectForKey:[NSNumber numberWithInt:folderId]]; + return smartfoldersDict[@(folderId)]; } /* addSmartFolder @@ -1772,20 +1683,17 @@ -(CriteriaTree *)searchStringForSmartFolder:(NSInteger)folderId */ -(NSInteger)addSmartFolder:(NSString *)folderName underParent:(NSInteger)parentId withQuery:(CriteriaTree *)criteriaTree { - Folder * folder = [self folderFromName:folderName]; - - if (folder) - { - [self updateSearchFolder:[folder itemId] withFolder:folderName withQuery:criteriaTree]; - return [folder itemId]; - } - NSInteger folderId = [self addFolder:parentId afterChild:0 folderName:folderName type:MA_Smart_Folder canAppendIndex:NO]; if (folderId != -1) { - NSString * preparedQueryString = [Database prepareStringForQuery:[criteriaTree string]]; - [self executeSQLWithFormat:@"insert into smart_folders (folder_id, search_string) values (%ld, '%@')", (long)folderId, preparedQueryString]; - [smartfoldersDict setObject:criteriaTree forKey:[NSNumber numberWithInt:folderId]]; + FMDatabaseQueue *queue = databaseQueue; + [queue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"insert into smart_folders (folder_id, search_string) values (?, ?)", + @(folderId), + criteriaTree.string]; + }]; + + smartfoldersDict[@(folderId)] = criteriaTree; } return folderId; } @@ -1793,20 +1701,26 @@ -(NSInteger)addSmartFolder:(NSString *)folderName underParent:(NSInteger)parentI /* updateSearchFolder * Updates the search string for the specified folder. */ --(BOOL)updateSearchFolder:(NSInteger)folderId withFolder:(NSString *)folderName withQuery:(CriteriaTree *)criteriaTree +-(void)updateSearchFolder:(NSInteger)folderId withFolder:(NSString *)folderName withQuery:(CriteriaTree *)criteriaTree { Folder * folder = [self folderFromID:folderId]; - if (![[folder name] isEqualToString:folderName]) - [self setFolderName:folderId newName:folderName]; - + if (![folder.name isEqualToString:folderName]) { + [self setName:folderName forFolder:folderId]; + } + // Update the smart folder string - NSString * preparedQueryString = [Database prepareStringForQuery:[criteriaTree string]]; - [self executeSQLWithFormat:@"update smart_folders set search_string='%@' where folder_id=%ld", preparedQueryString, (long)folderId]; - [smartfoldersDict setObject:criteriaTree forKey:[NSNumber numberWithInt:folderId]]; + FMDatabaseQueue *queue = databaseQueue; + [queue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"update smart_folders set search_string=? where folder_id=?", + criteriaTree.string, + @(folderId)]; + }]; + + smartfoldersDict[@(folderId)] = criteriaTree; NSNotificationCenter * nc = [NSNotificationCenter defaultCenter]; - [nc postNotificationOnMainThreadWithName:@"MA_Notify_FoldersUpdated" object:[NSNumber numberWithInt:folderId]]; - return YES; + [nc postNotificationOnMainThreadWithName:@"MA_Notify_ArticleListContentChange" + object:@(folderId)]; } /* initFolderArray @@ -1817,55 +1731,62 @@ -(void)initFolderArray if (!initializedfoldersDict) { // Make sure we have a database. - NSAssert(sqlDatabase, @"Database not assigned for this item"); + NSAssert(databaseQueue, @"Database not assigned for this item"); // Keep running count of total unread articles countOfUnread = 0; + + FMDatabaseQueue *queue = databaseQueue; + + [queue inTransaction:^(FMDatabase *db, BOOL *rollback) { + FMResultSet * results = [db executeQuery:@"select folder_id, parent_id, foldername, unread_count, last_update," + @" type, flags, next_sibling, first_child from folders order by folder_id"]; + if (!results) { + NSLog(@"%s: executeQuery error: %@", __FUNCTION__, [db lastErrorMessage]); + return; + } + + while ([results next]) + { + NSInteger newItemId = [results stringForColumnIndex:0].integerValue; + NSInteger newParentId = [results stringForColumnIndex:1].integerValue; + NSString * name = [results stringForColumnIndex:2]; + if (name == nil) // Paranoid check because of https://github.com/ViennaRSS/vienna-rss/issues/877 + name = [Database untitledFeedFolderName]; + NSInteger unreadCount = [results stringForColumnIndex:3].integerValue; + NSDate * lastUpdate = [NSDate dateWithTimeIntervalSince1970:[results stringForColumnIndex:4].doubleValue]; + NSInteger type = [results stringForColumnIndex:5].integerValue; + NSInteger flags = [results stringForColumnIndex:6].integerValue; + NSInteger nextSibling = [results stringForColumnIndex:7].integerValue; + NSInteger firstChild = [results stringForColumnIndex:8].integerValue; + + Folder * folder = [[Folder alloc] initWithId:newItemId parentId:newParentId name:name type:type]; + folder.nextSiblingId = nextSibling; + folder.firstChildId = firstChild; + if (!IsRSSFolder(folder) && !IsGoogleReaderFolder(folder)) + unreadCount = 0; + folder.unreadCount = unreadCount; + folder.lastUpdate = lastUpdate; + [folder setFlag:flags]; + if (unreadCount > 0) + countOfUnread += unreadCount; + foldersDict[@(newItemId)] = folder; + + // Remember the trash folder + if (IsTrashFolder(folder)) + self.trashFolder = folder; + + // Remember the search folder + if (IsSearchFolder(folder)) + self.searchFolder = folder; + } + [results close]; - dispatch_sync(_execQueue, ^() { - FMResultSet * results = [sqlDatabase executeQuery:@"select folder_id, parent_id, foldername, unread_count, last_update," - @" type, flags, next_sibling, first_child from folders order by folder_id"]; + // Load all RSS folders and add them to the list. + results = [db executeQuery:@"select folder_id, feed_url, username, last_update_string, description, home_page from rss_folders"]; while ([results next]) { - NSInteger newItemId = [[results stringForColumnIndex:0] intValue]; - NSInteger newParentId = [[results stringForColumnIndex:1] intValue]; - NSString * name = [results stringForColumnIndex:2]; - NSInteger unreadCount = [[results stringForColumnIndex:3] intValue]; - NSDate * lastUpdate = [NSDate dateWithTimeIntervalSince1970:[[results stringForColumnIndex:4] doubleValue]]; - NSInteger type = [[results stringForColumnIndex:5] intValue]; - NSInteger flags = [[results stringForColumnIndex:6] intValue]; - NSInteger nextSibling = [[results stringForColumnIndex:7] intValue]; - NSInteger firstChild = [[results stringForColumnIndex:8] intValue]; - - Folder * folder = [[[Folder alloc] initWithId:newItemId parentId:newParentId name:name type:type] autorelease]; - [folder setNextSiblingId:nextSibling]; - [folder setFirstChildId:firstChild]; - if (!IsRSSFolder(folder) && !IsGoogleReaderFolder(folder)) - unreadCount = 0; - [folder setUnreadCount:unreadCount]; - [folder setLastUpdate:lastUpdate]; - [folder setFlag:flags]; - if (unreadCount > 0) - countOfUnread += unreadCount; - [foldersDict setObject:folder forKey:[NSNumber numberWithInt:newItemId]]; - - // Remember the trash folder - if (IsTrashFolder(folder)) - [self setTrashFolder:folder]; - - // Remember the search folder - if (IsSearchFolder(folder)) - [self setSearchFolder:folder]; - } - [results close]; - }); - - // Load all RSS folders and add them to the list. - dispatch_sync(_execQueue, ^() { - FMResultSet * results = [sqlDatabase executeQuery:@"select folder_id, feed_url, username, last_update_string, description, home_page from rss_folders"]; - while ([results next]) - { - NSInteger folderId = [[results stringForColumnIndex:0] intValue]; + NSInteger folderId = [results stringForColumnIndex:0].integerValue; NSString * url = [results stringForColumnIndex:1]; NSString * username = [results stringForColumnIndex:2]; NSString * lastUpdateString = [results stringForColumnIndex:3]; @@ -1873,27 +1794,27 @@ -(void)initFolderArray NSString * linktext = [results stringForColumnIndex:5]; Folder * folder = [self folderFromID:folderId]; - [folder setFeedDescription:descriptiontext]; - [folder setHomePage:linktext]; - [folder setFeedURL:url]; - [folder setLastUpdateString:lastUpdateString]; - [folder setUsername:username]; + folder.feedDescription = descriptiontext; + folder.homePage = linktext; + folder.feedURL = url; + folder.lastUpdateString = lastUpdateString; + folder.username = username; } [results close]; - // Fix the childUnreadCount for every parent - for (Folder * folder in [foldersDict objectEnumerator]) + }]; + // Fix the childUnreadCount for every parent + for (Folder * folder in [foldersDict objectEnumerator]) + { + if (folder.unreadCount > 0 && folder.parentId != MA_Root_Folder) { - if ([folder unreadCount] > 0 && [folder parentId] != MA_Root_Folder) + Folder * parentFolder = [self folderFromID:folder.parentId]; + while (parentFolder != nil) { - Folder * parentFolder = [self folderFromID:[folder parentId]]; - while (parentFolder != nil) - { - [parentFolder setChildUnreadCount:[parentFolder childUnreadCount] + [folder unreadCount]]; - parentFolder = [self folderFromID:[parentFolder parentId]]; - } + parentFolder.childUnreadCount = parentFolder.childUnreadCount + folder.unreadCount; + parentFolder = [self folderFromID:parentFolder.parentId]; } } - }); + } // Done initializedfoldersDict = YES; } @@ -1916,11 +1837,11 @@ -(NSArray *)arrayOfFolders:(NSInteger)parentId { for (Folder * folder in [foldersDict objectEnumerator]) { - if ([folder parentId] == parentId) + if (folder.parentId == parentId) [newArray addObject:folder]; } } - return [newArray sortedArrayUsingSelector:@selector(folderNameCompare:)]; + return [newArray copy]; } /* arrayOfSubFolders @@ -1931,11 +1852,11 @@ -(NSArray *)arrayOfSubFolders:(Folder *)folder NSMutableArray * newArray = [NSMutableArray arrayWithObject:folder]; if (newArray != nil) { - NSInteger parentId = [folder itemId]; + NSInteger parentId = folder.itemId; for (Folder * item in [foldersDict objectEnumerator]) { - if ([item parentId] == parentId) + if (item.parentId == parentId) { if (IsGroupFolder(item)) [newArray addObjectsFromArray:[self arrayOfSubFolders:item]]; @@ -1956,72 +1877,68 @@ -(NSArray *)arrayOfAllFolders if (initializedfoldersDict == NO) [self initFolderArray]; - return [foldersDict allValues]; + return foldersDict.allValues; } -/* initArticleArray - * Ensures that the specified folder has a minimal cache of article information. +/* minimalCacheForFolder + * Returns a minimal cache of article information for the specified folder, + * which is enough for tasks like feed refreshes, but is not complete enough + * for displaying articles : it lacks articles' descriptions and dates. */ --(BOOL)initArticleArray:(Folder *)folder +-(NSArray *)minimalCacheForFolder:(NSInteger)folderId { // Prime the folder cache [self initFolderArray]; - // Exit now if we're already initialized - if ([folder countOfCachedArticles] == -1) - { - NSInteger folderId = [folder itemId]; + __block NSInteger unread_count = 0; + NSMutableArray * myCache = [NSMutableArray array]; - // Initialize to indicate that the folder array is valid. - [folder markFolderEmpty]; - - __block NSInteger unread_count = 0; - - dispatch_sync(_execQueue, ^() { - FMResultSet * results = [sqlDatabase executeQueryWithFormat:@"select message_id, read_flag, marked_flag, deleted_flag, title, link, revised_flag, hasenclosure_flag, enclosure from messages where folder_id=%ld", (long)folderId]; - while([results next]) - { - NSString * guid = [results stringForColumnIndex:0]; - BOOL read_flag = [[results stringForColumnIndex:1] intValue]; - BOOL marked_flag = [[results stringForColumnIndex:2] intValue]; - BOOL deleted_flag = [[results stringForColumnIndex:3] intValue]; - NSString * title = [results stringForColumnIndex:4]; - NSString * link = [results stringForColumnIndex:5]; - BOOL revised_flag = [[results stringForColumnIndex:6] intValue]; - BOOL hasenclosure_flag = [[results stringForColumnIndex:7] intValue]; - NSString * enclosure = [results stringForColumnIndex:8]; - - // Keep our own track of unread articles - if (!read_flag) - ++unread_count; - - Article * article = [[[Article alloc] initWithGuid:guid] autorelease]; - [article markRead:read_flag]; - [article markFlagged:marked_flag]; - [article markRevised:revised_flag]; - [article markDeleted:deleted_flag]; - [article setFolderId:folderId]; - [article setTitle:title]; - [article setLink:link]; - [article setEnclosure:enclosure]; - [article setHasEnclosure:hasenclosure_flag]; - [folder addArticleToCache:article]; - } - [results close]; - }); - - // This is a good time to do a quick check to ensure that our - // own count of unread is in sync with the folders count and fix - // them if not. - if (unread_count != [folder unreadCount]) + FMDatabaseQueue *queue = databaseQueue; + [queue inDatabase:^(FMDatabase *db) { + FMResultSet * results = [db executeQueryWithFormat:@"select message_id, read_flag, marked_flag, deleted_flag, title, link, revised_flag, hasenclosure_flag, enclosure from messages where folder_id=%ld", (long)folderId]; + while([results next]) { - NSLog(@"Fixing unread count for %@ (%ld on folder versus %ld in articles)", [folder name], (long)[folder unreadCount], (long)unread_count); - NSInteger diff = (unread_count - [folder unreadCount]); - [self setFolderUnreadCount:folder adjustment:diff]; - countOfUnread += diff; + NSString * guid = [results stringForColumnIndex:0]; + BOOL read_flag = [results stringForColumnIndex:1].integerValue; + BOOL marked_flag = [results stringForColumnIndex:2].integerValue; + BOOL deleted_flag = [results stringForColumnIndex:3].integerValue; + NSString * title = [results stringForColumnIndex:4]; + NSString * link = [results stringForColumnIndex:5]; + BOOL revised_flag = [results stringForColumnIndex:6].integerValue; + BOOL hasenclosure_flag = [results stringForColumnIndex:7].integerValue; + NSString * enclosure = [results stringForColumnIndex:8]; + + // Keep our own track of unread articles + if (!read_flag) + ++unread_count; + + Article * article = [[Article alloc] initWithGuid:guid]; + [article markRead:read_flag]; + [article markFlagged:marked_flag]; + [article markRevised:revised_flag]; + [article markDeleted:deleted_flag]; + article.folderId = folderId; + article.title = title; + article.link = link; + article.enclosure = enclosure; + article.hasEnclosure = hasenclosure_flag; + [myCache addObject:article]; } - } - return YES; + [results close]; + }]; + + // This is a good time to do a quick check to ensure that our + // own count of unread is in sync with the folders count and fix + // them if not. + Folder * folder = [self folderFromID:folderId]; + if (unread_count != folder.unreadCount) + { + NSLog(@"Fixing unread count for %@ (%ld on folder versus %ld in articles)", folder.name, (long)folder.unreadCount, (long)unread_count); + NSInteger diff = (unread_count - folder.unreadCount); + [self setFolderUnreadCount:folder adjustment:diff]; + } + + return [myCache copy]; } /* setSearchString @@ -2029,8 +1946,6 @@ -(BOOL)initArticleArray:(Folder *)folder */ -(void)setSearchString:(NSString *)newSearchString { - [newSearchString retain]; - [searchString release]; searchString = newSearchString; } @@ -2048,7 +1963,7 @@ -(NSString *)sqlScopeForFolder:(Folder *)folder flags:(NSInteger)scopeFlags // If folder is nil, rather than report an error, default to some impossible value if (folder != nil) - folderId = [folder itemId]; + folderId = folder.itemId; else { subScope = NO; @@ -2061,7 +1976,7 @@ -(NSString *)sqlScopeForFolder:(Folder *)folder flags:(NSInteger)scopeFlags // Straightforward folder is if (!subScope) - return [NSString stringWithFormat:@"%@%@%ld", [field sqlField], operatorString, (long)folderId]; + return [NSString stringWithFormat:@"%@%@%ld", field.sqlField, operatorString, (long)folderId]; // For under/not-under operators, we're creating a SQL statement of the format // (folder_id = || folder_id = ...). It is possible to try and simplify @@ -2070,21 +1985,21 @@ -(NSString *)sqlScopeForFolder:(Folder *)folder flags:(NSInteger)scopeFlags // NSArray * childFolders = [self arrayOfSubFolders:folder]; NSMutableString * sqlString = [[NSMutableString alloc] init]; - NSInteger count = [childFolders count]; + NSInteger count = childFolders.count; NSInteger index; if (count > 1) [sqlString appendString:@"("]; for (index = 0; index < count; ++index) { - Folder * folder = [childFolders objectAtIndex:index]; + Folder * folder = childFolders[index]; if (index > 0) [sqlString appendString:conditionString]; - [sqlString appendFormat:@"%@%@%ld", [field sqlField], operatorString, (long)[folder itemId]]; + [sqlString appendFormat:@"%@%@%ld", field.sqlField, operatorString, (long)folder.itemId]; } if (count > 1) [sqlString appendString:@")"]; - return [sqlString autorelease]; + return sqlString; } /* criteriaToSQL @@ -2095,15 +2010,15 @@ -(NSString *)criteriaToSQL:(CriteriaTree *)criteriaTree NSMutableString * sqlString = [[NSMutableString alloc] init]; NSInteger count = 0; - for (Criteria * criteria in [criteriaTree criteriaEnumerator]) + for (Criteria * criteria in criteriaTree.criteriaEnumerator) { - Field * field = [self fieldByName:[criteria field]]; + Field * field = [self fieldByName:criteria.field]; NSAssert1(field != nil, @"Criteria field %@ does not have an associated database field", [criteria field]); NSString * operatorString = nil; NSString * valueString = nil; - switch ([criteria operator]) + switch (criteria.operator) { case MA_CritOper_Is: operatorString = @"=%@"; break; case MA_CritOper_IsNot: operatorString = @"<>%@"; break; @@ -2131,19 +2046,19 @@ -(NSString *)criteriaToSQL:(CriteriaTree *)criteriaTree continue; if (count++ > 0) - [sqlString appendString:[criteriaTree condition] == MA_CritCondition_All ? @" and " : @" or "]; + [sqlString appendString:criteriaTree.condition == MA_CritCondition_All ? @" and " : @" or "]; - switch ([field type]) + switch (field.type) { case MA_FieldType_Flag: - valueString = [[criteria value] isEqualToString:@"Yes"] ? @"1" : @"0"; + valueString = [criteria.value isEqualToString:@"Yes"] ? @"1" : @"0"; break; case MA_FieldType_Folder: { - Folder * folder = [self folderFromName:[criteria value]]; + Folder * folder = [self folderFromName:criteria.value]; NSInteger scopeFlags = 0; - switch ([criteria operator]) + switch (criteria.operator) { case MA_CritOper_Under: scopeFlags = MA_Scope_SubFolders|MA_Scope_Inclusive; break; case MA_CritOper_NotUnder: scopeFlags = MA_Scope_SubFolders; break; @@ -2157,7 +2072,7 @@ -(NSString *)criteriaToSQL:(CriteriaTree *)criteriaTree case MA_FieldType_Date: { NSCalendarDate * startDate = [NSCalendarDate date]; - NSString * criteriaValue = [[criteria value] lowercaseString]; + NSString * criteriaValue = criteria.value.lowercaseString; NSInteger spanOfDays = 1; // "yesterday" is a short hand way of specifying the previous day. @@ -2175,27 +2090,38 @@ -(NSString *)criteriaToSQL:(CriteriaTree *)criteriaTree criteriaValue = [NSString stringWithFormat:@"%ld/%ld/%ld %d:%d:%d", (long)[startDate dayOfMonth], (long)[startDate monthOfYear], (long)[startDate yearOfCommonEra], 0, 0, 0]; startDate = [NSCalendarDate dateWithString:criteriaValue calendarFormat:@"%d/%m/%Y %H:%M:%S"]; - if ([criteria operator] == MA_CritOper_Is) + if (criteria.operator == MA_CritOper_Is) { NSCalendarDate * endDate; // Special case for Date is because the resolution of the date field is in // milliseconds. So we need to translate this to a range for this to make sense. endDate = [startDate dateByAddingYears:0 months:0 days:spanOfDays hours:0 minutes:0 seconds:0]; - operatorString = [NSString stringWithFormat:@">=%f and %@<%f", [startDate timeIntervalSince1970], [field sqlField], [endDate timeIntervalSince1970]]; + operatorString = [NSString stringWithFormat:@">=%f and %@<%f", startDate.timeIntervalSince1970, field.sqlField, endDate.timeIntervalSince1970]; valueString = @""; } else { - if (([criteria operator] == MA_CritOper_IsAfter) || ([criteria operator] == MA_CritOper_IsOnOrBefore)) + if ((criteria.operator == MA_CritOper_IsAfter) || (criteria.operator == MA_CritOper_IsOnOrBefore)) startDate = [startDate dateByAddingYears:0 months:0 days:0 hours:23 minutes:59 seconds:59]; - valueString = [NSString stringWithFormat:@"%f", [startDate timeIntervalSince1970]]; + valueString = [NSString stringWithFormat:@"%f", startDate.timeIntervalSince1970]; } break; } - case MA_FieldType_String: - if ([field tag] == MA_FieldID_Text) + case MA_FieldType_String: { + NSString * escapedText = [self escapeSpecialCharactersInSQLString:criteria.value]; + CriteriaOperator operator = criteria.operator; + if (operator == MA_CritOper_Is) + { + operatorString = @"='%@'"; + } + else if (operator == MA_CritOper_IsNot) + { + operatorString = @"!='%@'"; + } + + if (field.tag == MA_FieldID_Text) { // Special case for searching the text field. We always include the title field in the // search so the resulting SQL statement becomes: @@ -2205,23 +2131,29 @@ -(NSString *)criteriaToSQL:(CriteriaTree *)criteriaTree // where op is the appropriate operator. // Field * titleField = [self fieldByName:MA_Field_Subject]; - NSString * value = [NSString stringWithFormat:operatorString, [criteria value]]; - [sqlString appendFormat:@"(%@%@ or %@%@)", [field sqlField], value, [titleField sqlField], value]; - break; + NSString * logicalOperator = (operator == MA_CritOper_IsNot) ? @"and" : @"or"; + NSString * value = [NSString stringWithFormat:operatorString, escapedText]; + [sqlString appendFormat:@"(%@%@ %@ %@%@)", field.sqlField, value, logicalOperator, titleField.sqlField, value]; + } + else + { + valueString = [NSString stringWithFormat:@"%@", escapedText]; + } + break; } case MA_FieldType_Integer: - valueString = [NSString stringWithFormat:@"%@", [criteria value]]; + valueString = [NSString stringWithFormat:@"%@", criteria.value]; break; } if (valueString != nil) { - [sqlString appendString:[field sqlField]]; + [sqlString appendString:field.sqlField]; [sqlString appendFormat:operatorString, valueString]; } } - return [sqlString autorelease]; + return sqlString; } /* criteriaForFolder @@ -2234,84 +2166,76 @@ -(CriteriaTree *)criteriaForFolder:(NSInteger)folderId return nil; if (IsSearchFolder(folder)) - return [self searchStringToTree]; + return self.searchStringToTree; if (IsTrashFolder(folder)) { CriteriaTree * tree = [[CriteriaTree alloc] init]; Criteria * clause = [[Criteria alloc] initWithField:MA_Field_Deleted withOperator:MA_CritOper_Is withValue:@"Yes"]; [tree addCriteria:clause]; - [clause release]; - return [tree autorelease]; + return tree; } if (IsSmartFolder(folder)) { [self initSmartfoldersDict]; - return [smartfoldersDict objectForKey:[NSNumber numberWithInt:folderId]]; + return smartfoldersDict[@(folderId)]; } CriteriaTree * tree = [[CriteriaTree alloc] init]; - Criteria * clause = [[Criteria alloc] initWithField:MA_Field_Folder withOperator:MA_CritOper_Under withValue:[folder name]]; + Criteria * clause = [[Criteria alloc] initWithField:MA_Field_Folder withOperator:MA_CritOper_Under withValue:folder.name]; [tree addCriteria:clause]; - [clause release]; - return [tree autorelease]; + return tree; } /* arrayOfUnreadArticlesRefs * Retrieves an array of ArticleReference objects that represent all unread * articles in the specified folder. + * Note : when possible, you should use the interface provided by the Folder class instead of this */ -(NSArray *)arrayOfUnreadArticlesRefs:(NSInteger)folderId { Folder * folder = [self folderFromID:folderId]; - NSMutableArray * newArray = [NSMutableArray arrayWithCapacity:[folder unreadCount]]; if (folder != nil) { - if ([folder countOfCachedArticles] > 0) - { - // Messages already cached in this folder so use those. Note the use of - // reverseObjectEnumerator since the odds are that the unread articles are - // likely to be clustered with the most recent articles at the end of the - // array so it makes the code slightly faster. - NSInteger unreadCount = [folder unreadCount]; - NSEnumerator * enumerator = [[folder articles] reverseObjectEnumerator]; - Article * theRecord; - - while (unreadCount > 0 && (theRecord = [enumerator nextObject]) != nil) - if (![theRecord isRead]) - { - [newArray addObject:[ArticleReference makeReference:theRecord]]; - --unreadCount; - } - } - else - { - dispatch_sync(_execQueue, ^() { - FMResultSet * results = [sqlDatabase executeQueryWithFormat:@"select message_id from messages where folder_id=%ld and read_flag=0", (long)folderId]; - while ([results next]) - { - NSString * guid = [results stringForColumn:@"message_id"]; - [newArray addObject:[ArticleReference makeReferenceFromGUID:guid inFolder:folderId]]; - } - [results close]; - }); - } + NSMutableArray * newArray = [NSMutableArray arrayWithCapacity:folder.unreadCount]; + FMDatabaseQueue *queue = databaseQueue; + [queue inDatabase:^(FMDatabase *db) { + FMResultSet * results = [db executeQuery:@"select message_id from messages where folder_id=? and read_flag=0", @(folderId)]; + while ([results next]) + { + NSString * guid = [results stringForColumnIndex:0]; + [newArray addObject:[ArticleReference makeReferenceFromGUID:guid inFolder:folderId]]; + } + [results close]; + }]; + return [newArray copy]; } - return newArray; + else + return nil; +} + +/* escapeSpecialCharactersInSearchString: + * Escapes single quote characters for SQLite. + */ +-(NSString *)escapeSpecialCharactersInSQLString:(NSString *)string +{ + return [string stringByReplacingOccurrencesOfString:@"'" withString:@"''"]; } /* arrayOfArticles - * Retrieves an array containing all articles (except for text) for the + * Retrieves an array containing all articles (including text) for the * specified folder. If folderId is zero, all folders are searched. The * filterString option constrains the array to all those articles that * contain the specified filter. */ -(NSArray *)arrayOfArticles:(NSInteger)folderId filterString:(NSString *)filterString { + filterString = [self escapeSpecialCharactersInSQLString:filterString]; + NSMutableArray * newArray = [NSMutableArray array]; NSString * filterClause = @""; - NSString * queryString; + __weak NSString * queryString; Folder * folder = nil; __block NSInteger unread_count = 0; @@ -2322,74 +2246,75 @@ -(NSArray *)arrayOfArticles:(NSInteger)folderId filterString:(NSString *)filterS // database with or without a filter string. if (folderId == 0) { - if ([filterString isNotEqualTo:@""]) + if ([filterString isNotEqualTo:@""]) { filterClause = [NSString stringWithFormat:@" where text like '%%%@%%'", filterString]; + } queryString = [NSString stringWithFormat:@"%@%@", queryString, filterClause]; } else { folder = [self folderFromID:folderId]; - if (folder == nil) + if (folder == nil) { return nil; + } // Construct a criteria tree for this query CriteriaTree * tree = [self criteriaForFolder:folderId]; - if ([filterString isNotEqualTo:@""]) + if ([filterString isNotEqualTo:@""]) { filterClause = [NSString stringWithFormat:@" and (title like '%%%@%%' or text like '%%%@%%')", filterString, filterString]; + } queryString = [NSString stringWithFormat:@"%@ where (%@)%@", queryString, [self criteriaToSQL:tree], filterClause]; } // Time to run the query - @synchronized(self) { - [folder clearCache]; - FMResultSet * results = [sqlDatabase executeQuery:queryString]; + FMDatabaseQueue *queue = databaseQueue; + [queue inDatabase:^(FMDatabase *db) { + FMResultSet * results = [db executeQuery:queryString]; while ([results next]) { - Article * article = [[[Article alloc] initWithGuid:[results stringForColumnIndex:0]] autorelease]; - [article setFolderId:[[results stringForColumnIndex:1] intValue]]; - [article setParentId:[[results stringForColumnIndex:2] intValue]]; - [article markRead:[[results stringForColumnIndex:3] intValue]]; - [article markFlagged:[[results stringForColumnIndex:4] intValue]]; - [article markDeleted:[[results stringForColumnIndex:5] intValue]]; - [article setTitle:[results stringForColumnIndex:6]]; - [article setAuthor:[results stringForColumnIndex:7]]; - [article setLink:[results stringForColumnIndex:8]]; - [article setCreatedDate:[NSDate dateWithTimeIntervalSince1970:[[results stringForColumnIndex:9] doubleValue]]]; - [article setDate:[NSDate dateWithTimeIntervalSince1970:[[results stringForColumnIndex:10] doubleValue]]]; + Article * article = [[Article alloc] initWithGuid:[results stringForColumnIndex:0]]; + article.folderId = [results intForColumnIndex:1]; + article.parentId = [results intForColumnIndex:2]; + [article markRead:[results intForColumnIndex:3]]; + [article markFlagged:[results intForColumnIndex:4]]; + [article markDeleted:[results intForColumnIndex:5]]; + article.title = [results stringForColumnIndex:6]; + article.author = [results stringForColumnIndex:7]; + article.link = [results stringForColumnIndex:8]; + article.createdDate = [NSDate dateWithTimeIntervalSince1970:[results stringForColumnIndex:9].doubleValue]; + article.date = [NSDate dateWithTimeIntervalSince1970:[results stringForColumnIndex:10].doubleValue]; NSString * text = [results stringForColumnIndex:11]; - [article setBody:text]; - [article markRevised:[[results stringForColumnIndex:12] intValue]]; - [article setHasEnclosure:[[results stringForColumnIndex:13] intValue]]; - [article setEnclosure:[results stringForColumnIndex:14]]; + article.body = text; + [article markRevised:[results intForColumnIndex:12]]; + article.hasEnclosure = [results intForColumnIndex:13]; + article.enclosure = [results stringForColumnIndex:14]; - if (folder == nil || ![article isDeleted] || IsTrashFolder(folder)) + if (folder == nil || !article.deleted || IsTrashFolder(folder)) [newArray addObject:article]; - [folder addArticleToCache:article]; // Keep our own track of unread articles - if (![article isRead]) + if (!article.read) ++unread_count; } [results close]; - }; + }]; // This is a good time to do a quick check to ensure that our // own count of unread is in sync with the folders count and fix // them if not. if (folder && [filterString isEqualTo:@""] && (IsRSSFolder(folder) || IsGoogleReaderFolder(folder))) { - if (unread_count != [folder unreadCount]) + if (unread_count != folder.unreadCount) { - NSLog(@"Fixing unread count for %@ (%ld on folder versus %ld in articles)", [folder name], (long)[folder unreadCount], (long)unread_count); - NSInteger diff = (unread_count - [folder unreadCount]); + NSLog(@"Fixing unread count for %@ (%ld on folder versus %ld in articles)", folder.name, (long)folder.unreadCount, (long)unread_count); + NSInteger diff = (unread_count - folder.unreadCount); [self setFolderUnreadCount:folder adjustment:diff]; - countOfUnread += diff; } } - return newArray; + return [newArray copy]; } /* markFolderRead @@ -2404,34 +2329,31 @@ -(BOOL)markFolderRead:(NSInteger)folderId // Recurse and mark child folders read too for (folder in [self arrayOfFolders:folderId]) { - if ([self markFolderRead:[folder itemId]]) + if ([self markFolderRead:folder.itemId]) result = YES; } folder = [self folderFromID:folderId]; - if (folder != nil && [folder unreadCount] > 0) + if (folder != nil && folder.unreadCount > 0) { - NSInteger results = [self executeSQLWithFormat:@"update messages set read_flag=1 where folder_id=%ld and read_flag=0", (long)folderId]; - if (results == SQLITE_OK) + FMDatabaseQueue *queue = databaseQueue; + __block BOOL success; + [queue inDatabase:^(FMDatabase *db) { + success = [db executeUpdate:@"update messages set read_flag=1 where folder_id=? and read_flag=0", + @(folderId)]; + }]; + + if (success) { - NSInteger count = [folder unreadCount]; - if ([folder countOfCachedArticles] > 0) + if (folder.countOfCachedArticles > 0) { - NSEnumerator * enumerator = [[folder articles] objectEnumerator]; - NSInteger remainingUnread = count; - Article * article; - - while (remainingUnread > 0 && (article = [enumerator nextObject]) != nil) - if (![article isRead]) - { - [article markRead:YES]; - --remainingUnread; - } + // update the existing cache of articles and update the unread count + [folder markArticlesInCacheRead]; } - countOfUnread -= count; - [self setFolderUnreadCount:folder adjustment:-count]; + // set the unread count to 0 + [self setFolderUnreadCount:folder adjustment:-folder.unreadCount]; + result = YES; } - result = YES; } return result; } @@ -2444,22 +2366,21 @@ -(void)markArticleRead:(NSInteger)folderId guid:(NSString *)guid isRead:(BOOL)is Folder * folder = [self folderFromID:folderId]; if (folder != nil) { - // Prime the article cache - [self initArticleArray:folder]; - Article * article = [folder articleFromGuid:guid]; - if (article != nil && isRead != [article isRead]) + if (article != nil && isRead != article.read) { - NSString * preparedGuid = [Database prepareStringForQuery:guid]; - // Mark an individual article read - NSInteger results = [self executeSQLWithFormat:@"update messages set read_flag=%d where folder_id=%ld and message_id='%@'", isRead, (long)folderId, preparedGuid]; - if (results == SQLITE_OK) + FMDatabaseQueue *queue = databaseQueue; + __block BOOL success; + [queue inDatabase:^(FMDatabase *db) { + success = [db executeUpdate:@"update messages set read_flag=? where folder_id=? and message_id=?", + @(isRead), @(folderId), guid]; + }]; + if (success) { NSInteger adjustment = (isRead ? -1 : 1); [article markRead:isRead]; - countOfUnread += adjustment; [self setFolderUnreadCount:folder adjustment:adjustment]; } } @@ -2471,19 +2392,25 @@ -(void)markArticleRead:(NSInteger)folderId guid:(NSString *)guid isRead:(BOOL)is */ -(void)markUnreadArticlesFromFolder:(Folder *)folder guidArray:(NSArray *)guidArray { - NSInteger folderId = [folder itemId]; - if([guidArray count]>0) + FMDatabaseQueue *queue = databaseQueue; + NSInteger folderId = folder.itemId; + if(guidArray.count>0) { NSString * guidList = [guidArray componentsJoinedByString:@"','"]; - [self executeSQLWithFormat:@"update messages set read_flag=1 where folder_id=%ld and read_flag=0 and message_id NOT IN ('%@')", (long)folderId, guidList]; - [self executeSQLWithFormat:@"update messages set read_flag=0 where folder_id=%ld and read_flag=1 and message_id IN ('%@')", (long)folderId, guidList]; + [queue inTransaction:^(FMDatabase *db, BOOL *rollback) { + NSString * statement1 = [NSString stringWithFormat:@"update messages set read_flag=1 where folder_id=%ld and read_flag=0 and message_id NOT IN ('%@')", (long)folderId, guidList]; + [db executeUpdate:statement1]; + NSString * statement2 = [NSString stringWithFormat:@"update messages set read_flag=0 where folder_id=%ld and read_flag=1 and message_id IN ('%@')", (long)folderId, guidList]; + [db executeUpdate:statement2]; + }]; } else { - [self executeSQLWithFormat:@"update messages set read_flag=1 where folder_id=%ld and read_flag=0", (long)folderId]; + [queue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"update messages set read_flag=1 where folder_id=? and read_flag=0", @(folderId)]; + }]; } - NSInteger adjustment = [guidArray count]-[folder unreadCount]; - countOfUnread += adjustment; + NSInteger adjustment = guidArray.count-folder.unreadCount; [self setFolderUnreadCount:folder adjustment:adjustment]; } @@ -2492,16 +2419,23 @@ -(void)markUnreadArticlesFromFolder:(Folder *)folder guidArray:(NSArray *)guidAr */ -(void)markStarredArticlesFromFolder:(Folder *)folder guidArray:(NSArray *)guidArray { - NSInteger folderId = [folder itemId]; - if([guidArray count]>0) + FMDatabaseQueue *queue = databaseQueue; + NSInteger folderId = folder.itemId; + if(guidArray.count>0) { NSString * guidList = [guidArray componentsJoinedByString:@"','"]; - [self executeSQLWithFormat:@"update messages set marked_flag=1 where folder_id=%ld and marked_flag=0 and message_id IN ('%@')", (long)folderId, guidList]; - [self executeSQLWithFormat:@"update messages set marked_flag=0 where folder_id=%ld and marked_flag=1 and message_id NOT IN ('%@')", (long)folderId, guidList]; + [queue inTransaction:^(FMDatabase *db, BOOL *rollback) { + NSString * statement1 = [NSString stringWithFormat:@"update messages set marked_flag=1 where folder_id=%ld and marked_flag=0 and message_id IN ('%@')", (long)folderId, guidList]; + [db executeUpdate:statement1]; + NSString * statement2 = [NSString stringWithFormat:@"update messages set marked_flag=0 where folder_id=%ld and marked_flag=1 and message_id NOT IN ('%@')", (long)folderId, guidList]; + [db executeUpdate:statement2]; + }]; } else { - [self executeSQLWithFormat:@"update messages set marked_flag=0 where folder_id=%ld and marked_flag=1", (long)folderId]; + [queue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"update messages set marked_flag=0 where folder_id=? and marked_flag=1", @(folderId)]; + }]; } } @@ -2511,20 +2445,22 @@ -(void)markStarredArticlesFromFolder:(Folder *)folder guidArray:(NSArray *)guidA */ -(void)setFolderUnreadCount:(Folder *)folder adjustment:(NSUInteger)adjustment { - dispatch_sync(_execQueue, ^() { - NSInteger newCount = [folder unreadCount] + adjustment; - [folder setUnreadCount:newCount]; - [sqlDatabase executeUpdate:[NSString stringWithFormat:@"update folders set unread_count=%ld where folder_id=%ld", newCount, [folder itemId]]]; - - // Update childUnreadCount for our parent. Since we're just working - // on one article, we do this the faster way. - Folder * tmpFolder = folder; - while ([tmpFolder parentId] != MA_Root_Folder) - { - tmpFolder = [self folderFromID:[tmpFolder parentId]]; - [tmpFolder setChildUnreadCount:[tmpFolder childUnreadCount] + adjustment]; - } - }); + countOfUnread += adjustment; + NSInteger newCount = folder.unreadCount + adjustment; + folder.unreadCount = newCount; + FMDatabaseQueue *queue = databaseQueue; + [queue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"UPDATE folders set unread_count=? where folder_id=?", @(newCount), @(folder.itemId)]; + }]; + + // Update childUnreadCount for our parent. Since we're just working + // on one article, we do this the faster way. + Folder * tmpFolder = folder; + while (tmpFolder.parentId != MA_Root_Folder) + { + tmpFolder = [self folderFromID:tmpFolder.parentId]; + tmpFolder.childUnreadCount = tmpFolder.childUnreadCount + adjustment; + } } /* markArticleFlagged @@ -2535,39 +2471,62 @@ -(void)markArticleFlagged:(NSInteger)folderId guid:(NSString *)guid isFlagged:(B Folder * folder = [self folderFromID:folderId]; if (folder != nil) { - // Prime the article cache - [self initArticleArray:folder]; - Article * article = [folder articleFromGuid:guid]; - if (article != nil && isFlagged != [article isFlagged]) + if (article != nil && isFlagged != article.flagged) { - NSString * preparedGuid = [Database prepareStringForQuery:guid]; - - // Mark an individual article flagged - NSInteger results = [self executeSQLWithFormat:@"update messages set marked_flag=%d where folder_id=%ld and message_id='%@'", isFlagged, (long)folderId, preparedGuid]; - if (results == SQLITE_OK) + FMDatabaseQueue *queue = databaseQueue; + __block BOOL success; + [queue inDatabase:^(FMDatabase *db) { + success = [db executeUpdate:@"update messages set marked_flag=? where folder_id=? and message_id=?", + @(isFlagged), + @(folderId), + guid]; + }]; + + if (success) { - - [article markFlagged:isFlagged]; + // Mark an individual article flagged + [article markFlagged:isFlagged]; } } } } /* markArticleDeleted - * Marks a article as deleted. Deleted articles always get marked read first. + * Marks an article as deleted. Deleted articles should have been marked read first. */ --(void)markArticleDeleted:(NSInteger)folderId guid:(NSString *)guid isDeleted:(BOOL)isDeleted +-(void)markArticleDeleted:(Article *)article isDeleted:(BOOL)isDeleted { + NSInteger folderId = article.folderId; + NSString * guid = article.guid; Folder * folder = [self folderFromID:folderId]; if (folder !=nil) { - // Prime the article cache - [self initArticleArray:folder]; - Article * article = [folder articleFromGuid:guid]; - if (isDeleted && ![article isRead]) + FMDatabaseQueue *queue = databaseQueue; + if (isDeleted && !article.read) { [self markArticleRead:folderId guid:guid isRead:YES]; - NSString * preparedGuid = [Database prepareStringForQuery:guid]; - [self executeSQLWithFormat:@"update messages set deleted_flag=%d where folder_id=%ld and message_id='%@'", isDeleted, (long)folderId, preparedGuid]; + } + [queue inDatabase:^(FMDatabase *db) { + [db executeUpdate:@"update messages set deleted_flag=? where folder_id=? and message_id=?", + @(isDeleted), + @(folderId), + guid]; + }]; + if (isDeleted && !article.deleted) { + [article markDeleted:YES]; + if ([folder countOfCachedArticles] > 0) + { + // If we're in a smart folder, the cached article may be different. + Article * cachedArticle = [folder articleFromGuid:guid]; + [cachedArticle markDeleted:YES]; + [folder removeArticleFromCache:guid]; + } + } + else if (!isDeleted) { + // if we undelete, allow the RSS or OpenReader folder + // to get the restored article + [folder restoreArticleToCache:article]; + [article markDeleted:NO]; + } } } @@ -2577,16 +2536,18 @@ -(void)markArticleDeleted:(NSInteger)folderId guid:(NSString *)guid isDeleted:(B -(BOOL)isTrashEmpty { __block BOOL result; - dispatch_sync(_execQueue, ^() { - FMResultSet * results = [sqlDatabase executeQuery:@"select deleted_flag from messages where deleted_flag=1"]; - if ([results next]) - { - result= NO; - } - else - result=YES; - [results close]; - }); + FMDatabaseQueue *queue = databaseQueue; + [queue inDatabase:^(FMDatabase *db) { + FMResultSet * results = [db executeQuery:@"select deleted_flag from messages where deleted_flag=1"]; + if ([results next]) + { + result= NO; + } + else + result=YES; + [results close]; + }]; + return result; } @@ -2596,9 +2557,9 @@ -(BOOL)isTrashEmpty -(NSArray *)guidHistoryForFolderId:(NSInteger)folderId { NSMutableArray * articleGuids = [NSMutableArray array]; - - dispatch_sync(_execQueue, ^() { - FMResultSet * results = [sqlDatabase executeQueryWithFormat:@"select message_id from rss_guids where folder_id=%ld", (long)folderId]; + FMDatabaseQueue *queue = databaseQueue; + [queue inDatabase:^(FMDatabase *db) { + FMResultSet * results = [db executeQuery:@"select message_id from rss_guids where folder_id=?", @(folderId)]; while ([results next]) { NSString * guid = [results stringForColumn:@"message_id"]; @@ -2608,11 +2569,39 @@ -(NSArray *)guidHistoryForFolderId:(NSInteger)folderId } } [results close]; - }); + }]; - return articleGuids; + return [articleGuids copy]; +} + +/*! + * Get the path to the database file + * + * @return A string representation of the database file's path + */ ++ (NSString *)databasePath { + // Fully expand the path and make sure it exists because if the + // database file itself doesn't exist, we want to create it and + // we can't create it on a non-existent path. + NSFileManager * fileManager = [NSFileManager defaultManager]; + NSString * qualifiedDatabaseFileName = [[Preferences standardPreferences] defaultDatabase].stringByExpandingTildeInPath; + NSString * databaseFolder = qualifiedDatabaseFileName.stringByDeletingLastPathComponent; + BOOL isDir; + + + if (![fileManager fileExistsAtPath:databaseFolder isDirectory:&isDir]) + { + NSError *error; + if (![fileManager createDirectoryAtPath:databaseFolder withIntermediateDirectories:YES attributes:NULL error:&error]) + { + NSLog(@"Cannot create database folder: %@", error); + } + } + + return qualifiedDatabaseFileName; } + /* close * Close the database. All internal resources are released and a new, * possibly different, database can be opened instead. @@ -2622,15 +2611,12 @@ -(void)close [[NSNotificationCenter defaultCenter] removeObserver:self]; [foldersDict removeAllObjects]; [smartfoldersDict removeAllObjects]; - [fieldsOrdered release]; - [fieldsByName release]; [self setTrashFolder:nil]; [self setSearchFolder:nil]; - [sqlDatabase close]; initializedfoldersDict = NO; initializedSmartfoldersDict = NO; countOfUnread = 0; - sqlDatabase = nil; + [self.databaseQueue close]; } /* dealloc @@ -2638,22 +2624,6 @@ -(void)close */ -(void)dealloc { - [trashFolder release]; - trashFolder=nil; - [searchFolder release]; - searchFolder=nil; - [searchString release]; - searchString=nil; - [foldersDict release]; - foldersDict=nil; - [smartfoldersDict release]; - smartfoldersDict=nil; - dispatch_release(_execQueue); - dispatch_release(_transactionQueue); - if (sqlDatabase) - [self close]; - [sqlDatabase release]; - sqlDatabase=nil; - [super dealloc]; + [self close]; } @end diff --git a/src/DownloadManager.h b/src/DownloadManager.h index bbd47c0b29..0e5fbe60bf 100644 --- a/src/DownloadManager.h +++ b/src/DownloadManager.h @@ -31,7 +31,7 @@ @interface DownloadItem : NSObject { long long expectedSize; long long fileSize; - int state; + NSInteger state; NSImage * image; NSString * filename; NSURLDownload * download; @@ -39,32 +39,26 @@ } // Public functions --(void)setState:(int)newState; --(void)setSize:(long long)newSize; --(void)setExpectedSize:(long long)newExpectedSize; --(void)setDownload:(NSURLDownload *)theDownload; --(void)setFilename:(NSString *)theFilename; --(void)setStartTime:(NSDate *)newStartTime; --(int)state; --(long long)expectedSize; --(long long)size; --(NSURLDownload *)download; --(NSString *)filename; --(NSImage *)image; --(NSDate *)startTime; +@property (nonatomic) NSInteger state; +@property (nonatomic) long long expectedSize; +@property (nonatomic) long long size; +@property (nonatomic, strong) NSURLDownload *download; +@property (nonatomic, copy) NSString *filename; +@property (nonatomic, readonly, copy) NSImage *image; +@property (nonatomic, copy) NSDate *startTime; @end @interface DownloadManager : NSObject { NSMutableArray * downloadsList; - int activeDownloads; + NSInteger activeDownloads; } // Public functions +(DownloadManager *)sharedInstance; +(BOOL)isFileDownloaded:(NSString *)filename; +(NSString *)fullDownloadPath:(NSString *)filename; --(NSArray *)downloadsList; --(int)activeDownloads; +@property (nonatomic, readonly, copy) NSArray *downloadsList; +@property (nonatomic, readonly) NSInteger activeDownloads; -(void)clearList; -(void)cancelItem:(DownloadItem *)item; -(void)removeItem:(DownloadItem *)item; diff --git a/src/DownloadManager.m b/src/DownloadManager.m index fa06117c08..272c19716b 100644 --- a/src/DownloadManager.m +++ b/src/DownloadManager.m @@ -23,10 +23,6 @@ #import "Constants.h" #import "Preferences.h" -// There's just one database and we manage access to it through a -// singleton object. -static DownloadManager * _sharedDownloadManager = nil; - // Private functions @interface DownloadManager (Private) -(void)archiveDownloadsList; @@ -39,7 +35,7 @@ @implementation DownloadItem /* init * Initialise a new DownloadItem object */ --(id)init +-(instancetype)init { if ((self = [super init]) != nil) { @@ -58,11 +54,11 @@ -(id)init * Initalises a decoded object. All decoded objects are assumed to be * completed downloads. */ --(id)initWithCoder:(NSCoder *)coder +-(instancetype)initWithCoder:(NSCoder *)coder { if ((self = [super init]) != nil) { - [self setFilename:[coder decodeObject]]; + self.filename = [coder decodeObject]; [coder decodeValueOfObjCType:@encode(long long) at:&fileSize]; state = DOWNLOAD_COMPLETED; } @@ -81,7 +77,7 @@ -(void)encodeWithCoder:(NSCoder *)coder /* setState * Sets the download state. */ --(void)setState:(int)newState +-(void)setState:(NSInteger)newState { state = newState; } @@ -89,7 +85,7 @@ -(void)setState:(int)newState /* state * Returns the download state. */ --(int)state +-(NSInteger)state { return state; } @@ -132,8 +128,6 @@ -(long long)size */ -(void)setDownload:(NSURLDownload *)theDownload { - [theDownload retain]; - [download release]; download = theDownload; } @@ -151,12 +145,9 @@ -(NSURLDownload *)download */ -(void)setFilename:(NSString *)theFilename { - [filename release]; - [theFilename retain]; filename = theFilename; // Force the image to be recached. - [image release]; image = nil; } @@ -175,13 +166,12 @@ -(NSImage *)image { if (image == nil) { - image = [[NSWorkspace sharedWorkspace] iconForFileType:[[self filename] pathExtension]]; - if (![image isValid]) + image = [[NSWorkspace sharedWorkspace] iconForFileType:self.filename.pathExtension]; + if (!image.valid) image = nil; else { - [image retain]; - [image setSize:NSMakeSize(32, 32)]; + image.size = NSMakeSize(32, 32); } } return image; @@ -192,8 +182,6 @@ -(NSImage *)image */ -(void)setStartTime:(NSDate *)newStartTime { - [newStartTime retain]; - [startTime release]; startTime = newStartTime; } @@ -205,19 +193,6 @@ -(NSDate *)startTime return startTime; } -/* dealloc - * Clean up behind ourself. - */ --(void)dealloc -{ - [filename release]; - filename=nil; - [download release]; - download=nil; - [image release]; - image=nil; - [super dealloc]; -} @end @implementation DownloadManager @@ -228,18 +203,20 @@ @implementation DownloadManager */ +(DownloadManager *)sharedInstance { - if (_sharedDownloadManager == nil) - { + // Singleton + static DownloadManager * _sharedDownloadManager = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ _sharedDownloadManager = [[DownloadManager alloc] init]; [_sharedDownloadManager unarchiveDownloadsList]; - } + }); return _sharedDownloadManager; } /* init * Initialise the DownloadManager object. */ --(id)init +-(instancetype)init { if ((self = [super init]) != nil) { @@ -254,13 +231,13 @@ -(id)init */ -(NSArray *)downloadsList { - return downloadsList; + return [downloadsList copy]; } /* activeDownloads * Return the number of downloads in progress. */ --(int)activeDownloads +-(NSInteger)activeDownloads { return activeDownloads; } @@ -270,11 +247,11 @@ -(int)activeDownloads */ -(void)clearList { - int index = [downloadsList count] - 1; + NSInteger index = downloadsList.count - 1; while (index >= 0) { - DownloadItem * item = [downloadsList objectAtIndex:index--]; - if ([item state] != DOWNLOAD_STARTED) + DownloadItem * item = downloadsList[index--]; + if (item.state != DOWNLOAD_STARTED) [downloadsList removeObject:item]; } [self notifyDownloadItemChange:nil]; @@ -286,13 +263,12 @@ -(void)clearList */ -(void)archiveDownloadsList { - NSMutableArray * listArray = [[NSMutableArray alloc] initWithCapacity:[downloadsList count]]; + NSMutableArray * listArray = [[NSMutableArray alloc] initWithCapacity:downloadsList.count]; for (DownloadItem * item in downloadsList) [listArray addObject:[NSArchiver archivedDataWithRootObject:item]]; [[Preferences standardPreferences] setArray:listArray forKey:MAPref_DownloadsList]; - [listArray release]; } /* unarchiveDownloadsList @@ -322,7 +298,7 @@ -(void)removeItem:(DownloadItem *)item */ -(void)cancelItem:(DownloadItem *)item { - [[item download] cancel]; + [item.download cancel]; [item setState:DOWNLOAD_CANCELLED]; NSAssert(activeDownloads > 0, @"cancelItem called with zero activeDownloads count!"); --activeDownloads; @@ -336,22 +312,21 @@ -(void)cancelItem:(DownloadItem *)item */ -(void)downloadFileFromURL:(NSString *)url { - NSString * filename = [[NSURL URLWithString:url] lastPathComponent]; + NSString * filename = [NSURL URLWithString:url].lastPathComponent; NSString * destPath = [DownloadManager fullDownloadPath:filename]; NSURLRequest * theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; NSURLDownload * theDownload = [[NSURLDownload alloc] initWithRequest:theRequest delegate:(id)self]; if (theDownload) { - DownloadItem * newItem = [[DownloadItem new] autorelease]; + DownloadItem * newItem = [DownloadItem new]; [newItem setState:DOWNLOAD_INIT]; - [newItem setDownload:theDownload]; - [newItem setFilename:filename]; + newItem.download = theDownload; + newItem.filename = destPath; [downloadsList addObject:newItem]; // The following line will stop us getting decideDestinationWithSuggestedFilename. [theDownload setDestination:destPath allowOverwrite:YES]; - [theDownload release]; } } @@ -362,11 +337,11 @@ -(void)downloadFileFromURL:(NSString *)url */ -(DownloadItem *)itemForDownload:(NSURLDownload *)download { - int index = [downloadsList count] - 1; + NSInteger index = downloadsList.count - 1; while (index >= 0) { - DownloadItem * item = [downloadsList objectAtIndex:index--]; - if ([item download] == download) + DownloadItem * item = downloadsList[index--]; + if (item.download == download) return item; } return nil; @@ -379,15 +354,14 @@ -(DownloadItem *)itemForDownload:(NSURLDownload *)download */ +(NSString *)fullDownloadPath:(NSString *)filename { - NSString * downloadPath = [[Preferences standardPreferences] downloadFolder]; - NSString * decodedFilename = [filename stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + NSString * downloadPath = [Preferences standardPreferences].downloadFolder; NSFileManager * fileManager = [NSFileManager defaultManager]; BOOL isDir = YES; if (![fileManager fileExistsAtPath:downloadPath isDirectory:&isDir] || !isDir) downloadPath = @"~/Desktop"; - return [[downloadPath stringByExpandingTildeInPath] stringByAppendingPathComponent:decodedFilename]; + return [downloadPath.stringByExpandingTildeInPath stringByAppendingPathComponent:filename]; } /* isFileDownloaded @@ -396,21 +370,20 @@ +(NSString *)fullDownloadPath:(NSString *)filename */ +(BOOL)isFileDownloaded:(NSString *)filename { - NSString * decodedFilename = [filename stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; DownloadManager * downloadManager = [DownloadManager sharedInstance]; - int count = [[downloadManager downloadsList] count]; - int index; + NSInteger count = downloadManager.downloadsList.count; + NSInteger index; - NSString * firstFile = [decodedFilename stringByStandardizingPath]; + NSString * firstFile = filename.stringByStandardizingPath; for (index = 0; index < count; ++index) { - DownloadItem * item = [[downloadManager downloadsList] objectAtIndex:index]; - NSString * secondFile = [decodedFilename stringByStandardizingPath]; + DownloadItem * item = downloadManager.downloadsList[index]; + NSString * secondFile = filename.stringByStandardizingPath; if ([firstFile compare:secondFile options:NSCaseInsensitiveSearch] == NSOrderedSame) { - if ([item state] != DOWNLOAD_COMPLETED) + if (item.state != DOWNLOAD_COMPLETED) return NO; // File completed download but possibly moved or deleted after download @@ -438,20 +411,20 @@ -(void)downloadDidBegin:(NSURLDownload *)download DownloadItem * theItem = [self itemForDownload:download]; if (theItem == nil) { - theItem = [[[DownloadItem alloc] init] autorelease]; - [theItem setDownload:download]; + theItem = [[DownloadItem alloc] init]; + theItem.download = download; [downloadsList addObject:theItem]; } [theItem setState:DOWNLOAD_STARTED]; - if ([theItem filename] == nil) - [theItem setFilename:[[[download request] URL] path]]; + if (theItem.filename == nil) + theItem.filename = download.request.URL.path; // Keep count of active downloads ++activeDownloads; // Record the time we started. We'll need this to work out the remaining // time and the number of KBytes/second we're getting - [theItem setStartTime:[NSDate date]]; + theItem.startTime = [NSDate date]; [self notifyDownloadItemChange:theItem]; // If there's no download window visible, display one now. @@ -470,13 +443,13 @@ -(void)downloadDidFinish:(NSURLDownload *)download [self notifyDownloadItemChange:theItem]; [self archiveDownloadsList]; - NSString * filename = [[theItem filename] lastPathComponent]; + NSString * filename = theItem.filename.lastPathComponent; if (filename == nil) - filename = [theItem filename]; + filename = theItem.filename; NSMutableDictionary * contextDict = [[NSMutableDictionary alloc] init]; - [contextDict setValue:[NSNumber numberWithInt:MA_GrowlContext_DownloadCompleted] forKey:@"ContextType"]; - [contextDict setValue:[theItem filename] forKey:@"ContextData"]; + [contextDict setValue:@MA_GrowlContext_DownloadCompleted forKey:@"ContextType"]; + [contextDict setValue:theItem.filename forKey:@"ContextData"]; [APPCONTROLLER growlNotify:contextDict title:NSLocalizedString(@"Download completed", nil) @@ -486,7 +459,6 @@ -(void)downloadDidFinish:(NSURLDownload *)download // Post a notification when the download completes. [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_DownloadCompleted" object:filename]; - [contextDict autorelease]; } /* didFailWithError @@ -501,20 +473,19 @@ -(void)download:(NSURLDownload *)download didFailWithError:(NSError *)error [self notifyDownloadItemChange:theItem]; [self archiveDownloadsList]; - NSString * filename = [[theItem filename] lastPathComponent]; + NSString * filename = theItem.filename.lastPathComponent; if (filename == nil) - filename = [theItem filename]; + filename = theItem.filename; NSMutableDictionary * contextDict = [[NSMutableDictionary alloc] init]; - [contextDict setValue:[NSNumber numberWithInt:MA_GrowlContext_DownloadFailed] forKey:@"ContextType"]; - [contextDict setValue:[theItem filename] forKey:@"ContextData"]; + [contextDict setValue:@MA_GrowlContext_DownloadFailed forKey:@"ContextType"]; + [contextDict setValue:theItem.filename forKey:@"ContextData"]; [APPCONTROLLER growlNotify:contextDict title:NSLocalizedString(@"Download failed", nil) description:[NSString stringWithFormat:NSLocalizedString(@"File %@ failed to download", nil), filename] notificationName:NSLocalizedString(@"Growl download failed", nil)]; - [contextDict autorelease]; } /* didReceiveDataOfLength @@ -523,7 +494,7 @@ -(void)download:(NSURLDownload *)download didFailWithError:(NSError *)error -(void)download:(NSURLDownload *)download didReceiveDataOfLength:(NSUInteger)length { DownloadItem * theItem = [self itemForDownload:download]; - [theItem setSize:[theItem size] + length]; + theItem.size = theItem.size + length; // TODO: How many bytes are we getting each second? @@ -539,7 +510,7 @@ -(void)download:(NSURLDownload *)download didReceiveDataOfLength:(NSUInteger)len -(void)download:(NSURLDownload *)download didReceiveResponse:(NSURLResponse *)response { DownloadItem * theItem = [self itemForDownload:download]; - [theItem setExpectedSize:[response expectedContentLength]]; + theItem.expectedSize = response.expectedContentLength; [self notifyDownloadItemChange:theItem]; } @@ -549,7 +520,7 @@ -(void)download:(NSURLDownload *)download didReceiveResponse:(NSURLResponse *)re -(void)download:(NSURLDownload *)download willResumeWithResponse:(NSURLResponse *)response fromByte:(long long)startingByte { DownloadItem * theItem = [self itemForDownload:download]; - [theItem setSize:startingByte]; + theItem.size = startingByte; [self notifyDownloadItemChange:theItem]; } @@ -579,21 +550,12 @@ -(void)download:(NSURLDownload *)download decideDestinationWithSuggestedFilename // Hack for certain compression types that are converted to .txt extension when // downloaded. SITX is the only one I know about. DownloadItem * theItem = [self itemForDownload:download]; - if ([[[theItem filename] pathExtension] isEqualToString:@"sitx"] && [[filename pathExtension] isEqualToString:@"txt"]) - destPath = [destPath stringByDeletingPathExtension]; + if ([theItem.filename.pathExtension isEqualToString:@"sitx"] && [filename.pathExtension isEqualToString:@"txt"]) + destPath = destPath.stringByDeletingPathExtension; // Save the filename [download setDestination:destPath allowOverwrite:NO]; - [theItem setFilename:destPath]; + theItem.filename = destPath; } -/* dealloc - * Clean up at the end. - */ --(void)dealloc -{ - [downloadsList release]; - downloadsList=nil; - [super dealloc]; -} @end diff --git a/src/DownloadWindow.h b/src/DownloadWindow.h index b1337e4945..e7c6dbf8b2 100644 --- a/src/DownloadWindow.h +++ b/src/DownloadWindow.h @@ -19,14 +19,13 @@ // #import -#import "SquareWindow.h" #import "TableViewExtensions.h" @interface DownloadWindow : NSWindowController { - IBOutlet SquareWindow * downloadWindow; + IBOutlet NSWindow * downloadWindow; IBOutlet ExtendedTableView * table; IBOutlet NSButton * clearButton; - int lastCount; + NSInteger lastCount; } // Public functions diff --git a/src/DownloadWindow.m b/src/DownloadWindow.m index 4f281580d3..580c573fb7 100644 --- a/src/DownloadWindow.m +++ b/src/DownloadWindow.m @@ -28,7 +28,7 @@ @implementation DownloadWindow /* init * Just init the download window. */ --(id)init +-(instancetype)init { if ((self = [super initWithWindowNibName:@"Downloads"]) != nil) { @@ -44,8 +44,8 @@ -(void)windowDidLoad { // Work around a Cocoa bug where the window positions aren't saved [self setShouldCascadeWindows:NO]; - [self setWindowFrameAutosaveName:@"downloadWindow"]; - [downloadWindow setDelegate:self]; + self.windowFrameAutosaveName = @"downloadWindow"; + downloadWindow.delegate = self; // Register to get notified when the download manager's list changes NSNotificationCenter * nc = [NSNotificationCenter defaultCenter]; @@ -54,16 +54,16 @@ -(void)windowDidLoad // Set the cell for each row ImageAndTextCell * imageAndTextCell; NSTableColumn * tableColumn = [table tableColumnWithIdentifier:@"listColumn"]; - imageAndTextCell = [[[ImageAndTextCell alloc] init] autorelease]; - [imageAndTextCell setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; - [imageAndTextCell setTextColor:[NSColor darkGrayColor]]; - [tableColumn setDataCell:imageAndTextCell]; + imageAndTextCell = [[ImageAndTextCell alloc] init]; + imageAndTextCell.font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]; + imageAndTextCell.textColor = [NSColor darkGrayColor]; + tableColumn.dataCell = imageAndTextCell; // We are the delegate and the datasource [table setDelegate:self]; [table setDataSource:self]; - [table setDoubleAction:@selector(handleDoubleClick:)]; - [table setTarget:self]; + table.doubleAction = @selector(handleDoubleClick:); + table.target = self; // Create the popup menu NSMenu * downloadMenu = [[NSMenu alloc] init]; @@ -71,8 +71,7 @@ -(void)windowDidLoad [downloadMenu addItemWithTitle:NSLocalizedString(@"Show in Finder", nil) action:@selector(showInFinder:) keyEquivalent:@""]; [downloadMenu addItemWithTitle:NSLocalizedString(@"Remove From List", nil) action:@selector(removeFromList:) keyEquivalent:@""]; [downloadMenu addItemWithTitle:NSLocalizedString(@"Cancel", nil) action:@selector(cancelDownload:) keyEquivalent:@""]; - [table setMenu:downloadMenu]; - [downloadMenu release]; + table.menu = downloadMenu; // Set Clear button caption [clearButton setTitle:NSLocalizedString(@"ClearButton", nil)]; @@ -95,12 +94,12 @@ -(IBAction)clearList:(id)sender */ -(void)tableView:(ExtendedTableView *)tableView menuWillAppear:(NSEvent *)theEvent { - int row = [table rowAtPoint:[table convertPoint:[theEvent locationInWindow] fromView:nil]]; + NSInteger row = [table rowAtPoint:[table convertPoint:theEvent.locationInWindow fromView:nil]]; if (row >= 0) { // Select the row under the cursor if it isn't already selected - if ([table numberOfSelectedRows] <= 1) - [table selectRowIndexes:[NSIndexSet indexSetWithIndex:(NSUInteger )row] byExtendingSelection:NO]; + if (table.numberOfSelectedRows <= 1) + [table selectRowIndexes:[NSIndexSet indexSetWithIndex:(NSUInteger)row] byExtendingSelection:NO]; } } @@ -110,15 +109,15 @@ -(void)tableView:(ExtendedTableView *)tableView menuWillAppear:(NSEvent *)theEve */ -(void)handleDoubleClick:(id)sender { - NSArray * list = [[DownloadManager sharedInstance] downloadsList]; - int index = [table selectedRow]; + NSArray * list = [DownloadManager sharedInstance].downloadsList; + NSInteger index = table.selectedRow; if (index != -1) { - DownloadItem * item = [list objectAtIndex:index]; - if (item && [item state] == DOWNLOAD_COMPLETED) + DownloadItem * item = list[index]; + if (item && item.state == DOWNLOAD_COMPLETED) { - if ([[NSWorkspace sharedWorkspace] openFile:[DownloadManager fullDownloadPath:[item filename]]] == NO) - runOKAlertSheet(NSLocalizedString(@"Vienna cannot open the file title", nil), NSLocalizedString(@"Vienna cannot open the file body", nil), [[item filename] lastPathComponent]); + if ([[NSWorkspace sharedWorkspace] openFile:item.filename] == NO) + runOKAlertSheet(NSLocalizedString(@"Vienna cannot open the file title", nil), NSLocalizedString(@"Vienna cannot open the file body", nil), item.filename.lastPathComponent); } } } @@ -128,15 +127,15 @@ -(void)handleDoubleClick:(id)sender */ -(void)showInFinder:(id)sender { - NSArray * list = [[DownloadManager sharedInstance] downloadsList]; - int index = [table selectedRow]; + NSArray * list = [DownloadManager sharedInstance].downloadsList; + NSInteger index = table.selectedRow; if (index != -1) { - DownloadItem * item = [list objectAtIndex:index]; - if (item && [item state] == DOWNLOAD_COMPLETED) + DownloadItem * item = list[index]; + if (item && item.state == DOWNLOAD_COMPLETED) { - if ([[NSWorkspace sharedWorkspace] selectFile:[DownloadManager fullDownloadPath:[item filename]] inFileViewerRootedAtPath:@""] == NO) - runOKAlertSheet(NSLocalizedString(@"Vienna cannot show the file title", nil), NSLocalizedString(@"Vienna cannot show the file body", nil), [[item filename] lastPathComponent]); + if ([[NSWorkspace sharedWorkspace] selectFile:item.filename inFileViewerRootedAtPath:@""] == NO) + runOKAlertSheet(NSLocalizedString(@"Vienna cannot show the file title", nil), NSLocalizedString(@"Vienna cannot show the file body", nil), item.filename.lastPathComponent); } } } @@ -146,11 +145,11 @@ -(void)showInFinder:(id)sender */ -(void)removeFromList:(id)sender { - NSArray * list = [[DownloadManager sharedInstance] downloadsList]; - int index = [table selectedRow]; + NSArray * list = [DownloadManager sharedInstance].downloadsList; + NSInteger index = table.selectedRow; if (index != -1) { - DownloadItem * item = [list objectAtIndex:index]; + DownloadItem * item = list[index]; [[DownloadManager sharedInstance] removeItem:item]; [table reloadData]; } @@ -161,11 +160,11 @@ -(void)removeFromList:(id)sender */ -(void)cancelDownload:(id)sender { - NSArray * list = [[DownloadManager sharedInstance] downloadsList]; - int index = [table selectedRow]; + NSArray * list = [DownloadManager sharedInstance].downloadsList; + NSInteger index = table.selectedRow; if (index != -1) { - DownloadItem * item = [list objectAtIndex:index]; + DownloadItem * item = list[index]; [[DownloadManager sharedInstance] cancelItem:item]; [table reloadData]; } @@ -177,8 +176,8 @@ -(void)cancelDownload:(id)sender */ -(NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView { - NSInteger itemCount = [[[DownloadManager sharedInstance] downloadsList] count]; - [clearButton setEnabled:itemCount > 0]; + NSInteger itemCount = [DownloadManager sharedInstance].downloadsList.count; + clearButton.enabled = itemCount > 0; return itemCount; } @@ -189,12 +188,12 @@ -(void)tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableCol { if ([aCell isKindOfClass:[ImageAndTextCell class]]) { - NSArray * list = [[DownloadManager sharedInstance] downloadsList]; - DownloadItem * item = [list objectAtIndex:rowIndex]; + NSArray * list = [DownloadManager sharedInstance].downloadsList; + DownloadItem * item = list[rowIndex]; - if ([item image] != nil) - [aCell setImage:[item image]]; - [aCell setTextColor:(rowIndex == [aTableView selectedRow]) ? [NSColor whiteColor] : [NSColor darkGrayColor]]; + if (item.image != nil) + [aCell setImage:item.image]; + [aCell setTextColor:(rowIndex == aTableView.selectedRow) ? [NSColor whiteColor] : [NSColor darkGrayColor]]; } } @@ -203,20 +202,20 @@ -(void)tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableCol */ -(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex { - NSArray * list = [[DownloadManager sharedInstance] downloadsList]; + NSArray * list = [DownloadManager sharedInstance].downloadsList; NSAssert(rowIndex >= 0 && rowIndex < [list count], @"objectValueForTableColumn sent an out-of-range rowIndex"); - DownloadItem * item = [list objectAtIndex:rowIndex]; + DownloadItem * item = list[rowIndex]; // TODO: return item when we have a cell that can parse it. Until then, construct our // own data. - NSString * rawfilename = [[item filename] lastPathComponent]; + NSString * rawfilename = item.filename.lastPathComponent; NSString * filename = [rawfilename stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; if (filename == nil) filename = @""; // Different layout depending on the state NSString * objectString = filename; - switch ([item state]) + switch (item.state) { case DOWNLOAD_INIT: break; @@ -224,7 +223,7 @@ -(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColum case DOWNLOAD_COMPLETED: { // Filename on top // Final size of file at bottom. - double size = [item size]; + double size = item.size; NSString * sizeString = @""; if (size > 1024 * 1024) @@ -242,8 +241,8 @@ -(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColum // Progress gauge in middle // Size gathered so far at bottom NSString * progressString = @""; - double expectedSize = [item expectedSize]; - double sizeSoFar = [item size]; + double expectedSize = item.expectedSize; + double sizeSoFar = item.size; if (expectedSize == -1) { @@ -279,10 +278,10 @@ -(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColum */ -(void)handleDownloadsChange:(NSNotification *)notification { - DownloadItem * item = (DownloadItem *)[notification object]; - NSArray * list = [[DownloadManager sharedInstance] downloadsList]; + DownloadItem * item = (DownloadItem *)notification.object; + NSArray * list = [DownloadManager sharedInstance].downloadsList; NSUInteger rowIndex = [list indexOfObject:item]; - if ([list count] != lastCount) + if (list.count != lastCount) { [table reloadData]; if (rowIndex != NSNotFound) @@ -291,7 +290,7 @@ -(void)handleDownloadsChange:(NSNotification *)notification [table selectRowIndexes:indexes byExtendingSelection:NO]; [table scrollRowToVisible:rowIndex]; } - lastCount = [list count]; + lastCount = list.count; } else { @@ -307,6 +306,5 @@ -(void)dealloc [[NSNotificationCenter defaultCenter] removeObserver:self]; [downloadWindow setDelegate:nil]; [table setDelegate:nil]; - [super dealloc]; } @end diff --git a/src/EmptyTrashWarning.h b/src/EmptyTrashWarning.h index a69607e7d7..231764496a 100644 --- a/src/EmptyTrashWarning.h +++ b/src/EmptyTrashWarning.h @@ -25,7 +25,7 @@ IBOutlet NSButton * doNotShowWarningAgain; } --(BOOL)shouldEmptyTrash; +@property (nonatomic, readonly) BOOL shouldEmptyTrash; -(IBAction)doNotEmptyTrash:(id)sender; -(IBAction)emptyTrash:(id)sender; @end diff --git a/src/EmptyTrashWarning.m b/src/EmptyTrashWarning.m index a146a9cafe..21ba8a250c 100644 --- a/src/EmptyTrashWarning.m +++ b/src/EmptyTrashWarning.m @@ -30,21 +30,21 @@ @implementation EmptyTrashWarning --(id)init +-(instancetype)init { return [super initWithWindowNibName:@"EmptyTrashWarning"]; } -(void)windowWillLoad { - [doNotShowWarningAgain setState:NSOffState]; + doNotShowWarningAgain.state = NSOffState; } -(BOOL)shouldEmptyTrash { - BOOL shouldEmptyTrash = ([NSApp runModalForWindow:[self window]] == MA_EmptyTrashReturnCode_Yes); + BOOL shouldEmptyTrash = ([NSApp runModalForWindow:self.window] == MA_EmptyTrashReturnCode_Yes); - if ([doNotShowWarningAgain state] == NSOnState) + if (doNotShowWarningAgain.state == NSOnState) { [[Preferences standardPreferences] setInteger:(shouldEmptyTrash ? MA_EmptyTrash_WithoutWarning : MA_EmptyTrash_None) forKey:MAPref_EmptyTrashNotification]; } diff --git a/src/Export.h b/src/Export.h index 8faa0110a6..01897f5cac 100644 --- a/src/Export.h +++ b/src/Export.h @@ -19,10 +19,13 @@ // #import -#import "Database.h" -#import "AppController.h" +@class FoldersTree; + +@interface Export : NSObject + ++(NSInteger)exportToFile:(NSString *)exportFileName from:(NSArray *)foldersArray + inFoldersTree:(FoldersTree *)foldersTree withGroups:(BOOL)groupFlag; ++(NSInteger)exportToFile:(NSString *)exportFileName fromFoldersTree:(FoldersTree *)foldersTree + selection:(BOOL)selectionFlag withGroups:(BOOL)groupFlag; -@interface AppController (Export) - -(IBAction)exportSubscriptions:(id)sender; - -(int)exportToFile:(NSString *)exportFileName from:(NSArray *)foldersArray withGroups:(BOOL)groupFlag; @end diff --git a/src/Export.m b/src/Export.m index 2eb9954044..c77f21d063 100644 --- a/src/Export.m +++ b/src/Export.m @@ -20,149 +20,149 @@ #import "Export.h" #import "FoldersTree.h" -#import "XMLParser.h" #import "StringExtensions.h" #import "BJRWindowWithToolbar.h" -@implementation AppController (Export) - -/* exportSubscriptions - * Export the list of RSS subscriptions as an OPML file. - */ --(IBAction)exportSubscriptions:(id)sender -{ - NSSavePanel * panel = [NSSavePanel savePanel]; - - // If multiple selections in the folder list, default to selected folders - // for simplicity. - if ([foldersTree countOfSelectedFolders] > 1) - { - [exportSelected setState:NSOnState]; - [exportAll setState:NSOffState]; - } - else - { - [exportSelected setState:NSOffState]; - [exportAll setState:NSOnState]; - } - - // Localise the strings - [exportAll setTitle:NSLocalizedString(@"Export all subscriptions", nil)]; - [exportSelected setTitle:NSLocalizedString(@"Export selected subscriptions", nil)]; - [exportWithGroups setTitle:NSLocalizedString(@"Preserve group folders in exported file", nil)]; - - [panel setAccessoryView:exportSaveAccessory]; - [panel setAllowedFileTypes:[NSArray arrayWithObject:@"opml"]]; - [panel beginSheetModalForWindow:mainWindow completionHandler:^(NSInteger returnCode) { - if (returnCode == NSOKButton) - { - [panel orderOut:self]; +@interface Export() ++ (NSXMLDocument *)opmlDocumentFromFolders:(NSArray *)folders inFoldersTree:(FoldersTree *)foldersTree withGroups:(BOOL)groupFlag exportCount:(NSInteger *)countExported; +@end - NSArray * foldersArray = ([exportSelected state] == NSOnState) ? [foldersTree selectedFolders] : [db arrayOfFolders:MA_Root_Folder]; - int countExported = [self exportToFile:[[panel URL] path] from:foldersArray withGroups:([exportWithGroups state] == NSOnState)]; - - if (countExported < 0) - { - NSBeginCriticalAlertSheet(NSLocalizedString(@"Cannot open export file message", nil), - NSLocalizedString(@"OK", nil), - nil, - nil, [NSApp mainWindow], self, - nil, nil, nil, - NSLocalizedString(@"Cannot open export file message text", nil)); - } - else - { - // Announce how many we successfully imported - NSRunAlertPanel(NSLocalizedString(@"RSS Subscription Export Title", nil), NSLocalizedString(@"%d subscriptions successfully exported", nil), NSLocalizedString(@"OK", nil), nil, nil, countExported); - } - } - }]; -} +@implementation Export /* exportSubscriptionGroup * Export one group of folders. */ --(int)exportSubscriptionGroup:(XMLParser *)xmlTree fromArray:(NSArray *)feedArray withGroups:(BOOL)groupFlag ++(NSInteger)exportSubscriptionGroup:(NSXMLElement *)parentElement fromArray:(NSArray *)feedArray + inFoldersTree:(FoldersTree *)foldersTree withGroups:(BOOL)groupFlag { - int countExported = 0; - + NSInteger countExported = 0; for (Folder * folder in feedArray) { NSMutableDictionary * itemDict = [[NSMutableDictionary alloc] init]; - NSString * name = [folder name]; + NSString * name = folder.name; if (IsGroupFolder(folder)) { - NSArray * subFolders = [db arrayOfFolders:[folder itemId]]; + NSArray * subFolders = [foldersTree children:folder.itemId]; - if (!groupFlag) - countExported += [self exportSubscriptionGroup:xmlTree fromArray:subFolders withGroups:groupFlag]; + if (!groupFlag) { + countExported += [Export exportSubscriptionGroup:parentElement fromArray:subFolders inFoldersTree:foldersTree withGroups:groupFlag]; + } else { - [itemDict setObject:[XMLParser quoteAttributes:(name ? name : @"")] forKey:@"text"]; - XMLParser * subTree = [xmlTree addTree:@"outline" withAttributes:itemDict]; - countExported += [self exportSubscriptionGroup:subTree fromArray:subFolders withGroups:groupFlag]; + itemDict[@"text"] = [NSString stringByConvertingHTMLEntities:(name ? name : @"")]; + NSXMLElement *outlineElement = [NSXMLElement elementWithName:@"outline"]; + [outlineElement setAttributesWithDictionary:itemDict]; + [parentElement addChild:outlineElement]; + countExported += [Export exportSubscriptionGroup:outlineElement fromArray:subFolders inFoldersTree:foldersTree withGroups:groupFlag]; } } else if (IsRSSFolder(folder) || IsGoogleReaderFolder(folder)) { - NSString * link = [folder homePage]; - NSString * description = [folder feedDescription]; - NSString * url = [folder feedURL]; + NSString * link = folder.homePage; + NSString * description = folder.feedDescription; + NSString * url = folder.feedURL; - [itemDict setObject:@"rss" forKey:@"type"]; - [itemDict setObject:[XMLParser quoteAttributes:(name ? name : @"")] forKey:@"text"]; - [itemDict setObject:[XMLParser quoteAttributes:(link ? link : @"")] forKey:@"htmlUrl"]; - [itemDict setObject:[XMLParser quoteAttributes:(url ? url : @"")] forKey:@"xmlUrl"]; - [itemDict setObject:[XMLParser quoteAttributes:description] forKey:@"description"]; - [xmlTree addClosedTree:@"outline" withAttributes:itemDict]; + itemDict[@"type"] = @"rss"; + itemDict[@"text"] = [NSString stringByConvertingHTMLEntities:(name ? name : @"")]; + itemDict[@"htmlUrl"] = SafeString(link); + itemDict[@"xmlUrl"] = SafeString(url); + itemDict[@"description"] = [NSString stringByConvertingHTMLEntities:description]; + NSXMLElement *outlineElement = [NSXMLElement elementWithName:@"outline"]; + [outlineElement setAttributesWithDictionary:itemDict]; + [parentElement addChild:outlineElement]; ++countExported; } - [itemDict autorelease]; } return countExported; } /* exportToFile - * Export a list of RSS subscriptions to the specified file. If onlySelected is set then only those - * folders selected in the folders tree are exported. Otherwise all RSS folders are exported. + * Export a list of RSS subscriptions to the specified file. * Returns the number of subscriptions exported, or -1 on error. */ --(int)exportToFile:(NSString *)exportFileName from:(NSArray *)foldersArray withGroups:(BOOL)groupFlag ++(NSInteger)exportToFile:(NSString *)exportFileName from:(NSArray *)foldersArray inFoldersTree:(FoldersTree *)foldersTree withGroups:(BOOL)groupFlag { - XMLParser * newTree = [[XMLParser alloc] initWithEmptyTree]; - XMLParser * opmlTree = [newTree addTree:@"opml" withAttributes:[NSDictionary dictionaryWithObject:@"1.0" forKey:@"version"]]; - - // Create the header section - XMLParser * headTree = [opmlTree addTree:@"head"]; - if (headTree != nil) + NSInteger countExported = 0; + NSXMLDocument *opmlDocument = [Export opmlDocumentFromFolders:foldersArray inFoldersTree:foldersTree withGroups:groupFlag exportCount:&countExported]; + // Now write the complete XML to the file + + NSString * fqFilename = exportFileName.stringByExpandingTildeInPath; + if (![[NSFileManager defaultManager] createFileAtPath:fqFilename contents:nil attributes:nil]) { - [headTree addTree:@"title" withElement:@"Vienna Subscriptions"]; - [headTree addTree:@"dateCreated" withElement:[[NSCalendarDate date] description]]; + return -1; // Indicate an error condition (impossible number of exports) } + + NSData *xmlData = [opmlDocument XMLDataWithOptions:NSXMLNodePrettyPrint | NSXMLNodeCompactEmptyElement]; + [xmlData writeToFile:fqFilename atomically:YES]; + - // Create the body section - XMLParser * bodyTree = [opmlTree addTree:@"body"]; - int countExported = [self exportSubscriptionGroup:bodyTree fromArray:foldersArray withGroups:groupFlag]; + return countExported; +} - // Now write the complete XML to the file - NSString * fqFilename = [exportFileName stringByExpandingTildeInPath]; +/* exportToFile + * Export a list of RSS subscriptions to the specified file. If selectionFlag is set then only those + * folders selected in the folders tree are exported. Otherwise all RSS folders are exported. + * Returns the number of subscriptions exported, or -1 on error. + */ ++(NSInteger)exportToFile:(NSString *)exportFileName fromFoldersTree:(FoldersTree *)foldersTree selection:(BOOL)selectionFlag withGroups:(BOOL)groupFlag +{ + NSInteger countExported = 0; + NSArray * folders; + if (selectionFlag) + folders = foldersTree.selectedFolders; + else + folders = [foldersTree children:0]; + NSXMLDocument *opmlDocument = [Export opmlDocumentFromFolders:folders inFoldersTree:foldersTree withGroups:groupFlag exportCount:&countExported]; + // Now write the complete XML to the file + + NSString * fqFilename = exportFileName.stringByExpandingTildeInPath; if (![[NSFileManager defaultManager] createFileAtPath:fqFilename contents:nil attributes:nil]) { - [newTree release]; return -1; // Indicate an error condition (impossible number of exports) } - // Put some newlines in for readability - NSMutableString * xmlString = [[NSMutableString alloc] initWithString:[newTree xmlForTree]]; - [xmlString replaceString:@"><" withString:@">\n<"]; - [xmlString appendString:@"\n"]; - - NSData *xmlData = [xmlString dataUsingEncoding:NSUTF8StringEncoding]; // [xmlString writeToFile:atomically:] will write xmlString in other encoding than UTF-8 - [xmlString release]; + NSData *xmlData = [opmlDocument XMLDataWithOptions:NSXMLNodePrettyPrint | NSXMLNodeCompactEmptyElement]; [xmlData writeToFile:fqFilename atomically:YES]; + - // Clean up at the end - [newTree release]; return countExported; } + +/** + * Creates an OPML NSXMLDocument from an array of feeds + * + * @param folders An array of Folders (feeds) to export + * @param groupFlag Keep groups in tact or flatten during export + * @param countExported An integer pointer to hold the number of exported feeds + * + * @return NSXMLDocument with OPML containing the exported folders + */ ++ (NSXMLDocument *)opmlDocumentFromFolders:(NSArray *)folders inFoldersTree:(FoldersTree *)foldersTree withGroups:(BOOL)groupFlag exportCount:(NSInteger *)countExported { + *countExported = 0; + NSXMLDocument *opmlDocument = [[NSXMLDocument alloc] initWithKind:NSXMLDocumentKind options:NSXMLNodePreserveEmptyElements]; + opmlDocument.characterEncoding = @"UTF-8"; + opmlDocument.version = @"1.0"; + [opmlDocument setStandalone:YES]; + + NSXMLElement *opmlElement = [NSXMLElement elementWithName:@"opml"]; + [opmlElement setAttributesAsDictionary:@{@"version":@"1.0"}]; + + NSXMLElement *headElement = [NSXMLElement elementWithName:@"head"]; + NSXMLElement *title = [NSXMLElement elementWithName:@"title" stringValue:@"Vienna Subscriptions"]; + NSXMLElement *dateCreated = [NSXMLElement elementWithName:@"dateCreated" + stringValue:[NSCalendarDate date].description]; + [headElement addChild:title]; + [headElement addChild:dateCreated]; + [opmlElement addChild:headElement]; + + NSXMLElement *bodyElement = [NSXMLElement elementWithName:@"body"]; + *countExported = [Export exportSubscriptionGroup:bodyElement fromArray:folders inFoldersTree:foldersTree withGroups:groupFlag]; + + + [opmlElement addChild:bodyElement]; + + [opmlDocument addChild:opmlElement]; + return opmlDocument; +} + @end diff --git a/src/FeedCredentials.h b/src/FeedCredentials.h index 1107751366..94f5a99ca1 100644 --- a/src/FeedCredentials.h +++ b/src/FeedCredentials.h @@ -32,6 +32,8 @@ Folder * folder; } +@property(strong) NSArray * topObjects; + // Public functions -(void)credentialsForFolder:(NSWindow *)window folder:(Folder *)folder; -(IBAction)doCancelButton:(id)sender; diff --git a/src/FeedCredentials.m b/src/FeedCredentials.m index 38708e5c25..8cc6f121e9 100644 --- a/src/FeedCredentials.m +++ b/src/FeedCredentials.m @@ -31,7 +31,7 @@ @implementation FeedCredentials /* init * Initialise an instance of ourselves with the specified database */ --(id)init +-(instancetype)init { if ((self = [super init]) != nil) { @@ -48,27 +48,27 @@ -(void)credentialsForFolder:(NSWindow *)window folder:(Folder *)aFolder if (credentialsWindow == nil) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleTextDidChange:) name:NSControlTextDidChangeNotification object:userName]; - [NSBundle loadNibNamed:@"FeedCredentials" owner:self]; + NSArray * objects; + [[NSBundle bundleForClass:[self class]] loadNibNamed:@"FeedCredentials" owner:self topLevelObjects:&objects]; + self.topObjects = objects; } // Retain the folder as we need it to update the // username and/or password. - [aFolder retain]; - [folder release]; folder = aFolder; // Show the feed URL in the prompt so the user knows which site credentials are being // requested. (We don't use [folder name] here as that is likely to be "Untitled Folder" mostly). - NSURL * secureURL = [NSURL URLWithString:[folder feedURL]]; - NSString * prompt = [NSString stringWithFormat:NSLocalizedString(@"Credentials Prompt", nil), [secureURL host]]; - [promptString setStringValue:prompt]; + NSURL * secureURL = [NSURL URLWithString:folder.feedURL]; + NSString * prompt = [NSString stringWithFormat:NSLocalizedString(@"Credentials Prompt", nil), secureURL.host]; + promptString.stringValue = prompt; // Fill out any existing values. - [userName setStringValue:[folder username]]; - [password setStringValue:[folder password]]; + userName.stringValue = folder.username; + password.stringValue = folder.password; // Set the focus - [credentialsWindow makeFirstResponder:([[folder username] isBlank]) ? userName : password]; + [credentialsWindow makeFirstResponder:(folder.username.blank) ? userName : password]; [self enableOKButton]; [NSApp beginSheet:credentialsWindow modalForWindow:window modalDelegate:nil didEndSelector:nil contextInfo:nil]; @@ -90,12 +90,12 @@ -(IBAction)doCancelButton:(id)sender */ -(IBAction)doOKButton:(id)sender { - NSString * usernameString = [[userName stringValue] trim]; - NSString * passwordString = [password stringValue]; + NSString * usernameString = (userName.stringValue).trim; + NSString * passwordString = password.stringValue; - Database * db = [Database sharedDatabase]; - [db setFolderUsername:[folder itemId] newUsername:usernameString]; - [folder setPassword:passwordString]; + Database * db = [Database sharedManager]; + [db setFolderUsername:folder.itemId newUsername:usernameString]; + folder.password = passwordString; [NSApp endSheet:credentialsWindow]; [credentialsWindow orderOut:self]; @@ -118,7 +118,7 @@ -(void)handleTextDidChange:(NSNotification *)aNotification */ -(void)enableOKButton { - [okButton setEnabled:![[userName stringValue] isBlank]]; + okButton.enabled = !(userName.stringValue).blank; } /* dealloc @@ -127,8 +127,5 @@ -(void)enableOKButton -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - [folder release]; - folder=nil; - [super dealloc]; } @end diff --git a/src/Field.h b/src/Field.h index fe41609945..ca99d538df 100644 --- a/src/Field.h +++ b/src/Field.h @@ -21,13 +21,14 @@ #import // Enum of valid field types. -typedef enum { + +typedef NS_ENUM(NSUInteger, FieldType) { MA_FieldType_Integer = 1, MA_FieldType_Date, MA_FieldType_String, MA_FieldType_Flag, MA_FieldType_Folder -} FieldType; +}; @interface Field : NSObject { NSString * name; @@ -35,23 +36,16 @@ typedef enum { NSString * sqlField; FieldType type; NSInteger tag; - int width; + NSInteger width; BOOL visible; } -// Accessor functions --(void)setName:(NSString *)newName; --(void)setDisplayName:(NSString *)newDisplayName; --(void)setSqlField:(NSString *)newSqlField; --(void)setType:(FieldType)newType; --(void)setTag:(NSInteger)newTag; --(void)setVisible:(BOOL)flag; --(void)setWidth:(int)newWidth; --(NSString *)name; --(NSString *)displayName; --(NSString *)sqlField; --(NSInteger)tag; --(FieldType)type; --(int)width; --(BOOL)visible; +// Accessors +@property (nonatomic, copy) NSString *name; +@property (nonatomic, copy) NSString *displayName; +@property (nonatomic, copy) NSString *sqlField; +@property (nonatomic) NSInteger tag; +@property (nonatomic) FieldType type; +@property (nonatomic) NSInteger width; +@property (nonatomic) BOOL visible; @end diff --git a/src/Field.m b/src/Field.m index 57f27d3578..b46d23a2ae 100644 --- a/src/Field.m +++ b/src/Field.m @@ -25,7 +25,7 @@ @implementation Field /* init * Init an empty Field object. */ --(id)init +-(instancetype)init { if ((self = [super init]) != nil) { @@ -43,17 +43,17 @@ -(id)init /* initWithCoder * Initalises a decoded object */ --(id)initWithCoder:(NSCoder *)coder +-(instancetype)initWithCoder:(NSCoder *)coder { if ((self = [super init]) != nil) { - [self setDisplayName:[coder decodeObject]]; - [self setName:[coder decodeObject]]; - [self setSqlField:[coder decodeObject]]; + displayName = [coder decodeObject]; + name = [coder decodeObject]; + sqlField = [coder decodeObject]; [coder decodeValueOfObjCType:@encode(bool) at:&visible]; - [coder decodeValueOfObjCType:@encode(int) at:&width]; - [coder decodeValueOfObjCType:@encode(int) at:&tag]; - [coder decodeValueOfObjCType:@encode(int) at:&type]; + [coder decodeValueOfObjCType:@encode(NSInteger) at:&width]; + [coder decodeValueOfObjCType:@encode(NSInteger) at:&tag]; + [coder decodeValueOfObjCType:@encode(NSInteger) at:&type]; } return self; } @@ -64,8 +64,6 @@ -(id)initWithCoder:(NSCoder *)coder */ -(void)setName:(NSString *)newName { - [newName retain]; - [name release]; name = newName; } @@ -75,8 +73,6 @@ -(void)setName:(NSString *)newName */ -(void)setDisplayName:(NSString *)newDisplayName { - [newDisplayName retain]; - [displayName release]; displayName = newDisplayName; } @@ -87,8 +83,6 @@ -(void)setDisplayName:(NSString *)newDisplayName */ -(void)setSqlField:(NSString *)newSqlField { - [newSqlField retain]; - [sqlField release]; sqlField = newSqlField; } @@ -122,7 +116,7 @@ -(void)setVisible:(BOOL)flag /* setWidth * Sets the default width of the field in the article list view. */ --(void)setWidth:(int)newWidth +-(void)setWidth:(NSInteger)newWidth { width = newWidth; } @@ -170,7 +164,7 @@ -(FieldType)type /* width * Returns the default width of the field in the article list view. */ --(int)width +-(NSInteger)width { return width; } @@ -188,7 +182,7 @@ -(BOOL)visible */ -(NSString *)description { - return [NSString stringWithFormat:@"('%@', displayName='%@', sqlField='%@', tag=%ld, width=%d, visible=%d)", name, displayName, sqlField, tag, width, visible]; + return [NSString stringWithFormat:@"('%@', displayName='%@', sqlField='%@', tag=%ld, width=%ld, visible=%d)", name, displayName, sqlField, (long)tag, (long)width, visible]; } /* encodeWithCoder @@ -200,22 +194,9 @@ -(void)encodeWithCoder:(NSCoder *)coder [coder encodeObject:name]; [coder encodeObject:sqlField]; [coder encodeValueOfObjCType:@encode(bool) at:&visible]; - [coder encodeValueOfObjCType:@encode(int) at:&width]; - [coder encodeValueOfObjCType:@encode(int) at:&tag]; - [coder encodeValueOfObjCType:@encode(int) at:&type]; + [coder encodeValueOfObjCType:@encode(NSInteger) at:&width]; + [coder encodeValueOfObjCType:@encode(NSInteger) at:&tag]; + [coder encodeValueOfObjCType:@encode(NSInteger) at:&type]; } -/* dealloc - * Release our resources. - */ --(void)dealloc -{ - [sqlField release]; - sqlField=nil; - [displayName release]; - displayName=nil; - [name release]; - name=nil; - [super dealloc]; -} @end diff --git a/src/FilterView.m b/src/FilterView.m index 1ad535ecbc..a904c4f7f3 100644 --- a/src/FilterView.m +++ b/src/FilterView.m @@ -22,7 +22,7 @@ @implementation FilterView --(id)initWithFrame:(NSRect)frameRect +-(instancetype)initWithFrame:(NSRect)frameRect { if ((self = [super initWithFrame:frameRect]) != nil) { @@ -40,7 +40,7 @@ -(void)awakeFromNib backgroundBrush = [[NSImage alloc] initWithContentsOfFile: backgroundBrushURL ]; // Give the label the typical embossed look - [[filterByLabel cell] setBackgroundStyle:NSBackgroundStyleRaised]; + filterByLabel.cell.backgroundStyle = NSBackgroundStyleRaised; // Make sure we localise the label [filterByLabel setStringValue:NSLocalizedString(@"Filter by:", nil)]; @@ -49,7 +49,7 @@ -(void)awakeFromNib [filterViewPopUp setToolTip:NSLocalizedString(@"Filter articles", nil)]; [filterViewPopUp.cell accessibilitySetOverrideValue:filterByLabel.cell forAttribute:NSAccessibilityTitleUIElementAttribute]; [filterCloseButton setToolTip:NSLocalizedString(@"Close the filter bar", nil)]; - [[filterCloseButton cell] accessibilitySetOverrideValue:NSLocalizedString(@"Close the filter bar", nil) forAttribute:NSAccessibilityTitleAttribute]; + [filterCloseButton.cell accessibilitySetOverrideValue:NSLocalizedString(@"Close the filter bar", nil) forAttribute:NSAccessibilityTitleAttribute]; } /* drawRect @@ -57,17 +57,8 @@ -(void)awakeFromNib */ -(void)drawRect:(NSRect)rect { - NSRect iRect = NSMakeRect(0, 0, 1, [backgroundBrush size].height - 1); + NSRect iRect = NSMakeRect(0, 0, 1, backgroundBrush.size.height - 1); [backgroundBrush drawInRect:rect fromRect:iRect operation:NSCompositeSourceOver fraction:1]; } -/* dealloc - * Release resources at the end. - */ --(void)dealloc -{ - [backgroundBrush release]; - backgroundBrush=nil; - [super dealloc]; -} @end diff --git a/src/Folder.h b/src/Folder.h index fd3dfca7ab..e5b0e87caf 100644 --- a/src/Folder.h +++ b/src/Folder.h @@ -64,7 +64,7 @@ #define IsUpdating(f) ([(f) nonPersistedFlags] & MA_FFlag_Updating) #define IsError(f) ([(f) nonPersistedFlags] & MA_FFlag_Error) -@interface Folder : NSObject { +@interface Folder : NSObject { NSInteger itemId; NSInteger parentId; NSInteger nextSiblingId; @@ -76,68 +76,55 @@ NSUInteger nonPersistedFlags; BOOL isCached; BOOL hasPassword; + BOOL containsBodies; NSDate * lastUpdate; NSMutableDictionary * attributes; - NSMutableDictionary * cachedArticles; } // Initialisation functions --(id)initWithId:(NSInteger)itemId parentId:(NSInteger)parentId name:(NSString *)name type:(NSInteger)type; --(NSString *)name; --(NSString *)feedDescription; --(NSString *)homePage; --(NSString *)feedURL; --(NSDate *)lastUpdate; --(NSString *)lastUpdateString; --(NSString *)username; --(NSString *)password; --(NSDictionary *)attributes; +-(instancetype)initWithId:(NSInteger)itemId parentId:(NSInteger)parentId name:(NSString *)name type:(NSInteger)type /*NS_DESIGNATED_INITIALIZER*/; +@property (nonatomic, copy) NSString *name; +@property (nonatomic, copy) NSString *feedDescription; +@property (nonatomic, copy) NSString *homePage; +@property (nonatomic, copy) NSString *feedURL; +@property (nonatomic, copy) NSDate *lastUpdate; +@property (nonatomic, copy) NSString *lastUpdateString; +@property (nonatomic, copy) NSString *username; +@property (nonatomic, copy) NSString *password; -(NSArray *)articles; -(NSArray *)articlesWithFilter:(NSString *)fstring; --(NSInteger)parentId; --(NSInteger)itemId; --(NSInteger)nextSiblingId; --(NSInteger)firstChildId; --(NSInteger)countOfCachedArticles; --(NSInteger)unreadCount; --(NSInteger)type; --(NSUInteger)nonPersistedFlags; --(NSUInteger)flags; --(NSImage *)image; --(BOOL)hasCachedImage; +@property (nonatomic, readonly) NSInteger parentId; +@property (nonatomic, readonly) NSInteger itemId; +@property (nonatomic) NSInteger nextSiblingId; +@property (nonatomic) NSInteger firstChildId; +@property (nonatomic, readonly) NSInteger countOfCachedArticles; +@property (nonatomic) NSInteger unreadCount; +@property (nonatomic) NSInteger type; +@property (nonatomic, readonly) NSUInteger nonPersistedFlags; +@property (nonatomic, readonly) NSUInteger flags; +@property (nonatomic, copy) NSImage *image; +@property (nonatomic, readonly) BOOL hasCachedImage; -(NSImage *)standardImage; --(NSInteger)childUnreadCount; +@property (nonatomic) NSInteger childUnreadCount; -(void)clearCache; --(BOOL)isGroupFolder; --(BOOL)isSmartFolder; --(BOOL)isRSSFolder; --(BOOL)loadsFullHTML; --(void)setName:(NSString *)name; --(void)setUnreadCount:(NSInteger)count; --(void)setType:(NSInteger)newType; +@property (nonatomic, getter=isGroupFolder, readonly) BOOL groupFolder; +@property (nonatomic, getter=isSmartFolder, readonly) BOOL smartFolder; +@property (nonatomic, getter=isRSSFolder, readonly) BOOL RSSFolder; +@property (nonatomic, readonly) BOOL loadsFullHTML; -(void)setParent:(NSInteger)newParent; --(void)setNextSiblingId:(NSInteger)newNextSibling; --(void)setFirstChildId:(NSInteger)newFirstChild; --(void)setImage:(NSImage *)newImage; -(void)setFlag:(NSUInteger)flagToSet; -(void)clearFlag:(NSUInteger)flagToClear; -(void)setNonPersistedFlag:(NSUInteger)flagToSet; -(void)clearNonPersistedFlag:(NSUInteger)flagToClear; --(void)setChildUnreadCount:(NSInteger)count; --(void)setFeedDescription:(NSString *)newFeedDescription; --(void)setHomePage:(NSString *)newHomePage; --(void)setFeedURL:(NSString *)feedURL; --(void)setUsername:(NSString *)newUsername; --(void)setPassword:(NSString *)newPassword; --(void)setLastUpdate:(NSDate *)newLastUpdate; --(void)setLastUpdateString:(NSString *)newLastUpdateString; --(unsigned)indexOfArticle:(Article *)article; +-(NSUInteger)indexOfArticle:(Article *)article; -(Article *)articleFromGuid:(NSString *)guid; --(void)addArticleToCache:(Article *)newArticle; +-(BOOL)createArticle:(Article *)article guidHistory:(NSArray *)guidHistory; -(void)removeArticleFromCache:(NSString *)guid; --(void)markFolderEmpty; +-(void)restoreArticleToCache:(Article *)article; +-(void)markArticlesInCacheRead; +-(NSArray *)arrayOfUnreadArticlesRefs; -(NSComparisonResult)folderNameCompare:(Folder *)otherObject; -(NSComparisonResult)folderIDCompare:(Folder *)otherObject; --(NSString *)feedSourceFilePath; --(BOOL)hasFeedSource; +@property (nonatomic, readonly, copy) NSString *feedSourceFilePath; +@property (nonatomic, readonly) BOOL hasFeedSource; @end diff --git a/src/Folder.m b/src/Folder.m index 15733c3b86..91c8baa35e 100644 --- a/src/Folder.m +++ b/src/Folder.m @@ -21,192 +21,32 @@ #import "Folder.h" #import "AppController.h" #import "Constants.h" -#import "Preferences.h" -#import "StringExtensions.h" #import "KeyChain.h" - -// Indexes into folder image array -enum { - MA_FolderIcon = 0, - MA_SmartFolderIcon, - MA_RSSFolderIcon, - MA_RSSFeedIcon, - MA_TrashFolderIcon, - MA_SearchFolderIcon, - MA_GoogleReaderFolderIcon, - MA_Max_Icons -}; - -// Folder image cache interface. This is exclusive to the -// folder code and only used privately. -@interface FolderImageCache : NSObject { - NSString * imagesCacheFolder; - NSMutableDictionary * folderImagesArray; - BOOL initializedFolderImagesArray; -} - -// Accessor functions -+(FolderImageCache *)defaultCache; --(void)addImage:(NSImage *)image forURL:(NSString *)baseURL; --(NSImage *)retrieveImage:(NSString *)baseURL; - -// Support functions --(void)initFolderImagesArray; -@end - -// Static pointers -static FolderImageCache * _folderImageCache = nil; -static NSArray * iconArray = nil; +#import "FolderImageCache.h" +#import "StringExtensions.h" +#import "Preferences.h" +#import "ArticleRef.h" // Private internal functions @interface Folder (Private) +(NSArray *)_iconArray; @end -@implementation FolderImageCache - -/* defaultCache - * Returns a pointer to the default cache. There is just one default cache - * and we instantiate it if it doesn't exist. - */ -+(FolderImageCache *)defaultCache -{ - if (_folderImageCache == nil) - _folderImageCache = [[FolderImageCache alloc] init]; - return _folderImageCache; -} - -/* init - * Init an instance of the folder image cache. - */ --(id)init -{ - if ((self = [super init]) != nil) - { - imagesCacheFolder = nil; - initializedFolderImagesArray = NO; - folderImagesArray = [[NSMutableDictionary alloc] init]; - } - return self; -} - -/* addImage - * Add the specified image to the cache and save it to disk. - */ --(void)addImage:(NSImage *)image forURL:(NSString *)baseURL -{ - // Add in memory - [self initFolderImagesArray]; - [folderImagesArray setObject:image forKey:baseURL]; - - // Save icon to disk here. - if (imagesCacheFolder != nil) - { - NSString * fullFilePath = [[imagesCacheFolder stringByAppendingPathComponent:baseURL] stringByAppendingPathExtension:@"tiff"]; - NSData *imageData = nil; - @try { - imageData = [image TIFFRepresentation]; - } - @catch (NSException *error) { - imageData = nil; - NSLog(@"tiff exception with %@", fullFilePath); - } - if (imageData != nil) - [[NSFileManager defaultManager] createFileAtPath:fullFilePath contents:imageData attributes:nil]; - } -} - -/* retrieveImage - * Retrieve the image for the specified URL from the cache. - */ --(NSImage *)retrieveImage:(NSString *)baseURL -{ - [self initFolderImagesArray]; - return [folderImagesArray objectForKey:baseURL]; -} +@interface Folder () + @property (nonatomic, strong) NSCache * cachedArticles; + @property (nonatomic, strong) NSMutableArray * cachedGuids; +@end -/* initFolderImagesArray - * Load the existing list of folder images from the designated folder image cache. We - * do this only once and we do it as quickly as possible. When we're done, the folderImagesArray - * will be filled with image representations for each valid image file we find in the cache. - */ --(void)initFolderImagesArray -{ - if (!initializedFolderImagesArray) - { - NSFileManager * fileManager = [NSFileManager defaultManager]; - NSArray * listOfFiles; - BOOL isDir; - - // Get and cache the path to the folder. This is the best time to make sure it - // exists. The penalty for it not existing AND us being unable to create it is that - // we don't cache folder icons in this session. - imagesCacheFolder = [[Preferences standardPreferences] imagesFolder]; - if (![fileManager fileExistsAtPath:imagesCacheFolder isDirectory:&isDir]) - { - if (![fileManager createDirectoryAtPath:imagesCacheFolder withIntermediateDirectories:YES attributes:nil error:nil]) - { - NSLog(@"Cannot create image cache at %@. Will not cache folder images in this session.", imagesCacheFolder); - imagesCacheFolder = nil; - } - initializedFolderImagesArray = YES; - return; - } - - if (!isDir) - { - NSLog(@"The file at %@ is not a directory. Will not cache folder images in this session.", imagesCacheFolder); - [imagesCacheFolder release]; - imagesCacheFolder = nil; - initializedFolderImagesArray = YES; - return; - } - - // Remember - not every file we find may be a valid image file. We use the filename as - // the key but check the extension too. - listOfFiles = [fileManager contentsOfDirectoryAtPath:imagesCacheFolder error:nil]; - if (listOfFiles != nil) - { - NSString * fileName; - - for (fileName in listOfFiles) - { - if ([[fileName pathExtension] isEqualToString:@"tiff"]) - { - NSString * fullPath = [imagesCacheFolder stringByAppendingPathComponent:fileName]; - NSData * imageData = [fileManager contentsAtPath:fullPath]; - NSImage * iconImage = [[NSImage alloc] initWithData:imageData]; - if ([iconImage isValid]) - { - [iconImage setSize:NSMakeSize(16, 16)]; - NSString * homePageSiteRoot = [[[fullPath lastPathComponent] stringByDeletingPathExtension] convertStringToValidPath]; - [folderImagesArray setObject:iconImage forKey:homePageSiteRoot]; - } - [iconImage release]; - } - } - } - initializedFolderImagesArray = YES; - } -} +// Static pointers +static NSArray * iconArray = nil; -/* dealloc - * Clean up. - */ --(void)dealloc -{ - [folderImagesArray release]; - folderImagesArray=nil; - [super dealloc]; -} -@end @implementation Folder /* initWithId * Initialise a new folder object instance. */ --(id)initWithId:(NSInteger)newId parentId:(NSInteger)newIdParent name:(NSString *)newName type:(NSInteger)newType +-(instancetype)initWithId:(NSInteger)newId parentId:(NSInteger)newIdParent name:(NSString *)newName type:(NSInteger)newType { if ((self = [super init]) != nil) { @@ -220,13 +60,16 @@ -(id)initWithId:(NSInteger)newId parentId:(NSInteger)newIdParent name:(NSString flags = 0; nonPersistedFlags = 0; isCached = NO; + containsBodies = NO; hasPassword = NO; - cachedArticles = [[NSMutableDictionary dictionary] retain]; - attributes = [[NSMutableDictionary dictionary] retain]; - [self setName:newName]; - [self setLastUpdate:[NSDate distantPast]]; - [self setLastUpdateString:@""]; - [self setUsername:@""]; + self.cachedArticles = [NSCache new]; + self.cachedArticles.delegate = self; + self.cachedGuids = [NSMutableArray array]; + attributes = [NSMutableDictionary dictionary]; + self.name = newName; + self.lastUpdateString = @""; + self.username = @""; + lastUpdate = [NSDate distantPast]; } return self; } @@ -237,15 +80,15 @@ -(id)initWithId:(NSInteger)newId parentId:(NSInteger)newIdParent name:(NSString +(NSArray *)_iconArray { if (iconArray == nil) - iconArray = [[NSArray arrayWithObjects: - [NSImage imageNamed:@"smallFolder.tiff"], - [NSImage imageNamed:@"smartFolder.tiff"], - [NSImage imageNamed:@"rssFolder.tiff"], - [NSImage imageNamed:@"rssFeedNew.tiff"], - [NSImage imageNamed:@"trashFolder.tiff"], - [NSImage imageNamed:@"searchFolder.tiff"], - [NSImage imageNamed:@"googleFeed.tiff"], - nil] retain]; + iconArray = @[ + [NSImage imageNamed:@"smallFolder.tiff"], + [NSImage imageNamed:@"smartFolder.tiff"], + [NSImage imageNamed:@"rssFolder.tiff"], + [NSImage imageNamed:@"rssFeedNew.tiff"], + [NSImage imageNamed:@"trashFolder.tiff"], + [NSImage imageNamed:@"searchFolder.tiff"], + [NSImage imageNamed:@"googleFeed.tiff"], + ]; return iconArray; } @@ -285,7 +128,10 @@ -(NSInteger)firstChildId */ -(NSInteger)unreadCount { - return unreadCount; + @synchronized(self) + { + return unreadCount; + } } /* type @@ -313,15 +159,10 @@ -(NSUInteger)nonPersistedFlags */ -(NSInteger)childUnreadCount { - return childUnreadCount; -} - -/* attributes - * Return the folder attributes. - */ --(NSDictionary *)attributes -{ - return attributes; + @synchronized(self) + { + return childUnreadCount; + } } /* feedDescription @@ -329,7 +170,7 @@ -(NSDictionary *)attributes */ -(NSString *)feedDescription { - return SafeString([attributes valueForKey:@"FeedDescription"]); + return SafeString(attributes[@"FeedDescription"]); } /* homePage @@ -337,7 +178,7 @@ -(NSString *)feedDescription */ -(NSString *)homePage { - return SafeString([attributes valueForKey:@"HomePage"]); + return SafeString(attributes[@"HomePage"]); } /* image @@ -346,36 +187,34 @@ -(NSString *)homePage -(NSImage *)image { if (IsGroupFolder(self)) - return [[Folder _iconArray] objectAtIndex:MA_RSSFolderIcon]; + return [Folder _iconArray][MA_RSSFolderIcon]; if (IsSmartFolder(self)) - return [[Folder _iconArray] objectAtIndex:MA_SmartFolderIcon]; + return [Folder _iconArray][MA_SmartFolderIcon]; if (IsTrashFolder(self)) - return [[Folder _iconArray] objectAtIndex:MA_TrashFolderIcon]; + return [Folder _iconArray][MA_TrashFolderIcon]; if (IsSearchFolder(self)) - return [[Folder _iconArray] objectAtIndex:MA_SearchFolderIcon]; - // if (IsGoogleReaderFolder(self)) - // return [[Folder _iconArray] objectAtIndex:MA_GoogleReaderFolderIcon]; + return [Folder _iconArray][MA_SearchFolderIcon]; if (IsRSSFolder(self) || IsGoogleReaderFolder(self)) { // Try the folder icon cache. NSImage * imagePtr = nil; - if ([self feedURL]) + if (self.feedURL) { NSString * homePageSiteRoot; - homePageSiteRoot = [[[self homePage] host] convertStringToValidPath]; + homePageSiteRoot = self.homePage.host.convertStringToValidPath; imagePtr = [[FolderImageCache defaultCache] retrieveImage:homePageSiteRoot]; } NSImage *altIcon; if (IsRSSFolder(self)) { - altIcon = [[Folder _iconArray] objectAtIndex:MA_RSSFeedIcon]; + altIcon = [Folder _iconArray][MA_RSSFeedIcon]; } else { - altIcon = [[Folder _iconArray] objectAtIndex:MA_GoogleReaderFolderIcon]; + altIcon = [Folder _iconArray][MA_GoogleReaderFolderIcon]; } return (imagePtr) ? imagePtr : altIcon; } // Use the generic folder icon for anything else - return [[Folder _iconArray] objectAtIndex:MA_FolderIcon]; + return [Folder _iconArray][MA_FolderIcon]; } /* hasCachedImage @@ -386,9 +225,9 @@ -(BOOL)hasCachedImage if (!IsRSSFolder(self) && !IsGoogleReaderFolder(self)) return NO; NSImage * imagePtr = nil; - if ([self feedURL]) + if (self.feedURL) { - NSString * homePageSiteRoot = [[[self homePage] host] convertStringToValidPath]; + NSString * homePageSiteRoot = self.homePage.host.convertStringToValidPath; imagePtr = [[FolderImageCache defaultCache] retrieveImage:homePageSiteRoot]; } return (imagePtr != nil); @@ -400,10 +239,10 @@ -(BOOL)hasCachedImage -(NSImage *)standardImage { if (IsRSSFolder(self)) - return [[Folder _iconArray] objectAtIndex:MA_RSSFeedIcon]; + return [Folder _iconArray][MA_RSSFeedIcon]; if (IsGoogleReaderFolder(self)) - return [[Folder _iconArray] objectAtIndex:MA_GoogleReaderFolderIcon]; - return [self image]; + return [Folder _iconArray][MA_GoogleReaderFolderIcon]; + return self.image; } /* setImage @@ -412,10 +251,10 @@ -(NSImage *)standardImage */ -(void)setImage:(NSImage *)iconImage { - if ([self feedURL] != nil && iconImage != nil) + if (self.feedURL != nil && iconImage != nil) { NSString * homePageSiteRoot; - homePageSiteRoot = [[[self homePage] host] convertStringToValidPath]; + homePageSiteRoot = self.homePage.host.convertStringToValidPath; [[FolderImageCache defaultCache] addImage:iconImage forURL:homePageSiteRoot]; } } @@ -425,7 +264,7 @@ -(void)setImage:(NSImage *)iconImage */ -(void)setFeedDescription:(NSString *)newFeedDescription { - [attributes setValue:newFeedDescription forKey:@"FeedDescription"]; + [attributes setValue:SafeString(newFeedDescription) forKey:@"FeedDescription"]; } /* setHomePage @@ -433,7 +272,7 @@ -(void)setFeedDescription:(NSString *)newFeedDescription */ -(void)setHomePage:(NSString *)newHomePage { - [attributes setValue:newHomePage forKey:@"HomePage"]; + [attributes setValue:SafeString(newHomePage) forKey:@"HomePage"]; } /* username @@ -459,8 +298,8 @@ -(NSString *)password { if (!hasPassword) { - if ([self username] != nil && [self feedURL] != nil) - [attributes setValue:[KeyChain getPasswordFromKeychain:[self username] url:[self feedURL]] forKey:@"Password"]; + if (self.username != nil && self.feedURL != nil) + [attributes setValue:[KeyChain getPasswordFromKeychain:self.username url:self.feedURL] forKey:@"Password"]; hasPassword = YES; } return [attributes valueForKey:@"Password"]; @@ -471,8 +310,8 @@ -(NSString *)password */ -(void)setPassword:(NSString *)newPassword { - if ([self username] != nil && [self feedURL] != nil) - [KeyChain setPasswordInKeychain:newPassword username:[self username] url:[self feedURL]]; + if (self.username != nil && self.feedURL != nil) + [KeyChain setPasswordInKeychain:newPassword username:self.username url:self.feedURL]; [attributes setValue:newPassword forKey:@"Password"]; hasPassword = YES; } @@ -490,8 +329,6 @@ -(NSDate *)lastUpdate */ -(void)setLastUpdate:(NSDate *)newLastUpdate { - [newLastUpdate retain]; - [lastUpdate release]; lastUpdate = newLastUpdate; } @@ -648,19 +485,108 @@ -(void)setFirstChildId:(NSInteger)newFirstChild; /* indexOfArticle * Returns the index of the article that matches the specified article based on guid. */ --(unsigned)indexOfArticle:(Article *)article +-(NSUInteger)indexOfArticle:(Article *)article { - NSArray * cacheArray = [self articles]; - Article * realArticle = [cachedArticles objectForKey:[article guid]]; - return [cacheArray indexOfObjectIdenticalTo:realArticle]; + @synchronized(self) + { + [self ensureCache]; + return [self.cachedGuids indexOfObject:article.guid]; + } } /* articleFromGuid */ -(Article *)articleFromGuid:(NSString *)guid { - NSAssert(isCached, @"Folder's cache of articles should be initialized before articleFromGuid can be used"); - return [cachedArticles objectForKey:guid]; + @synchronized(self) + { + [self ensureCache]; + return [self.cachedArticles objectForKey:guid]; + } +} + +/* createArticle + * Adds or updates an article in the folder. + * Returns YES if the article was added or updated + * or NO if we couldn't add the article for some reason. + * On success, status information is updated in the article to mark + * if it is new or updated (from the point of view of the user). + */ +-(BOOL)createArticle:(Article *)article guidHistory:(NSArray *)guidHistory +{ +@synchronized(self) + { + // Prime the article cache + [self ensureCache]; + + // Unread count adjustment factor + NSInteger adjustment = 0; + + NSString * articleGuid = article.guid; + // Does this article already exist? + // We're going to ignore here the problem of feeds re-using guids, which is very naughty! Bad feed! + Article * existingArticle = [self.cachedArticles objectForKey:articleGuid]; + + if (existingArticle == nil) + { + if ([guidHistory containsObject:articleGuid]) + return NO; // Article has been deleted and removed from database, so ignore + else + { + // add the article as new + BOOL success = [[Database sharedManager] addArticle:article toFolder:itemId]; + if(success) + { + article.status = ArticleStatusNew; + // add to the cache + NSString * guid = article.guid; + [self.cachedArticles setObject:article forKey:[NSString stringWithString:guid]]; + [self.cachedGuids addObject:guid]; + if(!article.read) + adjustment = 1; + } + else + return NO; + } + } + else if (existingArticle.deleted) + { + return NO; + } + else if (![[Preferences standardPreferences] boolForKey:MAPref_CheckForUpdatedArticles]) + { + return NO; + } + else + { + BOOL success = [[Database sharedManager] updateArticle:existingArticle ofFolder:itemId withArticle:article]; + if (success) + { + // Update folder unread count if necessary + if (existingArticle.read) + { + adjustment = 1; + article.status = ArticleStatusNew; + [existingArticle markRead:NO]; + } + else + { + article.status = ArticleStatusUpdated; + } + } + else + { + return NO; + } + } + + // Fix unread count on parent folders and Database manager + if (adjustment != 0) + { + [[Database sharedManager] setFolderUnreadCount:self adjustment:adjustment]; + } + return YES; + } // synchronized } /* setUnreadCount @@ -690,36 +616,44 @@ -(void)setChildUnreadCount:(NSInteger)count */ -(void)clearCache { -@autoreleasepool { - [cachedArticles removeAllObjects]; + @synchronized(self) + { + [self.cachedArticles removeAllObjects]; + [self.cachedGuids removeAllObjects]; isCached = NO; + containsBodies = NO; } } -/* addArticleToCache - * Add the specified article to our cache, replacing any existing instance. - */ --(void)addArticleToCache:(Article *)newArticle -{ - [cachedArticles setObject:newArticle forKey:[newArticle guid]]; - isCached = YES; -} - /* removeArticleFromCache * Remove the article identified by the specified GUID from the cache. */ -(void)removeArticleFromCache:(NSString *)guid { - NSAssert(isCached, @"Folder's cache of articles should be initialized before removeArticleFromCache can be used"); - [cachedArticles removeObjectForKey:guid]; + @synchronized(self) + { + NSAssert(isCached, @"Folder's cache of articles should be initialized before removeArticleFromCache can be used"); + [self.cachedArticles removeObjectForKey:guid]; + [self.cachedGuids removeObject:guid]; + } } -/* markFolderEmpty - * Mark this folder as empty on the service +/* restoreArticleToCache + * Re-add an article to the cache (useful for unmarking article as deleted). */ --(void)markFolderEmpty +-(void)restoreArticleToCache:(Article *)article { - isCached = YES; + @synchronized(self) + { + NSString * guid = article.guid; + [self.cachedArticles setObject:article forKey:[NSString stringWithString:guid]]; + [self.cachedGuids addObject:guid]; + // note if article has incomplete data + if (article.createdDate == nil) + { + containsBodies = NO; + } + } } /* countOfCachedArticles @@ -730,7 +664,30 @@ -(void)markFolderEmpty */ -(NSInteger)countOfCachedArticles { - return isCached ? (NSInteger)[cachedArticles count] : -1; + @synchronized(self) + { + return isCached ? (NSInteger)self.cachedGuids.count : -1; + } +} + +/* ensureCache + * Prepare the cache if it is not yet ready + */ + -(void)ensureCache + { + if (!isCached) + { + NSArray * myArray = [[Database sharedManager] minimalCacheForFolder:itemId]; + for (Article * myArticle in myArray) + { + NSString * guid = myArticle.guid; + [self.cachedArticles setObject:myArticle forKey:[NSString stringWithString:guid]]; + [self.cachedGuids addObject:guid]; + } + isCached = YES; + // Note that this only builds a minimal cache, so we cannot set the containsBodies flag + // Note also that articles' statuses are left at the default value (0) which is ArticleStatusEmpty + } } /* articles @@ -738,9 +695,62 @@ -(NSInteger)countOfCachedArticles */ -(NSArray *)articles { - if (!isCached) - [[Database sharedDatabase] arrayOfArticles:itemId filterString:nil]; - return [cachedArticles allValues]; + return [self articlesWithFilter:@""]; +} + +/* markArticlesInCacheRead + * iterate through the cache and mark the articles as read + */ +-(void)markArticlesInCacheRead +{ +@synchronized(self) + { + NSInteger count = unreadCount; + // Note the use of reverseObjectEnumerator + // since the unread articles are likely to be clustered + // with the most recent articles at the end of the array + // so it makes the code slightly faster. + for (id obj in self.cachedGuids.reverseObjectEnumerator.allObjects) + { + Article * article = [self.cachedArticles objectForKey:(NSString *)obj]; + if (!article.read) + { + [article markRead:YES]; + count--; + if (count == 0) + break; + } + } + } // synchronized +} + +/* arrayOfUnreadArticlesRefs + * Return an array of ArticleReference of all unread articles + */ +-(NSArray *)arrayOfUnreadArticlesRefs +{ +@synchronized(self) + { + if (isCached) + { + NSInteger count = unreadCount; + NSMutableArray * result = [NSMutableArray arrayWithCapacity:unreadCount]; + for (id obj in self.cachedGuids.reverseObjectEnumerator.allObjects) + { + Article * article = [self.cachedArticles objectForKey:(NSString *)obj]; + if (!article.read) + { + [result addObject:[ArticleReference makeReference:article]]; + count--; + if (count == 0) + break; + } + } + return [result copy]; + } + else + return [[Database sharedManager] arrayOfUnreadArticlesRefs:itemId]; + } // synchronized } /* articlesWithFilter @@ -748,7 +758,64 @@ -(NSArray *)articles */ -(NSArray *)articlesWithFilter:(NSString *)fstring { - return [[Database sharedDatabase] arrayOfArticles:itemId filterString:fstring]; + if ([fstring isEqualToString:@""]) + { + if (IsGroupFolder(self)) + { + NSMutableArray * articles = [NSMutableArray array]; + NSArray * subFolders = [[Database sharedManager] arrayOfFolders:itemId]; + for (Folder * folder in subFolders) { + [articles addObjectsFromArray:[folder articlesWithFilter:fstring]]; + } + return [articles copy]; + } + @synchronized(self) { + if (isCached && containsBodies) + { + self.cachedArticles.evictsObjectsWithDiscardedContent = NO; + NSMutableArray * articles = [NSMutableArray arrayWithCapacity:self.cachedGuids.count]; + for (id object in self.cachedGuids) + { + Article * theArticle = [self.cachedArticles objectForKey:object]; + if (theArticle != nil) + [articles addObject:theArticle]; + else + { // some problem + NSLog(@"Bug retrieving from cache in folder %li : after %lu insertions of %lu, guid %@",(long)itemId, (unsigned long)articles.count,(unsigned long)self.cachedGuids.count,object); + isCached = NO; + containsBodies = NO; + break; + } + } + self.cachedArticles.evictsObjectsWithDiscardedContent = YES; + return [articles copy]; + } + else + { + NSArray * articles = [[Database sharedManager] arrayOfArticles:itemId filterString:fstring]; + // Only feeds folders can be cached, as they are the only ones to guarantee + // bijection : one article <-> one guid + if (IsRSSFolder(self) || IsGoogleReaderFolder(self)) + { + isCached = NO; + containsBodies = NO; + [self.cachedArticles removeAllObjects]; + [self.cachedGuids removeAllObjects]; + for (id object in articles) + { + NSString * guid = ((Article *)object).guid; + [self.cachedArticles setObject:object forKey:[NSString stringWithString:guid]]; + [self.cachedGuids addObject:guid]; + } + isCached = YES; + containsBodies = YES; + } + return articles; + } + } // synchronized + } + else + return [[Database sharedManager] arrayOfArticles:itemId filterString:fstring]; } /* folderNameCompare @@ -756,7 +823,7 @@ -(NSArray *)articlesWithFilter:(NSString *)fstring */ -(NSComparisonResult)folderNameCompare:(Folder *)otherObject { - return [[self name] caseInsensitiveCompare:[otherObject name]]; + return [self.name caseInsensitiveCompare:otherObject.name]; } /* folderIDCompare @@ -764,8 +831,8 @@ -(NSComparisonResult)folderNameCompare:(Folder *)otherObject */ -(NSComparisonResult)folderIDCompare:(Folder *)otherObject { - if ([self itemId] > [otherObject itemId]) return NSOrderedAscending; - if ([self itemId] < [otherObject itemId]) return NSOrderedDescending; + if (self.itemId > otherObject.itemId) return NSOrderedAscending; + if (self.itemId < otherObject.itemId) return NSOrderedDescending; return NSOrderedSame; } @@ -775,10 +842,10 @@ -(NSComparisonResult)folderIDCompare:(Folder *)otherObject -(NSString *)feedSourceFilePath { NSString * feedSourceFilePath = nil; - if ([self isRSSFolder]) + if (self.RSSFolder) { - NSString * feedSourceFileName = [NSString stringWithFormat:@"folder%li.xml", [self itemId]]; - feedSourceFilePath = [[[Preferences standardPreferences] feedSourcesFolder] stringByAppendingPathComponent:feedSourceFileName]; + NSString * feedSourceFileName = [NSString stringWithFormat:@"folder%li.xml", (long)self.itemId]; + feedSourceFilePath = [[Preferences standardPreferences].feedSourcesFolder stringByAppendingPathComponent:feedSourceFileName]; } return feedSourceFilePath; } @@ -788,7 +855,7 @@ -(NSString *)feedSourceFilePath */ -(BOOL)hasFeedSource { - NSString * feedSourceFilePath = [self feedSourceFilePath]; + NSString * feedSourceFilePath = self.feedSourceFilePath; BOOL isDirectory = YES; return feedSourceFilePath != nil && [[NSFileManager defaultManager] fileExistsAtPath:feedSourceFilePath isDirectory:&isDirectory] && !isDirectory; } @@ -798,12 +865,12 @@ -(BOOL)hasFeedSource */ -(NSScriptObjectSpecifier *)objectSpecifier { - NSArray * folders = [APPCONTROLLER folders]; + NSArray * folders = APPCONTROLLER.folders; NSUInteger index = [folders indexOfObjectIdenticalTo:self]; if (index != NSNotFound) { - NSScriptObjectSpecifier *containerRef = [APPCONTROLLER objectSpecifier]; - return [[[NSIndexSpecifier allocWithZone:[self zone]] initWithContainerClassDescription:(NSScriptClassDescription *)[NSApp classDescription] containerSpecifier:containerRef key:@"folders" index:index] autorelease]; + NSScriptObjectSpecifier *containerRef = APPCONTROLLER.objectSpecifier; + return [[NSIndexSpecifier allocWithZone:nil] initWithContainerClassDescription:(NSScriptClassDescription *)NSApp.classDescription containerSpecifier:containerRef key:@"folders" index:index]; } return nil; } @@ -813,20 +880,22 @@ -(NSScriptObjectSpecifier *)objectSpecifier */ -(NSString *)description { - return [NSString stringWithFormat:@"Folder id %ld (%@)", itemId, [self name]]; + return [NSString stringWithFormat:@"Folder id %li (%@)", (long)itemId, self.name]; } -/* dealloc - * Clean up and release resources. - */ --(void)dealloc +#pragma mark NSCacheDelegate +-(void)cache:(NSCache *)cache willEvictObject:(id)obj { - [lastUpdate release]; - lastUpdate=nil; - [attributes release]; - attributes=nil; - [cachedArticles release]; - cachedArticles=nil; - [super dealloc]; + @synchronized(self) + { + Article * theArticle = ((Article *)obj); + NSString * guid = theArticle.guid; + if (isCached && !theArticle.isDeleted) + { + isCached = NO; + containsBodies = NO; + } + [self.cachedGuids removeObject:guid]; + } } @end diff --git a/src/FolderView.h b/src/FolderView.h index 901842ebfb..ca35186ab3 100644 --- a/src/FolderView.h +++ b/src/FolderView.h @@ -32,6 +32,9 @@ -(void)keyDown:(NSEvent *)theEvent; -(void)buildTooltips; -(void)prvtResizeTheFieldEditor; + +@property (nonatomic) NSPredicate* filterPredicate; + @end @interface NSObject (FolderViewDataSource) diff --git a/src/FolderView.m b/src/FolderView.m index 211f8e5009..d63fe420ab 100644 --- a/src/FolderView.m +++ b/src/FolderView.m @@ -22,21 +22,27 @@ #import "ImageAndTextCell.h" #import "TreeNode.h" #import "AppController.h" +#import "FoldersFilterable.h" @interface NSObject (FolderViewDelegate) - -(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger )flags; + -(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger)flags; -(BOOL)copyTableSelection:(NSArray *)items toPasteboard:(NSPasteboard *)pboard; - -(BOOL)canDeleteFolderAtRow:(int)row; + -(BOOL)canDeleteFolderAtRow:(NSInteger)row; -(IBAction)deleteFolder:(id)sender; -(void)outlineViewWillBecomeFirstResponder; @end -@implementation FolderView +@implementation FolderView { + NSPredicate* _filterPredicate; + FoldersFilterableDataSourceImpl* _filterDataSource; + NSDictionary* _prefilterState; + id _directDataSource; +} /* init * Our initialisation. */ --(id)init +-(instancetype)init { if ((self = [super init]) != nil) useTooltips = NO; @@ -54,7 +60,7 @@ -(void)awakeFromNib NSString * grayGradientURL = [[NSBundle mainBundle] pathForResource:@"selGray" ofType:@"tiff"]; grayGradient = [[NSImage alloc] initWithContentsOfFile: grayGradientURL ]; - iRect = NSMakeRect(0,0,1,[blueGradient size].height-1); + iRect = NSMakeRect(0,0,1,blueGradient.size.height-1); // Add the notifications for collapse and expand. NSNotificationCenter * nc = [NSNotificationCenter defaultCenter]; @@ -96,10 +102,10 @@ -(void)setEnableTooltips:(BOOL)flag */ -(void)keyDown:(NSEvent *)theEvent { - if ([[theEvent characters] length] == 1) + if (theEvent.characters.length == 1) { - unichar keyChar = [[theEvent characters] characterAtIndex:0]; - if ([APPCONTROLLER handleKeyDown:keyChar withFlags:[theEvent modifierFlags]]) + unichar keyChar = [theEvent.characters characterAtIndex:0]; + if ([APPCONTROLLER handleKeyDown:keyChar withFlags:theEvent.modifierFlags]) return; } [super keyDown:theEvent]; @@ -120,7 +126,7 @@ -(void)buildTooltips if (!useTooltips || ![_dataSource respondsToSelector:@selector(outlineView:tooltipForItem:)]) return; - range = [self rowsInRect:[self visibleRect]]; + range = [self rowsInRect:self.visibleRect]; for (index = range.location; index < NSMaxRange(range); index++) { NSString *tooltip; @@ -138,7 +144,7 @@ -(void)buildTooltips */ -(NSString *)view:(NSView *)view stringForToolTip:(NSToolTipTag)tag point:(NSPoint)point userData:(void *)data { - int row; + NSInteger row; row = [self rowAtPoint:point]; return [_dataSource outlineView:self tooltipForItem:[self itemAtRow:row]]; @@ -158,7 +164,9 @@ -(void)resetCursorRects */ -(void)setDataSource:(id)aSource { - [super setDataSource:aSource]; + _directDataSource = aSource; + _filterDataSource = [[FoldersFilterableDataSourceImpl alloc] initWithDataSource:aSource]; + [super setDataSource:aSource]; [self buildTooltips]; } @@ -168,10 +176,46 @@ -(void)setDataSource:(id)aSource */ -(void)reloadData { + if (_filterDataSource && _filterPredicate) + [_filterDataSource reloadData:self]; [super reloadData]; [self buildTooltips]; } +- (NSPredicate*)filterPredicate { + return _filterPredicate; +} + +- (void)setFilterPredicate:(NSPredicate *)filterPredicate { + if (_filterPredicate == filterPredicate) + return; + + if (_filterPredicate == nil) { + _prefilterState = self.state; + } + + _filterPredicate = filterPredicate; + if (_filterDataSource && _filterPredicate){ + [_filterDataSource setFilterPredicate:_filterPredicate outlineView:self]; + [super setDataSource:_filterDataSource]; + } + else{ + [super setDataSource:_directDataSource]; + } + + [super reloadData]; + + if (_filterPredicate) { + [self expandItem:nil expandChildren:YES]; + self.selectionState = _prefilterState[@"Selection"]; + } + else if (_prefilterState) { + self.state = _prefilterState; + _prefilterState = nil; + } +} + + /* noteNumberOfRowsChanged * Called by the user to tell the view to re-request data. Again, this could mean the * contents changing => tooltips change. @@ -204,7 +248,7 @@ -(void)outlineViewItemDidCollapse:(NSNotification *)notification [self buildTooltips]; // Have the collapsed item remove any progress indicators. - TreeNode * collapsedItem = [[notification userInfo] objectForKey:@"NSObject"]; + TreeNode * collapsedItem = notification.userInfo[@"NSObject"]; [collapsedItem stopAndReleaseProgressIndicator]; } @@ -216,7 +260,7 @@ -(NSMenu *)menuForEvent:(NSEvent *)theEvent { if ([self delegate] && [[self delegate] respondsToSelector:@selector(outlineView:menuWillAppear:)]) [(id)[self delegate] outlineView:self menuWillAppear:theEvent]; - return [self menu]; + return self.menu; } /* copy @@ -224,11 +268,11 @@ -(NSMenu *)menuForEvent:(NSEvent *)theEvent */ -(IBAction)copy:(id)sender { - if ([self selectedRow] >= 0) + if (self.selectedRow >= 0) { - NSMutableArray * array = [NSMutableArray arrayWithCapacity:[self numberOfSelectedRows]]; - NSIndexSet * selectedRowIndexes = [self selectedRowIndexes]; - NSUInteger item = [selectedRowIndexes firstIndex]; + NSMutableArray * array = [NSMutableArray arrayWithCapacity:self.numberOfSelectedRows]; + NSIndexSet * selectedRowIndexes = self.selectedRowIndexes; + NSUInteger item = selectedRowIndexes.firstIndex; while (item != NSNotFound) { @@ -254,15 +298,15 @@ -(IBAction)delete:(id)sender */ -(BOOL)validateMenuItem:(NSMenuItem *)menuItem { - if ([menuItem action] == @selector(copy:)) + if (menuItem.action == @selector(copy:)) { - return ([self selectedRow] >= 0); + return (self.selectedRow >= 0); } - if ([menuItem action] == @selector(delete:)) + if (menuItem.action == @selector(delete:)) { - return [(id)[self delegate] canDeleteFolderAtRow:[self selectedRow]]; + return [(id)[self delegate] canDeleteFolderAtRow:self.selectedRow]; } - if ([menuItem action] == @selector(selectAll:)) + if (menuItem.action == @selector(selectAll:)) { return YES; } @@ -283,8 +327,8 @@ -(id)_highlightColorForCell:(NSCell *)cell */ -(void)highlightSelectionInClipRect:(NSRect)rect { - NSIndexSet * selectedRowIndexes = [self selectedRowIndexes]; - NSUInteger rowIndex = [selectedRowIndexes firstIndex]; + NSIndexSet * selectedRowIndexes = self.selectedRowIndexes; + NSUInteger rowIndex = selectedRowIndexes.firstIndex; while (rowIndex != NSNotFound) { @@ -293,12 +337,12 @@ -(void)highlightSelectionInClipRect:(NSRect)rect { [blueGradient drawInRect:selectedRect fromRect:iRect operation:NSCompositeSourceOver fraction:1 respectFlipped:YES hints:nil]; - if ([self editedRow] == -1) + if (self.editedRow == -1) { - if ([[self window] firstResponder] != self || ![[self window] isKeyWindow]) + if (self.window.firstResponder != self || !self.window.keyWindow) [grayGradient drawInRect:selectedRect fromRect:iRect operation:NSCompositeSourceOver fraction:1 respectFlipped:YES hints:nil]; } - if ([self editedRow] != -1) + if (self.editedRow != -1) [self performSelector:@selector(prvtResizeTheFieldEditor) withObject:nil afterDelay:0.001]; } rowIndex = [selectedRowIndexes indexGreaterThanIndex:rowIndex]; @@ -312,27 +356,27 @@ -(void)highlightSelectionInClipRect:(NSRect)rect */ -(void)prvtResizeTheFieldEditor { - id editor = [[self window] fieldEditor:YES forObject:self]; - NSRect editRect = NSIntersectionRect([self rectOfColumn:[self editedColumn]], [self rectOfRow:[self editedRow]]); - NSRect frame = [[editor superview] frame]; + id editor = [self.window fieldEditor:YES forObject:self]; + NSRect editRect = NSIntersectionRect([self rectOfColumn:self.editedColumn], [self rectOfRow:self.editedRow]); + NSRect frame = [editor superview].frame; NSLayoutManager * layoutManager = [editor layoutManager]; - [layoutManager boundingRectForGlyphRange:NSMakeRange(0, [layoutManager numberOfGlyphs]) inTextContainer:[editor textContainer]]; + [layoutManager boundingRectForGlyphRange:NSMakeRange(0, layoutManager.numberOfGlyphs) inTextContainer:[editor textContainer]]; frame.size.width = [layoutManager usedRectForTextContainer:[editor textContainer]].size.width; if (editRect.size.width > frame.size.width) - [[editor superview] setFrame:frame]; + [editor superview].frame = frame; else { frame.size.width = editRect.size.width-4; - [[editor superview] setFrame:frame]; + [editor superview].frame = frame; } [editor setNeedsDisplay:YES]; if ([self lockFocusIfCanDraw]) { - id clipView = [[[self window] fieldEditor:YES forObject:self] superview]; + id clipView = [self.window fieldEditor:YES forObject:self].superview; NSRect borderRect = [clipView frame]; // Get rid of the white border, leftover from resizing the fieldEditor.. @@ -341,17 +385,17 @@ -(void)prvtResizeTheFieldEditor [blueGradient drawInRect:editRect fromRect:iRect operation:NSCompositeSourceOver fraction:1 respectFlipped:YES hints:nil]; // Put back any cell image - int editColumnIndex = [self editedColumn]; + NSInteger editColumnIndex = self.editedColumn; if (editColumnIndex != -1) { - NSTableColumn * editColumn = [[self tableColumns] objectAtIndex:editColumnIndex]; - ImageAndTextCell * fieldCell = [editColumn dataCell]; + NSTableColumn * editColumn = self.tableColumns[editColumnIndex]; + ImageAndTextCell * fieldCell = editColumn.dataCell; if ([fieldCell respondsToSelector:@selector(drawCellImage:inView:)]) { // The fieldCell needs to be primed with the image for the cell. - [[self delegate] outlineView:self willDisplayCell:fieldCell forTableColumn:editColumn item:[self itemAtRow:[self editedRow]]]; + [[self delegate] outlineView:self willDisplayCell:fieldCell forTableColumn:editColumn item:[self itemAtRow:self.editedRow]]; - NSRect cellRect = [self frameOfCellAtColumn:editColumnIndex row:[self editedRow]]; + NSRect cellRect = [self frameOfCellAtColumn:editColumnIndex row:self.editedRow]; [fieldCell drawCellImage:&cellRect inView:clipView]; } } @@ -385,8 +429,8 @@ -(void)textDidChange:(NSNotification *)aNotification */ - (void)textDidBeginEditing:(NSNotification *)aNotification { - NSText * editor = [[self window] fieldEditor:YES forObject:self]; - backupString = [[editor string] copy]; + NSText * editor = [self.window fieldEditor:YES forObject:self]; + backupString = [editor.string copy]; [super textDidBeginEditing:aNotification]; } @@ -396,23 +440,22 @@ - (void)textDidBeginEditing:(NSNotification *)aNotification */ -(void)textDidEndEditing:(NSNotification *)notification; { - [backupString release]; backupString=nil; // This is ugly, but just about the only way to do it. NSTableView is determined to select and edit something else, even the // text field that it just finished editing, unless we mislead it about what key was pressed to end editing. - if ([[[notification userInfo] objectForKey:@"NSTextMovement"] intValue] == NSReturnTextMovement) + if ([notification.userInfo[@"NSTextMovement"] integerValue] == NSReturnTextMovement) { NSMutableDictionary *newUserInfo; NSNotification *newNotification; - newUserInfo = [NSMutableDictionary dictionaryWithDictionary:[notification userInfo]]; - [newUserInfo setObject:[NSNumber numberWithInt:NSIllegalTextMovement] forKey:@"NSTextMovement"]; - newNotification = [NSNotification notificationWithName:[notification name] object:[notification object] userInfo:newUserInfo]; + newUserInfo = [NSMutableDictionary dictionaryWithDictionary:notification.userInfo]; + newUserInfo[@"NSTextMovement"] = @(NSIllegalTextMovement); + newNotification = [NSNotification notificationWithName:notification.name object:notification.object userInfo:newUserInfo]; [super textDidEndEditing:newNotification]; // For some reason we lose firstResponder status when when we do the above. - [[self window] makeFirstResponder:self]; + [self.window makeFirstResponder:self]; } else [super textDidEndEditing:notification]; @@ -426,8 +469,8 @@ - (void)cancelOperation:(id)sender { if (backupString !=nil) { - NSText * editor = [[self window] fieldEditor:YES forObject:self]; - [editor setString:backupString]; + NSText * editor = [self.window fieldEditor:YES forObject:self]; + editor.string = backupString; } [self reloadData]; } @@ -438,12 +481,5 @@ - (void)cancelOperation:(id)sender -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - [backupString release]; - backupString=nil; - [grayGradient release]; - grayGradient=nil; - [blueGradient release]; - blueGradient=nil; - [super dealloc]; } @end diff --git a/src/FoldersFilterable.h b/src/FoldersFilterable.h new file mode 100644 index 0000000000..8ab3094df1 --- /dev/null +++ b/src/FoldersFilterable.h @@ -0,0 +1,30 @@ +// +// FoldersFilterable.h +// Vienna +// +// Created by wolf on 1/10/16. +// Copyright © 2016 uk.co.opencommunity. All rights reserved. +// + +@import Cocoa; + +@interface FoldersFilterableDataSource : NSObject { +@protected +__unsafe_unretained id _dataSource; +} + +- (instancetype)initWithDataSource:(id)dataSource /*NS_DESIGNATED_INITIALIZER*/; + +@end + +@interface FoldersFilterableDataSourceImpl : FoldersFilterableDataSource +- (void)setFilterPredicate:(NSPredicate*)predicate outlineView:(NSOutlineView*)outlineView; +- (void)reloadData:(NSOutlineView*)outlineView; +@end + +@interface NSOutlineView (MCStateSave) +@property (nonatomic) NSSet* selectionState; +@property (nonatomic) NSArray* expansionState; +@property (nonatomic) NSDictionary* scrollState; +@property (nonatomic) NSDictionary* state; +@end diff --git a/src/FoldersFilterable.m b/src/FoldersFilterable.m new file mode 100644 index 0000000000..8f6982b2fb --- /dev/null +++ b/src/FoldersFilterable.m @@ -0,0 +1,358 @@ +// +// FoldersFilterable.m +// Vienna +// +// Created by wolf on 1/10/16. +// Copyright © 2016 uk.co.opencommunity. All rights reserved. +// + +#import "FoldersFilterable.h" + +@implementation FoldersFilterableDataSource + +- (instancetype)initWithDataSource:(id )dataSource { + self = [super init]; + if (!self) + return nil; + + _dataSource = dataSource; + return self; +} + +- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item { + return [_dataSource outlineView:outlineView numberOfChildrenOfItem:item]; +} + +- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item { + return [_dataSource outlineView:outlineView child:index ofItem:item]; +} + +- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item { + return [_dataSource outlineView:outlineView isItemExpandable:item]; +} + +- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item { + return [_dataSource outlineView:outlineView objectValueForTableColumn:tableColumn byItem:item]; +} + +- (void)outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item { + [_dataSource outlineView:outlineView setObjectValue:object forTableColumn:tableColumn byItem:item]; +} + +- (id)outlineView:(NSOutlineView *)outlineView itemForPersistentObject:(id)object { + return [_dataSource outlineView:outlineView itemForPersistentObject:object]; +} + +- (id)outlineView:(NSOutlineView *)outlineView persistentObjectForItem:(id)item { + return [_dataSource outlineView:outlineView persistentObjectForItem:item]; +} + +- (void)outlineView:(NSOutlineView *)outlineView sortDescriptorsDidChange:(NSArray *)oldDescriptors { + [_dataSource outlineView:outlineView sortDescriptorsDidChange:oldDescriptors]; +} + +- (id )outlineView:(NSOutlineView *)outlineView pasteboardWriterForItem:(id)item { + return [_dataSource outlineView:outlineView pasteboardWriterForItem:item]; +} + +- (void)outlineView:(NSOutlineView *)outlineView draggingSession:(NSDraggingSession *)session willBeginAtPoint:(NSPoint)screenPoint forItems:(NSArray *)draggedItems { + [_dataSource outlineView:outlineView draggingSession:session willBeginAtPoint:screenPoint forItems:draggedItems]; +} + +- (void)outlineView:(NSOutlineView *)outlineView draggingSession:(NSDraggingSession *)session endedAtPoint:(NSPoint)screenPoint operation:(NSDragOperation)operation { + [_dataSource outlineView:outlineView draggingSession:session endedAtPoint:screenPoint operation:operation]; +} + +- (BOOL)outlineView:(NSOutlineView *)outlineView writeItems:(NSArray *)items toPasteboard:(NSPasteboard *)pasteboard { + return [_dataSource outlineView:outlineView writeItems:items toPasteboard:pasteboard]; +} + +- (void)outlineView:(NSOutlineView *)outlineView updateDraggingItemsForDrag:(id )draggingInfo { + [_dataSource outlineView:outlineView updateDraggingItemsForDrag:draggingInfo]; +} + +- (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id )info proposedItem:(id)item proposedChildIndex:(NSInteger)index { + return [_dataSource outlineView:outlineView validateDrop:info proposedItem:item proposedChildIndex:index]; +} + +- (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id )info item:(id)item childIndex:(NSInteger)index { + return [_dataSource outlineView:outlineView acceptDrop:info item:item childIndex:index]; +} + +- (NSArray *)outlineView:(NSOutlineView *)outlineView namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination forDraggedItems:(NSArray *)items { + return [_dataSource outlineView:outlineView namesOfPromisedFilesDroppedAtDestination:dropDestination forDraggedItems:items]; +} + +@end + +@implementation FoldersFilterableDataSourceImpl +{ + dispatch_queue_t _queue; + dispatch_queue_t _queueMap; + dispatch_group_t _loadGroup; + NSPredicate* _filterPredicate; + NSMapTable* _filtered; + NSUInteger _generation; + id _root; +} + +- (instancetype)initWithDataSource:(id)dataSource { + _queue = dispatch_queue_create("com.modclassic.MCFilterableDataSource", DISPATCH_QUEUE_CONCURRENT); + _queueMap = dispatch_queue_create("com.modclassic.MCFilterableDataSource.Map", DISPATCH_QUEUE_SERIAL); + _loadGroup = dispatch_group_create(); + _root = [NSNull null]; + return [super initWithDataSource:dataSource]; +} + +- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item { + if (_filterPredicate == nil) + return [_dataSource outlineView:outlineView numberOfChildrenOfItem:item]; + + if (item == nil) { + item = _root; + } + + dispatch_group_wait(_loadGroup, DISPATCH_TIME_FOREVER); + + NSArray* a = [_filtered objectForKey:item]; + if (a) { + return a.count; + } + + return 0; +} + +- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item { + if (_filterPredicate == nil) + return [_dataSource outlineView:outlineView child:index ofItem:item]; + + if (item == nil) { + item = _root; + } + + dispatch_group_wait(_loadGroup, DISPATCH_TIME_FOREVER); + + NSArray* a = [_filtered objectForKey:item]; + if (a) { + return a[index]; + } + + return nil; +} + +- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item { + if (_filterPredicate == nil) + return [_dataSource outlineView:outlineView isItemExpandable:item]; + + dispatch_group_wait(_loadGroup, DISPATCH_TIME_FOREVER); + + NSArray* a = [_filtered objectForKey:item]; + if (a) { + return a.count > 0; + } + + return NO; +} + +- (void)loadDataForItem:(NSOutlineView*)outlineView + item:(id)item + table:(NSMapTable*)table + container:(NSMutableArray*)array + generation:(NSUInteger)generation + predicate:(NSPredicate*)predicate + parentGroup:(dispatch_group_t)parentGroup { + dispatch_group_enter(parentGroup); + dispatch_async(_queue, ^{ + if (generation != _generation) { + dispatch_group_leave(parentGroup); + return; + } + + NSUInteger count = [_dataSource outlineView:outlineView numberOfChildrenOfItem:item]; + if (count == 0) { + if (![predicate evaluateWithObject:item]) { + dispatch_async(_queueMap, ^{ + [array removeObject:item]; + dispatch_group_leave(parentGroup); + }); + } + else { + dispatch_group_leave(parentGroup); + } + + return; + } + + dispatch_group_t childGroup = dispatch_group_create(); + NSMutableArray* childArray = [NSMutableArray array]; + BOOL hasSpinned = NO; + + for (NSUInteger index = 0; index < count; ++index) { + id child = [_dataSource outlineView:outlineView child:index ofItem:item]; + BOOL expandable = [_dataSource outlineView:outlineView isItemExpandable:child]; + + if (expandable) { + if (hasSpinned) { + dispatch_async(_queueMap, ^{ + [childArray addObject:child]; + }); + } + else { + [childArray addObject:child]; + } + + hasSpinned = YES; + [self loadDataForItem:outlineView + item:child + table:table + container:childArray + generation:generation + predicate:predicate + parentGroup:childGroup]; + } + else { + if ([predicate evaluateWithObject:child]) { + if (hasSpinned) { + dispatch_async(_queueMap, ^{ + [childArray addObject:child]; + }); + } + else { + [childArray addObject:child]; + } + } + } + } + + dispatch_group_notify(childGroup, _queueMap, ^{ + if ((childArray.count == 0) && (item != nil)) { + if (![predicate evaluateWithObject:item]) { + [array removeObject:item]; + } + } + else + [table setObject:childArray forKey:item? item: _root]; + + dispatch_group_leave(parentGroup); + }); + }); +} + +- (void)reloadData:(NSOutlineView*)outlineView { + if (_filterPredicate == nil) + return; + + _generation++; + + NSMapTable* filtered = [[NSMapTable alloc] initWithKeyOptions:NSMapTableStrongMemory + valueOptions:NSMapTableStrongMemory + capacity:0]; + + dispatch_async(_queueMap, ^{ + _filtered = filtered; + }); + + [self loadDataForItem:outlineView + item:nil + table:filtered + container:[NSMutableArray array] + generation:_generation + predicate:_filterPredicate + parentGroup:_loadGroup]; +} + +- (void)setFilterPredicate:(NSPredicate *)filterPredicate outlineView:(NSOutlineView*)outlineView { + _filterPredicate = filterPredicate; + [self reloadData:outlineView]; +} + +@end + + +@implementation NSOutlineView (MCStateSave) + +- (NSDictionary*)state { + return @{ + @"Selection": self.selectionState, + @"Expansion": self.expansionState, + @"Scroll": self.scrollState + }; +} + +- (void)setState:(NSDictionary*)state { + self.expansionState = state[@"Expansion"]; + self.selectionState = state[@"Selection"]; + self.scrollState = state[@"Scroll"]; +} + +- (NSDictionary*)scrollState { + NSClipView* clipView = (NSClipView*)self.superview; + if (![clipView isKindOfClass:[NSClipView class]]) + return @{}; + + NSScrollView* scrollView = (NSScrollView*)clipView.superview; + if (![scrollView isKindOfClass:[NSScrollView class]]) + return @{}; + + return @{ + @"VisibleRect": [NSValue valueWithRect:scrollView.documentVisibleRect] + }; +} + +- (void)setScrollState:(NSDictionary*)state { + NSValue* rectValue = state[@"VisibleRect"]; + if (!rectValue) + return; + + [self scrollPoint:rectValue.rectValue.origin]; +} + +- (NSSet*)selectionState { + NSMutableSet* selectedItems = [NSMutableSet set]; + NSInteger numberOfRows = self.numberOfRows; + + for (NSInteger row = 0; row < numberOfRows; row++) { + if ([self isRowSelected:row]) { + [selectedItems addObject:[self itemAtRow:row]]; + } + } + + return [selectedItems copy]; +} + +- (void)setSelectionState:(NSSet*)newSelection { + NSMutableIndexSet* indexes = [NSMutableIndexSet indexSet]; + + for (id wanted in newSelection) { + NSInteger index = [self rowForItem:wanted]; + if (index < 0) + continue; + + [indexes addIndex:index]; + } + + [self selectRowIndexes:indexes byExtendingSelection:NO]; +} + +- (NSArray*)expansionState { + NSMutableArray* expandedItems = [NSMutableArray array]; + NSInteger numberOfRows = self.numberOfRows; + + for (NSInteger row = 0; row < numberOfRows; row++) { + id item = [self itemAtRow:row]; + + if ([self isItemExpanded:item]) { + [expandedItems addObject:item]; + } + } + + return [expandedItems copy]; +} + +- (void)setExpansionState:(NSArray*)newExpansion { + for (id wanted in newExpansion) { + [self expandItem:wanted]; + } +} + +@end diff --git a/src/FoldersTree.h b/src/FoldersTree.h index 8a2cd21c2f..f0b393db14 100644 --- a/src/FoldersTree.h +++ b/src/FoldersTree.h @@ -27,7 +27,7 @@ @class AppController; @class Database; -@interface FoldersTree : NSView +@interface FoldersTree : NSView { IBOutlet AppController * controller; IBOutlet FolderView * outlineView; @@ -47,18 +47,20 @@ -(void)initialiseFoldersTree; -(void)saveFolderSettings; -(void)updateAlternateMenuTitle; --(void)updateFolder:(int)folderId recurseToParents:(BOOL)recurseToParents; --(BOOL)canDeleteFolderAtRow:(int)row; --(BOOL)selectFolder:(int)folderId; --(void)renameFolder:(int)folderId; --(int)actualSelection; +-(void)updateFolder:(NSInteger)folderId recurseToParents:(BOOL)recurseToParents; +-(BOOL)canDeleteFolderAtRow:(NSInteger)row; +-(BOOL)selectFolder:(NSInteger)folderId; +-(void)renameFolder:(NSInteger)folderId; +@property (nonatomic, readonly) NSInteger actualSelection; -(void)setOutlineViewBackgroundColor: (NSColor *)color; --(int)groupParentSelection; --(int)countOfSelectedFolders; --(NSArray *)selectedFolders; --(int)firstFolderWithUnread; --(int)nextFolderWithUnread:(int)currentFolderId; --(NSArray *)folders:(int)folderId; --(NSView *)mainView; +@property (nonatomic, readonly) NSInteger groupParentSelection; +@property (nonatomic, readonly) NSInteger countOfSelectedFolders; +@property (nonatomic, readonly, copy) NSArray *selectedFolders; +@property (nonatomic, readonly) NSInteger firstFolderWithUnread; +-(NSInteger)nextFolderWithUnread:(NSInteger)currentFolderId; +-(NSArray *)folders:(NSInteger)folderId; +-(NSArray *)children:(NSInteger)folderId; +@property (nonatomic, readonly, strong) NSView *mainView; -(void)outlineViewWillBecomeFirstResponder; +-(void)setSearch:(NSString *)string; @end diff --git a/src/FoldersTree.m b/src/FoldersTree.m index e06a208a42..1001066f41 100644 --- a/src/FoldersTree.m +++ b/src/FoldersTree.m @@ -34,7 +34,7 @@ // Private functions @interface FoldersTree (Private) -(void)setFolderListFont; - -(NSArray *)archiveState; + @property (nonatomic, readonly, copy) NSArray *archiveState; -(void)unarchiveState:(NSArray *)stateArray; -(void)reloadDatabase:(NSArray *)stateArray; -(BOOL)loadTree:(NSArray *)listOfFolders rootNode:(TreeNode *)node; @@ -60,7 +60,7 @@ @implementation FoldersTree /* initWithFrame * Initialise ourself. */ --(id)initWithFrame:(NSRect)frameRect +-(instancetype)initWithFrame:(NSRect)frameRect { if ((self = [super initWithFrame:frameRect]) != nil) { @@ -86,9 +86,9 @@ -(void)awakeFromNib // Our folders have images next to them. tableColumn = [outlineView tableColumnWithIdentifier:@"folderColumns"]; - imageAndTextCell = [[[ImageAndTextCell alloc] init] autorelease]; + imageAndTextCell = [[ImageAndTextCell alloc] init]; [imageAndTextCell setEditable:YES]; - [tableColumn setDataCell:imageAndTextCell]; + tableColumn.dataCell = imageAndTextCell; // Folder image folderErrorImage = [NSImage imageNamed:@"folderError.tiff"]; @@ -99,12 +99,12 @@ -(void)awakeFromNib [self setFolderListFont]; // Set background colour - [outlineView setBackgroundColor:[NSColor colorWithCalibratedRed:0.84 green:0.87 blue:0.90 alpha:1.00]]; + outlineView.backgroundColor = [NSColor colorWithCalibratedRed:0.84 green:0.87 blue:0.90 alpha:1.00]; // Allow a second click in a node to edit the node - [outlineView setAction:@selector(handleSingleClick:)]; - [outlineView setDoubleAction:@selector(handleDoubleClick:)]; - [outlineView setTarget:self]; + outlineView.action = @selector(handleSingleClick:); + outlineView.doubleAction = @selector(handleDoubleClick:); + outlineView.target = self; // Initially size the outline view column to be the correct width [outlineView sizeLastColumnToFit]; @@ -114,11 +114,11 @@ -(void)awakeFromNib [outlineView setAutoresizesOutlineColumn:NO]; // Register for dragging - [outlineView registerForDraggedTypes:[NSArray arrayWithObjects:MA_PBoardType_FolderList, MA_PBoardType_RSSSource, @"WebURLsWithTitlesPboardType", NSStringPboardType, nil]]; + [outlineView registerForDraggedTypes:@[MA_PBoardType_FolderList, MA_PBoardType_RSSSource, @"WebURLsWithTitlesPboardType", NSStringPboardType]]; [outlineView setVerticalMotionCanBeginDrag:YES]; // Make sure selected row is visible - [outlineView scrollRowToVisible:[outlineView selectedRow]]; + [outlineView scrollRowToVisible:outlineView.selectedRow]; [outlineView accessibilitySetOverrideValue:NSLocalizedString(@"Folders", nil) forAttribute:NSAccessibilityDescriptionAttribute]; } @@ -129,7 +129,7 @@ -(void)awakeFromNib -(void)setOutlineViewBackgroundColor: (NSColor *)color; { - [outlineView setBackgroundColor: color]; + outlineView.backgroundColor = color; } /* initialiseFoldersTree @@ -141,7 +141,7 @@ -(void)initialiseFoldersTree [outlineView setEnableTooltips:YES]; // Set the menu for the popup button - [outlineView setMenu:[APPCONTROLLER folderMenu]]; + outlineView.menu = APPCONTROLLER.folderMenu; blockSelectionHandler = YES; [self reloadDatabase:[[Preferences standardPreferences] arrayForKey:MAPref_FolderStates]]; @@ -163,7 +163,7 @@ -(void)handleGRSFolderChange:(NSNotification *)nc { // No need to sync with Google because this is triggered when Open Reader // folder layout has changed. Making a sync call would be redundant. - [self moveFolders:[nc object] withGoogleSync:NO]; + [self moveFolders:nc.object withGoogleSync:NO]; } /* handleFolderFontChange @@ -181,18 +181,16 @@ -(void)handleFolderFontChange:(NSNotification *)nc */ -(void)setFolderListFont { - int height; + NSInteger height; - [cellFont release]; - [boldCellFont release]; Preferences * prefs = [Preferences standardPreferences]; - cellFont = [[NSFont fontWithName:[prefs folderListFont] size:[prefs folderListFontSize]] retain]; - boldCellFont = [[[NSFontManager sharedFontManager] convertWeight:YES ofFont:cellFont] retain]; + cellFont = [NSFont fontWithName:prefs.folderListFont size:prefs.folderListFontSize]; + boldCellFont = [[NSFontManager sharedFontManager] convertWeight:YES ofFont:cellFont]; - height = [[APPCONTROLLER layoutManager] defaultLineHeightForFont:boldCellFont]; - [outlineView setRowHeight:height + 5]; - [outlineView setIntercellSpacing:NSMakeSize(10, 2)]; + height = [APPCONTROLLER.layoutManager defaultLineHeightForFont:boldCellFont]; + outlineView.rowHeight = height + 5; + outlineView.intercellSpacing = NSMakeSize(10, 2); } /* reloadDatabase @@ -201,11 +199,11 @@ -(void)setFolderListFont -(void)reloadDatabase:(NSArray *)stateArray { [rootNode removeChildren]; - if (![self loadTree:[[Database sharedDatabase] arrayOfFolders:MA_Root_Folder] rootNode:rootNode]) + if (![self loadTree:[[Database sharedManager] arrayOfFolders:MA_Root_Folder] rootNode:rootNode]) { [[Preferences standardPreferences] setFoldersTreeSortMethod:MA_FolderSort_ByName]; [rootNode removeChildren]; - [self loadTree:[[Database sharedDatabase] arrayOfFolders:MA_Root_Folder] rootNode:rootNode]; + [self loadTree:[[Database sharedManager] arrayOfFolders:MA_Root_Folder] rootNode:rootNode]; } [outlineView reloadData]; [self unarchiveState:stateArray]; @@ -217,7 +215,7 @@ -(void)reloadDatabase:(NSArray *)stateArray */ -(void)saveFolderSettings { - [[Preferences standardPreferences] setArray:[self archiveState] forKey:MAPref_FolderStates]; + [[Preferences standardPreferences] setArray:self.archiveState forKey:MAPref_FolderStates]; } /* archiveState @@ -226,8 +224,8 @@ -(void)saveFolderSettings -(NSArray *)archiveState { NSMutableArray * archiveArray = [NSMutableArray arrayWithCapacity:16]; - int count = [outlineView numberOfRows]; - int index; + NSInteger count = outlineView.numberOfRows; + NSInteger index; for (index = 0; index < count; ++index) { @@ -238,13 +236,13 @@ -(NSArray *)archiveState if (isItemExpanded || isItemSelected) { NSDictionary * newDict = [NSMutableDictionary dictionary]; - [newDict setValue:[NSNumber numberWithInt:[node nodeId]] forKey:@"NodeID"]; - [newDict setValue:[NSNumber numberWithBool:isItemExpanded] forKey:@"ExpandedState"]; - [newDict setValue:[NSNumber numberWithBool:isItemSelected] forKey:@"SelectedState"]; + [newDict setValue:@(node.nodeId) forKey:@"NodeID"]; + [newDict setValue:@(isItemExpanded) forKey:@"ExpandedState"]; + [newDict setValue:@(isItemSelected) forKey:@"SelectedState"]; [archiveArray addObject:newDict]; } } - return archiveArray; + return [archiveArray copy]; } /* unarchiveState @@ -255,7 +253,7 @@ -(void)unarchiveState:(NSArray *)stateArray { for (NSDictionary * dict in stateArray) { - int folderId = [[dict valueForKey:@"NodeID"] intValue]; + NSInteger folderId = [[dict valueForKey:@"NodeID"] integerValue]; TreeNode * node = [rootNode nodeFromID:folderId]; if (node != nil) { @@ -265,10 +263,10 @@ -(void)unarchiveState:(NSArray *)stateArray [outlineView expandItem:node]; if (doSelectItem) { - int row = [outlineView rowForItem:node]; + NSInteger row = [outlineView rowForItem:node]; if (row >= 0) { - NSIndexSet * indexes = [NSIndexSet indexSetWithIndex:(NSUInteger )row]; + NSIndexSet * indexes = [NSIndexSet indexSetWithIndex:(NSUInteger)row]; [outlineView selectRowIndexes:indexes byExtendingSelection:YES]; } } @@ -283,38 +281,37 @@ -(void)unarchiveState:(NSArray *)stateArray -(BOOL)loadTree:(NSArray *)listOfFolders rootNode:(TreeNode *)node { Folder * folder; - if ([[Preferences standardPreferences] foldersTreeSortMethod] != MA_FolderSort_Manual) + if ([Preferences standardPreferences].foldersTreeSortMethod != MA_FolderSort_Manual) { for (folder in listOfFolders) { - int itemId = [folder itemId]; - NSArray * listOfSubFolders = [[Database sharedDatabase] arrayOfFolders:itemId]; - int count = [listOfSubFolders count]; + NSInteger itemId = folder.itemId; + NSArray * listOfSubFolders = [[[Database sharedManager] arrayOfFolders:itemId] sortedArrayUsingSelector:@selector(folderNameCompare:)]; + NSInteger count = listOfSubFolders.count; TreeNode * subNode; subNode = [[TreeNode alloc] init:node atIndex:-1 folder:folder canHaveChildren:(count > 0)]; if (count) [self loadTree:listOfSubFolders rootNode:subNode]; - [subNode release]; } } else { NSArray * listOfFolderIds = [listOfFolders valueForKey:@"itemId"]; NSUInteger index = 0; - NSInteger nextChildId = (node == rootNode) ? [[Database sharedDatabase] firstFolderId] : [[node folder] firstChildId]; + NSInteger nextChildId = (node == rootNode) ? [Database sharedManager].firstFolderId : node.folder.firstChildId; while (nextChildId > 0) { - NSUInteger listIndex = [listOfFolderIds indexOfObject:[NSNumber numberWithInt:nextChildId]]; + NSUInteger listIndex = [listOfFolderIds indexOfObject:@(nextChildId)]; if (listIndex == NSNotFound) { - NSLog(@"Cannot find child with id %ld for folder with id %ld", (long)nextChildId, (long)[node nodeId]); + NSLog(@"Cannot find child with id %ld for folder with id %ld", (long)nextChildId, (long)node.nodeId); return NO; } - folder = [listOfFolders objectAtIndex:listIndex]; - NSArray * listOfSubFolders = [[Database sharedDatabase] arrayOfFolders:nextChildId]; - NSUInteger count = [listOfSubFolders count]; + folder = listOfFolders[listIndex]; + NSArray * listOfSubFolders = [[Database sharedManager] arrayOfFolders:nextChildId]; + NSUInteger count = listOfSubFolders.count; TreeNode * subNode; subNode = [[TreeNode alloc] init:node atIndex:index folder:folder canHaveChildren:(count > 0)]; @@ -322,17 +319,15 @@ -(BOOL)loadTree:(NSArray *)listOfFolders rootNode:(TreeNode *)node { if (![self loadTree:listOfSubFolders rootNode:subNode]) { - [subNode release]; return NO; } } - [subNode release]; - nextChildId = [folder nextSiblingId]; + nextChildId = folder.nextSiblingId; ++index; } - if (index < [listOfFolders count]) + if (index < listOfFolders.count) { - NSLog(@"Missing children for folder with id %ld, %ld", (long)nextChildId, (long)[node nodeId]); + NSLog(@"Missing children for folder with id %ld, %ld", (long)nextChildId, (long)node.nodeId); return NO; } } @@ -343,7 +338,7 @@ -(BOOL)loadTree:(NSArray *)listOfFolders rootNode:(TreeNode *)node * Returns an array that contains the all RSS folders in the database * ordered by the order in which they appear in the folders list view. */ --(NSArray *)folders:(int)folderId +-(NSArray *)folders:(NSInteger)folderId { NSMutableArray * array = [NSMutableArray array]; TreeNode * node; @@ -352,15 +347,37 @@ -(NSArray *)folders:(int)folderId node = rootNode; else node = [rootNode nodeFromID:folderId]; - if ([node folder] != nil && (IsRSSFolder([node folder]) || IsGoogleReaderFolder([node folder]))) - [array addObject:[node folder]]; - node = [node firstChild]; + if (node.folder != nil && (IsRSSFolder([node folder]) || IsGoogleReaderFolder([node folder]))) + [array addObject:node.folder]; + node = node.firstChild; while (node != nil) { - [array addObjectsFromArray:[self folders:[node nodeId]]]; - node = [node nextSibling]; + [array addObjectsFromArray:[self folders:node.nodeId]]; + node = node.nextSibling; } - return array; + return [array copy]; +} + +/* children + * Returns an array that contains the children folders in the database + * ordered by the order in which they appear in the folders list view. + */ +-(NSArray *)children:(NSInteger)folderId +{ + NSMutableArray * array = [NSMutableArray array]; + TreeNode * node; + + if (!folderId) + node = rootNode; + else + node = [rootNode nodeFromID:folderId]; + node = node.firstChild; + while (node != nil) + { + [array addObject:node.folder]; + node = node.nextSibling; + } + return [array copy]; } /* updateAlternateMenuTitle @@ -372,16 +389,16 @@ -(void)updateAlternateMenuTitle NSMenuItem * mainMenuItem = menuItemWithAction(@selector(viewSourceHomePageInAlternateBrowser:)); if (mainMenuItem == nil) return; - NSString * menuTitle = [mainMenuItem title]; - int index; - NSMenu * folderMenu = [outlineView menu]; + NSString * menuTitle = mainMenuItem.title; + NSInteger index; + NSMenu * folderMenu = outlineView.menu; if (folderMenu != nil) { index = [folderMenu indexOfItemWithTarget:nil andAction:@selector(viewSourceHomePageInAlternateBrowser:)]; if (index >= 0) { NSMenuItem * contextualItem = [folderMenu itemAtIndex:index]; - [contextualItem setTitle:menuTitle]; + contextualItem.title = menuTitle; } } } @@ -390,7 +407,7 @@ -(void)updateAlternateMenuTitle * Redraws a folder node and optionally recurses up and redraws all our * parent nodes too. */ --(void)updateFolder:(int)folderId recurseToParents:(BOOL)recurseToParents +-(void)updateFolder:(NSInteger)folderId recurseToParents:(BOOL)recurseToParents { TreeNode * node = [rootNode nodeFromID:folderId]; if (node != nil) @@ -398,9 +415,9 @@ -(void)updateFolder:(int)folderId recurseToParents:(BOOL)recurseToParents [outlineView reloadItem:node reloadChildren:YES]; if (recurseToParents) { - while ([node parentNode] != rootNode) + while (node.parentNode != rootNode) { - node = [node parentNode]; + node = node.parentNode; [outlineView reloadItem:node]; } } @@ -410,15 +427,15 @@ -(void)updateFolder:(int)folderId recurseToParents:(BOOL)recurseToParents /* canDeleteFolderAtRow * Returns YES if the folder at the specified row can be deleted, otherwise NO. */ --(BOOL)canDeleteFolderAtRow:(int)row +-(BOOL)canDeleteFolderAtRow:(NSInteger)row { if (row >= 0) { TreeNode * node = [outlineView itemAtRow:row]; if (node != nil) { - Folder * folder = [[Database sharedDatabase] folderFromID:[node nodeId]]; - return folder && !IsSearchFolder(folder) && !IsTrashFolder(folder) && ![[Database sharedDatabase] readOnly] && [[outlineView window] isVisible]; + Folder * folder = [[Database sharedManager] folderFromID:node.nodeId]; + return folder && !IsSearchFolder(folder) && !IsTrashFolder(folder) && ![Database sharedManager].readOnly && outlineView.window.visible; } } return NO; @@ -428,7 +445,7 @@ -(BOOL)canDeleteFolderAtRow:(int)row * Move the selection to the specified folder and make sure * it's visible in the UI. */ --(BOOL)selectFolder:(int)folderId +-(BOOL)selectFolder:(NSInteger)folderId { TreeNode * node = [rootNode nodeFromID:folderId]; if (!node) @@ -436,11 +453,11 @@ -(BOOL)selectFolder:(int)folderId // Walk up to our parent [self expandToParent:node]; - int rowIndex = [outlineView rowForItem:node]; + NSInteger rowIndex = [outlineView rowForItem:node]; if (rowIndex >= 0) { blockSelectionHandler = YES; - [outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:(NSUInteger )rowIndex] byExtendingSelection:NO]; + [outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:(NSUInteger)rowIndex] byExtendingSelection:NO]; [outlineView scrollRowToVisible:rowIndex]; [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_FolderSelectionChange" object:node]; @@ -456,10 +473,10 @@ -(BOOL)selectFolder:(int)folderId */ -(void)expandToParent:(TreeNode *)node { - if ([node parentNode]) + if (node.parentNode) { - [self expandToParent:[node parentNode]]; - [outlineView expandItem:[node parentNode]]; + [self expandToParent:node.parentNode]; + [outlineView expandItem:node.parentNode]; } } @@ -467,36 +484,45 @@ -(void)expandToParent:(TreeNode *)node * Finds the ID of the next folder after the specified node that has * unread articles. */ --(int)nextFolderWithUnreadAfterNode:(TreeNode *)startingNode +-(NSInteger)nextFolderWithUnreadAfterNode:(TreeNode *)startingNode { + // keep track of parent (or grandparent) of starting node + TreeNode * parentOfStartingNode = startingNode; + while (parentOfStartingNode.parentNode != rootNode) + { + parentOfStartingNode = parentOfStartingNode.parentNode; + } TreeNode * node = startingNode; while (node != nil) { TreeNode * nextNode = nil; - TreeNode * parentNode = [node parentNode]; - if (([[node folder] childUnreadCount] > 0) && [outlineView isItemExpanded:node]) - nextNode = [node firstChild]; + TreeNode * parentNode = node.parentNode; + if ((node.folder.childUnreadCount > 0) && [outlineView isItemExpanded:node]) + nextNode = node.firstChild; if (nextNode == nil) - nextNode = [node nextSibling]; + nextNode = node.nextSibling; while (nextNode == nil && parentNode != nil) { - nextNode = [parentNode nextSibling]; - parentNode = [parentNode parentNode]; + nextNode = parentNode.nextSibling; + parentNode = parentNode.parentNode; } if (nextNode == nil) - nextNode = [rootNode firstChild]; + nextNode = rootNode.firstChild; - if (([[nextNode folder] childUnreadCount]) && ![outlineView isItemExpanded:nextNode]) - return [nextNode nodeId]; + if ((nextNode.folder.childUnreadCount) && ![outlineView isItemExpanded:nextNode]) + return nextNode.nodeId; - if ([[nextNode folder] unreadCount]) - return [nextNode nodeId]; + if (nextNode.folder.unreadCount) + return nextNode.nodeId; // If we've gone full circle and not found // anything, we're out of unread articles - if (nextNode == startingNode) - return [startingNode nodeId]; + if (nextNode == startingNode + || (nextNode == parentOfStartingNode && !nextNode.folder.childUnreadCount)) + { + return startingNode.nodeId; + } node = nextNode; } @@ -506,13 +532,13 @@ -(int)nextFolderWithUnreadAfterNode:(TreeNode *)startingNode /* firstFolderWithUnread * Finds the ID of the first folder that has unread articles. */ --(int)firstFolderWithUnread +-(NSInteger)firstFolderWithUnread { // Get the first Node from the root node. - TreeNode * firstNode = [rootNode firstChild]; + TreeNode * firstNode = rootNode.firstChild; // Now get the ID of the next unread node after it and return it. - int nextNodeID = [self nextFolderWithUnreadAfterNode:firstNode]; + NSInteger nextNodeID = [self nextFolderWithUnreadAfterNode:firstNode]; return nextNodeID; } @@ -520,13 +546,13 @@ -(int)firstFolderWithUnread * Finds the ID of the next folder after currentFolderId that has * unread articles. */ --(int)nextFolderWithUnread:(int)currentFolderId +-(NSInteger)nextFolderWithUnread:(NSInteger)currentFolderId { // Get the current Node from the ID. TreeNode * currentNode = [rootNode nodeFromID:currentFolderId]; // Now get the ID of the next unread node after it and return it. - int nextNodeID = [self nextFolderWithUnreadAfterNode:currentNode]; + NSInteger nextNodeID = [self nextFolderWithUnreadAfterNode:currentNode]; return nextNodeID; } @@ -534,27 +560,27 @@ -(int)nextFolderWithUnread:(int)currentFolderId * If the selected folder is a group folder, it returns the ID of the group folder * otherwise it returns the ID of the parent folder. */ --(int)groupParentSelection +-(NSInteger)groupParentSelection { - Folder * folder = [[Database sharedDatabase] folderFromID:[self actualSelection]]; - return folder ? ((IsGroupFolder(folder)) ? [folder itemId] : [folder parentId]) : MA_Root_Folder; + Folder * folder = [[Database sharedManager] folderFromID:self.actualSelection]; + return folder ? ((IsGroupFolder(folder)) ? folder.itemId : folder.parentId) : MA_Root_Folder; } /* actualSelection * Return the ID of the selected folder in the folder list. */ --(int)actualSelection +-(NSInteger)actualSelection { - TreeNode * node = [outlineView itemAtRow:[outlineView selectedRow]]; - return [node nodeId]; + TreeNode * node = [outlineView itemAtRow:outlineView.selectedRow]; + return node.nodeId; } /* countOfSelectedFolders * Return the total number of folders selected in the tree. */ --(int)countOfSelectedFolders +-(NSInteger)countOfSelectedFolders { - return [outlineView numberOfSelectedRows]; + return outlineView.numberOfSelectedRows; } /* selectedFolders @@ -563,19 +589,19 @@ -(int)countOfSelectedFolders */ -(NSArray *)selectedFolders { - NSIndexSet * rowIndexes = [outlineView selectedRowIndexes]; - NSUInteger count = [rowIndexes count]; + NSIndexSet * rowIndexes = outlineView.selectedRowIndexes; + NSUInteger count = rowIndexes.count; // Make a mutable array NSMutableArray * arrayOfSelectedFolders = [NSMutableArray arrayWithCapacity:count]; if (count > 0) { - NSUInteger index = [rowIndexes firstIndex]; + NSUInteger index = rowIndexes.firstIndex; while (index != NSNotFound) { TreeNode * node = [outlineView itemAtRow:index]; - Folder * folder = [node folder]; + Folder * folder = node.folder; if (folder != nil) { [arrayOfSelectedFolders addObject:folder]; @@ -584,7 +610,7 @@ -(NSArray *)selectedFolders } } - return arrayOfSelectedFolders; + return [arrayOfSelectedFolders copy]; } /* setManualSortOrderForNode @@ -592,26 +618,29 @@ -(NSArray *)selectedFolders */ -(void)setManualSortOrderForNode:(TreeNode *)node { - if (node == nil) + if (node == nil) { return; - Database * db = [Database sharedDatabase]; - int folderId = [node nodeId]; + } + NSInteger folderId = node.nodeId; + Database *dbManager = [Database sharedManager]; - int count = [node countOfChildren]; + NSInteger count = node.countOfChildren; if (count > 0) { - [db setFirstChild:[[node childByIndex:0] nodeId] forFolder:folderId]; + + [dbManager setFirstChild:[node childByIndex:0].nodeId forFolder:folderId]; [self setManualSortOrderForNode:[node childByIndex:0]]; - int index; + NSInteger index; for (index = 1; index < count; ++index) { - [db setNextSibling:[[node childByIndex:index] nodeId] forFolder:[[node childByIndex:index - 1] nodeId]]; + [dbManager setNextSibling:[node childByIndex:index].nodeId forFolder:[node childByIndex:index - 1].nodeId]; [self setManualSortOrderForNode:[node childByIndex:index]]; } - [db setNextSibling:0 forFolder:[[node childByIndex:index - 1] nodeId]]; + [dbManager setNextSibling:0 forFolder:[node childByIndex:index - 1].nodeId]; } - else - [db setFirstChild:0 forFolder:folderId]; + else { + [dbManager setFirstChild:0 forFolder:folderId]; + } } /* handleAutoSortFoldersTreeChange @@ -619,14 +648,11 @@ -(void)setManualSortOrderForNode:(TreeNode *)node */ -(void)handleAutoSortFoldersTreeChange:(NSNotification *)nc { - int selectedFolderId = [self actualSelection]; + NSInteger selectedFolderId = self.actualSelection; - if ([[Preferences standardPreferences] foldersTreeSortMethod] == MA_FolderSort_Manual) + if ([Preferences standardPreferences].foldersTreeSortMethod == MA_FolderSort_Manual) { - Database * db = [Database sharedDatabase]; - [db doTransactionWithBlock:^(BOOL *rollback) { - [self setManualSortOrderForNode:rootNode]; - }]; //end transaction block + [self setManualSortOrderForNode:rootNode]; } blockSelectionHandler = YES; @@ -652,7 +678,7 @@ -(void)handleSingleClick:(id)sender { if (canRenameFolders) { - int clickedRow = [outlineView clickedRow]; + NSInteger clickedRow = outlineView.clickedRow; if (clickedRow >= 0) [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(renameFolderByTimer:) userInfo:[outlineView itemAtRow:clickedRow] repeats:NO]; } @@ -666,12 +692,12 @@ -(void)handleDoubleClick:(id)sender // Prevent the first click of the double click from triggering immediate folder name editing. [self enableFoldersRenamingAfterDelay]; - TreeNode * node = [outlineView itemAtRow:[outlineView selectedRow]]; + TreeNode * node = [outlineView itemAtRow:outlineView.selectedRow]; if (IsRSSFolder([node folder])||IsGoogleReaderFolder([node folder])) { - NSString * urlString = [[node folder] homePage]; - if (urlString && ![urlString isBlank]) + NSString * urlString = node.folder.homePage; + if (urlString && !urlString.blank) [APPCONTROLLER openURLFromString:urlString inPreferredBrowser:YES]; } else if (IsSmartFolder([node folder])) @@ -687,8 +713,8 @@ -(void)handleDoubleClick:(id)sender */ -(void)handleFolderDeleted:(NSNotification *)nc { - int currentFolderId = [controller currentFolderId]; - int folderId = [(NSNumber *)[nc object] intValue]; + NSInteger currentFolderId = controller.currentFolderId; + NSInteger folderId = ((NSNumber *)nc.object).integerValue; TreeNode * thisNode = [rootNode nodeFromID:folderId]; TreeNode * nextNode; @@ -696,17 +722,17 @@ -(void)handleFolderDeleted:(NSNotification *)nc [thisNode stopAndReleaseProgressIndicator]; // First find the next node we'll select - if ([thisNode nextSibling] != nil) - nextNode = [thisNode nextSibling]; + if (thisNode.nextSibling != nil) + nextNode = thisNode.nextSibling; else { - nextNode = [thisNode parentNode]; - if ([nextNode countOfChildren] > 1) - nextNode = [nextNode childByIndex:[nextNode countOfChildren] - 2]; + nextNode = thisNode.parentNode; + if (nextNode.countOfChildren > 1) + nextNode = [nextNode childByIndex:nextNode.countOfChildren - 2]; } // Ask our parent to delete us - TreeNode * ourParent = [thisNode parentNode]; + TreeNode * ourParent = thisNode.parentNode; [ourParent removeChild:thisNode andChildren:YES]; [self reloadFolderItem:ourParent reloadChildren:YES]; @@ -716,7 +742,7 @@ -(void)handleFolderDeleted:(NSNotification *)nc if (currentFolderId == folderId) { blockSelectionHandler = YES; - [self selectFolder:[nextNode nodeId]]; + [self selectFolder:nextNode.nodeId]; [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_FolderSelectionChange" object:nextNode]; blockSelectionHandler = NO; } @@ -728,23 +754,23 @@ -(void)handleFolderDeleted:(NSNotification *)nc */ -(void)handleFolderNameChange:(NSNotification *)nc { - int folderId = [(NSNumber *)[nc object] intValue]; + NSInteger folderId = ((NSNumber *)nc.object).integerValue; TreeNode * node = [rootNode nodeFromID:folderId]; - TreeNode * parentNode = [node parentNode]; + TreeNode * parentNode = node.parentNode; - BOOL moveSelection = (folderId == [self actualSelection]); + BOOL moveSelection = (folderId == self.actualSelection); - if ([[Preferences standardPreferences] foldersTreeSortMethod] == MA_FolderSort_ByName) + if ([Preferences standardPreferences].foldersTreeSortMethod == MA_FolderSort_ByName) [parentNode sortChildren:MA_FolderSort_ByName]; [self reloadFolderItem:parentNode reloadChildren:YES]; if (moveSelection) { - int row = [outlineView rowForItem:node]; + NSInteger row = [outlineView rowForItem:node]; if (row >= 0) { blockSelectionHandler = YES; - NSIndexSet * indexes = [NSIndexSet indexSetWithIndex:(NSUInteger )row]; + NSIndexSet * indexes = [NSIndexSet indexSetWithIndex:(NSUInteger)row]; [outlineView selectRowIndexes:indexes byExtendingSelection:NO]; [outlineView scrollRowToVisible:row]; blockSelectionHandler = NO; @@ -758,7 +784,7 @@ -(void)handleFolderNameChange:(NSNotification *)nc */ -(void)handleFolderUpdate:(NSNotification *)nc { - int folderId = [(NSNumber *)[nc object] intValue]; + NSInteger folderId = ((NSNumber *)nc.object).integerValue; if (folderId == 0) [self reloadFolderItem:rootNode reloadChildren:YES]; else @@ -770,18 +796,18 @@ -(void)handleFolderUpdate:(NSNotification *)nc */ -(void)handleFolderAdded:(NSNotification *)nc { - Folder * newFolder = (Folder *)[nc object]; + Folder * newFolder = (Folder *)nc.object; NSAssert(newFolder, @"Somehow got a NULL folder object here"); - int parentId = [newFolder parentId]; + NSInteger parentId = newFolder.parentId; TreeNode * node = (parentId == MA_Root_Folder) ? rootNode : [rootNode nodeFromID:parentId]; - if (![node canHaveChildren]) + if (!node.canHaveChildren) [node setCanHaveChildren:YES]; - int childIndex = -1; - if ([[Preferences standardPreferences] foldersTreeSortMethod] == MA_FolderSort_Manual) + NSInteger childIndex = -1; + if ([Preferences standardPreferences].foldersTreeSortMethod == MA_FolderSort_Manual) { - int nextSiblingId = [newFolder nextSiblingId]; + NSInteger nextSiblingId = newFolder.nextSiblingId; if (nextSiblingId > 0) { TreeNode * nextSibling = [node nodeFromID:nextSiblingId]; @@ -790,9 +816,9 @@ -(void)handleFolderAdded:(NSNotification *)nc } } - TreeNode * newNode = [[TreeNode alloc] init:node atIndex:childIndex folder:newFolder canHaveChildren:NO]; + TreeNode __unused * newNode = [[TreeNode alloc] init:node atIndex:childIndex folder:newFolder canHaveChildren:NO]; [self reloadFolderItem:node reloadChildren:YES]; - [newNode release]; + [self selectFolder:newFolder.itemId]; } /* reloadFolderItem @@ -813,12 +839,12 @@ -(void)reloadFolderItem:(id)node reloadChildren:(BOOL)flag */ -(void)outlineView:(FolderView *)olv menuWillAppear:(NSEvent *)theEvent { - int row = [olv rowAtPoint:[olv convertPoint:[theEvent locationInWindow] fromView:nil]]; + NSInteger row = [olv rowAtPoint:[olv convertPoint:theEvent.locationInWindow fromView:nil]]; if (row >= 0) { // Select the row under the cursor if it isn't already selected - if ([olv numberOfSelectedRows] <= 1) - [olv selectRowIndexes:[NSIndexSet indexSetWithIndex:(NSUInteger )row] byExtendingSelection:NO]; + if (olv.numberOfSelectedRows <= 1) + [olv selectRowIndexes:[NSIndexSet indexSetWithIndex:(NSUInteger)row] byExtendingSelection:NO]; } } @@ -831,24 +857,24 @@ -(BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item TreeNode * node = (TreeNode *)item; if (node == nil) node = rootNode; - return [node canHaveChildren]; + return node.canHaveChildren; } /* numberOfChildrenOfItem * Returns the number of children belonging to the specified item */ --(int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item +-(NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item { TreeNode * node = (TreeNode *)item; if (node == nil) node = rootNode; - return [node countOfChildren]; + return node.countOfChildren; } /* child * Returns the child at the specified offset of the item */ --(id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item +-(id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item { TreeNode * node = (TreeNode *)item; if (node == nil) @@ -864,10 +890,10 @@ -(NSString *)outlineView:(FolderView *)outlineView tooltipForItem:(id)item TreeNode * node = (TreeNode *)item; if (node != nil) { - if ([[node folder] nonPersistedFlags] & MA_FFlag_Error) + if (node.folder.nonPersistedFlags & MA_FFlag_Error) return NSLocalizedString(@"An error occurred when this feed was last refreshed", nil); - if ([[node folder] childUnreadCount]) - return [NSString stringWithFormat:NSLocalizedString(@"%d unread articles", nil), [[node folder] childUnreadCount]]; + if (node.folder.childUnreadCount) + return [NSString stringWithFormat:NSLocalizedString(@"%d unread articles", nil), node.folder.childUnreadCount]; } return nil; } @@ -886,26 +912,26 @@ -(id)outlineView:(NSOutlineView *)olv objectValueForTableColumn:(NSTableColumn * if (info == nil) { NSMutableParagraphStyle * style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; - [style setLineBreakMode:NSLineBreakByClipping]; - info = [[NSDictionary alloc] initWithObjectsAndKeys:style, NSParagraphStyleAttributeName, nil]; - [style release]; + style.lineBreakMode = NSLineBreakByTruncatingTail; + style.tighteningFactorForTruncation = 0.0; + info = @{NSParagraphStyleAttributeName: style}; } - Folder * folder = [node folder]; - int rowIndex = [olv rowForItem:item]; + Folder * folder = node.folder; + NSInteger rowIndex = [olv rowForItem:item]; NSMutableDictionary * myInfo = [NSMutableDictionary dictionaryWithDictionary:info]; // Set the colour of the text in the cell : default is blackColor if (IsUnsubscribed(folder)) - [myInfo setObject:[NSColor grayColor] forKey:NSForegroundColorAttributeName]; - else if ([olv selectedRow] == rowIndex && [olv editedRow] != rowIndex) - [myInfo setObject:[NSColor whiteColor] forKey:NSForegroundColorAttributeName]; + myInfo[NSForegroundColorAttributeName] = [NSColor grayColor]; + else if (olv.selectedRow == rowIndex && olv.editedRow != rowIndex) + myInfo[NSForegroundColorAttributeName] = [NSColor whiteColor]; // Set the font - if ([folder unreadCount] || ([folder childUnreadCount] && ![olv isItemExpanded:item])) - [myInfo setObject:boldCellFont forKey:NSFontAttributeName]; + if (folder.unreadCount || (folder.childUnreadCount && ![olv isItemExpanded:item])) + myInfo[NSFontAttributeName] = boldCellFont; else - [myInfo setObject:cellFont forKey:NSFontAttributeName]; + myInfo[NSFontAttributeName] = cellFont; - return [[[NSAttributedString alloc] initWithString:[node nodeName] attributes:myInfo] autorelease]; + return [[NSAttributedString alloc] initWithString:node.nodeName attributes:myInfo]; } /* willDisplayCell @@ -915,10 +941,10 @@ -(id)outlineView:(NSOutlineView *)olv objectValueForTableColumn:(NSTableColumn * */ -(void)outlineView:(NSOutlineView *)olv willDisplayCell:(NSCell *)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item { - if ([[tableColumn identifier] isEqualToString:@"folderColumns"]) + if ([tableColumn.identifier isEqualToString:@"folderColumns"]) { TreeNode * node = (TreeNode *)item; - Folder * folder = [node folder]; + Folder * folder = node.folder; ImageAndTextCell * realCell = (ImageAndTextCell *)cell; // Use the auxiliary position of the feed item to show @@ -931,7 +957,7 @@ -(void)outlineView:(NSOutlineView *)olv willDisplayCell:(NSCell *)cell forTableC } else if (IsError(folder)) { - [realCell setAuxiliaryImage:folderErrorImage]; + realCell.auxiliaryImage = folderErrorImage; [realCell setInProgress:NO]; } else @@ -944,14 +970,14 @@ -(void)outlineView:(NSOutlineView *)olv willDisplayCell:(NSCell *)cell forTableC { [realCell clearCount]; } - else if ([folder unreadCount]) + else if (folder.unreadCount) { - [realCell setCount:[folder unreadCount]]; + [realCell setCount:folder.unreadCount]; [realCell setCountBackgroundColour:[NSColor colorForControlTint:[NSColor currentControlTint]]]; } - else if ([folder childUnreadCount] && ![olv isItemExpanded:item]) + else if (folder.childUnreadCount && ![olv isItemExpanded:item]) { - [realCell setCount:[folder childUnreadCount]]; + [realCell setCount:folder.childUnreadCount]; [realCell setCountBackgroundColour:[NSColor colorForControlTint:[NSColor currentControlTint]]]; } else @@ -961,7 +987,7 @@ -(void)outlineView:(NSOutlineView *)olv willDisplayCell:(NSCell *)cell forTableC // Only show folder images if the user prefers them. Preferences * prefs = [Preferences standardPreferences]; - [realCell setImage:([prefs showFolderImages] ? [folder image] : [folder standardImage])]; + realCell.image = (prefs.showFolderImages ? folder.image : [folder standardImage]); [realCell setItem:item]; } @@ -984,7 +1010,7 @@ -(void)outlineViewSelectionDidChange:(NSNotification *)notification if (!blockSelectionHandler) { - TreeNode * node = [outlineView itemAtRow:[outlineView selectedRow]]; + TreeNode * node = [outlineView itemAtRow:outlineView.selectedRow]; [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_FolderSelectionChange" object:node]; } } @@ -992,14 +1018,14 @@ -(void)outlineViewSelectionDidChange:(NSNotification *)notification /* renameFolder * Begin in-place editing of the selected folder name. */ --(void)renameFolder:(int)folderId +-(void)renameFolder:(NSInteger)folderId { TreeNode * node = [rootNode nodeFromID:folderId]; NSInteger rowIndex = [outlineView rowForItem:node]; if (rowIndex != -1) { - [outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:(NSUInteger )rowIndex] byExtendingSelection:NO]; + [outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:(NSUInteger)rowIndex] byExtendingSelection:NO]; [outlineView editColumn:[outlineView columnWithIdentifier:@"folderColumns"] row:rowIndex withEvent:nil select:YES]; } } @@ -1011,7 +1037,7 @@ -(void)renameFolderByTimer:(id)sender { if (canRenameFolders) { - [self renameFolder:[(TreeNode *)[sender userInfo] nodeId]]; + [self renameFolder:((TreeNode *)[sender userInfo]).nodeId]; } } @@ -1038,7 +1064,7 @@ -(void)enableFoldersRenamingAfterDelay */ -(void)outlineViewWillBecomeFirstResponder { - [[controller browserView] setActiveTabToPrimaryTab]; + [controller.browserView setActiveTabToPrimaryTab]; [self enableFoldersRenamingAfterDelay]; } @@ -1057,7 +1083,7 @@ -(void)outlineView:(NSOutlineView *)olv setObjectValue:(id)object forTableColumn { TreeNode * node = (TreeNode *)item; NSString * newName = (NSString *)object; - Folder * folder = [node folder]; + Folder * folder = node.folder; // Remove the "☁️ " symbols on Open Reader feeds if (IsGoogleReaderFolder(folder) && [newName hasPrefix:@"☁️ "]) { @@ -1065,14 +1091,14 @@ -(void)outlineView:(NSOutlineView *)olv setObjectValue:(id)object forTableColumn newName = tmpName; } - if (![[folder name] isEqualToString:newName]) + if (![folder.name isEqualToString:newName]) { - Database * db = [Database sharedDatabase]; - if ([db folderFromName:newName] != nil) + Database * dbManager = [Database sharedManager]; + if ([dbManager folderFromName:newName] != nil) runOKAlertPanel(NSLocalizedString(@"Cannot rename folder", nil), NSLocalizedString(@"A folder with that name already exists", nil)); else { - [db setFolderName:[folder itemId] newName:newName]; + [dbManager setName:newName forFolder:folder.itemId]; } } } @@ -1081,10 +1107,10 @@ -(void)outlineView:(NSOutlineView *)olv setObjectValue:(id)object forTableColumn * Called when something is being dragged over us. We respond with an NSDragOperation value indicating the * feedback for the user given where we are. */ --(NSDragOperation)outlineView:(NSOutlineView*)olv validateDrop:(id )info proposedItem:(id)item proposedChildIndex:(int)index +-(NSDragOperation)outlineView:(NSOutlineView*)olv validateDrop:(id )info proposedItem:(id)item proposedChildIndex:(NSInteger)index { NSPasteboard * pb = [info draggingPasteboard]; - NSString * type = [pb availableTypeFromArray:[NSArray arrayWithObjects:MA_PBoardType_FolderList, MA_PBoardType_RSSSource, @"WebURLsWithTitlesPboardType", NSStringPboardType, nil]]; + NSString * type = [pb availableTypeFromArray:@[MA_PBoardType_FolderList, MA_PBoardType_RSSSource, @"WebURLsWithTitlesPboardType", NSStringPboardType]]; NSDragOperation dragType = ([type isEqualToString:MA_PBoardType_FolderList]) ? NSDragOperationMove : NSDragOperationCopy; TreeNode * node = (TreeNode *)item; @@ -1127,53 +1153,52 @@ -(BOOL)outlineView:(NSOutlineView *)olv writeItems:(NSArray*)items toPasteboard: */ -(BOOL)copyTableSelection:(NSArray *)items toPasteboard:(NSPasteboard *)pboard { - int count = [items count]; + NSInteger count = items.count; NSMutableArray * externalDragData = [NSMutableArray arrayWithCapacity:count]; NSMutableArray * internalDragData = [NSMutableArray arrayWithCapacity:count]; NSMutableString * stringDragData = [NSMutableString string]; NSMutableArray * arrayOfURLs = [NSMutableArray arrayWithCapacity:count]; NSMutableArray * arrayOfTitles = [NSMutableArray arrayWithCapacity:count]; - int index; + NSInteger index; // We'll create the types of data on the clipboard. - [pboard declareTypes:[NSArray arrayWithObjects:MA_PBoardType_FolderList, MA_PBoardType_RSSSource, @"WebURLsWithTitlesPboardType", NSStringPboardType, nil] owner:self]; + [pboard declareTypes:@[MA_PBoardType_FolderList, MA_PBoardType_RSSSource, @"WebURLsWithTitlesPboardType", NSStringPboardType] owner:self]; // Create an array of NSNumber objects containing the selected folder IDs. - int countOfItems = 0; + NSInteger countOfItems = 0; for (index = 0; index < count; ++index) { - TreeNode * node = [items objectAtIndex:index]; - Folder * folder = [node folder]; + TreeNode * node = items[index]; + Folder * folder = node.folder; if (IsRSSFolder(folder) || IsGoogleReaderFolder(folder) || IsSmartFolder(folder) || IsGroupFolder(folder) || IsSearchFolder(folder) || IsTrashFolder(folder)) { - [internalDragData addObject:[NSNumber numberWithInt:[node nodeId]]]; + [internalDragData addObject:@(node.nodeId)]; ++countOfItems; } if (IsRSSFolder(folder)||IsGoogleReaderFolder(folder)) { - NSString * feedURL = [folder feedURL]; + NSString * feedURL = folder.feedURL; NSMutableDictionary * dict = [NSMutableDictionary dictionary]; - [dict setValue:[folder name] forKey:@"sourceName"]; - [dict setValue:[folder description] forKey:@"sourceDescription"]; + [dict setValue:folder.name forKey:@"sourceName"]; + [dict setValue:folder.description forKey:@"sourceDescription"]; [dict setValue:feedURL forKey:@"sourceRSSURL"]; - [dict setValue:[folder homePage] forKey:@"sourceHomeURL"]; + [dict setValue:folder.homePage forKey:@"sourceHomeURL"]; [externalDragData addObject:dict]; - [stringDragData appendString:feedURL]; - [stringDragData appendString:@"\n"]; + [stringDragData appendFormat:@"%@\n", feedURL]; NSURL * safariURL = [NSURL URLWithString:feedURL]; - if (safariURL != nil && ![safariURL isFileURL]) + if (safariURL != nil && !safariURL.fileURL) { - if (![@"feed" isEqualToString:[safariURL scheme]]) + if (![@"feed" isEqualToString:safariURL.scheme]) { - feedURL = [NSString stringWithFormat:@"feed:%@", [safariURL resourceSpecifier]]; + feedURL = [NSString stringWithFormat:@"feed:%@", safariURL.resourceSpecifier]; } [arrayOfURLs addObject:feedURL]; - [arrayOfTitles addObject:[folder name]]; + [arrayOfTitles addObject:folder.name]; } } } @@ -1182,7 +1207,7 @@ -(BOOL)copyTableSelection:(NSArray *)items toPasteboard:(NSPasteboard *)pboard [pboard setPropertyList:externalDragData forType:MA_PBoardType_RSSSource]; [pboard setString:stringDragData forType:NSStringPboardType]; [pboard setPropertyList:internalDragData forType:MA_PBoardType_FolderList]; - [pboard setPropertyList:[NSArray arrayWithObjects:arrayOfURLs, arrayOfTitles, nil] forType:@"WebURLsWithTitlesPboardType"]; + [pboard setPropertyList:@[arrayOfURLs, arrayOfTitles] forType:@"WebURLsWithTitlesPboardType"]; return countOfItems > 0; } @@ -1203,8 +1228,8 @@ -(void)moveFoldersUndo:(id)anObject -(BOOL)moveFolders:(NSArray *)array withGoogleSync:(BOOL)sync { NSAssert(([array count] % 3) == 0, @"Incorrect number of items in array passed to moveFolders"); - int count = [array count]; - __block int index = 0; + NSInteger count = array.count; + __block NSInteger index = 0; // Need to create a running undo array NSMutableArray * undoArray = [[NSMutableArray alloc] initWithCapacity:count]; @@ -1212,55 +1237,58 @@ -(BOOL)moveFolders:(NSArray *)array withGoogleSync:(BOOL)sync // Internal drag and drop so we're just changing the parent IDs around. One thing // we have to watch for is to make sure that we don't re-parent to a subordinate // folder. - Database * db = [Database sharedDatabase]; - BOOL autoSort = [[Preferences standardPreferences] foldersTreeSortMethod] != MA_FolderSort_Manual; + Database * dbManager = [Database sharedManager]; + BOOL autoSort = [Preferences standardPreferences].foldersTreeSortMethod != MA_FolderSort_Manual; - [db doTransactionWithBlock:^(BOOL *rollback) { while (index < count) { - int folderId = [[array objectAtIndex:index++] intValue]; - int newParentId = [[array objectAtIndex:index++] intValue]; - int newPredecessorId = [[array objectAtIndex:index++] intValue]; - Folder * folder = [db folderFromID:folderId]; - int oldParentId = [folder parentId]; + NSInteger folderId = [array[index++] integerValue]; + NSInteger newParentId = [array[index++] integerValue]; + NSInteger newPredecessorId = [array[index++] integerValue]; + Folder * folder = [dbManager folderFromID:folderId]; + NSInteger oldParentId = folder.parentId; TreeNode * node = [rootNode nodeFromID:folderId]; TreeNode * oldParent = [rootNode nodeFromID:oldParentId]; - int oldChildIndex = [oldParent indexOfChild:node]; - int oldPredecessorId = (oldChildIndex > 0) ? [[oldParent childByIndex:(oldChildIndex - 1)] nodeId] : 0; + NSInteger oldChildIndex = [oldParent indexOfChild:node]; + NSInteger oldPredecessorId = (oldChildIndex > 0) ? [oldParent childByIndex:(oldChildIndex - 1)].nodeId : 0; TreeNode * newParent = [rootNode nodeFromID:newParentId]; TreeNode * newPredecessor = [newParent nodeFromID:newPredecessorId]; if ((newPredecessor == nil) || (newPredecessor == newParent)) newPredecessorId = 0; - int newChildIndex = (newPredecessorId > 0) ? ([newParent indexOfChild:newPredecessor] + 1) : 0; + NSInteger newChildIndex = (newPredecessorId > 0) ? ([newParent indexOfChild:newPredecessor] + 1) : 0; if (newParentId == oldParentId) { // With automatic sorting, moving under the same parent is impossible. - if (autoSort) + if (autoSort) { continue; + } // No need to move if destination is the same as origin. - if (newPredecessorId == oldPredecessorId) + if (newPredecessorId == oldPredecessorId) { continue; + } // Adjust the index for the removal of the old child. - if (newChildIndex > oldChildIndex) - --newChildIndex; + if (newChildIndex > oldChildIndex) { + --newChildIndex; + } + } else { - if (![newParent canHaveChildren]) + if (!newParent.canHaveChildren) [newParent setCanHaveChildren:YES]; - if ([db setParent:newParentId forFolder:folderId]) + if ([dbManager setParent:newParentId forFolder:folderId]) { if (IsGoogleReaderFolder(folder)) { GoogleReader * myGoogle = [GoogleReader sharedManager]; // remove old label - NSString * folderName = [[db folderFromID:oldParentId] name]; - [myGoogle setFolderName:folderName forFeed:[folder feedURL] set:FALSE]; + NSString * folderName = [dbManager folderFromID:oldParentId].name; + [myGoogle setFolderName:folderName forFeed:folder.feedURL set:FALSE]; // add new label - folderName = [[db folderFromID:newParentId] name]; - [myGoogle setFolderName:folderName forFeed:[folder feedURL] set:TRUE]; + folderName = [dbManager folderFromID:newParentId].name; + [myGoogle setFolderName:folderName forFeed:folder.feedURL set:TRUE]; } } else @@ -1271,57 +1299,54 @@ -(BOOL)moveFolders:(NSArray *)array withGoogleSync:(BOOL)sync { if (oldPredecessorId > 0) { - if (![db setNextSibling:[folder nextSiblingId] forFolder:oldPredecessorId]) + if (![dbManager setNextSibling:folder.nextSiblingId forFolder:oldPredecessorId]) continue; } else { - if (![db setFirstChild:[folder nextSiblingId] forFolder:oldParentId]) + if (![dbManager setFirstChild:folder.nextSiblingId forFolder:oldParentId]) continue; } } - [node retain]; [oldParent removeChild:node andChildren:NO]; [newParent addChild:node atIndex:newChildIndex]; - [node release]; // Put at beginning of undoArray in order to undo moves in reverse order. - [undoArray insertObject:[NSNumber numberWithInt:folderId] atIndex:0u]; - [undoArray insertObject:[NSNumber numberWithInt:oldParentId] atIndex:1u]; - [undoArray insertObject:[NSNumber numberWithInt:oldPredecessorId] atIndex:2u]; + [undoArray insertObject:@(folderId) atIndex:0u]; + [undoArray insertObject:@(oldParentId) atIndex:1u]; + [undoArray insertObject:@(oldPredecessorId) atIndex:2u]; if (!autoSort) { if (newPredecessorId > 0) { - if (![db setNextSibling:[[db folderFromID:newPredecessorId] nextSiblingId] forFolder:folderId]) + if (![dbManager setNextSibling:[dbManager folderFromID:newPredecessorId].nextSiblingId + forFolder:folderId]) { continue; - [db setNextSibling:folderId forFolder:newPredecessorId]; + } + [dbManager setNextSibling:folderId forFolder:newPredecessorId]; } else { - int oldFirstChildId = (newParent == rootNode) ? [db firstFolderId] : [[newParent folder] firstChildId]; - if (![db setNextSibling:oldFirstChildId forFolder:folderId]) + NSInteger oldFirstChildId = (newParent == rootNode) ? dbManager.firstFolderId : newParent.folder.firstChildId; + if (![dbManager setNextSibling:oldFirstChildId forFolder:folderId]) continue; - [db setFirstChild:folderId forFolder:newParentId]; + [dbManager setFirstChild:folderId forFolder:newParentId]; } } } - }]; //end transaction block // If undo array is empty, then nothing has been moved. - if ([undoArray count] == 0u) + if (undoArray.count == 0u) { - [undoArray release]; return NO; } // Set up to undo this action - NSUndoManager * undoManager = [[NSApp mainWindow] undoManager]; + NSUndoManager * undoManager = NSApp.mainWindow.undoManager; [undoManager registerUndoWithTarget:self selector:@selector(moveFoldersUndo:) object:undoArray]; [undoManager setActionName:NSLocalizedString(@"Move Folders", nil)]; - [undoArray release]; // Make the outline control reload its data [outlineView reloadData]; @@ -1329,7 +1354,7 @@ -(BOOL)moveFolders:(NSArray *)array withGoogleSync:(BOOL)sync // If any parent was a collapsed group, expand it now for (index = 0; index < count; index += 2) { - int newParentId = [[array objectAtIndex:++index] intValue]; + NSInteger newParentId = [array[++index] integerValue]; if (newParentId != MA_Root_Folder) { TreeNode * parentNode = [rootNode nodeFromID:newParentId]; @@ -1341,31 +1366,30 @@ -(BOOL)moveFolders:(NSArray *)array withGoogleSync:(BOOL)sync // Properly set selection back to the original items. This has to be done after the // refresh so that rowForItem returns the new positions. NSMutableIndexSet * selIndexSet = [[NSMutableIndexSet alloc] init]; - int selRowIndex = 9999; + NSInteger selRowIndex = 9999; for (index = 0; index < count; index += 2) { - int folderId = [[array objectAtIndex:index++] intValue]; - int rowIndex = [outlineView rowForItem:[rootNode nodeFromID:folderId]]; + NSInteger folderId = [array[index++] integerValue]; + NSInteger rowIndex = [outlineView rowForItem:[rootNode nodeFromID:folderId]]; selRowIndex = MIN(selRowIndex, rowIndex); [selIndexSet addIndex:rowIndex]; } [outlineView scrollRowToVisible:selRowIndex]; [outlineView selectRowIndexes:selIndexSet byExtendingSelection:NO]; - [selIndexSet release]; return YES; } /* acceptDrop * Accept a drop on or between nodes either from within the folder view or from outside. */ --(BOOL)outlineView:(NSOutlineView *)olv acceptDrop:(id )info item:(id)targetItem childIndex:(int)child +-(BOOL)outlineView:(NSOutlineView *)olv acceptDrop:(id )info item:(id)targetItem childIndex:(NSInteger)child { - __block int childIndex = child; + __block NSInteger childIndex = child; NSPasteboard * pb = [info draggingPasteboard]; - NSString * type = [pb availableTypeFromArray:[NSArray arrayWithObjects:MA_PBoardType_FolderList, MA_PBoardType_RSSSource, @"WebURLsWithTitlesPboardType", NSStringPboardType, nil]]; + NSString * type = [pb availableTypeFromArray:@[MA_PBoardType_FolderList, MA_PBoardType_RSSSource, @"WebURLsWithTitlesPboardType", NSStringPboardType]]; TreeNode * node = targetItem ? (TreeNode *)targetItem : rootNode; - int parentId = [node nodeId]; + NSInteger parentId = node.nodeId; if ((childIndex == NSOutlineViewDropOnItemIndex) || (childIndex < 0)) childIndex = 0; @@ -1374,75 +1398,75 @@ -(BOOL)outlineView:(NSOutlineView *)olv acceptDrop:(id )info ite { // This is possibly a URL that we'll handle as a potential feed subscription. It's // not our call to make though. - int predecessorId = (childIndex > 0) ? [[node childByIndex:(childIndex - 1)] nodeId] : 0; + NSInteger predecessorId = (childIndex > 0) ? [node childByIndex:(childIndex - 1)].nodeId : 0; [APPCONTROLLER createNewSubscription:[pb stringForType:type] underFolder:parentId afterChild:predecessorId]; return YES; } if ([type isEqualToString:MA_PBoardType_FolderList]) { - Database * db = [Database sharedDatabase]; + Database * db = [Database sharedManager]; NSArray * arrayOfSources = [pb propertyListForType:type]; - int count = [arrayOfSources count]; - int index; - int predecessorId = (childIndex > 0) ? [[node childByIndex:(childIndex - 1)] nodeId] : 0; + NSInteger count = arrayOfSources.count; + NSInteger index; + NSInteger predecessorId = (childIndex > 0) ? [node childByIndex:(childIndex - 1)].nodeId : 0; // Create an NSArray of triples (folderId, newParentId, predecessorId) that will be passed to moveFolders // to do the actual move. NSMutableArray * array = [[NSMutableArray alloc] initWithCapacity:count * 3]; - int trashFolderId = [db trashFolderId]; + NSInteger trashFolderId = db.trashFolderId; for (index = 0; index < count; ++index) { - int folderId = [[arrayOfSources objectAtIndex:index] intValue]; + NSInteger folderId = [arrayOfSources[index] integerValue]; // Don't allow the trash folder to move under a group folder, because the group folder could get deleted. // Also, don't allow perverse moves. We should probably do additional checking: not only whether the new parent // is the folder itself but also whether the new parent is a subfolder. if (((folderId == trashFolderId) && (node != rootNode)) || (folderId == parentId) || (folderId == predecessorId)) continue; - [array addObject:[NSNumber numberWithInt:folderId]]; - [array addObject:[NSNumber numberWithInt:parentId]]; - [array addObject:[NSNumber numberWithInt:predecessorId]]; + [array addObject:@(folderId)]; + [array addObject:@(parentId)]; + [array addObject:@(predecessorId)]; predecessorId = folderId; } // Do the move BOOL result = [self moveFolders:array withGoogleSync:YES]; - [array release]; return result; } if ([type isEqualToString:MA_PBoardType_RSSSource]) { - Database * db = [Database sharedDatabase]; + Database * dbManager = [Database sharedManager]; NSArray * arrayOfSources = [pb propertyListForType:type]; - int count = [arrayOfSources count]; - int index; + NSInteger count = arrayOfSources.count; + NSInteger index; // This is an RSS drag using the protocol defined by Ranchero for NetNewsWire. See // http://ranchero.com/netnewswire/rssclipboard.php for more details. // - __block int folderToSelect = -1; + __block NSInteger folderToSelect = -1; for (index = 0; index < count; ++index) { - [db doTransactionWithBlock:^(BOOL *rollback) { - NSDictionary * sourceItem = [arrayOfSources objectAtIndex:index]; + NSDictionary * sourceItem = arrayOfSources[index]; NSString * feedTitle = [sourceItem valueForKey:@"sourceName"]; NSString * feedHomePage = [sourceItem valueForKey:@"sourceHomeURL"]; NSString * feedURL = [sourceItem valueForKey:@"sourceRSSURL"]; NSString * feedDescription = [sourceItem valueForKey:@"sourceDescription"]; - if ((feedURL != nil) && [db folderFromFeedURL:feedURL] == nil) + if ((feedURL != nil) && [dbManager folderFromFeedURL:feedURL] == nil) { - int predecessorId = (childIndex > 0) ? [[node childByIndex:(childIndex - 1)] nodeId] : 0; - int folderId = [db addRSSFolder:feedTitle underParent:parentId afterChild:predecessorId subscriptionURL:feedURL]; - if (feedDescription != nil) - [db setFolderDescription:folderId newDescription:feedDescription]; - if (feedHomePage != nil) - [db setFolderHomePage:folderId newHomePage:feedHomePage]; - if (folderId > 0) + NSInteger predecessorId = (childIndex > 0) ? [node childByIndex:(childIndex - 1)].nodeId : 0; + NSInteger folderId = [dbManager addRSSFolder:feedTitle underParent:parentId afterChild:predecessorId subscriptionURL:feedURL]; + if (feedDescription != nil) { + [dbManager setDescription:feedDescription forFolder:folderId]; + } + if (feedHomePage != nil) { + [dbManager setHomePage:feedHomePage forFolder:folderId]; + } + if (folderId > 0) { folderToSelect = folderId; + } ++childIndex; } - }]; //end transaction block } // If parent was a group, expand it now @@ -1457,32 +1481,31 @@ -(BOOL)outlineView:(NSOutlineView *)olv acceptDrop:(id )info ite } if ([type isEqualToString:@"WebURLsWithTitlesPboardType"]) { - Database * db = [Database sharedDatabase]; + Database * dbManager = [Database sharedManager]; NSArray * webURLsWithTitles = [pb propertyListForType:type]; - NSArray * arrayOfURLs = [webURLsWithTitles objectAtIndex:0]; - NSArray * arrayOfTitles = [webURLsWithTitles objectAtIndex:1]; - int count = [arrayOfURLs count]; - int index; + NSArray * arrayOfURLs = webURLsWithTitles[0]; + NSArray * arrayOfTitles = webURLsWithTitles[1]; + NSInteger count = arrayOfURLs.count; + NSInteger index; - __block int folderToSelect = -1; + __block NSInteger folderToSelect = -1; for (index = 0; index < count; ++index) { - [db doTransactionWithBlock:^(BOOL *rollback) { - NSString * feedTitle = [arrayOfTitles objectAtIndex:index]; - NSString * feedURL = [arrayOfURLs objectAtIndex:index]; + NSString * feedTitle = arrayOfTitles[index]; + NSString * feedURL = arrayOfURLs[index]; NSURL * draggedURL = [NSURL URLWithString:feedURL]; - if (([draggedURL scheme] != nil) && [[draggedURL scheme] isEqualToString:@"feed"]) - feedURL = [NSString stringWithFormat:@"http:%@", [draggedURL resourceSpecifier]]; + if ((draggedURL.scheme != nil) && [draggedURL.scheme isEqualToString:@"feed"]) + feedURL = [NSString stringWithFormat:@"http:%@", draggedURL.resourceSpecifier]; - if ([db folderFromFeedURL:feedURL] == nil) + if ([dbManager folderFromFeedURL:feedURL] == nil) { - int predecessorId = (childIndex > 0) ? [[node childByIndex:(childIndex - 1)] nodeId] : 0; - int newFolderId = [db addRSSFolder:feedTitle underParent:parentId afterChild:predecessorId subscriptionURL:feedURL]; - if (newFolderId > 0) + NSInteger predecessorId = (childIndex > 0) ? [node childByIndex:(childIndex - 1)].nodeId : 0; + NSInteger newFolderId = [dbManager addRSSFolder:feedTitle underParent:parentId afterChild:predecessorId subscriptionURL:feedURL]; + if (newFolderId > 0) { folderToSelect = newFolderId; + } ++childIndex; } - }]; //end transaction block } // If parent was a group, expand it now @@ -1498,22 +1521,32 @@ -(BOOL)outlineView:(NSOutlineView *)olv acceptDrop:(id )info ite return NO; } +/* setSearch + * Set string to filter nodes by name, description, url + */ +-(void)setSearch:(NSString *)f { + NSString* tf = [f stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + + if (tf.length == 0) { + outlineView.filterPredicate = nil; + return; + } + + NSString *match = [NSString stringWithFormat:@"*%@*", tf]; + NSPredicate* predicate = [NSPredicate predicateWithFormat:@"folder.name like[cd] %@ OR folder.feedDescription like[cd] %@ OR folder.feedURL like[cd] %@", match, match, match]; + + if ([outlineView.filterPredicate.predicateFormat isEqualToString:predicate.predicateFormat]) { + return; + } + + outlineView.filterPredicate = predicate; +} + /* dealloc * Clean up and release resources. */ -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - [cellFont release]; - cellFont=nil; - [boldCellFont release]; - boldCellFont=nil; - [folderErrorImage release]; - folderErrorImage=nil; - [refreshProgressImage release]; - refreshProgressImage=nil; - [rootNode release]; - rootNode=nil; - [super dealloc]; } @end diff --git a/src/GoogleReader.h b/src/GoogleReader.h index 8f482bfccb..cd50e47ddf 100644 --- a/src/GoogleReader.h +++ b/src/GoogleReader.h @@ -9,6 +9,7 @@ #import #import "ASIHTTPRequest.h" #import "Folder.h" +#import "Article.h" #import "ASINetworkQueue.h" #import "ActivityLog.h" #import "Debug.h" @@ -26,20 +27,19 @@ +(GoogleReader *)sharedManager; // Check if an accessToken is available --(BOOL)isReady; +@property (nonatomic, getter=isReady, readonly) BOOL ready; -(void)loadSubscriptions:(NSNotification*)nc; --(void)authenticate; -(void)getToken; -(void)clearAuthentication; -(void)resetAuthentication; -(void)subscribeToFeed:(NSString *)feedURL; -(void)unsubscribeFromFeed:(NSString *)feedURL; --(void)markRead:(NSString *)itemGuid readFlag:(BOOL)flag; --(void)markStarred:(NSString *)itemGuid starredFlag:(BOOL)flag; +-(void)markRead:(Article *)article readFlag:(BOOL)flag; +-(void)markStarred:(Article *)article starredFlag:(BOOL)flag; -(void)setFolderName:(NSString *)folderName forFeed:(NSString *)feedURL set:(BOOL)flag; -(ASIHTTPRequest*)refreshFeed:(Folder*)thisFolder withLog:(ActivityItem *)aItem shouldIgnoreArticleLimit:(BOOL)ignoreLimit; --(NSUInteger)countOfNewArticles; +@property (nonatomic, readonly) NSUInteger countOfNewArticles; @end diff --git a/src/GoogleReader.m b/src/GoogleReader.m index 2bf3d4b0a5..aed9f2081c 100644 --- a/src/GoogleReader.m +++ b/src/GoogleReader.m @@ -21,18 +21,17 @@ #import "GoogleReader.h" #import "ASIHTTPRequest.h" #import "ASIFormDataRequest.h" -#import "JSONKit.h" #import "HelperFunctions.h" #import "Folder.h" #import "Database.h" #import -#import "Article.h" #import "AppController.h" #import "RefreshManager.h" #import "Preferences.h" #import "StringExtensions.h" #import "NSNotificationAdditions.h" #import "KeyChain.h" +#import #define TIMESTAMP [NSString stringWithFormat:@"%0.0f",[[NSDate date] timeIntervalSince1970]] @@ -48,14 +47,14 @@ BOOL hostRequiresSParameter; BOOL hostRequiresLastPathOnly; BOOL hostRequiresInoreaderAdditionalHeaders; +BOOL hostRequiresBackcrawling; NSDictionary * inoreaderAdditionalHeaders; -// Singleton -static GoogleReader * _googleReader = nil; - enum GoogleReaderStatus { notAuthenticated = 0, isAuthenticating, + isMissingToken, + isGettingToken, isAuthenticated } googleReaderStatus; @@ -63,8 +62,8 @@ @interface GoogleReader() @property (nonatomic, copy) NSMutableArray * localFeeds; @property (atomic, copy) NSString *token; @property (atomic, copy) NSString *clientAuthToken; -@property (nonatomic, retain) NSTimer * tokenTimer; -@property (nonatomic, retain) NSTimer * authTimer; +@property (nonatomic, strong) NSTimer * tokenTimer; +@property (nonatomic, strong) NSTimer * authTimer; @end @implementation GoogleReader @@ -75,21 +74,14 @@ @implementation GoogleReader @synthesize tokenTimer; @synthesize authTimer; -JSONDecoder * jsonDecoder; - --(BOOL)isReady -{ - return (googleReaderStatus == isAuthenticated && tokenTimer != nil); -} - +# pragma mark initialization -- (id)init +- (instancetype)init { self = [super init]; if (self) { // Initialization code here. localFeeds = [[NSMutableArray alloc] init]; - jsonDecoder = [[JSONDecoder decoder] retain]; googleReaderStatus = notAuthenticated; countOfNewArticles = 0; clientAuthToken= nil; @@ -100,21 +92,38 @@ - (id)init username=nil; password=nil; APIBaseURL=nil; - inoreaderAdditionalHeaders = [[NSDictionary alloc] initWithObjectsAndKeys:@"1000001359", @"AppID", @"rAlfs2ELSuFxZJ5adJAW54qsNbUa45Qn", @"AppKey", nil]; + inoreaderAdditionalHeaders = @{ + @"AppID": @"1000001359", + @"AppKey": @"rAlfs2ELSuFxZJ5adJAW54qsNbUa45Qn" + }; } return self; } -/* countOfNewArticles +/* sharedManager + * Returns the single instance of the Open Reader. */ --(NSUInteger)countOfNewArticles ++(GoogleReader *)sharedManager { - NSUInteger count = countOfNewArticles; - countOfNewArticles = 0; - return count; + // Singleton + static GoogleReader * _googleReader = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _googleReader = [[GoogleReader alloc] init]; + Preferences * prefs = [Preferences standardPreferences]; + if (prefs.syncGoogleReader) + { + openReaderHost = prefs.syncServer; + APIBaseURL = [NSString stringWithFormat:@"https://%@/reader/api/0/", openReaderHost]; + } + + }); + return _googleReader; } +# pragma mark user authentication and requests preparation + /* prepare an ASIHTTPRequest from an NSURL */ - (ASIHTTPRequest *)requestFromURL:(NSURL *)url @@ -129,104 +138,319 @@ - (ASIHTTPRequest *)requestFromURL:(NSURL *)url - (ASIFormDataRequest *)authentifiedFormRequestFromURL:(NSURL *)url { ASIFormDataRequest * request = [ASIFormDataRequest requestWithURL:url]; - if (![self isReady]) - [self authenticate]; - [request setPostValue:token forKey:@"T"]; [self commonRequestPrepare:request]; + [self getToken]; + if (token == nil) { + [request cancel]; + } else { + [request setPostValue:token forKey:@"T"]; + } return request; } -(void)commonRequestPrepare:(ASIHTTPRequest *)request { - if (clientAuthToken != nil) + [self authenticate]; + if (clientAuthToken == nil) { + [request cancel]; + } else { [request addRequestHeader:@"Authorization" value:[NSString stringWithFormat:@"GoogleLogin auth=%@", clientAuthToken]]; + } if (hostRequiresInoreaderAdditionalHeaders) { - NSMutableDictionary * theHeaders = [[[request requestHeaders] mutableCopy] autorelease]; + NSMutableDictionary * theHeaders = [request.requestHeaders mutableCopy]; [theHeaders addEntriesFromDictionary:inoreaderAdditionalHeaders]; - [request setRequestHeaders:theHeaders]; + request.requestHeaders = theHeaders; } [request setUseCookiePersistence:NO]; - [request setTimeOutSeconds:180]; - [request setDelegate:self]; + request.timeOutSeconds = 180; + request.delegate = self; +} + +-(void)authenticate +{ + if (googleReaderStatus == isAuthenticated || googleReaderStatus == isMissingToken) + { + return; //we are already connected + } + self.clientAuthToken = nil; + Preferences * prefs = [Preferences standardPreferences]; + if (!prefs.syncGoogleReader) + return; + if (googleReaderStatus != notAuthenticated) { + LLog(@"Another instance is authenticating..."); + return; + } else { + LLog(@"Start first authentication..."); + googleReaderStatus = isAuthenticating; + [APPCONTROLLER setStatusMessage:NSLocalizedString(@"Authenticating on Open Reader", nil) persist:NO]; + } + + // restore from Preferences and from keychain + username = prefs.syncingUser; + openReaderHost = prefs.syncServer; + // set server-specific particularities + hostSupportsLongId=NO; + hostRequiresSParameter=NO; + hostRequiresLastPathOnly=NO; + hostRequiresInoreaderAdditionalHeaders=NO; + hostRequiresBackcrawling=YES; + if([openReaderHost isEqualToString:@"theoldreader.com"]){ + hostSupportsLongId=YES; + hostRequiresSParameter=YES; + hostRequiresLastPathOnly=YES; + hostRequiresBackcrawling=NO; + } + if([openReaderHost rangeOfString:@"inoreader.com"].length !=0){ + hostRequiresInoreaderAdditionalHeaders=YES; + hostRequiresBackcrawling=NO; + } + if([openReaderHost rangeOfString:@"bazqux.com"].length !=0){ + hostRequiresBackcrawling=NO; + } + + + password = [KeyChain getGenericPasswordFromKeychain:username serviceName:@"Vienna sync"]; + APIBaseURL = [NSString stringWithFormat:@"https://%@/reader/api/0/", openReaderHost]; + + NSURL * url = [NSURL URLWithString:[NSString stringWithFormat:LoginBaseURL, openReaderHost]]; + ASIFormDataRequest *myRequest = [ASIFormDataRequest requestWithURL:url]; + if (hostRequiresInoreaderAdditionalHeaders) + { + NSMutableDictionary * theHeaders = [myRequest.requestHeaders mutableCopy]; + [theHeaders addEntriesFromDictionary:inoreaderAdditionalHeaders]; + myRequest.requestHeaders = theHeaders; + } + [myRequest setUseCookiePersistence:NO]; + myRequest.timeOutSeconds = 180; + [myRequest setPostValue:username forKey:@"Email"]; + [myRequest setPostValue:password forKey:@"Passwd"]; + myRequest.delegate = nil; + [myRequest startSynchronous]; + + NSString * response = [myRequest responseString]; + if (!response || myRequest.responseStatusCode != 200) + { + LOG_EXPR([myRequest responseStatusCode]); + LOG_EXPR([myRequest responseHeaders]); + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_GoogleAuthFailed" object:nil]; + [APPCONTROLLER setStatusMessage:nil persist:NO]; + googleReaderStatus = notAuthenticated; + [myRequest clearDelegatesAndCancel]; + return; + } + + NSArray * components = [response componentsSeparatedByString:@"\n"]; + [myRequest clearDelegatesAndCancel]; + + //NSString * sid = [[components objectAtIndex:0] substringFromIndex:4]; //unused + //NSString * lsid = [[components objectAtIndex:1] substringFromIndex:5]; //unused + self.clientAuthToken = [NSString stringWithString:[components[2] substringFromIndex:5]]; + + googleReaderStatus = isMissingToken; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"GRSync_Autheticated" object:nil]; + + if (authTimer == nil || !authTimer.valid) + //new request every 6 days + authTimer = [NSTimer scheduledTimerWithTimeInterval:6*24*3600 target:self selector:@selector(resetAuthentication) userInfo:nil repeats:YES]; } +-(void)getToken +{ + if(token != nil) + return; //We already have a transaction token + LLog(@"Start Token Request!"); + if (clientAuthToken == nil) { + LLog(@"Failed authenticate..."); + googleReaderStatus = notAuthenticated; + return; + } + ASIHTTPRequest * request = [self requestFromURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@token", APIBaseURL]]]; + [request addRequestHeader:@"Content-Type" value:@"application/x-www-form-urlencoded"]; + googleReaderStatus = isGettingToken; + + request.delegate = nil; + [request startSynchronous]; + if (request.error) + { + LOG_EXPR([request originalURL]); + LOG_EXPR([request requestHeaders]); + LOG_EXPR([[NSString alloc] initWithData:[request postBody] encoding:NSUTF8StringEncoding]); + LOG_EXPR([request responseHeaders]); + LOG_EXPR([[NSString alloc] initWithData:[request responseData] encoding:NSUTF8StringEncoding]); + [self setToken:nil]; + [request clearDelegatesAndCancel]; + googleReaderStatus = isMissingToken; + return; + } + // Save token + self.token = [request responseString]; + [request clearDelegatesAndCancel]; + googleReaderStatus = isAuthenticated; + + if (tokenTimer == nil || !tokenTimer.valid) + //tokens expire after 30 minutes : renew them every 25 minutes + tokenTimer = [NSTimer scheduledTimerWithTimeInterval:25*60 target:self selector:@selector(renewToken) userInfo:nil repeats:YES]; +} + +-(void)renewToken +{ + token = nil; + [self getToken]; +} + +-(void)clearAuthentication +{ + googleReaderStatus = notAuthenticated; + [self setClientAuthToken:nil]; + [self setToken:nil]; +} + +-(void)resetAuthentication +{ + [self clearAuthentication]; + [self authenticate]; +} + +# pragma mark default handlers + // default handler for didFailSelector - (void)requestFailed:(ASIHTTPRequest *)request { - LLog(@"Failed on request"); - LOG_EXPR([request originalURL]); + LLog(@"Failed on request %@", [request originalURL]); LOG_EXPR([request error]); LOG_EXPR([request responseHeaders]); - if ([[request error] code] == ASIAuthenticationErrorType) //Error caused by lack of authentication + if (request.error.code == ASIAuthenticationErrorType) //Error caused by lack of authentication [self clearAuthentication]; } // default handler for didFinishSelector - (void)requestFinished:(ASIHTTPRequest *)request { - LLog(@"HTTP response status code: %d -- URL: %@", [request responseStatusCode], [[request originalURL] absoluteString]); - NSString *requestResponse = [[[NSString alloc] initWithData:[request responseData] encoding:NSUTF8StringEncoding] autorelease]; + NSString *requestResponse = [[NSString alloc] initWithData:[request responseData] encoding:NSUTF8StringEncoding]; if (![requestResponse isEqualToString:@"OK"]) { - LLog(@"Error on request"); + LLog(@"Error (response status code %d) on request %@", [request responseStatusCode], [request originalURL]); LOG_EXPR([request error]); - LOG_EXPR([request originalURL]); LOG_EXPR([request requestHeaders]); - LOG_EXPR([[[NSString alloc] initWithData:[request postBody] encoding:NSUTF8StringEncoding] autorelease]); + LOG_EXPR([[NSString alloc] initWithData:[request postBody] encoding:NSUTF8StringEncoding]); LOG_EXPR([request responseHeaders]); LOG_EXPR(requestResponse); - //[self clearAuthentication]; } } +# pragma mark status accessors + +-(BOOL)isReady +{ + return (googleReaderStatus == isAuthenticated && tokenTimer != nil); +} + +/* countOfNewArticles + */ +-(NSUInteger)countOfNewArticles +{ + NSUInteger count = countOfNewArticles; + countOfNewArticles = 0; + return count; +} + +# pragma mark operations + -(ASIHTTPRequest*)refreshFeed:(Folder*)thisFolder withLog:(ActivityItem *)aItem shouldIgnoreArticleLimit:(BOOL)ignoreLimit { //This is a workaround throw a BAD folderupdate value on DB - NSString *folderLastUpdateString = ignoreLimit ? @"0" : [thisFolder lastUpdateString]; + NSString *folderLastUpdateString = ignoreLimit ? @"0" : thisFolder.lastUpdateString; if ([folderLastUpdateString isEqualToString:@""] || [folderLastUpdateString isEqualToString:@"(null)"]) folderLastUpdateString=@"0"; NSString *itemsLimitation; if (ignoreLimit) itemsLimitation = @"&n=10000"; //just stay reasonable… else + { //Note : we don't set "r" (sorting order) here. //But according to some documentation, Google Reader and TheOldReader //need "r=o" order to make the "ot" time limitation work. //In fact, Vienna used successfully "r=n" with Google Reader. - itemsLimitation = [NSString stringWithFormat:@"&ot=%@&n=500",folderLastUpdateString]; - - if (![self isReady]) - [self authenticate]; + if (hostRequiresBackcrawling) + // For FeedHQ servers, we need to search articles which are older than last refresh + { + @try { + double limit = [folderLastUpdateString doubleValue] - 2 * 24 * 3600; + if (limit < 0.0f) { + limit = 0.0 ; + } + NSString * startEpoch = [NSNumber numberWithDouble:limit].stringValue; + itemsLimitation = [NSString stringWithFormat:@"&ot=%@&n=500",startEpoch]; + } @catch (NSException *exception) { + itemsLimitation = @"&n=500"; + } + } + else + // Bazqux.com, TheOldReader.com and Inoreader.com + { + itemsLimitation = [NSString stringWithFormat:@"&ot=%@&n=500",folderLastUpdateString]; + } + } NSString* feedIdentifier; if( hostRequiresLastPathOnly ) { - feedIdentifier = [[thisFolder feedURL] lastPathComponent]; + feedIdentifier = thisFolder.feedURL.lastPathComponent; } else { - feedIdentifier = [thisFolder feedURL]; + feedIdentifier = thisFolder.feedURL; } NSURL *refreshFeedUrl = [NSURL URLWithString:[NSString stringWithFormat:@"%@stream/contents/feed/%@?client=%@&comments=false&likes=false%@&ck=%@&output=json",APIBaseURL, percentEscape(feedIdentifier),ClientName,itemsLimitation,TIMESTAMP]]; ASIHTTPRequest *request = [self requestFromURL:refreshFeedUrl]; - [request setDidFinishSelector:@selector(feedRequestDone:)]; - [request setDidFailSelector:@selector(feedRequestFailed:)]; - [request setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:thisFolder, @"folder",aItem, @"log",folderLastUpdateString,@"lastupdatestring", [NSNumber numberWithInt:MA_Refresh_GoogleFeed], @"type", nil]]; + request.didFinishSelector = @selector(feedRequestDone:); + request.didFailSelector = @selector(feedRequestFailed:); + request.userInfo = @{@"folder": thisFolder,@"log": aItem,@"lastupdatestring": folderLastUpdateString, @"type": @(MA_Refresh_GoogleFeed)}; + // Request id's of unread items + NSString * args = [NSString stringWithFormat:@"?ck=%@&client=%@&s=feed/%@&xt=user/-/state/com.google/read&n=1000&output=json", TIMESTAMP, ClientName, + percentEscape(feedIdentifier)]; + NSURL * url = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@%@", APIBaseURL, @"stream/items/ids", args]]; + ASIHTTPRequest *request2 = [self requestFromURL:url]; + request2.userInfo = @{@"folder": thisFolder, @"log": aItem}; + request2.didFinishSelector = @selector(readRequestDone:); + [request2 addDependency:request]; + [[RefreshManager sharedManager] addConnection:request2]; + + // Request id's of starred items + // Note: Inoreader requires syntax "it=user/-/state/...", while TheOldReader ignores it and requires "s=user/-/state/..." + NSString* starredSelector; + if (hostRequiresSParameter) + { + starredSelector=@"s=user/-/state/com.google/starred"; + } + else + { + starredSelector=@"it=user/-/state/com.google/starred"; + } + + NSString * args3 = [NSString stringWithFormat:@"?ck=%@&client=%@&s=feed/%@&%@&n=1000&output=json", TIMESTAMP, ClientName, percentEscape(feedIdentifier), starredSelector]; + NSURL * url3 = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@%@", APIBaseURL, @"stream/items/ids", args3]]; + ASIHTTPRequest *request3 = [self requestFromURL:url3]; + request3.userInfo = @{@"folder": thisFolder, @"log": aItem}; + request3.didFinishSelector = @selector(starredRequestDone:); + [request3 addDependency:request2]; + [[RefreshManager sharedManager] addConnection:request3]; + return request; } // callback : handler for timed out feeds, etc... - (void)feedRequestFailed:(ASIHTTPRequest *)request { - ActivityItem *aItem = [[request userInfo] objectForKey:@"log"]; - Folder *refreshedFolder = [[request userInfo] objectForKey:@"folder"]; + ActivityItem *aItem = request.userInfo[@"log"]; + Folder *refreshedFolder = request.userInfo[@"folder"]; - [aItem appendDetail:[NSString stringWithFormat:@"%@ %@",NSLocalizedString(@"Error", nil),[[request error] localizedDescription ]]]; + [aItem appendDetail:[NSString stringWithFormat:@"%@ %@",NSLocalizedString(@"Error", nil),request.error.localizedDescription ]]; [aItem setStatus:NSLocalizedString(@"Error", nil)]; [refreshedFolder clearNonPersistedFlag:MA_FFlag_Updating]; [refreshedFolder setNonPersistedFlag:MA_FFlag_Error]; @@ -235,94 +459,99 @@ - (void)feedRequestFailed:(ASIHTTPRequest *)request // callback - (void)feedRequestDone:(ASIHTTPRequest *)request { - dispatch_queue_t queue = [[RefreshManager sharedManager] asyncQueue]; + dispatch_queue_t queue = [RefreshManager sharedManager].asyncQueue; dispatch_async(queue, ^() { - - ActivityItem *aItem = [[request userInfo] objectForKey:@"log"]; - Folder *refreshedFolder = [[request userInfo] objectForKey:@"folder"]; + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + + ActivityItem *aItem = request.userInfo[@"log"]; + Folder *refreshedFolder = request.userInfo[@"folder"]; LLog(@"Refresh Done: %@",[refreshedFolder feedURL]); - if ([request responseStatusCode] == 404) { + if (request.responseStatusCode == 404) { [aItem appendDetail:NSLocalizedString(@"Error: Feed not found!", nil)]; [aItem setStatus:NSLocalizedString(@"Error", nil)]; [refreshedFolder clearNonPersistedFlag:MA_FFlag_Updating]; [refreshedFolder setNonPersistedFlag:MA_FFlag_Error]; - } else if ([request responseStatusCode] == 200) { + } else if (request.responseStatusCode == 200) { + // reset unread statuses in cache : we will receive in -ReadRequestDone: the updated list of unreads + [refreshedFolder markArticlesInCacheRead]; NSData *data = [request responseData]; - NSDictionary * dict; - @synchronized(jsonDecoder) { - dict = [[NSDictionary alloc] initWithDictionary:[jsonDecoder objectWithData:data]]; - } - NSString *folderLastUpdateString = [[dict objectForKey:@"updated"] stringValue]; + NSDictionary * subscriptionsDict; + NSError *jsonError; + subscriptionsDict = [NSJSONSerialization JSONObjectWithData:data + options:NSJSONReadingMutableContainers + error:&jsonError]; + NSString *folderLastUpdateString = [subscriptionsDict[@"updated"] stringValue]; if ([folderLastUpdateString isEqualToString:@""] || [folderLastUpdateString isEqualToString:@"(null)"]) { LOG_EXPR([request url]); - NSLog(@"Feed name: %@",[dict objectForKey:@"title"]); - NSLog(@"Last Check: %@",[[request userInfo] objectForKey:@"lastupdatestring"]); + NSLog(@"Feed name: %@",subscriptionsDict[@"title"]); + NSLog(@"Last Check: %@",request.userInfo[@"lastupdatestring"]); NSLog(@"Last update: %@",folderLastUpdateString); - NSLog(@"Found %lu items", (unsigned long)[[dict objectForKey:@"items"] count]); - LOG_EXPR(dict); - LOG_EXPR([[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]); + NSLog(@"Found %lu items", (unsigned long)[subscriptionsDict[@"items"] count]); + LOG_EXPR(subscriptionsDict); + LOG_EXPR([[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); ALog(@"Error !!! Incoherent data !"); //keep the previously recorded one - folderLastUpdateString = [[request userInfo] objectForKey:@"lastupdatestring"]; + folderLastUpdateString = request.userInfo[@"lastupdatestring"]; } // Log number of bytes we received - [aItem appendDetail:[NSString stringWithFormat:NSLocalizedString(@"%ld bytes received", nil), [data length]]]; + [aItem appendDetail:[NSString stringWithFormat:NSLocalizedString(@"%ld bytes received", nil), data.length]]; - LLog(@"%ld items returned from %@", [[dict objectForKey:@"items"] count], [request url]); + LLog(@"%ld items returned from %@", [subscriptionsDict[@"items"] count], [request url]); NSMutableArray * articleArray = [NSMutableArray array]; - for (NSDictionary *newsItem in (NSArray*)[dict objectForKey:@"items"]) { + for (NSDictionary *newsItem in (NSArray*)subscriptionsDict[@"items"]) { - NSDate * articleDate = [NSDate dateWithTimeIntervalSince1970:[[newsItem objectForKey:@"published"] doubleValue]]; - NSString * articleGuid = [newsItem objectForKey:@"id"]; - Article *article = [[[Article alloc] initWithGuid:articleGuid] autorelease]; - [article setFolderId:[refreshedFolder itemId]]; + NSDate * articleDate = [NSDate dateWithTimeIntervalSince1970:[newsItem[@"published"] doubleValue]]; + NSString * articleGuid = newsItem[@"id"]; + Article *article = [[Article alloc] initWithGuid:articleGuid]; + article.folderId = refreshedFolder.itemId; - if ([newsItem objectForKey:@"author"] != nil) { - [article setAuthor:[newsItem objectForKey:@"author"]]; + if (newsItem[@"author"] != nil) { + article.author = newsItem[@"author"]; } else { - [article setAuthor:@""]; + article.author = @""; } - if ([newsItem objectForKey:@"content"] != nil ) { - [article setBody:[[newsItem objectForKey:@"content"] objectForKey:@"content"]]; - } else if ([newsItem objectForKey:@"summary"] != nil ) { - [article setBody:[[newsItem objectForKey:@"summary"] objectForKey:@"content"]]; + if (newsItem[@"content"] != nil ) { + article.body = newsItem[@"content"][@"content"]; + } else if (newsItem[@"summary"] != nil ) { + article.body = newsItem[@"summary"][@"content"]; } else { - [article setBody:@"Not available..."]; + article.body = @"Not available..."; } - for (NSString * category in (NSArray*)[newsItem objectForKey:@"categories"]) + for (NSString * category in (NSArray*)newsItem[@"categories"]) { if ([category hasSuffix:@"/read"]) [article markRead:YES]; if ([category hasSuffix:@"/starred"]) [article markFlagged:YES]; if ([category hasSuffix:@"/kept-unread"]) [article markRead:NO]; } - if ([newsItem objectForKey:@"title"]!=nil) { - [article setTitle:[[newsItem objectForKey:@"title"] summaryTextFromHTML]]; + if (newsItem[@"title"]!=nil) { + article.title = [newsItem[@"title"] summaryTextFromHTML]; } else { - [article setTitle:@""]; + article.title = @""; } - if ([[newsItem objectForKey:@"alternate"] count] != 0) { - [article setLink:[[[newsItem objectForKey:@"alternate"] objectAtIndex:0] objectForKey:@"href"]]; + if ([newsItem[@"alternate"] count] != 0) { + article.link = newsItem[@"alternate"][0][@"href"]; } else { - [article setLink:[refreshedFolder feedURL]]; + article.link = refreshedFolder.feedURL; } - [article setDate:articleDate]; + article.date = articleDate; - if ([[newsItem objectForKey:@"enclosure"] count] != 0) { - [article setEnclosure:[[[newsItem objectForKey:@"enclosure"] objectAtIndex:0] objectForKey:@"href"]]; + if ([newsItem[@"enclosure"] count] != 0) { + article.enclosure = newsItem[@"enclosure"][0][@"href"]; } else { - [article setEnclosure:@""]; + article.enclosure = @""; } - if ([[article enclosure] isNotEqualTo:@""]) + if ([article.enclosure isNotEqualTo:@""]) { [article setHasEnclosure:YES]; } @@ -330,212 +559,186 @@ - (void)feedRequestDone:(ASIHTTPRequest *)request [articleArray addObject:article]; } - Database *db = [Database sharedDatabase]; - __block NSInteger newArticlesFromFeed = 0; + Database *dbManager = [Database sharedManager]; + NSInteger newArticlesFromFeed = 0; // Here's where we add the articles to the database - if ([articleArray count] > 0) + if (articleArray.count > 0) { - [db doTransactionWithBlock:^(BOOL *rollback) { - NSArray * guidHistory = [db guidHistoryForFolderId:[refreshedFolder itemId]]; - [refreshedFolder clearCache]; - //BOOL hasCache = [db initArticleArray:refreshedFolder]; + NSArray * guidHistory = [dbManager guidHistoryForFolderId:refreshedFolder.itemId]; for (Article * article in articleArray) { - if ([db createArticle:[refreshedFolder itemId] article:article guidHistory:guidHistory] && ([article status] == MA_MsgStatus_New)) + if ([refreshedFolder createArticle:article guidHistory:guidHistory] && + (article.status == ArticleStatusNew)) { newArticlesFromFeed++; + } } // Set the last update date for this folder. - [db setFolderLastUpdate:[refreshedFolder itemId] lastUpdate:[NSDate date]]; - }]; //end transaction block + [dbManager setLastUpdate:[NSDate date] forFolder:refreshedFolder.itemId]; + } - if ([folderLastUpdateString isEqualToString:@""] || [folderLastUpdateString isEqualToString:@"(null)"]) folderLastUpdateString=@"0"; + if ([folderLastUpdateString isEqualToString:@""] || [folderLastUpdateString isEqualToString:@"(null)"]) { + folderLastUpdateString=@"0"; + } - [db doTransactionWithBlock:^(BOOL *rollback) { // Set the last update date given by the Open Reader server for this folder. - [db setFolderLastUpdateString:[refreshedFolder itemId] lastUpdateString:folderLastUpdateString]; + [dbManager setLastUpdateString:folderLastUpdateString forFolder:refreshedFolder.itemId]; // Set the HTML homepage for this folder. // a legal JSON string can have, as its outer "container", either an array or a dictionary/"object" - if ([[dict objectForKey:@"alternate"] isKindOfClass:[NSArray class]]) - [db setFolderHomePage:[refreshedFolder itemId] newHomePage:[[[dict objectForKey:@"alternate"] objectAtIndex:0] objectForKey:@"href"]]; - else - [db setFolderHomePage:[refreshedFolder itemId] newHomePage:[[dict objectForKey:@"alternate"] objectForKey:@"href"]]; - }]; //end transaction block + if ([subscriptionsDict[@"alternate"] isKindOfClass:[NSArray class]]) { + [dbManager setHomePage:subscriptionsDict[@"alternate"][0][@"href"] + forFolder:refreshedFolder.itemId]; + } + else { + [dbManager setHomePage:subscriptionsDict[@"alternate"][@"href"] + forFolder:refreshedFolder.itemId]; + } // Add to count of new articles so far countOfNewArticles += newArticlesFromFeed; - // Unread count may have changed - dispatch_async(dispatch_get_main_queue(), ^{ - AppController *controller = APPCONTROLLER; - [controller setStatusMessage:nil persist:NO]; - [controller showUnreadCountOnApplicationIconAndWindowTitle]; - [refreshedFolder clearNonPersistedFlag:MA_FFlag_Error]; - - // Send status to the activity log - if (newArticlesFromFeed == 0) - [aItem setStatus:NSLocalizedString(@"No new articles available", nil)]; - else - { - [aItem setStatus:[NSString stringWithFormat:NSLocalizedString(@"%d new articles retrieved", nil), newArticlesFromFeed]]; - [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_ArticleListStateChange" object:refreshedFolder]; - } - }); + [APPCONTROLLER setStatusMessage:nil persist:NO]; + [refreshedFolder clearNonPersistedFlag:MA_FFlag_Error]; + // Send status to the activity log + if (newArticlesFromFeed == 0) { + aItem.status = NSLocalizedString(@"No new articles available", nil); + } else { + aItem.status = [NSString stringWithFormat:NSLocalizedString(@"%d new articles retrieved", nil), newArticlesFromFeed]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_FoldersUpdated" + object:@(refreshedFolder.itemId)]; + } - [dict release]; - - NSString* feedIdentifier; - if( hostRequiresLastPathOnly ) - { - feedIdentifier = [[refreshedFolder feedURL] lastPathComponent]; - } - else - { - feedIdentifier = [refreshedFolder feedURL]; - } - - // Request id's of unread items - NSString * args = [NSString stringWithFormat:@"?ck=%@&client=%@&s=feed/%@&xt=user/-/state/com.google/read&n=1000&output=json", TIMESTAMP, ClientName, - percentEscape(feedIdentifier)]; - NSURL * url = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@%@", APIBaseURL, @"stream/items/ids", args]]; - ASIHTTPRequest *request2 = [self requestFromURL:url]; - [request2 setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:refreshedFolder, @"folder", aItem, @"log", nil]]; - [request2 setDidFinishSelector:@selector(readRequestDone:)]; - [[RefreshManager sharedManager] addConnection:request2]; - - // Request id's of starred items - // Note: Inoreader requires syntax "it=user/-/state/...", while TheOldReader ignores it and requires "s=user/-/state/..." - NSString* starredSelector; - if (hostRequiresSParameter) - { - starredSelector=@"s=user/-/state/com.google/starred"; - } - else - { - starredSelector=@"it=user/-/state/com.google/starred"; - } - - NSString * args3 = [NSString stringWithFormat:@"?ck=%@&client=%@&s=feed/%@&%@&n=1000&output=json", TIMESTAMP, ClientName, percentEscape(feedIdentifier), starredSelector]; - NSURL * url3 = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@%@", APIBaseURL, @"stream/items/ids", args3]]; - ASIHTTPRequest *request3 = [self requestFromURL:url3]; - [request3 setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:refreshedFolder, @"folder", aItem, @"log", nil]]; - [request3 setDidFinishSelector:@selector(starredRequestDone:)]; - [[RefreshManager sharedManager] addConnection:request3]; - } else { //other HTTP status response... - [aItem appendDetail:[NSString stringWithFormat:NSLocalizedString(@"HTTP code %d reported from server", nil), [request responseStatusCode]]]; + [aItem appendDetail:[NSString stringWithFormat:NSLocalizedString(@"HTTP code %d reported from server", nil), request.responseStatusCode]]; LOG_EXPR([request originalURL]); LOG_EXPR([request requestHeaders]); - LOG_EXPR([[[NSString alloc] initWithData:[request postBody] encoding:NSUTF8StringEncoding] autorelease]); + LOG_EXPR([[NSString alloc] initWithData:[request postBody] encoding:NSUTF8StringEncoding]); LOG_EXPR([request responseHeaders]); - LOG_EXPR([[[NSString alloc] initWithData:[request responseData] encoding:NSUTF8StringEncoding] autorelease]); + LOG_EXPR([[NSString alloc] initWithData:[request responseData] encoding:NSUTF8StringEncoding]); [aItem setStatus:NSLocalizedString(@"Error", nil)]; [refreshedFolder clearNonPersistedFlag:MA_FFlag_Updating]; [refreshedFolder setNonPersistedFlag:MA_FFlag_Error]; } + [CATransaction commit]; }); //block for dispatch_async } // callback - (void)readRequestDone:(ASIHTTPRequest *)request { - Folder *refreshedFolder = [[request userInfo] objectForKey:@"folder"]; - ActivityItem *aItem = [[request userInfo] objectForKey:@"log"]; - if ([request responseStatusCode] == 200) + dispatch_queue_t queue = [RefreshManager sharedManager].asyncQueue; + dispatch_async(queue, ^() { + + Folder *refreshedFolder = request.userInfo[@"folder"]; + ActivityItem *aItem = request.userInfo[@"log"]; + if (request.responseStatusCode == 200) { @try { - NSArray * dict; - @synchronized(jsonDecoder) { - dict = (NSArray *)[[jsonDecoder objectWithData:[request responseData]] objectForKey:@"itemRefs"]; - } - NSMutableArray * guidArray = [NSMutableArray arrayWithCapacity:[dict count]]; - for (NSDictionary *itemRef in dict) + NSArray * itemRefsArray; + NSError *jsonError; + itemRefsArray = [NSJSONSerialization JSONObjectWithData:request.responseData + options:NSJSONReadingMutableContainers + error:&jsonError][@"itemRefs"]; + NSMutableArray * guidArray = [NSMutableArray arrayWithCapacity:itemRefsArray.count]; + for (NSDictionary *itemRef in itemRefsArray) { NSString * guid; if( hostSupportsLongId ) { - guid = [NSString stringWithFormat:@"tag:google.com,2005:reader/item/%@",[itemRef objectForKey:@"id"]]; + guid = [NSString stringWithFormat:@"tag:google.com,2005:reader/item/%@",itemRef[@"id"]]; } else { // as described in http://code.google.com/p/google-reader-api/wiki/ItemId // the short version of id is a base 10 signed integer ; the long version includes a 16 characters base 16 representation - NSInteger shortId = [[itemRef objectForKey:@"id"] integerValue]; + NSInteger shortId = [itemRef[@"id"] integerValue]; guid = [NSString stringWithFormat:@"tag:google.com,2005:reader/item/%016qx",(long long)shortId]; } [guidArray addObject:guid]; + // now, mark relevant articles unread + [[refreshedFolder articleFromGuid:guid] markRead:NO]; } LLog(@"%ld unread items for %@", [guidArray count], [request url]); - Database * db = [Database sharedDatabase]; - [db doTransactionWithBlock:^(BOOL *rollback) { - [db markUnreadArticlesFromFolder:refreshedFolder guidArray:guidArray]; - }]; //end transaction block + + [[Database sharedManager] markUnreadArticlesFromFolder:refreshedFolder guidArray:guidArray]; + // reset starred statuses in cache : we will receive in -StarredRequestDone: the updated list + for (Article * article in [refreshedFolder articles]) + { + [article markFlagged:NO]; + } + } @catch (NSException *exception) { [aItem appendDetail:[NSString stringWithFormat:@"%@ %@",NSLocalizedString(@"Error", nil),exception]]; [aItem setStatus:NSLocalizedString(@"Error", nil)]; [refreshedFolder clearNonPersistedFlag:MA_FFlag_Updating]; [refreshedFolder setNonPersistedFlag:MA_FFlag_Error]; - [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_FoldersUpdated" object:[NSNumber numberWithInt:[refreshedFolder itemId]]]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_FoldersUpdated" object:@(refreshedFolder.itemId)]; return; } // try/catch // If this folder also requires an image refresh, add that - dispatch_queue_t queue = [[RefreshManager sharedManager] asyncQueue]; - if ([refreshedFolder flags] & MA_FFlag_CheckForImage) + dispatch_queue_t queue = [RefreshManager sharedManager].asyncQueue; + if (refreshedFolder.flags & MA_FFlag_CheckForImage) dispatch_async(queue, ^() { - [[RefreshManager sharedManager] refreshFavIcon:refreshedFolder]; + [[RefreshManager sharedManager] refreshFavIconForFolder:refreshedFolder]; }); } else //response status other than OK (200) { - [aItem appendDetail:[NSString stringWithFormat:@"%@ %@",NSLocalizedString(@"Error", nil),[[request error] localizedDescription ]]]; + [aItem appendDetail:[NSString stringWithFormat:@"%@ %@",NSLocalizedString(@"Error", nil),request.error.localizedDescription ]]; [aItem setStatus:NSLocalizedString(@"Error", nil)]; [refreshedFolder clearNonPersistedFlag:MA_FFlag_Updating]; [refreshedFolder setNonPersistedFlag:MA_FFlag_Error]; } + }); //block for dispatch_async } // callback - (void)starredRequestDone:(ASIHTTPRequest *)request { - Folder *refreshedFolder = [[request userInfo] objectForKey:@"folder"]; - ActivityItem *aItem = [[request userInfo] objectForKey:@"log"]; - if ([request responseStatusCode] == 200) + dispatch_queue_t queue = [RefreshManager sharedManager].asyncQueue; + dispatch_async(queue, ^() { + + Folder *refreshedFolder = request.userInfo[@"folder"]; + ActivityItem *aItem = request.userInfo[@"log"]; + if (request.responseStatusCode == 200) { @try { - NSArray * dict; - @synchronized(jsonDecoder) { - dict = (NSArray *)[[jsonDecoder objectWithData:[request responseData]] objectForKey:@"itemRefs"]; - } - NSMutableArray * guidArray = [NSMutableArray arrayWithCapacity:[dict count]]; - for (NSDictionary *itemRef in dict) + NSArray * itemRefsArray; + NSError *jsonError; + itemRefsArray = [NSJSONSerialization JSONObjectWithData:request.responseData + options:NSJSONReadingMutableContainers + error:&jsonError][@"itemRefs"]; + NSMutableArray * guidArray = [NSMutableArray arrayWithCapacity:itemRefsArray.count]; + for (NSDictionary *itemRef in itemRefsArray) { NSString * guid; if( hostSupportsLongId ) { - guid = [NSString stringWithFormat:@"tag:google.com,2005:reader/item/%@",[itemRef objectForKey:@"id"]]; + guid = [NSString stringWithFormat:@"tag:google.com,2005:reader/item/%@",itemRef[@"id"]]; } else { // as described in http://code.google.com/p/google-reader-api/wiki/ItemId // the short version of id is a base 10 signed integer ; the long version includes a 16 characters base 16 representation - NSInteger shortId = [[itemRef objectForKey:@"id"] integerValue]; + NSInteger shortId = [itemRef[@"id"] integerValue]; guid = [NSString stringWithFormat:@"tag:google.com,2005:reader/item/%016qx",(long long)shortId]; } [guidArray addObject:guid]; + [[refreshedFolder articleFromGuid:guid] markFlagged:YES]; } LLog(@"%ld starred items for %@", [guidArray count], [request url]); - Database * db = [Database sharedDatabase]; - [db doTransactionWithBlock:^(BOOL *rollback) { - [db markStarredArticlesFromFolder:refreshedFolder guidArray:guidArray]; - }]; //end transaction block + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_ArticleListContentChange" object:@(refreshedFolder.itemId)]; + + [[Database sharedManager] markStarredArticlesFromFolder:refreshedFolder guidArray:guidArray]; + [refreshedFolder clearNonPersistedFlag:MA_FFlag_Updating]; } @catch (NSException *exception) { [aItem appendDetail:[NSString stringWithFormat:@"%@ %@",NSLocalizedString(@"Error", nil),exception]]; @@ -546,129 +749,14 @@ - (void)starredRequestDone:(ASIHTTPRequest *)request } else //response status other than OK (200) { - [aItem appendDetail:[NSString stringWithFormat:@"%@ %@",NSLocalizedString(@"Error", nil),[[request error] localizedDescription ]]]; + [aItem appendDetail:[NSString stringWithFormat:@"%@ %@",NSLocalizedString(@"Error", nil),request.error.localizedDescription ]]; [aItem setStatus:NSLocalizedString(@"Error", nil)]; [refreshedFolder clearNonPersistedFlag:MA_FFlag_Updating]; [refreshedFolder setNonPersistedFlag:MA_FFlag_Error]; } - [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_FoldersUpdated" object:[NSNumber numberWithInt:[refreshedFolder itemId]]]; -} - --(void)authenticate -{ - Preferences * prefs = [Preferences standardPreferences]; - if (![prefs syncGoogleReader]) - return; - if (googleReaderStatus != notAuthenticated) { - LLog(@"Another instance is authenticating..."); - return; - } else { - LLog(@"Start first authentication..."); - googleReaderStatus = isAuthenticating; - [APPCONTROLLER setStatusMessage:NSLocalizedString(@"Authenticating on Open Reader", nil) persist:NO]; - } - - // restore from Preferences and from keychain - [username release]; - username = [[prefs syncingUser] retain]; - [openReaderHost release]; - openReaderHost = [[prefs syncServer] retain]; - // set server-specific particularities - hostSupportsLongId=NO; - hostRequiresSParameter=NO; - hostRequiresLastPathOnly=NO; - hostRequiresInoreaderAdditionalHeaders=NO; - if([openReaderHost isEqualToString:@"theoldreader.com"]){ - hostSupportsLongId=YES; - hostRequiresSParameter=YES; - hostRequiresLastPathOnly=YES; - } - if([openReaderHost rangeOfString:@"inoreader.com"].length !=0){ - hostRequiresInoreaderAdditionalHeaders=YES; - } - - - [password release]; - password = [[KeyChain getGenericPasswordFromKeychain:username serviceName:@"Vienna sync"] retain]; - [APIBaseURL release]; - APIBaseURL = [[NSString stringWithFormat:@"https://%@/reader/api/0/", openReaderHost] retain]; - - NSURL * url = [NSURL URLWithString:[NSString stringWithFormat:LoginBaseURL, openReaderHost]]; - ASIFormDataRequest *myRequest = [ASIFormDataRequest requestWithURL:url]; - [self commonRequestPrepare:myRequest]; - [myRequest setPostValue:username forKey:@"Email"]; - [myRequest setPostValue:password forKey:@"Passwd"]; - [myRequest startSynchronous]; - - NSString * response = [myRequest responseString]; - if (!response || [myRequest responseStatusCode] != 200) - { - LOG_EXPR([myRequest responseStatusCode]); - LOG_EXPR([myRequest responseHeaders]); - [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_GoogleAuthFailed" object:nil]; - [APPCONTROLLER setStatusMessage:nil persist:NO]; - googleReaderStatus = notAuthenticated; - [myRequest clearDelegatesAndCancel]; - return; - } - - NSArray * components = [response componentsSeparatedByString:@"\n"]; - [myRequest clearDelegatesAndCancel]; - - //NSString * sid = [[components objectAtIndex:0] substringFromIndex:4]; //unused - //NSString * lsid = [[components objectAtIndex:1] substringFromIndex:5]; //unused - [self setClientAuthToken:[NSString stringWithString:[[components objectAtIndex:2] substringFromIndex:5]]]; - - [self getToken]; - - if (authTimer == nil || ![authTimer isValid]) - //new request every 6 days - authTimer = [NSTimer scheduledTimerWithTimeInterval:6*24*3600 target:self selector:@selector(resetAuthentication) userInfo:nil repeats:YES]; -} - --(void)getToken -{ - LLog(@"Start Token Request!"); - ASIHTTPRequest * request = [self requestFromURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@token", APIBaseURL]]]; - [request addRequestHeader:@"Content-Type" value:@"application/x-www-form-urlencoded"]; - googleReaderStatus = isAuthenticating; - - [request startSynchronous]; - if ([request error]) - { - LOG_EXPR([request originalURL]); - LOG_EXPR([request requestHeaders]); - LOG_EXPR([[[NSString alloc] initWithData:[request postBody] encoding:NSUTF8StringEncoding] autorelease]); - LOG_EXPR([request responseHeaders]); - LOG_EXPR([[[NSString alloc] initWithData:[request responseData] encoding:NSUTF8StringEncoding] autorelease]); - [self setToken:nil]; - [request clearDelegatesAndCancel]; - return; - } - // Save token - [self setToken:[request responseString]]; - [request clearDelegatesAndCancel]; - googleReaderStatus = isAuthenticated; - - if (tokenTimer == nil || ![tokenTimer isValid]) - //tokens expire after 30 minutes : renew them every 25 minutes - tokenTimer = [NSTimer scheduledTimerWithTimeInterval:25*60 target:self selector:@selector(getToken) userInfo:nil repeats:YES]; - - [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"GRSync_Autheticated" object:nil]; -} - --(void)clearAuthentication -{ - googleReaderStatus = notAuthenticated; - [self setClientAuthToken:nil]; - [self setToken:nil]; -} - --(void)resetAuthentication -{ - [self clearAuthentication]; - [self authenticate]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_FoldersUpdated" object:@(refreshedFolder.itemId)]; + }); //block for dispatch_async } -(void)submitLoadSubscriptions { @@ -677,31 +765,32 @@ -(void)submitLoadSubscriptions { ASIHTTPRequest *subscriptionRequest = [self requestFromURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@subscription/list?client=%@&output=json",APIBaseURL,ClientName]]]; - [subscriptionRequest setDidFinishSelector:@selector(subscriptionsRequestDone:)]; + subscriptionRequest.didFinishSelector = @selector(subscriptionsRequestDone:); [[RefreshManager sharedManager] addConnection:subscriptionRequest]; } -(void)subscriptionsRequestDone:(ASIHTTPRequest *)request { LLog(@"Ending subscriptionRequest"); - NSDictionary * dict; - @synchronized(jsonDecoder) { - dict = [jsonDecoder objectWithData:[request responseData]]; - } + NSDictionary * subscriptionsDict; + NSError *jsonError; + subscriptionsDict = [NSJSONSerialization JSONObjectWithData:request.responseData + options:NSJSONReadingMutableContainers + error:&jsonError]; [localFeeds removeAllObjects]; - NSArray * localFolders = [APPCONTROLLER folders]; + NSArray * localFolders = APPCONTROLLER.folders; for (Folder * f in localFolders) { - if ([f feedURL]) { - [localFeeds addObject:[f feedURL]]; + if (f.feedURL) { + [localFeeds addObject:f.feedURL]; } } NSMutableArray * googleFeeds=[[NSMutableArray alloc] init]; - for (NSDictionary * feed in [dict objectForKey:@"subscriptions"]) + for (NSDictionary * feed in subscriptionsDict[@"subscriptions"]) { - NSString * feedID = [feed objectForKey:@"id"]; + NSString * feedID = feed[@"id"]; if (feedID == nil) break; NSString * feedURL = [feedID stringByReplacingOccurrencesOfString:@"feed/" withString:@"" options:0 range:NSMakeRange(0, 5)]; @@ -710,17 +799,17 @@ -(void)subscriptionsRequestDone:(ASIHTTPRequest *)request NSString * folderName = nil; - NSArray * categories = [feed objectForKey:@"categories"]; + NSArray * categories = feed[@"categories"]; for (NSDictionary * category in categories) { - if ([category objectForKey:@"label"]) + if (category[@"label"]) { - NSString * label = [category objectForKey:@"label"]; + NSString * label = category[@"label"]; NSArray * folderNames = [label componentsSeparatedByString:@" — "]; - folderName = [folderNames lastObject]; + folderName = folderNames.lastObject; // NNW nested folder char: — - NSMutableArray * params = [NSMutableArray arrayWithObjects:[[folderNames mutableCopy] autorelease], [NSNumber numberWithInt:MA_Root_Folder], nil]; + NSMutableArray * params = [NSMutableArray arrayWithObjects:[folderNames mutableCopy], @(MA_Root_Folder), nil]; [self createFolders:params]; break; //In case of multiple labels, we retain only the first one } @@ -728,25 +817,23 @@ -(void)subscriptionsRequestDone:(ASIHTTPRequest *)request if (![localFeeds containsObject:feedURL]) { - NSString *rssTitle = nil; - if ([feed objectForKey:@"title"]) { - rssTitle = [feed objectForKey:@"title"]; + NSString *rssTitle = @""; + if (feed[@"title"]) { + rssTitle = feed[@"title"]; } - NSArray * params = [NSArray arrayWithObjects:feedURL, rssTitle, folderName, nil]; + // folderName could be nil + NSArray * params = folderName ? @[feedURL, rssTitle, folderName] : @[feedURL, rssTitle]; [self createNewSubscription:params]; } else { // the feed is already known // set HomePage if the info is available - NSString* homePageURL = [feed objectForKey:@"htmlUrl"]; + NSString* homePageURL = feed[@"htmlUrl"]; if (homePageURL) { for (Folder * f in localFolders) { - if (IsGoogleReaderFolder(f) && [[f feedURL] isEqualToString:feedURL]) { - Database *db = [Database sharedDatabase]; - [db doTransactionWithBlock:^(BOOL *rollback) { - [db setFolderHomePage:[f itemId] newHomePage:homePageURL]; - }]; + if (IsGoogleReaderFolder(f) && [f.feedURL isEqualToString:feedURL]) { + [[Database sharedManager] setHomePage:homePageURL forFolder:f.itemId]; break; } } @@ -757,10 +844,10 @@ -(void)subscriptionsRequestDone:(ASIHTTPRequest *)request } //check if we have a folder which is not registered as a Open Reader feed - for (Folder * f in [APPCONTROLLER folders]) { - if (IsGoogleReaderFolder(f) && ![googleFeeds containsObject:[f feedURL]]) + for (Folder * f in APPCONTROLLER.folders) { + if (IsGoogleReaderFolder(f) && ![googleFeeds containsObject:f.feedURL]) { - [[Database sharedDatabase] deleteFolder:[f itemId]]; + [[Database sharedManager] deleteFolder:f.itemId]; } } @@ -769,7 +856,6 @@ -(void)subscriptionsRequestDone:(ASIHTTPRequest *)request // Unread count may have changed [controller setStatusMessage:nil persist:NO]; - [googleFeeds release]; } @@ -782,7 +868,7 @@ -(void)loadSubscriptions:(NSNotification *)nc } else { LLog(@"Firing directly"); - if ([self isReady]) { + if (clientAuthToken != nil) { LLog(@"Token available, finish subscription"); [self submitLoadSubscriptions]; } else { @@ -795,13 +881,12 @@ -(void)loadSubscriptions:(NSNotification *)nc -(void)subscribeToFeed:(NSString *)feedURL { - if (![self isReady]) - [self authenticate]; NSURL * url = [NSURL URLWithString:[NSString stringWithFormat:@"%@subscription/quickadd?client=%@",APIBaseURL,ClientName]]; ASIFormDataRequest *request = [self authentifiedFormRequestFromURL:url]; [request setPostValue:feedURL forKey:@"quickadd"]; // Needs to be synchronous so UI doesn't refresh too soon. + request.delegate = nil; [request startSynchronous]; LLog(@"Subscribe response status code: %d", [request responseStatusCode]); [request clearDelegatesAndCancel]; @@ -809,8 +894,6 @@ -(void)subscribeToFeed:(NSString *)feedURL -(void)unsubscribeFromFeed:(NSString *)feedURL { - if (![self isReady]) - [self authenticate]; NSURL *unsubscribeURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@subscription/edit",APIBaseURL]]; ASIFormDataRequest * myRequest = [self authentifiedFormRequestFromURL:unsubscribeURL]; [myRequest setPostValue:@"unsubscribe" forKey:@"ac"]; @@ -824,23 +907,20 @@ -(void)unsubscribeFromFeed:(NSString *)feedURL */ -(void)setFolderName:(NSString *)folderName forFeed:(NSString *)feedURL set:(BOOL)flag { - if (![self isReady]) - [self authenticate]; NSURL * url = [NSURL URLWithString:[NSString stringWithFormat:@"%@subscription/edit?client=%@",APIBaseURL,ClientName]]; ASIFormDataRequest *request = [self authentifiedFormRequestFromURL:url]; [request setPostValue:@"edit" forKey:@"ac"]; [request setPostValue:[NSString stringWithFormat:@"feed/%@", feedURL] forKey:@"s"]; [request setPostValue:[NSString stringWithFormat:@"user/-/label/%@", folderName] forKey:flag ? @"a" : @"r"]; + request.delegate = nil; [request startSynchronous]; LLog(@"Set folder response status code: %d", [request responseStatusCode]); [request clearDelegatesAndCancel]; } --(void)markRead:(NSString *)itemGuid readFlag:(BOOL)flag +-(void)markRead:(Article *)article readFlag:(BOOL)flag { - if (![self isReady]) - [self authenticate]; NSURL *markReadURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@edit-tag",APIBaseURL]]; ASIFormDataRequest * myRequest = [self authentifiedFormRequestFromURL:markReadURL]; if (flag) { @@ -849,14 +929,29 @@ -(void)markRead:(NSString *)itemGuid readFlag:(BOOL)flag [myRequest setPostValue:@"user/-/state/com.google/read" forKey:@"r"]; } [myRequest setPostValue:@"true" forKey:@"async"]; - [myRequest setPostValue:itemGuid forKey:@"i"]; + [myRequest setPostValue:article.guid forKey:@"i"]; + myRequest.userInfo = @{@"article": article,@"readFlag": @(flag)}; + myRequest.didFinishSelector = @selector(markReadDone:); [[RefreshManager sharedManager] addConnection:myRequest]; } --(void)markStarred:(NSString *)itemGuid starredFlag:(BOOL)flag +// callback : we check if the server did confirm the read status change +- (void)markReadDone:(ASIHTTPRequest *)request +{ + NSString *requestResponse = [[NSString alloc] initWithData:[request responseData] encoding:NSUTF8StringEncoding]; + if ([requestResponse isEqualToString:@"OK"]) { + Article * article = request.userInfo[@"article"]; + BOOL readFlag = [[request.userInfo valueForKey:@"readFlag"] boolValue]; + [[Database sharedManager] markArticleRead:article.folderId guid:article.guid isRead:readFlag]; + [article markRead:readFlag]; + NSNotificationCenter * nc = [NSNotificationCenter defaultCenter]; + [nc postNotificationOnMainThreadWithName:@"MA_Notify_FoldersUpdated" object:@(article.folderId)]; + [nc postNotificationOnMainThreadWithName:@"MA_Notify_ArticleListStateChange" object:@(article.folderId)]; + } +} + +-(void)markStarred:(Article *)article starredFlag:(BOOL)flag { - if (![self isReady]) - [self authenticate]; NSURL *markStarredURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@edit-tag",APIBaseURL]]; ASIFormDataRequest * myRequest = [self authentifiedFormRequestFromURL:markStarredURL]; if (flag) { @@ -867,64 +962,26 @@ -(void)markStarred:(NSString *)itemGuid starredFlag:(BOOL)flag } [myRequest setPostValue:@"true" forKey:@"async"]; - [myRequest setPostValue:itemGuid forKey:@"i"]; + [myRequest setPostValue:article.guid forKey:@"i"]; [[RefreshManager sharedManager] addConnection:myRequest]; } - --(void)dealloc -{ - [localFeeds release]; - localFeeds=nil; - [jsonDecoder release]; - jsonDecoder=nil; - [username release]; - username=nil; - [openReaderHost release]; - openReaderHost=nil; - [password release]; - password=nil; - [APIBaseURL release]; - APIBaseURL=nil; - [clientAuthToken release]; - clientAuthToken=nil; - [token release]; - token=nil; - [tokenTimer release]; - tokenTimer=nil; - [authTimer release]; - authTimer=nil; - [inoreaderAdditionalHeaders release]; - inoreaderAdditionalHeaders=nil; - [super dealloc]; -} - -/* sharedManager - * Returns the single instance of the Open Reader. - */ -+(GoogleReader *)sharedManager -{ - if (!_googleReader) - _googleReader = [[GoogleReader alloc] init]; - return _googleReader; -} - -(void)createNewSubscription:(NSArray *)params { LLog(@"createNewSubscription - START"); NSInteger underFolder = MA_Root_Folder; - NSString * feedURL = [params objectAtIndex:0]; + NSString * feedURL = params[0]; NSString *rssTitle = [NSString stringWithFormat:@""]; - if ([params count] > 1) + if (params.count > 1) { - if ([params count] > 2 ) { - NSString * folderName = [params objectAtIndex:2]; - Database * db = [Database sharedDatabase]; + if (params.count > 2 ) { + NSString * folderName = params[2]; + Database * db = [Database sharedManager]; Folder * folder = [db folderFromName:folderName]; - underFolder = [folder itemId]; + underFolder = folder.itemId; } - rssTitle = [params objectAtIndex:1]; + rssTitle = params[1]; } [APPCONTROLLER createNewGoogleReaderSubscription:feedURL underFolder:underFolder withTitle:rssTitle afterChild:-1]; @@ -935,39 +992,34 @@ -(void)createNewSubscription:(NSArray *)params - (void)createFolders:(NSMutableArray *)params { - LLog(@"createFolder - START"); - - NSMutableArray * folderNames = [params objectAtIndex:0]; - NSNumber * parentNumber = [params objectAtIndex:1]; + NSMutableArray * folderNames = params[0]; + NSNumber * parentNumber = params[1]; // Remove the parent parameter. We'll re-add it with a new value later. [params removeObjectAtIndex:1]; - Database * db = [Database sharedDatabase]; - NSString * folderName = [folderNames objectAtIndex:0]; - Folder * folder = [db folderFromName:folderName]; + Database * dbManager = [Database sharedManager]; + NSString * folderName = folderNames[0]; + Folder * folder = [dbManager folderFromName:folderName]; if (!folder) { - __block NSInteger newFolderId; - [db doTransactionWithBlock:^(BOOL *rollback) { - newFolderId = [db addFolder:[parentNumber intValue] afterChild:-1 folderName:folderName type:MA_Group_Folder canAppendIndex:NO]; - }]; //end transaction block - - parentNumber = [NSNumber numberWithInteger:newFolderId]; + NSInteger newFolderId; + newFolderId = [dbManager addFolder:parentNumber.integerValue afterChild:-1 folderName:folderName type:MA_Group_Folder canAppendIndex:NO]; + + parentNumber = @(newFolderId); + } + else { + parentNumber = @(folder.itemId); } - else parentNumber = [NSNumber numberWithInteger:[folder itemId]]; [folderNames removeObjectAtIndex:0]; - if ([folderNames count] > 0) + if (folderNames.count > 0) { // Add the new parent parameter. [params addObject:parentNumber]; [self createFolders:params]; } - - LLog(@"createFolder - END"); - } @end diff --git a/src/GradientView.m b/src/GradientView.m index c5e3637a7b..971a2e23d0 100644 --- a/src/GradientView.m +++ b/src/GradientView.m @@ -36,16 +36,8 @@ -(void)awakeFromNib */ -(void)drawRect:(NSRect)rect { - NSRect iRect = NSMakeRect(0, 0, 1, [backgroundBrush size].height - 1); + NSRect iRect = NSMakeRect(0, 0, 1, backgroundBrush.size.height - 1); [backgroundBrush drawInRect:rect fromRect:iRect operation:NSCompositeSourceOver fraction:1]; } -/* dealloc - * Release resources at the end. - */ --(void)dealloc -{ - [backgroundBrush release]; - backgroundBrush=nil; - [super dealloc]; -}@end +@end diff --git a/src/HelperFunctions.h b/src/HelperFunctions.h index d8aa2f09ec..3be7105036 100644 --- a/src/HelperFunctions.h +++ b/src/HelperFunctions.h @@ -47,5 +47,4 @@ NSMenuItem * copyOfMenuItemWithAction(SEL theSelector); NSString * getDefaultBrowser(void); NSURL * cleanedUpAndEscapedUrlFromString(NSString * theUrl); BOOL hasOSScriptsMenu(void); -OSStatus GotoHelpPage(CFStringRef pagePath, CFStringRef anchorName); NSString * percentEscape(NSString *string); diff --git a/src/HelperFunctions.m b/src/HelperFunctions.m index 35ff6ac89d..572b7abd39 100644 --- a/src/HelperFunctions.m +++ b/src/HelperFunctions.m @@ -19,25 +19,21 @@ #import "HelperFunctions.h" #import -#import #import -// Private functions -static OSStatus RegisterMyHelpBook(void); - /* hasOSScriptsMenu * Determines whether the OS script menu is present or not. */ BOOL hasOSScriptsMenu(void) { - NSString * pathToUIServerPlist = [@"~/Library/Preferences/com.apple.systemuiserver.plist" stringByExpandingTildeInPath]; + NSString * pathToUIServerPlist = (@"~/Library/Preferences/com.apple.systemuiserver.plist").stringByExpandingTildeInPath; NSDictionary * properties = [NSDictionary dictionaryWithContentsOfFile:pathToUIServerPlist]; - NSArray * menuExtras = [properties objectForKey:@"menuExtras"]; - int index; + NSArray * menuExtras = properties[@"menuExtras"]; + NSInteger index; - for (index = 0; index < [menuExtras count]; ++index) + for (index = 0; index < menuExtras.count; ++index) { - if ([[menuExtras objectAtIndex:index] hasSuffix:@"Script Menu.menu"]) + if ([menuExtras[index] hasSuffix:@"Script Menu.menu"]) return YES; } return NO; @@ -48,15 +44,10 @@ BOOL hasOSScriptsMenu(void) */ NSString * getDefaultBrowser(void) { - NSURL * testURL = [NSURL URLWithString:@"http://example.net"]; - NSString * registeredAppURL = nil; - CFURLRef appURL = nil; + NSURL *testURL = [NSURL URLWithString:@"http://example.net"]; + NSURL *defaultBrowserURL = [[NSWorkspace sharedWorkspace] URLForApplicationToOpenURL:testURL]; - if (LSGetApplicationForURL((CFURLRef)testURL, kLSRolesAll, NULL, &appURL) != kLSApplicationNotFoundErr) - registeredAppURL = [(NSURL *)appURL path]; - if (appURL != nil) - CFRelease(appURL); - return [[registeredAppURL lastPathComponent] stringByDeletingPathExtension]; + return defaultBrowserURL.lastPathComponent.stringByDeletingPathExtension; } /* menuWithAction @@ -65,14 +56,14 @@ BOOL hasOSScriptsMenu(void) */ NSMenuItem * menuItemWithAction(SEL theSelector) { - NSArray * arrayOfMenus = [[NSApp mainMenu] itemArray]; - int count = [arrayOfMenus count]; - int index; + NSArray * arrayOfMenus = NSApp.mainMenu.itemArray; + NSInteger count = arrayOfMenus.count; + NSInteger index; for (index = 0; index < count; ++index) { - NSMenu * subMenu = [[arrayOfMenus objectAtIndex:index] submenu]; - int itemIndex = [subMenu indexOfItemWithTarget:[NSApp delegate] andAction:theSelector]; + NSMenu * subMenu = [arrayOfMenus[index] submenu]; + NSInteger itemIndex = [subMenu indexOfItemWithTarget:NSApp.delegate andAction:theSelector]; if (itemIndex >= 0) return [subMenu itemAtIndex:itemIndex]; } @@ -85,14 +76,14 @@ BOOL hasOSScriptsMenu(void) */ NSMenuItem * menuItemOfMenuWithAction(NSMenu * menu, SEL theSelector) { - NSArray * arrayOfMenus = [menu itemArray]; - int count = [arrayOfMenus count]; - int index; + NSArray * arrayOfMenus = menu.itemArray; + NSInteger count = arrayOfMenus.count; + NSInteger index; for (index = 0; index < count; ++index) { - NSMenu * subMenu = [[arrayOfMenus objectAtIndex:index] submenu]; - int itemIndex = [subMenu indexOfItemWithTarget:[NSApp delegate] andAction:theSelector]; + NSMenu * subMenu = [arrayOfMenus[index] submenu]; + NSInteger itemIndex = [subMenu indexOfItemWithTarget:NSApp.delegate andAction:theSelector]; if (itemIndex >= 0) return [subMenu itemAtIndex:itemIndex]; } @@ -122,7 +113,7 @@ BOOL hasOSScriptsMenu(void) { NSURL *urlToLoad = nil; NSPasteboard * pasteboard = [NSPasteboard pasteboardWithName:@"ViennaIDNURLPasteboard"]; - [pasteboard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil]; + [pasteboard declareTypes:@[NSStringPboardType] owner:nil]; @try { if ([pasteboard setString:theUrl forType:NSStringPboardType]) @@ -148,7 +139,7 @@ BOOL hasOSScriptsMenu(void) NSMenuItem * copyOfMenuItemWithAction(SEL theSelector) { NSMenuItem * item = menuItemWithAction(theSelector); - return (item) ? [[[NSMenuItem alloc] initWithTitle:[item title] action:theSelector keyEquivalent:@""] autorelease] : nil; + return (item) ? [[NSMenuItem alloc] initWithTitle:item.title action:theSelector keyEquivalent:@""] : nil; } /* menuWithTitleAndAction @@ -156,7 +147,7 @@ BOOL hasOSScriptsMenu(void) */ NSMenuItem * menuItemWithTitleAndAction(NSString * theTitle, SEL theSelector) { - return [[[NSMenuItem alloc] initWithTitle:theTitle action:theSelector keyEquivalent:@""] autorelease]; + return [[NSMenuItem alloc] initWithTitle:theTitle action:theSelector keyEquivalent:@""]; } /* loadMapFromPath @@ -183,7 +174,7 @@ void loadMapFromPath(NSString * path, NSMutableDictionary * pathMappings, BOOL f if ([fileName isEqualToString:@".DS_Store"]) continue; - [pathMappings setValue:fullPath forKey:[fileName stringByDeletingPathExtension]]; + [pathMappings setValue:fullPath forKey:fileName.stringByDeletingPathExtension]; } } } @@ -200,7 +191,7 @@ BOOL isAccessible(NSString * urlString) NSURL * url = [NSURL URLWithString:urlString]; - target = SCNetworkReachabilityCreateWithName(NULL, [[url host] UTF8String]); + target = SCNetworkReachabilityCreateWithName(NULL, url.host.UTF8String); if (target!= nil) { ok = SCNetworkReachabilityGetFlags(target, &flags); @@ -225,8 +216,11 @@ void runOKAlertPanel(NSString * titleString, NSString * bodyText, ...) va_start(arguments, bodyText); fullBodyText = [[NSString alloc] initWithFormat:bodyText arguments:arguments]; // Security: arguments may contain formatting characters, so don't use fullBodyText as format string. - NSRunAlertPanel(titleString, @"%@", NSLocalizedString(@"OK", nil), nil, nil, fullBodyText); - [fullBodyText release]; + NSAlert *alert = [[NSAlert alloc] init]; + alert.alertStyle = NSAlertStyleInformational; + alert.messageText = titleString; + alert.informativeText = fullBodyText; + [alert runModal]; va_end(arguments); } @@ -241,75 +235,13 @@ void runOKAlertSheet(NSString * titleString, NSString * bodyText, ...) va_start(arguments, bodyText); fullBodyText = [[NSString alloc] initWithFormat:bodyText arguments:arguments]; // Security: arguments may contain formatting characters, so don't use fullBodyText as format string. - NSBeginAlertSheet(titleString, - NSLocalizedString(@"OK", nil), - nil, - nil, - [NSApp mainWindow], - nil, - nil, - nil, nil, - @"%@", - fullBodyText); - [fullBodyText release]; + NSAlert *alert = [[NSAlert alloc] init]; + alert.alertStyle = NSAlertStyleInformational; + alert.messageText = titleString; + alert.informativeText = fullBodyText; + [alert beginSheetModalForWindow:NSApp.mainWindow completionHandler:^(NSModalResponse returnCode) { + // No action to take + }]; + va_end(arguments); } - -/* RegisterMyHelpBook - * Ensure that the help book is registered before GotoHelpPage can be used. - */ -static OSStatus RegisterMyHelpBook(void) -{ - OSStatus err = noErr; - - CFBundleRef myApplicationBundle = CFBundleGetMainBundle(); - if (myApplicationBundle == NULL) - err = fnfErr; - else - { - CFURLRef myBundleURL = CFBundleCopyBundleURL(myApplicationBundle); - if (myBundleURL == NULL) - err = fnfErr; - else - { - FSRef myBundleRef; - if (!CFURLGetFSRef(myBundleURL, &myBundleRef)) - err = fnfErr; - if (err == noErr) - err = AHRegisterHelpBook(&myBundleRef); - CFRelease(myBundleURL); - } - } - return err; -} - -/* GotoHelpPage - * Displays a specified page of the help file. - */ -OSStatus GotoHelpPage (CFStringRef pagePath, CFStringRef anchorName) -{ - CFBundleRef myApplicationBundle = NULL; - CFStringRef myBookName = NULL; - OSStatus err; - - err = RegisterMyHelpBook(); - if (err != noErr) - return err; - myApplicationBundle = CFBundleGetMainBundle(); - if (myApplicationBundle == NULL) - err = fnfErr; - else - { - myBookName = CFBundleGetValueForInfoDictionaryKey(myApplicationBundle, CFSTR("CFBundleHelpBookName")); - if (myBookName == NULL) - err = fnfErr; - else - { - if (CFGetTypeID(myBookName) != CFStringGetTypeID()) - err = paramErr; - } - } - if (err == noErr) - err = AHGotoPage(myBookName, pagePath, anchorName); - return err; -} diff --git a/src/ImageAndTextCell.h b/src/ImageAndTextCell.h index 4119b5934f..ca2b547ec3 100644 --- a/src/ImageAndTextCell.h +++ b/src/ImageAndTextCell.h @@ -28,8 +28,8 @@ NSImage * image; NSImage * auxiliaryImage; NSColor * countBackgroundColour; - int offset; - int count; + NSInteger offset; + NSInteger count; BOOL hasCount; BOOL inProgress; @@ -37,15 +37,12 @@ } // Accessor functions --(void)setOffset:(int)offset; --(void)setImage:(NSImage *)anImage; --(void)setAuxiliaryImage:(NSImage *)anAuxiliaryImage; --(void)setCount:(int)newCount; +-(void)setCount:(NSInteger)newCount; -(void)clearCount; -(void)setCountBackgroundColour:(NSColor *)newColour; --(NSImage *)image; --(NSImage *)auxiliaryImage; --(int)offset; +@property (strong) NSImage *image; +@property (nonatomic, strong) NSImage *auxiliaryImage; +@property (nonatomic) NSInteger offset; -(void)drawCellImage:(NSRect *)cellFrame inView:(NSView *)controlView; - (void)setInProgress:(BOOL)newInProgress; - (void)setItem:(TreeNode *)newItem; diff --git a/src/ImageAndTextCell.m b/src/ImageAndTextCell.m index 49f1660663..dc03d14867 100644 --- a/src/ImageAndTextCell.m +++ b/src/ImageAndTextCell.m @@ -34,7 +34,7 @@ @implementation ImageAndTextCell /* init * Initialise a default instance of our cell. */ --(id)init +-(instancetype)init { if ((self = [super init]) != nil) { @@ -51,13 +51,13 @@ -(id)init -copyWithZone:(NSZone *)zone\ { ImageAndTextCell *cell = (ImageAndTextCell *)[super copyWithZone:zone]; - cell->image = [image retain]; - cell->auxiliaryImage = [auxiliaryImage retain]; + cell->image = image; + cell->auxiliaryImage = auxiliaryImage; cell->offset = offset; cell->hasCount = hasCount; cell->count = count; cell->inProgress = inProgress; - cell->countBackgroundColour = [countBackgroundColour retain]; + cell->countBackgroundColour = countBackgroundColour; cell->item = item; return cell; @@ -66,7 +66,7 @@ -(id)init /* setOffset * Sets the new offset at which the cell contents will be drawn. */ --(void)setOffset:(int)newOffset +-(void)setOffset:(NSInteger)newOffset { offset = newOffset; } @@ -74,7 +74,7 @@ -(void)setOffset:(int)newOffset /* offset * Returns the current cell offset in effect. */ --(int)offset +-(NSInteger)offset { return offset; } @@ -84,8 +84,6 @@ -(int)offset */ -(void)setImage:(NSImage *)anImage { - [anImage retain]; - [image release]; image = anImage; } @@ -94,7 +92,7 @@ -(void)setImage:(NSImage *)anImage */ -(NSImage *)image { - return [[image retain] autorelease]; + return image; } /* setAuxiliaryImage @@ -103,8 +101,6 @@ -(NSImage *)image */ -(void)setAuxiliaryImage:(NSImage *)newAuxiliaryImage { - [newAuxiliaryImage retain]; - [auxiliaryImage release]; auxiliaryImage = newAuxiliaryImage; } @@ -113,13 +109,13 @@ -(void)setAuxiliaryImage:(NSImage *)newAuxiliaryImage */ -(NSImage *)auxiliaryImage { - return [[auxiliaryImage retain] autorelease];; + return auxiliaryImage;; } /* setCount * Sets the value to be displayed in the count button. */ --(void)setCount:(int)newCount +-(void)setCount:(NSInteger)newCount { count = newCount; hasCount = YES; @@ -138,8 +134,6 @@ -(void)clearCount */ -(void)setCountBackgroundColour:(NSColor *)newColour { - [newColour retain]; - [countBackgroundColour release]; countBackgroundColour = newColour; } @@ -169,11 +163,11 @@ -(void)drawCellImage:(NSRect *)cellFrame inView:(NSView *)controlView NSSize imageSize; NSRect imageFrame; - imageSize = [image size]; + imageSize = image.size; NSDivideRect(*cellFrame, &imageFrame, cellFrame, 3 + imageSize.width, NSMinXEdge); - if ([self drawsBackground]) + if (self.drawsBackground) { - [[self backgroundColor] set]; + [self.backgroundColor set]; NSRectFill(imageFrame); } imageFrame.origin.x += 3; @@ -195,9 +189,9 @@ - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView // and then reduce cellFrame to keep from overlapping it if (inProgress) { - NSProgressIndicator *progressIndicator = [item progressIndicator]; + NSProgressIndicator *progressIndicator = item.progressIndicator; if (!progressIndicator) - progressIndicator = [item allocAndStartProgressIndicator]; + progressIndicator = item.allocAndStartProgressIndicator; NSRect progressIndicatorFrame; @@ -207,10 +201,10 @@ - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView progressIndicatorFrame.origin.x += PROGRESS_INDICATOR_LEFT_MARGIN; progressIndicatorFrame.origin.y += (cellFrame.size.height - PROGRESS_INDICATOR_DIMENSION) / 2.0; - if (!NSEqualRects([progressIndicator frame], progressIndicatorFrame)) { - [progressIndicator setFrame:progressIndicatorFrame]; + if (!NSEqualRects(progressIndicator.frame, progressIndicatorFrame)) { + progressIndicator.frame = progressIndicatorFrame; - if ([progressIndicator superview] != controlView) + if (progressIndicator.superview != controlView) [controlView addSubview:progressIndicator]; } } @@ -231,11 +225,11 @@ - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView NSSize imageSize; NSRect imageFrame; - imageSize = [auxiliaryImage size]; + imageSize = auxiliaryImage.size; NSDivideRect(cellFrame, &imageFrame, &cellFrame, 3 + imageSize.width, NSMaxXEdge); - if ([self drawsBackground]) + if (self.drawsBackground) { - [[self backgroundColor] set]; + [self.backgroundColor set]; NSRectFill(imageFrame); } imageFrame.size = imageSize; @@ -250,27 +244,24 @@ - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView // button on the right of the cell. if (hasCount) { - NSString * number = [NSString stringWithFormat:@"%i", count]; + NSString * number = [NSString stringWithFormat:@"%li", (long)count]; // Use the current font point size as a guide for the count font size - float pointSize = [[self font] pointSize]; + CGFloat pointSize = self.font.pointSize; // Create attributes for drawing the count. - NSDictionary * attributes = [[NSDictionary alloc] initWithObjectsAndKeys:[NSFont fontWithName:@"Helvetica-Bold" size:pointSize], - NSFontAttributeName, - [NSColor whiteColor], - NSForegroundColorAttributeName, - nil]; + NSDictionary * attributes = @{NSFontAttributeName: [NSFont fontWithName:@"Helvetica-Bold" size:pointSize], + NSForegroundColorAttributeName: [NSColor whiteColor]}; NSSize numSize = [number sizeWithAttributes:attributes]; // Compute the dimensions of the count rectangle. - int cellWidth = MAX(numSize.width + 6, numSize.height + 1) + 1; + CGFloat cellWidth = MAX(numSize.width + 6.0, numSize.height + 1.0) + 1.0; NSRect countFrame; NSDivideRect(cellFrame, &countFrame, &cellFrame, cellWidth, NSMaxXEdge); - if ([self drawsBackground]) + if (self.drawsBackground) { - [[self backgroundColor] set]; + [self.backgroundColor set]; NSRectFill(countFrame); } @@ -283,7 +274,6 @@ - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView // Draw the count in the rounded rectangle we just created. NSPoint point = NSMakePoint(NSMidX(countFrame) - numSize.width / 2.0f, NSMidY(countFrame) - numSize.height / 2.0f ); [number drawAtPoint:point withAttributes:attributes]; - [attributes release]; } // Draw the text @@ -302,7 +292,7 @@ -(void)selectWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText if ([controlView isKindOfClass:[FolderView class]]) { if (image != nil) - aRect.origin.x += [image size].width + 3; + aRect.origin.x += image.size.width + 3; ++aRect.origin.y; [controlView performSelector:@selector(prvtResizeTheFieldEditor) withObject:nil afterDelay:0.001]; } @@ -315,7 +305,7 @@ -(NSArray*)accessibilityAttributeNames if (!attributes) { NSSet * set = [NSSet setWithArray:[super accessibilityAttributeNames]]; - attributes = [[[set setByAddingObject:NSAccessibilityDescriptionAttribute] allObjects] retain]; + attributes = [set setByAddingObject:NSAccessibilityDescriptionAttribute].allObjects; } return attributes; } @@ -337,18 +327,4 @@ -(id)accessibilityAttributeValue:(NSString *)attribute return [super accessibilityAttributeValue:attribute]; } -/* dealloc - * Delete our resources. - */ --(void)dealloc -{ - [countBackgroundColour release]; - countBackgroundColour=nil; - [auxiliaryImage release]; - auxiliaryImage=nil; - [image release]; - image=nil; - [super dealloc]; -} - @end \ No newline at end of file diff --git a/src/Import.h b/src/Import.h index d536255cfb..7895bfd1b7 100644 --- a/src/Import.h +++ b/src/Import.h @@ -19,10 +19,9 @@ // #import -#import "Database.h" -#import "AppController.h" -@interface AppController (Import) - -(IBAction)importSubscriptions:(id)sender; - -(void)importFromFile:(NSString *)importFileName; +@interface Import : NSObject + ++ (void)importFromFile:(NSString *)importFileName; + @end diff --git a/src/Import.m b/src/Import.m index 04eae78846..9b4021b67c 100644 --- a/src/Import.m +++ b/src/Import.m @@ -19,126 +19,115 @@ // #import "Import.h" -#import "XMLParser.h" #import "StringExtensions.h" -#import "ViennaApp.h" #import "BJRWindowWithToolbar.h" +#import "Database.h" -@implementation AppController (Import) -/* importSubscriptions - * Import an OPML file which lists RSS feeds. +@implementation Import + +/* importFromFile + * Import a list of RSS subscriptions. */ --(IBAction)importSubscriptions:(id)sender ++ (void)importFromFile:(NSString *)importFileName { - NSOpenPanel * panel = [NSOpenPanel openPanel]; - [panel beginSheetModalForWindow:mainWindow - completionHandler: ^(NSInteger returnCode) { - if (returnCode == NSOKButton) - { - [panel orderOut:self]; - [self importFromFile:[[panel URL] path]]; - } - }]; - panel = nil; + NSData * data = [NSData dataWithContentsOfFile:importFileName.stringByExpandingTildeInPath]; + BOOL hasError = NO; + NSInteger countImported = 0; + + if (data != nil) + { + NSError *error = nil; + NSXMLDocument *opmlDocument = [[NSXMLDocument alloc] initWithData:data + options:NSXMLNodeLoadExternalEntitiesNever + error:&error]; + if (error) + { + NSRunAlertPanel(NSLocalizedString(@"Error importing subscriptions title", nil), + NSLocalizedString(@"Error importing subscriptions body", nil), + NSLocalizedString(@"OK", nil), nil, nil); + hasError = YES; + } + else + { + NSArray *outlines = [opmlDocument nodesForXPath:@"opml/body/outline" error:nil]; + + countImported = [self importSubscriptionGroup:outlines underParent:MA_Root_Folder]; + } + } + + // Announce how many we successfully imported + if (!hasError) + { + NSRunAlertPanel(NSLocalizedString(@"RSS Subscription Import Title", nil), NSLocalizedString(@"%d subscriptions successfully imported", nil), NSLocalizedString(@"OK", nil), nil, nil, countImported); + } } + /* importSubscriptionGroup * Import one group of an OPML subscription tree. */ --(int)importSubscriptionGroup:(XMLParser *)tree underParent:(int)parentId ++ (NSInteger)importSubscriptionGroup:(NSArray *)outlines underParent:(NSInteger)parentId { - int countImported = 0; - int count = [tree countOfChildren]; - int index; + NSInteger countImported = 0; - for (index = 0; index < count; ++index) + for (NSXMLElement *outlineElement in outlines) { - XMLParser * outlineItem = [tree treeByIndex:index]; - NSDictionary * entry = [outlineItem attributesForTree]; - NSString * feedTitle = [[entry objectForKey:@"title"] stringByUnescapingExtendedCharacters]; - NSString * feedDescription = [[entry objectForKey:@"description"] stringByUnescapingExtendedCharacters]; - NSString * feedURL = [[entry objectForKey:@"xmlurl"] stringByUnescapingExtendedCharacters]; - NSString * feedHomePage = [[entry objectForKey:@"htmlurl"] stringByUnescapingExtendedCharacters]; + NSString *feedText = ([outlineElement attributeForName:@"text"].stringValue).stringByEscapingExtendedCharacters; + NSString *feedDescription = ([outlineElement attributeForName:@"description"].stringValue).stringByEscapingExtendedCharacters; + NSString *feedURL = ([outlineElement attributeForName:@"xmlUrl"].stringValue).stringByEscapingExtendedCharacters; + NSString *feedHomePage = ([outlineElement attributeForName:@"htmlUrl"].stringValue).stringByEscapingExtendedCharacters; + + Database * dbManager = [Database sharedManager]; - // Some OPML exports use 'text' instead of 'title'. - if (feedTitle == nil || [feedTitle length] == 0u) + // Some OPML exports use 'title' instead of 'text'. + if (feedText == nil || feedText.length == 0u) { - NSString * feedText = [[entry objectForKey:@"text"] stringByUnescapingExtendedCharacters]; - if (feedText != nil) - feedTitle = feedText; + NSString * feedTitle = ([outlineElement attributeForName:@"title"].stringValue).stringByEscapingExtendedCharacters; + if (feedTitle != nil) { + feedText = feedTitle; + } } // Do double-decoding of the title to get around a bug in some commercial newsreaders // where they double-encode characters - feedTitle = [feedTitle stringByUnescapingExtendedCharacters]; + feedText = feedText.stringByUnescapingExtendedCharacters; if (feedURL == nil) { // This is a new group so try to create it. If there's an error then default to adding // the sub-group items under the parent. - if (feedTitle != nil) + if (feedText != nil) { - int folderId = [db addFolder:parentId afterChild:-1 folderName:feedTitle type:MA_Group_Folder canAppendIndex:NO]; - if (folderId == -1) + NSInteger folderId = [dbManager addFolder:parentId afterChild:-1 + folderName:feedText type:MA_Group_Folder + canAppendIndex:NO]; + if (folderId == -1) { folderId = MA_Root_Folder; - countImported += [self importSubscriptionGroup:outlineItem underParent:folderId]; + } + countImported += [self importSubscriptionGroup:outlineElement.children underParent:folderId]; } } - else if (feedTitle != nil) + else if (feedText != nil) { Folder * folder; - int folderId; + NSInteger folderId; - if ((folder = [db folderFromFeedURL:feedURL]) != nil) - folderId = [folder itemId]; + if ((folder = [dbManager folderFromFeedURL:feedURL]) != nil) + folderId = folder.itemId; else { - folderId = [db addRSSFolder:feedTitle underParent:parentId afterChild:-1 subscriptionURL:feedURL]; + folderId = [dbManager addRSSFolder:feedText underParent:parentId afterChild:-1 subscriptionURL:feedURL]; ++countImported; } - if (feedDescription != nil) - [db setFolderDescription:folderId newDescription:feedDescription]; - if (feedHomePage != nil) - [db setFolderHomePage:folderId newHomePage:feedHomePage]; + if (feedDescription != nil) { + [dbManager setDescription:feedDescription forFolder:folderId]; + } + if (feedHomePage != nil) { + [dbManager setHomePage:feedHomePage forFolder:folderId]; + } } } return countImported; } - -/* importFromFile - * Import a list of RSS subscriptions. - */ --(void)importFromFile:(NSString *)importFileName -{ - NSData * data = [NSData dataWithContentsOfFile:[importFileName stringByExpandingTildeInPath]]; - BOOL hasError = NO; - __block int countImported = 0; - - if (data != nil) - { - XMLParser * tree = [[XMLParser alloc] init]; - if (![tree setData:data]) - { - NSRunAlertPanel(NSLocalizedString(@"Error importing subscriptions title", nil), - NSLocalizedString(@"Error importing subscriptions body", nil), - NSLocalizedString(@"OK", nil), nil, nil); - hasError = YES; - } - else - { - XMLParser * bodyTree = [tree treeByPath:@"opml/body"]; - [db doTransactionWithBlock:^(BOOL *rollback) { - countImported = [self importSubscriptionGroup:bodyTree underParent:MA_Root_Folder]; - }]; //end transaction block - } - [tree release]; - } - - // Announce how many we successfully imported - if (!hasError) - { - NSRunAlertPanel(NSLocalizedString(@"RSS Subscription Import Title", nil), NSLocalizedString(@"%d subscriptions successfully imported", nil), NSLocalizedString(@"OK", nil), nil, nil, countImported); - } -} @end diff --git a/src/InfoWindow.h b/src/InfoWindow.h index 7aac57aa7a..06364cdcfd 100644 --- a/src/InfoWindow.h +++ b/src/InfoWindow.h @@ -26,7 +26,7 @@ // Public functions +(InfoWindowManager *)infoWindowManager; --(void)showInfoWindowForFolder:(int)folderId; +-(void)showInfoWindowForFolder:(NSInteger)folderId; @end @interface InfoWindow : NSWindowController { @@ -42,7 +42,7 @@ IBOutlet NSButton * loadFullHTML; IBOutlet NSTextField * folderDescription; IBOutlet NSButton * validateButton; - int infoFolderId; + NSInteger infoFolderId; } // Action handlers diff --git a/src/InfoWindow.m b/src/InfoWindow.m index 7d3fce04cf..c9fb619c7e 100644 --- a/src/InfoWindow.m +++ b/src/InfoWindow.m @@ -25,11 +25,8 @@ #import "AppController.h" #import "Folder.h" -// Singleton controller for all info windows -static InfoWindowManager * _infoWindowManager = nil; - @interface InfoWindow (private) - -(id)initWithFolder:(int)folderId; + -(instancetype)initWithFolder:(NSInteger)folderId; -(void)enableValidateButton; -(void)updateFolder; @end @@ -41,27 +38,15 @@ @implementation InfoWindowManager */ +(InfoWindowManager *)infoWindowManager { - @synchronized(self) - { - if (_infoWindowManager == nil) + // Singleton controller for all info windows + static InfoWindowManager * _infoWindowManager = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ _infoWindowManager = [[InfoWindowManager alloc] init]; - } + }); return _infoWindowManager; } -/* allocWithZone - * Override to ensure that only one instance can be initialised. - */ -+(id)allocWithZone:(NSZone *)zone -{ - @synchronized(self) - { - if (_infoWindowManager == nil) - return [super allocWithZone:zone]; - } - return _infoWindowManager; -} - /* copyWithZone * Override to return ourself. */ @@ -70,43 +55,12 @@ -(id)copyWithZone:(NSZone *)zone return self; } -/* retain - * Override to return ourself. - */ --(id)retain -{ - return self; -} - -/* retainCount - * Return NSUIntegerMax to denote an object that cannot be released. - */ --(NSUInteger)retainCount -{ - return NSUIntegerMax; -} - -/* release - * Override to do nothing. - */ --(oneway void)release -{ -} - -/* autorelease - * Override to return ourself - */ --(id)autorelease -{ - return self; -} /* init * Inits the single instance of the info window manager. */ --(id)init +-(instancetype)init { - NSAssert(_infoWindowManager == nil, @""); if ((self = [super init]) != nil) { controllerList = [[NSMutableDictionary alloc] initWithCapacity:10]; @@ -125,7 +79,6 @@ -(id)init -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - [super dealloc]; } /* handleFolderDeleted @@ -134,11 +87,11 @@ -(void)dealloc */ -(void)handleFolderDeleted:(NSNotification *)nc { - int folderId = [(NSNumber *)[nc object] intValue]; - NSNumber * folderNumber = [NSNumber numberWithInt:folderId]; + NSInteger folderId = ((NSNumber *)nc.object).integerValue; + NSNumber * folderNumber = @(folderId); InfoWindow * infoWindow; - infoWindow = [controllerList objectForKey:folderNumber]; + infoWindow = controllerList[folderNumber]; if (infoWindow != nil) { [infoWindow close]; @@ -152,11 +105,11 @@ -(void)handleFolderDeleted:(NSNotification *)nc */ -(void)handleFolderChange:(NSNotification *)nc { - int folderId = [(NSNumber *)[nc object] intValue]; - NSNumber * folderNumber = [NSNumber numberWithInt:folderId]; + NSInteger folderId = ((NSNumber *)nc.object).integerValue; + NSNumber * folderNumber = @(folderId); InfoWindow * infoWindow; - infoWindow = [controllerList objectForKey:folderNumber]; + infoWindow = controllerList[folderNumber]; if (infoWindow != nil) [infoWindow updateFolder]; } @@ -165,20 +118,19 @@ -(void)handleFolderChange:(NSNotification *)nc * If there's an active info window for the specified folder then it is activated * and brought to the front. Otherwise a new window is created for the folder. */ --(void)showInfoWindowForFolder:(int)folderId +-(void)showInfoWindowForFolder:(NSInteger)folderId { - NSNumber * folderNumber = [NSNumber numberWithInt:folderId]; + NSNumber * folderNumber = @(folderId); InfoWindow * infoWindow; - infoWindow = [[controllerList objectForKey:folderNumber] retain]; + infoWindow = controllerList[folderNumber]; if (infoWindow == nil) { infoWindow = [[InfoWindow alloc] initWithFolder:folderId]; - [controllerList setObject:infoWindow forKey:folderNumber]; + controllerList[folderNumber] = infoWindow; } - [infoWindow showWindow:[NSApp mainWindow]]; + [infoWindow showWindow:NSApp.mainWindow]; - [infoWindow release]; } @end @@ -187,7 +139,7 @@ @implementation InfoWindow /* init * Just init the Info window. */ --(id)initWithFolder:(int)folderId +-(instancetype)initWithFolder:(NSInteger)folderId { if ((self = [super initWithWindowNibName:@"InfoWindow"]) != nil) infoFolderId = folderId; @@ -200,7 +152,6 @@ -(id)initWithFolder:(int)folderId -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - [super dealloc]; } /* awakeFromNib @@ -210,8 +161,8 @@ -(void)awakeFromNib { [self updateFolder]; [self enableValidateButton]; - [[self window] setInitialFirstResponder:urlField]; - [[self window] setDelegate:self]; + self.window.initialFirstResponder = urlField; + self.window.delegate = self; NSNotificationCenter * nc = [NSNotificationCenter defaultCenter]; [nc addObserver:self selector:@selector(handleUrlTextDidChange:) name:NSControlTextDidChangeNotification object:urlField]; @@ -224,39 +175,39 @@ -(void)awakeFromNib */ -(void)updateFolder { - Folder * folder = [[Database sharedDatabase] folderFromID:infoFolderId]; + Folder * folder = [[Database sharedManager] folderFromID:infoFolderId]; // Set the window caption - NSString * caption = [NSString stringWithFormat:NSLocalizedString(@"%@ Info", nil), [folder name]]; - [[self window] setTitle:caption]; + NSString * caption = [NSString stringWithFormat:NSLocalizedString(@"%@ Info", nil), folder.name]; + self.window.title = caption; // Set the header details - [folderName setStringValue:[folder name]]; - [folderImage setImage:[folder image]]; - if ([[folder lastUpdate] isEqualToDate:[NSDate distantPast]]) + folderName.stringValue = folder.name; + folderImage.image = folder.image; + if ([folder.lastUpdate isEqualToDate:[NSDate distantPast]]) [lastRefreshDate setStringValue:NSLocalizedString(@"Never", nil)]; else - [lastRefreshDate setStringValue:[[[folder lastUpdate] dateWithCalendarFormat:nil timeZone:nil] friendlyDescription]]; + lastRefreshDate.stringValue = [folder.lastUpdate dateWithCalendarFormat:nil timeZone:nil].friendlyDescription; // Fill out the panels - [urlField setStringValue:[folder feedURL]]; - [username setStringValue:[folder username]]; - [password setStringValue:[folder password]]; + urlField.stringValue = folder.feedURL; + username.stringValue = folder.username; + password.stringValue = folder.password; // for Google feeds, URL may not be changed and no authentication is supported if (IsGoogleReaderFolder(folder)) { //[urlField setSelectable:NO]; [urlField setEditable:NO]; - [urlField setTextColor:[NSColor disabledControlTextColor]]; + urlField.textColor = [NSColor disabledControlTextColor]; [username setEditable:NO]; - [username setTextColor:[NSColor disabledControlTextColor]]; + username.textColor = [NSColor disabledControlTextColor]; [password setEditable:NO]; - [password setTextColor:[NSColor disabledControlTextColor]]; + password.textColor = [NSColor disabledControlTextColor]; } - [folderDescription setStringValue:[folder feedDescription]]; - [folderSize setStringValue:[NSString stringWithFormat:NSLocalizedString(@"%u articles", nil), MAX(0, [folder countOfCachedArticles])]]; - [folderUnread setStringValue:[NSString stringWithFormat:NSLocalizedString(@"%u unread", nil), [folder unreadCount]]]; - [isSubscribed setState:([folder flags] & MA_FFlag_Unsubscribed) ? NSOffState : NSOnState]; - [loadFullHTML setState:([folder flags] & MA_FFlag_LoadFullHTML) ? NSOnState : NSOffState]; + folderDescription.stringValue = folder.feedDescription; + folderSize.stringValue = [NSString stringWithFormat:NSLocalizedString(@"%u articles", nil), MAX(0, [folder countOfCachedArticles])]; + folderUnread.stringValue = [NSString stringWithFormat:NSLocalizedString(@"%u unread", nil), folder.unreadCount]; + isSubscribed.state = (folder.flags & MA_FFlag_Unsubscribed) ? NSOffState : NSOnState; + loadFullHTML.state = (folder.flags & MA_FFlag_LoadFullHTML) ? NSOnState : NSOffState; } /* urlFieldChanged @@ -264,8 +215,8 @@ -(void)updateFolder */ -(IBAction)urlFieldChanged:(id)sender { - NSString * newUrl = [[urlField stringValue] trim]; - [[Database sharedDatabase] setFolderFeedURL:infoFolderId newFeedURL:newUrl]; + NSString * newUrl = (urlField.stringValue).trim; + [[Database sharedManager] setFeedURL:newUrl forFolder:infoFolderId]; } /* subscribedChanged @@ -273,11 +224,14 @@ -(IBAction)urlFieldChanged:(id)sender */ -(IBAction)subscribedChanged:(id)sender { - if ([isSubscribed state] == NSOnState) - [[Database sharedDatabase] clearFolderFlag:infoFolderId flagToClear:MA_FFlag_Unsubscribed]; - else - [[Database sharedDatabase] setFolderFlag:infoFolderId flagToSet:MA_FFlag_Unsubscribed]; - [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_FoldersUpdated" object:[NSNumber numberWithInt:infoFolderId]]; + if (isSubscribed.state == NSOnState) { + [[Database sharedManager] clearFlag:MA_FFlag_Unsubscribed forFolder:infoFolderId]; + } + else { + [[Database sharedManager] setFlag:MA_FFlag_Unsubscribed forFolder:infoFolderId]; + } + [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_FoldersUpdated" + object:@(infoFolderId)]; } /* loadFullHTMLChanged @@ -285,11 +239,14 @@ -(IBAction)subscribedChanged:(id)sender */ -(IBAction)loadFullHTMLChanged:(id)sender { - if ([loadFullHTML state] == NSOnState) - [[Database sharedDatabase] setFolderFlag:infoFolderId flagToSet:MA_FFlag_LoadFullHTML]; - else - [[Database sharedDatabase] clearFolderFlag:infoFolderId flagToClear:MA_FFlag_LoadFullHTML]; - [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_LoadFullHTMLChange" object:[NSNumber numberWithInt:infoFolderId]]; + if (loadFullHTML.state == NSOnState) { + [[Database sharedManager] setFlag:MA_FFlag_LoadFullHTML forFolder:infoFolderId]; + } + else { + [[Database sharedManager] clearFlag:MA_FFlag_LoadFullHTML forFolder:infoFolderId]; + } + [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_LoadFullHTMLChange" + object:@(infoFolderId)]; } /* handleUrlTextDidChange [delegate] @@ -307,7 +264,7 @@ -(void)handleUrlTextDidChange:(NSNotification *)aNotification */ -(void)handleFolderNameTextDidChange:(NSNotification *)aNotification { - [[Database sharedDatabase] setFolderName:infoFolderId newName:[folderName stringValue]]; + [[Database sharedManager] setName:folderName.stringValue forFolder:infoFolderId]; } /* enableValidateButton @@ -315,7 +272,7 @@ -(void)handleFolderNameTextDidChange:(NSNotification *)aNotification */ -(void)enableValidateButton { - [validateButton setEnabled:![[urlField stringValue] isBlank]]; + validateButton.enabled = !(urlField.stringValue).blank; } /* validateURL @@ -326,15 +283,15 @@ -(IBAction)validateURL:(id)sender NSString * validatorPage = [[APPCONTROLLER standardURLs] valueForKey:@"FeedValidatorTemplate"]; if (validatorPage != nil) { - NSString * url = [[urlField stringValue] trim]; + NSString * url = (urlField.stringValue).trim; // Escape any special query characters in the URL, because the URL itself will be in a query. - NSString * query = [[NSURL URLWithString:url] query]; + NSString * query = [NSURL URLWithString:url].query; if (query != nil) { NSMutableString * escapedQuery = [NSMutableString stringWithString:query]; - [escapedQuery replaceOccurrencesOfString:@"&" withString:@"%26" options:0u range:NSMakeRange(0u, [escapedQuery length])]; - [escapedQuery replaceOccurrencesOfString:@"=" withString:@"%3D" options:0u range:NSMakeRange(0u, [escapedQuery length])]; + [escapedQuery replaceOccurrencesOfString:@"&" withString:@"%26" options:0u range:NSMakeRange(0u, escapedQuery.length)]; + [escapedQuery replaceOccurrencesOfString:@"=" withString:@"%3D" options:0u range:NSMakeRange(0u, escapedQuery.length)]; if (![query isEqualToString:escapedQuery]) { url = [[url substringToIndex:[url rangeOfString:query].location] stringByAppendingString:escapedQuery]; @@ -352,13 +309,13 @@ -(IBAction)validateURL:(id)sender */ -(IBAction)authenticationChanged:(id)sender { - NSString * usernameString = [[username stringValue] trim]; - NSString * passwordString = [password stringValue]; + NSString * usernameString = (username.stringValue).trim; + NSString * passwordString = password.stringValue; - Database * db = [Database sharedDatabase]; + Database * db = [Database sharedManager]; Folder * folder = [db folderFromID:infoFolderId]; - [db setFolderUsername:[folder itemId] newUsername:usernameString]; - [folder setPassword:passwordString]; + [db setFolderUsername:folder.itemId newUsername:usernameString]; + folder.password = passwordString; } /* windowShouldClose @@ -367,7 +324,7 @@ -(IBAction)authenticationChanged:(id)sender - (BOOL)windowShouldClose:(id)sender { // Set the first responder so any open edit fields get committed. - [[self window] makeFirstResponder:[self window]]; + [self.window makeFirstResponder:self.window]; // Go ahead and close the window. return YES; diff --git a/src/KeyChain.m b/src/KeyChain.m index cc05f0fa2c..9a2d06a170 100644 --- a/src/KeyChain.m +++ b/src/KeyChain.m @@ -30,10 +30,10 @@ @implementation KeyChain +(NSString *)getPasswordFromKeychain:(NSString *)username url:(NSString *)url { NSURL * secureUrl = [NSURL URLWithString:url]; - const char * cServiceName = [[secureUrl host] UTF8String]; - const char * cUsername = [username UTF8String]; - int portNumber = [secureUrl port] ? [[secureUrl port] intValue] : ([[secureUrl scheme] caseInsensitiveCompare:@"https"] == NSOrderedSame ? 443 : 80); - SecProtocolType protocolType = ([[secureUrl scheme] caseInsensitiveCompare:@"https"] == NSOrderedSame) ? kSecProtocolTypeHTTPS : kSecProtocolTypeHTTP; + const char * cServiceName = secureUrl.host.UTF8String; + const char * cUsername = username.UTF8String; + NSInteger portNumber = secureUrl.port ? secureUrl.port.integerValue : ([secureUrl.scheme caseInsensitiveCompare:@"https"] == NSOrderedSame ? 443 : 80); + SecProtocolType protocolType = ([secureUrl.scheme caseInsensitiveCompare:@"https"] == NSOrderedSame) ? kSecProtocolTypeHTTPS : kSecProtocolTypeHTTP; NSString * thePassword; if (!cServiceName || !cUsername) @@ -46,13 +46,13 @@ +(NSString *)getPasswordFromKeychain:(NSString *)username url:(NSString *)url OSStatus status; status = SecKeychainFindInternetPassword(NULL, - strlen(cServiceName), + (UInt32)strlen(cServiceName), cServiceName, 0, NULL, - strlen(cUsername), + (UInt32)strlen(cUsername), cUsername, - strlen(cPath), + (UInt32)strlen(cPath), cPath, portNumber, protocolType, @@ -64,7 +64,7 @@ +(NSString *)getPasswordFromKeychain:(NSString *)username url:(NSString *)url thePassword = @""; else { - thePassword = [[[NSString alloc] initWithBytes:passwordPtr length:passwordLength encoding:NSUTF8StringEncoding] autorelease]; + thePassword = [[NSString alloc] initWithBytes:passwordPtr length:passwordLength encoding:NSUTF8StringEncoding]; SecKeychainItemFreeContent(NULL, passwordPtr); } } @@ -77,25 +77,25 @@ +(NSString *)getPasswordFromKeychain:(NSString *)username url:(NSString *)url +(void)setPasswordInKeychain:(NSString *)password username:(NSString *)username url:(NSString *)url { NSURL * secureUrl = [NSURL URLWithString:url]; - const char * cServiceName = [[secureUrl host] UTF8String]; - const char * cUsername = [username UTF8String]; + const char * cServiceName = secureUrl.host.UTF8String; + const char * cUsername = username.UTF8String; const char * cPath = ""; - int portNumber = [secureUrl port] ? [[secureUrl port] intValue] : ([[secureUrl scheme] caseInsensitiveCompare:@"https"] == NSOrderedSame ? 443 : 80); - SecProtocolType protocolType = ([[secureUrl scheme] caseInsensitiveCompare:@"https"] == NSOrderedSame) ? kSecProtocolTypeHTTPS : kSecProtocolTypeHTTP; - const char * cPassword = [password UTF8String]; + NSInteger portNumber = secureUrl.port ? secureUrl.port.integerValue : ([secureUrl.scheme caseInsensitiveCompare:@"https"] == NSOrderedSame ? 443 : 80); + SecProtocolType protocolType = ([secureUrl.scheme caseInsensitiveCompare:@"https"] == NSOrderedSame) ? kSecProtocolTypeHTTPS : kSecProtocolTypeHTTP; + const char * cPassword = password.UTF8String; SecKeychainItemRef itemRef; OSStatus status; if (!cServiceName || !cUsername || !cPassword) return; status = SecKeychainFindInternetPassword(NULL, - strlen(cServiceName), + (UInt32)strlen(cServiceName), cServiceName, 0, NULL, - strlen(cUsername), + (UInt32)strlen(cUsername), cUsername, - strlen(cPath), + (UInt32)strlen(cPath), cPath, portNumber, protocolType, @@ -106,18 +106,18 @@ +(void)setPasswordInKeychain:(NSString *)password username:(NSString *)username if (status == noErr) SecKeychainItemDelete(itemRef); SecKeychainAddInternetPassword(NULL, - strlen(cServiceName), + (UInt32)strlen(cServiceName), cServiceName, 0, NULL, - strlen(cUsername), + (UInt32)strlen(cUsername), cUsername, - strlen(cPath), + (UInt32)strlen(cPath), cPath, portNumber, protocolType, kSecAuthenticationTypeDefault, - strlen(cPassword), + (UInt32)strlen(cPassword), cPassword, NULL); } @@ -128,9 +128,9 @@ +(void)setPasswordInKeychain:(NSString *)password username:(NSString *)username +(NSString *)getWebPasswordFromKeychain:(NSString *)username url:(NSString *)url { NSURL * secureUrl = [NSURL URLWithString:url]; - const char * cServiceName = [[secureUrl host] UTF8String]; - const char * cUsername = [username UTF8String]; - int portNumber = 0; + const char * cServiceName = secureUrl.host.UTF8String; + const char * cUsername = username.UTF8String; + NSInteger portNumber = 0; SecProtocolType protocolType = kSecProtocolTypeHTTPS ; NSString * thePassword; @@ -144,13 +144,13 @@ +(NSString *)getWebPasswordFromKeychain:(NSString *)username url:(NSString *)url OSStatus status; status = SecKeychainFindInternetPassword(NULL, - strlen(cServiceName), + (UInt32)strlen(cServiceName), cServiceName, 0, NULL, - strlen(cUsername), + (UInt32)strlen(cUsername), cUsername, - strlen(cPath), + (UInt32)strlen(cPath), cPath, portNumber, protocolType, @@ -162,7 +162,7 @@ +(NSString *)getWebPasswordFromKeychain:(NSString *)username url:(NSString *)url thePassword = @""; else { - thePassword = [[[NSString alloc] initWithBytes:passwordPtr length:passwordLength encoding:NSUTF8StringEncoding] autorelease]; + thePassword = [[NSString alloc] initWithBytes:passwordPtr length:passwordLength encoding:NSUTF8StringEncoding]; SecKeychainItemFreeContent(NULL, passwordPtr); } } @@ -174,8 +174,8 @@ +(NSString *)getWebPasswordFromKeychain:(NSString *)username url:(NSString *)url */ +(NSString *)getGenericPasswordFromKeychain:(NSString *)username serviceName:(NSString *)service { - const char * cServiceName = [service UTF8String]; - const char * cUsername = [username UTF8String]; + const char * cServiceName = service.UTF8String; + const char * cUsername = username.UTF8String; NSString * thePassword; if (!cServiceName || !cUsername) @@ -187,9 +187,9 @@ +(NSString *)getGenericPasswordFromKeychain:(NSString *)username serviceName:(NS OSStatus status; status = SecKeychainFindGenericPassword(NULL, - strlen(cServiceName), + (UInt32)strlen(cServiceName), cServiceName, - strlen(cUsername), + (UInt32)strlen(cUsername), cUsername, &passwordLength, &passwordPtr, @@ -198,7 +198,7 @@ +(NSString *)getGenericPasswordFromKeychain:(NSString *)username serviceName:(NS thePassword = @""; else { - thePassword = [[[NSString alloc] initWithBytes:passwordPtr length:passwordLength encoding:NSUTF8StringEncoding] autorelease]; + thePassword = [[NSString alloc] initWithBytes:passwordPtr length:passwordLength encoding:NSUTF8StringEncoding]; SecKeychainItemFreeContent(NULL, passwordPtr); } } @@ -210,17 +210,17 @@ +(NSString *)getGenericPasswordFromKeychain:(NSString *)username serviceName:(NS */ +(void)deleteGenericPasswordInKeychain:(NSString *)username service:(NSString *)service { - const char * cServiceName = [service UTF8String]; - const char * cUsername = [username UTF8String]; + const char * cServiceName = service.UTF8String; + const char * cUsername = username.UTF8String; SecKeychainItemRef itemRef; OSStatus status; if (!cServiceName || !cUsername) return; status = SecKeychainFindGenericPassword(NULL, - strlen(cServiceName), + (UInt32)strlen(cServiceName), cServiceName, - strlen(cUsername), + (UInt32)strlen(cUsername), cUsername, NULL, NULL, @@ -234,20 +234,20 @@ +(void)deleteGenericPasswordInKeychain:(NSString *)username service:(NSString *) */ +(void)setGenericPasswordInKeychain:(NSString *)password username:(NSString *)username service:(NSString *)service { - const char * cServiceName = [service UTF8String]; - const char * cUsername = [username UTF8String]; - const char * cPassword = [password UTF8String]; + const char * cServiceName = service.UTF8String; + const char * cUsername = username.UTF8String; + const char * cPassword = password.UTF8String; if (!cServiceName || !cUsername || !cPassword) return; [self deleteGenericPasswordInKeychain:username service:service]; SecKeychainAddGenericPassword(NULL, - strlen(cServiceName), + (UInt32)strlen(cServiceName), cServiceName, - strlen(cUsername), + (UInt32)strlen(cUsername), cUsername, - strlen(cPassword), + (UInt32)strlen(cPassword), cPassword, NULL); } diff --git a/src/MessageListView.m b/src/MessageListView.m index a37854e511..444f6f7b10 100644 --- a/src/MessageListView.m +++ b/src/MessageListView.m @@ -22,9 +22,9 @@ #import "AppController.h" @interface NSObject(MessageListViewDelegate) - -(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger )flags; + -(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger)flags; -(BOOL)copyTableSelection:(NSArray *)rows toPasteboard:(NSPasteboard *)pboard; - -(BOOL)canDeleteMessageAtRow:(int)row; + -(BOOL)canDeleteMessageAtRow:(NSInteger)row; -(IBAction)deleteMessage:(id)sender; @end @@ -36,10 +36,10 @@ @implementation MessageListView */ -(void)keyDown:(NSEvent *)theEvent { - if ([[theEvent characters] length] == 1) + if (theEvent.characters.length == 1) { - unichar keyChar = [[theEvent characters] characterAtIndex:0]; - if ([APPCONTROLLER handleKeyDown:keyChar withFlags:[theEvent modifierFlags]]) + unichar keyChar = [theEvent.characters characterAtIndex:0]; + if ([APPCONTROLLER handleKeyDown:keyChar withFlags:theEvent.modifierFlags]) return; } [super keyDown:theEvent]; @@ -50,14 +50,14 @@ -(void)keyDown:(NSEvent *)theEvent */ -(IBAction)copy:(id)sender { - if ([self selectedRow] >= 0) + if (self.selectedRow >= 0) { - NSIndexSet * selectedRowIndexes = [self selectedRowIndexes]; - NSMutableArray *rows = [NSMutableArray arrayWithCapacity:[selectedRowIndexes count]]; - NSUInteger rowIndex = [selectedRowIndexes firstIndex]; + NSIndexSet * selectedRowIndexes = self.selectedRowIndexes; + NSMutableArray *rows = [NSMutableArray arrayWithCapacity:selectedRowIndexes.count]; + NSUInteger rowIndex = selectedRowIndexes.firstIndex; while (rowIndex != NSNotFound) { - [rows addObject:[NSNumber numberWithUnsignedInt:rowIndex]]; + [rows addObject:@(rowIndex)]; rowIndex = [selectedRowIndexes indexGreaterThanIndex:rowIndex]; } [(id)[self delegate] copyTableSelection:rows toPasteboard:[NSPasteboard generalPasteboard]]; @@ -78,15 +78,15 @@ -(IBAction)delete:(id)sender */ -(BOOL)validateMenuItem:(NSMenuItem *)menuItem { - if ([menuItem action] == @selector(copy:)) + if (menuItem.action == @selector(copy:)) { - return ([self selectedRow] >= 0); + return (self.selectedRow >= 0); } - if ([menuItem action] == @selector(delete:)) + if (menuItem.action == @selector(delete:)) { - return [(id)[self delegate] canDeleteMessageAtRow:[self selectedRow]]; + return [(id)[self delegate] canDeleteMessageAtRow:self.selectedRow]; } - if ([menuItem action] == @selector(selectAll:)) + if (menuItem.action == @selector(selectAll:)) { return YES; } diff --git a/src/NSDate+Vienna.h b/src/NSDate+Vienna.h new file mode 100644 index 0000000000..cc8d8ac31c --- /dev/null +++ b/src/NSDate+Vienna.h @@ -0,0 +1,15 @@ +// +// NSDate+Vienna.h +// Vienna +// +// Created by Joshua Pore on 8/08/2015. +// Copyright (c) 2015 uk.co.opencommunity. All rights reserved. +// + +@import Cocoa; + +@interface NSDate (Vienna) + ++ (NSDate *)parseXMLDate:(NSString *)dateString; + +@end diff --git a/src/NSDate+Vienna.m b/src/NSDate+Vienna.m new file mode 100644 index 0000000000..e374d8e440 --- /dev/null +++ b/src/NSDate+Vienna.m @@ -0,0 +1,139 @@ +// +// NSDate+Vienna.m +// Vienna +// +// Created by Joshua Pore on 8/08/2015. +// Copyright (c) 2015 uk.co.opencommunity. All rights reserved. +// + +#import "NSDate+Vienna.h" + +/* C array of NSDateFormatter format strings. This array is used only once to populate dateFormatterArray. +* +* Note: for every four-digit year entry, we need an earlier two-digit year entry +* so that NSDateFormatter parses two-digit years considering the two-digit-year start date. +* +* For the different date formats, see +* IMPORTANT hack : remove in these strings any colon [:] beginning from character # 20 (first char is #0) +* We do so because some servers incorrectly return strings with a colon (:) in timezone indication +* which NSDateFormatter refuses to handle +* +*/ +static NSString * kDateFormats[] = { + // 2010-09-28T15:31:25Z and 2010-09-28T17:31:25+02:00 + @"yy-MM-dd'T'HH:mm:ssZZZ", @"yyyy-MM-dd'T'HH:mm:ssZZZ", + // 2010-09-28T15:31:25.815+02:00 + @"yy-MM-dd'T'HH:mm:ss.SSSZZZ", @"yyyy-MM-dd'T'HH:mm:ss.SSSZZZ", + // "Sat, 13 Dec 2008 18:45:15 EAT" and "Fri, 12 Dec 2008 18:45:15 -08:00" + @"EEE, dd MMM yy HH:mmss zzz", @"EEE, dd MMM yyyy HH:mmss zzz", + @"EEE, dd MMM yy HH:mmss ZZZ", @"EEE, dd MMM yyyy HH:mmss ZZZ", + @"EEE, dd MMM yy HH:mmss", @"EEE, dd MMM yyyy HH:mmss", + // Required by compatibility with older OS X versions + @"yy-MM-dd'T'HH:mm:ss'Z'", @"yyyy-MM-dd'T'HH:mm:ss'Z'", + @"yy-MM-dd'T'HH:mm:ss.SSS'Z'", @"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", + // Other exotic and non standard date formats + @"yy-MM-dd HH:mm:ss ZZZ", @"yyyy-MM-dd HH:mm:ss ZZZ", + @"yy-MM-dd HH:mm:ss zzz", @"yyyy-MM-dd HH:mm:ss zzz", + @"EEE dd MMM yy HH:mmss zzz", @"EEE dd MMM yyyy HH:mmss zzz", + @"EEE dd MMM yy HH:mmss ZZZ", @"EEE dd MMM yyyy HH:mmss ZZZ", + @"EEE dd MMM yy HH:mmss", @"EEE dd MMM yyyy HH:mmss", + @"EEEE dd MMMM yy", @"EEEE dd MMMM yyyy", +}; +static const size_t kNumberOfDateFormatters = sizeof(kDateFormats) / sizeof(kDateFormats[0]); + +// C array of NSDateFormatter's : creating a NSDateFormatter is very expensive, so we create +// those we need early in the program launch and keep them in memory. +static NSDateFormatter * dateFormatterArray[kNumberOfDateFormatters]; + +static NSLock * dateFormatters_lock; +static NSLocale * enUSLocale; +static BOOL threadSafe; + +@implementation NSDate (Vienna) + + ++ (void)load +{ + // Initializes the date formatters + enUSLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]; + + for (NSInteger i=0; i= NSAppKitVersionNumber10_9) + threadSafe=YES; + else + { + // Initializes our multi-thread lock + dateFormatters_lock = [[NSLock alloc] init]; + threadSafe=NO; + } +} + + + +/* parseXMLDate + * Parse a date in an XML header into an NSCalendarDate. + * + */ ++ (NSDate *)parseXMLDate:(NSString *)dateString +{ + NSDate *date ; + NSString *modifiedDateString ; + // Hack : remove colon in timezone as NSDateFormatter doesn't recognize them + if (dateString.length > 20) + { + modifiedDateString = [dateString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + modifiedDateString = [modifiedDateString + stringByReplacingOccurrencesOfString:@":" withString:@"" + options:0 range:NSMakeRange(20,modifiedDateString.length-20)]; + } + else + { + modifiedDateString = dateString; + } + + if (threadSafe) + { + // test with the date formatters we are aware of + // exit as soon as we find a match + for (NSInteger i=0; i 0) { for (NSString *feedSourceType in sourcesDict.allKeys) { //[feedSource addItemWithTitle:NSLocalizedString(feedSourceType, nil)]; - NSMenuItem *feedMenuItem = [[[NSMenuItem alloc] initWithTitle:NSLocalizedString(feedSourceType, nil) action:NULL keyEquivalent:@""] autorelease]; + NSMenuItem *feedMenuItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(feedSourceType, nil) action:NULL keyEquivalent:@""]; feedMenuItem.representedObject = feedSourceType; [feedSource.menu addItem:feedMenuItem]; } @@ -91,20 +90,20 @@ -(void)newSubscription:(NSWindow *)window underParent:(int)itemId initialURL:(NS // URL field with it. A handy shortcut. if (initialURL != nil) { - [feedURL setStringValue:initialURL]; + feedURL.stringValue = initialURL; [feedSource selectItemWithTitle:NSLocalizedString(@"URL", @"URL")]; } else { NSData * pboardData = [[NSPasteboard generalPasteboard] dataForType:NSStringPboardType]; - [feedURL setStringValue:@""]; + feedURL.stringValue = @""; if (pboardData != nil) { - NSString * pasteString = [[[NSString alloc] initWithData:pboardData encoding:NSASCIIStringEncoding] autorelease]; - NSString * lowerCasePasteString = [pasteString lowercaseString]; + NSString * pasteString = [[NSString alloc] initWithData:pboardData encoding:NSASCIIStringEncoding]; + NSString * lowerCasePasteString = pasteString.lowercaseString; if (lowerCasePasteString != nil && ([lowerCasePasteString hasPrefix:@"http://"] || [lowerCasePasteString hasPrefix:@"https://"] || [lowerCasePasteString hasPrefix:@"feed://"])) { - [feedURL setStringValue:pasteString]; + feedURL.stringValue = pasteString; [feedURL selectText:self]; [feedSource selectItemWithTitle:NSLocalizedString(@"URL", @"URL")]; } @@ -118,46 +117,45 @@ -(void)newSubscription:(NSWindow *)window underParent:(int)itemId initialURL:(NS parentId = itemId; [newRSSFeedWindow makeFirstResponder:feedURL]; //restore from preferences, if it can be done ; otherwise, uncheck this option - self.googleOptionButton=[[Preferences standardPreferences] syncGoogleReader] - &&[[Preferences standardPreferences] prefersGoogleNewSubscription]; + self.googleOptionButton=[Preferences standardPreferences].syncGoogleReader + &&[Preferences standardPreferences].prefersGoogleNewSubscription; [NSApp beginSheet:newRSSFeedWindow modalForWindow:window modalDelegate:nil didEndSelector:nil contextInfo:nil]; } /* didEndSubscriptionEdit * Notification that the editing is done. */ -- (void)didEndSubscriptionEdit:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo +- (void)didEndSubscriptionEdit:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo { - NSNumber * folderNumber = (NSNumber *)contextInfo; + NSNumber * folderNumber = (__bridge NSNumber *)contextInfo; // Notify any open windows. [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_FoldersUpdated" object:folderNumber]; // Now release the folder number. - [folderNumber release]; } /* editSubscription * Edit an existing RSS subscription. */ --(void)editSubscription:(NSWindow *)window folderId:(int)folderId +-(void)editSubscription:(NSWindow *)window folderId:(NSInteger)folderId { [self loadRSSFeedBundle]; Folder * folder = [db folderFromID:folderId]; if (folder != nil) { - [editFeedURL setStringValue:[folder feedURL]]; + editFeedURL.stringValue = folder.feedURL; [self enableSaveButton]; editFolderId = folderId; // Create a context object which contains the folder ID for the sheet to pass to // selector which it will call when done. Retain it so it is still around for the // selector. - NSNumber * folderContext = [[NSNumber numberWithInt:folderId] retain]; + NSNumber * folderContext = @(folderId); // Open the edit sheet. - [NSApp beginSheet:editRSSFeedWindow modalForWindow:window modalDelegate:self didEndSelector:@selector(didEndSubscriptionEdit:returnCode:contextInfo:) contextInfo:folderContext]; + [NSApp beginSheet:editRSSFeedWindow modalForWindow:window modalDelegate:self didEndSelector:@selector(didEndSubscriptionEdit:returnCode:contextInfo:) contextInfo:(__bridge void *)(folderContext)]; } } @@ -168,7 +166,9 @@ -(void)loadRSSFeedBundle { if (!editRSSFeedWindow || !newRSSFeedWindow) { - [NSBundle loadNibNamed:@"RSSFeed" owner:self]; + NSArray * objects; + [[NSBundle bundleForClass:[self class]] loadNibNamed:@"RSSFeed" owner:self topLevelObjects:&objects]; + self.topObjects = objects; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleTextDidChange:) name:NSControlTextDidChangeNotification object:feedURL]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleTextDidChange2:) name:NSControlTextDidChangeNotification object:editFeedURL]; } @@ -180,7 +180,7 @@ -(void)loadRSSFeedBundle -(IBAction)doSubscribe:(id)sender { NSURL * rssFeedURL; - NSString * feedURLString = [[feedURL stringValue] trim]; + NSString * feedURLString = (feedURL.stringValue).trim; // Replace feed:// with http:// if necessary if ([feedURLString hasPrefix:@"feed://"]) feedURLString = [NSString stringWithFormat:@"http://%@", [feedURLString substringFromIndex:7]]; @@ -188,7 +188,7 @@ -(IBAction)doSubscribe:(id)sender // Format the URL based on the selected feed source. if (sourcesDict != nil) { - NSString * selectedSource = (NSString *)[[feedSource selectedItem] representedObject]; + NSString * selectedSource = (NSString *)feedSource.selectedItem.representedObject; NSDictionary * feedSourceType = [sourcesDict valueForKey:selectedSource]; NSString * linkTemplate = [feedSourceType valueForKey:@"LinkTemplate"]; if ([selectedSource.lowercaseString isEqualToString:@"local file"]) { @@ -202,6 +202,7 @@ -(IBAction)doSubscribe:(id)sender // Validate the subscription, possibly replacing the feedURLString with a real one if // it originally pointed to a web page. rssFeedURL = [subscriptionModel verifiedFeedURLFromURL:rssFeedURL]; + NSAssert(rssFeedURL != nil, @"No valid URL verified to attempt subscription !"); // Check if we have already subscribed to this feed by seeing if a folder exists in the db if ([db folderFromFeedURL:rssFeedURL.absoluteString] != nil) @@ -225,10 +226,10 @@ -(IBAction)doSubscribe:(id)sender */ -(IBAction)doSave:(id)sender { - NSString * feedURLString = [[editFeedURL stringValue] trim]; + NSString * feedURLString = editFeedURL.stringValue.trim; // Save the new information to the database - [db setFolderFeedURL:editFolderId newFeedURL:feedURLString]; + [[Database sharedManager] setFeedURL:feedURLString forFolder:editFolderId]; // Close the window [NSApp endSheet:editRSSFeedWindow]; @@ -270,7 +271,7 @@ -(IBAction)doLinkSourceChanged:(id)sender */ -(IBAction)doGoogleOption:(id)sender { - [[Preferences standardPreferences] setPrefersGoogleNewSubscription:([sender state] == NSOnState)]; + [Preferences standardPreferences].prefersGoogleNewSubscription = ([sender state] == NSOnState); } /* handleTextDidChange [delegate] @@ -297,12 +298,12 @@ -(void)handleTextDidChange2:(NSNotification *)aNotification */ -(void)setLinkTitle { - NSMenuItem * feedSourceItem = [feedSource selectedItem]; + NSMenuItem * feedSourceItem = feedSource.selectedItem; NSString * linkTitleString = nil; BOOL showButton = NO; if (feedSourceItem != nil) { - NSDictionary * itemDict = [sourcesDict valueForKey:[feedSourceItem title]]; + NSDictionary * itemDict = [sourcesDict valueForKey:feedSourceItem.title]; if (itemDict != nil) { linkTitleString = [itemDict valueForKey:@"LinkName"]; @@ -311,24 +312,23 @@ -(void)setLinkTitle } if (linkTitleString == nil) linkTitleString = @"Link"; - [linkTitle setStringValue:[NSString stringWithFormat:@"%@:", NSLocalizedString(linkTitleString, nil)]]; - [siteHomePageButton setHidden:!showButton]; + linkTitle.stringValue = [NSString stringWithFormat:@"%@:", NSLocalizedString(linkTitleString, nil)]; + siteHomePageButton.hidden = !showButton; } /* doShowSiteHomePage */ -(void)doShowSiteHomePage:(id)sender { - NSMenuItem * feedSourceItem = [feedSource selectedItem]; + NSMenuItem * feedSourceItem = feedSource.selectedItem; if (feedSourceItem != nil) { - NSDictionary * itemDict = [sourcesDict valueForKey:[feedSourceItem title]]; + NSDictionary * itemDict = [sourcesDict valueForKey:feedSourceItem.title]; if (itemDict != nil) { NSString * siteHomePageURL = [itemDict valueForKey:@"SiteHomePage"]; NSURL * url = [[NSURL alloc] initWithString:siteHomePageURL]; [[NSWorkspace sharedWorkspace] openURL:url]; - [url release]; } } } @@ -339,8 +339,8 @@ -(void)doShowSiteHomePage:(id)sender */ -(void)enableSubscribeButton { - NSString * feedURLString = [feedURL stringValue]; - [subscribeButton setEnabled:![feedURLString isBlank]]; + NSString * feedURLString = feedURL.stringValue; + subscribeButton.enabled = !feedURLString.blank; } /* enableSaveButton @@ -349,8 +349,8 @@ -(void)enableSubscribeButton */ -(void)enableSaveButton { - NSString * feedURLString = [editFeedURL stringValue]; - [saveButton setEnabled:![feedURLString isBlank]]; + NSString * feedURLString = editFeedURL.stringValue; + saveButton.enabled = !feedURLString.blank; } /* dealloc @@ -359,12 +359,5 @@ -(void)enableSaveButton -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - [sourcesDict release]; - sourcesDict=nil; - [subscriptionModel release]; - subscriptionModel=nil; - [db release]; - db=nil; - [super dealloc]; } @end diff --git a/src/PluginManager.h b/src/PluginManager.h index 83428a9c0d..5ae33128c0 100644 --- a/src/PluginManager.h +++ b/src/PluginManager.h @@ -27,8 +27,8 @@ } -(void)resetPlugins; --(NSArray *)searchMethods; --(NSArray *)toolbarItems; +@property (nonatomic, readonly, copy) NSArray *searchMethods; +@property (nonatomic, readonly, copy) NSArray *toolbarItems; -(NSArray *)defaultToolbarItems; -(void)loadPlugin:(NSString *)pluginPath; -(void)toolbarItem:(ToolbarItem *)item withIdentifier:(NSString *)itemIdentifier; diff --git a/src/PluginManager.m b/src/PluginManager.m index 75579a098e..206b9d3b31 100644 --- a/src/PluginManager.m +++ b/src/PluginManager.m @@ -37,7 +37,7 @@ @implementation PluginManager /* init * Initialises the plugin manager. */ --(id)init +-(instancetype)init { if ((self = [super init]) != nil) { @@ -63,19 +63,18 @@ -(void)resetPlugins pluginPaths = [[NSMutableDictionary alloc] init]; - path = [[[NSBundle mainBundle] sharedSupportPath] stringByAppendingPathComponent:@"Plugins"]; + path = [[NSBundle mainBundle].sharedSupportPath stringByAppendingPathComponent:@"Plugins"]; loadMapFromPath(path, pluginPaths, YES, nil); - path = [[Preferences standardPreferences] pluginsFolder]; + path = [Preferences standardPreferences].pluginsFolder; loadMapFromPath(path, pluginPaths, YES, nil); for (pluginName in pluginPaths) { - NSString * pluginPath = [pluginPaths objectForKey:pluginName]; + NSString * pluginPath = pluginPaths[pluginName]; [self loadPlugin:pluginPath]; } - [pluginPaths release]; } /* loadPlugin @@ -84,7 +83,7 @@ -(void)resetPlugins -(void)loadPlugin:(NSString *)pluginPath { NSString * listFile = [pluginPath stringByAppendingPathComponent:@"info.plist"]; - NSString * pluginName = [pluginPath lastPathComponent]; + NSString * pluginName = pluginPath.lastPathComponent; NSMutableDictionary * pluginInfo = [NSMutableDictionary dictionaryWithContentsOfFile:listFile]; // If the info.plist is missing or corrupted, warn but then just move on and the user @@ -95,8 +94,8 @@ -(void)loadPlugin:(NSString *)pluginPath { // We need to save the path to the plugin in the plugin object for later access to other // resources in the plugin folder. - [pluginInfo setObject:pluginPath forKey:@"Path"]; - [allPlugins setObject:pluginInfo forKey:pluginName]; + pluginInfo[@"Path"] = pluginPath; + allPlugins[pluginName] = pluginInfo; // Pop it on the menu if needed [self installPlugin:pluginInfo]; @@ -110,16 +109,16 @@ -(void)installPlugin:(NSDictionary *)onePlugin { // If it's a blog editor plugin, don't show it in the menu // if the app in question is not present on the system. - if ([[onePlugin objectForKey:@"Type"] isEqualToString:@"BlogEditor"]) + if ([onePlugin[@"Type"] isEqualToString:@"BlogEditor"]) { - NSString * bundleIdentifier = [onePlugin objectForKey:@"BundleIdentifier"]; + NSString * bundleIdentifier = onePlugin[@"BundleIdentifier"]; if (![[NSWorkspace sharedWorkspace] absolutePathForAppBundleWithIdentifier: bundleIdentifier]) return; } - NSString * pluginName = [onePlugin objectForKey:@"Name"]; - NSString * menuPath = [onePlugin objectForKey:@"MenuPath"]; + NSString * pluginName = onePlugin[@"Name"]; + NSString * menuPath = onePlugin[@"MenuPath"]; if (menuPath == nil) return; @@ -133,7 +132,7 @@ -(void)installPlugin:(NSDictionary *)onePlugin NSString * menuTitle = nil; [scanner scanUpToString:@"/" intoString:&topLevelMenu]; - if ([scanner isAtEnd] || topLevelMenu == nil) + if (scanner.atEnd || topLevelMenu == nil) { topLevelMenu = @"Article"; menuTitle = menuPath; @@ -145,21 +144,21 @@ -(void)installPlugin:(NSDictionary *)onePlugin } topLevelMenu = NSLocalizedString(topLevelMenu, nil); - NSArray * menuArray = [[NSApp mainMenu] itemArray]; + NSArray * menuArray = NSApp.mainMenu.itemArray; BOOL didInstall = NO; - int c; + NSInteger c; - for (c = 0; !didInstall && c < [menuArray count]; ++c) + for (c = 0; !didInstall && c < menuArray.count; ++c) { - NSMenuItem * topMenu = [menuArray objectAtIndex:c]; - if ([[topMenu title] isEqualToString:topLevelMenu]) + NSMenuItem * topMenu = menuArray[c]; + if ([topMenu.title isEqualToString:topLevelMenu]) { // Parse off the shortcut key, if there is one. The format is a series of // control key specifiers: Cmd, Shift, Alt or Ctrl - specified in any // order and separated by '+', plus a single key character. If more than // one key character is given, the last one is used but generally that is // a bug in the MenuKey. - NSString * menuKey = [onePlugin objectForKey:@"MenuKey"]; + NSString * menuKey = onePlugin[@"MenuKey"]; NSUInteger keyMod = 0; NSString * keyChar = @""; @@ -180,7 +179,7 @@ -(void)installPlugin:(NSDictionary *)onePlugin keyMod |= NSControlKeyMask; else { - if (![keyChar isBlank]) + if (!keyChar.blank) NSLog(@"Warning: malformed MenuKey found in info.plist for plugin %@", pluginName); keyChar = oneKey; } @@ -189,21 +188,20 @@ -(void)installPlugin:(NSDictionary *)onePlugin // Keep the menus tidy. If the last menu item is not currently a plugin invocator then // add a separator. - NSMenu * parentMenu = [topMenu submenu]; - int lastItem = [parentMenu numberOfItems] - 1; + NSMenu * parentMenu = topMenu.submenu; + NSInteger lastItem = parentMenu.numberOfItems - 1; - if (lastItem >= 0 && [[parentMenu itemAtIndex:lastItem] action] != @selector(pluginInvocator:)) + if (lastItem >= 0 && [parentMenu itemAtIndex:lastItem].action != @selector(pluginInvocator:)) [parentMenu addItem:[NSMenuItem separatorItem]]; // Finally add the plugin to the end of the selected menu complete with // key equivalent and save the plugin object in the NSMenuItem so that we // can associate it in pluginInvocator. NSMenuItem * menuItem = [[NSMenuItem alloc] initWithTitle:menuTitle action:@selector(pluginInvocator:) keyEquivalent:keyChar]; - [menuItem setTarget:self]; - [menuItem setKeyEquivalentModifierMask:keyMod]; - [menuItem setRepresentedObject:onePlugin]; + menuItem.target = self; + menuItem.keyEquivalentModifierMask = keyMod; + menuItem.representedObject = onePlugin; [parentMenu addItem:menuItem]; - [menuItem release]; didInstall = YES; } @@ -222,12 +220,12 @@ -(void)installPlugin:(NSDictionary *)onePlugin */ -(NSArray *)searchMethods { - NSMutableArray * searchMethods = [NSMutableArray arrayWithCapacity:[allPlugins count]]; - for (NSDictionary * plugin in [allPlugins allValues]) + NSMutableArray * searchMethods = [NSMutableArray arrayWithCapacity:allPlugins.count]; + for (NSDictionary * plugin in allPlugins.allValues) { if ([[plugin valueForKey:@"Type"] isEqualToString:@"SearchEngine"]) { - SearchMethod * method = [[[SearchMethod alloc] initWithDictionary:plugin] autorelease]; + SearchMethod * method = [[SearchMethod alloc] initWithDictionary:plugin]; [searchMethods addObject:method]; } } @@ -239,13 +237,13 @@ -(NSArray *)searchMethods */ -(NSArray *)toolbarItems { - NSMutableArray * toolbarKeys = [NSMutableArray arrayWithCapacity:[allPlugins count]]; + NSMutableArray * toolbarKeys = [NSMutableArray arrayWithCapacity:allPlugins.count]; NSString * pluginName; NSString * pluginType; for (pluginName in allPlugins) { - NSDictionary * onePlugin = [allPlugins objectForKey:pluginName]; - pluginType = [onePlugin objectForKey:@"Type"]; + NSDictionary * onePlugin = allPlugins[pluginName]; + pluginType = onePlugin[@"Type"]; if (![pluginType isEqualToString:@"SearchEngine"]) [toolbarKeys addObject:pluginName]; } @@ -257,13 +255,13 @@ -(NSArray *)toolbarItems */ -(NSArray *)defaultToolbarItems { - NSMutableArray * newArray = [NSMutableArray arrayWithCapacity:[allPlugins count]]; + NSMutableArray * newArray = [NSMutableArray arrayWithCapacity:allPlugins.count]; NSString * pluginName; for (pluginName in allPlugins) { - NSDictionary * onePlugin = [allPlugins objectForKey:pluginName]; - if ([[onePlugin objectForKey:@"Default"] intValue]) + NSDictionary * onePlugin = allPlugins[pluginName]; + if ([onePlugin[@"Default"] integerValue]) [newArray addObject:pluginName]; } return newArray; @@ -274,23 +272,23 @@ -(NSArray *)defaultToolbarItems */ -(void)toolbarItem:(ToolbarItem *)item withIdentifier:(NSString *)itemIdentifier { - NSDictionary * pluginItem = [allPlugins objectForKey:itemIdentifier]; + NSDictionary * pluginItem = allPlugins[itemIdentifier]; if (pluginItem != nil) { - NSString * friendlyName = [pluginItem objectForKey:@"FriendlyName"]; - NSString * tooltip = [pluginItem objectForKey:@"Tooltip"]; + NSString * friendlyName = pluginItem[@"FriendlyName"]; + NSString * tooltip = pluginItem[@"Tooltip"]; if (friendlyName == nil) friendlyName = itemIdentifier; if (tooltip == nil) tooltip = friendlyName; - [item setLabel:friendlyName]; - [item setPaletteLabel:[item label]]; - [item compositeButtonImage:[pluginItem objectForKey:@"ButtonImage"] fromPath:[pluginItem objectForKey:@"Path"]]; - [item setTarget:self]; - [item setAction:@selector(pluginInvocator:)]; - [item setToolTip:tooltip]; + item.label = friendlyName; + item.paletteLabel = item.label; + [item compositeButtonImage:pluginItem[@"ButtonImage"] fromPath:pluginItem[@"Path"]]; + item.target = self; + item.action = @selector(pluginInvocator:); + item.toolTip = tooltip; } } @@ -299,13 +297,13 @@ -(void)toolbarItem:(ToolbarItem *)item withIdentifier:(NSString *)itemIdentifier */ -(BOOL)validateToolbarItem:(ToolbarItem *)toolbarItem { - NSView * theView = [[APPCONTROLLER browserView] activeTabItemView]; - Article * thisArticle = [APPCONTROLLER selectedArticle]; + NSView * theView = APPCONTROLLER.browserView.activeTabItemView; + Article * thisArticle = APPCONTROLLER.selectedArticle; if ([theView isKindOfClass:[BrowserPane class]]) - return (([theView viewLink] != nil) && [NSApp isActive]); + return ((theView.viewLink != nil) && NSApp.active); else - return (thisArticle != nil && [NSApp isActive]); + return (thisArticle != nil && NSApp.active); } /* pluginInvocator @@ -316,11 +314,11 @@ -(IBAction)pluginInvocator:(id)sender NSDictionary * pluginItem; if ([sender isKindOfClass:[ToolbarButton class]]) - pluginItem = [allPlugins objectForKey:[sender itemIdentifier]]; + pluginItem = allPlugins[[sender itemIdentifier]]; else { NSMenuItem * menuItem = (NSMenuItem *)sender; - pluginItem = [menuItem representedObject]; + pluginItem = menuItem.representedObject; } if (pluginItem != nil) @@ -328,33 +326,32 @@ -(IBAction)pluginInvocator:(id)sender // This is a link plugin. There should be a URL field which we invoke and possibly // placeholders to be filled from the current article or website. - NSString * itemType = [pluginItem objectForKey:@"Type"]; + NSString * itemType = pluginItem[@"Type"]; if ([itemType isEqualToString:@"Link"]) { - NSMutableString * urlString = [NSMutableString stringWithString:[pluginItem objectForKey:@"URL"]]; + NSMutableString * urlString = [NSMutableString stringWithString:pluginItem[@"URL"]]; if (urlString == nil) return; // Get the view that the user is currently looking at... - NSView * theView = [[APPCONTROLLER browserView] activeTabItemView]; + NSView * theView = APPCONTROLLER.browserView.activeTabItemView; // ...and do the following in case the user is currently looking at a website. if ([theView isKindOfClass:[BrowserPane class]]) { - [urlString replaceString:@"$ArticleTitle$" withString:[theView viewTitle]]; + [urlString replaceString:@"$ArticleTitle$" withString:theView.viewTitle]; // If ShortenURLs is true in the plugin's info.plist, we attempt to shorten it via the bit.ly service. - if ([[pluginItem objectForKey:@"ShortenURLs"] boolValue]) + if ([pluginItem[@"ShortenURLs"] boolValue]) { BitlyAPIHelper * bitlyHelper = [[BitlyAPIHelper alloc] initWithLogin:@"viennarss" andAPIKey:@"R_852929122e82d2af45fe9e238f1012d3"]; - NSString * shortURL = [bitlyHelper shortenURL:[theView viewLink]]; + NSString * shortURL = [bitlyHelper shortenURL:theView.viewLink]; [urlString replaceString:@"$ArticleLink$" withString:shortURL]; - [bitlyHelper release]; } else { - [urlString replaceString:@"$ArticleLink$" withString:[[theView viewLink] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; + [urlString replaceString:@"$ArticleLink$" withString:[theView.viewLink stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; } } @@ -363,22 +360,21 @@ -(IBAction)pluginInvocator:(id)sender else { // We can only work on one article, so ignore selection range. - Article * currentMessage = [APPCONTROLLER selectedArticle]; - [urlString replaceString:@"$ArticleTitle$" withString: [currentMessage title]]; + Article * currentMessage = APPCONTROLLER.selectedArticle; + [urlString replaceString:@"$ArticleTitle$" withString: currentMessage.title]; // URL shortening again, as above... - if ([[pluginItem objectForKey:@"ShortenURLs"] boolValue]) + if ([pluginItem[@"ShortenURLs"] boolValue]) { BitlyAPIHelper * bitlyHelper = [[BitlyAPIHelper alloc] initWithLogin:@"viennarss" andAPIKey:@"R_852929122e82d2af45fe9e238f1012d3"]; - NSString * shortURL = [bitlyHelper shortenURL:[currentMessage link]]; + NSString * shortURL = [bitlyHelper shortenURL:currentMessage.link]; // If URL shortening fails, we fall back to the long URL. - [urlString replaceString:@"$ArticleLink$" withString:(shortURL ? shortURL : [[[currentMessage link] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding])]; - [bitlyHelper release]; + [urlString replaceString:@"$ArticleLink$" withString:(shortURL ? shortURL : [[currentMessage.link stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding])]; } else { - [urlString replaceString:@"$ArticleLink$" withString: [[[currentMessage link] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; + [urlString replaceString:@"$ArticleLink$" withString: [[currentMessage.link stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; } } @@ -400,8 +396,8 @@ -(IBAction)pluginInvocator:(id)sender { // This is a script plugin. There should be a Script field which specifies the // filename of the script file in the same folder. - NSString * pluginPath = [pluginItem objectForKey:@"Path"]; - NSString * scriptFile = [pluginPath stringByAppendingPathComponent:[pluginItem objectForKey:@"Script"]]; + NSString * pluginPath = pluginItem[@"Path"]; + NSString * scriptFile = [pluginPath stringByAppendingPathComponent:pluginItem[@"Script"]]; if (scriptFile == nil) return; @@ -412,18 +408,9 @@ -(IBAction)pluginInvocator:(id)sender else if ([itemType isEqualToString:@"BlogEditor"]) { // This is a blog-editor plugin. Simply send the info to the application. - [APPCONTROLLER blogWithExternalEditor:[pluginItem objectForKey:@"BundleIdentifier"]]; + [APPCONTROLLER blogWithExternalEditor:pluginItem[@"BundleIdentifier"]]; } } } -/* dealloc - * Clean up after ourselves. - */ --(void)dealloc -{ - [allPlugins release]; - allPlugins=nil; - [super dealloc]; -} @end diff --git a/src/PopUpButtonExtensions.h b/src/PopUpButtonExtensions.h index 7112d68f89..2511aaf9f5 100644 --- a/src/PopUpButtonExtensions.h +++ b/src/PopUpButtonExtensions.h @@ -23,10 +23,10 @@ @interface NSPopUpButton (PopUpButtonExtensions) -(void)addItemWithTitle:(NSString *)title image:(NSImage *)image; -(void)addItemWithTarget:(NSString *)title target:(SEL)target; - -(void)addItemWithTag:(NSString *)title tag:(int)tag; + -(void)addItemWithTag:(NSString *)title tag:(NSInteger)tag; -(void)addItemWithRepresentedObject:(NSString *)title object:(id)object; - -(void)insertItemWithTag:(NSString *)title tag:(int)tag atIndex:(int)index; - -(id)representedObjectForSelection; - -(int)tagForSelection; + -(void)insertItemWithTag:(NSString *)title tag:(NSInteger)tag atIndex:(NSInteger)index; + @property (nonatomic, readonly, strong) id representedObjectForSelection; + @property (nonatomic, readonly) NSInteger tagForSelection; -(void)addSeparator; @end diff --git a/src/PopUpButtonExtensions.m b/src/PopUpButtonExtensions.m index 1e2c12e927..b17c44d154 100644 --- a/src/PopUpButtonExtensions.m +++ b/src/PopUpButtonExtensions.m @@ -30,10 +30,9 @@ @implementation NSPopUpButton (PopUpButtonExtensions) -(void)addItemWithTitle:(NSString *)title image:(NSImage *)image { NSMenuItem * newItem = [[NSMenuItem alloc] initWithTitle:title action:nil keyEquivalent:@""]; - [image setSize:NSMakeSize(16, 16)]; - [newItem setImage:image]; - [[self menu] addItem:newItem]; - [newItem release]; + image.size = NSMakeSize(16, 16); + newItem.image = image; + [self.menu addItem:newItem]; } /* addItemWithTarget @@ -42,19 +41,17 @@ -(void)addItemWithTitle:(NSString *)title image:(NSImage *)image -(void)addItemWithTarget:(NSString *)title target:(SEL)target { NSMenuItem * newItem = [[NSMenuItem alloc] initWithTitle:title action:target keyEquivalent:@""]; - [[self menu] addItem:newItem]; - [newItem release]; + [self.menu addItem:newItem]; } /* addItemWithTag * Add an item to the popup button menu with the specified tag. */ --(void)addItemWithTag:(NSString *)title tag:(int)tag +-(void)addItemWithTag:(NSString *)title tag:(NSInteger)tag { NSMenuItem * newItem = [[NSMenuItem alloc] initWithTitle:title action:nil keyEquivalent:@""]; - [newItem setTag:tag]; - [[self menu] addItem:newItem]; - [newItem release]; + newItem.tag = tag; + [self.menu addItem:newItem]; } /* addItemWithRepresentedObject @@ -63,21 +60,19 @@ -(void)addItemWithTag:(NSString *)title tag:(int)tag -(void)addItemWithRepresentedObject:(NSString *)title object:(id)object { NSMenuItem * newItem = [[NSMenuItem alloc] initWithTitle:title action:nil keyEquivalent:@""]; - [newItem setRepresentedObject:object]; - [[self menu] addItem:newItem]; - [newItem release]; + newItem.representedObject = object; + [self.menu addItem:newItem]; } /* insertItemWithTag * Inserts the specified menu item into the popup menu at the given index and assigns it * an initial tag value. */ --(void)insertItemWithTag:(NSString *)title tag:(int)tag atIndex:(int)index +-(void)insertItemWithTag:(NSString *)title tag:(NSInteger)tag atIndex:(NSInteger)index { NSMenuItem * newItem = [[NSMenuItem alloc] initWithTitle:title action:nil keyEquivalent:@""]; - [newItem setTag:tag]; - [[self menu] insertItem:newItem atIndex:index]; - [newItem release]; + newItem.tag = tag; + [self.menu insertItem:newItem atIndex:index]; } /* representedObjectForSelection @@ -85,17 +80,17 @@ -(void)insertItemWithTag:(NSString *)title tag:(int)tag atIndex:(int)index */ -(id)representedObjectForSelection { - NSMenuItem * theItem = [self selectedItem]; - return [theItem representedObject]; + NSMenuItem * theItem = self.selectedItem; + return theItem.representedObject; } /* tagForSelection * Returns the tag associated with the selected item. */ --(int)tagForSelection +-(NSInteger)tagForSelection { - NSMenuItem * theItem = [self selectedItem]; - return [theItem tag]; + NSMenuItem * theItem = self.selectedItem; + return theItem.tag; } /* addSeparator @@ -103,6 +98,6 @@ -(int)tagForSelection */ -(void)addSeparator { - [[self menu] addItem:[NSMenuItem separatorItem]]; + [self.menu addItem:[NSMenuItem separatorItem]]; } @end diff --git a/src/PopupButton.h b/src/PopupButton.h index a66cd9076f..ea28d5eb1b 100644 --- a/src/PopupButton.h +++ b/src/PopupButton.h @@ -28,8 +28,7 @@ } // Public functions --(NSMenu *)theMenu; +@property (nonatomic, copy) NSMenu *theMenu; -(void)setSmallMenu:(BOOL)useSmallMenu; -(void)setPopupBelow:(BOOL)flag; --(void)setTheMenu:(NSMenu *)menu; @end diff --git a/src/PopupButton.m b/src/PopupButton.m index 90278622d0..bd1dcd84f4 100644 --- a/src/PopupButton.m +++ b/src/PopupButton.m @@ -26,7 +26,7 @@ @implementation PopupButton * Initialises a simple subclass of NSButton that pops up a menu * if one is associated with it. */ --(id)initWithFrame:(NSRect)frameRect withItem:(NSToolbarItem *)theItem +-(instancetype)initWithFrame:(NSRect)frameRect withItem:(NSToolbarItem *)theItem { if ((self = [super initWithFrame:frameRect withItem:theItem]) != nil) { @@ -59,8 +59,6 @@ -(void)setSmallMenu:(BOOL)useSmallMenu */ -(void)setTheMenu:(NSMenu *)menu { - [menu retain]; - [theMenu release]; theMenu = menu; } @@ -69,7 +67,7 @@ -(void)setTheMenu:(NSMenu *)menu */ -(NSMenu *)theMenu { - return [[theMenu retain] autorelease]; + return theMenu; } /* mouseDown @@ -78,21 +76,21 @@ -(NSMenu *)theMenu */ -(void)mouseDown:(NSEvent *)theEvent { - if ([self isEnabled] && theMenu != nil) + if (self.enabled && theMenu != nil) { [self highlight:YES]; - NSPoint popPoint = NSMakePoint([self bounds].origin.x, [self bounds].origin.y); + NSPoint popPoint = NSMakePoint(self.bounds.origin.x, self.bounds.origin.y); if (popBelow) - popPoint.y += [self bounds].size.height + 5; - NSEvent * evt = [NSEvent mouseEventWithType:[theEvent type] - location:[self convertPoint:popPoint toView:nil] - modifierFlags:[theEvent modifierFlags] - timestamp:[theEvent timestamp] - windowNumber:[theEvent windowNumber] - context:[theEvent context] - eventNumber:[theEvent eventNumber] - clickCount:[theEvent clickCount] - pressure:[theEvent pressure]]; + popPoint.y += self.bounds.size.height + 5; + NSEvent * evt = [NSEvent mouseEventWithType:theEvent.type + location:[self convertPoint:popPoint toView:nil] + modifierFlags:theEvent.modifierFlags + timestamp:theEvent.timestamp + windowNumber:theEvent.windowNumber + context:theEvent.context + eventNumber:theEvent.eventNumber + clickCount:theEvent.clickCount + pressure:theEvent.pressure]; [NSMenu popUpContextMenu:theMenu withEvent:evt forView:self withFont:popupFont]; [self highlight:NO]; } @@ -103,17 +101,8 @@ -(void)mouseDown:(NSEvent *)theEvent */ -(void)mouseUp:(NSEvent *)theEvent { - if ([self isEnabled]) + if (self.enabled) [self highlight:NO]; } -/* dealloc - * Clean up behind ourself. - */ --(void)dealloc -{ - [theMenu release]; - theMenu=nil; - [super dealloc]; -} @end diff --git a/src/Preferences.h b/src/Preferences.h index 50edb26d9b..6bf4052c7c 100644 --- a/src/Preferences.h +++ b/src/Preferences.h @@ -27,13 +27,13 @@ NSString * profilePath; NSString * preferencesPath; float markReadInterval; - int minimumFontSize; - int refreshFrequency; - int autoExpireDuration; - int filterMode; - int layout; - int newArticlesNotification; - int foldersTreeSortMethod; + NSInteger minimumFontSize; + NSInteger refreshFrequency; + NSInteger autoExpireDuration; + NSInteger filterMode; + NSInteger layout; + NSInteger newArticlesNotification; + NSInteger foldersTreeSortMethod; BOOL refreshOnStartup; BOOL checkForNewOnStartup; BOOL alwaysAcceptBetas; @@ -54,7 +54,7 @@ BOOL sendSystemSpecs; NSString * downloadFolder; NSString * displayStyle; - float textSizeMultiplier; + CGFloat textSizeMultiplier; NSString * defaultDatabase; NSString * imagesFolder; NSString * scriptsFolder; @@ -96,163 +96,126 @@ extern NSString * const kMA_Notify_UseWebPluginsChange; -(void)setDefaultDatabase:(NSString *)newDatabase; // Path to scripts folder --(NSString *)scriptsFolder; +@property (nonatomic, readonly, copy) NSString *scriptsFolder; // Path to images folder --(NSString *)imagesFolder; +@property (nonatomic, readonly, copy) NSString *imagesFolder; // Path to styles folder --(NSString *)stylesFolder; +@property (nonatomic, readonly, copy) NSString *stylesFolder; // Path to the external plugins folder --(NSString *)pluginsFolder; +@property (nonatomic, readonly, copy) NSString *pluginsFolder; // Read-only internal settings --(int)backTrackQueueSize; +@property (nonatomic, readonly) NSInteger backTrackQueueSize; // Auto-expire values --(int)autoExpireDuration; --(void)setAutoExpireDuration:(int)newDuration; +@property (nonatomic) NSInteger autoExpireDuration; // Download folder --(NSString *)downloadFolder; --(void)setDownloadFolder:(NSString *)newFolder; +@property (nonatomic, copy) NSString *downloadFolder; // New articles notification method --(int)newArticlesNotification; --(void)setNewArticlesNotification:(int)newMethod; +@property (nonatomic) NSInteger newArticlesNotification; // Mark read interval --(float)markReadInterval; --(void)setMarkReadInterval:(float)newInterval; +@property (nonatomic) float markReadInterval; // Layout style --(int)layout; --(void)setLayout:(int)newLayout; +@property (nonatomic) NSInteger layout; // Controls how articles are filtered in the view --(int)filterMode; --(void)setFilterMode:(int)newMode; +@property (nonatomic) NSInteger filterMode; // Whether or not we show folder images --(BOOL)showFolderImages; --(void)setShowFolderImages:(BOOL)showImages; +@property (nonatomic) BOOL showFolderImages; // Refresh all subscriptions on startup --(BOOL)refreshOnStartup; --(void)setRefreshOnStartup:(BOOL)flag; +@property (nonatomic) BOOL refreshOnStartup; // Check for new versions of Vienna on startup --(BOOL)checkForNewOnStartup; --(void)setCheckForNewOnStartup:(BOOL)flag; +@property (nonatomic) BOOL checkForNewOnStartup; // When checking a newer version, always search for Betas versions --(BOOL)alwaysAcceptBetas; --(void)setAlwaysAcceptBetas:(BOOL)flag; +@property (nonatomic) BOOL alwaysAcceptBetas; // Opening URL links in Vienna --(BOOL)openLinksInVienna; --(void)setOpenLinksInVienna:(BOOL)flag; +@property (nonatomic) BOOL openLinksInVienna; // Opening URL links in background --(BOOL)openLinksInBackground; --(void)setOpenLinksInBackground:(BOOL)flag; +@property (nonatomic) BOOL openLinksInBackground; // Minimum font size settings --(int)minimumFontSize; --(BOOL)enableMinimumFontSize; --(void)setMinimumFontSize:(int)newSize; --(void)setEnableMinimumFontSize:(BOOL)flag; +@property (nonatomic) NSInteger minimumFontSize; +@property (nonatomic) BOOL enableMinimumFontSize; // JavaScript settings --(BOOL)useJavaScript; --(void)setUseJavaScript:(BOOL)flag; +@property (nonatomic) BOOL useJavaScript; // Web Plugins settings --(BOOL)useWebPlugins; --(void)setUseWebPlugins:(BOOL)flag; +@property (nonatomic) BOOL useWebPlugins; // Refresh frequency --(void)setRefreshFrequency:(int)newFrequency; --(int)refreshFrequency; +@property (nonatomic) NSInteger refreshFrequency; // Current display style --(NSString *)displayStyle; --(void)setDisplayStyle:(NSString *)newStyle; +@property (nonatomic, copy) NSString *displayStyle; -(void)setDisplayStyle:(NSString *)newStyle withNotification:(BOOL)flag; --(float)textSizeMultiplier; --(void)setTextSizeMultiplier:(float)newValue; +@property (nonatomic) CGFloat textSizeMultiplier; // Folder list font --(NSString *)folderListFont; --(int)folderListFontSize; --(void)setFolderListFont:(NSString *)newFontName; --(void)setFolderListFontSize:(int)newFontSize; +@property (nonatomic, copy) NSString *folderListFont; +@property (nonatomic) NSInteger folderListFontSize; // Article list font --(NSString *)articleListFont; --(int)articleListFontSize; --(void)setArticleListFont:(NSString *)newFontName; --(void)setArticleListFontSize:(int)newFontSize; +@property (nonatomic, copy) NSString *articleListFont; +@property (nonatomic) NSInteger articleListFontSize; // Article list sort descriptors --(NSArray *)articleSortDescriptors; --(void)setArticleSortDescriptors:(NSArray *)newSortDescriptors; +@property (nonatomic, copy) NSArray *articleSortDescriptors; // Automatically sort folders tree --(int)foldersTreeSortMethod; --(void)setFoldersTreeSortMethod:(int)newMethod; +@property (nonatomic) NSInteger foldersTreeSortMethod; // Do we show an icon in the status bar? --(BOOL)showAppInStatusBar; --(void)setShowAppInStatusBar:(BOOL)show; +@property (nonatomic) BOOL showAppInStatusBar; -// Handle update via Sparkle +// Handle update via Sparkle / ViennaSparkleDelegate -(void)handleUpdateRestart; // Show or hide the status bar --(BOOL)showStatusBar; --(void)setShowStatusBar:(BOOL)show; +@property (nonatomic) BOOL showStatusBar; // Show or hide the filter bar --(BOOL)showFilterBar; --(void)setShowFilterBar:(BOOL)show; +@property (nonatomic) BOOL showFilterBar; // Should we save the raw feed source XML? --(NSString *)feedSourcesFolder; --(BOOL)shouldSaveFeedSource; --(void)setShouldSaveFeedSource:(BOOL)shouldSave; +@property (nonatomic, readonly, copy) NSString *feedSourcesFolder; +@property (nonatomic) BOOL shouldSaveFeedSource; // Current search method --(SearchMethod *)searchMethod; --(void)setSearchMethod:(SearchMethod *)newMethod; +@property (nonatomic, strong) SearchMethod *searchMethod; // Concurrent download settings --(NSUInteger)concurrentDownloads; --(void)setConcurrentDownloads:(NSUInteger)downloads; +@property (nonatomic) NSUInteger concurrentDownloads; // Do we show updated articles as new ? --(BOOL)markUpdatedAsNew; --(void)setMarkUpdatedAsNew:(BOOL)flag; +@property (nonatomic) BOOL markUpdatedAsNew; // Do we send system specs when checking for updates? --(BOOL)sendSystemSpecs; --(void)setSendSystemSpecs:(BOOL)flag; +@property (nonatomic) BOOL sendSystemSpecs; #pragma mark - #pragma mark Open Reader syncing --(BOOL)syncGoogleReader; --(void)setSyncGoogleReader:(BOOL)flag; +@property (nonatomic) BOOL syncGoogleReader; --(BOOL)prefersGoogleNewSubscription; --(void)setPrefersGoogleNewSubscription:(BOOL)flag; +@property (nonatomic) BOOL prefersGoogleNewSubscription; // server used for syncing --(NSString *)syncServer; --(void)setSyncServer:(NSString *)newServer; +@property (nonatomic, copy) NSString *syncServer; // username used for syncing --(NSString *)syncingUser; --(void)setSyncingUser:(NSString *)newUser; +@property (nonatomic, copy) NSString *syncingUser; @end \ No newline at end of file diff --git a/src/Preferences.m b/src/Preferences.m index dce6651e59..29807cc9f4 100644 --- a/src/Preferences.m +++ b/src/Preferences.m @@ -48,7 +48,7 @@ // Private methods @interface Preferences (Private) --(NSDictionary *)allocFactoryDefaults; +@property (nonatomic, readonly, copy) NSDictionary *allocFactoryDefaults; -(void)createFeedSourcesFolderIfNecessary; -(void)handleUpdateRestart:(NSNotification *)nc; @end @@ -68,7 +68,7 @@ +(Preferences *)standardPreferences /* init * The designated initialiser. */ --(id)init +-(instancetype)init { if ((self = [super init]) != nil) { @@ -81,13 +81,13 @@ -(id)init // If no profile is specified, is called "default" or is absent then we fall back // on the user profile. // - NSArray * appArguments = [[NSProcessInfo processInfo] arguments]; + NSArray * appArguments = [NSProcessInfo processInfo].arguments; NSEnumerator * enumerator = [appArguments objectEnumerator]; NSString * argName; while ((argName = [enumerator nextObject]) != nil) { - if ([[argName lowercaseString] isEqualToString:@"-profile"]) + if ([argName.lowercaseString isEqualToString:@"-profile"]) { NSString * argValue = [enumerator nextObject]; if (argValue == nil || [argValue isEqualToString:@"default"]) @@ -103,7 +103,7 @@ -(id)init [[NSUserDefaults standardUserDefaults] removeObjectForKey:MAPref_Profile_Path]; // Merge in the user preferences from the defaults. - NSDictionary * defaults = [self allocFactoryDefaults]; + NSDictionary * defaults = self.allocFactoryDefaults; if (profilePath == nil) { preferencesPath = nil; @@ -111,12 +111,12 @@ -(id)init [userPrefs registerDefaults:defaults]; // Application-specific folder locations - defaultDatabase = [[userPrefs valueForKey:MAPref_DefaultDatabase] retain]; - imagesFolder = [[[MA_ApplicationSupportFolder stringByAppendingPathComponent:MA_ImagesFolder_Name] stringByExpandingTildeInPath] retain]; - stylesFolder = [[[MA_ApplicationSupportFolder stringByAppendingPathComponent:MA_StylesFolder_Name] stringByExpandingTildeInPath] retain]; - pluginsFolder = [[[MA_ApplicationSupportFolder stringByAppendingPathComponent:MA_PluginsFolder_Name] stringByExpandingTildeInPath] retain]; - scriptsFolder = [[MA_ScriptsFolder stringByExpandingTildeInPath] retain]; - feedSourcesFolder = [[[MA_ApplicationSupportFolder stringByAppendingPathComponent:MA_FeedSourcesFolder_Name] stringByExpandingTildeInPath] retain]; + defaultDatabase = [userPrefs valueForKey:MAPref_DefaultDatabase]; + imagesFolder = [MA_ApplicationSupportFolder stringByAppendingPathComponent:MA_ImagesFolder_Name].stringByExpandingTildeInPath; + stylesFolder = [MA_ApplicationSupportFolder stringByAppendingPathComponent:MA_StylesFolder_Name].stringByExpandingTildeInPath; + pluginsFolder = [MA_ApplicationSupportFolder stringByAppendingPathComponent:MA_PluginsFolder_Name].stringByExpandingTildeInPath; + scriptsFolder = MA_ScriptsFolder.stringByExpandingTildeInPath; + feedSourcesFolder = [MA_ApplicationSupportFolder stringByAppendingPathComponent:MA_FeedSourcesFolder_Name].stringByExpandingTildeInPath; } else { @@ -131,7 +131,6 @@ -(id)init if (![fileManager createDirectoryAtPath:profilePath withIntermediateDirectories:YES attributes:NULL error:&error]) { NSLog(@"Cannot create profile folder %@: %@", profilePath, error); - [error release]; profilePath = nil; } } @@ -140,29 +139,27 @@ -(id)init // name plus the .plist extension. (This is the same convention used by NSUserDefaults.) if (profilePath != nil) { - [profilePath retain]; - NSDictionary * fileAttributes = [[NSBundle mainBundle] infoDictionary]; - preferencesPath = [profilePath stringByAppendingPathComponent:[fileAttributes objectForKey:@"CFBundleIdentifier"]]; - preferencesPath = [[preferencesPath stringByAppendingString:@".plist"] retain]; + NSDictionary * fileAttributes = [NSBundle mainBundle].infoDictionary; + preferencesPath = [profilePath stringByAppendingPathComponent:fileAttributes[@"CFBundleIdentifier"]]; + preferencesPath = [preferencesPath stringByAppendingString:@".plist"]; } userPrefs = [[NSMutableDictionary alloc] initWithDictionary:defaults]; if (preferencesPath != nil) [userPrefs addEntriesFromDictionary:[NSDictionary dictionaryWithContentsOfFile:preferencesPath]]; // Other folders are local to the profilePath - defaultDatabase = [[profilePath stringByAppendingPathComponent:MA_Database_Name] retain]; - imagesFolder = [[[profilePath stringByAppendingPathComponent:MA_ImagesFolder_Name] stringByExpandingTildeInPath] retain]; - stylesFolder = [[[profilePath stringByAppendingPathComponent:MA_StylesFolder_Name] stringByExpandingTildeInPath] retain]; - scriptsFolder = [[[profilePath stringByAppendingPathComponent:MA_ScriptsFolder_Name] stringByExpandingTildeInPath] retain]; - pluginsFolder = [[[profilePath stringByAppendingPathComponent:MA_PluginsFolder_Name] stringByExpandingTildeInPath] retain]; - feedSourcesFolder = [[[profilePath stringByAppendingPathComponent:MA_FeedSourcesFolder_Name] stringByExpandingTildeInPath] retain]; + defaultDatabase = [profilePath stringByAppendingPathComponent:MA_Database_Name]; + imagesFolder = [profilePath stringByAppendingPathComponent:MA_ImagesFolder_Name].stringByExpandingTildeInPath; + stylesFolder = [profilePath stringByAppendingPathComponent:MA_StylesFolder_Name].stringByExpandingTildeInPath; + scriptsFolder = [profilePath stringByAppendingPathComponent:MA_ScriptsFolder_Name].stringByExpandingTildeInPath; + pluginsFolder = [profilePath stringByAppendingPathComponent:MA_PluginsFolder_Name].stringByExpandingTildeInPath; + feedSourcesFolder = [profilePath stringByAppendingPathComponent:MA_FeedSourcesFolder_Name].stringByExpandingTildeInPath; } - [defaults release]; // Load those settings that we cache. foldersTreeSortMethod = [self integerForKey:MAPref_AutoSortFoldersTree]; - articleSortDescriptors = [[NSUnarchiver unarchiveObjectWithData:[userPrefs valueForKey:MAPref_ArticleSortDescriptors]] retain]; + articleSortDescriptors = [NSUnarchiver unarchiveObjectWithData:[userPrefs valueForKey:MAPref_ArticleSortDescriptors]]; refreshFrequency = [self integerForKey:MAPref_CheckFrequency]; filterMode = [self integerForKey:MAPref_FilterMode]; layout = [self integerForKey:MAPref_Layout]; @@ -175,30 +172,30 @@ -(id)init autoExpireDuration = [self integerForKey:MAPref_AutoExpireDuration]; openLinksInVienna = [self boolForKey:MAPref_OpenLinksInVienna]; openLinksInBackground = [self boolForKey:MAPref_OpenLinksInBackground]; - displayStyle = [[userPrefs valueForKey:MAPref_ActiveStyleName] retain]; - textSizeMultiplier = [[userPrefs valueForKey:MAPref_ActiveTextSizeMultiplier] floatValue]; + displayStyle = [userPrefs valueForKey:MAPref_ActiveStyleName]; + textSizeMultiplier = [[userPrefs valueForKey:MAPref_ActiveTextSizeMultiplier] doubleValue]; showFolderImages = [self boolForKey:MAPref_ShowFolderImages]; showStatusBar = [self boolForKey:MAPref_ShowStatusBar]; showFilterBar = [self boolForKey:MAPref_ShowFilterBar]; useJavaScript = [self boolForKey:MAPref_UseJavaScript]; useWebPlugins = [self boolForKey:MAPref_UseWebPlugins]; showAppInStatusBar = [self boolForKey:MAPref_ShowAppInStatusBar]; - folderFont = [[NSUnarchiver unarchiveObjectWithData:[userPrefs objectForKey:MAPref_FolderFont]] retain]; - articleFont = [[NSUnarchiver unarchiveObjectWithData:[userPrefs objectForKey:MAPref_ArticleListFont]] retain]; - downloadFolder = [[userPrefs valueForKey:MAPref_DownloadsFolder] retain]; + folderFont = [NSUnarchiver unarchiveObjectWithData:[userPrefs objectForKey:MAPref_FolderFont]]; + articleFont = [NSUnarchiver unarchiveObjectWithData:[userPrefs objectForKey:MAPref_ArticleListFont]]; + downloadFolder = [userPrefs valueForKey:MAPref_DownloadsFolder]; shouldSaveFeedSource = [self boolForKey:MAPref_ShouldSaveFeedSource]; - searchMethod = [[NSKeyedUnarchiver unarchiveObjectWithData:[userPrefs objectForKey:MAPref_SearchMethod]] retain]; + searchMethod = [NSKeyedUnarchiver unarchiveObjectWithData:[userPrefs objectForKey:MAPref_SearchMethod]]; concurrentDownloads = [self integerForKey:MAPref_ConcurrentDownloads]; // Open Reader sync syncGoogleReader = [self boolForKey:MAPref_SyncGoogleReader]; prefersGoogleNewSubscription = [self boolForKey:MAPref_GoogleNewSubscription]; - syncServer = [[userPrefs valueForKey:MAPref_SyncServer] retain]; - syncingUser = [[userPrefs valueForKey:MAPref_SyncingUser] retain]; + syncServer = [userPrefs valueForKey:MAPref_SyncServer]; + syncingUser = [userPrefs valueForKey:MAPref_SyncingUser]; //Sparkle autoupdate - checkForNewOnStartup = [[SUUpdater sharedUpdater] automaticallyChecksForUpdates]; - sendSystemSpecs = [[SUUpdater sharedUpdater] sendsSystemProfile]; + checkForNewOnStartup = [SUUpdater sharedUpdater].automaticallyChecksForUpdates; + sendSystemSpecs = [SUUpdater sharedUpdater].sendsSystemProfile; alwaysAcceptBetas = [self boolForKey:MAPref_AlwaysAcceptBetas]; if (shouldSaveFeedSource) @@ -210,7 +207,7 @@ -(id)init NSString * bundleVersionString = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]; if (bundleVersionString != nil) { - int bundleVersion = [bundleVersionString intValue]; + NSInteger bundleVersion = bundleVersionString.integerValue; if (bundleVersion > 0) { if (bundleVersion > [self integerForKey:MAPref_HighestViennaVersionRun]) @@ -230,33 +227,6 @@ -(id)init -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - [defaultDatabase release]; - defaultDatabase=nil; - [imagesFolder release]; - imagesFolder=nil; - [downloadFolder release]; - downloadFolder=nil; - [folderFont release]; - folderFont=nil; - [articleFont release]; - articleFont=nil; - [displayStyle release]; - displayStyle=nil; - [preferencesPath release]; - preferencesPath=nil; - [articleSortDescriptors release]; - articleSortDescriptors=nil; - [profilePath release]; - profilePath=nil; - [feedSourcesFolder release]; - feedSourcesFolder=nil; - [searchMethod release]; - searchMethod=nil; - [syncServer release]; - syncServer=nil; - [syncingUser release]; - syncingUser=nil; - [super dealloc]; } /* allocFactoryDefaults @@ -268,56 +238,56 @@ -(NSDictionary *)allocFactoryDefaults NSMutableDictionary * defaultValues = [[NSMutableDictionary alloc] init]; NSData * defaultArticleListFont = [NSArchiver archivedDataWithRootObject:[NSFont fontWithName:@"LucidaGrande" size:11.0]]; NSData * defaultFolderFont = [NSArchiver archivedDataWithRootObject:[NSFont fontWithName:@"LucidaGrande" size:11.0]]; - NSData * defaultArticleSortDescriptors = [NSArchiver archivedDataWithRootObject:[NSArray array]]; + NSData * defaultArticleSortDescriptors = [NSArchiver archivedDataWithRootObject:@[]]; - NSNumber * boolNo = [NSNumber numberWithBool:NO]; - NSNumber * boolYes = [NSNumber numberWithBool:YES]; + NSNumber * boolNo = @NO; + NSNumber * boolYes = @YES; - [defaultValues setObject:[MA_ApplicationSupportFolder stringByAppendingPathComponent:MA_Database_Name] forKey:MAPref_DefaultDatabase]; - [defaultValues setObject:boolNo forKey:MAPref_CheckForUpdatedArticles]; - [defaultValues setObject:boolYes forKey:MAPref_ShowUnreadArticlesInBold]; - [defaultValues setObject:defaultArticleListFont forKey:MAPref_ArticleListFont]; - [defaultValues setObject:defaultFolderFont forKey:MAPref_FolderFont]; - [defaultValues setObject:boolYes forKey:MAPref_CheckForNewArticlesOnStartup]; - [defaultValues setObject:[NSNumber numberWithInt:1] forKey:MAPref_CachedFolderID]; - [defaultValues setObject:MA_Field_Date forKey:MAPref_SortColumn]; - [defaultValues setObject:[NSNumber numberWithInteger:MA_Default_Check_Frequency] forKey:MAPref_CheckFrequency]; - [defaultValues setObject:[NSNumber numberWithFloat:MA_Default_Read_Interval] forKey:MAPref_MarkReadInterval]; - [defaultValues setObject:[NSNumber numberWithInt:MA_Default_RefreshThreads] forKey:MAPref_RefreshThreads]; - [defaultValues setObject:MA_DefaultStyleName forKey:MAPref_ActiveStyleName]; - [defaultValues setObject:[NSNumber numberWithFloat:1.0] forKey:MAPref_ActiveTextSizeMultiplier]; - [defaultValues setObject:[NSNumber numberWithInteger:MA_Default_BackTrackQueueSize] forKey:MAPref_BacktrackQueueSize]; - [defaultValues setObject:[NSNumber numberWithInt:MA_FolderSort_ByName] forKey:MAPref_AutoSortFoldersTree]; - [defaultValues setObject:boolYes forKey:MAPref_ShowFolderImages]; - [defaultValues setObject:boolYes forKey:MAPref_UseJavaScript]; - [defaultValues setObject:boolYes forKey:MAPref_UseWebPlugins]; - [defaultValues setObject:boolYes forKey:MAPref_OpenLinksInVienna]; - [defaultValues setObject:boolYes forKey:MAPref_OpenLinksInBackground]; - [defaultValues setObject:boolNo forKey:MAPref_ShowAppInStatusBar]; - [defaultValues setObject:boolYes forKey:MAPref_ShowStatusBar]; - [defaultValues setObject:boolYes forKey:MAPref_ShowFilterBar]; - [defaultValues setObject:boolNo forKey:MAPref_NewFolderUI]; - [defaultValues setObject:boolNo forKey:MAPref_UseMinimumFontSize]; - [defaultValues setObject:[NSNumber numberWithInt:MA_Filter_All] forKey:MAPref_FilterMode]; - [defaultValues setObject:[NSNumber numberWithInteger:MA_Default_MinimumFontSize] forKey:MAPref_MinimumFontSize]; - [defaultValues setObject:[NSNumber numberWithInteger:MA_Default_AutoExpireDuration] forKey:MAPref_AutoExpireDuration]; - [defaultValues setObject:MA_DefaultDownloadsFolder forKey:MAPref_DownloadsFolder]; - [defaultValues setObject:defaultArticleSortDescriptors forKey:MAPref_ArticleSortDescriptors]; - [defaultValues setObject:[NSDate distantPast] forKey:MAPref_LastRefreshDate]; - [defaultValues setObject:[NSNumber numberWithInt:MA_Layout_Report] forKey:MAPref_Layout]; - [defaultValues setObject:[NSNumber numberWithInt:MA_NewArticlesNotification_Badge] forKey:MAPref_NewArticlesNotification]; - [defaultValues setObject:[NSNumber numberWithInt:MA_EmptyTrash_WithWarning] forKey:MAPref_EmptyTrashNotification]; - [defaultValues setObject:[NSNumber numberWithInt:0] forKey:MAPref_HighestViennaVersionRun]; - [defaultValues setObject:[NSNumber numberWithInt:0] forKey:MAPref_LastViennaVersionRun]; - [defaultValues setObject:boolYes forKey:MAPref_ShouldSaveFeedSource]; - [defaultValues setObject:boolNo forKey:MAPref_ShouldSaveFeedSourceBackup]; - [defaultValues setObject:[NSKeyedArchiver archivedDataWithRootObject:[SearchMethod searchAllArticlesMethod]] forKey:MAPref_SearchMethod]; - [defaultValues setObject:[NSNumber numberWithInteger:MA_Default_ConcurrentDownloads] forKey:MAPref_ConcurrentDownloads]; - [defaultValues setObject:boolNo forKey:MAPref_SyncGoogleReader]; - [defaultValues setObject:boolNo forKey:MAPref_GoogleNewSubscription]; - [defaultValues setObject:boolNo forKey:MAPref_AlwaysAcceptBetas]; + defaultValues[MAPref_DefaultDatabase] = [MA_ApplicationSupportFolder stringByAppendingPathComponent:MA_Database_Name]; + defaultValues[MAPref_CheckForUpdatedArticles] = boolNo; + defaultValues[MAPref_ShowUnreadArticlesInBold] = boolYes; + defaultValues[MAPref_ArticleListFont] = defaultArticleListFont; + defaultValues[MAPref_FolderFont] = defaultFolderFont; + defaultValues[MAPref_CheckForNewArticlesOnStartup] = boolYes; + defaultValues[MAPref_CachedFolderID] = @1; + defaultValues[MAPref_SortColumn] = MA_Field_Date; + defaultValues[MAPref_CheckFrequency] = @(MA_Default_Check_Frequency); + defaultValues[MAPref_MarkReadInterval] = @((float)MA_Default_Read_Interval); + defaultValues[MAPref_RefreshThreads] = @(MA_Default_RefreshThreads); + defaultValues[MAPref_ActiveStyleName] = MA_DefaultStyleName; + defaultValues[MAPref_ActiveTextSizeMultiplier] = @1.0; + defaultValues[MAPref_BacktrackQueueSize] = @(MA_Default_BackTrackQueueSize); + defaultValues[MAPref_AutoSortFoldersTree] = @MA_FolderSort_Manual; + defaultValues[MAPref_ShowFolderImages] = boolYes; + defaultValues[MAPref_UseJavaScript] = boolYes; + defaultValues[MAPref_UseWebPlugins] = boolYes; + defaultValues[MAPref_OpenLinksInVienna] = boolYes; + defaultValues[MAPref_OpenLinksInBackground] = boolYes; + defaultValues[MAPref_ShowAppInStatusBar] = boolNo; + defaultValues[MAPref_ShowStatusBar] = boolYes; + defaultValues[MAPref_ShowFilterBar] = boolYes; + defaultValues[MAPref_NewFolderUI] = boolNo; + defaultValues[MAPref_UseMinimumFontSize] = boolNo; + defaultValues[MAPref_FilterMode] = @MA_Filter_All; + defaultValues[MAPref_MinimumFontSize] = @(MA_Default_MinimumFontSize); + defaultValues[MAPref_AutoExpireDuration] = @(MA_Default_AutoExpireDuration); + defaultValues[MAPref_DownloadsFolder] = MA_DefaultDownloadsFolder; + defaultValues[MAPref_ArticleSortDescriptors] = defaultArticleSortDescriptors; + defaultValues[MAPref_LastRefreshDate] = [NSDate distantPast]; + defaultValues[MAPref_Layout] = @MA_Layout_Report; + defaultValues[MAPref_NewArticlesNotification] = @MA_NewArticlesNotification_Badge; + defaultValues[MAPref_EmptyTrashNotification] = @MA_EmptyTrash_WithWarning; + defaultValues[MAPref_HighestViennaVersionRun] = @0; + defaultValues[MAPref_LastViennaVersionRun] = @0; + defaultValues[MAPref_ShouldSaveFeedSource] = boolYes; + defaultValues[MAPref_ShouldSaveFeedSourceBackup] = boolNo; + defaultValues[MAPref_SearchMethod] = [NSKeyedArchiver archivedDataWithRootObject:[SearchMethod searchAllArticlesMethod]]; + defaultValues[MAPref_ConcurrentDownloads] = @(MA_Default_ConcurrentDownloads); + defaultValues[MAPref_SyncGoogleReader] = boolNo; + defaultValues[MAPref_GoogleNewSubscription] = boolNo; + defaultValues[MAPref_AlwaysAcceptBetas] = boolNo; - return defaultValues; + return [defaultValues copy]; } /* savePreferences @@ -339,7 +309,7 @@ -(void)savePreferences */ -(void)setBool:(BOOL)value forKey:(NSString *)defaultName { - [userPrefs setObject:[NSNumber numberWithBool:value] forKey:defaultName]; + [userPrefs setObject:@(value) forKey:defaultName]; } /* setInteger @@ -347,7 +317,7 @@ -(void)setBool:(BOOL)value forKey:(NSString *)defaultName */ -(void)setInteger:(NSInteger)value forKey:(NSString *)defaultName { - [userPrefs setObject:[NSNumber numberWithInteger:value] forKey:defaultName]; + [userPrefs setObject:@(value) forKey:defaultName]; } /* setString @@ -461,8 +431,7 @@ -(void)setDefaultDatabase:(NSString *)newDatabase { if (defaultDatabase != newDatabase) { - [defaultDatabase release]; - defaultDatabase = [newDatabase retain]; + defaultDatabase = newDatabase; [userPrefs setValue:newDatabase forKey:MAPref_DefaultDatabase]; } } @@ -470,7 +439,7 @@ -(void)setDefaultDatabase:(NSString *)newDatabase /* backTrackQueueSize * Returns the length of the back track queue. */ --(int)backTrackQueueSize +-(NSInteger)backTrackQueueSize { return [self integerForKey:MAPref_BacktrackQueueSize]; } @@ -545,7 +514,7 @@ -(void)setConcurrentDownloads:(NSUInteger)downloads { /* minimumFontSize * Return the current minimum font size. */ --(int)minimumFontSize +-(NSInteger)minimumFontSize { return minimumFontSize; } @@ -553,7 +522,7 @@ -(int)minimumFontSize /* setMinimumFontSize * Change the minimum font size. */ --(void)setMinimumFontSize:(int)newSize +-(void)setMinimumFontSize:(NSInteger)newSize { if (newSize != minimumFontSize) { @@ -603,7 +572,7 @@ -(void)setShowFolderImages:(BOOL)flag * Returns the number of days worth of non-flagged articles to be preserved. Articles older than * this are automatically deleted. A value of 0 means never expire. */ --(int)autoExpireDuration +-(NSInteger)autoExpireDuration { return autoExpireDuration; } @@ -613,7 +582,7 @@ -(int)autoExpireDuration * disables auto-expire. Increments of 1000 specify months so 1000 = 1 month, 1001 = 1 month * and 1 day, etc. */ --(void)setAutoExpireDuration:(int)newDuration +-(void)setAutoExpireDuration:(NSInteger)newDuration { if (newDuration != autoExpireDuration) { @@ -637,8 +606,6 @@ -(void)setDownloadFolder:(NSString *)newFolder { if (![newFolder isEqualToString:downloadFolder]) { - [newFolder retain]; - [downloadFolder release]; downloadFolder = newFolder; [self setObject:downloadFolder forKey:MAPref_DownloadsFolder]; [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_PreferenceChange" object:nil]; @@ -648,7 +615,7 @@ -(void)setDownloadFolder:(NSString *)newFolder /* layout * Returns the current layout. */ --(int)layout +-(NSInteger)layout { return layout; } @@ -656,7 +623,7 @@ -(int)layout /* setLayout * Changes the current layout. */ --(void)setLayout:(int)newLayout +-(void)setLayout:(NSInteger)newLayout { if (layout != newLayout) { @@ -671,8 +638,6 @@ -(void)setLayout:(int)newLayout */ -(void)setSearchMethod:(SearchMethod *)newMethod { - [searchMethod release]; - [newMethod retain]; searchMethod = newMethod; [self setObject:[NSKeyedArchiver archivedDataWithRootObject:newMethod] forKey:MAPref_SearchMethod]; } @@ -690,7 +655,7 @@ -(SearchMethod *)searchMethod /* refreshFrequency * Return the frequency with which we refresh all subscriptions */ --(int)refreshFrequency +-(NSInteger)refreshFrequency { return refreshFrequency; } @@ -698,7 +663,7 @@ -(int)refreshFrequency /* setRefreshFrequency * Updates the refresh frequency and then updates the preferences. */ --(void)setRefreshFrequency:(int)newFrequency +-(void)setRefreshFrequency:(NSInteger)newFrequency { if (refreshFrequency != newFrequency) { @@ -745,7 +710,7 @@ -(void)setCheckForNewOnStartup:(BOOL)flag if (flag != checkForNewOnStartup) { checkForNewOnStartup = flag; - [[SUUpdater sharedUpdater] setAutomaticallyChecksForUpdates:flag]; + [SUUpdater sharedUpdater].automaticallyChecksForUpdates = flag; [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_PreferenceChange" object:nil]; } } @@ -767,15 +732,9 @@ -(void)setAlwaysAcceptBetas:(BOOL)flag { alwaysAcceptBetas = flag; [self setBool:flag forKey:MAPref_AlwaysAcceptBetas]; - if (flag) - { - [[SUUpdater sharedUpdater] setFeedURL:[NSURL URLWithString:@"http://vienna-rss.org/spstats/changelog_beta.php"]]; - } - else - { - // restore the default as defined in Info.plist - [[SUUpdater sharedUpdater] setFeedURL:nil]; - } + // we suppress what might be in user prefs for the SUFeedURL key : + // feed URL is now handled by -feedURLStringForUpdater: and Info.plist + [[SUUpdater sharedUpdater] setFeedURL:nil]; [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_PreferenceChange" object:nil]; } } @@ -798,7 +757,7 @@ -(void)setMarkReadInterval:(float)newInterval if (newInterval != markReadInterval) { markReadInterval = newInterval; - [self setObject:[NSNumber numberWithFloat:newInterval] forKey:MAPref_MarkReadInterval]; + [self setObject:@((float)newInterval) forKey:MAPref_MarkReadInterval]; [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_PreferenceChange" object:nil]; } } @@ -806,7 +765,7 @@ -(void)setMarkReadInterval:(float)newInterval /* filterMode * Returns the current filtering mode. */ --(int)filterMode +-(NSInteger)filterMode { return filterMode; } @@ -814,7 +773,7 @@ -(int)filterMode /* setFilterMode * Sets the new filtering mode for articles. */ --(void)setFilterMode:(int)newMode +-(void)setFilterMode:(NSInteger)newMode { if (filterMode != newMode) { @@ -914,8 +873,6 @@ -(void)setDisplayStyle:(NSString *)newStyleName withNotification:(BOOL)flag { if (![displayStyle isEqualToString:newStyleName]) { - [newStyleName retain]; - [displayStyle release]; displayStyle = newStyleName; [self setString:displayStyle forKey:MAPref_ActiveStyleName]; if (flag) @@ -926,7 +883,7 @@ -(void)setDisplayStyle:(NSString *)newStyleName withNotification:(BOOL)flag /* textSizeMultiplier * Return the textSizeMultiplier to be applied to an ArticleView */ --(float)textSizeMultiplier +-(CGFloat)textSizeMultiplier { return textSizeMultiplier; } @@ -934,12 +891,12 @@ -(float)textSizeMultiplier /* setTextSizeMultiplier * Changes the textSizeMultiplier to be applied to an ArticleView */ --(void)setTextSizeMultiplier:(float)newValue +-(void)setTextSizeMultiplier:(CGFloat)newValue { if (newValue != textSizeMultiplier) { textSizeMultiplier = newValue; - [self setObject:[NSNumber numberWithFloat:newValue] forKey:MAPref_ActiveTextSizeMultiplier]; + [self setObject:@(newValue) forKey:MAPref_ActiveTextSizeMultiplier]; [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_StyleChange" object:nil]; } } @@ -949,15 +906,15 @@ -(void)setTextSizeMultiplier:(float)newValue */ -(NSString *)folderListFont { - return [folderFont fontName]; + return folderFont.fontName; } /* folderListFontSize * Retrieve the size of the font used in the folder list */ --(int)folderListFontSize +-(NSInteger)folderListFontSize { - return [folderFont pointSize]; + return folderFont.pointSize; } /* setFolderListFont @@ -965,8 +922,7 @@ -(int)folderListFontSize */ -(void)setFolderListFont:(NSString *)newFontName { - [folderFont release]; - folderFont = [[NSFont fontWithName:newFontName size:[self folderListFontSize]] retain]; + folderFont = [NSFont fontWithName:newFontName size:self.folderListFontSize]; [self setObject:[NSArchiver archivedDataWithRootObject:folderFont] forKey:MAPref_FolderFont]; [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_FolderFontChange" object:folderFont]; } @@ -974,10 +930,9 @@ -(void)setFolderListFont:(NSString *)newFontName /* setFolderListFontSize * Changes the size of the font used in the folder list. */ --(void)setFolderListFontSize:(int)newFontSize +-(void)setFolderListFontSize:(NSInteger)newFontSize { - [folderFont release]; - folderFont = [[NSFont fontWithName:[self folderListFont] size:newFontSize] retain]; + folderFont = [NSFont fontWithName:self.folderListFont size:newFontSize]; [self setObject:[NSArchiver archivedDataWithRootObject:folderFont] forKey:MAPref_FolderFont]; [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_FolderFontChange" object:folderFont]; } @@ -987,15 +942,15 @@ -(void)setFolderListFontSize:(int)newFontSize */ -(NSString *)articleListFont { - return [articleFont fontName]; + return articleFont.fontName; } /* articleListFontSize * Retrieve the size of the font used in the article list */ --(int)articleListFontSize +-(NSInteger)articleListFontSize { - return [articleFont pointSize]; + return articleFont.pointSize; } /* setArticleListFont @@ -1003,8 +958,7 @@ -(int)articleListFontSize */ -(void)setArticleListFont:(NSString *)newFontName { - [articleFont release]; - articleFont = [[NSFont fontWithName:newFontName size:[self articleListFontSize]] retain]; + articleFont = [NSFont fontWithName:newFontName size:self.articleListFontSize]; [self setObject:[NSArchiver archivedDataWithRootObject:articleFont] forKey:MAPref_ArticleListFont]; [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_ArticleListFontChange" object:articleFont]; } @@ -1012,10 +966,9 @@ -(void)setArticleListFont:(NSString *)newFontName /* setArticleListFontSize * Changes the size of the font used in the article list. */ --(void)setArticleListFontSize:(int)newFontSize +-(void)setArticleListFontSize:(NSInteger)newFontSize { - [articleFont release]; - articleFont = [[NSFont fontWithName:[self articleListFont] size:newFontSize] retain]; + articleFont = [NSFont fontWithName:self.articleListFont size:newFontSize]; [self setObject:[NSArchiver archivedDataWithRootObject:articleFont] forKey:MAPref_ArticleListFont]; [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_ArticleListFontChange" object:articleFont]; } @@ -1036,7 +989,6 @@ -(void)setArticleSortDescriptors:(NSArray *)newSortDescriptors if (![articleSortDescriptors isEqualToArray:newSortDescriptors]) { NSArray * descriptors = [[NSArray alloc] initWithArray:newSortDescriptors]; - [articleSortDescriptors release]; articleSortDescriptors = descriptors; [self setObject:[NSArchiver archivedDataWithRootObject:descriptors] forKey:MAPref_ArticleSortDescriptors]; [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_PreferenceChange" object:nil]; @@ -1046,7 +998,7 @@ -(void)setArticleSortDescriptors:(NSArray *)newSortDescriptors /* foldersTreeSortMethod * Returns the method by which the folders tree is sorted. See MA_FolderSort_xxx for the possible values. */ --(int)foldersTreeSortMethod +-(NSInteger)foldersTreeSortMethod { return foldersTreeSortMethod; } @@ -1054,7 +1006,7 @@ -(int)foldersTreeSortMethod /* setFoldersTreeSortMethod * Sets the method by which the folders tree is sorted. */ --(void)setFoldersTreeSortMethod:(int)newMethod +-(void)setFoldersTreeSortMethod:(NSInteger)newMethod { if (foldersTreeSortMethod != newMethod) { @@ -1067,7 +1019,7 @@ -(void)setFoldersTreeSortMethod:(int)newMethod /* newArticlesNotification * Returns the current method by which Vienna indicates new articles are available. */ --(int)newArticlesNotification +-(NSInteger)newArticlesNotification { return newArticlesNotification; } @@ -1075,7 +1027,7 @@ -(int)newArticlesNotification /* setNewArticlesNotification * Sets the method by which Vienna indicates new articles are available. */ --(void)setNewArticlesNotification:(int)newMethod +-(void)setNewArticlesNotification:(NSInteger)newMethod { if (newMethod != newArticlesNotification) { @@ -1197,7 +1149,7 @@ -(void)createFeedSourcesFolderIfNecessary NSError * error = nil; if (![[NSFileManager defaultManager] createDirectoryAtPath:feedSourcesFolder withIntermediateDirectories:YES attributes:nil error:&error]) { - NSLog(@"Could not create feed sources folder at path '%@'. Error: %@", feedSourcesFolder, [error localizedDescription]); + NSLog(@"Could not create feed sources folder at path '%@'. Error: %@", feedSourcesFolder, error.localizedDescription); } } else if (!isDirectory) @@ -1223,7 +1175,7 @@ -(void)setSendSystemSpecs:(BOOL)flag if (flag != sendSystemSpecs) { sendSystemSpecs = flag; - [[SUUpdater sharedUpdater] setSendsSystemProfile:flag]; + [SUUpdater sharedUpdater].sendsSystemProfile = flag; [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_PreferenceChange" object:nil]; } } @@ -1276,8 +1228,6 @@ -(void)setSyncServer:(NSString *)newServer { if (![syncServer isEqualToString:newServer]) { - [newServer retain]; - [syncServer release]; syncServer = newServer; [self setString:syncServer forKey:MAPref_SyncServer]; [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_SyncGoogleReaderChange" object:nil]; @@ -1296,8 +1246,6 @@ -(void)setSyncingUser:(NSString *)newUser { if (![syncingUser isEqualToString:newUser]) { - [newUser retain]; - [syncingUser release]; syncingUser = newUser; [self setString:syncingUser forKey:MAPref_SyncingUser]; [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_SyncGoogleReaderChange" object:nil]; diff --git a/src/Preferences/AdvancedPreferencesViewController.m b/src/Preferences/AdvancedPreferencesViewController.m index c476c079fe..b2910a5bdc 100644 --- a/src/Preferences/AdvancedPreferencesViewController.m +++ b/src/Preferences/AdvancedPreferencesViewController.m @@ -65,7 +65,8 @@ - (NSString *)toolbarItemLabel */ -(IBAction)showAdvancedHelp:(id)sender { - GotoHelpPage((CFStringRef)@"advanced.html", NULL); + NSString *helpBook = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleHelpBookName"]; + [[NSHelpManager sharedHelpManager] openHelpAnchor:@"AdvancedSettingsSection" inBook:helpBook]; } @@ -77,9 +78,9 @@ -(void)initializePreferences Preferences * prefs = [Preferences standardPreferences]; // Show use JavaScript option - [useJavaScriptButton setState:[prefs useJavaScript] ? NSOnState : NSOffState]; - [useWebPluginsButton setState:[prefs useWebPlugins] ? NSOnState : NSOffState]; - [concurrentDownloads selectItemWithTitle:[NSString stringWithFormat:@"%ld",[prefs concurrentDownloads]]]; + useJavaScriptButton.state = prefs.useJavaScript ? NSOnState : NSOffState; + useWebPluginsButton.state = prefs.useWebPlugins ? NSOnState : NSOffState; + [concurrentDownloads selectItemWithTitle:[NSString stringWithFormat:@"%lu",(unsigned long)prefs.concurrentDownloads]]; } /* changeUseJavaScript @@ -88,7 +89,7 @@ -(void)initializePreferences -(IBAction)changeUseJavaScript:(id)sender { BOOL useJavaScript = [sender state] == NSOnState; - [[Preferences standardPreferences] setUseJavaScript:useJavaScript]; + [Preferences standardPreferences].useJavaScript = useJavaScript; } /* changeUseWebPlugins @@ -96,12 +97,12 @@ -(IBAction)changeUseJavaScript:(id)sender * e.g. Flash */ - (IBAction)changeUseWebPlugins:(NSButton *)sender { - BOOL useWebPlugins = [sender state] == NSOnState; - [[Preferences standardPreferences] setUseWebPlugins:useWebPlugins]; + BOOL useWebPlugins = sender.state == NSOnState; + [Preferences standardPreferences].useWebPlugins = useWebPlugins; } -(IBAction)changeConcurrentDownloads:(id)sender { - [[Preferences standardPreferences] setConcurrentDownloads:[[concurrentDownloads titleOfSelectedItem] integerValue]]; + [Preferences standardPreferences].concurrentDownloads = concurrentDownloads.titleOfSelectedItem.integerValue; } @end diff --git a/src/Preferences/AppearancePreferencesViewController.m b/src/Preferences/AppearancePreferencesViewController.m index d016c7b76c..07ab6dfe26 100644 --- a/src/Preferences/AppearancePreferencesViewController.m +++ b/src/Preferences/AppearancePreferencesViewController.m @@ -25,18 +25,18 @@ // List of available font sizes. I picked the ones that matched // Mail but you easily could add or remove from the list as needed. -int availableFontSizes[] = { 6, 8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 32, 48, 64 }; +NSInteger availableFontSizes[] = { 6, 8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 32, 48, 64 }; #define countOfAvailableFontSizes (sizeof(availableFontSizes)/sizeof(availableFontSizes[0])) // List of minimum font sizes. I picked the ones that matched the same option in // Safari but you easily could add or remove from the list as needed. -int availableMinimumFontSizes[] = { 9, 10, 11, 12, 14, 18, 24 }; +NSInteger availableMinimumFontSizes[] = { 9, 10, 11, 12, 14, 18, 24 }; #define countOfAvailableMinimumFontSizes (sizeof(availableMinimumFontSizes)/sizeof(availableMinimumFontSizes[0])) @interface AppearancePreferencesViewController () -(void)initializePreferences; --(void)selectUserDefaultFont:(NSString *)name size:(int)size control:(NSTextField *)control; +-(void)selectUserDefaultFont:(NSString *)name size:(NSInteger)size control:(NSTextField *)control; @end @@ -44,7 +44,16 @@ @implementation AppearancePreferencesViewController - (instancetype)init { - return [super initWithNibName:@"AppearancePreferencesView" bundle:nil]; + if ((self = [super initWithNibName:@"AppearancePreferencesView" bundle:nil]) != nil) + { + // Set up to be notified if preferences change outside this window + NSNotificationCenter * nc = [NSNotificationCenter defaultCenter]; + [nc addObserver:self selector:@selector(handleReloadPreferences:) name:@"MA_Notify_FolderFontChange" object:nil]; + [nc addObserver:self selector:@selector(handleReloadPreferences:) name:@"MA_Notify_ArticleListFontChange" object:nil]; + [nc addObserver:self selector:@selector(handleReloadPreferences:) name:kMA_Notify_MinimumFontSizeChange object:nil]; + [nc addObserver:self selector:@selector(handleReloadPreferences:) name:@"MA_Notify_PreferenceChange" object:nil]; + } + return self; } @@ -55,12 +64,6 @@ - (void)viewWillAppear { // Do view setup here. [self initializePreferences]; - // Set up to be notified if preferences change outside this window - NSNotificationCenter * nc = [NSNotificationCenter defaultCenter]; - [nc addObserver:self selector:@selector(handleReloadPreferences:) name:@"MA_Notify_FolderFontChange" object:nil]; - [nc addObserver:self selector:@selector(handleReloadPreferences:) name:@"MA_Notify_ArticleListFontChange" object:nil]; - [nc addObserver:self selector:@selector(handleReloadPreferences:) name:kMA_Notify_MinimumFontSizeChange object:nil]; - [nc addObserver:self selector:@selector(handleReloadPreferences:) name:@"MA_Notify_PreferenceChange" object:nil]; } @@ -99,21 +102,21 @@ -(void)initializePreferences Preferences * prefs = [Preferences standardPreferences]; // Populate the drop downs with the font names and sizes - [self selectUserDefaultFont:[prefs articleListFont] size:[prefs articleListFontSize] control:articleFontSample]; - [self selectUserDefaultFont:[prefs folderListFont] size:[prefs folderListFontSize] control:folderFontSample]; + [self selectUserDefaultFont:prefs.articleListFont size:prefs.articleListFontSize control:articleFontSample]; + [self selectUserDefaultFont:prefs.folderListFont size:prefs.folderListFontSize control:folderFontSample]; // Show folder images option - [showFolderImagesButton setState:[prefs showFolderImages] ? NSOnState : NSOffState]; + showFolderImagesButton.state = prefs.showFolderImages ? NSOnState : NSOffState; // Set minimum font size option - [enableMinimumFontSize setState:[prefs enableMinimumFontSize] ? NSOnState : NSOffState]; - [minimumFontSizes setEnabled:[prefs enableMinimumFontSize]]; + enableMinimumFontSize.state = prefs.enableMinimumFontSize ? NSOnState : NSOffState; + minimumFontSizes.enabled = prefs.enableMinimumFontSize; NSUInteger i; [minimumFontSizes removeAllItems]; for (i = 0; i < countOfAvailableMinimumFontSizes; ++i) - [minimumFontSizes addItemWithObjectValue:[NSNumber numberWithInt:availableMinimumFontSizes[i]]]; - [minimumFontSizes setFloatValue:[prefs minimumFontSize]]; + [minimumFontSizes addItemWithObjectValue:@(availableMinimumFontSizes[i])]; + minimumFontSizes.doubleValue = prefs.minimumFontSize; } /* changeShowFolderImages @@ -122,7 +125,7 @@ -(void)initializePreferences -(IBAction)changeShowFolderImages:(id)sender { BOOL showFolderImages = [sender state] == NSOnState; - [[Preferences standardPreferences] setShowFolderImages:showFolderImages]; + [Preferences standardPreferences].showFolderImages = showFolderImages; } /* changeMinimumFontSize @@ -131,8 +134,8 @@ -(IBAction)changeShowFolderImages:(id)sender -(IBAction)changeMinimumFontSize:(id)sender { BOOL useMinimumFontSize = [sender state] == NSOnState; - [[Preferences standardPreferences] setEnableMinimumFontSize:useMinimumFontSize]; - [minimumFontSizes setEnabled:useMinimumFontSize]; + [Preferences standardPreferences].enableMinimumFontSize = useMinimumFontSize; + minimumFontSizes.enabled = useMinimumFontSize; } /* selectMinimumFontSize @@ -140,17 +143,17 @@ -(IBAction)changeMinimumFontSize:(id)sender */ -(IBAction)selectMinimumFontSize:(id)sender { - float newMinimumFontSize = [minimumFontSizes floatValue]; - [[Preferences standardPreferences] setMinimumFontSize:newMinimumFontSize]; + CGFloat newMinimumFontSize = minimumFontSizes.doubleValue; + [Preferences standardPreferences].minimumFontSize = newMinimumFontSize; } /* selectUserDefaultFont * Display sample text in the specified font and size. */ --(void)selectUserDefaultFont:(NSString *)name size:(int)size control:(NSTextField *)control +-(void)selectUserDefaultFont:(NSString *)name size:(NSInteger)size control:(NSTextField *)control { - [control setFont:[NSFont fontWithName:name size:size]]; - [control setStringValue:[NSString stringWithFormat:@"%@ %i", name, size]]; + control.font = [NSFont fontWithName:name size:size]; + control.stringValue = [NSString stringWithFormat:@"%@ %li", name, (long)size]; } /* selectArticleFont @@ -159,11 +162,14 @@ -(void)selectUserDefaultFont:(NSString *)name size:(int)size control:(NSTextFiel -(IBAction)selectArticleFont:(id)sender { Preferences * prefs = [Preferences standardPreferences]; - NSFontManager * manager = [NSFontManager sharedFontManager]; - [manager setSelectedFont:[NSFont fontWithName:[prefs articleListFont] size:[prefs articleListFontSize]] isMultiple:NO]; - [manager setAction:@selector(changeArticleFont:)]; - [manager setDelegate:self]; - [manager orderFrontFontPanel:self]; + NSFontManager * fontManager = NSFontManager.sharedFontManager; + fontManager.target = self; + fontManager.action = @selector(changeArticleFont:); + + NSFontPanel *fontPanel = [fontManager fontPanel:YES]; + [fontPanel setPanelFont:[NSFont fontWithName:prefs.articleListFont size:prefs.articleListFontSize] isMultiple:NO]; + [fontPanel orderFront:self]; + fontPanel.enabled = YES; } /* selectFolderFont @@ -172,11 +178,14 @@ -(IBAction)selectArticleFont:(id)sender -(IBAction)selectFolderFont:(id)sender { Preferences * prefs = [Preferences standardPreferences]; - NSFontManager * manager = [NSFontManager sharedFontManager]; - [manager setSelectedFont:[NSFont fontWithName:[prefs folderListFont] size:[prefs folderListFontSize]] isMultiple:NO]; - [manager setAction:@selector(changeFolderFont:)]; - [manager setDelegate:self]; - [manager orderFrontFontPanel:self]; + NSFontManager * fontManager = NSFontManager.sharedFontManager; + fontManager.target = self; + fontManager.action = @selector(changeFolderFont:); + + NSFontPanel *fontPanel = [fontManager fontPanel:YES]; + [fontPanel setPanelFont:[NSFont fontWithName:prefs.folderListFont size:prefs.folderListFontSize] isMultiple:NO]; + [fontPanel orderFront:self]; + fontPanel.enabled = YES; } /* changeArticleFont @@ -185,11 +194,11 @@ -(IBAction)selectFolderFont:(id)sender -(IBAction)changeArticleFont:(id)sender { Preferences * prefs = [Preferences standardPreferences]; - NSFont * font = [NSFont fontWithName:[prefs articleListFont] size:[prefs articleListFontSize]]; + NSFont * font = [NSFont fontWithName:prefs.articleListFont size:prefs.articleListFontSize]; font = [sender convertFont:font]; - [prefs setArticleListFont:[font fontName]]; - [prefs setArticleListFontSize:[font pointSize]]; - [self selectUserDefaultFont:[prefs articleListFont] size:[prefs articleListFontSize] control:articleFontSample]; + prefs.articleListFont = font.fontName; + prefs.articleListFontSize = font.pointSize; + [self selectUserDefaultFont:prefs.articleListFont size:prefs.articleListFontSize control:articleFontSample]; } /* changeFolderFont @@ -198,11 +207,11 @@ -(IBAction)changeArticleFont:(id)sender -(IBAction)changeFolderFont:(id)sender { Preferences * prefs = [Preferences standardPreferences]; - NSFont * font = [NSFont fontWithName:[prefs folderListFont] size:[prefs folderListFontSize]]; + NSFont * font = [NSFont fontWithName:prefs.folderListFont size:prefs.folderListFontSize]; font = [sender convertFont:font]; - [prefs setFolderListFont:[font fontName]]; - [prefs setFolderListFontSize:[font pointSize]]; - [self selectUserDefaultFont:[prefs folderListFont] size:[prefs folderListFontSize] control:folderFontSample]; + prefs.folderListFont = font.fontName; + prefs.folderListFontSize = font.pointSize; + [self selectUserDefaultFont:prefs.folderListFont size:prefs.folderListFontSize control:folderFontSample]; } /* dealloc @@ -211,6 +220,5 @@ -(IBAction)changeFolderFont:(id)sender -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - [super dealloc]; } @end diff --git a/src/Preferences/GeneralPreferencesViewController.m b/src/Preferences/GeneralPreferencesViewController.m index 45e01ed876..323cec50d3 100644 --- a/src/Preferences/GeneralPreferencesViewController.m +++ b/src/Preferences/GeneralPreferencesViewController.m @@ -39,7 +39,15 @@ @implementation GeneralPreferencesViewController - (instancetype)init { - return [super initWithNibName:@"GeneralPreferencesView" bundle:nil]; + if ((self = [super initWithNibName:@"GeneralPreferencesView" bundle:nil]) != nil) + { + // Set up to be notified if preferences change outside this window + NSNotificationCenter * nc = [NSNotificationCenter defaultCenter]; + [nc addObserver:self selector:@selector(handleReloadPreferences:) name:@"MA_Notify_CheckFrequencyChange" object:nil]; + [nc addObserver:self selector:@selector(handleReloadPreferences:) name:@"MA_Notify_PreferenceChange" object:nil]; + appToPathMap = [[NSMutableDictionary alloc] init]; + } + return self; } @@ -50,10 +58,6 @@ - (void)viewWillAppear { [self initializePreferences]; - // Set up to be notified if preferences change outside this window - NSNotificationCenter * nc = [NSNotificationCenter defaultCenter]; - [nc addObserver:self selector:@selector(handleReloadPreferences:) name:@"MA_Notify_CheckFrequencyChange" object:nil]; - [nc addObserver:self selector:@selector(handleReloadPreferences:) name:@"MA_Notify_PreferenceChange" object:nil]; } @@ -91,19 +95,19 @@ -(void)initializePreferences Preferences * prefs = [Preferences standardPreferences]; // Set the check frequency - [checkFrequency selectItemAtIndex:[checkFrequency indexOfItemWithTag:[prefs refreshFrequency]]]; + [checkFrequency selectItemAtIndex:[checkFrequency indexOfItemWithTag:prefs.refreshFrequency]]; // Set check for updates when starting - [checkForUpdates setState:[prefs checkForNewOnStartup] ? NSOnState : NSOffState]; + checkForUpdates.state = prefs.checkForNewOnStartup ? NSOnState : NSOffState; // Set sending system specs when checking for updates - [sendSystemSpecs setState:[prefs sendSystemSpecs] ? NSOnState : NSOffState]; + sendSystemSpecs.state = prefs.sendSystemSpecs ? NSOnState : NSOffState; // Set search for latest Beta versions when checking for updates - [alwaysAcceptBetas setState:[prefs alwaysAcceptBetas] ? NSOnState : NSOffState]; + alwaysAcceptBetas.state = prefs.alwaysAcceptBetas ? NSOnState : NSOffState; // Set check for new articles when starting - [checkOnStartUp setState:[prefs refreshOnStartup] ? NSOnState : NSOffState]; + checkOnStartUp.state = prefs.refreshOnStartup ? NSOnState : NSOffState; // Set range of auto-expire values [expireDuration removeAllItems]; @@ -115,30 +119,30 @@ -(void)initializePreferences [expireDuration insertItemWithTag:NSLocalizedString(@"After a Month", nil) tag:1000 atIndex:5]; // Set auto-expire duration - [expireDuration selectItemAtIndex:[expireDuration indexOfItemWithTag:[prefs autoExpireDuration]]]; + [expireDuration selectItemAtIndex:[expireDuration indexOfItemWithTag:prefs.autoExpireDuration]]; // Set download folder - [self updateDownloadsPopUp:[prefs downloadFolder]]; + [self updateDownloadsPopUp:prefs.downloadFolder]; // Set whether the application is shown in the menu bar - [showAppInMenuBar setState:[prefs showAppInStatusBar] ? NSOnState : NSOffState]; + showAppInMenuBar.state = prefs.showAppInStatusBar ? NSOnState : NSOffState; // Set whether links are opened in the background - [openLinksInBackground setState:[prefs openLinksInBackground] ? NSOnState : NSOffState]; + openLinksInBackground.state = prefs.openLinksInBackground ? NSOnState : NSOffState; // Set whether links are opened in the external browser - [openLinksInExternalBrowser setState:[prefs openLinksInVienna] ? NSOffState : NSOnState]; + openLinksInExternalBrowser.state = prefs.openLinksInVienna ? NSOffState : NSOnState; // Set mark read behaviour - [markReadAfterNext setState:[prefs markReadInterval] == 0 ? NSOnState : NSOffState]; - [markReadAfterDelay setState:[prefs markReadInterval] != 0 ? NSOnState : NSOffState]; + markReadAfterNext.state = prefs.markReadInterval == 0 ? NSOnState : NSOffState; + markReadAfterDelay.state = prefs.markReadInterval != 0 ? NSOnState : NSOffState; // Show new articles notification options - [newArticlesNotificationBadgeButton setState:(([prefs newArticlesNotification] & MA_NewArticlesNotification_Badge) !=0) ? NSOnState : NSOffState]; - [newArticlesNotificationBounceButton setState:(([prefs newArticlesNotification] & MA_NewArticlesNotification_Bounce) !=0) ? NSOnState : NSOffState]; + newArticlesNotificationBadgeButton.state = ((prefs.newArticlesNotification & MA_NewArticlesNotification_Badge) !=0) ? NSOnState : NSOffState; + newArticlesNotificationBounceButton.state = ((prefs.newArticlesNotification & MA_NewArticlesNotification_Bounce) !=0) ? NSOnState : NSOffState; // Set whether updated articles are considered as new - [markUpdatedAsNew setState:[prefs markUpdatedAsNew] ? NSOnState : NSOffState]; + markUpdatedAsNew.state = prefs.markUpdatedAsNew ? NSOnState : NSOffState; [self refreshLinkHandler]; } @@ -150,55 +154,56 @@ -(void)initializePreferences -(void)refreshLinkHandler { NSBundle * appBundle = [NSBundle mainBundle]; - NSString * ourAppName = [[[appBundle executablePath] lastPathComponent] stringByDeletingPathExtension]; + NSString * ourAppName = [[NSFileManager defaultManager] displayNameAtPath:appBundle.bundlePath]; BOOL onTheList = NO; NSURL * testURL = [NSURL URLWithString:@"feed://www.test.com"]; NSString * registeredAppURL = nil; - CFURLRef appURL = nil; // Clear all existing items [linksHandler removeAllItems]; // Add the current registered link handler to the start of the list as Safari does. If // there's no current registered handler, default to ourself. - if (LSGetApplicationForURL((CFURLRef)testURL, kLSRolesAll, NULL, &appURL) != kLSApplicationNotFoundErr) - registeredAppURL = [(NSURL *)appURL path]; + CFStringRef defaultBundleIdentifier = LSCopyDefaultHandlerForURLScheme((__bridge CFStringRef)@"feed"); + if (defaultBundleIdentifier != NULL) + { + registeredAppURL = [[NSWorkspace sharedWorkspace] URLForApplicationWithBundleIdentifier:(__bridge NSString *)defaultBundleIdentifier].path; + CFRelease(defaultBundleIdentifier); + } else { - registeredAppURL = [appBundle executablePath]; + registeredAppURL = appBundle.executablePath; onTheList = YES; } - NSString * regAppName = [[registeredAppURL lastPathComponent] stringByDeletingPathExtension]; - [linksHandler addItemWithTitle:regAppName image:[[NSWorkspace sharedWorkspace] iconForFile:registeredAppURL]]; - [linksHandler addSeparator]; - + NSString * regAppName = [[NSFileManager defaultManager] displayNameAtPath:registeredAppURL]; // Maintain a table to map from the short name to the file URL for when // the user changes selection and we later need the file URL to register // the new selection. - [appToPathMap setValue:registeredAppURL forKey:regAppName]; - - if (appURL != nil) - CFRelease(appURL); - + if (regAppName != nil) { + [linksHandler addItemWithTitle:regAppName image:[[NSWorkspace sharedWorkspace] iconForFile:registeredAppURL]]; + [linksHandler addSeparator]; + [appToPathMap setValue:registeredAppURL forKey:regAppName]; + } + // Next, add the list of all registered link handlers under the /Applications folder // except for the registered application. - CFArrayRef cfArrayOfApps = LSCopyApplicationURLsForURL((CFURLRef)testURL, kLSRolesAll); + CFArrayRef cfArrayOfApps = LSCopyApplicationURLsForURL((__bridge CFURLRef)testURL, kLSRolesAll); if (cfArrayOfApps != nil) { CFIndex count = CFArrayGetCount(cfArrayOfApps); - int index; + NSInteger index; for (index = 0; index < count; ++index) { NSURL * appURL = (NSURL *)CFArrayGetValueAtIndex(cfArrayOfApps, index); - if ([appURL isFileURL] && [[appURL path] hasPrefix:@"/Applications/"]) + if (appURL.fileURL && [appURL.path hasPrefix:@"/Applications/"]) { - NSString * appName = [[[appURL path] lastPathComponent] stringByDeletingPathExtension]; + NSString * appName = [[NSFileManager defaultManager] displayNameAtPath:appURL.path]; if ([appName isEqualToString:ourAppName]) onTheList = YES; - if (![appName isEqualToString:regAppName]) - [linksHandler addItemWithTitle:appName image:[[NSWorkspace sharedWorkspace] iconForFile:[appURL path]]]; + if (appName != nil && ![appName isEqualToString:regAppName]) + [linksHandler addItemWithTitle:appName image:[[NSWorkspace sharedWorkspace] iconForFile:appURL.path]]; [appToPathMap setValue:appURL forKey:appName]; } @@ -210,11 +215,10 @@ -(void)refreshLinkHandler // complete with our icon. if (!onTheList) { - [linksHandler addItemWithTitle:ourAppName image:[[NSWorkspace sharedWorkspace] iconForFile:[appBundle bundlePath]]]; + [linksHandler addItemWithTitle:ourAppName image:[[NSWorkspace sharedWorkspace] iconForFile:appBundle.bundlePath]]; - NSURL * fileURL = [[NSURL alloc] initFileURLWithPath:[appBundle bundlePath]]; + NSURL * fileURL = [[NSURL alloc] initFileURLWithPath:appBundle.bundlePath]; [appToPathMap setValue:fileURL forKey:ourAppName]; - [fileURL release]; } // Add a Select command so the user can manually pick a registered @@ -231,9 +235,9 @@ -(void)refreshLinkHandler */ -(IBAction)changeExpireDuration:(id)sender { - NSMenuItem * selectedItem = [expireDuration selectedItem]; + NSMenuItem * selectedItem = expireDuration.selectedItem; if (selectedItem != nil) - [[Preferences standardPreferences] setAutoExpireDuration:[selectedItem tag]]; + [Preferences standardPreferences].autoExpireDuration = selectedItem.tag; } /* changeOpenLinksInBackground @@ -242,7 +246,7 @@ -(IBAction)changeExpireDuration:(id)sender */ -(IBAction)changeOpenLinksInBackground:(id)sender { - [[Preferences standardPreferences] setOpenLinksInBackground:[sender state] == NSOnState]; + [Preferences standardPreferences].openLinksInBackground = [sender state] == NSOnState; } /* changeShowAppInMenuBar @@ -250,7 +254,7 @@ -(IBAction)changeOpenLinksInBackground:(id)sender */ -(IBAction)changeShowAppInMenuBar:(id)sender { - [[Preferences standardPreferences] setShowAppInStatusBar:[sender state] == NSOnState]; + [Preferences standardPreferences].showAppInStatusBar = [sender state] == NSOnState; } /* changeMarkUpdatedAsNew @@ -259,7 +263,7 @@ -(IBAction)changeShowAppInMenuBar:(id)sender */ -(IBAction)changeMarkUpdatedAsNew:(id)sender { - [[Preferences standardPreferences] setMarkUpdatedAsNew:[sender state] == NSOnState]; + [Preferences standardPreferences].markUpdatedAsNew = [sender state] == NSOnState; } /* changeOpenLinksInExternalBrowser @@ -268,7 +272,7 @@ -(IBAction)changeMarkUpdatedAsNew:(id)sender */ -(IBAction)changeOpenLinksInExternalBrowser:(id)sender { - [[Preferences standardPreferences] setOpenLinksInVienna:[sender state] == NSOffState]; + [Preferences standardPreferences].openLinksInVienna = [sender state] == NSOffState; } /* changeDownloadFolder @@ -277,12 +281,12 @@ -(IBAction)changeOpenLinksInExternalBrowser:(id)sender -(IBAction)changeDownloadFolder:(id)sender { NSOpenPanel * openPanel = [NSOpenPanel openPanel]; - NSWindow * prefPaneWindow = [downloadFolder window]; + NSWindow * prefPaneWindow = downloadFolder.window; [openPanel setCanChooseDirectories:YES]; [openPanel setCanCreateDirectories:YES]; [openPanel setCanChooseFiles:NO]; - [openPanel setDirectoryURL:[[NSFileManager defaultManager] URLForDirectory:NSDownloadsDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nil]]; + openPanel.directoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDownloadsDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nil]; [openPanel beginSheetModalForWindow:prefPaneWindow completionHandler:^(NSInteger returnCode) { // Force the focus back to the main preferences pane [openPanel orderOut:self]; @@ -290,8 +294,8 @@ -(IBAction)changeDownloadFolder:(id)sender if (returnCode == NSOKButton) { - NSString * downloadFolderPath = [[openPanel directoryURL] path]; - [[Preferences standardPreferences] setDownloadFolder:downloadFolderPath]; + NSString * downloadFolderPath = openPanel.directoryURL.path; + [Preferences standardPreferences].downloadFolder = downloadFolderPath; [self updateDownloadsPopUp:downloadFolderPath]; } @@ -308,11 +312,11 @@ -(void)updateDownloadsPopUp:(NSString *)downloadFolderPath NSMenuItem * downloadPathItem = [downloadFolder itemAtIndex:0]; NSImage * pathImage = [[NSWorkspace sharedWorkspace] iconForFile:downloadFolderPath]; - [pathImage setSize:NSMakeSize(16, 16)]; + pathImage.size = NSMakeSize(16, 16); - [downloadPathItem setTitle:[downloadFolderPath lastPathComponent]]; - [downloadPathItem setImage:pathImage]; - [downloadPathItem setState:NSOffState]; + downloadPathItem.title = [[NSFileManager defaultManager] displayNameAtPath:downloadFolderPath]; + downloadPathItem.image = pathImage; + downloadPathItem.state = NSOffState; [downloadFolder selectItemAtIndex:0]; } @@ -322,7 +326,7 @@ -(void)updateDownloadsPopUp:(NSString *)downloadFolderPath */ -(IBAction)changeCheckForUpdates:(id)sender { - [[Preferences standardPreferences] setCheckForNewOnStartup:[sender state] == NSOnState]; + [Preferences standardPreferences].checkForNewOnStartup = [sender state] == NSOnState; } /* changeCheckOnStartUp @@ -330,7 +334,7 @@ -(IBAction)changeCheckForUpdates:(id)sender */ -(IBAction)changeCheckOnStartUp:(id)sender { - [[Preferences standardPreferences] setRefreshOnStartup:[sender state] == NSOnState]; + [Preferences standardPreferences].refreshOnStartup = [sender state] == NSOnState; } /* selectDefaultLinksHandler @@ -338,16 +342,16 @@ -(IBAction)changeCheckOnStartUp:(id)sender */ -(IBAction)selectDefaultLinksHandler:(id)sender { - NSMenuItem * selectedItem = [linksHandler selectedItem]; + NSMenuItem * selectedItem = linksHandler.selectedItem; if (selectedItem != nil) { - if ([selectedItem tag] == -1) + if (selectedItem.tag == -1) { [self handleLinkSelector:self]; return; } } - [self setDefaultLinksHandler:[appToPathMap valueForKey:[selectedItem title]]]; + [self setDefaultLinksHandler:[appToPathMap valueForKey:selectedItem.title]]; [self refreshLinkHandler]; } @@ -359,17 +363,17 @@ -(IBAction)selectDefaultLinksHandler:(id)sender -(IBAction)handleLinkSelector:(id)sender { NSOpenPanel * panel = [NSOpenPanel openPanel]; - NSWindow * prefPaneWindow = [linksHandler window]; + NSWindow * prefPaneWindow = linksHandler.window; - [panel setDirectoryURL:[[NSFileManager defaultManager] URLForDirectory:NSApplicationDirectory inDomain:NSLocalDomainMask appropriateForURL:nil create:NO error:nil]]; - [panel setAllowedFileTypes:[NSArray arrayWithObjects:NSFileTypeForHFSTypeCode('APPL'), nil]]; + panel.directoryURL = [[NSFileManager defaultManager] URLForDirectory:NSApplicationDirectory inDomain:NSLocalDomainMask appropriateForURL:nil create:NO error:nil]; + panel.allowedFileTypes = @[NSFileTypeForHFSTypeCode('APPL')]; [panel beginSheetModalForWindow:prefPaneWindow completionHandler:^(NSInteger returnCode) { [panel orderOut:self]; - NSWindow * prefPaneWindow = [linksHandler window]; + NSWindow * prefPaneWindow = linksHandler.window; [prefPaneWindow makeKeyAndOrderFront:self]; if (returnCode == NSOKButton) - [self setDefaultLinksHandler:[panel URL]]; + [self setDefaultLinksHandler:panel.URL]; [self refreshLinkHandler]; }]; } @@ -380,8 +384,8 @@ -(IBAction)handleLinkSelector:(id)sender -(void)setDefaultLinksHandler:(NSURL *)fileURLToNewHandler { NSBundle * appBundle = [NSBundle bundleWithURL:fileURLToNewHandler]; - NSDictionary * fileAttributes = [appBundle infoDictionary]; - CFStringRef bundleIdentifier = (__bridge CFStringRef)[fileAttributes objectForKey:@"CFBundleIdentifier"]; + NSDictionary * fileAttributes = appBundle.infoDictionary; + CFStringRef bundleIdentifier = (__bridge CFStringRef)fileAttributes[@"CFBundleIdentifier"]; CFStringRef scheme = (__bridge CFStringRef)@"feed"; LSSetDefaultHandlerForURLScheme(scheme, bundleIdentifier); } @@ -392,8 +396,8 @@ -(void)setDefaultLinksHandler:(NSURL *)fileURLToNewHandler */ -(IBAction)changeCheckFrequency:(id)sender { - int newFrequency = [[checkFrequency selectedItem] tag]; - [[Preferences standardPreferences] setRefreshFrequency:newFrequency]; + NSInteger newFrequency = checkFrequency.selectedItem.tag; + [Preferences standardPreferences].refreshFrequency = newFrequency; } /* changeNewArticlesNotificationBadge @@ -402,14 +406,14 @@ -(IBAction)changeCheckFrequency:(id)sender -(IBAction)changeNewArticlesNotificationBadge:(id)sender { Preferences * prefs = [Preferences standardPreferences]; - int currentNotificationValue = [prefs newArticlesNotification]; + NSInteger currentNotificationValue = prefs.newArticlesNotification; if ([sender state] == NSOnState) { - [prefs setNewArticlesNotification:currentNotificationValue | MA_NewArticlesNotification_Badge]; + prefs.newArticlesNotification = currentNotificationValue | MA_NewArticlesNotification_Badge; } else { - [prefs setNewArticlesNotification:currentNotificationValue & ~MA_NewArticlesNotification_Badge]; + prefs.newArticlesNotification = currentNotificationValue & ~MA_NewArticlesNotification_Badge; } } @@ -419,14 +423,14 @@ -(IBAction)changeNewArticlesNotificationBadge:(id)sender -(IBAction)changeNewArticlesNotificationBounce:(id)sender { Preferences * prefs = [Preferences standardPreferences]; - int currentNotificationValue = [prefs newArticlesNotification]; + NSInteger currentNotificationValue = prefs.newArticlesNotification; if ([sender state] == NSOnState) { - [prefs setNewArticlesNotification:currentNotificationValue | MA_NewArticlesNotification_Bounce]; + prefs.newArticlesNotification = currentNotificationValue | MA_NewArticlesNotification_Bounce; } else { - [prefs setNewArticlesNotification:currentNotificationValue & ~MA_NewArticlesNotification_Bounce]; + prefs.newArticlesNotification = currentNotificationValue & ~MA_NewArticlesNotification_Bounce; } } @@ -436,7 +440,7 @@ -(IBAction)changeNewArticlesNotificationBounce:(id)sender -(IBAction)changeMarkReadBehaviour:(id)sender { float newReadInterval = ([sender selectedCell] == markReadAfterNext) ? 0 : MA_Default_Read_Interval; - [[Preferences standardPreferences] setMarkReadInterval:newReadInterval]; + [Preferences standardPreferences].markReadInterval = newReadInterval; } @@ -445,7 +449,7 @@ -(IBAction)changeMarkReadBehaviour:(id)sender */ -(IBAction)changeSendSystemSpecs:(id)sender { - [[Preferences standardPreferences] setSendSystemSpecs:[sender state] == NSOnState]; + [Preferences standardPreferences].sendSystemSpecs = [sender state] == NSOnState; } /* changeAlwaysAcceptBetas @@ -453,7 +457,7 @@ -(IBAction)changeSendSystemSpecs:(id)sender */ -(IBAction)changeAlwaysAcceptBetas:(id)sender { - [[Preferences standardPreferences] setAlwaysAcceptBetas:[sender state] == NSOnState]; + [Preferences standardPreferences].alwaysAcceptBetas = [sender state] == NSOnState; } /* dealloc @@ -461,10 +465,7 @@ -(IBAction)changeAlwaysAcceptBetas:(id)sender */ -(void)dealloc { - [appToPathMap release]; - appToPathMap=nil; [[NSNotificationCenter defaultCenter] removeObserver:self]; - [super dealloc]; } @end diff --git a/src/Preferences/PreferencesWindowController.h b/src/Preferences/PreferencesWindowController.h new file mode 100644 index 0000000000..ec6e40ac1f --- /dev/null +++ b/src/Preferences/PreferencesWindowController.h @@ -0,0 +1,26 @@ +// +// PreferencesWindowController.h +// Vienna +// +// Copyright 2017 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import Cocoa; + +#import "MASPreferencesWindowController.h" + +@interface PreferencesWindowController : MASPreferencesWindowController + +@end diff --git a/src/Preferences/PreferencesWindowController.m b/src/Preferences/PreferencesWindowController.m new file mode 100644 index 0000000000..6e3e31ae96 --- /dev/null +++ b/src/Preferences/PreferencesWindowController.m @@ -0,0 +1,44 @@ +// +// PreferencesWindowController.m +// Vienna +// +// Copyright 2017 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "PreferencesWindowController.h" + +#import "GeneralPreferencesViewController.h" +#import "AppearancePreferencesViewController.h" +#import "SyncingPreferencesViewController.h" +#import "AdvancedPreferencesViewController.h" + +@implementation PreferencesWindowController + +/* + This initializer is called by -initWithWindow. + */ +- (instancetype)init { + NSViewController *general = [GeneralPreferencesViewController new]; + NSViewController *appearance = [AppearancePreferencesViewController new]; + NSViewController *syncing = [SyncingPreferencesViewController new]; + NSViewController *advanced = [AdvancedPreferencesViewController new]; + + NSArray *controllers = @[general, appearance, syncing, advanced]; + NSString *title = NSLocalizedString(@"Preferences", @"Title of the Preferences window"); + + return [self initWithViewControllers:controllers title:title]; +} + +@end diff --git a/src/Preferences/SyncingPreferencesViewController.h b/src/Preferences/SyncingPreferencesViewController.h index dce4682887..832400227f 100644 --- a/src/Preferences/SyncingPreferencesViewController.h +++ b/src/Preferences/SyncingPreferencesViewController.h @@ -27,10 +27,10 @@ IBOutlet NSTextField * openReaderHost; IBOutlet NSTextField * username; IBOutlet NSSecureTextField * password; - IBOutlet NSButton *syncButton; + IBOutlet NSButton *__weak syncButton; } -@property (assign) IBOutlet NSButton *syncButton; +@property (weak) IBOutlet NSButton *syncButton; -(IBAction)changeSyncOpenReader:(id)sender; -(IBAction)changeSource:(id)sender; diff --git a/src/Preferences/SyncingPreferencesViewController.m b/src/Preferences/SyncingPreferencesViewController.m index f2a5926e26..8357b5b9f1 100644 --- a/src/Preferences/SyncingPreferencesViewController.m +++ b/src/Preferences/SyncingPreferencesViewController.m @@ -35,7 +35,16 @@ @implementation SyncingPreferencesViewController - (instancetype)init { - return [super initWithNibName:@"SyncingPreferencesView" bundle:nil]; + if ((self = [super initWithNibName:@"SyncingPreferencesView" bundle:nil]) != nil) + { + // Set up to be notified if preferences change outside this window + NSNotificationCenter * nc = [NSNotificationCenter defaultCenter]; + [nc addObserver:self selector:@selector(handleGoogleAuthFailed:) name:@"MA_Notify_GoogleAuthFailed" object:nil]; + [nc addObserver:self selector:@selector(handleServerTextDidChange:) name:NSControlTextDidChangeNotification object:openReaderHost]; + [nc addObserver:self selector:@selector(handleUserTextDidChange:) name:NSControlTextDidChangeNotification object:username]; + [nc addObserver:self selector:@selector(handlePasswordTextDidChange:) name:NSControlTextDidEndEditingNotification object:password]; + } + return self; } - (void)viewWillAppear { @@ -44,30 +53,24 @@ - (void)viewWillAppear { } // Do view setup here. sourcesDict = nil; - // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. - NSNotificationCenter * nc = [NSNotificationCenter defaultCenter]; - [nc addObserver:self selector:@selector(handleGoogleAuthFailed:) name:@"MA_Notify_GoogleAuthFailed" object:nil]; - [nc addObserver:self selector:@selector(handleServerTextDidChange:) name:NSControlTextDidChangeNotification object:openReaderHost]; - [nc addObserver:self selector:@selector(handleUserTextDidChange:) name:NSControlTextDidChangeNotification object:username]; - [nc addObserver:self selector:@selector(handlePasswordTextDidChange:) name:NSControlTextDidEndEditingNotification object:password]; // restore from Preferences and from keychain Preferences * prefs = [Preferences standardPreferences]; - [syncButton setState:[prefs syncGoogleReader] ? NSOnState : NSOffState]; - NSString * theUsername = [prefs syncingUser]; + syncButton.state = prefs.syncGoogleReader ? NSOnState : NSOffState; + NSString * theUsername = prefs.syncingUser; if (!theUsername) theUsername=@""; - NSString * theHost = [prefs syncServer]; + NSString * theHost = prefs.syncServer; if (!theHost) theHost=@""; NSString * thePassword = [KeyChain getGenericPasswordFromKeychain:theUsername serviceName:@"Vienna sync"]; if (!thePassword) thePassword=@""; - [username setStringValue:theUsername]; - [openReaderHost setStringValue:theHost]; - [password setStringValue:thePassword]; + username.stringValue = theUsername; + openReaderHost.stringValue = theHost; + password.stringValue = thePassword; - if(![prefs syncGoogleReader]) + if(!prefs.syncGoogleReader) { [openReaderSource setEnabled:NO]; [openReaderHost setEnabled:NO]; @@ -86,7 +89,7 @@ - (void)viewWillAppear { NSString * pathToPList = [thisBundle pathForResource:@"KnownSyncServers" ofType:@"plist"]; if (pathToPList != nil) { - sourcesDict = [[NSDictionary dictionaryWithContentsOfFile:pathToPList] retain]; + sourcesDict = [NSDictionary dictionaryWithContentsOfFile:pathToPList]; [openReaderSource removeAllItems]; if (sourcesDict) { @@ -106,7 +109,7 @@ - (void)viewWillAppear { if (!match) { [openReaderSource selectItemWithTitle:NSLocalizedString(@"Other", nil)]; - [openReaderHost setStringValue:theHost]; + openReaderHost.stringValue = theHost; } } } @@ -140,7 +143,7 @@ - (NSString *)toolbarItemLabel -(void)windowWillClose:(NSNotification *)notification { [[NSNotificationCenter defaultCenter] removeObserver:self]; - if([syncButton state] == NSOnState && _credentialsChanged) + if(syncButton.state == NSOnState && _credentialsChanged) { [[GoogleReader sharedManager] resetAuthentication]; [[GoogleReader sharedManager] loadSubscriptions:nil]; @@ -153,7 +156,7 @@ -(IBAction)changeSyncOpenReader:(id)sender // enable/disable syncing BOOL sync = [sender state] == NSOnState; Preferences *prefs = [Preferences standardPreferences]; - [prefs setSyncGoogleReader:sync]; + prefs.syncGoogleReader = sync; [prefs savePreferences]; if (sync) { [openReaderSource setEnabled:YES]; @@ -173,8 +176,8 @@ -(IBAction)changeSyncOpenReader:(id)sender -(IBAction)changeSource:(id)sender; { - NSMenuItem * readerItem = [openReaderSource selectedItem]; - NSString * key = [readerItem title]; + NSMenuItem * readerItem = openReaderSource.selectedItem; + NSString * key = readerItem.title; NSDictionary * itemDict = [sourcesDict valueForKey:key]; NSString* hostName = [itemDict valueForKey:@"Address"]; if (!hostName) @@ -182,15 +185,15 @@ -(IBAction)changeSource:(id)sender; NSString* hint = [itemDict valueForKey:@"Hint"]; if (!hint) hint=@""; - [openReaderHost setStringValue:hostName]; - [credentialsInfoText setStringValue:hint]; + openReaderHost.stringValue = hostName; + credentialsInfoText.stringValue = hint; if (sender != nil) //user action [self handleServerTextDidChange:nil]; } - (IBAction)visitWebsite:(id)sender { - NSURL * url = [NSURL URLWithString:[NSString stringWithFormat:@"https://%@/", [openReaderHost stringValue]]]; + NSURL * url = [NSURL URLWithString:[NSString stringWithFormat:@"https://%@/", openReaderHost.stringValue]]; [[NSWorkspace sharedWorkspace] openURL:url]; } @@ -203,17 +206,17 @@ -(void)handleServerTextDidChange:(NSNotification *)aNotification { _credentialsChanged = YES; Preferences *prefs = [Preferences standardPreferences]; - if ( !([[openReaderHost stringValue] isBlank] || [[username stringValue] isBlank]) ) + if ( !((openReaderHost.stringValue).blank || (username.stringValue).blank) ) { // can we get password via keychain ? - NSString * thePass = [KeyChain getWebPasswordFromKeychain:[username stringValue] url:[NSString stringWithFormat:@"https://%@", [openReaderHost stringValue]]]; - if (![thePass isBlank]) + NSString * thePass = [KeyChain getWebPasswordFromKeychain:username.stringValue url:[NSString stringWithFormat:@"https://%@", openReaderHost.stringValue]]; + if (!thePass.blank) { - [password setStringValue:thePass]; - [KeyChain setGenericPasswordInKeychain:[password stringValue] username:[username stringValue] service:@"Vienna sync"]; + password.stringValue = thePass; + [KeyChain setGenericPasswordInKeychain:password.stringValue username:username.stringValue service:@"Vienna sync"]; } } - [prefs setSyncServer:[openReaderHost stringValue]]; + prefs.syncServer = openReaderHost.stringValue; [prefs savePreferences]; } @@ -226,18 +229,18 @@ -(void)handleUserTextDidChange:(NSNotification *)aNotification { _credentialsChanged = YES; Preferences *prefs = [Preferences standardPreferences]; - [KeyChain deleteGenericPasswordInKeychain:[prefs syncingUser] service:@"Vienna sync"]; - if ( !([[openReaderHost stringValue] isBlank] || [[username stringValue] isBlank]) ) + [KeyChain deleteGenericPasswordInKeychain:prefs.syncingUser service:@"Vienna sync"]; + if ( !((openReaderHost.stringValue).blank || (username.stringValue).blank) ) { // can we get password via keychain ? - NSString * thePass = [KeyChain getWebPasswordFromKeychain:[username stringValue] url:[NSString stringWithFormat:@"https://%@", [openReaderHost stringValue]]]; - if (![thePass isBlank]) + NSString * thePass = [KeyChain getWebPasswordFromKeychain:username.stringValue url:[NSString stringWithFormat:@"https://%@", openReaderHost.stringValue]]; + if (!thePass.blank) { - [password setStringValue:thePass]; - [KeyChain setGenericPasswordInKeychain:[password stringValue] username:[username stringValue] service:@"Vienna sync"]; + password.stringValue = thePass; + [KeyChain setGenericPasswordInKeychain:password.stringValue username:username.stringValue service:@"Vienna sync"]; } } - [prefs setSyncingUser:[username stringValue]]; + prefs.syncingUser = username.stringValue; [prefs savePreferences]; } @@ -249,18 +252,18 @@ -(void)handleUserTextDidChange:(NSNotification *)aNotification -(void)handlePasswordTextDidChange:(NSNotification *)aNotification { _credentialsChanged = YES; - [KeyChain setGenericPasswordInKeychain:[password stringValue] username:[username stringValue] service:@"Vienna sync"]; + [KeyChain setGenericPasswordInKeychain:password.stringValue username:username.stringValue service:@"Vienna sync"]; } -(void)handleGoogleAuthFailed:(NSNotification *)nc { - if ([self.view.window isVisible]) + if ((self.view.window).visible) { - NSAlert *alert = [[[NSAlert alloc] init] autorelease]; + NSAlert *alert = [[NSAlert alloc] init]; [alert addButtonWithTitle:@"OK"]; [alert setMessageText:NSLocalizedString(@"Open Reader Authentication Failed",nil)]; [alert setInformativeText:NSLocalizedString(@"Open Reader Authentication Failed text",nil)]; - [alert setAlertStyle:NSWarningAlertStyle]; + alert.alertStyle = NSWarningAlertStyle; [alert beginSheetModalForWindow:self.view.window modalDelegate:self didEndSelector:nil contextInfo:nil]; [[GoogleReader sharedManager] clearAuthentication]; } @@ -268,11 +271,9 @@ -(void)handleGoogleAuthFailed:(NSNotification *)nc -(void)dealloc { - [syncButton release]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; syncButton=nil; - [sourcesDict release]; sourcesDict=nil; - [super dealloc]; } diff --git a/src/ProgressTextCell.m b/src/ProgressTextCell.m index 0826829c8d..707e23b4b6 100644 --- a/src/ProgressTextCell.m +++ b/src/ProgressTextCell.m @@ -37,7 +37,7 @@ @implementation ProgressTextCell /* init * Initialise a default instance of our cell. */ --(id)init +-(instancetype)init { if ((self = [super init]) != nil) { @@ -93,8 +93,8 @@ - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView // Allocate and initialize the spinning progress indicator. NSRect progressRect = NSMakeRect(0, 0, PROGRESS_INDICATOR_DIMENSION, PROGRESS_INDICATOR_DIMENSION); progressIndicator = [[NSProgressIndicator alloc] initWithFrame:progressRect]; - [progressIndicator setControlSize:NSSmallControlSize]; - [progressIndicator setStyle:NSProgressIndicatorSpinningStyle]; + progressIndicator.controlSize = NSSmallControlSize; + progressIndicator.style = NSProgressIndicatorSpinningStyle; [progressIndicator setDisplayedWhenStopped:YES]; [progressIndicator setUsesThreadedAnimation:YES]; } @@ -116,23 +116,22 @@ - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView // Add the progress indicator as a subview of the controlView if // it is not already one. - if ([progressIndicator superview] != controlView) + if (progressIndicator.superview != controlView) [controlView addSubview:progressIndicator]; // Set the progress indicator frame. - if (!NSEqualRects([progressIndicator frame], progressIndicatorFrame)) - [progressIndicator setFrame:progressIndicatorFrame]; + if (!NSEqualRects(progressIndicator.frame, progressIndicatorFrame)) + progressIndicator.frame = progressIndicatorFrame; } else { // Stop the animation and remove from the superview. [progressIndicator setDisplayedWhenStopped:NO]; [progressIndicator stopAnimation:self]; - [[progressIndicator superview] setNeedsDisplayInRect:[progressIndicator frame]]; + [progressIndicator.superview setNeedsDisplayInRect:progressIndicator.frame]; [progressIndicator removeFromSuperviewWithoutNeedingDisplay]; // Release the progress indicator. - [progressIndicator release]; progressIndicator = nil; } } diff --git a/src/RefreshManager.h b/src/RefreshManager.h index 15c5ae8a15..44b1d27e94 100644 --- a/src/RefreshManager.h +++ b/src/RefreshManager.h @@ -50,19 +50,19 @@ -(void)refreshSubscriptionsAfterMerge:(NSArray *)foldersArray ignoringSubscriptionStatus:(BOOL)ignoreSubStatus; -(void)forceRefreshSubscriptionForFolders:(NSArray*)foldersArray; -(void)cancelAll; --(BOOL)isConnecting; --(NSUInteger)countOfNewArticles; --(NSString *)statusMessageDuringRefresh; --(void)refreshFavIcon:(Folder *)folder; +@property (nonatomic, getter=isConnecting, readonly) BOOL connecting; +@property (nonatomic, readonly) NSUInteger countOfNewArticles; +@property (nonatomic, readonly, copy) NSString *statusMessageDuringRefresh; +-(void)refreshFavIconForFolder:(Folder *)folder; -(void)addConnection:(ASIHTTPRequest *)conn; --(dispatch_queue_t)asyncQueue; +@property (nonatomic, readonly, strong) dispatch_queue_t asyncQueue; @end // Refresh types -typedef enum { +typedef NS_ENUM(int, RefreshTypes) { MA_Refresh_NilType = -1, MA_Refresh_Feed, MA_Refresh_FavIcon, MA_Refresh_GoogleFeed, MA_ForceRefresh_Google_Feed -} RefreshTypes; +}; diff --git a/src/RefreshManager.m b/src/RefreshManager.m index aac93d69bb..24e38d29bf 100644 --- a/src/RefreshManager.m +++ b/src/RefreshManager.m @@ -21,7 +21,6 @@ #import "RefreshManager.h" #import "FeedCredentials.h" #import "ActivityLog.h" -#import "FoldersTree.h" #import "RichXMLParser.h" #import "StringExtensions.h" #import "Preferences.h" @@ -33,14 +32,12 @@ #import "ASIHTTPRequest.h" #import "NSNotificationAdditions.h" #import "VTPG_Common.h" - -// Singleton -static RefreshManager * _refreshManager = nil; +#import "FeedItem.h" +#import // Private functions @interface RefreshManager (Private) -(BOOL)isRefreshingFolder:(Folder *)folder ofType:(RefreshTypes)type; --(void)refreshFavIcon:(Folder *)folder; -(void)getCredentialsForFolder; -(void)setFolderErrorFlag:(Folder *)folder flag:(BOOL)theFlag; -(void)setFolderUpdatingFlag:(Folder *)folder flag:(BOOL)theFlag; @@ -67,7 +64,7 @@ + (void)initialize /* init * Initialise the class. */ --(id)init +-(instancetype)init { if ((self = [super init]) != nil) { @@ -78,10 +75,10 @@ -(id)init networkQueue = [[ASINetworkQueue alloc] init]; [networkQueue setShouldCancelAllRequestsOnFailure:NO]; networkQueue.delegate = self; - [networkQueue setRequestDidFinishSelector:@selector(nqRequestFinished:)]; - [networkQueue setRequestDidStartSelector:@selector(nqRequestStarted:)]; - [networkQueue setQueueDidFinishSelector:@selector(nqQueueDidFinishSelector:)]; - [networkQueue setMaxConcurrentOperationCount:[[Preferences standardPreferences] integerForKey:MAPref_ConcurrentDownloads]]; + networkQueue.requestDidFinishSelector = @selector(nqRequestFinished:); + networkQueue.requestDidStartSelector = @selector(nqRequestStarted:); + networkQueue.queueDidFinishSelector = @selector(nqQueueDidFinishSelector:); + networkQueue.maxConcurrentOperationCount = [[Preferences standardPreferences] integerForKey:MAPref_ConcurrentDownloads]; NSNotificationCenter * nc = [NSNotificationCenter defaultCenter]; [nc addObserver:self selector:@selector(handleGotAuthenticationForFolder:) name:@"MA_Notify_GotAuthenticationForFolder" object:nil]; @@ -89,7 +86,7 @@ -(id)init [nc addObserver:self selector:@selector(handleWillDeleteFolder:) name:@"MA_Notify_WillDeleteFolder" object:nil]; [nc addObserver:self selector:@selector(handleChangeConcurrentDownloads:) name:@"MA_Notify_CowncurrentDownloadsChange" object:nil]; // be notified on system wake up after sleep - [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(handleDidWake:) name:@"NSWorkspaceDidWakeNotification" object:nil]; + [[NSWorkspace sharedWorkspace].notificationCenter addObserver:self selector:@selector(handleDidWake:) name:@"NSWorkspaceDidWakeNotification" object:nil]; _queue = dispatch_queue_create("uk.co.opencommunity.vienna2.refresh", NULL); hasStarted = NO; } @@ -101,32 +98,27 @@ -(dispatch_queue_t)asyncQueue { } - (void)nqQueueDidFinishSelector:(ASIHTTPRequest *)request { - [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_ArticleListStateChange" object:nil]; if (hasStarted) { - [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_RefreshStatus" object:nil]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_RefreshStatus" object:nil]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_ArticleListContentChange" object:nil]; hasStarted = NO; } + else + { + [APPCONTROLLER setStatusMessage:nil persist:YES]; + } LLog(@"Queue empty!!!"); } - (void)nqRequestFinished:(ASIHTTPRequest *)request { - statusMessageDuringRefresh = [NSString stringWithFormat:@"%@: (%i) - %@",NSLocalizedString(@"Queue",nil),[networkQueue requestsCount],NSLocalizedString(@"Refreshing subscriptions...", nil)]; - [APPCONTROLLER setStatusMessage:[self statusMessageDuringRefresh] persist:YES]; - LLog(@"Removed queue: %d", [networkQueue requestsCount]); + statusMessageDuringRefresh = [NSString stringWithFormat:@"%@: (%i) - %@",NSLocalizedString(@"Queue",nil),networkQueue.requestsCount,NSLocalizedString(@"Refreshing subscriptions...", nil)]; + [APPCONTROLLER setStatusMessage:self.statusMessageDuringRefresh persist:YES]; } - (void)nqRequestStarted:(ASIHTTPRequest *)request { - if (!hasStarted) - { - hasStarted = YES; - [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_RefreshStatus" object:nil]; - } - - statusMessageDuringRefresh = [NSString stringWithFormat:@"%@: (%i) - %@",NSLocalizedString(@"Queue",nil),[networkQueue requestsCount],NSLocalizedString(@"Refreshing subscriptions...", nil)]; - [APPCONTROLLER setStatusMessage:[self statusMessageDuringRefresh] persist:YES]; - LLog(@"Added queue: %d", [networkQueue requestsCount]); - + statusMessageDuringRefresh = [NSString stringWithFormat:@"%@: (%i) - %@",NSLocalizedString(@"Queue",nil),networkQueue.requestsCount,NSLocalizedString(@"Refreshing subscriptions...", nil)]; + [APPCONTROLLER setStatusMessage:self.statusMessageDuringRefresh persist:YES]; } @@ -135,15 +127,19 @@ - (void)nqRequestStarted:(ASIHTTPRequest *)request { */ +(RefreshManager *)sharedManager { - if (!_refreshManager) + // Singleton + static RefreshManager * _refreshManager = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ _refreshManager = [[RefreshManager alloc] init]; + }); return _refreshManager; } -(void)handleChangeConcurrentDownloads:(NSNotification *)nc { NSLog(@"Handling new downloads count"); - [networkQueue setMaxConcurrentOperationCount:[[Preferences standardPreferences] integerForKey:MAPref_ConcurrentDownloads]]; + networkQueue.maxConcurrentOperationCount = [[Preferences standardPreferences] integerForKey:MAPref_ConcurrentDownloads]; } /* handleWillDeleteFolder @@ -155,11 +151,11 @@ -(void)handleChangeConcurrentDownloads:(NSNotification *)nc */ -(void)handleWillDeleteFolder:(NSNotification *)nc { - Folder * folder = [[Database sharedDatabase] folderFromID:[[nc object] intValue]]; + Folder * folder = [[Database sharedManager] folderFromID:[nc.object integerValue]]; if (folder != nil) { - for (ASIHTTPRequest *theRequest in [networkQueue operations]) { - if ([[theRequest userInfo] objectForKey:@"folder"] == folder) { + for (ASIHTTPRequest *theRequest in networkQueue.operations) { + if (theRequest.userInfo[@"folder"] == folder) { [self removeConnection:theRequest]; break; } @@ -170,7 +166,7 @@ -(void)handleWillDeleteFolder:(NSNotification *)nc -(void)handleDidWake:(NSNotification *)nc { - NSString * currentAddress = [[NSHost currentHost] address] ; + NSString * currentAddress = [NSHost currentHost].address ; if (![currentAddress isEqualToString:riskyIPAddress]) { // we might have moved to a new network @@ -188,7 +184,7 @@ -(void)forceRefreshSubscriptionForFolders:(NSArray*)foldersArray for (Folder * folder in foldersArray) { if (IsGroupFolder(folder)) - [self forceRefreshSubscriptionForFolders:[[Database sharedDatabase] arrayOfFolders:[folder itemId]]]; + [self forceRefreshSubscriptionForFolders:[[Database sharedManager] arrayOfFolders:folder.itemId]]; else if (IsGoogleReaderFolder(folder)) { if (![self isRefreshingFolder:folder ofType:MA_Refresh_GoogleFeed] && ![self isRefreshingFolder:folder ofType:MA_ForceRefresh_Google_Feed]) @@ -207,7 +203,7 @@ -(void)refreshSubscriptions:(NSArray *)foldersArray ignoringSubscriptionStatus:( for (Folder * folder in foldersArray) { if (IsGroupFolder(folder)) - [self refreshSubscriptions:[[Database sharedDatabase] arrayOfFolders:[folder itemId]] ignoringSubscriptionStatus:NO]; + [self refreshSubscriptions:[[Database sharedManager] arrayOfFolders:folder.itemId] ignoringSubscriptionStatus:NO]; else if (IsRSSFolder(folder) || IsGoogleReaderFolder(folder)) { if (!IsUnsubscribed(folder) || ignoreSubStatus) @@ -247,22 +243,11 @@ -(void)refreshSubscriptionsAfterRefresh:(NSArray *)foldersArray ignoringSubscrip [self refreshSubscriptions:foldersArray ignoringSubscriptionStatus:ignoreSubStatus]; } -- (void)addRSSFoldersIn:(Folder *)folder toArray:(NSMutableArray *)array -{ - if (IsRSSFolder(folder) || IsGoogleReaderFolder(folder)) [array addObject:folder]; - else - { - Database * db = [Database sharedDatabase]; - for (Folder * f in [db arrayOfFolders:[folder itemId]]) - [self addRSSFoldersIn:f toArray:array]; - } -} - -(void)refreshSubscriptionsAfterRefreshAll:(NSArray *)foldersArray ignoringSubscriptionStatus:(BOOL)ignoreSubStatus { syncType = MA_Sync_Refresh_All; - if ([[Preferences standardPreferences] syncGoogleReader]) [[GoogleReader sharedManager] loadSubscriptions:nil]; + if ([Preferences standardPreferences].syncGoogleReader) [[GoogleReader sharedManager] loadSubscriptions:nil]; [self refreshSubscriptions:foldersArray ignoringSubscriptionStatus:ignoreSubStatus]; } @@ -277,35 +262,37 @@ -(void)refreshFolderIconCacheForSubscriptions:(NSArray *)foldersArray for (Folder * folder in foldersArray) { if (IsGroupFolder(folder)) - [self refreshFolderIconCacheForSubscriptions:[[Database sharedDatabase] arrayOfFolders:[folder itemId]]]; + [self refreshFolderIconCacheForSubscriptions:[[Database sharedManager] arrayOfFolders:folder.itemId]]; else if (IsRSSFolder(folder) || IsGoogleReaderFolder(folder)) { - dispatch_async(dispatch_get_main_queue(), ^{ - [self refreshFavIcon:folder]; - }); + [self refreshFavIconForFolder:folder]; } } } -/* refreshFavIcon +/* refreshFavIconForFolder * Adds the specified folder to the refresh queue. */ --(void)refreshFavIcon:(Folder *)folder +/** + * Refreshes the favicon for the specified folder + * + * @param folder The folder object to refresh the favicon for + */ +-(void)refreshFavIconForFolder:(Folder *)folder { // Do nothing if there's no homepage associated with the feed // or if the feed already has a favicon. - if ((IsRSSFolder(folder)||IsGoogleReaderFolder(folder)) && ([folder homePage] == nil || [[folder homePage] isBlank] || [folder hasCachedImage])) + if ((IsRSSFolder(folder)||IsGoogleReaderFolder(folder)) && + (folder.homePage == nil || folder.homePage.blank || folder.hasCachedImage)) { - Database *db = [Database sharedDatabase]; - [db doTransactionWithBlock:^(BOOL *rollback) { - [db clearFolderFlag:[folder itemId] flagToClear:MA_FFlag_CheckForImage]; - }]; //end transaction block + [[Database sharedManager] clearFlag:MA_FFlag_CheckForImage forFolder:folder.itemId]; return; } - if (![self isRefreshingFolder:folder ofType:MA_Refresh_FavIcon]) + if (![self isRefreshingFolder:folder ofType:MA_Refresh_FavIcon]) { [self pumpFolderIconRefresh:folder]; + } } @@ -315,9 +302,9 @@ -(void)refreshFavIcon:(Folder *)folder */ -(BOOL)isRefreshingFolder:(Folder *)folder ofType:(RefreshTypes)type { - for (ASIHTTPRequest *theRequest in [networkQueue operations]) + for (ASIHTTPRequest *theRequest in networkQueue.operations) { - if (([[theRequest userInfo] objectForKey:@"folder"] == folder) && ([[[theRequest userInfo] valueForKey:@"type"] intValue] == [[NSNumber numberWithInt:type] intValue])) + if ((theRequest.userInfo[@"folder"] == folder) && ([[theRequest.userInfo valueForKey:@"type"] integerValue] == @(type).integerValue)) return YES; } @@ -359,10 +346,10 @@ -(void)getCredentialsForFolder // Pull next folder out of the queue. The UI will post a // notification when it is done and we can move on to the // next one. - if ([authQueue count] > 0 && ![[credentialsController window] isVisible]) + if (authQueue.count > 0 && !credentialsController.window.visible) { - Folder * folder = [authQueue objectAtIndex:0]; - [credentialsController credentialsForFolder:[NSApp mainWindow] folder:folder]; + Folder * folder = authQueue[0]; + [credentialsController credentialsForFolder:NSApp.mainWindow folder:folder]; } } @@ -372,7 +359,7 @@ -(void)getCredentialsForFolder */ -(void)handleRequireAuthenticationForFolder:(NSNotification *)nc { - Folder * folder = (Folder *)[nc object]; + Folder * folder = (Folder *)nc.object; if (![authQueue containsObject:folder]) [authQueue addObject:folder]; [self getCredentialsForFolder]; @@ -384,7 +371,7 @@ -(void)handleRequireAuthenticationForFolder:(NSNotification *)nc */ -(void)handleCancelAuthenticationForFolder:(NSNotification *)nc { - Folder * folder = (Folder *)[nc object]; + Folder * folder = (Folder *)nc.object; [authQueue removeObject:folder]; // Get the next one in the queue, if any @@ -398,10 +385,10 @@ -(void)handleCancelAuthenticationForFolder:(NSNotification *)nc */ -(void)handleGotAuthenticationForFolder:(NSNotification *)nc { - Folder * folder = (Folder *)[nc object]; - [[Database sharedDatabase] clearFolderFlag:[folder itemId] flagToClear:MA_FFlag_NeedCredentials]; + Folder * folder = (Folder *)nc.object; + [[Database sharedManager] clearFlag:MA_FFlag_NeedCredentials forFolder:folder.itemId]; [authQueue removeObject:folder]; - [self refreshSubscriptions:[NSArray arrayWithObject:folder] ignoringSubscriptionStatus:YES]; + [self refreshSubscriptions:@[folder] ignoringSubscriptionStatus:YES]; // Get the next one in the queue, if any [self getCredentialsForFolder]; @@ -417,7 +404,7 @@ -(void)setFolderErrorFlag:(Folder *)folder flag:(BOOL)theFlag [folder setNonPersistedFlag:MA_FFlag_Error]; else [folder clearNonPersistedFlag:MA_FFlag_Error]; - [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_FoldersUpdated" object:[NSNumber numberWithInt:[folder itemId]]]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_FoldersUpdated" object:@(folder.itemId)]; } /* setFolderUpdatingFlag @@ -430,7 +417,7 @@ -(void)setFolderUpdatingFlag:(Folder *)folder flag:(BOOL)theFlag [folder setNonPersistedFlag:MA_FFlag_Updating]; else [folder clearNonPersistedFlag:MA_FFlag_Updating]; - [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_FoldersUpdated" object:[NSNumber numberWithInt:[folder itemId]]]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_FoldersUpdated" object:@(folder.itemId)]; } /* pumpSubscriptionRefresh @@ -441,7 +428,7 @@ -(void)pumpSubscriptionRefresh:(Folder *)folder shouldForceRefresh:(BOOL)force { // If this folder needs credentials, add the folder to the list requiring authentication // and since we can't progress without it, skip this folder on the connection - if ([folder flags] & MA_FFlag_NeedCredentials) + if (folder.flags & MA_FFlag_NeedCredentials) { [authQueue addObject:folder]; [self getCredentialsForFolder]; @@ -450,15 +437,15 @@ -(void)pumpSubscriptionRefresh:(Folder *)folder shouldForceRefresh:(BOOL)force // The activity log name we use depends on whether or not this folder has a real name. - NSString * name = [[folder name] isEqualToString:[Database untitledFeedFolderName]] ? [folder feedURL] : [folder name]; + NSString * name = [folder.name isEqualToString:[Database untitledFeedFolderName]] ? folder.feedURL : folder.name; ActivityItem * aItem = [[ActivityLog defaultLog] itemByName:name]; // Compute the URL for this connection - NSString * urlString = [folder feedURL]; + NSString * urlString = folder.feedURL; NSURL * url = nil; if ([urlString hasPrefix:@"file://"]) - url = [NSURL fileURLWithPath:[[urlString substringFromIndex:7] stringByExpandingTildeInPath]]; + url = [NSURL fileURLWithPath:[urlString substringFromIndex:7].stringByExpandingTildeInPath]; else if ([urlString hasPrefix:@"feed://"]) url = [NSURL URLWithString:[NSString stringWithFormat:@"http://%@", [urlString substringFromIndex:7]]]; else @@ -495,32 +482,38 @@ -(void)refreshFeed:(Folder *)folder fromURL:(NSURL *)url withLog:(ActivityItem * if (IsRSSFolder(folder)) { myRequest = [ASIHTTPRequest requestWithURL:url]; - NSString * theLastUpdateString = [folder lastUpdateString]; + NSString * theLastUpdateString = folder.lastUpdateString; if (![theLastUpdateString isEqualToString:@""]) { [myRequest addRequestHeader:@"If-Modified-Since" value:theLastUpdateString]; + [myRequest addRequestHeader:@"A-IM" value:@"feed"]; } - [myRequest setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:folder, @"folder", aItem, @"log", [NSNumber numberWithInt:MA_Refresh_Feed], @"type", nil]]; - if (![[folder username] isEqualToString:@""]) + myRequest.userInfo = @{@"folder": folder, @"log": aItem, @"type": @(MA_Refresh_Feed)}; + if (![folder.username isEqualToString:@""]) { - [myRequest setUsername:[folder username]]; - [myRequest setPassword:[folder password]]; + myRequest.username = folder.username; + myRequest.password = folder.password; [myRequest setUseCookiePersistence:NO]; } - [myRequest setDelegate:self]; - [myRequest setDidFinishSelector:@selector(folderRefreshCompleted:)]; - [myRequest setDidFailSelector:@selector(folderRefreshFailed:)]; - [myRequest setWillRedirectSelector:@selector(folderRefreshRedirect:)]; + myRequest.delegate = self; + myRequest.didFinishSelector = @selector(folderRefreshCompleted:); + myRequest.didFailSelector = @selector(folderRefreshFailed:); + myRequest.willRedirectSelector = @selector(folderRefreshRedirect:); [myRequest addRequestHeader:@"Accept" value:@"application/rss+xml,application/rdf+xml,application/atom+xml,text/xml,application/xml,application/xhtml+xml;q=0.9,text/html;q=0.8,*/*;q=0.5"]; } else { // Open Reader feed myRequest = [[GoogleReader sharedManager] refreshFeed:folder withLog:(ActivityItem *)aItem shouldIgnoreArticleLimit:force]; } - [myRequest setTimeOutSeconds:180]; + myRequest.timeOutSeconds = 180; // hack for handling file:// URLs - if ([url isFileURL]) { + if (url.fileURL) { [self folderRefreshCompleted:myRequest]; } else { [self addConnection:myRequest]; + if (!hasStarted) + { + hasStarted = YES; + [[NSNotificationCenter defaultCenter] postNotificationName:@"MA_Notify_RefreshStatus" object:nil]; + } } } @@ -529,16 +522,16 @@ -(void)refreshFeed:(Folder *)folder fromURL:(NSURL *)url withLog:(ActivityItem * - (void)folderRefreshFailed:(ASIHTTPRequest *)request { LOG_EXPR([request error]); - Folder * folder = (Folder *)[[request userInfo] objectForKey:@"folder"]; - if ([[request error] code] == ASIAuthenticationErrorType) //Error caused by lack of authentication + Folder * folder = (Folder *)request.userInfo[@"folder"]; + if (request.error.code == ASIAuthenticationErrorType) //Error caused by lack of authentication { if (![authQueue containsObject:folder]) [authQueue addObject:folder]; [self getCredentialsForFolder]; } - ActivityItem * aItem = (ActivityItem *)[[request userInfo] objectForKey:@"log"]; + ActivityItem * aItem = (ActivityItem *)request.userInfo[@"log"]; [self setFolderErrorFlag:folder flag:YES]; - [aItem appendDetail:[NSString stringWithFormat:@"%@ %@",NSLocalizedString(@"Error retrieving RSS feed:", nil),[[request error] localizedDescription ]]]; + [aItem appendDetail:[NSString stringWithFormat:@"%@ %@",NSLocalizedString(@"Error retrieving RSS feed:", nil),request.error.localizedDescription ]]; [aItem setStatus:NSLocalizedString(@"Error",nil)]; [self syncFinishedForFolder:folder]; } @@ -549,24 +542,24 @@ - (void)folderRefreshFailed:(ASIHTTPRequest *)request -(void)pumpFolderIconRefresh:(Folder *)folder { // The activity log name we use depends on whether or not this folder has a real name. - NSString * name = [[folder name] isEqualToString:[Database untitledFeedFolderName]] ? [folder feedURL] : [folder name]; + NSString * name = [folder.name isEqualToString:[Database untitledFeedFolderName]] ? folder.feedURL : folder.name; ActivityItem * aItem = [[ActivityLog defaultLog] itemByName:name]; NSString * favIconPath; if (IsRSSFolder(folder)) { [aItem appendDetail:NSLocalizedString(@"Retrieving folder image", nil)]; - favIconPath = [NSString stringWithFormat:@"%@/favicon.ico", [[[folder homePage] trim] baseURL]]; + favIconPath = [NSString stringWithFormat:@"%@/favicon.ico", folder.homePage.trim.baseURL]; } else { // Open Reader feed [aItem appendDetail:NSLocalizedString(@"Retrieving folder image for Open Reader Feed", nil)]; - favIconPath = [NSString stringWithFormat:@"%@/favicon.ico", [[[folder homePage] trim] baseURL]]; + favIconPath = [NSString stringWithFormat:@"%@/favicon.ico", folder.homePage.trim.baseURL]; } ASIHTTPRequest *myRequest = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:favIconPath]]; - [myRequest setDelegate:self]; - [myRequest setDidFinishSelector:@selector(iconRequestDone:)]; - [myRequest setDidFailSelector:@selector(iconRequestFailed:)]; - [myRequest setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:folder, @"folder", aItem, @"log", [NSNumber numberWithInt:MA_Refresh_FavIcon], @"type", nil]]; + myRequest.delegate = self; + myRequest.didFinishSelector = @selector(iconRequestDone:); + myRequest.didFailSelector = @selector(iconRequestFailed:); + myRequest.userInfo = @{@"folder": folder, @"log": aItem, @"type": @(MA_Refresh_FavIcon)}; [self addConnection:myRequest]; } @@ -574,59 +567,51 @@ -(void)pumpFolderIconRefresh:(Folder *)folder // success callback - (void)iconRequestDone:(ASIHTTPRequest *)request { - Folder * folder = (Folder *)[[request userInfo] objectForKey:@"folder"]; - ActivityItem * aItem = [[ActivityLog defaultLog] itemByName:[folder name]]; + Folder * folder = (Folder *)request.userInfo[@"folder"]; + ActivityItem * aItem = [[ActivityLog defaultLog] itemByName:folder.name]; [self setFolderUpdatingFlag:folder flag:NO]; - if ([request responseStatusCode] == 404) { + if (request.responseStatusCode == 404) { [aItem appendDetail:NSLocalizedString(@"RSS Icon not found!", nil)]; - } else if ([request responseStatusCode] == 200) { + } else if (request.responseStatusCode == 200) { NSImage * iconImage = [[NSImage alloc] initWithData:[request responseData]]; - if (iconImage != nil && [iconImage isValid]) + if (iconImage != nil && iconImage.valid) { - [iconImage setSize:NSMakeSize(16, 16)]; - [folder setImage:iconImage]; + iconImage.size = NSMakeSize(16, 16); + folder.image = iconImage; // Broadcast a notification since the folder image has now changed - [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_FoldersUpdated" object:[NSNumber numberWithInt:[folder itemId]]]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_FoldersUpdated" object:@(folder.itemId)]; // Log additional details about this. - [aItem appendDetail:[NSString stringWithFormat:NSLocalizedString(@"Folder image retrieved from %@", nil), [request url]]]; - [aItem appendDetail:[NSString stringWithFormat:NSLocalizedString(@"%ld bytes received", nil), [[request responseData] length]]]; + [aItem appendDetail:[NSString stringWithFormat:NSLocalizedString(@"Folder image retrieved from %@", nil), request.url]]; + [aItem appendDetail:[NSString stringWithFormat:NSLocalizedString(@"%ld bytes received", nil), [request responseData].length]]; } - [iconImage release]; } else { - [aItem appendDetail:[NSString stringWithFormat:NSLocalizedString(@"HTTP code %d reported from server", nil), [request responseStatusCode]]]; + [aItem appendDetail:[NSString stringWithFormat:NSLocalizedString(@"HTTP code %d reported from server", nil), request.responseStatusCode]]; } - Database *db = [Database sharedDatabase]; - [db doTransactionWithBlock:^(BOOL *rollback) { - [db clearFolderFlag:[folder itemId] flagToClear:MA_FFlag_CheckForImage]; - }]; //end transaction block + [[Database sharedManager] clearFlag:MA_FFlag_CheckForImage forFolder:folder.itemId]; + } // failure callback - (void)iconRequestFailed:(ASIHTTPRequest *)request { - Folder * folder = (Folder *)[[request userInfo] objectForKey:@"folder"]; - ActivityItem * aItem = [[ActivityLog defaultLog] itemByName:[folder name]]; - [aItem appendDetail:[NSString stringWithFormat:@"%@ %@",NSLocalizedString(@"Error retrieving RSS Icon:", nil),[[request error] localizedDescription ]]]; - - Database *db = [Database sharedDatabase]; - [db doTransactionWithBlock:^(BOOL *rollback) { - [db clearFolderFlag:[folder itemId] flagToClear:MA_FFlag_CheckForImage]; - }]; //end transaction block + Folder * folder = (Folder *)request.userInfo[@"folder"]; + ActivityItem * aItem = [[ActivityLog defaultLog] itemByName:folder.name]; + [aItem appendDetail:[NSString stringWithFormat:@"%@ %@",NSLocalizedString(@"Error retrieving RSS Icon:", nil),request.error.localizedDescription ]]; + [[Database sharedManager] clearFlag:MA_FFlag_CheckForImage forFolder:folder.itemId]; } - (void)syncFinishedForFolder:(Folder *)folder { [self setFolderUpdatingFlag:folder flag:NO]; - dispatch_async(dispatch_get_main_queue(), ^{ - // Unread count may have changed - AppController *controller = APPCONTROLLER; - [controller setStatusMessage:nil persist:NO]; - [controller showUnreadCountOnApplicationIconAndWindowTitle]; - }); + // Unread count may have changed + AppController *controller = APPCONTROLLER; + [controller setStatusMessage:nil persist:NO]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_FoldersUpdated" + object:@(folder.itemId)]; } /* folderRefreshRedirect @@ -635,24 +620,21 @@ - (void)syncFinishedForFolder:(Folder *)folder -(void)folderRefreshRedirect:(ASIHTTPRequest *)connector { - NSURL *newURL = [NSURL URLWithString:[[connector responseHeaders] valueForKey:@"Location"] relativeToURL:[connector url]]; - int responseStatusCode = [connector responseStatusCode]; + NSURL *newURL = [NSURL URLWithString:[connector.responseHeaders valueForKey:@"Location"] relativeToURL:connector.url]; + NSInteger responseStatusCode = connector.responseStatusCode; if (responseStatusCode == 301) { // We got a permanent redirect from the feed so change the feed URL to the new location. - Folder * folder = (Folder *)[[connector userInfo] objectForKey:@"folder"]; - ActivityItem *connectorItem = [[connector userInfo] objectForKey:@"log"]; - NSInteger folderId = [folder itemId]; - Database * db = [Database sharedDatabase]; + Folder * folder = (Folder *)connector.userInfo[@"folder"]; + ActivityItem *connectorItem = connector.userInfo[@"log"]; - if ([[newURL host] isEqualToString:[[connector originalURL] host]] || [self canTrust301Redirects:connector]) + if ([newURL.host isEqualToString:connector.originalURL.host] || [self canTrust301Redirects:connector]) { - [db doTransactionWithBlock:^(BOOL *rollback) { - [db setFolderFeedURL:folderId newFeedURL:[newURL absoluteString]]; - }]; //end transaction block - - [connectorItem appendDetail:[NSString stringWithFormat:NSLocalizedString(@"Feed URL updated to %@", nil), [newURL absoluteString]]]; + [[Database sharedManager] setFeedURL:newURL.absoluteString + forFolder:folder.itemId]; + + [connectorItem appendDetail:[NSString stringWithFormat:NSLocalizedString(@"Feed URL updated to %@", nil), newURL.absoluteString]]; } else [connectorItem appendDetail:NSLocalizedString(@"Redirection attempt treated as temporary for safety concern", nil)]; @@ -663,22 +645,22 @@ -(void)folderRefreshRedirect:(ASIHTTPRequest *)connector -(BOOL)canTrust301Redirects:(ASIHTTPRequest *)connector { - if (unsafe301RedirectionTimer == nil || ![unsafe301RedirectionTimer isValid]) + if (unsafe301RedirectionTimer == nil || !unsafe301RedirectionTimer.valid) { - NSURL * testURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@://www.example.com", [[connector originalURL] scheme]]]; + NSURL * testURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@://www.example.com", connector.originalURL.scheme]]; ASIHTTPRequest * testRequest = [ASIHTTPRequest requestWithURL:testURL]; [testRequest setUseCookiePersistence:NO]; - [testRequest setTimeOutSeconds:180]; + testRequest.timeOutSeconds = 180; [testRequest startSynchronous]; - if ([testRequest responseStatusCode] == 301 || [testRequest error]) + if (testRequest.responseStatusCode == 301 || testRequest.error) { // there is no valid reason for www.example.com to be permanently redirected // (cf RFC 6761 http://www.iana.org/go/rfc6761) // so we probably have a misconfigured router / proxy // and we will not consider 301 redirections as permanent for 24 hours unsafe301RedirectionTimer = [NSTimer scheduledTimerWithTimeInterval:24*3600 target:self selector:@selector(resetUnsafe301Timer:) userInfo:nil repeats:NO]; - riskyIPAddress = [[NSHost currentHost] address]; + riskyIPAddress = [NSHost currentHost].address; return NO; } else @@ -704,28 +686,30 @@ - (void)resetUnsafe301Timer:(NSTimer *)timer -(void)folderRefreshCompleted:(ASIHTTPRequest *)connector { dispatch_async(_queue, ^() { + [CATransaction begin]; + [CATransaction setDisableActions:YES]; - Folder * folder = (Folder *)[[connector userInfo] objectForKey:@"folder"]; - ActivityItem *connectorItem = [[connector userInfo] objectForKey:@"log"]; - int responseStatusCode = [connector responseStatusCode]; - NSURL *url = [connector url]; - BOOL isCancelled = [connector isCancelled]; - NSInteger folderId = [folder itemId]; - Database * db = [Database sharedDatabase]; + Folder * folder = (Folder *)connector.userInfo[@"folder"]; + ActivityItem *connectorItem = connector.userInfo[@"log"]; + NSInteger responseStatusCode = connector.responseStatusCode; + NSURL *url = connector.url; + BOOL isCancelled = connector.cancelled; + NSInteger folderId = folder.itemId; + Database * dbManager = [Database sharedManager]; // hack for handling file:// URLs - if ([url isFileURL]) + if (url.fileURL) { NSFileManager *fileManager = [NSFileManager defaultManager]; - NSString *filePath = [[url path] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + NSString *filePath = [url.path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; BOOL isDirectory = NO; if ([fileManager fileExistsAtPath:filePath isDirectory:&isDirectory] && !isDirectory) { responseStatusCode = 200; NSData * receivedData = [NSData dataWithContentsOfFile:filePath]; - [connector setRawResponseData:[NSMutableData dataWithContentsOfFile:filePath]]; - [connector setContentLength:[receivedData length]]; - [connector setTotalBytesRead:[receivedData length]]; + connector.rawResponseData = [NSMutableData dataWithContentsOfFile:filePath]; + connector.contentLength = receivedData.length; + connector.totalBytesRead = receivedData.length; } else { responseStatusCode = 404; } @@ -734,14 +718,14 @@ -(void)folderRefreshCompleted:(ASIHTTPRequest *)connector if (responseStatusCode == 304) { // No modification from last check - [db doTransactionWithBlock:^(BOOL *rollback) { - [db setFolderLastUpdate:folderId lastUpdate:[NSDate date]]; - }]; + + [dbManager setLastUpdate:[NSDate date] forFolder:folderId]; [self setFolderErrorFlag:folder flag:NO]; [connectorItem appendDetail:NSLocalizedString(@"Got HTTP status 304 - No news from last check", nil)]; [connectorItem setStatus:NSLocalizedString(@"No new articles available", nil)]; [self syncFinishedForFolder:folder]; + [CATransaction commit]; return; } else if (isCancelled) @@ -751,32 +735,35 @@ -(void)folderRefreshCompleted:(ASIHTTPRequest *)connector // FIX: if we don't check this folder we shouldn't update the lastupdate field // Set the last update date for this folder. - // [db setFolderLastUpdate:folderId lastUpdate:[NSDate date]]; + // [dbManager setFolderLastUpdate:folderId lastUpdate:[NSDate date]]; // If this folder also requires an image refresh, add that - if (([folder flags] & MA_FFlag_CheckForImage)) [self refreshFavIcon:folder]; + if ((folder.flags & MA_FFlag_CheckForImage)) [self refreshFavIconForFolder:folder]; } else if (responseStatusCode == 410) { // We got HTTP 410 which means the feed has been intentionally removed so unsubscribe the feed. - [db doTransactionWithBlock:^(BOOL *rollback) { - [db setFolderFlag:folderId flagToSet:MA_FFlag_Unsubscribed]; - }]; - [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_FoldersUpdated" object:[NSNumber numberWithInt:folderId]]; + [dbManager setFlag:MA_FFlag_Unsubscribed forFolder:folderId]; + + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_FoldersUpdated" + object:@(folderId)]; } - else if (responseStatusCode == 200) + else if (responseStatusCode == 200 || responseStatusCode == 226) { NSData * receivedData = [connector responseData]; - NSString * lastModifiedString = [[connector responseHeaders] valueForKey:@"Last-Modified"]; - - [self finalizeFolderRefresh:[NSDictionary dictionaryWithObjectsAndKeys: - folder, @"folder", - connectorItem, @"log", - url, @"url", - receivedData, @"data", - lastModifiedString, @"lastModifiedString", - nil]]; + NSString * lastModifiedString = SafeString([connector.responseHeaders valueForKey:@"Last-Modified"]); + + if (receivedData != nil) + { + [self finalizeFolderRefresh:@{ + @"folder": folder, + @"log": connectorItem, + @"url": url, + @"data": receivedData, + @"lastModifiedString": lastModifiedString, + }]; + } } else //other HTTP response codes like 404, 403... { @@ -787,6 +774,7 @@ -(void)folderRefreshCompleted:(ASIHTTPRequest *)connector [self syncFinishedForFolder:folder]; + [CATransaction commit]; }); //block for dispatch_async on _queue }; @@ -794,13 +782,13 @@ -(void)finalizeFolderRefresh:(NSDictionary*)parameters; { ZAssert(parameters!=NULL, @"Null"); - Folder * folder = (Folder *)[parameters objectForKey:@"folder"]; - NSInteger folderId = [folder itemId]; - Database * db = [Database sharedDatabase]; - ActivityItem *connectorItem = [parameters objectForKey:@"log"]; - NSURL *url = [parameters objectForKey:@"url"]; - NSData * receivedData = [parameters objectForKey:@"data"]; - NSString * lastModifiedString = [parameters objectForKey:@"lastModifiedString"]; + Folder * folder = (Folder *)parameters[@"folder"]; + NSInteger folderId = folder.itemId; + Database * dbManager = [Database sharedManager]; + ActivityItem *connectorItem = parameters[@"log"]; + NSURL *url = parameters[@"url"]; + NSData * receivedData = parameters[@"data"]; + NSString * lastModifiedString = parameters[@"lastModifiedString"]; // Check whether this is an HTML redirect. If so, create a new connection using // the redirect. @@ -810,10 +798,10 @@ -(void)finalizeFolderRefresh:(NSDictionary*)parameters; if (redirectURL != nil) { - if ([redirectURL isEqualToString:[url absoluteString]]) + if ([redirectURL isEqualToString:url.absoluteString]) { // To prevent an infinite loop, don't redirect to the same URL. - [connectorItem appendDetail:[NSString stringWithFormat:NSLocalizedString(@"Improper infinitely looping URL redirect to %@", nil), [url absoluteString]]]; + [connectorItem appendDetail:[NSString stringWithFormat:NSLocalizedString(@"Improper infinitely looping URL redirect to %@", nil), url.absoluteString]]; } else { @@ -826,12 +814,12 @@ -(void)finalizeFolderRefresh:(NSDictionary*)parameters; // Empty data feed is OK if we got HTTP 200 __block NSUInteger newArticlesFromFeed = 0; RichXMLParser * newFeed = [[RichXMLParser alloc] init]; - if ([receivedData length] > 0) + if (receivedData.length > 0) { Preferences * standardPreferences = [Preferences standardPreferences]; - if ([standardPreferences shouldSaveFeedSource]) + if (standardPreferences.shouldSaveFeedSource) { - NSString * feedSourcePath = [folder feedSourceFilePath]; + NSString * feedSourcePath = folder.feedSourceFilePath; if ([standardPreferences boolForKey:MAPref_ShouldSaveFeedSourceBackup]) { @@ -857,40 +845,47 @@ -(void)finalizeFolderRefresh:(NSDictionary*)parameters; // Mark the feed as failed [self setFolderErrorFlag:folder flag:YES]; [connectorItem setStatus:NSLocalizedString(@"Error parsing XML data in feed", nil)]; - [newFeed release]; return; } // Log number of bytes we received - [connectorItem appendDetail:[NSString stringWithFormat:NSLocalizedString(@"%ld bytes received", nil), [receivedData length]]]; + [connectorItem appendDetail:[NSString stringWithFormat:NSLocalizedString(@"%ld bytes received", nil), receivedData.length]]; + if(newFeed.items.count == 0) + { + // Mark the feed as empty + [self setFolderErrorFlag:folder flag:YES]; + [connectorItem setStatus:NSLocalizedString(@"No articles in feed", nil)]; + return; + } + // Extract the latest title and description - NSString * feedTitle = [newFeed title]; - NSString * feedDescription = [newFeed description]; - NSString * feedLink = [newFeed link]; + NSString * feedTitle = newFeed.title; + NSString * feedDescription = newFeed.description; + NSString * feedLink = newFeed.link; // Synthesize feed link if it is missing - if (feedLink == nil || [feedLink isBlank]) - feedLink = [[folder feedURL] baseURL]; + if (feedLink == nil || feedLink.blank) + feedLink = folder.feedURL.baseURL; if (feedLink != nil && ![feedLink hasPrefix:@"http:"] && ![feedLink hasPrefix:@"https:"]) - feedLink = [[NSURL URLWithString:feedLink relativeToURL:url] absoluteString]; + feedLink = [NSURL URLWithString:feedLink relativeToURL:url].absoluteString; // We'll be collecting articles into this array NSMutableArray * articleArray = [NSMutableArray array]; NSMutableArray * articleGuidArray = [NSMutableArray array]; - NSDate * itemAlternativeDate = [newFeed lastModified]; + NSDate * itemAlternativeDate = newFeed.lastModified; if (itemAlternativeDate == nil) itemAlternativeDate = [NSDate date]; // Parse off items. - for (FeedItem * newsItem in [newFeed items]) + for (FeedItem * newsItem in newFeed.items) { - NSDate * articleDate = [newsItem date]; + NSDate * articleDate = newsItem.date; - NSString * articleGuid = [newsItem guid]; + NSString * articleGuid = newsItem.guid; // This routine attempts to synthesize a GUID from an incomplete item that lacks an // ID field. Generally we'll have three things to work from: a link, a title and a @@ -899,31 +894,31 @@ -(void)finalizeFolderRefresh:(NSDictionary*)parameters; // to be careful since separate articles with different descriptions may have the same // title. The solution is to use the link and title and build a GUID from those. // We add the folderId at the beginning to ensure that items in different feeds do not share a guid. - if ([articleGuid isEqualToString:@""]) - articleGuid = [NSString stringWithFormat:@"%ld-%@-%@", folderId, [newsItem link], [newsItem title]]; - + if ([articleGuid isEqualToString:@""]) { + articleGuid = [NSString stringWithFormat:@"%ld-%@-%@", (long)folderId, newsItem.link, newsItem.title]; + } // This is a horrible hack for horrible feeds that contain more than one item with the same guid. // Bad feeds! I'm talking to you, kerbalstuff.com NSUInteger articleIndex = [articleGuidArray indexOfObject:articleGuid]; if (articleIndex != NSNotFound) { // We rebuild complex guids which should eliminate most duplicates - Article * firstFoundArticle = [articleArray objectAtIndex:articleIndex]; + Article * firstFoundArticle = articleArray[articleIndex]; if (articleDate == nil) { // first, hack the initial article (which is probably the first loaded / most recent one) - NSString * firstFoundArticleNewGuid = [NSString stringWithFormat:@"%ld-%@-%@", (long)folderId, [firstFoundArticle link], [firstFoundArticle title]]; - [firstFoundArticle setGuid:firstFoundArticleNewGuid]; - [articleGuidArray replaceObjectAtIndex:articleIndex withObject:firstFoundArticleNewGuid]; + NSString * firstFoundArticleNewGuid = [NSString stringWithFormat:@"%ld-%@-%@", (long)folderId, firstFoundArticle.link, firstFoundArticle.title]; + firstFoundArticle.guid = firstFoundArticleNewGuid; + articleGuidArray[articleIndex] = firstFoundArticleNewGuid; // then hack the guid for the item being processed - articleGuid = [NSString stringWithFormat:@"%ld-%@-%@", (long)folderId, [newsItem link], [newsItem title]]; + articleGuid = [NSString stringWithFormat:@"%ld-%@-%@", (long)folderId, newsItem.link, newsItem.title]; } else { // first, hack the initial article (which is probably the first loaded / most recent one) - NSString * firstFoundArticleNewGuid = [NSString stringWithFormat:@"%ld-%@-%@-%@", (long)folderId, [NSString stringWithFormat:@"%1.3f", [[firstFoundArticle date] timeIntervalSince1970]], [firstFoundArticle link], [firstFoundArticle title]]; - [firstFoundArticle setGuid:firstFoundArticleNewGuid]; - [articleGuidArray replaceObjectAtIndex:articleIndex withObject:firstFoundArticleNewGuid]; + NSString * firstFoundArticleNewGuid = [NSString stringWithFormat:@"%ld-%@-%@-%@", (long)folderId, [NSString stringWithFormat:@"%1.3f", firstFoundArticle.date.timeIntervalSince1970], firstFoundArticle.link, firstFoundArticle.title]; + firstFoundArticle.guid = firstFoundArticleNewGuid; + articleGuidArray[articleIndex] = firstFoundArticleNewGuid; // then hack the guid for the item being processed - articleGuid = [NSString stringWithFormat:@"%ld-%@-%@-%@", (long)folderId, [NSString stringWithFormat:@"%1.3f", [articleDate timeIntervalSince1970]], [newsItem link], [newsItem title]]; + articleGuid = [NSString stringWithFormat:@"%ld-%@-%@-%@", (long)folderId, [NSString stringWithFormat:@"%1.3f", articleDate.timeIntervalSince1970], newsItem.link, newsItem.title]; } } [articleGuidArray addObject:articleGuid]; @@ -937,22 +932,22 @@ -(void)finalizeFolderRefresh:(NSDictionary*)parameters; itemAlternativeDate = [itemAlternativeDate dateByAddingTimeInterval:-1.0]; } - Article * article = [[[Article alloc] initWithGuid:articleGuid] autorelease]; - [article setFolderId:folderId]; - [article setAuthor:[newsItem author]]; - [article setBody:[newsItem description]]; - [article setTitle:[newsItem title]]; - NSString * articleLink = [newsItem link]; + Article * article = [[Article alloc] initWithGuid:articleGuid]; + article.folderId = folderId; + article.author = newsItem.author; + article.body = newsItem.description; + article.title = newsItem.title; + NSString * articleLink = newsItem.link; if (![articleLink hasPrefix:@"http:"] && ![articleLink hasPrefix:@"https:"]) - articleLink = [[NSURL URLWithString:articleLink relativeToURL:url] absoluteString]; + articleLink = [NSURL URLWithString:articleLink relativeToURL:url].absoluteString; if (articleLink == nil) articleLink = feedLink; - [article setLink:articleLink]; - [article setDate:articleDate]; - NSString * enclosureLink = [newsItem enclosure]; + article.link = articleLink; + article.date = articleDate; + NSString * enclosureLink = newsItem.enclosure; if ([enclosureLink isNotEqualTo:@""] && ![enclosureLink hasPrefix:@"http:"] && ![enclosureLink hasPrefix:@"https:"]) - enclosureLink = [[NSURL URLWithString:enclosureLink relativeToURL:url] absoluteString]; - [article setEnclosure:enclosureLink]; + enclosureLink = [NSURL URLWithString:enclosureLink relativeToURL:url].absoluteString; + article.enclosure = enclosureLink; if ([enclosureLink isNotEqualTo:@""]) { [article setHasEnclosure:YES]; @@ -962,25 +957,21 @@ -(void)finalizeFolderRefresh:(NSDictionary*)parameters; // Here's where we add the articles to the database - if ([articleArray count] > 0u) + if (articleArray.count > 0u) { - // Should we wrap the entire loop or just individual article updates? - [db doTransactionWithBlock:^(BOOL *rollback) { - NSArray * guidHistory = [db guidHistoryForFolderId:folderId]; - [folder clearCache]; + NSArray * guidHistory = [dbManager guidHistoryForFolderId:folderId]; for (Article * article in articleArray) { - if ([db createArticle:folderId article:article guidHistory:guidHistory] && ([article status] == MA_MsgStatus_New)) + if ([folder createArticle:article + guidHistory:guidHistory] && (article.status == ArticleStatusNew)) { ++newArticlesFromFeed; + } } - }]; //end transaction block - } - [db doTransactionWithBlock:^(BOOL *rollback) { // A notify is only needed if we added any new articles. - if ([[folder name] hasPrefix:[Database untitledFeedFolderName]] && ![feedTitle isBlank]) + if (feedTitle != nil && !feedTitle.blank && [folder.name hasPrefix:[Database untitledFeedFolderName]]) { // If there's an existing feed with this title, make ours unique // BUGBUG: This duplicates logic in database.m so consider moving it there. @@ -988,26 +979,26 @@ -(void)finalizeFolderRefresh:(NSDictionary*)parameters; NSString * newFeedTitle = feedTitle; NSUInteger index = 1; - while (([db folderFromName:newFeedTitle]) != nil) - newFeedTitle = [NSString stringWithFormat:@"%@ (%li)", oldFeedTitle, index++]; + while (([dbManager folderFromName:newFeedTitle]) != nil) + newFeedTitle = [NSString stringWithFormat:@"%@ (%lu)", oldFeedTitle, (unsigned long)index++]; - [connectorItem setName:newFeedTitle]; - [db setFolderName:folderId newName:newFeedTitle]; + connectorItem.name = newFeedTitle; + [dbManager setName:newFeedTitle forFolder:folderId]; } - if (feedDescription != nil) - [db setFolderDescription:folderId newDescription:feedDescription]; - - if (feedLink!= nil) - [db setFolderHomePage:folderId newHomePage:feedLink]; + if (feedDescription != nil) { + [dbManager setDescription:feedDescription forFolder:folderId]; + } + if (feedLink!= nil) { + [dbManager setHomePage:feedLink forFolder:folderId]; + } // Remember the last modified date - if (lastModifiedString != nil) - [db setFolderLastUpdateString:folderId lastUpdateString:lastModifiedString]; - + if (lastModifiedString != nil && lastModifiedString.length > 0) { + [dbManager setLastUpdateString:lastModifiedString forFolder:folderId]; + } // Set the last update date for this folder. - [db setFolderLastUpdate:folderId lastUpdate:[NSDate date]]; + [dbManager setLastUpdate:[NSDate date] forFolder:folderId]; - }]; //end transaction block // Mark the feed as succeeded [self setFolderErrorFlag:folder flag:NO]; @@ -1015,24 +1006,25 @@ -(void)finalizeFolderRefresh:(NSDictionary*)parameters; }; // Send status to the activity log - if (newArticlesFromFeed == 0) - [connectorItem setStatus:NSLocalizedString(@"No new articles available", nil)]; + if (newArticlesFromFeed == 0) { + [connectorItem setStatus:NSLocalizedString(@"No new articles available", nil)]; + } else { NSString * logText = [NSString stringWithFormat:NSLocalizedString(@"%d new articles retrieved", nil), newArticlesFromFeed]; - [connectorItem setStatus:logText]; - [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_ArticleListStateChange" object:folder]; + connectorItem.status = logText; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"MA_Notify_ArticleListContentChange" object:@(folder.itemId)]; } // Done with this connection - [newFeed release]; // Add to count of new articles so far countOfNewArticles += newArticlesFromFeed; // If this folder also requires an image refresh, do that - if (([folder flags] & MA_FFlag_CheckForImage)) - [self refreshFavIcon:folder]; + if ((folder.flags & MA_FFlag_CheckForImage)) { + [self refreshFavIconForFolder:folder]; + } } @@ -1044,8 +1036,8 @@ -(void)finalizeFolderRefresh:(NSDictionary*)parameters; */ -(NSString *)getRedirectURL:(NSData *)data { - const char * scanPtr = [data bytes]; - const char * scanPtrEnd = scanPtr + [data length]; + const char * scanPtr = data.bytes; + const char * scanPtrEnd = scanPtr + data.length; // Make sure this is HTML otherwise this is likely just valid // XML and we can ignore everything else. @@ -1107,7 +1099,7 @@ -(NSString *)getRedirectURL:(NSData *)data ++urlEnd; if (urlEnd == scanPtrEnd) return nil; - return [[[NSString alloc] initWithBytes:urlStart length:(urlEnd - urlStart) encoding:NSASCIIStringEncoding] autorelease]; + return [[NSString alloc] initWithBytes:urlStart length:(urlEnd - urlStart) encoding:NSASCIIStringEncoding]; } ++scanPtr; } @@ -1129,9 +1121,9 @@ -(NSString *)getRedirectURL:(NSData *)data */ -(void)addConnection:(ASIHTTPRequest *)conn { - if (![[networkQueue operations] containsObject:conn]) { + if (![networkQueue.operations containsObject:conn]) { [networkQueue addOperation:conn]; - if ([networkQueue requestsCount] == 1) // networkQueue is NOT YET started + if (networkQueue.requestsCount == 1) // networkQueue is NOT YET started { countOfNewArticles = 0; [networkQueue go]; @@ -1146,7 +1138,7 @@ -(void)addConnection:(ASIHTTPRequest *)conn -(void)removeConnection:(ASIHTTPRequest *)conn { NSAssert([networkQueue requestsCount] > 0, @"Calling removeConnection with zero active connection count"); - if ([[networkQueue operations] containsObject:conn]) + if ([networkQueue.operations containsObject:conn]) { // Close the connection before we release as otherwise it leaks [conn clearDelegatesAndCancel]; @@ -1156,7 +1148,7 @@ -(void)removeConnection:(ASIHTTPRequest *)conn -(BOOL)isConnecting { - return [networkQueue requestsCount] > 0; + return networkQueue.requestsCount > 0; } @@ -1166,17 +1158,5 @@ -(BOOL)isConnecting -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - [pumpTimer release]; - pumpTimer=nil; - [authQueue release]; - authQueue=nil; - [networkQueue release]; - networkQueue=nil; - [unsafe301RedirectionTimer release]; - unsafe301RedirectionTimer=nil; - [riskyIPAddress release]; - riskyIPAddress=nil; - dispatch_release(_queue); - [super dealloc]; } @end diff --git a/src/RenameFolder.h b/src/RenameFolder.h index f62ddae74b..5c24b54882 100644 --- a/src/RenameFolder.h +++ b/src/RenameFolder.h @@ -26,7 +26,7 @@ IBOutlet NSTextField * folderName; IBOutlet NSButton * renameButton; IBOutlet NSButton * cancelButton; - int folderId; + NSInteger folderId; } // Action handlers @@ -34,5 +34,5 @@ -(IBAction)doCancel:(id)sender; // General functions --(void)renameFolder:(NSWindow *)window folderId:(int)itemId; +-(void)renameFolder:(NSWindow *)window folderId:(NSInteger)itemId; @end diff --git a/src/RenameFolder.m b/src/RenameFolder.m index c6986bfe6f..129635fc31 100644 --- a/src/RenameFolder.m +++ b/src/RenameFolder.m @@ -32,7 +32,7 @@ @implementation RenameFolder /* renameFolder * Display the sheet to rename the specified folder. */ --(void)renameFolder:(NSWindow *)window folderId:(int)itemId +-(void)renameFolder:(NSWindow *)window folderId:(NSInteger)itemId { if (!renameFolderWindow) { @@ -42,7 +42,7 @@ -(void)renameFolder:(NSWindow *)window folderId:(int)itemId // Reset from the last time we used this sheet. folderId = itemId; - Folder * folder = [[Database sharedDatabase] folderFromID:folderId]; + Folder * folder = [[Database sharedManager] folderFromID:folderId]; [folderName setStringValue:[folder name]]; [self enableSaveButton]; @@ -55,12 +55,13 @@ -(void)renameFolder:(NSWindow *)window folderId:(int)itemId -(IBAction)doRename:(id)sender { NSString * newName = [[folderName stringValue] trim]; - Database * db = [Database sharedDatabase]; + Database * db = [Database sharedManager]; Folder * folder = [db folderFromID:folderId]; if ([[folder name] isEqualToString:newName]) { [renameFolderWindow orderOut:sender]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; [NSApp endSheet:renameFolderWindow returnCode:0]; } else @@ -71,6 +72,7 @@ -(IBAction)doRename:(id)sender { [db setFolderName:folderId newName:newName]; [renameFolderWindow orderOut:sender]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; [NSApp endSheet:renameFolderWindow returnCode:1]; } } @@ -81,6 +83,7 @@ -(IBAction)doRename:(id)sender */ -(IBAction)doCancel:(id)sender { + [[NSNotificationCenter defaultCenter] removeObserver:self]; [NSApp endSheet:renameFolderWindow]; [renameFolderWindow orderOut:self]; } @@ -110,6 +113,5 @@ -(void)enableSaveButton -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - [super dealloc]; } @end diff --git a/src/RichXMLParser.h b/src/RichXMLParser.h index 38543fb302..73499e04e9 100644 --- a/src/RichXMLParser.h +++ b/src/RichXMLParser.h @@ -18,43 +18,31 @@ // limitations under the License. #import -#import "XMLParser.h" -@interface FeedItem : NSObject { - NSString * title; - NSString * author; - NSString * link; - NSString * guid; - NSDate * date; - NSString * description; - NSString * enclosure; -} - -// Accessor functions --(NSString *)title; --(NSString *)description; --(NSString *)author; --(NSString *)guid; --(NSDate *)date; --(NSString *)link; --(NSString *)enclosure; -@end - -@interface RichXMLParser : XMLParser { - NSString * title; - NSString * link; - NSString * description; - NSDate * lastModified; - NSMutableArray * items; - NSMutableArray * orderArray; +@interface RichXMLParser : NSObject { + NSString * title; + NSString * link; + NSString * description; + NSDate * lastModified; + NSMutableArray * items; + NSMutableArray * orderArray; + @private + // prefixes for XML namespaces + NSString * rssPrefix; + NSString * rdfPrefix; + NSString * atomPrefix; + NSString * dcPrefix; + NSString * contentPrefix; + NSString * mediaPrefix; + NSString * encPrefix; } // General functions -(BOOL)parseRichXML:(NSData *)xmlData; +(BOOL)extractFeeds:(NSData *)xmlData toArray:(NSMutableArray *)linkArray; --(NSString *)title; --(NSString *)description; --(NSString *)link; --(NSDate *)lastModified; --(NSArray *)items; +@property (nonatomic, readonly, copy) NSString * title; +@property (nonatomic, readonly, copy) NSString * description; +@property (nonatomic, readonly, copy) NSString * link; +@property (nonatomic, readonly, copy) NSDate * lastModified; +@property (nonatomic, readonly, copy) NSArray * items; @end diff --git a/src/RichXMLParser.m b/src/RichXMLParser.m index 0356aafd60..1d1cc01530 100644 --- a/src/RichXMLParser.m +++ b/src/RichXMLParser.m @@ -21,270 +21,75 @@ #import "StringExtensions.h" #import "ArrayExtensions.h" #import "XMLTag.h" - -@interface FeedItem (Private) - -(void)setTitle:(NSString *)newTitle; - -(void)setDescription:(NSString *)newDescription; - -(void)setAuthor:(NSString *)newAuthor; - -(void)setDate:(NSDate *)newDate; - -(void)setGuid:(NSString *)newGuid; - -(void)setLink:(NSString *)newLink; - -(void)setEnclosure:(NSString *)newEnclosure; -@end +#import "FeedItem.h" +#import "NSDate+Vienna.h" @interface RichXMLParser (Private) - -(void)reset; - -(NSData *)preFlightValidation:(NSData *)xmlData; - -(NSStringEncoding)parseEncodingType:(NSData *)xmlData; - -(BOOL)initRSSFeed:(XMLParser *)feedTree isRDF:(BOOL)isRDF; - -(XMLParser *)channelTree:(XMLParser *)feedTree; - -(BOOL)initRSSFeedHeader:(XMLParser *)feedTree; - -(BOOL)initRSSFeedItems:(XMLParser *)feedTree; - -(BOOL)initAtomFeed:(XMLParser *)feedTree; - -(void)parseSequence:(XMLParser *)seqTree; - -(void)setTitle:(NSString *)newTitle; - -(void)setLink:(NSString *)newLink; - -(void)setDescription:(NSString *)newDescription; - -(void)setLastModified:(NSDate *)newDate; - -(void)ensureTitle:(FeedItem *)item; + -(BOOL)initRSSFeed:(NSXMLElement *)rssElement isRDF:(BOOL)isRDF; + -(NSXMLElement *)channelElementFromRSSElement:(NSXMLElement *)rssElement; + -(BOOL)initRSSFeedHeaderWithElement:(NSXMLElement *)channelElement; + -(BOOL)initRSSFeedItems:(NSXMLElement *)startElement; + -(BOOL)initAtomFeed:(NSXMLElement *)atomElement; + -(void)parseSequence:(NSXMLElement *)seqElement; + -(void)setTitle:(NSString *)newTitle; + -(void)setLink:(NSString *)newLink; + -(void)setDescription:(NSString *)newDescription; + -(void)setLastModified:(NSDate *)newDate; + -(void)ensureTitle:(FeedItem *)item; + -(void)identifyNamespacesPrefixes:(NSXMLElement *)element; @end -@implementation FeedItem - -/* init - * Creates a FeedItem instance - */ --(id)init -{ - if ((self = [super init]) != nil) - { - [self setTitle:@""]; - [self setDescription:@""]; - [self setAuthor:@""]; - [self setGuid:@""]; - [self setDate:nil]; - [self setLink:@""]; - [self setEnclosure:@""]; - } - return self; -} - -/* setEnclosure - * Set the item title. - */ --(void)setEnclosure:(NSString *)newEnclosure -{ - [newEnclosure retain]; - [enclosure release]; - enclosure = newEnclosure; -} -/* setTitle - * Set the item title. - */ --(void)setTitle:(NSString *)newTitle -{ - [newTitle retain]; - [title release]; - title = newTitle; -} - -/* setDescription - * Set the item description. - */ --(void)setDescription:(NSString *)newDescription -{ - [newDescription retain]; - [description release]; - description = newDescription; -} - -/* setAuthor - * Set the item author. - */ --(void)setAuthor:(NSString *)newAuthor -{ - [newAuthor retain]; - [author release]; - author = newAuthor; -} - -/* setDate - * Set the item date - */ --(void)setDate:(NSDate *)newDate -{ - [newDate retain]; - [date release]; - date = newDate; -} - -/* setGuid - * Set the item GUID. - */ --(void)setGuid:(NSString *)newGuid -{ - [newGuid retain]; - [guid release]; - guid = newGuid; -} - -/* setLink - * Set the item link. - */ --(void)setLink:(NSString *)newLink -{ - [newLink retain]; - [link release]; - link = newLink; -} - -/* title - * Returns the item title. - */ --(NSString *)title -{ - return title; -} - -/* description - * Returns the item description - */ --(NSString *)description -{ - return description; -} - -/* author - * Returns the item author - */ --(NSString *)author -{ - return author; -} - -/* date - * Returns the item date - */ --(NSDate *)date -{ - return date; -} - -/* guid - * Returns the item GUID. - */ --(NSString *)guid -{ - return guid; -} - -/* link - * Returns the item link. - */ --(NSString *)link -{ - return link; -} - -/* enclosure - * Returns the associated enclosure. - */ --(NSString *)enclosure -{ - return enclosure; -} - -/* dealloc - * Clean up when we're released. - */ --(void)dealloc -{ - [guid release]; - guid=nil; - [title release]; - title=nil; - [description release]; - description=nil; - [author release]; - author=nil; - [date release]; - date=nil; - [link release]; - link=nil; - [enclosure release]; - enclosure=nil; - [super dealloc]; -} -@end @implementation RichXMLParser -/* init - * Creates a RichXMLParser instance. - */ --(id)init -{ - if ((self = [super init]) != nil) - { - [self setTitle:@""]; - [self setDescription:@""]; - lastModified = nil; - link = nil; - items = nil; - orderArray = nil; - } - return self; -} - -/* reset - * Reset to remove existing feed info. - */ --(void)reset -{ - [title release]; - [description release]; - [lastModified release]; - [link release]; - [items release]; - title = nil; - description = nil; - lastModified = nil; - link = nil; - items = nil; -} - /* parseRichXML * Given an XML feed in xmlData, parses the feed as either an RSS or an Atom feed. * The actual parsed items can subsequently be accessed through the interface. */ -(BOOL)parseRichXML:(NSData *)xmlData { - BOOL success = NO; - @try { - NSData * parsedXmlData = [self preFlightValidation:xmlData]; - if (parsedXmlData && [self setData:parsedXmlData]) - { - XMLParser * subtree; - - // If this RSS? - if ((subtree = [self treeByName:@"rss"]) != nil) - success = [self initRSSFeed:subtree isRDF:NO]; - - // If this RSS:RDF? - else if ((subtree = [self treeByName:@"rdf:RDF"]) != nil) - success = [self initRSSFeed:subtree isRDF:YES]; - - // Atom? - else if ((subtree = [self treeByName:@"feed"]) != nil) - success = [self initAtomFeed:subtree]; - } - } - @catch (NSException *error) { - success = NO; - } - return success; -} + BOOL success = NO; + NSError * error = nil; + NSXMLDocument * xmlDocument; + + @try { + xmlDocument = [[NSXMLDocument alloc] initWithData:xmlData + options:NSXMLNodeLoadExternalEntitiesNever + error:&error]; + if (xmlDocument == nil && error != nil) { + if ([error.domain isEqualToString:NSXMLParserErrorDomain]) { + // handle here cases identified to cause + // application crashes caused by + // NSXMLDocument's -initWithData:options:error + // when option NSXMLDocumentTidyXML is enabled + switch (error.code) { + case NSXMLParserGTRequiredError: + return NO; + } + } + // recover some cases like text encoding errors, non standard tags... + xmlDocument = [[NSXMLDocument alloc] initWithData:xmlData + options:NSXMLDocumentTidyXML|NSXMLNodeLoadExternalEntitiesNever + error:&error]; + } + } @catch (NSException * exception) { + xmlDocument = nil; + } + + if (xmlDocument != nil) { + if ([(xmlDocument.rootElement).name isEqualToString:@"rss"]) { + success = [self initRSSFeed:xmlDocument.rootElement isRDF:NO]; + } else if ([(xmlDocument.rootElement).name isEqualToString:@"rdf:RDF"]) { + success = [self initRSSFeed:xmlDocument.rootElement isRDF:YES]; + } else if ([(xmlDocument.rootElement).name isEqualToString:@"feed"]) { + success = [self initAtomFeed:xmlDocument.rootElement]; + } + } + xmlDocument = nil; + + return success; +} /* parseRichXML */ /* extractFeeds * Given a block of XML data, determine whether this is HTML format and, if so, @@ -293,749 +98,665 @@ -(BOOL)parseRichXML:(NSData *)xmlData */ +(BOOL)extractFeeds:(NSData *)xmlData toArray:(NSMutableArray *)linkArray { - BOOL success = NO; - @try { - NSArray * arrayOfTags = [XMLTag parserFromData:xmlData]; - if (arrayOfTags != nil) - { - for (XMLTag * tag in arrayOfTags) - { - NSString * tagName = [tag name]; - - if ([tagName isEqualToString:@"rss"] || [tagName isEqualToString:@"rdf:rdf"] || [tagName isEqualToString:@"feed"]) - { - success = NO; - break; - } - if ([tagName isEqualToString:@"link"]) - { - NSDictionary * tagAttributes = [tag attributes]; - NSString * linkType = [tagAttributes objectForKey:@"type"]; - - // We're looking for the link tag. Specifically we're looking for the one which - // has application/rss+xml or atom+xml type. There may be more than one which is why we're - // going to be returning an array. - if ([linkType isEqualToString:@"application/rss+xml"]) - { - NSString * href = [tagAttributes objectForKey:@"href"]; - if (href != nil) - [linkArray addObject:href]; - } - else if ([linkType isEqualToString:@"application/atom+xml"]) - { - NSString * href = [tagAttributes objectForKey:@"href"]; - if (href != nil) - [linkArray addObject:href]; - } - } - if ([tagName isEqualToString:@"/head"]) - break; - success = [linkArray count] > 0; - } - } - } - @catch (NSException *error) { - success = NO; - } - return success; -} - -/* preFlightValidation - * Try and sanitise the XML data before the XML parser gets a chance to reject it. This - * should address the most common bad-feed errors until we can change the parser to one - * that provides us more control. - */ --(NSData *)preFlightValidation:(NSData *)xmlData -{ - NSUInteger count = [xmlData length]; - const unsigned char * srcPtr = [xmlData bytes]; - const unsigned char * srcEndPtr = srcPtr + count; - - // We'll create another data stream with the converted characters - NSMutableData * newXmlData = [NSMutableData dataWithLength:count]; - char * destPtr = [newXmlData mutableBytes]; - NSUInteger destCapacity = count; - NSUInteger destSize = count; - NSUInteger destIndex = 0; - - // Determine XML encoding and BOM - NSStringEncoding encodedType; - - if ( (count > 2 && srcPtr[0] == 0xFE && srcPtr[1] == 0xFF) || - (count > 2 && srcPtr[0] == 0xFF && srcPtr[1] == 0xFE) ) - { - // Copy Unicode UTF-16 big/little-endian BOM. - destPtr[destIndex++] = srcPtr[0]; - destPtr[destIndex++] = srcPtr[1]; - srcPtr += 2; - - char* encodingNameStr = "UTF-16"; - CFStringRef encodingName = CFStringCreateWithBytes(kCFAllocatorDefault, (unsigned char *)encodingNameStr, strlen(encodingNameStr), kCFStringEncodingISOLatin1, false); - encodedType = CFStringConvertIANACharSetNameToEncoding(encodingName); - CFRelease(encodingName); - } - - else if (count > 3 && srcPtr[0] == 0xEF && srcPtr[1] == 0xBB && srcPtr[2] == 0xBF) - { - // Copy Unicode UTF-8 little-endian BOM. - destPtr[destIndex++] = srcPtr[0]; - destPtr[destIndex++] = srcPtr[1]; - destPtr[destIndex++] = srcPtr[2]; - srcPtr += 3; - - char* encodingNameStr = "UTF-8"; - CFStringRef encodingName = CFStringCreateWithBytes(kCFAllocatorDefault, (unsigned char *)encodingNameStr, strlen(encodingNameStr), kCFStringEncodingISOLatin1, false); - encodedType = CFStringConvertIANACharSetNameToEncoding(encodingName); - CFRelease(encodingName); - } - - else - { - // Lets see if we have any better luck parsing the XML - encodedType = [self parseEncodingType:xmlData]; - } - - while (srcPtr < srcEndPtr) - { - unsigned char ch = *srcPtr++; - if (ch >= 0xC0 && ch <= 0xFD && srcPtr < srcEndPtr && *srcPtr >= 0x80 && *srcPtr <= 0xBF) - { - // Copy UTF-8 lead bytes unchanged. The parser can cope with - // these fine. - destPtr[destIndex++] = ch; - while (srcPtr < srcEndPtr && (*srcPtr & 0x80)) - destPtr[destIndex++] = *srcPtr++; - } - else if (ch > 0x7F && encodedType == NSUTF8StringEncoding) - { - // Other characters with their high bits set are not valid UTF-8. - // But regardless of the encoding scheme, their entity equivalents - // are. So convert them into a hex entity character code. - if (destSize + 5 > destCapacity) - { - [newXmlData setLength:destCapacity += 256]; - destPtr = [newXmlData mutableBytes]; - } - destPtr[destIndex++] = '&'; - destPtr[destIndex++] = '#'; - destPtr[destIndex++] = 'x'; - destPtr[destIndex++] = "0123456789ABCDEF"[(ch / 16)]; - destPtr[destIndex++] = "0123456789ABCDEF"[(ch % 16)]; - destPtr[destIndex++] = ';'; - destSize += 5; - } - else if (ch == '&' && srcPtr < srcEndPtr && *srcPtr != '#') - { - // Some feeds use a '&' outside of its intended use as an entity - // delimiter. So if '&' is followed by a non-alphanumeric, make it - // into its entity equivalent. - const unsigned char * srcTmpPtr = srcPtr; - while (srcTmpPtr < srcEndPtr && isalpha(*srcTmpPtr)) - ++srcTmpPtr; - if (srcTmpPtr < srcEndPtr && *srcTmpPtr == ';') - destPtr[destIndex++] = '&'; - else - { - if (destSize + 4 > destCapacity) - { - [newXmlData setLength:destCapacity += 256]; - destPtr = [newXmlData mutableBytes]; - } - destPtr[destIndex++] = '&'; - destPtr[destIndex++] = 'a'; - destPtr[destIndex++] = 'm'; - destPtr[destIndex++] = 'p'; - destPtr[destIndex++] = ';'; - destSize += 4; - } - } - else - destPtr[destIndex++] = ch; - } - NSAssert(destIndex == destSize, @"Did not copy all data bytes to destination buffer"); - [newXmlData setLength:destIndex]; - - // Make sure that the last valid character of the feed is '>' otherwise it was truncated. The - // CFXML parser annoyingly crashes if it is given a truncated feed. - while (--destIndex > 0 && (destPtr[destIndex] == '\0' || isspace(destPtr[destIndex]))); - return (destPtr[destIndex] == '>') ? newXmlData : nil; -} - -/* parseEncodingType - * Parse off the encoding field. - */ --(NSStringEncoding)parseEncodingType:(NSData *)xmlData -{ - NSStringEncoding encodingType = NSUTF8StringEncoding; - const char * textPtr = [xmlData bytes]; - const char * textEndPtr = textPtr + [xmlData length]; - - while (textPtr < textEndPtr && *textPtr != '<') - ++textPtr; - - // Scan for the encoding attribute name up until the closing tag - const char * encodingAttribute = "encoding="; - const char * encodingAttributePtr = encodingAttribute; - while (textPtr < textEndPtr && *encodingAttributePtr != '\0' && *textPtr != '>') - { - if (*textPtr == *encodingAttributePtr) - ++encodingAttributePtr; - else - encodingAttributePtr = encodingAttribute; - ++textPtr; - } - - // If we found it, parse off the encoding type name - if (*encodingAttributePtr == '\0') - { - if (textPtr < textEndPtr && *textPtr == '"') - ++textPtr; - - // We need to special case UTF-8 as CFStringConvertIANACharSetNameToEncoding - // doesn't recognise it. - const char * encodingNamePtr = textPtr; - const char * utf8EncodingName = "UTF-8"; - const char * utf8EncodingNamePtr = utf8EncodingName; - while (textPtr < textEndPtr && *textPtr != '"') - { - if (toupper(*textPtr) == *utf8EncodingNamePtr) - ++utf8EncodingNamePtr; - else - utf8EncodingNamePtr = utf8EncodingName; - ++textPtr; - } - - // Now extract the encoding name if it wasn't UTF-8 - if (*utf8EncodingNamePtr != '\0') - { - CFStringRef encodingName = CFStringCreateWithBytes(kCFAllocatorDefault, (unsigned char *)encodingNamePtr, textPtr - encodingNamePtr, kCFStringEncodingISOLatin1, false); - encodingType = CFStringConvertIANACharSetNameToEncoding(encodingName); - CFRelease(encodingName); - } - } - return encodingType; -} + BOOL success = NO; + + @try { + NSArray * arrayOfTags = [XMLTag parserFromData:xmlData]; + if (arrayOfTags != nil) { + for (XMLTag * tag in arrayOfTags) { + NSString * tagName = tag.name; + + if ([tagName isEqualToString:@"rss"] || [tagName isEqualToString:@"rdf:rdf"] || [tagName isEqualToString:@"feed"]) { + success = NO; + break; + } + if ([tagName isEqualToString:@"link"]) { + NSDictionary * tagAttributes = tag.attributes; + NSString * linkType = tagAttributes[@"type"]; + + // We're looking for the link tag. Specifically we're looking for the one which + // has application/rss+xml or atom+xml type. There may be more than one which is why we're + // going to be returning an array. + if ([linkType isEqualToString:@"application/rss+xml"]) { + NSString * href = tagAttributes[@"href"]; + if (href != nil) { + [linkArray addObject:href]; + } + } else if ([linkType isEqualToString:@"application/atom+xml"]) { + NSString * href = tagAttributes[@"href"]; + if (href != nil) { + [linkArray addObject:href]; + } + } + } + if ([tagName isEqualToString:@"/head"]) { + break; + } + success = linkArray.count > 0; + } + } + } + @catch (NSException * error) { + success = NO; + } + return success; +} /* extractFeeds */ /* initRSSFeed * Prime the feed with header and items from an RSS feed */ --(BOOL)initRSSFeed:(XMLParser *)feedTree isRDF:(BOOL)isRDF -{ - BOOL success = [self initRSSFeedHeader:[self channelTree:feedTree]]; - if (success) - { - if (isRDF) - success = [self initRSSFeedItems:feedTree]; - else - success = [self initRSSFeedItems:[self channelTree:feedTree]]; - } - return success; +-(BOOL)initRSSFeed:(NSXMLElement *)rssElement isRDF:(BOOL)isRDF +{ + BOOL success = NO; + + [self identifyNamespacesPrefixes:rssElement]; + NSXMLElement * channelElement = [self channelElementFromRSSElement:rssElement]; + success = [self initRSSFeedHeaderWithElement:channelElement]; + if (success) { + if (isRDF) { + success = [self initRSSFeedItems:rssElement]; + } else { + success = [self initRSSFeedItems:channelElement]; + } + } + return success; +} + +/** + * Get the root of the RSS feed's channel. + * + * @param rssElement The rss element of the feed + * + * @return the channel element + */ +-(NSXMLElement *)channelElementFromRSSElement:(NSXMLElement *)rssElement +{ + NSXMLElement * channelElement; + + if ([rssPrefix isEqualToString:@""]) { + channelElement = [rssElement elementsForName:@"channel"].firstObject; + } else { + channelElement = [rssElement elementsForName:[NSString stringWithFormat:@"%@:channel", rssPrefix]].firstObject; + } + return channelElement; +} + +/** + * Identify the prefixes used for namespaces we handle, if defined + * If prefixes are not defined in our data, set to frequently used ones + * + * @param rssElement The rss of atom element of the feed + * + */ +-(void)identifyNamespacesPrefixes:(NSXMLElement *)element +{ + // default : empty + rssPrefix = [element resolvePrefixForNamespaceURI:@"http://purl.org/net/rss1.1#"]; // RSS 1.1 + if (!rssPrefix) { + rssPrefix = [element resolvePrefixForNamespaceURI:@"http://purl.org/rss/1.0/"]; // RSS 1.0 + } + if (!rssPrefix) { + rssPrefix = @""; + } + + // default : 'rdf' + rdfPrefix = [element resolvePrefixForNamespaceURI:@"http://www.w3.org/1999/02/22-rdf-syntax-ns#"]; + if (!rdfPrefix) { + rdfPrefix = @"rdf"; + } + + // default : empty + atomPrefix = [element resolvePrefixForNamespaceURI:@"http://www.w3.org/2005/Atom"]; + if (!atomPrefix) { + atomPrefix = @""; + } + + // default : 'dc' + dcPrefix = [element resolvePrefixForNamespaceURI:@"http://purl.org/dc/elements/1.1/"]; + if (!dcPrefix) { + dcPrefix = @"dc"; + } + + // default : 'content' + contentPrefix = [element resolvePrefixForNamespaceURI:@"http://purl.org/rss/1.0/modules/content/"]; + if (!contentPrefix) { + contentPrefix = @"content"; + } + + // default : 'media' + mediaPrefix = [element resolvePrefixForNamespaceURI:@"http://search.yahoo.com/mrss/"]; + if (!mediaPrefix) { + mediaPrefix = @"media"; + } + + // default : 'enc' + encPrefix = [element resolvePrefixForNamespaceURI:@"http://purl.oclc.org/net/rss_2.0/enc#"]; + if (!encPrefix) { + encPrefix = @"enc"; + } +} /* identifyNamespacesPrefixes */ + +/** + * Parse an RSS feed's header items + * + * @param channelElement the element containing header items. + * This is typically a channel element for RSS feeds + * + * @return YES on success + */ +-(BOOL)initRSSFeedHeaderWithElement:(NSXMLElement *)channelElement +{ + BOOL success = NO; + + // Iterate through the channel items + for (NSXMLElement * element in channelElement.children) { + NSString * channelItemTag = element.localName; + BOOL isRSSElement = [element.prefix isEqualToString:rssPrefix]; + + // Parse title + if (isRSSElement && [channelItemTag isEqualToString:@"title"]) { + [self setTitle:(element.stringValue).stringByUnescapingExtendedCharacters]; + success = YES; + continue; + } + // Parse items group which dictates the sequence of the articles. + if (isRSSElement && [channelItemTag isEqualToString:@"items"]) { + NSXMLElement * seqElement = [element elementsForName:[NSString stringWithFormat:@"%@:Seq", rdfPrefix]].firstObject; + + if (seqElement != nil) { + [self parseSequence:seqElement]; + } + } + + // Parse description + if (isRSSElement && [channelItemTag isEqualToString:@"description"]) { + [self setDescription:element.stringValue]; + continue; + } + + // Parse link + if (isRSSElement && [channelItemTag isEqualToString:@"link"]) { + [self setLink:(element.stringValue).stringByUnescapingExtendedCharacters]; + continue; + } + + // Parse the date when this feed was last updated + if ((isRSSElement && [channelItemTag isEqualToString:@"lastBuildDate"]) || + (isRSSElement && [channelItemTag isEqualToString:@"pubDate"]) || + ([element.prefix isEqualToString:dcPrefix] && [channelItemTag isEqualToString:@"date"]) ) { + NSString * dateString = element.stringValue; + [self setLastModified:[NSDate parseXMLDate:dateString]]; + continue; + } + } + return success; +} /* initRSSFeedHeaderWithElement */ + + +/** + * Parses an RDF sequence and initialises orderArray with the appropriate sequence. + * The RSS parser will then use this to order the actual items appropriately. + * + * @param seqElement the sequence element + */ +-(void)parseSequence:(NSXMLElement *)seqElement +{ + orderArray = [[NSMutableArray alloc] init]; + for (NSXMLElement * element in seqElement.children) { + if ([element.name isEqualToString:[NSString stringWithFormat:@"%@:li", rdfPrefix]]) { + NSString * resourceString = [element attributeForName:[NSString stringWithFormat:@"%@:resource", rdfPrefix]].stringValue; + if (resourceString == nil) { + resourceString = [element attributeForName:@"resource"].stringValue; + } + if (resourceString != nil) { + [orderArray addObject:resourceString]; + } + + } + } } -/* channelTree - * Return the root of the RSS feed's channel. +/* initRSSFeedItems + * Parse the items from an RSS feed */ --(XMLParser *)channelTree:(XMLParser *)feedTree +-(BOOL)initRSSFeedItems:(NSXMLElement *)startElement { - XMLParser * channelTree = [feedTree treeByName:@"channel"]; - if (channelTree == nil) - channelTree = [feedTree treeByName:@"rss:channel"]; - return channelTree; -} + BOOL success = YES; -/* initRSSFeedHeader - * Parse an RSS feed header items. - */ --(BOOL)initRSSFeedHeader:(XMLParser *)feedTree -{ - BOOL success = YES; - - // Iterate through the channel items - CFIndex count = [feedTree countOfChildren]; - CFIndex index; - - for (index = 0; index < count; ++index) - { - XMLParser * subTree = [feedTree treeByIndex:index]; - NSString * nodeName = [subTree nodeName]; - - // Parse title - if ([nodeName isEqualToString:@"title"] || [nodeName isEqualToString:@"rss:title"]) - { - [self setTitle:[[subTree valueOfElement] stringByUnescapingExtendedCharacters]]; - continue; - } - - // Parse items group which dictates the sequence of the articles. - if ([nodeName isEqualToString:@"items"] || [nodeName isEqualToString:@"rss:items"]) - { - XMLParser * seqTree = [subTree treeByName:@"rdf:Seq"]; - if (seqTree != nil) - [self parseSequence:seqTree]; - } - - // Parse description - if ([nodeName isEqualToString:@"description"] || [nodeName isEqualToString:@"rss:description"]) - { - [self setDescription:[subTree valueOfElement]]; - continue; - } - - // Parse link - if ([nodeName isEqualToString:@"link"] || [nodeName isEqualToString:@"rss:link"]) - { - [self setLink:[[subTree valueOfElement] stringByUnescapingExtendedCharacters]]; - continue; - } - - // Parse the date when this feed was last updated - if ([nodeName isEqualToString:@"lastBuildDate"] || [nodeName isEqualToString:@"pubDate"] || [nodeName isEqualToString:@"dc:date"]) - { - NSString * dateString = [subTree valueOfElement]; - [self setLastModified:[XMLParser parseXMLDate:dateString]]; - continue; - } - } - return success; -} + // Allocate an items array + NSAssert(items == nil, @"initRSSFeedItems called more than once per initialisation"); + items = [[NSMutableArray alloc] init]; -/* parseSequence - * Parses an RDF sequence and initialises orderArray with the appropriate sequence. - * The RSS parser will then use this to order the actual items appropriately. - */ --(void)parseSequence:(XMLParser *)seqTree -{ - CFIndex count = [seqTree countOfChildren]; - CFIndex index; - - [orderArray release]; - orderArray = [[NSMutableArray alloc] initWithCapacity:count]; - for (index = 0; index < count; ++index) - { - XMLParser * subTree = [seqTree treeByIndex:index]; - if ([[subTree nodeName] isEqualToString:@"rdf:li"]) - { - NSString * resourceString = [subTree valueOfAttribute:@"rdf:resource"]; - if (resourceString == nil) - resourceString = [subTree valueOfAttribute:@"resource"]; - if (resourceString != nil) - [orderArray addObject:resourceString]; - } - } -} + for (NSXMLElement * element in startElement.children) { + // Parse a single item to construct a FeedItem object which is appended to + // the items array we maintain. + if ([element.prefix isEqualToString:rssPrefix] && [element.localName isEqualToString:@"item"]) { + FeedItem * newFeedItem = [FeedItem new]; + NSMutableString * articleBody = nil; + BOOL hasDetailedContent = NO; + BOOL hasLink = NO; + + // Check for rdf:about so we can identify this item in the orderArray. + NSString * itemIdentifier = [element attributeForName:[NSString stringWithFormat:@"%@:about", rdfPrefix]].stringValue; + + for (NSXMLElement * itemChildElement in element.children) { + BOOL isRSSElement = [itemChildElement.prefix isEqualToString:rssPrefix]; + NSString * articleItemTag = itemChildElement.localName; + + // Parse item title + if (isRSSElement && [articleItemTag isEqualToString:@"title"]) { + newFeedItem.title = (itemChildElement.stringValue).summaryTextFromHTML; + continue; + } + + // Parse item description + if (isRSSElement && [articleItemTag isEqualToString:@"description"] && + !hasDetailedContent) { + NSString * type = [itemChildElement attributeForName:@"type"].stringValue; + if ([type isEqualToString:@"xhtml"]) { + articleBody = [NSMutableString stringWithString:itemChildElement.XMLString]; + } else if (type != nil && ![type isEqualToString:@"text/xml"] && ![type isEqualToString:@"text/html"] && + [type rangeOfString:@"text" options:NSRegularExpressionSearch | NSCaseInsensitiveSearch].location != NSNotFound) { + // 'type' attribute is 'text*' and not 'text/xml' nor 'text/html' + articleBody = [[NSString stringByConvertingHTMLEntities:itemChildElement.stringValue] mutableCopy]; + } else { + articleBody = [NSMutableString stringWithString:itemChildElement.stringValue]; + } + continue; + } + + // Parse GUID. The GUID may optionally have a permaLink attribute + // in which case this is also the article link unless overridden by + // an explicit link tag. + if (isRSSElement && [articleItemTag isEqualToString:@"guid"]) { + NSString * permaLink = [itemChildElement + attributeForName:@"isPermaLink"].stringValue; + + if (permaLink && [permaLink isEqualToString:@"true"] && !hasLink) { + newFeedItem.link = itemChildElement.stringValue; + } + newFeedItem.guid = itemChildElement.stringValue; + continue; + } + + // Parse detailed item description. This overrides the existing + // description for this item. + if ([itemChildElement.prefix isEqualToString:contentPrefix] && [articleItemTag isEqualToString:@"encoded"]) { + articleBody = [NSMutableString stringWithString:itemChildElement.stringValue]; + hasDetailedContent = YES; + continue; + } -/* initRSSFeedItems - * Parse the items from an RSS feed - */ --(BOOL)initRSSFeedItems:(XMLParser *)feedTree -{ - BOOL success = YES; - - // Iterate through the channel items - CFIndex count = [feedTree countOfChildren]; - CFIndex index; - - // Allocate an items array - NSAssert(items == nil, @"initRSSFeedItems called more than once per initialisation"); - items = [[NSMutableArray alloc] initWithCapacity:count]; - - for (index = 0; index < count; ++index) - { - XMLParser * subTree = [feedTree treeByIndex:index]; - NSString * nodeName = [subTree nodeName]; - - // Parse a single item to construct a FeedItem object which is appended to - // the items array we maintain. - if ([nodeName isEqualToString:@"item"] || [nodeName isEqualToString:@"rss:item"]) - { - FeedItem * newItem = [[FeedItem new] autorelease]; - CFIndex itemCount = [subTree countOfChildren]; - NSMutableString * articleBody = nil; - BOOL hasDetailedContent = NO; - BOOL hasLink = NO; - CFIndex itemIndex; - - // Check for rdf:about so we can identify this item in the orderArray. - NSString * itemIdentifier = [subTree valueOfAttribute:@"rdf:about"]; - - for (itemIndex = 0; itemIndex < itemCount; ++itemIndex) - { - XMLParser * subItemTree = [subTree treeByIndex:itemIndex]; - NSString * itemNodeName = [subItemTree nodeName]; - - // Parse item title - if ([itemNodeName isEqualToString:@"title"] || [itemNodeName isEqualToString:@"rss:title"]) - { - [newItem setTitle:[[subItemTree valueOfElement] summaryTextFromHTML]]; - continue; - } - - // Parse item description - if (([itemNodeName isEqualToString:@"description"] || [itemNodeName isEqualToString:@"rss:description"]) && !hasDetailedContent) - { - articleBody = [[[NSMutableString alloc] initWithString:[subItemTree valueOfElement]] autorelease]; - continue; - } - - // Parse GUID. The GUID may optionally have a permaLink attribute - // in which case this is also the article link unless overridden by - // an explicit link tag. - if ([itemNodeName isEqualToString:@"guid"] || [itemNodeName isEqualToString:@"rss:guid"]) - { - NSString * permaLink = [subItemTree valueOfAttribute:@"isPermaLink"]; - if (permaLink && [permaLink isEqualToString:@"true"] && !hasLink) - [newItem setLink:[subItemTree valueOfElement]]; - [newItem setGuid:[subItemTree valueOfElement]]; - continue; - } - - // Parse detailed item description. This overrides the existing - // description for this item. - if ([itemNodeName isEqualToString:@"content:encoded"]) - { - articleBody = [[[NSMutableString alloc] initWithString:[subItemTree valueOfElement]] autorelease]; - hasDetailedContent = YES; - continue; - } - // Parse item author - if ([itemNodeName isEqualToString:@"author"] || [itemNodeName isEqualToString:@"dc:creator"] || [itemNodeName isEqualToString:@"rss:author"]) - { - NSString *authorName = [subItemTree valueOfElement]; - + if ( (isRSSElement && [articleItemTag isEqualToString:@"author"]) + || ([itemChildElement.prefix isEqualToString:dcPrefix] && [articleItemTag isEqualToString:@"creator"]) ) { + NSString * authorName = itemChildElement.stringValue; + // the author is in the feed's entry if (authorName != nil) { // if we currently have a string set as the author then append the new author name - if ([[newItem author] length] > 0) { - [newItem setAuthor:[NSString stringWithFormat:NSLocalizedString(@"%@, %@", @"{existing authors},{new author name}"), [newItem author], authorName]]; + if (newFeedItem.author.length > 0) { + newFeedItem.author = [NSString stringWithFormat: + NSLocalizedString(@"%@, %@", @"{existing authors},{new author name}"), newFeedItem.author, authorName]; } // else we currently don't have an author set, so set it to the first author else { - [newItem setAuthor:authorName]; + newFeedItem.author = authorName; } } continue; - } - - // Parse item date - if ([itemNodeName isEqualToString:@"dc:date"] || [itemNodeName isEqualToString:@"pubDate"]) - { - NSString * dateString = [subItemTree valueOfElement]; - [newItem setDate:[XMLParser parseXMLDate:dateString]]; - continue; - } - - // Parse item link - if ([itemNodeName isEqualToString:@"link"] || [itemNodeName isEqualToString:@"rss:link"]) - { - [newItem setLink:[[subItemTree valueOfElement] stringByUnescapingExtendedCharacters]]; - hasLink = YES; - continue; - } - - // Parse associated enclosure - if ([itemNodeName isEqualToString:@"enclosure"]) - { - if ([subItemTree valueOfAttribute:@"url"]) - [newItem setEnclosure:[subItemTree valueOfAttribute:@"url"]]; - continue; - } - - } - - // If no link, set it to the feed link if there is one - if (!hasLink && [self link]) - [newItem setLink:[self link]]; - - // Do relative IMG, IFRAME and A tags fixup - [articleBody fixupRelativeImgTags:[self link]]; - [articleBody fixupRelativeIframeTags:[self link]]; - [articleBody fixupRelativeAnchorTags:[self link]]; - [newItem setDescription:SafeString(articleBody)]; - - // Derive any missing title - [self ensureTitle:newItem]; - - // Add this item in the proper location in the array - NSUInteger indexOfItem = (orderArray && itemIdentifier) ? [orderArray indexOfStringInArray:itemIdentifier] : NSNotFound; - if (indexOfItem == NSNotFound || indexOfItem >= [items count]) - [items addObject:newItem]; - else - [items insertObject:newItem atIndex:indexOfItem]; - } - } - - return success; -} + } + + // Parse item date + if ( (isRSSElement && [articleItemTag isEqualToString:@"pubDate"]) + || ([itemChildElement.prefix isEqualToString:dcPrefix] && [articleItemTag isEqualToString:@"date"]) ) { + NSString * dateString = itemChildElement.stringValue; + newFeedItem.date = [NSDate parseXMLDate:dateString]; + continue; + } + + // Parse item link + if (isRSSElement && [articleItemTag isEqualToString:@"link"]) { + newFeedItem.link = (itemChildElement.stringValue).stringByUnescapingExtendedCharacters; + hasLink = YES; + continue; + } + + // Parse associated enclosure + if ( (isRSSElement && [articleItemTag isEqualToString:@"enclosure"]) + || ([itemChildElement.prefix isEqualToString:mediaPrefix] && [articleItemTag isEqualToString:@"content"]) ) { + if ([itemChildElement attributeForName:@"url"].stringValue) { + newFeedItem.enclosure = [itemChildElement attributeForName:@"url"].stringValue; + } + continue; + } + if ([itemChildElement.prefix isEqualToString:encPrefix] && [articleItemTag isEqualToString:@"enclosure"]) { + if ([itemChildElement attributeForName:@"url"].stringValue) { + newFeedItem.enclosure = [itemChildElement attributeForName:@"url"].stringValue; + } + NSString * resourceString = [NSString stringWithFormat:@"%@:resource", rdfPrefix]; + if ([itemChildElement attributeForName:resourceString].stringValue) { + newFeedItem.enclosure = [itemChildElement attributeForName:resourceString].stringValue; + } + continue; + } + + } + + // If no link, set it to the feed link if there is one + if (!hasLink && self.link) { + newFeedItem.link = self.link; + } + + // Do relative IMG, IFRAME and A tags fixup + [articleBody fixupRelativeImgTags:self.link]; + [articleBody fixupRelativeIframeTags:self.link]; + [articleBody fixupRelativeAnchorTags:self.link]; + [newFeedItem setDescription:SafeString(articleBody)]; + + // Derive any missing title + [self ensureTitle:newFeedItem]; + + // Add this item in the proper location in the array + NSUInteger indexOfItem = (orderArray && itemIdentifier) ? [orderArray indexOfStringInArray:itemIdentifier] : NSNotFound; + if (indexOfItem == NSNotFound || indexOfItem >= items.count) { + [items addObject:newFeedItem]; + } else { + [items insertObject:newFeedItem atIndex:indexOfItem]; + } + } + } + + return success; +} /* initRSSFeedItems */ /* initAtomFeed * Prime the feed with header and items from an Atom feed */ --(BOOL)initAtomFeed:(XMLParser *)feedTree -{ - BOOL success = YES; - - // Allocate an items array - NSAssert(items == nil, @"initAtomFeed called more than once per initialisation"); - items = [[NSMutableArray alloc] initWithCapacity:10]; - - // Look for feed attributes we need to process - NSString * linkBase = [[feedTree valueOfAttribute:@"xml:base"] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; - if (linkBase == nil) - linkBase = [[self link] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; - NSURL * linkBaseURL = (linkBase != nil) ? [NSURL URLWithString:linkBase] : nil; - - // Iterate through the atom items - NSString * defaultAuthor = @""; - CFIndex count = [feedTree countOfChildren]; - CFIndex index; - - for (index = 0; index < count; ++index) - { - XMLParser * subTree = [feedTree treeByIndex:index]; - NSString * nodeName = [subTree nodeName]; - - // Parse title - if ([nodeName isEqualToString:@"title"]) - { - [self setTitle:[[[subTree valueOfElement] stringByUnescapingExtendedCharacters] summaryTextFromHTML]]; - continue; - } - - // Parse description] - if ([nodeName isEqualToString:@"subtitle"]) - { - [self setDescription:[subTree valueOfElement]]; - continue; - } - - // Parse description - if ([nodeName isEqualToString:@"tagline"]) - { - [self setDescription:[subTree valueOfElement]]; - continue; - } - - // Parse link - if ([nodeName isEqualToString:@"link"]) - { - if ([subTree valueOfAttribute:@"rel"] == nil || [[subTree valueOfAttribute:@"rel"] isEqualToString:@"alternate"]) - { - NSString * theLink = [[subTree valueOfAttribute:@"href"] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; - if (theLink != nil) - { - if ((linkBaseURL != nil) && ![theLink hasPrefix:@"http://"] && ![theLink hasPrefix:@"https://"]) - { - NSURL * theLinkURL = [NSURL URLWithString:theLink relativeToURL:linkBaseURL]; - [self setLink:(theLinkURL != nil) ? [theLinkURL absoluteString] : theLink]; - } - else - [self setLink:theLink]; - } - } - - if (linkBase == nil) - linkBase = [[self link] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; - - continue; - } - - // Parse author at the feed level. This is the default for any entry - // that doesn't have an explicit author. - if ([nodeName isEqualToString:@"author"]) - { - XMLParser * emailTree = [subTree treeByName:@"name"]; - if (emailTree != nil) - defaultAuthor = [emailTree valueOfElement]; - continue; - } - - // Parse the date when this feed was last updated - if ([nodeName isEqualToString:@"updated"]) - { - NSString * dateString = [subTree valueOfElement]; - [self setLastModified:[XMLParser parseXMLDate:dateString]]; - continue; - } - - // Parse the date when this feed was last updated - if ([nodeName isEqualToString:@"modified"]) - { - NSString * dateString = [subTree valueOfElement]; - [self setLastModified:[XMLParser parseXMLDate:dateString]]; - continue; - } - - // Parse a single item to construct a FeedItem object which is appended to - // the items array we maintain. - if ([nodeName isEqualToString:@"entry"]) - { - FeedItem * newItem = [[FeedItem new] autorelease]; - CFIndex itemCount = [subTree countOfChildren]; - NSMutableString * articleBody = nil; - CFIndex itemIndex; - - // Look for the xml:base attribute, and use absolute url or stack relative url - NSString * entryBase = [[subTree valueOfAttribute:@"xml:base"] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; - if (entryBase == nil) - entryBase = linkBase; - NSURL * entryBaseURL = (entryBase != nil) ? [NSURL URLWithString:entryBase] : nil; - if ((entryBaseURL != nil) && (linkBaseURL != nil) && ([entryBaseURL scheme] == nil)) - { - entryBaseURL = [NSURL URLWithString:entryBase relativeToURL:linkBaseURL]; - if (entryBaseURL != nil) - entryBase = [entryBaseURL absoluteString]; - } - - for (itemIndex = 0; itemIndex < itemCount; ++itemIndex) - { - XMLParser * subItemTree = [subTree treeByIndex:itemIndex]; - NSString * itemNodeName = [subItemTree nodeName]; - - // Parse item title - if ([itemNodeName isEqualToString:@"title"]) - { - [newItem setTitle:[[subItemTree valueOfElement] summaryTextFromHTML]]; - continue; - } - - // Parse item description - if ([itemNodeName isEqualToString:@"content"]) - { - articleBody = [[[NSMutableString alloc] initWithString:[subItemTree valueOfElement]] autorelease]; - continue; - } - - // Parse item description - if ([itemNodeName isEqualToString:@"summary"]) - { - articleBody = [[[NSMutableString alloc] initWithString:[subItemTree valueOfElement]] autorelease]; - continue; - } - - // Parse item author - if ([itemNodeName isEqualToString:@"author"]) - { - NSString * authorName = [[subItemTree treeByName:@"name"] valueOfElement]; - if (authorName == nil) { - authorName = [[subItemTree treeByName:@"email"] valueOfElement]; +-(BOOL)initAtomFeed:(NSXMLElement *)atomElement +{ + BOOL success = NO; + + [self identifyNamespacesPrefixes:atomElement]; + + // Allocate an items array + NSAssert(items == nil, @"initAtomFeed called more than once per initialisation"); + items = [[NSMutableArray alloc] init]; + + // Look for feed attributes we need to process + NSString * linkBase = [[atomElement attributeForName:@"xml:base"].stringValue stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + if (linkBase == nil) { + linkBase = [self.link stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + } + NSURL * linkBaseURL = (linkBase != nil) ? [NSURL URLWithString:linkBase] : nil; + + // Iterate through the atom items + NSString * defaultAuthor = @""; + + for (NSXMLElement * atomChildElement in atomElement.children) { + BOOL isAtomElement = [atomChildElement.prefix isEqualToString:atomPrefix]; + NSString * elementTag = atomChildElement.localName; + + // Parse title + if (isAtomElement && [elementTag isEqualToString:@"title"]) { + [self setTitle:(atomChildElement.stringValue).stringByUnescapingExtendedCharacters.summaryTextFromHTML]; + success = YES; + continue; + } + + // Parse description] + if (isAtomElement && [elementTag isEqualToString:@"subtitle"]) { + [self setDescription:atomChildElement.stringValue]; + continue; + } + + // Parse description + if (isAtomElement && [elementTag isEqualToString:@"tagline"]) { + [self setDescription:atomChildElement.stringValue]; + continue; + } + + // Parse link + if (isAtomElement && [elementTag isEqualToString:@"link"]) { + if ([atomChildElement attributeForName:@"rel"].stringValue == nil || + [[atomChildElement attributeForName:@"rel"].stringValue isEqualToString:@"alternate"]) { + NSString * theLink = [[atomChildElement attributeForName:@"href"].stringValue stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + if (theLink != nil) { + if ((linkBaseURL != nil) && ![theLink hasPrefix:@"http://"] && ![theLink hasPrefix:@"https://"]) { + NSURL * theLinkURL = [NSURL URLWithString:theLink relativeToURL:linkBaseURL]; + [self setLink:(theLinkURL != nil) ? theLinkURL.absoluteString : theLink]; + } else { + [self setLink:theLink]; + } + } + } + + if (linkBase == nil) { + linkBase = [self.link stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + } + + continue; + } + + // Parse author at the feed level. This is the default for any entry + // that doesn't have an explicit author. + if (isAtomElement && [elementTag isEqualToString:@"author"]) { + NSXMLElement * nameElement = [atomChildElement elementsForName:@"name"].firstObject; + if (nameElement != nil) { + defaultAuthor = nameElement.stringValue; + } + continue; + } + + // Parse the date when this feed was last updated + if (isAtomElement && [elementTag isEqualToString:@"updated"]) { + NSString * dateString = atomChildElement.stringValue; + [self setLastModified:[NSDate parseXMLDate:dateString]]; + continue; + } + + // Parse the date when this feed was last updated + if (isAtomElement && [elementTag isEqualToString:@"modified"]) { + NSString * dateString = atomChildElement.stringValue; + [self setLastModified:[NSDate parseXMLDate:dateString]]; + continue; + } + + // Parse a single item to construct a FeedItem object which is appended to + // the items array we maintain. + if (isAtomElement && [elementTag isEqualToString:@"entry"]) { + FeedItem * newFeedItem = [FeedItem new]; + NSMutableString * articleBody = nil; + + // Look for the xml:base attribute, and use absolute url or stack relative url + NSString * entryBase = [[atomChildElement attributeForName:@"xml:base"].stringValue stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + if (entryBase == nil) { + entryBase = linkBase; + } + + NSURL * entryBaseURL = (entryBase != nil) ? [NSURL URLWithString:entryBase] : nil; + if ((entryBaseURL != nil) && (linkBaseURL != nil) && (entryBaseURL.scheme == nil)) { + entryBaseURL = [NSURL URLWithString:entryBase relativeToURL:linkBaseURL]; + if (entryBaseURL != nil) { + entryBase = entryBaseURL.absoluteString; + } + } + + for (NSXMLElement * itemChildElement in atomChildElement.children) { + BOOL isArticleElementAtomType = [itemChildElement.prefix isEqualToString:atomPrefix]; + + NSString * articleItemTag = itemChildElement.localName; + + // Parse item title + if (isArticleElementAtomType && [articleItemTag isEqualToString:@"title"]) { + newFeedItem.title = (itemChildElement.stringValue).summaryTextFromHTML; + continue; + } + + // Parse item description + if (isArticleElementAtomType && [articleItemTag isEqualToString:@"content"]) { + NSString * type = [itemChildElement attributeForName:@"type"].stringValue; + if ([type isEqualToString:@"xhtml"]) { + articleBody = [NSMutableString stringWithString:itemChildElement.XMLString]; + } else if (type != nil && ![type isEqualToString:@"text/xml"] && ![type isEqualToString:@"text/html"] && + [type rangeOfString:@"text" options:NSRegularExpressionSearch | NSCaseInsensitiveSearch].location != NSNotFound) { + // 'type' attribute is 'text*' and not 'text/xml' nor 'text/html' + articleBody = [[NSString stringByConvertingHTMLEntities:itemChildElement.stringValue] mutableCopy]; + } else { + articleBody = [NSMutableString stringWithString:itemChildElement.stringValue]; + } + continue; + } + + // Parse item description + if (isArticleElementAtomType && [articleItemTag isEqualToString:@"summary"] && articleBody == nil) { + NSString * type = [itemChildElement attributeForName:@"type"].stringValue; + if ([type isEqualToString:@"xhtml"]) { + articleBody = [NSMutableString stringWithString:itemChildElement.XMLString]; + } else if (type != nil && ![type isEqualToString:@"text/xml"] && ![type isEqualToString:@"text/html"] && + [type rangeOfString:@"text" options:NSRegularExpressionSearch | NSCaseInsensitiveSearch].location != NSNotFound) { + // 'type' attribute is 'text*' and not 'text/xml' nor 'text/html' + articleBody = [[NSString stringByConvertingHTMLEntities:itemChildElement.stringValue] mutableCopy]; + } else { + articleBody = [NSMutableString stringWithString:itemChildElement.stringValue]; + } + continue; + } + + // Parse item author + if (isArticleElementAtomType && [articleItemTag isEqualToString:@"author"]) { + NSString * authorName = ([itemChildElement elementsForName:@"name"].firstObject).stringValue; + if (authorName == nil) { + authorName = ([itemChildElement elementsForName:@"email"].firstObject).stringValue; } // the author is in the feed's entry - if (authorName != nil) { - // if we currently have a string set as the author then append the new author name - if ([[newItem author] length] > 0) { - [newItem setAuthor:[NSString stringWithFormat:NSLocalizedString(@"%@, %@", @"{existing authors},{new author name}"), [newItem author], authorName]]; + if (authorName != nil) { + // if we currently have a string set as the author then append the new author name + if (newFeedItem.author.length > 0) { + newFeedItem.author = [NSString stringWithFormat:NSLocalizedString(@"%@, %@", @"{existing authors},{new author name}"), newFeedItem.author, authorName]; } // else we currently don't have an author set, so set it to the first author else { - [newItem setAuthor:authorName]; + newFeedItem.author = authorName; } } - continue; - } - - // Parse item link - if ([itemNodeName isEqualToString:@"link"]) - { - if ([[subItemTree valueOfAttribute:@"rel"] isEqualToString:@"enclosure"] || [[subItemTree valueOfAttribute:@"rel"] isEqualToString:@"http://opds-spec.org/acquisition"]) - { - NSString * theLink = [[subItemTree valueOfAttribute:@"href"] stringByUnescapingExtendedCharacters]; - if (theLink != nil) - { - if ((entryBaseURL != nil) && ([[NSURL URLWithString:theLink] scheme] == nil)) - { - NSURL * theLinkURL = [NSURL URLWithString:theLink relativeToURL:entryBaseURL]; - [newItem setEnclosure:(theLinkURL != nil) ? [theLinkURL absoluteString] : theLink]; - } - else - [newItem setEnclosure:theLink]; - } - } - else - { - if ([subItemTree valueOfAttribute:@"rel"] == nil || [[subItemTree valueOfAttribute:@"rel"] isEqualToString:@"alternate"]) - { - NSString * theLink = [[subItemTree valueOfAttribute:@"href"] stringByUnescapingExtendedCharacters]; - if (theLink != nil) - { - if ((entryBaseURL != nil) && ([[NSURL URLWithString:theLink] scheme] == nil)) - { - NSURL * theLinkURL = [NSURL URLWithString:theLink relativeToURL:entryBaseURL]; - [newItem setLink:(theLinkURL != nil) ? [theLinkURL absoluteString] : theLink]; - } - else - [newItem setLink:theLink]; - } - } - continue; - } - } - - // Parse item id - if ([itemNodeName isEqualToString:@"id"]) - { - [newItem setGuid:[subItemTree valueOfElement]]; - continue; - } - - // Parse item date - if ([itemNodeName isEqualToString:@"modified"]) - { - NSString * dateString = [subItemTree valueOfElement]; - NSDate * newDate = [XMLParser parseXMLDate:dateString]; - if ([newItem date] == nil || [newDate isGreaterThan:[newItem date]]) - [newItem setDate:newDate]; - continue; - } - - // Parse item date - if ([itemNodeName isEqualToString:@"created"]) - { - NSString * dateString = [subItemTree valueOfElement]; - NSDate * newDate = [XMLParser parseXMLDate:dateString]; - if ([newItem date] == nil || [newDate isGreaterThan:[newItem date]]) - [newItem setDate:newDate]; - continue; - } - - // Parse item date - if ([itemNodeName isEqualToString:@"updated"]) - { - NSString * dateString = [subItemTree valueOfElement]; - NSDate * newDate = [XMLParser parseXMLDate:dateString]; - if ([newItem date] == nil || [newDate isGreaterThan:[newItem date]]) - [newItem setDate:newDate]; - continue; - } - } - - // if we didn't find an author, set it to the default one - if ([[newItem author] isEqualToString:@""]) - [newItem setAuthor:defaultAuthor]; - - // Do relative IMG, IFRAME and A tags fixup - [articleBody fixupRelativeImgTags:entryBase]; - [articleBody fixupRelativeIframeTags:entryBase]; - [articleBody fixupRelativeAnchorTags:entryBase]; - [newItem setDescription:SafeString(articleBody)]; - - // Derive any missing title - [self ensureTitle:newItem]; - [items addObject:newItem]; - } - } - - return success; -} + continue; + } + + // Parse item link + if (isArticleElementAtomType && [articleItemTag isEqualToString:@"link"]) { + if ([[itemChildElement attributeForName:@"rel"].stringValue isEqualToString:@"enclosure"] || + [[itemChildElement attributeForName:@"rel"].stringValue isEqualToString:@"http://opds-spec.org/acquisition"]) { + NSString * theLink = ([itemChildElement attributeForName:@"href"].stringValue).stringByUnescapingExtendedCharacters; + if (theLink != nil) { + if ((entryBaseURL != nil) && ([NSURL URLWithString:theLink].scheme == nil)) { + NSURL * theLinkURL = [NSURL URLWithString:theLink relativeToURL:entryBaseURL]; + newFeedItem.enclosure = (theLinkURL != nil) ? theLinkURL.absoluteString : theLink; + } else { + newFeedItem.enclosure = theLink; + } + } + } else { + if ([itemChildElement attributeForName:@"rel"].stringValue == nil || + [[itemChildElement attributeForName:@"rel"].stringValue isEqualToString:@"alternate"]) { + NSString * theLink = ([itemChildElement attributeForName:@"href"].stringValue).stringByUnescapingExtendedCharacters; + if (theLink != nil) { + if ((entryBaseURL != nil) && ([NSURL URLWithString:theLink].scheme == nil)) { + NSURL * theLinkURL = [NSURL URLWithString:theLink relativeToURL:entryBaseURL]; + newFeedItem.link = (theLinkURL != nil) ? theLinkURL.absoluteString : theLink; + } else { + newFeedItem.link = theLink; + } + } + } + continue; + } + } + + // Parse item id + if (isArticleElementAtomType && [articleItemTag isEqualToString:@"id"]) { + newFeedItem.guid = itemChildElement.stringValue; + continue; + } + + // Parse item date + if (isArticleElementAtomType && [articleItemTag isEqualToString:@"modified"]) { + NSString * dateString = itemChildElement.stringValue; + NSDate * newDate = [NSDate parseXMLDate:dateString]; + if (newFeedItem.date == nil || [newDate isGreaterThan:newFeedItem.date]) { + newFeedItem.date = newDate; + } + continue; + } + + // Parse item date + if (isArticleElementAtomType && [articleItemTag isEqualToString:@"created"]) { + NSString * dateString = itemChildElement.stringValue; + NSDate * newDate = [NSDate parseXMLDate:dateString]; + if (newFeedItem.date == nil || [newDate isGreaterThan:newFeedItem.date]) { + newFeedItem.date = newDate; + } + continue; + } + + // Parse item date + if (isArticleElementAtomType && [articleItemTag isEqualToString:@"updated"]) { + NSString * dateString = itemChildElement.stringValue; + NSDate * newDate = [NSDate parseXMLDate:dateString]; + if (newFeedItem.date == nil || [newDate isGreaterThan:newFeedItem.date]) { + newFeedItem.date = newDate; + } + continue; + } + + // Parse associated enclosure + if ([itemChildElement.prefix isEqualToString:mediaPrefix] && [articleItemTag isEqualToString:@"content"]) { + if ([itemChildElement attributeForName:@"url"].stringValue) { + newFeedItem.enclosure = [itemChildElement attributeForName:@"url"].stringValue; + } + continue; + } + + // Parse associated enclosure + if ([itemChildElement.prefix isEqualToString:encPrefix] && [articleItemTag isEqualToString:@"enclosure"]) { + if ([itemChildElement attributeForName:@"url"].stringValue) { + newFeedItem.enclosure = [itemChildElement attributeForName:@"url"].stringValue; + } + NSString * resourceString = [NSString stringWithFormat:@"%@:resource", rdfPrefix]; + if ([itemChildElement attributeForName:resourceString].stringValue) { + newFeedItem.enclosure = [itemChildElement attributeForName:resourceString].stringValue; + } + continue; + } + } + + // if we didn't find an author, set it to the default one + if ([newFeedItem.author isEqualToString:@""]) { + newFeedItem.author = defaultAuthor; + } + + // Do relative IMG, IFRAME and A tags fixup + [articleBody fixupRelativeImgTags:entryBase]; + [articleBody fixupRelativeIframeTags:entryBase]; + [articleBody fixupRelativeAnchorTags:entryBase]; + [newFeedItem setDescription:SafeString(articleBody)]; + + // Derive any missing title + [self ensureTitle:newFeedItem]; + [items addObject:newFeedItem]; + success = YES; + } + } + + return success; +} /* initAtomFeed */ /* setTitle * Set this feed's title string. */ -(void)setTitle:(NSString *)newTitle { - [newTitle retain]; - [title release]; - title = newTitle; + title = newTitle; } /* setDescription @@ -1043,9 +764,7 @@ -(void)setTitle:(NSString *)newTitle */ -(void)setDescription:(NSString *)newDescription { - [newDescription retain]; - [description release]; - description = newDescription; + description = newDescription; } /* setLink @@ -1053,9 +772,7 @@ -(void)setDescription:(NSString *)newDescription */ -(void)setLink:(NSString *)newLink { - [newLink retain]; - [link release]; - link = newLink; + link = newLink; } /* setLastModified @@ -1063,9 +780,7 @@ -(void)setLink:(NSString *)newLink */ -(void)setLastModified:(NSDate *)newDate { - [newDate retain]; - [lastModified release]; - lastModified = newDate; + lastModified = newDate; } /* title @@ -1073,7 +788,7 @@ -(void)setLastModified:(NSDate *)newDate */ -(NSString *)title { - return title; + return title; } /* description @@ -1081,7 +796,7 @@ -(NSString *)title */ -(NSString *)description { - return description; + return description; } /* link @@ -1089,7 +804,7 @@ -(NSString *)description */ -(NSString *)link { - return link; + return link; } /* items @@ -1097,7 +812,7 @@ -(NSString *)link */ -(NSArray *)items { - return items; + return [items copy]; } /* lastModified @@ -1105,7 +820,7 @@ -(NSArray *)items */ -(NSDate *)lastModified { - return lastModified; + return lastModified; } /* ensureTitle @@ -1113,32 +828,13 @@ -(NSDate *)lastModified */ -(void)ensureTitle:(FeedItem *)item { - if (![item title] || [[item title] isBlank]) - { - NSString * newTitle = [[[item description] titleTextFromHTML] stringByUnescapingExtendedCharacters]; - if ([newTitle isBlank]) - newTitle = NSLocalizedString(@"(No title)", nil); - [item setTitle:newTitle]; - } + if (!item.title || item.title.blank) { + NSString * newTitle = item.description.titleTextFromHTML.stringByUnescapingExtendedCharacters; + if (newTitle.blank) { + newTitle = NSLocalizedString(@"(No title)", nil); + } + item.title = newTitle; + } } -/* dealloc - * Clean up afterwards. - */ --(void)dealloc -{ - [orderArray release]; - orderArray=nil; - [title release]; - title=nil; - [description release]; - description=nil; - [lastModified release]; - lastModified=nil; - [link release]; - link=nil; - [items release]; - items=nil; - [super dealloc]; -} @end diff --git a/src/SSTextField.m b/src/SSTextField.m index d7770b8698..a056f7638a 100644 --- a/src/SSTextField.m +++ b/src/SSTextField.m @@ -13,20 +13,20 @@ @implementation SSTextField -- (id)initWithCoder:(NSCoder *)coder { +- (instancetype)initWithCoder:(NSCoder *)coder { self = [super initWithCoder:coder]; if (self) { [self setDrawsBackground:NO]; - if ([[self cell] controlSize] == NSMiniControlSize) { // doesn't work well for mini size - text needs to be adjusted up - [self setFont:[NSFont systemFontOfSize:8.0]]; + if (self.cell.controlSize == NSMiniControlSize) { // doesn't work well for mini size - text needs to be adjusted up + self.font = [NSFont systemFontOfSize:8.0]; } - else if ([[self cell] controlSize] == NSSmallControlSize) { - [self setFont:[NSFont systemFontOfSize:9.4]]; + else if (self.cell.controlSize == NSSmallControlSize) { + self.font = [NSFont systemFontOfSize:9.4]; } else { - [self setFont:[NSFont systemFontOfSize:12.88]]; + self.font = [NSFont systemFontOfSize:12.88]; } } @@ -36,37 +36,37 @@ - (id)initWithCoder:(NSCoder *)coder { - (void)drawRect:(NSRect)dirtyRect { // bottom white highlight - NSRect hightlightFrame = NSMakeRect(0.0, 10.0, [self bounds].size.width, [self bounds].size.height-10.0); + NSRect hightlightFrame = NSMakeRect(0.0, 10.0, self.bounds.size.width, self.bounds.size.height-10.0); [[NSColor colorWithCalibratedWhite:1.0 alpha:0.394] set]; [[NSBezierPath bezierPathWithRoundedRect:hightlightFrame xRadius:3.6 yRadius:3.6] fill]; // black outline - NSRect blackOutlineFrame = NSMakeRect(0.0, 0.0, [self bounds].size.width, [self bounds].size.height-1.0); + NSRect blackOutlineFrame = NSMakeRect(0.0, 0.0, self.bounds.size.width, self.bounds.size.height-1.0); NSGradient *gradient = nil; - if ([NSApp isActive]) { - gradient = [[[NSGradient alloc] initWithStartingColor:[NSColor colorWithCalibratedWhite:0.24 alpha:1.0] endingColor:[NSColor colorWithCalibratedWhite:0.374 alpha:1.0]] autorelease]; + if (NSApp.active) { + gradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithCalibratedWhite:0.24 alpha:1.0] endingColor:[NSColor colorWithCalibratedWhite:0.374 alpha:1.0]]; } else { - gradient = [[[NSGradient alloc] initWithStartingColor:[NSColor colorWithCalibratedWhite:0.55 alpha:1.0] endingColor:[NSColor colorWithCalibratedWhite:0.558 alpha:1.0]] autorelease]; + gradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithCalibratedWhite:0.55 alpha:1.0] endingColor:[NSColor colorWithCalibratedWhite:0.558 alpha:1.0]]; } [gradient drawInBezierPath:[NSBezierPath bezierPathWithRoundedRect:blackOutlineFrame xRadius:3.6 yRadius:3.6] angle:90]; // top inner shadow - NSRect shadowFrame = NSMakeRect(1, 1, [self bounds].size.width-2.0, 10.0); + NSRect shadowFrame = NSMakeRect(1, 1, self.bounds.size.width-2.0, 10.0); [[NSColor colorWithCalibratedWhite:0.88 alpha:1.0] set]; [[NSBezierPath bezierPathWithRoundedRect:shadowFrame xRadius:2.9 yRadius:2.9] fill]; // main white area - NSRect whiteFrame = NSMakeRect(1, 2, [self bounds].size.width-2.0, [self bounds].size.height-4.0); + NSRect whiteFrame = NSMakeRect(1, 2, self.bounds.size.width-2.0, self.bounds.size.height-4.0); [[NSColor whiteColor] set]; [[NSBezierPath bezierPathWithRoundedRect:whiteFrame xRadius:2.6 yRadius:2.6] fill]; // draw the keyboard focus ring if we're the first responder and the application is active - if (([[self window] firstResponder] == [self currentEditor]) && [NSApp isActive]) + if ((self.window.firstResponder == [self currentEditor]) && NSApp.active) { [NSGraphicsContext saveGraphicsState]; NSSetFocusRingStyle(NSFocusRingOnly); @@ -77,7 +77,7 @@ - (void)drawRect:(NSRect)dirtyRect { // I don't like that the point to draw at is hard-coded, but it works for now // VIENNA-DEVS: We change this to 23.0 from the left to leave room for the favicon - [[self attributedStringValue] drawInRect:NSMakeRect(23.0, 3.0, [self bounds].size.width-8.0, [self bounds].size.width-6.0)]; + [self.attributedStringValue drawInRect:NSMakeRect(23.0, 3.0, self.bounds.size.width-8.0, self.bounds.size.width-6.0)]; } } diff --git a/src/SearchFolder.h b/src/SearchFolder.h index 26eedabd73..2e9cddac6a 100644 --- a/src/SearchFolder.h +++ b/src/SearchFolder.h @@ -42,12 +42,14 @@ NSMutableArray * arrayOfViews; Database * db; NSRect searchWindowFrame; - int smartFolderId; - int totalCriteria; - int parentId; + NSInteger smartFolderId; + NSInteger totalCriteria; + NSInteger parentId; BOOL firstRun; } +@property(strong) NSArray * topObjects; + // Action routines -(IBAction)doSave:(id)sender; -(IBAction)doCancel:(id)sender; @@ -56,9 +58,9 @@ -(IBAction)fieldChanged:(id)sender; // Public functions --(void)newCriteria:(NSWindow *)window underParent:(int)itemId; --(void)loadCriteria:(NSWindow *)window folderId:(int)folderId; +-(void)newCriteria:(NSWindow *)window underParent:(NSInteger)itemId; +-(void)loadCriteria:(NSWindow *)window folderId:(NSInteger)folderId; // General functions --(id)initWithDatabase:(Database *)newDb; +-(instancetype)initWithDatabase:(Database *)newDb /*NS_DESIGNATED_INITIALIZER*/; @end diff --git a/src/SearchFolder.m b/src/SearchFolder.m index 6eb2a3c91f..27af93fe9a 100644 --- a/src/SearchFolder.m +++ b/src/SearchFolder.m @@ -37,14 +37,14 @@ #define MA_SFEdit_FolderValueTag 1008 @interface SmartFolder (Private) - -(void)initFolderValueField:(int)parentId atIndent:(int)indentation; + -(void)initFolderValueField:(NSInteger)parentId atIndent:(NSInteger)indentation; -(void)initSearchSheet:(NSString *)folderName; -(void)displaySearchSheet:(NSWindow *)window; -(void)initForField:(NSString *)fieldName inRow:(NSView *)row; - -(void)setOperatorsPopup:(NSPopUpButton *)popUpButton, ...; - -(void)addCriteria:(NSUInteger )index; - -(void)addDefaultCriteria:(int)index; - -(void)removeCriteria:(int)index; + -(void)setOperatorsPopup:(NSPopUpButton *)popUpButton operators:(NSArray *)operators; + -(void)addCriteria:(NSUInteger)index; + -(void)addDefaultCriteria:(NSInteger)index; + -(void)removeCriteria:(NSInteger)index; -(void)removeAllCriteria; -(void)resizeSearchWindow; @end @@ -54,7 +54,7 @@ @implementation SmartFolder /* initWithDatabase * Just init the search criteria class. */ --(id)initWithDatabase:(Database *)newDb +-(instancetype)initWithDatabase:(Database *)newDb { if ((self = [super init]) != nil) { @@ -72,7 +72,7 @@ -(id)initWithDatabase:(Database *)newDb * Initialises the smart folder panel with a single empty criteria to get * started. */ --(void)newCriteria:(NSWindow *)window underParent:(int)itemId +-(void)newCriteria:(NSWindow *)window underParent:(NSInteger)itemId { [self initSearchSheet:@""]; smartFolderId = -1; @@ -87,14 +87,14 @@ -(void)newCriteria:(NSWindow *)window underParent:(int)itemId /* loadCriteria * Loads the criteria for the specified folder. */ --(void)loadCriteria:(NSWindow *)window folderId:(int)folderId +-(void)loadCriteria:(NSWindow *)window folderId:(NSInteger)folderId { Folder * folder = [db folderFromID:folderId]; if (folder != nil) { - int index = 0; + NSInteger index = 0; - [self initSearchSheet:[folder name]]; + [self initSearchSheet:folder.name]; smartFolderId = folderId; [smartFolderName setEnabled:YES]; @@ -102,17 +102,17 @@ -(void)loadCriteria:(NSWindow *)window folderId:(int)folderId CriteriaTree * criteriaTree = [db searchStringForSmartFolder:folderId]; // Set the criteria condition - [criteriaConditionPopup selectItemWithTag:[criteriaTree condition]]; + [criteriaConditionPopup selectItemWithTag:criteriaTree.condition]; - for (Criteria * criteria in [criteriaTree criteriaEnumerator]) + for (Criteria * criteria in criteriaTree.criteriaEnumerator) { - [self initForField:[criteria field] inRow:searchCriteriaView]; + [self initForField:criteria.field inRow:searchCriteriaView]; [fieldNamePopup selectItemWithTitle:NSLocalizedString([criteria field], nil)]; [operatorPopup selectItemWithTitle:NSLocalizedString([Criteria stringFromOperator:[criteria operator]], nil)]; - Field * field = [nameToFieldMap valueForKey:[criteria field]]; - switch ([field type]) + Field * field = [nameToFieldMap valueForKey:criteria.field]; + switch (field.type) { case MA_FieldType_Flag: { [flagValueField selectItemWithTitle:NSLocalizedString([criteria value], nil)]; @@ -120,24 +120,24 @@ -(void)loadCriteria:(NSWindow *)window folderId:(int)folderId } case MA_FieldType_Folder: { - Folder * folder = [db folderFromName:[criteria value]]; + Folder * folder = [db folderFromName:criteria.value]; if (folder != nil) - [folderValueField selectItemWithTitle:[folder name]]; + [folderValueField selectItemWithTitle:folder.name]; break; } case MA_FieldType_String: { - [valueField setStringValue:[criteria value]]; + valueField.stringValue = criteria.value; break; } case MA_FieldType_Integer: { - [numberValueField setStringValue:[criteria value]]; + numberValueField.stringValue = criteria.value; break; } case MA_FieldType_Date: { - [dateValueField selectItemAtIndex:[dateValueField indexOfItemWithRepresentedObject:[criteria value]]]; + [dateValueField selectItemAtIndex:[dateValueField indexOfItemWithRepresentedObject:criteria.value]]; break; } } @@ -163,7 +163,9 @@ -(void)initSearchSheet:(NSString *)folderName // Initialize UI if (!searchWindow) { - [NSBundle loadNibNamed:@"SearchFolder" owner:self]; + NSArray * objects; + [[NSBundle bundleForClass:[self class]] loadNibNamed:@"SearchFolder" owner:self topLevelObjects:&objects]; + self.topObjects = objects; // Register our notifications [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleTextDidChange:) name:NSControlTextDidChangeNotification object:smartFolderName]; @@ -177,17 +179,17 @@ -(void)initSearchSheet:(NSString *)folderName [fieldNamePopup removeAllItems]; for (Field * field in [db arrayOfFields]) { - if ([field tag] != MA_FieldID_Headlines && - [field tag] != MA_FieldID_GUID && - [field tag] != MA_FieldID_Link && - [field tag] != MA_FieldID_Comments && - [field tag] != MA_FieldID_Summary && - [field tag] != MA_FieldID_Parent && - [field tag] != MA_FieldID_Enclosure && - [field tag] != MA_FieldID_EnclosureDownloaded) + if (field.tag != MA_FieldID_Headlines && + field.tag != MA_FieldID_GUID && + field.tag != MA_FieldID_Link && + field.tag != MA_FieldID_Comments && + field.tag != MA_FieldID_Summary && + field.tag != MA_FieldID_Parent && + field.tag != MA_FieldID_Enclosure && + field.tag != MA_FieldID_EnclosureDownloaded) { - [fieldNamePopup addItemWithRepresentedObject:[field displayName] object:field]; - [nameToFieldMap setValue:field forKey:[field name]]; + [fieldNamePopup addItemWithRepresentedObject:field.displayName object:field]; + [nameToFieldMap setValue:field forKey:field.name]; } } @@ -228,8 +230,8 @@ -(void)initSearchSheet:(NSString *)folderName [self initFolderValueField:MA_Root_Folder atIndent:0]; // Init the folder name field and disable the Save button if it is blank - [smartFolderName setStringValue:folderName]; - [saveButton setEnabled:![folderName isBlank]]; + smartFolderName.stringValue = folderName; + saveButton.enabled = !folderName.blank; } /* initFolderValueField @@ -238,18 +240,18 @@ -(void)initSearchSheet:(NSString *)folderName * is used to indent the items in the menu when they are part of a group. I've used * an increment of 2 which looks clearer than 1 in the UI. */ --(void)initFolderValueField:(int)fromId atIndent:(int)indentation +-(void)initFolderValueField:(NSInteger)fromId atIndent:(NSInteger)indentation { - for (Folder * folder in [db arrayOfFolders:fromId]) + for (Folder * folder in [[db arrayOfFolders:fromId] sortedArrayUsingSelector:@selector(folderNameCompare:)]) { if (IsRSSFolder(folder)||IsGoogleReaderFolder(folder)||IsGroupFolder(folder)) { - [folderValueField addItemWithTitle:[folder name]]; - NSMenuItem * menuItem = [folderValueField itemWithTitle:[folder name]]; - [menuItem setImage:[folder image]]; - [menuItem setIndentationLevel:indentation]; + [folderValueField addItemWithTitle:folder.name]; + NSMenuItem * menuItem = [folderValueField itemWithTitle:folder.name]; + menuItem.image = folder.image; + menuItem.indentationLevel = indentation; if (IsGroupFolder(folder)) - [self initFolderValueField:[folder itemId] atIndent:indentation + 2]; + [self initFolderValueField:folder.itemId atIndent:indentation + 2]; } } } @@ -268,7 +270,7 @@ -(void)displaySearchSheet:(NSWindow *)window // it back to it's default size. if (firstRun) { - searchWindowFrame = [NSWindow contentRectForFrameRect:[searchWindow frame] styleMask:[searchWindow styleMask]]; + searchWindowFrame = [NSWindow contentRectForFrameRect:searchWindow.frame styleMask:searchWindow.styleMask]; firstRun = NO; } } @@ -278,7 +280,7 @@ -(void)displaySearchSheet:(NSWindow *)window */ -(IBAction)removeCurrentCriteria:(id)sender { - int index = [arrayOfViews indexOfObject:[sender superview]]; + NSInteger index = [arrayOfViews indexOfObject:[sender superview]]; NSAssert(index >= 0 && index < totalCriteria, @"Got an out of bounds index of view in superview"); [self removeCriteria:index]; [self resizeSearchWindow]; @@ -289,7 +291,7 @@ -(IBAction)removeCurrentCriteria:(id)sender */ -(IBAction)addNewCriteria:(id)sender { - int index = [arrayOfViews indexOfObject:[sender superview]]; + NSInteger index = [arrayOfViews indexOfObject:[sender superview]]; NSAssert(index >= 0 && index < totalCriteria, @"Got an out of bounds index of view in superview"); [self addDefaultCriteria:index + 1]; [self resizeSearchWindow]; @@ -299,13 +301,13 @@ -(IBAction)addNewCriteria:(id)sender * Add a new default criteria row. For this we use the static defaultField declared at * the start of this source and the default operator for that field, and an empty value. */ --(void)addDefaultCriteria:(int)index +-(void)addDefaultCriteria:(NSInteger)index { Field * defaultField = [db fieldByName:MA_Field_Read]; - [self initForField:[defaultField name] inRow:searchCriteriaView]; - [fieldNamePopup selectItemWithTitle:[defaultField displayName]]; - [valueField setStringValue:@""]; + [self initForField:defaultField.name inRow:searchCriteriaView]; + [fieldNamePopup selectItemWithTitle:defaultField.displayName]; + valueField.stringValue = @""; [self addCriteria:index]; } @@ -316,7 +318,7 @@ -(void)addDefaultCriteria:(int)index -(IBAction)fieldChanged:(id)sender { Field * field = [sender representedObjectForSelection]; - [self initForField:[field name] inRow:[sender superview]]; + [self initForField:field.name inRow:[sender superview]]; } /* initForField @@ -330,49 +332,49 @@ -(void)initForField:(NSString *)fieldName inRow:(NSView *)row // Need to flip on the operator popup for the field that changed NSPopUpButton * theOperatorPopup = [row viewWithTag:MA_SFEdit_OperatorTag]; [theOperatorPopup removeAllItems]; - switch ([field type]) + switch (field.type) { case MA_FieldType_Flag: - [self setOperatorsPopup:theOperatorPopup, - MA_CritOper_Is, - 0]; + [self setOperatorsPopup:theOperatorPopup operators:@[ + @(MA_CritOper_Is)] + ]; break; case MA_FieldType_Folder: - [self setOperatorsPopup:theOperatorPopup, - MA_CritOper_Is, - MA_CritOper_IsNot, - 0]; + [self setOperatorsPopup:theOperatorPopup operators:@[ + @(MA_CritOper_Is), + @(MA_CritOper_IsNot)] + ]; break; case MA_FieldType_String: - [self setOperatorsPopup:theOperatorPopup, - MA_CritOper_Is, - MA_CritOper_IsNot, - MA_CritOper_Contains, - MA_CritOper_NotContains, - 0]; + [self setOperatorsPopup:theOperatorPopup operators:@[ + @(MA_CritOper_Is), + @(MA_CritOper_IsNot), + @(MA_CritOper_Contains), + @(MA_CritOper_NotContains)] + ]; break; case MA_FieldType_Integer: - [self setOperatorsPopup:theOperatorPopup, - MA_CritOper_Is, - MA_CritOper_IsNot, - MA_CritOper_IsGreaterThan, - MA_CritOper_IsGreaterThanOrEqual, - MA_CritOper_IsLessThan, - MA_CritOper_IsLessThanOrEqual, - 0]; + [self setOperatorsPopup:theOperatorPopup operators:@[ + @(MA_CritOper_Is), + @(MA_CritOper_IsNot), + @(MA_CritOper_IsGreaterThan), + @(MA_CritOper_IsGreaterThanOrEqual), + @(MA_CritOper_IsLessThan), + @(MA_CritOper_IsLessThanOrEqual)] + ]; break; case MA_FieldType_Date: - [self setOperatorsPopup:theOperatorPopup, - MA_CritOper_Is, - MA_CritOper_IsAfter, - MA_CritOper_IsBefore, - MA_CritOper_IsOnOrAfter, - MA_CritOper_IsOnOrBefore, - 0]; + [self setOperatorsPopup:theOperatorPopup operators:@[ + @(MA_CritOper_Is), + @(MA_CritOper_IsAfter), + @(MA_CritOper_IsBefore), + @(MA_CritOper_IsOnOrAfter), + @(MA_CritOper_IsOnOrBefore)] + ]; break; } @@ -383,24 +385,21 @@ -(void)initForField:(NSString *)fieldName inRow:(NSView *)row NSView * theDateValueField = [row viewWithTag:MA_SFEdit_DateValueTag]; NSView * theFolderValueField = [row viewWithTag:MA_SFEdit_FolderValueTag]; - [theFlagValueField setHidden:[field type] != MA_FieldType_Flag]; - [theValueField setHidden:[field type] != MA_FieldType_String]; - [theDateValueField setHidden:[field type] != MA_FieldType_Date]; - [theNumberValueField setHidden:[field type] != MA_FieldType_Integer]; - [theFolderValueField setHidden:[field type] != MA_FieldType_Folder]; + theFlagValueField.hidden = field.type != MA_FieldType_Flag; + theValueField.hidden = field.type != MA_FieldType_String; + theDateValueField.hidden = field.type != MA_FieldType_Date; + theNumberValueField.hidden = field.type != MA_FieldType_Integer; + theFolderValueField.hidden = field.type != MA_FieldType_Folder; } /* setOperatorsPopup * Fills the specified pop up button field with a list of valid operators. */ --(void)setOperatorsPopup:(NSPopUpButton *)popUpButton, ... +-(void)setOperatorsPopup:(NSPopUpButton *)popUpButton operators:(NSArray *)operators { - va_list arguments; - va_start(arguments, popUpButton); - CriteriaOperator operator; - - while ((operator = va_arg(arguments, int)) != 0) + for ( NSNumber * number in operators ) { + CriteriaOperator operator = [number integerValue]; NSString * operatorString = NSLocalizedString([Criteria stringFromOperator:operator], nil); [popUpButton addItemWithTag:operatorString tag:operator]; } @@ -412,13 +411,13 @@ -(void)setOperatorsPopup:(NSPopUpButton *)popUpButton, ... */ -(IBAction)doSave:(id)sender { - NSString * folderName = [[smartFolderName stringValue] trim]; + NSString * folderName = (smartFolderName.stringValue).trim; NSAssert(![folderName isBlank], @"doSave called with empty folder name"); NSUInteger c; // Check whether there is another folder with the same name. Folder * folder = [db folderFromName:folderName]; - if (folder != nil && [folder itemId] != smartFolderId) + if (folder != nil && folder.itemId != smartFolderId) { runOKAlertPanel(NSLocalizedString(@"Cannot rename folder", nil), NSLocalizedString(@"A folder with that name already exists", nil)); return; @@ -426,64 +425,60 @@ -(IBAction)doSave:(id)sender // Build the criteria string CriteriaTree * criteriaTree = [[CriteriaTree alloc] init]; - for (c = 0; c < [arrayOfViews count]; ++c) + for (c = 0; c < arrayOfViews.count; ++c) { - NSView * row = [arrayOfViews objectAtIndex:c]; + NSView * row = arrayOfViews[c]; NSPopUpButton * theField = [row viewWithTag:MA_SFEdit_FieldTag]; NSPopUpButton * theOperator = [row viewWithTag:MA_SFEdit_OperatorTag]; - Field * field = [theField representedObjectForSelection]; - CriteriaOperator operator = [theOperator tagForSelection]; + Field * field = theField.representedObjectForSelection; + CriteriaOperator operator = theOperator.tagForSelection; NSString * valueString; - if ([field type] == MA_FieldType_Flag) + if (field.type == MA_FieldType_Flag) { NSPopUpButton * theValue = [row viewWithTag:MA_SFEdit_FlagValueTag]; - valueString = [theValue representedObjectForSelection]; + valueString = theValue.representedObjectForSelection; } - else if ([field type] == MA_FieldType_Date) + else if (field.type == MA_FieldType_Date) { NSPopUpButton * theValue = [row viewWithTag:MA_SFEdit_DateValueTag]; - valueString = [theValue representedObjectForSelection]; + valueString = theValue.representedObjectForSelection; } - else if ([field type] == MA_FieldType_Folder) + else if (field.type == MA_FieldType_Folder) { NSPopUpButton * theValue = [row viewWithTag:MA_SFEdit_FolderValueTag]; - valueString = [theValue titleOfSelectedItem]; + valueString = theValue.titleOfSelectedItem; } - else if ([field type] == MA_FieldType_Integer) + else if (field.type == MA_FieldType_Integer) { NSTextField * theValue = [row viewWithTag:MA_SFEdit_NumberValueTag]; - valueString = [theValue stringValue]; + valueString = theValue.stringValue; } else { NSTextField * theValue = [row viewWithTag:MA_SFEdit_ValueTag]; - valueString = [theValue stringValue]; + valueString = theValue.stringValue; } - Criteria * newCriteria = [[Criteria alloc] initWithField:[field name] withOperator:operator withValue:valueString]; + Criteria * newCriteria = [[Criteria alloc] initWithField:field.name withOperator:operator withValue:valueString]; [criteriaTree addCriteria:newCriteria]; - [newCriteria release]; } // Set the criteria condition - [criteriaTree setCondition:[criteriaConditionPopup selectedTag]]; + criteriaTree.condition = criteriaConditionPopup.selectedTag; - [db doTransactionWithBlock:^(BOOL *rollback) { if (smartFolderId == -1) { AppController * controller = APPCONTROLLER; - smartFolderId = [db addSmartFolder:folderName underParent:parentId withQuery:criteriaTree]; + smartFolderId = [[Database sharedManager] addSmartFolder:folderName underParent:parentId withQuery:criteriaTree]; [controller selectFolder:smartFolderId]; } else { - [db updateSearchFolder:smartFolderId withFolder:folderName withQuery:criteriaTree]; + [[Database sharedManager] updateSearchFolder:smartFolderId withFolder:folderName withQuery:criteriaTree]; } - }]; //end transaction block - [criteriaTree release]; [NSApp endSheet:searchWindow]; [searchWindow orderOut:self]; @@ -503,8 +498,8 @@ -(IBAction)doCancel:(id)sender */ -(void)handleTextDidChange:(NSNotification *)aNotification { - NSString * folderName = [smartFolderName stringValue]; - [saveButton setEnabled:![folderName isBlank]]; + NSString * folderName = smartFolderName.stringValue; + saveButton.enabled = !folderName.blank; } /* removeAllCriteria @@ -512,12 +507,12 @@ -(void)handleTextDidChange:(NSNotification *)aNotification */ -(void)removeAllCriteria { - int c; + NSInteger c; - NSArray * subviews = [searchCriteriaSuperview subviews]; - for (c = [subviews count] - 1; c >= 0; --c) + NSArray * subviews = searchCriteriaSuperview.subviews; + for (c = subviews.count - 1; c >= 0; --c) { - NSView * row = [subviews objectAtIndex:c]; + NSView * row = subviews[c]; [row removeFromSuperview]; } [arrayOfViews removeAllObjects]; @@ -527,17 +522,17 @@ -(void)removeAllCriteria /* removeCriteria * Remove the criteria at the specified index. */ --(void)removeCriteria:(int)index +-(void)removeCriteria:(NSInteger)index { - int rowHeight = [searchCriteriaView frame].size.height; - int c; + NSInteger rowHeight = searchCriteriaView.frame.size.height; + NSInteger c; // Do nothing if there's just one criteria if (totalCriteria <= 1) return; // Remove the view from the parent view - NSView * row = [arrayOfViews objectAtIndex:index]; + NSView * row = arrayOfViews[index]; [row removeFromSuperview]; [arrayOfViews removeObject:row]; --totalCriteria; @@ -545,8 +540,8 @@ -(void)removeCriteria:(int)index // Shift the subviews for (c = 0; c < index; ++c) { - NSView * row = [arrayOfViews objectAtIndex:c]; - NSPoint origin = [row frame].origin; + NSView * row = arrayOfViews[c]; + NSPoint origin = row.frame.origin; [row setFrameOrigin:NSMakePoint(origin.x, origin.y - rowHeight)]; } } @@ -555,11 +550,11 @@ -(void)removeCriteria:(int)index * Add a new criteria clause. Before calling this function, initialise the * searchView with the settings to be added. */ --(void)addCriteria:(NSUInteger )index +-(void)addCriteria:(NSUInteger)index { NSData * archRow; NSView * previousRow = nil; - int rowHeight = [searchCriteriaView frame].size.height; + NSInteger rowHeight = searchCriteriaView.frame.size.height; NSUInteger c; // Bump up the criteria count @@ -568,22 +563,22 @@ -(void)addCriteria:(NSUInteger )index [self resizeSearchWindow]; // Shift the existing subviews up by rowHeight - if (index > [arrayOfViews count]) - index = [arrayOfViews count]; + if (index > arrayOfViews.count) + index = arrayOfViews.count; for (c = 0; c < index; ++c) { - NSView * row = [arrayOfViews objectAtIndex:c]; - NSPoint origin = [row frame].origin; + NSView * row = arrayOfViews[c]; + NSPoint origin = row.frame.origin; [row setFrameOrigin:NSMakePoint(origin.x, origin.y + rowHeight)]; previousRow = row; } // Now add the new subview archRow = [NSArchiver archivedDataWithRootObject:searchCriteriaView]; - NSRect bounds = [searchCriteriaSuperview bounds]; + NSRect bounds = searchCriteriaSuperview.bounds; NSView * row = (NSView *)[NSUnarchiver unarchiveObjectWithData:archRow]; [row setFrameOrigin:NSMakePoint(bounds.origin.x, bounds.origin.y + (((totalCriteria - 1) - index) * rowHeight))]; - [searchCriteriaSuperview addSubview:[row retain]]; + [searchCriteriaSuperview addSubview:row]; [arrayOfViews insertObject:row atIndex:index]; // Link the previous row to the next one so that the Tab key behaves @@ -591,12 +586,11 @@ -(void)addCriteria:(NSUInteger )index // BUGBUG: This doesn't work and I can't figure out why not yet. This needs to be fixed. if (previousRow) { - NSView * lastKeyView = [previousRow nextKeyView]; - [previousRow setNextKeyView:row]; - [row setNextKeyView:lastKeyView]; + NSView * lastKeyView = previousRow.nextKeyView; + previousRow.nextKeyView = row; + row.nextKeyView = lastKeyView; } [searchCriteriaSuperview display]; - [row release]; } /* resizeSearchWindow @@ -609,12 +603,12 @@ -(void)resizeSearchWindow newFrame = searchWindowFrame; if (totalCriteria > 0) { - int rowHeight = [searchCriteriaView frame].size.height; - int newHeight = newFrame.size.height + rowHeight * (totalCriteria - 1); + NSInteger rowHeight = searchCriteriaView.frame.size.height; + NSInteger newHeight = newFrame.size.height + rowHeight * (totalCriteria - 1); newFrame.origin.y += newFrame.size.height; newFrame.origin.y -= newHeight; newFrame.size.height = newHeight; - newFrame = [NSWindow frameRectForContentRect:newFrame styleMask:[searchWindow styleMask]]; + newFrame = [NSWindow frameRectForContentRect:newFrame styleMask:searchWindow.styleMask]; } [searchWindow setFrame:newFrame display:YES animate:YES]; } @@ -625,12 +619,5 @@ -(void)resizeSearchWindow -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - [arrayOfViews release]; - arrayOfViews=nil; - [nameToFieldMap release]; - nameToFieldMap=nil; - [db release]; - db=nil; - [super dealloc]; } @end diff --git a/src/SearchMethod.h b/src/SearchMethod.h index aaeeda78ee..78785e09d0 100644 --- a/src/SearchMethod.h +++ b/src/SearchMethod.h @@ -18,6 +18,8 @@ // limitations under the License. // +@import Foundation; + @interface SearchMethod : NSObject { NSString * friendlyName; NSString * searchQueryString; @@ -28,13 +30,10 @@ +(SearchMethod *)searchCurrentWebPageMethod; +(NSArray *)builtInSearchMethods; --(id)initWithDictionary:(NSDictionary *)dict; // Designated initializer. +-(instancetype)initWithDictionary:(NSDictionary *)dict /*NS_DESIGNATED_INITIALIZER*/; -(NSURL *)queryURLforSearchString:(NSString *)searchString; --(NSString *)searchQueryString; --(void)setSearchQueryString:(NSString *)newQueryString; --(NSString *)friendlyName; --(void)setFriendlyName:(NSString *)newName; --(void)setHandler:(SEL)theHandler; --(SEL)handler; +@property (nonatomic, copy) NSString *searchQueryString; +@property (nonatomic, copy) NSString *friendlyName; +@property (nonatomic) SEL handler; -@end \ No newline at end of file +@end diff --git a/src/SearchMethod.m b/src/SearchMethod.m index dbf18ef598..9e9dee5656 100644 --- a/src/SearchMethod.m +++ b/src/SearchMethod.m @@ -28,7 +28,7 @@ @implementation SearchMethod /* init * Create an "empty" search method that will not do anything on its own. */ --(id)init +-(instancetype)init { if ((self = [super init]) != nil) { @@ -44,7 +44,7 @@ -(id)init * of doing different things with searches according to the plugin definition. * At the moment, however, we only ever do a normal web-search.*/ --(id)initWithDictionary:(NSDictionary *)dict +-(instancetype)initWithDictionary:(NSDictionary *)dict { if ((self = [super init]) != nil) { @@ -64,12 +64,12 @@ - (void)encodeWithCoder:(NSCoder *)coder; [coder encodeValueOfObjCType:@encode(SEL) at:&handler]; } -- (id)initWithCoder:(NSCoder *)coder; +- (instancetype)initWithCoder:(NSCoder *)coder; { if ((self = [super init]) != nil) { - [self setFriendlyName:[coder decodeObjectForKey:@"friendlyName"]]; - [self setSearchQueryString:[coder decodeObjectForKey:@"searchQueryString"]]; + self.friendlyName = [coder decodeObjectForKey:@"friendlyName"]; + self.searchQueryString = [coder decodeObjectForKey:@"searchQueryString"]; [coder decodeValueOfObjCType:@encode(SEL) at:&handler]; } return self; @@ -84,7 +84,7 @@ - (id)initWithCoder:(NSCoder *)coder; */ +(NSArray *)builtInSearchMethods { - return [NSArray arrayWithObjects: [SearchMethod searchAllArticlesMethod], [SearchMethod searchCurrentWebPageMethod], nil]; + return @[[SearchMethod searchAllArticlesMethod], [SearchMethod searchCurrentWebPageMethod]]; } /* searchAllArticlesMethod @@ -93,10 +93,10 @@ +(NSArray *)builtInSearchMethods +(SearchMethod *)searchAllArticlesMethod { SearchMethod * method = [[SearchMethod alloc] init]; - [method setFriendlyName:@"Search all articles"]; - [method setHandler:@selector(performAllArticlesSearch)]; + method.friendlyName = @"Search all articles"; + method.handler = @selector(performAllArticlesSearch); - return [method autorelease]; + return method; } /* searchCurrentWebPageMethod @@ -106,10 +106,10 @@ +(SearchMethod *)searchAllArticlesMethod +(SearchMethod *)searchCurrentWebPageMethod { SearchMethod * method = [[SearchMethod alloc] init]; - [method setFriendlyName:@"Search current web page"]; - [method setHandler:@selector(performWebPageSearch)]; + method.friendlyName = @"Search current web page"; + method.handler = @selector(performWebPageSearch); - return [method autorelease]; + return method; } # pragma mark Instance Methods @@ -120,7 +120,7 @@ +(SearchMethod *)searchCurrentWebPageMethod - (NSURL *)queryURLforSearchString:(NSString *)searchString; { NSURL * queryURL; - NSString * temp = [[self searchQueryString] stringByReplacingOccurrencesOfString:@"$SearchTerm$" withString:searchString]; + NSString * temp = [self.searchQueryString stringByReplacingOccurrencesOfString:@"$SearchTerm$" withString:searchString]; queryURL = cleanedUpAndEscapedUrlFromString(temp); return queryURL; } @@ -132,8 +132,7 @@ - (NSURL *)queryURLforSearchString:(NSString *)searchString; */ -(void)setFriendlyName:(NSString *) newName { - [friendlyName release]; - friendlyName = [newName retain]; + friendlyName = newName; } /* friendlyName @@ -149,8 +148,7 @@ -(NSString *)friendlyName */ -(void)setSearchQueryString:(NSString *) newQueryString { - [searchQueryString release]; - searchQueryString = [newQueryString retain]; + searchQueryString = newQueryString; } /* searchQueryString @@ -179,13 +177,4 @@ -(SEL)handler return handler; } --(void)dealloc -{ - [friendlyName release]; - friendlyName=nil; - [searchQueryString release]; - searchQueryString=nil; - [super dealloc]; -} - @end diff --git a/src/SearchPanel.h b/src/SearchPanel.h index d4d54d0901..6a7859f7aa 100644 --- a/src/SearchPanel.h +++ b/src/SearchPanel.h @@ -27,6 +27,8 @@ IBOutlet NSTextField * searchLabel; } +@property(strong) NSArray * topObjects; + // Public functions -(IBAction)searchStringChanged:(id)sender; -(void)runSearchPanel:(NSWindow *)window; diff --git a/src/SearchPanel.m b/src/SearchPanel.m index 0b5c197255..bcc7d4536a 100644 --- a/src/SearchPanel.m +++ b/src/SearchPanel.m @@ -25,7 +25,7 @@ // Pull in the private functions we need from the delegate @interface AppController (Private) --(NSMenu *)searchFieldMenu; +@property (nonatomic, readonly, copy) NSMenu *searchFieldMenu; -(void)searchArticlesWithString:(NSString *)searchString; @end @@ -38,8 +38,10 @@ -(void)runSearchPanel:(NSWindow *)window { if (!searchPanelWindow) { - [NSBundle loadNibNamed:@"SearchPanel" owner:self]; - [[searchField cell] setSearchMenuTemplate:[APPCONTROLLER searchFieldMenu]]; + NSArray * objects; + [[NSBundle bundleForClass:[self class]] loadNibNamed:@"SearchPanel" owner:self topLevelObjects:&objects]; + self.topObjects = objects; + ((NSSearchFieldCell *)searchField.cell).searchMenuTemplate = APPCONTROLLER.searchFieldMenu; } [searchLabel setStringValue:NSLocalizedString(@"Search all articles or the current web page", nil)]; [NSApp beginSheet:searchPanelWindow modalForWindow:window modalDelegate:nil didEndSelector:nil contextInfo:nil]; @@ -50,7 +52,7 @@ -(void)runSearchPanel:(NSWindow *)window */ -(void)setSearchString:(NSString *)newSearchString { - [searchField setStringValue:newSearchString]; + searchField.stringValue = newSearchString; } /* searchStringChanged @@ -60,16 +62,16 @@ -(void)setSearchString:(NSString *)newSearchString */ -(IBAction)searchStringChanged:(id)sender; { - [APPCONTROLLER setSearchString:[searchField stringValue]]; + APPCONTROLLER.searchString = searchField.stringValue; - NSView * theView = [[APPCONTROLLER browserView] activeTabItemView]; + NSView * theView = APPCONTROLLER.browserView.activeTabItemView; if ([theView isKindOfClass:[BrowserPane class]]) { [theView performFindPanelAction:NSFindPanelActionSetFindString]; [APPCONTROLLER setFocusToSearchField:self]; } else - [APPCONTROLLER searchArticlesWithString:[searchField stringValue]]; + [APPCONTROLLER searchArticlesWithString:searchField.stringValue]; [NSApp endSheet:searchPanelWindow]; [searchPanelWindow orderOut:self]; diff --git a/src/SearchString.h b/src/SearchString.h index 7783cda7c3..7fc416d786 100644 --- a/src/SearchString.h +++ b/src/SearchString.h @@ -19,5 +19,5 @@ // @interface Database (SearchString) - -(CriteriaTree *)searchStringToTree; + @property (nonatomic, readonly, strong) CriteriaTree *searchStringToTree; @end diff --git a/src/SearchString.m b/src/SearchString.m index 09de278cea..34e27df04c 100644 --- a/src/SearchString.m +++ b/src/SearchString.m @@ -31,7 +31,6 @@ -(CriteriaTree *)searchStringToTree CriteriaTree * tree = [[CriteriaTree alloc] init]; Criteria * clause = [[Criteria alloc] initWithField:MA_Field_Text withOperator:MA_CritOper_Contains withValue:searchString]; [tree addCriteria:clause]; - [clause release]; - return [tree autorelease]; + return tree; } @end diff --git a/src/SplitViewExtensions.h b/src/SplitViewExtensions.h index ebdd7d28f9..4bad7147ee 100644 --- a/src/SplitViewExtensions.h +++ b/src/SplitViewExtensions.h @@ -21,6 +21,5 @@ #import @interface NSSplitView (SplitViewExtensions) - -(NSArray *)layout; - -(void)setLayout:(NSArray *)newLayout; + @property (nonatomic, copy) NSArray *xlayout; @end diff --git a/src/SplitViewExtensions.m b/src/SplitViewExtensions.m index a32201fc2d..5bc33eb3c5 100644 --- a/src/SplitViewExtensions.m +++ b/src/SplitViewExtensions.m @@ -30,44 +30,46 @@ @implementation NSSplitView (SplitViewExtensions) /* layout * Returns an NSArray of the splitview layouts. */ --(NSArray *)layout +-(NSArray *)xlayout { NSMutableArray * viewRects = [NSMutableArray array]; NSRect frame; - for (NSView * view in [self subviews]) + for (NSView * view in self.subviews) { if ([self isSubviewCollapsed:view]) frame = NSZeroRect; else - frame = [view frame]; + frame = view.frame; [viewRects addObject:NSStringFromRect(frame)]; + //view.needsLayout = YES; } - return viewRects; + return [viewRects copy]; } /* setLayout * Sets the splitview layout from the specified array */ --(void)setLayout:(NSArray *)viewRects +-(void)setXlayout:(NSArray *)viewRects { - NSArray * views = [self subviews]; - int i, count; + NSArray * views = self.subviews; + NSInteger i, count; NSRect frame; count = MIN([viewRects count], [views count]); for (i = 0; i < count; i++) { - frame = NSRectFromString([viewRects objectAtIndex: i]); + frame = NSRectFromString(viewRects[i]); if (NSIsEmptyRect(frame)) { - frame = [[views objectAtIndex:i] frame]; - if( [self isVertical] ) + frame = [views[i] frame]; + if( self.vertical ) frame.size.width = 0; else frame.size.height = 0; } - [[views objectAtIndex:i] setFrame:frame]; + [views[i] setFrame:frame]; + [views[i] setNeedsLayout:YES]; } } @end diff --git a/src/SquareWindow.h b/src/SquareWindow.h deleted file mode 100644 index d12e50923e..0000000000 --- a/src/SquareWindow.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// SquareWindow.h -// Vienna -// -// Created by Steve on 10/14/05. -// Copyright (c) 2004-2005 Steve Palmer. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#import - -@interface NSWindow (ViennaSquareWindow) --(void)setBottomCornerRounded:(BOOL)rounded; -@end - -@interface SquareWindow : NSWindow { -} -@end diff --git a/src/SquareWindow.m b/src/SquareWindow.m deleted file mode 100644 index 280ca62b57..0000000000 --- a/src/SquareWindow.m +++ /dev/null @@ -1,37 +0,0 @@ -// -// SquareWindow.m -// Vienna -// -// Created by Steve on 10/14/05. -// Copyright (c) 2004-2005 Steve Palmer. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#import "SquareWindow.h" - -@implementation SquareWindow - -/* initWithContentRect - * Subclass the designated initialiser for NSWindow to set the square bottom edge style using the - * undocumented setBottomCornerRounded function. - */ --(id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag -{ - if ((self = [super initWithContentRect:contentRect styleMask:styleMask backing:backingType defer:flag]) != nil) - { - if ([self respondsToSelector:@selector(setBottomCornerRounded:)]) - [self setBottomCornerRounded:NO]; - } - return self; -} -@end diff --git a/src/StdEnclosureView.h b/src/StdEnclosureView.h index aa7f803329..acc4ef94c1 100644 --- a/src/StdEnclosureView.h +++ b/src/StdEnclosureView.h @@ -28,7 +28,7 @@ IBOutlet NSTextField * filenameLabel; IBOutlet DSClickableURLTextField * filenameField; IBOutlet NSButton * downloadButton; - NSString * enclosureFilename; + NSString * enclosureURLString; BOOL isITunes; } diff --git a/src/StdEnclosureView.m b/src/StdEnclosureView.m index 221eb0b7b6..af97714b54 100644 --- a/src/StdEnclosureView.m +++ b/src/StdEnclosureView.m @@ -22,6 +22,7 @@ #import "Preferences.h" #import "DownloadManager.h" #import "DSClickableURLTextField.h" +#import "HelperFunctions.h" // Private functions @interface StdEnclosureView (Private) @@ -33,11 +34,11 @@ @implementation StdEnclosureView /* initWithFrame * Initialise the standard enclosure view. */ --(id)initWithFrame:(NSRect)frameRect +-(instancetype)initWithFrame:(NSRect)frameRect { if ((self = [super initWithFrame:frameRect]) != nil) { - enclosureFilename = nil; + enclosureURLString = nil; isITunes = NO; // Register to be notified when a download completes. @@ -61,8 +62,8 @@ -(void)awakeFromNib */ -(void)handleDownloadCompleted:(NSNotification *)notification { - if (enclosureFilename != nil) - [self setEnclosureFile:enclosureFilename]; + if (enclosureURLString != nil) + [self setEnclosureFile:enclosureURLString]; } /* setEnclosureFile @@ -75,28 +76,30 @@ -(void)setEnclosureFile:(NSString *)newFilename FSRef appRef; // Keep this for the download/open - [newFilename retain]; - [enclosureFilename release]; - enclosureFilename = newFilename; + enclosureURLString = [cleanedUpAndEscapedUrlFromString(newFilename) absoluteString]; - NSString * basename = [[NSURL URLWithString:enclosureFilename] lastPathComponent]; - NSString * encodedname = [basename stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; - NSString * ext = [encodedname pathExtension]; + NSString * basename = [NSURL URLWithString:enclosureURLString].lastPathComponent; + if (basename==nil) + { + return; + } + + NSString * ext = basename.pathExtension; // Find the file's likely location in Finder and see if it is already there. // We'll set the options in the pane based on whether the file is there or not. - NSString * destPath = [DownloadManager fullDownloadPath:encodedname]; + NSString * destPath = [DownloadManager fullDownloadPath:basename]; if (![DownloadManager isFileDownloaded:destPath]) { [downloadButton setTitle:NSLocalizedString(@"Download", nil)]; [downloadButton sizeToFit]; - [downloadButton setAction:@selector(downloadFile:)]; + downloadButton.action = @selector(downloadFile:); [filenameLabel setStringValue:NSLocalizedString(@"This article contains an enclosed file.", nil)]; } else { isITunes = NO; - if (LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator, (CFStringRef)ext, kLSRolesAll, &appRef, &appURL) != kLSApplicationNotFoundErr) + if (LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator, (__bridge CFStringRef)ext, kLSRolesAll, &appRef, &appURL) != kLSApplicationNotFoundErr) { LSItemInfoRecord outItemInfo; @@ -112,27 +115,27 @@ -(void)setEnclosureFile:(NSString *)newFilename { [downloadButton setTitle:NSLocalizedString(@"Play", nil)]; [downloadButton sizeToFit]; - [downloadButton setAction:@selector(openFile:)]; + downloadButton.action = @selector(openFile:); [filenameLabel setStringValue:NSLocalizedString(@"Click the Play button to play this enclosure in iTunes.", nil)]; } else { [downloadButton setTitle:NSLocalizedString(@"Open", nil)]; [downloadButton sizeToFit]; - [downloadButton setAction:@selector(openFile:)]; + downloadButton.action = @selector(openFile:); [filenameLabel setStringValue:NSLocalizedString(@"Click the Open button to open this file.", nil)]; } } NSImage * iconImage = [[NSWorkspace sharedWorkspace] iconForFileType:ext]; - [fileImage setImage:iconImage]; - NSDictionary *linkAttributes = [NSDictionary dictionaryWithObjectsAndKeys: - enclosureFilename, NSLinkAttributeName, - [NSColor colorWithCalibratedHue:240.0f/360.0f saturation:1.0f brightness:0.75f alpha:1.0f], NSForegroundColorAttributeName, - [NSNumber numberWithBool:YES], NSUnderlineStyleAttributeName, - nil]; - NSAttributedString * link = [[[NSAttributedString alloc] initWithString:encodedname attributes:linkAttributes] autorelease]; - [filenameField setAttributedStringValue:link]; + fileImage.image = iconImage; + NSDictionary *linkAttributes = @{ + NSLinkAttributeName: enclosureURLString, + NSForegroundColorAttributeName: [NSColor colorWithCalibratedHue:240.0f/360.0f saturation:1.0f brightness:0.75f alpha:1.0f], + NSUnderlineStyleAttributeName: @YES, + }; + NSAttributedString * link = [[NSAttributedString alloc] initWithString:basename attributes:linkAttributes]; + filenameField.attributedStringValue = link; } /* downloadFile @@ -140,7 +143,7 @@ -(void)setEnclosureFile:(NSString *)newFilename */ -(IBAction)downloadFile:(id)sender { - [[DownloadManager sharedInstance] downloadFileFromURL:enclosureFilename]; + [[DownloadManager sharedInstance] downloadFileFromURL:enclosureURLString]; } /* openFile @@ -148,8 +151,8 @@ -(IBAction)downloadFile:(id)sender */ -(IBAction)openFile:(id)sender { - NSString * theFilename = [enclosureFilename lastPathComponent]; - NSString * destPath = [DownloadManager fullDownloadPath:theFilename]; + NSString * basename = [NSURL URLWithString:enclosureURLString].lastPathComponent; + NSString * destPath = [DownloadManager fullDownloadPath:basename]; [[NSWorkspace sharedWorkspace] openFile:destPath]; } @@ -168,8 +171,7 @@ -(void)drawRect:(NSRect)rect */ -(void)dealloc { - [enclosureFilename release]; - enclosureFilename=nil; - [super dealloc]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; + enclosureURLString=nil; } @end diff --git a/src/StringExtensions.h b/src/StringExtensions.h index 72d7079b2c..71a7219482 100644 --- a/src/StringExtensions.h +++ b/src/StringExtensions.h @@ -20,7 +20,7 @@ #import -#define SafeString(s) ((s) ? (s) : @"") +#define SafeString(s) ((s) ?: @"") @interface NSMutableString (MutableStringExtensions) -(void)replaceString:(NSString *)source withString:(NSString *)dest; @@ -32,24 +32,24 @@ @interface NSString (StringExtensions) +(NSString *)stringByRemovingHTML:(NSString *)theString; +(NSString *)mapEntityToString:(NSString *)entityString; - +(NSString * )stringByCleaningURLString:(NSString *) urlString; - -(NSString *)firstNonBlankLine; - -(NSString *)summaryTextFromHTML; - -(NSString *)titleTextFromHTML; + +(NSString *)stringByConvertingHTMLEntities:(NSString *)stringToProcess; + @property (nonatomic, readonly, copy) NSString *firstNonBlankLine; + @property (nonatomic, readonly, copy) NSString *summaryTextFromHTML; + @property (nonatomic, readonly, copy) NSString *titleTextFromHTML; -(NSUInteger)indexOfCharacterInString:(char)ch afterIndex:(NSUInteger)startIndex; - -(NSString *)stringByEscapingExtendedCharacters; - -(NSString *)stringByUnescapingExtendedCharacters; - -(NSString *)stringByDeletingLastURLComponent; - -(NSString *)lastURLComponent; + @property (nonatomic, readonly, copy) NSString *stringByEscapingExtendedCharacters; + @property (nonatomic, readonly, copy) NSString *stringByUnescapingExtendedCharacters; + @property (nonatomic, readonly, copy) NSString *stringByDeletingLastURLComponent; + @property (nonatomic, readonly, copy) NSString *lastURLComponent; -(NSString *)stringByAppendingURLComponent:(NSString *)newComponent; -(BOOL)hasCharacter:(char)ch; - -(NSString *)firstWord; - -(NSString *)convertStringToValidPath; + @property (nonatomic, readonly, copy) NSString *firstWord; + @property (nonatomic, readonly, copy) NSString *convertStringToValidPath; -(NSComparisonResult)numericCompare:(NSString *)aString; - -(NSString *)normalised; - -(NSString *)baseURL; - -(NSString *)host; - -(NSString *)trim; - -(int)hexValue; - -(BOOL)isBlank; + @property (nonatomic, readonly, copy) NSString *normalised; + @property (nonatomic, readonly, copy) NSString *baseURL; + @property (nonatomic, readonly, copy) NSString *host; + @property (nonatomic, readonly, copy) NSString *trim; + @property (nonatomic, readonly) NSInteger hexValue; + @property (nonatomic, getter=isBlank, readonly) BOOL blank; @end diff --git a/src/StringExtensions.m b/src/StringExtensions.m index 796b44e46c..cd20ce50b9 100644 --- a/src/StringExtensions.m +++ b/src/StringExtensions.m @@ -31,7 +31,7 @@ @implementation NSMutableString (MutableStringExtensions) */ -(void)replaceString:(NSString *)source withString:(NSString *)dest { - [self replaceOccurrencesOfString:source withString:dest options:NSLiteralSearch range:NSMakeRange(0, [self length])]; + [self replaceOccurrencesOfString:source withString:dest options:NSLiteralSearch range:NSMakeRange(0, self.length)]; } /* fixupRelativeImgTags @@ -45,7 +45,7 @@ -(void)fixupRelativeImgTags:(NSString *)baseURL return; NSURL * imgBaseURL = [NSURL URLWithString:baseURL]; - NSUInteger textLength = [self length]; + NSUInteger textLength = self.length; NSRange srchRange; srchRange.location = 0; @@ -73,14 +73,14 @@ -(void)fixupRelativeImgTags:(NSString *)baseURL NSURL * imgURL = [NSURL URLWithString:srcPath relativeToURL:imgBaseURL]; if (imgURL != nil) { - srcPath = [imgURL absoluteString]; + srcPath = imgURL.absoluteString; [self replaceCharactersInRange:srcRange withString:srcPath]; - textLength = [self length]; + textLength = self.length; } } // Start searching again from beyond the URL - srchRange.location = srcRange.location + [srcPath length]; + srchRange.location = srcRange.location + srcPath.length; } else ++srchRange.location; @@ -99,7 +99,7 @@ -(void)fixupRelativeAnchorTags:(NSString *)baseURL return; NSURL * anchorBaseURL = [NSURL URLWithString:baseURL]; - NSUInteger textLength = [self length]; + NSUInteger textLength = self.length; NSRange srchRange; srchRange.location = 0; @@ -127,14 +127,14 @@ -(void)fixupRelativeAnchorTags:(NSString *)baseURL NSURL * anchorURL = [NSURL URLWithString:srcPath relativeToURL:anchorBaseURL]; if (anchorURL != nil) { - srcPath = [anchorURL absoluteString]; + srcPath = anchorURL.absoluteString; [self replaceCharactersInRange:srcRange withString:srcPath]; - textLength = [self length]; + textLength = self.length; } } // Start searching again from beyond the URL - srchRange.location = srcRange.location + [srcPath length]; + srchRange.location = srcRange.location + srcPath.length; } else ++srchRange.location; @@ -153,7 +153,7 @@ -(void)fixupRelativeIframeTags:(NSString *)baseURL return; NSURL * imgBaseURL = [NSURL URLWithString:baseURL]; - NSUInteger textLength = [self length]; + NSUInteger textLength = self.length; NSRange srchRange; srchRange.location = 0; @@ -181,14 +181,14 @@ -(void)fixupRelativeIframeTags:(NSString *)baseURL NSURL * iframeURL = [NSURL URLWithString:srcPath relativeToURL:imgBaseURL]; if (iframeURL != nil) { - srcPath = [iframeURL absoluteString]; + srcPath = iframeURL.absoluteString; [self replaceCharactersInRange:srcRange withString:srcPath]; - textLength = [self length]; + textLength = self.length; } } // Start searching again from beyond the URL - srchRange.location = srcRange.location + [srcPath length]; + srchRange.location = srcRange.location + srcPath.length; } else ++srchRange.location; @@ -203,13 +203,13 @@ -(void)fixupRelativeIframeTags:(NSString *)baseURL @implementation NSString (StringExtensions) /* hexValue - * A counterpart to intValue, but parses a hexadecimal number. + * A counterpart to integerValue, but parses a hexadecimal number. */ --(int)hexValue +-(NSInteger)hexValue { - int count = [self length]; - int intValue = 0; - int index = 0; + NSInteger count = self.length; + NSInteger intValue = 0; + NSInteger index = 0; while (index < count) { @@ -234,7 +234,7 @@ -(int)hexValue */ -(NSString *)summaryTextFromHTML { - return [[NSString stringByRemovingHTML:self] normalised]; + return [NSString stringByRemovingHTML:self].normalised; } /* titleTextFromHTML @@ -244,7 +244,7 @@ -(NSString *)summaryTextFromHTML */ -(NSString *)titleTextFromHTML { - return [[NSString stringByRemovingHTML:self] firstNonBlankLine]; + return [NSString stringByRemovingHTML:self].firstNonBlankLine; } /* firstWord @@ -252,7 +252,7 @@ -(NSString *)titleTextFromHTML */ -(NSString *)firstWord { - NSString * trimmedSelf = [self trim]; + NSString * trimmedSelf = self.trim; NSInteger wordLength = [trimmedSelf indexOfCharacterInString:' ' afterIndex:0]; return (wordLength == NSNotFound) ? trimmedSelf : [trimmedSelf substringToIndex:wordLength]; } @@ -263,11 +263,11 @@ -(NSString *)firstWord +(NSString *)stringByRemovingHTML:(NSString *)theString { NSMutableString * aString = [NSMutableString stringWithString:theString]; - int maxChrs = [theString length]; - int cutOff = 600; - int indexOfChr = 0; - int tagLength = 0; - int tagStartIndex = 0; + NSInteger maxChrs = theString.length; + NSInteger cutOff = 600; + NSInteger indexOfChr = 0; + NSInteger tagLength = 0; + NSInteger tagStartIndex = 0; BOOL isInQuote = NO; BOOL isInTag = NO; @@ -295,14 +295,14 @@ +(NSString *)stringByRemovingHTML:(NSString *)theString if (++tagLength > 2) { NSRange tagRange = NSMakeRange(tagStartIndex, tagLength); - NSString * tag = [[aString substringWithRange:tagRange] lowercaseString]; - int indexOfTagName = 1; + NSString * tag = [aString substringWithRange:tagRange].lowercaseString; + NSInteger indexOfTagName = 1; // Extract the tag name if ([tag characterAtIndex:indexOfTagName] == '/') ++indexOfTagName; - int chIndex = indexOfTagName; + NSInteger chIndex = indexOfTagName; unichar ch = [tag characterAtIndex:chIndex]; while (chIndex < tagLength && [[NSCharacterSet lowercaseLetterCharacterSet] characterIsMember:ch]) ch = [tag characterAtIndex:++chIndex]; @@ -317,7 +317,7 @@ +(NSString *)stringByRemovingHTML:(NSString *)theString // Reset scan to the point where the tag started minus one because // we bump up indexOfChr at the end of the loop. indexOfChr = tagStartIndex - 1; - maxChrs = [aString length]; + maxChrs = aString.length; isInTag = NO; isInQuote = NO; // Fix problem with Tribe.net feeds that have bogus quotes in HTML tags } @@ -328,7 +328,7 @@ +(NSString *)stringByRemovingHTML:(NSString *)theString if (maxChrs > cutOff) [aString deleteCharactersInRange:NSMakeRange(cutOff, maxChrs - cutOff)]; - return [aString stringByUnescapingExtendedCharacters]; + return aString.stringByUnescapingExtendedCharacters; } /* normalised @@ -339,8 +339,8 @@ -(NSString *)normalised { NSMutableString * string = [NSMutableString stringWithString:self]; BOOL isInWhitespace = YES; - int length = [string length]; - int index = 0; + NSInteger length = string.length; + NSInteger index = 0; while (index < length) { @@ -374,7 +374,7 @@ -(NSString *)firstNonBlankLine NSUInteger indexOfLastChr = 0; NSUInteger indexOfChr = 0; - NSUInteger length = [self length]; + NSUInteger length = self.length; while (indexOfChr < length) { unichar ch = [self characterAtIndex:indexOfChr]; @@ -408,8 +408,8 @@ -(NSString *)firstNonBlankLine */ -(NSString *)stringByDeletingLastURLComponent { - int index = [self length] - 1; - int beginning = 0; + NSInteger index = self.length - 1; + NSInteger beginning = 0; if ([self hasPrefix:@"http://"]) beginning = 6; @@ -429,13 +429,13 @@ -(NSString *)stringByDeletingLastURLComponent */ -(NSString *)lastURLComponent { - int index = [self length] - 1; + NSInteger index = self.length - 1; while (index >= 0 && [self characterAtIndex:index] != '/') --index; if (index <= 0) return self; - return [self substringWithRange:NSMakeRange(index+1, [self length] -1-index)]; + return [self substringWithRange:NSMakeRange(index+1, self.length -1-index)]; } /* stringByAppendingURLComponent @@ -445,12 +445,12 @@ -(NSString *)lastURLComponent -(NSString *)stringByAppendingURLComponent:(NSString *)newComponent { NSMutableString * newString = [NSMutableString stringWithString:self]; - int index = [newString length] - 1; - int newIndex = 0; + NSInteger index = newString.length - 1; + NSInteger newIndex = 0; if (index >= 0 && [newString characterAtIndex:index] != '/') [newString appendString:@"/"]; - if ([newComponent length] > 0 && [newComponent characterAtIndex:0] == '/') + if (newComponent.length > 0 && [newComponent characterAtIndex:0] == '/') ++newIndex; [newString appendString:[newComponent substringFromIndex:newIndex]]; return newString; @@ -463,8 +463,8 @@ -(NSString *)stringByAppendingURLComponent:(NSString *)newComponent -(NSString *)stringByEscapingExtendedCharacters { NSMutableString * escapedString = [NSMutableString stringWithString:self]; - int length = [escapedString length]; - int index = 0; + NSInteger length = escapedString.length; + NSInteger index = 0; while (index < length) { @@ -475,8 +475,8 @@ -(NSString *)stringByEscapingExtendedCharacters { NSString * escapedCharacter = [NSString stringWithFormat:@"&#%d;", ch]; [escapedString replaceCharactersInRange:NSMakeRange(index, 1) withString:escapedCharacter]; - index += [escapedCharacter length]; - length = [escapedString length]; + index += escapedCharacter.length; + length = escapedString.length; } } return escapedString; @@ -506,8 +506,7 @@ -(NSString *)stringByUnescapingExtendedCharacters entityStart = [processedString indexOfCharacterInString:'&' afterIndex:entityStart + 1]; } - NSString * returnString = [processedString trim]; - [processedString release]; + NSString * returnString = processedString.trim; return returnString; } @@ -518,17 +517,17 @@ +(NSString *)mapEntityToString:(NSString *)entityString { if (entityMap == nil) { - entityMap = [[NSMutableDictionary dictionaryWithObjectsAndKeys: - @"<", @"lt", - @">", @"gt", - @"\"", @"quot", - @"&", @"amp", - @"'", @"rsquo", - @"'", @"lsquo", - @"'", @"apos", - @"...", @"hellip", - @" ", @"nbsp", - nil, nil] retain]; + entityMap = [@{ + @"lt": @"<", + @"gt": @">", + @"quot": @"\"", + @"amp": @"&", + @"rsquo": @"'", + @"lsquo": @"'", + @"apos": @"'", + @"hellip": @"...", + @"nbsp": @" ", + } mutableCopy]; // Add entities that map to non-ASCII characters [entityMap setValue:[NSString stringWithFormat:@"%C", (unsigned short)0xA1] forKey:@"iexcl"]; @@ -630,17 +629,17 @@ +(NSString *)mapEntityToString:(NSString *)entityString } // Parse off numeric codes of the format #xxx - if ([entityString length] > 1 && [entityString characterAtIndex:0] == '#') + if (entityString.length > 1 && [entityString characterAtIndex:0] == '#') { - int intValue; + NSInteger intValue; if ([entityString characterAtIndex:1] == 'x') - intValue = [[entityString substringFromIndex:2] hexValue]; + intValue = [entityString substringFromIndex:2].hexValue; else - intValue = [[entityString substringFromIndex:1] intValue]; + intValue = [entityString substringFromIndex:1].integerValue; return [NSString stringWithFormat:@"%C", (unsigned short)MAX(intValue, ' ')]; } - NSString * mappedString = [entityMap objectForKey:entityString]; + NSString * mappedString = entityMap[entityString]; return mappedString ? mappedString : [NSString stringWithFormat:@"&%@;", entityString]; } @@ -650,7 +649,7 @@ +(NSString *)mapEntityToString:(NSString *)entityString */ -(NSUInteger)indexOfCharacterInString:(char)ch afterIndex:(NSUInteger)startIndex { - NSUInteger length = [self length]; + NSUInteger length = self.length; NSUInteger index; if (startIndex < length - 1) @@ -684,7 +683,7 @@ -(NSString *)trim */ -(BOOL)isBlank { - return [[self trim] length] == 0; + return self.trim.length == 0; } /* convertStringToValidPath @@ -694,11 +693,11 @@ -(BOOL)isBlank -(NSString *)convertStringToValidPath { NSMutableString * baseURLString = [NSMutableString stringWithString:self]; - [baseURLString replaceOccurrencesOfString:@":" withString:@"_" options:NSLiteralSearch range:NSMakeRange(0, [baseURLString length])]; - [baseURLString replaceOccurrencesOfString:@"." withString:@"_" options:NSLiteralSearch range:NSMakeRange(0, [baseURLString length])]; - [baseURLString replaceOccurrencesOfString:@"/" withString:@"_" options:NSLiteralSearch range:NSMakeRange(0, [baseURLString length])]; - [baseURLString replaceOccurrencesOfString:@"?" withString:@"_" options:NSLiteralSearch range:NSMakeRange(0, [baseURLString length])]; - [baseURLString replaceOccurrencesOfString:@"*" withString:@"_" options:NSLiteralSearch range:NSMakeRange(0, [baseURLString length])]; + [baseURLString replaceOccurrencesOfString:@":" withString:@"_" options:NSLiteralSearch range:NSMakeRange(0, baseURLString.length)]; + [baseURLString replaceOccurrencesOfString:@"." withString:@"_" options:NSLiteralSearch range:NSMakeRange(0, baseURLString.length)]; + [baseURLString replaceOccurrencesOfString:@"/" withString:@"_" options:NSLiteralSearch range:NSMakeRange(0, baseURLString.length)]; + [baseURLString replaceOccurrencesOfString:@"?" withString:@"_" options:NSLiteralSearch range:NSMakeRange(0, baseURLString.length)]; + [baseURLString replaceOccurrencesOfString:@"*" withString:@"_" options:NSLiteralSearch range:NSMakeRange(0, baseURLString.length)]; return baseURLString; } @@ -715,7 +714,7 @@ -(NSString *)convertStringToValidPath -(NSString *)baseURL { NSURL * url = [NSURL URLWithString:self]; - return (url && [url host]) ? [NSString stringWithFormat:@"%@://%@", [url scheme], [url host]] : self; + return (url && url.host) ? [NSString stringWithFormat:@"%@://%@", url.scheme, url.host] : self; } /* host @@ -731,7 +730,7 @@ -(NSString *)baseURL -(NSString *)host { NSURL * url = [NSURL URLWithString:self]; - return (url && [url host]) ? [url host] : self; + return (url && url.host) ? url.host : self; } /* numericCompare @@ -742,6 +741,21 @@ -(NSComparisonResult)numericCompare:(NSString *)aString; return [self compare:aString options:NSCaseInsensitiveSearch|NSNumericSearch]; } + +/* convertHTMLEntities + * Scan the specified string and convert HTML literal characters to their entity equivalents. + */ ++(NSString *)stringByConvertingHTMLEntities:(NSString *)stringToProcess +{ + NSMutableString * newString = [NSMutableString stringWithString:stringToProcess]; + [newString replaceString:@"&" withString:@"&"]; + [newString replaceString:@"<" withString:@"<"]; + [newString replaceString:@">" withString:@">"]; + [newString replaceString:@"\"" withString:@"""]; + [newString replaceString:@"'" withString:@"'"]; + return newString; +} + /* stringByCleaningURLString * Percent escape invalid and reserved URL characters and return a legal URL string. * Better alternative to -stringByAddingPercentEscapesUsingEncoding: @@ -753,12 +767,12 @@ -(NSComparisonResult)numericCompare:(NSString *)aString; +(NSString * )stringByCleaningURLString:(NSString *) urlString { NSString *newString; - NSPasteboard * pasteboard = [NSPasteboard pasteboardWithName:@"ViennaIDNURLPasteboard"]; - [pasteboard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil]; @try { + NSPasteboard * pasteboard = [NSPasteboard pasteboardWithName:@"ViennaIDNURLPasteboard"]; + [pasteboard declareTypes:@[NSStringPboardType] owner:nil]; if ([pasteboard setString:urlString forType:NSStringPboardType]) - newString = [[WebView URLFromPasteboard:pasteboard] absoluteString]; + newString = [WebView URLFromPasteboard:pasteboard].absoluteString; else { newString = @""; diff --git a/src/SubscriptionModel.m b/src/SubscriptionModel.m index 50e3c39119..ff05ca9ccd 100644 --- a/src/SubscriptionModel.m +++ b/src/SubscriptionModel.m @@ -21,9 +21,9 @@ @implementation SubscriptionModel * then OK. Otherwise if it looks like an HTML page, we scan for links in the * page text. * -* @param feedURLString A pointer to the NSString containing the URL to verify +* @param feedURLString A pointer to the URL to verify * -* @return A pointer to an NSString containing a verified URL +* @return A pointer to a verified URL */ -(NSURL *)verifiedFeedURLFromURL:(NSURL *)rssFeedURL { @@ -60,15 +60,20 @@ -(NSURL *)verifiedFeedURLFromURL:(NSURL *)rssFeedURL if ([RichXMLParser extractFeeds:urlContent toArray:linkArray]) { NSString * feedPart = linkArray.firstObject; - if (![feedPart hasPrefix:@"http:"] && ![feedPart hasPrefix:@"https:"]) - { - rssFeedURL = [NSURL URLWithString:feedPart relativeToURL:rssFeedURL]; - } - else { - rssFeedURL = [NSURL URLWithString:feedPart]; - } + NSURL * myURL = [NSURL URLWithString:feedPart relativeToURL:rssFeedURL]; + if (myURL ==nil) + { + // try cleaning up the string : unescape then re-add escapes + NSString * urlString = [[feedPart stringByUnescapingExtendedCharacters] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + myURL = [NSURL URLWithString:urlString relativeToURL:rssFeedURL]; + } + return myURL; + } + else + { + // no link found, return the original URL + return rssFeedURL; } - return rssFeedURL.absoluteURL; } diff --git a/src/TabbedWebView.h b/src/TabbedWebView.h index e6540d9cb7..3a5de643e9 100644 --- a/src/TabbedWebView.h +++ b/src/TabbedWebView.h @@ -38,8 +38,9 @@ -(void)setOpenLinksInNewBrowser:(BOOL)flag; -(void)keyDown:(NSEvent *)theEvent; -(void)printDocument:(id)sender; --(BOOL)isFeedRedirect; --(BOOL)isDownload; +@property (nonatomic, getter=isFeedRedirect, readonly) BOOL feedRedirect; +@property (nonatomic, getter=isDownload, readonly) BOOL download; -(void)scrollToTop; -(void)scrollToBottom; + @end diff --git a/src/TabbedWebView.m b/src/TabbedWebView.m index 126565a169..0e1b2903e9 100644 --- a/src/TabbedWebView.m +++ b/src/TabbedWebView.m @@ -31,6 +31,8 @@ -(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger)flags; @end @interface TabbedWebView (Private) + +(NSArray *)acceptedSchemes; + +(NSArray *)downloadableExtensions; -(BOOL)isDownloadFileType:(NSURL *)filename; -(void)loadMinimumFontSize; -(void)handleMinimumFontSizeChange:(NSNotification *)nc; @@ -44,23 +46,39 @@ +(NSString *)userAgent { if(!_userAgent) { - NSString * webkitVersion = [[[NSBundle bundleWithIdentifier:@"com.apple.WebKit"] infoDictionary] objectForKey:@"CFBundleVersion"]; + NSString * webkitVersion = [NSBundle bundleWithIdentifier:@"com.apple.WebKit"].infoDictionary[@"CFBundleVersion"]; if (webkitVersion) webkitVersion = [webkitVersion substringFromIndex:2]; else webkitVersion = @"536.30"; - NSString * shortSafariVersion = [[[NSBundle bundleWithPath:@"/Applications/Safari.app"] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; + NSString * shortSafariVersion = [NSBundle bundleWithPath:@"/Applications/Safari.app"].infoDictionary[@"CFBundleShortVersionString"]; if (!shortSafariVersion) shortSafariVersion = @"6.0"; - _userAgent = [NSString stringWithFormat:MA_BrowserUserAgentString, [[((ViennaApp *)NSApp) applicationVersion] firstWord], shortSafariVersion, webkitVersion]; + _userAgent = [NSString stringWithFormat:MA_BrowserUserAgentString, ((ViennaApp *)NSApp).applicationVersion.firstWord, shortSafariVersion, webkitVersion]; } return _userAgent; } +/* acceptedSchemes + * schemes listener objects are able to handle directly + */ ++(NSArray *)acceptedSchemes +{ + return @[@"http", @"https", @"feed", @"file", @"data", @"applewebdata", @"about"]; +} + +/* downloadableExtensions + * file extensions which are deemed to be downloaded + */ ++(NSArray *)downloadableExtensions +{ + return @[@"dmg", @"zip", @"gz", @"tgz", @"7z", @"rar", @"tar", @"bin", @"bz2", @"exe", @"sit", @"sitx"]; +} + /* initWithFrame * The designated instance initialiser. */ --(id)initWithFrame:(NSRect)frameRect frameName:(NSString *)frameName groupName:(NSString *)groupName +-(instancetype)initWithFrame:(NSRect)frameRect frameName:(NSString *)frameName groupName:(NSString *)groupName { if ((self = [super initWithFrame:frameRect frameName:frameName groupName:groupName]) != nil) [self initTabbedWebView]; @@ -79,11 +97,11 @@ -(void)initTabbedWebView isDownload = NO; // Set a host window so that plugins can keep active while not in the front-most tab. - [self setHostWindow:[NSApp mainWindow]]; + self.hostWindow = NSApp.mainWindow; // We'll be the webview policy handler. - [self setPolicyDelegate:self]; - [self setDownloadDelegate:[DownloadManager sharedInstance]]; + self.policyDelegate = self; + self.downloadDelegate = [DownloadManager sharedInstance]; // Set up to be notified of changes NSNotificationCenter * nc = [NSNotificationCenter defaultCenter]; @@ -95,14 +113,14 @@ -(void)initTabbedWebView name:kMA_Notify_UseWebPluginsChange object:nil]; // Handle minimum font size, use of JavaScript, and use of plugins - defaultWebPrefs = [[self preferences] retain]; - [defaultWebPrefs setStandardFontFamily:@"Arial"]; - [defaultWebPrefs setDefaultFontSize:12]; + defaultWebPrefs = self.preferences; + defaultWebPrefs.standardFontFamily = @"Arial"; + defaultWebPrefs.defaultFontSize = 12; [defaultWebPrefs setPrivateBrowsingEnabled:NO]; [defaultWebPrefs setJavaScriptEnabled:NO]; [defaultWebPrefs setPlugInsEnabled:NO]; // handle UserAgent - [self setApplicationNameForUserAgent:[TabbedWebView userAgent]]; + self.applicationNameForUserAgent = [TabbedWebView userAgent]; [self loadMinimumFontSize]; [self loadUseJavaScript]; [self loadUseWebPlugins]; @@ -113,10 +131,8 @@ -(void)initTabbedWebView */ -(void)setController:(AppController *)theController { - [theController retain]; - [controller release]; controller = theController; - [self setPolicyDelegate:self]; + self.policyDelegate = self; } /* setOpenLinksInNewBrowser @@ -165,19 +181,8 @@ -(BOOL)isFeedRedirect */ -(BOOL)isDownloadFileType:(NSURL *)url { - NSString * newURLExtension = [[url path] pathExtension]; - return ([newURLExtension isEqualToString:@"dmg"] || - [newURLExtension isEqualToString:@"sit"] || - [newURLExtension isEqualToString:@"bin"] || - [newURLExtension isEqualToString:@"bz2"] || - [newURLExtension isEqualToString:@"exe"] || - [newURLExtension isEqualToString:@"sitx"] || - [newURLExtension isEqualToString:@"zip"] || - [newURLExtension isEqualToString:@"gz"] || - [newURLExtension isEqualToString:@"tgz"] || - [newURLExtension isEqualToString:@"7z"] || - [newURLExtension isEqualToString:@"rar"] || - [newURLExtension isEqualToString:@"tar"]); + NSString * newURLExtension = url.path.pathExtension; + return ([[TabbedWebView downloadableExtensions] containsObject:newURLExtension]); } /* decidePolicyForMIMEType @@ -191,7 +196,7 @@ -(void)webView:(WebView *)sender decidePolicyForMIMEType:(NSString *)type reques // Convert the link to a feed:// link so that the system will redirect it to the // appropriate handler. (We can't assume that we're the registered handler and it is // too much work for us to figure it out when the system can do it easily enough). - NSScanner * scanner = [NSScanner scannerWithString:[[request URL] absoluteString]]; + NSScanner * scanner = [NSScanner scannerWithString:request.URL.absoluteString]; [scanner scanString:@"http://" intoString:nil]; [scanner scanString:@"https://" intoString:nil]; [scanner scanString:@"feed://" intoString:nil]; @@ -227,7 +232,7 @@ -(void)webView:(WebView *)sender decidePolicyForMIMEType:(NSString *)type reques */ -(void)webView:(WebView *)sender decidePolicyForNewWindowAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request newFrameName:(NSString *)frameName decisionListener:(id)listener { - int navType = [[actionInformation valueForKey:WebActionNavigationTypeKey] intValue]; + NSInteger navType = [[actionInformation valueForKey:WebActionNavigationTypeKey] integerValue]; if (navType == WebNavigationTypeLinkClicked) { NSDictionary * webElementKey = [actionInformation valueForKey:@"WebActionElementKey"]; @@ -244,10 +249,10 @@ -(void)webView:(WebView *)sender decidePolicyForNewWindowAction:(NSDictionary *) } // For anything else, we open in a new tab or in the external browser. - NSUInteger modifierFlag = [[actionInformation valueForKey:WebActionModifierFlagsKey] unsignedIntValue]; + NSUInteger modifierFlag = [[actionInformation valueForKey:WebActionModifierFlagsKey] unsignedIntegerValue]; BOOL useAlternateBrowser = (modifierFlag & NSAlternateKeyMask) ? YES : NO; // This is to avoid problems in casting the value into BOOL [listener ignore]; - [controller openURL:[request URL] inPreferredBrowser:!useAlternateBrowser]; + [controller openURL:request.URL inPreferredBrowser:!useAlternateBrowser]; return; } [listener use]; @@ -260,44 +265,43 @@ -(void)webView:(WebView *)sender decidePolicyForNewWindowAction:(NSDictionary *) */ -(void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener { - int navType = [[actionInformation valueForKey:WebActionNavigationTypeKey] intValue]; - NSUInteger modifierFlags = [[actionInformation valueForKey:WebActionModifierFlagsKey] unsignedIntValue]; - BOOL useAlternateBrowser = (modifierFlags & NSAlternateKeyMask) ? YES : NO; // This is to avoid problems in casting the value into BOOL - - NSString * scheme = [[[request URL] scheme] lowercaseString]; + NSInteger navType = [[actionInformation valueForKey:WebActionNavigationTypeKey] integerValue]; + NSString * scheme = request.URL.scheme.lowercaseString; if (navType == WebNavigationTypeLinkClicked) { - if ([scheme isEqualToString:@"file"] && [[[request URL] resourceSpecifier] hasPrefix:@"/#"]) + if ([scheme isEqualToString:@"file"] && [request.URL.resourceSpecifier hasPrefix:@"/#"]) // clicked a link to an anchor in the same webview { [listener use]; return; } + NSUInteger modifierFlags = [[actionInformation valueForKey:WebActionModifierFlagsKey] unsignedIntegerValue]; + BOOL useAlternateBrowser = (modifierFlags & NSAlternateKeyMask) ? YES : NO; // This is to avoid problems in casting the value into BOOL if (openLinksInNewBrowser || (modifierFlags & NSCommandKeyMask)) { [listener ignore]; - [controller openURL:[request URL] inPreferredBrowser:!useAlternateBrowser]; + [controller openURL:request.URL inPreferredBrowser:!useAlternateBrowser]; return; } else { Preferences * prefs = [Preferences standardPreferences]; - if ([prefs openLinksInVienna] == useAlternateBrowser) + if (prefs.openLinksInVienna == useAlternateBrowser) { [listener ignore]; - [controller openURLInDefaultBrowser:[request URL]]; + [controller openURLInDefaultBrowser:request.URL]; return; } } } - if (scheme == nil || [scheme isEqualToString:@""] || [scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"] || [scheme isEqualToString:@"feed"] || [scheme isEqualToString:@"file"] || [scheme isEqualToString:@"applewebdata"] || [scheme isEqualToString:@"about"]) + if (scheme == nil || [[TabbedWebView acceptedSchemes] containsObject:scheme]) { [listener use]; } else { [listener ignore]; - [[NSWorkspace sharedWorkspace] openURL:[request URL]]; + [[NSWorkspace sharedWorkspace] openURL:request.URL]; } } @@ -331,12 +335,12 @@ -(void)handleUseWebPluginsChange:(NSNotification *)nc -(void)loadMinimumFontSize { Preferences * prefs = [Preferences standardPreferences]; - if (![prefs enableMinimumFontSize]) - [defaultWebPrefs setMinimumFontSize:1]; + if (!prefs.enableMinimumFontSize) + defaultWebPrefs.minimumFontSize = 1; else { - int size = [prefs minimumFontSize]; - [defaultWebPrefs setMinimumFontSize:size]; + NSInteger size = prefs.minimumFontSize; + defaultWebPrefs.minimumFontSize = (int)size; } } @@ -348,17 +352,17 @@ -(void)scrollToBottom NSPoint newScrollOrigin; NSScrollView * myScrollView; - myScrollView = [[[[self mainFrame] frameView] documentView] enclosingScrollView]; + myScrollView = self.mainFrame.frameView.documentView.enclosingScrollView; - if ([[myScrollView documentView] isFlipped]) - newScrollOrigin = NSMakePoint(0.0,NSMaxY([[myScrollView documentView] frame])-NSHeight([[myScrollView contentView] bounds])); + if ([myScrollView.documentView isFlipped]) + newScrollOrigin = NSMakePoint(0.0,NSMaxY([myScrollView.documentView frame])-NSHeight(myScrollView.contentView.bounds)); else newScrollOrigin = NSMakePoint(0.0,0.0); - [[myScrollView documentView] scrollPoint: newScrollOrigin]; + [myScrollView.documentView scrollPoint: newScrollOrigin]; - if ([[myScrollView verticalScroller] knobProportion] < 0.05) - [[myScrollView verticalScroller] setKnobProportion:0.05]; + if (myScrollView.verticalScroller.knobProportion < 0.05) + myScrollView.verticalScroller.knobProportion = 0.05; } /* scrollToTop @@ -376,7 +380,7 @@ -(void)scrollToTop -(void)loadUseJavaScript { Preferences * prefs = [Preferences standardPreferences]; - [defaultWebPrefs setJavaScriptEnabled:[prefs useJavaScript]]; + defaultWebPrefs.javaScriptEnabled = prefs.useJavaScript; } /* loadUseWebPlugins @@ -385,7 +389,7 @@ -(void)loadUseJavaScript -(void)loadUseWebPlugins { Preferences * prefs = [Preferences standardPreferences]; - [defaultWebPrefs setPlugInsEnabled:[prefs useWebPlugins]]; + defaultWebPrefs.plugInsEnabled = prefs.useWebPlugins; } /* keyDown @@ -394,15 +398,15 @@ -(void)loadUseWebPlugins */ -(void)keyDown:(NSEvent *)theEvent { - if ([[theEvent characters] length] == 1) + if (theEvent.characters.length == 1) { - unichar keyChar = [[theEvent characters] characterAtIndex:0]; - if ((keyChar == NSLeftArrowFunctionKey) && ([theEvent modifierFlags] & NSCommandKeyMask)) + unichar keyChar = [theEvent.characters characterAtIndex:0]; + if ((keyChar == NSLeftArrowFunctionKey) && (theEvent.modifierFlags & NSCommandKeyMask)) { [self goBack:self]; return; } - else if ((keyChar == NSRightArrowFunctionKey) && ([theEvent modifierFlags] & NSCommandKeyMask)) + else if ((keyChar == NSRightArrowFunctionKey) && (theEvent.modifierFlags & NSCommandKeyMask)) { [self goForward:self]; return; @@ -416,14 +420,14 @@ -(void)keyDown:(NSEvent *)theEvent */ -(void)printDocument:(id)sender { - NSView * printView = [[[self mainFrame] frameView] documentView]; + NSView * printView = self.mainFrame.frameView.documentView; NSPrintInfo * printInfo = [NSPrintInfo sharedPrintInfo]; NSMutableDictionary * dict = [printInfo dictionary]; - [dict setObject:[NSNumber numberWithFloat:36.0f] forKey:NSPrintLeftMargin]; - [dict setObject:[NSNumber numberWithFloat:36.0f] forKey:NSPrintRightMargin]; - [dict setObject:[NSNumber numberWithFloat:36.0f] forKey:NSPrintTopMargin]; - [dict setObject:[NSNumber numberWithFloat:36.0f] forKey:NSPrintBottomMargin]; + dict[NSPrintLeftMargin] = @36.0; + dict[NSPrintRightMargin] = @36.0; + dict[NSPrintTopMargin] = @36.0; + dict[NSPrintBottomMargin] = @36.0; [printInfo setVerticallyCentered:NO]; [printView print:self]; @@ -448,10 +452,5 @@ -(void)dealloc [self setPolicyDelegate:nil]; [self setDownloadDelegate:nil]; [self removeFromSuperviewWithoutNeedingDisplay]; - [controller release]; - controller=nil; - [defaultWebPrefs release]; - defaultWebPrefs=nil; - [super dealloc]; } @end diff --git a/src/TableViewExtensions.h b/src/TableViewExtensions.h index dc8de2efcd..6d1073c89f 100644 --- a/src/TableViewExtensions.h +++ b/src/TableViewExtensions.h @@ -31,7 +31,7 @@ @interface NSObject(TaskWindowTableViewDelegate) -(BOOL)tableViewShouldDisplayCellToolTips:(ExtendedTableView *)tableView; - -(NSString *)tableView:(ExtendedTableView *)tableView toolTipForTableColumn:(NSTableColumn *)tableColumn row:(int)rowIndex; + -(NSString *)tableView:(ExtendedTableView *)tableView toolTipForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex; -(void)tableView:(ExtendedTableView *)tableView menuWillAppear:(NSEvent *)theEvent; @end diff --git a/src/TableViewExtensions.m b/src/TableViewExtensions.m index fb38b4ffe7..2330477ca8 100644 --- a/src/TableViewExtensions.m +++ b/src/TableViewExtensions.m @@ -61,13 +61,13 @@ -(void)resetCursorRects [self removeAllToolTips]; if (delegateImplementsShouldDisplayToolTips && [(id)[self delegate] tableViewShouldDisplayCellToolTips:self]) { - NSRect visibleRect = [self visibleRect]; + NSRect visibleRect = self.visibleRect; NSIndexSet *columnIndexes = [self columnIndexesInRect:visibleRect]; NSRange rowRange = [self rowsInRect:visibleRect]; NSRect frameOfCell; NSInteger col, row; - col = [columnIndexes firstIndex]; + col = columnIndexes.firstIndex; while (col != NSNotFound) { for (row = rowRange.location; row < rowRange.location + rowRange.length; row++) @@ -87,7 +87,7 @@ -(NSString *)view:(NSView *)view stringForToolTip:(NSToolTipTag)tag point:(NSPoi { NSInteger rowIndex = [self rowAtPoint:point]; NSInteger columnIndex = [self columnAtPoint:point]; - NSTableColumn *tableColumn = (columnIndex != -1) ? [[self tableColumns] objectAtIndex:columnIndex] : nil; + NSTableColumn *tableColumn = (columnIndex != -1) ? self.tableColumns[columnIndex] : nil; return (columnIndex != -1) ? [(id)[self delegate] tableView:self toolTipForTableColumn:tableColumn row:rowIndex] : @""; } @@ -98,9 +98,9 @@ -(NSString *)view:(NSView *)view stringForToolTip:(NSToolTipTag)tag point:(NSPoi */ -(void)localiseHeaderStrings { - for (NSTableColumn * aColumn in [self tableColumns]) + for (NSTableColumn * aColumn in self.tableColumns) { - id headerCell = [aColumn headerCell]; + id headerCell = aColumn.headerCell; [headerCell setStringValue:NSLocalizedString([headerCell stringValue], nil)]; } } @@ -112,7 +112,7 @@ -(NSMenu *)menuForEvent:(NSEvent *)theEvent { if ([self delegate] && [[self delegate] respondsToSelector:@selector(tableView:menuWillAppear:)]) [(id)[self delegate] tableView:self menuWillAppear:theEvent]; - return [self selectedRow] >= 0 ? [self menu] : nil; + return self.selectedRow >= 0 ? self.menu : nil; } /* setHeaderImage @@ -121,12 +121,11 @@ -(NSMenu *)menuForEvent:(NSEvent *)theEvent -(void)setHeaderImage:(NSString *)identifier imageName:(NSString *)name { NSTableColumn * tableColumn = [self tableColumnWithIdentifier:identifier]; - NSTableHeaderCell * headerCell = [tableColumn headerCell]; - [headerCell setImage:[NSImage imageNamed:name]]; + NSTableHeaderCell * headerCell = tableColumn.headerCell; + headerCell.image = [NSImage imageNamed:name]; NSImageCell * imageCell = [[NSImageCell alloc] init]; - [tableColumn setDataCell:imageCell]; - [imageCell release]; + tableColumn.dataCell = imageCell; } @end diff --git a/src/ThinSplitView.h b/src/ThinSplitView.h index 35fca5af43..969685012b 100644 --- a/src/ThinSplitView.h +++ b/src/ThinSplitView.h @@ -21,5 +21,5 @@ #import @interface ThinSplitView : NSSplitView {} --(CGFloat)dividerThickness; +@property (readonly) CGFloat dividerThickness; @end diff --git a/src/ThinSplitView.m b/src/ThinSplitView.m index e66bd182fd..41361b2247 100644 --- a/src/ThinSplitView.m +++ b/src/ThinSplitView.m @@ -27,7 +27,7 @@ @implementation ThinSplitView */ -(CGFloat)dividerThickness { - return [self isVertical] ? 1.0 : 8.0; + return self.vertical ? 1.0 : 8.0; } /* drawDividerInRect @@ -35,7 +35,7 @@ -(CGFloat)dividerThickness */ -(void)drawDividerInRect:(NSRect)aRect { - if ([self isVertical]) + if (self.vertical) { [[NSColor colorWithCalibratedWhite:0.4 alpha:1] set]; NSRectFill(aRect); @@ -44,10 +44,10 @@ -(void)drawDividerInRect:(NSRect)aRect { NSImage * grip = [NSImage imageNamed:@"DBListSplitViewDimple"]; NSImage * bar = [NSImage imageNamed:@"DBListSplitViewBar"]; - NSRect gripRect = NSMakeRect(NSMinX(aRect) + (NSWidth(aRect) - [grip size].width) / 2, - NSMinY(aRect) + (NSHeight(aRect) - [grip size].height) / 2, - [grip size].width, - [grip size].height); + NSRect gripRect = NSMakeRect(NSMinX(aRect) + (NSWidth(aRect) - grip.size.width) / 2, + NSMinY(aRect) + (NSHeight(aRect) - grip.size.height) / 2, + grip.size.width, + grip.size.height); [bar drawInRect: aRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0]; [grip drawInRect: gripRect fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0]; diff --git a/src/ToolbarButton.h b/src/ToolbarButton.h index 754c0d7d7c..82b02b76fa 100644 --- a/src/ToolbarButton.h +++ b/src/ToolbarButton.h @@ -30,8 +30,8 @@ } // Public functions --(NSString *)itemIdentifier; --(id)initWithFrame:(NSRect)frameRect withItem:(NSToolbarItem *)tbItem; +@property (nonatomic, readonly, copy) NSString *itemIdentifier; +-(instancetype)initWithFrame:(NSRect)frameRect withItem:(NSToolbarItem *)tbItem /*NS_DESIGNATED_INITIALIZER*/; -(void)setSmallImage:(NSImage *)image; -(void)setSmallAlternateImage:(NSImage *)image; @end diff --git a/src/ToolbarButton.m b/src/ToolbarButton.m index 951e12a4aa..38064e7486 100644 --- a/src/ToolbarButton.m +++ b/src/ToolbarButton.m @@ -25,7 +25,7 @@ @implementation ToolbarButton * Initialise a ToolbarButton item. This is a subclass of a toolbar button * that responds properly to sizing requests from the toolbar. */ --(id)initWithFrame:(NSRect)frameRect withItem:(NSToolbarItem *)tbItem +-(instancetype)initWithFrame:(NSRect)frameRect withItem:(NSToolbarItem *)tbItem { if ((self = [super initWithFrame:frameRect]) != nil) { @@ -41,8 +41,8 @@ -(id)initWithFrame:(NSRect)frameRect withItem:(NSToolbarItem *)tbItem // behave like toolbar buttons. [self setButtonType:NSMomentaryChangeButton]; [self setBordered:NO]; - [self setBezelStyle:NSSmallSquareBezelStyle]; - [self setImagePosition:NSImageOnly]; + self.bezelStyle = NSSmallSquareBezelStyle; + self.imagePosition = NSImageOnly; } return self; } @@ -52,7 +52,7 @@ -(id)initWithFrame:(NSRect)frameRect withItem:(NSToolbarItem *)tbItem */ -(NSString *)itemIdentifier { - return [item itemIdentifier]; + return item.itemIdentifier; } /* setSmallImage @@ -60,11 +60,9 @@ -(NSString *)itemIdentifier */ -(void)setSmallImage:(NSImage *)newImage { - [newImage retain]; - [smallImage release]; smallImage = newImage; if (smallImage != nil) - smallImageSize = [smallImage size]; + smallImageSize = smallImage.size; } /* setSmallAlternateImage @@ -72,8 +70,6 @@ -(void)setSmallImage:(NSImage *)newImage */ -(void)setSmallAlternateImage:(NSImage *)newImage { - [newImage retain]; - [smallAlternateImage release]; smallAlternateImage = newImage; } @@ -84,14 +80,12 @@ -(void)setSmallAlternateImage:(NSImage *)newImage */ -(void)setImage:(NSImage *)newImage { - [newImage retain]; - [image release]; image = newImage; - [super setImage:image]; + super.image = image; if (image != nil) { - imageSize = [image size]; + imageSize = image.size; } } @@ -102,11 +96,9 @@ -(void)setImage:(NSImage *)newImage */ -(void)setAlternateImage:(NSImage *)newImage { - [newImage retain]; - [alternateImage release]; alternateImage = newImage; - [super setAlternateImage:alternateImage]; + super.alternateImage = alternateImage; } /* controlSize @@ -114,7 +106,7 @@ -(void)setAlternateImage:(NSImage *)newImage */ -(NSControlSize)controlSize { - return [[self cell] controlSize]; + return self.cell.controlSize; } /* setControlSize @@ -131,9 +123,9 @@ -(void)setControlSize:(NSControlSize)size // can assume that we're switching from those small versions. So we // need to replace the button image. if (image) - [super setImage:image]; + super.image = image; if (alternateImage) - [super setAlternateImage:alternateImage]; + super.alternateImage = alternateImage; s = imageSize; } else @@ -145,41 +137,24 @@ -(void)setControlSize:(NSControlSize)size NSImage * scaledDownImage = [image copy]; // Small size is about 3/4 the size of the regular image or // generally 24x24. - [scaledDownImage setSize:NSMakeSize(imageSize.width * 0.80, imageSize.height * 0.80)]; + scaledDownImage.size = NSMakeSize(imageSize.width * 0.80, imageSize.height * 0.80); [self setSmallImage:scaledDownImage]; - [scaledDownImage release]; } if (smallAlternateImage == nil) { NSImage * scaledDownAlternateImage = [alternateImage copy]; // Small size is about 3/4 the size of the regular image or // generally 24x24. - [scaledDownAlternateImage setSize:NSMakeSize(imageSize.width * 0.80, imageSize.height * 0.80)]; + scaledDownAlternateImage.size = NSMakeSize(imageSize.width * 0.80, imageSize.height * 0.80); [self setSmallAlternateImage:scaledDownAlternateImage]; - [scaledDownAlternateImage release]; } - [super setImage:smallImage]; - [super setAlternateImage:smallAlternateImage]; + super.image = smallImage; + super.alternateImage = smallAlternateImage; s = smallImageSize; } - [item setMinSize:s]; - [item setMaxSize:s]; + item.minSize = s; + item.maxSize = s; } -/* dealloc - * Clean up afterwards. - */ --(void)dealloc -{ - [image release]; - image=nil; - [alternateImage release]; - alternateImage=nil; - [smallImage release]; - smallImage=nil; - [smallAlternateImage release]; - smallAlternateImage=nil; - [super dealloc]; -} @end diff --git a/src/ToolbarItem.m b/src/ToolbarItem.m index 4904caf818..6361490e59 100644 --- a/src/ToolbarItem.m +++ b/src/ToolbarItem.m @@ -32,11 +32,11 @@ @implementation ToolbarItem */ -(void)validate { - if (![NSApp isActive]) + if (!NSApp.active) [self setEnabled:NO]; else [self setEnabled:YES]; - id target = [self target]; + id target = self.target; if ([target respondsToSelector:@selector(validateToolbarItem:)]) [self setEnabled:[target validateToolbarItem:self]]; } @@ -47,8 +47,8 @@ -(void)validate */ -(void)setEnabled:(BOOL)enabled { - [super setEnabled:enabled]; - [[self menuFormRepresentation] setEnabled:enabled]; + super.enabled = enabled; + self.menuFormRepresentation.enabled = enabled; } /* setView @@ -56,10 +56,10 @@ -(void)setEnabled:(BOOL)enabled */ -(void)setView:(NSView *)theView { - NSRect fRect = [theView frame]; - [super setView:theView]; - [self setMinSize:fRect.size]; - [self setMaxSize:fRect.size]; + NSRect fRect = theView.frame; + super.view = theView; + self.minSize = fRect.size; + self.maxSize = fRect.size; } /* compositeButtonImage @@ -71,9 +71,9 @@ -(void)compositeButtonImage:(NSString *)imageName fromPath:(NSString *)path { NSString * theImage = [NSString stringWithFormat:@"%@.tiff", imageName]; NSString * theSmallImage = [NSString stringWithFormat:@"small%@.tiff", imageName]; - NSString * resourcePath = [[NSBundle mainBundle] resourcePath]; + NSString * resourcePath = [NSBundle mainBundle].resourcePath; NSImage * userImage = [[NSImage alloc] initWithContentsOfFile:[path stringByAppendingPathComponent:theImage]]; - NSSize userImageSize = [userImage size]; + NSSize userImageSize = userImage.size; NSRect userImageRect = NSMakeRect(0.0, 0.0, userImageSize.width, userImageSize.height); // May not necessarily be a small image in which case we'd need to synthesize one from the large one @@ -83,37 +83,36 @@ -(void)compositeButtonImage:(NSString *)imageName fromPath:(NSString *)path if (smallUserImage != nil) { - smallUserImageSize = [smallUserImage size]; + smallUserImageSize = smallUserImage.size; smallUserImageRect = NSMakeRect(0.0, 0.0, smallUserImageSize.width, smallUserImageSize.height); } else { - [smallUserImage release]; - smallUserImage = [userImage retain]; + smallUserImage = userImage; smallUserImageSize = NSMakeSize(12.0, 12.0); smallUserImageRect = userImageRect; } NSImage * buttonImage = [[NSImage alloc] initWithContentsOfFile:[resourcePath stringByAppendingPathComponent:@"blankButton.tiff"]]; - NSSize buttonSize = [buttonImage size]; + NSSize buttonSize = buttonImage.size; [buttonImage lockFocus]; [userImage drawInRect:CenterRect(buttonSize, userImageSize) fromRect:userImageRect operation:NSCompositeSourceOver fraction:1.0]; [buttonImage unlockFocus]; NSImage * pressedImage = [[NSImage alloc] initWithContentsOfFile:[resourcePath stringByAppendingPathComponent:@"blankButtonPressedBurned.tiff"]]; - buttonSize = [pressedImage size]; + buttonSize = pressedImage.size; [pressedImage lockFocus]; [userImage drawInRect:CenterRect(buttonSize, userImageSize) fromRect:userImageRect operation:NSCompositeSourceOver fraction:1.0]; [pressedImage unlockFocus]; NSImage * smallNormalImage = [[NSImage alloc] initWithContentsOfFile:[resourcePath stringByAppendingPathComponent:@"blankSmallButton.tiff"]]; - buttonSize = [smallNormalImage size]; + buttonSize = smallNormalImage.size; [smallNormalImage lockFocus]; [smallUserImage drawInRect:CenterRect(buttonSize, smallUserImageSize) fromRect:smallUserImageRect operation:NSCompositeSourceOver fraction:1.0]; [smallNormalImage unlockFocus]; NSImage * smallPressedImage = [[NSImage alloc] initWithContentsOfFile:[resourcePath stringByAppendingPathComponent:@"blankSmallButtonPressed.tiff"]]; - buttonSize = [smallPressedImage size]; + buttonSize = smallPressedImage.size; [smallPressedImage lockFocus]; [smallUserImage drawInRect:CenterRect(buttonSize, smallUserImageSize) fromRect:smallUserImageRect operation:NSCompositeSourceOver fraction:1.0]; [smallPressedImage unlockFocus]; @@ -123,12 +122,6 @@ -(void)compositeButtonImage:(NSString *)imageName fromPath:(NSString *)path smallNormalImage:smallNormalImage smallPressedImage:smallPressedImage]; - [buttonImage release]; - [pressedImage release]; - [smallNormalImage release]; - [smallPressedImage release]; - [smallUserImage release]; - [userImage release]; } /* setButtonImage @@ -154,23 +147,22 @@ -(void)setButtonImage:(NSString *)imageName */ -(void)setButtonImages:(NSImage *)buttonImage pressedImage:(NSImage *)pressedImage smallNormalImage:(NSImage *)smallNormalImage smallPressedImage:(NSImage *)smallPressedImage { - NSSize buttonSize = [buttonImage size]; + NSSize buttonSize = buttonImage.size; ToolbarButton * button = [[ToolbarButton alloc] initWithFrame:NSMakeRect(0, 0, buttonSize.width, buttonSize.height) withItem:self]; - [button setImage:buttonImage]; - [button setAlternateImage:pressedImage]; + button.image = buttonImage; + button.alternateImage = pressedImage; [button setSmallImage:smallNormalImage]; [button setSmallAlternateImage:smallPressedImage]; // Save the current target and action and reapply them afterward because assigning a view // causes them to be deleted. - id currentTarget = [self target]; - SEL currentAction = [self action]; + id currentTarget = self.target; + SEL currentAction = self.action; [self setView:button]; - [self setTarget:currentTarget]; - [self setAction:currentAction]; + self.target = currentTarget; + self.action = currentAction; - [button release]; } /* setPopup @@ -185,23 +177,22 @@ -(void)setPopup:(NSString *)imageName withMenu:(NSMenu *)theMenu NSString * smallPressedImage = [NSString stringWithFormat:@"%@SmallPressed.tiff", imageName]; NSImage * buttonImage = [NSImage imageNamed:normalImage]; - NSSize buttonSize = [buttonImage size]; + NSSize buttonSize = buttonImage.size; PopupButton * button = [[PopupButton alloc] initWithFrame:NSMakeRect(0, 0, buttonSize.width, buttonSize.height) withItem:self]; - [button setImage:buttonImage]; - [button setAlternateImage:[NSImage imageNamed:pressedImage]]; + button.image = buttonImage; + button.alternateImage = [NSImage imageNamed:pressedImage]; [button setSmallImage:[NSImage imageNamed:smallNormalImage]]; [button setSmallAlternateImage:[NSImage imageNamed:smallPressedImage]]; [self setView:button]; - NSMenuItem * menuItem = [[[NSMenuItem alloc] init] autorelease]; - [button setTheMenu:theMenu]; + NSMenuItem * menuItem = [[NSMenuItem alloc] init]; + button.theMenu = theMenu; [button setPopupBelow:YES]; - [menuItem setSubmenu:[button theMenu]]; - [menuItem setTitle:[self label]]; - [self setMenuFormRepresentation:menuItem]; + menuItem.submenu = button.theMenu; + menuItem.title = self.label; + self.menuFormRepresentation = menuItem; - [button release]; } @end diff --git a/src/TreeFilterView.h b/src/TreeFilterView.h new file mode 100644 index 0000000000..622d2a0c60 --- /dev/null +++ b/src/TreeFilterView.h @@ -0,0 +1,28 @@ +// +// FilterView.h +// Vienna +// +// Created by Steve on 29/7/07. +// Copyright (c) 2004-2007 Steve Palmer. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +@interface TreeFilterView : NSView +{ + IBOutlet NSSearchField * filterSearchField; + NSImage * backgroundBrush; +} +@end diff --git a/src/TreeFilterView.m b/src/TreeFilterView.m new file mode 100644 index 0000000000..da6d3465b2 --- /dev/null +++ b/src/TreeFilterView.m @@ -0,0 +1,56 @@ +// +// FilterView.h +// Vienna +// +// Created by Steve on 29/7/07. +// Copyright (c) 2004-2007 Steve Palmer. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "TreeFilterView.h" + +@implementation TreeFilterView + +-(instancetype)initWithFrame:(NSRect)frameRect +{ + if ((self = [super initWithFrame:frameRect]) != nil) + { + backgroundBrush = nil; + } + return self; +} + +/* awakeFromNib + * Our init. + */ +-(void)awakeFromNib +{ + NSString * backgroundBrushURL = [[NSBundle mainBundle] pathForResource:@"filterViewBackground" ofType:@"tiff"]; + backgroundBrush = [[NSImage alloc] initWithContentsOfFile: backgroundBrushURL ]; + + // Set some useful tooltips. + [filterSearchField setToolTip:NSLocalizedString(@"Filter folders", nil)]; + [filterSearchField.cell setPlaceholderString:NSLocalizedString(@"Filter folders", nil)]; +} + +/* drawRect + * Draw the filter view background. + */ +-(void)drawRect:(NSRect)rect +{ + NSRect iRect = NSMakeRect(0, 0, 1, backgroundBrush.size.height - 1); + [backgroundBrush drawInRect:rect fromRect:iRect operation:NSCompositeSourceOver fraction:1]; +} + +@end diff --git a/src/TreeNode.h b/src/TreeNode.h index f99e810e11..40541a0aa1 100644 --- a/src/TreeNode.h +++ b/src/TreeNode.h @@ -35,32 +35,27 @@ } // Accessor functions --(id)init:(TreeNode *)parentNode atIndex:(NSInteger)insertIndex folder:(Folder *)folder canHaveChildren:(BOOL)childflag; --(void)setParentNode:(TreeNode *)parent; --(void)setFolder:(Folder *)newFolder; --(TreeNode *)parentNode; --(TreeNode *)nextSibling; --(TreeNode *)firstChild; +-(instancetype)init:(TreeNode *)parentNode atIndex:(NSInteger)insertIndex folder:(Folder *)folder canHaveChildren:(BOOL)childflag /*NS_DESIGNATED_INITIALIZER*/; +@property (nonatomic, strong) TreeNode *parentNode; +@property (nonatomic, readonly, strong) TreeNode *nextSibling; +@property (nonatomic, readonly, strong) TreeNode *firstChild; -(void)addChild:(TreeNode *)child atIndex:(NSInteger)insertIndex; -(void)removeChildren; -(void)removeChild:(TreeNode *)child andChildren:(BOOL)removeChildrenFlag; -(void)sortChildren:(NSInteger)sortMethod; --(NSString *)nodeName; +@property (nonatomic, readonly, copy) NSString *nodeName; -(TreeNode *)childByName:(NSString *)childName; -(TreeNode *)childByIndex:(NSInteger)index; -(NSInteger)indexOfChild:(TreeNode *)node; -(TreeNode *)nodeFromID:(NSInteger)n; --(Folder *)folder; --(NSInteger)nodeId; --(void)setNodeId:(NSInteger)n; --(NSUInteger)countOfChildren; --(void)setCanHaveChildren:(BOOL)childflag; --(BOOL)canHaveChildren; +@property (nonatomic, strong) Folder *folder; +@property (nonatomic) NSInteger nodeId; +@property (nonatomic, readonly) NSUInteger countOfChildren; +@property (nonatomic) BOOL canHaveChildren; -(NSComparisonResult)folderNameCompare:(TreeNode *)otherObject; --(NSProgressIndicator *)allocAndStartProgressIndicator; +@property (nonatomic, readonly, strong) NSProgressIndicator *allocAndStartProgressIndicator; -(void)stopAndReleaseProgressIndicator; --(NSProgressIndicator *)progressIndicator; --(void)setProgressIndicator:(NSProgressIndicator *)inProgressIndicator; +@property (nonatomic, strong) NSProgressIndicator *progressIndicator; @end diff --git a/src/TreeNode.m b/src/TreeNode.m index 886de297da..bb6d7ad459 100644 --- a/src/TreeNode.m +++ b/src/TreeNode.m @@ -27,20 +27,20 @@ @implementation TreeNode /* init * Initialises a treenode. */ --(id)init:(TreeNode *)parent atIndex:(NSInteger)insertIndex folder:(Folder *)theFolder canHaveChildren:(BOOL)childflag +-(instancetype)init:(TreeNode *)parent atIndex:(NSInteger)insertIndex folder:(Folder *)theFolder canHaveChildren:(BOOL)childflag { if ((self = [super init]) != nil) { - int folderId = (theFolder ? [theFolder itemId] : MA_Root_Folder); - [self setFolder:theFolder]; - [self setParentNode:parent]; - [self setCanHaveChildren:childflag]; - [self setNodeId:folderId]; + NSInteger folderId = (theFolder ? theFolder.itemId : MA_Root_Folder); + folder = theFolder; + parentNode = parent; + canHaveChildren = childflag; + nodeId = folderId; if (parent != nil) { [parent addChild:self atIndex:insertIndex]; } - children = [[NSMutableArray array] retain]; + children = [NSMutableArray array]; progressIndicator = nil; } return self; @@ -60,8 +60,8 @@ -(id)init:(TreeNode *)parent atIndex:(NSInteger)insertIndex folder:(Folder *)the -(void)addChild:(TreeNode *)child atIndex:(NSInteger)insertIndex { NSAssert(canHaveChildren, @"Trying to add children to a node that cannot have children (canHaveChildren==NO)"); - NSUInteger count = [children count]; - NSInteger sortMethod = [[Preferences standardPreferences] foldersTreeSortMethod]; + NSUInteger count = children.count; + NSInteger sortMethod = [Preferences standardPreferences].foldersTreeSortMethod; if (sortMethod != MA_FolderSort_Manual) { @@ -69,7 +69,7 @@ -(void)addChild:(TreeNode *)child atIndex:(NSInteger)insertIndex while (insertIndex < count) { - TreeNode * theChild = [children objectAtIndex:insertIndex]; + TreeNode * theChild = children[insertIndex]; if (sortMethod == MA_FolderSort_ByName) { if ([child folderNameCompare:theChild] == NSOrderedAscending) @@ -77,7 +77,7 @@ -(void)addChild:(TreeNode *)child atIndex:(NSInteger)insertIndex } else { - NSAssert1(TRUE, @"Unsupported folder sort method in addChild: %ld", sortMethod); + NSAssert1(TRUE, @"Unsupported folder sort method in addChild: %ld", (long)sortMethod); } ++insertIndex; } @@ -85,7 +85,7 @@ -(void)addChild:(TreeNode *)child atIndex:(NSInteger)insertIndex else if ((insertIndex < 0) || (insertIndex > count)) insertIndex = count; - [child setParentNode:self]; + child.parentNode = self; [children insertObject:child atIndex:insertIndex]; } @@ -116,7 +116,7 @@ -(void)sortChildren:(NSInteger)sortMethod break; default: - NSAssert1(TRUE, @"Unsupported folder sort method in sortChildren: %ld", sortMethod); + NSAssert1(TRUE, @"Unsupported folder sort method in sortChildren: %ld", (long)sortMethod); break; } } @@ -126,14 +126,14 @@ -(void)sortChildren:(NSInteger)sortMethod */ -(NSComparisonResult)folderNameCompare:(TreeNode *)otherObject { - Folder * thisFolder = [self folder]; - Folder * otherFolder = [otherObject folder]; + Folder * thisFolder = self.folder; + Folder * otherFolder = otherObject.folder; if (FolderType(thisFolder) < FolderType(otherFolder)) return NSOrderedAscending; if (FolderType(thisFolder) > FolderType(otherFolder)) return NSOrderedDescending; - return [[thisFolder name] caseInsensitiveCompare:[otherFolder name]]; + return [thisFolder.name caseInsensitiveCompare:otherFolder.name]; } /* removeChildren @@ -150,7 +150,7 @@ -(void)removeChildren */ -(TreeNode *)nodeFromID:(NSInteger)n { - if ([self nodeId] == n) + if (self.nodeId == n) return self; TreeNode * theNode; @@ -170,7 +170,7 @@ -(TreeNode *)childByName:(NSString *)childName { for (TreeNode * node in children) { - if ([childName isEqual:[node nodeName]]) + if ([childName isEqual:node.nodeName]) return node; } return nil; @@ -182,7 +182,7 @@ -(TreeNode *)childByName:(NSString *)childName */ -(TreeNode *)childByIndex:(NSInteger)index { - return [children objectAtIndex:index]; + return children[index]; } /* indexOfChild @@ -215,7 +215,7 @@ -(TreeNode *)parentNode -(TreeNode *)nextSibling { NSInteger childIndex = [parentNode indexOfChild:self]; - if (childIndex == NSNotFound || ++childIndex >= [parentNode countOfChildren]) + if (childIndex == NSNotFound || ++childIndex >= parentNode.countOfChildren) return nil; return [parentNode childByIndex:childIndex]; } @@ -225,9 +225,9 @@ -(TreeNode *)nextSibling */ -(TreeNode *)firstChild { - if ([children count] == 0) + if (children.count == 0) return nil; - return [children objectAtIndex:0]; + return children[0]; } /* setNodeId @@ -251,8 +251,6 @@ -(NSInteger)nodeId */ -(void)setFolder:(Folder *)newFolder { - [newFolder retain]; - [folder release]; folder = newFolder; } @@ -273,9 +271,9 @@ -(NSString *)nodeName { if (folder != nil) { if (IsGoogleReaderFolder(folder)) { - return [NSString stringWithFormat:@"☁️ %@",[folder name]]; + return [NSString stringWithFormat:@"☁️ %@",folder.name]; } else { - return [folder name]; + return folder.name; } } return @""; @@ -286,7 +284,7 @@ -(NSString *)nodeName */ -(NSUInteger)countOfChildren { - return [children count]; + return children.count; } /* setCanHaveChildren @@ -313,7 +311,8 @@ -(BOOL)canHaveChildren */ -(NSString *)description { - return [NSString stringWithFormat:@"%@ (Parent=%p, # of children=%ld)", [folder name], parentNode, [children count]]; + return [NSString stringWithFormat:@"%@ (Parent=%p, # of children=%ld)", + folder.name, parentNode, (unsigned long)children.count]; } /* allocAndStartProgressIndicator: @@ -324,8 +323,8 @@ -(NSProgressIndicator *)allocAndStartProgressIndicator // Allocate and initialize the spinning progress indicator. NSRect progressRect = NSMakeRect(0, 0, PROGRESS_INDICATOR_DIMENSION, PROGRESS_INDICATOR_DIMENSION); progressIndicator = [[NSProgressIndicator alloc] initWithFrame:progressRect]; - [progressIndicator setControlSize:NSSmallControlSize]; - [progressIndicator setStyle:NSProgressIndicatorSpinningStyle]; + progressIndicator.controlSize = NSSmallControlSize; + progressIndicator.style = NSProgressIndicatorSpinningStyle; [progressIndicator setUsesThreadedAnimation:YES]; // Start the animation. @@ -347,7 +346,6 @@ -(void)stopAndReleaseProgressIndicator [progressIndicator removeFromSuperviewWithoutNeedingDisplay]; // Release the progress indicator. - [progressIndicator release]; progressIndicator = nil; } @@ -371,22 +369,8 @@ - (void)setProgressIndicator:(NSProgressIndicator *)inProgressIndicator { if (progressIndicator != inProgressIndicator) { - [progressIndicator release]; - progressIndicator = [inProgressIndicator retain]; + progressIndicator = inProgressIndicator; } } -/* dealloc - * Clean up and release resources. - */ --(void)dealloc -{ - [children release]; - children=nil; - [folder release]; - folder=nil; - [progressIndicator release]; - progressIndicator=nil; - [super dealloc]; -} @end diff --git a/src/URLHandlerCommand.m b/src/URLHandlerCommand.m index 3c2d00b82e..7a8c675375 100644 --- a/src/URLHandlerCommand.m +++ b/src/URLHandlerCommand.m @@ -34,7 +34,7 @@ @implementation ViennaScriptCommand */ -(id)performDefaultImplementation { - NSScanner * scanner = [NSScanner scannerWithString:[self directParameter]]; + NSScanner * scanner = [NSScanner scannerWithString:self.directParameter]; NSString * urlPrefix = nil; [scanner scanUpToString:@":" intoString:&urlPrefix]; diff --git a/src/UnifiedDisplayView.h b/src/UnifiedDisplayView.h index f4c6280a76..1f08840d93 100644 --- a/src/UnifiedDisplayView.h +++ b/src/UnifiedDisplayView.h @@ -21,34 +21,27 @@ #import #import "BrowserView.h" #import "ArticleBaseView.h" -#import "PXListView.h" +#import "TableViewExtensions.h" @class AppController; @class ArticleController; @class ArticleView; -@class FoldersTree; -@interface UnifiedDisplayView : NSView +@interface UnifiedDisplayView : NSView { IBOutlet AppController * controller; IBOutlet ArticleController * articleController; - IBOutlet PXListView *articleList; - IBOutlet FoldersTree * foldersTree; - - int currentSelectedRow; - BOOL blockSelectionHandler; - BOOL blockMarkRead; + IBOutlet ExtendedTableView *articleList; NSTimer * markReadTimer; - NSString * guidOfArticleToSelect; NSMutableArray * rowHeightArray; + NSProgressIndicator * progressIndicator; } // Public functions --(void)initTableView; -(void)updateAlternateMenuTitle; --(NSArray *)markedArticleRange; --(BOOL)canDeleteMessageAtRow:(int)row; +-(void)saveTableSettings; +-(BOOL)canDeleteMessageAtRow:(NSInteger)row; - (void)webViewLoadFinished:(NSNotification *)notification; @end diff --git a/src/UnifiedDisplayView.m b/src/UnifiedDisplayView.m index 44e5107cb2..fbdd530c7a 100644 --- a/src/UnifiedDisplayView.m +++ b/src/UnifiedDisplayView.m @@ -30,10 +30,11 @@ #import "BrowserPane.h" #define LISTVIEW_CELL_IDENTIFIER @"ArticleCellView" -// 150 seems a reasonable value to avoid calculating too many frames before being able to update display -#define DEFAULT_CELL_HEIGHT 150 -#define XPOS_IN_CELL 6 -#define YPOS_IN_CELL 2 +// 300 seems a reasonable value to avoid calculating too many frames before being able to update display +// this is big enough to allow the user to start reading while the frame is being rendered +#define DEFAULT_CELL_HEIGHT 300.0 +#define XPOS_IN_CELL 6.0 +#define YPOS_IN_CELL 2.0 // Private functions @interface UnifiedDisplayView (Private) @@ -41,11 +42,9 @@ -(void)initTableView; -(BOOL)copyTableSelection:(NSArray *)rows toPasteboard:(NSPasteboard *)pboard; -(void)selectArticleAfterReload; -(void)handleReadingPaneChange:(NSNotificationCenter *)nc; - -(BOOL)scrollToArticle:(NSString *)guid; - -(void)selectFirstUnreadInFolder; - -(BOOL)viewNextUnreadInCurrentFolder:(int)currentRow; + -(BOOL)viewNextUnreadInCurrentFolder:(NSInteger)currentRow; -(void)markCurrentRead:(NSTimer *)aTimer; - -(void)makeRowSelectedAndVisible:(int)rowIndex; + -(void)makeRowSelectedAndVisible:(NSInteger)rowIndex; -(void)printDocument; @end @@ -57,14 +56,11 @@ @implementation UnifiedDisplayView /* initWithFrame * Initialise our view. */ --(id)initWithFrame:(NSRect)frame +-(instancetype)initWithFrame:(NSRect)frame { self= [super initWithFrame:frame]; if (self) { - blockSelectionHandler = NO; - blockMarkRead = NO; - guidOfArticleToSelect = nil; markReadTimer = nil; rowHeightArray = [[NSMutableArray alloc] init]; } @@ -79,8 +75,8 @@ -(void)awakeFromNib // Register for notification NSNotificationCenter * nc = [NSNotificationCenter defaultCenter]; [nc addObserver:self selector:@selector(handleReadingPaneChange:) name:@"MA_Notify_ReadingPaneChange" object:nil]; - [nc addObserver:self selector:@selector(handleArticleListStateChange:) name:@"MA_Notify_ArticleListStateChange" object:nil]; + [self initTableView]; } /* initTableView @@ -89,9 +85,7 @@ -(void)awakeFromNib -(void)initTableView { // Variable initialization here - currentSelectedRow = -1; - - [articleList setBackgroundColor:[NSColor whiteColor]]; + articleList.backgroundColor = [NSColor whiteColor]; [articleList setAllowsMultipleSelection:YES]; // Dynamically create the popup menu. This is one less thing to @@ -106,19 +100,20 @@ -(void)initTableView [articleListMenu addItem:[NSMenuItem separatorItem]]; [articleListMenu addItem:copyOfMenuItemWithAction(@selector(viewSourceHomePage:))]; NSMenuItem * alternateItem = copyOfMenuItemWithAction(@selector(viewSourceHomePageInAlternateBrowser:)); - [alternateItem setKeyEquivalentModifierMask:NSAlternateKeyMask]; + alternateItem.keyEquivalentModifierMask = NSAlternateKeyMask; [alternateItem setAlternate:YES]; [articleListMenu addItem:alternateItem]; [articleListMenu addItem:copyOfMenuItemWithAction(@selector(viewArticlePages:))]; alternateItem = copyOfMenuItemWithAction(@selector(viewArticlePagesInAlternateBrowser:)); - [alternateItem setKeyEquivalentModifierMask:NSAlternateKeyMask]; + alternateItem.keyEquivalentModifierMask = NSAlternateKeyMask; [alternateItem setAlternate:YES]; [articleListMenu addItem:alternateItem]; - [articleList setMenu:articleListMenu]; - [articleListMenu release]; + articleList.menu = articleListMenu; // Set the target for copy, drag... [articleList setDelegate:self]; + [articleList setDataSource:self]; + [articleList accessibilitySetOverrideValue:NSLocalizedString(@"Articles", nil) forAttribute:NSAccessibilityDescriptionAttribute]; } /* dealloc @@ -127,14 +122,9 @@ -(void)initTableView -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; + [articleList setDataSource:nil]; [articleList setDelegate:nil]; - [markReadTimer release]; - markReadTimer=nil; - [guidOfArticleToSelect release]; - guidOfArticleToSelect=nil; - [rowHeightArray release]; - rowHeightArray=nil; - [super dealloc]; + [rowHeightArray removeAllObjects]; } #pragma mark - @@ -145,10 +135,10 @@ -(void)dealloc */ -(WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request { - [controller openURL:[request URL] inPreferredBrowser:YES]; + [controller openURL:request.URL inPreferredBrowser:YES]; // Change this to handle modifier key? // Is this covered by the webView policy? - [[NSApp mainWindow] makeFirstResponder:self]; + [NSApp.mainWindow makeFirstResponder:self]; return nil; } @@ -183,7 +173,7 @@ - (BOOL)webView:(WebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString */ -(void)webView:(WebView *)sender setStatusText:(NSString *)text { - if ([[controller browserView] activeTabItemView] == self) + if (controller.browserView.activeTabItemView == self) [controller setStatusMessage:text persist:NO]; } @@ -191,10 +181,10 @@ -(void)webView:(WebView *)sender setStatusText:(NSString *)text * Called from the webview when the user positions the mouse over an element. If it's a link * then echo the URL to the status bar like Safari does. */ --(void)webView:(WebView *)sender mouseDidMoveOverElement:(NSDictionary *)elementInformation modifierFlags:(NSUInteger )modifierFlags +-(void)webView:(WebView *)sender mouseDidMoveOverElement:(NSDictionary *)elementInformation modifierFlags:(NSUInteger)modifierFlags { NSURL * url = [elementInformation valueForKey:@"WebElementLinkURL"]; - [controller setStatusMessage:(url ? [url absoluteString] : @"") persist:NO]; + [controller setStatusMessage:(url ? url.absoluteString : @"") persist:NO]; } /* contextMenuItemsForElement @@ -208,27 +198,26 @@ -(NSArray *)webView:(WebView *)sender contextMenuItemsForElement:(NSDictionary * return [controller contextMenuItemsForElement:element defaultMenuItems:defaultMenuItems]; NSMutableArray * newDefaultMenu = [[NSMutableArray alloc] init]; - int count = [defaultMenuItems count]; - int index; + NSInteger count = defaultMenuItems.count; + NSInteger index; // Copy over everything but the reload menu item, which we can't handle if // this is not a full HTML page since we don't have an URL. for (index = 0; index < count; index++) { - NSMenuItem * menuItem = [defaultMenuItems objectAtIndex:index]; - if ([menuItem tag] != WebMenuItemTagReload) + NSMenuItem * menuItem = defaultMenuItems[index]; + if (menuItem.tag != WebMenuItemTagReload) [newDefaultMenu addObject:menuItem]; } // If we still have some useful menu items (other than Webkit's Web Inspector) // then use them for the new default menu - if ([newDefaultMenu count] > 0 && ![[newDefaultMenu objectAtIndex:0] isSeparatorItem]) - defaultMenuItems = [newDefaultMenu autorelease]; + if (newDefaultMenu.count > 0 && ![newDefaultMenu[0] isSeparatorItem]) + defaultMenuItems = [newDefaultMenu copy]; // otherwise set the default items to nil as we may have removed all the items. else { defaultMenuItems = nil; - [newDefaultMenu release]; } // Return the default menu items. @@ -238,20 +227,17 @@ -(NSArray *)webView:(WebView *)sender contextMenuItemsForElement:(NSDictionary * #pragma mark - #pragma mark WebFrameLoadDelegate -/* didCommitLoadForFrame - * Invoked when content of a frame starts arriving for a webview load +/* didStartProvisionalLoadForFrame: + * Invoked when a frame load is in progress */ --(void)webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)webFrame +-(void)webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)webFrame { - if([webFrame isEqual:[sender mainFrame]]) + if([webFrame isEqual:sender.mainFrame]) { - id obj = [sender superview]; + id obj = sender.superview; if ([obj isKindOfClass:[ArticleCellView class]]) { ArticleCellView * cell = (ArticleCellView *)obj; [cell setInProgress:YES]; - NSRect frame = sender.frame; - frame.size.height = 1; // Set the height to a small one. - frame.size.width = 1; } } } @@ -261,27 +247,24 @@ -(void)webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)webFrame */ -(void)webView:(WebView *)sender didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)webFrame { - // Not really an error. A plugin is grabbing the URL and will handle it by itself. - if (!([[error domain] isEqualToString:WebKitErrorDomain] && [error code] == WebKitErrorPlugInWillHandleLoad)) + // Not really errors. Load is cancelled or a plugin is grabbing the URL and will handle it by itself. + if (!([error.domain isEqualToString:WebKitErrorDomain] && (error.code == NSURLErrorCancelled || error.code == WebKitErrorPlugInWillHandleLoad))) { - id obj = [sender superview]; + id obj = sender.superview; if ([obj isKindOfClass:[ArticleCellView class]]) { ArticleCellView * cell = (ArticleCellView *)obj; [cell setInProgress:NO]; - NSUInteger row= [cell articleRow]; - NSArray * allArticles = [articleController allArticles]; - if (row < (NSInteger)[allArticles count]) + NSUInteger row= cell.articleRow; + NSArray * allArticles = articleController.allArticles; + if (row < (NSInteger)allArticles.count) { - NSRect frame = sender.frame; - frame.size.height = 1; // Set the height to a small one. - frame.size.width = 1; - [articleList reloadRowAtIndex:row]; + [articleList reloadDataForRowIndexes:[NSIndexSet indexSetWithIndex:row] columnIndexes:[NSIndexSet indexSetWithIndex:0]]; } } else // TODO : what should we do ? - NSLog(@"Webview error associated to object of class %@", [obj class]); + NSLog(@"Webview error %@ associated to object of class %@", error, [obj class]); } } @@ -293,91 +276,75 @@ -(void)webView:(WebView *)sender didFailLoadWithError:(NSError *)error forFrame: */ - (void)webViewLoadFinished:(NSNotification *)notification { - id obj = [notification object]; + id obj = notification.object; if([obj isKindOfClass:[ArticleView class]]) { ArticleView * sender = (ArticleView *)obj; - id objView = [sender superview]; + id objView = sender.superview; if ([objView isKindOfClass:[ArticleCellView class]]) { ArticleCellView * cell = (ArticleCellView *)objView; - NSUInteger row= [cell row]; - // get the height of the rendered frame. - // I have tested many NSHeight([[ ... ] frame]) tricks, but they were unreliable - // and using DOM to get documentElement scrollHeight and/or offsetHeight was the simplest - // way to get the height with WebKit - // Ref : http://james.padolsey.com/javascript/get-document-height-cross-browser/ - // - // this temporary enable Javascript if it is not enabled, then reset to preference - [[sender preferences] setJavaScriptEnabled:YES]; - NSString* outputHeight = [sender stringByEvaluatingJavaScriptFromString:@"document.documentElement.scrollHeight"]; - NSString* bodyHeight = [sender stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight"]; - NSString* clientHeight = [sender stringByEvaluatingJavaScriptFromString:@"document.documentElement.clientHeight"]; - [[sender preferences] setJavaScriptEnabled:[[Preferences standardPreferences] useJavaScript]]; - CGFloat fittingHeight = [outputHeight floatValue]; - - //get the rect of the current webview frame - NSRect webViewRect = [sender frame]; - //calculate the new frame - NSRect newWebViewRect = NSMakeRect(XPOS_IN_CELL, - YPOS_IN_CELL, - NSWidth(webViewRect), - fittingHeight); - //set the new frame to the webview - [sender setFrame:newWebViewRect]; - if (row == [cell articleRow] && row < [[articleController allArticles] count] - && [cell folderId] == [[[articleController allArticles] objectAtIndex:row] folderId]) + NSUInteger row= [articleList rowForView:objView]; + if (row == cell.articleRow && row < articleController.allArticles.count + && cell.folderId == [articleController.allArticles[row] folderId]) { //relevant cell - if ([bodyHeight isEqualToString:outputHeight] && [bodyHeight isEqualToString:clientHeight]) { - if (row < [rowHeightArray count]) - [rowHeightArray replaceObjectAtIndex:row withObject:[NSNumber numberWithFloat:fittingHeight]]; - else - { NSInteger toAdd = row - [rowHeightArray count] ; - for (NSInteger i = 0 ; i < toAdd ; i++) { - [rowHeightArray addObject:[NSNumber numberWithFloat:DEFAULT_CELL_HEIGHT]]; - } - [rowHeightArray addObject:[NSNumber numberWithFloat:fittingHeight]]; - } - [cell setInProgress:NO]; - [articleList reloadRowAtIndex:row]; - } - else - { - // something in the dimensions went wrong : force a reload - [self resubmitWebView:sender]; - } - } - else { //non relevant cell - [cell setInProgress:NO]; - NSRect frame = sender.frame; - frame.size.height = 1; // Set the height to a small one. - frame.size.width = 1; - [articleList reloadRowAtIndex:row]; - } + NSString* outputHeight; + NSString* bodyHeight; + NSString* clientHeight; + CGFloat fittingHeight; + do // loop until dimensions are OK + { + // get the height of the rendered frame. + // I have tested many NSHeight([[ ... ] frame]) tricks, but they were unreliable + // and using DOM to get documentElement scrollHeight and/or offsetHeight was the simplest + // way to get the height with WebKit + // Ref : http://james.padolsey.com/javascript/get-document-height-cross-browser/ + // + // this temporary enable Javascript if it is not enabled, then reset to preference + [sender.preferences setJavaScriptEnabled:YES]; + outputHeight = [sender stringByEvaluatingJavaScriptFromString:@"document.documentElement.scrollHeight"]; + bodyHeight = [sender stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight"]; + clientHeight = [sender stringByEvaluatingJavaScriptFromString:@"document.documentElement.clientHeight"]; + sender.preferences.javaScriptEnabled = [Preferences standardPreferences].useJavaScript; + fittingHeight = outputHeight.doubleValue; + //get the rect of the current webview frame + NSRect webViewRect = sender.frame; + //calculate the new frame + NSRect newWebViewRect = NSMakeRect(XPOS_IN_CELL, + YPOS_IN_CELL, + NSWidth(webViewRect), + fittingHeight); + //set the new frame to the webview + sender.frame = newWebViewRect; + } while (![bodyHeight isEqualToString:outputHeight] || ![bodyHeight isEqualToString:clientHeight]); + + if (row < rowHeightArray.count) + rowHeightArray[row] = @(fittingHeight); + else + { NSInteger toAdd = row - rowHeightArray.count ; + for (NSInteger i = 0 ; i < toAdd ; i++) + { + [rowHeightArray addObject:@DEFAULT_CELL_HEIGHT]; + } + [rowHeightArray addObject:@(fittingHeight)]; + } + [cell setInProgress:NO]; + [articleList noteHeightOfRowsWithIndexesChanged:[NSIndexSet indexSetWithIndex:row]]; + } + else { //non relevant cell + [cell setInProgress:NO]; + if (row < articleController.allArticles.count) + { + [articleList reloadDataForRowIndexes:[NSIndexSet indexSetWithIndex:row] columnIndexes:[NSIndexSet indexSetWithIndex:0]]; + } + } } else { - // not an ArticleCellView anymore : reposition it, just in case... - NSRect frame = sender.frame; - frame.size.height = 1; // Set the height to a small one. - frame.size.width = 1; + // not an ArticleCellView anymore + // ??? } } } --(void)resubmitWebView:(WebView *)sender -{ - ArticleCellView * cell = (ArticleCellView *)[sender superview]; - NSUInteger row = [cell row]; - if (cell != nil) - { - NSRect frame = sender.frame; - frame.size.height = 1; // Set the height to a small one. - frame.size.width = 1; - [self webViewLoadFinished:[NSNotification notificationWithName:WebViewProgressFinishedNotification object:sender]]; - } - else - [articleList reloadRowAtIndex:row]; -} - /* updateAlternateMenuTitle * Sets the approprate title for the alternate item in the contextual menu * when user changes preference for opening pages in external browser @@ -386,8 +353,8 @@ -(void)updateAlternateMenuTitle { NSMenuItem * mainMenuItem; NSMenuItem * contextualMenuItem; - int index; - NSMenu * articleListMenu = [articleList menu]; + NSInteger index; + NSMenu * articleListMenu = articleList.menu; if (articleListMenu == nil) return; mainMenuItem = menuItemWithAction(@selector(viewSourceHomePageInAlternateBrowser:)); @@ -397,7 +364,7 @@ -(void)updateAlternateMenuTitle if (index >= 0) { contextualMenuItem = [articleListMenu itemAtIndex:index]; - [contextualMenuItem setTitle:[mainMenuItem title]]; + contextualMenuItem.title = mainMenuItem.title; } } mainMenuItem = menuItemWithAction(@selector(viewArticlePagesInAlternateBrowser:)); @@ -407,7 +374,7 @@ -(void)updateAlternateMenuTitle if (index >= 0) { contextualMenuItem = [articleListMenu itemAtIndex:index]; - [contextualMenuItem setTitle:[mainMenuItem title]]; + contextualMenuItem.title = mainMenuItem.title; } } } @@ -415,47 +382,34 @@ -(void)updateAlternateMenuTitle /* ensureSelectedArticle * Ensure that there is a selected article and that it is visible. */ --(void)ensureSelectedArticle:(BOOL)singleSelection +-(void)ensureSelectedArticle { - if (singleSelection) - { - int nextRow =[[articleList selectedRows] firstIndex]; - int articlesCount = [[articleController allArticles] count]; - - currentSelectedRow = -1; - if (nextRow < 0 || nextRow >= articlesCount) - nextRow = articlesCount - 1; - [self makeRowSelectedAndVisible:nextRow]; - } + if (articleList.selectedRow == -1) + [self makeRowSelectedAndVisible:0]; else - { - if ([articleList selectedRow] == -1) - [self makeRowSelectedAndVisible:0]; - else - [articleList scrollRowToVisible:[articleList selectedRow]]; - } + [articleList scrollRowToVisible:articleList.selectedRow]; } /* scrollToArticle - * Moves the selection to the specified article. Returns YES if we found the - * article, NO otherwise. + * Moves the selection to the specified article. */ --(BOOL)scrollToArticle:(NSString *)guid +-(void)scrollToArticle:(NSString *)guid { - int rowIndex = 0; - BOOL found = NO; - - for (Article * thisArticle in [articleController allArticles]) + if (guid != nil) { - if ([[thisArticle guid] isEqualToString:guid]) + NSInteger rowIndex = 0; + for (Article * thisArticle in articleController.allArticles) { - [self makeRowSelectedAndVisible:rowIndex]; - found = YES; - break; + if ([thisArticle.guid isEqualToString:guid]) + { + [self makeRowSelectedAndVisible:rowIndex]; + return; + } + ++rowIndex; } - ++rowIndex; } - return found; + + [articleList deselectAll:self]; } #pragma mark - @@ -474,25 +428,25 @@ -(NSView *)mainView */ -(WebView *)webView { - ArticleCellView * cellView = (ArticleCellView *)[[articleList visibleCells] objectAtIndex:0]; - return [cellView articleView]; + ArticleCellView * cellView = (ArticleCellView *)[articleList viewAtColumn:0 row:0 makeIfNecessary:YES]; + return cellView.articleView; } /* performFindPanelAction * Implement the search action. */ --(void)performFindPanelAction:(int)actionTag +-(void)performFindPanelAction:(NSInteger)actionTag { - [self refreshFolder:MA_Refresh_ReloadFromDatabase]; + [articleController reloadArrayOfArticles]; // This action is send continuously by the filter field, so make sure not the mark read while searching - if (currentSelectedRow < 0 && [[articleController allArticles] count] > 0 ) + if ([articleList selectedRow] < 0 && articleController.allArticles.count > 0 ) { BOOL shouldSelectArticle = YES; - if ([[Preferences standardPreferences] markReadInterval] > 0.0f) + if ([Preferences standardPreferences].markReadInterval > 0.0f) { - Article * article = [[articleController allArticles] objectAtIndex:0u]; - if (![article isRead]) + Article * article = articleController.allArticles[0u]; + if (!article.read) shouldSelectArticle = NO; } if (shouldSelectArticle) @@ -538,16 +492,16 @@ -(void)saveTableSettings Preferences * prefs = [Preferences standardPreferences]; // Remember the current folder and article - NSString * guid = (currentSelectedRow >= 0 && currentSelectedRow < [[articleController allArticles] count]) ? [[[articleController allArticles] objectAtIndex:currentSelectedRow] guid] : @""; - [prefs setInteger:[articleController currentFolderId] forKey:MAPref_CachedFolderID]; - [prefs setString:guid forKey:MAPref_CachedArticleGUID]; + NSString * guid = [self.selectedArticle guid]; + [prefs setInteger:articleController.currentFolderId forKey:MAPref_CachedFolderID]; + [prefs setString:(guid != nil ? guid : @"") forKey:MAPref_CachedArticleGUID]; } /* handleKeyDown [delegate] * Support special key codes. If we handle the key, return YES otherwise * return NO to allow the framework to pass it on for default processing. */ --(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger )flags +-(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger)flags { return [controller handleKeyDown:keyChar withFlags:flags]; } @@ -555,14 +509,9 @@ -(BOOL)handleKeyDown:(unichar)keyChar withFlags:(NSUInteger )flags /* canDeleteMessageAtRow * Returns YES if the message at the specified row can be deleted, otherwise NO. */ --(BOOL)canDeleteMessageAtRow:(int)row +-(BOOL)canDeleteMessageAtRow:(NSInteger)row { - if ((row >= 0) && (row < [[articleController allArticles] count])) - { - Article * article = [[articleController allArticles] objectAtIndex:row]; - return (article != nil) && ![[Database sharedDatabase] readOnly] && [[articleList window] isVisible]; - } - return NO; + return articleList.window.visible && (self.selectedArticle != nil) && ![Database sharedManager].readOnly; } /* selectedArticle @@ -570,7 +519,8 @@ -(BOOL)canDeleteMessageAtRow:(int)row */ -(Article *)selectedArticle { - return (currentSelectedRow >= 0 && currentSelectedRow < [[articleController allArticles] count]) ? [[articleController allArticles] objectAtIndex:currentSelectedRow] : nil; + NSInteger currentSelectedRow = articleList.selectedRow; + return (currentSelectedRow >= 0 && currentSelectedRow < articleController.allArticles.count) ? articleController.allArticles[currentSelectedRow] : nil; } /* printDocument @@ -581,26 +531,12 @@ -(void)printDocument:(id)sender //TODO } --(void)handleArticleListStateChange:(NSNotification *)note -{ - if (self == [articleController mainArticleView]) - { - NSInteger folderId = [(Folder *)[note object] itemId]; - NSInteger controllerFolderId = [controller currentFolderId]; - Folder * controllerFolder = [[Database sharedDatabase] folderFromID:controllerFolderId]; - if (folderId == controllerFolderId || ( !IsRSSFolder(controllerFolder) && !IsGoogleReaderFolder(controllerFolder) )) - { - [self refreshCurrentFolder]; - } - } -} - /* handleReadingPaneChange * Respond to the change to the reading pane orientation. */ -(void)handleReadingPaneChange:(NSNotificationCenter *)nc { - if (self == [articleController mainArticleView]) + if (self == articleController.mainArticleView) { [articleList reloadData]; } @@ -610,95 +546,44 @@ -(void)handleReadingPaneChange:(NSNotificationCenter *)nc * Selects the specified row in the table and makes it visible by * scrolling to it. */ --(void)makeRowSelectedAndVisible:(int)rowIndex +-(void)makeRowSelectedAndVisible:(NSInteger)rowIndex { - if ([[articleController allArticles] count] == 0u) + if (articleController.allArticles.count == 0u) { - currentSelectedRow = -1; + [articleList deselectAll:self]; } else { - [articleList setSelectedRow:rowIndex]; - if (currentSelectedRow == -1 || blockSelectionHandler) - { - currentSelectedRow = rowIndex; - } + [articleList selectRowIndexes:[NSIndexSet indexSetWithIndex:rowIndex] byExtendingSelection:NO]; [articleList scrollRowToVisible:rowIndex]; } } -/* displayFirstUnread - * Locate the first unread article. +/* + * viewNextUnreadInFolder + * Search the following unread article in the current folder + * and select it if found */ --(void)displayFirstUnread +-(BOOL)viewNextUnreadInFolder { - // Mark the current article read. - [self markCurrentRead:nil]; - - // If there are any unread articles then select the first one in the - // first folder. - if ([[Database sharedDatabase] countOfUnread] > 0) - { - guidOfArticleToSelect = nil; - - // Get the first folder with unread articles. - int firstFolderWithUnread = [foldersTree firstFolderWithUnread]; - - // Select the folder in the tree view. - [foldersTree selectFolder:firstFolderWithUnread]; - - // Now select the first unread article. - [self selectFirstUnreadInFolder]; - } -} - -/* displayNextUnread - * Locate the next unread article from the current article onward. - */ --(void)displayNextUnread -{ - // Save the value of currentSelectedRow. - int currentRow = currentSelectedRow; - - // Mark the current article read. - [self markCurrentRead:nil]; - - // Scan the current folder from the selection forward. If nothing found, try - // other folders until we come back to ourselves. - if (([[Database sharedDatabase] countOfUnread] > 0) && (![self viewNextUnreadInCurrentFolder:currentRow])) - { - int nextFolderWithUnread = [foldersTree nextFolderWithUnread:[articleController currentFolderId]]; - if (nextFolderWithUnread != -1) - { - if (nextFolderWithUnread == [articleController currentFolderId]) - { - [self viewNextUnreadInCurrentFolder:-1]; - } - else - { - guidOfArticleToSelect = nil; - [foldersTree selectFolder:nextFolderWithUnread]; - [self selectFirstUnreadInFolder]; - } - } - } + return [self viewNextUnreadInCurrentFolder:([articleList selectedRow] + 1)]; } /* viewNextUnreadInCurrentFolder * Select the next unread article in the current folder after currentRow. */ --(BOOL)viewNextUnreadInCurrentFolder:(int)currentRow +-(BOOL)viewNextUnreadInCurrentFolder:(NSInteger)currentRow { if (currentRow < 0) currentRow = 0; - NSArray * allArticles = [articleController allArticles]; - int totalRows = [allArticles count]; + NSArray * allArticles = articleController.allArticles; + NSInteger totalRows = allArticles.count; Article * theArticle; while (currentRow < totalRows) { - theArticle = [allArticles objectAtIndex:currentRow]; - if (![theArticle isRead]) + theArticle = allArticles[currentRow]; + if (!theArticle.read) { [self makeRowSelectedAndVisible:currentRow]; return YES; @@ -710,36 +595,18 @@ -(BOOL)viewNextUnreadInCurrentFolder:(int)currentRow /* selectFirstUnreadInFolder * Moves the selection to the first unread article in the current article list or the - * last article if the folder has no unread articles. + * first article if the folder has no unread articles. */ --(void)selectFirstUnreadInFolder +-(BOOL)selectFirstUnreadInFolder { - if (![self viewNextUnreadInCurrentFolder:-1]) + BOOL result = [self viewNextUnreadInCurrentFolder:-1]; + if (!result) { - int count = [[articleController allArticles] count]; + NSInteger count = articleController.allArticles.count; if (count > 0) - [self makeRowSelectedAndVisible:[[[[Preferences standardPreferences] articleSortDescriptors] objectAtIndex:0] ascending] ? 0 : count - 1]; - } -} - -/* selectFolderAndArticle - * Select a folder and select a specified article within the folder. - */ --(void)selectFolderAndArticle:(int)folderId guid:(NSString *)guid -{ - // If we're in the right folder, easy enough. - if (folderId == [articleController currentFolderId]) - [self scrollToArticle:guid]; - else - { - // Otherwise we force the folder to be selected and seed guidOfArticleToSelect - // so that after handleFolderSelection has been invoked, it will select the - // requisite article on our behalf. - currentSelectedRow = -1; - [guidOfArticleToSelect release]; - guidOfArticleToSelect = [guid retain]; - [foldersTree selectFolder:folderId]; + [self makeRowSelectedAndVisible:0]; } + return result; } /* viewLink @@ -751,119 +618,55 @@ -(NSString *)viewLink return nil; } -/* refreshCurrentFolder - * Reload the current folder after a refresh. - */ --(void)refreshCurrentFolder -{ - // Preserve the article that the user might currently be reading. - Preferences * prefs = [Preferences standardPreferences]; - if (([prefs refreshFrequency] > 0) && - (currentSelectedRow >= 0 && currentSelectedRow < (int)[[articleController allArticles] count])) - { - Article * currentArticle = [[articleController allArticles] objectAtIndex:currentSelectedRow]; - if (![currentArticle isDeleted]) - [articleController setArticleToPreserve:currentArticle]; - } - - [self refreshFolder:MA_Refresh_ReloadFromDatabase]; -} - /* refreshFolder * Refreshes the current folder by applying the current sort or thread * logic and redrawing the article list. The selected article is preserved * and restored on completion of the refresh. */ --(void)refreshFolder:(int)refreshFlag +-(void)refreshFolder:(NSInteger)refreshFlag { - NSArray * allArticles = [articleController allArticles]; - NSString * guid = nil; - - [markReadTimer invalidate]; - [markReadTimer release]; - markReadTimer = nil; - - if (refreshFlag == MA_Refresh_SortAndRedraw) - blockSelectionHandler = blockMarkRead = YES; - if ([articleList visibleRange].location < [allArticles count]) - guid = [[[allArticles objectAtIndex:[articleList visibleRange].location] guid] retain]; - if (refreshFlag == MA_Refresh_ReloadFromDatabase) - [articleController reloadArrayOfArticles]; - else if (refreshFlag == MA_Refresh_ReapplyFilter) - [articleController refilterArrayOfArticles]; - if (refreshFlag != MA_Refresh_RedrawList) - [articleController sortArticles]; - [articleList reloadData]; - if (guid != nil) - { - // To avoid upsetting the current displayed article after a refresh, we check to see if the first visible article is the same - // elsewhere we scroll to the previous article - allArticles = [articleController allArticles]; - BOOL isUnchanged = [articleList visibleRange].location < [allArticles count] - && [guid isEqualToString:[[allArticles objectAtIndex:[articleList visibleRange].location] guid]]; - if (!isUnchanged) - { - if (![self scrollToArticle:guid]) - { - currentSelectedRow = -1; - [articleList deselectRows]; - } - } - } - else - currentSelectedRow = -1; - if ((currentSelectedRow == -1) && ([[NSApp mainWindow] firstResponder] == articleList)) - [[NSApp mainWindow] makeFirstResponder:[foldersTree mainView]]; - else if (refreshFlag == MA_Refresh_SortAndRedraw) - blockSelectionHandler = blockMarkRead = NO; - [guid release]; -} + Article * currentSelectedArticle = self.selectedArticle; -/* selectArticleAfterReload - * Sets the selection in the article list after the list is reloaded. The value of guidOfArticleToSelect - * is either MA_Select_None, meaning no selection, MA_Select_Unread meaning select the first unread - * article from the beginning (after sorting is applied) or it is the ID of a specific article to be - * selected. - */ --(void)selectArticleAfterReload -{ - if (guidOfArticleToSelect == nil) - [self selectFirstUnreadInFolder]; - else - [self scrollToArticle:guidOfArticleToSelect]; - [guidOfArticleToSelect release]; - guidOfArticleToSelect = nil; -} + switch (refreshFlag) + { + case MA_Refresh_RedrawList: + break; + case MA_Refresh_ReapplyFilter: + [articleController refilterArrayOfArticles]; + [articleController sortArticles]; + break; + case MA_Refresh_SortAndRedraw: + [articleController sortArticles]; + break; + } -/* selectFolderWithFilter - * Switches to the specified folder and displays articles filtered by whatever is in - * the search field. - */ --(void)selectFolderWithFilter:(int)newFolderId -{ - @autoreleasepool { - currentSelectedRow = -1; - [rowHeightArray removeAllObjects]; - [articleList reloadData]; - if (guidOfArticleToSelect == nil) - [articleList scrollRowToVisible:0]; - else - [self selectArticleAfterReload]; - } + [articleList reloadData]; + [self scrollToArticle:currentSelectedArticle.guid]; } -/* handleRefreshArticle - * Respond to the notification to refresh the current article pane. +/* startLoadIndicator + * add the indicator of articles' data being loaded */ --(void)handleRefreshArticle:(NSNotification *)nc +-(void)startLoadIndicator { + if (progressIndicator == nil) + { + progressIndicator = [[NSProgressIndicator alloc] initWithFrame:articleList.visibleRect]; + progressIndicator.style = NSProgressIndicatorSpinningStyle; + progressIndicator.displayedWhenStopped = NO; + [articleList addSubview:progressIndicator]; + } + [progressIndicator startAnimation:self]; } -/* refreshArticlePane - * Updates the article pane for the current selected articles. +/* stopLoadIndicator + * remove the indicator of articles loading */ --(void)refreshArticlePane +-(void)stopLoadIndicator { + [progressIndicator stopAnimation:self]; + [progressIndicator removeFromSuperviewWithoutNeedingDisplay]; + progressIndicator = nil; } /* markCurrentRead @@ -871,42 +674,39 @@ -(void)refreshArticlePane */ -(void)markCurrentRead:(NSTimer *)aTimer { - NSArray * allArticles = [articleController allArticles]; - if (currentSelectedRow >=0 && currentSelectedRow < (int)[allArticles count] && ![[Database sharedDatabase] readOnly]) + Article * theArticle = self.selectedArticle; + if (theArticle != nil && !theArticle.read && ![Database sharedManager].readOnly) { - Article * theArticle = [allArticles objectAtIndex:currentSelectedRow]; - if (![theArticle isRead]) - [articleController markReadByArray:[NSArray arrayWithObject:theArticle] readFlag:YES]; + [articleController markReadByArray:@[theArticle] readFlag:YES]; } } #pragma mark - -#pragma mark PXListViewDelegate +#pragma mark NSTableViewDelegate -/* numberOfRowsInListView [datasource] +/* numberOfRowsInTableView [datasource] * Datasource for the table view. Return the total number of rows we'll display which * is equivalent to the number of articles in the current folder. */ --(NSUInteger)numberOfRowsInListView:(PXListView*)aTableView +-(NSInteger)numberOfRowsInTableView:(NSTableView*)aTableView { - return [[articleController allArticles] count]; + return articleController.allArticles.count; } -- (CGFloat)listView:(PXListView*)aListView heightOfRow:(NSUInteger)row +- (CGFloat)tableView:(NSTableView *)aListView heightOfRow:(NSInteger)row { - CGFloat height; - if (row >= [rowHeightArray count]) + if (row >= rowHeightArray.count) { - NSInteger toAdd = row - [rowHeightArray count] + 1 ; + NSInteger toAdd = row - rowHeightArray.count + 1 ; for (NSInteger i = 0 ; i < toAdd ; i++) { - [rowHeightArray addObject:[NSNumber numberWithFloat:DEFAULT_CELL_HEIGHT]]; + [rowHeightArray addObject:@(DEFAULT_CELL_HEIGHT)]; } return (CGFloat)DEFAULT_CELL_HEIGHT; } else { - id object= [rowHeightArray objectAtIndex:row]; - height = [object floatValue]; + id object= rowHeightArray[row]; + CGFloat height = [object doubleValue]; return (height) ; } } @@ -914,46 +714,43 @@ - (CGFloat)listView:(PXListView*)aListView heightOfRow:(NSUInteger)row /* cellForRow [datasource] * Called by the table view to obtain the object at the specified row. */ -- (PXListViewCell*)listView:(PXListView*)aListView cellForRow:(NSUInteger)row +- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { - if (![aListView isEqualTo:articleList]) + if (![tableView isEqualTo:articleList]) return nil; - NSArray * allArticles = [articleController allArticles]; - if (row >= [allArticles count]) - return nil; - - Article * theArticle = [allArticles objectAtIndex:row]; - NSInteger articleFolderId = [theArticle folderId]; - Folder * folder = [[Database sharedDatabase] folderFromID:articleFolderId]; - NSString * feedURL = SafeString([folder feedURL]); - ArticleCellView *cellView = (ArticleCellView*)[aListView dequeueCellWithReusableIdentifier:LISTVIEW_CELL_IDENTIFIER]; + ArticleCellView *cellView = (ArticleCellView*)[tableView makeViewWithIdentifier:LISTVIEW_CELL_IDENTIFIER owner:self]; if (cellView == nil) { - cellView = [[[ArticleCellView alloc] initWithReusableIdentifier:LISTVIEW_CELL_IDENTIFIER - inFrame:NSMakeRect(XPOS_IN_CELL, YPOS_IN_CELL, aListView.bounds.size.width - XPOS_IN_CELL, DEFAULT_CELL_HEIGHT)] autorelease]; + cellView = [[ArticleCellView alloc] initWithFrame:NSMakeRect( + XPOS_IN_CELL, YPOS_IN_CELL, tableView.bounds.size.width - XPOS_IN_CELL, DEFAULT_CELL_HEIGHT)]; + cellView.identifier = LISTVIEW_CELL_IDENTIFIER; } - ArticleView * view = [cellView articleView]; - [cellView setFolderId:articleFolderId]; - [cellView setArticleRow:row]; - NSString * htmlText = [view articleTextFromArray:[NSArray arrayWithObject:theArticle]]; - [cellView setInProgress:YES]; - [view setHTML:htmlText withBase:feedURL]; + NSArray * allArticles = articleController.allArticles; + if (row < 0 || row >= allArticles.count) + return nil; + + Article * theArticle = allArticles[row]; + NSInteger articleFolderId = theArticle.folderId; + + cellView.folderId = articleFolderId; + cellView.articleRow = row; + cellView.listView = articleList; + ArticleView * view = cellView.articleView; + [view removeFromSuperviewWithoutNeedingDisplay]; + NSString * htmlText = [view articleTextFromArray:@[theArticle]]; + [view setHTML:htmlText]; [cellView addSubview:view]; return cellView; } -/* listViewSelectionDidChange [delegate] - * Handle the selection changing in the table view unless blockSelectionHandler is set. +/* tableViewSelectionDidChange [delegate] + * Handle the selection changing in the table view. */ -- (void)listViewSelectionDidChange:(NSNotification*)aNotification +-(void)tableViewSelectionDidChange:(NSNotification *)aNotification { - if (!blockSelectionHandler) - { - currentSelectedRow = [articleList selectedRow]; - } } /* copyTableSelection @@ -968,26 +765,26 @@ -(BOOL)copyIndexesSelection:(NSIndexSet*)rowIndexes toPasteboard:(NSPasteboard * NSMutableArray * arrayOfTitles = [[NSMutableArray alloc] init]; NSMutableString * fullHTMLText = [[NSMutableString alloc] init]; NSMutableString * fullPlainText = [[NSMutableString alloc] init]; - Database * db = [Database sharedDatabase]; - int count = [rowIndexes count]; + Database * db = [Database sharedManager]; + NSInteger count = rowIndexes.count; // Set up the pasteboard - [pboard declareTypes:[NSArray arrayWithObjects:MA_PBoardType_RSSItem, @"WebURLsWithTitlesPboardType", NSStringPboardType, NSHTMLPboardType, nil] owner:self]; + [pboard declareTypes:@[MA_PBoardType_RSSItem, @"WebURLsWithTitlesPboardType", NSStringPboardType, NSHTMLPboardType] owner:self]; if (count == 1) - [pboard addTypes:[NSArray arrayWithObjects:MA_PBoardType_url, MA_PBoardType_urln, NSURLPboardType, nil] owner:self]; + [pboard addTypes:@[MA_PBoardType_url, MA_PBoardType_urln, NSURLPboardType] owner:self]; // Open the HTML string [fullHTMLText appendString:@""]; // Get all the articles that are being dragged - NSUInteger msgIndex = [rowIndexes firstIndex]; + NSUInteger msgIndex = rowIndexes.firstIndex; while (msgIndex != NSNotFound) { - Article * thisArticle = [[articleController allArticles] objectAtIndex:msgIndex]; - Folder * folder = [db folderFromID:[thisArticle folderId]]; - NSString * msgText = [thisArticle body]; - NSString * msgTitle = [thisArticle title]; - NSString * msgLink = [thisArticle link]; + Article * thisArticle = articleController.allArticles[msgIndex]; + Folder * folder = [db folderFromID:thisArticle.folderId]; + NSString * msgText = thisArticle.body; + NSString * msgTitle = thisArticle.title; + NSString * msgLink = thisArticle.link; [arrayOfURLs addObject:msgLink]; [arrayOfTitles addObject:msgTitle]; @@ -996,9 +793,9 @@ -(BOOL)copyIndexesSelection:(NSIndexSet*)rowIndexes toPasteboard:(NSPasteboard * [articleDict setValue:msgTitle forKey:@"rssItemTitle"]; [articleDict setValue:msgLink forKey:@"rssItemLink"]; [articleDict setValue:msgText forKey:@"rssItemDescription"]; - [articleDict setValue:[folder name] forKey:@"sourceName"]; - [articleDict setValue:[folder homePage] forKey:@"sourceHomeURL"]; - [articleDict setValue:[folder feedURL] forKey:@"sourceRSSURL"]; + [articleDict setValue:folder.name forKey:@"sourceName"]; + [articleDict setValue:folder.homePage forKey:@"sourceHomeURL"]; + [articleDict setValue:folder.feedURL forKey:@"sourceRSSURL"]; [arrayOfArticles addObject:articleDict]; // Plain text @@ -1025,23 +822,18 @@ -(BOOL)copyIndexesSelection:(NSIndexSet*)rowIndexes toPasteboard:(NSPasteboard * // Put string on the pasteboard for external drops. [pboard setPropertyList:arrayOfArticles forType:MA_PBoardType_RSSItem]; - [pboard setPropertyList:[NSArray arrayWithObjects:arrayOfURLs, arrayOfTitles, nil] forType:@"WebURLsWithTitlesPboardType"]; + [pboard setPropertyList:@[arrayOfURLs, arrayOfTitles] forType:@"WebURLsWithTitlesPboardType"]; [pboard setString:fullPlainText forType:NSStringPboardType]; - [pboard setString:[fullHTMLText stringByEscapingExtendedCharacters] forType:NSHTMLPboardType]; + [pboard setString:fullHTMLText.stringByEscapingExtendedCharacters forType:NSHTMLPboardType]; - [arrayOfArticles release]; - [arrayOfURLs release]; - [arrayOfTitles release]; - [fullHTMLText release]; - [fullPlainText release]; return YES; } /* writeRowsWithIndexes - * Called to initiate a drag from PXListView. Use the common copy selection code to copy to + * Use the common copy selection code to copy to * the pasteboard. */ --(BOOL)listView:(PXListView*)aListView writeRowsWithIndexes:(NSIndexSet*)rowIndexes toPasteboard:(NSPasteboard *)pboard; +-(BOOL)tableView:(NSTableView*)aListView writeRowsWithIndexes:(NSIndexSet*)rowIndexes toPasteboard:(NSPasteboard *)pboard; { return [self copyIndexesSelection:rowIndexes toPasteboard:pboard]; } @@ -1051,7 +843,36 @@ -(BOOL)listView:(PXListView*)aListView writeRowsWithIndexes:(NSIndexSet*)rowInde */ -(IBAction)copy:(id)sender { - [self copyIndexesSelection:[articleList selectedRows] toPasteboard:[NSPasteboard generalPasteboard]]; + [self copyIndexesSelection:articleList.selectedRowIndexes toPasteboard:[NSPasteboard generalPasteboard]]; +} + +/* delete + * Handle the Delete action when the article list has focus. + */ +-(IBAction)delete:(id)sender +{ + [APPCONTROLLER deleteMessage:self]; +} + +/* validateMenuItem + * This is our override where we handle item validation for the + * commands that we own. + */ +-(BOOL)validateMenuItem:(NSMenuItem *)menuItem +{ + if (menuItem.action == @selector(copy:)) + { + return (articleList.numberOfSelectedRows > 0); + } + if (menuItem.action == @selector(delete:)) + { + return [self canDeleteMessageAtRow:[articleList selectedRow]]; + } + if (menuItem.action == @selector(selectAll:)) + { + return YES; + } + return NO; } /* markedArticleRange @@ -1060,19 +881,19 @@ -(IBAction)copy:(id)sender -(NSArray *)markedArticleRange { NSMutableArray * articleArray = nil; - if ([[articleList selectedRows] count] > 0) + if (articleList.selectedRowIndexes.count > 0) { - NSIndexSet * rowIndexes = [articleList selectedRows]; - NSUInteger rowIndex = [rowIndexes firstIndex]; + NSIndexSet * rowIndexes = articleList.selectedRowIndexes; + NSUInteger rowIndex = rowIndexes.firstIndex; - articleArray = [NSMutableArray arrayWithCapacity:[rowIndexes count]]; + articleArray = [NSMutableArray arrayWithCapacity:rowIndexes.count]; while (rowIndex != NSNotFound) { - [articleArray addObject:[[articleController allArticles] objectAtIndex:rowIndex]]; + [articleArray addObject:articleController.allArticles[rowIndex]]; rowIndex = [rowIndexes indexGreaterThanIndex:rowIndex]; } } - return articleArray; + return [articleArray copy]; } #pragma mark - @@ -1085,11 +906,16 @@ - (BOOL)acceptsFirstResponder -(BOOL)becomeFirstResponder { - if ([articleList selectedRow] == -1 && [[articleController allArticles] count] != 0u) + NSInteger currentSelectedRow = [articleList selectedRow]; + if (currentSelectedRow >= 0 && currentSelectedRow < articleController.allArticles.count) + { + [articleList selectRowIndexes:[NSIndexSet indexSetWithIndex:currentSelectedRow] byExtendingSelection:NO]; + } + else if (articleController.allArticles.count != 0u) { - [articleList setSelectedRow:0]; - currentSelectedRow = 0; + [articleList selectRowIndexes:[NSIndexSet indexSetWithIndex:0] byExtendingSelection:NO]; } + [NSApp.mainWindow makeFirstResponder:articleList]; return YES; } @@ -1099,57 +925,31 @@ -(BOOL)becomeFirstResponder */ -(void)keyDown:(NSEvent *)theEvent { - if ([[theEvent characters] length] == 1) + if (theEvent.characters.length == 1) { - unichar keyChar = [[theEvent characters] characterAtIndex:0]; - if ([controller handleKeyDown:keyChar withFlags:[theEvent modifierFlags]]) + unichar keyChar = [theEvent.characters characterAtIndex:0]; + if ([controller handleKeyDown:keyChar withFlags:theEvent.modifierFlags]) return; } - [self interpretKeyEvents:[NSArray arrayWithObject:theEvent]]; -} - -- (void)moveDown:(id)sender -{ - [articleList moveDown:sender]; -} - -- (void)moveUp:(id)sender -{ - [articleList moveUp:sender]; -} - -- (void)scrollPageDown:(id)sender -{ - [articleList pageDown:sender]; - [[NSApp mainWindow] makeFirstResponder:self]; + [self interpretKeyEvents:@[theEvent]]; } -- (void)scrollPageUp:(id)sender -{ - [articleList pageUp:sender]; - [[NSApp mainWindow] makeFirstResponder:self]; -} - -- (void)pageDown:(id)sender -{ - [self scrollPageDown:sender]; -} - -- (void)pageUp:(id)sender -{ - [self scrollPageUp:sender]; -} - -- (void)scrollToEndOfDocument:(id)sender -{ - [articleList scrollRowToVisible:([[articleController allArticles] count]-1)]; - [[NSApp mainWindow] makeFirstResponder:self]; -} - -- (void)scrollToBeginningOfDocument:(id)sender +/* menuWillAppear + * Called when the popup menu is opened on the table. We ensure that the item under the + * cursor is selected. + */ +-(void)tableView:(ExtendedTableView *)tableView menuWillAppear:(NSEvent *)theEvent { - [articleList scrollRowToVisible:0]; - [[NSApp mainWindow] makeFirstResponder:self]; + NSInteger row = [articleList rowAtPoint:[articleList convertPoint:theEvent.locationInWindow fromView:nil]]; + if (row >= 0) + { + // Select the row under the cursor if it isn't already selected + if (articleList.numberOfSelectedRows <= 1) + { + [articleList selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO]; + } + } + [articleList scrollRowToVisible:row]; } @end diff --git a/src/VNADatabaseMigration.h b/src/VNADatabaseMigration.h new file mode 100644 index 0000000000..805778b8fd --- /dev/null +++ b/src/VNADatabaseMigration.h @@ -0,0 +1,16 @@ +// +// VNADatabaseMigration.h +// Vienna +// +// Created by Joshua Pore on 3/03/2015. +// Copyright (c) 2015 The Vienna Project. All rights reserved. +// + +#import +#import + +@interface VNADatabaseMigration : NSObject + ++ (void)migrateDatabase:(FMDatabase *)db fromVersion:(NSInteger)fromVersion; + +@end diff --git a/src/VNADatabaseMigration.m b/src/VNADatabaseMigration.m new file mode 100644 index 0000000000..9ae0e3f9cb --- /dev/null +++ b/src/VNADatabaseMigration.m @@ -0,0 +1,134 @@ +// +// VNADatabaseMigration.m +// Vienna +// +// Created by Joshua Pore on 3/03/2015. +// Copyright (c) 2015 The Vienna Project. All rights reserved. +// + +#import "VNADatabaseMigration.h" +#import "Preferences.h" +#import "Constants.h" + +@implementation VNADatabaseMigration + + +/*! + * Migrate the Vienna database schema + * + * @param fromVer the version we want to migrate from + */ ++ (void)migrateDatabase:(FMDatabase *)db fromVersion:(NSInteger)fromVersion { + + switch (fromVersion+1) { + case 13: { + // Upgrade to rev 13. + // Add createddate field to the messages table and initialise it to a date in the past. + // Create an index on the message_id column. + + [db executeUpdate:@"alter table messages add column createddate"]; + [db executeUpdate:@"update messages set createddate=?", @([NSDate distantPast].timeIntervalSince1970)]; + [db executeUpdate:@"create index messages_message_idx on messages (message_id)"]; + [db setUserVersion:(uint32_t)13]; + + NSLog(@"Updated database schema to version 13."); + } + case 14: { + // Upgrade to rev 14. + // Add next_sibling and next_child columns to folders table and first_folder column to info table to allow for manual sorting. + // Initialize all values to 0. The correct values will be set by -[FoldersTree setManualSortOrderForNode:]. + // Make sure that all parent_id values are integers rather than strings, because previous versions of setParent:forFolder: + // set them as strings. + + [db executeUpdate:@"alter table info add column first_folder"]; + [db executeUpdate:@"update info set first_folder=0"]; + + [db executeUpdate:@"alter table folders add column next_sibling"]; + [db executeUpdate:@"update folders set next_sibling=0"]; + + [db executeUpdate:@"alter table folders add column first_child"]; + [db executeUpdate:@"update folders set first_child=0"]; + + [[Preferences standardPreferences] setFoldersTreeSortMethod:MA_FolderSort_ByName]; + + FMResultSet * results = [db executeQuery:@"select folder_id, parent_id from folders"]; + while([results next]) + { + NSNumber *folderId = [results objectForColumn:@"folder_id"]; + NSNumber *parentId = [results objectForColumn:@"parent_id"]; + [db executeUpdate:@"update folders set parent_id=? where folder_id=?", + parentId, folderId]; + } + [results close]; + [db setUserVersion:(uint32_t)14]; + + NSLog(@"Updated database schema to version 14."); + } + case 15: { + // Upgrade to rev 15. + // Move the folders tree sort method preference to the database, so that it can survive deletion of the preferences file. + // Do not disturb the manual sort order, if it exists. + + [db executeUpdate:@"alter table info add column folder_sort"]; + NSInteger oldFoldersTreeSortMethod = [Preferences standardPreferences].foldersTreeSortMethod; + [db executeUpdate:@"update info set folder_sort=?", @(oldFoldersTreeSortMethod)]; + [db setUserVersion:(uint32_t)15]; + + NSLog(@"Updated database schema to version 15."); + } + case 16: { + // Upgrade to rev 16. + // Add revised_flag to messages table, and initialize all values to 0. + + [db executeUpdate:@"alter table messages add column revised_flag"]; + [db executeUpdate:@"update messages set revised_flag=0"]; + [db setUserVersion:(uint32_t)16]; + + NSLog(@"Updated database schema to version 16."); + } + case 17: { + // Upgrade to rev 17. + // Add hasenclosure_flag, enclosuredownloaded_flag and enclosure to messages table, and initialize stuff. + + [db executeUpdate:@"alter table messages add column hasenclosure_flag"]; + [db executeUpdate:@"update messages set hasenclosure_flag=0"]; + [db executeUpdate:@"alter table messages add column enclosure"]; + [db executeUpdate:@"update messages set enclosure=''"]; + [db executeUpdate:@"alter table messages add column enclosuredownloaded_flag"]; + [db executeUpdate:@"update messages set enclosuredownloaded_flag=0"]; + [db setUserVersion:(uint32_t)17]; + + NSLog(@"Updated database schema to version 17."); + } + case 18: { + // Upgrade to rev 18. + // Add table all message guids. + + [db executeUpdate:@"create table rss_guids as select message_id, folder_id from messages"]; + [db executeUpdate:@"create index rss_guids_idx on rss_guids (folder_id)"]; + [db setUserVersion:(uint32_t)18]; + + NSLog(@"Updated database schema to version 18."); + } + case 19: { + // Upgrade to rev 19. + // Update the Vienna Developer's blog RSS URL after we changed from .org to .com + + FMResultSet *results = [db executeQuery:@"SELECT folder_id FROM rss_folders WHERE feed_url LIKE ?", @"%%vienna-rss.org%%"]; + + if([results next]) { + int viennaFolderId = [results intForColumn:@"folder_id"]; + [db executeUpdate:@"UPDATE rss_folders SET feed_url=?, home_page=? WHERE folder_id=?", + @"http://www.vienna-rss.com/?feed=rss2", + @"http://www.vienna-rss.com", + @(viennaFolderId)]; + } + [results close]; + [db setUserVersion:(uint32_t)19]; + NSLog(@"Updated database schema to version 19."); + } + } + +} + +@end diff --git a/src/ViennaApp.h b/src/ViennaApp.h index cc52ca70e7..db97d336a0 100644 --- a/src/ViennaApp.h +++ b/src/ViennaApp.h @@ -19,12 +19,8 @@ // #import -#import #import "Folder.h" -// This is needed for iTunes-like buttons with different option-key personalities. -OSStatus keyPressed(EventHandlerCallRef nextHandler, EventRef theEvent, void *userData); - @interface ViennaApp : NSApplication // Refresh commands @@ -52,57 +48,37 @@ OSStatus keyPressed(EventHandlerCallRef nextHandler, EventRef theEvent, void *us -(id)resetFolderSort:(NSScriptCommand *)cmd; // General read-only properties. --(NSString *)applicationVersion; --(NSArray *)folders; --(BOOL)isRefreshing; --(int)totalUnreadCount; --(NSString *)currentTextSelection; --(NSString *)documentHTMLSource; --(NSString *)documentTabURL; +@property (nonatomic, readonly, copy) NSString *applicationVersion; +@property (nonatomic, readonly, copy) NSArray *folders; +@property (nonatomic, getter=isRefreshing, readonly) BOOL refreshing; +@property (nonatomic, readonly) NSInteger totalUnreadCount; +@property (nonatomic, readonly, copy) NSString *currentTextSelection; +@property (nonatomic, readonly, copy) NSString *documentHTMLSource; +@property (nonatomic, readonly, copy) NSString *documentTabURL; // Change folder selection --(Folder *)currentFolder; --(void)setCurrentFolder:(Folder *)newCurrentFolder; +@property (nonatomic, strong) Folder *currentFolder; // Current article --(Article *)currentArticle; - -// Preference getters --(int)autoExpireDuration; --(float)markReadInterval; --(BOOL)readingPaneOnRight; --(BOOL)refreshOnStartup; --(BOOL)checkForNewOnStartup; --(BOOL)openLinksInVienna; --(BOOL)openLinksInBackground; --(int)minimumFontSize; --(BOOL)enableMinimumFontSize; --(int)refreshFrequency; --(NSString *)displayStyle; --(NSString *)folderListFont; --(int)folderListFontSize; --(NSString *)articleListFont; --(int)articleListFontSize; --(BOOL)statusBarVisible; --(BOOL)filterBarVisible; - -// Preference setters --(void)setAutoExpireDuration:(int)newDuration; --(void)setMarkReadInterval:(float)newInterval; --(void)setReadingPaneOnRight:(BOOL)flag; --(void)setRefreshOnStartup:(BOOL)flag; --(void)setCheckForNewOnStartup:(BOOL)flag; --(void)setOpenLinksInVienna:(BOOL)flag; --(void)setOpenLinksInBackground:(BOOL)flag; --(void)setMinimumFontSize:(int)newSize; --(void)setEnableMinimumFontSize:(BOOL)flag; --(void)setRefreshFrequency:(int)newFrequency; --(void)setDisplayStyle:(NSString *)newStyle; --(void)setFolderListFont:(NSString *)newFontName; --(void)setFolderListFontSize:(int)newFontSize; --(void)setArticleListFont:(NSString *)newFontName; --(void)setArticleListFontSize:(int)newFontSize; --(void)setStatusBarVisible:(BOOL)flag; --(void)setFilterBarVisible:(BOOL)flag; +@property (nonatomic, readonly, strong) Article *currentArticle; + +// Preference properties +@property (nonatomic) NSInteger autoExpireDuration; +@property (nonatomic) float markReadInterval; +@property (nonatomic) BOOL readingPaneOnRight; +@property (nonatomic) BOOL refreshOnStartup; +@property (nonatomic) BOOL checkForNewOnStartup; +@property (nonatomic) BOOL openLinksInVienna; +@property (nonatomic) BOOL openLinksInBackground; +@property (nonatomic) NSInteger minimumFontSize; +@property (nonatomic) BOOL enableMinimumFontSize; +@property (nonatomic) NSInteger refreshFrequency; +@property (nonatomic, copy) NSString *displayStyle; +@property (nonatomic, copy) NSString *folderListFont; +@property (nonatomic) NSInteger folderListFontSize; +@property (nonatomic, copy) NSString *articleListFont; +@property (nonatomic) NSInteger articleListFontSize; +@property (nonatomic) BOOL statusBarVisible; +@property (nonatomic) BOOL filterBarVisible; @end diff --git a/src/ViennaApp.m b/src/ViennaApp.m index cd497d9317..dce19b289a 100644 --- a/src/ViennaApp.m +++ b/src/ViennaApp.m @@ -20,32 +20,27 @@ #import "ViennaApp.h" #import "AppController.h" -#import "ArticleListView.h" #import "Preferences.h" #import "Import.h" #import "Export.h" #import "RefreshManager.h" #import "Constants.h" -#import "FoldersTree.h" #import "BrowserPane.h" -#import "UnifiedDisplayView.h" -#import @implementation ViennaApp /* sendEvent * We override sendEvent in order to catch the status of the option key. */ --(void)sendEvent:(NSEvent *)anEvent +-(void)sendEvent:(NSEvent *)anEvent { - if(([anEvent type] == NSFlagsChanged) && ( ([anEvent keyCode] == 61) || ([anEvent keyCode] == 58))) + if((anEvent.type == NSFlagsChanged) && ( (anEvent.keyCode == 61) || (anEvent.keyCode == 58))) { - AppController * controller = APPCONTROLLER; - [controller toggleOptionKeyButtonStates]; + [(AppController*)self.delegate toggleOptionKeyButtonStates]; } - else - // Only handle the events we actually need. - [super sendEvent:anEvent]; + else + // Only handle the events we actually need. + [super sendEvent:anEvent]; } /* handleRefreshAllSubscriptions @@ -53,7 +48,7 @@ -(void)sendEvent:(NSEvent *)anEvent */ -(id)handleRefreshAllSubscriptions:(NSScriptCommand *)cmd { - [(AppController*)[self delegate] refreshAllSubscriptions:nil]; + [(AppController*)self.delegate refreshAllSubscriptions:nil]; return nil; } @@ -73,11 +68,11 @@ -(NSArray *)evaluatedArrayOfFolders:(id)argObject withCommand:(NSScriptCommand * else if ([argObject isKindOfClass:[NSArray class]]) { NSArray * argArray = (NSArray *)argObject; - int index; + NSInteger index; - for (index = 0; index < [argArray count]; ++index) + for (index = 0; index < argArray.count; ++index) { - id argItem = [argArray objectAtIndex:index]; + id argItem = argArray[index]; if ([argItem isKindOfClass:[Folder class]]) { [newArgArray addObject:argItem]; @@ -106,11 +101,11 @@ -(NSArray *)evaluatedArrayOfFolders:(id)argObject withCommand:(NSScriptCommand * } } if (!hasError) - return newArgArray; + return [newArgArray copy]; // At least one of the arguments didn't evaluate to a Folder object - [cmd setScriptErrorNumber:errASIllegalFormalParameter]; - [cmd setScriptErrorString:@"Argument must evaluate to a valid folder"]; + cmd.scriptErrorNumber = errASIllegalFormalParameter; + cmd.scriptErrorString = @"Argument must evaluate to a valid folder"; return nil; } @@ -119,8 +114,8 @@ -(NSArray *)evaluatedArrayOfFolders:(id)argObject withCommand:(NSScriptCommand * */ -(id)handleRefreshSubscription:(NSScriptCommand *)cmd { - NSDictionary * args = [cmd evaluatedArguments]; - NSArray * argArray = [self evaluatedArrayOfFolders:[args objectForKey:@"Folder"] withCommand:cmd]; + NSDictionary * args = cmd.evaluatedArguments; + NSArray * argArray = [self evaluatedArrayOfFolders:args[@"Folder"] withCommand:cmd]; if (argArray != nil) [[RefreshManager sharedManager] refreshSubscriptionsAfterRefresh:argArray ignoringSubscriptionStatus:YES]; @@ -132,10 +127,10 @@ -(id)handleRefreshSubscription:(NSScriptCommand *)cmd */ -(id)handleMarkAllRead:(NSScriptCommand *)cmd { - NSDictionary * args = [cmd evaluatedArguments]; - NSArray * argArray = [self evaluatedArrayOfFolders:[args objectForKey:@"Folder"] withCommand:cmd]; + NSDictionary * args = cmd.evaluatedArguments; + NSArray * argArray = [self evaluatedArrayOfFolders:args[@"Folder"] withCommand:cmd]; if (argArray != nil) - [(AppController*)[self delegate] markSelectedFoldersRead:argArray]; + [(AppController*)self.delegate markSelectedFoldersRead:argArray]; return nil; } @@ -145,7 +140,7 @@ -(id)handleMarkAllRead:(NSScriptCommand *)cmd */ -(id)handleMarkAllSubscriptionsRead:(NSScriptCommand *)cmd { - [(AppController*)[self delegate] markAllSubscriptionsRead:nil]; + [(AppController*)self.delegate markAllSubscriptionsRead:nil]; return nil; } @@ -155,7 +150,7 @@ -(id)handleMarkAllSubscriptionsRead:(NSScriptCommand *)cmd */ -(id)handleCompactDatabase:(NSScriptCommand *)cmd { - [[Database sharedDatabase] compactDatabase]; + [[Database sharedManager] compactDatabase]; return nil; } @@ -164,8 +159,8 @@ -(id)handleCompactDatabase:(NSScriptCommand *)cmd */ -(id)handleEmptyTrash:(NSScriptCommand *)cmd { - [(AppController*)[self delegate] clearUndoStack]; - [[Database sharedDatabase] purgeDeletedArticles]; + [(AppController*)self.delegate clearUndoStack]; + [[Database sharedManager] purgeDeletedArticles]; return nil; } @@ -174,8 +169,8 @@ -(id)handleEmptyTrash:(NSScriptCommand *)cmd */ -(id)handleImportSubscriptions:(NSScriptCommand *)cmd { - NSDictionary * args = [cmd evaluatedArguments]; - [(AppController*)[self delegate] importFromFile:[args objectForKey:@"FileName"]]; + NSDictionary * args = cmd.evaluatedArguments; + [Import importFromFile:args[@"FileName"]]; return nil; } @@ -184,14 +179,14 @@ -(id)handleImportSubscriptions:(NSScriptCommand *)cmd */ -(id)handleExportSubscriptions:(NSScriptCommand *)cmd { - NSDictionary * args = [cmd evaluatedArguments]; - id argObject = [args objectForKey:@"Folder"]; - NSArray * argArray = argObject ? [self evaluatedArrayOfFolders:argObject withCommand:cmd] : [[Database sharedDatabase] arrayOfFolders:MA_Root_Folder]; + NSDictionary * args = cmd.evaluatedArguments; + id argObject = args[@"Folder"]; + NSArray * argArray = argObject ? [self evaluatedArrayOfFolders:argObject withCommand:cmd] : [[Database sharedManager] arrayOfFolders:MA_Root_Folder]; - int countExported = 0; + NSInteger countExported = 0; if (argArray != nil) - countExported = [(AppController*)[self delegate] exportToFile:[args objectForKey:@"FileName"] from:argArray withGroups:YES]; - return [NSNumber numberWithInt:countExported]; + countExported = [Export exportToFile:args[@"FileName"] from:argArray inFoldersTree:((AppController*)self.delegate).foldersTree withGroups:YES]; + return @(countExported); } /* handleNewSubscription @@ -200,12 +195,12 @@ -(id)handleExportSubscriptions:(NSScriptCommand *)cmd */ -(id)handleNewSubscription:(NSScriptCommand *)cmd { - NSDictionary * args = [cmd evaluatedArguments]; - Folder * folder = [args objectForKey:@"UnderFolder"]; + NSDictionary * args = cmd.evaluatedArguments; + Folder * folder = args[@"UnderFolder"]; - int parentId = folder ? ((IsGroupFolder(folder)) ? [folder itemId] :[folder parentId]) : MA_Root_Folder; + NSInteger parentId = folder ? ((IsGroupFolder(folder)) ? folder.itemId : folder.parentId) : MA_Root_Folder; - [(AppController*)[self delegate] createNewSubscription:[args objectForKey:@"URL"] underFolder:parentId afterChild:-1]; + [(AppController*)self.delegate createNewSubscription:args[@"URL"] underFolder:parentId afterChild:-1]; return nil; } @@ -226,8 +221,8 @@ -(id)resetFolderSort:(NSScriptCommand *)cmd -(NSString *)applicationVersion { NSBundle * appBundle = [NSBundle mainBundle]; - NSDictionary * fileAttributes = [appBundle infoDictionary]; - return [fileAttributes objectForKey:@"CFBundleShortVersionString"]; + NSDictionary * fileAttributes = appBundle.infoDictionary; + return fileAttributes[@"CFBundleShortVersionString"]; } /* folders @@ -235,7 +230,7 @@ -(NSString *)applicationVersion */ -(NSArray *)folders { - return [(AppController*)[self delegate] folders]; + return ((AppController*)self.delegate).folders; } /* isRefreshing @@ -243,15 +238,15 @@ -(NSArray *)folders */ -(BOOL)isRefreshing { - return [(AppController*)[self delegate] isConnecting]; + return ((AppController*)self.delegate).connecting; } /* totalUnreadCount * Return the total number of unread articles. */ --(int)totalUnreadCount +-(NSInteger)totalUnreadCount { - return [[Database sharedDatabase] countOfUnread]; + return [Database sharedManager].countOfUnread; } /* currentSelection @@ -260,21 +255,21 @@ -(int)totalUnreadCount */ -(NSString *)currentTextSelection { - NSView * theView = [[(AppController*)[self delegate] browserView] activeTabItemView]; + NSView * theView = ((AppController*)self.delegate).browserView.activeTabItemView; WebView * webPane = nil; if ([theView isKindOfClass:[BrowserPane class]]) - webPane = (WebView *)[(BrowserPane *)theView mainView]; + webPane = (WebView *)((BrowserPane *)theView).mainView; if ([theView isKindOfClass:[ArticleListView class]]) - webPane = (WebView *)[(ArticleListView *)theView webView]; + webPane = (WebView *)((ArticleListView *)theView).webView; if ([theView isKindOfClass:[UnifiedDisplayView class]]) - webPane = (WebView *)[(UnifiedDisplayView *)theView webView]; + webPane = (WebView *)((UnifiedDisplayView *)theView).webView; if (webPane != nil) { - NSView * docView = [[[webPane mainFrame] frameView] documentView]; + NSView * docView = webPane.mainFrame.frameView.documentView; if ([docView conformsToProtocol:@protocol(WebDocumentText)]) return [(id)docView selectedString]; @@ -284,15 +279,15 @@ -(NSString *)currentTextSelection -(NSString *)documentHTMLSource { - NSView * theView = [[(AppController*)[self delegate] browserView] activeTabItemView]; - WebView * webPane = [theView webView]; + NSView * theView = ((AppController*)self.delegate).browserView.activeTabItemView; + WebView * webPane = theView.webView; if (webPane != nil) { - WebDataSource * dataSource = [[webPane mainFrame] dataSource]; + WebDataSource * dataSource = webPane.mainFrame.dataSource; if (dataSource != nil) { - id representation = [dataSource representation]; + id representation = dataSource.representation; if ((representation != nil) && ([representation conformsToProtocol:@protocol(WebDocumentRepresentation)]) && ([(id)representation canProvideDocumentSource])) return [(id)representation documentSource]; } @@ -302,10 +297,10 @@ -(NSString *)documentHTMLSource -(NSString *)documentTabURL { - NSView * theView = [[(AppController*)[self delegate] browserView] activeTabItemView]; + NSView * theView = ((AppController*)self.delegate).browserView.activeTabItemView; if ([theView isKindOfClass:[BrowserPane class]]) { - return [[(BrowserPane *)theView url] absoluteString]; + return ((BrowserPane *)theView).url.absoluteString; } else return @""; @@ -316,7 +311,7 @@ -(NSString *)documentTabURL */ -(Article *)currentArticle; { - return [(AppController*)[self delegate] selectedArticle]; + return ((AppController*)self.delegate).selectedArticle; } /* currentFolder @@ -324,7 +319,7 @@ -(Article *)currentArticle; */ -(Folder *)currentFolder { - return [[Database sharedDatabase] folderFromID:[(AppController*)[self delegate] currentFolderId]]; + return [[Database sharedManager] folderFromID:((AppController*)self.delegate).currentFolderId]; } /* setCurrentFolder @@ -333,51 +328,51 @@ -(Folder *)currentFolder -(void)setCurrentFolder:(Folder *)newCurrentFolder { AppController * controller = APPCONTROLLER; - int folderId = [newCurrentFolder itemId]; + NSInteger folderId = newCurrentFolder.itemId; [controller selectFolder:folderId]; } /* Accessor getters * These thunk through the standard preferences. */ --(int)autoExpireDuration { return [[Preferences standardPreferences] autoExpireDuration]; } --(float)markReadInterval { return [[Preferences standardPreferences] markReadInterval]; } --(BOOL)readingPaneOnRight { return [[Preferences standardPreferences] layout] == MA_Layout_Condensed; } --(int)filterMode { return [[Preferences standardPreferences] filterMode]; } --(BOOL)refreshOnStartup { return [[Preferences standardPreferences] refreshOnStartup]; } --(BOOL)checkForNewOnStartup { return [[Preferences standardPreferences] checkForNewOnStartup]; } --(BOOL)openLinksInVienna { return [[Preferences standardPreferences] openLinksInVienna]; } --(BOOL)openLinksInBackground { return [[Preferences standardPreferences] openLinksInBackground]; } --(int)minimumFontSize { return [[Preferences standardPreferences] minimumFontSize]; } --(BOOL)enableMinimumFontSize { return [[Preferences standardPreferences] enableMinimumFontSize]; } --(int)refreshFrequency { return [[Preferences standardPreferences] refreshFrequency]; } --(NSString *)displayStyle { return [[Preferences standardPreferences] displayStyle]; } --(NSString *)folderListFont { return [[Preferences standardPreferences] folderListFont]; } --(int)folderListFontSize { return [[Preferences standardPreferences] folderListFontSize]; } --(NSString *)articleListFont { return [[Preferences standardPreferences] articleListFont]; } --(int)articleListFontSize { return [[Preferences standardPreferences] articleListFontSize]; } --(BOOL)statusBarVisible { return [[Preferences standardPreferences] showStatusBar]; } --(BOOL)filterBarVisible { return [[Preferences standardPreferences] showFilterBar]; } +-(NSInteger)autoExpireDuration { return [Preferences standardPreferences].autoExpireDuration; } +-(float)markReadInterval { return [Preferences standardPreferences].markReadInterval; } +-(BOOL)readingPaneOnRight { return [Preferences standardPreferences].layout == MA_Layout_Condensed; } +-(NSInteger)filterMode { return [Preferences standardPreferences].filterMode; } +-(BOOL)refreshOnStartup { return [Preferences standardPreferences].refreshOnStartup; } +-(BOOL)checkForNewOnStartup { return [Preferences standardPreferences].checkForNewOnStartup; } +-(BOOL)openLinksInVienna { return [Preferences standardPreferences].openLinksInVienna; } +-(BOOL)openLinksInBackground { return [Preferences standardPreferences].openLinksInBackground; } +-(NSInteger)minimumFontSize { return [Preferences standardPreferences].minimumFontSize; } +-(BOOL)enableMinimumFontSize { return [Preferences standardPreferences].enableMinimumFontSize; } +-(NSInteger)refreshFrequency { return [Preferences standardPreferences].refreshFrequency; } +-(NSString *)displayStyle { return [Preferences standardPreferences].displayStyle; } +-(NSString *)folderListFont { return [Preferences standardPreferences].folderListFont; } +-(NSInteger)folderListFontSize { return [Preferences standardPreferences].folderListFontSize; } +-(NSString *)articleListFont { return [Preferences standardPreferences].articleListFont; } +-(NSInteger)articleListFontSize { return [Preferences standardPreferences].articleListFontSize; } +-(BOOL)statusBarVisible { return [Preferences standardPreferences].showStatusBar; } +-(BOOL)filterBarVisible { return [Preferences standardPreferences].showFilterBar; } /* Accessor setters * These thunk through the standard preferences. */ --(void)setAutoExpireDuration:(int)newDuration { [[Preferences standardPreferences] setAutoExpireDuration:newDuration]; } --(void)setMarkReadInterval:(float)newInterval { [[Preferences standardPreferences] setMarkReadInterval:newInterval]; } +-(void)setAutoExpireDuration:(NSInteger)newDuration { [Preferences standardPreferences].autoExpireDuration = newDuration; } +-(void)setMarkReadInterval:(float)newInterval { [Preferences standardPreferences].markReadInterval = newInterval; } -(void)setReadingPaneOnRight:(BOOL)flag { ; } --(void)setRefreshOnStartup:(BOOL)flag { [[Preferences standardPreferences] setRefreshOnStartup:flag]; } --(void)setFilterMode:(int)newMode { [[Preferences standardPreferences] setFilterMode:newMode]; } --(void)setCheckForNewOnStartup:(BOOL)flag { [[Preferences standardPreferences] setCheckForNewOnStartup:flag]; } --(void)setOpenLinksInVienna:(BOOL)flag { [[Preferences standardPreferences] setOpenLinksInVienna:flag]; } --(void)setOpenLinksInBackground:(BOOL)flag { [[Preferences standardPreferences] setOpenLinksInBackground:flag]; } --(void)setMinimumFontSize:(int)newSize { [[Preferences standardPreferences] setMinimumFontSize:newSize]; } --(void)setEnableMinimumFontSize:(BOOL)flag { [[Preferences standardPreferences] setEnableMinimumFontSize:flag]; } --(void)setRefreshFrequency:(int)newFrequency { [[Preferences standardPreferences] setRefreshFrequency:newFrequency]; } --(void)setDisplayStyle:(NSString *)newStyle { [[Preferences standardPreferences] setDisplayStyle:newStyle]; } --(void)setFolderListFont:(NSString *)newFontName { [[Preferences standardPreferences] setFolderListFont:newFontName]; } --(void)setFolderListFontSize:(int)newFontSize { [[Preferences standardPreferences] setFolderListFontSize:newFontSize]; } --(void)setArticleListFont:(NSString *)newFontName { [[Preferences standardPreferences] setArticleListFont:newFontName]; } --(void)setArticleListFontSize:(int)newFontSize { [[Preferences standardPreferences] setArticleListFontSize:newFontSize]; } --(void)setStatusBarVisible:(BOOL)flag { [[Preferences standardPreferences] setShowStatusBar:flag]; } --(void)setFilterBarVisible:(BOOL)flag { [[Preferences standardPreferences] setShowFilterBar:flag]; } +-(void)setRefreshOnStartup:(BOOL)flag { [Preferences standardPreferences].refreshOnStartup = flag; } +-(void)setFilterMode:(NSInteger)newMode { [Preferences standardPreferences].filterMode = newMode; } +-(void)setCheckForNewOnStartup:(BOOL)flag { [Preferences standardPreferences].checkForNewOnStartup = flag; } +-(void)setOpenLinksInVienna:(BOOL)flag { [Preferences standardPreferences].openLinksInVienna = flag; } +-(void)setOpenLinksInBackground:(BOOL)flag { [Preferences standardPreferences].openLinksInBackground = flag; } +-(void)setMinimumFontSize:(NSInteger)newSize { [Preferences standardPreferences].minimumFontSize = newSize; } +-(void)setEnableMinimumFontSize:(BOOL)flag { [Preferences standardPreferences].enableMinimumFontSize = flag; } +-(void)setRefreshFrequency:(NSInteger)newFrequency { [Preferences standardPreferences].refreshFrequency = newFrequency; } +-(void)setDisplayStyle:(NSString *)newStyle { [Preferences standardPreferences].displayStyle = newStyle; } +-(void)setFolderListFont:(NSString *)newFontName { [Preferences standardPreferences].folderListFont = newFontName; } +-(void)setFolderListFontSize:(NSInteger)newFontSize { [Preferences standardPreferences].folderListFontSize = newFontSize; } +-(void)setArticleListFont:(NSString *)newFontName { [Preferences standardPreferences].articleListFont = newFontName; } +-(void)setArticleListFontSize:(NSInteger)newFontSize { [Preferences standardPreferences].articleListFontSize = newFontSize; } +-(void)setStatusBarVisible:(BOOL)flag { [Preferences standardPreferences].showStatusBar = flag; } +-(void)setFilterBarVisible:(BOOL)flag { [Preferences standardPreferences].showFilterBar = flag; } @end diff --git a/src/ViennaSparkleDelegate.h b/src/ViennaSparkleDelegate.h new file mode 100644 index 0000000000..664f388d48 --- /dev/null +++ b/src/ViennaSparkleDelegate.h @@ -0,0 +1,19 @@ +// +// ViennaSparkleDelegate.h +// Vienna +// +// Created by Barijaona Ramaholimihaso on 03/05/2016. +// Copyright © 2016 uk.co.opencommunity. All rights reserved. +// + +#import +#import + +@interface ViennaSparkleDelegate : NSObject +{ +} + +// Public functions +-(void)showSystemProfileInfoAlert; + +@end diff --git a/src/ViennaSparkleDelegate.m b/src/ViennaSparkleDelegate.m new file mode 100644 index 0000000000..a41d57e94a --- /dev/null +++ b/src/ViennaSparkleDelegate.m @@ -0,0 +1,69 @@ +// +// ViennaSparkleDelegate.m +// Vienna +// +// Created by Barijaona Ramaholimihaso on 03/05/2016. +// Copyright © 2016 uk.co.opencommunity. All rights reserved. +// + +#import "ViennaSparkleDelegate.h" +#import "Preferences.h" + +@implementation ViennaSparkleDelegate + +/* updaterWillRelaunchApplication + * This is a delegate for Sparkle.framwork + */ +- (void)updaterWillRelaunchApplication:(SUUpdater *)updater +{ + [[Preferences standardPreferences] handleUpdateRestart]; +} + +/* feedURLStringForUpdater: + * This is a delegate for Sparkle.framework + */ +-(NSString *)feedURLStringForUpdater:(SUUpdater *)updater +{ + // the default as it is defined in Info.plist + NSString * URLstring = [NSBundle mainBundle].infoDictionary[@"SUFeedURL"]; + if ([[Preferences standardPreferences] alwaysAcceptBetas]) + { + NSURL * referenceURL = [NSURL URLWithString:URLstring]; + NSString * extension = [referenceURL pathExtension]; + NSURL * pathURL = [referenceURL URLByDeletingLastPathComponent]; + // same extension and path, except name is "changelog_beta" + NSURL * newURL = [[pathURL URLByAppendingPathComponent:@"changelog_beta"] URLByAppendingPathExtension:extension]; + URLstring = [newURL absoluteString]; + } + return URLstring; +} + +/*! showSystemProfileInfoAlert + * displays an alert asking the user to opt-in to sending anonymous system profile throug Sparkle + */ +-(void)showSystemProfileInfoAlert { + NSAlert *alert = [[NSAlert alloc] init]; + [alert addButtonWithTitle:NSLocalizedString(@"OK", @"OK")]; + [alert addButtonWithTitle:NSLocalizedString(@"No thanks", @"No thanks")]; + [alert setMessageText:NSLocalizedString(@"Include anonymous system profile when checking for updates?", @"Include anonymous system profile when checking for updates?")]; + [alert setInformativeText:NSLocalizedString(@"Include anonymous system profile when checking for updates text", @"This helps Vienna development by letting us know what versions of Mac OS X are most popular amongst our users.")]; + alert.alertStyle = NSInformationalAlertStyle; + NSModalResponse buttonClicked = alert.runModal; + NSLog(@"buttonClicked: %ld", (long)buttonClicked); + switch (buttonClicked) { + case NSAlertFirstButtonReturn: + /* Agreed to send system profile. Uses preferences to set value otherwise + the preference control is out of sync */ + [[Preferences standardPreferences] setSendSystemSpecs:YES]; + break; + case NSAlertSecondButtonReturn: + /* Declined to send system profile. Uses SUUpdater to set the value + otherwise it stays nil instead of being set to 0 */ + [[SUUpdater sharedUpdater] setSendsSystemProfile:NO]; + break; + default: + break; + } +} + +@end diff --git a/src/Vienna_Prefix.pch b/src/Vienna_Prefix.pch deleted file mode 100644 index aabef477dd..0000000000 --- a/src/Vienna_Prefix.pch +++ /dev/null @@ -1,3 +0,0 @@ -#ifdef __OBJC__ - #import -#endif diff --git a/src/ViewExtensions.h b/src/ViewExtensions.h index 81b498b061..de114f8747 100644 --- a/src/ViewExtensions.h +++ b/src/ViewExtensions.h @@ -21,10 +21,10 @@ #import @interface NSView (ViewExtensions) - -(void)resizeViewWithAnimation:(NSRect)newFrame withTag:(int)viewTag; + -(void)resizeViewWithAnimation:(NSRect)newFrame withTag:(NSInteger)viewTag; @end @interface NSObject(ViewExtensionsDelegate) --(void)viewAnimationCompleted:(NSView *)theView withTag:(int)viewTag; +-(void)viewAnimationCompleted:(NSView *)theView withTag:(NSInteger)viewTag; @end diff --git a/src/ViewExtensions.m b/src/ViewExtensions.m index adab728e0d..e95c445a5f 100644 --- a/src/ViewExtensions.m +++ b/src/ViewExtensions.m @@ -21,8 +21,8 @@ #import "ViewExtensions.h" @interface NSAnimation (ViennaAnimationWithTags) --(void)MA_setTag:(int)newTag; --(int)MA_tag; +-(void)MA_setTag:(NSInteger)newTag; +@property (nonatomic, readonly) NSInteger MA_tag; @end @implementation NSAnimation (ViennaAnimationWithTags) @@ -43,20 +43,19 @@ - (NSMutableDictionary *)MA_tagDict /* MA_setTag * Assigns the specified tag value to the animation object. */ --(void)MA_setTag:(int)newTag +-(void)MA_setTag:(NSInteger)newTag { - [[self MA_tagDict] setObject:[NSNumber numberWithInt:newTag] - forKey:[NSValue valueWithPointer:self]]; + [self MA_tagDict][[NSValue valueWithPointer:(__bridge const void *)(self)]] = @(newTag); } /* MA_tag * Returns the associated tag. */ --(int)MA_tag +-(NSInteger)MA_tag { NSMutableDictionary *tagDict = [self MA_tagDict]; - NSValue *key = [NSValue valueWithPointer:self]; - int tag = [[tagDict objectForKey:key] intValue]; + NSValue *key = [NSValue valueWithPointer:(__bridge const void *)(self)]; + NSInteger tag = [tagDict[key] integerValue]; [tagDict removeObjectForKey:key]; return tag; } @@ -67,18 +66,18 @@ @implementation NSView (ViewExtensions) /* resizeViewWithAnimation * Resizes the specified view with animation. */ --(void)resizeViewWithAnimation:(NSRect)newFrame withTag:(int)viewTag +-(void)resizeViewWithAnimation:(NSRect)newFrame withTag:(NSInteger)viewTag { - NSDictionary * dict = [NSDictionary dictionaryWithObjectsAndKeys: - [NSValue valueWithRect:newFrame], NSViewAnimationEndFrameKey, - self, NSViewAnimationTargetKey, - nil]; + NSDictionary * dict = @{ + NSViewAnimationEndFrameKey: [NSValue valueWithRect:newFrame], + NSViewAnimationTargetKey: self, + }; - NSViewAnimation * animation = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObject:dict]]; - [animation setAnimationBlockingMode:NSAnimationNonblocking]; - [animation setDuration:0.1]; - [animation setAnimationCurve:NSAnimationEaseInOut]; - [animation setDelegate:(id)self]; + NSViewAnimation * animation = [[NSViewAnimation alloc] initWithViewAnimations:@[dict]]; + animation.animationBlockingMode = NSAnimationNonblocking; + animation.duration = 0.1; + animation.animationCurve = NSAnimationEaseInOut; + animation.delegate = (id)self; [animation MA_setTag:viewTag]; [animation startAnimation]; } @@ -88,12 +87,11 @@ -(void)resizeViewWithAnimation:(NSRect)newFrame withTag:(int)viewTag */ -(void)animationDidEnd:(NSAnimation *)animation { - NSWindow * viewWindow = [self window]; - int viewTag = [animation MA_tag]; + NSWindow * viewWindow = self.window; + NSInteger viewTag = animation.MA_tag; - [animation release]; - if ([[viewWindow delegate] respondsToSelector:@selector(viewAnimationCompleted:withTag:)]) - [(id)[viewWindow delegate] viewAnimationCompleted:self withTag:viewTag]; + if ([viewWindow.delegate respondsToSelector:@selector(viewAnimationCompleted:withTag:)]) + [(id)viewWindow.delegate viewAnimationCompleted:self withTag:viewTag]; } @end diff --git a/src/XMLParser.h b/src/XMLParser.h deleted file mode 100644 index 628088940f..0000000000 --- a/src/XMLParser.h +++ /dev/null @@ -1,47 +0,0 @@ -// -// XMLParser.h -// Vienna -// -// Created by Steve on 5/27/05. -// Copyright (c) 2004-2005 Steve Palmer. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// - -#import - -@interface XMLParser : NSObject { - CFXMLTreeRef tree; - CFXMLNodeRef node; -} - -// Functions --(BOOL)setData:(NSData *)data; --(id)initWithEmptyTree; --(BOOL)hasValidTree; --(CFIndex)countOfChildren; --(NSString *)nodeName; --(XMLParser *)addTree:(NSString *)name; --(XMLParser *)addTree:(NSString *)name withElement:(NSString *)value; --(XMLParser *)addTree:(NSString *)name withAttributes:(NSDictionary *)attributesDict; --(XMLParser *)addClosedTree:(NSString *)name withAttributes:(NSDictionary *)attributesDict; --(void)addElement:(NSString *)value; --(NSDictionary *)attributesForTree; --(NSString *)xmlForTree; --(NSString *)valueOfElement; --(NSString *)valueOfAttribute:(NSString *)attributeName; --(XMLParser *)treeByName:(NSString *)name; --(XMLParser *)treeByPath:(NSString *)path; --(XMLParser *)treeByIndex:(CFIndex)index; -+(NSString *)quoteAttributes:(NSString *)stringToProcess; -+(NSDate *)parseXMLDate:(NSString *)dateString; -@end diff --git a/src/XMLParser.m b/src/XMLParser.m deleted file mode 100644 index 21b7785ae3..0000000000 --- a/src/XMLParser.m +++ /dev/null @@ -1,548 +0,0 @@ -// -// XMLParser.m -// Vienna -// -// Created by Steve on 5/27/05. -// Copyright (c) 2004-2005 Steve Palmer. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// - -#import "XMLParser.h" -#import "StringExtensions.h" -#import "Debug.h" -#import "AppController.h" - -@interface XMLParser (Private) - -(void)setTreeRef:(CFXMLTreeRef)treeRef; - +(XMLParser *)treeWithCFXMLTreeRef:(CFXMLTreeRef)ref; - -(XMLParser *)addTree:(NSString *)name withAttributes:(NSDictionary *)attributesDict closed:(BOOL)flag; -@end - -@implementation XMLParser - -/* setData - * Initialises the XMLParser with a data block which contains the XML data. - */ --(BOOL)setData:(NSData *)data -{ - CFXMLTreeRef newTree; - - @try { - newTree = CFXMLTreeCreateFromDataWithError(kCFAllocatorDefault, (CFDataRef)data, NULL, kCFXMLParserNoOptions, kCFXMLNodeCurrentVersion, NULL); - } - @catch (NSException *error) { - if (newTree != nil) - CFRelease(newTree); - newTree = nil; - } - if (newTree != nil) - { - [self setTreeRef:newTree]; - CFRelease(newTree); - return YES; - } - return NO; -} - -/* hasValidTree - * Return TRUE if we have a valid tree. - */ --(BOOL)hasValidTree -{ - return tree != nil; -} - -/* treeWithCFXMLTreeRef - * Allocates a new instance of an XMLParser with the specified tree. - */ -+(XMLParser *)treeWithCFXMLTreeRef:(CFXMLTreeRef)ref -{ - XMLParser * parser = [[XMLParser alloc] init]; - [parser setTreeRef:ref]; - return [parser autorelease]; -} - -/* setTreeRef - * Initialises the XMLParser with a data block which contains the XML data. - */ --(void)setTreeRef:(CFXMLTreeRef)treeRef -{ - if (tree != nil) - CFRelease(tree); - if (node != nil) - CFRelease(node); - tree = treeRef; - node = CFXMLTreeGetNode(tree); - CFRetain(tree); - CFRetain(node); -} - -/* initWithEmptyTree - * Creates an empty XML tree to which we can add nodes. - */ --(id)initWithEmptyTree -{ - if ((self = [self init]) != nil) - { - // Create the document node - CFXMLDocumentInfo documentInfo; - documentInfo.sourceURL = NULL; - documentInfo.encoding = kCFStringEncodingUTF8; - CFXMLNodeRef docNode = CFXMLNodeCreate(kCFAllocatorDefault, kCFXMLNodeTypeDocument, CFSTR(""), &documentInfo, kCFXMLNodeCurrentVersion); - CFXMLTreeRef xmlDocument = CFXMLTreeCreateWithNode(kCFAllocatorDefault, docNode); - CFRelease(docNode); - - // Add the XML header to the document - CFXMLProcessingInstructionInfo instructionInfo; - instructionInfo.dataString = CFSTR("version=\"1.0\" encoding=\"utf-8\""); - CFXMLNodeRef instructionNode = CFXMLNodeCreate(kCFAllocatorDefault, kCFXMLNodeTypeProcessingInstruction, CFSTR("xml"), &instructionInfo, kCFXMLNodeCurrentVersion); - CFXMLTreeRef instructionTree = CFXMLTreeCreateWithNode(kCFAllocatorDefault, instructionNode); - CFTreeAppendChild(xmlDocument, instructionTree); - CFRelease(xmlDocument); - - // Create the parser object from this - [self setTreeRef:instructionTree]; - CFRelease(instructionTree); - CFRelease(instructionNode); - } - return self; -} - -/* init - * Designated initialiser. - */ - --(id)init -{ - if ((self = [super init]) != nil) - { - tree = nil; - node = nil; - } - return self; -} - -/* addTree - * Adds a sub-tree to the current tree and returns its XMLParser object. - */ --(XMLParser *)addTree:(NSString *)name -{ - CFXMLElementInfo info; - info.attributes = NULL; - info.attributeOrder = NULL; - info.isEmpty = NO; - - CFXMLNodeRef newTreeNode = CFXMLNodeCreate(kCFAllocatorDefault, kCFXMLNodeTypeElement, (CFStringRef)name, &info, kCFXMLNodeCurrentVersion); - CFXMLTreeRef newTree = CFXMLTreeCreateWithNode(kCFAllocatorDefault, newTreeNode); - CFTreeAppendChild(tree, newTree); - - // Create the parser object from this - XMLParser * newParser = [XMLParser treeWithCFXMLTreeRef:newTree]; - CFRelease(newTreeNode); - CFRelease(newTree); - return newParser; -} - -/* addTree:withElement - * Add a new tree and give it the specified element. - */ --(XMLParser *)addTree:(NSString *)name withElement:(NSString *)value -{ - XMLParser * newTree = [self addTree:name]; - [newTree addElement:value]; - return newTree; -} - -/* addElement - * Add an element to the tree. - */ --(void)addElement:(NSString *)value -{ - CFStringRef escapedString = CFXMLCreateStringByEscapingEntities(kCFAllocatorDefault, (CFStringRef)value, NULL); - CFXMLNodeRef newNode = CFXMLNodeCreate(kCFAllocatorDefault, kCFXMLNodeTypeText, escapedString, NULL, kCFXMLNodeCurrentVersion); - CFXMLTreeRef newTree = CFXMLTreeCreateWithNode(kCFAllocatorDefault, newNode); - CFTreeAppendChild(tree, newTree); - CFRelease(newTree); - CFRelease(newNode); - CFRelease(escapedString); -} - -/* addClosedTree:withAttributes - * Add a new tree with attributes to the tree. - */ --(XMLParser *)addClosedTree:(NSString *)name withAttributes:(NSDictionary *)attributesDict -{ - return [self addTree:name withAttributes:attributesDict closed:YES]; -} - -/* addTree:withAttributes - * Add a new tree with attributes to the tree. - */ --(XMLParser *)addTree:(NSString *)name withAttributes:(NSDictionary *)attributesDict -{ - return [self addTree:name withAttributes:attributesDict closed:NO]; -} - -/* addTree:withAttributes:closed - * Add a new tree with attributes to the tree. - */ --(XMLParser *)addTree:(NSString *)name withAttributes:(NSDictionary *)attributesDict closed:(BOOL)flag -{ - CFXMLElementInfo info; - info.attributes = (CFDictionaryRef)attributesDict; - info.attributeOrder = (CFArrayRef)[attributesDict allKeys]; - info.isEmpty = flag; - - CFXMLNodeRef newNode = CFXMLNodeCreate (kCFAllocatorDefault, kCFXMLNodeTypeElement, (CFStringRef)name, &info, kCFXMLNodeCurrentVersion); - CFXMLTreeRef newTree = CFXMLTreeCreateWithNode(kCFAllocatorDefault, newNode); - CFTreeAppendChild(tree, newTree); - - // Create the parser object from this - XMLParser * newParser = [XMLParser treeWithCFXMLTreeRef:newTree]; - CFRelease(newTree); - CFRelease(newNode); - return newParser; -} - -/* treeByIndex - * Returns an XMLParser object for the child tree at the specified index. - */ --(XMLParser *)treeByIndex:(CFIndex)index -{ - return [XMLParser treeWithCFXMLTreeRef:CFTreeGetChildAtIndex(tree, index)]; -} - -/* treeByPath - * Retrieves a tree located by a specified sub-nesting of XML nodes. For example, given the - * following XML document: - * - * - * - * - * - * - * - * Then treeByPath:@"root/body/element" will return the tree for the node. If any - * element does not exist, it returns nil. - */ --(XMLParser *)treeByPath:(NSString *)path -{ - NSArray * pathElements = [path componentsSeparatedByString:@"/"]; - XMLParser * treeFound = self; - - for (NSString * treeName in pathElements) - { - treeFound = [treeFound treeByName:treeName]; - if (treeFound == nil) - return nil; - } - return treeFound; -} - -/* treeByName - * Given a node in the XML tree, this returns the sub-tree with the specified name or nil - * if the tree cannot be found. - */ --(XMLParser *)treeByName:(NSString *)name -{ - CFIndex count = CFTreeGetChildCount(tree); - CFIndex index; - - for (index = count - 1; index >= 0; --index) - { - CFXMLTreeRef subTree = CFTreeGetChildAtIndex(tree, index); - CFXMLNodeRef subNode = CFXMLTreeGetNode(subTree); - if ([name isEqualToString:(NSString *)CFXMLNodeGetString(subNode)]) - return [XMLParser treeWithCFXMLTreeRef:subTree]; - } - return nil; -} - -/* countOfChildren - * Count of children of this tree - */ --(CFIndex)countOfChildren -{ - return CFTreeGetChildCount(tree); -} - -/* xmlForTree - * Returns the XML text for the specified tree. - */ --(NSString *)xmlForTree -{ - NSData * data = (NSData *)CFXMLTreeCreateXMLData(kCFAllocatorDefault, tree); - NSString * xmlString = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; - CFRelease(data); - return xmlString; -} - -/* description - * Make this return the XML string which is pretty useful. - */ --(NSString *)description -{ - return [self xmlForTree]; -} - -/* attributesForTree - * Returns a dictionary of all attributes on the current tree. - */ --(NSDictionary *)attributesForTree -{ - if (CFXMLNodeGetTypeCode(node) == kCFXMLNodeTypeElement ) - { - CFXMLElementInfo eInfo = *(CFXMLElementInfo *)CFXMLNodeGetInfoPtr(node); - NSDictionary * dict = (NSDictionary *)eInfo.attributes; - NSMutableDictionary * newDict = [[NSMutableDictionary alloc] init]; - - // Make a copy of the attributes dictionary but force the keys to - // lowercase. - for (NSString * keyName in dict) - { - [newDict setObject:[dict objectForKey:keyName] forKey:[keyName lowercaseString]]; - } - return [newDict autorelease]; - } - return nil; -} - -/* valueOfAttribute - * Returns the value of the named attribute of the specified node. If the node is a processing instruction - * then what we obtain from CFXMLNodeGetInfoPtr is a pointer to a CFXMLProcessingInstructionInfo structure - * which encodes the entire processing instructions as a single string. Thus to obtain the 'attribute' that - * equates to the processing instruction element we're interested in we need to parse that string to extract - * the value. - */ --(NSString *)valueOfAttribute:(NSString *)attributeName -{ - if (CFXMLNodeGetTypeCode(node) == kCFXMLNodeTypeElement) - { - CFXMLElementInfo eInfo = *(CFXMLElementInfo *)CFXMLNodeGetInfoPtr(node); - if (eInfo.attributes != nil) - { - return (NSString *)CFDictionaryGetValue(eInfo.attributes, attributeName); - } - } - else if (CFXMLNodeGetTypeCode(node) == kCFXMLNodeTypeProcessingInstruction) - { - CFXMLProcessingInstructionInfo eInfo = *(CFXMLProcessingInstructionInfo *)CFXMLNodeGetInfoPtr(node); - NSScanner * scanner = [NSScanner scannerWithString:(NSString *)eInfo.dataString]; - while (![scanner isAtEnd]) - { - NSString * instructionName = nil; - NSString * instructionValue = nil; - - [scanner scanUpToString:@"=" intoString:&instructionName]; - [scanner scanString:@"=" intoString:nil]; - [scanner scanUpToString:@" " intoString:&instructionValue]; - - if (instructionName != nil && instructionValue != nil) - { - if ([instructionName isEqualToString:attributeName]) - return [instructionValue stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\""]]; - } - } - } - return nil; -} - -/* nodeName - * Returns the name of the node of this tree. - */ --(NSString *)nodeName -{ - return (NSString *)CFXMLNodeGetString(node); -} - -/* valueOfElement - * Returns the value of the element of the specified tree. Special case for handling application/xhtml+xml which - * is a bunch of XML/HTML embedded in the tree without a CDATA. In order to get the raw text, we need to extract - * the XML data itself and append it as we go along. - */ --(NSString *)valueOfElement -{ - NSMutableString * valueString = [NSMutableString stringWithCapacity:16]; - - CFIndex count = CFTreeGetChildCount(tree); - CFIndex index; - - for (index = 0; index < count; ++index) - { - if (index > 20000) // there is an episodic problem with some Flickr feeds, which contain multiple
tags ; - break; // so, we speedup things a little... - CFXMLTreeRef subTree = CFTreeGetChildAtIndex(tree, index); - CFXMLNodeRef subNode = CFXMLTreeGetNode(subTree); - CFXMLNodeTypeCode type = CFXMLNodeGetTypeCode(subNode); - - if (type== kCFXMLNodeTypeElement) // XML or HTML... - { - CFDataRef valueData = CFXMLTreeCreateXMLData(NULL, subTree); - - NSString * nString = [[NSString alloc] initWithBytes:CFDataGetBytePtr(valueData) length:CFDataGetLength(valueData) encoding:NSUTF8StringEncoding]; - [valueString appendString:nString]; - [nString release]; - - CFRelease(valueData); - } - else //CDATA, string... - { - NSString * valueName = (NSString *)CFXMLNodeGetString(subNode); - if (valueName != nil) - { - if (type == kCFXMLNodeTypeEntityReference) - valueName = [NSString mapEntityToString:valueName]; - [valueString appendString:valueName]; - } - } - } - return valueString; -} - -/* quoteAttributes - * Scan the specified string and convert HTML literal characters to their entity equivalents. - */ -+(NSString *)quoteAttributes:(NSString *)stringToProcess -{ - NSMutableString * newString = [NSMutableString stringWithString:stringToProcess]; - [newString replaceString:@"&" withString:@"&"]; - [newString replaceString:@"<" withString:@"<"]; - [newString replaceString:@">" withString:@">"]; - [newString replaceString:@"\"" withString:@"""]; - [newString replaceString:@"'" withString:@"'"]; - return newString; -} - - - -/* parseXMLDate - * Parse a date in an XML header into an NSCalendarDate. This is horribly expensive and needs - * to be replaced with a parser that can handle these formats: - * - * 2005-10-23T10:12:22-4:00 - * 2005-10-23T10:12:22 - * 2005-10-23T10:12:22Z - * Mon, 10 Oct 2005 10:12:22 -4:00 - * 10 Oct 2005 10:12:22 -4:00 - * - * These are the formats that I've discovered so far. - */ -+(NSDate *)parseXMLDate:(NSString *)dateString -{ - int yearValue = 0; - int monthValue = 1; - int dayValue = 0; - int hourValue = 0; - int minuteValue = 0; - int secondValue = 0; - int tzOffset = 0; - - //We handle garbage there! (At least 1/1/00, so four digit) - if ([[dateString stringByTrimmingCharactersInSet:[NSCharacterSet decimalDigitCharacterSet]] length] < 4) return nil; - - NSDate *curlDate = [AppController getDateFromString:dateString]; - - if (curlDate != nil) - return curlDate; - - // Otherwise do it ourselves. - // Expect the string to be loosely like a ISO 8601 subset - NSScanner * scanner = [NSScanner scannerWithString:dateString]; - - [scanner setScanLocation:0u]; - if (![scanner scanInt:&yearValue]) - return nil; - if (yearValue < 100) - yearValue += 2000; - if ([scanner scanString:@"-" intoString:nil]) - { - if (![scanner scanInt:&monthValue]) - return nil; - if (monthValue < 1 || monthValue > 12) - return nil; - if ([scanner scanString:@"-" intoString:nil]) - { - if (![scanner scanInt:&dayValue]) - return nil; - if (dayValue < 1 || dayValue > 31) - return nil; - } - } - - // Parse the time portion. - // (I discovered that GMail sometimes returns a timestamp with 24 as the hour - // portion although this is clearly contrary to the RFC spec. So be - // prepared for things like this.) - if ([scanner scanString:@"T" intoString:nil]) - { - if (![scanner scanInt:&hourValue]) - return nil; - hourValue %= 24; - if ([scanner scanString:@":" intoString:nil]) - { - if (![scanner scanInt:&minuteValue]) - return nil; - if (minuteValue < 0 || minuteValue > 59) - return nil; - if ([scanner scanString:@":" intoString:nil] || [scanner scanString:@"." intoString:nil]) - { - if (![scanner scanInt:&secondValue]) - return nil; - if (secondValue < 0 || secondValue > 59) - return nil; - // Drop any fractional seconds - if ([scanner scanString:@"." intoString:nil]) - { - if (![scanner scanInt:nil]) - return nil; - } - } - } - } - else - { - // If no time is specified, set the time to 11:59pm, - // so new articles within the last 24 hours are detected. - hourValue = 23; - minuteValue = 59; - } - - // At this point we're at any potential timezone - // tzOffset needs to be the number of seconds since GMT - if ([scanner scanString:@"Z" intoString:nil]) - tzOffset = 0; - else if (![scanner isAtEnd]) - { - if (![scanner scanInt:&tzOffset]) - return nil; - if (tzOffset > 12) - return nil; - } - - // Now combine the whole thing into a date we know about. - NSTimeZone * tzValue = [NSTimeZone timeZoneForSecondsFromGMT:tzOffset * 60 * 60]; - return [NSCalendarDate dateWithYear:yearValue month:monthValue day:dayValue hour:hourValue minute:minuteValue second:secondValue timeZone:tzValue]; -} - -/* dealloc - * Clean up when we're done. - */ --(void)dealloc -{ - if (node != nil) - CFRelease(node); - if (tree != nil) - CFRelease(tree); - [super dealloc]; -} -@end diff --git a/src/XMLSourceWindow.h b/src/XMLSourceWindow.h index e2bf0b0665..54e19ecd59 100644 --- a/src/XMLSourceWindow.h +++ b/src/XMLSourceWindow.h @@ -32,6 +32,6 @@ NSString * sourceWindowTitle; } --(id)initWithFolder:(Folder *)folder; // Designated initializer +-(instancetype)initWithFolder:(Folder *)folder /*NS_DESIGNATED_INITIALIZER*/; @end diff --git a/src/XMLSourceWindow.m b/src/XMLSourceWindow.m index efaeaf6c0e..490c2513c3 100644 --- a/src/XMLSourceWindow.m +++ b/src/XMLSourceWindow.m @@ -39,14 +39,14 @@ @implementation XMLSourceWindow /* initWithFolder: * Just init the "View Source" window. */ --(id)initWithFolder:(Folder *)folder +-(instancetype)initWithFolder:(Folder *)folder { NSParameterAssert( folder != nil ); if ((self = [super initWithWindowNibName:@"XMLSource"]) != nil) { - sourceWindowTitle = [[NSString alloc] initWithFormat:@"%@ %li: %@", NSLocalizedString(@"Source of folder", nil), [folder itemId], [folder name]]; - feedSourceFilePath = [[folder feedSourceFilePath] copy]; + sourceWindowTitle = [[NSString alloc] initWithFormat:@"%@ %li: %@", NSLocalizedString(@"Source of folder", nil), (long)folder.itemId, folder.name]; + feedSourceFilePath = [folder.feedSourceFilePath copy]; } return self; } @@ -86,7 +86,7 @@ -(void)displayXmlSource syntaxHighlighter = [syntaxHighlighter stringByReplacingOccurrencesOfString:@"$XMLSourceData" withString:xmlSource]; } else - errorDescription = [error localizedDescription]; + errorDescription = error.localizedDescription; } if (errorDescription != nil) @@ -94,7 +94,7 @@ -(void)displayXmlSource syntaxHighlighter = [NSString stringWithFormat:@"


%@
", errorDescription]; } - [[sourceWebView mainFrame] loadHTMLString:syntaxHighlighter baseURL:[NSURL fileURLWithPath:pathToSyntaxHighlighter isDirectory:NO]]; + [sourceWebView.mainFrame loadHTMLString:syntaxHighlighter baseURL:[NSURL fileURLWithPath:pathToSyntaxHighlighter isDirectory:NO]]; } } } @@ -121,15 +121,15 @@ - (void)windowDidLoad [sJavaScriptPreferences setUsesPageCache:NO]; } - [[self window] setTitle:sourceWindowTitle]; - [sourceWebView setPreferencesIdentifier:@"ViennaJavaScriptEnabled"]; + self.window.title = sourceWindowTitle; + sourceWebView.preferencesIdentifier = @"ViennaJavaScriptEnabled"; [self displayXmlSource]; } - (void)windowWillClose:(NSNotification *)notification { // Post this for interested observers (namely, the AppController) - [[NSNotificationCenter defaultCenter] postNotificationName:[notification name] object:self]; + [[NSNotificationCenter defaultCenter] postNotificationName:notification.name object:self]; } /* @@ -139,14 +139,14 @@ - (void)windowWillClose:(NSNotification *)notification */ - (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id < WebPolicyDecisionListener >)listener { - NSNumber * navigationTypeObject = [actionInformation objectForKey:WebActionNavigationTypeKey]; + NSNumber * navigationTypeObject = actionInformation[WebActionNavigationTypeKey]; if (navigationTypeObject != nil) { - int navigationType = [navigationTypeObject intValue]; + NSInteger navigationType = navigationTypeObject.integerValue; if (navigationType == WebNavigationTypeLinkClicked) { [listener ignore]; - [APPCONTROLLER openURL:[request URL] inPreferredBrowser:YES]; + [APPCONTROLLER openURL:request.URL inPreferredBrowser:YES]; return; } } @@ -154,13 +154,4 @@ - (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary [listener use]; } --(void)dealloc -{ - [feedSourceFilePath release]; - feedSourceFilePath=nil; - [sourceWindowTitle release]; - sourceWindowTitle=nil; - [super dealloc]; -} - @end \ No newline at end of file diff --git a/src/XMLTag.h b/src/XMLTag.h index 98d99a6c81..ede5c13d65 100644 --- a/src/XMLTag.h +++ b/src/XMLTag.h @@ -27,6 +27,6 @@ // Public functions +(NSArray *)parserFromData:(NSData *)xmlData; --(NSString *)name; --(NSDictionary *)attributes; +@property (nonatomic, readonly, copy) NSString *name; +@property (nonatomic, readonly, copy) NSDictionary *attributes; @end diff --git a/src/XMLTag.m b/src/XMLTag.m index d9dad85e87..bb541c2cdc 100644 --- a/src/XMLTag.m +++ b/src/XMLTag.m @@ -40,8 +40,6 @@ -(NSString *)name */ -(void)setName:(NSString *)newName { - [newName retain]; - [name release]; name = newName; } @@ -59,8 +57,6 @@ -(NSDictionary *)attributes */ -(void)setAttributes:(NSDictionary *)newAttributes { - [newAttributes retain]; - [attributes release]; attributes = newAttributes; } @@ -87,10 +83,10 @@ -(NSString *)description +(NSArray *)parserFromData:(NSData *)data { NSMutableArray * tagArray = [NSMutableArray arrayWithCapacity:10]; - const char * textPtr = [data bytes]; - const char * endPtr = textPtr + [data length]; + const char * textPtr = data.bytes; + const char * endPtr = textPtr + data.length; const char * tagStartPtr = nil; - int cntrlCharCount = 0; + NSInteger cntrlCharCount = 0; BOOL inTag = NO; BOOL inQuote = NO; @@ -120,7 +116,7 @@ +(NSArray *)parserFromData:(NSData *)data // tag name so collect and save it. if (*tagStartPtr != '!') { - XMLTag * tag = [[XMLTag new] autorelease]; + XMLTag * tag = [XMLTag new]; NSMutableDictionary * tagDict = [[NSMutableDictionary alloc] init]; const char * tagEndPtr = tagStartPtr; @@ -128,8 +124,8 @@ +(NSArray *)parserFromData:(NSData *)data ++tagEndPtr; while (isalpha(*tagEndPtr)) ++tagEndPtr; - NSString * tagName = [[[NSString alloc] initWithBytes:tagStartPtr length:(tagEndPtr - tagStartPtr) encoding:NSASCIIStringEncoding] autorelease]; - [tag setName:[tagName lowercaseString]]; + NSString * tagName = [[NSString alloc] initWithBytes:tagStartPtr length:(tagEndPtr - tagStartPtr) encoding:NSASCIIStringEncoding]; + [tag setName:tagName.lowercaseString]; while (isspace(*tagEndPtr)) ++tagEndPtr; @@ -148,7 +144,7 @@ +(NSArray *)parserFromData:(NSData *)data tagStartPtr = tagEndPtr; while (isalpha(*tagEndPtr)) ++tagEndPtr; - NSString * attrName = [[[[NSString alloc] initWithBytes:tagStartPtr length:(tagEndPtr - tagStartPtr) encoding:NSASCIIStringEncoding] autorelease] lowercaseString]; + NSString * attrName = [[NSString alloc] initWithBytes:tagStartPtr length:(tagEndPtr - tagStartPtr) encoding:NSASCIIStringEncoding].lowercaseString; // Skip the '=' and any whitespaces between the name and the value while (isspace(*tagEndPtr)) @@ -170,7 +166,7 @@ +(NSArray *)parserFromData:(NSData *)data inQuote = !inQuote; ++tagEndPtr; } - NSString * attrValue = [[[NSString alloc] initWithBytes:tagStartPtr length:(tagEndPtr - tagStartPtr) encoding:NSASCIIStringEncoding] autorelease]; + NSString * attrValue = [[NSString alloc] initWithBytes:tagStartPtr length:(tagEndPtr - tagStartPtr) encoding:NSASCIIStringEncoding]; attrValue = [attrValue stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\""]]; if (attrValue != nil && attrName != nil ) { @@ -183,7 +179,6 @@ +(NSArray *)parserFromData:(NSData *)data [tag setAttributes:tagDict]; [tagArray addObject:tag]; - [tagDict release]; } inTag = NO; inQuote = NO; @@ -191,19 +186,7 @@ +(NSArray *)parserFromData:(NSData *)data } ++textPtr; } - return tagArray; + return [tagArray copy]; } - -/* dealloc - * Clean up afterwards. - */ --(void)dealloc -{ - [name release]; - name=nil; - [attributes release]; - attributes=nil; - [super dealloc]; -} @end diff --git a/src/models/Article.h b/src/models/Article.h index cc85374007..3c265bd326 100644 --- a/src/models/Article.h +++ b/src/models/Article.h @@ -40,12 +40,8 @@ extern NSString * MA_Field_Enclosure; extern NSString * MA_Field_EnclosureDownloaded; extern NSString * MA_Field_HasEnclosure; -// Article status values -#define MA_MsgStatus_Empty 0 -#define MA_MsgStatus_New 1 -#define MA_MsgStatus_Updated 2 -// Article field IDs +// Article field IDs. Convert to enum #define MA_FieldID_GUID 400 #define MA_FieldID_Subject 401 #define MA_FieldID_Author 402 @@ -76,43 +72,37 @@ extern NSString * MA_Field_HasEnclosure; BOOL deletedFlag; BOOL enclosureDownloadedFlag; BOOL hasEnclosureFlag; - int status; + NSInteger status; } +typedef NS_ENUM(NSInteger, ArticleStatus) { + ArticleStatusEmpty = 0, + ArticleStatusNew, + ArticleStatusUpdated +}; + // Accessor functions --(id)initWithGuid:(NSString *)theGuid; --(int)parentId; --(NSString *)guid; --(NSString *)author; --(NSString *)body; --(NSString *)title; --(NSString *)link; --(NSString *)summary; --(NSString *)enclosure; --(NSDate *)date; --(NSDate *)createdDate; --(Folder *)containingFolder; --(int)folderId; --(BOOL)isRead; --(BOOL)isRevised; --(BOOL)isFlagged; --(BOOL)isDeleted; --(BOOL)hasComments; --(BOOL)hasEnclosure; --(BOOL)enclosureDownloaded; --(int)status; --(void)setGuid:(NSString *)newGuid; --(void)setParentId:(int)newParentId; --(void)setTitle:(NSString *)newTitle; --(void)setLink:(NSString *)newLink; --(void)setAuthor:(NSString *)newAuthor; --(void)setFolderId:(int)newFolderId; --(void)setDate:(NSDate *)newDate; --(void)setCreatedDate:(NSDate *)newCreatedDate; --(void)setBody:(NSString *)newText; --(void)setEnclosure:(NSString *)newEnclosure; --(void)setStatus:(int)newStatus; --(void)setHasEnclosure:(BOOL)flag; +-(instancetype)initWithGuid:(NSString *)theGuid /*NS_DESIGNATED_INITIALIZER*/; +@property (nonatomic) NSInteger parentId; +@property (nonatomic, copy) NSString *guid; +@property (nonatomic, copy) NSString *author; +@property (nonatomic, copy) NSString *body; +@property (nonatomic, copy) NSString *title; +@property (nonatomic, copy) NSString *link; +@property (nonatomic, readonly, copy) NSString *summary; +@property (nonatomic, copy) NSString *enclosure; +@property (nonatomic, copy) NSDate *date; +@property (nonatomic, copy) NSDate *createdDate; +@property (nonatomic, readonly, strong) Folder *containingFolder; +@property (nonatomic) NSInteger folderId; +@property (nonatomic, getter=isRead, readonly) BOOL read; +@property (nonatomic, getter=isRevised, readonly) BOOL revised; +@property (nonatomic, getter=isFlagged, readonly) BOOL flagged; +@property (nonatomic, getter=isDeleted, readonly) BOOL deleted; +@property (nonatomic, readonly) BOOL hasComments; +@property (nonatomic) BOOL hasEnclosure; +@property (nonatomic, readonly) BOOL enclosureDownloaded; +@property (nonatomic) NSInteger status; -(void)markRead:(BOOL)flag; -(void)markRevised:(BOOL)flag; -(void)markFlagged:(BOOL)flag; diff --git a/src/models/Article.m b/src/models/Article.m index b61a5ab070..b2985537de 100644 --- a/src/models/Article.m +++ b/src/models/Article.m @@ -22,8 +22,8 @@ #import "Article.h" #import "Database.h" #import "StringExtensions.h" -#import "XMLParser.h" #import "CalendarExtensions.h" +#import "HelperFunctions.h" // The names here are internal field names, not for localisation. NSString * MA_Field_GUID = @"GUID"; @@ -49,7 +49,7 @@ @implementation Article /* initWithGuid */ --(id)initWithGuid:(NSString *)theGuid +-(instancetype)initWithGuid:(NSString *)theGuid { if ((self = [super init]) != nil) { @@ -61,10 +61,10 @@ -(id)initWithGuid:(NSString *)theGuid deletedFlag = NO; hasEnclosureFlag = NO; enclosureDownloadedFlag = NO; - status = MA_MsgStatus_Empty; - [self setFolderId:-1]; - [self setGuid:theGuid]; - [self setParentId:0]; + status = ArticleStatusEmpty; + self.folderId = -1; + self.guid = theGuid; + self.parentId = 0; } return self; } @@ -73,21 +73,21 @@ -(id)initWithGuid:(NSString *)theGuid */ -(void)setTitle:(NSString *)newTitle { - [articleData setObject:newTitle forKey:MA_Field_Subject]; + articleData[MA_Field_Subject] = newTitle; } /* setAuthor */ -(void)setAuthor:(NSString *)newAuthor { - [articleData setObject:newAuthor forKey:MA_Field_Author]; + articleData[MA_Field_Author] = newAuthor; } /* setLink */ -(void)setLink:(NSString *)newLink { - [articleData setObject:newLink forKey:MA_Field_Link]; + articleData[MA_Field_Link] = newLink; } /* setDate @@ -95,7 +95,7 @@ -(void)setLink:(NSString *)newLink */ -(void)setDate:(NSDate *)newDate { - [articleData setObject:newDate forKey:MA_Field_Date]; + articleData[MA_Field_Date] = newDate; } /* setCreatedDate @@ -103,14 +103,14 @@ -(void)setDate:(NSDate *)newDate */ -(void)setCreatedDate:(NSDate *)newCreatedDate { - [articleData setObject:newCreatedDate forKey:MA_Field_CreatedDate]; + articleData[MA_Field_CreatedDate] = newCreatedDate; } /* setBody */ -(void)setBody:(NSString *)newText { - [articleData setObject:newText forKey:MA_Field_Text]; + articleData[MA_Field_Text] = newText; [articleData removeObjectForKey:MA_Field_Summary]; } @@ -119,7 +119,7 @@ -(void)setBody:(NSString *)newText -(void)setEnclosure:(NSString *)newEnclosure { if (newEnclosure) - [articleData setObject:newEnclosure forKey:MA_Field_Enclosure]; + articleData[MA_Field_Enclosure] = newEnclosure; else [articleData removeObjectForKey:MA_Field_Enclosure]; } @@ -181,26 +181,26 @@ -(id)valueForKeyPath:(NSString *)keyPath { if ([keyPath hasPrefix:@"articleData."]) { - NSString * key = [keyPath substringFromIndex:[@"articleData." length]]; + NSString * key = [keyPath substringFromIndex:(@"articleData.").length]; if ([key isEqualToString:MA_Field_Date]) { - return [self date]; + return self.date; } else if ([key isEqualToString:MA_Field_Author]) { - return [self author]; + return self.author; } else if ([key isEqualToString:MA_Field_Subject]) { - return [self title]; + return self.title; } else if ([key isEqualToString:MA_Field_Link]) { - return [self link]; + return self.link; } else if ([key isEqualToString:MA_Field_Summary]) { - return [self summary]; + return self.summary; } else { @@ -219,64 +219,64 @@ -(BOOL)isRead { return readFlag; } -(BOOL)isRevised { return revisedFlag; } -(BOOL)isFlagged { return markedFlag; } -(BOOL)isDeleted { return deletedFlag; } --(BOOL)hasComments { return [commentsArray count] > 0; } +-(BOOL)hasComments { return commentsArray.count > 0; } -(BOOL)hasEnclosure { return hasEnclosureFlag; } -(BOOL)enclosureDownloaded { return enclosureDownloadedFlag; } --(int)status { return status; } --(int)folderId { return [[articleData objectForKey:MA_Field_Folder] intValue]; } --(NSString *)author { return [articleData objectForKey:MA_Field_Author]; } --(NSString *)link { return [articleData objectForKey:MA_Field_Link]; } --(NSString *)guid { return [articleData objectForKey:MA_Field_GUID]; } --(int)parentId { return [[articleData objectForKey:MA_Field_Parent] intValue]; } --(NSString *)title { return [articleData objectForKey:MA_Field_Subject]; } +-(NSInteger)status { return status; } +-(NSInteger)folderId { return [articleData[MA_Field_Folder] integerValue]; } +-(NSString *)author { return articleData[MA_Field_Author]; } +-(NSString *)link { return articleData[MA_Field_Link]; } +-(NSString *)guid { return articleData[MA_Field_GUID]; } +-(NSInteger)parentId { return [articleData[MA_Field_Parent] integerValue]; } +-(NSString *)title { return articleData[MA_Field_Subject]; } -(NSString *)summary { - NSString * summary = [articleData objectForKey:MA_Field_Summary]; + NSString * summary = articleData[MA_Field_Summary]; if (summary == nil) { - summary = [[articleData objectForKey:MA_Field_Text] summaryTextFromHTML]; + summary = [articleData[MA_Field_Text] summaryTextFromHTML]; if (summary == nil) summary = @""; - [articleData setObject:summary forKey:MA_Field_Summary]; + articleData[MA_Field_Summary] = summary; } return summary; } --(NSDate *)date { return [articleData objectForKey:MA_Field_Date]; } --(NSDate *)createdDate { return [articleData objectForKey:MA_Field_CreatedDate]; } --(NSString *)body { return [articleData objectForKey:MA_Field_Text]; } --(NSString *)enclosure { return [NSString stringByCleaningURLString:[articleData objectForKey:MA_Field_Enclosure]]; } +-(NSDate *)date { return articleData[MA_Field_Date]; } +-(NSDate *)createdDate { return articleData[MA_Field_CreatedDate]; } +-(NSString *)body { return articleData[MA_Field_Text]; } +-(NSString *)enclosure { return articleData[MA_Field_Enclosure]; } /* containingFolder */ -(Folder *)containingFolder { - return [[Database sharedDatabase] folderFromID:[self folderId]]; + return [[Database sharedManager] folderFromID:self.folderId]; } /* setFolderId */ --(void)setFolderId:(int)newFolderId +-(void)setFolderId:(NSInteger)newFolderId { - [articleData setObject:[NSNumber numberWithInt:newFolderId] forKey:MA_Field_Folder]; + articleData[MA_Field_Folder] = @(newFolderId); } /* setGuid */ -(void)setGuid:(NSString *)newGuid { - [articleData setObject:newGuid forKey:MA_Field_GUID]; + articleData[MA_Field_GUID] = newGuid; } /* setParentId */ --(void)setParentId:(int)newParentId +-(void)setParentId:(NSInteger)newParentId { - [articleData setObject:[NSNumber numberWithInt:newParentId] forKey:MA_Field_Parent]; + articleData[MA_Field_Parent] = @(newParentId); } /* setStatus */ --(void)setStatus:(int)newStatus +-(void)setStatus:(NSInteger)newStatus { status = newStatus; } @@ -286,7 +286,7 @@ -(void)setStatus:(int)newStatus */ -(NSString *)description { - return [NSString stringWithFormat:@"{GUID=%@ title=\"%@\"", [self guid], [self title]]; + return [NSString stringWithFormat:@"{GUID=%@ title=\"%@\"", self.guid, self.title]; } /* objectSpecifier @@ -294,15 +294,15 @@ -(NSString *)description */ -(NSScriptObjectSpecifier *)objectSpecifier { - Folder * folder = [[Database sharedDatabase] folderFromID:[self folderId]]; + Folder * folder = [[Database sharedManager] folderFromID:self.folderId]; NSUInteger index = [folder indexOfArticle:self]; if (index != NSNotFound) { - NSScriptObjectSpecifier * containerRef = [folder objectSpecifier]; - return [[[NSIndexSpecifier allocWithZone:[self zone]] initWithContainerClassDescription:(NSScriptClassDescription *)[Folder classDescription] + NSScriptObjectSpecifier * containerRef = folder.objectSpecifier; + return [[NSIndexSpecifier allocWithZone:nil] initWithContainerClassDescription:(NSScriptClassDescription *)[Folder classDescription] containerSpecifier:containerRef key:@"articles" - index:index] autorelease]; + index:index]; } return nil; } @@ -312,7 +312,7 @@ -(NSScriptObjectSpecifier *)objectSpecifier */ -(NSString *)tagArticleLink { - return [NSString stringByCleaningURLString:[self link]]; + return [cleanedUpAndEscapedUrlFromString(self.link) absoluteString]; } /* tagArticleTitle @@ -323,7 +323,7 @@ -(NSString *)tagArticleTitle NSMutableString * articleTitle = [NSMutableString stringWithString:SafeString([self title])]; [articleTitle replaceString:@"$Article" withString:@"$_%$%_Article"]; [articleTitle replaceString:@"$Feed" withString:@"$_%$%_Feed"]; - return [XMLParser quoteAttributes:articleTitle]; + return [NSString stringByConvertingHTMLEntities:articleTitle]; } /* tagArticleBody @@ -331,12 +331,12 @@ -(NSString *)tagArticleTitle */ -(NSString *)tagArticleBody { - NSMutableString * articleBody = [NSMutableString stringWithString:[self body]]; + NSMutableString * articleBody = [NSMutableString stringWithString:SafeString(self.body)]; [articleBody replaceString:@"$Article" withString:@"$_%$%_Article"]; [articleBody replaceString:@"$Feed" withString:@"$_%$%_Feed"]; - [articleBody fixupRelativeImgTags:[self link]]; - [articleBody fixupRelativeIframeTags:[self link]]; - [articleBody fixupRelativeAnchorTags:[self link]]; + [articleBody fixupRelativeImgTags:self.link]; + [articleBody fixupRelativeIframeTags:self.link]; + [articleBody fixupRelativeAnchorTags:self.link]; return articleBody; } @@ -353,7 +353,7 @@ -(NSString *)tagArticleAuthor */ -(NSString *)tagArticleDate { - return [[[self date] dateWithCalendarFormat:nil timeZone:nil] friendlyDescription]; + return [self.date dateWithCalendarFormat:nil timeZone:nil].friendlyDescription; } /* tagArticleEnclosureLink @@ -361,7 +361,7 @@ -(NSString *)tagArticleDate */ -(NSString *)tagArticleEnclosureLink { - return [self enclosure]; + return [cleanedUpAndEscapedUrlFromString(self.enclosure) absoluteString]; } /* tagArticleEnclosureFilename @@ -369,7 +369,7 @@ -(NSString *)tagArticleEnclosureLink */ -(NSString *)tagArticleEnclosureFilename { - return [[[self enclosure] lastPathComponent] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + return [self.enclosure.lastPathComponent stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; } /* tagFeedTitle @@ -377,8 +377,8 @@ -(NSString *)tagArticleEnclosureFilename */ -(NSString *)tagFeedTitle { - Folder * folder = [[Database sharedDatabase] folderFromID:[self folderId]]; - return [XMLParser quoteAttributes:SafeString([folder name])]; + Folder * folder = [[Database sharedManager] folderFromID:self.folderId]; + return [NSString stringByConvertingHTMLEntities:SafeString([folder name])]; } /* tagFeedLink @@ -386,8 +386,8 @@ -(NSString *)tagFeedTitle */ -(NSString *)tagFeedLink { - Folder * folder = [[Database sharedDatabase] folderFromID:[self folderId]]; - return [NSString stringByCleaningURLString:[folder homePage]]; + Folder * folder = [[Database sharedManager] folderFromID:self.folderId]; + return [cleanedUpAndEscapedUrlFromString(folder.homePage) absoluteString]; } /* tagFeedDescription @@ -395,8 +395,8 @@ -(NSString *)tagFeedLink */ -(NSString *)tagFeedDescription { - Folder * folder = [[Database sharedDatabase] folderFromID:[self folderId]]; - return [folder feedDescription]; + Folder * folder = [[Database sharedManager] folderFromID:self.folderId]; + return folder.feedDescription; } /* expandTags @@ -405,7 +405,7 @@ -(NSString *)tagFeedDescription */ -(NSString *)expandTags:(NSString *)theString withConditional:(BOOL)cond { - NSMutableString * newString = [NSMutableString stringWithString:theString]; + NSMutableString * newString = [NSMutableString stringWithString:SafeString(theString)]; BOOL hasOneTag = NO; NSUInteger tagStartIndex = 0; @@ -423,8 +423,14 @@ -(NSString *)expandTags:(NSString *)theString withConditional:(BOOL)cond // value. If no function exists then we just delete the tag name from the source string. NSString * tagSelName = [@"tag" stringByAppendingString:tagName]; const char * cTagSelName = [tagSelName cStringUsingEncoding:NSASCIIStringEncoding]; - replacementString = [self performSelector:sel_registerName(cTagSelName)]; - + SEL selector = sel_registerName(cTagSelName); + // this is equivalent with replacementString = [self performSelector:selector]; + // http://stackoverflow.com/questions/7017281/performselector-may-cause-a-leak-because-its-selector-is-unknown + // see also : http://stackoverflow.com/questions/7043999/im-writing-a-button-class-in-objective-c-with-arc-how-do-i-prevent-clangs-m + IMP imp = [self methodForSelector:selector]; + NSString * (*func)(id, SEL) = (void *)imp; + replacementString = func(self, selector); + if (replacementString == nil) [newString deleteCharactersInRange:NSMakeRange(tagStartIndex, tagLength)]; else @@ -432,25 +438,13 @@ -(NSString *)expandTags:(NSString *)theString withConditional:(BOOL)cond [newString replaceCharactersInRange:NSMakeRange(tagStartIndex, tagLength) withString:replacementString]; hasOneTag = YES; - if (![replacementString isBlank]) + if (!replacementString.blank) cond = NO; - tagStartIndex += [replacementString length]; + tagStartIndex += replacementString.length; } } return (cond && hasOneTag) ? @"" : newString; } -/* dealloc - * Clean up and release resources. - */ --(void)dealloc -{ - [commentsArray release]; - commentsArray=nil; - [articleData release]; - articleData=nil; - [super dealloc]; -} - @end diff --git a/src/models/FeedItem.h b/src/models/FeedItem.h new file mode 100644 index 0000000000..41dad7a412 --- /dev/null +++ b/src/models/FeedItem.h @@ -0,0 +1,29 @@ +// +// FeedItem.h +// Vienna +// +// Created by Joshua Pore on 7/08/2015. +// Copyright (c) 2015 uk.co.opencommunity. All rights reserved. +// + +#import + +@interface FeedItem : NSObject { + NSString * title; + NSString * author; + NSString * link; + NSString * guid; + NSDate * date; + NSString * description; + NSString * enclosure; +} + +@property (nonatomic, copy) NSString *title; +@property (nonatomic, copy) NSString *description; +@property (nonatomic, copy) NSString *author; +@property (nonatomic, copy) NSString *guid; +@property (nonatomic, copy) NSDate *date; +@property (nonatomic, copy) NSString *link; +@property (nonatomic, copy) NSString *enclosure; + +@end diff --git a/src/models/FeedItem.m b/src/models/FeedItem.m new file mode 100644 index 0000000000..9cc41d9d01 --- /dev/null +++ b/src/models/FeedItem.m @@ -0,0 +1,143 @@ +// +// FeedItem.m +// Vienna +// +// Created by Joshua Pore on 7/08/2015. +// Copyright (c) 2015 uk.co.opencommunity. All rights reserved. +// + +#import "FeedItem.h" + +@implementation FeedItem + +/* init + * Creates a FeedItem instance + */ +-(instancetype)init +{ + if ((self = [super init]) != nil) + { + title = @""; + description = @""; + author = @""; + guid = @""; + date = nil; + link = @""; + enclosure = @""; + } + return self; +} + +/* setEnclosure + * Set the item title. + */ +-(void)setEnclosure:(NSString *)newEnclosure +{ + enclosure = newEnclosure; +} + +/* setTitle + * Set the item title. + */ +-(void)setTitle:(NSString *)newTitle +{ + title = newTitle; +} + +/* setDescription + * Set the item description. + */ +-(void)setDescription:(NSString *)newDescription +{ + description = newDescription; +} + +/* setAuthor + * Set the item author. + */ +-(void)setAuthor:(NSString *)newAuthor +{ + author = newAuthor; +} + +/* setDate + * Set the item date + */ +-(void)setDate:(NSDate *)newDate +{ + date = newDate; +} + +/* setGuid + * Set the item GUID. + */ +-(void)setGuid:(NSString *)newGuid +{ + guid = newGuid; +} + +/* setLink + * Set the item link. + */ +-(void)setLink:(NSString *)newLink +{ + link = newLink; +} + +/* title + * Returns the item title. + */ +-(NSString *)title +{ + return title; +} + +/* description + * Returns the item description + */ +-(NSString *)description +{ + return description; +} + +/* author + * Returns the item author + */ +-(NSString *)author +{ + return author; +} + +/* date + * Returns the item date + */ +-(NSDate *)date +{ + return date; +} + +/* guid + * Returns the item GUID. + */ +-(NSString *)guid +{ + return guid; +} + +/* link + * Returns the item link. + */ +-(NSString *)link +{ + return link; +} + +/* enclosure + * Returns the associated enclosure. + */ +-(NSString *)enclosure +{ + return enclosure; +} + +@end \ No newline at end of file diff --git a/src/models/FolderImageCache.h b/src/models/FolderImageCache.h new file mode 100644 index 0000000000..6f8b232cdd --- /dev/null +++ b/src/models/FolderImageCache.h @@ -0,0 +1,33 @@ +// +// FolderImageCache.h +// Vienna +// +// Created by Joshua Pore on 8/03/2015. +// Copyright (c) 2015 The Vienna Project. All rights reserved. +// + +#import + +@interface FolderImageCache : NSObject { + NSString * imagesCacheFolder; + NSMutableDictionary * folderImagesArray; + BOOL initializedFolderImagesArray; +} + +// Indexes into folder image array +enum { + MA_FolderIcon = 0, + MA_SmartFolderIcon, + MA_RSSFolderIcon, + MA_RSSFeedIcon, + MA_TrashFolderIcon, + MA_SearchFolderIcon, + MA_GoogleReaderFolderIcon, + MA_Max_Icons +}; + ++(FolderImageCache *)defaultCache; +-(void)addImage:(NSImage *)image forURL:(NSString *)baseURL; +-(NSImage *)retrieveImage:(NSString *)baseURL; + +@end diff --git a/src/models/FolderImageCache.m b/src/models/FolderImageCache.m new file mode 100644 index 0000000000..4199c71a94 --- /dev/null +++ b/src/models/FolderImageCache.m @@ -0,0 +1,147 @@ +// +// FolderImageCache.m +// Vienna +// +// Created by Joshua Pore on 8/03/2015. +// Copyright (c) 2015 The Vienna Project. All rights reserved. +// + +#import "FolderImageCache.h" +#import "Preferences.h" +#import "StringExtensions.h" + +@interface FolderImageCache () +-(void)initFolderImagesArray; + +@end + + +static FolderImageCache * _folderImageCache = nil; + +@implementation FolderImageCache + + +/* defaultCache + * Returns a pointer to the default cache. There is just one default cache + * and we instantiate it if it doesn't exist. + */ ++(FolderImageCache *)defaultCache +{ + if (_folderImageCache == nil) + _folderImageCache = [[FolderImageCache alloc] init]; + return _folderImageCache; +} + +/* init + * Init an instance of the folder image cache. + */ +-(instancetype)init +{ + if ((self = [super init]) != nil) + { + imagesCacheFolder = nil; + initializedFolderImagesArray = NO; + folderImagesArray = [[NSMutableDictionary alloc] init]; + } + return self; +} + +/* addImage + * Add the specified image to the cache and save it to disk. + */ +-(void)addImage:(NSImage *)image forURL:(NSString *)baseURL +{ + // Add in memory + [self initFolderImagesArray]; + folderImagesArray[baseURL] = image; + + // Save icon to disk here. + if (imagesCacheFolder != nil) + { + NSString * fullFilePath = [[imagesCacheFolder stringByAppendingPathComponent:baseURL] stringByAppendingPathExtension:@"tiff"]; + NSData *imageData = nil; + @try { + imageData = image.TIFFRepresentation; + } + @catch (NSException *error) { + imageData = nil; + NSLog(@"tiff exception with %@", fullFilePath); + } + if (imageData != nil) + [[NSFileManager defaultManager] createFileAtPath:fullFilePath contents:imageData attributes:nil]; + } +} + +/* retrieveImage + * Retrieve the image for the specified URL from the cache. + */ +-(NSImage *)retrieveImage:(NSString *)baseURL +{ + [self initFolderImagesArray]; + return folderImagesArray[baseURL]; +} + +/* initFolderImagesArray + * Load the existing list of folder images from the designated folder image cache. We + * do this only once and we do it as quickly as possible. When we're done, the folderImagesArray + * will be filled with image representations for each valid image file we find in the cache. + */ +-(void)initFolderImagesArray +{ + if (!initializedFolderImagesArray) + { + NSFileManager * fileManager = [NSFileManager defaultManager]; + NSArray * listOfFiles; + BOOL isDir; + + // Get and cache the path to the folder. This is the best time to make sure it + // exists. The penalty for it not existing AND us being unable to create it is that + // we don't cache folder icons in this session. + imagesCacheFolder = [Preferences standardPreferences].imagesFolder; + if (![fileManager fileExistsAtPath:imagesCacheFolder isDirectory:&isDir]) + { + if (![fileManager createDirectoryAtPath:imagesCacheFolder withIntermediateDirectories:YES attributes:nil error:nil]) + { + NSLog(@"Cannot create image cache at %@. Will not cache folder images in this session.", imagesCacheFolder); + imagesCacheFolder = nil; + } + initializedFolderImagesArray = YES; + return; + } + + if (!isDir) + { + NSLog(@"The file at %@ is not a directory. Will not cache folder images in this session.", imagesCacheFolder); + imagesCacheFolder = nil; + initializedFolderImagesArray = YES; + return; + } + + // Remember - not every file we find may be a valid image file. We use the filename as + // the key but check the extension too. + listOfFiles = [fileManager contentsOfDirectoryAtPath:imagesCacheFolder error:nil]; + if (listOfFiles != nil) + { + NSString * fileName; + + for (fileName in listOfFiles) + { + if ([fileName.pathExtension isEqualToString:@"tiff"]) + { + NSString * fullPath = [imagesCacheFolder stringByAppendingPathComponent:fileName]; + NSData * imageData = [fileManager contentsAtPath:fullPath]; + NSImage * iconImage = [[NSImage alloc] initWithData:imageData]; + if (iconImage.valid) + { + iconImage.size = NSMakeSize(16, 16); + NSString * homePageSiteRoot = (fullPath.lastPathComponent.stringByDeletingPathExtension).convertStringToValidPath; + folderImagesArray[homePageSiteRoot] = iconImage; + } + } + } + } + initializedFolderImagesArray = YES; + } +} + +@end