Commit d3b37a82 authored by Felix Paul Kühne's avatar Felix Paul Kühne

macosx: add basic addon manager

no fancy UI, but it works

Needs further UX improvements
parent ca3e0cb5
......@@ -118,6 +118,7 @@ EXTRA_DIST += \
extras/package/macosx/VLC.entitlements \
extras/package/macosx/Resources/dsa_pub.pem \
extras/package/macosx/Resources/English.lproj/About.xib \
extras/package/macosx/Resources/English.lproj/AddonManager.xib \
extras/package/macosx/Resources/English.lproj/AudioEffects.xib \
extras/package/macosx/Resources/English.lproj/Bookmarks.xib \
extras/package/macosx/Resources/English.lproj/ConvertAndSave.xib \
......
This diff is collapsed.
......@@ -11,6 +11,7 @@
7D8BB0B71830311300FAE9B7 /* DebugMessageVisualizer.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7D8BB0B51830311300FAE9B7 /* DebugMessageVisualizer.xib */; };
7D8BB0BA1830367200FAE9B7 /* PlaylistMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7D8BB0B81830367200FAE9B7 /* PlaylistMenu.xib */; };
7D8BB0C01830393300FAE9B7 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7D8BB0BE1830393300FAE9B7 /* MainWindow.xib */; };
7DB65D5618ABD6490053B874 /* AddonManager.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7DB65D5418ABD6490053B874 /* AddonManager.xib */; };
7DE88F2A1831396A00CD9DA2 /* PlaylistAccessoryView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7DE88F281831396A00CD9DA2 /* PlaylistAccessoryView.xib */; };
7DFFA16C16124F38001AF89F /* effects-one-button-pressed-dark.png in Resources */ = {isa = PBXBuildFile; fileRef = 7DFFA16A16124F38001AF89F /* effects-one-button-pressed-dark.png */; };
7DFFA16D16124F38001AF89F /* effects-one-button-pressed-dark@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7DFFA16B16124F38001AF89F /* effects-one-button-pressed-dark@2x.png */; };
......@@ -481,6 +482,9 @@
7D8BB0B61830311300FAE9B7 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Resources/English.lproj/DebugMessageVisualizer.xib; sourceTree = "<group>"; };
7D8BB0B91830367200FAE9B7 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Resources/English.lproj/PlaylistMenu.xib; sourceTree = "<group>"; };
7D8BB0BF1830393300FAE9B7 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Resources/English.lproj/MainWindow.xib; sourceTree = "<group>"; };
7DB65D5218ABD6380053B874 /* AddonManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AddonManager.h; path = ../../../modules/gui/macosx/AddonManager.h; sourceTree = "<group>"; };
7DB65D5318ABD6380053B874 /* AddonManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = AddonManager.m; path = ../../../modules/gui/macosx/AddonManager.m; sourceTree = "<group>"; };
7DB65D5518ABD6490053B874 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Resources/English.lproj/AddonManager.xib; sourceTree = "<group>"; };
7DE88F291831396A00CD9DA2 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Resources/English.lproj/PlaylistAccessoryView.xib; sourceTree = "<group>"; };
7DFFA16A16124F38001AF89F /* effects-one-button-pressed-dark.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "effects-one-button-pressed-dark.png"; path = "Resources/mainwindow_dark/effects-one-button-pressed-dark.png"; sourceTree = "<group>"; };
7DFFA16B16124F38001AF89F /* effects-one-button-pressed-dark@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "effects-one-button-pressed-dark@2x.png"; path = "Resources/mainwindow_dark/effects-one-button-pressed-dark@2x.png"; sourceTree = "<group>"; };
......@@ -1095,6 +1099,8 @@
5CCED71114C0D4A90057F8D1 /* ExtensionsDialogProvider.m */,
5CCED71214C0D4A90057F8D1 /* ExtensionsManager.h */,
5CCED71314C0D4A90057F8D1 /* ExtensionsManager.m */,
7DB65D5218ABD6380053B874 /* AddonManager.h */,
7DB65D5318ABD6380053B874 /* AddonManager.m */,
5CCED71414C0D4A90057F8D1 /* VLCUIWidgets.h */,
5CCED71514C0D4A90057F8D1 /* VLCUIWidgets.m */,
8E6BC6FA041684EC0059A3A7 /* controls.h */,
......@@ -1811,6 +1817,7 @@
7D8BB0BE1830393300FAE9B7 /* MainWindow.xib */,
7DE88F281831396A00CD9DA2 /* PlaylistAccessoryView.xib */,
7D3F6523188051F2005776C4 /* BWQuincyMain.xib */,
7DB65D5418ABD6490053B874 /* AddonManager.xib */,
);
name = xibs;
sourceTree = "<group>";
......@@ -1870,6 +1877,7 @@
files = (
CC8062641021F8790021EB9A /* dsa_pub.pem in Resources */,
CC402EB80E00ABBB006A4BA4 /* InfoPlist.strings in Resources */,
7DB65D5618ABD6490053B874 /* AddonManager.xib in Resources */,
CC402EB90E00ABBB006A4BA4 /* vlc.scriptSuite in Resources */,
CC402EBA0E00ABBB006A4BA4 /* vlc.scriptTerminology in Resources */,
CC402EBB0E00ABBB006A4BA4 /* README.MacOSX.rtf in Resources */,
......@@ -2329,6 +2337,14 @@
name = MainWindow.xib;
sourceTree = "<group>";
};
7DB65D5418ABD6490053B874 /* AddonManager.xib */ = {
isa = PBXVariantGroup;
children = (
7DB65D5518ABD6490053B874 /* English */,
);
name = AddonManager.xib;
sourceTree = "<group>";
};
7DE88F281831396A00CD9DA2 /* PlaylistAccessoryView.xib */ = {
isa = PBXVariantGroup;
children = (
......
/*****************************************************************************
* AddonManager.h: Addons manager for the Mac
****************************************************************************
* Copyright (C) 2014 VideoLAN and authors
* Author: Felix Paul Kühne <fkuehne # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import <Cocoa/Cocoa.h>
@interface VLCAddonManager : NSObject <NSTableViewDataSource, NSTableViewDelegate>
{
IBOutlet NSWindow *_window;
IBOutlet NSPopUpButton *_typeSwitcher;
IBOutlet NSButton *_localAddonsOnlyCheckbox;
IBOutlet NSTableView *_addonsTable;
IBOutlet NSProgressIndicator *_spinner;
}
+ (VLCAddonManager *)sharedInstance;
- (void)showWindow;
- (IBAction)switchType:(id)sender;
- (IBAction)toggleLocalCheckbox:(id)sender;
- (IBAction)tableAction:(id)sender;
@end
\ No newline at end of file
/*****************************************************************************
* AddonManager.m: Addons manager for the Mac
****************************************************************************
* Copyright (C) 2014 VideoLAN and authors
* Author: Felix Paul Kühne <fkuehne # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import "AddonManager.h"
#import <vlc_common.h>
#import <vlc_events.h>
#import <vlc_addons.h>
#import "intf.h"
@interface VLCAddonManager ()
{
addons_manager_t *_manager;
NSMutableArray *_addons;
NSArray *_displayedAddons;
}
- (void)addAddon:(addon_entry_t *)data;
- (void)discoveryEnded;
- (void)addonChanged:(addon_entry_t *)data;
@end
static void addonsEventsCallback( const vlc_event_t *, void * );
static void addonsEventsCallback( const vlc_event_t *event, void *data )
{
if (event->type == vlc_AddonFound)
[[VLCAddonManager sharedInstance] addAddon:event->u.addon_generic_event.p_entry];
else if (event->type == vlc_AddonsDiscoveryEnded)
[[VLCAddonManager sharedInstance] discoveryEnded];
else if (event->type == vlc_AddonChanged)
[[VLCAddonManager sharedInstance] addonChanged:event->u.addon_generic_event.p_entry];
}
@implementation VLCAddonManager
static VLCAddonManager *_o_sharedInstance = nil;
+ (VLCAddonManager *)sharedInstance
{
return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];
}
#pragma mark - object handling
- (id)init
{
if (_o_sharedInstance)
[self dealloc];
else {
_o_sharedInstance = [super init];
_addons = [[NSMutableArray alloc] init];
}
return _o_sharedInstance;
}
- (void)dealloc
{
[_addons release];
[_displayedAddons release];
if ( _manager )
addons_manager_Delete(_manager);
[super dealloc];
}
#pragma mark - UI handling
- (void)awakeFromNib
{
[_typeSwitcher removeAllItems];
[_typeSwitcher addItemWithTitle:_NS("All")];
[[_typeSwitcher lastItem] setTag: -1];
[_typeSwitcher addItemWithTitle:_NS("Skins")];
[[_typeSwitcher lastItem] setTag:ADDON_SKIN2];
[_typeSwitcher addItemWithTitle:_NS("Playlist parsers")];
[[_typeSwitcher lastItem] setTag:ADDON_PLAYLIST_PARSER];
[_typeSwitcher addItemWithTitle:_NS("Service discovery")];
[[_typeSwitcher lastItem] setTag:ADDON_SERVICE_DISCOVERY];
[_typeSwitcher addItemWithTitle:_NS("Extensions")];
[[_typeSwitcher lastItem] setTag:ADDON_EXTENSION];
[_localAddonsOnlyCheckbox setTitle:_NS("Show Installed Only")];
[_localAddonsOnlyCheckbox setState:NSOffState];
[_spinner setUsesThreadedAnimation:YES];
[_window setTitle:_NS("Addon Manager")];
[[[_addonsTable tableColumnWithIdentifier:@"installed"] headerCell] setStringValue:_NS("Installed")];
[[[_addonsTable tableColumnWithIdentifier:@"name"] headerCell] setStringValue:_NS("Name")];
[[[_addonsTable tableColumnWithIdentifier:@"author"] headerCell] setStringValue:_NS("Author")];
[[[_addonsTable tableColumnWithIdentifier:@"type"] headerCell] setStringValue:_NS("Type")];
_manager = addons_manager_New((vlc_object_t *)VLCIntf);
if (!_manager)
return;
vlc_event_manager_t *p_em = _manager->p_event_manager;
vlc_event_attach(p_em, vlc_AddonFound, addonsEventsCallback, self);
vlc_event_attach(p_em, vlc_AddonsDiscoveryEnded, addonsEventsCallback, self);
vlc_event_attach(p_em, vlc_AddonChanged, addonsEventsCallback, self);
}
- (void)showWindow
{
[self _findNewAddons];
[_spinner startAnimation:nil];
[_window makeKeyAndOrderFront:nil];
}
- (IBAction)switchType:(id)sender
{
[self _refactorDataModel];
}
- (IBAction)toggleLocalCheckbox:(id)sender
{
[self _refactorDataModel];
}
- (IBAction)tableAction:(id)sender
{
NSInteger clickedRow = [_addonsTable clickedRow];
if (clickedRow > _displayedAddons.count - 1 || clickedRow < 0)
return;
NSDictionary *currentItem = _displayedAddons[clickedRow];
if ([[currentItem objectForKey:@"state"] intValue] == ADDON_INSTALLED)
[self _removeAddonWithID:[[currentItem objectForKey:@"uuid"] pointerValue]];
else
[self _installAddonWithID:[[currentItem objectForKey:@"uuid"] pointerValue]];
}
- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView
{
return [_displayedAddons count];
}
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
{
NSString *identifier = [aTableColumn identifier];
if ([identifier isEqualToString:@"installed"]) {
if ([[_displayedAddons[rowIndex] objectForKey:@"state"] intValue] == ADDON_INSTALLED)
return @"✔";
return @"✘";
} else if([identifier isEqualToString:@"type"])
return [self _getAddonType:[[_displayedAddons[rowIndex] objectForKey:@"type"] intValue]];
return [_displayedAddons[rowIndex] objectForKey:identifier];
}
#pragma mark - data handling
- (void)addAddon:(addon_entry_t *)p_entry
{
@autoreleasepool {
NSString *name = [NSString stringWithUTF8String:p_entry->psz_name ? p_entry->psz_name : ""];
if (p_entry->e_state == ADDON_INSTALLED)
name = [name stringByAppendingFormat: @" (%@)", _NS("installed")];
NSDictionary *addonProperties = [NSDictionary dictionaryWithObjectsAndKeys:
name, @"name",
[NSString stringWithUTF8String:p_entry->psz_description ? p_entry->psz_description : ""], @"description",
[NSString stringWithUTF8String:p_entry->psz_author ? p_entry->psz_author : ""], @"author",
[NSString stringWithUTF8String:p_entry->psz_source_uri ? p_entry->psz_source_uri : ""], @"uri",
[NSString stringWithUTF8String:p_entry->psz_version ? p_entry->psz_version : ""], @"version",
[NSString stringWithUTF8String:p_entry->psz_image_uri ? p_entry->psz_image_uri : ""], @"imageuri",
[NSNumber numberWithInt:p_entry->e_state], @"state",
[NSNumber numberWithInt:p_entry->e_type], @"type",
[NSValue valueWithPointer:&p_entry->uuid], @"uuid",
nil];
[_addons addObject:addonProperties];
}
}
- (void)discoveryEnded
{
[self _refactorDataModel];
[_spinner stopAnimation:nil];
}
- (void)addonChanged:(addon_entry_t *)data
{
[self _refactorDataModel];
}
#pragma mark - helpers
- (void)_refactorDataModel
{
BOOL installedOnly = _localAddonsOnlyCheckbox.state == NSOnState;
int type = [[_typeSwitcher selectedItem] tag];
NSUInteger count = _addons.count;
NSMutableArray *filteredItems = [[NSMutableArray alloc] initWithCapacity:count];
NSDictionary *currentItem;
for (NSUInteger x = 0; x < count; x++) {
currentItem = _addons[x];
if (type != -1) {
if ([[currentItem objectForKey:@"type"] intValue] == type) {
if (installedOnly) {
if ([[currentItem objectForKey:@"state"] intValue] == ADDON_INSTALLED)
[filteredItems addObject:currentItem];
} else
[filteredItems addObject:currentItem];
}
} else {
if (installedOnly) {
if ([[currentItem objectForKey:@"state"] intValue] == ADDON_INSTALLED)
[filteredItems addObject:currentItem];
} else
[filteredItems addObject:currentItem];
}
}
if (_displayedAddons)
[_displayedAddons release];
_displayedAddons = [NSArray arrayWithArray:filteredItems];
[_displayedAddons retain];
[_addonsTable reloadData];
}
- (void)_findNewAddons
{
addons_manager_Gather(_manager, NULL);
}
/* FIXME: un-used */
- (void)_findDesignatedAddon:(NSString *)uri
{
addons_manager_Gather(_manager, [uri UTF8String]);
}
/* FIXME: un-used */
- (void)_findInstalled
{
addons_manager_LoadCatalog(_manager);
}
- (void)_installAddonWithID:(addon_uuid_t)addonid
{
addons_manager_Install(_manager, addonid);
}
- (void)_removeAddonWithID:(addon_uuid_t)addonid
{
addons_manager_Remove(_manager, addonid);
}
- (NSString *)_getAddonType:(int)i_type
{
switch (i_type)
{
case ADDON_SKIN2:
return @"Skins";
case ADDON_PLAYLIST_PARSER:
return @"Playlist parsers";
case ADDON_SERVICE_DISCOVERY:
return @"Service Discovery";
case ADDON_EXTENSION:
return @"Extensions";
default:
return @"Unknown";
}
}
@end
\ No newline at end of file
......@@ -35,6 +35,7 @@
BOOL b_nib_tracksynchro_loaded;
BOOL b_nib_bookmarks_loaded;
BOOL b_nib_convertandsave_loaded;
BOOL b_nib_addonmanager_loaded;
id o_about; /* VLAboutBox */
id o_videoeffects; /* VLCVideoEffects */
......@@ -42,6 +43,7 @@
id o_trackSynchronization; /* VLCTrackSynchronization */
id o_bookmarks; /* VLCBookmarks */
id o_convertandsave; /* VLCConvertAndSave */
id o_addonManager; /* VLCAddonManager */
id o_extMgr; /* Extensions Manager */
......@@ -52,6 +54,7 @@
IBOutlet NSMenuItem * o_mi_checkForUpdate;
IBOutlet NSMenuItem * o_mi_extensions;
IBOutlet NSMenu * o_mu_extensions;
IBOutlet NSMenuItem * o_mi_addonManager;
IBOutlet NSMenuItem * o_mi_add_intf;
IBOutlet NSMenu * o_mu_add_intf;
IBOutlet NSMenuItem * o_mi_services;
......@@ -237,6 +240,8 @@
- (void)setupExtensionsMenu;
- (void)updateSidebarMenuItem;
- (IBAction)openAddonManager:(id)sender;
- (IBAction)intfOpenFile:(id)sender;
- (IBAction)intfOpenFileGeneric:(id)sender;
- (IBAction)intfOpenDisc:(id)sender;
......
......@@ -45,6 +45,7 @@
#import "ExtensionsManager.h"
#import "ConvertAndSave.h"
#import "DebugMessageVisualizer.h"
#import "AddonManager.h"
@implementation VLCMainMenu
static VLCMainMenu *_o_sharedInstance = nil;
......@@ -312,6 +313,7 @@ static VLCMainMenu *_o_sharedInstance = nil;
[o_mi_prefs setTitle: _NS("Preferences...")];
[o_mi_extensions setTitle: _NS("Extensions")];
[o_mu_extensions setTitle: _NS("Extensions")];
[o_mi_addonManager setTitle: _NS("Addon Manager")];
[o_mi_add_intf setTitle: _NS("Add Interface")];
[o_mu_add_intf setTitle: _NS("Add Interface")];
[o_mi_services setTitle: _NS("Services")];
......@@ -1126,6 +1128,17 @@ static VLCMainMenu *_o_sharedInstance = nil;
[[[VLCMain sharedInstance] simplePreferences] showSimplePrefsWithLevel:i_level];
}
- (IBAction)openAddonManager:(id)sender
{
if (!o_addonManager)
o_addonManager = [[VLCAddonManager alloc] init];
if (!b_nib_addonmanager_loaded)
b_nib_addonmanager_loaded = [NSBundle loadNibNamed:@"AddonManager" owner:NSApp];
[o_addonManager showWindow];
}
- (IBAction)showMessagesPanel:(id)showMessagesPanel
{
[[VLCDebugMessageVisualizer sharedInstance] showPanel];
......
......@@ -20,6 +20,8 @@ SOURCES_macosx = \
ExtensionsManager.m \
ExtensionsDialogProvider.h \
ExtensionsDialogProvider.m \
AddonManager.h \
AddonManager.m \
VLCUIWidgets.h \
VLCUIWidgets.m \
about.h \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment