Imports System.Collections.ObjectModel Imports System.Data.SQLite Imports System.IO Imports EgtUILib Imports EgtWPFLib5 Imports System.Text.RegularExpressions Public Class Slab Inherits VMBase #Region "FIELDS & PROPERTIES" Private m_bRefreshImage As Boolean = False Friend Const DB_SLABS As String = "Slabs" Friend Const DB_ID As String = "Id" Friend Const DB_IMAGEPATH As String = "ImagePath" Friend Const DB_STATE As String = "State" Friend Const DB_PROJASSIGNEDTO As String = "ProjectAssignedTo" Friend Const DB_MATERIAL As String = "Material" Friend Const DB_THICKNESS As String = "Thickness" Friend Const DB_WAREHOUSEPOS As String = "WarehousePosition" Friend Const DB_ADDEDDATE As String = "AddedDate" Friend Const DB_ISSELECTED As String = "IsSelected" Friend Const DB_TIMESTAMP As String = "TimeStamp" Friend Const DB_DATATIME As String = "DataTime" Friend Shared IndexAddedDate As Integer = 7 Friend Shared m_IsEnabledBtn As Action(Of Boolean) Public Enum StateOpt As Integer AVAILABLE = 1 ASSIGNED = 2 TAKEN = 3 End Enum Public ReadOnly Property CapsLock As String Get If MainData.bCapsLock Then Return "Upper" End If Return "Normal" End Get End Property Private m_IsModifiedId As Boolean = False Friend ReadOnly Property IsModifiedId As Boolean Get Return m_IsModifiedId End Get End Property Private m_OrigId As String Friend ReadOnly Property OrigId As String Get Return m_OrigId End Get End Property Private m_Id As String Public Property Id As String Get SplitID(m_Id, m_sNbrID, m_sNameBlock) RefreshPage() Return m_Id End Get Set(value As String) SetID(value) End Set End Property ' assegno il valore di ID alla proprietà privata Private Sub SetID(value As String) If Not String.IsNullOrWhiteSpace(value) Then m_Id = value m_IsModifiedId = m_Id <> m_OrigId Else NotifyPropertyChanged("Id") End If m_IsEnabledBtn(IsValid And IsModified) If Not String.IsNullOrWhiteSpace(m_IdError) Then LibMap.refStatusBarVM.SetOutputMessage(m_IdError, 5, MSG_TYPE.ERROR_) End If End Sub '-------------------------INIZIO NUOVA GESTIONE ID ------------------------- Private m_sOrigNbrID As String = String.Empty Private m_sNbrID As String = String.Empty Public Property sNbrID As String Get Return m_sNbrID End Get Set(value As String) Dim nVal As Integer = 0 If Not StringToInt(value, nVal) Then m_sNbrID = value Else m_sNbrID = GetNbrToString(nVal) End If ' eventualmente ricostruisco il nuovo valore Identificativo BuildID() RefreshPage() End Set End Property Private m_sOrigNameBlock As String = String.Empty Private m_sNameBlock As String = String.Empty Public Property sNameBlock As String Get Return m_sNameBlock End Get Set(value As String) If m_sNameBlock.Trim <> value.Trim Then ' se il valore indicato è uguale a quello iniziale allora recupero l'indice originale If value.Trim <> m_sOrigNameBlock Then ' azzero il contatore e cerco il primo indice libero m_sNbrID = GenerateIdNbr(value) Else m_sNbrID = m_sOrigNbrID End If m_sNameBlock = value BuildID() RefreshPage() End If End Set End Property ' ricevuto l'ID della lastra estrae il nome del blocco e l'indice Friend Shared Sub SplitID(ByVal sID As String, ByRef sRefNbr As String, ByRef sRefNameBlock As String) Dim sItems As String() = sID.Split("-"c) Dim bOk As Boolean = False If sItems.Count = 2 Then ' verifico che il secondo termine sia un numero Dim nVal As Integer = 0 If StringToInt(sItems(1), nVal) Then ' allora assegno i valori sRefNameBlock = sItems(0).Trim sRefNbr = GetNbrToString(nVal) bOk = True End If End If If bOk And Not MainData.bEnableTextId Then Return ' altimenti devo nascondere il campo Block e lasciare attivo solo il campo ID sRefNbr = sID End Sub ' assegnato l'indice restituisco il valore in formato stringa aggiugendo gli zeri Friend Shared Function GetNbrToString(nVal As Integer) As String Dim sVal As String = String.Empty If nVal < 10 Then sVal = "00" & nVal.ToString ElseIf nVal > 10 And nVal < 100 Then sVal = "0" & nVal.ToString Else sVal = nVal.ToString End If Return sVal.Trim End Function Private Sub BuildID() If Not String.IsNullOrEmpty(m_sNameBlock) Then m_Id = m_sNameBlock.Trim & " - " & m_sNbrID.Trim Else m_Id = m_sNbrID End If ' assegno il valore alla proprietà SetID(m_Id) End Sub Private Sub RefreshPage() NotifyPropertyChanged("sNbrID") NotifyPropertyChanged("sNameBlock") End Sub '-------------------------FINE NUOVA GESTIONE ID ------------------------- Public ReadOnly Property GraphicalImagePath As BitMapImage Get Dim src As BitMapImage = New BitMapImage() src.BeginInit() src.DecodePixelWidth = 256 If m_bRefreshImage Then ' se immagine modificata allora deve essere ricaricata src.CacheOption = BitmapCacheOption.None src.UriCachePolicy = New Net.Cache.RequestCachePolicy(Net.Cache.RequestCacheLevel.BypassCache) src.CacheOption = BitmapCacheOption.OnLoad src.CreateOptions = BitmapCreateOptions.IgnoreImageCache m_bRefreshImage = False Else src.CacheOption = BitmapCacheOption.OnLoad End If src.UriSource = New Uri(m_ImagePath, UriKind.Absolute) src.EndInit() Return src End Get End Property Private m_IsModifiedImagePath As Boolean = False Friend ReadOnly Property IsModifiedImagePath As Boolean Get Return m_IsModifiedImagePath End Get End Property Private m_OrigImagePath As String Private m_ImagePath As String Public Property ImagePath As String Get Return m_ImagePath End Get Set(value As String) If Not String.IsNullOrWhiteSpace(value) Then m_ImagePath = value m_IsModifiedImagePath = m_ImagePath <> m_OrigImagePath Else NotifyPropertyChanged("ImagePath") End If m_IsEnabledBtn(IsValid And IsModified) If Not String.IsNullOrWhiteSpace(m_ImagePathError) Then LibMap.refStatusBarVM.SetOutputMessage(m_ImagePathError, 5, MSG_TYPE.ERROR_) End If End Set End Property Public Function NewPhotoPath(Newpath As String) As Boolean Dim bOk As Boolean = False ' devo ricaricare l'immagine nella scena senza assegnare la db il nome del file bOk = PhotoMap.refDetailPageVM.LoadPhoto(Newpath) EgtZoom(ZM.ALL) m_bRefreshImage = True NotifyPropertyChanged("GraphicalImagePath") Return bOk End Function Private m_IsModifiedState As Boolean = False Friend ReadOnly Property IsModifiedState As Boolean Get Return m_IsModifiedState End Get End Property Private m_OrigState As StateOpt Private m_State As StateOpt Private m_LastState As StateOpt Public Property State As StateOpt Get Return m_State End Get Set(value As StateOpt) m_LastState = m_State End Set End Property Public Function SetStatus(nStatus As StateOpt) As Boolean Dim sMessage As String = String.Empty Select Case nStatus Case StateOpt.TAKEN If String.IsNullOrEmpty(Me.ProjectAssignedTo) Then Return False sMessage = String.Format(EgtMsg(92202), Me.ProjectAssignedTo & vbCrLf) If MessageBox.Show(sMessage, EgtMsg(92201), MessageBoxButton.OKCancel, MessageBoxImage.Question) = MessageBoxResult.Cancel Then Return False End If Case StateOpt.ASSIGNED If Not MainData.bIsOmagOFFICE AndAlso String.IsNullOrEmpty(Me.ProjectAssignedTo) Then sMessage = String.Format(EgtMsg(92203), Me.ProjectAssignedTo & vbCrLf) If MessageBox.Show(sMessage, EgtMsg(92201), MessageBoxButton.OKCancel, MessageBoxImage.Question) = MessageBoxResult.Cancel Then Return False End If End If Case StateOpt.AVAILABLE If Not MainData.bIsOmagOFFICE AndAlso Not String.IsNullOrEmpty(Me.ProjectAssignedTo) Then sMessage = String.Format(EgtMsg(92204), Me.ProjectAssignedTo & vbCrLf) If MessageBox.Show(sMessage, EgtMsg(92201), MessageBoxButton.OKCancel, MessageBoxImage.Question) = MessageBoxResult.Cancel Then Return False End If End If End Select m_State = nStatus m_IsModifiedState = m_State <> m_OrigState m_IsEnabledBtn(IsValid And IsModified) Return True End Function Private m_IsModifiedProjectAssignedTo As Boolean = False Friend ReadOnly Property IsModifiedProjectAssignedTo As Boolean Get Return m_IsModifiedProjectAssignedTo End Get End Property Private m_OrigProjectAssignedTo As String Private m_ProjectAssignedTo As String Public Property ProjectAssignedTo As String Get Return m_ProjectAssignedTo End Get Set(value As String) m_ProjectAssignedTo = value m_IsModifiedProjectAssignedTo = m_ProjectAssignedTo <> m_OrigProjectAssignedTo m_IsEnabledBtn(IsValid And IsModified) End Set End Property Private m_IsModifiedMaterial As Boolean = False Friend ReadOnly Property IsModifiedMaterial As Boolean Get Return m_IsModifiedMaterial End Get End Property Private m_OrigMaterial As String Private m_Material As String Public Property Material As String Get Return m_Material End Get Set(value As String) m_Material = value m_IsModifiedMaterial = m_Material <> m_OrigMaterial m_IsEnabledBtn(IsValid And IsModified) NotifyPropertyChanged("Material") End Set End Property Public Sub SetMaterial(sMaterial As String) m_Material = sMaterial NotifyPropertyChanged("Material") End Sub Private m_IsModifiedThickness As Boolean = False Friend ReadOnly Property IsModifiedThickness As Boolean Get Return m_IsModifiedThickness End Get End Property Private m_OrigThickness As Double Private m_Thickness As Double Public Property Thickness As String Get If m_Thickness < EPS_SMALL Then Return "" Return LenToString(m_Thickness, 2) End Get Set(value As String) Dim dThickness As Double = 0 If StringToLen(value, dThickness) And dThickness > -EPS_ZERO Then m_Thickness = dThickness m_IsModifiedThickness = m_Thickness <> m_OrigThickness Else NotifyPropertyChanged("Thickness") End If m_IsEnabledBtn(IsValid) If Not String.IsNullOrWhiteSpace(m_ThicknessError) Then LibMap.refStatusBarVM.SetOutputMessage(m_ThicknessError, 5, MSG_TYPE.ERROR_) Return End If If Not PhotoMap.refDetailPageVM.UpdatePhoto() Then EgtOutLog("Modifica spessore: Errore in fase di scalatura (UpdatePhoto)") End If EgtDraw() End Set End Property Friend Function GetThickness() As Double Return m_Thickness End Function Private m_IsModifiedWarehousePosition As Boolean = False Friend ReadOnly Property IsModifiedWarehousePosition As Boolean Get Return m_IsModifiedWarehousePosition End Get End Property Private m_OrigWarehousePosition As String Private m_WarehousePosition As String Public Property WarehousePosition As String Get Return m_WarehousePosition End Get Set(value As String) m_WarehousePosition = value m_IsModifiedWarehousePosition = m_WarehousePosition <> m_OrigWarehousePosition m_IsEnabledBtn(IsValid And IsModified) NotifyPropertyChanged("WarehousePosition") End Set End Property Private m_AddedDate As Date Public Property AddedDate As Date Get Return m_AddedDate End Get Set(value As Date) m_AddedDate = value End Set End Property Private m_IsLoaded As Boolean Public Property IsLoaded As Boolean Get Return m_IsLoaded End Get Set(value As Boolean) m_IsLoaded = value NotifyPropertyChanged("IsLoaded") End Set End Property Private m_IsSelected As Integer = 0 Public Property IsSelected As Integer Get Return m_IsSelected End Get Set(value As Integer) m_IsSelected = value NotifyPropertyChanged("IsSelected") NotifyPropertyChanged("BackGroundColor") End Set End Property Public ReadOnly Property BackGroundColor As SolidColorBrush Get ' In attesa di gestire l'aggiornamento della pagina (lettura della tabella DataTime nuova) If m_IsSelected = 0 Then Return DirectCast(New BrushConverter().ConvertFrom("LightGray"), SolidColorBrush) Else Return DirectCast(New BrushConverter().ConvertFrom("DarkOrange"), SolidColorBrush) End If Return DirectCast(New BrushConverter().ConvertFrom("LightGray"), SolidColorBrush) End Get End Property Public ReadOnly Property Slab_Tooltip As String Get Dim CurrState As String = String.Empty For Index = 0 To PhotoMap.refProjectVM.StateList.Count - 1 If PhotoMap.refProjectVM.StateList(Index).Id = m_State Then CurrState = PhotoMap.refProjectVM.StateList(Index).Name End If Next Dim Tooltip As String = EgtMsg(MSG_SLAB + 1) & ": " & m_Id & Environment.NewLine & EgtMsg(MSG_SLAB + 3) & ": " & CurrState & Environment.NewLine & EgtMsg(MSG_SLAB + 4) & ": " & m_ProjectAssignedTo & Environment.NewLine & EgtMsg(MSG_RAWPARTPAGEUC + 9) & ": " & m_Material & Environment.NewLine & EgtMsg(MSG_RAWPARTPAGEUC + 5) & ": " & Thickness & Environment.NewLine & EgtMsg(MSG_SLAB + 5) & ": " & m_WarehousePosition & Environment.NewLine & EgtMsg(MSG_SLAB + 6) & ": " & m_AddedDate & Environment.NewLine & "In reading" & ": " & m_IsSelected.ToString Return Tooltip End Get End Property #End Region ' FIELDS & PROPERTIES #Region "CONSTRUCTOR" Sub New(sId As String, sBlock As String, sPath As String, State As StateOpt, sProjectAssignedTo As String, Material As String, dThickness As Double, sWarehousePosition As String) m_sNbrID = sId m_sNameBlock = sBlock ' costriosco l'ID BuildID() m_ImagePath = sPath m_State = State m_ProjectAssignedTo = sProjectAssignedTo m_Material = Material m_Thickness = dThickness m_WarehousePosition = sWarehousePosition m_AddedDate = Date.Today m_IsLoaded = False m_IsSelected = 0 End Sub Sub New(SlabReader As SQLiteDataReader) m_Id = SlabReader(DB_ID) Dim TempPath As String = SlabReader(DB_IMAGEPATH) If Not File.Exists(TempPath) Then TempPath = MainData.sPhotoDir & "\" & CStr(SlabReader(DB_IMAGEPATH)) m_ImagePath = TempPath m_State = SlabReader(DB_STATE) m_ProjectAssignedTo = If(SlabReader(DB_PROJASSIGNEDTO) Is DBNull.Value, Nothing, SlabReader(DB_PROJASSIGNEDTO)) Dim MaterialName As String = SlabReader(DB_MATERIAL) m_Material = If(Not String.IsNullOrWhiteSpace(MaterialName), MaterialName, Nothing) m_Thickness = SlabReader(DB_THICKNESS) m_WarehousePosition = SlabReader(DB_WAREHOUSEPOS) ' m_AddedDate = Date.Today ' il database corrente non funziona perchè attende un dato di tipo Intero Try Dim sData As Integer = SlabReader(DB_ADDEDDATE) ' So che l'ottava colonna è quella destinata alla data Dim sMsg As String = SlabReader.GetString(IndexAddedDate) m_AddedDate = CDate(sMsg) Catch ex As Exception m_AddedDate = Date.Today End Try m_IsSelected = If(SlabReader(DB_ISSELECTED) Is DBNull.Value, 0, SlabReader(DB_ISSELECTED)) End Sub #End Region ' CONSTRUCTOR #Region "METHODS" Private m_IdError As String Public ReadOnly Property IdErrorMsg As String Get Return m_IdError End Get End Property Private m_ImagePathError As String Public ReadOnly Property ImagePathErrorMsg As String Get Return m_ImagePathError End Get End Property Private m_ThicknessError As String Public ReadOnly Property ThicknessErrorMsg As String Get Return m_ThicknessError End Get End Property Private Function GetValidationError(propertyName As String) As Boolean Dim bOk As Boolean = True Select Case propertyName Case "Id" bOk = Me.ValidateId() Case "ImagePath" bOk = Me.ValidateImagePath() Case "Thickness" bOk = Me.ValidateThickness() End Select Return bOk End Function ''' ''' Returns true if this object has no validation errors. ''' Public ReadOnly Property IsValid() As Boolean Get For Each [property] As String In ValidatedProperties If Not GetValidationError([property]) Then Return False End If Next [property] Return True End Get End Property Private Shared ReadOnly ValidatedProperties() As String = {"Id", "ImagePath", "Thickness"} Private Function ValidateId() As Boolean m_IdError = String.Empty ' AndAlso Not m_Id.IndexOfAny("[~`!@#$%^&*()-+=|{}':;.,<>/?]".ToCharArray) <> -1 If Not String.IsNullOrEmpty(m_Id) Then For Each Slab In PhotoMap.refProjectVM.SlabList If Slab IsNot Me AndAlso Slab.Id = m_Id Then ' Nome già utilizzato m_IdError = EgtMsg(MSG_SLAB + 1) 'LibMap.refStatusBarVM.SetOutputMessage(sMsg, 3, MSG_TYPE.ERROR_) Return False End If Next Return True Else ' Il nome è obbligatorio m_IdError = EgtMsg(MSG_SLAB + 2) 'LibMap.refStatusBarVM.SetOutputMessage(sMsg, 3, MSG_TYPE.ERROR_) Return False End If End Function Friend Shared Function ValidateIntgerId(nLastId As Integer) As Integer ' AndAlso Not m_Id.IndexOfAny("[~`!@#$%^&*()-+=|{}':;.,<>/?]".ToCharArray) <> -1 Dim bIsValidId As Boolean = False While Not bIsValidId If Not String.IsNullOrEmpty(nLastId) Then bIsValidId = True For Each Slab In PhotoMap.refProjectVM.SlabList ' verifico che sia un numero Dim nVal As Integer = 0 If StringToInt(Slab.Id, nVal) Then If nLastId = nVal Then ' incremento l'indice e riparto a controllare da capo nLastId += 1 bIsValidId = False ' Nome già utilizzato Exit For End If End If Next End If End While Return nLastId End Function ' genero l'ID secondo le nuove regole: ricavo genro il primo indice libero Friend Shared Function GenerateIdNbr(sNewNameBlcok As String) As String Dim nLastIndex As Integer = 1 ' se non esiste nessuno nome blocco allora il valore Id deve essere univoco If String.IsNullOrEmpty(sNewNameBlcok) Or String.IsNullOrWhiteSpace(sNewNameBlcok) Then nLastIndex = ValidateIntgerId(nLastIndex) Return GetNbrToString(nLastIndex) End If ' recupero l'ultimo indice salvato (prelevato da file Config.ini di Omga-PHOTO) If Not String.IsNullOrEmpty(nLastIndex) Then For Each Slab In PhotoMap.refProjectVM.SlabList Dim sNbr As String = String.Empty Dim sBlock As String = String.Empty Dim sCurrID As String = Slab.Id.Trim ' Assegnato l'ID corrente recupero il numero e il nome del blocco SplitID(sCurrID, sNbr, sBlock) ' se l'ID corrente è del tipo NomeBlocco-NN If Not String.IsNullOrEmpty(sBlock) AndAlso IsNumeric(sNbr) Then ' se è lo stesso nome del blocco If sNewNameBlcok.Trim = sBlock Then If nLastIndex <= CInt(sNbr) Then nLastIndex = CInt(sNbr) + 1 End If End If End If Next End If Return GetNbrToString(nLastIndex) End Function Private Function ValidateImagePath() As Boolean m_ImagePathError = String.Empty If Not String.IsNullOrEmpty(m_ImagePath) Then Return True ' Il nome immagine è obbligatorio m_ImagePathError = EgtMsg(MSG_SLAB + 3) Return False End Function Private Function ValidateThickness() As Boolean m_ThicknessError = String.Empty If Not IsNothing(m_Thickness) Then Dim dThickness As Double = 0 StringToLen(m_Thickness, dThickness) If dThickness > EPS_SMALL Then Return True ' Non sono ammessi spessori negativi m_ThicknessError = EgtMsg(MSG_RAWPARTPAGEUC + 18) 'LibMap.refStatusBarVM.SetOutputMessage(sMsg, 3, MSG_TYPE.ERROR_) Return False End If Return False End Function Public ReadOnly Property IsModified() As Boolean Get Return m_IsModifiedId OrElse m_IsModifiedImagePath OrElse m_IsModifiedState OrElse m_IsModifiedProjectAssignedTo OrElse m_IsModifiedMaterial OrElse m_IsModifiedThickness OrElse m_IsModifiedWarehousePosition End Get End Property Friend Sub ResetIsModified() m_IsModifiedId = False m_IsModifiedImagePath = False m_IsModifiedState = False m_IsModifiedProjectAssignedTo = False m_IsModifiedMaterial = False m_IsModifiedThickness = False m_IsModifiedWarehousePosition = False End Sub Friend Sub SetOrigValues() m_OrigId = m_Id SplitID(m_Id, m_sOrigNbrID, m_sOrigNameBlock) m_OrigImagePath = m_ImagePath m_OrigState = m_State m_OrigProjectAssignedTo = m_ProjectAssignedTo m_OrigMaterial = m_Material m_OrigThickness = m_Thickness m_OrigWarehousePosition = m_WarehousePosition End Sub Public Sub UpDateComboBox() NotifyPropertyChanged("Selected") End Sub #End Region ' METHODS End Class Public Class Material Private m_nId As Integer Private m_sName As String Public ReadOnly Property nId As Integer Get Return m_nId End Get End Property Public Property sName As String Get Return m_sName End Get Set(value As String) m_sName = value End Set End Property Sub New(sName As String, MaterialList As ObservableCollection(Of Material)) Dim nMaxId As Integer = 0 For Each Material In MaterialList If Material.nId > nMaxId Then nMaxId = Material.nId End If Next m_nId = nMaxId + 1 m_sName = sName End Sub Sub New(nId As Integer, sName As String) m_nId = nId m_sName = sName End Sub End Class ''' ''' Class that represent a Converter that convert mm in inch if necessary for the param depth. ''' Public Class StateIndexConverter Implements IMultiValueConverter Dim StateList As List(Of IdNameStruct) Public Function Convert(value() As Object, targetType As Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object Implements IMultiValueConverter.Convert If Not TypeOf value(1) Is List(Of IdNameStruct) Then Return value(0) StateList = DirectCast(value(1), List(Of IdNameStruct)) Dim SelState As Slab.StateOpt If Not TypeOf value(0) Is Slab.StateOpt Then Return value(0) SelState = DirectCast(value(0), Slab.StateOpt) For Index = 0 To StateList.Count - 1 If StateList(Index).Id = SelState Then Return Index End If Next Return value End Function Public Function ConvertBack(value As Object, targetType() As Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object() Implements IMultiValueConverter.ConvertBack Return {StateList(value).Id} End Function End Class Public Class DataTimeRecord Private m_CurrentKey As String Public Property CurrentKey As String Get Return m_CurrentKey End Get Set(value As String) m_CurrentKey = value End Set End Property Private m_sLastDate As String Public Property sLastDate As String Get Return m_sLastDate End Get Set(value As String) m_sLastDate = value End Set End Property Sub New(SlabReader As SQLiteDataReader) m_CurrentKey = SlabReader("Id") Try ' So che l'ottava colonna è quella destinata alla data Dim sMsg As String = SlabReader.GetString(1) m_sLastDate = sMsg Catch ex As Exception End Try End Sub End Class