Example #1
0
        // FIXME: Keyboard and general mouse movement events!!
        public override bool KeyPressed(CircuitEditor editor, Gdk.EventKey eventKey)
        {
            bool consumed = false;

            var modifiers = eventKey.State & Accelerator.DefaultModMask;

            if (modifiers == Gdk.ModifierType.None)
            {
                // No modifiers are pressed
                if (eventKey.Key == Gdk.Key.Up)
                {
                    CompOrientation = Circuit.Orientation.North;
                    consumed        = true;
                }
                if (eventKey.Key == Gdk.Key.Down)
                {
                    CompOrientation = Circuit.Orientation.South;
                    consumed        = true;
                }
                if (eventKey.Key == Gdk.Key.Left)
                {
                    CompOrientation = Circuit.Orientation.West;
                    consumed        = true;
                }
                if (eventKey.Key == Gdk.Key.Right)
                {
                    CompOrientation = Circuit.Orientation.East;
                    consumed        = true;
                }
            }

            if (consumed)
            {
                editor.DrawingArea.QueueDraw();
            }
            return(consumed);
        }
Example #2
0
        /// <summary>
        /// Parses a project file. The results are saved in FileManager.Wires, FileManager.Components, and FileManager.Labels.
        /// </summary>
        /// <param name="filename">The path of the project file.</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="InvalidProjectDataException">The XML-file doesn't match with the schema.</exception>
        /// <exception cref="ArgumentException">Unable to access the file.</exception>
        public static void Load(string filename)
        {
            Vector2i getPos(XmlNode pos)
            {
                int x = int.Parse(pos.Attributes["x"].InnerText);
                int y = int.Parse(pos.Attributes["y"].InnerText);

                return(new Vector2i(x, y));
            }

            XmlDocument doc = new XmlDocument();
            XmlReader?  reader;

            XmlReaderSettings settings = new XmlReaderSettings();

            settings.ValidationType          = ValidationType.Schema;
            settings.ValidationFlags        |= XmlSchemaValidationFlags.ProcessInlineSchema;
            settings.ValidationFlags        |= XmlSchemaValidationFlags.ProcessSchemaLocation;
            settings.ValidationFlags        |= XmlSchemaValidationFlags.ReportValidationWarnings;
            settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);

            try
            {
                reader = XmlReader.Create(filename, settings);

                doc.Load(reader);

                /* STRUCTURE:
                 *  circuit
                 *    wires
                 *      wire
                 *        from < -x: int, y: int
                 *        to < -x: int, y: int
                 *      ...
                 *    components
                 *      component
                 *        type
                 *          "and" | "dFlipFlop" | "not"
                 *        location < -x: int, y: int
                 *        orientation
                 *          "north" | "east" | "south" | "west"...
                 *    labels
                 *      label < -size: int(10, 100)
                 *        location < -x: int, y: int
                 *        text
                 *          <string>...
                 */

                #region Parse Wires

                foreach (var _wire in doc.SelectNodes("/circuit/wires"))
                {
                    if (_wire != null)
                    {
                        XmlNode wire = ((XmlNode)_wire).FirstChild;

                        Vector2i start = getPos(wire.SelectSingleNode("from"));
                        Vector2i end   = getPos(wire.SelectSingleNode("to"));

                        if (start.X == end.X)
                        {
                            int length = Math.Abs(Math.Abs(end.Y) - start.Y);

                            Wires.Add(new Wire(start, length, Direction.Horizontal));
                        }
                        else if (start.Y == end.Y)
                        {
                            int length = Math.Abs(Math.Abs(end.X) - start.X);

                            Wires.Add(new Wire(start, length, Direction.Vertical));
                        }
                        else
                        {
                            throw new InvalidProjectDataException($"Start ({ start.X }, { start.Y }) and end ({ end.X }, { end.Y }) of wire #{ Wires.Count + 1 } has to be on the same axis.");
                        }

                        // FIXME: Diagonal wire support
                    }
                }

                #endregion

                #region Parse Components

                foreach (var _component in doc.SelectNodes("/circuit/components"))
                {
                    if (_component != null)
                    {
                        XmlNode component = ((XmlNode)_component).FirstChild;



                        ComponentType       type        = types[component.SelectSingleNode("type").InnerText];
                        Vector2i            location    = getPos(component.SelectSingleNode("location"));
                        Circuit.Orientation orientation = orientations[component.SelectSingleNode("orientation").InnerText];

                        Components.Add(InstanceData.Create(type, location, orientation));

                        // FIXME: Update list of gates.
                    }
                }

                #endregion

                #region Parse Labels

                foreach (var _label in doc.SelectNodes("/circuit/labels"))
                {
                    if (_label != null)
                    {
                        XmlNode label = ((XmlNode)_label).FirstChild;

                        int size = int.Parse(label.Attributes["size"].InnerText);

                        Vector2i location = getPos(label.SelectSingleNode("location"));

                        string text = label.SelectSingleNode("text").InnerText;

                        Labels.Add(new TextLabel(location, text, size));
                    }
                }

                #endregion

                #region Parse Recent Files

                foreach (var _recent_file in doc.SelectNodes("/circuit/recent_files"))
                {
                    if (_recent_file != null)
                    {
                        XmlNode file = ((XmlNode)_recent_file).FirstChild;

                        string text = file.SelectSingleNode("file_name").InnerText;

                        RecentFiles.Add(text);
                    }
                }

                #endregion

                // FIXME: Save wires, components, and labels in higher level objects

                IsNew = false;
                FileManager.filename = filename;
            }
            catch (Exception e)
            {
                if (e is XmlException || e is XPathException || e is InvalidProjectDataException || e is XmlSchemaException)
                {
                    MessageDialog md = new MessageDialog(null, DialogFlags.DestroyWithParent, MessageType.Info, ButtonsType.Ok, "Logik is unable to read file. Please choose a valid project file.");
                    md.Run();
                    md.Dispose();

                    throw new ArgumentException("Not a project file.", e);
                }
                else
                {
                    MessageDialog md = new MessageDialog(null, DialogFlags.DestroyWithParent, MessageType.Error, ButtonsType.Ok, "Logik is unable to access choosen file.");
                    md.Run();
                    md.Dispose();

                    throw new ArgumentException("Unable to access file.", e);
                }
            }

            if (reader != null)
            {
                reader.Close();
            }
        }
