vendredi 5 janvier 2018

Mémo-LiteDB (LiteDB.FileStorage)

Memo-LiteDB est un exemple d'utilisation des fonctions "FileStorage" de LiteDB. Ce programme ouvre un fichier RichTextBox depuis la base de données, et l'affiche dans la fenêtre "Mémo" après l'avoir décrypté à l'aide du mot de passe saisi à l'ouverture du programme. A la fermeture de la fenêtre, le fichier est enregistré dans la base de données LiteDB après l'avoir crypté.

Memo-LiteDB


Ce programme nécessite la Dll "LiteDB.dll" v5.0.10. Créer un dossier "ldb" au même niveau que le script. Puis télécharger la Dll dans le dossier "ldb".

Site de référence : http://www.litedb.org


 

###################################################################################
#                                                                                 #
# Mémo v2.1.0                                                                     #
# http://powershell.sekki.fr                                                      #
# Validé sous : Windows 10 / PowerShell v5 / LiteDB v5                            #
#                                                                                 #
###################################################################################


#Assembly.
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void][Reflection.Assembly]::LoadWithPartialName("Microsoft.VisualBasic")

#Chemin courant.
$global:curpath = ""
if ($psISE) { $global:curpath = Split-Path -parent $psISE.CurrentFile.Fullpath }
else        { $global:curpath = Split-Path $MyInvocation.MyCommand.Path }

#Alerte.
function Alerte([string]$TEXT,[switch]$Q)
  {
    if (!$TEXT) { Return }
    $MessageBox = [Windows.Forms.MessageBox]
    if ($Q) { $BoutonBox = [Windows.Forms.MessageBoxButtons]::YESNO
              $titre     = "Memo - Choix"
              $IconBox   = [windows.forms.MessageBoxIcon]::Question
              $MessageBox::show($TEXT,$Titre,$BoutonBox,$IconBox) }
    else    { $BoutonBox = [Windows.Forms.MessageBoxButtons]::OK
              $titre     = "Memo - Alerte"
              $IconBox   = [windows.forms.MessageBoxIcon]::Warning
              $null      = $MessageBox::show($TEXT,$Titre,$BoutonBox,$IconBox) }
  }

#Charge les fonctions LiteDB.
Try { [void][Reflection.Assembly]::LoadFile($global:curpath+"\ldb\LiteDB.dll") }
Catch { Alerte "LiteDB.dll manquant."; Return }


################################################
# Fonctions.
################################################


#Input.
function Password([string]$TEXT)
{
   $formB = New-Object Windows.Forms.Form
   $formB.text = "Mémo"
   $formB.ClientSize = New-Object System.Drawing.Size(220,70)
   $formB.MinimumSize = New-Object System.Drawing.Size(220,70)
   $labelB1 = New-Object Windows.Forms.Label
   $labelB1.Location = New-Object Drawing.Point 10,10
   $labelB1.Size = New-Object Drawing.Point 200,16
   $labelB1.Text = $TEXT
   $textB1 = New-Object Windows.Forms.MaskedTextBox
   $textB1.PasswordChar = '*'
   $textB1.Location = New-Object Drawing.Point 10,30
   $textB1.Size = New-Object Drawing.Point 200,16
   $textB1.Add_KeyDown({ if ($_.KeyCode -eq "Enter") { $formB.Close() } })
   $formB.Controls.Add($labelB1)
   $formB.Controls.Add($textB1)
   [void]$formB.ShowDialog()
   $textB1.Text
}

#Codage/décodage du texte.
function Code_Txt([string]$crcode,[string]$mk,[int]$crsw)
{
   $j = 0
   $out = ""
   $key = @()
   $lk = $mk.length
   $lc = $crcode.length
   For($i = 0;$i -lt $lk;$i++) { $d=[Convert]::ToInt32($mk[$i], 16); $key += ,$d }
   For($i = 0;$i -lt $lc;$i++)
    {
      $dec = [byte][char]$crcode[$i]
      $dec = $dec + ($key[$j] * $crsw)
      if ($dec -lt 0)   {$dec = $dec + 256}
      if ($dec -ge 256) {$dec = $dec - 256}
      $car = [char][byte]$dec
      $out = $out + $car
      $j++
      if ($j -gt $lk) {$j = 0}
    }
   return $out
}

