Example #1
0
        /// <summary>
        /// Creates a new feature ID that doesn't reference anything (and does not add it to the map model).
        /// </summary>
        /// <returns>The created feature ID.</returns>
        internal FeatureId CreateId()
        {
            IdPacket p = m_Group.FindPacket(m_Id);

            p.ReserveId(m_Id);
            return(p.CreateId(m_Id));
        }
Example #2
0
        /// <summary>
        /// Associates an ID allocation with this group
        /// </summary>
        /// <param name="a">The allocation associated with this group</param>
        /// <returns>The ID packet corresponding to the supplied allocation</returns>
        internal IdPacket AddIdPacket(IdAllocation a)
        {
            IdPacket result = new IdPacket(this, a);

            m_Packets.Add(result);
            m_MaxAllocatedId = Math.Max(m_MaxAllocatedId, a.HighestId);
            return(result);
        }
Example #3
0
        /// <summary>
        /// Gets a new allocation for this ID group.
        /// </summary>
        /// <param name="announce">Should the allocation be announced to the user?</param>
        /// <returns>Information about the allocated range.</returns>
        internal IdPacket GetAllocation(bool announce)
        {
            IdPacket result = null;

            IDataServer ds = EditingController.Current.DataServer;

            if (ds == null)
            {
                throw new ApplicationException("Database not available");
            }

            ds.RunTransaction(delegate
            {
                // May be best to remove this from IIdGroup! -- DO want to be able to retrieve the value
                // currently stored in the database.
                int oldMaxUsedId = m_MaxAllocatedId;
                int newMaxUsedId = (oldMaxUsedId == 0 ? LowestId + PacketSize - 1 : oldMaxUsedId + PacketSize);

                /*
                 * // The following should be covered by the implementation of the ID server (for a personal ID server,
                 * // there should be nothing to do).
                 * string sql = String.Format("UPDATE [ced].[IdGroups] SET [MaxUsedId]={0} WHERE [GroupId]={1} AND [MaxUsedId]={2}",
                 *                              newMaxUsedId, Id, oldMaxUsedId);
                 * int nRows = ds.ExecuteNonQuery(sql);
                 *
                 * if (nRows != 1)
                 *  throw new ApplicationException("Allocation failed");
                 */

                // Remember the allocation as as part of this group
                IdAllocation alloc = new IdAllocation()
                {
                    GroupId   = this.Id,
                    LowestId  = newMaxUsedId - PacketSize + 1,
                    HighestId = newMaxUsedId,
                };

                result           = AddIdPacket(alloc);
                m_MaxAllocatedId = newMaxUsedId;

                // Write event data for the allocation
                CadastralMapModel.Current.WorkingSession.AddAllocation(alloc);
                EditingController.Current.Project.WriteChange(alloc);
            });

            // If the user should be informed, list out any ranges we created.
            if (announce && result != null)
            {
                string announcement = String.Format("Allocating extra IDs: {0}-{1}", result.Min, result.Max);
                MessageBox.Show(announcement);
            }

            return(result);
        }
Example #4
0
        /// <summary>
        /// Release an allocated ID for a feature that is being removed due to an undo.
        /// This nulls out the reference to the ID from its enclosing ID packet.
        /// </summary>
        /// <param name="id">The ID that should be returned to the pool of available IDs.</param>
        internal void ReleaseId(NativeId id)
        {
            IdPacket p = FindPacket(id);

            if (p == null)
            {
                throw new ApplicationException("Cannot locate packet for ID: " + id.FormattedKey);
            }

            p.DeleteId(id);
        }
Example #5
0
        /// <summary>
        /// Restores (un-deletes) this feature.
        /// </summary>
        /// <returns>True if feature restored. False if the feature wasn't marked as inactive.</returns>
        internal virtual bool Restore()
        {
            // Return if this feature doesn't currently have the "inactive" state
            if (!IsInactive)
            {
                return(false);
            }

            // If this feature referred to an ID, restore it.
            if (m_Id != null)
            {
                // Ensure that the ID is cross-referenced to this feature.
                m_Id.AddReference(this);

                // That's pretty well it. When a feature is de-activated, only the back
                // pointer from the ID is nulled out. The feature retained it's pointer to the ID,
                // and the ID itself was left in place as part of the IdPacket to which it belongs.
                // For native IDs, the packet needs to be told to decrement the number of free
                // IDs.

                // TODO: This may be irrelevant (need to also review the logic when something is
                // de-activated).

                if (m_Id is NativeId)
                {
                    IdManager idMan = MapModel.IdManager;
                    if (idMan != null)
                    {
                        // Find the ID group that applies to the feature's
                        // entity type (this will be null if the entity type was
                        // not originally listed in the IdEntity table, or the
                        // group is considered to be obsolete).
                        IdGroup g = idMan.GetGroup(this.EntityType);

                        // If we got a group (and the ID if not foreign) try to find
                        // the ID packet that refers to the feature's ID.
                        if (g != null)
                        {
                            NativeId nid = (m_Id as NativeId);
                            IdPacket p   = g.FindPacket(nid);
                            p.RestoreId(m_Id);
                        }
                    }
                }
            }

            // Add back into the map index.
            MapModel.EditingIndex.AddFeature(this);

            // Remember that the feature is now active
            IsInactive = false;

            return(true);
        }
