PDFList.xaml.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. using Comal.Classes;
  2. using InABox.Clients;
  3. using InABox.Core;
  4. using Syncfusion.SfPdfViewer.XForms;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Threading.Tasks;
  10. using Xamarin.Essentials;
  11. using Xamarin.Forms;
  12. using Xamarin.Forms.Xaml;
  13. using XF.Material.Forms.UI.Dialogs;
  14. using Document = InABox.Core.Document;
  15. namespace comal.timesheets
  16. {
  17. [XamlCompilation(XamlCompilationOptions.Compile)]
  18. public partial class PDFList : ContentPage
  19. {
  20. List<DocShell> pDFShells = new List<DocShell>();
  21. bool bAllowPrintShare;
  22. bool bAllowDelete;
  23. bool bAllowView = true;
  24. Entity Entity;
  25. DeviceIdiom DeviceIdiom;
  26. //allowing of print/share is disabled by default
  27. //allowing of upload is disabled by default
  28. public PDFList(Dictionary<string, Guid> fileNameIDs, bool allowprintshare = false)
  29. {
  30. InitializeComponent();
  31. NavigationPage.SetHasBackButton(this, false);
  32. bAllowPrintShare = allowprintshare;
  33. LoadScreen(fileNameIDs);
  34. }
  35. //2nd constructor requires an entity for uploading of files or deleting (if allowed)
  36. public PDFList(Dictionary<string, Guid> fileNameIDs, Entity entity, bool allowprintshare = false, bool allowUpload = false, bool allowDelete = false, bool allowView = true)
  37. {
  38. InitializeComponent();
  39. NavigationPage.SetHasBackButton(this, false);
  40. bAllowPrintShare = allowprintshare;
  41. Entity = entity;
  42. if (allowUpload)
  43. uploadBtn.IsVisible = true;
  44. bAllowDelete = allowDelete;
  45. bAllowView = allowView;
  46. LoadScreen(fileNameIDs);
  47. }
  48. //standard load
  49. private void LoadScreen(Dictionary<string, Guid> fileNameIDs)
  50. {
  51. foreach (KeyValuePair<string, Guid> pair in fileNameIDs)
  52. {
  53. DocShell shell = new DocShell();
  54. shell.FileName = pair.Key;
  55. shell.DocID = pair.Value;
  56. shell = AssignIcon(shell);
  57. pDFShells.Add(shell);
  58. }
  59. pdfListView.ItemsSource = pDFShells;
  60. }
  61. private DocShell AssignThumbnail(DocShell shell)
  62. {
  63. shell.ImageRow = 0;
  64. shell.ImageRowSpan = 2;
  65. shell.ImageSource = ImageSource.FromStream(() => new MemoryStream(shell.ThumbNail));
  66. shell.TypeColumn = 1;
  67. shell.TypeColumnSpan = 1;
  68. if (DeviceIdiom == DeviceIdiom.Tablet)
  69. {
  70. shell.ImageHeightRequest = 300;
  71. shell.ImageWidthRequest = 400;
  72. shell.ColumnWidth = 400;
  73. }
  74. else
  75. {
  76. shell.ImageHeightRequest = 150;
  77. shell.ImageWidthRequest = 200;
  78. shell.ColumnWidth = 200;
  79. shell.ExpandVisible = true;
  80. }
  81. return shell;
  82. }
  83. private DocShell AssignIcon(DocShell shell)
  84. {
  85. if (shell.FileName.ToLower().EndsWith("pdf"))
  86. shell.ImageSource = "pdficon.png";
  87. else if (shell.FileName.ToLower().EndsWith("docx") || shell.FileName.ToLower().EndsWith("doc"))
  88. shell.ImageSource = "worddoc.png";
  89. else if (shell.FileName.ToLower().EndsWith("png") || shell.FileName.ToLower().EndsWith("jpg"))
  90. shell.ImageSource = "productimage.png";
  91. return shell;
  92. }
  93. private void ExpandImage_Tapped(object sender, EventArgs e)
  94. {
  95. var item = ((TappedEventArgs)e).Parameter as DocShell;
  96. if (item == null)
  97. return;
  98. }
  99. void ExitBtn_Clicked(object sender, EventArgs e)
  100. {
  101. Navigation.PopAsync();
  102. }
  103. private async void Upload_Clicked(object sender, EventArgs e)
  104. {
  105. var result = await FilePicker.PickAsync(new PickOptions { FileTypes = FilePickerFileType.Pdf });
  106. if (result != null)
  107. {
  108. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Saving"))
  109. {
  110. string fileName = $"File Name: {result.FileName}";
  111. var stream = await result.OpenReadAsync();
  112. var memoryStream = new MemoryStream();
  113. stream.CopyTo(memoryStream);
  114. var data = memoryStream.ToArray();
  115. var doc = new Document { FileName = fileName, Data = data };
  116. new Client<Document>().Save(doc, "Uploaded from mobile device");
  117. pDFShells.Add(new DocShell { FileName = fileName, DocID = doc.ID });
  118. pdfListView.ItemsSource = null;
  119. pdfListView.ItemsSource = pDFShells;
  120. SaveEntityDoc(doc.ID);
  121. }
  122. }
  123. }
  124. private void SaveEntityDoc(Guid docID)
  125. {
  126. if (Entity is EmployeeQualification)
  127. {
  128. EmployeeQualificationDocument empDoc = new EmployeeQualificationDocument();
  129. empDoc.DocumentLink.ID = docID;
  130. empDoc.EntityLink.ID = Entity.ID;
  131. new Client<EmployeeQualificationDocument>().Save(empDoc, "Upload from mobile device");
  132. }
  133. if (Entity is Notification)
  134. {
  135. NotificationDocument notificationDoc = new NotificationDocument();
  136. notificationDoc.DocumentLink.ID = docID;
  137. notificationDoc.EntityLink.ID = Entity.ID;
  138. new Client<NotificationDocument>().Save(notificationDoc, "Upload from mobile device");
  139. }
  140. }
  141. private async void List_Tapped(object sender, EventArgs e)
  142. {
  143. DocShell shell = pdfListView.SelectedItem as DocShell;
  144. if (!bAllowView)
  145. {
  146. DisplayAlert("Alert", "Opening is not allowed from this module", "OK");
  147. return;
  148. }
  149. if (bAllowDelete)
  150. {
  151. string chosenOption = await DisplayActionSheet("Choose an option", "Cancel", null, "View", "Delete File");
  152. switch (chosenOption)
  153. {
  154. case "Cancel":
  155. return;
  156. default:
  157. return;
  158. case "View":
  159. OpenDocViewer(shell);
  160. break;
  161. case "Delete File":
  162. ConfirmDelete(shell);
  163. break;
  164. }
  165. }
  166. else
  167. {
  168. OpenDocViewer(shell);
  169. }
  170. }
  171. private async void ConfirmDelete(DocShell shell)
  172. {
  173. string chosenOption = await DisplayActionSheet("Confirm Delete?", "Cancel", null, "Yes", "No");
  174. switch (chosenOption)
  175. {
  176. case "Cancel":
  177. return;
  178. default:
  179. return;
  180. case "No":
  181. return;
  182. case "Yes":
  183. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Working"))
  184. {
  185. pDFShells.Remove(shell);
  186. pdfListView.ItemsSource = null;
  187. pdfListView.ItemsSource = pDFShells;
  188. Document document = new Document { ID = shell.DocID };
  189. DeleteEntityDocument(shell.DocID);
  190. new Client<Document>().Delete(document, "Deleted from mobile device");
  191. }
  192. break;
  193. }
  194. }
  195. void DeleteEntityDocument(Guid id)
  196. {
  197. if (Entity is EmployeeQualification)
  198. {
  199. CoreTable table = new Client<EmployeeQualificationDocument>().Query(new Filter<EmployeeQualificationDocument>(x => x.DocumentLink.ID).IsEqualTo(id),
  200. new Columns<EmployeeQualificationDocument>(x => x.ID));
  201. EmployeeQualificationDocument empDoc = new EmployeeQualificationDocument();
  202. empDoc.ID = Guid.Parse(table.Rows.First().Values[0].ToString());
  203. new Client<EmployeeQualificationDocument>().Delete(empDoc, "Deleted from mobile device");
  204. }
  205. }
  206. void OpenDocViewer(DocShell shell)
  207. {
  208. shell.FileName = shell.FileName.ToLower();
  209. if (shell.FileName.EndsWith("pdf"))
  210. {
  211. if (Device.RuntimePlatform.Equals(Device.Android) && Security.IsAllowed<CanOpenMobileNativePDFViewer>())
  212. OpenNativeViewer(shell);
  213. else
  214. {
  215. PDFViewer viewer = new PDFViewer(shell.DocID, bAllowPrintShare);
  216. Navigation.PushAsync(viewer);
  217. }
  218. }
  219. else if (shell.FileName.EndsWith("docx") || shell.FileName.EndsWith("doc"))
  220. {
  221. CoreTable table = new Client<Document>().Query(new Filter<Document>(x => x.ID).IsEqualTo(shell.DocID),
  222. new Columns<Document>(x => x.Data));
  223. Document doc = table.Rows.First().ToObject<Document>();
  224. MemoryStream memoryStream = new MemoryStream(doc.Data);
  225. DisplayAlert("Error", "Word documents not available at this time", "OK");
  226. }
  227. else if (shell.FileName.EndsWith("png") || shell.FileName.EndsWith("jpg") || shell.FileName.EndsWith("jpeg"))
  228. {
  229. CoreTable table = new Client<Document>().Query(new Filter<Document>(x => x.ID).IsEqualTo(shell.DocID),
  230. new Columns<Document>(x => x.Data));
  231. Document doc = table.Rows.First().ToObject<Document>();
  232. ImageSource src = ImageSource.FromStream(() => new MemoryStream(doc.Data));
  233. ImageViewer viewer = new ImageViewer(src);
  234. Navigation.PushAsync(viewer);
  235. }
  236. }
  237. private async void OpenNativeViewer(DocShell shell)
  238. {
  239. CoreTable table = new Client<Document>().Query(new Filter<Document>(x => x.ID).IsEqualTo(shell.DocID));
  240. Document doc = table.Rows.First().ToObject<Document>();
  241. var filePath = Path.Combine(FileSystem.AppDataDirectory, doc.FileName);
  242. File.WriteAllBytes(filePath, doc.Data);
  243. await Launcher.OpenAsync(new OpenFileRequest
  244. {
  245. File = new ReadOnlyFile(filePath)
  246. });
  247. }
  248. void SearchEnt_Changed(object sender, EventArgs e)
  249. {
  250. pdfListView.ItemsSource = pDFShells.Where(x =>
  251. x.FileName.Contains(searchEnt.Text) || x.FileName.Contains(searchEnt.Text.ToLower())
  252. || x.FileName.Contains(searchEnt.Text.ToUpper()) || x.FileName.Contains(UpperCaseFirst(searchEnt.Text))
  253. );
  254. }
  255. static String UpperCaseFirst(string s)
  256. {
  257. char[] a = s.ToCharArray();
  258. a[0] = char.ToUpper(a[0]);
  259. return new string(a);
  260. }
  261. }
  262. public class DocShell
  263. {
  264. public string FileName { get; set; }
  265. public Guid DocID { get; set; }
  266. public ImageSource ImageSource { get; set; }
  267. public double FirstRowHeight { get; set; }
  268. public string Type { get; set; }
  269. public double ImageHeightRequest { get; set; }
  270. public double ImageWidthRequest { get; set; }
  271. public double ColumnWidth { get; set; }
  272. public double ImageRow { get; set; }
  273. public double ImageRowSpan { get; set; }
  274. public byte[] ThumbNail { get; set; }
  275. public double TypeColumn { get; set; }
  276. public double TypeColumnSpan { get; set; }
  277. public string FileDetails { get; set; }
  278. public bool ExpandVisible { get; set; }
  279. public DocShell()
  280. {
  281. FileName = "";
  282. DocID = Guid.Empty;
  283. ImageSource = "";
  284. FirstRowHeight = 0;
  285. Type = "";
  286. ImageHeightRequest = 30;
  287. ImageWidthRequest = 30;
  288. ColumnWidth = 40;
  289. ImageRow = 1;
  290. ImageRowSpan = 1;
  291. TypeColumn = 0;
  292. TypeColumnSpan = 2;
  293. FileDetails = "";
  294. ExpandVisible = false;
  295. }
  296. }
  297. }