#Fonctions RichTextBox (voir article dédié).
Function ChangeRT($rtmode,$rtdata)
{
   $rtfont  = $global:textA1.SelectionFont.FontFamily
   $rtsize  = $global:textA1.SelectionFont.Size
   $rtstyle = $global:textA1.SelectionFont.Style
   if ($rtmode -eq 1) { $rtfont = $rtdata }   #Mode 1 : Change le nom.
   if ($rtmode -eq 2) { $rtsize = $rtdata }   #Mode 2 : Change la taille.
   if ($rtmode -eq 3) {                       #Mode 3 : Change le style.
                        $tbit = $rtstyle -band $rtdata
                        if ($tbit -ne $rtdata)
                          { $rtstyle = $rtstyle -bor $rtdata }
                        else                  
                          { $rbit = 255 -bxor $rtdata
                            $rtstyle = $rtstyle -band $rbit  }
                      }
   $myfont  = New-Object System.Drawing.Font($rtfont,$rtsize,$rtstyle,3,0)
   $global:textA1.SelectionFont = $myfont
}

#Template Bride.
Function New_Button([string]$text,[int]$p)
{
   $l = 72
   $button = New-Object Windows.Forms.Button
   $button.Location = New-Object Drawing.Point ((($l-1)*($p-1))-1),-1
   $button.Size = New-Object Drawing.Point $l,23
   $button.FlatStyle = [System.Windows.Forms.FlatStyle]::Flat
   $button.BackColor = [System.Drawing.Color]::FromArgb(255,225,225,225)
   $button.Text = $text
   return $button
}


################################################
# Main.
################################################


#Initialisation.
$global:bride = 1

#Ouvrir/Créer une Base de Données.
$db = New-Object LiteDB.LiteDatabase(($curpath+"\ldb\memo.db"),$null)

#Demander le code d'ouverture.
$smdp = Password "Code d'ouverture."

#Converti le mot de passe en clé.
$imdp = ""
$l = $smdp.length
for($i = 0;$i -lt $l;$i++)
{
   if ($smdp[$i] -match "^[0-9]+$") { $imdp += $smdp[$i] }
   else { $imdp += [string][int][char]$smdp[$i] }
}

#Vérification.
if ($imdp.length -lt 4) { Alerte "Le mot de passe n'est pas valide."; Return }

#Fenêtre principale.
$formA = New-Object Windows.Forms.Form
$formA.text = "Mémo - v2.1.0"
$formA.ClientSize = New-Object System.Drawing.Size(279,367)
$formA.MinimumSize = New-Object System.Drawing.Size(300,186)
$formA.KeyPreview  = $True
$formA.Add_KeyDown({if ($_.KeyCode -eq "Escape") { $gridA1.ClearSelection() }})

#Client Size.
$csw = $formA.ClientSize.Width
$csh = $formA.ClientSize.Height

#Couleurs.
$noir  = [System.Drawing.Color]::FromArgb(255,0,0,0)
$rouge = [System.Drawing.Color]::FromArgb(255,200,0,0)
$vert  = [System.Drawing.Color]::FromArgb(255,0,200,0)
$gris1 = [System.Drawing.Color]::FromArgb(255,240,240,240)
$bleu1 = [System.Drawing.Color]::FromArgb(255,94,191,212)
$blue2 = [System.Drawing.Color]::FromArgb(255,44,40,109)

