/clients/cs/samples/PhotoBrowser/PhotoBrowser.cs

http://google-gdata.googlecode.com/ · C# · 571 lines · 445 code · 64 blank · 62 comment · 58 complexity · 97578212eb3318e77cb48a9cb37a5107 MD5 · raw file

  1. using System;
  2. using System.Drawing;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.ComponentModel;
  6. using System.Windows.Forms;
  7. using Google.GData.Photos;
  8. using Google.GData.Client;
  9. using Google.GData.Extensions.MediaRss;
  10. using Google.GData.Extensions;
  11. using Google.Picasa;
  12. using System.IO;
  13. namespace PhotoBrowser
  14. {
  15. /// <summary>
  16. /// Summary description for PhotoBrowser.
  17. /// </summary>
  18. public class PictureBrowser : System.Windows.Forms.Form
  19. {
  20. private PicasaService picasaService;
  21. private PicasaFeed photoFeed;
  22. private System.Windows.Forms.PictureBox PhotoPreview;
  23. private System.Windows.Forms.ListView PhotoList;
  24. private System.Windows.Forms.PropertyGrid PhotoInspector;
  25. private System.Windows.Forms.Label label1;
  26. private System.Windows.Forms.Label label2;
  27. private System.Windows.Forms.Button DownloadPhoto;
  28. private System.Windows.Forms.Button UploadPhoto;
  29. private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog;
  30. private System.Windows.Forms.OpenFileDialog openFileDialog;
  31. private List<UserState> states = new List<UserState>();
  32. private delegate void SaveAnotherPictureDelegate(UserState us);
  33. private ProgressBar progressBar;
  34. private Label FileInfo;
  35. private Button CancelAsync;
  36. /// <summary>
  37. /// Required designer variable.
  38. /// </summary>
  39. private System.ComponentModel.Container components = null;
  40. public PictureBrowser(PicasaService service, bool doBackup)
  41. {
  42. //
  43. // Required for Windows Form Designer support
  44. //
  45. InitializeComponent();
  46. this.picasaService = service;
  47. this.picasaService.AsyncOperationCompleted += new AsyncOperationCompletedEventHandler(this.OnDone);
  48. this.picasaService.AsyncOperationProgress += new AsyncOperationProgressEventHandler(this.OnProgress);
  49. if (doBackup == true)
  50. {
  51. this.DownloadPhoto.Enabled = false;
  52. this.DownloadPhoto.Visible = false;
  53. this.UploadPhoto.Enabled = false;
  54. this.UploadPhoto.Visible = false;
  55. }
  56. }
  57. public void StartQuery(string uri, string albumTitle)
  58. {
  59. UserState us = new UserState();
  60. this.states.Add(us);
  61. us.opType = UserState.OperationType.query;
  62. us.filename = albumTitle;
  63. this.picasaService.QueryFeedAync(new Uri(uri), DateTime.MinValue, us);
  64. }
  65. /// <summary>
  66. /// Clean up any resources being used.
  67. /// </summary>
  68. protected override void Dispose( bool disposing )
  69. {
  70. if( disposing )
  71. {
  72. if(components != null)
  73. {
  74. components.Dispose();
  75. }
  76. }
  77. base.Dispose( disposing );
  78. }
  79. #region Windows Form Designer generated code
  80. /// <summary>
  81. /// Required method for Designer support - do not modify
  82. /// the contents of this method with the code editor.
  83. /// </summary>
  84. private void InitializeComponent()
  85. {
  86. this.PhotoPreview = new System.Windows.Forms.PictureBox();
  87. this.PhotoList = new System.Windows.Forms.ListView();
  88. this.PhotoInspector = new System.Windows.Forms.PropertyGrid();
  89. this.label1 = new System.Windows.Forms.Label();
  90. this.label2 = new System.Windows.Forms.Label();
  91. this.DownloadPhoto = new System.Windows.Forms.Button();
  92. this.UploadPhoto = new System.Windows.Forms.Button();
  93. this.folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog();
  94. this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
  95. this.progressBar = new System.Windows.Forms.ProgressBar();
  96. this.FileInfo = new System.Windows.Forms.Label();
  97. this.CancelAsync = new System.Windows.Forms.Button();
  98. ((System.ComponentModel.ISupportInitialize)(this.PhotoPreview)).BeginInit();
  99. this.SuspendLayout();
  100. //
  101. // PhotoPreview
  102. //
  103. this.PhotoPreview.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
  104. this.PhotoPreview.Location = new System.Drawing.Point(240, 64);
  105. this.PhotoPreview.Name = "PhotoPreview";
  106. this.PhotoPreview.Size = new System.Drawing.Size(280, 216);
  107. this.PhotoPreview.TabIndex = 1;
  108. this.PhotoPreview.TabStop = false;
  109. //
  110. // PhotoList
  111. //
  112. this.PhotoList.Alignment = System.Windows.Forms.ListViewAlignment.Default;
  113. this.PhotoList.FullRowSelect = true;
  114. this.PhotoList.GridLines = true;
  115. this.PhotoList.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
  116. this.PhotoList.LabelWrap = false;
  117. this.PhotoList.Location = new System.Drawing.Point(24, 64);
  118. this.PhotoList.MultiSelect = false;
  119. this.PhotoList.Name = "PhotoList";
  120. this.PhotoList.ShowGroups = false;
  121. this.PhotoList.Size = new System.Drawing.Size(210, 216);
  122. this.PhotoList.Sorting = System.Windows.Forms.SortOrder.Ascending;
  123. this.PhotoList.TabIndex = 0;
  124. this.PhotoList.UseCompatibleStateImageBehavior = false;
  125. this.PhotoList.View = System.Windows.Forms.View.List;
  126. this.PhotoList.SelectedIndexChanged += new System.EventHandler(this.PhotoList_SelectedIndexChanged);
  127. //
  128. // PhotoInspector
  129. //
  130. this.PhotoInspector.LineColor = System.Drawing.SystemColors.ScrollBar;
  131. this.PhotoInspector.Location = new System.Drawing.Point(24, 296);
  132. this.PhotoInspector.Name = "PhotoInspector";
  133. this.PhotoInspector.Size = new System.Drawing.Size(496, 192);
  134. this.PhotoInspector.TabIndex = 2;
  135. //
  136. // label1
  137. //
  138. this.label1.Location = new System.Drawing.Point(24, 16);
  139. this.label1.Name = "label1";
  140. this.label1.Size = new System.Drawing.Size(176, 24);
  141. this.label1.TabIndex = 3;
  142. this.label1.Text = "List of photos:";
  143. //
  144. // label2
  145. //
  146. this.label2.Location = new System.Drawing.Point(240, 16);
  147. this.label2.Name = "label2";
  148. this.label2.Size = new System.Drawing.Size(120, 32);
  149. this.label2.TabIndex = 4;
  150. this.label2.Text = "Preview:";
  151. //
  152. // DownloadPhoto
  153. //
  154. this.DownloadPhoto.Enabled = false;
  155. this.DownloadPhoto.Location = new System.Drawing.Point(27, 575);
  156. this.DownloadPhoto.Name = "DownloadPhoto";
  157. this.DownloadPhoto.Size = new System.Drawing.Size(88, 40);
  158. this.DownloadPhoto.TabIndex = 5;
  159. this.DownloadPhoto.Text = "&Export Photo";
  160. this.DownloadPhoto.Click += new System.EventHandler(this.DownloadPhoto_Click);
  161. //
  162. // UploadPhoto
  163. //
  164. this.UploadPhoto.Enabled = false;
  165. this.UploadPhoto.Location = new System.Drawing.Point(131, 575);
  166. this.UploadPhoto.Name = "UploadPhoto";
  167. this.UploadPhoto.Size = new System.Drawing.Size(88, 40);
  168. this.UploadPhoto.TabIndex = 6;
  169. this.UploadPhoto.Text = "&Upload Photos";
  170. this.UploadPhoto.Click += new System.EventHandler(this.UploadPhoto_Click);
  171. //
  172. // folderBrowserDialog
  173. //
  174. this.folderBrowserDialog.RootFolder = System.Environment.SpecialFolder.MyPictures;
  175. //
  176. // openFileDialog
  177. //
  178. this.openFileDialog.Filter = "JPeg Files|*.jpg";
  179. this.openFileDialog.Multiselect = true;
  180. //
  181. // progressBar
  182. //
  183. this.progressBar.Location = new System.Drawing.Point(24, 551);
  184. this.progressBar.Name = "progressBar";
  185. this.progressBar.Size = new System.Drawing.Size(496, 18);
  186. this.progressBar.TabIndex = 7;
  187. //
  188. // FileInfo
  189. //
  190. this.FileInfo.Location = new System.Drawing.Point(24, 491);
  191. this.FileInfo.Name = "FileInfo";
  192. this.FileInfo.Size = new System.Drawing.Size(496, 57);
  193. this.FileInfo.TabIndex = 8;
  194. //
  195. // CancelAsync
  196. //
  197. this.CancelAsync.Enabled = false;
  198. this.CancelAsync.Location = new System.Drawing.Point(421, 575);
  199. this.CancelAsync.Name = "CancelAsync";
  200. this.CancelAsync.Size = new System.Drawing.Size(99, 40);
  201. this.CancelAsync.TabIndex = 9;
  202. this.CancelAsync.Text = "&Cancel";
  203. this.CancelAsync.UseVisualStyleBackColor = true;
  204. this.CancelAsync.Visible = false;
  205. this.CancelAsync.Click += new System.EventHandler(this.CancelAsync_Click);
  206. //
  207. // PictureBrowser
  208. //
  209. this.AutoScaleBaseSize = new System.Drawing.Size(6, 15);
  210. this.ClientSize = new System.Drawing.Size(534, 627);
  211. this.Controls.Add(this.CancelAsync);
  212. this.Controls.Add(this.FileInfo);
  213. this.Controls.Add(this.progressBar);
  214. this.Controls.Add(this.UploadPhoto);
  215. this.Controls.Add(this.DownloadPhoto);
  216. this.Controls.Add(this.label2);
  217. this.Controls.Add(this.label1);
  218. this.Controls.Add(this.PhotoInspector);
  219. this.Controls.Add(this.PhotoList);
  220. this.Controls.Add(this.PhotoPreview);
  221. this.Name = "PictureBrowser";
  222. this.Text = "Waiting for data to load";
  223. this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.PictureBrowser_FormClosing);
  224. ((System.ComponentModel.ISupportInitialize)(this.PhotoPreview)).EndInit();
  225. this.ResumeLayout(false);
  226. }
  227. #endregion
  228. private void InitializeList(string title)
  229. {
  230. this.Text = title;
  231. if (this.photoFeed != null && this.photoFeed.Entries.Count > 0)
  232. {
  233. foreach (PicasaEntry entry in this.photoFeed.Entries)
  234. {
  235. ListViewItem item = new ListViewItem(entry.Title.Text);
  236. item.Tag = entry;
  237. this.PhotoList.Items.Add(item);
  238. }
  239. this.UploadPhoto.Enabled = true;
  240. }
  241. }
  242. private void PhotoList_SelectedIndexChanged(object sender, System.EventArgs e)
  243. {
  244. if (this.PhotoList.SelectedItems.Count == 1)
  245. {
  246. foreach (ListViewItem item in this.PhotoList.SelectedItems)
  247. {
  248. PicasaEntry entry = item.Tag as PicasaEntry;
  249. setSelection(entry);
  250. }
  251. }
  252. else
  253. {
  254. setSelection(null);
  255. }
  256. }
  257. private void setSelection(PicasaEntry entry)
  258. {
  259. if (entry != null)
  260. {
  261. this.Cursor = Cursors.WaitCursor;
  262. try
  263. {
  264. Stream stream = this.picasaService.Query(new Uri(findLargestThumbnail(entry.Media.Thumbnails)));
  265. this.PhotoPreview.Image = new Bitmap(stream);
  266. }
  267. catch
  268. {
  269. Icon error = new Icon(SystemIcons.Exclamation, 40, 40);
  270. this.PhotoPreview.Image = error.ToBitmap();
  271. }
  272. Photo photo = new Photo();
  273. photo.AtomEntry = entry;
  274. this.PhotoInspector.SelectedObject = photo;
  275. this.Cursor = Cursors.Default;
  276. this.DownloadPhoto.Enabled = true;
  277. }
  278. else
  279. {
  280. this.PhotoPreview.Image = null;
  281. this.PhotoInspector.SelectedObject = null;
  282. this.DownloadPhoto.Enabled = false;
  283. }
  284. }
  285. private string findLargestThumbnail(ExtensionCollection<MediaThumbnail> collection)
  286. {
  287. MediaThumbnail largest = null;
  288. int width = 0;
  289. foreach (MediaThumbnail thumb in collection)
  290. {
  291. int iWidth = int.Parse(thumb.Attributes["width"] as string);
  292. if (iWidth > width)
  293. {
  294. largest = thumb;
  295. }
  296. }
  297. return largest.Attributes["url"] as string;
  298. }
  299. private void DownloadPhoto_Click(object sender, System.EventArgs e)
  300. {
  301. // Show the FolderBrowserDialog.
  302. DialogResult result = folderBrowserDialog.ShowDialog();
  303. if( result == DialogResult.OK )
  304. {
  305. string folderName = folderBrowserDialog.SelectedPath;
  306. int i=1;
  307. foreach (ListViewItem item in this.PhotoList.SelectedItems)
  308. {
  309. string filename = folderName + "\\image" + i.ToString() + ".jpg";
  310. i++;
  311. PicasaEntry entry = item.Tag as PicasaEntry;
  312. this.DoSaveImageFile(entry, filename);
  313. }
  314. }
  315. }
  316. public void BackupAlbum(string albumUri, string foldername)
  317. {
  318. UserState us = new UserState();
  319. us.opType = UserState.OperationType.queryForBackup;
  320. us.filename = "Starting backup to : " + foldername;
  321. us.foldername = foldername;
  322. this.states.Add(us);
  323. this.picasaService.QueryFeedAync(new Uri(albumUri), DateTime.MinValue, us);
  324. }
  325. public void DoSaveImageFile(PicasaEntry entry, string filename)
  326. {
  327. if (entry.Media != null &&
  328. entry.Media.Content != null)
  329. {
  330. UserState ut = new UserState();
  331. ut.opType = UserState.OperationType.download;
  332. ut.filename = filename;
  333. this.states.Add(ut);
  334. this.picasaService.QueryStreamAync(new Uri(entry.Media.Content.Attributes["url"] as string), DateTime.MinValue, ut);
  335. }
  336. }
  337. private void UploadPhoto_Click(object sender, System.EventArgs e)
  338. {
  339. DialogResult result = openFileDialog.ShowDialog();
  340. if( result == DialogResult.OK )
  341. {
  342. string[] files = openFileDialog.FileNames;
  343. // Open each file and display the image in PictureBox1.
  344. // Call Application.DoEvents to force a repaint after each
  345. // file is read.
  346. foreach (string file in files )
  347. {
  348. System.IO.FileInfo fileInfo = new System.IO.FileInfo(file);
  349. System.IO.FileStream fileStream = fileInfo.OpenRead();
  350. this.FileInfo.Text = "Starting upload....";
  351. PicasaEntry entry = new PhotoEntry();
  352. UserState ut = new UserState();
  353. ut.opType = UserState.OperationType.upload;
  354. this.states.Add(ut);
  355. entry.MediaSource = new Google.GData.Client.MediaFileSource(fileStream, file, "image/jpeg");
  356. this.picasaService.InsertAsync(new Uri(this.photoFeed.Post), entry, ut);
  357. }
  358. }
  359. }
  360. private void OnProgress(object sender, AsyncOperationProgressEventArgs e)
  361. {
  362. this.CancelAsync.Enabled = true;
  363. this.CancelAsync.Visible = true;
  364. if (this.states.Contains(e.UserState as UserState) == true)
  365. {
  366. this.progressBar.Value = e.ProgressPercentage ;
  367. }
  368. }
  369. private void OnDone(object sender, AsyncOperationCompletedEventArgs e)
  370. {
  371. UserState ut = e.UserState as UserState;
  372. if (this.states.Contains(ut) == false)
  373. return;
  374. this.states.Remove(ut);
  375. if (e.Error == null && e.Cancelled == false)
  376. {
  377. if (ut.opType == UserState.OperationType.query ||
  378. ut.opType == UserState.OperationType.queryForBackup)
  379. {
  380. if (e.Feed != null)
  381. {
  382. this.photoFeed = e.Feed as PicasaFeed;
  383. this.InitializeList(ut.filename);
  384. }
  385. }
  386. if (ut.opType == UserState.OperationType.upload)
  387. {
  388. if (e.Entry != null)
  389. {
  390. ListViewItem item = new ListViewItem(e.Entry.Title.Text);
  391. item.Tag = e.Entry;
  392. this.PhotoList.Items.Add(item);
  393. this.FileInfo.Text = "Upload succeeded";
  394. }
  395. }
  396. if (ut.opType == UserState.OperationType.download ||
  397. ut.opType == UserState.OperationType.downloadList)
  398. {
  399. if (e.ResponseStream != null)
  400. {
  401. WriteFile(ut.filename, e.ResponseStream);
  402. this.FileInfo.Text = "Saved file: " + ut.filename;
  403. }
  404. }
  405. if (ut.opType == UserState.OperationType.downloadList)
  406. {
  407. // we need to create a new object for uniqueness
  408. UserState u = new UserState();
  409. u.counter = ut.counter + 1;
  410. u.feed = ut.feed;
  411. u.foldername = ut.foldername;
  412. u.opType = UserState.OperationType.downloadList;
  413. if (u.feed.Entries.Count > 0)
  414. {
  415. u.feed.Entries.RemoveAt(0);
  416. this.PhotoList.Items.RemoveAt(0);
  417. }
  418. this.states.Add(u);
  419. SaveAnotherPictureDelegate d = new SaveAnotherPictureDelegate(this.CreateAnotherSaveFile);
  420. this.BeginInvoke(d, u);
  421. }
  422. if (ut.opType == UserState.OperationType.queryForBackup)
  423. {
  424. UserState u = new UserState();
  425. u.opType = UserState.OperationType.downloadList;
  426. u.feed = this.photoFeed;
  427. u.counter = 1;
  428. u.foldername = ut.foldername;
  429. u.filename = ut.foldername + "\\image1.jpg";
  430. this.states.Add(u);
  431. SaveAnotherPictureDelegate d = new SaveAnotherPictureDelegate(this.CreateAnotherSaveFile);
  432. this.BeginInvoke(d, u);
  433. }
  434. }
  435. this.progressBar.Value = 0;
  436. if (this.states.Count == 0)
  437. {
  438. this.CancelAsync.Enabled = false;
  439. this.CancelAsync.Visible = false;
  440. }
  441. }
  442. private void CreateAnotherSaveFile(UserState us)
  443. {
  444. if (us.feed.Entries.Count > 0)
  445. {
  446. PicasaEntry p = us.feed.Entries[0] as PicasaEntry;
  447. us.filename = us.foldername + "\\image" + us.counter.ToString() + ".jpg";
  448. this.picasaService.QueryStreamAync(new Uri(p.Media.Content.Attributes["url"] as string), DateTime.MinValue, us);
  449. }
  450. else if (us.feed.Entries.Count == 0 && us.feed.NextChunk != null)
  451. {
  452. }
  453. else
  454. {
  455. this.Close();
  456. }
  457. }
  458. private void WriteFile(string filename, Stream input)
  459. {
  460. FileStream fs = new FileStream(filename, FileMode.OpenOrCreate);
  461. BinaryWriter w = new BinaryWriter(fs);
  462. byte[] buffer = new byte[4096];
  463. int iRead = 0;
  464. int iOffset = 0;
  465. while ((iRead = input.Read(buffer, 0, 4069)) > 0)
  466. {
  467. w.Write(buffer, 0, iRead);
  468. iOffset += iRead;
  469. }
  470. w.Close();
  471. fs.Close();
  472. }
  473. private void PictureBrowser_FormClosing(object sender, FormClosingEventArgs e)
  474. {
  475. // here we should cancel our async events
  476. foreach (object o in this.states)
  477. {
  478. this.picasaService.CancelAsync(o);
  479. }
  480. }
  481. private void CancelAsync_Click(object sender, EventArgs e)
  482. {
  483. // here we should cancel our async events
  484. foreach (object o in this.states)
  485. {
  486. this.picasaService.CancelAsync(o);
  487. }
  488. this.FileInfo.Text = "Operation was cancelled";
  489. }
  490. }
  491. public class UserState
  492. {
  493. public enum OperationType
  494. {
  495. upload,
  496. download,
  497. downloadList,
  498. query,
  499. queryForBackup
  500. }
  501. public string filename;
  502. public OperationType opType;
  503. public PicasaFeed feed;
  504. public int counter = 0;
  505. public string foldername;
  506. }
  507. }