diff --git a/contrib/mobile/iOS/Onelab/AboutViewController.mm b/contrib/mobile/iOS/Onelab/AboutViewController.mm index f68b1f6eadfd3e93e883d20fc064901ab2b2c8b4..d9af6501100c4f2b4d2bbc700016951b98fc84e4 100644 --- a/contrib/mobile/iOS/Onelab/AboutViewController.mm +++ b/contrib/mobile/iOS/Onelab/AboutViewController.mm @@ -48,7 +48,7 @@ baseURL:[[NSBundle mainBundle] bundleURL]]; } else if([self.fileToEdit isEqual:@"Help"]){ - [self.aboutView loadHTMLString:@"<html><head><style type=\"text/css\">body { background-color: #FFFFFF; color: #252525; margin: 35px 10px 35px 10px; padding: 0; font-family: helvetica-neue,sans-serif; font-size: 1em; } h3 { text-align: center; } b { font-weight: normal; color: rgb(0,122,255); }</style></head><!-- img width=32 src=\"icon_onelab.png\"--><h3>Onelab/Mobile</h3> <h4>Running an existing model</h4> <p> The list of available models appears when you launch the app. Selecting a model will load it. You can then press <b>Run</b> to launch a simulation with the default set of parameters. When available, additional information about a model can be obtained by long-pressing on the model descrition and selecting <b>Visit model website</b>.</p> <h4>Modifying a model</h4> <p>To run a model with different parameters, press <b>Parameters</b> and modify any of the presets. Then press <b>Run</b> again: all the simulation steps will be performed with the new parameter values. To restore the preset parameters values, press <b>Reset</b>. </p> <p> Advanced users can also directly edit the model input files: long-press on the model description and select <b>Edit model files</b>. </p> <p> To free up space, temporary model files (meshes, solution files) can be removed by long-pressing on the model description and selecting <b>Clear results</b>. </p> <p> To completey remove a model, long-press on the model description and select <b>Remove</b>. </p> <h4>Sharing a model</h4> <p> To share a model by email, long-press on the model description and select <b>Email model files</b>. </p> <h4>Installing a new model</h4> <p> To install a new model: <ol> <li>Put all the model files (.pro, .geo) in a directory, which should also contain a file named <code>infos.xml</code> with the model information: <pre>\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<models>\n <model>\n <title>Model title</title>\n <summary>Model summary</summary>\n <file type=\"pro\">main_pro_file.pro</file>\n <preview type=\"png\">128x128_pixel_screenshot.png</preview>\n <url>http://model_website.com</url>\n </model>\n</models>\n</pre><li>Zip the directory. <li>Open the .zip file on your device, e.g. through iCloud or by emailing it to yourself and opening the attachment; or by putting it on a web server and downloading the file on the device with Safari. <li>Refresh the list of models: the new model will be extracted alongside Onelab/Mobile\'s built-in models.</ol> <p style=\"padding-top: 2em;\">Visit <a href=\"http://onelab.info/\">http://onelab.info/</a> for more information.</p> </body></html>" + [self.aboutView loadHTMLString:@"<html><head><style type=\"text/css\">body { background-color: #FFFFFF; color: #252525; margin: 35px 10px 35px 10px; padding: 0; font-family: helvetica-neue,sans-serif; font-size: 1em; } h3 { text-align: center; } b { font-weight: normal; color: rgb(0,122,255); }</style></head><!-- img width=32 src=\"icon_onelab.png\"--><h3>Onelab/Mobile</h3> <h4>Running an existing model</h4> <p> The list of available models appears when you launch the app. Selecting a model will load it. You can then press <b>Run</b> to launch a simulation with the default set of parameters. When available, additional information about a model can be obtained by long-pressing on the model description and selecting <b>Visit model website</b>.</p> <h4>Modifying a model</h4> <p>To run a model with different parameters, press <b>Parameters</b> and modify any of the presets. Then press <b>Run</b> again: all the simulation steps will be performed with the new parameter values. To restore the preset parameters values, press <b>Reset</b>. </p> <p> Advanced users can also directly edit the model input files: long-press on the model description and select <b>Edit model files</b>. </p> <p> To free up space, temporary model files (meshes, solution files) can be removed by long-pressing on the model description and selecting <b>Clear results</b>. </p> <p> To completey remove a model, long-press on the model description and select <b>Remove</b>. </p> <h4>Sharing a model</h4> <p> To share a model by email, long-press on the model description and select <b>Email model files</b>. </p> <h4>Installing a new model</h4> <p> To install a new model: <ol> <li>Put all the model files (.pro, .geo) in a directory, which should also contain a file named <code>infos.xml</code> with the model information: <pre>\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<models>\n <model>\n <title>Model title</title>\n <summary>Model summary</summary>\n <file type=\"pro\">main_pro_file.pro</file>\n <preview type=\"png\">128x128_pixel_screenshot.png</preview>\n <url>http://model_website.com</url>\n </model>\n</models>\n</pre><li>Zip the directory. <li>Open the .zip file on your device, e.g. through iCloud or by emailing it to yourself and opening the attachment; or by putting it on a web server and downloading the file on the device with Safari. <li>Refresh the list of models: the new model will be extracted alongside Onelab/Mobile\'s built-in models.</ol> <p style=\"padding-top: 2em;\">Visit <a href=\"http://onelab.info/\">http://onelab.info/</a> for more information.</p> </body></html>" baseURL:[[NSBundle mainBundle] bundleURL]]; } else{ diff --git a/contrib/mobile/iOS/Onelab/ModelListController.h b/contrib/mobile/iOS/Onelab/ModelListController.h index 7d4d76654c25631cc3a219b802d117e69583fbc2..b7deab23da8f4ff9bf8ac4d19601c5103b9a11e3 100644 --- a/contrib/mobile/iOS/Onelab/ModelListController.h +++ b/contrib/mobile/iOS/Onelab/ModelListController.h @@ -2,7 +2,7 @@ #import <MessageUI/MessageUI.h> #import "EAGLView.h" -@interface ModelListController : UITableViewController <NSXMLParserDelegate, UIActionSheetDelegate, MFMailComposeViewControllerDelegate> +@interface ModelListController : UITableViewController <NSXMLParserDelegate, MFMailComposeViewControllerDelegate> { @private NSMutableArray *models; @@ -13,7 +13,5 @@ NSString *currentFileToEdit; } @property (nonatomic, retain) EAGLView *glView; -@property (nonatomic, retain) UIActionSheet *longPressActionSheet; -@property (nonatomic, retain) UIActionSheet *editFilesActionSheet; @end diff --git a/contrib/mobile/iOS/Onelab/ModelListController.mm b/contrib/mobile/iOS/Onelab/ModelListController.mm index 1a0881d960d7c24110f22c97652b19ee05b9acaa..e1df4f3f386defbbbd4a32899b3627fccc09a3f9 100644 --- a/contrib/mobile/iOS/Onelab/ModelListController.mm +++ b/contrib/mobile/iOS/Onelab/ModelListController.mm @@ -151,113 +151,107 @@ if(sender.state == UIGestureRecognizerStateCancelled) return; NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:p]; if(indexPath == nil) return; - if([[models objectAtIndex:indexPath.row] getUrl]) - self.longPressActionSheet = - [[UIActionSheet alloc] initWithTitle:[[models objectAtIndex:indexPath.row] getName] - delegate:self - cancelButtonTitle:@"Cancel" - destructiveButtonTitle:nil - otherButtonTitles: @"Open", @"Remove", @"Clear results", - @"Edit model files", @"Email model files", - @"Visit model website", nil]; - else - self.longPressActionSheet = - [[UIActionSheet alloc] initWithTitle:[[models objectAtIndex:indexPath.row] getName] - delegate:self - cancelButtonTitle:@"Cancel" - destructiveButtonTitle:nil - otherButtonTitles: @"Open", @"Remove", @"Clear results", - @"Edit model files", @"Email model files", - nil]; - self.longPressActionSheet.tag = indexPath.row; - [self.longPressActionSheet showInView:self.view]; -} + UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; --(void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex -{ - if(actionSheet == self.longPressActionSheet){ - switch (buttonIndex) { - case 5: - [[UIApplication sharedApplication] openURL:[[models objectAtIndex:actionSheet.tag] getUrl]]; - break; - case 4: - { - NSString *modelFile = [[models objectAtIndex:actionSheet.tag] getFile]; + UIAlertController *actionSheet = + [UIAlertController alertControllerWithTitle:[[models objectAtIndex:indexPath.row] getName] + message:nil + preferredStyle:UIAlertControllerStyleActionSheet]; + + [actionSheet addAction:[UIAlertAction actionWithTitle:@"Cancel" + style:UIAlertActionStyleCancel + handler:^(UIAlertAction *action) { + }]]; + [actionSheet addAction:[UIAlertAction actionWithTitle:@"Open" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *action) { + [self tableView:self.tableView + didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row inSection:0]]; + }]]; + [actionSheet addAction:[UIAlertAction actionWithTitle:@"Remove" + style:UIAlertActionStyleDestructive + handler:^(UIAlertAction *action) { + NSString *file = [[models objectAtIndex:indexPath.row] getFile]; + NSString *path = [file stringByDeletingLastPathComponent]; + [[NSFileManager defaultManager] removeItemAtPath:path error:nil]; + [self refreshList]; + }]]; + [actionSheet addAction:[UIAlertAction actionWithTitle:@"Clear results" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *action) { + NSString *modelFile = [[models objectAtIndex:indexPath.row] getFile]; NSString *modelPath = [modelFile stringByDeletingLastPathComponent]; NSArray *modelFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:modelPath error:NULL]; - // TODO: would probably be better to email a zip archive? (this ignores subdirectories) - [self attachFilesToEmail:modelFiles filePath:modelPath]; - } - break; - case 3: - { - NSString *modelFile = [[models objectAtIndex:actionSheet.tag] getFile]; + for (NSString *obj in modelFiles){ + NSString *extension = [obj pathExtension]; + if([extension isEqualToString:@"msh"] || + [extension isEqualToString:@"pre"] || + [extension isEqualToString:@"res"] || + [extension isEqualToString:@"pos"]){ + NSString *file = [[modelPath stringByAppendingString:@"/"] stringByAppendingString:obj]; + NSLog(@"Removing file %@", file); + [[NSFileManager defaultManager] removeItemAtPath:file error:nil]; + } + } + }]]; + [actionSheet addAction:[UIAlertAction actionWithTitle:@"Edit model files" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *action) { + NSString *modelFile = [[models objectAtIndex:indexPath.row] getFile]; NSString *modelPath = [modelFile stringByDeletingLastPathComponent]; NSArray *modelFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:modelPath error:NULL]; - self.editFilesActionSheet = [[UIActionSheet alloc] initWithTitle:@"Model files" - delegate:self - cancelButtonTitle: nil - destructiveButtonTitle: nil - otherButtonTitles: nil]; + UIAlertController *actionSheet2 = + [UIAlertController alertControllerWithTitle:@"Edit files" + message:nil + preferredStyle:UIAlertControllerStyleActionSheet]; + [actionSheet2 addAction:[UIAlertAction actionWithTitle:@"Cancel" + style:UIAlertActionStyleCancel + handler:^(UIAlertAction *action) { + }]]; for(NSString *file in modelFiles) { NSString *extension = [file pathExtension]; if([extension isEqualToString:@"txt"] || [extension isEqualToString:@"geo"] || [extension isEqualToString:@"pro"] || [extension isEqualToString:@"dat"]){ - [self.editFilesActionSheet addButtonWithTitle:file]; + [actionSheet2 addAction: [UIAlertAction actionWithTitle:file + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *action) { + NSString *modelFile = [[models objectAtIndex:indexPath.row] getFile]; + NSString *modelPath = [modelFile stringByDeletingLastPathComponent]; + currentFileToEdit = [[modelPath stringByAppendingString:@"/"] stringByAppendingString:file]; + [self performSegueWithIdentifier:@"showAboutSegue" sender:self]; + }]]; } } - self.editFilesActionSheet.cancelButtonIndex = - [self.editFilesActionSheet addButtonWithTitle:@"Cancel"]; - self.editFilesActionSheet.tag = self.longPressActionSheet.tag; - [self.editFilesActionSheet showInView:self.view]; - } - break; - case 2: - { - NSString *modelFile = [[models objectAtIndex:actionSheet.tag] getFile]; + actionSheet2.popoverPresentationController.sourceView = cell; + actionSheet2.popoverPresentationController.sourceRect = cell.bounds; + [self presentViewController:actionSheet2 animated:YES completion:nil]; + }]]; + [actionSheet addAction:[UIAlertAction actionWithTitle:@"Email model files" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *action) { + NSString *modelFile = [[models objectAtIndex:indexPath.row] getFile]; NSString *modelPath = [modelFile stringByDeletingLastPathComponent]; NSArray *modelFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:modelPath error:NULL]; - for (NSString *obj in modelFiles){ - NSString *extension = [obj pathExtension]; - if([extension isEqualToString:@"msh"] || - [extension isEqualToString:@"pre"] || - [extension isEqualToString:@"res"] || - [extension isEqualToString:@"pos"]){ - NSString *file = [[modelPath stringByAppendingString:@"/"] stringByAppendingString:obj]; - NSLog(@"Removing file %@", file); - [[NSFileManager defaultManager] removeItemAtPath:file error:nil]; - } - } - } - break; - case 1: - { - NSString *file = [[models objectAtIndex:actionSheet.tag] getFile]; - NSString *path = [file stringByDeletingLastPathComponent]; - [[NSFileManager defaultManager] removeItemAtPath:path error:nil]; - [self refreshList]; - } - break; - case 0: - [self tableView:self.tableView - didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:actionSheet.tag inSection:0]]; - break; - } - } - else{ - if(buttonIndex != actionSheet.cancelButtonIndex){ - NSString *modelFile = [[models objectAtIndex:actionSheet.tag] getFile]; - NSString *modelPath = [modelFile stringByDeletingLastPathComponent]; - NSString *file = [actionSheet buttonTitleAtIndex:buttonIndex]; - currentFileToEdit = [[modelPath stringByAppendingString:@"/"] stringByAppendingString:file]; - [self performSegueWithIdentifier:@"showAboutSegue" sender:self]; - } + // TODO: would probably be better to email a zip archive? (this ignores subdirectories) + [self attachFilesToEmail:modelFiles filePath:modelPath]; + }]]; + if([[models objectAtIndex:indexPath.row] getUrl]){ + [actionSheet addAction:[UIAlertAction actionWithTitle:@"Visit model website" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *action) { + [[UIApplication sharedApplication] openURL:[[models objectAtIndex:indexPath.row] getUrl]]; + }]]; } + + actionSheet.popoverPresentationController.sourceView = cell; + actionSheet.popoverPresentationController.sourceRect = cell.bounds; + + [self presentViewController:actionSheet animated:YES completion:nil]; } - (void)attachFilesToEmail:(NSArray*)files filePath:(NSString*)path