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