public DownloadInformationControl(Download download)
 {
     InitializeComponent();
     m_Download = download;
     iconPictureBox.Tag = m_Download.FileName;
     try
     {
         // 2008-10-21 Eroli: Mono-Fix
         if (!UtilitiesForMono.IsRunningOnMono)
             iconPictureBox.Image = ShellIcon.GetLargeSystemIcon((string)iconPictureBox.Tag);
     }
     catch
     {
     }
     fileSizeTextBox.Text = m_Download.FileSizeString;
     fileNameTextBox.Text = m_Download.FileName;
     subFolderTextBox.Text = m_Download.SubFolder;
     fileHashTextBox.Text = m_Download.FileHashString;
     if (m_Download.LastReception != null)
     {
         TimeSpan span = DateTime.Now.Subtract((DateTime)m_Download.LastReception);
         lastReceptionTextBox.Text = string.Format(Properties.Resources.Date_Diff, span.Days, span.Hours, span.Minutes, span.Seconds);
     }
     try
     {
         progressPictureBox.Image = ProgressBars.GetProgressBar(m_Download, progressPictureBox.Width, progressPictureBox.Height, Font);
     }
     catch
     {
     }
 }
        private Image GetRatingImage(Download.Source source)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            switch (source.Rating)
            {
                case 1:
                    return Properties.Resources.rating1_16x16;
                case 2:
                    return Properties.Resources.rating2_16x16;
                case 3:
                    return Properties.Resources.rating3_16x16;
                default:
                    return Properties.Resources.rating0_16x16;
            }
        }
        private string GetTypeString(Download.Source source)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            string type;
            int minutes = (int)DateTime.Now.Subtract(source.LastReceived).TotalMinutes;
            if (minutes < 12)
                type = string.Format("0 +{0}", minutes);
            else if (minutes < 24)
                type = string.Format("1 +{0}", minutes - 12);
            else if (minutes < 36)
                type = string.Format("2 +{0}", minutes - 24);
            else if (minutes < 48)
                type = string.Format("3 +{0}", minutes - 36);
            else
                type = string.Format("4 +{0}", minutes - 48);

            return string.Format("{0} ({1}{2})", GetSourceStateString(source.State), type, source.IsComplete ? string.Empty : "; " + RShare.Properties.Resources.Swarming);
        }
        private Image GetTypeImage(Download.Source source)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            int minutes = (int)DateTime.Now.Subtract(source.LastReceived).TotalMinutes;
            if (minutes < 12)
                return Properties.Resources.peer0_16x16;
            else if (minutes < 24)
                return Properties.Resources.peer1_16x16;
            else if (minutes < 36)
                return Properties.Resources.peer2_16x16;
            else if (minutes < 48)
                return Properties.Resources.peer3_16x16;
            else
                return Properties.Resources.peer4_16x16;
        }
        //2008-07-29 Nochbaer BZ 52
        private string GetSourceString(Download download)
        {
            if (download == null)
                throw new ArgumentNullException("download");

            if (download.Sources.Values.Count == 0)
            {
                return "0";
            }
            else
            {
                int active = 0;
                int verified = 0;
                int total = download.Sources.Count;
                foreach (Download.Source source in download.Sources.Values)
                    if (source.State == Download.SourceState.Active)
                    {
                        active++;
                        verified++;
                    }
                    else if (source.State == Download.SourceState.Requested ||
                        source.State == Download.SourceState.Verified)
                        verified++;
                return string.Format("{0} ({1})/{2}", active, verified, total);
            }
        }
 private string GetSourceStateString(Download.SourceState state)
 {
     switch (state)
     {
         case Download.SourceState.Active:
             return RShare.Properties.Resources.SourceState_Active;
         case Download.SourceState.Requested:
             return RShare.Properties.Resources.SourceState_Requested;
         case Download.SourceState.Requesting:
             return RShare.Properties.Resources.SourceState_Requesting;
         case Download.SourceState.Verified:
             return RShare.Properties.Resources.SourceState_Verified;
         case Download.SourceState.Verifying:
             return RShare.Properties.Resources.SourceState_Verifying;
         case Download.SourceState.NotNeeded:
             return RShare.Properties.Resources.SourceState_NotNeeded;
         default:
             return "error getting localized string";
     }
 }
