diff --git a/app/TaskFlow/My Project/licenses.licx b/app/TaskFlow/My Project/licenses.licx
index 1bfb691..9b6e497 100644
--- a/app/TaskFlow/My Project/licenses.licx
+++ b/app/TaskFlow/My Project/licenses.licx
@@ -1,16 +1,17 @@
-DevExpress.XtraEditors.LookUpEdit, DevExpress.XtraEditors.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
-DevExpress.XtraLayout.LayoutControl, DevExpress.XtraLayout.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
-DevExpress.XtraEditors.TextEdit, DevExpress.XtraEditors.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
-DevExpress.XtraEditors.ComboBoxEdit, DevExpress.XtraEditors.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
-DevExpress.XtraEditors.Repository.RepositoryItemComboBox, DevExpress.XtraEditors.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
-DevExpress.XtraGrid.GridControl, DevExpress.XtraGrid.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
-DevExpress.XtraDataLayout.DataLayoutControl, DevExpress.XtraLayout.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
-DevExpress.XtraEditors.PictureEdit, DevExpress.XtraEditors.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
-DevExpress.XtraVerticalGrid.PropertyGridControl, DevExpress.XtraVerticalGrid.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
-DevExpress.XtraTreeList.TreeList, DevExpress.XtraTreeList.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
-DevExpress.XtraBars.BarManager, DevExpress.XtraBars.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
-DevExpress.XtraEditors.CheckEdit, DevExpress.XtraEditors.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
-DevExpress.XtraBars.Ribbon.RibbonControl, DevExpress.XtraBars.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
-DevExpress.XtraEditors.Repository.RepositoryItemProgressBar, DevExpress.XtraEditors.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
-DevExpress.XtraCharts.ChartControl, DevExpress.XtraCharts.v21.2.UI, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
DevExpress.XtraNavBar.NavBarControl, DevExpress.XtraNavBar.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
+DevExpress.XtraEditors.PictureEdit, DevExpress.XtraEditors.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
+DevExpress.XtraBars.Ribbon.RibbonControl, DevExpress.XtraBars.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
+DevExpress.XtraLayout.LayoutControl, DevExpress.XtraLayout.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
+DevExpress.XtraTreeList.TreeList, DevExpress.XtraTreeList.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
+DevExpress.XtraEditors.Repository.RepositoryItemComboBox, DevExpress.XtraEditors.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
+DevExpress.XtraEditors.TextEdit, DevExpress.XtraEditors.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
+DevExpress.XtraDataLayout.DataLayoutControl, DevExpress.XtraLayout.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
+DevExpress.XtraEditors.TreeListLookUpEdit, DevExpress.XtraTreeList.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
+DevExpress.XtraEditors.ComboBoxEdit, DevExpress.XtraEditors.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
+DevExpress.XtraGrid.GridControl, DevExpress.XtraGrid.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
+DevExpress.XtraBars.BarManager, DevExpress.XtraBars.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
+DevExpress.XtraCharts.ChartControl, DevExpress.XtraCharts.v21.2.UI, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
+DevExpress.XtraVerticalGrid.PropertyGridControl, DevExpress.XtraVerticalGrid.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
+DevExpress.XtraEditors.LookUpEdit, DevExpress.XtraEditors.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
+DevExpress.XtraEditors.Repository.RepositoryItemProgressBar, DevExpress.XtraEditors.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
+DevExpress.XtraEditors.CheckEdit, DevExpress.XtraEditors.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
diff --git a/app/TaskFlow/TaskFlow.vbproj b/app/TaskFlow/TaskFlow.vbproj
index a6ee759..70dc920 100644
--- a/app/TaskFlow/TaskFlow.vbproj
+++ b/app/TaskFlow/TaskFlow.vbproj
@@ -504,6 +504,12 @@
+
+ crmCockpit_UserTest.vb
+
+
+ Form
+
True
True
@@ -565,6 +571,12 @@
Form
+
+ frmCockpitConfig.vb
+
+
+ Form
+
frmConnection.vb
@@ -722,6 +734,12 @@
Form
+
+ frmUserSelect.vb
+
+
+ Form
+
frmValidator.vb
@@ -792,6 +810,9 @@
+
+ crmCockpit_UserTest.vb
+
frmAbout.vb
Designer
@@ -832,6 +853,10 @@
frmClientLogin.vb
Designer
+
+ frmCockpitConfig.vb
+ Designer
+
frmConnection.vb
Designer
@@ -970,6 +995,9 @@
frmMain.vb
Designer
+
+ frmUserSelect.vb
+
frmValidator.vb
Designer
diff --git a/app/TaskFlow/crmCockpit_UserTest.Designer.vb b/app/TaskFlow/crmCockpit_UserTest.Designer.vb
new file mode 100644
index 0000000..af8b39a
--- /dev/null
+++ b/app/TaskFlow/crmCockpit_UserTest.Designer.vb
@@ -0,0 +1,88 @@
+ _
+Partial Class crmCockpit_UserTest
+ Inherits DevExpress.XtraEditors.XtraForm
+
+ 'Das Formular überschreibt den Löschvorgang, um die Komponentenliste zu bereinigen.
+ _
+ Protected Overrides Sub Dispose(ByVal disposing As Boolean)
+ Try
+ If disposing AndAlso components IsNot Nothing Then
+ components.Dispose()
+ End If
+ Finally
+ MyBase.Dispose(disposing)
+ End Try
+ End Sub
+
+ 'Wird vom Windows Form-Designer benötigt.
+ Private components As System.ComponentModel.IContainer
+
+ 'Hinweis: Die folgende Prozedur ist für den Windows Form-Designer erforderlich.
+ 'Das Bearbeiten ist mit dem Windows Form-Designer möglich.
+ 'Das Bearbeiten mit dem Code-Editor ist nicht möglich.
+ _
+ Private Sub InitializeComponent()
+ Me.components = New System.ComponentModel.Container()
+ Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(crmCockpit_UserTest))
+ Me.ImageCollection1 = New DevExpress.Utils.ImageCollection(Me.components)
+ Me.TreeList_Cockpit = New DevExpress.XtraTreeList.TreeList()
+ CType(Me.ImageCollection1, System.ComponentModel.ISupportInitialize).BeginInit()
+ CType(Me.TreeList_Cockpit, System.ComponentModel.ISupportInitialize).BeginInit()
+ Me.SuspendLayout()
+ '
+ 'ImageCollection1
+ '
+ Me.ImageCollection1.ImageSize = New System.Drawing.Size(24, 24)
+ Me.ImageCollection1.ImageStream = CType(resources.GetObject("ImageCollection1.ImageStream"), DevExpress.Utils.ImageCollectionStreamer)
+ Me.ImageCollection1.Images.SetKeyName(0, "overview")
+ Me.ImageCollection1.Images.SetKeyName(1, "profile")
+ Me.ImageCollection1.Images.SetKeyName(2, "monitor")
+ Me.ImageCollection1.Images.SetKeyName(3, "chart")
+ '
+ 'TreeList_Cockpit
+ '
+ Me.TreeList_Cockpit.Dock = System.Windows.Forms.DockStyle.Left
+ Me.TreeList_Cockpit.Font = New System.Drawing.Font("Tahoma", 9.75!)
+ Me.TreeList_Cockpit.ImageIndexFieldName = "ICON_INDEX"
+ Me.TreeList_Cockpit.KeyFieldName = "PK_CFG_COCKPIT_DEFINITION_ID"
+ Me.TreeList_Cockpit.Location = New System.Drawing.Point(0, 0)
+ Me.TreeList_Cockpit.Name = "TreeList_Cockpit"
+ Me.TreeList_Cockpit.OptionsBehavior.Editable = False
+ Me.TreeList_Cockpit.OptionsBehavior.PopulateServiceColumns = True
+ Me.TreeList_Cockpit.OptionsBehavior.ReadOnly = True
+ Me.TreeList_Cockpit.OptionsLayout.AddNewColumns = False
+ Me.TreeList_Cockpit.OptionsMenu.ShowExpandCollapseItems = False
+ Me.TreeList_Cockpit.OptionsSelection.EnableAppearanceFocusedCell = False
+ Me.TreeList_Cockpit.OptionsView.ShowColumns = False
+ Me.TreeList_Cockpit.OptionsView.ShowFilterPanelMode = DevExpress.XtraTreeList.ShowFilterPanelMode.Never
+ Me.TreeList_Cockpit.OptionsView.ShowFirstLines = False
+ Me.TreeList_Cockpit.OptionsView.ShowHorzLines = False
+ Me.TreeList_Cockpit.OptionsView.ShowIndentAsRowStyle = True
+ Me.TreeList_Cockpit.OptionsView.ShowIndicator = False
+ Me.TreeList_Cockpit.OptionsView.ShowVertLines = False
+ Me.TreeList_Cockpit.OptionsView.TreeLineStyle = DevExpress.XtraTreeList.LineStyle.Dark
+ Me.TreeList_Cockpit.ParentFieldName = "Parent_ID"
+ Me.TreeList_Cockpit.SelectImageList = Me.ImageCollection1
+ Me.TreeList_Cockpit.Size = New System.Drawing.Size(375, 588)
+ Me.TreeList_Cockpit.TabIndex = 12
+ '
+ 'crmCockpit_UserTest
+ '
+ Me.Appearance.Options.UseFont = True
+ Me.AutoScaleDimensions = New System.Drawing.SizeF(7.0!, 17.0!)
+ Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
+ Me.ClientSize = New System.Drawing.Size(933, 588)
+ Me.Controls.Add(Me.TreeList_Cockpit)
+ Me.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.Margin = New System.Windows.Forms.Padding(4, 4, 4, 4)
+ Me.Name = "crmCockpit_UserTest"
+ Me.Text = "crmCockpit_UserTest"
+ CType(Me.ImageCollection1, System.ComponentModel.ISupportInitialize).EndInit()
+ CType(Me.TreeList_Cockpit, System.ComponentModel.ISupportInitialize).EndInit()
+ Me.ResumeLayout(False)
+
+ End Sub
+
+ Friend WithEvents ImageCollection1 As DevExpress.Utils.ImageCollection
+ Friend WithEvents TreeList_Cockpit As DevExpress.XtraTreeList.TreeList
+End Class
diff --git a/app/TaskFlow/crmCockpit_UserTest.resx b/app/TaskFlow/crmCockpit_UserTest.resx
new file mode 100644
index 0000000..fad6699
--- /dev/null
+++ b/app/TaskFlow/crmCockpit_UserTest.resx
@@ -0,0 +1,182 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFpEZXZFeHByZXNzLlV0aWxzLnYyMS4yLCBWZXJzaW9uPTIxLjIu
+ NC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI4OGQxNzU0ZDcwMGU0OWEMAwAAAFFT
+ eXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRv
+ a2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAAChEZXZFeHByZXNzLlV0aWxzLkltYWdlQ29sbGVjdGlvblN0
+ cmVhbWVyAgAAAAlJbWFnZVNpemUERGF0YQQHE1N5c3RlbS5EcmF3aW5nLlNpemUDAAAAAgIAAAAF/P//
+ /xNTeXN0ZW0uRHJhd2luZy5TaXplAgAAAAV3aWR0aAZoZWlnaHQAAAgIAwAAABgAAAAYAAAACQUAAAAP
+ BQAAACcLAAAC+gIAAIlQTkcNChoKAAAADUlIRFIAAAAYAAAAGAgGAAAA4Hc9+AAAAARnQU1BAACxjwv8
+ YQUAAAAJcEhZcwAADrwAAA68AZW8ckkAAAKcSURBVEhL3ZTLaxNRFMYLrvRfkD4yc5OgFeeZIIiLVkrV
+ Jq1O6SNGqxUhCtZVkWBIbQitdOVS3AlZtXUnKAq1mUcmr6aPpCVod9KmuBbXn8z0NTMki9Yuij/4uDNn
+ 7jnfnLl3blPTf4PO0NBYAp2lkGFc0BgXVMaF/GUKzrnHQhbcSItepHkCjaWg827IXBt0jj4w0JhmKIwL
+ CkdD4QhUjoLKUrsjR5l5Km/kEhRZYn8xxUeQET3QuGYU2BbzocpeRMZi8E8oAo0lznNQTObdWDS7cbzJ
+ cTE+kc57kGM8ZlGNd0MR3MjxhwYK14o0TyEtEhgdy37alC4SfLne8dte0cE3H420QGCuBU+wKO4mZ32H
+ XZ1+5ubmzjjlnHNsMqwLMu9CWmjGgq8FC/4WyCKFPHtC/4Gxd50xg7wlXpFuoizdwNrALZSHAqhYNRjA
+ +lAP1ocDqA734UdIstczdo0tsEdWrG98ZDJC/UJWg5XXiZ5qLJoyNRFLVeMvU9V4NPU9Hk3Zs+qgCjSy
+ b9+0OeNWg1pEwtbTAWyNhQ60PTaM2rNBFGZmvPZMB5+uMn8UgTIXdl+qSENr0NnpQ74moMgR5AWCrOA2
+ tcQSrF44ocOuwBN8HXnU+/H5k0vvOzvPf5Ck1s+PR9qXLbtrdXraU4pNRlYmkqZKhianIqVYMmLG958l
+ k5Gfs7NnbQZ5f/0zp2g5izb7e1AJBbAWDmLtXi8q9wOoGKOhcBDrd4PYCPViIxTE5mDAXi9/xVvXoJHx
+ kWlkYO1gJxxELdyH7Qe3URvtx86ohNrDO/g10ofS+HjCnulA9xEURQq6n0ZO9CInelAQPLAaLL17da4c
+ f9FVTsS7ylMJU8tTcfPeXq0B890d7fPBPRnX3R3tzjlH5S88LZDGXf/36QAAAABJRU5ErkJggjMCAACJ
+ UE5HDQoaCgAAAA1JSERSAAAAGAAAABgIBgAAAOB3PfgAAAAEZ0FNQQAAsY8L/GEFAAAACXBIWXMAAA68
+ AAAOvAGVvHJJAAAB1UlEQVRIS+2Uu24aQRSGz7hImqTLA1DQpIwiFCF5l9vewciSCysRRap0KEqRmhoW
+ h1swVdLbZaS8gzsXKfwGlgs3thUMhuGPZmE3u3iXTBuJTxrtzsw58885c2aItvzXAGDh/vnHz/vhfiL1
+ ev1pmwib2hEReozg+4yNPO7VXfx4++FFdLUY/EWa6ZeXbragullFdbO66v1nCmono6idV1nVt59Ubcz1
+ HKZFLRBMxGWEL/R3Z//iyrHvFmUD3LbkfI5YNPRNnOzV0twpAZWKlL2HSE1fUoCXC1hU7MB2dFh7H7WI
+ QaRowFjgdK/lcK3ojwR5WcesYgbjp43Gk4FMaoVAP2Q4MRQ86CrO9t9998dmtoa5o+PWrAZ2LmMYhjaW
+ iDBcP4OpXcC8tKyQX7XaT24VwZ3ooUoLtBIO+cHMg2sm5oaGmfW4HEXkUgJxEQh+20VMzBy4ZeJCq96s
+ z7cYw/GOjICoooTDGlsKpkYpdq7pCcT7RRARhKtIFukUiTcmKYJNiNv/VUZg8Ow57xFBqqZX9GgZtZtK
+ 3a3PxSIEjlc57RKhs3qfRBP/fl/MDRmh641J7D7M6PWbjrc4MbQZQ4vIa83VV1RNe2d56785B5/W/bdI
+ 8werE/HGFidAHwAAAABJRU5ErkJgghADAACJUE5HDQoaCgAAAA1JSERSAAAAGAAAABgIBgAAAOB3PfgA
+ AAAEZ0FNQQAAsY8L/GEFAAAACXBIWXMAAA68AAAOvAGVvHJJAAACsklEQVRIS8VVzW7TQBDOc/AeHKom
+ 3t2Z3bVDy08R4gaqKvUZOHDoK3BDvAEHClVVceEaqKqCWtvrnyQOVPAKnHL50Dp2G6WtRNUIPmnl8ex4
+ /vzNbqfzr1BqRmIJJyzgKEBqAqTUw4nqIWYvC5yqHhK/pwI42UMiu8ikQKYEYtGF4wA5CZQqwNH9dZw7
+ H3IPLlRwTMhZISMB1zpjgZgEUpLImXAqAiRKoGBCyVQ7T5v3jCUcC4wNoSCJD0+fvKoDVMYgtuIi4hJQ
+ WMaYejOfmVZIIrPcAEZhTE3SpWHERt0owN7W5tbu9vbdRX2LMtIYa9lUYBTcDQNUljHkxsEVKO9pTAzN
+ 9lOtcHqN8YglDiP7e153pro4I4VKS0xE0+cF5BGhapPOrMJXvmw4oi5OwwCjhepKffE+vKby3EqMTZO0
+ 04RvTQW7L19QznJaapoWfV3rciNRqZVarqiLn3L13GllFX7JALmmqeP+tNVnhjBpg6da4iSc9evTo4fT
+ UksUhjBqM+h0OhPNtfzdzILOo6AAuVEo9AXVc0uYUNC2iHA8t3kVCruKLFIYqcutvAp+Dn5wU0EeMo7n
+ sr0OZ3LWpr9B1beYtDTNrcY321BqSSisxLAdtCQkxNFyA3hilC31i0hj1PZrSfAkKbmpwE9lbhmJFki0
+ bJaqn84SYn+isj9RZ6zIjETCAp4cfqVGIW5s/f9MWNb6hOe64rSqDVNLcGZ2N/jlLMNPemwVEiOxt7Nz
+ x5ef2pltYhVcSEj8cRNq5KGGM4T8Cjr/X2S0gpy7yGgVJa9i9/HG60WbW6FSBMcSZd/AD9HB883lBjix
+ Ap+twlFf4zBivH229WbR5sZ492Djy9D/MBXUnPZyfV8bAX8LZiSR3XZ+Pobrg/1obbAfrQ8OogvZr/fR
+ 2uDArg8Wv5nHH4RP7Rpx+BP5AAAAAElFTkSuQmCC2gIAAIlQTkcNChoKAAAADUlIRFIAAAAYAAAAGAgG
+ AAAA4Hc9+AAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADrwAAA68AZW8ckkAAAJ8SURBVEhL3VXNbtNA
+ EPaBQx+CQ2t7HSde24l6yKGAk1IREBd+GnCjVgEunLkgVQj1CXgCDrlwRXkEUA48AGpVQqWIZmNDiNcO
+ eYFB42Bn3VAoNFz4pNHO7oz9eXZnP0vSf4NAocA1CoFSgEgzISImcM2GQKUQEQtCzYSQUOCqEY8453HM
+ jP0IY7ge55jAV3RIX/6x0XyZYVsA8EPSyeH2zsIJQoUKFTQfzRFw2QCuWhAoBoxVIfmM4Ct5gcDdzhAE
+ cgFCZVaip5egd+3mazGnXS4vt8vOcrtWS+3N3tOLSTwSnpcOG7MtOtp6UEOCNChJUq9atY/ubD77cNe1
+ xPVfIVKECrrNhykBl+e3I9SseI2vzIj7t+51/Lrb8etbneP1G6/YptvprVVfJPHMIe/XG6cShMI8Eg/u
+ NwhJpotmbcqJnQbGxIp7PY0J/oBYE0+zJz6aak08lU48Wv6WxEOxgp910XmRvQfCIS8Kodgo4hksCqEs
+ dNHBOSrYc5wl1KqT65kKMlvkOBecH5bxT2AkT/e45ThLXJ4K25jMmiBQBYKDnT8XO5QSHLECrhjQz9vv
+ UFqSeCTKy75QAbtUbfUrV1t+ZaPFKhutT1eq8di/ff95kjNCKZENeL+7q/ceP7FRr7CFcT3JyUqFcA/O
+ Anw5Xjq82eiHsgljmcZ+khNpopoK/wMvR5mnW8zPl9jnXIn5GmXHOcpY+XI3jhfL3iBfZH5+lXl6kQ1y
+ RebpJeajFUrMN1bZHEHX/fsuOg34h0snvtu8nokuAHO69ZWYEJtCYagaMEIfR4VCkLOmc2LCSLNgiAeK
+ ljxDTBjKBfhC8FkKQ9kAtrb+NkPwr/Ad3DFsyGIxcj4AAAAASUVORK5CYIIL
+
+
+
\ No newline at end of file
diff --git a/app/TaskFlow/crmCockpit_UserTest.vb b/app/TaskFlow/crmCockpit_UserTest.vb
new file mode 100644
index 0000000..d802379
--- /dev/null
+++ b/app/TaskFlow/crmCockpit_UserTest.vb
@@ -0,0 +1,320 @@
+Imports System.Threading.Tasks
+
+Public Class crmCockpit_UserTest
+ Public CheckUserID As Integer
+ Public CheckUserName As String
+ Public CheckUserLanguage As String
+ Private _treeNodeCounts As New Dictionary(Of Integer, Integer)
+ Private GRID_LOAD_TYPE As String = "OVERVIEW"
+ Private Sub crmCockpit_UserTest_Load(sender As Object, e As EventArgs) Handles Me.Load
+ Me.Text = $"Cockpit Test for User [{CheckUserName}] - Language [{CheckUserLanguage}] "
+ Load_Treeview()
+ End Sub
+ Private Sub Load_Treeview()
+ Try
+ Me.Cursor = Cursors.WaitCursor
+ Dim oSQL = $"SELECT * FROM [dbo].[FNTF_GET_COCKPIT_DEFINITION] ({CheckUserID},'{CheckUserLanguage}')"
+ Dim oDT_STRUCTURE_NODES As DataTable = DatabaseFallback.GetDatatableECM(oSQL)
+ If oDT_STRUCTURE_NODES Is Nothing OrElse oDT_STRUCTURE_NODES.Rows.Count = 0 Then
+ Dim oMsg As String
+ Dim oTitle As String
+ Select Case CheckUserLanguage
+ Case "fr-FR", "fr-BE", "fr-CH"
+ oMsg = "Aucune configuration de cockpit n'a pu être lue. Veuillez contacter votre équipe d'administration!"
+ oTitle = "Erreur de configuration"
+ Case "es-ES", "es-MX", "es-AR"
+ oMsg = "No se pudo leer ninguna configuración de cockpit. ¡Póngase en contacto con su equipo de administración!"
+ oTitle = "Error de configuración"
+ Case "de-DE", "de-AT", "de-CH"
+ oMsg = "Es konnte keine Cockpit-Konfiguration ausgelesen werden. Kontaktieren Sie Ihr Administrationsteam!"
+ oTitle = "Konfigurationsfehler"
+ Case Else ' en-US, en-GB und alle weiteren
+ oMsg = "No cockpit configuration could be read. Please contact your administration team!"
+ oTitle = "Configuration Error"
+ End Select
+ LOGGER.Warn($"Load_Treeview: No node configuration found for CheckUserID [{CheckUserID}] - CheckUserLanguage [{CheckUserLanguage}]")
+ MsgBox(oMsg, MsgBoxStyle.Critical, oTitle)
+ Exit Sub
+ End If
+
+ ' ===== NUR AKTIVE KNOTEN BEHALTEN =====
+ If oDT_STRUCTURE_NODES.Columns.Contains("ACTIVE") Then
+ Dim oInactiveRows As DataRow() = oDT_STRUCTURE_NODES.Select("ACTIVE = 0 OR ACTIVE IS NULL")
+ If oInactiveRows.Length > 0 Then
+ LOGGER.Debug($"Load_Treeview: Removing [{oInactiveRows.Length}] inactive node(s) (ACTIVE=0 or NULL)")
+ For Each oRow As DataRow In oInactiveRows
+ oRow.Delete()
+ Next
+ oDT_STRUCTURE_NODES.AcceptChanges()
+ End If
+ Else
+ LOGGER.Warn("Load_Treeview: ACTIVE column not found in FNTF_GET_COCKPIT_DEFINITION result")
+ End If
+
+ ' ===== ANZAHL DER OVERVIEW-KNOTEN ERMITTELN (VOR WEITEREN FILTERN) =====
+ Dim oOverviewRows As DataRow() = oDT_STRUCTURE_NODES.Select("TYPE_ID = 0")
+ LOGGER.Debug($"Load_Treeview: Found [{oOverviewRows.Length}] node(s) with TYPE_ID=0 (Overview)")
+
+ ' ===== MONITOR-KNOTEN ENTFERNEN WENN KEIN RECHT =====
+ If MONITORING_ACTIVE = False AndAlso oDT_STRUCTURE_NODES.Columns.Contains("TYPE_ID") Then
+ Dim oMonitorRows As DataRow() = oDT_STRUCTURE_NODES.Select("TYPE_ID = 2")
+ If oMonitorRows.Length > 0 Then
+ LOGGER.Debug($"Load_Treeview: MONITORING_ACTIVE=False - removing [{oMonitorRows.Length}] monitor node(s) from TreeList datasource")
+ For Each oRow As DataRow In oMonitorRows
+ oRow.Delete()
+ Next
+ oDT_STRUCTURE_NODES.AcceptChanges()
+ End If
+ End If
+
+ ' ===== CHART-KNOTEN ENTFERNEN WENN KEIN RECHT =====
+ If SHOW_CHARTS = False AndAlso oDT_STRUCTURE_NODES.Columns.Contains("TYPE_ID") Then
+ Dim oChartRows As DataRow() = oDT_STRUCTURE_NODES.Select("TYPE_ID = 3")
+ If oChartRows.Length > 0 Then
+ LOGGER.Debug($"Load_Treeview: SHOW_CHARTS=False - removing [{oChartRows.Length}] chart node(s) from TreeList datasource")
+ For Each oRow As DataRow In oChartRows
+ oRow.Delete()
+ Next
+ oDT_STRUCTURE_NODES.AcceptChanges()
+ End If
+ End If
+
+ TreeList_Cockpit.BeginUpdate()
+ Try
+ TreeList_Cockpit.DataSource = oDT_STRUCTURE_NODES
+ AddHandler TreeList_Cockpit.CustomDrawNodeCell, AddressOf TreeList_Cockpit_CustomDrawNodeCell
+ TreeList_Cockpit.KeyFieldName = "PK_CFG_COCKPIT_DEFINITION_ID"
+ TreeList_Cockpit.ParentFieldName = "PARENT_ID"
+ TreeList_Cockpit.Columns("PK_RESULT_ID").SortOrder = SortOrder.Ascending
+
+ ' ===== MODERNES DESIGN =====
+ ' Schriftgröße und -art
+ TreeList_Cockpit.Appearance.Row.Font = New Font("Segoe UI", 12, FontStyle.Regular)
+ TreeList_Cockpit.Appearance.FocusedRow.Font = New Font("Segoe UI", 12, FontStyle.Bold)
+ TreeList_Cockpit.Appearance.HideSelectionRow.Font = New Font("Segoe UI", 12, FontStyle.Regular)
+
+ ' Modernes Farbschema (passend zum Office2019-Skin)
+ TreeList_Cockpit.Appearance.Row.BackColor = Color.White
+ TreeList_Cockpit.Appearance.Row.ForeColor = Color.FromArgb(50, 50, 50)
+ TreeList_Cockpit.Appearance.FocusedRow.BackColor = Color.FromArgb(210, 230, 255)
+ TreeList_Cockpit.Appearance.FocusedRow.ForeColor = Color.FromArgb(20, 20, 20)
+ TreeList_Cockpit.Appearance.HideSelectionRow.BackColor = Color.FromArgb(225, 235, 250)
+ TreeList_Cockpit.Appearance.HideSelectionRow.ForeColor = Color.FromArgb(50, 50, 50)
+
+ ' Zeilenhöhe erhöhen für bessere Lesbarkeit
+ TreeList_Cockpit.RowHeight = 28
+
+ Dim oVisibleColumns As New System.Collections.Generic.HashSet(Of String)(StringComparer.OrdinalIgnoreCase) From {"NAME"}
+ For Each oColumn As DevExpress.XtraTreeList.Columns.TreeListColumn In TreeList_Cockpit.Columns
+ oColumn.Visible = oVisibleColumns.Contains(oColumn.FieldName)
+ Next
+ Finally
+ TreeList_Cockpit.EndUpdate()
+ End Try
+
+ ' ===== KNOTEN AUF-/ZUKLAPPEN BASIEREND AUF ANZAHL DER OVERVIEW-KNOTEN =====
+ If oOverviewRows.Length = 1 Then
+ LOGGER.Debug("Load_Treeview: Only 1 overview node found - expanding all nodes")
+ For Each oNode As DevExpress.XtraTreeList.Nodes.TreeListNode In TreeList_Cockpit.Nodes
+ oNode.Expanded = True
+ Next
+ ElseIf oOverviewRows.Length > 1 Then
+ LOGGER.Debug($"Load_Treeview: [{oOverviewRows.Length}] overview nodes found - collapsing all nodes")
+ For Each oNode As DevExpress.XtraTreeList.Nodes.TreeListNode In TreeList_Cockpit.Nodes
+ oNode.Expanded = False
+ Next
+ Else
+ LOGGER.Warn("Load_Treeview: No overview nodes (TYPE_ID=0) found - keeping default collapsed state")
+ End If
+
+ TreeList_Cockpit.Refresh()
+
+ ' ===== ANZAHL ASYNCHRON NACHLADEN =====
+ If oDT_STRUCTURE_NODES.Columns.Contains("SQL_QUERY_COUNT") Then
+ AppendCountsToTreeAsync()
+ End If
+
+ Catch ex As Exception
+ LOGGER.Error(ex)
+ Finally
+ Me.Cursor = Cursors.Default
+ End Try
+ End Sub
+ Private Sub TreeList_Cockpit_CustomDrawNodeCell(sender As Object, e As DevExpress.XtraTreeList.CustomDrawNodeCellEventArgs)
+ Try
+ Dim oPk As Object = e.Node.GetValue("PK_CFG_COCKPIT_DEFINITION_ID")
+ If oPk Is Nothing OrElse IsDBNull(oPk) Then
+ Exit Sub
+ End If
+
+ Dim oPkInt As Integer = CInt(oPk)
+ If Not _treeNodeCounts.ContainsKey(oPkInt) Then
+ Exit Sub
+ End If
+
+ If _treeNodeCounts(oPkInt) > 0 Then
+ e.Appearance.Font = New Font(e.Appearance.Font, FontStyle.Bold)
+ Else
+ e.Appearance.Font = New Font(e.Appearance.Font, FontStyle.Regular)
+ End If
+ Catch ex As Exception
+ LOGGER.Error(ex)
+ End Try
+ End Sub
+ Private Async Sub AppendCountsToTreeAsync()
+ Try
+ LOGGER.Debug("AppendCountsToTreeAsync: Starting background count queries...")
+
+ Dim oWorkItems As New List(Of (Node As DevExpress.XtraTreeList.Nodes.TreeListNode, SQL As String, OriginalName As String))
+
+ TreeList_Cockpit.NodesIterator.DoOperation(
+ Sub(oNode As DevExpress.XtraTreeList.Nodes.TreeListNode)
+ Dim oTypeId As Object = oNode.GetValue("TYPE_ID")
+ Dim oProfileID As Object = oNode.GetValue("FK_PROFILE_ID")
+ If oTypeId Is Nothing OrElse IsDBNull(oTypeId) Then
+ LOGGER.Debug($"AppendCountsToTreeAsync: Node [{oNode.GetValue("NAME")}] has no TYPE_ID - skipping.")
+ Exit Sub
+ End If
+ Dim oTypeIdInt As Integer = CInt(oTypeId)
+ If oTypeIdInt <> 0 AndAlso oTypeIdInt <> 1 Then
+ Exit Sub
+ End If
+
+ Dim oSqlCount As Object = oNode.GetValue("SQL_QUERY_COUNT")
+ If oSqlCount IsNot Nothing AndAlso Not IsDBNull(oSqlCount) AndAlso Not String.IsNullOrWhiteSpace(oSqlCount.ToString()) Then
+ Dim oProfileIdInt As Integer = If(oProfileID IsNot Nothing AndAlso Not IsDBNull(oProfileID), CInt(oProfileID), 0)
+ Dim oRawSQL As String = oSqlCount.ToString()
+ LOGGER.Debug($"AppendCountsToTreeAsync: Preparing SQL for node [{oNode.GetValue("NAME")}] with PROFILE_ID [{oProfileIdInt}]")
+ LOGGER.Debug($"AppendCountsToTreeAsync: Original SQL: {oRawSQL}")
+ oRawSQL = oRawSQL.Replace("@PROFILE_ID", oProfileIdInt.ToString())
+ oRawSQL = oRawSQL.Replace("@PROFIL_ID", oProfileIdInt.ToString())
+ oRawSQL = oRawSQL.Replace("{#USER#PROFILE_ID}", oProfileIdInt.ToString())
+ oRawSQL = oRawSQL.Replace("{#USER#PROFIL_ID}", oProfileIdInt.ToString())
+ Dim oPreparedSQL As String = PrepareSQLWithReplacements(oRawSQL, oProfileIdInt)
+
+ ' ===== COUNT-SUFFIX VOM VORHERIGEN DURCHLAUF ENTFERNEN =====
+ Dim oRawName As String = oNode.GetValue("NAME")?.ToString()
+ Dim oSuffixMatch = System.Text.RegularExpressions.Regex.Match(oRawName, "^(.*)\s+\(\d+\)$")
+ Dim oCleanName As String = If(oSuffixMatch.Success, oSuffixMatch.Groups(1).Value.Trim(), oRawName)
+
+ If Not String.IsNullOrWhiteSpace(oCleanName) Then
+ oWorkItems.Add((oNode, oPreparedSQL, oCleanName))
+ End If
+ Else
+ LOGGER.Debug($"AppendCountsToTreeAsync: Node [{oNode.GetValue("NAME")}] has no valid SQL_QUERY_COUNT, skipping.")
+ End If
+ End Sub)
+
+ If oWorkItems.Count = 0 Then
+ LOGGER.Debug("AppendCountsToTreeAsync: No nodes with SQL_QUERY_COUNT found, exiting.")
+ Exit Sub
+ End If
+
+ LOGGER.Debug($"AppendCountsToTreeAsync: {oWorkItems.Count} node(s) with SQL_QUERY_COUNT found")
+
+ Dim oResults As New List(Of (Node As DevExpress.XtraTreeList.Nodes.TreeListNode, OriginalName As String, Count As String))
+
+ Await Task.Run(Sub()
+ For Each oItem In oWorkItems
+ Try
+ Dim oResult As Object = DatabaseFallback.GetScalarValueECM(oItem.SQL)
+ If oResult IsNot Nothing AndAlso Not IsDBNull(oResult) Then
+ SyncLock oResults
+ oResults.Add((oItem.Node, oItem.OriginalName, oResult.ToString()))
+ End SyncLock
+ End If
+ Catch ex As Exception
+ LOGGER.Warn($"AppendCountsToTreeAsync: Count query failed for node [{oItem.OriginalName}] - {ex.Message}")
+ End Try
+ Next
+ End Sub)
+
+ _treeNodeCounts.Clear()
+
+ TreeList_Cockpit.BeginUpdate()
+ Try
+ For Each oResult In oResults
+ Dim oPk As Object = oResult.Node.GetValue("PK_CFG_COCKPIT_DEFINITION_ID")
+ If oPk IsNot Nothing AndAlso Not IsDBNull(oPk) Then
+ Dim oCount As Integer = 0
+ Integer.TryParse(oResult.Count, oCount)
+ _treeNodeCounts(CInt(oPk)) = oCount
+ End If
+ oResult.Node.SetValue("NAME", $"{oResult.OriginalName} ({oResult.Count})")
+ LOGGER.Debug($"AppendCountsToTreeAsync: Node [{oResult.OriginalName}] → [{oResult.OriginalName} ({oResult.Count})]")
+ Next
+ Finally
+ TreeList_Cockpit.EndUpdate()
+ End Try
+
+ TreeList_Cockpit.Refresh()
+ LOGGER.Debug("AppendCountsToTreeAsync: Finished")
+ Decide_Show_Empty_Workflows(Not CONFIG.Config.Hide_Empty_Workflows)
+ Catch ex As Exception
+ LOGGER.Error(ex)
+ End Try
+ End Sub
+ ' ========================================
+ ' HILFSMETHODEN - Extrahierte Logik für Wiederverwendung
+ ' ========================================
+
+ Private Function PrepareSQLWithReplacements(oSQL As String, oProfileID As Integer) As String
+ oSQL = clsPatterns.ReplaceInternalValues(oSQL)
+ oSQL = clsPatterns.ReplaceUserValues(oSQL)
+ LOGGER.Debug("PrepareSQLWithReplacements - Original SQL: " & oSQL)
+ oSQL = oSQL.Replace("@USERNAME", USER_USERNAME)
+ oSQL = oSQL.Replace("@MACHINE_NAME", System.Environment.MachineName)
+ oSQL = oSQL.Replace("@DATE", Now.ToShortDateString)
+ ' ===== ZUSÄTZLICHE PLATZHALTER-FORMATE FÜR USER_ID =====
+ oSQL = oSQL.Replace("{#USER#USER_ID}", USER_ID)
+ oSQL = oSQL.Replace("#USER#USER_ID", USER_ID)
+ oSQL = oSQL.Replace("@USER_ID", USER_ID)
+ LOGGER.Debug("PrepareSQLWithReplacements - SQL after replacements: " & oSQL)
+ If oProfileID = 0 Then
+ If GRID_LOAD_TYPE = "OVERVIEW" Then
+ LOGGER.Debug("PrepareSQLWithReplacements called with oProfileID = 0 in OVERVIEW context")
+ Else
+ LOGGER.Warn("PrepareSQLWithReplacements called with oProfileID = 0, using CURRENT_CLICKED_PROFILE_ID instead")
+ End If
+ oProfileID = CURRENT_CLICKED_PROFILE_ID
+ Else
+ LOGGER.Debug($"PrepareSQLWithReplacements called with oProfileID = {oProfileID}")
+ End If
+ oSQL = oSQL.Replace("@PROFILE_ID", oProfileID)
+ oSQL = oSQL.Replace("@PROFIL_ID", oProfileID)
+ Return oSQL
+ End Function
+ Sub Decide_Show_Empty_Workflows(pShow As Boolean)
+ Try
+ LOGGER.Debug($"Decide_Show_Empty_Workflows: pShow=[{pShow}], cached node counts: [{_treeNodeCounts.Count}]")
+ TreeList_Cockpit.BeginUpdate()
+ Try
+ TreeList_Cockpit.NodesIterator.DoOperation(
+ Sub(oNode As DevExpress.XtraTreeList.Nodes.TreeListNode)
+ Dim oPk As Object = oNode.GetValue("PK_CFG_COCKPIT_DEFINITION_ID")
+
+ If oPk Is Nothing OrElse IsDBNull(oPk) Then
+ oNode.Visible = True
+ LOGGER.Debug($"Decide_Show_Empty_Workflows: oPk is Nothing/DBNull - Node visible set to True")
+ Exit Sub
+ End If
+
+ Dim oPkInt As Integer = CInt(oPk)
+
+ If Not _treeNodeCounts.ContainsKey(oPkInt) Then
+ oNode.Visible = True
+ LOGGER.Debug($"Decide_Show_Empty_Workflows: oPkInt [{oPkInt}] not found in _treeNodeCounts - Node visible set to True")
+ Exit Sub
+ End If
+
+ oNode.Visible = pShow OrElse (_treeNodeCounts(oPkInt) > 0)
+ End Sub)
+ Finally
+ TreeList_Cockpit.EndUpdate()
+ End Try
+ TreeList_Cockpit.Refresh()
+ Catch ex As Exception
+ LOGGER.Error(ex)
+ End Try
+ End Sub
+End Class
\ No newline at end of file
diff --git a/app/TaskFlow/frmCockpitConfig.Designer.vb b/app/TaskFlow/frmCockpitConfig.Designer.vb
new file mode 100644
index 0000000..075aa32
--- /dev/null
+++ b/app/TaskFlow/frmCockpitConfig.Designer.vb
@@ -0,0 +1,565 @@
+
+Partial Class frmCockpitConfig
+ Inherits DevExpress.XtraBars.Ribbon.RibbonForm
+
+ 'Das Formular überschreibt den Löschvorgang, um die Komponentenliste zu bereinigen.
+
+ Protected Overrides Sub Dispose(ByVal disposing As Boolean)
+ Try
+ If disposing AndAlso components IsNot Nothing Then
+ components.Dispose()
+ End If
+ Finally
+ MyBase.Dispose(disposing)
+ End Try
+ End Sub
+
+ 'Wird vom Windows Form-Designer benötigt.
+ Private components As System.ComponentModel.IContainer
+
+ 'Hinweis: Die folgende Prozedur ist für den Windows Form-Designer erforderlich.
+ 'Das Bearbeiten ist mit dem Windows Form-Designer möglich.
+ 'Das Bearbeiten mit dem Code-Editor ist nicht möglich.
+
+ Private Sub InitializeComponent()
+ Me.components = New System.ComponentModel.Container()
+ Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(frmCockpitConfig))
+ Me.RibbonControl1 = New DevExpress.XtraBars.Ribbon.RibbonControl()
+ Me.BarButtonItem1 = New DevExpress.XtraBars.BarButtonItem()
+ Me.BarButtonItem2 = New DevExpress.XtraBars.BarButtonItem()
+ Me.bbtnSQL_Data = New DevExpress.XtraBars.BarButtonItem()
+ Me.bbtnSQL_Count = New DevExpress.XtraBars.BarButtonItem()
+ Me.bbtnitm_Save = New DevExpress.XtraBars.BarButtonItem()
+ Me.BarButtonItem4 = New DevExpress.XtraBars.BarButtonItem()
+ Me.bbtnitm_NodeOverviewAdd = New DevExpress.XtraBars.BarButtonItem()
+ Me.bbtnitm_NodeProfilAdd = New DevExpress.XtraBars.BarButtonItem()
+ Me.bbtnitmCopy = New DevExpress.XtraBars.BarButtonItem()
+ Me.RibbonPage1 = New DevExpress.XtraBars.Ribbon.RibbonPage()
+ Me.RibbonPageGroup1 = New DevExpress.XtraBars.Ribbon.RibbonPageGroup()
+ Me.RibbonPageGroup2 = New DevExpress.XtraBars.Ribbon.RibbonPageGroup()
+ Me.RibbonStatusBar1 = New DevExpress.XtraBars.Ribbon.RibbonStatusBar()
+ Me.RibbonPage2 = New DevExpress.XtraBars.Ribbon.RibbonPage()
+ Me.LabelControl1 = New DevExpress.XtraEditors.LabelControl()
+ Me.LookUpEdit1 = New DevExpress.XtraEditors.LookUpEdit()
+ Me.CheckEdit_Cockpit_Active = New DevExpress.XtraEditors.CheckEdit()
+ Me.ImageCollection1 = New DevExpress.Utils.ImageCollection(Me.components)
+ Me.TreeList_Cockpit = New DevExpress.XtraTreeList.TreeList()
+ Me.LabelControl2 = New DevExpress.XtraEditors.LabelControl()
+ Me.LabelControl3 = New DevExpress.XtraEditors.LabelControl()
+ Me.LabelControl4 = New DevExpress.XtraEditors.LabelControl()
+ Me.TextEdit_PK_CFG_COCKPIT_DEFINITION_ID = New DevExpress.XtraEditors.TextEdit()
+ Me.TextEdit_ParentID = New DevExpress.XtraEditors.TextEdit()
+ Me.LookUpEditTypeID = New DevExpress.XtraEditors.LookUpEdit()
+ Me.TextEdit_Bezeichnung = New DevExpress.XtraEditors.TextEdit()
+ Me.LabelControl5 = New DevExpress.XtraEditors.LabelControl()
+ Me.CheckEdit_Active = New DevExpress.XtraEditors.CheckEdit()
+ Me.LookUpEdit_Image = New DevExpress.XtraEditors.LookUpEdit()
+ Me.LabelControl6 = New DevExpress.XtraEditors.LabelControl()
+ Me.TextEdit_Comment = New DevExpress.XtraEditors.TextEdit()
+ Me.LabelControl7 = New DevExpress.XtraEditors.LabelControl()
+ Me.LabelControl_Profil = New DevExpress.XtraEditors.LabelControl()
+ Me.LookUpEditProfil = New DevExpress.XtraEditors.LookUpEdit()
+ Me.LookUpEditChart = New DevExpress.XtraEditors.LookUpEdit()
+ Me.LabelControl_Chart = New DevExpress.XtraEditors.LabelControl()
+ Me.LookUpEditMonitor = New DevExpress.XtraEditors.LookUpEdit()
+ Me.LabelControl_Monitor = New DevExpress.XtraEditors.LabelControl()
+ CType(Me.RibbonControl1, System.ComponentModel.ISupportInitialize).BeginInit()
+ CType(Me.LookUpEdit1.Properties, System.ComponentModel.ISupportInitialize).BeginInit()
+ CType(Me.CheckEdit_Cockpit_Active.Properties, System.ComponentModel.ISupportInitialize).BeginInit()
+ CType(Me.ImageCollection1, System.ComponentModel.ISupportInitialize).BeginInit()
+ CType(Me.TreeList_Cockpit, System.ComponentModel.ISupportInitialize).BeginInit()
+ CType(Me.TextEdit_PK_CFG_COCKPIT_DEFINITION_ID.Properties, System.ComponentModel.ISupportInitialize).BeginInit()
+ CType(Me.TextEdit_ParentID.Properties, System.ComponentModel.ISupportInitialize).BeginInit()
+ CType(Me.LookUpEditTypeID.Properties, System.ComponentModel.ISupportInitialize).BeginInit()
+ CType(Me.TextEdit_Bezeichnung.Properties, System.ComponentModel.ISupportInitialize).BeginInit()
+ CType(Me.CheckEdit_Active.Properties, System.ComponentModel.ISupportInitialize).BeginInit()
+ CType(Me.LookUpEdit_Image.Properties, System.ComponentModel.ISupportInitialize).BeginInit()
+ CType(Me.TextEdit_Comment.Properties, System.ComponentModel.ISupportInitialize).BeginInit()
+ CType(Me.LookUpEditProfil.Properties, System.ComponentModel.ISupportInitialize).BeginInit()
+ CType(Me.LookUpEditChart.Properties, System.ComponentModel.ISupportInitialize).BeginInit()
+ CType(Me.LookUpEditMonitor.Properties, System.ComponentModel.ISupportInitialize).BeginInit()
+ Me.SuspendLayout()
+ '
+ 'RibbonControl1
+ '
+ Me.RibbonControl1.EmptyAreaImageOptions.ImagePadding = New System.Windows.Forms.Padding(35, 39, 35, 39)
+ Me.RibbonControl1.ExpandCollapseItem.Id = 0
+ Me.RibbonControl1.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.RibbonControl1.Items.AddRange(New DevExpress.XtraBars.BarItem() {Me.RibbonControl1.ExpandCollapseItem, Me.RibbonControl1.SearchEditItem, Me.BarButtonItem1, Me.BarButtonItem2, Me.bbtnSQL_Data, Me.bbtnSQL_Count, Me.bbtnitm_Save, Me.BarButtonItem4, Me.bbtnitm_NodeOverviewAdd, Me.bbtnitm_NodeProfilAdd, Me.bbtnitmCopy})
+ Me.RibbonControl1.Location = New System.Drawing.Point(0, 0)
+ Me.RibbonControl1.Margin = New System.Windows.Forms.Padding(4)
+ Me.RibbonControl1.MaxItemId = 10
+ Me.RibbonControl1.Name = "RibbonControl1"
+ Me.RibbonControl1.OptionsMenuMinWidth = 385
+ Me.RibbonControl1.Pages.AddRange(New DevExpress.XtraBars.Ribbon.RibbonPage() {Me.RibbonPage1})
+ Me.RibbonControl1.ShowApplicationButton = DevExpress.Utils.DefaultBoolean.[False]
+ Me.RibbonControl1.Size = New System.Drawing.Size(974, 158)
+ Me.RibbonControl1.StatusBar = Me.RibbonStatusBar1
+ '
+ 'BarButtonItem1
+ '
+ Me.BarButtonItem1.Caption = "Cockpit für User testen"
+ Me.BarButtonItem1.Id = 1
+ Me.BarButtonItem1.ImageOptions.SvgImage = CType(resources.GetObject("BarButtonItem1.ImageOptions.SvgImage"), DevExpress.Utils.Svg.SvgImage)
+ Me.BarButtonItem1.Name = "BarButtonItem1"
+ '
+ 'BarButtonItem2
+ '
+ Me.BarButtonItem2.Caption = "Aktualisieren"
+ Me.BarButtonItem2.Id = 2
+ Me.BarButtonItem2.ImageOptions.SvgImage = CType(resources.GetObject("BarButtonItem2.ImageOptions.SvgImage"), DevExpress.Utils.Svg.SvgImage)
+ Me.BarButtonItem2.Name = "BarButtonItem2"
+ '
+ 'bbtnSQL_Data
+ '
+ Me.bbtnSQL_Data.Caption = "Data SQL ändern"
+ Me.bbtnSQL_Data.Id = 3
+ Me.bbtnSQL_Data.ImageOptions.SvgImage = CType(resources.GetObject("bbtnSQL_Data.ImageOptions.SvgImage"), DevExpress.Utils.Svg.SvgImage)
+ Me.bbtnSQL_Data.Name = "bbtnSQL_Data"
+ '
+ 'bbtnSQL_Count
+ '
+ Me.bbtnSQL_Count.Caption = "Count SQL Rows ändern"
+ Me.bbtnSQL_Count.Id = 4
+ Me.bbtnSQL_Count.ImageOptions.SvgImage = CType(resources.GetObject("bbtnSQL_Count.ImageOptions.SvgImage"), DevExpress.Utils.Svg.SvgImage)
+ Me.bbtnSQL_Count.Name = "bbtnSQL_Count"
+ '
+ 'bbtnitm_Save
+ '
+ Me.bbtnitm_Save.Caption = "Speichern"
+ Me.bbtnitm_Save.Id = 5
+ Me.bbtnitm_Save.ImageOptions.SvgImage = CType(resources.GetObject("bbtnitm_Save.ImageOptions.SvgImage"), DevExpress.Utils.Svg.SvgImage)
+ Me.bbtnitm_Save.Name = "bbtnitm_Save"
+ '
+ 'BarButtonItem4
+ '
+ Me.BarButtonItem4.Caption = "Löschen"
+ Me.BarButtonItem4.Id = 6
+ Me.BarButtonItem4.ImageOptions.SvgImage = CType(resources.GetObject("BarButtonItem4.ImageOptions.SvgImage"), DevExpress.Utils.Svg.SvgImage)
+ Me.BarButtonItem4.Name = "BarButtonItem4"
+ '
+ 'bbtnitm_NodeOverviewAdd
+ '
+ Me.bbtnitm_NodeOverviewAdd.Caption = "Overview hinzufügen"
+ Me.bbtnitm_NodeOverviewAdd.Id = 7
+ Me.bbtnitm_NodeOverviewAdd.ImageOptions.SvgImage = CType(resources.GetObject("bbtnitm_NodeOverviewAdd.ImageOptions.SvgImage"), DevExpress.Utils.Svg.SvgImage)
+ Me.bbtnitm_NodeOverviewAdd.Name = "bbtnitm_NodeOverviewAdd"
+ '
+ 'bbtnitm_NodeProfilAdd
+ '
+ Me.bbtnitm_NodeProfilAdd.Caption = "Profil hinzufügen"
+ Me.bbtnitm_NodeProfilAdd.Id = 8
+ Me.bbtnitm_NodeProfilAdd.ImageOptions.SvgImage = CType(resources.GetObject("bbtnitm_NodeProfilAdd.ImageOptions.SvgImage"), DevExpress.Utils.Svg.SvgImage)
+ Me.bbtnitm_NodeProfilAdd.Name = "bbtnitm_NodeProfilAdd"
+ '
+ 'bbtnitmCopy
+ '
+ Me.bbtnitmCopy.Caption = "Knoten kopieren"
+ Me.bbtnitmCopy.Id = 9
+ Me.bbtnitmCopy.ImageOptions.SvgImage = CType(resources.GetObject("bbtnitmCopy.ImageOptions.SvgImage"), DevExpress.Utils.Svg.SvgImage)
+ Me.bbtnitmCopy.Name = "bbtnitmCopy"
+ '
+ 'RibbonPage1
+ '
+ Me.RibbonPage1.Groups.AddRange(New DevExpress.XtraBars.Ribbon.RibbonPageGroup() {Me.RibbonPageGroup1, Me.RibbonPageGroup2})
+ Me.RibbonPage1.Name = "RibbonPage1"
+ Me.RibbonPage1.Text = "Start"
+ '
+ 'RibbonPageGroup1
+ '
+ Me.RibbonPageGroup1.AllowTextClipping = False
+ Me.RibbonPageGroup1.ItemLinks.Add(Me.BarButtonItem1)
+ Me.RibbonPageGroup1.ItemLinks.Add(Me.BarButtonItem2)
+ Me.RibbonPageGroup1.Name = "RibbonPageGroup1"
+ Me.RibbonPageGroup1.Text = "Aktionen"
+ '
+ 'RibbonPageGroup2
+ '
+ Me.RibbonPageGroup2.AllowTextClipping = False
+ Me.RibbonPageGroup2.ItemLinks.Add(Me.bbtnitm_Save)
+ Me.RibbonPageGroup2.ItemLinks.Add(Me.bbtnSQL_Data)
+ Me.RibbonPageGroup2.ItemLinks.Add(Me.bbtnSQL_Count)
+ Me.RibbonPageGroup2.ItemLinks.Add(Me.BarButtonItem4)
+ Me.RibbonPageGroup2.ItemLinks.Add(Me.bbtnitm_NodeOverviewAdd)
+ Me.RibbonPageGroup2.ItemLinks.Add(Me.bbtnitm_NodeProfilAdd)
+ Me.RibbonPageGroup2.ItemLinks.Add(Me.bbtnitmCopy)
+ Me.RibbonPageGroup2.Name = "RibbonPageGroup2"
+ Me.RibbonPageGroup2.Text = "Knoten Aktionen"
+ '
+ 'RibbonStatusBar1
+ '
+ Me.RibbonStatusBar1.Location = New System.Drawing.Point(0, 566)
+ Me.RibbonStatusBar1.Margin = New System.Windows.Forms.Padding(4)
+ Me.RibbonStatusBar1.Name = "RibbonStatusBar1"
+ Me.RibbonStatusBar1.Ribbon = Me.RibbonControl1
+ Me.RibbonStatusBar1.Size = New System.Drawing.Size(974, 22)
+ '
+ 'RibbonPage2
+ '
+ Me.RibbonPage2.Name = "RibbonPage2"
+ Me.RibbonPage2.Text = "RibbonPage2"
+ '
+ 'LabelControl1
+ '
+ Me.LabelControl1.Appearance.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.LabelControl1.Appearance.Options.UseFont = True
+ Me.LabelControl1.Location = New System.Drawing.Point(12, 167)
+ Me.LabelControl1.Name = "LabelControl1"
+ Me.LabelControl1.Size = New System.Drawing.Size(83, 17)
+ Me.LabelControl1.TabIndex = 16
+ Me.LabelControl1.Text = "Wähle Cockpit"
+ '
+ 'LookUpEdit1
+ '
+ Me.LookUpEdit1.Location = New System.Drawing.Point(12, 190)
+ Me.LookUpEdit1.MenuManager = Me.RibbonControl1
+ Me.LookUpEdit1.Name = "LookUpEdit1"
+ Me.LookUpEdit1.Properties.Appearance.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.LookUpEdit1.Properties.Appearance.Options.UseFont = True
+ Me.LookUpEdit1.Properties.Buttons.AddRange(New DevExpress.XtraEditors.Controls.EditorButton() {New DevExpress.XtraEditors.Controls.EditorButton(DevExpress.XtraEditors.Controls.ButtonPredefines.Combo)})
+ Me.LookUpEdit1.Size = New System.Drawing.Size(289, 24)
+ Me.LookUpEdit1.TabIndex = 17
+ '
+ 'CheckEdit_Cockpit_Active
+ '
+ Me.CheckEdit_Cockpit_Active.Location = New System.Drawing.Point(320, 191)
+ Me.CheckEdit_Cockpit_Active.MenuManager = Me.RibbonControl1
+ Me.CheckEdit_Cockpit_Active.Name = "CheckEdit_Cockpit_Active"
+ Me.CheckEdit_Cockpit_Active.Properties.Caption = "Active"
+ Me.CheckEdit_Cockpit_Active.Size = New System.Drawing.Size(64, 18)
+ Me.CheckEdit_Cockpit_Active.TabIndex = 20
+ '
+ 'ImageCollection1
+ '
+ Me.ImageCollection1.ImageSize = New System.Drawing.Size(24, 24)
+ Me.ImageCollection1.ImageStream = CType(resources.GetObject("ImageCollection1.ImageStream"), DevExpress.Utils.ImageCollectionStreamer)
+ Me.ImageCollection1.Images.SetKeyName(0, "overview")
+ Me.ImageCollection1.Images.SetKeyName(1, "profile")
+ Me.ImageCollection1.Images.SetKeyName(2, "monitor")
+ Me.ImageCollection1.Images.SetKeyName(3, "chart")
+ '
+ 'TreeList_Cockpit
+ '
+ Me.TreeList_Cockpit.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
+ Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
+ Me.TreeList_Cockpit.Font = New System.Drawing.Font("Tahoma", 9.75!)
+ Me.TreeList_Cockpit.ImageIndexFieldName = "ICON_ID"
+ Me.TreeList_Cockpit.KeyFieldName = "PK_CFG_COCKPIT_DEFINITION_ID"
+ Me.TreeList_Cockpit.Location = New System.Drawing.Point(12, 220)
+ Me.TreeList_Cockpit.MenuManager = Me.RibbonControl1
+ Me.TreeList_Cockpit.Name = "TreeList_Cockpit"
+ Me.TreeList_Cockpit.OptionsBehavior.Editable = False
+ Me.TreeList_Cockpit.OptionsBehavior.PopulateServiceColumns = True
+ Me.TreeList_Cockpit.OptionsBehavior.ReadOnly = True
+ Me.TreeList_Cockpit.OptionsLayout.AddNewColumns = False
+ Me.TreeList_Cockpit.OptionsMenu.ShowExpandCollapseItems = False
+ Me.TreeList_Cockpit.OptionsSelection.EnableAppearanceFocusedCell = False
+ Me.TreeList_Cockpit.OptionsView.ShowColumns = False
+ Me.TreeList_Cockpit.OptionsView.ShowFilterPanelMode = DevExpress.XtraTreeList.ShowFilterPanelMode.Never
+ Me.TreeList_Cockpit.OptionsView.ShowFirstLines = False
+ Me.TreeList_Cockpit.OptionsView.ShowHorzLines = False
+ Me.TreeList_Cockpit.OptionsView.ShowIndentAsRowStyle = True
+ Me.TreeList_Cockpit.OptionsView.ShowIndicator = False
+ Me.TreeList_Cockpit.OptionsView.ShowVertLines = False
+ Me.TreeList_Cockpit.OptionsView.TreeLineStyle = DevExpress.XtraTreeList.LineStyle.Dark
+ Me.TreeList_Cockpit.ParentFieldName = "PARENT_ID"
+ Me.TreeList_Cockpit.SelectImageList = Me.ImageCollection1
+ Me.TreeList_Cockpit.Size = New System.Drawing.Size(383, 339)
+ Me.TreeList_Cockpit.TabIndex = 24
+ '
+ 'LabelControl2
+ '
+ Me.LabelControl2.Appearance.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.LabelControl2.Appearance.Options.UseFont = True
+ Me.LabelControl2.Location = New System.Drawing.Point(418, 220)
+ Me.LabelControl2.Name = "LabelControl2"
+ Me.LabelControl2.Size = New System.Drawing.Size(12, 17)
+ Me.LabelControl2.TabIndex = 27
+ Me.LabelControl2.Text = "ID"
+ '
+ 'LabelControl3
+ '
+ Me.LabelControl3.Appearance.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.LabelControl3.Appearance.Options.UseFont = True
+ Me.LabelControl3.Location = New System.Drawing.Point(495, 220)
+ Me.LabelControl3.Name = "LabelControl3"
+ Me.LabelControl3.Size = New System.Drawing.Size(49, 17)
+ Me.LabelControl3.TabIndex = 28
+ Me.LabelControl3.Text = "ParentID"
+ '
+ 'LabelControl4
+ '
+ Me.LabelControl4.Appearance.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.LabelControl4.Appearance.Options.UseFont = True
+ Me.LabelControl4.Location = New System.Drawing.Point(418, 270)
+ Me.LabelControl4.Name = "LabelControl4"
+ Me.LabelControl4.Size = New System.Drawing.Size(67, 17)
+ Me.LabelControl4.TabIndex = 29
+ Me.LabelControl4.Text = "Knoten-Typ"
+ '
+ 'TextEdit_PK_CFG_COCKPIT_DEFINITION_ID
+ '
+ Me.TextEdit_PK_CFG_COCKPIT_DEFINITION_ID.Location = New System.Drawing.Point(418, 240)
+ Me.TextEdit_PK_CFG_COCKPIT_DEFINITION_ID.MenuManager = Me.RibbonControl1
+ Me.TextEdit_PK_CFG_COCKPIT_DEFINITION_ID.Name = "TextEdit_PK_CFG_COCKPIT_DEFINITION_ID"
+ Me.TextEdit_PK_CFG_COCKPIT_DEFINITION_ID.Properties.Appearance.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.TextEdit_PK_CFG_COCKPIT_DEFINITION_ID.Properties.Appearance.Options.UseFont = True
+ Me.TextEdit_PK_CFG_COCKPIT_DEFINITION_ID.Properties.ReadOnly = True
+ Me.TextEdit_PK_CFG_COCKPIT_DEFINITION_ID.Size = New System.Drawing.Size(55, 24)
+ Me.TextEdit_PK_CFG_COCKPIT_DEFINITION_ID.TabIndex = 31
+ '
+ 'TextEdit_ParentID
+ '
+ Me.TextEdit_ParentID.Location = New System.Drawing.Point(495, 240)
+ Me.TextEdit_ParentID.MenuManager = Me.RibbonControl1
+ Me.TextEdit_ParentID.Name = "TextEdit_ParentID"
+ Me.TextEdit_ParentID.Properties.Appearance.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.TextEdit_ParentID.Properties.Appearance.Options.UseFont = True
+ Me.TextEdit_ParentID.Properties.ReadOnly = True
+ Me.TextEdit_ParentID.Size = New System.Drawing.Size(55, 24)
+ Me.TextEdit_ParentID.TabIndex = 32
+ '
+ 'LookUpEditTypeID
+ '
+ Me.LookUpEditTypeID.Location = New System.Drawing.Point(418, 293)
+ Me.LookUpEditTypeID.MenuManager = Me.RibbonControl1
+ Me.LookUpEditTypeID.Name = "LookUpEditTypeID"
+ Me.LookUpEditTypeID.Properties.Appearance.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.LookUpEditTypeID.Properties.Appearance.Options.UseFont = True
+ Me.LookUpEditTypeID.Properties.Buttons.AddRange(New DevExpress.XtraEditors.Controls.EditorButton() {New DevExpress.XtraEditors.Controls.EditorButton(DevExpress.XtraEditors.Controls.ButtonPredefines.Combo)})
+ Me.LookUpEditTypeID.Size = New System.Drawing.Size(143, 24)
+ Me.LookUpEditTypeID.TabIndex = 33
+ '
+ 'TextEdit_Bezeichnung
+ '
+ Me.TextEdit_Bezeichnung.Location = New System.Drawing.Point(566, 240)
+ Me.TextEdit_Bezeichnung.MenuManager = Me.RibbonControl1
+ Me.TextEdit_Bezeichnung.Name = "TextEdit_Bezeichnung"
+ Me.TextEdit_Bezeichnung.Properties.Appearance.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.TextEdit_Bezeichnung.Properties.Appearance.Options.UseFont = True
+ Me.TextEdit_Bezeichnung.Size = New System.Drawing.Size(283, 24)
+ Me.TextEdit_Bezeichnung.TabIndex = 36
+ '
+ 'LabelControl5
+ '
+ Me.LabelControl5.Appearance.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.LabelControl5.Appearance.Options.UseFont = True
+ Me.LabelControl5.Location = New System.Drawing.Point(566, 220)
+ Me.LabelControl5.Name = "LabelControl5"
+ Me.LabelControl5.Size = New System.Drawing.Size(72, 17)
+ Me.LabelControl5.TabIndex = 35
+ Me.LabelControl5.Text = "Bezeichnung"
+ '
+ 'CheckEdit_Active
+ '
+ Me.CheckEdit_Active.Location = New System.Drawing.Point(855, 241)
+ Me.CheckEdit_Active.MenuManager = Me.RibbonControl1
+ Me.CheckEdit_Active.Name = "CheckEdit_Active"
+ Me.CheckEdit_Active.Properties.Appearance.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.CheckEdit_Active.Properties.Appearance.Options.UseFont = True
+ Me.CheckEdit_Active.Properties.Caption = "Active"
+ Me.CheckEdit_Active.Size = New System.Drawing.Size(75, 21)
+ Me.CheckEdit_Active.TabIndex = 37
+ '
+ 'LookUpEdit_Image
+ '
+ Me.LookUpEdit_Image.Location = New System.Drawing.Point(418, 403)
+ Me.LookUpEdit_Image.MenuManager = Me.RibbonControl1
+ Me.LookUpEdit_Image.Name = "LookUpEdit_Image"
+ Me.LookUpEdit_Image.Properties.Appearance.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.LookUpEdit_Image.Properties.Appearance.Options.UseFont = True
+ Me.LookUpEdit_Image.Properties.Buttons.AddRange(New DevExpress.XtraEditors.Controls.EditorButton() {New DevExpress.XtraEditors.Controls.EditorButton(DevExpress.XtraEditors.Controls.ButtonPredefines.Combo)})
+ Me.LookUpEdit_Image.Size = New System.Drawing.Size(143, 24)
+ Me.LookUpEdit_Image.TabIndex = 39
+ '
+ 'LabelControl6
+ '
+ Me.LabelControl6.Appearance.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.LabelControl6.Appearance.Options.UseFont = True
+ Me.LabelControl6.Location = New System.Drawing.Point(418, 380)
+ Me.LabelControl6.Name = "LabelControl6"
+ Me.LabelControl6.Size = New System.Drawing.Size(47, 17)
+ Me.LabelControl6.TabIndex = 38
+ Me.LabelControl6.Text = "Bild-Typ"
+ '
+ 'TextEdit_Comment
+ '
+ Me.TextEdit_Comment.Location = New System.Drawing.Point(573, 403)
+ Me.TextEdit_Comment.MenuManager = Me.RibbonControl1
+ Me.TextEdit_Comment.Name = "TextEdit_Comment"
+ Me.TextEdit_Comment.Properties.Appearance.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.TextEdit_Comment.Properties.Appearance.Options.UseFont = True
+ Me.TextEdit_Comment.Size = New System.Drawing.Size(360, 24)
+ Me.TextEdit_Comment.TabIndex = 41
+ '
+ 'LabelControl7
+ '
+ Me.LabelControl7.Appearance.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.LabelControl7.Appearance.Options.UseFont = True
+ Me.LabelControl7.Location = New System.Drawing.Point(573, 380)
+ Me.LabelControl7.Name = "LabelControl7"
+ Me.LabelControl7.Size = New System.Drawing.Size(65, 17)
+ Me.LabelControl7.TabIndex = 40
+ Me.LabelControl7.Text = "Bemerkung"
+ '
+ 'LabelControl_Profil
+ '
+ Me.LabelControl_Profil.Appearance.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.LabelControl_Profil.Appearance.Options.UseFont = True
+ Me.LabelControl_Profil.Location = New System.Drawing.Point(566, 270)
+ Me.LabelControl_Profil.Name = "LabelControl_Profil"
+ Me.LabelControl_Profil.Size = New System.Drawing.Size(30, 17)
+ Me.LabelControl_Profil.TabIndex = 42
+ Me.LabelControl_Profil.Text = "Profil"
+ '
+ 'LookUpEditProfil
+ '
+ Me.LookUpEditProfil.Location = New System.Drawing.Point(566, 293)
+ Me.LookUpEditProfil.MenuManager = Me.RibbonControl1
+ Me.LookUpEditProfil.Name = "LookUpEditProfil"
+ Me.LookUpEditProfil.Properties.Appearance.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.LookUpEditProfil.Properties.Appearance.Options.UseFont = True
+ Me.LookUpEditProfil.Properties.Buttons.AddRange(New DevExpress.XtraEditors.Controls.EditorButton() {New DevExpress.XtraEditors.Controls.EditorButton(DevExpress.XtraEditors.Controls.ButtonPredefines.Combo)})
+ Me.LookUpEditProfil.Size = New System.Drawing.Size(364, 24)
+ Me.LookUpEditProfil.TabIndex = 43
+ '
+ 'LookUpEditChart
+ '
+ Me.LookUpEditChart.Location = New System.Drawing.Point(418, 350)
+ Me.LookUpEditChart.MenuManager = Me.RibbonControl1
+ Me.LookUpEditChart.Name = "LookUpEditChart"
+ Me.LookUpEditChart.Properties.Appearance.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.LookUpEditChart.Properties.Appearance.Options.UseFont = True
+ Me.LookUpEditChart.Properties.Buttons.AddRange(New DevExpress.XtraEditors.Controls.EditorButton() {New DevExpress.XtraEditors.Controls.EditorButton(DevExpress.XtraEditors.Controls.ButtonPredefines.Combo)})
+ Me.LookUpEditChart.Size = New System.Drawing.Size(143, 24)
+ Me.LookUpEditChart.TabIndex = 45
+ '
+ 'LabelControl_Chart
+ '
+ Me.LabelControl_Chart.Appearance.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.LabelControl_Chart.Appearance.Options.UseFont = True
+ Me.LabelControl_Chart.Location = New System.Drawing.Point(418, 327)
+ Me.LabelControl_Chart.Name = "LabelControl_Chart"
+ Me.LabelControl_Chart.Size = New System.Drawing.Size(91, 17)
+ Me.LabelControl_Chart.TabIndex = 44
+ Me.LabelControl_Chart.Text = "Chart-Definition"
+ '
+ 'LookUpEditMonitor
+ '
+ Me.LookUpEditMonitor.Location = New System.Drawing.Point(567, 350)
+ Me.LookUpEditMonitor.MenuManager = Me.RibbonControl1
+ Me.LookUpEditMonitor.Name = "LookUpEditMonitor"
+ Me.LookUpEditMonitor.Properties.Appearance.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.LookUpEditMonitor.Properties.Appearance.Options.UseFont = True
+ Me.LookUpEditMonitor.Properties.Buttons.AddRange(New DevExpress.XtraEditors.Controls.EditorButton() {New DevExpress.XtraEditors.Controls.EditorButton(DevExpress.XtraEditors.Controls.ButtonPredefines.Combo)})
+ Me.LookUpEditMonitor.Size = New System.Drawing.Size(143, 24)
+ Me.LookUpEditMonitor.TabIndex = 47
+ '
+ 'LabelControl_Monitor
+ '
+ Me.LabelControl_Monitor.Appearance.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.LabelControl_Monitor.Appearance.Options.UseFont = True
+ Me.LabelControl_Monitor.Location = New System.Drawing.Point(567, 327)
+ Me.LabelControl_Monitor.Name = "LabelControl_Monitor"
+ Me.LabelControl_Monitor.Size = New System.Drawing.Size(107, 17)
+ Me.LabelControl_Monitor.TabIndex = 46
+ Me.LabelControl_Monitor.Text = "Monitor-Definition"
+ '
+ 'frmCockpitConfig
+ '
+ Me.Appearance.Options.UseFont = True
+ Me.AutoScaleDimensions = New System.Drawing.SizeF(7.0!, 17.0!)
+ Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
+ Me.ClientSize = New System.Drawing.Size(974, 588)
+ Me.Controls.Add(Me.LookUpEditMonitor)
+ Me.Controls.Add(Me.LabelControl_Monitor)
+ Me.Controls.Add(Me.LookUpEditChart)
+ Me.Controls.Add(Me.LabelControl_Chart)
+ Me.Controls.Add(Me.LookUpEditProfil)
+ Me.Controls.Add(Me.LabelControl_Profil)
+ Me.Controls.Add(Me.TextEdit_Comment)
+ Me.Controls.Add(Me.LabelControl7)
+ Me.Controls.Add(Me.LookUpEdit_Image)
+ Me.Controls.Add(Me.LabelControl6)
+ Me.Controls.Add(Me.CheckEdit_Active)
+ Me.Controls.Add(Me.TextEdit_Bezeichnung)
+ Me.Controls.Add(Me.LabelControl5)
+ Me.Controls.Add(Me.LookUpEditTypeID)
+ Me.Controls.Add(Me.TextEdit_ParentID)
+ Me.Controls.Add(Me.TextEdit_PK_CFG_COCKPIT_DEFINITION_ID)
+ Me.Controls.Add(Me.LabelControl4)
+ Me.Controls.Add(Me.LabelControl3)
+ Me.Controls.Add(Me.LabelControl2)
+ Me.Controls.Add(Me.TreeList_Cockpit)
+ Me.Controls.Add(Me.CheckEdit_Cockpit_Active)
+ Me.Controls.Add(Me.LookUpEdit1)
+ Me.Controls.Add(Me.LabelControl1)
+ Me.Controls.Add(Me.RibbonStatusBar1)
+ Me.Controls.Add(Me.RibbonControl1)
+ Me.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.IconOptions.SvgImage = CType(resources.GetObject("frmCockpitConfig.IconOptions.SvgImage"), DevExpress.Utils.Svg.SvgImage)
+ Me.Margin = New System.Windows.Forms.Padding(4)
+ Me.Name = "frmCockpitConfig"
+ Me.Ribbon = Me.RibbonControl1
+ Me.StatusBar = Me.RibbonStatusBar1
+ Me.Text = "Cockpit Config"
+ CType(Me.RibbonControl1, System.ComponentModel.ISupportInitialize).EndInit()
+ CType(Me.LookUpEdit1.Properties, System.ComponentModel.ISupportInitialize).EndInit()
+ CType(Me.CheckEdit_Cockpit_Active.Properties, System.ComponentModel.ISupportInitialize).EndInit()
+ CType(Me.ImageCollection1, System.ComponentModel.ISupportInitialize).EndInit()
+ CType(Me.TreeList_Cockpit, System.ComponentModel.ISupportInitialize).EndInit()
+ CType(Me.TextEdit_PK_CFG_COCKPIT_DEFINITION_ID.Properties, System.ComponentModel.ISupportInitialize).EndInit()
+ CType(Me.TextEdit_ParentID.Properties, System.ComponentModel.ISupportInitialize).EndInit()
+ CType(Me.LookUpEditTypeID.Properties, System.ComponentModel.ISupportInitialize).EndInit()
+ CType(Me.TextEdit_Bezeichnung.Properties, System.ComponentModel.ISupportInitialize).EndInit()
+ CType(Me.CheckEdit_Active.Properties, System.ComponentModel.ISupportInitialize).EndInit()
+ CType(Me.LookUpEdit_Image.Properties, System.ComponentModel.ISupportInitialize).EndInit()
+ CType(Me.TextEdit_Comment.Properties, System.ComponentModel.ISupportInitialize).EndInit()
+ CType(Me.LookUpEditProfil.Properties, System.ComponentModel.ISupportInitialize).EndInit()
+ CType(Me.LookUpEditChart.Properties, System.ComponentModel.ISupportInitialize).EndInit()
+ CType(Me.LookUpEditMonitor.Properties, System.ComponentModel.ISupportInitialize).EndInit()
+ Me.ResumeLayout(False)
+ Me.PerformLayout()
+
+ End Sub
+
+ Friend WithEvents RibbonControl1 As DevExpress.XtraBars.Ribbon.RibbonControl
+ Friend WithEvents RibbonPage1 As DevExpress.XtraBars.Ribbon.RibbonPage
+ Friend WithEvents RibbonPageGroup1 As DevExpress.XtraBars.Ribbon.RibbonPageGroup
+ Friend WithEvents RibbonPageGroup2 As DevExpress.XtraBars.Ribbon.RibbonPageGroup
+ Friend WithEvents RibbonStatusBar1 As DevExpress.XtraBars.Ribbon.RibbonStatusBar
+ Friend WithEvents RibbonPage2 As DevExpress.XtraBars.Ribbon.RibbonPage
+ Friend WithEvents BarButtonItem1 As DevExpress.XtraBars.BarButtonItem
+ Friend WithEvents BarButtonItem2 As DevExpress.XtraBars.BarButtonItem
+ Friend WithEvents LabelControl1 As DevExpress.XtraEditors.LabelControl
+ Friend WithEvents LookUpEdit1 As DevExpress.XtraEditors.LookUpEdit
+ Friend WithEvents CheckEdit_Cockpit_Active As DevExpress.XtraEditors.CheckEdit
+ Friend WithEvents ImageCollection1 As DevExpress.Utils.ImageCollection
+ Friend WithEvents TreeList_Cockpit As DevExpress.XtraTreeList.TreeList
+ Friend WithEvents LabelControl2 As DevExpress.XtraEditors.LabelControl
+ Friend WithEvents LabelControl3 As DevExpress.XtraEditors.LabelControl
+ Friend WithEvents LabelControl4 As DevExpress.XtraEditors.LabelControl
+ Friend WithEvents TextEdit_PK_CFG_COCKPIT_DEFINITION_ID As DevExpress.XtraEditors.TextEdit
+ Friend WithEvents TextEdit_ParentID As DevExpress.XtraEditors.TextEdit
+ Friend WithEvents LookUpEditTypeID As DevExpress.XtraEditors.LookUpEdit
+ Friend WithEvents TextEdit_Bezeichnung As DevExpress.XtraEditors.TextEdit
+ Friend WithEvents LabelControl5 As DevExpress.XtraEditors.LabelControl
+ Friend WithEvents CheckEdit_Active As DevExpress.XtraEditors.CheckEdit
+ Friend WithEvents bbtnSQL_Data As DevExpress.XtraBars.BarButtonItem
+ Friend WithEvents bbtnSQL_Count As DevExpress.XtraBars.BarButtonItem
+ Friend WithEvents LookUpEdit_Image As DevExpress.XtraEditors.LookUpEdit
+ Friend WithEvents LabelControl6 As DevExpress.XtraEditors.LabelControl
+ Friend WithEvents bbtnitm_Save As DevExpress.XtraBars.BarButtonItem
+ Friend WithEvents TextEdit_Comment As DevExpress.XtraEditors.TextEdit
+ Friend WithEvents LabelControl7 As DevExpress.XtraEditors.LabelControl
+ Friend WithEvents BarButtonItem4 As DevExpress.XtraBars.BarButtonItem
+ Friend WithEvents bbtnitm_NodeOverviewAdd As DevExpress.XtraBars.BarButtonItem
+ Friend WithEvents bbtnitm_NodeProfilAdd As DevExpress.XtraBars.BarButtonItem
+ Friend WithEvents LabelControl_Profil As DevExpress.XtraEditors.LabelControl
+ Friend WithEvents LookUpEditProfil As DevExpress.XtraEditors.LookUpEdit
+ Friend WithEvents LookUpEditChart As DevExpress.XtraEditors.LookUpEdit
+ Friend WithEvents LabelControl_Chart As DevExpress.XtraEditors.LabelControl
+ Friend WithEvents LookUpEditMonitor As DevExpress.XtraEditors.LookUpEdit
+ Friend WithEvents LabelControl_Monitor As DevExpress.XtraEditors.LabelControl
+ Friend WithEvents bbtnitmCopy As DevExpress.XtraBars.BarButtonItem
+End Class
diff --git a/app/TaskFlow/frmCockpitConfig.resx b/app/TaskFlow/frmCockpitConfig.resx
new file mode 100644
index 0000000..a9f00db
--- /dev/null
+++ b/app/TaskFlow/frmCockpitConfig.resx
@@ -0,0 +1,387 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFlEZXZFeHByZXNzLkRhdGEudjIxLjIsIFZlcnNpb249MjEuMi40
+ LjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjg4ZDE3NTRkNzAwZTQ5YQUBAAAAHURl
+ dkV4cHJlc3MuVXRpbHMuU3ZnLlN2Z0ltYWdlAQAAAAREYXRhBwICAAAACQMAAAAPAwAAAKEDAAAC77u/
+ PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz4NCjxzdmcgeD0iMHB4IiB5PSIwcHgi
+ IHZpZXdCb3g9IjAgMCAzMiAzMiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv
+ MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3Bh
+ Y2U9InByZXNlcnZlIiBpZD0iTGF5ZXJfMSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAg
+ MzIgMzIiPg0KICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLkJsdWV7ZmlsbDojMTE3N0Q3O30KCS5Z
+ ZWxsb3d7ZmlsbDojRkZCMTE1O30KCS5CbGFja3tmaWxsOiM3MjcyNzI7fQoJLkdyZWVue2ZpbGw6IzAz
+ OUMyMzt9CgkuUmVke2ZpbGw6I0QxMUMxQzt9Cgkuc3Qwe29wYWNpdHk6MC43NTt9Cgkuc3Qxe29wYWNp
+ dHk6MC41O30KPC9zdHlsZT4NCiAgPGcgaWQ9IlVzZXIiPg0KICAgIDxwYXRoIGQ9Ik0xMCw5LjljLTAu
+ MSwwLjUsMC4yLDAuOSwwLjQsMS40YzAuMiwwLjUtMC4xLDEuNywwLjksMS42YzAsMCwwLDAuMSwwLDAu
+ MmMwLjYsMi4zLDIsNC45LDQuNyw0LjkgICBjMi43LDAsNC4yLTIuNiw0LjctNC45YzAsMCwwLTAuMSww
+ LTAuMWMxLDAuMSwwLjYtMS4xLDAuOS0xLjZjMC4yLTAuNSwwLjQtMC45LDAuMy0xLjRjLTAuMS0wLjQt
+ MC40LTAuNC0wLjUtMC4zICAgYzEuOC00LjktMS4xLTQuNy0xLjEtNC43UzIwLDIsMTQuOCwyQzEwLDIs
+ OS40LDYsMTAuNSw5LjZDMTAuNCw5LjYsMTAuMSw5LjcsMTAsOS45eiIgY2xhc3M9IkJsYWNrIiAvPg0K
+ ICAgIDxwYXRoIGQ9Ik0yMCwxOGMtMC44LDEuNS0yLjEsNC00LDRjLTEuOSwwLTMuMi0yLjUtNC00Yy0y
+ LjMsMy41LTgsMS04LDguNVYzMGgyNHYtMy41QzI4LDE5LjEsMjIuMywyMS40LDIwLDE4eiIgY2xhc3M9
+ IkJsYWNrIiAvPg0KICA8L2c+DQo8L3N2Zz4L
+
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFlEZXZFeHByZXNzLkRhdGEudjIxLjIsIFZlcnNpb249MjEuMi40
+ LjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjg4ZDE3NTRkNzAwZTQ5YQUBAAAAHURl
+ dkV4cHJlc3MuVXRpbHMuU3ZnLlN2Z0ltYWdlAQAAAAREYXRhBwICAAAACQMAAAAPAwAAAC4DAAAC77u/
+ PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz4NCjxzdmcgeD0iMHB4IiB5PSIwcHgi
+ IHZpZXdCb3g9IjAgMCAzMiAzMiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv
+ MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3Bh
+ Y2U9InByZXNlcnZlIiBpZD0iTGF5ZXJfMSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAg
+ MzIgMzIiPg0KICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLkJsdWV7ZmlsbDojMTE3N0Q3O30KCS5Z
+ ZWxsb3d7ZmlsbDojRkZCMTE1O30KCS5CbGFja3tmaWxsOiM3MjcyNzI7fQoJLkdyZWVue2ZpbGw6IzAz
+ OUMyMzt9CgkuUmVke2ZpbGw6I0QxMUMxQzt9Cgkuc3Qwe29wYWNpdHk6MC43NTt9Cgkuc3Qxe29wYWNp
+ dHk6MC41O30KPC9zdHlsZT4NCiAgPGcgaWQ9IlJlZnJlc2hfMV8iPg0KICAgIDxwYXRoIGQ9Ik0yNC41
+ LDcuNUMyMi4zLDUuMywxOS4zLDQsMTYsNEMxMC4xLDQsNS4xLDguMyw0LjIsMTRoNC4xYzAuOS0zLjQs
+ NC02LDcuNy02YzIuMiwwLDQuMiwwLjksNS42LDIuNEwxOCwxNCAgIGg1LjdoNC4xSDI4VjRMMjQuNSw3
+ LjV6IiBjbGFzcz0iR3JlZW4iIC8+DQogICAgPHBhdGggZD0iTTE2LjIsMjRjLTIuMiwwLTQuMi0wLjkt
+ NS42LTIuNGwzLjYtMy42SDguNEg0LjRINC4ydjEwbDMuNS0zLjVjMi4yLDIuMiw1LjIsMy41LDguNSwz
+ LjUgICBDMjIuMSwyOCwyNywyMy43LDI4LDE4aC00LjFDMjMsMjEuNCwxOS45LDI0LDE2LjIsMjR6IiBj
+ bGFzcz0iR3JlZW4iIC8+DQogIDwvZz4NCjwvc3ZnPgs=
+
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFlEZXZFeHByZXNzLkRhdGEudjIxLjIsIFZlcnNpb249MjEuMi40
+ LjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjg4ZDE3NTRkNzAwZTQ5YQUBAAAAHURl
+ dkV4cHJlc3MuVXRpbHMuU3ZnLlN2Z0ltYWdlAQAAAAREYXRhBwICAAAACQMAAAAPAwAAADIDAAAC77u/
+ PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz4NCjxzdmcgeD0iMHB4IiB5PSIwcHgi
+ IHZpZXdCb3g9IjAgMCAzMiAzMiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv
+ MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3Bh
+ Y2U9InByZXNlcnZlIiBpZD0iTGF5ZXJfMSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAg
+ MzIgMzIiPg0KICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLkJsdWV7ZmlsbDojMTE3N0Q3O30KCS5Z
+ ZWxsb3d7ZmlsbDojRkZCMTE1O30KCS5CbGFja3tmaWxsOiM3MjcyNzI7fQoJLkdyZWVue2ZpbGw6IzAz
+ OUMyMzt9CgkuUmVke2ZpbGw6I0QxMUMxQzt9Cgkuc3Qwe29wYWNpdHk6MC43NTt9Cgkuc3Qxe29wYWNp
+ dHk6MC41O30KPC9zdHlsZT4NCiAgPGcgaWQ9IkRhdGFiYXNlIj4NCiAgICA8cGF0aCBkPSJNMTYsMjRj
+ LTUuNSwwLTEwLTEuOC0xMC00djRjMCwyLjIsNC41LDQsMTAsNHMxMC0xLjgsMTAtNHYtNEMyNiwyMi4y
+ LDIxLjUsMjQsMTYsMjR6IiBjbGFzcz0iWWVsbG93IiAvPg0KICAgIDxwYXRoIGQ9Ik0xNiwxOGMtNS41
+ LDAtMTAtMS44LTEwLTR2NGMwLDIuMiw0LjUsNCwxMCw0czEwLTEuOCwxMC00di00QzI2LDE2LjIsMjEu
+ NSwxOCwxNiwxOHoiIGNsYXNzPSJZZWxsb3ciIC8+DQogICAgPHBhdGggZD0iTTE2LDRDMTAuNSw0LDYs
+ NS44LDYsOHY0YzAsMi4yLDQuNSw0LDEwLDRzMTAtMS44LDEwLTRWOEMyNiw1LjgsMjEuNSw0LDE2LDR6
+ IiBjbGFzcz0iWWVsbG93IiAvPg0KICA8L2c+DQo8L3N2Zz4L
+
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFlEZXZFeHByZXNzLkRhdGEudjIxLjIsIFZlcnNpb249MjEuMi40
+ LjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjg4ZDE3NTRkNzAwZTQ5YQUBAAAAHURl
+ dkV4cHJlc3MuVXRpbHMuU3ZnLlN2Z0ltYWdlAQAAAAREYXRhBwICAAAACQMAAAAPAwAAADIDAAAC77u/
+ PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz4NCjxzdmcgeD0iMHB4IiB5PSIwcHgi
+ IHZpZXdCb3g9IjAgMCAzMiAzMiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv
+ MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3Bh
+ Y2U9InByZXNlcnZlIiBpZD0iTGF5ZXJfMSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAg
+ MzIgMzIiPg0KICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLkJsdWV7ZmlsbDojMTE3N0Q3O30KCS5Z
+ ZWxsb3d7ZmlsbDojRkZCMTE1O30KCS5CbGFja3tmaWxsOiM3MjcyNzI7fQoJLkdyZWVue2ZpbGw6IzAz
+ OUMyMzt9CgkuUmVke2ZpbGw6I0QxMUMxQzt9Cgkuc3Qwe29wYWNpdHk6MC43NTt9Cgkuc3Qxe29wYWNp
+ dHk6MC41O30KPC9zdHlsZT4NCiAgPGcgaWQ9IkRhdGFiYXNlIj4NCiAgICA8cGF0aCBkPSJNMTYsMjRj
+ LTUuNSwwLTEwLTEuOC0xMC00djRjMCwyLjIsNC41LDQsMTAsNHMxMC0xLjgsMTAtNHYtNEMyNiwyMi4y
+ LDIxLjUsMjQsMTYsMjR6IiBjbGFzcz0iWWVsbG93IiAvPg0KICAgIDxwYXRoIGQ9Ik0xNiwxOGMtNS41
+ LDAtMTAtMS44LTEwLTR2NGMwLDIuMiw0LjUsNCwxMCw0czEwLTEuOCwxMC00di00QzI2LDE2LjIsMjEu
+ NSwxOCwxNiwxOHoiIGNsYXNzPSJZZWxsb3ciIC8+DQogICAgPHBhdGggZD0iTTE2LDRDMTAuNSw0LDYs
+ NS44LDYsOHY0YzAsMi4yLDQuNSw0LDEwLDRzMTAtMS44LDEwLTRWOEMyNiw1LjgsMjEuNSw0LDE2LDR6
+ IiBjbGFzcz0iWWVsbG93IiAvPg0KICA8L2c+DQo8L3N2Zz4L
+
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFlEZXZFeHByZXNzLkRhdGEudjIxLjIsIFZlcnNpb249MjEuMi40
+ LjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjg4ZDE3NTRkNzAwZTQ5YQUBAAAAHURl
+ dkV4cHJlc3MuVXRpbHMuU3ZnLlN2Z0ltYWdlAQAAAAREYXRhBwICAAAACQMAAAAPAwAAAMICAAAC77u/
+ PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz4NCjxzdmcgeD0iMHB4IiB5PSIwcHgi
+ IHZpZXdCb3g9IjAgMCAzMiAzMiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv
+ MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3Bh
+ Y2U9InByZXNlcnZlIiBpZD0iTGF5ZXJfMSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAg
+ MzIgMzIiPg0KICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLkJsYWNre2ZpbGw6IzczNzM3NDt9Cgku
+ WWVsbG93e2ZpbGw6I0ZDQjAxQjt9CgkuR3JlZW57ZmlsbDojMTI5QzQ5O30KCS5CbHVle2ZpbGw6IzM4
+ N0NCNzt9CgkuUmVke2ZpbGw6I0QwMjEyNzt9CgkuV2hpdGV7ZmlsbDojRkZGRkZGO30KCS5zdDB7b3Bh
+ Y2l0eTowLjU7fQoJLnN0MXtvcGFjaXR5OjAuNzU7fQoJLnN0MntvcGFjaXR5OjAuMjU7fQoJLnN0M3tk
+ aXNwbGF5Om5vbmU7ZmlsbDojNzM3Mzc0O30KPC9zdHlsZT4NCiAgPHBhdGggZD0iTTI3LDRoLTN2MTBI
+ OFY0SDVDNC40LDQsNCw0LjQsNCw1djIyYzAsMC42LDAuNCwxLDEsMWgyMmMwLjYsMCwxLTAuNCwxLTFW
+ NUMyOCw0LjQsMjcuNiw0LDI3LDR6IE0yNCwyNEg4di02ICBoMTZWMjR6IE0xMCw0djhoMTBWNEgxMHog
+ TTE0LDEwaC0yVjZoMlYxMHoiIGNsYXNzPSJCbGFjayIgLz4NCjwvc3ZnPgs=
+
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFlEZXZFeHByZXNzLkRhdGEudjIxLjIsIFZlcnNpb249MjEuMi40
+ LjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjg4ZDE3NTRkNzAwZTQ5YQUBAAAAHURl
+ dkV4cHJlc3MuVXRpbHMuU3ZnLlN2Z0ltYWdlAQAAAAREYXRhBwICAAAACQMAAAAPAwAAAD4DAAAC77u/
+ PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz4NCjxzdmcgeD0iMHB4IiB5PSIwcHgi
+ IHZpZXdCb3g9IjAgMCAzMiAzMiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv
+ MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3Bh
+ Y2U9InByZXNlcnZlIiBpZD0iTGF5ZXJfMSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAg
+ MzIgMzIiPg0KICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLkJsYWNre2ZpbGw6IzczNzM3NDt9Cgku
+ WWVsbG93e2ZpbGw6I0ZDQjAxQjt9CgkuR3JlZW57ZmlsbDojMTI5QzQ5O30KCS5CbHVle2ZpbGw6IzM4
+ N0NCNzt9CgkuUmVke2ZpbGw6I0QwMjEyNzt9CgkuV2hpdGV7ZmlsbDojRkZGRkZGO30KCS5zdDB7b3Bh
+ Y2l0eTowLjU7fQoJLnN0MXtvcGFjaXR5OjAuNzU7fQoJLnN0MntvcGFjaXR5OjAuMjU7fQoJLnN0M3tk
+ aXNwbGF5Om5vbmU7ZmlsbDojNzM3Mzc0O30KPC9zdHlsZT4NCiAgPHBhdGggZD0iTTE4LjgsMTZsOC45
+ LTguOWMwLjQtMC40LDAuNC0xLDAtMS40bC0xLjQtMS40Yy0wLjQtMC40LTEtMC40LTEuNCwwTDE2LDEz
+ LjJMNy4xLDQuM2MtMC40LTAuNC0xLTAuNC0xLjQsMCAgTDQuMyw1LjdjLTAuNCwwLjQtMC40LDEsMCwx
+ LjRsOC45LDguOWwtOC45LDguOWMtMC40LDAuNC0wLjQsMSwwLDEuNGwxLjQsMS40YzAuNCwwLjQsMSww
+ LjQsMS40LDBsOC45LTguOWw4LjksOC45ICBjMC40LDAuNCwxLDAuNCwxLjQsMGwxLjQtMS40YzAuNC0w
+ LjQsMC40LTEsMC0xLjRMMTguOCwxNnoiIGNsYXNzPSJSZWQiIC8+DQo8L3N2Zz4L
+
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFlEZXZFeHByZXNzLkRhdGEudjIxLjIsIFZlcnNpb249MjEuMi40
+ LjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjg4ZDE3NTRkNzAwZTQ5YQUBAAAAHURl
+ dkV4cHJlc3MuVXRpbHMuU3ZnLlN2Z0ltYWdlAQAAAAREYXRhBwICAAAACQMAAAAPAwAAAGICAAAC77u/
+ PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz4NCjxzdmcgeD0iMHB4IiB5PSIwcHgi
+ IHZpZXdCb3g9IjAgMCAzMiAzMiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv
+ MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3Bh
+ Y2U9InByZXNlcnZlIiBpZD0iTGF5ZXJfMSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAg
+ MzIgMzIiPg0KICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLkJsdWV7ZmlsbDojMTE3N0Q3O30KCS5Z
+ ZWxsb3d7ZmlsbDojRkZCMTE1O30KCS5CbGFja3tmaWxsOiM3MjcyNzI7fQoJLkdyZWVue2ZpbGw6IzAz
+ OUMyMzt9CgkuUmVke2ZpbGw6I0QxMUMxQzt9Cgkuc3Qwe29wYWNpdHk6MC43NTt9Cgkuc3Qxe29wYWNp
+ dHk6MC41O30KPC9zdHlsZT4NCiAgPGcgaWQ9IkFkZENpcmNsZWQiPg0KICAgIDxwYXRoIGQ9Ik0xNiw0
+ QzkuNCw0LDQsOS40LDQsMTZzNS40LDEyLDEyLDEyczEyLTUuNCwxMi0xMlMyMi42LDQsMTYsNHogTTI0
+ LDE4aC02djZoLTR2LTZIOHYtNGg2VjhoNHY2aDZWMTh6IiBjbGFzcz0iR3JlZW4iIC8+DQogIDwvZz4N
+ Cjwvc3ZnPgs=
+
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFlEZXZFeHByZXNzLkRhdGEudjIxLjIsIFZlcnNpb249MjEuMi40
+ LjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjg4ZDE3NTRkNzAwZTQ5YQUBAAAAHURl
+ dkV4cHJlc3MuVXRpbHMuU3ZnLlN2Z0ltYWdlAQAAAAREYXRhBwICAAAACQMAAAAPAwAAAGICAAAC77u/
+ PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz4NCjxzdmcgeD0iMHB4IiB5PSIwcHgi
+ IHZpZXdCb3g9IjAgMCAzMiAzMiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv
+ MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3Bh
+ Y2U9InByZXNlcnZlIiBpZD0iTGF5ZXJfMSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAg
+ MzIgMzIiPg0KICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLkJsdWV7ZmlsbDojMTE3N0Q3O30KCS5Z
+ ZWxsb3d7ZmlsbDojRkZCMTE1O30KCS5CbGFja3tmaWxsOiM3MjcyNzI7fQoJLkdyZWVue2ZpbGw6IzAz
+ OUMyMzt9CgkuUmVke2ZpbGw6I0QxMUMxQzt9Cgkuc3Qwe29wYWNpdHk6MC43NTt9Cgkuc3Qxe29wYWNp
+ dHk6MC41O30KPC9zdHlsZT4NCiAgPGcgaWQ9IkFkZENpcmNsZWQiPg0KICAgIDxwYXRoIGQ9Ik0xNiw0
+ QzkuNCw0LDQsOS40LDQsMTZzNS40LDEyLDEyLDEyczEyLTUuNCwxMi0xMlMyMi42LDQsMTYsNHogTTI0
+ LDE4aC02djZoLTR2LTZIOHYtNGg2VjhoNHY2aDZWMTh6IiBjbGFzcz0iR3JlZW4iIC8+DQogIDwvZz4N
+ Cjwvc3ZnPgs=
+
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFlEZXZFeHByZXNzLkRhdGEudjIxLjIsIFZlcnNpb249MjEuMi40
+ LjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjg4ZDE3NTRkNzAwZTQ5YQUBAAAAHURl
+ dkV4cHJlc3MuVXRpbHMuU3ZnLlN2Z0ltYWdlAQAAAAREYXRhBwICAAAACQMAAAAPAwAAAMcCAAAC77u/
+ PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz4NCjxzdmcgeD0iMHB4IiB5PSIwcHgi
+ IHZpZXdCb3g9IjAgMCAzMiAzMiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv
+ MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3Bh
+ Y2U9InByZXNlcnZlIiBpZD0iTGF5ZXJfMSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAg
+ MzIgMzIiPg0KICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLlllbGxvd3tmaWxsOiNGRkIxMTU7fQoJ
+ LlJlZHtmaWxsOiNEMTFDMUM7fQoJLkJsdWV7ZmlsbDojMTE3N0Q3O30KCS5HcmVlbntmaWxsOiMwMzlD
+ MjM7fQoJLkJsYWNre2ZpbGw6IzcyNzI3Mjt9CgkuV2hpdGV7ZmlsbDojRkZGRkZGO30KCS5zdDB7b3Bh
+ Y2l0eTowLjc1O30KPC9zdHlsZT4NCiAgPGcgaWQ9IkNvcHkiPg0KICAgIDxwYXRoIGQ9Ik0yMSwySDEx
+ Yy0wLjUsMC0xLDAuNS0xLDF2NUg1QzQuNSw4LDQsOC41LDQsOXYyMGMwLDAuNSwwLjUsMSwxLDFoMTZj
+ MC41LDAsMS0wLjUsMS0xdi01aDVjMC41LDAsMS0wLjUsMS0xICAgVjlMMjEsMnogTTIwLDI4SDZWMTBo
+ OHY1YzAsMC41LDAuNSwxLDEsMWg1VjI4eiBNMjYsMjJoLTR2LTdsLTctN2gtM1Y0aDh2NWMwLDAuNSww
+ LjUsMSwxLDFoNVYyMnoiIGNsYXNzPSJCbGFjayIgLz4NCiAgPC9nPg0KPC9zdmc+Cw==
+
+
+
+ 17, 17
+
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFpEZXZFeHByZXNzLlV0aWxzLnYyMS4yLCBWZXJzaW9uPTIxLjIu
+ NC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI4OGQxNzU0ZDcwMGU0OWEMAwAAAFFT
+ eXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRv
+ a2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAAChEZXZFeHByZXNzLlV0aWxzLkltYWdlQ29sbGVjdGlvblN0
+ cmVhbWVyAgAAAAlJbWFnZVNpemUERGF0YQQHE1N5c3RlbS5EcmF3aW5nLlNpemUDAAAAAgIAAAAF/P//
+ /xNTeXN0ZW0uRHJhd2luZy5TaXplAgAAAAV3aWR0aAZoZWlnaHQAAAgIAwAAABgAAAAYAAAACQUAAAAP
+ BQAAACcLAAAC+gIAAIlQTkcNChoKAAAADUlIRFIAAAAYAAAAGAgGAAAA4Hc9+AAAAARnQU1BAACxjwv8
+ YQUAAAAJcEhZcwAADrwAAA68AZW8ckkAAAKcSURBVEhL3ZTLaxNRFMYLrvRfkD4yc5OgFeeZIIiLVkrV
+ Jq1O6SNGqxUhCtZVkWBIbQitdOVS3AlZtXUnKAq1mUcmr6aPpCVod9KmuBbXn8z0NTMki9Yuij/4uDNn
+ 7jnfnLl3blPTf4PO0NBYAp2lkGFc0BgXVMaF/GUKzrnHQhbcSItepHkCjaWg827IXBt0jj4w0JhmKIwL
+ CkdD4QhUjoLKUrsjR5l5Km/kEhRZYn8xxUeQET3QuGYU2BbzocpeRMZi8E8oAo0lznNQTObdWDS7cbzJ
+ cTE+kc57kGM8ZlGNd0MR3MjxhwYK14o0TyEtEhgdy37alC4SfLne8dte0cE3H420QGCuBU+wKO4mZ32H
+ XZ1+5ubmzjjlnHNsMqwLMu9CWmjGgq8FC/4WyCKFPHtC/4Gxd50xg7wlXpFuoizdwNrALZSHAqhYNRjA
+ +lAP1ocDqA734UdIstczdo0tsEdWrG98ZDJC/UJWg5XXiZ5qLJoyNRFLVeMvU9V4NPU9Hk3Zs+qgCjSy
+ b9+0OeNWg1pEwtbTAWyNhQ60PTaM2rNBFGZmvPZMB5+uMn8UgTIXdl+qSENr0NnpQ74moMgR5AWCrOA2
+ tcQSrF44ocOuwBN8HXnU+/H5k0vvOzvPf5Ck1s+PR9qXLbtrdXraU4pNRlYmkqZKhianIqVYMmLG958l
+ k5Gfs7NnbQZ5f/0zp2g5izb7e1AJBbAWDmLtXi8q9wOoGKOhcBDrd4PYCPViIxTE5mDAXi9/xVvXoJHx
+ kWlkYO1gJxxELdyH7Qe3URvtx86ohNrDO/g10ofS+HjCnulA9xEURQq6n0ZO9CInelAQPLAaLL17da4c
+ f9FVTsS7ylMJU8tTcfPeXq0B890d7fPBPRnX3R3tzjlH5S88LZDGXf/36QAAAABJRU5ErkJggjMCAACJ
+ UE5HDQoaCgAAAA1JSERSAAAAGAAAABgIBgAAAOB3PfgAAAAEZ0FNQQAAsY8L/GEFAAAACXBIWXMAAA68
+ AAAOvAGVvHJJAAAB1UlEQVRIS+2Uu24aQRSGz7hImqTLA1DQpIwiFCF5l9vewciSCysRRap0KEqRmhoW
+ h1swVdLbZaS8gzsXKfwGlgs3thUMhuGPZmE3u3iXTBuJTxrtzsw58885c2aItvzXAGDh/vnHz/vhfiL1
+ ev1pmwib2hEReozg+4yNPO7VXfx4++FFdLUY/EWa6ZeXbragullFdbO66v1nCmono6idV1nVt59Ubcz1
+ HKZFLRBMxGWEL/R3Z//iyrHvFmUD3LbkfI5YNPRNnOzV0twpAZWKlL2HSE1fUoCXC1hU7MB2dFh7H7WI
+ QaRowFjgdK/lcK3ojwR5WcesYgbjp43Gk4FMaoVAP2Q4MRQ86CrO9t9998dmtoa5o+PWrAZ2LmMYhjaW
+ iDBcP4OpXcC8tKyQX7XaT24VwZ3ooUoLtBIO+cHMg2sm5oaGmfW4HEXkUgJxEQh+20VMzBy4ZeJCq96s
+ z7cYw/GOjICoooTDGlsKpkYpdq7pCcT7RRARhKtIFukUiTcmKYJNiNv/VUZg8Ow57xFBqqZX9GgZtZtK
+ 3a3PxSIEjlc57RKhs3qfRBP/fl/MDRmh641J7D7M6PWbjrc4MbQZQ4vIa83VV1RNe2d56785B5/W/bdI
+ 8werE/HGFidAHwAAAABJRU5ErkJgghADAACJUE5HDQoaCgAAAA1JSERSAAAAGAAAABgIBgAAAOB3PfgA
+ AAAEZ0FNQQAAsY8L/GEFAAAACXBIWXMAAA68AAAOvAGVvHJJAAACsklEQVRIS8VVzW7TQBDOc/AeHKom
+ 3t2Z3bVDy08R4gaqKvUZOHDoK3BDvAEHClVVceEaqKqCWtvrnyQOVPAKnHL50Dp2G6WtRNUIPmnl8ex4
+ /vzNbqfzr1BqRmIJJyzgKEBqAqTUw4nqIWYvC5yqHhK/pwI42UMiu8ikQKYEYtGF4wA5CZQqwNH9dZw7
+ H3IPLlRwTMhZISMB1zpjgZgEUpLImXAqAiRKoGBCyVQ7T5v3jCUcC4wNoSCJD0+fvKoDVMYgtuIi4hJQ
+ WMaYejOfmVZIIrPcAEZhTE3SpWHERt0owN7W5tbu9vbdRX2LMtIYa9lUYBTcDQNUljHkxsEVKO9pTAzN
+ 9lOtcHqN8YglDiP7e153pro4I4VKS0xE0+cF5BGhapPOrMJXvmw4oi5OwwCjhepKffE+vKby3EqMTZO0
+ 04RvTQW7L19QznJaapoWfV3rciNRqZVarqiLn3L13GllFX7JALmmqeP+tNVnhjBpg6da4iSc9evTo4fT
+ UksUhjBqM+h0OhPNtfzdzILOo6AAuVEo9AXVc0uYUNC2iHA8t3kVCruKLFIYqcutvAp+Dn5wU0EeMo7n
+ sr0OZ3LWpr9B1beYtDTNrcY321BqSSisxLAdtCQkxNFyA3hilC31i0hj1PZrSfAkKbmpwE9lbhmJFki0
+ bJaqn84SYn+isj9RZ6zIjETCAp4cfqVGIW5s/f9MWNb6hOe64rSqDVNLcGZ2N/jlLMNPemwVEiOxt7Nz
+ x5ef2pltYhVcSEj8cRNq5KGGM4T8Cjr/X2S0gpy7yGgVJa9i9/HG60WbW6FSBMcSZd/AD9HB883lBjix
+ Ap+twlFf4zBivH229WbR5sZ492Djy9D/MBXUnPZyfV8bAX8LZiSR3XZ+Pobrg/1obbAfrQ8OogvZr/fR
+ 2uDArg8Wv5nHH4RP7Rpx+BP5AAAAAElFTkSuQmCC2gIAAIlQTkcNChoKAAAADUlIRFIAAAAYAAAAGAgG
+ AAAA4Hc9+AAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADrwAAA68AZW8ckkAAAJ8SURBVEhL3VXNbtNA
+ EPaBQx+CQ2t7HSde24l6yKGAk1IREBd+GnCjVgEunLkgVQj1CXgCDrlwRXkEUA48AGpVQqWIZmNDiNcO
+ eYFB42Bn3VAoNFz4pNHO7oz9eXZnP0vSf4NAocA1CoFSgEgzISImcM2GQKUQEQtCzYSQUOCqEY8453HM
+ jP0IY7ge55jAV3RIX/6x0XyZYVsA8EPSyeH2zsIJQoUKFTQfzRFw2QCuWhAoBoxVIfmM4Ct5gcDdzhAE
+ cgFCZVaip5egd+3mazGnXS4vt8vOcrtWS+3N3tOLSTwSnpcOG7MtOtp6UEOCNChJUq9atY/ubD77cNe1
+ xPVfIVKECrrNhykBl+e3I9SseI2vzIj7t+51/Lrb8etbneP1G6/YptvprVVfJPHMIe/XG6cShMI8Eg/u
+ NwhJpotmbcqJnQbGxIp7PY0J/oBYE0+zJz6aak08lU48Wv6WxEOxgp910XmRvQfCIS8Kodgo4hksCqEs
+ dNHBOSrYc5wl1KqT65kKMlvkOBecH5bxT2AkT/e45ThLXJ4K25jMmiBQBYKDnT8XO5QSHLECrhjQz9vv
+ UFqSeCTKy75QAbtUbfUrV1t+ZaPFKhutT1eq8di/ff95kjNCKZENeL+7q/ceP7FRr7CFcT3JyUqFcA/O
+ Anw5Xjq82eiHsgljmcZ+khNpopoK/wMvR5mnW8zPl9jnXIn5GmXHOcpY+XI3jhfL3iBfZH5+lXl6kQ1y
+ RebpJeajFUrMN1bZHEHX/fsuOg34h0snvtu8nokuAHO69ZWYEJtCYagaMEIfR4VCkLOmc2LCSLNgiAeK
+ ljxDTBjKBfhC8FkKQ9kAtrb+NkPwr/Ad3DFsyGIxcj4AAAAASUVORK5CYIIL
+
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFlEZXZFeHByZXNzLkRhdGEudjIxLjIsIFZlcnNpb249MjEuMi40
+ LjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjg4ZDE3NTRkNzAwZTQ5YQUBAAAAHURl
+ dkV4cHJlc3MuVXRpbHMuU3ZnLlN2Z0ltYWdlAQAAAAREYXRhBwICAAAACQMAAAAPAwAAAIkDAAAC77u/
+ PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz4NCjxzdmcgeD0iMHB4IiB5PSIwcHgi
+ IHZpZXdCb3g9IjAgMCAzMiAzMiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv
+ MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3Bh
+ Y2U9InByZXNlcnZlIiBpZD0iTGF5ZXJfMSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAg
+ MzIgMzIiPg0KICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLkdyZWVue2ZpbGw6IzAzOUMyMzt9Cgku
+ QmxhY2t7ZmlsbDojNzI3MjcyO30KCS5SZWR7ZmlsbDojRDExQzFDO30KCS5ZZWxsb3d7ZmlsbDojRkZC
+ MTE1O30KCS5CbHVle2ZpbGw6IzExNzdENzt9CgkuV2hpdGV7ZmlsbDojRkZGRkZGO30KCS5zdDB7b3Bh
+ Y2l0eTowLjU7fQoJLnN0MXtvcGFjaXR5OjAuNzU7fQo8L3N0eWxlPg0KICA8ZyBpZD0iSW5zZXJ0VHJl
+ ZVZpZXciPg0KICAgIDxwYXRoIGQ9Ik0xMyw4SDVDNC40LDgsNCw3LjYsNCw3VjNjMC0wLjUsMC40LTEs
+ MS0xaDhjMC42LDAsMSwwLjUsMSwxdjRDMTQsNy42LDEzLjYsOCwxMyw4eiBNMjYsMTd2LTQgICBjMC0w
+ LjYtMC41LTEtMS0xaC04Yy0wLjUsMC0xLDAuNC0xLDF2NGMwLDAuNSwwLjUsMSwxLDFoOEMyNS41LDE4
+ LDI2LDE3LjUsMjYsMTd6IE0yNiwyN3YtNGMwLTAuNS0wLjUtMS0xLTFoLThjLTAuNSwwLTEsMC41LTEs
+ MSAgIHY0YzAsMC41LDAuNSwxLDEsMWg4QzI1LjUsMjgsMjYsMjcuNSwyNiwyN3oiIGNsYXNzPSJZZWxs
+ b3ciIC8+DQogICAgPHBvbHlnb24gcG9pbnRzPSIxNCwxNiAxNCwxNCAxMCwxNCAxMCwxMCA4LDEwIDgs
+ MjYgMTQsMjYgMTQsMjQgMTAsMjQgMTAsMTYgICIgY2xhc3M9IkJsYWNrIiAvPg0KICA8L2c+DQo8L3N2
+ Zz4L
+
+
+
\ No newline at end of file
diff --git a/app/TaskFlow/frmCockpitConfig.vb b/app/TaskFlow/frmCockpitConfig.vb
new file mode 100644
index 0000000..2318f97
--- /dev/null
+++ b/app/TaskFlow/frmCockpitConfig.vb
@@ -0,0 +1,931 @@
+Imports DevExpress.XtraBars.Ribbon
+Imports DigitalData.GUIs.Common
+
+Public Class frmCockpitConfig
+ Private Selected_Cockpit_ID As Integer
+ Private LoadInAction As Boolean = False
+ Private _treeNodeCounts As New Dictionary(Of Integer, Integer)
+ Private _currentCockpitDefinition As CockpitDefinitionData ' <-- NEU
+ ' ===== NESTED CLASS FÜR COCKPIT-DEFINITION =====
+ Private Class CockpitDefinitionData
+ Public Property PK_CFG_COCKPIT_DEFINITION_ID As Integer
+ Public Property Active As Boolean
+ Public Property ParentID As Integer?
+ Public Property TypeID As Integer?
+ Public Property IconID As Integer?
+ Public Property Name As String
+ Public Property FK_ProfileID As Integer?
+ Public Property FK_ChartID As Integer?
+ Public Property FK_MonitorID As Integer?
+ Public Property SQL_Query As String
+ Public Property SQL_Query_Count As String
+ Public Property Comment As String
+
+ Public Sub New()
+ Name = String.Empty
+ SQL_Query = String.Empty
+ SQL_Query_Count = String.Empty
+ Comment = String.Empty
+ End Sub
+
+ Public Shared Function FromTreeNode(oNode As DevExpress.XtraTreeList.Nodes.TreeListNode) As CockpitDefinitionData
+ Dim data As New CockpitDefinitionData()
+
+ data.PK_CFG_COCKPIT_DEFINITION_ID = GetNodeValue(Of Integer)(oNode, "PK_CFG_COCKPIT_DEFINITION_ID", 0)
+ data.Active = GetNodeValue(Of Boolean)(oNode, "ACTIVE", False)
+ data.ParentID = GetNodeValueNullable(Of Integer)(oNode, "PARENT_ID")
+ data.TypeID = GetNodeValueNullable(Of Integer)(oNode, "TYPE_ID")
+ data.IconID = GetNodeValueNullable(Of Integer)(oNode, "ICON_ID")
+ data.Name = GetNodeValue(Of String)(oNode, "NAME", String.Empty)
+ data.FK_ProfileID = GetNodeValueNullable(Of Integer)(oNode, "FK_PROFILE_ID")
+ data.FK_ChartID = GetNodeValueNullable(Of Integer)(oNode, "FK_CHART_ID")
+ data.FK_MonitorID = GetNodeValueNullable(Of Integer)(oNode, "FK_MONITOR_ID")
+ data.SQL_Query = GetNodeValue(Of String)(oNode, "SQL_QUERY", String.Empty)
+ data.SQL_Query_Count = GetNodeValue(Of String)(oNode, "SQL_QUERY_COUNT", String.Empty)
+ data.Comment = GetNodeValue(Of String)(oNode, "COMMENT", String.Empty)
+
+ Return data
+ End Function
+
+ Private Shared Function GetNodeValue(Of T)(oNode As DevExpress.XtraTreeList.Nodes.TreeListNode, fieldName As String, defaultValue As T) As T
+ Dim value As Object = oNode.GetValue(fieldName)
+ If value Is Nothing OrElse IsDBNull(value) Then
+ Return defaultValue
+ End If
+ Return CType(value, T)
+ End Function
+
+ Private Shared Function GetNodeValueNullable(Of T As Structure)(oNode As DevExpress.XtraTreeList.Nodes.TreeListNode, fieldName As String) As T?
+ Dim value As Object = oNode.GetValue(fieldName)
+ If value Is Nothing OrElse IsDBNull(value) Then
+ Return Nothing
+ End If
+ Return CType(value, T)
+ End Function
+ End Class
+ ' ===== ENDE NESTED CLASS =====
+
+ Private Sub BarButtonItem1_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItem1.ItemClick
+ Dim frm As New frmUserSelect
+ frm.ShowDialog()
+ If Not String.IsNullOrEmpty(frm.SelectedUserName) Then
+ Dim frmUserTest As New crmCockpit_UserTest
+ frmUserTest.CheckUserID = frm.SelectedUserID
+ frmUserTest.CheckUserName = frm.SelectedUserName
+ frmUserTest.CheckUserLanguage = frm.SelectedUserLanguage
+ frmUserTest.ShowDialog()
+ End If
+ End Sub
+
+ Private Sub BarButtonItem2_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItem2.ItemClick
+ Load_TBTF_CFG_COCKPIT_DEFINITION()
+ End Sub
+ Sub Load_CFG_COCKPIT()
+ Try
+ LoadInAction = True
+ Dim oSQL = "SELECT PK_CFG_COCKPIT_ID, ACTIVE, NAME, COMMENT FROM TBTF_CFG_COCKPIT WITH (NOLOCK)"
+ Dim DT_CONFIG = DatabaseFallback.GetDatatableECM(oSQL)
+ If Not IsNothing(DT_CONFIG) Then
+ ' DataBindings.Clear() ist nur für Two-Way-Binding notwendig
+ LookUpEdit1.Properties.DataSource = DT_CONFIG
+ LookUpEdit1.Properties.DisplayMember = "NAME"
+ LookUpEdit1.Properties.ValueMember = "PK_CFG_COCKPIT_ID"
+ ' Spalten automatisch aus DataSource generieren
+ LookUpEdit1.Properties.PopulateColumns()
+ ' Jetzt können Sie die Spalten konfigurieren
+ LookUpEdit1.Properties.Columns("PK_CFG_COCKPIT_ID").Visible = False
+ LookUpEdit1.Properties.Columns("ACTIVE").Visible = False
+ LookUpEdit1.Properties.Columns("COMMENT").Visible = False
+ ' Optional: Erste Element auswählen
+ LookUpEdit1.EditValue = DT_CONFIG.Rows(0)("PK_CFG_COCKPIT_ID")
+
+ ' Optional: Dropdown-Style festlegen
+ LookUpEdit1.Properties.TextEditStyle = DevExpress.XtraEditors.Controls.TextEditStyles.DisableTextEditor
+ Else
+ MsgBox("No cockpit config found.", MsgBoxStyle.Exclamation)
+ End If
+ Catch ex As Exception
+ LOGGER.Error($"Error in Load_CFG_COCKPIT: {ex.Message}")
+ Finally
+ LoadInAction = False
+
+ End Try
+
+ End Sub
+ Sub Load_TBTF_CFG_COCKPIT_DEFINITION()
+ Try
+ Dim oSQL = $"
+ SELECT
+ PK_CFG_COCKPIT_DEFINITION_ID
+ ,ACTIVE
+ ,PARENT_ID
+ ,TYPE_ID
+ ,ICON_ID
+ ,NAME
+ ,FK_PROFILE_ID
+ ,FK_CHART_ID
+ ,FK_MONITOR_ID
+ ,SQL_QUERY
+ ,SQL_QUERY_COUNT
+ ,COMMENT
+ ,ADDED_WHO
+ ,ADDED_WHEN
+ ,CHANGED_WHO
+ ,CHANGED_WHEN
+ FROM [dbo].[TBTF_CFG_COCKPIT_DEFINITION] WITH (NOLOCK) WHERE FK_CFG_COCKPIT_ID = {Selected_Cockpit_ID} ORDER BY PARENT_ID "
+ Dim DT_CONFIG_DEF = DatabaseFallback.GetDatatableECM(oSQL)
+ If Not IsNothing(DT_CONFIG_DEF) Then
+ ' ===== NEUE DATATABLE MIT KORREKTEN TYPEN ERSTELLEN =====
+ Dim cleanedTable As New DataTable()
+ cleanedTable.Columns.Add("PK_CFG_COCKPIT_DEFINITION_ID", GetType(Integer))
+ cleanedTable.Columns.Add("ACTIVE", GetType(Boolean))
+ cleanedTable.Columns.Add("PARENT_ID", GetType(Integer))
+ cleanedTable.Columns.Add("TYPE_ID", GetType(Integer))
+ cleanedTable.Columns.Add("ICON_ID", GetType(Integer))
+ cleanedTable.Columns.Add("NAME", GetType(String))
+ cleanedTable.Columns.Add("FK_PROFILE_ID", GetType(Integer))
+ cleanedTable.Columns.Add("FK_CHART_ID", GetType(Integer))
+ cleanedTable.Columns.Add("FK_MONITOR_ID", GetType(Integer))
+ cleanedTable.Columns.Add("SQL_QUERY", GetType(String))
+ cleanedTable.Columns.Add("SQL_QUERY_COUNT", GetType(String))
+ cleanedTable.Columns.Add("COMMENT", GetType(String))
+ cleanedTable.Columns.Add("ADDED_WHO", GetType(String))
+ cleanedTable.Columns.Add("ADDED_WHEN", GetType(DateTime))
+ cleanedTable.Columns.Add("CHANGED_WHO", GetType(String))
+ cleanedTable.Columns.Add("CHANGED_WHEN", GetType(DateTime))
+
+ ' ===== DATEN MIT KORREKTEN TYPEN KOPIEREN =====
+ For Each row As DataRow In DT_CONFIG_DEF.Rows
+ Dim newRow = cleanedTable.NewRow()
+ newRow("PK_CFG_COCKPIT_DEFINITION_ID") = Convert.ToInt32(row("PK_CFG_COCKPIT_DEFINITION_ID"))
+ newRow("ACTIVE") = row("ACTIVE")
+ newRow("PARENT_ID") = If(IsDBNull(row("PARENT_ID")), 0, Convert.ToInt32(row("PARENT_ID")))
+ newRow("TYPE_ID") = If(IsDBNull(row("TYPE_ID")), 0, Convert.ToInt32(row("TYPE_ID")))
+
+ ' ===== ICON_ID KORRIGIERT: Mit Konvertierung =====
+ newRow("ICON_ID") = If(IsDBNull(row("ICON_ID")), 0, Convert.ToInt32(row("ICON_ID")))
+
+ newRow("NAME") = If(IsDBNull(row("NAME")), String.Empty, row("NAME").ToString())
+
+ ' ===== AUCH FK-FELDER SOLLTEN KONVERTIERT WERDEN =====
+ newRow("FK_PROFILE_ID") = If(IsDBNull(row("FK_PROFILE_ID")), 0, Convert.ToInt32(row("FK_PROFILE_ID")))
+ newRow("FK_CHART_ID") = If(IsDBNull(row("FK_CHART_ID")), 0, Convert.ToInt32(row("FK_CHART_ID")))
+ newRow("FK_MONITOR_ID") = If(IsDBNull(row("FK_MONITOR_ID")), 0, Convert.ToInt32(row("FK_MONITOR_ID")))
+
+ newRow("SQL_QUERY") = row("SQL_QUERY")
+ newRow("SQL_QUERY_COUNT") = row("SQL_QUERY_COUNT")
+ newRow("COMMENT") = row("COMMENT")
+ newRow("ADDED_WHO") = row("ADDED_WHO")
+ newRow("ADDED_WHEN") = row("ADDED_WHEN")
+ newRow("CHANGED_WHO") = row("CHANGED_WHO")
+ newRow("CHANGED_WHEN") = row("CHANGED_WHEN")
+ cleanedTable.Rows.Add(newRow)
+ Next
+
+ LOGGER.Debug($"Cleaned table created with {cleanedTable.Rows.Count} rows")
+ LOGGER.Debug($"PK_CFG_COCKPIT_DEFINITION_ID Type: {cleanedTable.Columns("PK_CFG_COCKPIT_DEFINITION_ID").DataType.Name}")
+ LOGGER.Debug($"PARENT_ID Column Type: {cleanedTable.Columns("PARENT_ID").DataType.Name}")
+ LOGGER.Debug($"ICON_ID Column Type: {cleanedTable.Columns("ICON_ID").DataType.Name}")
+
+ Load_TreeView_CONFIG(cleanedTable)
+ Else
+ MsgBox("No cockpit definition found.", MsgBoxStyle.Exclamation)
+ End If
+ Catch ex As Exception
+ LOGGER.Error($"Error in Load_TBTF_CFG_COCKPIT_DEFINITION: {ex.Message}")
+ LOGGER.Error(ex)
+ End Try
+ End Sub
+
+ Private Sub LookUpEdit1_EditValueChanged(sender As Object, e As EventArgs) Handles LookUpEdit1.EditValueChanged
+ If Not IsNothing(LookUpEdit1.EditValue) Then
+ Try
+ Selected_Cockpit_ID = LookUpEdit1.EditValue
+ CheckEdit_Cockpit_Active.Checked = LookUpEdit1.Properties.GetDataSourceValue("ACTIVE", LookUpEdit1.ItemIndex)
+ Load_TBTF_CFG_COCKPIT_DEFINITION()
+ Catch ex As Exception
+ LOGGER.Error($"Error in LookUpEdit1_EditValueChanged: {ex.Message}")
+ End Try
+
+ End If
+
+ End Sub
+
+ Private Sub frmCockpitConfig_Load(sender As Object, e As EventArgs) Handles Me.Load
+ Load_TypeID_LookUp()
+ Load_IconID_LookUp()
+ Load_Profile_LookUp()
+ Load_Chart_LookUp()
+ Load_Monitor_LookUp()
+ Load_CFG_COCKPIT()
+ End Sub
+ Private Sub CheckEdit_Cockpit_Active_CheckedChanged(sender As Object, e As EventArgs) Handles CheckEdit_Cockpit_Active.CheckedChanged
+ If LoadInAction Then
+ Exit Sub
+ End If
+ Dim updateSQL = $"UPDATE TBTF_CFG_COCKPIT SET ACTIVE = {(If(CheckEdit_Cockpit_Active.Checked, 1, 0))},
+ CHANGED_WHO = '{Environment.UserName}', CHANGED_WHEN = GETDATE()
+ WHERE PK_CFG_COCKPIT_ID = {Selected_Cockpit_ID}"
+ Dim result = DatabaseFallback.ExecuteNonQueryECM(updateSQL)
+ End Sub
+ Private Sub Load_TreeView_CONFIG(pDTNodes As DataTable)
+ Try
+ LOGGER.Debug("=== TreeView Data Analysis ===")
+ LOGGER.Debug($"Total rows: {pDTNodes.Rows.Count}")
+
+ 'For Each row As DataRow In pDTNodes.Rows
+ ' Dim pkId = If(IsDBNull(row("PK_CFG_COCKPIT_DEFINITION_ID")), "NULL", row("PK_CFG_COCKPIT_DEFINITION_ID").ToString())
+ ' Dim parentId = If(IsDBNull(row("PARENT_ID")), "NULL", row("PARENT_ID").ToString())
+ ' Dim name = If(IsDBNull(row("NAME")), "NULL", row("NAME").ToString())
+ ' LOGGER.Debug($"ID={pkId}, PARENT_ID={parentId}, NAME={name}")
+ 'Next
+
+ Dim rootCount = pDTNodes.AsEnumerable().Count(Function(r) Not IsDBNull(r("PARENT_ID")) AndAlso CInt(r("PARENT_ID")) = 0)
+ LOGGER.Debug($"Root nodes (PARENT_ID = 0): {rootCount}")
+
+ ' ===== PARENT_ID-Datentyp prüfen =====
+ If pDTNodes.Rows.Count > 0 Then
+ Dim firstParentId = pDTNodes.Rows(0)("PARENT_ID")
+ LOGGER.Debug($"PARENT_ID Type: {firstParentId.GetType().Name}, Value: {firstParentId}")
+ End If
+
+ ' ===== ANZAHL DER OVERVIEW-KNOTEN ERMITTELN (VOR WEITEREN FILTERN) =====
+ Dim oOverviewRows As DataRow() = pDTNodes.Select("TYPE_ID = 0")
+ LOGGER.Debug($"Load_Treeview: Found [{oOverviewRows.Length}] node(s) with TYPE_ID=0 (Overview)")
+
+ TreeList_Cockpit.BeginUpdate()
+ Try
+ ' ===== TreeList VOLLSTÄNDIG zurücksetzen =====
+ TreeList_Cockpit.DataSource = Nothing
+ TreeList_Cockpit.ClearNodes()
+
+ ' ===== Hierarchie-Felder setzen =====
+ TreeList_Cockpit.KeyFieldName = "PK_CFG_COCKPIT_DEFINITION_ID"
+ TreeList_Cockpit.ParentFieldName = "PARENT_ID"
+ TreeList_Cockpit.RootValue = 0 ' Explizit setzen: Root-Nodes haben PARENT_ID = 0
+
+ ' ===== Jetzt DataSource zuweisen =====
+ TreeList_Cockpit.DataSource = pDTNodes
+
+ '' ===== DEBUG: ImageList-Inhalt prüfen =====
+ 'If TreeList_Cockpit.SelectImageList IsNot Nothing Then
+ ' LOGGER.Debug($"SelectImageList hat {TreeList_Cockpit.SelectImageList.Images.Count} Bilder")
+ ' For i As Integer = 0 To TreeList_Cockpit.SelectImageList.Images.Count - 1
+ ' LOGGER.Debug($" Image Index {i}: {TreeList_Cockpit.SelectImageList.Images.Keys(i)}")
+ ' Next
+ 'Else
+ ' LOGGER.Warn("SelectImageList ist Nothing!")
+ 'End If
+
+ AddHandler TreeList_Cockpit.CustomDrawNodeCell, AddressOf TreeList_Config_CustomDrawNodeCell
+
+ ' ===== MODERNES DESIGN =====
+ TreeList_Cockpit.Appearance.Row.Font = New Font("Segoe UI", 12, FontStyle.Regular)
+ TreeList_Cockpit.Appearance.FocusedRow.Font = New Font("Segoe UI", 12, FontStyle.Bold)
+ TreeList_Cockpit.Appearance.HideSelectionRow.Font = New Font("Segoe UI", 12, FontStyle.Regular)
+
+ TreeList_Cockpit.Appearance.Row.BackColor = Color.White
+ TreeList_Cockpit.Appearance.Row.ForeColor = Color.FromArgb(50, 50, 50)
+ TreeList_Cockpit.Appearance.FocusedRow.BackColor = Color.FromArgb(210, 230, 255)
+ TreeList_Cockpit.Appearance.FocusedRow.ForeColor = Color.FromArgb(20, 20, 20)
+ TreeList_Cockpit.Appearance.HideSelectionRow.BackColor = Color.FromArgb(225, 235, 250)
+ TreeList_Cockpit.Appearance.HideSelectionRow.ForeColor = Color.FromArgb(50, 50, 50)
+
+ TreeList_Cockpit.RowHeight = 28
+
+ Dim oVisibleColumns As New System.Collections.Generic.HashSet(Of String)(StringComparer.OrdinalIgnoreCase) From {"NAME"}
+ For Each oColumn As DevExpress.XtraTreeList.Columns.TreeListColumn In TreeList_Cockpit.Columns
+ oColumn.Visible = oVisibleColumns.Contains(oColumn.FieldName)
+ Next
+ Finally
+ TreeList_Cockpit.EndUpdate()
+ End Try
+
+ ' ===== KNOTEN AUF-/ZUKLAPPEN BASIEREND AUF ANZAHL DER OVERVIEW-KNOTEN =====
+ If oOverviewRows.Length = 1 Then
+ LOGGER.Debug("Load_Treeview: Only 1 overview node found - expanding all nodes")
+ TreeList_Cockpit.ExpandAll()
+ ElseIf oOverviewRows.Length > 1 Then
+ LOGGER.Debug($"Load_Treeview: [{oOverviewRows.Length}] overview nodes found - collapsing all nodes")
+ TreeList_Cockpit.CollapseAll()
+ Else
+ LOGGER.Warn("Load_Treeview: No overview nodes (TYPE_ID=0) found - keeping default collapsed state")
+ End If
+
+ '' ===== DETAILLIERTES LOGGING =====
+ 'LOGGER.Debug("=== DETAILED NODE STRUCTURE AFTER SETUP ===")
+ 'LOGGER.Debug($"TreeList State - AllNodesCount: {TreeList_Cockpit.AllNodesCount}, RootNodes: {TreeList_Cockpit.Nodes.Count}")
+
+ 'Dim allNodesList As New List(Of DevExpress.XtraTreeList.Nodes.TreeListNode)
+ 'CollectAllNodes(TreeList_Cockpit.Nodes, allNodesList)
+
+ 'LOGGER.Debug($"Total nodes collected recursively: {allNodesList.Count}")
+
+ 'For Each node As DevExpress.XtraTreeList.Nodes.TreeListNode In allNodesList
+ ' Dim nodeId = node.GetValue("PK_CFG_COCKPIT_DEFINITION_ID")
+ ' Dim nodeName = node.GetValue("NAME")
+ ' Dim nodeParent = node.GetValue("PARENT_ID")
+ ' Dim level = node.Level
+ ' Dim parentInfo = If(node.ParentNode Is Nothing, "NULL", $"ID={node.ParentNode.GetValue("PK_CFG_COCKPIT_DEFINITION_ID")}")
+
+ ' LOGGER.Debug($" [Level {level}] ID={nodeId}, NAME={nodeName}, PARENT_ID={nodeParent}, ParentNode={parentInfo}, HasChildren={node.HasChildren}, ChildCount={node.Nodes.Count}, IsExpanded={node.Expanded}")
+ 'Next
+
+ Catch ex As Exception
+ LOGGER.Error(ex)
+ Finally
+ Me.Cursor = Cursors.Default
+ End Try
+ End Sub
+
+
+ ' Hilfsmethode zum rekursiven Sammeln aller Nodes
+ Private Sub CollectAllNodes(nodes As DevExpress.XtraTreeList.Nodes.TreeListNodes, ByRef nodeList As List(Of DevExpress.XtraTreeList.Nodes.TreeListNode))
+ For Each node As DevExpress.XtraTreeList.Nodes.TreeListNode In nodes
+ nodeList.Add(node)
+ If node.Nodes.Count > 0 Then
+ CollectAllNodes(node.Nodes, nodeList)
+ End If
+ Next
+ End Sub
+ Private Sub TreeList_Config_CustomDrawNodeCell(sender As Object, e As DevExpress.XtraTreeList.CustomDrawNodeCellEventArgs)
+ Try
+ Dim oPk As Object = e.Node.GetValue("PK_CFG_COCKPIT_DEFINITION_ID")
+ If oPk Is Nothing OrElse IsDBNull(oPk) Then
+ Exit Sub
+ End If
+ ' ===== ACTIVE-Status prüfen und Hintergrundfarbe setzen =====
+ Dim oActive As Object = e.Node.GetValue("ACTIVE")
+ If oActive IsNot Nothing AndAlso Not IsDBNull(oActive) Then
+ If Not CBool(oActive) Then ' ACTIVE = 0/False
+ e.Appearance.BackColor = Color.FromArgb(255, 235, 235) ' Leicht rot
+ e.Appearance.ForeColor = Color.FromArgb(120, 0, 0) ' Dunkelrot für Text
+ End If
+ End If
+
+ Dim oPkInt As Integer = CInt(oPk)
+ If Not _treeNodeCounts.ContainsKey(oPkInt) Then
+ Exit Sub
+ End If
+
+ If _treeNodeCounts(oPkInt) > 0 Then
+ e.Appearance.Font = New Font(e.Appearance.Font, FontStyle.Bold)
+ Else
+ e.Appearance.Font = New Font(e.Appearance.Font, FontStyle.Regular)
+ End If
+ Catch ex As Exception
+ LOGGER.Error(ex)
+ End Try
+ End Sub
+
+ Private Sub TreeList_Cockpit_FocusedNodeChanged(sender As Object, e As DevExpress.XtraTreeList.FocusedNodeChangedEventArgs) Handles TreeList_Cockpit.FocusedNodeChanged
+ Try
+ If e.Node Is Nothing Then
+ LOGGER.Debug("TreeList1_FocusedNodeChanged: Node is Nothing - skipping")
+ Exit Sub
+ End If
+
+ If LoadInAction = True Then
+ LOGGER.Debug("TreeList1_FocusedNodeChanged: Form not shown - skipping")
+ Exit Sub
+ End If
+ LOGGER.Debug("TreeList1_FocusedNodeChanged: Node changed - processing")
+ ProcessTreeListNodeAsync(e.Node)
+
+ Catch ex As Exception
+ LOGGER.Error(ex)
+ End Try
+ End Sub
+ Private Function ProcessTreeListNodeAsync(oNode As DevExpress.XtraTreeList.Nodes.TreeListNode)
+ Try
+ ' Daten in formularweites Objekt laden
+ _currentCockpitDefinition = CockpitDefinitionData.FromTreeNode(oNode)
+
+
+ LOGGER.Debug($"TreeList_Cockpit Node selected - PK_CFG_COCKPIT_DEFINITION_ID:[{_currentCockpitDefinition.PK_CFG_COCKPIT_DEFINITION_ID}] NAME:[{_currentCockpitDefinition.Name}] TYPE_ID:[{_currentCockpitDefinition.TypeID}] FK_PROFILE_ID:[{_currentCockpitDefinition.FK_ProfileID}]")
+
+ If Not _currentCockpitDefinition.TypeID.HasValue Then
+ LOGGER.Debug("ProcessTreeListNodeAsync: TYPE_ID is Nothing - Folder node, skipping")
+ Exit Function
+ End If
+
+ ' Jetzt können Sie überall im Formular auf _currentCockpitDefinition zugreifen
+ ' z.B. _currentCockpitDefinition.SQL_Query, _currentCockpitDefinition.TypeID.Value etc.
+ TextEdit_PK_CFG_COCKPIT_DEFINITION_ID.Text = _currentCockpitDefinition.PK_CFG_COCKPIT_DEFINITION_ID.ToString()
+ TextEdit_ParentID.Text = If(_currentCockpitDefinition.ParentID.HasValue, _currentCockpitDefinition.ParentID.Value.ToString(), String.Empty)
+ CheckEdit_Active.Checked = _currentCockpitDefinition.Active
+ TextEdit_Bezeichnung.Text = _currentCockpitDefinition.Name
+ TextEdit_Comment.Text = _currentCockpitDefinition.Comment
+
+ If _currentCockpitDefinition.FK_ProfileID.HasValue Then
+ LookUpEditProfil.EditValue = _currentCockpitDefinition.FK_ProfileID.Value
+ 'Else
+ ' LookUpEditProfil.EditValue = 0
+ End If
+ If _currentCockpitDefinition.FK_ChartID.HasValue Then
+ LookUpEditChart.EditValue = _currentCockpitDefinition.FK_ChartID.Value
+ Else
+ LookUpEditChart.EditValue = 0
+ End If
+ If _currentCockpitDefinition.FK_MonitorID.HasValue Then
+ LookUpEditMonitor.EditValue = _currentCockpitDefinition.FK_MonitorID.Value
+ Else
+ LookUpEditMonitor.EditValue = 0
+ End If
+
+ ' TYPE_ID im LookUpEdit setzen
+ If _currentCockpitDefinition.TypeID.HasValue Then
+ LookUpEditTypeID.EditValue = _currentCockpitDefinition.TypeID.Value
+ bbtnSQL_Data.Visibility = DevExpress.XtraBars.BarItemVisibility.Never
+ bbtnSQL_Count.Visibility = DevExpress.XtraBars.BarItemVisibility.Never
+ bbtnitm_NodeOverviewAdd.Visibility = DevExpress.XtraBars.BarItemVisibility.Never
+ bbtnitm_NodeProfilAdd.Visibility = DevExpress.XtraBars.BarItemVisibility.Never
+ ProfileID_display(False)
+ Monitor_display(False)
+ Chart_display(False)
+ Select Case _currentCockpitDefinition.TypeID.Value
+ Case 0 ' Overview
+ bbtnSQL_Data.Visibility = DevExpress.XtraBars.BarItemVisibility.Always
+ bbtnSQL_Count.Visibility = DevExpress.XtraBars.BarItemVisibility.Always
+ bbtnitm_NodeOverviewAdd.Visibility = DevExpress.XtraBars.BarItemVisibility.Always
+ bbtnitm_NodeProfilAdd.Visibility = DevExpress.XtraBars.BarItemVisibility.Always
+ LOGGER.Debug("Selected node is of type Overview")
+ Case 1 ' Profil
+ bbtnSQL_Data.Visibility = DevExpress.XtraBars.BarItemVisibility.Always
+ bbtnSQL_Count.Visibility = DevExpress.XtraBars.BarItemVisibility.Always
+ bbtnitm_NodeProfilAdd.Visibility = DevExpress.XtraBars.BarItemVisibility.Always
+ ProfileID_display(True)
+ LOGGER.Debug("Selected node is of type Profil")
+ Case 2 ' Monitor
+ LOGGER.Debug("Selected node is of type Monitor")
+ Monitor_display(True)
+ Case 3 ' Chart
+ LOGGER.Debug("Selected node is of type Chart")
+ Chart_display(True)
+ Case Else
+ LOGGER.Warn($"Selected node has an unknown TYPE_ID: {_currentCockpitDefinition.TypeID.Value}")
+ End Select
+ Else
+ LookUpEditTypeID.EditValue = Nothing
+ End If
+
+ ' ICON_ID im LookUpEdit setzen
+ If _currentCockpitDefinition.IconID.HasValue Then
+ LookUpEdit_Image.EditValue = _currentCockpitDefinition.IconID.Value
+ Else
+ LookUpEdit_Image.EditValue = Nothing
+ End If
+
+ Catch ex As Exception
+ LOGGER.Error(ex)
+ Finally
+
+ End Try
+ End Function
+ Sub Monitor_display(visible As Boolean)
+ LookUpEditMonitor.Visible = visible
+ LabelControl_Monitor.Visible = visible
+ End Sub
+ Sub Chart_display(visible As Boolean)
+ LookUpEditChart.Visible = visible
+ LabelControl_Chart.Visible = visible
+ End Sub
+ Sub ProfileID_display(visible As Boolean)
+ LookUpEditProfil.Visible = visible
+ LabelControl_Profil.Visible = visible
+ End Sub
+ Private Sub frmCockpitConfig_Shown(sender As Object, e As EventArgs) Handles Me.Shown
+ Dim oFirstNode As DevExpress.XtraTreeList.Nodes.TreeListNode = TreeList_Cockpit.Nodes.FirstOrDefault()
+ If oFirstNode IsNot Nothing Then
+ LOGGER.Debug($"Selecting first TreeList node: [{oFirstNode.GetValue("NAME")}]")
+ TreeList_Cockpit.FocusedNode = oFirstNode
+ ProcessTreeListNodeAsync(oFirstNode)
+ Else
+ LOGGER.Debug("No TreeList nodes found - falling back to Decide_Load")
+ End If
+ End Sub
+
+ Private Sub SimpleButton1_Click(sender As Object, e As EventArgs)
+
+ End Sub
+ Private Sub Load_TypeID_LookUp()
+ Try
+ Dim typeList As New List(Of Object) From {
+ New With {.TYPE_ID = 0, .TYPE_NAME = "Overview"},
+ New With {.TYPE_ID = 1, .TYPE_NAME = "Profil"},
+ New With {.TYPE_ID = 2, .TYPE_NAME = "Monitor"},
+ New With {.TYPE_ID = 3, .TYPE_NAME = "Chart"}
+ }
+
+ LookUpEditTypeID.Properties.DataSource = typeList
+ LookUpEditTypeID.Properties.DisplayMember = "TYPE_NAME"
+ LookUpEditTypeID.Properties.ValueMember = "TYPE_ID"
+
+ LookUpEditTypeID.Properties.PopulateColumns()
+ LookUpEditTypeID.Properties.Columns("TYPE_ID").Visible = False
+
+ LookUpEditTypeID.Properties.TextEditStyle = DevExpress.XtraEditors.Controls.TextEditStyles.DisableTextEditor
+ Catch ex As Exception
+ LOGGER.Error($"Error in Load_TypeID_LookUp: {ex.Message}")
+ End Try
+ End Sub
+ Private Sub Load_Profile_LookUp()
+ Try
+ Dim oSQL = "SELECT 0 GUID, '' NAME UNION SELECT GUID, NAME FROM TBPM_PROFILE WITH (NOLOCK)"
+ Dim oDT = DatabaseFallback.GetDatatableECM(oSQL)
+
+ LookUpEditProfil.Properties.DataSource = oDT
+ LookUpEditProfil.Properties.DisplayMember = "NAME"
+ LookUpEditProfil.Properties.ValueMember = "GUID"
+
+ LookUpEditProfil.Properties.PopulateColumns()
+ LookUpEditProfil.Properties.Columns("GUID").Visible = False
+
+ LookUpEditProfil.Properties.TextEditStyle = DevExpress.XtraEditors.Controls.TextEditStyles.DisableTextEditor
+ Catch ex As Exception
+ LOGGER.Error($"Error in Load_ProfileID_LookUp: {ex.Message}")
+ End Try
+ End Sub
+ Private Sub Load_Chart_LookUp()
+ Try
+ Dim oSQL = "SELECT 0 COCKPIT_CHART_ID UNION SELECT DISTINCT COCKPIT_CHART_ID FROM TBPM_CHART WITH (NOLOCK) ORDER BY COCKPIT_CHART_ID"
+ Dim oDT = DatabaseFallback.GetDatatableECM(oSQL)
+
+ LookUpEditChart.Properties.DataSource = oDT
+ LookUpEditChart.Properties.DisplayMember = "COCKPIT_CHART_ID"
+ LookUpEditChart.Properties.ValueMember = "COCKPIT_CHART_ID"
+
+ LookUpEditChart.Properties.PopulateColumns()
+
+ LookUpEditChart.Properties.TextEditStyle = DevExpress.XtraEditors.Controls.TextEditStyles.DisableTextEditor
+ Catch ex As Exception
+ LOGGER.Error($"Error in Load_Chart_LookUp: {ex.Message}")
+ End Try
+ End Sub
+ Private Sub Load_Monitor_LookUp()
+ Try
+ Dim oSQL = "SELECT 0 ID UNION SELECT DISTINCT COCKPIT_ID ID FROM TBPM_MONITOR_KONFIG WITH (NOLOCK) ORDER BY COCKPIT_ID"
+ Dim oDT = DatabaseFallback.GetDatatableECM(oSQL)
+
+ LookUpEditMonitor.Properties.DataSource = oDT
+ LookUpEditMonitor.Properties.DisplayMember = "ID"
+ LookUpEditMonitor.Properties.ValueMember = "ID"
+
+ LookUpEditMonitor.Properties.PopulateColumns()
+
+ LookUpEditMonitor.Properties.TextEditStyle = DevExpress.XtraEditors.Controls.TextEditStyles.DisableTextEditor
+ Catch ex As Exception
+ LOGGER.Error($"Error in Load_Monitor_LookUp: {ex.Message}")
+ End Try
+ End Sub
+ Private Sub Load_IconID_LookUp()
+ Try
+ If ImageCollection1 Is Nothing OrElse ImageCollection1.Images.Count = 0 Then
+ LOGGER.Warn("ImageCollection1 ist leer oder nicht initialisiert")
+ Exit Sub
+ End If
+
+ Dim iconList As New List(Of Object)
+
+ For i As Integer = 0 To ImageCollection1.Images.Count - 1
+ Dim imageKey = If(String.IsNullOrEmpty(ImageCollection1.Images.Keys(i)), $"Image_{i}", ImageCollection1.Images.Keys(i))
+ iconList.Add(New With {
+ .ICON_ID = i,
+ .ICON_NAME = imageKey
+ })
+ Next
+
+ LookUpEdit_Image.Properties.DataSource = iconList
+ LookUpEdit_Image.Properties.DisplayMember = "ICON_NAME"
+ LookUpEdit_Image.Properties.ValueMember = "ICON_ID"
+
+ LookUpEdit_Image.Properties.PopulateColumns()
+ LookUpEdit_Image.Properties.Columns("ICON_ID").Visible = False
+
+ LookUpEdit_Image.Properties.TextEditStyle = DevExpress.XtraEditors.Controls.TextEditStyles.DisableTextEditor
+
+ ' Event für dynamische Bildanzeige
+ AddHandler LookUpEdit_Image.Properties.CustomDisplayText, AddressOf LookUpEdit_Image_CustomDisplayText
+
+ LOGGER.Debug($"Loaded {iconList.Count} icons into LookUpEdit_Image")
+ Catch ex As Exception
+ LOGGER.Error($"Error in Load_IconID_LookUp: {ex.Message}")
+ End Try
+ End Sub
+ Private Sub LookUpEdit_Image_CustomDisplayText(sender As Object, e As DevExpress.XtraEditors.Controls.CustomDisplayTextEventArgs)
+ Try
+ If e.Value IsNot Nothing AndAlso IsNumeric(e.Value) Then
+ Dim iconIndex As Integer = CInt(e.Value)
+ If iconIndex >= 0 AndAlso iconIndex < ImageCollection1.Images.Count Then
+ e.DisplayText = If(String.IsNullOrEmpty(ImageCollection1.Images.Keys(iconIndex)),
+ $"Image_{iconIndex}",
+ ImageCollection1.Images.Keys(iconIndex))
+ End If
+ End If
+ Catch ex As Exception
+ LOGGER.Error($"Error in LookUpEdit_Image_CustomDisplayText: {ex.Message}")
+ End Try
+ End Sub
+
+ Private Sub BarButtonItem4_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles bbtnSQL_Count.ItemClick
+ Try
+ Dim praefix As String = $"DECLARE @PROFILE_ID INT = {_currentCockpitDefinition.FK_ProfileID} " & vbCrLf
+ Dim oSQL = praefix & _currentCockpitDefinition.SQL_Query_Count
+ Dim oForm As New frmSQLEditor(LOGCONFIG, DatabaseECM) With {.SQLCommand = oSQL, .SQLConnection = 0}
+ oForm.ShowDialog()
+
+ If oForm.DialogResult = DialogResult.OK Then
+ _currentCockpitDefinition.SQL_Query_Count = oForm.SQLCommand.Replace(praefix, "")
+ End If
+ Catch ex As Exception
+ MsgBox("Error in Saving SQL: " & vbNewLine & vbNewLine & ex.Message)
+ LOGGER.Error(ex)
+ End Try
+ End Sub
+
+ Private Sub bbtnSQL_Data_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles bbtnSQL_Data.ItemClick
+ Try
+ Dim praefix As String = $"DECLARE @PROFILE_ID INT = {_currentCockpitDefinition.FK_ProfileID} " & vbCrLf
+ Dim oSQL = praefix & _currentCockpitDefinition.SQL_Query
+ Dim oForm As New frmSQLEditor(LOGCONFIG, DatabaseECM) With {.SQLCommand = oSQL, .SQLConnection = 0}
+ oForm.ShowDialog()
+
+ If oForm.DialogResult = DialogResult.OK Then
+ _currentCockpitDefinition.SQL_Query = oForm.SQLCommand.Replace(praefix, "")
+ End If
+ Catch ex As Exception
+ MsgBox("Error in Saving SQL: " & vbNewLine & vbNewLine & ex.Message)
+ LOGGER.Error(ex)
+ End Try
+ End Sub
+
+ Private Sub bbtnitm_Save_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles bbtnitm_Save.ItemClick
+ Try
+ If _currentCockpitDefinition Is Nothing Then
+ MsgBox("No node selected to save.", MsgBoxStyle.Exclamation)
+ Exit Sub
+ End If
+
+ ' Werte aus den Formularfeldern in das Datenobjekt übernehmen
+ _currentCockpitDefinition.Active = CheckEdit_Active.Checked
+ _currentCockpitDefinition.Name = TextEdit_Bezeichnung.Text.Trim()
+ _currentCockpitDefinition.Comment = TextEdit_Comment.Text.Trim()
+
+ ' TYPE_ID
+ If LookUpEditTypeID.EditValue IsNot Nothing AndAlso IsNumeric(LookUpEditTypeID.EditValue) Then
+ _currentCockpitDefinition.TypeID = CInt(LookUpEditTypeID.EditValue)
+ Else
+ _currentCockpitDefinition.TypeID = Nothing
+ End If
+
+ ' ICON_ID
+ If LookUpEdit_Image.EditValue IsNot Nothing AndAlso IsNumeric(LookUpEdit_Image.EditValue) Then
+ _currentCockpitDefinition.IconID = CInt(LookUpEdit_Image.EditValue)
+ Else
+ _currentCockpitDefinition.IconID = Nothing
+ End If
+
+ ' FK_PROFILE_ID
+ If LookUpEditProfil.EditValue IsNot Nothing AndAlso IsNumeric(LookUpEditProfil.EditValue) AndAlso CInt(LookUpEditProfil.EditValue) > 0 Then
+ _currentCockpitDefinition.FK_ProfileID = CInt(LookUpEditProfil.EditValue)
+ Else
+ _currentCockpitDefinition.FK_ProfileID = Nothing
+ End If
+
+ ' FK_CHART_ID
+ If LookUpEditChart.EditValue IsNot Nothing AndAlso IsNumeric(LookUpEditChart.EditValue) AndAlso CInt(LookUpEditChart.EditValue) > 0 Then
+ _currentCockpitDefinition.FK_ChartID = CInt(LookUpEditChart.EditValue)
+ Else
+ _currentCockpitDefinition.FK_ChartID = Nothing
+ End If
+
+ ' FK_MONITOR_ID
+ If LookUpEditMonitor.EditValue IsNot Nothing AndAlso IsNumeric(LookUpEditMonitor.EditValue) AndAlso CInt(LookUpEditMonitor.EditValue) > 0 Then
+ _currentCockpitDefinition.FK_MonitorID = CInt(LookUpEditMonitor.EditValue)
+ Else
+ _currentCockpitDefinition.FK_MonitorID = Nothing
+ End If
+
+ ' SQL-Statements für NULL-Werte vorbereiten
+ Dim activeValue = If(_currentCockpitDefinition.Active, 1, 0)
+ Dim typeIdValue = If(_currentCockpitDefinition.TypeID.HasValue, _currentCockpitDefinition.TypeID.Value.ToString(), "NULL")
+ Dim iconIdValue = If(_currentCockpitDefinition.IconID.HasValue, _currentCockpitDefinition.IconID.Value.ToString(), "NULL")
+ Dim profileIdValue = If(_currentCockpitDefinition.FK_ProfileID.HasValue, _currentCockpitDefinition.FK_ProfileID.Value.ToString(), "NULL")
+ Dim chartIdValue = If(_currentCockpitDefinition.FK_ChartID.HasValue, _currentCockpitDefinition.FK_ChartID.Value.ToString(), "NULL")
+ Dim monitorIdValue = If(_currentCockpitDefinition.FK_MonitorID.HasValue, _currentCockpitDefinition.FK_MonitorID.Value.ToString(), "NULL")
+
+ ' SQL-String escapen für Texte
+ Dim safeName = _currentCockpitDefinition.Name.Replace("'", "''")
+ Dim safeComment = _currentCockpitDefinition.Comment.Replace("'", "''")
+ Dim safeSqlQuery = _currentCockpitDefinition.SQL_Query.Replace("'", "''")
+ Dim safeSqlQueryCount = _currentCockpitDefinition.SQL_Query_Count.Replace("'", "''")
+
+ ' UPDATE-Statement erstellen
+ Dim updateSQL = $"
+ UPDATE TBTF_CFG_COCKPIT_DEFINITION
+ SET
+ ACTIVE = {activeValue},
+ TYPE_ID = {typeIdValue},
+ ICON_ID = {iconIdValue},
+ NAME = '{safeName}',
+ FK_PROFILE_ID = {profileIdValue},
+ FK_CHART_ID = {chartIdValue},
+ FK_MONITOR_ID = {monitorIdValue},
+ SQL_QUERY = '{safeSqlQuery}',
+ SQL_QUERY_COUNT = '{safeSqlQueryCount}',
+ COMMENT = '{safeComment}',
+ CHANGED_WHO = '{Environment.UserName}',
+ CHANGED_WHEN = GETDATE()
+ WHERE PK_CFG_COCKPIT_DEFINITION_ID = {_currentCockpitDefinition.PK_CFG_COCKPIT_DEFINITION_ID}"
+
+ If DatabaseFallback.ExecuteNonQueryECM(updateSQL) Then
+ MsgBox("Node definition saved successfully.", MsgBoxStyle.Information)
+ LOGGER.Debug($"Saved node definition ID={_currentCockpitDefinition.PK_CFG_COCKPIT_DEFINITION_ID}, Name={_currentCockpitDefinition.Name}")
+
+ ' TreeView neu laden, um Änderungen anzuzeigen
+ Load_TBTF_CFG_COCKPIT_DEFINITION()
+ Else
+ MsgBox("Error saving node definition. No rows were updated.", MsgBoxStyle.Exclamation)
+ LOGGER.Warn($"No rows updated for PK_CFG_COCKPIT_DEFINITION_ID={_currentCockpitDefinition.PK_CFG_COCKPIT_DEFINITION_ID}")
+ End If
+
+ Catch ex As Exception
+ MsgBox($"Error saving node definition:{vbNewLine}{vbNewLine}{ex.Message}", MsgBoxStyle.Critical)
+ LOGGER.Error($"Error in bbtnitm_Save_ItemClick: {ex.Message}")
+ LOGGER.Error(ex)
+ End Try
+ End Sub
+
+ Private Sub BarButtonItem4_ItemClick_1(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItem4.ItemClick
+ Dim Msgboxresult = MsgBox("Wollen Sie den ausgewählten Knoten wirklich löschen?", MsgBoxStyle.YesNo + MsgBoxStyle.Question, "Löschen bestätigen")
+ If Msgboxresult = MsgBoxResult.Yes Then
+ Try
+ Dim oSQLParent = $"DELETE FROM TBTF_CFG_COCKPIT_DEFINITION WHERE PARENT_ID = {_currentCockpitDefinition.PK_CFG_COCKPIT_DEFINITION_ID}"
+ If DatabaseFallback.ExecuteNonQueryECM(oSQLParent) Then
+ Dim oSQL = $"DELETE FROM TBTF_CFG_COCKPIT_DEFINITION WHERE PK_CFG_COCKPIT_DEFINITION_ID = {_currentCockpitDefinition.PK_CFG_COCKPIT_DEFINITION_ID}"
+ If DatabaseFallback.ExecuteNonQueryECM(oSQL) Then
+ MsgBox("Knotendefinition erfolgreich gelöscht.", MsgBoxStyle.Information)
+ Load_TBTF_CFG_COCKPIT_DEFINITION()
+ Else
+ MsgBox("Keine Knotendefinition wurde gelöscht. Bitte überprüfen Sie, ob die ausgewählte Definition existiert.", MsgBoxStyle.Exclamation)
+ End If
+ End If
+ Catch ex As Exception
+ MsgBox("Fehler beim Löschen der Knotendefinition: " & vbNewLine & vbNewLine & ex.Message, MsgBoxStyle.Critical)
+ LOGGER.Error(ex)
+ End Try
+ End If
+ End Sub
+
+ Private Sub BarButtonItem5_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles bbtnitm_NodeOverviewAdd.ItemClick
+ Add_Node("Overview")
+ End Sub
+
+ Private Function Add_Node(oVariant As String)
+ Dim oParentID As Integer = _currentCockpitDefinition.PK_CFG_COCKPIT_DEFINITION_ID
+ Dim oType As Integer = 0
+ Dim oIcon As Integer = 0
+ If oVariant = "Overview" Then
+ oParentID = 0
+ oType = 0
+ oIcon = 0
+ ElseIf oVariant = "Profil" Then
+ oType = 1
+ oIcon = 1
+ End If
+ Dim oInsert = $"INSERT INTO TBTF_CFG_COCKPIT_DEFINITION (
+ FK_CFG_COCKPIT_ID,
+ [ACTIVE]
+ ,[PARENT_ID]
+ ,[TYPE_ID]
+ ,[ICON_ID]
+ ,[NAME]
+ ,[FK_PROFILE_ID]
+ ,[FK_CHART_ID]
+ ,[FK_MONITOR_ID]
+ ,[SQL_QUERY]
+ ,[SQL_QUERY_COUNT]
+ ,[COMMENT])
+ VALUES (
+ {Selected_Cockpit_ID},
+ 0,
+ {oParentID},
+ {oType},
+ {oIcon},
+ 'New {oVariant}-Node',
+ 0,
+ 0,
+ 0,
+ '',
+ '',
+ '')"
+ If DatabaseFallback.ExecuteNonQueryECM(oInsert) Then
+ Load_TBTF_CFG_COCKPIT_DEFINITION()
+ Else
+ MsgBox("Fehler beim Anlegen des Knotens. Prüfen Sie Ihr Log", MsgBoxStyle.Exclamation)
+ End If
+
+ End Function
+
+ Private Sub bbtnitm_NodeProfilAdd_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles bbtnitm_NodeProfilAdd.ItemClick
+ Add_Node("Profil")
+ End Sub
+
+ Private Sub LabelControl6_Click(sender As Object, e As EventArgs) Handles LabelControl6.Click
+
+ End Sub
+ Private Sub LookUpEdit_Image_EditValueChanged(sender As Object, e As EventArgs) Handles LookUpEdit_Image.EditValueChanged
+
+ End Sub
+
+ Private Sub LabelControl7_Click(sender As Object, e As EventArgs) Handles LabelControl7.Click
+
+ End Sub
+
+ Private Sub TextEdit_Comment_EditValueChanged(sender As Object, e As EventArgs) Handles TextEdit_Comment.EditValueChanged
+
+ End Sub
+
+ Private Sub bbtnitmCopy_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles bbtnitmCopy.ItemClick
+ Try
+ If _currentCockpitDefinition Is Nothing Then
+ MsgBox("No node selected to copy.", MsgBoxStyle.Exclamation)
+ Exit Sub
+ End If
+
+ ' Bestätigung vom Benutzer einholen
+ Dim msgResult = MsgBox($"Möchten Sie den Knoten '{_currentCockpitDefinition.Name}' kopieren?{vbNewLine}{vbNewLine}Die Kopie wird als Geschwisterknoten erstellt.",
+ MsgBoxStyle.YesNo + MsgBoxStyle.Question, "Kopie bestätigen")
+
+ If msgResult <> MsgBoxResult.Yes Then
+ Exit Sub
+ End If
+
+ ' SQL-String escapen für Texte
+ Dim safeName = (_currentCockpitDefinition.Name & " - Copy").Replace("'", "''")
+ Dim safeComment = _currentCockpitDefinition.Comment.Replace("'", "''")
+ Dim safeSqlQuery = _currentCockpitDefinition.SQL_Query.Replace("'", "''")
+ Dim safeSqlQueryCount = _currentCockpitDefinition.SQL_Query_Count.Replace("'", "''")
+
+ ' NULL-Werte vorbereiten
+ 'Dim activeValue = If(_currentCockpitDefinition.Active, 1, 0)
+ Dim parentIdValue = If(_currentCockpitDefinition.ParentID.HasValue, _currentCockpitDefinition.ParentID.Value.ToString(), "0")
+ Dim typeIdValue = If(_currentCockpitDefinition.TypeID.HasValue, _currentCockpitDefinition.TypeID.Value.ToString(), "NULL")
+ Dim iconIdValue = If(_currentCockpitDefinition.IconID.HasValue, _currentCockpitDefinition.IconID.Value.ToString(), "NULL")
+ Dim profileIdValue = If(_currentCockpitDefinition.FK_ProfileID.HasValue, _currentCockpitDefinition.FK_ProfileID.Value.ToString(), "NULL")
+ Dim chartIdValue = If(_currentCockpitDefinition.FK_ChartID.HasValue, _currentCockpitDefinition.FK_ChartID.Value.ToString(), "NULL")
+ Dim monitorIdValue = If(_currentCockpitDefinition.FK_MonitorID.HasValue, _currentCockpitDefinition.FK_MonitorID.Value.ToString(), "NULL")
+
+ ' INSERT-Statement erstellen
+ Dim insertSQL = $"
+ INSERT INTO TBTF_CFG_COCKPIT_DEFINITION (
+ FK_CFG_COCKPIT_ID,
+ ACTIVE,
+ PARENT_ID,
+ TYPE_ID,
+ ICON_ID,
+ NAME,
+ FK_PROFILE_ID,
+ FK_CHART_ID,
+ FK_MONITOR_ID,
+ SQL_QUERY,
+ SQL_QUERY_COUNT,
+ COMMENT,
+ ADDED_WHO,
+ ADDED_WHEN
+ )
+ VALUES (
+ {Selected_Cockpit_ID},
+ {0},
+ {parentIdValue},
+ {typeIdValue},
+ {iconIdValue},
+ '{safeName}',
+ {profileIdValue},
+ {chartIdValue},
+ {monitorIdValue},
+ '{safeSqlQuery}',
+ '{safeSqlQueryCount}',
+ '{safeComment}',
+ '{Environment.UserName}',
+ GETDATE()
+ )"
+
+ If DatabaseFallback.ExecuteNonQueryECM(insertSQL) Then
+ MsgBox("Knoten erfolgreich kopiert und auf Inaktiv gesetzt.", MsgBoxStyle.Information)
+ LOGGER.Info($"Knotendefinition kopiert - Original ID={_currentCockpitDefinition.PK_CFG_COCKPIT_DEFINITION_ID}, Name={safeName}")
+
+ ' TreeView neu laden, um die Kopie anzuzeigen
+ Load_TBTF_CFG_COCKPIT_DEFINITION()
+ Else
+ MsgBox("Fehler beim Kopieren der Knotendefinition. Es wurden keine Zeilen eingefügt.", MsgBoxStyle.Exclamation)
+ LOGGER.Warn($"Failed to copy node with PK_CFG_COCKPIT_DEFINITION_ID={_currentCockpitDefinition.PK_CFG_COCKPIT_DEFINITION_ID}")
+ End If
+
+ Catch ex As Exception
+ MsgBox($"Fehler beim Kopieren der Knotendefinition:{vbNewLine}{vbNewLine}{ex.Message}", MsgBoxStyle.Critical)
+ LOGGER.Error($"Error in bbtnitmCopy_ItemClick: {ex.Message}")
+ LOGGER.Error(ex)
+ End Try
+ End Sub
+End Class
\ No newline at end of file
diff --git a/app/TaskFlow/frmGhostMode.vb b/app/TaskFlow/frmGhostMode.vb
index f602af0..e007dc5 100644
--- a/app/TaskFlow/frmGhostMode.vb
+++ b/app/TaskFlow/frmGhostMode.vb
@@ -4,13 +4,14 @@
Dim DT_USER = DatabaseFallback.GetDatatableECM(oSQL)
'
If IsNothing(DT_USER) Then
- LOGGER.Info("GHOST Select 1 was nothing, now trying 2nd..")
+ LOGGER.Info($"GHOST Select 1 [{oSQL}] was nothing, now trying 2nd..")
oSQL = "SELECT CONFIG_VALUE FROM TBIDB_BASE WITH (NOLOCK) WHERE CONFIG_NAME = 'GHOST_SELECT'"
If Not IsNothing(oSQL) Then
oSQL = DatabaseFallback.GetScalarValueIDB(oSQL)
DT_USER = DatabaseFallback.GetDatatableIDB(oSQL)
Else
- MsgBox("No SQL for Ghostmode via IDB. Check Your configuration.", MsgBoxStyle.Exclamation)
+ LOGGER.Info($"GHOST Select 2 [{oSQL}] was nothing, Exit.")
+ MsgBox("No SQL for Ghostmode via SQL. Check Your configuration.", MsgBoxStyle.Exclamation)
Exit Sub
End If
End If
diff --git a/app/TaskFlow/frmMain.Designer.vb b/app/TaskFlow/frmMain.Designer.vb
index 2d4de9c..283be91 100644
--- a/app/TaskFlow/frmMain.Designer.vb
+++ b/app/TaskFlow/frmMain.Designer.vb
@@ -192,6 +192,7 @@ Partial Class frmMain
Me.TimerInactivity = New System.Windows.Forms.Timer(Me.components)
Me.BarButtonItem5 = New DevExpress.XtraBars.BarButtonItem()
Me.BarButtonItem9 = New DevExpress.XtraBars.BarButtonItem()
+ Me.BarButtonItem3 = New DevExpress.XtraBars.BarButtonItem()
CType(Me.TreeList_Cockpit, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.RibbonControl1, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.RepositoryItemProgressBar1, System.ComponentModel.ISupportInitialize).BeginInit()
@@ -240,9 +241,9 @@ Partial Class frmMain
'RibbonControl1
'
Me.RibbonControl1.ExpandCollapseItem.Id = 0
- Me.RibbonControl1.Items.AddRange(New DevExpress.XtraBars.BarItem() {Me.RibbonControl1.ExpandCollapseItem, Me.RibbonControl1.SearchEditItem, Me.bbtniRefresh, Me.bbiProfilverwaltung, Me.bbiKonfiguration, Me.bbtniGrundeinstellung, Me.bbtnitemInfo, Me.BarButtonItem1, Me.bsiUser, Me.bsiLicenses, Me.bsiUserLoggedIn, Me.bsiVersion, Me.bsilastsync, Me.bsiDebug, Me.bsiMessage, Me.bbtniMetadataFile, Me.BarEditItem1, Me.bsiGeneralInfo, Me.bbtnitmGhostMode, Me.bsi_GhostMode, Me.BarButtonItemGhostMode, Me.SearchItem1, Me.SearchItem2, Me.BarStaticItemAppServer, Me.bbtniCW, Me.bsiInactivityCheck, Me.BarButtonItem2, Me.BarCheckItemAutofilter, Me.BarCheckItem2, Me.BarButtonItemResetLayout, Me.BarButtonItem4, Me.BarButtonItemExportExcel, Me.BarButtonItem6, Me.BarButtonItem7, Me.BarButtonItemWFSingle, Me.BarButtonItemWFGroup, Me.BarButtonItemFileLink, Me.BarButtonItemMassValidation, Me.BarCheckItemShowSearch, Me.barItemGridFontSize, Me.BarButtonItem8, Me.BbtnitmAHWF1, Me.BbtnitmAHWF2, Me.BbtnitmAHWF3, Me.BbtnitmAHWF4, Me.bbtnitmLanguage_Change, Me.BarButtonItem10, Me.BBtnItmNotfications, Me.BSIVERSION1, Me.barbtnitmsaveLogfiles, Me.bsitmCount, Me.BarButtonItemCock_refresh, Me.Bchkitm_load_empty_wf})
+ Me.RibbonControl1.Items.AddRange(New DevExpress.XtraBars.BarItem() {Me.RibbonControl1.ExpandCollapseItem, Me.RibbonControl1.SearchEditItem, Me.bbtniRefresh, Me.bbiProfilverwaltung, Me.bbiKonfiguration, Me.bbtniGrundeinstellung, Me.bbtnitemInfo, Me.BarButtonItem1, Me.bsiUser, Me.bsiLicenses, Me.bsiUserLoggedIn, Me.bsiVersion, Me.bsilastsync, Me.bsiDebug, Me.bsiMessage, Me.bbtniMetadataFile, Me.BarEditItem1, Me.bsiGeneralInfo, Me.bbtnitmGhostMode, Me.bsi_GhostMode, Me.BarButtonItemGhostMode, Me.SearchItem1, Me.SearchItem2, Me.BarStaticItemAppServer, Me.bbtniCW, Me.bsiInactivityCheck, Me.BarButtonItem2, Me.BarCheckItemAutofilter, Me.BarCheckItem2, Me.BarButtonItemResetLayout, Me.BarButtonItem4, Me.BarButtonItemExportExcel, Me.BarButtonItem6, Me.BarButtonItem7, Me.BarButtonItemWFSingle, Me.BarButtonItemWFGroup, Me.BarButtonItemFileLink, Me.BarButtonItemMassValidation, Me.BarCheckItemShowSearch, Me.barItemGridFontSize, Me.BarButtonItem8, Me.BbtnitmAHWF1, Me.BbtnitmAHWF2, Me.BbtnitmAHWF3, Me.BbtnitmAHWF4, Me.bbtnitmLanguage_Change, Me.BarButtonItem10, Me.BBtnItmNotfications, Me.BSIVERSION1, Me.barbtnitmsaveLogfiles, Me.bsitmCount, Me.BarButtonItemCock_refresh, Me.Bchkitm_load_empty_wf, Me.BarButtonItem3})
resources.ApplyResources(Me.RibbonControl1, "RibbonControl1")
- Me.RibbonControl1.MaxItemId = 60
+ Me.RibbonControl1.MaxItemId = 61
Me.RibbonControl1.Name = "RibbonControl1"
Me.RibbonControl1.Pages.AddRange(New DevExpress.XtraBars.Ribbon.RibbonPage() {Me.RibbonPageStart, Me.RibbonPageTabelle, Me.RibbonPageAktionen})
Me.RibbonControl1.RepositoryItems.AddRange(New DevExpress.XtraEditors.Repository.RepositoryItem() {Me.RepositoryItemProgressBar1, Me.RepositoryItemTrackBar1, Me.cmbGridFontSize})
@@ -703,6 +704,7 @@ Partial Class frmMain
Me.RibbonPageGroup3.ItemLinks.Add(Me.bbiProfilverwaltung)
Me.RibbonPageGroup3.ItemLinks.Add(Me.bbiKonfiguration)
Me.RibbonPageGroup3.ItemLinks.Add(Me.bbtnitmGhostMode)
+ Me.RibbonPageGroup3.ItemLinks.Add(Me.BarButtonItem3)
Me.RibbonPageGroup3.Name = "RibbonPageGroup3"
resources.ApplyResources(Me.RibbonPageGroup3, "RibbonPageGroup3")
'
@@ -1595,6 +1597,13 @@ Partial Class frmMain
Me.BarButtonItem9.Name = "BarButtonItem9"
Me.BarButtonItem9.Visibility = DevExpress.XtraBars.BarItemVisibility.Never
'
+ 'BarButtonItem3
+ '
+ resources.ApplyResources(Me.BarButtonItem3, "BarButtonItem3")
+ Me.BarButtonItem3.Id = 60
+ Me.BarButtonItem3.ImageOptions.SvgImage = CType(resources.GetObject("BarButtonItem3.ImageOptions.SvgImage"), DevExpress.Utils.Svg.SvgImage)
+ Me.BarButtonItem3.Name = "BarButtonItem3"
+ '
'frmMain
'
Me.Appearance.Options.UseFont = True
@@ -1805,4 +1814,5 @@ Partial Class frmMain
Friend WithEvents SplitterControl1 As DevExpress.XtraEditors.SplitterControl
Friend WithEvents BarButtonItemCock_refresh As DevExpress.XtraBars.BarButtonItem
Friend WithEvents Bchkitm_load_empty_wf As DevExpress.XtraBars.BarCheckItem
+ Friend WithEvents BarButtonItem3 As DevExpress.XtraBars.BarButtonItem
End Class
diff --git a/app/TaskFlow/frmMain.resx b/app/TaskFlow/frmMain.resx
index b548838..b42bb5f 100644
--- a/app/TaskFlow/frmMain.resx
+++ b/app/TaskFlow/frmMain.resx
@@ -1433,6 +1433,32 @@
LDEgICB2NGMwLDAuNSwwLjUsMSwxLDFoOEMzMS41LDI4LDMyLDI3LjUsMzIsMjd6IiBjbGFzcz0iWWVs
bG93IiAvPg0KICAgIDxwYXRoIGQ9Ik0wLDRoOEw0LDhMMCw0eiBNMTYsMjR2LTZoNHYtMmgtNHYtNGgt
MnYxNGg2di0ySDE2eiIgY2xhc3M9IkJsYWNrIiAvPg0KICA8L2c+DQo8L3N2Zz4L
+
+
+
+ Cockpit Konfiguration
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFlEZXZFeHByZXNzLkRhdGEudjIxLjIsIFZlcnNpb249MjEuMi40
+ LjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjg4ZDE3NTRkNzAwZTQ5YQUBAAAAHURl
+ dkV4cHJlc3MuVXRpbHMuU3ZnLlN2Z0ltYWdlAQAAAAREYXRhBwICAAAACQMAAAAPAwAAAIkDAAAC77u/
+ PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz4NCjxzdmcgeD0iMHB4IiB5PSIwcHgi
+ IHZpZXdCb3g9IjAgMCAzMiAzMiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv
+ MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3Bh
+ Y2U9InByZXNlcnZlIiBpZD0iTGF5ZXJfMSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAg
+ MzIgMzIiPg0KICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLkdyZWVue2ZpbGw6IzAzOUMyMzt9Cgku
+ QmxhY2t7ZmlsbDojNzI3MjcyO30KCS5SZWR7ZmlsbDojRDExQzFDO30KCS5ZZWxsb3d7ZmlsbDojRkZC
+ MTE1O30KCS5CbHVle2ZpbGw6IzExNzdENzt9CgkuV2hpdGV7ZmlsbDojRkZGRkZGO30KCS5zdDB7b3Bh
+ Y2l0eTowLjU7fQoJLnN0MXtvcGFjaXR5OjAuNzU7fQo8L3N0eWxlPg0KICA8ZyBpZD0iSW5zZXJ0VHJl
+ ZVZpZXciPg0KICAgIDxwYXRoIGQ9Ik0xMyw4SDVDNC40LDgsNCw3LjYsNCw3VjNjMC0wLjUsMC40LTEs
+ MS0xaDhjMC42LDAsMSwwLjUsMSwxdjRDMTQsNy42LDEzLjYsOCwxMyw4eiBNMjYsMTd2LTQgICBjMC0w
+ LjYtMC41LTEtMS0xaC04Yy0wLjUsMC0xLDAuNC0xLDF2NGMwLDAuNSwwLjUsMSwxLDFoOEMyNS41LDE4
+ LDI2LDE3LjUsMjYsMTd6IE0yNiwyN3YtNGMwLTAuNS0wLjUtMS0xLTFoLThjLTAuNSwwLTEsMC41LTEs
+ MSAgIHY0YzAsMC41LDAuNSwxLDEsMWg4QzI1LjUsMjgsMjYsMjcuNSwyNiwyN3oiIGNsYXNzPSJZZWxs
+ b3ciIC8+DQogICAgPHBvbHlnb24gcG9pbnRzPSIxNCwxNiAxNCwxNCAxMCwxNCAxMCwxMCA4LDEwIDgs
+ MjYgMTQsMjYgMTQsMjQgMTAsMjQgMTAsMTYgICIgY2xhc3M9IkJsYWNrIiAvPg0KICA8L2c+DQo8L3N2
+ Zz4L
@@ -1519,7 +1545,7 @@
cmVhbWVyAgAAAAlJbWFnZVNpemUERGF0YQQHE1N5c3RlbS5EcmF3aW5nLlNpemUDAAAAAgIAAAAF/P//
/xNTeXN0ZW0uRHJhd2luZy5TaXplAgAAAAV3aWR0aAZoZWlnaHQAAAgIAwAAABgAAAAYAAAACQUAAAAP
BQAAACcLAAAC+gIAAIlQTkcNChoKAAAADUlIRFIAAAAYAAAAGAgGAAAA4Hc9+AAAAARnQU1BAACxjwv8
- YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAKcSURBVEhL3ZTLaxNRFMYLrvRfkD4yc5OgFeeZIIiLVkrV
+ YQUAAAAJcEhZcwAADsAAAA7AAWrWiQkAAAKcSURBVEhL3ZTLaxNRFMYLrvRfkD4yc5OgFeeZIIiLVkrV
Jq1O6SNGqxUhCtZVkWBIbQitdOVS3AlZtXUnKAq1mUcmr6aPpCVod9KmuBbXn8z0NTMki9Yuij/4uDNn
7jnfnLl3blPTf4PO0NBYAp2lkGFc0BgXVMaF/GUKzrnHQhbcSItepHkCjaWg827IXBt0jj4w0JhmKIwL
CkdD4QhUjoLKUrsjR5l5Km/kEhRZYn8xxUeQET3QuGYU2BbzocpeRMZi8E8oAo0lznNQTObdWDS7cbzJ
@@ -1531,8 +1557,8 @@
k5Gfs7NnbQZ5f/0zp2g5izb7e1AJBbAWDmLtXi8q9wOoGKOhcBDrd4PYCPViIxTE5mDAXi9/xVvXoJHx
kWlkYO1gJxxELdyH7Qe3URvtx86ohNrDO/g10ofS+HjCnulA9xEURQq6n0ZO9CInelAQPLAaLL17da4c
f9FVTsS7ylMJU8tTcfPeXq0B890d7fPBPRnX3R3tzjlH5S88LZDGXf/36QAAAABJRU5ErkJggjMCAACJ
- UE5HDQoaCgAAAA1JSERSAAAAGAAAABgIBgAAAOB3PfgAAAAEZ0FNQQAAsY8L/GEFAAAACXBIWXMAAA7C
- AAAOwgEVKEqAAAAB1UlEQVRIS+2Uu24aQRSGz7hImqTLA1DQpIwiFCF5l9vewciSCysRRap0KEqRmhoW
+ UE5HDQoaCgAAAA1JSERSAAAAGAAAABgIBgAAAOB3PfgAAAAEZ0FNQQAAsY8L/GEFAAAACXBIWXMAAA7A
+ AAAOwAFq1okJAAAB1UlEQVRIS+2Uu24aQRSGz7hImqTLA1DQpIwiFCF5l9vewciSCysRRap0KEqRmhoW
h1swVdLbZaS8gzsXKfwGlgs3thUMhuGPZmE3u3iXTBuJTxrtzsw58885c2aItvzXAGDh/vnHz/vhfiL1
ev1pmwib2hEReozg+4yNPO7VXfx4++FFdLUY/EWa6ZeXbragullFdbO66v1nCmono6idV1nVt59Ubcz1
HKZFLRBMxGWEL/R3Z//iyrHvFmUD3LbkfI5YNPRNnOzV0twpAZWKlL2HSE1fUoCXC1hU7MB2dFh7H7WI
@@ -1541,7 +1567,7 @@
z7cYw/GOjICoooTDGlsKpkYpdq7pCcT7RRARhKtIFukUiTcmKYJNiNv/VUZg8Ow57xFBqqZX9GgZtZtK
3a3PxSIEjlc57RKhs3qfRBP/fl/MDRmh641J7D7M6PWbjrc4MbQZQ4vIa83VV1RNe2d56785B5/W/bdI
8werE/HGFidAHwAAAABJRU5ErkJgghADAACJUE5HDQoaCgAAAA1JSERSAAAAGAAAABgIBgAAAOB3PfgA
- AAAEZ0FNQQAAsY8L/GEFAAAACXBIWXMAAA7CAAAOwgEVKEqAAAACsklEQVRIS8VVzW7TQBDOc/AeHKom
+ AAAEZ0FNQQAAsY8L/GEFAAAACXBIWXMAAA7AAAAOwAFq1okJAAACsklEQVRIS8VVzW7TQBDOc/AeHKom
3t2Z3bVDy08R4gaqKvUZOHDoK3BDvAEHClVVceEaqKqCWtvrnyQOVPAKnHL50Dp2G6WtRNUIPmnl8ex4
/vzNbqfzr1BqRmIJJyzgKEBqAqTUw4nqIWYvC5yqHhK/pwI42UMiu8ikQKYEYtGF4wA5CZQqwNH9dZw7
H3IPLlRwTMhZISMB1zpjgZgEUpLImXAqAiRKoGBCyVQ7T5v3jCUcC4wNoSCJD0+fvKoDVMYgtuIi4hJQ
@@ -1554,7 +1580,7 @@
x5ef2pltYhVcSEj8cRNq5KGGM4T8Cjr/X2S0gpy7yGgVJa9i9/HG60WbW6FSBMcSZd/AD9HB883lBjix
Ap+twlFf4zBivH229WbR5sZ492Djy9D/MBXUnPZyfV8bAX8LZiSR3XZ+Pobrg/1obbAfrQ8OogvZr/fR
2uDArg8Wv5nHH4RP7Rpx+BP5AAAAAElFTkSuQmCC2gIAAIlQTkcNChoKAAAADUlIRFIAAAAYAAAAGAgG
- AAAA4Hc9+AAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAJ8SURBVEhL3VXNbtNA
+ AAAA4Hc9+AAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsAAAA7AAWrWiQkAAAJ8SURBVEhL3VXNbtNA
EPaBQx+CQ2t7HSde24l6yKGAk1IREBd+GnCjVgEunLkgVQj1CXgCDrlwRXkEUA48AGpVQqWIZmNDiNcO
eYFB42Bn3VAoNFz4pNHO7oz9eXZnP0vSf4NAocA1CoFSgEgzISImcM2GQKUQEQtCzYSQUOCqEY8453HM
jP0IY7ge55jAV3RIX/6x0XyZYVsA8EPSyeH2zsIJQoUKFTQfzRFw2QCuWhAoBoxVIfmM4Ct5gcDdzhAE
@@ -1678,7 +1704,7 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADw
- CAAAAk1TRnQBSQFMAgEBAgEAAXgBDAF4AQwBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
+ CAAAAk1TRnQBSQFMAgEBAgEAAYgBDAGIAQwBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA
@@ -3114,6 +3140,12 @@
DevExpress.XtraBars.BarButtonItem, DevExpress.XtraBars.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
+
+ BarButtonItem3
+
+
+ DevExpress.XtraBars.BarButtonItem, DevExpress.XtraBars.v21.2, Version=21.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
+
frmMain
diff --git a/app/TaskFlow/frmMain.vb b/app/TaskFlow/frmMain.vb
index 01da54f..65371b2 100644
--- a/app/TaskFlow/frmMain.vb
+++ b/app/TaskFlow/frmMain.vb
@@ -1598,6 +1598,7 @@ Public Class frmMain
If Application.OpenForms().OfType(Of frmMassValidator).Any() Or
Application.OpenForms().OfType(Of frmValidator).Any() Or
Application.OpenForms().OfType(Of frmAdministration).Any() Or
+ Application.OpenForms().OfType(Of frmCockpitConfig).Any() Or
Application.OpenForms().OfType(Of frmAdmin2).Any() Then
Exit Sub
End If
@@ -5239,4 +5240,7 @@ FROM VWPM_PROFILE_ACTIVE T WHERE T.GUID IN (SELECT PROFILE_ID FROM [dbo].[FNPM_G
Public Const SW_RESTORE As Integer = 9
End Class
+ Private Sub BarButtonItem3_ItemClick_3(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItem3.ItemClick
+ frmCockpitConfig.Show()
+ End Sub
End Class
\ No newline at end of file
diff --git a/app/TaskFlow/frmUserSelect.Designer.vb b/app/TaskFlow/frmUserSelect.Designer.vb
new file mode 100644
index 0000000..482d00c
--- /dev/null
+++ b/app/TaskFlow/frmUserSelect.Designer.vb
@@ -0,0 +1,150 @@
+ _
+Partial Class frmUserSelect
+ Inherits DevExpress.XtraBars.Ribbon.RibbonForm
+
+ 'Das Formular überschreibt den Löschvorgang, um die Komponentenliste zu bereinigen.
+ _
+ Protected Overrides Sub Dispose(ByVal disposing As Boolean)
+ Try
+ If disposing AndAlso components IsNot Nothing Then
+ components.Dispose()
+ End If
+ Finally
+ MyBase.Dispose(disposing)
+ End Try
+ End Sub
+
+ 'Wird vom Windows Form-Designer benötigt.
+ Private components As System.ComponentModel.IContainer
+
+ 'Hinweis: Die folgende Prozedur ist für den Windows Form-Designer erforderlich.
+ 'Das Bearbeiten ist mit dem Windows Form-Designer möglich.
+ 'Das Bearbeiten mit dem Code-Editor ist nicht möglich.
+ _
+ Private Sub InitializeComponent()
+ Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(frmUserSelect))
+ Me.RibbonControl1 = New DevExpress.XtraBars.Ribbon.RibbonControl()
+ Me.BarButtonItem2 = New DevExpress.XtraBars.BarButtonItem()
+ Me.RibbonPage1 = New DevExpress.XtraBars.Ribbon.RibbonPage()
+ Me.RibbonPageGroup1 = New DevExpress.XtraBars.Ribbon.RibbonPageGroup()
+ Me.RibbonStatusBar1 = New DevExpress.XtraBars.Ribbon.RibbonStatusBar()
+ Me.RibbonPage2 = New DevExpress.XtraBars.Ribbon.RibbonPage()
+ Me.GridControl1 = New DevExpress.XtraGrid.GridControl()
+ Me.GridView1 = New DevExpress.XtraGrid.Views.Grid.GridView()
+ Me.BarButtonItem1 = New DevExpress.XtraBars.BarButtonItem()
+ CType(Me.RibbonControl1, System.ComponentModel.ISupportInitialize).BeginInit()
+ CType(Me.GridControl1, System.ComponentModel.ISupportInitialize).BeginInit()
+ CType(Me.GridView1, System.ComponentModel.ISupportInitialize).BeginInit()
+ Me.SuspendLayout()
+ '
+ 'RibbonControl1
+ '
+ Me.RibbonControl1.ExpandCollapseItem.Id = 0
+ Me.RibbonControl1.Items.AddRange(New DevExpress.XtraBars.BarItem() {Me.RibbonControl1.ExpandCollapseItem, Me.RibbonControl1.SearchEditItem, Me.BarButtonItem2})
+ Me.RibbonControl1.Location = New System.Drawing.Point(0, 0)
+ Me.RibbonControl1.MaxItemId = 2
+ Me.RibbonControl1.Name = "RibbonControl1"
+ Me.RibbonControl1.Pages.AddRange(New DevExpress.XtraBars.Ribbon.RibbonPage() {Me.RibbonPage1})
+ Me.RibbonControl1.ShowApplicationButton = DevExpress.Utils.DefaultBoolean.[False]
+ Me.RibbonControl1.Size = New System.Drawing.Size(800, 158)
+ Me.RibbonControl1.StatusBar = Me.RibbonStatusBar1
+ '
+ 'BarButtonItem2
+ '
+ Me.BarButtonItem2.Caption = "User wählen"
+ Me.BarButtonItem2.Id = 1
+ Me.BarButtonItem2.ImageOptions.SvgImage = CType(resources.GetObject("BarButtonItem2.ImageOptions.SvgImage"), DevExpress.Utils.Svg.SvgImage)
+ Me.BarButtonItem2.Name = "BarButtonItem2"
+ '
+ 'RibbonPage1
+ '
+ Me.RibbonPage1.Groups.AddRange(New DevExpress.XtraBars.Ribbon.RibbonPageGroup() {Me.RibbonPageGroup1})
+ Me.RibbonPage1.Name = "RibbonPage1"
+ Me.RibbonPage1.Text = "Start"
+ '
+ 'RibbonPageGroup1
+ '
+ Me.RibbonPageGroup1.ItemLinks.Add(Me.BarButtonItem2)
+ Me.RibbonPageGroup1.Name = "RibbonPageGroup1"
+ Me.RibbonPageGroup1.Text = "Aktionen"
+ '
+ 'RibbonStatusBar1
+ '
+ Me.RibbonStatusBar1.Location = New System.Drawing.Point(0, 428)
+ Me.RibbonStatusBar1.Name = "RibbonStatusBar1"
+ Me.RibbonStatusBar1.Ribbon = Me.RibbonControl1
+ Me.RibbonStatusBar1.Size = New System.Drawing.Size(800, 22)
+ '
+ 'RibbonPage2
+ '
+ Me.RibbonPage2.Name = "RibbonPage2"
+ Me.RibbonPage2.Text = "RibbonPage2"
+ '
+ 'GridControl1
+ '
+ Me.GridControl1.Dock = System.Windows.Forms.DockStyle.Fill
+ Me.GridControl1.Font = New System.Drawing.Font("Segoe UI", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
+ Me.GridControl1.Location = New System.Drawing.Point(0, 158)
+ Me.GridControl1.MainView = Me.GridView1
+ Me.GridControl1.Name = "GridControl1"
+ Me.GridControl1.Size = New System.Drawing.Size(800, 270)
+ Me.GridControl1.TabIndex = 10
+ Me.GridControl1.ViewCollection.AddRange(New DevExpress.XtraGrid.Views.Base.BaseView() {Me.GridView1})
+ '
+ 'GridView1
+ '
+ Me.GridView1.Appearance.EvenRow.BackColor = System.Drawing.Color.LightBlue
+ Me.GridView1.Appearance.EvenRow.Options.UseBackColor = True
+ Me.GridView1.GridControl = Me.GridControl1
+ Me.GridView1.Name = "GridView1"
+ Me.GridView1.OptionsBehavior.AllowAddRows = DevExpress.Utils.DefaultBoolean.[False]
+ Me.GridView1.OptionsBehavior.AllowDeleteRows = DevExpress.Utils.DefaultBoolean.[False]
+ Me.GridView1.OptionsBehavior.AllowFixedGroups = DevExpress.Utils.DefaultBoolean.[True]
+ Me.GridView1.OptionsBehavior.AllowGroupExpandAnimation = DevExpress.Utils.DefaultBoolean.[True]
+ Me.GridView1.OptionsBehavior.Editable = False
+ Me.GridView1.OptionsClipboard.CopyColumnHeaders = DevExpress.Utils.DefaultBoolean.[False]
+ Me.GridView1.OptionsView.ColumnAutoWidth = False
+ Me.GridView1.OptionsView.EnableAppearanceEvenRow = True
+ Me.GridView1.OptionsView.ShowAutoFilterRow = True
+ Me.GridView1.OptionsView.ShowErrorPanel = DevExpress.Utils.DefaultBoolean.[True]
+ Me.GridView1.OptionsView.ShowViewCaption = True
+ Me.GridView1.ViewCaption = "Bitte wählen Sie einen User"
+ '
+ 'BarButtonItem1
+ '
+ Me.BarButtonItem1.Caption = "Ghost Modus aktivieren"
+ Me.BarButtonItem1.Id = 1
+ Me.BarButtonItem1.ImageOptions.SvgImage = CType(resources.GetObject("BarButtonItem1.ImageOptions.SvgImage"), DevExpress.Utils.Svg.SvgImage)
+ Me.BarButtonItem1.Name = "BarButtonItem1"
+ '
+ 'frmUserSelect
+ '
+ Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
+ Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
+ Me.ClientSize = New System.Drawing.Size(800, 450)
+ Me.Controls.Add(Me.GridControl1)
+ Me.Controls.Add(Me.RibbonStatusBar1)
+ Me.Controls.Add(Me.RibbonControl1)
+ Me.IconOptions.SvgImage = CType(resources.GetObject("frmUserSelect.IconOptions.SvgImage"), DevExpress.Utils.Svg.SvgImage)
+ Me.Name = "frmUserSelect"
+ Me.Ribbon = Me.RibbonControl1
+ Me.StatusBar = Me.RibbonStatusBar1
+ Me.Text = "frmUserSelect"
+ CType(Me.RibbonControl1, System.ComponentModel.ISupportInitialize).EndInit()
+ CType(Me.GridControl1, System.ComponentModel.ISupportInitialize).EndInit()
+ CType(Me.GridView1, System.ComponentModel.ISupportInitialize).EndInit()
+ Me.ResumeLayout(False)
+ Me.PerformLayout()
+
+ End Sub
+
+ Friend WithEvents RibbonControl1 As DevExpress.XtraBars.Ribbon.RibbonControl
+ Friend WithEvents RibbonPage1 As DevExpress.XtraBars.Ribbon.RibbonPage
+ Friend WithEvents RibbonPageGroup1 As DevExpress.XtraBars.Ribbon.RibbonPageGroup
+ Friend WithEvents RibbonStatusBar1 As DevExpress.XtraBars.Ribbon.RibbonStatusBar
+ Friend WithEvents RibbonPage2 As DevExpress.XtraBars.Ribbon.RibbonPage
+ Friend WithEvents GridControl1 As DevExpress.XtraGrid.GridControl
+ Friend WithEvents GridView1 As DevExpress.XtraGrid.Views.Grid.GridView
+ Friend WithEvents BarButtonItem2 As DevExpress.XtraBars.BarButtonItem
+ Friend WithEvents BarButtonItem1 As DevExpress.XtraBars.BarButtonItem
+End Class
diff --git a/app/TaskFlow/frmUserSelect.resx b/app/TaskFlow/frmUserSelect.resx
new file mode 100644
index 0000000..63ca053
--- /dev/null
+++ b/app/TaskFlow/frmUserSelect.resx
@@ -0,0 +1,197 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFlEZXZFeHByZXNzLkRhdGEudjIxLjIsIFZlcnNpb249MjEuMi40
+ LjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjg4ZDE3NTRkNzAwZTQ5YQUBAAAAHURl
+ dkV4cHJlc3MuVXRpbHMuU3ZnLlN2Z0ltYWdlAQAAAAREYXRhBwICAAAACQMAAAAPAwAAAMwEAAAC77u/
+ PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz4NCjxzdmcgeD0iMHB4IiB5PSIwcHgi
+ IHZpZXdCb3g9IjAgMCAzMiAzMiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv
+ MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3Bh
+ Y2U9InByZXNlcnZlIiBpZD0iTGF5ZXJfMSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAg
+ MzIgMzIiPg0KICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLkJsdWV7ZmlsbDojMTE3N0Q3O30KCS5Z
+ ZWxsb3d7ZmlsbDojRkZCMTE1O30KCS5SZWR7ZmlsbDojRDExQzFDO30KCS5HcmVlbntmaWxsOiMwMzlD
+ MjM7fQoJLkJsYWNre2ZpbGw6IzcyNzI3Mjt9CgkuV2hpdGV7ZmlsbDojRkZGRkZGO30KCS5zdDB7b3Bh
+ Y2l0eTowLjU7fQoJLnN0MXtvcGFjaXR5OjAuNzU7fQoJLnN0MntkaXNwbGF5Om5vbmU7fQoJLnN0M3tk
+ aXNwbGF5OmlubGluZTtmaWxsOiNGRkIxMTU7fQoJLnN0NHtkaXNwbGF5OmlubGluZTt9Cgkuc3Q1e2Rp
+ c3BsYXk6aW5saW5lO29wYWNpdHk6MC43NTt9Cgkuc3Q2e2Rpc3BsYXk6aW5saW5lO29wYWNpdHk6MC41
+ O30KCS5zdDd7ZGlzcGxheTppbmxpbmU7ZmlsbDojMDM5QzIzO30KCS5zdDh7ZGlzcGxheTppbmxpbmU7
+ ZmlsbDojRDExQzFDO30KCS5zdDl7ZGlzcGxheTppbmxpbmU7ZmlsbDojMTE3N0Q3O30KCS5zdDEwe2Rp
+ c3BsYXk6aW5saW5lO2ZpbGw6I0ZGRkZGRjt9Cjwvc3R5bGU+DQogIDxnIGlkPSJMZWFkXzFfIj4NCiAg
+ ICA8cGF0aCBkPSJNMTAuNSw5LjZDOS40LDYsMTAsMiwxNC44LDJjNS4yLDAsNS41LDMsNS41LDNzMi45
+ LTAuMiwxLjEsNC43YzAuMS0wLjEsMC40LTAuMSwwLjUsMC4zICAgYzAuMSwwLjUtMC4xLDAuOS0wLjMs
+ MS40Yy0wLjMsMC41LDAuMSwxLjctMC45LDEuNnYwLjFjLTAuNSwyLjMtMiw0LjktNC43LDQuOXMtNC4x
+ LTIuNi00LjctNC45YzAtMC4xLDAtMC4yLDAtMC4yICAgYy0xLDAuMS0wLjctMS4xLTAuOS0xLjZTOS45
+ LDEwLjQsMTAsOS45QzEwLjEsOS43LDEwLjQsOS42LDEwLjUsOS42eiBNMjAsMThsLTIuNCw3LjlMMTcs
+ MjJsMC42LTJoLTMuMmwwLjYsMmwtMC42LDMuOUwxMiwxOCAgIGMtMi4zLDMuNS04LDEtOCw4LjVWMzBo
+ MTBoMWgyaDFoMTB2LTMuNUMyOCwxOS4xLDIyLjMsMjEuNCwyMCwxOHoiIGlkPSJMZWFkIiBjbGFzcz0i
+ QmxhY2siIC8+DQogIDwvZz4NCjwvc3ZnPgs=
+
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFlEZXZFeHByZXNzLkRhdGEudjIxLjIsIFZlcnNpb249MjEuMi40
+ LjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjg4ZDE3NTRkNzAwZTQ5YQUBAAAAHURl
+ dkV4cHJlc3MuVXRpbHMuU3ZnLlN2Z0ltYWdlAQAAAAREYXRhBwICAAAACQMAAAAPAwAAAAIEAAAC77u/
+ PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz4NCjxzdmcgeD0iMHB4IiB5PSIwcHgi
+ IHZpZXdCb3g9IjAgMCAzMiAzMiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv
+ MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3Bh
+ Y2U9InByZXNlcnZlIiBpZD0iTGF5ZXJfMSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAg
+ MzIgMzIiPg0KICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLkJsdWV7ZmlsbDojMTE3N0Q3O30KCS5Z
+ ZWxsb3d7ZmlsbDojRkZCMTE1O30KCS5SZWR7ZmlsbDojRDExQzFDO30KCS5HcmVlbntmaWxsOiMwMzlD
+ MjM7fQoJLkJsYWNre2ZpbGw6IzcyNzI3Mjt9CgkuV2hpdGV7ZmlsbDojRkZGRkZGO30KCS5zdDB7b3Bh
+ Y2l0eTowLjU7fQoJLnN0MXtvcGFjaXR5OjAuNzU7fQoJLnN0MntkaXNwbGF5Om5vbmU7fQoJLnN0M3tk
+ aXNwbGF5OmlubGluZTtmaWxsOiNGRkIxMTU7fQoJLnN0NHtkaXNwbGF5OmlubGluZTt9Cgkuc3Q1e2Rp
+ c3BsYXk6aW5saW5lO29wYWNpdHk6MC43NTt9Cgkuc3Q2e2Rpc3BsYXk6aW5saW5lO29wYWNpdHk6MC41
+ O30KCS5zdDd7ZGlzcGxheTppbmxpbmU7ZmlsbDojMDM5QzIzO30KCS5zdDh7ZGlzcGxheTppbmxpbmU7
+ ZmlsbDojRDExQzFDO30KCS5zdDl7ZGlzcGxheTppbmxpbmU7ZmlsbDojMTE3N0Q3O30KCS5zdDEwe2Rp
+ c3BsYXk6aW5saW5lO2ZpbGw6I0ZGRkZGRjt9Cjwvc3R5bGU+DQogIDxnIGlkPSJSb2xlIj4NCiAgICA8
+ cGF0aCBkPSJNNCwydjE2YzAsNi42LDUuNCwxMiwxMiwxMnMxMi01LjQsMTItMTJWMkg0eiBNMTEsOWMx
+ LjcsMCwzLDEuMywzLDNIOEM4LDEwLjMsOS4zLDksMTEsOXogTTE2LDI0ICAgYy0zLjMsMC02LTIuNy02
+ LTZjMCwxLjEsMi43LDIsNiwyczYtMC45LDYtMkMyMiwyMS4zLDE5LjMsMjQsMTYsMjR6IE0xOCwxMmMw
+ LTEuNywxLjMtMywzLTNzMywxLjMsMywzSDE4eiIgY2xhc3M9IlllbGxvdyIgLz4NCiAgPC9nPg0KPC9z
+ dmc+Cw==
+
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFlEZXZFeHByZXNzLkRhdGEudjIxLjIsIFZlcnNpb249MjEuMi40
+ LjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjg4ZDE3NTRkNzAwZTQ5YQUBAAAAHURl
+ dkV4cHJlc3MuVXRpbHMuU3ZnLlN2Z0ltYWdlAQAAAAREYXRhBwICAAAACQMAAAAPAwAAAKEDAAAC77u/
+ PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz4NCjxzdmcgeD0iMHB4IiB5PSIwcHgi
+ IHZpZXdCb3g9IjAgMCAzMiAzMiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv
+ MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3Bh
+ Y2U9InByZXNlcnZlIiBpZD0iTGF5ZXJfMSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAg
+ MzIgMzIiPg0KICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLkJsdWV7ZmlsbDojMTE3N0Q3O30KCS5Z
+ ZWxsb3d7ZmlsbDojRkZCMTE1O30KCS5CbGFja3tmaWxsOiM3MjcyNzI7fQoJLkdyZWVue2ZpbGw6IzAz
+ OUMyMzt9CgkuUmVke2ZpbGw6I0QxMUMxQzt9Cgkuc3Qwe29wYWNpdHk6MC43NTt9Cgkuc3Qxe29wYWNp
+ dHk6MC41O30KPC9zdHlsZT4NCiAgPGcgaWQ9IlVzZXIiPg0KICAgIDxwYXRoIGQ9Ik0xMCw5LjljLTAu
+ MSwwLjUsMC4yLDAuOSwwLjQsMS40YzAuMiwwLjUtMC4xLDEuNywwLjksMS42YzAsMCwwLDAuMSwwLDAu
+ MmMwLjYsMi4zLDIsNC45LDQuNyw0LjkgICBjMi43LDAsNC4yLTIuNiw0LjctNC45YzAsMCwwLTAuMSww
+ LTAuMWMxLDAuMSwwLjYtMS4xLDAuOS0xLjZjMC4yLTAuNSwwLjQtMC45LDAuMy0xLjRjLTAuMS0wLjQt
+ MC40LTAuNC0wLjUtMC4zICAgYzEuOC00LjktMS4xLTQuNy0xLjEtNC43UzIwLDIsMTQuOCwyQzEwLDIs
+ OS40LDYsMTAuNSw5LjZDMTAuNCw5LjYsMTAuMSw5LjcsMTAsOS45eiIgY2xhc3M9IkJsYWNrIiAvPg0K
+ ICAgIDxwYXRoIGQ9Ik0yMCwxOGMtMC44LDEuNS0yLjEsNC00LDRjLTEuOSwwLTMuMi0yLjUtNC00Yy0y
+ LjMsMy41LTgsMS04LDguNVYzMGgyNHYtMy41QzI4LDE5LjEsMjIuMywyMS40LDIwLDE4eiIgY2xhc3M9
+ IkJsYWNrIiAvPg0KICA8L2c+DQo8L3N2Zz4L
+
+
+
\ No newline at end of file
diff --git a/app/TaskFlow/frmUserSelect.vb b/app/TaskFlow/frmUserSelect.vb
new file mode 100644
index 0000000..ba37b5e
--- /dev/null
+++ b/app/TaskFlow/frmUserSelect.vb
@@ -0,0 +1,73 @@
+Public Class frmUserSelect
+ Public SelectedUserName As String
+ Public SelectedUserID As Integer
+ Public SelectedUserLanguage As String
+ Private Sub frmUserSelect_Load(sender As Object, e As EventArgs) Handles Me.Load
+ Dim oSQL = "SELECT [SQL_COMMAND] FROM TBDD_SQL_COMMANDS WITH (NOLOCK) where TITLE = 'GHOST_SELECT'"
+ Dim DT_USER = DatabaseFallback.GetDatatableECM(oSQL)
+ '
+ If IsNothing(DT_USER) Then
+ LOGGER.Info($"Ghost Select 1 [{oSQL}] was nothing, now trying 2nd..")
+ oSQL = "SELECT CONFIG_VALUE FROM TBIDB_BASE WITH (NOLOCK) WHERE CONFIG_NAME = 'GHOST_SELECT'"
+ If Not IsNothing(oSQL) Then
+ oSQL = DatabaseFallback.GetScalarValueIDB(oSQL)
+ DT_USER = DatabaseFallback.GetDatatableIDB(oSQL)
+ Else
+ LOGGER.Info($"GHOST Select 2 [{oSQL}] was nothing, Exit.")
+ MsgBox("No SQL for Ghostmode via SQL. Check Your configuration.", MsgBoxStyle.Exclamation)
+ Exit Sub
+ End If
+ End If
+
+ Try
+ If Not IsNothing(DT_USER) Then
+ oSQL = DT_USER.Rows(0).Item(0)
+ DT_USER = DatabaseFallback.GetDatatableECM(oSQL)
+ GridControl1.DataSource = DT_USER
+ LOGGER.Info($"Received [{DT_USER.Rows.Count}] Users to select!")
+ End If
+
+
+ Catch ex As Exception
+ MsgBox("Error Load_Users:" & vbNewLine & ex.Message)
+ End Try
+ End Sub
+
+ Private Sub BarButtonItem2_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItem2.ItemClick
+ Dim oFocusedUserName
+ Try
+ oFocusedUserName = GridView1.GetFocusedRowCellValue(GridView1.Columns("UserName"))
+
+ If IsNothing(oFocusedUserName) Then
+ oFocusedUserName = GridView1.GetFocusedRowCellValue(GridView1.Columns("USERNAME"))
+ End If
+ If IsNothing(oFocusedUserName) Then
+ oFocusedUserName = GridView1.GetFocusedRowCellValue(GridView1.Columns("USER_NAME"))
+ End If
+ If IsNothing(oFocusedUserName) Then
+ oFocusedUserName = GridView1.GetFocusedRowCellValue(GridView1.Columns("USER"))
+ End If
+ Catch ex As Exception
+ oFocusedUserName = GridView1.GetFocusedRowCellValue(GridView1.Columns("UserName"))
+ If IsNothing(oFocusedUserName) Then
+ MsgBox(ex.Message, MsgBoxStyle.Critical)
+ Exit Sub
+ End If
+ End Try
+ If oFocusedUserName <> String.Empty Then
+ SelectedUserName = oFocusedUserName
+ Dim oDT As DataTable = DatabaseFallback.GetDatatableECM("SELECT * FROM TBDD_USER WITH (NOLOCK) WHERE USERNAME = '" & oFocusedUserName & "'")
+ If Not IsNothing(oDT) Then
+ SelectedUserID = oDT.Rows(0).Item("GUID")
+ SelectedUserLanguage = oDT.Rows(0).Item("LANGUAGE")
+ Else
+ MsgBox("Error: User not found in TBDD_USER!", MsgBoxStyle.Critical)
+ Exit Sub
+ End If
+ Me.Close()
+
+ Else
+ MsgBox("Please choose an user for ghostmode!", MsgBoxStyle.Information)
+ End If
+ End Sub
+End Class
\ No newline at end of file