#Création du menu contextuel.
$menu1 = New-Object System.Windows.Forms.ContextMenu
$item1 = New-Object System.Windows.Forms.MenuItem -ArgumentList "Gras"
$item1.Add_Click({ ChangeRT 3 ([System.Drawing.FontStyle]::Bold) })
$rtn = $menu1.MenuItems.Add($item1)
$item2 = New-Object System.Windows.Forms.MenuItem -ArgumentList "Italique"
$item2.Add_Click({ ChangeRT 3 ([System.Drawing.FontStyle]::Italic) })
$rtn = $menu1.MenuItems.Add($item2)
$item3 = New-Object System.Windows.Forms.MenuItem -ArgumentList "Souligne"
$item3.Add_Click({ ChangeRT 3 ([System.Drawing.FontStyle]::Underline) })
$rtn = $menu1.MenuItems.Add($item3)
$rtn = $menu1.MenuItems.Add("-")
$item4 = New-Object System.Windows.Forms.MenuItem -ArgumentList "Noir"
$item4.Add_Click({ $global:textA1.SelectionColor = $noir })
$rtn = $menu1.MenuItems.Add($item4)
$item5 = New-Object System.Windows.Forms.MenuItem -ArgumentList "Rouge"
$item5.Add_Click({ $global:textA1.SelectionColor = $rouge })
$rtn = $menu1.MenuItems.Add($item5)
$item6 = New-Object System.Windows.Forms.MenuItem -ArgumentList "Vert"
$item6.Add_Click({ $global:textA1.SelectionColor = $vert })
$rtn = $menu1.MenuItems.Add($item6)

#Création d'une RichTextBox.
$textA1 = New-Object Windows.Forms.RichTextBox
$textA1.Location = New-Object Drawing.Point -1, 21
$textA1.Size = New-Object Drawing.Point ($csw+2),($csh-36)
$textA1.Font = New-Object System.Drawing.Font("Lucida Console","10",0,3,0)
$textA1.DetectUrls = $true   #Active les liens Hyperlink.
$textA1.add_LinkClicked({ Invoke-Expression "start $($_.LinkText)" })
$textA1.ContextMenu = $menu1
$textA1.Visible = $true

#DataGrid - DataGridView.
$gridA1 = New-Object System.Windows.Forms.DataGridView
$gridA1.Location = New-Object Drawing.Point -1, 21
$gridA1.Size = New-Object Drawing.Point ($csw+2),($csh-36)
$gridA1.ScrollBars = "Vertical"
$gridA1.ReadOnly = $true
$gridA1.AutoSize = $false
$gridA1.GridColor = "Black"
$gridA1.AllowUserToResizeRows = $false
$gridA1.BorderStyle = [System.Windows.Forms.BorderStyle]::None
$gridA1.BackgroundColor = $gris1
$gridA1.DefaultCellStyle.SelectionBackColor = $bleu1
#$gridA1.SelectionMode = "FullRowSelect"
$gridA1.MultiSelect = $false


#DataGrid - Titre et Entête.
$gridA1.RowHeadersVisible    = $false
$gridA1.ColumnHeadersVisible = $true
$gridA1.ColumnHeadersHeightSizeMode = "DisableResizing"
$gridA1.EnableHeadersVisualStyles = $false
$gridA1.ColumnHeadersDefaultCellStyle.BackColor = $blue2
$gridA1.ColumnHeadersDefaultCellStyle.ForeColor = "White"
$gridA1.ColumnHeadersBorderStyle = "Single"
$gridA1.Visible = $false
$gridA1.ContextMenu = $menu1

