private static string GetImageSourcePath(string tmxPath, Tileset tileset, TilesetImage image)
        {
            // The image may be absolute, so only prepend the tmx path if the image is relative
            string sourcepath;

            if (FileManager.IsRelative(image.Source))
            {
                sourcepath = tmxPath + image.Source;
            }
            else
            {
                sourcepath = image.Source;
            }

            sourcepath = FileManager.RemoveDotDotSlash(sourcepath);

            if (tileset.Source != null)
            {
                if (tileset.SourceDirectory != "." && !tileset.SourceDirectory.Contains(":"))
                {
                    sourcepath = tmxPath + tileset.SourceDirectory.Replace("\\", "/") + "/" + image.sourceFileName;
                    sourcepath = FileManager.GetDirectory(sourcepath) + image.sourceFileName;
                }
                else if (tileset.SourceDirectory.Contains(":"))
                {
                    sourcepath = tileset.SourceDirectory + "/" + image.sourceFileName;
                }
                else
                {
                    sourcepath = tmxPath + image.sourceFileName;
                }
            }
            return sourcepath;
        }
        private static bool TryCopyTilesetImage(string tmxPath, string destinationPath, Tileset tileset, TilesetImage image)
        {
            string sourcepath = GetImageSourcePath(tmxPath, tileset, image);

            string whyCantCopy = null;

            if(!System.IO.File.Exists(sourcepath))
            {
                whyCantCopy = "Could not find the file\n" + sourcepath + "\nwhich is referenced by the tileset " + tileset.Name + " in the tmx\n" + tmxPath;
            }

            if (!string.IsNullOrEmpty(whyCantCopy))
            {
                System.Console.Error.WriteLine(whyCantCopy);
            }
            else
            {
                string destinationFullPath = destinationPath + image.sourceFileName;

                bool shouldCopy =
                    !sourcepath.Equals(destinationFullPath, StringComparison.InvariantCultureIgnoreCase) &&
                    !FileManager.GetDirectory(destinationFullPath).Equals(FileManager.GetDirectory(sourcepath));

                if(shouldCopy)
                {
                    if (File.Exists(destinationFullPath))
                    {
                        // Only copy if source is newer than destination
                        var sourceDate = File.GetLastWriteTimeUtc(sourcepath);
                        var destinationDate = File.GetLastWriteTimeUtc(destinationFullPath);
                        shouldCopy = sourceDate > destinationDate;
                    }
                }

                if (shouldCopy)
                {
                    System.Console.WriteLine("Copying \"{0}\" to \"{1}\".", sourcepath, destinationFullPath);

                    string fileWithoutDotDotSlash = FileManager.RemoveDotDotSlash(sourcepath);

                    const int maxFailures = 5;
                    int currentFailures = 0;

                    while (true)
                    {
                        try
                        {
                            // try it 3 times, in case someone else is copying it at the same time

                            File.Copy(fileWithoutDotDotSlash, destinationFullPath, true);

                            break;
                        }
                        catch (Exception e)
                        {
                            if (currentFailures < maxFailures)
                            {
                                System.Threading.Thread.Sleep(300);
                                // try again:
                                currentFailures++;
                            }
                            else
                            {
                                System.Console.Error.WriteLine("Could not copy \"{0}\" to \"{1}\" \n{2}.", sourcepath, destinationFullPath, e.ToString());
                                break;
                            }
                        }
                    }
                }
            }

            bool succeeded = string.IsNullOrEmpty(whyCantCopy);

            return succeeded;
        }
