windowcapture
исходный код / UI/MediaDownloadDialog.cs

MediaDownloadDialog.cs

314 строк · 10,843 байт · модуль UI
  1using System;
  2using System.Collections.Generic;
  3using System.Drawing;
  4using System.IO;
  5using System.Net;
  6using System.Threading;
  7using System.Windows.Forms;
  8using WindowCapture.Detection;
  9using WindowCapture.Models;
 10
 11namespace WindowCapture.UI
 12{
 13    /// <summary>
 14    /// Dialog for displaying and downloading found media items
 15    /// </summary>
 16    public class MediaDownloadDialog : Form
 17    {
 18        private ListView listView;
 19        private Button btnDownload;
 20        private Button btnDownloadAll;
 21        private Button btnClose;
 22        private Label lblStatus;
 23        private ProgressBar progressBar;
 24        private ImageList imageList;
 25        private List<MediaItem> mediaItems;
 26
 27        public MediaDownloadDialog(List<MediaItem> items)
 28        {
 29            mediaItems = items;
 30            InitializeComponents();
 31            PopulateList();
 32        }
 33
 34        private void InitializeComponents()
 35        {
 36            Text = "Media Parser - Found " + mediaItems.Count + " item(s)";
 37            Size = new Size(700, 500);
 38            MinimumSize = new Size(500, 300);
 39            StartPosition = FormStartPosition.CenterScreen;
 40            BackColor = Color.FromArgb(30, 30, 30);
 41            ForeColor = Color.White;
 42            Font = new Font("Segoe UI", 9f);
 43
 44            // Image list for icons
 45            imageList = new ImageList();
 46            imageList.ImageSize = new Size(48, 48);
 47            imageList.ColorDepth = ColorDepth.Depth32Bit;
 48
 49            // List view
 50            listView = new ListView();
 51            listView.View = View.Details;
 52            listView.FullRowSelect = true;
 53            listView.MultiSelect = true;
 54            listView.BackColor = Color.FromArgb(45, 45, 45);
 55            listView.ForeColor = Color.White;
 56            listView.BorderStyle = BorderStyle.None;
 57            listView.Dock = DockStyle.Top;
 58            listView.Height = 350;
 59            listView.SmallImageList = imageList;
 60
 61            listView.Columns.Add("Type", 60);
 62            listView.Columns.Add("Filename", 200);
 63            listView.Columns.Add("URL", 400);
 64
 65            listView.DoubleClick += ListView_DoubleClick;
 66
 67            // Buttons panel
 68            var buttonPanel = new Panel();
 69            buttonPanel.Dock = DockStyle.Bottom;
 70            buttonPanel.Height = 80;
 71            buttonPanel.Padding = new Padding(10);
 72
 73            btnDownload = CreateButton("Download Selected", 10, 10, 130);
 74            btnDownload.Click += BtnDownload_Click;
 75
 76            btnDownloadAll = CreateButton("Download All", 150, 10, 100);
 77            btnDownloadAll.Click += BtnDownloadAll_Click;
 78
 79            btnClose = CreateButton("Close", 580, 10, 80);
 80            btnClose.Click += (s, e) => Close();
 81
 82            lblStatus = new Label();
 83            lblStatus.Location = new Point(10, 45);
 84            lblStatus.Size = new Size(400, 20);
 85            lblStatus.ForeColor = Color.LightGray;
 86
 87            progressBar = new ProgressBar();
 88            progressBar.Location = new Point(10, 65);
 89            progressBar.Size = new Size(650, 10);
 90            progressBar.Style = ProgressBarStyle.Continuous;
 91            progressBar.Visible = false;
 92
 93            buttonPanel.Controls.AddRange(new Control[] { btnDownload, btnDownloadAll, btnClose, lblStatus, progressBar });
 94
 95            Controls.Add(listView);
 96            Controls.Add(buttonPanel);
 97        }
 98
 99        private Button CreateButton(string text, int x, int y, int width)
100        {
101            var btn = new Button();
102            btn.Text = text;
103            btn.Location = new Point(x, y);
104            btn.Size = new Size(width, 28);
105            btn.FlatStyle = FlatStyle.Flat;
106            btn.FlatAppearance.BorderColor = Color.FromArgb(80, 80, 80);
107            btn.BackColor = Color.FromArgb(60, 60, 60);
108            btn.ForeColor = Color.White;
109            btn.Cursor = Cursors.Hand;
110            return btn;
111        }
112
113        private void PopulateList()
114        {
115            listView.Items.Clear();
116
117            foreach (var item in mediaItems)
118            {
119                var lvi = new ListViewItem();
120
121                // Type icon
122                string typeIcon = "";
123                switch (item.Type)
124                {
125                    case "image": typeIcon = "IMG"; break;
126                    case "video": typeIcon = "VID"; break;
127                    case "audio": typeIcon = "AUD"; break;
128                }
129                lvi.Text = typeIcon;
130
131                lvi.SubItems.Add(item.FileName);
132                lvi.SubItems.Add(item.Url);
133                lvi.Tag = item;
134
135                // Color by type
136                switch (item.Type)
137                {
138                    case "image": lvi.ForeColor = Color.LightGreen; break;
139                    case "video": lvi.ForeColor = Color.LightBlue; break;
140                    case "audio": lvi.ForeColor = Color.Orange; break;
141                }
142
143                listView.Items.Add(lvi);
144            }
145
146            if (mediaItems.Count == 0)
147            {
148                lblStatus.Text = "No media found at this location";
149            }
150            else
151            {
152                lblStatus.Text = "Double-click to preview, or select and download";
153            }
154        }
155
156        private void ListView_DoubleClick(object sender, EventArgs e)
157        {
158            if (listView.SelectedItems.Count == 0) return;
159
160            var item = listView.SelectedItems[0].Tag as MediaItem;
161            if (item == null) return;
162
163            // Open URL in browser
164            try
165            {
166                System.Diagnostics.Process.Start(item.Url);
167            }
168            catch (Exception ex)
169            {
170                MessageBox.Show("Cannot open URL: " + ex.Message, "Error",
171                    MessageBoxButtons.OK, MessageBoxIcon.Error);
172            }
173        }
174
175        private void BtnDownload_Click(object sender, EventArgs e)
176        {
177            if (listView.SelectedItems.Count == 0)
178            {
179                lblStatus.Text = "Select items to download";
180                return;
181            }
182
183            var items = new List<MediaItem>();
184            foreach (ListViewItem lvi in listView.SelectedItems)
185            {
186                var item = lvi.Tag as MediaItem;
187                if (item != null) items.Add(item);
188            }
189
190            DownloadItems(items);
191        }
192
193        private void BtnDownloadAll_Click(object sender, EventArgs e)
194        {
195            if (mediaItems.Count == 0)
196            {
197                lblStatus.Text = "No items to download";
198                return;
199            }
200
201            DownloadItems(mediaItems);
202        }
203
204        private void DownloadItems(List<MediaItem> items)
205        {
206            // Ask for download folder
207            using (var fbd = new FolderBrowserDialog())
208            {
209                fbd.Description = "Select download folder";
210                fbd.ShowNewFolderButton = true;
211
212                // Default to Downloads folder
213                string downloads = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Downloads");
214                if (Directory.Exists(downloads))
215                    fbd.SelectedPath = downloads;
216
217                if (fbd.ShowDialog() != DialogResult.OK)
218                    return;
219
220                string folder = fbd.SelectedPath;
221
222                // Download in background
223                btnDownload.Enabled = false;
224                btnDownloadAll.Enabled = false;
225                progressBar.Visible = true;
226                progressBar.Maximum = items.Count;
227                progressBar.Value = 0;
228
229                ThreadPool.QueueUserWorkItem(state =>
230                {
231                    int success = 0;
232                    int failed = 0;
233
234                    for (int i = 0; i < items.Count; i++)
235                    {
236                        var item = items[i];
237
238                        int currentIndex = i;
239                        // Stop quietly if the user closed the dialog mid-download (otherwise Invoke throws on this pool thread).
240                        if (IsDisposed || !IsHandleCreated) return;
241                        try
242                        {
243                            Invoke(new Action(() =>
244                            {
245                                lblStatus.Text = string.Format("Downloading {0}/{1}: {2}", currentIndex + 1, items.Count, item.FileName);
246                                progressBar.Value = currentIndex;
247                            }));
248                        }
249                        catch { return; }
250
251                        // Generate unique filename
252                        string fileName = item.FileName;
253                        string savePath = Path.Combine(folder, fileName);
254
255                        // Add number if exists
256                        int num = 1;
257                        while (File.Exists(savePath))
258                        {
259                            string ext = Path.GetExtension(fileName);
260                            string name = Path.GetFileNameWithoutExtension(fileName);
261                            savePath = Path.Combine(folder, name + "_" + num + ext);
262                            num++;
263                        }
264
265                        if (MediaParser.DownloadMedia(item, savePath))
266                            success++;
267                        else
268                            failed++;
269                    }
270
271                    if (IsDisposed || !IsHandleCreated) return;
272                    try
273                    {
274                        Invoke(new Action(() =>
275                        {
276                            progressBar.Value = items.Count;
277                            lblStatus.Text = string.Format("Done! Downloaded: {0}, Failed: {1}", success, failed);
278                            btnDownload.Enabled = true;
279                            btnDownloadAll.Enabled = true;
280
281                            if (success > 0)
282                            {
283                                // Open folder
284                                System.Diagnostics.Process.Start("explorer.exe", folder);
285                            }
286                        }));
287                    }
288                    catch { }
289                });
290            }
291        }
292
293        protected override void OnResize(EventArgs e)
294        {
295            base.OnResize(e);
296            if (listView != null)
297            {
298                listView.Height = Height - 130;
299                if (listView.Columns.Count >= 3)
300                {
301                    listView.Columns[2].Width = Width - 300;
302                }
303            }
304            if (btnClose != null)
305            {
306                btnClose.Left = Width - 110;
307            }
308            if (progressBar != null)
309            {
310                progressBar.Width = Width - 50;
311            }
312        }
313    }
314}