/* * Copyright (c) 2009 Craig Sutherland * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using ThoughtWorks.CruiseControl.Remote.Monitor; using ThoughtWorks.CruiseControl.Remote; using FastForward.WinCore; using System.Diagnostics; using System.IO; namespace FastForward.Monitor { /// /// Displays the packages available for a project. /// public partial class PackagesForm : Form { #region Private fields private Project project; private object lockObject = new object(); private bool isRefreshing = false; private IEnumerable packages; private Exception lastError; private Stopwatch loadStopwatch = new Stopwatch(); #endregion #region Constructors /// /// Initialise a new . /// /// /// public PackagesForm(Project project, Form owner) { InitializeComponent(); this.project = project; Owner = owner; Text = "Packages List: " + project.Name; RefreshData(); } #endregion #region Private methods #region RefreshData() /// /// Refresh the data. /// private void RefreshData() { var canRefresh = false; // Check if a refresh is already running lock (lockObject) { canRefresh = !isRefreshing; isRefreshing = true; } // Trigger the refresh if (canRefresh) { loadStopwatch.Reset(); loadStopwatch.Start(); downloadWorker.RunWorkerAsync(); } } #endregion #region DownloadPackage() /// /// Downloads the currently selected package. /// private void DownloadPackage() { if (packagesList.SelectedItems.Count == 0) { MessageBox.Show(this, "You have not selected a package to download", "Unable to download", MessageBoxButtons.OK, MessageBoxIcon.Warning); } else { // Generate the default file name var selectedPackage = packagesList.SelectedItems[0].Tag as PackageDetails; var defaultFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), selectedPackage.Name + ".zip"); // Prompt the user where they want to save it var saveDialog = new SaveFileDialog { AddExtension = false, AutoUpgradeEnabled = true, CheckPathExists = true, FileName = defaultFile, Filter = "All files (*.*)|*.*", FilterIndex = 1, OverwritePrompt = true, InitialDirectory = Path.GetDirectoryName(defaultFile), RestoreDirectory = true, Title = "Download Package Location" }; if (saveDialog.ShowDialog(this) == DialogResult.OK) { // Perform the actual download // In future, this could be converted to a background process try { var fileTransfer = project.Server.Client.RetrieveFileTransfer(project.Name, selectedPackage.FileName); if (fileTransfer == null) throw new Exception("Unable to retrieve file!"); if (File.Exists(saveDialog.FileName)) File.Delete(saveDialog.FileName); using (var file = File.Create(saveDialog.FileName)) { fileTransfer.Download(file); } // See if the user wants to open the package if (MessageBox.Show(this, "Package downloaded, would you like to open it now?", "Download finished", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes) { // Open the package var openFile = new Process(); openFile.StartInfo = new ProcessStartInfo { FileName = saveDialog.FileName, UseShellExecute = true }; openFile.Start(); } } catch (Exception error) { // Tell the user if there were any problems statusLabel.Text = "Unable to download package: " + error.Message; } } } } #endregion #endregion #region Event handlers #region downloadButton_Click() /// /// The user has clicked on the download button. /// /// /// private void downloadButton_Click(object sender, EventArgs e) { DownloadPackage(); } #endregion #region refreshButton_Click() /// /// The user has clicked on the refresh button. /// /// /// private void refreshButton_Click(object sender, EventArgs e) { RefreshData(); } #endregion #region packagesList_DoubleClick() /// /// The user has double-clicked on a package. /// /// /// private void packagesList_DoubleClick(object sender, EventArgs e) { DownloadPackage(); } #endregion #region downloadWorker_DoWork() /// /// The worker needs to download the packages. /// /// /// private void downloadWorker_DoWork(object sender, DoWorkEventArgs e) { lastError = null; try { packages = project.Server.Client.RetrievePackageList(project.Name); } catch (Exception error) { packages = new List(); lastError = error; } } #endregion #region downloadWorker_RunWorkerCompleted() /// /// The packages have been downloaded. /// /// /// private void downloadWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { // Load all the packages packagesList.BeginUpdate(); try { packagesList.Items.Clear(); foreach (var package in packages) { var item = new ListViewItem(new string[] { package.Name, package.BuildLabel, package.DateTime.ToString("g"), package.NumberOfFiles.ToString(), StringUtils.FormatFileSize(package.Size) }, "Package"); item.Tag = package; packagesList.Items.Add(item); } loadStopwatch.Stop(); if (lastError == null) { statusLabel.Text = string.Format("List loaded: {0:0.00}s", loadStopwatch.Elapsed.TotalSeconds); } else { statusLabel.Text = "Unable to list packages: " + lastError.Message; } } finally { packagesList.EndUpdate(); } // Unlock the refresh process lock (lockObject) { isRefreshing = false; } } #endregion #endregion } }