예제 #1
0
        /* ЗАМЕТКА РАЗРАБОТЧИКУ
         *
         * В данном файле размещаются функции для работы с файлами и каталогами.
         * Данные функции запускаются в отдельных от UI потоках из кода
         * файла MainWindow-Actions.cs . Всякая функция должна иметь
         * префикс Do, означающий её чисто утилитарную принадлежность.
         *
         * Вызовы пользовательского интерфейса (XWT) должны производиться через
         * вызывалку Xwt.Application.Invoke(new Action(delegate { КОД ПОТОКА ИНТЕРФЕЙСА }));
         * в противном случае возможны глюки (вылеты WPF, зависания и лаги GTK).
         */
        /// <summary>
        /// Background file copier
        /// </summary>
        /// <param name='SourceFS'>Source FS.</param>
        /// <param name='DestinationFS'>Destination FS.</param>
        /// <param name='SourceURL'>Source file URL.</param>
        /// <param name='DestinationURL'>Destination URL.</param>
        /// <param name="Feedback">If at the destination URL a file exists, a ReplaceQuestionDialog will be shown. This argument is the place, where the user's last choose should be saved.</param>
        /// <param name="AC">The instance of AsyncCopy class that should be used to copy the file.</param>
        private void DoCp(IFSPlugin SourceFS, IFSPlugin DestinationFS, string SourceURL, string DestinationURL, ref ReplaceQuestionDialog.ClickedButton Feedback, AsyncCopy AC)
        {
            if (SourceURL == DestinationURL){
                string itself = Localizator.GetString("CantCopySelf");
                string toshow = string.Format(Localizator.GetString("CantCopy"), SourceFS.GetMetadata(SourceURL).Name, itself);

                Xwt.Application.Invoke(delegate { Xwt.MessageDialog.ShowWarning(toshow); });
                //calling the msgbox in non-main threads causes some UI bugs, so push this call into main thread
                return;
            }

            if(DestinationFS.FileExists (DestinationURL)){

                ReplaceQuestionDialog rpd = null;
                bool ready = false;

                Xwt.Application.Invoke(
                    delegate
                    {
                        rpd = new ReplaceQuestionDialog(DestinationFS.GetMetadata(DestinationURL).Name);
                        ready = true;
                    }
                );
                do { } while (!ready);
                ready = false;

                var ClickedButton = ReplaceQuestionDialog.ClickedButton.Skip;
                Xwt.Application.Invoke(
                    delegate
                    {
                        ClickedButton = rpd.Run();
                        ready = true;
                    }
                );

                do {} while (!ready);

                switch(ClickedButton){
                case ReplaceQuestionDialog.ClickedButton.Replace:
                    //continue execution
                    Feedback = rpd.ChoosedButton;
                    break;
                case ReplaceQuestionDialog.ClickedButton.ReplaceAll:
                    //continue execution
                    Feedback = rpd.ChoosedButton;
                    break;
                case ReplaceQuestionDialog.ClickedButton.ReplaceOld:
                    Feedback = rpd.ChoosedButton;
                    if(SourceFS.GetMetadata(SourceURL).LastWriteTimeUTC < DestinationFS.GetMetadata(DestinationURL).LastWriteTimeUTC)
                    {/*continue execution*/}
                    else
                    {return;}
                    break;
                case ReplaceQuestionDialog.ClickedButton.Skip:
                    Feedback = rpd.ChoosedButton;
                    return;
                case ReplaceQuestionDialog.ClickedButton.SkipAll:
                    Feedback = rpd.ChoosedButton;
                    return;
                }
            }

            try
            {
                pluginner.FSEntryMetadata md = SourceFS.GetMetadata(SourceURL);
                md.FullURL = DestinationURL;

                System.IO.Stream SrcStream = SourceFS.GetFileStream(SourceURL);
                DestinationFS.Touch(md);
                System.IO.Stream DestStream = DestinationFS.GetFileStream(DestinationURL,true);

                if(AC == null) AC = new AsyncCopy();
                bool CpComplete = false;

                AC.OnComplete += result => CpComplete = true;

                //warning: due to some GTK# bugs, buffer sizes lesser than 128KB may cause
                //an StackOverflowException at UI update code
                AC.CopyFile(SrcStream, DestStream, 131072); //buffer is 1/8 megabyte or 128KB

                do{ } while(!CpComplete); //don't stop this thread until the copy is finished
            }
            catch (Exception ex)
            {
                if (ex.GetType() != typeof(System.Threading.ThreadAbortException)) {
                    Utilities.ShowMessage(string.Format(Localizator.GetString("CantCopy"),SourceURL,ex.Message));
                    Console.WriteLine("Cannot copy because of {0}({1}) at \n{2}.", ex.GetType(), ex.Message, ex.StackTrace);
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Background file copier
        /// </summary>
        /// <param name='SourceFS'>
        /// Source FS.
        /// </param>
        /// <param name='DestinationFS'>
        /// Destination FS.
        /// </param>
        /// <param name='SourceFile'>
        /// Source file.
        /// </param>
        /// <param name='DestinationURL'>
        /// Destination URL.
        /// </param>
        /// <param name='SkipAll'>
        /// The referenced variable will be set to TRUE if user chooses "Skip all"
        /// </param>
        /// <param name='ReplaceAll'>
        /// The referenced variable will be set to TRUE if user chooses "Replace all"
        /// </param>
        void DoCp(pluginner.IFSPlugin SourceFS, pluginner.IFSPlugin DestinationFS, pluginner.File SourceFile, string DestinationURL, ref ReplaceQuestionDialog.ClickedButton Feedback, AsyncCopy AC)
        {
            pluginner.File NewFile = SourceFile;
            NewFile.Path = DestinationURL;

            if (SourceFile.Path == DestinationURL)
            {
                string itself = Locale.GetString("CantCopySelf");
                string toshow = string.Format(Locale.GetString("CantCopy"), SourceFile.Name, itself);

                Xwt.Application.Invoke(new Action(delegate { Xwt.MessageDialog.ShowWarning(toshow); }));
                //calling the msgbox in non-main threads causes some UI bugs, so push this call into main thread
                return;
            }

            if (DestinationFS.FileExists(DestinationURL))
            {
                ReplaceQuestionDialog rpd = null;
                bool ready = false;

                Xwt.Application.Invoke(
                    new Action(
                        delegate
                {
                    rpd   = new ReplaceQuestionDialog(DestinationFS.GetFile(DestinationURL, new double()).Name);
                    ready = true;
                }
                        )
                    );
                do
                {
                } while (!ready);
                ready = false;

                var ClickedButton = ReplaceQuestionDialog.ClickedButton.Skip;
                Xwt.Application.Invoke(
                    new Action(
                        delegate
                {
                    ClickedButton = rpd.Run();
                    ready         = true;
                }
                        )
                    );

                do
                {
                } while (!ready);

                switch (ClickedButton)
                {
                case ReplaceQuestionDialog.ClickedButton.Replace:
                    //continue execution
                    Feedback = rpd.ChoosedButton;
                    break;

                case ReplaceQuestionDialog.ClickedButton.ReplaceAll:
                    //continue execution
                    Feedback = rpd.ChoosedButton;
                    break;

                case ReplaceQuestionDialog.ClickedButton.ReplaceOld:
                    Feedback = rpd.ChoosedButton;
                    if (SourceFS.GetMetadata(SourceFile.Path).LastWriteTimeUTC < DestinationFS.GetFile(DestinationURL, new double()).Metadata.LastWriteTimeUTC)
                    {                    /*continue execution*/
                    }
                    else
                    {
                        return;
                    }
                    break;

                case ReplaceQuestionDialog.ClickedButton.Skip:
                    Feedback = rpd.ChoosedButton;
                    return;

                case ReplaceQuestionDialog.ClickedButton.SkipAll:
                    Feedback = rpd.ChoosedButton;
                    return;
                }
            }

            try
            {
                pluginner.FSEntryMetadata md = SourceFS.GetMetadata(SourceFile.Path);
                md.FullURL = NewFile.Path;

                System.IO.Stream SrcStream = SourceFS.GetStream(SourceFile.Path);
                DestinationFS.Touch(md);
                System.IO.Stream DestStream = DestinationFS.GetStream(DestinationURL, true);

                if (AC == null)
                {
                    AC = new AsyncCopy();
                }
                bool CpComplete = false;

                AC.OnComplete += (rezultat) => { CpComplete = true; };

                //warning: due to some GTK# bugs, buffer sizes lesser than 128KB may cause
                //an StackOverflowException at UI update code
                AC.CopyFile(SrcStream, DestStream, 131072);                 //buffer is 1/8 megabyte

                do /*nothing*/ } {
                while(!CpComplete);                 //don't stop this thread until the copy is finished
                return;
        }