#Script : #Charge les données dans la DataGrid.
$script1 = {
             $ascm = [System.Windows.Forms.DataGridViewAutoSizeColumnMode]::Fill
             $grille = $true; $i = 0; $noah = $false
             $lines = ($textA1.Text).split("`r`n")
             foreach ($line in $lines)
              {
                if ($line -notmatch "^.*;.*$") { $grille = $false}
              }
             if ($grille)
               {
                 $gridA1.Columns.Clear()
                 $textA1.Visible = $false
                 $labels = $lines[0].split(";")
                 $gridA1.ColumnCount = $labels.length
                 foreach ($label in $labels)
                  {
                    $gridA1.Columns[$i++].Name = $label
                  }
                 foreach($line in $lines)
                  {
                    if ($noah) { [void]$gridA1.Rows.Add($line.split(";")) }
                    else       { $noah = $true } }
                 foreach($column in $gridA1.Columns)
                  {
              
                    $column.SortMode = "NotSortable"
                    $column.AutoSizeMode = $ascm
                  }  
                 $gridA1.Visible = $true
                 $gridA1.ClearSelection()
                 $menu2 = New-Object System.Windows.Forms.ContextMenuStrip
                 [void]$menu2.Items.Add("Copier")
                 [void]$menu2.Items.Add("Editer")
                 $menu2.Add_ItemClicked({
Switch ($_.ClickedItem) {
Editer { $textA1.Visible = $true; $gridA1.Visible = $false }
Copier { $r = $gridA1.SelectedCells[0].RowIndex
          $c = $gridA1.SelectedCells[0].ColumnIndex
          [Windows.Forms.Clipboard]::Clear()
          [Windows.Forms.Clipboard]::SetText($gridA1.Rows[$r].Cells[$c].Value) }
        }  
                                       })
                 foreach($column in $gridA1.Columns)
                  {
                    $column.ContextMenuStrip = $menu2
                  }
               }
             else { $textA1.Visible = $true; $gridA1.Visible = $false }
           }

#Menu 1.
$buttonA1 = New_Button "I" 1
$buttonA1.Add_Click({
                      Switch ($global:bride)
                       {
                         1 { $global:bride1 = $textA1.Rtf }
                         2 { $global:bride2 = $textA1.Rtf }
                         3 { $global:bride3 = $textA1.Rtf }
                         4 { $global:bride4 = $textA1.Rtf }
                       }
                      Try { $textA1.Rtf = $global:bride1 }
                      Catch { $textA1.Text = $global:bride1 }
                      $global:bride = 1
                      &$script1
                   })
#Menu 2.
$buttonA2 = New_Button "II" 2
$buttonA2.Add_Click({
                      Switch ($global:bride)
                       {
                         1 { $global:bride1 = $textA1.Rtf }
                         2 { $global:bride2 = $textA1.Rtf }
                         3 { $global:bride3 = $textA1.Rtf }
                         4 { $global:bride4 = $textA1.Rtf }
                       }
                      Try { $textA1.Rtf = $global:bride2 }
                      Catch { $textA1.Text = $global:bride2 }
                      $global:bride = 2
                      &$script1
                   })
#Menu 3.
$buttonA3 = New_Button "III" 3
$buttonA3.Add_Click({
                      Switch ($global:bride)
                       {
                         1 { $global:bride1 = $textA1.Rtf }
                         2 { $global:bride2 = $textA1.Rtf }
                         3 { $global:bride3 = $textA1.Rtf }
                         4 { $global:bride4 = $textA1.Rtf }
                       }
                      Try { $textA1.Rtf = $global:bride3 }
                      Catch { $textA1.Text = $global:bride3 }
                      $global:bride = 3
                      &$script1
                   })
#Menu 4.
$buttonA4 = New_Button "IV" 4
$buttonA4.Add_Click({
                      Switch ($global:bride)
                       {
                         1 { $global:bride1 = $textA1.Rtf }
                         2 { $global:bride2 = $textA1.Rtf }
                         3 { $global:bride3 = $textA1.Rtf }
                         4 { $global:bride4 = $textA1.Rtf }
                       }
                      Try { $textA1.Rtf = $global:bride4 }
                      Catch { $textA1.Text = $global:bride4 }
                      $global:bride = 4
                      &$script1
                   })