Example #6
0
        /// <summary>
        /// Exhaustive search for the ID packet that refers to a specific ID. This method
        /// should only be called in situations where something has gone astray.
        /// </summary>
        /// <param name="fid">The ID to search for</param>
        /// <returns>The packet that contains the specified object (null if not found)</returns>
        internal IdPacket FindPacket(NativeId nid)
        {
            foreach (IdGroup g in m_IdGroups)
            {
                IdPacket p = g.FindPacket(nid);
                if (p != null)
                {
                    return(p);
                }
            }

            return(null);
        }
Example #7
0
        /// <summary>
        /// Defines a newly reserved ID.
        /// </summary>
        /// <param name="packet">The ID packet.</param>
        /// <param name="ent">The entity type for the ID.</param>
        /// <param name="id">The raw ID number.</param>
        /// <returns>True if the ID was valid.</returns>
        internal bool Define(IdPacket packet, IEntity ent, uint id)
        {
            // The ID has to be valid.
            if (id == 0)
            {
                return(false);
            }

            // Remember the supplied info.
            m_Packet = packet;
            m_Id     = id;
            m_Entity = ent;

            return(true);
        }
Example #8
0
        /// <summary>
        /// Gets a new allocation for every ID group. This function is used only when the
        /// user is explicitly allocating ID ranges (through the dialog that lists the allocations).
        /// </summary>
        /// <returns>Information about the allocations made.</returns>
        internal IdPacket[] GetAllocation()
        {
            List <IdPacket> allocs = new List <IdPacket>();

            foreach (IdGroup g in m_IdGroups)
            {
                IdPacket p = g.GetAllocation(false);
                if (p != null)
                {
                    allocs.Add(p);
                }
            }

            return(allocs.ToArray());
        }
Example #9
0
        /// <summary>
        /// Reserves a feature ID in a specific ID packet
        /// </summary>
        /// <devnote>This function is called by LoadIdCombo</devnote>
        /// <param name="packet">The ID packet containing the available ID.</param>
        /// <param name="ent">The entity type that the ID is for.</param>
        /// <param name="id">The available ID to reserve.</param>
        /// <returns>True if the ID was successfully reserved.</returns>
        internal bool ReserveId(IdPacket packet, IEntity ent, uint id)
        {
            // Ensure that any currently reserved ID is released.
            FreeReservedId();

            // Just get the packet to do it.
            if (packet.ReserveId(id))
            {
                m_Packet = packet;
                m_Id     = id;
                m_Entity = ent;
                return(true);
            }

            this.Reset();
            return(false);
        }
Example #10
0
        /// <summary>
        /// Reserves an ID belonging to this ID group.
        /// </summary>
        /// <param name="idh">The ID handle to define.</param>
        /// <param name="id">The specific ID to reserve. Specify 0 for the next
        /// available ID (in that case, an additional allocation will be made if
        /// necessary).</param>
        /// <returns>True if the ID was reserved ok. False if it is already reserved (or
        /// an allocation could not be obtained).</returns>
        internal bool ReserveId(IdHandle idh, uint id)
        {
            if (id > 0)
            {
                // Find the packet that contains the specified ID.
                IdPacket packet = FindPacket(id);
                if (packet == null)
                {
                    MessageBox.Show("IdGroup.ReserveId - Wrong ID group.");
                    return(false);
                }

                // Get the ID handle to reserve the ID.
                return(idh.ReserveId(packet, idh.Entity, id));
            }
            else
            {
                // Find the packet that contains the next available ID.
                IdPacket packet = FindNextAvail();

                // If we didn't find anything, ask the ID manager to make
                // a new allocation (most of the work actually gets passed
                // back to IdGroup.GetAllocation).
                if (packet == null)
                {
                    GetAllocation(true);
                    packet = FindNextAvail();
                    if (packet == null)
                    {
                        return(false);
                    }
                }

                // Get the next ID from the packet.
                uint nextid = packet.ReserveId();
                if (nextid == 0)
                {
                    MessageBox.Show("IdGroup.ReserveId - Range did not have any free IDs.");
                    return(false);
                }

                return(idh.Define(packet, idh.Entity, nextid));
            }
        }
