diff --git a/ios/experimental/LibreOfficeLight/LibreOfficeLight/DocumentController.swift b/ios/experimental/LibreOfficeLight/LibreOfficeLight/DocumentController.swift index 9c6cd1b9fb82..1b61f6bb2f2b 100755 --- a/ios/experimental/LibreOfficeLight/LibreOfficeLight/DocumentController.swift +++ b/ios/experimental/LibreOfficeLight/LibreOfficeLight/DocumentController.swift @@ -9,8 +9,87 @@ import UIKit -class DocumentController: UIViewController +class DocumentController: UIViewController, DocumentActionsControlDelegate { + @IBAction func returned(segue: UIStoryboardSegue) + { + print("I returned") + } + + + + // Last stop before displaying popover + override func prepare(for segue: UIStoryboardSegue, sender: Any?) + { + if segue.identifier == "showActions" { + let vc = segue.destination as! DocumentActions + vc.delegate = self + + // JIX, TO BE CHANGED + vc.isDocActive = true + } + } + + + + func actionNew(_ name : String) + { + // JIX Close active documents if any + // Start new (with default name + + // Only interact with DocumentBrowser + + } + + + + func actionOpen() + { + // JIX Close active documents if any + // Present FileManager + performSegue(withIdentifier: "showFileManager", sender: self) + + // start DocumentBrowser with new document + } + + + + func actionDelete() + { + // JIX Close active documents if any + // Delete document + } + + + + func actionSave() + { + // call save in DocumentBrowser + + } + + + + func actionSaveAs(_ name : String) + { + // call saveas in DocumentBrowser + + } + + + + func actionPDF() + { + // call savePDF in documentBrowser + } + + + + func actionPrint() + { + // call print in DocumentBrowser + } + override func viewDidLoad() @@ -20,49 +99,105 @@ class DocumentController: UIViewController } - @IBAction func returned(segue: UIStoryboardSegue) { - print("I returned") - } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } +} + +// Protocol for action popover callback +protocol DocumentActionsControlDelegate +{ + func actionNew(_ name : String) + func actionOpen() + func actionDelete() + func actionSave() + func actionSaveAs(_ name : String) + func actionPDF() + func actionPrint() } class DocumentActions: UITableViewController { + // Pointer to callback class + var delegate : DocumentActionsControlDelegate? + var isDocActive : Bool = false - @IBAction func doOpen(_ sender: UIButton) { + // Calling class might enable/disable each button + @IBOutlet weak var buttonNew: UIButton! + @IBOutlet weak var buttonOpen: UIButton! + @IBOutlet weak var buttonDelete: UIButton! + @IBOutlet weak var buttonSave: UIButton! + @IBOutlet weak var buttonSaveAs: UIButton! + @IBOutlet weak var buttonPDF: UIButton! + @IBOutlet weak var buttonPrint: UIButton! + + + // Actions + @IBAction func doOpen(_ sender: UIButton) + { + delegate?.actionOpen() + dismiss(animated: false) } - @IBAction func doNew(_ sender: UIButton) { + + + @IBAction func doDelete(_ sender: UIButton) + { + delegate?.actionDelete() + dismiss(animated: false) } - @IBAction func doSave(_ sender: UIButton) { + + + @IBAction func doSave(_ sender: UIButton) + { + delegate?.actionSave() + dismiss(animated: false) } - @IBAction func doPDF(_ sender: UIButton) { + + + @IBAction func doPDF(_ sender: UIButton) + { + delegate?.actionPDF() + dismiss(animated: false) } + + + + @IBAction func doPrint(_ sender: UIButton) + { + delegate?.actionPrint() + dismiss(animated: false) + } + + + override func viewDidLoad() { super.viewDidLoad() - // Do any additional setup after loading the view. + buttonDelete.isEnabled = isDocActive + buttonSave.isEnabled = isDocActive + buttonSaveAs.isEnabled = isDocActive + buttonPDF.isEnabled = isDocActive + buttonPrint.isEnabled = isDocActive } - override func didReceiveMemoryWarning() + // Last stop before displaying popover + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - super.didReceiveMemoryWarning() - // Dispose of any resources that can be recreated. + let vc = segue.destination as! setNameAction + vc.delegateDoc = self.delegate + vc.protocolActionToPerform = (segue.identifier == "showNew") ? 2 : 3 } - - } diff --git a/ios/experimental/LibreOfficeLight/LibreOfficeLight/FileManagerController.swift b/ios/experimental/LibreOfficeLight/LibreOfficeLight/FileManagerController.swift index 9f6352071c10..03003fd699b2 100755 --- a/ios/experimental/LibreOfficeLight/LibreOfficeLight/FileManagerController.swift +++ b/ios/experimental/LibreOfficeLight/LibreOfficeLight/FileManagerController.swift @@ -1,477 +1,479 @@ // -//ThisfileispartoftheLibreOfficeproject. +// This file is part of the LibreOffice project. // -//ThisSourceCodeFormissubjecttothetermsoftheMozillaPublic -//License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis -//file,Youcanobtainoneathttp://mozilla.org/MPL/2.0/. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v.2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. // -importUIKit +import UIKit -privateclassFileStorage +private class FileStorage { -//housekeepingvariables -privateletfilemgr:FileManager=FileManager.default -privatevarstorageIsLocal:Bool=true + // house keeping variables + private let filemgr : FileManager = FileManager.default + private var storageIsLocal : Bool = true -//Startpathforthe2storagelocations -privateletbaseLocalDocPath:URL -privateletbaseCloudDocPath:URL? -privatevarcurrentDocPath:URL?{ -get{ -returnstorageIsLocal?baseLocalDocPath:baseCloudDocPath -} -} + // Start path for the 2 storage locations + private let baseLocalDocPath : URL + private let baseCloudDocPath : URL? + private var currentDocPath : URL? { + get { + return storageIsLocal ? baseLocalDocPath : baseCloudDocPath + } + } -//makeaccesstocurrentdirindependentofstorageselection -privatevarlocalDir:URL -privatevarcloudDir:URL? -privatevarcurrentDir:URL{ -get{ -returnstorageIsLocal?localDir:cloudDir! -} -set(newDir){ -ifstorageIsLocal{ -localDir=newDir -}else{ -cloudDir=newDir -} -} + // make access to current dir independent of storage selection + private var localDir : URL + private var cloudDir : URL? + private var currentDir : URL { + get { + return storageIsLocal ? localDir : cloudDir! + } + set(newDir) { + if storageIsLocal { + localDir = newDir + } else { + cloudDir = newDir + } + } + } + + + + // content of current directory + var currentFileList : [String] = [] + var currentDirList : [String] = [] + + + + // Support functions + func iCloudEnabled() -> Bool + { + return filemgr.ubiquityIdentityToken != nil + } + + + func isSubDirectory() -> Bool + { + return currentDir != currentDocPath + } + + + + func selectStorage(_ doSwitch : Bool) -> Bool + { + if doSwitch { + storageIsLocal = !storageIsLocal + buildFileList() + } + return storageIsLocal + } + + + + func enterDirectory(_ name: String) + { + // simple add directory + currentDir = currentDir.appendingPathComponent(name) + filemgr.changeCurrentDirectoryPath(name) + buildFileList() + } + + + func leaveDirectory() + { + // step up for active storage, and only if not in root + if isSubDirectory() { + currentDir = currentDir.deletingLastPathComponent() + buildFileList() + } + } + + + + func createDirectory(_ name: String) + { + let newDir = currentDir.appendingPathComponent(name) + try! filemgr.createDirectory(at: newDir, withIntermediateDirectories: true, attributes: nil) + currentDir = currentDir.appendingPathComponent(name) + buildFileList() + } + + + + func deleteFileDirectory(_ name: String) + { + let delDir = currentDir.appendingPathComponent(name) + try! filemgr.removeItem(at: delDir) + buildFileList() + } + + + + func getFileURL(_ name: String) -> URL + { + return currentDir.appendingPathComponent(name) + } + + + + func copyFile(_ name: String) + { + try! filemgr.copyItem(at: currentDir.appendingPathComponent(name), + to: (storageIsLocal ? cloudDir! : localDir).appendingPathComponent(name)) + } + + + + func moveFile(_ name: String) + { + try! filemgr.moveItem(at: currentDir.appendingPathComponent(name), + to: (storageIsLocal ? localDir : cloudDir!).appendingPathComponent(name)) + buildFileList() + } + + + + func renameFile(_ oldName: String, _ newName: String) + { + try! filemgr.moveItem(at: currentDir.appendingPathComponent(oldName), + to: currentDir.appendingPathComponent(newName)) + buildFileList() + } + + + + private func buildFileList() + { + currentDirList = [] + currentFileList = [] + let rawFileList = try! filemgr.contentsOfDirectory(at: currentDir, + includingPropertiesForKeys: [URLResourceKey.isDirectoryKey]) + for rawFile in rawFileList { + var isDir: ObjCBool = false + filemgr.fileExists(atPath: rawFile.path, isDirectory: &isDir) + if isDir.boolValue { + currentDirList.append(rawFile.lastPathComponent) + } else { + currentFileList.append(rawFile.lastPathComponent) + } + } + } + + + + init() + { + baseLocalDocPath = filemgr.urls(for: .documentDirectory, in: .userDomainMask)[0] + localDir = baseLocalDocPath + + let cloudUrl = filemgr.url(forUbiquityContainerIdentifier: nil) + baseCloudDocPath = (cloudUrl == nil) ? nil : cloudUrl?.appendingPathComponent("Documents") + cloudDir = baseCloudDocPath + buildFileList() + } } -//contentofcurrentdirectory -varcurrentFileList:[String]=[] -varcurrentDirList:[String]=[] - - - -//Supportfunctions -funciCloudEnabled()->Bool -{ -returnfilemgr.ubiquityIdentityToken!=nil -} - - -funcisSubDirectory()->Bool -{ -returncurrentDir!=currentDocPath -} - - - -funcselectStorage(_doSwitch:Bool)->Bool -{ -ifdoSwitch{ -storageIsLocal=!storageIsLocal -buildFileList() -} -returnstorageIsLocal -} - - - -funcenterDirectory(_name:String) -{ -//simpleadddirectory -currentDir=currentDir.appendingPathComponent(name) -filemgr.changeCurrentDirectoryPath(name) -buildFileList() -} - - -funcleaveDirectory() -{ -//stepupforactivestorage,andonlyifnotinroot -ifisSubDirectory(){ -currentDir=currentDir.deletingLastPathComponent() -buildFileList() -} -} - - - -funccreateDirectory(_name:String) -{ -letnewDir=currentDir.appendingPathComponent(name) -try!filemgr.createDirectory(at:newDir,withIntermediateDirectories:true,attributes:nil) -currentDir=currentDir.appendingPathComponent(name) -buildFileList() -} - - - -funcdeleteFileDirectory(_name:String) -{ -letdelDir=currentDir.appendingPathComponent(name) -try!filemgr.removeItem(at:delDir) -buildFileList() -} - - - -funcgetFileURL(_name:String)->URL -{ -returncurrentDir.appendingPathComponent(name) -} - - - -funccopyFile(_name:String) -{ -try!filemgr.copyItem(at:currentDir.appendingPathComponent(name), -to:(storageIsLocal?cloudDir!:localDir).appendingPathComponent(name)) -} - - - -funcmoveFile(_name:String) -{ -try!filemgr.moveItem(at:currentDir.appendingPathComponent(name), -to:(storageIsLocal?localDir:cloudDir!).appendingPathComponent(name)) -buildFileList() -} - - - -funcrenameFile(_oldName:String,_newName:String) -{ -try!filemgr.moveItem(at:currentDir.appendingPathComponent(oldName), -to:currentDir.appendingPathComponent(newName)) -buildFileList() -} - - - -privatefuncbuildFileList() -{ -currentDirList=[] -currentFileList=[] -letrawFileList=try!filemgr.contentsOfDirectory(at:currentDir, -includingPropertiesForKeys:[URLResourceKey.isDirectoryKey]) -forrawFileinrawFileList{ -varisDir:ObjCBool=false -filemgr.fileExists(atPath:rawFile.path,isDirectory:&isDir) -ifisDir.boolValue{ -currentDirList.append(rawFile.lastPathComponent) -}else{ -currentFileList.append(rawFile.lastPathComponent) -} -} -} - - - -init() -{ -baseLocalDocPath=filemgr.urls(for:.documentDirectory,in:.userDomainMask)[0] -localDir=baseLocalDocPath - -letcloudUrl=filemgr.url(forUbiquityContainerIdentifier:nil) -baseCloudDocPath=(cloudUrl==nil)?nil:cloudUrl?.appendingPathComponent("Documents") -cloudDir=baseCloudDocPath -buildFileList() -} -} - - - -classFileManagerController:UITableViewController,actionsControlDelegate +class FileManagerController : UITableViewController, FileActionsControlDelegate { -//Housekeepingvariables -privatevarfileData=FileStorage() -privatevarselectedRow:IndexPath? + // Housekeeping variables + private var fileData = FileStorage() + private var selectedRow : IndexPath? -//selectStorageisonlyenabledwheniCloudisactive -@IBOutletweakvarbuttonSelectStorage:UIBarButtonItem! -overridefuncviewDidLoad() + // selectStorage is only enabled when iCloud is active + @IBOutlet weak var buttonSelectStorage: UIBarButtonItem! + override func viewDidLoad() + { + super.viewDidLoad() + buttonSelectStorage.isEnabled = fileData.iCloudEnabled() + } + + + + // Toogle between local and cloud storage + @IBAction func doSelectStorage(_ sender: UIBarButtonItem) + { + sender.image = fileData.selectStorage(true) ? #imageLiteral(resourceName: "iCloudDrive") : #imageLiteral(resourceName: "iPhone") + reloadData() + self.presentedViewController?.dismiss(animated: true, completion: nil) + } + + + + // Last stop before displaying popover + override func prepare(for segue: UIStoryboardSegue, sender: Any?) + { + if segue.identifier == "showActions" { + let vc = segue.destination as! FileManagerActions + vc.delegate = self + vc.inFileSelect = (selectedRow != nil) + vc.inSubDirectory = fileData.isSubDirectory() + vc.useCloud = fileData.iCloudEnabled() + } + } + + + + func actionOpen() + { + if selectedRow != nil { + let currentCell = tableView.cellForRow(at: selectedRow!) as! FileManagerCell + if currentCell.isDirectory { + fileData.enterDirectory(currentCell.fileName) + reloadData() + } else { + // JIX delegate to Document + } + } + } + + + + func actionDelete() + { + if selectedRow != nil { + let currentCell = self.tableView.cellForRow(at: selectedRow!) as! FileManagerCell + fileData.deleteFileDirectory(currentCell.fileName) + reloadData() + } + } + + + + func actionRename(_ name : String) + { + if selectedRow != nil { + let currentCell = tableView.cellForRow(at: selectedRow!) as! FileManagerCell + fileData.renameFile(currentCell.fileName, name) + reloadData() + } + } + + + + func actionUploadDownload() + { + if selectedRow != nil { + let currentCell = self.tableView.cellForRow(at: selectedRow!) as! FileManagerCell + fileData.copyFile(currentCell.fileName) + reloadData() + } + } + + + + func actionLevelUp() + { + fileData.leaveDirectory() + reloadData() + } + + + + func actionCreateDirectory(_ name : String) + { + fileData.createDirectory(name) + reloadData() + } + + + + // Table handling functions + override func numberOfSections(in tableView: UITableView) -> Int + { + return 1 + } + + + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int + { + return fileData.currentDirList.count + fileData.currentFileList.count + } + + + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell + { + let cell = self.tableView.dequeueReusableCell(withIdentifier: "fileEntry", for: indexPath) as! FileManagerCell + let row = indexPath.row + + if row < fileData.currentDirList.count { + cell.fileName = fileData.currentDirList[row] + cell.fileLabel.text = cell.fileName + "/" + cell.isDirectory = true + } else { + let inx = row - fileData.currentDirList.count + cell.fileName = fileData.currentFileList[inx] + cell.fileLabel.text = cell.fileName + cell.isDirectory = false + } + return cell + } + + + + // Select a row (file) and show actions + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) + { + selectedRow = indexPath + performSegue(withIdentifier: "showActions", sender: self) + } + + + + // Support function + func reloadData() + { + selectedRow = nil + tableView.reloadData() + } + +} + + + +// Space holder for extra information needed to do the right thing for each action +class FileManagerCell: UITableViewCell { + + @IBOutlet weak var fileLabel: UILabel! + var isDirectory : Bool = false + var fileName : String = "" +} + + + +// Protocol for action popover callback +protocol FileActionsControlDelegate { -super.viewDidLoad() -buttonSelectStorage.isEnabled=fileData.iCloudEnabled() + func actionOpen() + func actionDelete() + func actionRename(_ name : String) + func actionUploadDownload() + func actionLevelUp() + func actionCreateDirectory(_ name : String) } -//Tooglebetweenlocalandcloudstorage -@IBActionfuncdoSelectStorage(_sender:UIBarButtonItem) -{ -sender.image=fileData.selectStorage(true)?#imageLiteral(resourceName:"iCloudDrive"):#imageLiteral(resourceName:"iPhone") -reloadData() -self.presentedViewController?.dismiss(animated:true,completion:nil) -} - - - -//Laststopbeforedisplayingpopover -overridefuncprepare(forsegue:UIStoryboardSegue,sender:Any?) -{ -ifsegue.identifier=="showActions"{ -letvc=segue.destinationas!FileManagerActions -vc.delegate=self -vc.inFileSelect=(selectedRow!=nil) -vc.inSubDirectory=fileData.isSubDirectory() -vc.useCloud=fileData.iCloudEnabled() -} -} - - - -funcactionOpen() -{ -ifselectedRow!=nil{ -letcurrentCell=tableView.cellForRow(at:selectedRow!)as!FileManagerCell -ifcurrentCell.isDirectory{ -fileData.enterDirectory(currentCell.fileName) -reloadData() -}else{ -//JIXdelegatetoDocument -} -} -} - - - -funcactionDelete() -{ -ifselectedRow!=nil{ -letcurrentCell=self.tableView.cellForRow(at:selectedRow!)as!FileManagerCell -fileData.deleteFileDirectory(currentCell.fileName) -reloadData() -} -} - - - -funcactionRename(_name:String) -{ -ifselectedRow!=nil{ -letcurrentCell=tableView.cellForRow(at:selectedRow!)as!FileManagerCell -fileData.renameFile(currentCell.fileName,name) -reloadData() -} -} - - - -funcactionUploadDownload() -{ -ifselectedRow!=nil{ -letcurrentCell=self.tableView.cellForRow(at:selectedRow!)as!FileManagerCell -fileData.copyFile(currentCell.fileName) -reloadData() -} -} - - - -funcactionLevelUp() -{ -fileData.leaveDirectory() -reloadData() -} - - - -funcactionCreateDirectory(_name:String) -{ -fileData.createDirectory(name) -reloadData() -} - - - -//Tablehandlingfunctions -overridefuncnumberOfSections(intableView:UITableView)->Int -{ -return1 -} - - - -overridefunctableView(_tableView:UITableView,numberOfRowsInSectionsection:Int)->Int -{ -returnfileData.currentDirList.count+fileData.currentFileList.count -} - - - -overridefunctableView(_tableView:UITableView,cellForRowAtindexPath:IndexPath)->UITableViewCell -{ -letcell=self.tableView.dequeueReusableCell(withIdentifier:"fileEntry",for:indexPath)as!FileManagerCell -letrow=indexPath.row - -ifrow - + + - + + + - - - - - - - - - - - - - - + + + @@ -65,7 +57,7 @@ - +