#Lecture des fichiers dans la base.
$global:bride1 = "";$global:bride2 = "";$global:bride3 = "";$global:bride4 = ""
$file = $db.FileStorage.FindById("$/memo/bride1.rtf")
if ($file) { $sr = New-Object System.IO.StreamReader($file.OpenRead())
             $global:bride1 = Code_Txt $sr.ReadToEnd() $imdp -1 }
$file = $db.FileStorage.FindById("$/memo/bride2.rtf")
if ($file) { $sr = New-Object System.IO.StreamReader($file.OpenRead())
             $global:bride2 = Code_Txt $sr.ReadToEnd() $imdp -1 }
$file = $db.FileStorage.FindById("$/memo/bride3.rtf")
if ($file) { $sr = New-Object System.IO.StreamReader($file.OpenRead())
             $global:bride3 = Code_Txt $sr.ReadToEnd() $imdp -1 }
$file = $db.FileStorage.FindById("$/memo/bride4.rtf")
if ($file) { $sr = New-Object System.IO.StreamReader($file.OpenRead())
             $global:bride4 = Code_Txt $sr.ReadToEnd() $imdp -1 }  

#Chargement initial.
Try { $textA1.Rtf = $global:bride1 } Catch { $textA1.Text = $global:bride1 }
&$script1

#Liens.
$formA.controls.add($textA1)
$formA.controls.add($gridA1)
$formA.controls.add($buttonA1)
$formA.controls.add($buttonA2)
$formA.controls.add($buttonA3)
$formA.controls.add($buttonA4)

#Affiche le tout.
$formA.Add_Resize({
                    $csw = $formA.ClientSize.Width
                    $csh = $formA.ClientSize.Height
                    $textA1.Size = New-Object Drawing.Point ($csw+2),($csh-36)
                    $gridA1.Size = New-Object Drawing.Point ($csw+2),($csh-36)
                 })
$formA.Add_FormClosing({
           #Mémorise le contenu dans la fenêtre.
           Switch ($global:bride)
            {
              1 { $global:bride1 = $textA1.Rtf }
              2 { $global:bride2 = $textA1.Rtf }
              3 { $global:bride3 = $textA1.Rtf }
              4 { $global:bride4 = $textA1.Rtf }
            }
           #Sauvegarde des brides.
           if ((Alerte "Voulez-vous sauvegarder les infos ?" -Q) -eq "Yes")
             {
               #Bride 1:
               $tx = Code_Txt $global:bride1 $imdp 1
               [byte[]] $bytes = [System.Text.Encoding]::UTF8.GetBytes($tx)
               $ms = New-Object System.IO.MemoryStream($bytes,0,$bytes.Length)
               $db.FileStorage.Upload("$/memo/bride1.rtf", "bride1.rtf", $ms)
               #Bride 2:
               $tx = Code_Txt $global:bride2 $imdp 1
               [byte[]] $bytes = [System.Text.Encoding]::UTF8.GetBytes($tx)
               $ms = New-Object System.IO.MemoryStream($bytes,0,$bytes.Length)
               $db.FileStorage.Upload("$/memo/bride2.rtf", "bride2.rtf", $ms)
               #Bride 3:
               $tx = Code_Txt $global:bride3 $imdp 1
               [byte[]] $bytes = [System.Text.Encoding]::UTF8.GetBytes($tx)
               $ms = New-Object System.IO.MemoryStream($bytes,0,$bytes.Length)
               $db.FileStorage.Upload("$/memo/bride3.rtf", "bride3.rtf", $ms)
               #Bride 4:
               $tx = Code_Txt $global:bride4 $imdp 1
               [byte[]] $bytes = [System.Text.Encoding]::UTF8.GetBytes($tx)
               $ms = New-Object System.IO.MemoryStream($bytes,0,$bytes.Length)
               $db.FileStorage.Upload("$/memo/bride4.rtf", "bride4.rtf", $ms)
             }
                      })

[void]$formA.ShowDialog()

#Compresser la base de données.
[void]$db.Rebuild()

#Fermer la base de données.
$db.Dispose()

#Fin.