Example #11
0
 /// <summary>
 /// Resets everything in the class to null values.
 /// </summary>
 void Reset()
 {
     m_Packet = null;
     m_Entity = null;
     m_Id     = 0;
 }
Example #12
0
        /// <summary>
        /// Load an ID combo box with all the available IDs for a specific entity type.
        /// </summary>
        /// <param name="box">The combo box (not null)</param>
        /// <param name="ent">The entity type that the combo is for (if null, the combo will
        /// be empty)</param>
        /// <param name="handle">The ID handle that should be defined to correspond with the
        /// first available ID (may be null). If there are no available IDs for the specified
        /// entity type, any ID previously reserved will be released.</param>
        /// <returns>The number of IDs that were loaded into the combo (if any)</returns>
        internal static int LoadIdCombo(ComboBox box, IEntity ent, IdHandle handle)
        {
            if (box == null)
            {
                throw new ArgumentNullException();
            }

            // Clear out anything that was in the combo before.
            box.Items.Clear();

            if (ent == null)
            {
                return(0);
            }

            // Get a list of all the available IDs for the specified entity type...

            IdManager idMan = CadastralMapModel.Current.IdManager;

            if (idMan == null)
            {
                return(0);
            }

            IdGroup group = idMan.GetGroup(ent);

            if (group == null)
            {
                return(0);
            }

            // Get the available IDs for the group
            uint[] avail = group.GetAvailIds();

            // If we didn't find any, obtain an extra allocation
            if (avail.Length == 0)
            {
                IdPacket newPacket = group.GetAllocation(true); // with announcement
                avail = group.GetAvailIds();
                if (avail.Length == 0)
                {
                    throw new ApplicationException("Cannot obtain ID allocation");
                }
            }

            // Load the combo
            DisplayId[] ids = new DisplayId[avail.Length];
            for (int i = 0; i < ids.Length; i++)
            {
                ids[i] = new DisplayId(group, avail[i]);
            }

            box.Items.AddRange(ids);

            // Reserve the first available ID if a handle was supplied (and select it)
            if (handle != null)
            {
                IdPacket p = group.FindPacket(avail[0]);
                handle.ReserveId(p, ent, avail[0]);
                box.SelectedItem = ids[0];
            }

            return(avail.Length);
        }
Example #13
0
 /// <summary>
 /// Resets everything in the class to null values.
 /// </summary>
 void Reset()
 {
     m_Packet = null;
     m_Entity = null;
     m_Id = 0;
 }
Example #14
0
        /// <summary>
        /// Reserves a feature ID in a specific ID packet
        /// </summary>
        /// <devnote>This function is called by LoadIdCombo</devnote>
        /// <param name="packet">The ID packet containing the available ID.</param>
        /// <param name="ent">The entity type that the ID is for.</param>
        /// <param name="id">The available ID to reserve.</param>
        /// <returns>True if the ID was successfully reserved.</returns>
        internal bool ReserveId(IdPacket packet, IEntity ent, uint id)
        {
            // Ensure that any currently reserved ID is released.
            FreeReservedId();

            // Just get the packet to do it.
            if (packet.ReserveId(id))
            {
                m_Packet = packet;
                m_Id = id;
                m_Entity = ent;
                return true;
            }

            this.Reset();
            return false;
        }
Example #15
0
        /// <summary>
        /// Defines a newly reserved ID.
        /// </summary>
        /// <param name="packet">The ID packet.</param>
        /// <param name="ent">The entity type for the ID.</param>
        /// <param name="id">The raw ID number.</param>
        /// <returns>True if the ID was valid.</returns>
        internal bool Define(IdPacket packet, IEntity ent, uint id)
        {
            // The ID has to be valid.
            if (id==0)
                return false;

            // Remember the supplied info.
            m_Packet = packet;
            m_Id = id;
            m_Entity = ent;

            return true;
        }
Example #16
0
 /// <summary>
 /// Associates an ID allocation with this group
 /// </summary>
 /// <param name="a">The allocation associated with this group</param>
 /// <returns>The ID packet corresponding to the supplied allocation</returns>
 internal IdPacket AddIdPacket(IdAllocation a)
 {
     IdPacket result = new IdPacket(this, a);
     m_Packets.Add(result);
     m_MaxAllocatedId = Math.Max(m_MaxAllocatedId, a.HighestId);
     return result;
 }