Project editor: Handle controls from missing components gracefully.

[DEVELOPMENT ENVIRONMENT]
* NEW: Form editor: When a control cannot be loaded because of a missing
  component, now display the form with a red background, in read-only
  mode, and with a button that allows to remove all controls whose
  component is missing.
* NEW: Update French translation.
* NEW: Project properties dialog: Save the project before opening the dialog.
This commit is contained in:
gambas 2022-04-02 20:07:06 +02:00
parent 377a66d985
commit 0883d7f084
13 changed files with 7421 additions and 7449 deletions

File diff suppressed because it is too large Load diff

View file

@ -100,7 +100,7 @@ Public Sub CheckErrorMessage(hEditor As FEditor)
If hEditor Then
If hEditor.Name == $sPosClass And If hEditor.GetEditor().Line = ($iPosLine - 1) Then
hEditor.ShowErrorMessage($sError, "error")
hEditor.ShowErrorMessage($sError)
Else If $iPosLine > hEditor.GetEditor().Count Then
sPath = Project.FindForm(hEditor.Name)
FMain.ShowError($sError, sPath)

View file

@ -846,7 +846,7 @@ Public Sub mnuUpperCase_Click()
End
Public Sub ShowErrorMessage(sMsg As String, (sIcon) As String)
Public Sub ShowErrorMessage(sMsg As String)
$hEditor.SetFocus
Wait

View file

