Skip to content

Commit

Permalink
Add article filtering. Minor improvements to truncation of cells in t…
Browse files Browse the repository at this point in the history
…he article list.

Add 'createddate' field to messages table in the database and up the version to 13.
  • Loading branch information
stevewpalmer authored and stevewpalmer committed Mar 26, 2006
1 parent 5806052 commit ad60f21
Show file tree
Hide file tree
Showing 38 changed files with 718 additions and 201 deletions.
4 changes: 4 additions & 0 deletions AppController.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#import <Foundation/Foundation.h>
#import "Database.h"
#import "ActivityViewer.h"
#import "PopupButton.h"
#import "Growl/GrowlApplicationBridge.h"

@class NewPreferenceController;
Expand Down Expand Up @@ -54,6 +55,8 @@
IBOutlet NSMenuItem * sortByMenu;
IBOutlet NSMenuItem * columnsMenu;
IBOutlet NSMenuItem * stylesMenu;
IBOutlet NSMenuItem * filtersMenu;
IBOutlet PopupButton * filtersPopupMenu;

ActivityViewer * activityViewer;
NewPreferenceController * preferenceController;
Expand Down Expand Up @@ -132,6 +135,7 @@
-(IBAction)decreaseFontSize:(id)sender;
-(IBAction)increaseFontSize:(id)sender;
-(IBAction)openWebLocation:(id)sender;
-(IBAction)changeFiltering:(id)sender;

// Public functions
-(void)setStatusMessage:(NSString *)newStatusText persist:(BOOL)persistenceFlag;
Expand Down
65 changes: 61 additions & 4 deletions AppController.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#import "Preferences.h"
#import "DownloadManager.h"
#import "HelperFunctions.h"
#import "ArticleFilter.h"
#import "WebKit/WebFrame.h"
#import "WebKit/WebUIDelegate.h"
#import "Growl/GrowlDefines.h"
Expand All @@ -64,6 +65,7 @@ -(void)localiseMenus:(NSArray *)arrayOfMenus;
-(void)initSortMenu;
-(void)initColumnsMenu;
-(void)initStylesMenu;
-(void)initFiltersMenu;
-(void)initScriptsMenu;
-(void)startProgressIndicator;
-(void)stopProgressIndicator;
Expand Down Expand Up @@ -174,7 +176,8 @@ -(void)awakeFromNib
[self initSortMenu];
[self initColumnsMenu];
[self initStylesMenu];

[self initFiltersMenu];

// Restore the splitview layout
[splitView1 setLayout:[[Preferences standardPreferences] objectForKey:@"SplitView1Positions"]];
[splitView1 setDelegate:self];
Expand Down Expand Up @@ -1087,8 +1090,8 @@ -(void)initScriptsMenu

/* initStylesMenu
* Populate the Styles menu with a list of built-in and external styles. (Note that in the event of
* duplicates the styles in the external Styles folder wins. This is intended to allow the user to
* override the built-in styles if necessary).
* duplicates the styles in the external Styles folder wins. This is intended to allow the user to
* override the built-in styles if necessary).
*/
-(void)initStylesMenu
{
Expand Down Expand Up @@ -1120,6 +1123,42 @@ -(void)initStylesMenu
[stylesMenu setSubmenu:stylesSubMenu];
}

/* initFiltersMenu
* Populate both the Filters submenu on the View menu and the Filters popup menu on the Filter
* button in the article list. We need separate menus since the latter is eventually configured
* to use a smaller font than the former.
*/
-(void)initFiltersMenu
{
NSMenu * filterSubMenu = [[[NSMenu alloc] initWithTitle:@"Filter By"] autorelease];
NSMenu * filterPopupMenu = [[[NSMenu alloc] initWithTitle:@""] autorelease];

NSArray * filtersArray = [ArticleFilter arrayOfFilters];
int count = [filtersArray count];
int index;

for (index = 0; index < count; ++index)
{
ArticleFilter * filter = [filtersArray objectAtIndex:index];

NSMenuItem * menuItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString([filter name], nil) action:@selector(changeFiltering:) keyEquivalent:@""];
[menuItem setTag:[filter tag]];
[filterSubMenu addItem:menuItem];
[menuItem release];

menuItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString([filter name], nil) action:@selector(changeFiltering:) keyEquivalent:@""];
[menuItem setTag:[filter tag]];
[filterPopupMenu addItem:menuItem];
[menuItem release];
}