Example #3
0
        /// <summary>
        /// Parses a project file. The results are saved in FileManager.Wires, FileManager.Components, and FileManager.Labels.
        /// </summary>
        /// <param name="filename">The path of the project file.</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="InvalidProjectDataException">The XML-file doesn't match with the schema.</exception>
        /// <exception cref="ArgumentException">Unable to access the file.</exception>
        public static void Load(string filename)
        {
            Vector2i getPos(XmlNode pos)
            {
                int x = int.Parse(pos.Attributes["x"].InnerText);
                int y = int.Parse(pos.Attributes["y"].InnerText);

                return(new Vector2i(x, y));
            }

            //HACK: What does "Could not find schema information for the element '<element>'." for every element mean!?

            XmlSchemaSet schema = new XmlSchemaSet();
            // currentDirectory = ~\bin\Debug\netcoreapp3.1
            string path = Directory.GetCurrentDirectory() + "\\..\\..\\..\\File";

            schema.Add("http://www.w3.org/2001/XMLSchema", path + "\\structure.xsd");

            XmlDocument doc = new XmlDocument();

            doc.Schemas = schema;
            XmlReader?reader;

            XmlReaderSettings settings = new XmlReaderSettings();

            settings.ValidationType          = ValidationType.Schema;
            settings.ValidationFlags        |= XmlSchemaValidationFlags.ProcessInlineSchema;
            settings.ValidationFlags        |= XmlSchemaValidationFlags.ProcessSchemaLocation;
            settings.ValidationFlags        |= XmlSchemaValidationFlags.ReportValidationWarnings;
            settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);

            try
            {
                reader = XmlReader.Create(filename, settings);

                doc.Load(reader);

                #region Parse Wires

                foreach (var _wire in doc.SelectNodes("/circuit/wires"))
                {
                    if (_wire != null)
                    {
                        XmlNode wire = ((XmlNode)_wire).FirstChild;

                        Vector2i start = getPos(wire.SelectSingleNode("from"));
                        Vector2i end   = getPos(wire.SelectSingleNode("to"));

                        if (start.X == end.X)
                        {
                            int length = Math.Abs(Math.Abs(end.Y) - start.Y);

                            Wires.Add(new Wire(start, length, Direction.Horizontal));
                        }
                        else if (start.Y == end.Y)
                        {
                            int length = Math.Abs(Math.Abs(end.X) - start.X);

                            Wires.Add(new Wire(start, length, Direction.Vertical));
                        }
                        else
                        {
                            throw new InvalidProjectDataException($"Start ({ start.X }, { start.Y }) and end ({ end.X }, { end.Y }) of wire #{ Wires.Count + 1 } has to be on the same axis.");
                        }

                        // FIXME: Diagonal wire support
                    }
                }

                #endregion

                #region Parse Components

                foreach (var _component in doc.SelectNodes("/circuit/components"))
                {
                    if (_component != null)
                    {
                        XmlNode component = ((XmlNode)_component).FirstChild;

                        ComponentType       type        = types[component.SelectSingleNode("type").InnerText];
                        Vector2i            location    = getPos(component.SelectSingleNode("location"));
                        Circuit.Orientation orientation = orientations[component.SelectSingleNode("orientation").InnerText];

                        Components.Add(InstanceData.Create(type, location, orientation));

                        // FIXME: Update list of gates.
                    }
                }

                #endregion

                #region Parse Labels

                foreach (var _label in doc.SelectNodes("/circuit/labels"))
                {
                    if (_label != null)
                    {
                        XmlNode label = ((XmlNode)_label).FirstChild;

                        int      size     = int.Parse(label.Attributes["size"].InnerText);
                        Vector2i location = getPos(label.SelectSingleNode("location"));
                        string   text     = label.SelectSingleNode("text").InnerText;

                        Labels.Add(new TextLabel(location, text, size));
                    }
                }

                #endregion

                // FIXME: Save wires, components, and labels in higher level objects

                IsNew = false;
                FileManager.filename = filename;
            }
            catch (Exception e)
            {
                if (e is XmlException || e is XPathException || e is InvalidProjectDataException || e is XmlSchemaException || e is KeyNotFoundException)
                {
                    MessageDialog md = new MessageDialog(null, DialogFlags.DestroyWithParent, MessageType.Info, ButtonsType.Ok, "Logik is unable to read file. Please choose a valid project file.");
                    md.Run();
                    md.Dispose();

                    throw new ArgumentException("Not a project file.", e);
                }
                else
                {
                    MessageDialog md = new MessageDialog(null, DialogFlags.DestroyWithParent, MessageType.Error, ButtonsType.Ok, "Logik is unable to access choosen file.");
                    md.Run();
                    md.Dispose();

                    throw new ArgumentException("Unable to access file.", e);
                }
            }

            if (reader != null)
            {
                reader.Close();
            }
        }