Exemple #7
0
        public static void AddDownload(Search.Result result, string subFolder)
        {
            if (result == null)
                throw new ArgumentNullException("result");

            try
            {
                m_DownloadsAndQueue.Lock();
                if (m_DownloadsAndQueue.ContainsKey(ByteArrayToString(result.FileHash), DownloadCollection.KeyAccess.FileHash))
                    return;
                Download download = new Download(result);
                if (m_DownloadsAndQueue.Count >= Constants.MaximumDownloadsCount)
                {
                    download.SetSubFolderAndTime(subFolder, null);
                    download.RemoveSources();
                    if (bool.Parse(Settings.Instance["NewDownloadsToBeginngingOfQueue"]))
                        m_DownloadsAndQueue.Insert(Constants.MaximumDownloadsCount, download);
                    else
                        m_DownloadsAndQueue.Add(download);
                }
                else
                {
                    download.SetSubFolderAndTime(subFolder, DateTime.Now);
                    m_DownloadsAndQueue.Add(download);
                }
            }
            finally
            {
                m_DownloadsAndQueue.Unlock();
            }
            DownloadsXmlWriter.Write(m_DownloadsFilePath, m_DownloadsAndQueue);
        }
Exemple #8
0
        public static void AddDownload(byte[] fileHash, string fileName, long fileSize, string subFolder)
        {
            if (fileHash == null)
                throw new ArgumentNullException("fileHash");
            if (fileHash.Length != 64)
                throw new ArgumentException();
            if (fileName == null)
                throw new ArgumentNullException("fileName");
            if (fileSize < 0)
                throw new ArgumentOutOfRangeException("fileSize");

            try
            {
                m_DownloadsAndQueue.Lock();
                if (m_DownloadsAndQueue.ContainsKey(ByteArrayToString(fileHash), DownloadCollection.KeyAccess.FileHash))
                    return;
                Download download = new Download(fileHash, fileName, fileSize);
                if (m_DownloadsAndQueue.Count >= Constants.MaximumDownloadsCount)
                {
                    download.SetSubFolderAndTime(subFolder, null);
                    download.RemoveSources();
                    if (bool.Parse(Settings.Instance["NewDownloadsToBeginngingOfQueue"]))
                        m_DownloadsAndQueue.Insert(Constants.MaximumDownloadsCount, download);
                    else
                        m_DownloadsAndQueue.Add(download);
                }
                else
                {
                    download.SetSubFolderAndTime(subFolder, DateTime.Now);
                    m_DownloadsAndQueue.Add(download);
                }
            }
            finally
            {
                m_DownloadsAndQueue.Unlock();
            }
            DownloadsXmlWriter.Write(m_DownloadsFilePath, m_DownloadsAndQueue);
        }