Exemple #3
0
        private void LoadValuesFromSource()
        {
            if (!string.IsNullOrEmpty(this._sourceField))
            {
                _sourceField = _sourceField.Replace("/", "\\");

                tileset xts = null;

                try
                {

                    xts = FileManager.XmlDeserialize<tileset>(_sourceField);
                }
                catch (FileNotFoundException)
                {
                    string fileAttemptedToLoad = _sourceField;
                    if (FileManager.IsRelative(_sourceField))
                    {
                        fileAttemptedToLoad = FileManager.RelativeDirectory + _sourceField;
                    }

                    string message = "Could not find the shared tsx file \n" + fileAttemptedToLoad + 
                        "\nIf this is a relative file name, then the loader will use " +
                        "the FileManager's RelativeDirectory to make the file absolute.  Therefore, be sure to set the FileManger's RelativeDirectory to the file represented by " +
                        "this fileset before setting this property if setting this property manually.";


                    throw new FileNotFoundException(message);
                }

                if (xts.image != null)
                {

                    Images = new TilesetImage[xts.image.Length];

                    Parallel.For(0, xts.image.Length, count =>
                    {
                        this.Images[count] = new TilesetImage
                        {
                            Source = xts.image[count].source,
                            height = xts.image[count].height != 0 ? xts.image[count].height : xts.tileheight,
                            width = xts.image[count].width != 0 ? xts.image[count].width : xts.tilewidth
                        };
                    });
                }
                this.Name = xts.name;
                this.Margin = xts.margin;
                this.Spacing = xts.spacing;
                this.Tileheight = xts.tileheight;
                this.Tilewidth = xts.tilewidth;
                this.Tiles = xts.tile;
            }
        }
        private void HandleAddNewTilesetClick(object sender, EventArgs e)
        {
            string fileName;
            bool succeeded;
            GetTilesetFromFileOrOptions(canBeImageFile:true, fileName: out fileName, succeeded: out succeeded);

            if (fileName != null)
            {
                Tileset newTileset = new Tileset();
                // We're going to add this to the end, so we need to see what the last tileset is,
                // get its ID and count, and start this tileset at that number

                var lastTileset = AppState.Self.CurrentTiledMapSave.Tilesets.LastOrDefault();

                uint startingIndex = 1;

                if (lastTileset != null)
                {
                    startingIndex = lastTileset.Firstgid + (uint)lastTileset.GetTileCount();
                }

                newTileset.Firstgid = startingIndex;

                string oldRelative = FileManager.RelativeDirectory;
                FileManager.RelativeDirectory = AppState.Self.TmxFolder;

                bool isFileTsx = FileManager.GetExtension(fileName) == "tsx";

                bool shouldContinue = true;

                if (isFileTsx)
                {

                    newTileset.Source = FileManager.MakeRelative(fileName, AppState.Self.TmxFolder);
                }
                else
                {

                    TilesetWindow window = new TilesetWindow();
                    TilesetViewModel viewModel = new TilesetViewModel();

                    viewModel.Name = FileManager.RemovePath(FileManager.RemoveExtension(fileName));

                    window.DataContext = viewModel;

                    var result = window.ShowDialog();

                    if(result.HasValue && result.Value)
                    {
                        shouldContinue = true;

                        string sourceToSet = fileName;

                        if (viewModel.CopyFile && !FileManager.IsRelativeTo(fileName, AppState.Self.TmxFolder))
                        {
                            try
                            {
                                sourceToSet = AppState.Self.TmxFolder + FileManager.RemovePath(fileName);
                                System.IO.File.Copy(fileName, sourceToSet, overwrite: true);

                            }
                            catch (Exception copyException)
                            {
                                MessageBox.Show("Error copying file:\n" + copyException.Message);
                                shouldContinue = false;
                            }

                        }
                        if (shouldContinue)
                        {

                            sourceToSet = FileManager.MakeRelative(sourceToSet, AppState.Self.TmxFolder);

                            newTileset.Images = new TilesetImage[1];
                            newTileset.Name = viewModel.Name;
                            newTileset.Tilewidth = viewModel.TileWidth;
                            newTileset.Tileheight = viewModel.TileHeight;
                            newTileset.Margin = viewModel.Margin;
                            newTileset.Spacing = viewModel.Spacing;

                            var tilesetImage = new TilesetImage();
                            tilesetImage.Source = sourceToSet;

                            // We could use either the original file or the copied file.
                            // I'll use the original since it's in scope and shouldn't matter
                            var dimensions = ImageHeader.GetDimensions(fileName);

                            tilesetImage.width = dimensions.Width;
                            tilesetImage.height = dimensions.Height;

                            newTileset.Images[0] = tilesetImage;
                        }
                    }
                    else
                    {
                        shouldContinue = false;

                    }
                }
                FileManager.RelativeDirectory = oldRelative;

                if (shouldContinue)
                {
                    AppState.Self.CurrentTiledMapSave.Tilesets.Add(newTileset);

                    // refresh everything:
                    RefreshListBox(newTileset);
                    mTilesetsListBox.SelectedItem = newTileset;

                    UpdateXnaDisplayToTileset();
                    // and make sure the apps are notified about the change
                    if (AnyTileMapChange != null)
                    {
                        AnyTileMapChange(this, null);
                    }
                }
            }
        }