csharp/214175590/AMShell/AppMonitor/Plugin/SftpForm.cs

SftpForm.cs
using AppMonitor.Bex;
using AppMonitor.Model;
using AppMonitor.Nodel;
using FarsiLibrary.Win;
using log4net;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Tamir.SharpSsh.jsch;
using YSTools;

namespace AppMonitor.Plugin
{
    public partial clast SftpForm : CCWin.Skin_Metro
    {
        private static ILog logger = LogManager.GetLogger("LogFileAppender");
        SftpWinForm leftForm = null;
        SftpLinuxForm rightForm = null;
        SshUser user = null;
        private int idnum = 100000;
        private bool localToRemoteRun = false, remoteToLocalRun = false, transfering = false;
        private string remote_path = null;
        private delegate void CreateLinuxDirCallback();
        private delegate void GesatemCallback(TransferItem item);

        Queue remoteQueue = new Queue();
        Queue localQueue = new Queue();
        List remoteList = new List();
        List localList = new List();

        Dictionary TIMEDIC = new Dictionary();
        Dictionary BYTEDIC = new Dictionary();

        public SftpForm(SshUser user)
        {
            InitializeComponent();
            SkinUtil.SetFormSkin(this);
            this.user = user;
        }

        private void SftpForm_Load(object sender, EventArgs e)
        {
            LoadLeftForm();
            if(user != null){
                text_host.Text = user.Host;
                text_past.Text = "";
                text_username.Text = user.UserName;
                text_port.Text = "" + user.Port;
                LoadRightForm(user);
            }
        }

        public void HideTool()
        {
            this.BeginInvoke((MethodInvoker)delegate()
            {
                text_host.Enabled = false;
                text_past.Enabled = false;
                text_username.Enabled = false;
                text_port.Enabled = false;
                toolStripButton7.Enabled = false;

                if (null != rightForm)
                {
                    SshUser user = rightForm.getSshUser();
                    if (null != user)
                    {
                        status_info.Text = user.Host + "@" + user.UserName;
                    }
                }
                WriteLog2("Connect Success...\n");
            });
        }

        public void CloseTab(SftpLinuxForm form)
        {
            form.Disconnection();
            form.Close();
            panel2.Controls.Remove(form);
        }

        public void LoadRightForm(SshUser sshUser)
        {
            rightForm = new SftpLinuxForm(this, sshUser);
            rightForm.FormBorderStyle = FormBorderStyle.None;
            rightForm.TopLevel = false;
            rightForm.Dock = DockStyle.Fill;
            rightForm.Show();

            panel2.Controls.Add(rightForm);

            WriteLog2("Start Connect...\n");
        }

        public void LoadLeftForm()
        {
            leftForm = new SftpWinForm(this);
            leftForm.FormBorderStyle = FormBorderStyle.None;
            leftForm.TopLevel = false;
            leftForm.Dock = DockStyle.Fill;
            leftForm.Show();

            panel1.Controls.Add(leftForm);
        }

        public void StartL2R()
        {
            ThreadPool.QueueUserWorkItem((a) =>
            {
                localToRemoteRun = true;
                if (localQueue.Count > 0)
                {
                    while (localToRemoteRun)
                    {
                        try
                        {
                            if (!transfering)
                            {
                                Thread.Sleep(100);
                                RunLocalToRemote();
                            }                            
                        }
                        catch { }
                        Thread.Sleep(100);
                    }
                }                
                localToRemoteRun = false;
            });
        }

        public void StopL2R()
        {
            localToRemoteRun = false;
        }

        public void StartR2L()
        {
            ThreadPool.QueueUserWorkItem((a) =>
            {
                remoteToLocalRun = true;
                if (remoteQueue.Count > 0)
                {
                    while (remoteToLocalRun)
                    {
                        try
                        {
                            RunRemoteToLocal();
                        }
                        catch { }
                        Thread.Sleep(100);
                    }
                }                
                remoteToLocalRun = false;
            });
        }

        public void StopR2L()
        {
            remoteToLocalRun = false;
        }

        public void TransferFilesToRemote(List filesList)
        {
            // DirectoryInfo、FileInfo      
            string dir = rightForm.getCurrDir();
            FileInfo file = null;
            DirectoryInfo dire = null;
            foreach(Object obj in filesList){
                if (obj is DirectoryInfo)
                {
                    dire = (DirectoryInfo) obj;
                    ParseDireToQueue(dir, dire);
                }
                else if (obj is FileInfo)
                {
                    file = (FileInfo) obj;
                    ParseFileToQueue(dir, file);
                }
            }

            StartL2R();
        }

        private void ParseDireToQueue(string dir, DirectoryInfo dire)
        {
            FileInfo[] files = dire.GetFiles();
            foreach (FileInfo file1 in files)
            {
                ParseFileToQueue(dir + dire.Name + "/", file1);
            }
            DirectoryInfo[] dires = dire.GetDirectories();
            if (null != dires)
            {
                foreach (DirectoryInfo d in dires)
                {
                    ParseDireToQueue(dir + dire.Name + "/", d);
                }
            }
        }

        private void ParseFileToQueue(string dir, FileInfo file)
        {
            TransferItem item = new TransferItem();
            item.Id = "L2R" + (idnum++);
            item.Name = file.Name;
            item.LocalPath = file.FullName;
            item.RemotePath = dir + file.Name;
            item.Status = TransferStatus.Wait;
            item.Size = Utils.getFileSize(file.Length);
            item.Progress = 0;
            item.Speed = "0 kb/s";

            AddItemToListView(item);
            localQueue.Enqueue(item);
        }

        public void TransferFilesToLocal(List filesList)
        {
            //ChannelSftp.LsEntry  getDirFiles
            string local = leftForm.getCurrDir();
            string remote = rightForm.getCurrDir();
            Tamir.SharpSsh.jsch.ChannelSftp.LsEntry entry = null;
            foreach (Object obj in filesList)
            {
                if (obj is Tamir.SharpSsh.jsch.ChannelSftp.LsEntry)
                {
                    entry = (Tamir.SharpSsh.jsch.ChannelSftp.LsEntry)obj;
                    if(entry.getAttrs().isDir()){
                        ParseDirEntryToQueue(local, remote, entry);
                    }
                    else
                    {
                        ParseEntryToQueue(local, remote, entry);
                    }
                }
            }

            StartR2L();
        }

        private void ParseDirEntryToQueue(string local, string remote, Tamir.SharpSsh.jsch.ChannelSftp.LsEntry dirs)
        {
            remote = remote + dirs.getFilename() + "/";
            local = local + dirs.getFilename() + "/";
            ArrayList filesList = rightForm.getDirFiles(remote);
            Tamir.SharpSsh.jsch.ChannelSftp.LsEntry entry = null;
            foreach (var obj in filesList)
            {
                if (obj is Tamir.SharpSsh.jsch.ChannelSftp.LsEntry)
                {
                    entry = (Tamir.SharpSsh.jsch.ChannelSftp.LsEntry)obj;
                    if (entry.getAttrs().isDir())
                    {
                        if (!Utils.isLinuxRootPath(entry.getFilename()))
                        {
                            ParseDirEntryToQueue(local, remote, entry);
                        }                        
                    }
                    else
                    {
                        ParseEntryToQueue(local, remote, entry);
                    }
                }
            }
        }

        private void ParseEntryToQueue(string local, string remote, Tamir.SharpSsh.jsch.ChannelSftp.LsEntry file)
        {
            TransferItem item = new TransferItem();
            item.Id = "R2L" + (idnum++);
            item.Name = file.getFilename();
            item.LocalPath = local + file.getFilename();
            item.RemotePath = remote + file.getFilename();
            item.Status = TransferStatus.Wait;
            item.Size = Utils.getFileSize(file.getAttrs().getSize());
            item.Progress = 0;
            item.Speed = "0 kb/s";

            AddItemToListView(item);
            remoteQueue.Enqueue(item);
        }

        private void AddItemToListView(TransferItem obj)
        {
            ListViewItem item = new ListViewItem();
            item.Name = obj.Id;
            item.Tag = obj;
            item.Text = obj.Name;

            ListViewItem.ListViewSubItem subItem = new ListViewItem.ListViewSubItem();
            subItem.Text = obj.Status.ToString();
            item.SubItems.Add(subItem);

            subItem = new ListViewItem.ListViewSubItem();
            subItem.Text = obj.Progress + "%";
            item.SubItems.Add(subItem);

            subItem = new ListViewItem.ListViewSubItem();
            subItem.Text = obj.Size;
            item.SubItems.Add(subItem);

            subItem = new ListViewItem.ListViewSubItem();
            subItem.Text = obj.LocalPath;
            item.SubItems.Add(subItem);

            subItem = new ListViewItem.ListViewSubItem();
            subItem.Text = obj.RemotePath;
            item.SubItems.Add(subItem);

            subItem = new ListViewItem.ListViewSubItem();
            subItem.Text = obj.Speed;
            item.SubItems.Add(subItem);

            subItem = new ListViewItem.ListViewSubItem();
            subItem.Text = obj.TimeLeft;
            item.SubItems.Add(subItem);

            listView3.Items.Add(item);
        }

        private void getTransferItem(string flag, GesatemCallback callback)
        {
            TransferItem item = null;
            this.BeginInvoke((MethodInvoker)delegate()
            {
                if (flag == "L2R")
                {
                    TransferItem obj = localQueue.Count > 0 ? localQueue.Dequeue() : null;
                    if (null != obj)
                    {
                        if (checkTransferItem(obj))
                        {
                            item = obj;
                            localList.Add(item);
                            callback(item);
                        }
                        else
                        {
                            getTransferItem(flag, callback);
                        }
                    }
                    else
                    {
                        callback(null);
                    }
                }
                else
                {
                    TransferItem obj = remoteQueue.Count > 0 ? remoteQueue.Dequeue() : null;
                    if (null != obj)
                    {
                        if (checkTransferItem(obj))
                        {
                            item = obj;
                            remoteList.Add(item);
                            callback(item);
                        }
                        else
                        {
                            getTransferItem(flag, callback);
                        }
                    }
                    else
                    {
                        callback(null);
                    }
                }
            });
        }

        private bool checkTransferItem(TransferItem obj)
        {
            TransferItem ti = null;
            foreach(ListViewItem item in listView3.Items){
                ti = (TransferItem)item.Tag;
                if(ti.Id == obj.Id){
                    if (item.SubItems[1].Text == TransferStatus.Wait.ToString())
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        private void RunLocalToRemote() {
            getTransferItem("L2R", (item) => {
                if (item != null)
                {
                    transfering = true;
                    try
                    {
                        if (RemoteExist(item.RemotePath, item.Name))
                        {
                            this.BeginInvoke((MethodInvoker)delegate()
                            {
                                DialogResult dr = MessageBox.Show(this, item.RemotePath + "已存在,是否覆盖?", "警告", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                                if (dr == System.Windows.Forms.DialogResult.Yes)
                                {
                                    WriteLog("L2R", item.Id, item.LocalPath, item.RemotePath);
                                    SftpProgressMonitor monitor = rightForm.TransfersToRemote(item.Id, item.LocalPath, item.RemotePath, ChannelSftp.OVERWRITE, new ProgressDelegate(TransfersFileProgress), new TransfersEndDelegate(TransfersFileEnd));
                                }
                                else
                                {
                                    ChangeTransferItemStatus("L2R", item.Id, TransferStatus.Cancel);
                                }
                            });
                        }
                        else
                        {
                            createRemoteDir(item.RemotePath, () =>
                            {
                                WriteLog("L2R", item.Id, item.LocalPath, item.RemotePath);
                                SftpProgressMonitor monitor = rightForm.TransfersToRemote(item.Id, item.LocalPath, item.RemotePath, ChannelSftp.OVERWRITE, new ProgressDelegate(TransfersFileProgress), new TransfersEndDelegate(TransfersFileEnd));
                            });
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.Error("传输文件的到服务器时异常:" + ex.Message);
                        ChangeTransferItemStatus("L2R", item.Id, TransferStatus.Failed);
                    }
                }
                else
                {
                    localToRemoteRun = false;
                }
            });            
        }

        public void TransfersFileProgress(string id, long precent, long c, long max, int elapsed)
        {
            try
            {
                int start = 0, end = Convert.ToInt32(DateTime.Now.ToString("ffff"));
                if(TIMEDIC.ContainsKey(id)){
                    start = TIMEDIC[id];
                    TIMEDIC[id] = end;
                } else {
                    TIMEDIC.Add(id, end);
                }
                long startByte = 0, endByte = c;
                if (BYTEDIC.ContainsKey(id))
                {
                    startByte = BYTEDIC[id];
                    BYTEDIC[id] = endByte;
                } else {
                    BYTEDIC.Add(id, endByte);
                }
                this.BeginInvoke((MethodInvoker)delegate()
                {
                    TransferItem obj = null;
                    foreach (ListViewItem item in listView3.Items)
                    {
                        if (item.Name == id)
                        {
                            obj = (TransferItem)item.Tag;
                        
                            obj.Progress = precent;
                            item.SubItems[1].Text = TransferStatus.Transfers.ToString();
                            item.SubItems[2].Text = precent + "%";
                            item.SubItems[6].Text = Utils.CalculaSpeed(startByte, endByte, max, start, end);
                            item.SubItems[7].Text = Utils.CalculaTimeLeft(startByte, endByte, max, start, end);
                            break;
                        }
                    }
                });
            }
            catch(Exception ex) {
                logger.Error("传输文件的到服务器时异常:" + ex.Message, ex);
                ChangeTransferItemStatus("R2L", id, TransferStatus.Failed);
            }
            
        }

        public void TransfersFileEnd(string id)
        {
            ChangeTransferItemStatus(id.Substring(0, 3), id, TransferStatus.Success);    
        }

        private void RunRemoteToLocal()
        {
            getTransferItem("R2L", (item) =>
            {
                if (item != null)
                {
                    transfering = true;
                    try
                    {
                        if (File.Exists(item.LocalPath))
                        {
                            this.BeginInvoke((MethodInvoker)delegate()
                            {
                                DialogResult dr = MessageBox.Show(this, item.LocalPath + "已存在,是否覆盖?", "警告", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                                if (dr == System.Windows.Forms.DialogResult.Yes)
                                {
                                    WriteLog("R2L", item.Id, item.LocalPath, item.RemotePath);
                                    SftpProgressMonitor monitor = rightForm.TransfersToLocal(item.Id, item.LocalPath, item.RemotePath, ChannelSftp.OVERWRITE, new ProgressDelegate(TransfersFileProgress), new TransfersEndDelegate(TransfersFileEnd));
                                }
                                else
                                {
                                    ChangeTransferItemStatus("R2L", item.Id, TransferStatus.Cancel);
                                }
                            });
                        }
                        else
                        {
                            FileInfo file = new FileInfo(item.LocalPath);
                            if (!file.Directory.Exists)
                            {
                                Utils.createParentDir(file.Directory);
                            }
                            WriteLog("R2L", item.Id, item.LocalPath, item.RemotePath);
                            SftpProgressMonitor monitor = rightForm.TransfersToLocal(item.Id, item.LocalPath, item.RemotePath, ChannelSftp.OVERWRITE, new ProgressDelegate(TransfersFileProgress), new TransfersEndDelegate(TransfersFileEnd));
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.Error("传输文件的到服务器时异常:" + ex.Message, ex);
                        ChangeTransferItemStatus("R2L", item.Id, TransferStatus.Failed);
                    }
                }
                else
                {
                    remoteToLocalRun = false;
                }
            });
        }

        private void ChangeTransferItemStatus(string flag, string id, TransferStatus status)
        {
            if (id != null)
            {
                this.BeginInvoke((MethodInvoker)delegate()
                {
                    try
                    {
                        TransferItem obj = null;
                        foreach (ListViewItem item in listView3.Items)
                        {
                            if (item.Name == id)
                            {
                                obj = (TransferItem)item.Tag;
                                obj.Status = status;
                                item.SubItems[1].Text = status.ToString();
                                break;
                            }
                        }
                        List list = flag == "L2R" ? localList : remoteList;
                        foreach (TransferItem item in list)
                        {
                            if (item.Name == id)
                            {
                                item.Status = status;
                                break;
                            }
                        }
                    }
                    catch { }

                    try
                    {
                        int count = 0;
                        foreach (ListViewItem item in listView3.Items)
                        {
                            if (item.SubItems[1].Text == "Success" || item.SubItems[1].Text == "Failed")
                            {
                                count++;
                            }
                        }
                        if (count == listView3.Items.Count)
                        {
                            if(id != null){
                                if (id.Substring(0, 3) == "L2R")
                                {
                                    rightForm.RefreshFiles();

                                    removeListViewItem("Success", "L2R");
                                }
                                else
                                {
                                    leftForm.RefreshFiles();

                                    removeListViewItem("Success", "R2L");
                                }
                            }
                            else
                            {
                                rightForm.RefreshFiles();
                                leftForm.RefreshFiles();
                            }
                        }
                    }
                    catch
                    {
                    }
                    WriteLog2(status.ToString() + "\n");
                    transfering = false;
                });
            }
        }

        public void removeListViewItem(string flag, string way)
        {
            if (flag == "All")
            {
                listView3.Items.Clear();
                if (way == "L2R")
                {
                    localList.Clear();
                }
                else if(way == "R2L")
                {
                    remoteList.Clear();
                }
                else
                {
                    localList.Clear();
                    remoteList.Clear();
                }
            }
            else
            {
                int count = 0;
                foreach (ListViewItem item in listView3.Items)
                {
                    if (item.SubItems[1].Text == flag)
                    {
                        listView3.Items.Remove(item);
                        count++;
                        break;
                    }
                }
                if (way == "L2R")
                {
                    foreach (TransferItem item in localList)
                    {
                        if (item.Status.ToString() == flag)
                        {
                            localList.Remove(item);
                            count++;
                            break;
                        }
                    }
                }
                else
                {
                    foreach (TransferItem item in remoteList)
                    {
                        if (item.Status.ToString() == flag)
                        {
                            remoteList.Remove(item);
                            count++;
                            break;
                        }
                    }
                }
                if (count > 0)
                {
                    removeListViewItem(flag, way);
                }
            }
        }

        private void RemoveToList(string id)
        {
            string way = id.Substring(0, 3);
            if (way == "L2R")
            {
                foreach (TransferItem item in localList)
                {
                    if(item.Id == id){
                        localList.Remove(item);
                        return;
                    }
                }
            }
            else if (way == "R2L")
            {
                foreach (TransferItem item in remoteList)
                {
                    if (item.Id == id)
                    {
                        remoteList.Remove(item);
                        return;
                    }
                }
            }
        }

        private void WriteLog(string flag, string id, string local, string remote)
        {
            try
            {
                string log = "";
                if (flag == "L2R")
                {
                    log = string.Format("【{0}】 - [{1}] Transfers File To {2},{3} -> {4}   ", user.Host, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), "Remote", local, remote);
                }
                else
                {
                    log = string.Format("[{0} {1}] Transfers File To {2},{3} -> {4}   ", user.Host, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), "Local", remote, local);
                }
                WriteLog2(log);
            }
            catch(Exception e) {
                logger.Error("格式化日志报错", e);
            }
        }

        private void WriteLog2(string msg)
        {
            try
            {
                this.BeginInvoke((MethodInvoker)delegate() {
                    logtext.AppendText(msg);

                    logtext.Focus();
                    logtext.SelectionStart = logtext.TextLength + 1000;
                    logtext.ScrollToCaret();
                });                
            }
            catch (Exception e)
            {
                logger.Error("显示日志报错:" + e.Message, e);
            }
        }

        private void SftpForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            SftpLinuxForm.RUN_CUT = false;
            StopL2R();
            StopR2L();
            if (null != rightForm)
            {
                rightForm.Disconnection();
                rightForm.Close();
                rightForm = null;
            }            
        }

        private bool RemoteExist(string path, string name, bool isdir = false)
        {
            string dir = path.Substring(0, path.Length - name.Length);
            ArrayList filesList = rightForm.getDirFiles(dir);
            if (null != filesList)
            {
                Tamir.SharpSsh.jsch.ChannelSftp.LsEntry entry = null;
                foreach (Object obj in filesList)
                {
                    if (obj is Tamir.SharpSsh.jsch.ChannelSftp.LsEntry)
                    {
                        entry = (Tamir.SharpSsh.jsch.ChannelSftp.LsEntry)obj;
                        if (entry.getFilename() == name)
                        {
                            if(isdir){
                                return entry.getAttrs().isDir();
                            }
                            else
                            {
                                return true;
                            }                            
                        }
                    }
                }
            }            
            return false;
        }

        private void createRemoteDir(string remotePath, CreateLinuxDirCallback callback)
        {
            try
            {
                string dir = Utils.getLinuxPathDir(remotePath);
                if (remote_path != dir)
                {
                    rightForm.SendShell("mkdir -p " + dir);
                    remote_path = dir;
                    ThreadPool.QueueUserWorkItem((a) => {
                        if (null != callback)
                        {
                            Thread.Sleep(300);
                            callback();
                        }
                    });                    
                }
                else if (null != callback)
                {
                    callback();
                }
            }
            catch { }
        }

        private void toolStripButton7_Click(object sender, EventArgs e)
        {
            string host = text_host.Text;
            string username = text_username.Text;
            string past = text_past.Text;
            string port = text_port.Text;

            IPAddress ip;
            if (IPAddress.TryParse(host, out ip))
            {
                if(string.IsNullOrWhiteSpace(username)){
                    MessageBox.Show(this, "请输入用户名");
                }
                else if (string.IsNullOrWhiteSpace(past))
                {
                    MessageBox.Show(this, "请输入密码");
                }
                else if (string.IsNullOrWhiteSpace(port))
                {
                    MessageBox.Show(this, "请输入端口号");
                }
                else
                {
                    user.Host = host;
                    user.UserName = username;
                    user.Pastword = YSEncrypt.EncryptA(past, KeysUtil.PastKey);
                    user.Port = Convert.ToInt32(port);

                    LoadRightForm(user);
                }
            }
            else
            {
                MessageBox.Show(this, "Host地址不正确");
            }
        }

        private void listView3_SelectedIndexChanged(object sender, EventArgs e)
        {
            int count = listView3.SelectedItems.Count;

            removeToolStripMenuItem.Enabled = count > 0;
            removeAllToolStripMenuItem.Enabled = listView3.Items.Count > 0;

            if(localToRemoteRun || remoteToLocalRun){
                
                restartFailedsToolStripMenuItem.Enabled = false;
                restartTransfersToolStripMenuItem.Enabled = false;
            }
            else
            {
                restartFailedsToolStripMenuItem.Enabled = true;
                restartTransfersToolStripMenuItem.Enabled = true;
            }
        }

        private void copyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                string text = logtext.SelectedText;
                if (text != "")
                {
                    Clipboard.SetText(text);
                }
            }
            catch (Exception ex)
            {
                logger.Error("复制时异常:" + ex.Message, ex);
            }
        }

        private void clearToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                logtext.Clear();
            }
            catch (Exception ex)
            {
                logger.Error("清除所有日志时异常:" + ex.Message, ex);
            }
        }

        private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                logtext.SelectAll();
            }
            catch (Exception ex)
            {
                logger.Error("选择全部时异常:" + ex.Message, ex);
            }
        }

        private void removeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (listView3.SelectedItems.Count > 0)
            {
                foreach (ListViewItem item in listView3.SelectedItems)
                {
                    TransferItem tfItem = (TransferItem)item.Tag;
                    if (null != tfItem)
                    {
                        RemoveToList(tfItem.Id);
                        listView3.Items.Remove(item);
                    }
                }
            }
        }

        private void removeAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            removeListViewItem("All", "");

            StopL2R();
            StopR2L();
        }

        private void restartFailedsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if(localQueue.Count == 0 && localList.Count > 0){
                listView3.Items.Clear();
                foreach (TransferItem item in localList)
                {
                    if(item.Status == TransferStatus.Failed){
                        AddItemToListView(item);
                        localQueue.Enqueue(item);
                    }
                }
                localList.Clear();

                StartL2R();
            }
            else if (remoteQueue.Count == 0 && remoteList.Count > 0)
            {
                listView3.Items.Clear();
                foreach (TransferItem item in remoteList)
                {
                    if (item.Status == TransferStatus.Failed)
                    {
                        AddItemToListView(item);
                        remoteQueue.Enqueue(item);
                    }
                }
                remoteList.Clear();

                StartR2L();
            }
        }

        private void restartTransfersToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (localQueue.Count == 0 && localList.Count > 0)
            {
                listView3.Items.Clear();
                foreach (TransferItem item in localList)
                {
                    if (item.Status != TransferStatus.Success)
                    {
                        AddItemToListView(item);
                        localQueue.Enqueue(item);
                    }
                }
                localList.Clear();

                StartL2R();
            }
            else if (remoteQueue.Count == 0 && remoteList.Count > 0)
            {
                listView3.Items.Clear();
                foreach (TransferItem item in remoteList)
                {
                    if (item.Status != TransferStatus.Success)
                    {
                        AddItemToListView(item);
                        remoteQueue.Enqueue(item);
                    }
                }
                remoteList.Clear();

                StartR2L();
            }
        }

    }
}