Click Handlers¶
Per-handler implementation details for the five context menu items in FCoreModule_Popup.vb. For the high-level overview, see Menu Items. For the reset algorithm specifically, see Reset Module Algorithm.
Common preamble¶
Every handler starts with the same null-check:
If Activator Is Nothing OrElse Activator.m_CoreModule Is Nothing Then Exit Sub
Dim curCoreModule As CCoreModule = Activator.m_CoreModule
This is defensive — under normal flow Activator is always set by MyTabPage.ShowContextMenu before the popup opens. The early exit means a click on a stale popup is a silent no-op rather than an NPE.
Refresh Module¶
Private Sub btnRefresh_ItemClick(...) Handles btnRefresh.ItemClick
If Activator Is Nothing OrElse Activator.m_CoreModule Is Nothing Then Exit Sub
Dim curCoreModule As CCoreModule = Activator.m_CoreModule
Dim parentForm As Form = Activator.FindForm
If parentForm IsNot Nothing Then parentForm.Cursor = Cursors.WaitCursor
Try
For Each curTabPage As MyTabPage In curCoreModule.m_TabControl.TabPages
If curTabPage.RefreshWithModule Then
curTabPage.PulseContainer.RefreshAllBoxes()
End If
Next
Finally
If parentForm IsNot Nothing Then parentForm.Cursor = Cursors.Default
End Try
End Sub
Iterates each Pulse tab in the module's inner m_TabControl and calls PulseContainer.RefreshAllBoxes() on tabs flagged RefreshWithModule. Lifted directly from the per-module loop in Main.vb (around line 1484) used by the global Refresh button.
The Try/Finally around the loop guarantees the wait cursor is restored even if a refresh throws.
Reset Module to Default Settings…¶
The biggest handler. Three phases: 1. Resolve the default-tab folder for this module (with company-default override). 2. Confirm with the user. 3. Apply the changes — remove non-defaults, reset/create matching tabs, reorder.
See Reset Module Algorithm for the full walkthrough.
Save and Share Module…¶
Private Sub btnSaveAndShare_ItemClick(...) Handles btnSaveAndShare.ItemClick
If Activator Is Nothing OrElse Activator.m_CoreModule Is Nothing Then Exit Sub
Dim curCoreModule As CCoreModule = Activator.m_CoreModule
curCoreModule.Settings.RaiseOnDataSave() ' (1)
Dim newSS As New SaveAndShare.CSaveAndShareFile
newSS.FileName = curCoreModule.ModuleInfo.ModuleCaption ' (2)
newSS.SerialData = curCoreModule.Settings.m_SerialData
newSS.SettingsType = SaveAndShare.SettingsType.CORE_MODULE
newSS.ShowSaveAsForm(Activator.FindForm) ' (3)
End Sub
RaiseOnDataSave()triggersCCoreModule.Settings_DataSaveBegin(around line 374), which flushes the liveMyTabPageinstances back intoCoreModuleData.m_BoxModuleTabs. Without this, recently-edited tabs would be missing from the saved payload.- Default filename is the module's display caption (e.g. "Customer Service"). The user can change it in the Save-As form.
ShowSaveAsFormis the existing UI for the Save-and-Share dialog. Not new — same dialog used by the per-tab Save and Share.
The result is a .psm (or whatever extension CSaveAndShareFile.ShowSaveAsForm chooses based on SettingsType.CORE_MODULE) — the receiving side of this is Load Module from File….
Publish Module…¶
Private Sub btnPublish_ItemClick(...) Handles btnPublish.ItemClick
If Activator Is Nothing OrElse Activator.m_CoreModule Is Nothing Then Exit Sub
Dim curCoreModule As CCoreModule = Activator.m_CoreModule
curCoreModule.Settings.RaiseOnDataSave()
Dim newPF As New SaveAndShare.CPublishInfo_CSD_1(
curCoreModule.Settings.m_SerialData,
SaveAndShare.SettingsType.CORE_MODULE)
newPF.PublishPolicy.PublishPolicyCode = SaveAndShare.PolicyCode.Everyone
newPF.PublishMap.Add("Module", curCoreModule.ModuleInfo.ModuleID)
newPF.ShowPublishForm(Instance.MainForm)
End Sub
Builds a CPublishInfo_CSD_1 matching exactly the shape CPulseConnection.ProcessPublishQueue expects:
| Field | Value | Why |
|---|---|---|
SerialData |
curCoreModule.Settings.m_SerialData |
The CCoreModuleData payload |
SettingsType |
CORE_MODULE |
Discriminator the receiver dispatches on |
PublishPolicy.PublishPolicyCode |
PolicyCode.Everyone |
Default — recipients see it as a normal published item |
PublishMap("Module") |
ModuleID |
Receiver uses this to find \<ModuleID>.core virtual file |
ShowPublishForm is the existing publishing UI — picks recipients, writes to their PublishQueue columns. See Publish/Receive Loop for the receiving side.
Load Module from File…¶
Private Sub btnLoadFromFile_ItemClick(...) Handles btnLoadFromFile.ItemClick
If Activator Is Nothing OrElse Activator.m_CoreModule Is Nothing Then Exit Sub
Dim fileDialog As New OpenFileDialog
fileDialog.DefaultExt = "pmod"
fileDialog.Filter = "Pulse Module (*.pmod)|*.pmod"
If fileDialog.ShowDialog() <> DialogResult.OK Then Exit Sub
Try
Dim buffer() As Byte
Using fileStream As New IO.FileStream(fileDialog.FileName, IO.FileMode.Open)
ReDim buffer(fileStream.Length - 1)
fileStream.Read(buffer, 0, fileStream.Length)
End Using
Dim ssFile As SaveAndShareFile = FileIO.Functions.DeserializeFromBuffer(
buffer, FileIO.SerializationFlags.UseCompression)
' Confirm: replacing the module wipes out the current tabs.
If MsgBox(
"Loading this file will replace all tabs in the '" &
Activator.m_CoreModule.ModuleInfo.ModuleCaption &
"' module with the contents of '" &
IO.Path.GetFileName(fileDialog.FileName) & "'." &
vbCrLf & vbCrLf & "Continue?",
MsgBoxStyle.OkCancel Or MsgBoxStyle.Question, "Load Module") <> MsgBoxResult.Ok Then
Exit Sub
End If
Dim parentForm As Form = Activator.FindForm
If parentForm IsNot Nothing Then parentForm.Cursor = Cursors.WaitCursor
Try
Dim newCoreData As CCoreModuleData = FileIO.Functions.DeserializeFromBuffer(
ssFile.SaveAndShareData.ToArray, FileIO.SerializationFlags.UseCompression)
newCoreData = newCoreData.UpgradeSerialData
Activator.m_CoreModule.CoreModuleData = newCoreData
Activator.m_CoreModule.Settings.RaiseOnDataLoad()
Activator.m_CoreModule.m_TabControl.PerformLayout()
Finally
If parentForm IsNot Nothing Then parentForm.Cursor = Cursors.Default
End Try
Catch ex As Exception
MsgBox("This file is not a valid Pulse Module (pmod) file." & vbCrLf & vbCrLf & ex.Message,
MsgBoxStyle.Exclamation, "Load Module")
End Try
End Sub
Key steps¶
- Open dialog with filter for
*.pmod. The extension.pmodwas chosen by analogy with the existing.ptab/.pboxconventions; if the existing Save-and-Share machinery writes core modules with a different extension, changeDefaultExtandFilterto match. - Read the file into a byte buffer. Standard
FileStream.Readpattern. - Deserialize as a
SaveAndShareFile. This is the outer envelope. - Confirm with the user before mutating anything.
- Deserialize the inner
CCoreModuleDatafromssFile.SaveAndShareData. UpgradeSerialData— runs the schema migration if the file is from an older Pulse version.- Assign and raise —
m_CoreModule.CoreModuleData = newCoreDatafollowed bySettings.RaiseOnDataLoad(). The existingCCoreModule.Settings_DataLoadEndhandler (inCCoreModule.vbaround line 335) does the actual tab-rebuild work. PerformLayout()— forces a layout pass on the inner tab control.
Error handling¶
The whole thing is wrapped in Try/Catch. If any step fails (file read, deserialize, etc.), the user gets an MsgBox saying it's not a valid .pmod file. A more granular error path could distinguish "file IO failure" from "malformed payload" but the user-facing distinction is small enough that the catch-all is acceptable.