mirror of
https://github.com/zhigang1992/transshift.git
synced 2026-05-22 14:23:07 +08:00
1054 lines
36 KiB
Objective-C
1054 lines
36 KiB
Objective-C
//
|
|
// StatusListController.m
|
|
// TransmissionRPCClient
|
|
//
|
|
// Shows torrents statueses
|
|
//
|
|
|
|
#import "StatusListController.h"
|
|
#import "StatusListCell.h"
|
|
#import "TorrentListController.h"
|
|
#import "TorrentInfoController.h"
|
|
#import "PeerListController.h"
|
|
#import "FileListController.h"
|
|
#import "SessionConfigController.h"
|
|
#import "SpeedLimitController.h"
|
|
#import "RPCConnector.h"
|
|
#import "FooterViewFreeSpace.h"
|
|
#import "HeaderViewDURates.h"
|
|
#import "InfoMessage.h"
|
|
#import "RateLimitTable.h"
|
|
#import "StatusCategories.h"
|
|
|
|
#define STATUS_SECTION_TITILE @"Torrents"
|
|
|
|
#define POPOVER_LIMITSPEEDCONTROLLER_SIZE CGSizeMake(190,400)
|
|
|
|
|
|
@interface StatusListController () <RPCConnectorDelegate,
|
|
TorrentListControllerDelegate,
|
|
TorrentInfoControllerDelegate,
|
|
PeerListControllerDelegate,
|
|
FileListControllerDelegate,
|
|
SpeedLimitControllerDelegate,
|
|
UIAlertViewDelegate,
|
|
UIPopoverControllerDelegate,
|
|
UISplitViewControllerDelegate>
|
|
|
|
@end
|
|
|
|
@implementation StatusListController
|
|
|
|
{
|
|
NSArray *_sections;
|
|
NSArray *_itemNames;
|
|
NSArray *_itemFilterOptions;
|
|
NSArray *_itemImages;
|
|
|
|
RateLimitTable *_ratesDown; // holds download speed limits (kb/s)
|
|
RateLimitTable *_ratesUp; // holds uplaod speed limits (kb/s)
|
|
|
|
NSMutableDictionary *_cells;
|
|
|
|
// this flag used in ViewDidAppear
|
|
BOOL _appearedFirstTime;
|
|
BOOL _showCheckItems; // allows to see "checking" status
|
|
BOOL _showErrorItems; // allows to see "error" status
|
|
|
|
// holds main RPC connector
|
|
RPCConnector *_connector;
|
|
|
|
TRSessionInfo *_sessionInfo; // holds session configuration Information
|
|
|
|
NSTimer *_refreshTimer; // holds main autorefresh timer
|
|
|
|
// Header/Footer info views
|
|
FooterViewFreeSpace *_footerViewFreeSpace;
|
|
HeaderViewDURates *_headerViewDURates;
|
|
|
|
// toolbar buttons
|
|
UIBarButtonItem *_btnRefresh;
|
|
UIBarButtonItem *_btnLimitDownSpeed;
|
|
UIBarButtonItem *_btnLimitUpSpeed;
|
|
UIBarButtonItem *_btnSessionConfig;
|
|
UIBarButtonItem *_btnSpacer;
|
|
|
|
// controllers
|
|
TorrentListController *_torrentController; // holds detail torrent list controller
|
|
TorrentInfoController *_torrentInfoController; // holds torrent info controller (when torrent is selected from torrent list)
|
|
PeerListController *_peerListController; // holds controller for showing peers
|
|
FileListController *_fileListController; // holds controller for showing files
|
|
SessionConfigController *_sessionConfigController; // holds session config controller
|
|
SpeedLimitController *_speedLimitController; // holds speed limit controller
|
|
UIPopoverController *_speedPopOver; // holds popover for speed controller
|
|
|
|
// categories
|
|
StatusCategories *_items; // holds status categories
|
|
}
|
|
|
|
- (void)viewDidLoad
|
|
{
|
|
[super viewDidLoad];
|
|
|
|
_items = [[StatusCategories alloc] init];
|
|
|
|
_appearedFirstTime = YES;
|
|
|
|
// initialize section name and section row names
|
|
[self initNames];
|
|
|
|
// initialize speed limit tables with names
|
|
[self initSpeedLimitTables];
|
|
|
|
// create RPC connector to communicate with selected server
|
|
if( self.config )
|
|
{
|
|
_connector = [[RPCConnector alloc] initWithConfig:self.config andDelegate:self];
|
|
|
|
// config pull-to refresh control
|
|
self.refreshControl = [[UIRefreshControl alloc] init];
|
|
[self.refreshControl addTarget:self
|
|
action:@selector(autorefreshTimerUpdateHandler)
|
|
forControlEvents:UIControlEventValueChanged];
|
|
|
|
// schedule autorefresh timer
|
|
if( self.config.refreshTimeout > 0 )
|
|
{
|
|
_refreshTimer = [NSTimer scheduledTimerWithTimeInterval:self.config.refreshTimeout target:self
|
|
selector:@selector(autorefreshTimerUpdateHandler)
|
|
userInfo:nil
|
|
repeats:YES];
|
|
}
|
|
else
|
|
{
|
|
self.footerInfoMessage = @"Autorefreshing is off.\nPull down to refresh data.";
|
|
}
|
|
}
|
|
|
|
// getting detail controller - TorrentListController
|
|
// on iPad it is already created on start
|
|
// on iPhone it should be created from storyboard
|
|
if( self.splitViewController )
|
|
{
|
|
// left (detail) controller should be NavigationContoller with our TorrentListController
|
|
UINavigationController *rightNav = self.splitViewController.viewControllers[1];
|
|
|
|
_torrentController = (TorrentListController*)rightNav.topViewController;
|
|
// clear all current torrents
|
|
_torrentController.torrents = nil;
|
|
}
|
|
else
|
|
{
|
|
// on iPhone instantiate this controller
|
|
_torrentController = instantiateController( CONTROLLER_ID_TORRENTLIST );
|
|
}
|
|
|
|
// set us as delegate
|
|
_torrentController.delegate = self;
|
|
|
|
// Configure pull-to-refresh control for updating TorrentListController
|
|
_torrentController.refreshControl = [[UIRefreshControl alloc] init];
|
|
[_torrentController.refreshControl addTarget:self
|
|
action:@selector(autorefreshTimerUpdateHandler)
|
|
forControlEvents:UIControlEventValueChanged];
|
|
|
|
self.headerInfoMessage = @"Updating ...";
|
|
|
|
// configure bottom toolbar buttons
|
|
_btnRefresh = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"iconRefresh20x20"]
|
|
style:UIBarButtonItemStylePlain target:self
|
|
action:@selector(autorefreshTimerUpdateHandler)];
|
|
|
|
_btnLimitUpSpeed = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"iconTurtleUpload20x20"]
|
|
style:UIBarButtonItemStylePlain
|
|
target:self
|
|
action:@selector(showUploadLimitRateController:)];
|
|
|
|
_btnLimitDownSpeed = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"iconTurtleDownload20x20"]
|
|
style:UIBarButtonItemStylePlain
|
|
target:self
|
|
action:@selector(showDownloadLimitRateController:)];
|
|
|
|
_btnSessionConfig = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"iconGears20x20"]
|
|
style:UIBarButtonItemStylePlain
|
|
target:self
|
|
action:@selector(showSessionConfiguration)];
|
|
|
|
_btnSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
|
|
target:nil
|
|
action:nil];
|
|
|
|
_btnLimitDownSpeed.enabled = NO;
|
|
_btnLimitUpSpeed.enabled = NO;
|
|
_btnSessionConfig.enabled = NO;
|
|
|
|
self.toolbarItems = @[ _btnRefresh, _btnSpacer, _btnLimitUpSpeed, _btnSpacer, _btnLimitDownSpeed, _btnSpacer, _btnSessionConfig];
|
|
|
|
// configure "add torrent by url" right nav button
|
|
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"iconLinkAdd20x20"]
|
|
style:UIBarButtonItemStylePlain
|
|
target:self
|
|
action:@selector(showAddTorrentByURLDialog)];
|
|
|
|
// hide check and error statuses
|
|
_showCheckItems = NO;
|
|
_showErrorItems = NO;
|
|
}
|
|
|
|
- (void)initNames
|
|
{
|
|
_sections = @[ STATUS_SECTION_TITILE ];
|
|
|
|
_itemNames = @[ STATUS_ROW_ALL,
|
|
STATUS_ROW_ACTIVE,
|
|
STATUS_ROW_DOWNLOAD,
|
|
STATUS_ROW_SEED,
|
|
STATUS_ROW_STOP,
|
|
STATUS_ROW_CHECK,
|
|
STATUS_ROW_ERROR ];
|
|
|
|
_itemFilterOptions = @[ @(TRStatusOptionsAll),
|
|
@(TRStatusOptionsActive),
|
|
@(TRStatusOptionsDownload),
|
|
@(TRStatusOptionsSeed),
|
|
@(TRStatusOptionsStop),
|
|
@(TRStatusOptionsCheck),
|
|
@(TRStatusOptionsError) ];
|
|
|
|
_itemImages = @[ [[UIImage imageNamed:@"allIcon"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate],
|
|
[[UIImage imageNamed:@"activeIcon"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate],
|
|
[[UIImage imageNamed:@"downloadIcon"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate],
|
|
[[UIImage imageNamed:@"uploadIcon"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate],
|
|
[[UIImage imageNamed:@"stopIcon"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate],
|
|
[[UIImage imageNamed:@"checkIcon"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate],
|
|
[[UIImage imageNamed:@"iconErrorTorrent40x40"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] ];
|
|
|
|
_cells = [NSMutableDictionary dictionary];
|
|
}
|
|
|
|
- (void)initSpeedLimitTables
|
|
{
|
|
// UP rate limits
|
|
NSArray *titles = @[ @"Unlimited", @"50 Kb/s", @"100 Kb/s", @"150 Kb/s",
|
|
@"200 Kb/s", @"250 Kb/s", @"500 Kb/s",
|
|
@"750 Kb/s", @"1024 Kb/s", @"2048 Kb/s" ];
|
|
|
|
NSArray *rates = @[ @(0), @(50), @(100), @(150),
|
|
@(200), @(250), @(500),
|
|
@(750), @(1024),@(2048) ];
|
|
|
|
_ratesDown = [RateLimitTable tableWithTitles:titles andRates:rates];
|
|
_ratesUp = [RateLimitTable tableWithTitles:titles andRates:rates];
|
|
|
|
_ratesDown.tableTitle = @"Limit download speed";
|
|
_ratesUp.tableTitle = @"Limit upload speed";
|
|
}
|
|
|
|
- (void)showInfoPopup:(NSString*)infoStr
|
|
{
|
|
UIView *v = self.parentViewController.view;
|
|
|
|
float factor = 1.2;
|
|
if( self.splitViewController )
|
|
{
|
|
factor = 2.3;
|
|
v = self.splitViewController.view;
|
|
}
|
|
|
|
InfoMessage *msg = [InfoMessage infoMessageWithSize:CGSizeMake(v.bounds.size.width/factor, 50)];
|
|
[msg showInfo:infoStr fromView:v];
|
|
}
|
|
|
|
- (void)showErrorPopup:(NSString*)errStr
|
|
{
|
|
UIView *v = self.parentViewController.view;
|
|
|
|
float factor = 1.2;
|
|
if( self.splitViewController )
|
|
{
|
|
factor = 2.3;
|
|
v = self.splitViewController.view;
|
|
}
|
|
|
|
InfoMessage *msg = [InfoMessage infoMessageWithSize:CGSizeMake(v.bounds.size.width/factor, 50)];
|
|
[msg showErrorInfo:errStr fromView:v];
|
|
}
|
|
|
|
- (void)viewDidAppear:(BOOL)animated
|
|
{
|
|
[super viewDidAppear:animated];
|
|
|
|
// if there is a leftbutton on _torrentConroller -> change title
|
|
if( self.splitViewController )
|
|
{
|
|
_torrentController.popoverButtonTitle = self.title;
|
|
}
|
|
|
|
// check if it is ipad we shoud and none of rows is selected - select all row (0)
|
|
if( self.splitViewController && _appearedFirstTime )
|
|
{
|
|
if( ![self.tableView indexPathForSelectedRow] )
|
|
{
|
|
// select first row
|
|
// and do it manualy
|
|
// NSIndexPath *path = [NSIndexPath indexPathForRow:0 inSection:0];
|
|
// make first row selected
|
|
//[self.tableView selectRowAtIndexPath:path animated:YES scrollPosition:UITableViewScrollPositionNone];
|
|
|
|
// set filter to rows
|
|
//[self filterTorrentListWithFilterOptions:TRStatusOptionsAll];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
[_connector getAllTorrents];
|
|
}
|
|
|
|
// at first initialization, get session info
|
|
if( _appearedFirstTime )
|
|
[_connector getSessionInfo];
|
|
|
|
_appearedFirstTime = NO;
|
|
self.navigationController.toolbarHidden = NO;
|
|
|
|
[self fixFooterHeaderViews];
|
|
}
|
|
|
|
- (void)viewWillDisappear:(BOOL)animated
|
|
{
|
|
self.navigationController.toolbarHidden = YES;
|
|
}
|
|
|
|
- (void)stopUpdating
|
|
{
|
|
[_refreshTimer invalidate];
|
|
[_connector stopRequests];
|
|
|
|
_torrentController.refreshControl = nil;
|
|
_torrentController.infoMessage = @"There is no selected server";
|
|
}
|
|
|
|
// main refresh cycle, updates data in detail view controllers
|
|
- (void)autorefreshTimerUpdateHandler
|
|
{
|
|
[_connector getAllTorrents];
|
|
|
|
UINavigationController *nav = _torrentController.navigationController;
|
|
|
|
if( nav.topViewController == _torrentInfoController )
|
|
[_connector getDetailedInfoForTorrentWithId:_torrentInfoController.torrentId];
|
|
|
|
else if( nav.topViewController == _peerListController)
|
|
[_connector getAllPeersForTorrentWithId:_peerListController.torrentId];
|
|
|
|
else if( nav.topViewController == _fileListController )
|
|
[_connector getAllFilesForTorrentWithId:_fileListController.torrentId];
|
|
|
|
//if( _sessionInfo )
|
|
// update free space
|
|
// [_connector getFreeSpaceWithDownloadDir:_sessionInfo.downloadDir];
|
|
}
|
|
|
|
- (void)gotFreeSpaceString:(NSString *)freeSpace
|
|
{
|
|
//NSLog(@"gotFreeSpace");
|
|
NSString *str = [NSString stringWithFormat:@"Free space: %@", freeSpace];
|
|
|
|
//self.footerInfoMessage = str;
|
|
[self showFreeSpaceInfoWithString:str];
|
|
|
|
if( !self.splitViewController )
|
|
_torrentController.footerInfoMessage = str;
|
|
}
|
|
|
|
- (void)showFreeSpaceInfoWithString:(NSString*)string
|
|
{
|
|
if( !_footerViewFreeSpace )
|
|
{
|
|
_footerViewFreeSpace = [FooterViewFreeSpace view];
|
|
self.tableView.tableFooterView = _footerViewFreeSpace;
|
|
}
|
|
|
|
if( self.tableView.tableFooterView != _footerViewFreeSpace )
|
|
self.tableView.tableFooterView = _footerViewFreeSpace;
|
|
|
|
_footerViewFreeSpace.label.text = string;
|
|
}
|
|
|
|
- (void)showHeaderDLRate:(NSString*)dlRate ULRate:(NSString*)ulRate
|
|
{
|
|
if( !_headerViewDURates )
|
|
{
|
|
_headerViewDURates = [HeaderViewDURates view];
|
|
self.tableView.tableHeaderView = _headerViewDURates;
|
|
}
|
|
|
|
// fix - hide error message
|
|
if( self.tableView.tableHeaderView != _headerViewDURates )
|
|
self.tableView.tableHeaderView = _headerViewDURates;
|
|
|
|
_headerViewDURates.uploadString = ulRate;
|
|
_headerViewDURates.downloadString = dlRate;
|
|
}
|
|
|
|
- (void)fixFooterHeaderViews
|
|
{
|
|
if( _footerViewFreeSpace )
|
|
{
|
|
[_footerViewFreeSpace setBoundsFromTableView:self.tableView];
|
|
self.tableView.tableFooterView = _footerViewFreeSpace;
|
|
}
|
|
if( _headerViewDURates )
|
|
{
|
|
[_headerViewDURates setBoundsFromTableView:self.tableView];
|
|
self.tableView.tableHeaderView = _headerViewDURates;
|
|
}
|
|
}
|
|
|
|
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
|
|
{
|
|
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
|
|
|
|
[self fixFooterHeaderViews];
|
|
}
|
|
|
|
// should be performed when there is no errors
|
|
// occured upon rpc request
|
|
- (void)requestToServerSucceeded
|
|
{
|
|
[self.refreshControl endRefreshing];
|
|
[_torrentController.refreshControl endRefreshing];
|
|
|
|
// clear error message
|
|
//self.headerTitleString = @"Request OK";
|
|
}
|
|
|
|
// got all torrents, refresh statues
|
|
// this is a delegate method, performed asychronosly
|
|
// from RPCConnector
|
|
- (void)gotAllTorrents:(TRInfos *)torrents
|
|
{
|
|
[self requestToServerSucceeded];
|
|
|
|
//[_items updateInfos:torrents];
|
|
//[self.tableView reloadData];
|
|
|
|
NSArray *arr;
|
|
|
|
arr = [_items updateForDeleteWithInfos:torrents];
|
|
if( arr.count > 0 )
|
|
{
|
|
NSMutableArray *indexPathsToDelete = [NSMutableArray array];
|
|
for( NSNumber* n in arr )
|
|
{
|
|
[indexPathsToDelete addObject:[NSIndexPath indexPathForRow:[n intValue] inSection:0]];
|
|
}
|
|
|
|
[self.tableView beginUpdates];
|
|
|
|
[self.tableView deleteRowsAtIndexPaths:indexPathsToDelete withRowAnimation:UITableViewRowAnimationAutomatic];
|
|
|
|
[self.tableView endUpdates];
|
|
}
|
|
|
|
arr = [_items updateForInsertWithInfos: torrents];
|
|
if( arr.count > 0 )
|
|
{
|
|
NSMutableArray *indexPathsToInsert = [NSMutableArray array];
|
|
for( NSNumber* n in arr )
|
|
{
|
|
[indexPathsToInsert addObject:[NSIndexPath indexPathForRow:[n intValue] inSection:0]];
|
|
}
|
|
|
|
[self.tableView beginUpdates];
|
|
|
|
[self.tableView insertRowsAtIndexPaths:indexPathsToInsert withRowAnimation:UITableViewRowAnimationAutomatic];
|
|
|
|
[self.tableView endUpdates];
|
|
}
|
|
|
|
// update numbers
|
|
for( int i = 0; i < _items.countOfVisible; i++ )
|
|
{
|
|
StatusCategory *c = [_items categoryAtIndex:i];
|
|
|
|
StatusListCell *cell = (StatusListCell*)c.cell;
|
|
|
|
cell.numberLabel.text = [NSString stringWithFormat:@"%i", c.count];
|
|
}
|
|
|
|
// show torrents in list controller (update)
|
|
// find torrents that are finished downloading
|
|
TRInfos *prev = _torrentController.torrents;
|
|
if( prev )
|
|
{
|
|
NSArray *dtors = prev.downloadingTorrents;
|
|
NSArray *stors = torrents.seedingTorrents;
|
|
|
|
NSMutableString *sInfo = [NSMutableString string];
|
|
|
|
for (TRInfo* dt in dtors)
|
|
{
|
|
for( TRInfo* st in stors )
|
|
{
|
|
if( st.trId == dt.trId )
|
|
{
|
|
// we have found finished torrent need to
|
|
[sInfo appendString:[NSString stringWithFormat:@"Torrent: %@\n has finished downloading\n", st.name]];
|
|
}
|
|
}
|
|
}
|
|
|
|
if( sInfo.length > 0 )
|
|
{
|
|
[self showInfoPopup:sInfo];
|
|
}
|
|
|
|
// update NsUserDefaults for background fetch notifications
|
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
NSArray *currentDownTorrents = torrents.downloadingTorrents;
|
|
if( currentDownTorrents.count > 0 )
|
|
{
|
|
NSMutableArray *downIds = [NSMutableArray array];
|
|
for( TRInfo *t in currentDownTorrents )
|
|
[downIds addObject:@(t.trId)];
|
|
|
|
[defaults setObject:downIds forKey:USERDEFAULTS_BGFETCH_KEY_DOWNTORRENTIDS];
|
|
}
|
|
else
|
|
{
|
|
[defaults removeObjectForKey:USERDEFAULTS_BGFETCH_KEY_DOWNTORRENTIDS];
|
|
}
|
|
|
|
} // end of finding finished torrents
|
|
|
|
_torrentController.torrents = torrents;
|
|
|
|
NSString *str = [NSString stringWithFormat:@"↑UL:%@ ↓DL:%@",
|
|
torrents.totalUploadRateString,
|
|
torrents.totalDownloadRateString];
|
|
|
|
|
|
[self showHeaderDLRate:torrents.totalDownloadRateString ULRate:torrents.totalUploadRateString];
|
|
|
|
if( !self.splitViewController )
|
|
_torrentController.headerInfoMessage = str;
|
|
|
|
if( _config.showFreeSpace && _sessionInfo && self.navigationController.visibleViewController == self )
|
|
[_connector getFreeSpaceWithDownloadDir:_sessionInfo.downloadDir];
|
|
}
|
|
|
|
- (void)setCount:(int)count forCellWithTitle:(NSString*)cellTitle
|
|
{
|
|
StatusListCell *cell = _cells[cellTitle];
|
|
if( cell )
|
|
{
|
|
cell.numberLabel.text = [NSString stringWithFormat:@"%i", count];
|
|
|
|
// set icon in gray if there are not items
|
|
cell.iconImg.tintColor = count > 0 ? cell.tintColor : [UIColor lightGrayColor];
|
|
if( [cellTitle isEqualToString:STATUS_ROW_ERROR] )
|
|
cell.iconImg.tintColor = [UIColor colorWithRed:0.8 green:0 blue:0 alpha:1];
|
|
}
|
|
}
|
|
|
|
// shows alert view for adding torrent by URL (magnet url also)
|
|
- (void)showAddTorrentByURLDialog
|
|
{
|
|
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Add torrent"
|
|
message:@"Type URL or MAGNET URL"
|
|
delegate:self
|
|
cancelButtonTitle:@"Cancel"
|
|
otherButtonTitles:@"Add torrent", nil];
|
|
|
|
alert.delegate = self;
|
|
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
|
|
|
|
[alert show];
|
|
}
|
|
|
|
- (void)gotTorrentAdded
|
|
{
|
|
[self showInfoPopup:@"New torrent was added"];
|
|
}
|
|
|
|
#pragma mark - Alert View delegate methods
|
|
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
|
|
{
|
|
if( buttonIndex != alertView.cancelButtonIndex )
|
|
{
|
|
// get url
|
|
NSString* urlString = [alertView textFieldAtIndex:0].text;
|
|
[_connector addTorrentWithMagnet:urlString priority:0 startImmidiately:YES];
|
|
}
|
|
}
|
|
|
|
#pragma mark - Bottom toolbar button handlers
|
|
|
|
- (void)showDownloadLimitRateController:(UIBarButtonItem*)sender
|
|
{
|
|
_speedLimitController = instantiateController(CONTROLLER_ID_SPEEDLIMIT);
|
|
_speedLimitController.preferredContentSize = POPOVER_LIMITSPEEDCONTROLLER_SIZE;
|
|
_speedLimitController.rates = _ratesDown;
|
|
_speedLimitController.delegate = self;
|
|
_speedLimitController.title = @"Download speed limits";
|
|
_speedLimitController.isDownload = YES;
|
|
|
|
if( self.splitViewController )
|
|
{
|
|
if( _speedPopOver && _speedPopOver.isPopoverVisible )
|
|
[_speedPopOver dismissPopoverAnimated:YES];
|
|
|
|
_speedPopOver = [[UIPopoverController alloc] initWithContentViewController:_speedLimitController];
|
|
_speedPopOver.delegate = self;
|
|
|
|
[_speedPopOver presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
|
|
}
|
|
else
|
|
{
|
|
[self.navigationController pushViewController:_speedLimitController animated:YES];
|
|
}
|
|
}
|
|
|
|
- (void)showUploadLimitRateController:(UIBarButtonItem*)sender
|
|
{
|
|
_speedLimitController = instantiateController(CONTROLLER_ID_SPEEDLIMIT);
|
|
_speedLimitController.preferredContentSize = POPOVER_LIMITSPEEDCONTROLLER_SIZE;
|
|
_speedLimitController.rates = _ratesUp;
|
|
_speedLimitController.delegate = self;
|
|
_speedLimitController.title = @"Upload speed limits";
|
|
_speedLimitController.isDownload = NO;
|
|
|
|
if( self.splitViewController )
|
|
{
|
|
if( _speedPopOver && _speedPopOver.isPopoverVisible )
|
|
[_speedPopOver dismissPopoverAnimated:YES];
|
|
|
|
_speedPopOver = [[UIPopoverController alloc] initWithContentViewController:_speedLimitController];
|
|
_speedPopOver.delegate = self;
|
|
|
|
[_speedPopOver presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
|
|
}
|
|
else
|
|
{
|
|
[self.navigationController pushViewController:_speedLimitController animated:YES];
|
|
}
|
|
}
|
|
|
|
- (void)speedLimitControllerSpeedSelectedWithIndex:(int)index
|
|
{
|
|
// take limit number and dissmiss
|
|
if( _speedPopOver )
|
|
[_speedPopOver dismissPopoverAnimated:YES];
|
|
else
|
|
[self.navigationController popViewControllerAnimated:YES];
|
|
|
|
// get the limits!
|
|
if( _speedLimitController.isDownload )
|
|
{
|
|
[_connector limitDownloadRateWithSpeed:_ratesDown.selectedRate];
|
|
|
|
if( _ratesDown.selectedRate == 0)
|
|
{
|
|
[self showInfoPopup:@"Disable download speed limit"];
|
|
}
|
|
else
|
|
{
|
|
[self showInfoPopup:[NSString stringWithFormat:@"Setting download speed limit to %i KB/s", _ratesDown.selectedRate]];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
[_connector limitUploadRateWithSpeed:_ratesUp.selectedRate];
|
|
|
|
if( _ratesUp.selectedRate == 0)
|
|
{
|
|
[self showInfoPopup:@"Disable upload speed limit"];
|
|
}
|
|
else
|
|
{
|
|
[self showInfoPopup:[NSString stringWithFormat:@"Setting upload speed limit to %i KB/s", _ratesUp.selectedRate]];
|
|
}
|
|
}
|
|
|
|
_speedLimitController = nil;
|
|
_speedPopOver = nil;
|
|
}
|
|
|
|
#pragma mark - Working with session information
|
|
|
|
// shows SessionConfigController and make request
|
|
// for session info
|
|
- (void)showSessionConfiguration
|
|
{
|
|
_sessionConfigController = instantiateController(CONTROLLER_ID_SESSIONCONFIG);
|
|
_sessionConfigController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave
|
|
target:self
|
|
action:@selector(saveSessionParametes)];
|
|
[self.navigationController pushViewController:_sessionConfigController animated:YES];
|
|
|
|
[_connector getSessionInfo];
|
|
[_connector portTest];
|
|
|
|
// FIX: WARNING - don't get it right, but if I put this code
|
|
// above - app is crashing on iOS 8.3 (nsarray is filled with nil)
|
|
// it seems that controls is not loaded
|
|
if( _speedPopOver && _speedPopOver.isPopoverVisible )
|
|
{
|
|
[_speedPopOver dismissPopoverAnimated:NO];
|
|
_speedPopOver = nil;
|
|
}
|
|
}
|
|
|
|
- (void)saveSessionParametes
|
|
{
|
|
if( [_sessionConfigController saveConfig] )
|
|
{
|
|
[_connector setSessionWithSessionInfo:_sessionConfigController.sessionInfo];
|
|
[self.navigationController popViewControllerAnimated:YES];
|
|
_sessionConfigController = nil;
|
|
}
|
|
}
|
|
|
|
- (void)gotSessionWithInfo:(TRSessionInfo *)info
|
|
{
|
|
// getting session information for the first time
|
|
// get free space (fix)
|
|
if( !_sessionInfo && _config.showFreeSpace )
|
|
[_connector getFreeSpaceWithDownloadDir:info.downloadDir];
|
|
|
|
_sessionInfo = info;
|
|
|
|
// update session config if controller is on
|
|
// the screen
|
|
if( _sessionConfigController )
|
|
_sessionConfigController.sessionInfo = info;
|
|
|
|
// enable buttons
|
|
_btnSessionConfig.enabled = YES;
|
|
_btnLimitDownSpeed.enabled = YES;
|
|
_btnLimitUpSpeed.enabled = YES;
|
|
|
|
// show/hide limit icon
|
|
_headerViewDURates.upLimitIsOn = info.upLimitEnabled || info.altLimitEnabled;
|
|
_headerViewDURates.downLimitIsOn = info.downLimitEnabled || info.altLimitEnabled;
|
|
|
|
// NSLog(@"downLimits: %@ ,upLimits: %@",
|
|
// _headerViewDURates.downLimitIsOn ? @"ON":@"OFF",
|
|
// _headerViewDURates.upLimitIsOn ? @"ON":@"OFF");
|
|
|
|
_ratesUp.selectedRateIndex = 0;
|
|
if( info.upLimitEnabled || info.altLimitEnabled )
|
|
{
|
|
int curRate = _sessionInfo.altLimitEnabled ? _sessionInfo.altUploadRateLimit : _sessionInfo.upLimitRate;
|
|
[_ratesUp updateTableWithRate:curRate];
|
|
}
|
|
|
|
_ratesDown.selectedRateIndex = 0;
|
|
if( info.downLimitEnabled || info.altLimitEnabled )
|
|
{
|
|
int curRate = _sessionInfo.altLimitEnabled ? _sessionInfo.altDownloadRateLimit : _sessionInfo.downLimitRate;
|
|
[_ratesDown updateTableWithRate:curRate];
|
|
}
|
|
}
|
|
|
|
- (void)gotPortTestedWithSuccess:(BOOL)portIsOpen
|
|
{
|
|
if( _sessionConfigController )
|
|
_sessionConfigController.portIsOpen = portIsOpen;
|
|
}
|
|
|
|
- (void)gotSessionSetWithInfo:(TRSessionInfo *)info
|
|
{
|
|
[self gotSessionWithInfo:info];
|
|
[self showInfoPopup:@"Settings are saved"];
|
|
}
|
|
|
|
#pragma mark - RPCConnector error hangling
|
|
|
|
// RPCConnector signals error
|
|
- (void)connector:(RPCConnector *)cn complitedRequestName:(NSString *)requestName withError:(NSString *)errorMessage
|
|
{
|
|
// end of refreshing (if it is)
|
|
[self.refreshControl endRefreshing];
|
|
[_torrentController.refreshControl endRefreshing];
|
|
|
|
if( [requestName isEqualToString:TR_METHODNAME_TORRENTADD] ||
|
|
[requestName isEqualToString:TR_METHODNAME_TORRENTADDURL] )
|
|
{
|
|
[self showErrorPopup:errorMessage];
|
|
return;
|
|
}
|
|
|
|
|
|
// show error to background
|
|
//_torrentController.infoMessage = errorMessage;
|
|
_torrentController.torrents = nil;
|
|
_torrentController.errorMessage = errorMessage;
|
|
self.errorMessage = errorMessage;
|
|
|
|
UINavigationController *nav = _torrentController.navigationController;
|
|
if( _torrentInfoController && nav.visibleViewController == _torrentInfoController )
|
|
{
|
|
[_torrentInfoController showErrorMessage:errorMessage];
|
|
}
|
|
}
|
|
|
|
#pragma mark - TorrentInfoController delegate methods
|
|
|
|
- (void)stopTorrentWithId:(int)torrentId
|
|
{
|
|
//NSLog(@"Stopping torrent");
|
|
|
|
[_connector stopTorrent:torrentId];
|
|
}
|
|
|
|
- (void)gotTorrentStopedWithId:(int)torrentId
|
|
{
|
|
[_connector getDetailedInfoForTorrentWithId:torrentId];
|
|
[self showInfoPopup:@"Torrent was stopped"];
|
|
}
|
|
|
|
-(void)resumeTorrentWithId:(int)torrentId
|
|
{
|
|
// NSLog(@"Resuming torrent");
|
|
|
|
[_connector resumeTorrent:torrentId];
|
|
}
|
|
|
|
- (void)gotTorrentResumedWithId:(int)torrentId
|
|
{
|
|
[_connector getDetailedInfoForTorrentWithId:torrentId];
|
|
[self showInfoPopup:@"Torrent was resumed"];
|
|
|
|
}
|
|
|
|
-(void)verifyTorrentWithId:(int)torrentId
|
|
{
|
|
[_connector verifyTorrent:torrentId];
|
|
}
|
|
|
|
- (void)gotTorrentVerifyedWithId:(int)torrentId
|
|
{
|
|
[_connector getDetailedInfoForTorrentWithId:torrentId];
|
|
[self showInfoPopup:@"Torrent is verifying ..."];
|
|
}
|
|
|
|
// delegate method from TorrentInfoController
|
|
-(void)deleteTorrentWithId:(int)torrentId deleteWithData:(BOOL)deleteWithData
|
|
{
|
|
// pop view controller from stack
|
|
UINavigationController *nav = _torrentController.navigationController;
|
|
|
|
UIViewController *controller = nav.topViewController;
|
|
|
|
if( controller == _torrentInfoController )
|
|
{
|
|
[nav popToRootViewControllerAnimated:YES];
|
|
_torrentInfoController = nil;
|
|
|
|
//NSLog(@"StatusListController: Deleting torrent %@", deleteWithData ? @"with data" : @"");
|
|
|
|
[_connector deleteTorrentWithId:torrentId deleteWithData:deleteWithData];
|
|
}
|
|
}
|
|
|
|
- (void)torrentListRemoveTorrentWithId:(int)torrentId removeWithData:(BOOL)removeWithData
|
|
{
|
|
//NSLog(@"StatusListController: Deleting torrent %i %@", torrentId, removeWithData ? @"with data" : @"");
|
|
|
|
[_connector deleteTorrentWithId:torrentId deleteWithData:removeWithData];
|
|
}
|
|
|
|
- (void)gotTorrentDeletedWithId:(int)torrentId
|
|
{
|
|
//[_connector getDetailedInfoForTorrentWithId:torrentId];
|
|
[_connector getAllTorrents];
|
|
[self showInfoPopup:@"Torrent was deleted"];
|
|
}
|
|
|
|
- (void)reannounceTorrentWithId:(int)torrentId
|
|
{
|
|
//NSLog(@"Reannouncing torrent");
|
|
[_connector reannounceTorrent:torrentId];
|
|
}
|
|
|
|
- (void)gotTorrentReannouncedWithId:(int)torrentId
|
|
{
|
|
[_connector getDetailedInfoForTorrentWithId:torrentId];
|
|
[self showInfoPopup:@"Torrent is reannouncing ..."];
|
|
}
|
|
|
|
- (void)gotTorrentDetailedInfo:(TRInfo *)torrentInfo
|
|
{
|
|
if( _torrentInfoController )
|
|
{
|
|
[_torrentInfoController updateData:torrentInfo];
|
|
}
|
|
}
|
|
|
|
- (void)updateTorrentInfoWithId:(int)torrentId
|
|
{
|
|
[_connector getDetailedInfoForTorrentWithId:torrentId];
|
|
}
|
|
|
|
#pragma mark - TorrentListController delegate methods
|
|
|
|
// shows view controller with detailed info
|
|
- (void)showDetailedInfoForTorrentWithId:(int)torrentId
|
|
{
|
|
_torrentInfoController = instantiateController( CONTROLLER_ID_TORRENTINFO );
|
|
_torrentInfoController.torrentId = torrentId;
|
|
_torrentInfoController.delegate = self;
|
|
|
|
// we should make a request to RPCConnector
|
|
// (upon complite, info controller will be updated)
|
|
[_connector getDetailedInfoForTorrentWithId:torrentId];
|
|
|
|
// and show our controller
|
|
// get nav controller for detail panel
|
|
UINavigationController *nav = _torrentController.navigationController;
|
|
// and push this info controller on top of it
|
|
|
|
[nav pushViewController:_torrentInfoController animated:YES];
|
|
}
|
|
|
|
#pragma mark - TorrentInfoControllerDelegate
|
|
|
|
- (void)showPeersForTorrentWithId:(int)torrentId
|
|
{
|
|
_peerListController = instantiateController( CONTROLLER_ID_PEERLIST );
|
|
_peerListController.delegate = self;
|
|
_peerListController.torrentId = torrentId;
|
|
_peerListController.title = @"Peers"; //[NSString stringWithFormat:@"Peers: %@", _torrentInfoController.title];
|
|
|
|
UINavigationController *nav = _torrentController.navigationController;
|
|
[nav pushViewController:_peerListController animated:YES];
|
|
|
|
[_connector getAllPeersForTorrentWithId:torrentId];
|
|
}
|
|
|
|
- (void)gotAllPeers:(NSArray *)peerInfos forTorrentWithId:(int)torrentId
|
|
{
|
|
if( _peerListController )
|
|
{
|
|
_peerListController.peers = peerInfos;
|
|
}
|
|
}
|
|
|
|
- (void)peerListNeedUpdatePeersForTorrentId:(int)torrentId
|
|
{
|
|
[_connector getAllPeersForTorrentWithId:torrentId];
|
|
}
|
|
|
|
- (void)showFilesForTorrentWithId:(int)torrentId
|
|
{
|
|
_fileListController = instantiateController( CONTROLLER_ID_FILELIST );
|
|
_fileListController.delegate = self;
|
|
_fileListController.torrentId = torrentId;
|
|
_fileListController.title = @"Files";//[NSString stringWithFormat:@"Files: %@", _torrentInfoController.title];
|
|
|
|
UINavigationController *nav = _torrentController.navigationController;
|
|
[nav pushViewController:_fileListController animated:YES];
|
|
|
|
[_connector getAllFilesForTorrentWithId:torrentId];
|
|
}
|
|
|
|
- (void)gotAllFiles:(NSArray *)fileInfos forTorrentWithId:(int)torrentId
|
|
{
|
|
if( _fileListController )
|
|
_fileListController.fileInfos = fileInfos;
|
|
}
|
|
|
|
- (void)fileListControllerNeedUpdateFilesForTorrentWithId:(int)torrentId
|
|
{
|
|
[_connector getAllFilesForTorrentWithId:torrentId];
|
|
}
|
|
|
|
- (void)fileListControllerResumeDownloadingFilesWithIndexes:(NSArray *)indexes forTorrentWithId:(int)torrentId
|
|
{
|
|
[_connector resumeDownloadingFilesWithIndexes:indexes forTorrentWithId:torrentId];
|
|
}
|
|
|
|
- (void)fileListControllerStopDownloadingFilesWithIndexes:(NSArray *)indexes forTorrentWithId:(int)torrentId
|
|
{
|
|
[_connector stopDownloadingFilesWithIndexes:indexes forTorrentWithId:torrentId];
|
|
}
|
|
|
|
- (void)fileListControllerSetPriority:(int)priority forFilesWithIndexes:(NSArray *)indexes forTorrentWithId:(int)torrentId
|
|
{
|
|
[_connector setPriority:priority forFilesWithIndexes:indexes forTorrentWithId:torrentId];
|
|
}
|
|
|
|
// set the filter of TorrentListController
|
|
// and fetching all torrents
|
|
- (void)filterTorrentListWithFilterOptions:(TRStatusOptions)filterOptions
|
|
{
|
|
_torrentController.title = @"Torrents";
|
|
_torrentController.popoverButtonTitle = self.title;
|
|
_torrentController.filterOptions = filterOptions;
|
|
|
|
// on iPhone we should show _torrentController instead of ours
|
|
if( !self.splitViewController )
|
|
{
|
|
[self.navigationController pushViewController:_torrentController animated:YES];
|
|
}
|
|
else
|
|
{
|
|
// on iPad show torrent list
|
|
[_torrentController.navigationController popToRootViewControllerAnimated:YES];
|
|
}
|
|
|
|
// fetch data for all torrents
|
|
[_connector getAllTorrents];
|
|
}
|
|
|
|
#pragma mark - TableView delegate
|
|
|
|
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
|
{
|
|
TRStatusOptions filterOption = [_itemFilterOptions[indexPath.row] unsignedIntValue];
|
|
|
|
[self filterTorrentListWithFilterOptions: filterOption];
|
|
}
|
|
|
|
#pragma mark - Table view data source
|
|
|
|
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
|
|
{
|
|
// return _sections[section];
|
|
return STATUS_SECTION_TITILE;
|
|
}
|
|
|
|
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
|
|
{
|
|
return _items.countOfVisible > 0 ? 1 : 0;
|
|
}
|
|
|
|
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
|
{
|
|
return _items.countOfVisible;
|
|
}
|
|
|
|
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
|
{
|
|
//NSString *title = _itemNames[indexPath.row];
|
|
StatusCategory *c = [_items categoryAtIndex:indexPath.row];
|
|
|
|
StatusListCell *cell = [tableView dequeueReusableCellWithIdentifier:CELL_ID_STATUSLIST forIndexPath:indexPath];
|
|
|
|
// Configure the cell
|
|
cell.numberLabel.text = @" ";
|
|
cell.statusLabel.text = c.title;
|
|
cell.iconImg.image = c.iconImage;
|
|
cell.iconImg.tintColor = c.iconColor ? c.iconColor : cell.tintColor;
|
|
|
|
// store cell reference for later cell
|
|
// updating
|
|
c.cell = cell;
|
|
|
|
return cell;
|
|
}
|
|
|
|
@end
|