// Add it to the Filters menu
[filtersPopupMenu setMenu:filterPopupMenu];
[filtersPopupMenu setSmallMenu:YES];

[filtersMenu setSubmenu:filterSubMenu];
}

/* showUnreadCountOnApplicationIconAndWindowTitle
* Update the Vienna application icon to show the number of unread articles.
*/
Expand Down Expand Up @@ -1496,6 +1535,10 @@ -(void)handleRefreshStatusChange:(NSNotification *)nc
{
if ([NSApp isRefreshing])
{
// Save the date/time of this refresh so we do the right thing when
// we apply the filter.
[[Preferences standardPreferences] setObject:[NSCalendarDate date] forKey:MAPref_LastRefreshDate];

[self startProgressIndicator];
[self setStatusMessage:[[RefreshManager sharedManager] statusMessageDuringRefresh] persist:YES];
}
Expand Down Expand Up @@ -2305,7 +2348,16 @@ -(IBAction)mailLinkToArticlePage:(id)sender
}
[self openURLInDefaultBrowser:[NSURL URLWithString: mailtoLink]];
}
}
}

/* changeFiltering
* Refresh the filtering of articles.
*/
-(IBAction)changeFiltering:(id)sender
{
NSMenuItem * menuItem = (NSMenuItem *)sender;
[[Preferences standardPreferences] setFilterMode:[menuItem tag]];
}

/* setStatusMessage
* Sets a new status message for the info bar then updates the view. To remove
Expand Down Expand Up @@ -2527,6 +2579,11 @@ -(BOOL)validateMenuItem:(NSMenuItem *)menuItem
NSView<BaseView> * theView = [browserView activeTabView];
return ([theView isKindOfClass:[BrowserPane class]]) && [(BrowserPane *)theView isLoading];
}
else if (theAction == @selector(changeFiltering:))
{
[menuItem setState:([menuItem tag] == [[Preferences standardPreferences] filterMode]) ? NSOnState : NSOffState];
return isMainWindowVisible;
}
else if (theAction == @selector(markFlagged:))
{
Article * thisArticle = [self selectedArticle];
Expand Down
35 changes: 35 additions & 0 deletions ArticleFilter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// ArticleFilter.h
// Vienna
//
// Created by Steve on 3/24/06.
// Copyright (c) 2004-2006 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 <Cocoa/Cocoa.h>

@interface ArticleFilter : NSObject {
NSString * name;
int tag;
SEL comparator;
}

// Public functions
+(NSArray *)arrayOfFilters;
+(ArticleFilter *)filterByTag:(int)theTag;
-(NSString *)name;
-(int)tag;
-(SEL)comparator;
@end
159 changes: 159 additions & 0 deletions ArticleFilter.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
//
// ArticleFilter.m
// Vienna
//
// Created by Steve on 3/24/06.
// Copyright (c) 2004-2006 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 "ArticleFilter.h"
#import "CalendarExtensions.h"
#import "Preferences.h"
#import "Constants.h"
#import "Message.h"

@interface ArticleFilter (Private)
+(void)createFilter:(NSString *)name tag:(int)tag comparator:(SEL)comparator;
@end

// There's just one global filter list.
static NSMutableArray * _filterList = nil;

@implementation ArticleFilter

/* unreadArticleFilterComparator
* Returns TRUE if the specified article is unread.
*/
+(BOOL)unreadArticleFilterComparator:(Article *)theArticle
{
return ![theArticle isRead];
}