Exemple #9
0
 /// <summary>
 /// Neue ResumeDownloads()
 /// 10.06.2009 Lars
 /// 03.07.2009 Lars (Neue Downloadwarteschlange)
 /// 04.07.2009 Lars (Einfacheres und besseres Handling)
 /// </summary>
 private static void ResumeDownloads()
 {
     try
     {
         // Alle gesicherten Downloads einlesen
         RIndexedHashtable<string, XmlNode> downloadsXml = new RIndexedHashtable<string, XmlNode>();
         if (File.Exists(m_DownloadsFilePath))
         {
             XmlDocument downloadsXmlDocument = new XmlDocument();
             downloadsXmlDocument.Load(m_DownloadsFilePath);
             foreach (XmlNode downloadNode in downloadsXmlDocument.SelectSingleNode("downloads"))
                 try
                 {
                     downloadsXml.Add(downloadNode.Attributes["hash"].InnerText, downloadNode);
                 }
                 catch (Exception ex)
                 {
                     m_Logger.Log(ex, "A download cannot be resumed due to non existent information about it!");
                     continue;
                 }
         }
         // Alle vorhandenen Dateien durchgehen
         RList<Download> temporary = new RList<Download>(downloadsXml.Count);
         foreach (string filePath in Directory.GetFiles(Settings.Instance["TemporaryDirectory"]))
         {
             string fileName = new FileInfo(filePath).Name;
             try
             {
                 if (!Regex.IsMatch(fileName, "^[0-9A-F]{128,128}$", RegexOptions.IgnoreCase))
                 {
                     m_Logger.Log("The file \"{0}\" is no valid temporary download!", fileName);
                 }
                 XmlNode node;
                 if (!downloadsXml.TryGetValue(fileName, out node))
                 {
                     m_Logger.Log("The download of \"{0}\" cannot be resumed due to non existent information about it!", fileName);
                     continue;
                 }
                 bool hasInformation = true;
                 if ((node as XmlElement).HasAttribute("hasinformation") && (node as XmlElement).GetAttribute("hasinformation") == "none")
                     hasInformation = false;
                 string lastSeenString = null;
                 DateTime? lastSeen = null;
                 string lastReceptionString = null;
                 DateTime? lastReception = null;
                 String subfolder = string.Empty;
                 if (node.SelectSingleNode("lastseen") != null)
                 {
                     lastSeenString = node.SelectSingleNode("lastseen").InnerText;
                     if (lastSeenString != null && lastSeenString.Length > 0)
                         lastSeen = DateTime.Parse(lastSeenString);
                 }
                 if (node.SelectSingleNode("lastreception") != null)
                 {
                     lastReceptionString = node.SelectSingleNode("lastreception").InnerText;
                     if (lastReceptionString != null && lastReceptionString.Length > 0)
                         lastReception = DateTime.Parse(lastReceptionString);
                 }
                 if (node.SelectSingleNode("subfolder") != null)
                     subfolder = node.SelectSingleNode("subfolder").InnerText;
                 Download download = new Download(Core.FileHashStringToFileHash(fileName), node.SelectSingleNode("filename").InnerText, long.Parse(node.SelectSingleNode("filesize").InnerText), hasInformation, lastSeen, lastReception, hasInformation ? Convert.FromBase64String(node.SelectSingleNode("sectorsmap").InnerText) : null);
                 download.SetSubFolderAndTime(subfolder, null);
                 temporary.Add(download);
             }
             catch (Exception ex)
             {
                 m_Logger.Log(ex, "An exception was thrown while resuming the download of \"{0}\"!", fileName);
             }
         }
         // Wiederaufzunehmende Download sortieren
         for (int n = 1; n <= temporary.Count - 1; n++)
             for (int m = 0; m < temporary.Count - n; m++)
             {
                 Download a = temporary[m];
                 Download b = temporary[m + 1];
                 if (downloadsXml.IndexOfKey(a.FileHashString) > downloadsXml.IndexOfKey(b.FileHashString))
                 {
                     temporary[m] = b;
                     temporary[m + 1] = a;
                 }
             }
         // Downloads wiederaufnehmen
         try
         {
             m_DownloadsAndQueue.Lock();
             foreach (Download download in temporary)
                 m_DownloadsAndQueue.Add(download);
         }
         finally
         {
             m_DownloadsAndQueue.Unlock();
         }
     }
     catch (Exception ex)
     {
         m_Logger.Log(ex, "An exception was thrown while resuming downloads!");
     }
     finally
     {
         // Erst jetzt kann die downloads.xml wieder geschreiben werden...
         DownloadsXmlWriter.SetIsReady();
     }
 }
 /// <summary>
 /// Constructor
 /// 
 /// Create a StealthNetLink from a download.
 /// Use this contructor to display this link with method 
 /// </summary>
 /// <param name="download">download object to construct the link from</param>
 /// <param name="htmlLink">true, if the string representation of this link should contain a html link</param>
 public StealthNetLink(Download download, bool htmlLink)
 {
     m_FileHash = download.FileHash;
     m_FileName = download.FileName;
     m_FileSize = download.FileSize;
     m_htmlLink = htmlLink;
 }
 public DownloadSourcesControl(Download download)
 {
     InitializeComponent();
     sourcesDataGridView.Sort(sourcesDataGridView.Columns["FileName"], ListSortDirection.Ascending);
     m_Download = download;
 }
        public static unsafe Image GetProgressBar(Download download, Download.Source source, int width, int height)
        {
            if (download == null)
                throw new ArgumentNullException("download");
            if (source == null)
                throw new ArgumentNullException("source");
            if (width < 0)
                throw new ArgumentOutOfRangeException("width");
            if (height < 0)
                throw new ArgumentOutOfRangeException("height");

            Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);
            BitmapData bmd = bitmap.LockBits(new Rectangle(new Point(0, 0), bitmap.Size), ImageLockMode.ReadOnly, bitmap.PixelFormat);
            byte* pbmd;
            int y;
            int x;
            int receivedLeft = (int)Math.Floor((double)Math.Max(source.LastReceivedSector, 0) / (double)download.Sectors * (double)bitmap.Width);
            int requestedLeft = (int)Math.Floor((double)Math.Max(source.LastRequestedSector, 0) / (double)download.Sectors * (double)bitmap.Width);
            int progressWidth = (int)Math.Ceiling((double)bitmap.Width / (double)download.Sectors);
            bool[] downloadProgressBarMap = new bool[width];
            ScaleLinear(download.SectorsMap, (int)download.Sectors, downloadProgressBarMap);
            bool[] sourceProgressBarMap = new bool[width];
            if (!source.IsComplete)
                ScaleLinear(source.SectorsMap, (int)download.Sectors, sourceProgressBarMap);
            else
                for (int n = 0; n < sourceProgressBarMap.Length; n++)
                    sourceProgressBarMap[n] = true;
            Color neither;
            Color both;
            //Color clientOnly = Color.FromArgb(0, 100, 255);
            Color clientOnly;
            Color pending = Color.FromArgb(0, 150, 0);
            Color nextPending = Color.FromArgb(255, 208, 0);
            if (bool.Parse(Settings.Instance["ProgressBarsHaveShadow"]))
            {
                neither = Color.FromArgb(240, 240, 240);
                both = Color.FromArgb(104, 104, 104);
                clientOnly = Color.FromArgb(0, 210 - 22 * (download.Sources.Count - 1) < 0 ? 0 : 210 - 22 * (download.Sources.Count - 1), 255);
                double[] shadows = ComputeShadows(bitmap.Height, int.Parse(Settings.Instance["ProgressBarsShadow"]));
                UnsafeColor[] neitherColors = ComputeColors(neither, bitmap.Height, shadows);
                UnsafeColor[] bothColors = ComputeColors(both, bitmap.Height, shadows);
                UnsafeColor[] clientOnlyColors = ComputeColors(clientOnly, bitmap.Height, shadows);
                UnsafeColor[] pendingColors = ComputeColors(pending, bitmap.Height, shadows);
                UnsafeColor[] nextPendingColors = ComputeColors(nextPending, bitmap.Height, shadows);
                UnsafeColor* c;
                fixed (bool* pDownloadSector = &downloadProgressBarMap[0], pSourceSector = &sourceProgressBarMap[0])
                {
                    fixed (UnsafeColor* pNeither = &neitherColors[0], pBoth = &bothColors[0], pClientOnly = &clientOnlyColors[0])
                    {
                        bool* pDownload;
                        bool* pSource;
                        for (y = 0; y < bitmap.Height; y++)
                        {
                            pDownload = pDownloadSector;
                            pSource = pSourceSector;
                            pbmd = (byte*)bmd.Scan0 + y * bmd.Stride;
                            for (x = 0; x < bitmap.Width; x++)
                            {
                                c = *pDownload && *pSource ? &pBoth[y] : (*pSource ? (source.State != Download.SourceState.NotNeeded ? &pClientOnly[y] : &pNeither[y]) : &pNeither[y]);
                                pDownload++;
                                pSource++;
                                *pbmd++ = c->B;
                                *pbmd++ = c->G;
                                *pbmd++ = c->R;
                            }
                        }
                    }
                }
                if (source.State == Download.SourceState.Active)
                {
                    if (source.LastReceivedSector > -1)
                        fixed (UnsafeColor* pPending = &pendingColors[0])
                        {
                            int n;
                            for (y = 0; y < bitmap.Height; y++)
                            {
                                pbmd = (byte*)bmd.Scan0 + y * bmd.Stride + receivedLeft * 3;
                                for (n = 0, x = receivedLeft; n < progressWidth && x < bitmap.Width; n++, x++)
                                {
                                    c = &pPending[y];
                                    *pbmd++ = c->B;
                                    *pbmd++ = c->G;
                                    *pbmd++ = c->R;
                                }
                            }
                        }
                    if (source.LastRequestedSector > -1)
                        fixed (UnsafeColor* pNextPending = &nextPendingColors[0])
                        {
                            int n;
                            for (y = 0; y < bitmap.Height; y++)
                            {
                                pbmd = (byte*)bmd.Scan0 + y * bmd.Stride + requestedLeft * 3;
                                for (n = 0, x = requestedLeft; n < progressWidth && x < bitmap.Width; n++, x++)
                                {
                                    c = &pNextPending[y];
                                    *pbmd++ = c->B;
                                    *pbmd++ = c->G;
                                    *pbmd++ = c->R;
                                }
                            }
                        }
                }
            }
            else
            {
                neither = Color.FromArgb(224, 224, 224);
                both = Color.FromArgb(0, 0, 0);
                clientOnly = Color.FromArgb(64, 169 - 11 * (download.Sources.Count - 1) < 64 ? 64 : 169 - 11 * (download.Sources.Count - 1), 191);
                Color c;
                fixed (bool* pDownloadSector = &downloadProgressBarMap[0], pSourceSector = &sourceProgressBarMap[0])
                {
                    bool* pDownload;
                    bool* pSource;
                    for (y = 0; y < bitmap.Height; y++)
                    {
                        pDownload = pDownloadSector;
                        pSource = pSourceSector;
                        pbmd = (byte*)bmd.Scan0 + y * bmd.Stride;
                        for (x = 0; x < bitmap.Width; x++)
                        {
                            c = *pDownload && *pSource ? both : (*pSource ? (source.State != Download.SourceState.NotNeeded ? clientOnly : neither) : neither);
                            pDownload++;
                            pSource++;
                            *pbmd++ = c.B;
                            *pbmd++ = c.G;
                            *pbmd++ = c.R;
                        }
                    }
                }
                if (source.State == Download.SourceState.Active)
                {
                    if (source.LastReceivedSector > -1)
                    {
                        c = pending;
                        int n;
                        for (y = 0; y < bitmap.Height; y++)
                        {
                            pbmd = (byte*)bmd.Scan0 + y * bmd.Stride + receivedLeft * 3;
                            for (n = 0, x = receivedLeft; n < progressWidth && x < bitmap.Width; n++, x++)
                            {
                                *pbmd++ = c.B;
                                *pbmd++ = c.G;
                                *pbmd++ = c.R;
                            }
                        }
                    }
                    if (source.LastRequestedSector > -1)
                    {
                        c = nextPending;
                        int n;
                        for (y = 0; y < bitmap.Height; y++)
                        {
                            pbmd = (byte*)bmd.Scan0 + y * bmd.Stride + requestedLeft * 3;
                            for (n = 0, x = requestedLeft; n < progressWidth && x < bitmap.Width; n++, x++)
                            {
                                *pbmd++ = c.B;
                                *pbmd++ = c.G;
                                *pbmd++ = c.R;
                            }
                        }
                    }
                }
            }
            bitmap.UnlockBits(bmd);
            return bitmap;
        }
        public static unsafe Image GetProgressBar(Download download, int width, int height, Font font)
        {
            if (download == null)
                throw new ArgumentNullException("download");
            if (width < 0)
                throw new ArgumentOutOfRangeException("width");
            if (height < 0)
                throw new ArgumentOutOfRangeException("height");
            if (font == null)
                throw new ArgumentNullException("font");

            Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);
            BitmapData bmd = bitmap.LockBits(new Rectangle(new Point(0, 0), bitmap.Size), ImageLockMode.ReadOnly, bitmap.PixelFormat);
            byte* pbmd;
            int y;
            int x;
            if (download.HasInformation)
            {
                int progress = (int)((download.Progress * bitmap.Width) / 100);
                int progressWidth = (int)Math.Ceiling((double)bitmap.Width / (double)download.Sectors);
                bool[] progressBarMap = new bool[width];
                ScaleLinear(download.SectorsMap, (int)download.Sectors, progressBarMap);
                if (bool.Parse(Settings.Instance["ProgressBarsHaveShadow"]))
                {
                    Color done;
                    Color current;
                    Color available;
                    if (download.IsActive)
                    {
                        done = Color.FromArgb(104, 104, 104);
                        current = Color.FromArgb(255, 208, 0);
                        if (!download.Sources.IsEmpty)
                            available = Color.FromArgb(0, 210 - 22 * (download.Sources.Count - 1) < 0 ? 0 : 210 - 22 * (download.Sources.Count - 1), 255);
                        else
                            available = Color.FromArgb(255, 0, 0);
                    }
                    else
                    {
                        done = Color.FromArgb(116, 116, 116);
                        current = Color.FromArgb(191, 168, 64);
                        if (!download.Sources.IsEmpty)
                            available = Color.FromArgb(64, 169 - 11 * (download.Sources.Count - 1) < 64 ? 64 : 169 - 11 * (download.Sources.Count - 1), 191);
                        else
                            available = Color.FromArgb(191, 64, 64);
                    }
                    double[] shadows = ComputeShadows(bitmap.Height, int.Parse(Settings.Instance["ProgressBarsShadow"]));
                    UnsafeColor[] doneColors = ComputeColors(done, bitmap.Height, shadows);
                    UnsafeColor[] currentColors = ComputeColors(current, bitmap.Height, shadows);
                    UnsafeColor[] availableColors = ComputeColors(available, bitmap.Height, shadows);
                    UnsafeColor* c;
                    fixed (bool* pSector = &progressBarMap[0])
                    {
                        fixed (UnsafeColor* pDone = &doneColors[0], pAvailable = &availableColors[0])
                        {
                            bool* p;
                            for (y = 0; y < bitmap.Height; y++)
                            {
                                p = pSector;
                                pbmd = (byte*)bmd.Scan0 + y * bmd.Stride;
                                for (x = 0; x < bitmap.Width; x++)
                                {
                                    c = *p++ ? &pDone[y] : &pAvailable[y];
                                    *pbmd++ = c->B;
                                    *pbmd++ = c->G;
                                    *pbmd++ = c->R;
                                }
                            }
                        }
                    }
                    fixed (UnsafeColor* pCurrent = &currentColors[0])
                    {
                        foreach (Download.Source source in download.Sources.Values)
                        {
                            if (source.State != Download.SourceState.Active || source.LastRequestedSector == -1)
                                continue;
                            int progressLeft = (int)Math.Floor((double)Math.Max(source.LastRequestedSector, 0) / (double)download.Sectors * (double)bitmap.Width);
                            int n;
                            for (y = 0; y < bitmap.Height; y++)
                            {
                                pbmd = (byte*)bmd.Scan0 + y * bmd.Stride + progressLeft * 3;
                                for (n = 0, x = progressLeft; n < progressWidth && x < bitmap.Width; n++, x++)
                                {
                                    c = &pCurrent[y];
                                    *pbmd++ = c->B;
                                    *pbmd++ = c->G;
                                    *pbmd++ = c->R;
                                }
                            }
                        }
                    }
                    int ph = height >= 32 ? 6 : 3;
                    shadows = ComputeShadows(ph, int.Parse(Settings.Instance["ProgressBarsShadow"]));
                    UnsafeColor[] progressColors = ComputeColors(Color.FromArgb(0, 224, 0), ph, shadows);
                    fixed (UnsafeColor* pProgress = &progressColors[0])
                    {
                        for (y = 0; y < Math.Min(ph, bitmap.Height); y++)
                        {
                            pbmd = (byte*)bmd.Scan0 + y * bmd.Stride;
                            for (x = 0; x < progress; x++)
                            {
                                c = &pProgress[y];
                                *pbmd++ = c->B;
                                *pbmd++ = c->G;
                                *pbmd++ = c->R;
                            }
                        }
                    }
                }
                else
                {
                    Color done;
                    Color current;
                    Color available;
                    if (download.IsActive)
                    {
                        done = Color.FromArgb(0, 0, 0);
                        current = Color.FromArgb(255, 208, 0);
                        if (!download.Sources.IsEmpty)
                            available = Color.FromArgb(0, 210 - 22 * (download.Sources.Count - 1) < 0 ? 0 : 210 - 22 * (download.Sources.Count - 1), 255);
                        else
                            available = Color.FromArgb(255, 0, 0);
                    }
                    else
                    {
                        done = Color.FromArgb(64, 64, 64);
                        current = Color.FromArgb(191, 168, 64);
                        if (!download.Sources.IsEmpty)
                            available = Color.FromArgb(64, 169 - 11 * (download.Sources.Count - 1) < 64 ? 64 : 169 - 11 * (download.Sources.Count - 1), 191);
                        else
                            available = Color.FromArgb(191, 64, 64);
                    }
                    Color c;
                    fixed (bool* pSector = &progressBarMap[0])
                    {
                        bool* p;
                        for (y = 0; y < bitmap.Height; y++)
                        {
                            p = pSector;
                            pbmd = (byte*)bmd.Scan0 + y * bmd.Stride;
                            for (x = 0; x < bitmap.Width; x++)
                            {
                                c = *p++ ? done : available;
                                *pbmd++ = c.B;
                                *pbmd++ = c.G;
                                *pbmd++ = c.R;
                            }
                        }
                    }
                    foreach (Download.Source source in download.Sources.Values)
                    {
                        if (source.State != Download.SourceState.Active || source.LastRequestedSector == -1)
                            continue;
                        int progressLeft = (int)Math.Floor((double)Math.Max(source.LastRequestedSector, 0) / (double)download.Sectors * (double)bitmap.Width);
                        c = current;
                        int n;
                        for (y = 0; y < bitmap.Height; y++)
                        {
                            pbmd = (byte*)bmd.Scan0 + y * bmd.Stride + progressLeft * 3;
                            for (n = 0, x = progressLeft; n < progressWidth && x < bitmap.Width; n++, x++)
                            {
                                *pbmd++ = c.B;
                                *pbmd++ = c.G;
                                *pbmd++ = c.R;
                            }
                        }
                    }
                    int ph = height >= 32 ? 6 : 3;
                    Color progressForeground = Color.FromArgb(0, 150, 0);
                    Color progressBackground = Color.FromArgb(224, 224, 224);
                    for (y = 0; y < Math.Min(ph, bitmap.Height); y++)
                    {
                        pbmd = (byte*)bmd.Scan0 + y * bmd.Stride;
                        for (x = 0; x < bitmap.Width; x++)
                        {
                            c = x < progress ? progressForeground : progressBackground;
                            *pbmd++ = c.B;
                            *pbmd++ = c.G;
                            *pbmd++ = c.R;
                        }
                    }
                }
            }
            else
            {
                if (bool.Parse(Settings.Instance["ProgressBarsHaveShadow"]))
                {
                    Color available;
                    if (download.IsActive)
                        available = Color.FromArgb(255, 0, 0);
                    else
                        available = Color.FromArgb(191, 64, 64);
                    double[] shadows = ComputeShadows(bitmap.Height, int.Parse(Settings.Instance["ProgressBarsShadow"]));
                    UnsafeColor[] availableColors = ComputeColors(available, bitmap.Height, shadows);
                    UnsafeColor* c;
                    fixed (UnsafeColor* pAvailable = &availableColors[0])
                    {
                        for (y = 0; y < bitmap.Height; y++)
                        {
                            pbmd = (byte*)bmd.Scan0 + y * bmd.Stride;
                            for (x = 0; x < bitmap.Width; x++)
                            {
                                c = &pAvailable[y];
                                *pbmd++ = c->B;
                                *pbmd++ = c->G;
                                *pbmd++ = c->R;
                            }
                        }
                    }
                }
                else
                {
                    Color available;
                    if (download.IsActive)
                        available = Color.FromArgb(255, 0, 0);
                    else
                        available = Color.FromArgb(191, 64, 64);
                    Color c;
                    for (y = 0; y < bitmap.Height; y++)
                    {
                        pbmd = (byte*)bmd.Scan0 + y * bmd.Stride;
                        for (x = 0; x < bitmap.Width; x++)
                        {
                            c = available;
                            *pbmd++ = c.B;
                            *pbmd++ = c.G;
                            *pbmd++ = c.R;
                        }
                    }
                }
            }
            bitmap.UnlockBits(bmd);
            Graphics graphics = Graphics.FromImage(bitmap);
            StringFormat progressStringFormat = new StringFormat();
            progressStringFormat.Alignment = StringAlignment.Center;
            progressStringFormat.LineAlignment = StringAlignment.Center;
            if (download.NoAvailableDiscSpace)
            {
                graphics.DrawString(Properties.Resources.ProgressBar_NoSpace, font, Brushes.White, new Rectangle(new Point(0, 1), new Size(bitmap.Width, bitmap.Height - 1)), progressStringFormat);
            }
            else if (!download.IsFilledWithZeros && !download.HasInformation)
            {
                graphics.DrawString(Properties.Resources.ProgressBar_NoInfo, font, Brushes.White, new Rectangle(new Point(0, 1), new Size(bitmap.Width, bitmap.Height - 1)), progressStringFormat);
            }
            else if (!download.IsFilledWithZeros && download.HasInformation && download.IsFillingWithZeros)
            {
                graphics.DrawString(Properties.Resources.ProgressBar_ZeroFilling, font, Brushes.White, new Rectangle(new Point(0, 1), new Size(bitmap.Width, bitmap.Height - 1)), progressStringFormat);
            }
            else if (download.IsActive && download.IsSourceSearchDelayActive)
            {
                graphics.DrawString(Properties.Resources.ProgressBar_Preparing, font, Brushes.White, new Rectangle(new Point(0, 1), new Size(bitmap.Width, bitmap.Height - 1)), progressStringFormat);
            }
            else if (download.HasInformation && bool.Parse(Settings.Instance["ProgressBarsShowPercent"]))
            {
                graphics.DrawString(string.Format("{0:F1}%", download.HasInformation ? download.Progress : 0F), font, Brushes.White, new Rectangle(new Point(0, 1), new Size(bitmap.Width, bitmap.Height - 1)), progressStringFormat);
            }
            progressStringFormat.Dispose();
            graphics.Dispose();
            return bitmap;
        }