/// <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)); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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()); }
/// <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); }
/// <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)); } }
/// <summary> /// Resets everything in the class to null values. /// </summary> void Reset() { m_Packet = null; m_Entity = null; m_Id = 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); }
/// <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; }
/// <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; }
/// <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; }