@ -2690,7 +2690,7 @@ Public Sub ShowMessage(sMsg As String, Optional sIcon As String, Optional bNoEsc
End
Public Sub ShowErrorMessage(sMsg As String, (sIcon) As String)
Public Sub ShowErrorMessage(sMsg As String)
$hEditor.SetFocus
Wait

View file

@ -966,7 +966,7 @@ Public Sub mnuUpperCase_Click()
End
Public Sub ShowErrorMessage(sMsg As String, (sIcon) As String)
Public Sub ShowErrorMessage(sMsg As String)
$hEditor.SetFocus
Wait

View file

@ -22,6 +22,7 @@ Public {Public} As Boolean
Public VirtualCoord As Boolean
Public NoParent As Boolean
Public Tabs As Collection
Public Locked As Boolean ' When the component of the control is missing
Property Read X As Integer
Property Read Y As Integer
@ -173,6 +174,7 @@ Private Function CreateControl(sName As String, sClass As String, hParent As Obj
hClass = Project.Documentation.Classes[sClass]
bExist = hClass <> Null
If bExist Then
DrawWith = hClass.DrawWith
If DrawWith Then
sClass = DrawWith
@ -182,8 +184,10 @@ Private Function CreateControl(sName As String, sClass As String, hParent As Obj
sClass = Left(sClass, iPos - 1)
Endif
Endif
NoParent = Not hClass.ConstructorNeedParent()
Endif
NoParent = Not hClass.ConstructorNeedParent()
If IsMultiContainer() Then
If sClass <> "TabPanel" And If sClass <> "TabStrip" Then
@ -317,11 +321,16 @@ Private Function CreateControl(sName As String, sClass As String, hParent As Obj
hCtrl = New (sClass) ' Timer(hParent)
Endif
Else If Locked Then
hCtrl = New TabPanel(hParent)
hCtrl.ShowTabBar = False
Else
If bExist Then Try hCtrl = New (sClass, hParent)
If Not hCtrl Then Try hCtrl = New ($hFamily.Name & sClass, hParent)
If Not hCtrl Then hCtrl = New DrawingArea(hParent)
If Not hCtrl Then hCtrl = New TabPanel(hParent)
Endif
@ -400,6 +409,7 @@ Private Sub GetDefaultTabText(iIndex As Integer) As String
Dim hClass As CClassInfo
Dim sText As String
If Locked Then Return
hClass = Project.Documentation.Classes[Kind]
sText = hClass.DefaultText
If Not sText Then sText = "Tab &1"
@ -419,6 +429,11 @@ Public Sub _new(sName As String, sClass As String, hParent As CControl, hForm As
$hFamily = hFamily
hClass = Project.Documentation.Classes[sClass]
If Not hClass Then
'FMain.ShowError(Subst(("Component missing for control &1"), sClass))
hClass = Project.Documentation.Classes["TabStrip"]
Locked = True
Endif
Try $bIsContainer = hClass.Container
Try $bIsMultiContainer = hClass.MultiContainer
@ -462,6 +477,11 @@ Public Sub _new(sName As String, sClass As String, hParent As CControl, hForm As
hCtrl.Ignore = True
'$cValue["Ignore"] = True
Else If Locked Then
hCtrl = CreateControl(sName, "TabPanel", Parent.Control)
Unknown = True
Else
'If Not Parent Then Stop
@ -471,7 +491,7 @@ Public Sub _new(sName As String, sClass As String, hParent As CControl, hForm As
Endif
hCtrl.Drop = True
hCtrl.Drop = Not Locked
'hCtrl.Tracking = True
Endif

View file

@ -0,0 +1,39 @@
' Gambas class file
Public Sub _new()
gvwUnknown.AddColumn(("Control")).Expand = True
gvwUnknown.AddColumn(("Class"), -1)
End
Public Sub Run(hForm As FForm) As Boolean
Dim hCtrl As CControl
Dim I As Integer
For Each hCtrl In hForm.Control
If hCtrl.Locked Then
I = gvwUnknown.Rows.Count
Inc gvwUnknown.Rows.Count
gvwUnknown[I, 0].Text = hCtrl.Name
gvwUnknown[I, 1].Text = hCtrl.Kind
Endif
Next
Return Not Me.ShowModal()
End
Public Sub btnOK_Click()
Me.Close(True)
End
Public Sub btnCancel_Click()
Me.Close
End

View file

@ -0,0 +1,47 @@
# Gambas Form File 3.0
{ Form Form
MoveScaled(0,0,64,43)
Text = ("Delete controls from missing components")
Resizable = False
Arrangement = Arrange.Vertical
Spacing = True
Margin = True
{ HBox2 HBox
MoveScaled(1,1,62,6)
Spacing = True
{ PictureBox1 PictureBox
MoveScaled(0,0,7,11)
Picture = Picture.Load("icon:/large/trash")
}
{ TextLabel1 TextLabel
MoveScaled(8,0,47,5)
Expand = True
Text = ("The following controls will be removed.")
Alignment = Align.Normal
}
}
{ gvwUnknown GridView
MoveScaled(1,8,62,29)
Expand = True
}
{ HBox1 HBox
MoveScaled(1,38,62,4)
Spacing = True
{ Panel1 Panel
MoveScaled(4,0,4,4)
Expand = True
}
{ btnOK Button
MoveScaled(29,0,16,4)
Text = ("Delete")
Picture = Picture["icon:/small/trash"]
Default = True
}
{ btnCancel Button
MoveScaled(46,0,16,4)
Text = ("Cancel")
Cancel = True
}
}
}

View file

@ -65,6 +65,8 @@ Private $bDoNotArrange As Boolean
Private $cAction As Collection
Private $cToolbar As Collection
Private $bMissingControls As Boolean
Private $hContainer As CControl
Private $iContX As Integer
Private $iContY As Integer
@ -152,15 +154,17 @@ Public Sub Reload() As Boolean
Control[Me.Name] = Null
AllMenus.Clear
Endif
$bMissingControls = False
$bDoNotModify = True
$bAfterLock = False
sData = Mid$(sData, Len(Project.FORM_MAGIC) + 1)
Inc $iLockArrangement
'Inc $iLockArrangement
sErr = FromString(sData)
Dec $iLockArrangement
'Dec $iLockArrangement
If sErr Then Error.Raise(sErr)
@ -275,20 +279,20 @@ Private Sub FromString(sData As String, Optional hParent As CControl) As String
' Check that controls exist first
For Each sLine In aData
sLine = Trim(sLine)
If Left(sLine) = "{" Then
Inc iLevel
sClass = Split(Trim(Mid$(sLine, 2)), " ")[1]
If Left$(sClass) = "#" Then sClass = Mid$(sClass, 2)
If Not Project.Documentation.Classes.Exist(sClass) Then
Return Subst(("Unknown control: &1"), sClass)
Endif
Else If sLine = "}" Then
Dec iLevel
If iLevel = 0 Then Break
Endif
Next
' For Each sLine In aData
' sLine = Trim(sLine)
' If Left(sLine) = "{" Then
' Inc iLevel
' sClass = Split(Trim(Mid$(sLine, 2)), " ")[1]
' If Left$(sClass) = "#" Then sClass = Mid$(sClass, 2)
' If Not Project.Documentation.Classes.Exist(sClass) Then
' Return Subst(("Unknown control: &1"), sClass)
' Endif
' Else If sLine = "}" Then
' Dec iLevel
' If iLevel = 0 Then Break
' Endif
' Next
hCtrl = hParent
bFirst = True
@ -570,6 +574,7 @@ Private Sub FromString(sData As String, Optional hParent As CControl) As String
If Not hParent Then hParent = RootControl
ArrangeContainerByDefault(hParent, True, True)
SetMissingControls
End
@ -1357,13 +1362,8 @@ Public Function CreateControl(sClass As String, hParent As CControl, Optional sN
sName = GetName(sName)
Endif
' If the component is not loaded, then return null
If Not Project.Documentation.Classes.Exist(sClass) Then
FMain.ShowError(Subst(("Component missing for control &1"), sClass))
hCtrl = New CControl(sName, "DrawingArea", hParent, Me, $hFamily)
Else
hCtrl = New CControl(sName, sClass, hParent, Me, $hFamily)
Endif
hCtrl = New CControl(sName, sClass, hParent, Me, $hFamily)
If hCtrl.Locked Then $bMissingControls = True
$hUndo.Add("RemoveControl", [sName])
@ -1826,6 +1826,27 @@ Public Sub DeleteSelection()
End
Private Sub DeleteUnknown()
Dim hCCtrl As CControl
Dim aCtrl As New CControl[]
For Each hCCtrl In Control
If hCCtrl.Locked Then aCtrl.Add(hCCtrl)
Next
$bMissingControls = False
SetReadOnly()
For Each hCCtrl In aCtrl
hCCtrl.Delete
Next
Save(True)
End
Public Sub GetSelection(Optional bAbsolute As Boolean, Optional aSelection As CControl[]) As String
Dim hCtrl As CControl
@ -2436,7 +2457,7 @@ Private Sub CreatePopupMenu()
'If Not $bReadOnly Then
If Master Then
If Master And If Not Master.Locked Then
aCtrl = Project.Documentation.Classes[Master.Kind].Events
sGroup = Master.GetGroup()
Else
@ -2478,7 +2499,7 @@ Private Sub CreatePopupMenu()
mnuChange.Children.Clear
If Selection.Count = 1 Then
If Selection.Count = 1 And If Not Master.Locked Then
hClass = Project.Documentation.Classes[Master.Kind]
For Each sName In hClass.GetSimilars()
@ -2540,16 +2561,17 @@ Private Sub UpdateMenu()
Action[".text-*,.format-*,.undo,.redo", Me].Visible = Not bReadOnly
bOn = Not IsNull(Master) And Not bReadOnly
Action[".cut,.copy,.copy-same,.delete,.lower,.raise", Me].Enabled = bOn
Action[".cut,.copy,.copy-same,.lower,.raise", Me].Enabled = bOn
Action[".delete", Me].Enabled = bOn
Action[".paste", Me].Enabled = CanPaste()
mnuArrange.Visible = Not bReadOnly
mnuChange.Visible = Not bReadOnly
If mnuChange.Children.Count = 0 Then mnuChange.Hide
Action[".save,.cut,.paste,paste-form,.delete,.lower,.raise,.arrange*", Me].Visible = Not bReadOnly
Action[".save,.cut,.paste,.lower,.raise,.arrange*,.delete", Me].Visible = Not bReadOnly
Action[".delete-unknown", Me].Visible = $bMissingControls
bOn = Selection.Count >= 2 And Not bReadOnly
@ -2872,7 +2894,7 @@ End
Public Sub SetReadOnly()
$bReadOnly = False
If Project.ReadOnly Or If Project.Running Or If Project.IsReadOnly(Path) Then
If Project.ReadOnly Or If Project.Running Or If Project.IsReadOnly(Path) Or If $bMissingControls Then
$bReadOnly = True
Endif
FFormStack.RefreshReadOnly
@ -3183,6 +3205,8 @@ End
'
Public Sub Handle_MouseDown()
If $bMissingControls Then Return
$bMove = True
$X = Mouse.ScreenX
$Y = Mouse.ScreenY
@ -3241,6 +3265,8 @@ End
Public Sub Handle_MouseUp()
If Not $bMove Then Return
If $hUndo.IsDisabled() Then $hUndo.Enable
$hUndo.End
$bMove = False
@ -3358,6 +3384,9 @@ Public Sub Action_Activate((Key) As String) As Boolean
Case ".diff"
UpdateDiffMode
Case ".delete-unknown"
If Not FDeleteUnknown.Run(Me) Then DeleteUnknown
Default
Return True
@ -4132,6 +4161,8 @@ Public Sub CheckHovered(Optional hCtrl As Control)
Dim sTag As String
If Not RootControl Then Return
If $iLockArrangement Then Return
If $bMissingControls Then Return
If Not hCtrl Then
hCont = RootControl.Control
@ -4663,3 +4694,35 @@ Public Sub UpdateRemote()
Action[".run-me", Me].Picture = Project.GetDebuggerIcon(tlbForm.Size)
End
Private Sub SetMissingControls()
Dim iCol As Integer
If $bMissingControls Then
iCol = Color.RGB(255, 0, 0)
If Application.DarkTheme Then iCol = Color.Invert(iCol, True)
iCol = Color.SetAlpha(iCol, 192)
panUnknown.Background = iCol
panUnknown.Raise
panUnknown.Show
lblUnknown.Padding = Desktop.Scale * 2
Else
panUnknown.Hide
Endif
SetReadOnly
End
Public Sub panBorder_Arrange()
panUnknown.Move(panBorder.X, panBorder.Y, panBorder.W, panBorder.H)
End

View file

@ -239,6 +239,11 @@
}
{ mnuSep4 Menu
}
{ mnuDeleteUnknown Menu
Action = ".delete-unknown"
Text = ("Delete controls from missing components") & "..."
Picture = Picture["icon:/small/trash"]
}
{ Menu7 Menu
Action = ".locked"
Text = ("Locked")
@ -612,11 +617,18 @@
Action = ".format-foreground"
Picture = Picture["icon:/small/pen"]
}
{ btnRemoveUnknown ToolButton
MoveScaled(48,4,43,4)
Action = ".delete-unknown"
AutoResize = True
Text = ("Delete controls from missing components") & "..."
Picture = Picture["icon:/small/trash"]
}
{ Spring1 Spring
MoveScaled(42,4,7,4)
MoveScaled(106,4,7,4)
}
{ ToolButton7 ToolButton
MoveScaled(51,4,4,4)
MoveScaled(115,4,4,4)
ToolTip = ("Lock / unlock form")
Action = ".locked"
Picture = Picture["icon:/small/lock"]
@ -668,21 +680,21 @@
}
{ panRight Panel Handle
Name = "panRight"
MoveScaled(8,16,1,1)
MoveScaled(6,8,1,1)
Background = Color.TextBackground
Mouse = Cursor.SizeE
Border = Border.Plain
}
{ panDown Panel Handle
Name = "panDown"
MoveScaled(6,18,1,1)
MoveScaled(4,10,1,1)
Background = Color.TextBackground
Mouse = Cursor.SizeS
Border = Border.Plain
}
{ panRightDown Panel Handle
Name = "panRightDown"
MoveScaled(8,18,1,1)
MoveScaled(6,10,1,1)
Background = Color.TextBackground
Mouse = Cursor.SizeNWSE
Border = Border.Plain
@ -727,9 +739,25 @@
NoBackground = True
}
}
{ panUnknown Panel
MoveScaled(0,16,24,19)
Visible = False
Centered = True
Margin = True
{ lblUnknown TextLabel
MoveScaled(2,2,34,13)
Font = Font["Bold,+1"]
Background = &H20F4F4F4&
Padding = 16
AutoResize = True
Border = Border.Plain
Text = ("Some controls couldn't be loaded because of missing components.")
Alignment = Align.Center
}
}
}
{ dwgBackground DrawingArea
MoveScaled(76,26,12,9)
MoveScaled(75,25,12,9)
Background = Color.LightForeground
Ignore = True
}
@ -840,6 +868,11 @@
Shortcut = ""
Picture = "img/32/delete-container.png"
}
{ Action delete-unknown
Text = "Delete controls from missing components"
Shortcut = ""
Picture = "icon:/small/trash"
}
{ Action diff
Text = "Show modifications"
Picture = "icon:/small/modified"
@ -1007,7 +1040,7 @@
{ Toolbars
{ Toolbar form
Text = "Form"
List = "show-class,diff,diff-previous,diff-next,save,reload,run-me,undo,redo,cut,copy,paste,delete,menu,grid,tooltip,delete-container,embed-container,raise,lower,align-top,align-bottom,align-left,align-right,same-width,same-height,arrange-vertical,arrange-horizontal,arrange-column,arrange-row,arrange-hcenter,arrange-vcenter,move-tab-first,move-tab-previous,move-tab-next,move-tab-last,show-tab,text-font,text-bold,text-italic,text-underline,text-zoom-in,text-zoom-out,text-zoom-normal,format-background,format-foreground,locked"
Default = "show-class,diff,diff-previous,diff-next,|,save,reload,|,undo,redo,|,menu,grid,tooltip,|,|,raise,lower,align-top,align-bottom,align-left,align-right,same-width,same-height,arrange-hcenter,arrange-vcenter,|,move-tab-first,move-tab-previous,move-tab-next,move-tab-last,show-tab,|,text-font,text-bold,text-italic,text-underline,text-zoom-in,text-zoom-out,text-zoom-normal,format-background,format-foreground,~,locked"
List = "show-class,diff,diff-previous,diff-next,save,reload,run-me,undo,redo,cut,copy,paste,delete,menu,grid,tooltip,delete-container,embed-container,raise,lower,align-top,align-bottom,align-left,align-right,same-width,same-height,arrange-vertical,arrange-horizontal,arrange-column,arrange-row,arrange-hcenter,arrange-vcenter,move-tab-first,move-tab-previous,move-tab-next,move-tab-last,show-tab,text-font,text-bold,text-italic,text-underline,text-zoom-in,text-zoom-out,text-zoom-normal,format-background,format-foreground,delete-unknown,locked"
Default = "show-class,diff,diff-previous,diff-next,|,save,reload,|,undo,redo,|,menu,grid,tooltip,|,|,raise,lower,align-top,align-bottom,align-left,align-right,same-width,same-height,arrange-hcenter,arrange-vcenter,|,move-tab-first,move-tab-previous,move-tab-next,move-tab-last,show-tab,|,text-font,text-bold,text-italic,text-underline,text-zoom-in,text-zoom-out,text-zoom-normal,format-background,format-foreground,delete-unknown,~,locked"
}
}

View file

@ -134,24 +134,30 @@ Public Sub RefreshAll()
If sClass = "" Then
$hObject = hCtrl
sClass = hCtrl.Kind
Else If sClass <> hCtrl.Kind Then
Endif
If sClass <> hCtrl.Kind Then
bDiff = True
Break
Endif
Next
If bDiff Then sClass = $hFamily.ControlClass
grdProperty.Enabled = Not $hObject.Locked
UpdateLabel
$sClass = sClass
If bDiff Then sClass = $hFamily.ControlClass
If $hObject.Locked Then
$sClass = $hObject.Kind
Else
$sClass = sClass
Endif
'PRINT "Kind = "; sClass
'cProp = CControl.PropertiesInOrder[sClass]
Try aProp = Project.Documentation.Classes[sClass].PropertyList
Try aProp = Project.Documentation.Classes[$sClass].PropertyList
If Not aProp Then
Error "gambas3: cannot get property list of "; sClass
'Error "gambas3: cannot get property list of "; sClass
aProp = New String[]
Else
' sClassColor = sClass
@ -234,37 +240,17 @@ Public Sub RefreshAll()
' Can be lesser than predicted, as some properties may be hidden
grdProperty.Rows.Count = iRow
'grdProperty.Rows.Count = iRow
' iRow = 3
' WHILE aColor.Count
' FOR iRow = iRow TO aColor[0] + 2
' grdProperty[iRow, 0].
' NEXT
' WEND
' FOR iRow = 0 TO grdProperty.Rows.Count - 1
' grdProperty[iRow, 0].Font = grdProperty.Font
' grdProperty[iRow, 0].Font.Bold = TRUE
' grdProperty[iRow, 0].Alignment = Align.TopNormal
' grdProperty[iRow, 1].Alignment = Align.TopNormal
' NEXT
Form_Resize
panProperty.Show
sepProperty.Show
'lblMessage.Hide
'lblMessage.Ignore = TRUE
grdProperty.Show
lblName.Show
'VSplit1.Show
If Not $bMany Then
FFormStack.SelectCurrent
Endif
'If btnLock.Value Then
If $sFocus Then
iRow = FindProperty($sFocus)
If iRow >= 0 Then
@ -272,6 +258,8 @@ Public Sub RefreshAll()
ShowProperty
Endif
Endif
Return
@ -313,6 +301,7 @@ Public Sub RefreshOne(hCtrl As CControl, sProp As String)
If Not $bMany Then
If $hObject <> hCtrl Then Return
If $hObject.Locked Then Return
Endif
If sProp = "Name" Then
@ -446,12 +435,15 @@ Public Function SaveProperty() As Boolean
If $bMany Then
For Each hCtrl In $hForm.Selection
If hCtrl.Locked Then Continue
If hCtrl.SetProperty($sLast, vVal) Then Goto _BAD
Next
Else
If $hObject.SetProperty($sLast, vVal) Then Goto _BAD
If Not $hObject.Locked Then
If $hObject.SetProperty($sLast, vVal) Then Goto _BAD
Endif
Endif
@ -919,6 +911,7 @@ Private Sub GetConnection() As String
Dim sResult As String
For Each hCtrl In $hForm.Selection
If hCtrl.Locked Then Continue
sConn = hCtrl.GetConnection()
If Not sResult Then
sResult = sConn
@ -938,6 +931,7 @@ Private Sub GetTable(Optional sField As String) As String
Dim sResult As String
For Each hCtrl In $hForm.Selection
If hCtrl.Locked Then Continue
sTable = hCtrl.GetTable(sField)
If Not sResult Then
sResult = sTable
@ -1139,6 +1133,8 @@ Public Function GetProperty(sProp As String) As String
For Each hCtrl In $hForm.Selection
If hCtrl.Locked Then Continue
If bFirst Then
If sVal <> hCtrl.GetPropertyString(sProp) Then
CControl.WasDefaultValue = False

View file

@ -2380,9 +2380,9 @@ Private Sub CompileError(sMsg As String)
Endif
If hEditor Then
hForm.ShowErrorMessage(sMsg, "make")
hForm.ShowErrorMessage(sMsg)
Else
FMain.ShowMessage(sMsg, "make")
FMain.ShowError(sMsg)
Endif
'Catch

View file

@ -73,6 +73,8 @@ Public Sub Form_Open()
Me.Title = ("Project properties") & " - " & Project.Name
Project.Save
lblName.Text = Project.Name
txtPath.Text = File.Dir(Project.Dir)
'txtName.Text = "<font size=\"+2\"><b>" & Project.Name & "</b></font><br>" & File.Dir(Project.Dir)