/* todayFilterComparator
* Returns TRUE if the specified article was posted today.
*/
+(BOOL)todayFilterComparator:(Article *)theArticle
{
return ([[theArticle date] compare:[NSCalendarDate today]] != NSOrderedAscending);
}

/* lastRefreshFilterComparator
* Returns TRUE if the specified article is the same as or newer than the last refresh date.
*/
+(BOOL)lastRefreshFilterComparator:(Article *)theArticle
{
return ([[theArticle createdDate] compare:[[Preferences standardPreferences] objectForKey:MAPref_LastRefreshDate]] != NSOrderedAscending);
}

/* initalize
* Create all the default filters. To add a new filter:
*
* 1. Add an unique tag ID for the filter in constants.h (MA_Filter_xxx).
* 2. Add a comparator in this file that returns TRUE if the article should be filtered IN.
* 3. Add a new line below with the filter name, tag and comparator.
* 4. Localise the filter name in the Localizable.strings for each language.
*
* That's it really. The filtering and menu is handled automatically.
*/
+(void)initialize
{
[ArticleFilter createFilter:@"All Articles" tag:MA_Filter_All comparator:nil];
[ArticleFilter createFilter:@"Unread Articles" tag:MA_Filter_Unread comparator:@selector(unreadArticleFilterComparator:)];
[ArticleFilter createFilter:@"Last Refresh" tag:MA_Filter_LastRefresh comparator:@selector(lastRefreshFilterComparator:)];
[ArticleFilter createFilter:@"Today" tag:MA_Filter_Today comparator:@selector(todayFilterComparator:)];
}

/* arrayOfFilters
* Return the array of filters.
*/
+(NSArray *)arrayOfFilters
{
return _filterList;
}

/* filterByTag
* Returns the filter identified by the specified tag or nil if there's no filter
* with the given tag.
*/
+(ArticleFilter *)filterByTag:(int)theTag
{
int index;
for (index = 0; index < [_filterList count]; ++index)
{
ArticleFilter * filter = [_filterList objectAtIndex:index];
if ([filter tag] == theTag)
return filter;
}
return nil;
}

/* initWithName
* This is the designated initialiser for a new ArticleFilter object.
*/
-(id)initWithName:(NSString *)theName tag:(int)theTag comparator:(SEL)theComparator
{
if ((self = [super init]) != nil)
{
name = [theName retain];
tag = theTag;
comparator = theComparator;
}
return self;
}

/* name
* Return the filter name.
*/
-(NSString *)name
{
return name;
}

/* comparator
* Return the filter comparator function.
*/
-(SEL)comparator
{
return comparator;
}

/* tag
* Return the filter's unique ID (tag)
*/
-(int)tag
{
return tag;
}

/* createFilter
* Create a new article filter with the specified name and comparator.
*/
+(void)createFilter:(NSString *)name tag:(int)tag comparator:(SEL)comparator
{
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];
[super dealloc];
}
@end
3 changes: 2 additions & 1 deletion ArticleListView.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
NSTimer * markReadTimer;
NSTimer * selectionTimer;
NSArray * currentArrayOfArticles;
NSArray * folderArrayOfArticles;
BackTrackArray * backtrackArray;
BOOL isBacktracking;
NSString * guidOfArticleToSelect;
Expand All @@ -74,7 +75,7 @@
-(void)setController:(AppController *)theController;
-(void)initialiseArticleView;
-(BOOL)selectFolderAndArticle:(int)folderId guid:(NSString *)guid;
-(void)refreshFolder:(BOOL)reloadData;
-(void)refreshFolder:(int)refreshFlag;
-(void)updateAlternateMenuTitle;
-(void)updateVisibleColumns;
-(void)saveTableSettings;
Expand Down
Loading

0 comments on commit ad60f21

Please sign in to comment.