loupiottes/DMX-2.0/MainWindow.cs
tzim b5edcc497e * SeqLinUI.cs: Optimisation de l'affichage des tirettes.
* DMX-2.0.csproj:
* gui.stetic:
* DMX2.MainWindow.cs: 

* MainWindow.cs: Nécessaire pour permettre choix futur entre onglets
  et colonne de sequenceurs


Plus diverses choses
2014-06-04 19:13:23 +00:00

794 lines
No EOL
21 KiB
C#

/*
Copyright (C) Arnaud Houdelette 2012-2014
Copyright (C) Emmanuel Langlois 2012-2014
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using Gtk;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
namespace DMX2
{
public partial class MainWindow: Gtk.Window
{
static MainWindow win;
static object circuitKey = new object();
ListStore lsMatrice = null;
FileInfo conduiteFile=null;
int lastSaveHash=0;
Gtk.Container seqCtn=null;
public static MainWindow Win {
get { return win; }
}
public MainWindow (): base (Gtk.WindowType.Toplevel)
{
win=this;
Build ();
MajWidgets();
ContextMenuHelper ctxHelper = new ContextMenuHelper();
ctxHelper.ContextMenu += EventPopup;
ctxHelper.AttachToWidget(btnGo);
ctxHelper.AttachToWidget(btnGoBack);
ctxHelper.AttachToWidget(masterScale);
/*
Gtk.ScrolledWindow sw = new ScrolledWindow();
this.seqCtn = new VBox();
this.hpaned2.Add2(sw);
sw.AddWithViewport(seqCtn);
sw.HscrollbarPolicy = PolicyType.Never;
sw.VscrollbarPolicy= PolicyType.Always;
this.hpaned2.ShowAll ();
*/
seqCtn = new Gtk.Notebook();
hpaned2.Add2(seqCtn);
hpaned2.ShowAll();
}
void EventPopup (object sender, ContextMenuEventArgs e)
{
Menu m = Conduite.Courante.EventManager.GetMenu(e.Widget.Name,
delegate(object o,string eventId){
switch(o as string){
case "btnGo":
Conduite.Courante.SequenceurMaitre.BindEffetSuivant(eventId);
break;
case "btnGoBack":
Conduite.Courante.SequenceurMaitre.BindEffetPrecedent(eventId);
break;
case "masterScale":
Conduite.Courante.BindMaster(eventId);
break;
}
}
);
m.ShowAll();
m.Popup();
}
#region Sequenceur Maitre
protected void ConstruitMatrice ()
{
this.MatriceUI.EnableGridLines = TreeViewGridLines.Both;
var idCol = new Gtk.TreeViewColumn ();
var idCell = new Gtk.CellRendererText ();
idCol.Title = "Num";
idCol.PackStart (idCell, true);
idCol.SetCellDataFunc (idCell, new Gtk.TreeCellDataFunc (RenderMatriceNum));
this.MatriceUI.AppendColumn (idCol);
var nomCol = new Gtk.TreeViewColumn ();
var nomCell = new Gtk.CellRendererText ();
nomCol.Title = "Nom";
nomCol.PackStart (nomCell, true);
nomCol.SetCellDataFunc (nomCell, new Gtk.TreeCellDataFunc (RenderMatriceNom));
nomCell.Editable = true;
nomCell.Edited += OnNomCellEdited;
this.MatriceUI.AppendColumn (nomCol);
var dureeCol = new Gtk.TreeViewColumn ();
var dureeCell = new Gtk.CellRendererText ();
dureeCol.Title = "Durée";
dureeCol.PackStart (dureeCell, true);
dureeCol.SetCellDataFunc (dureeCell, new Gtk.TreeCellDataFunc (RenderMatriceDuree));
dureeCell.Editable = true;
dureeCell.Edited += OnDureeCellEdited;
this.MatriceUI.AppendColumn (dureeCol);
lsMatrice = new Gtk.ListStore(typeof (SequenceurMaitre.Ligne));
this.MatriceUI.Model = lsMatrice;
FillMatrice();
}
void DetruitMatrice ()
{
this.MatriceUI.Model = null;
if (lsMatrice != null) lsMatrice.Dispose();
foreach (var col in MatriceUI.Columns)
MatriceUI.RemoveColumn (col);
}
static object seqkey = new object();
void ConstruitMatriceSeqColumns ()
{
foreach(var c in MatriceUI.Columns)
if(c.CellRenderers[0].Data.ContainsKey(seqkey))
MatriceUI.RemoveColumn(c);
Gtk.TreeViewColumn seqCol;
Gtk.CellRendererText seqCell;
foreach (Sequenceur seq in Conduite.Courante.Sequenceurs) {
seqCol = new TreeViewColumn();
seqCell = new CellRendererText();
seqCol.Title = seq.Name;
seqCol.PackStart(seqCell, true);
seqCol.SetCellDataFunc ( seqCell, new Gtk.TreeCellDataFunc(RenderMatriceSeqVal));
seqCell.Editable = true;
seqCell.Edited += OnSeqValCellEdited;
seqCell.Data[seqkey] = seq;
this.MatriceUI.AppendColumn(seqCol);
}
}
void RenderMatriceNum (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
{
if (Conduite.Courante==null) return;
string num=string.Empty;
SequenceurMaitre.Ligne l = tree_model.GetValue (iter, 0) as SequenceurMaitre.Ligne;
if( Conduite.Courante.SequenceurMaitre.IndexLigneEnCours == Conduite.Courante.SequenceurMaitre.Lignes.IndexOf(l) )
num+= "->";
if( Conduite.Courante.SequenceurMaitre.IndexLigneaSuivre == Conduite.Courante.SequenceurMaitre.Lignes.IndexOf(l) )
num+= "* ";
(cell as Gtk.CellRendererText).Text = num + (Conduite.Courante.SequenceurMaitre.Lignes.IndexOf(l)+1).ToString();
}
void RenderMatriceNom (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
{
if (Conduite.Courante==null) return;
SequenceurMaitre.Ligne l = tree_model.GetValue (iter, 0) as SequenceurMaitre.Ligne;
(cell as Gtk.CellRendererText).Text = l.Nom;
}
void RenderMatriceDuree (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
{
if (Conduite.Courante==null) return;
SequenceurMaitre.Ligne l = tree_model.GetValue (iter, 0) as SequenceurMaitre.Ligne;
if (l.Duree== TimeSpan.Zero) (cell as Gtk.CellRendererText).Text = string.Empty;
else (cell as Gtk.CellRendererText).Text = (l.Duree.TotalMilliseconds /100).ToString();
}
void RenderMatriceSeqVal (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
{
if (Conduite.Courante==null) return;
SequenceurMaitre.Ligne l = tree_model.GetValue (iter, 0) as SequenceurMaitre.Ligne;
Sequenceur seq = cell.Data[seqkey] as Sequenceur;
(cell as Gtk.CellRendererText).Text = l[seq];
}
void FillMatrice ()
{
lsMatrice.Clear ();
foreach (SequenceurMaitre.Ligne l in Conduite.Courante.SequenceurMaitre.Lignes) {
lsMatrice.AppendValues(l);
}
}
void OnNomCellEdited (object o, EditedArgs args)
{
Gtk.TreeIter iter;
lsMatrice.GetIter (out iter, new Gtk.TreePath (args.Path));
SequenceurMaitre.Ligne l = lsMatrice.GetValue(iter,0) as SequenceurMaitre.Ligne;
l.Nom = args.NewText;
}
void OnDureeCellEdited (object o, EditedArgs args)
{
Gtk.TreeIter iter;
lsMatrice.GetIter (out iter, new Gtk.TreePath (args.Path));
SequenceurMaitre.Ligne l = lsMatrice.GetValue (iter, 0) as SequenceurMaitre.Ligne;
if (args.NewText.Length == 0)
l.Duree = TimeSpan.Zero;
else {
int val;
if(int.TryParse(args.NewText, out val))
l.Duree = TimeSpan.FromMilliseconds(val *100);
}
}
void OnSeqValCellEdited (object o, EditedArgs args)
{
Gtk.CellRendererText cell = o as CellRendererText;
Sequenceur seq = cell.Data[seqkey] as Sequenceur;
Gtk.TreeIter iter;
lsMatrice.GetIter (out iter, new Gtk.TreePath (args.Path));
SequenceurMaitre.Ligne l = lsMatrice.GetValue(iter,0) as SequenceurMaitre.Ligne;
l[seq] = args.NewText;
}
int IndexEffetSelectionne()
{
var sel = MatriceUI.Selection.GetSelectedRows();
if(sel.Length ==0) return -1;
return MatriceUI.Selection.GetSelectedRows()[0].Indices[0];
}
void SelectionneEffet (int index)
{
if(index <0 ) return;
MatriceUI.SetCursor( new TreePath( new int[1] {index }) ,null,false);
}
protected void OnBtnAjoutLigneClicked (object sender, EventArgs e)
{
int pos=IndexEffetSelectionne() + 1;
Conduite.Courante.SequenceurMaitre.AjoutLigne(pos);
FillMatrice();
MatriceUI.SetCursor( new TreePath( new int[1] {pos }) , MatriceUI.Columns[1] ,true);
}
protected void OnBtnRetireLigneClicked (object sender, EventArgs e)
{
if(IndexEffetSelectionne()==-1) return;
Conduite.Courante.SequenceurMaitre.RetireLigne(IndexEffetSelectionne());
FillMatrice();
}
protected void OnBtnGoBackClicked (object sender, EventArgs e)
{
Conduite.Courante.SequenceurMaitre.EffetPrecedent();
//FillMatrice();
}
protected void OnBtnGoClicked (object sender, EventArgs e)
{
Conduite.Courante.SequenceurMaitre.EffetSuivant();
//FillMatrice();
}
protected void OnMatriceUICursorChanged (object sender, EventArgs e)
{
if (Conduite.Courante==null) return;
TreeViewColumn col;
TreePath path;
MatriceUI.GetCursor (out path, out col);
if (MatriceUI.Columns [0] == col) {
Conduite.Courante.SequenceurMaitre.IndexLigneaSuivre = IndexEffetSelectionne();
}
}
#endregion
#region Application
protected void OnDeleteEvent (object sender, DeleteEventArgs a)
{
a.RetVal = !Quit();
}
protected void OnQuitActionActivated (object sender, EventArgs e)
{
Quit ();
}
bool Quit ()
{
if(!VerifSauvegarde ("Quitter ?","La conduite n'a pas été sauvegardée.\nQuitter quand même ?")) return false;
Application.Quit ();
return true;
}
#endregion
#region Gestion de la Conduite
protected void OnNewActionActivated (object sender, EventArgs e)
{
var dlg = new Dialog ("Nom ?", this, DialogFlags.Modal); var entry = new Entry ("Conduite sans Nom");
dlg.AddButton (Stock.Ok, ResponseType.Ok).GrabDefault(); dlg.AddButton (Stock.Cancel, ResponseType.Cancel);
dlg.VBox.Add (new Label("Nom de la nouvelle Conduite :")); dlg.VBox.Add (entry); dlg.VBox.ShowAll ();
entry.ActivatesDefault=true;
if ((ResponseType)dlg.Run () == ResponseType.Ok) {
new Conduite ();
Conduite.Courante.Name = entry.Text;
}
MajWidgets();
dlg.Destroy();
}
protected void OnCloseActionActivated (object sender, EventArgs e)
{
if(!VerifSauvegarde ("Fermer ?","La conduite n'a pas été sauvegardée.\nFermer quand même ?")) return;
Conduite.Courante.Dispose();
conduiteFile = null;
MajWidgets();
}
protected void OnSaveActionActivated (object sender, EventArgs e)
{
if(conduiteFile==null)
SaveFileAs();
else
SaveFile();
}
bool VerifSauvegarde (string titre, string message)
{
if (Conduite.Courante != null) {
if (Conduite.Courante.Save ().InnerXml.GetHashCode () != lastSaveHash) {
var dlg = new Dialog (titre, this, DialogFlags.Modal);
dlg.VBox.Add (new Label (message));
dlg.AddButton (titre=="Quitter ?"?Stock.Quit:Stock.Close, ResponseType.Close);
dlg.AddButton (conduiteFile == null?Stock.SaveAs:Stock.Save, ResponseType.Apply);
dlg.AddButton (Stock.Cancel, ResponseType.Cancel).GrabDefault ();
dlg.VBox.ShowAll ();
ResponseType res = (ResponseType)dlg.Run ();
if (res == ResponseType.Cancel) {
dlg.Destroy ();
return false;
}
if (res == ResponseType.Apply) {
dlg.Destroy ();
if (conduiteFile == null)
return SaveFileAs();
SaveFile ();
return true;
}
dlg.Destroy ();
return true;
}
}
return true;
}
protected void OnSaveAsActionActivated (object sender, EventArgs e)
{
SaveFileAs();
}
bool SaveFileAs ()
{
FileChooserDialog fcd = new FileChooserDialog ("Sauver sous ...", this, FileChooserAction.Save,
"Annuler", ResponseType.Cancel,
"Enregistrer", ResponseType.Accept);
fcd.Filter = new FileFilter ();
fcd.Filter.AddPattern ("*.dmx2");
bool ok = false;
while (!ok) {
if ((ResponseType)fcd.Run () == ResponseType.Cancel) {
fcd.Destroy ();
return false;
}
string file = fcd.Filename;
if (!file.EndsWith (".dmx2"))
file += ".dmx2";
conduiteFile = new FileInfo(file);
if(conduiteFile.Exists)
{
MessageDialog msg = new MessageDialog(fcd,DialogFlags.Modal,
MessageType.Warning,
ButtonsType.YesNo,
"Le fichier existe déja. \nVoulez vous écraser le fichier existant ?");
if ((ResponseType)msg.Run () == ResponseType.Yes)ok=true;
msg.Destroy();
}
else ok=true;
}
fcd.Destroy();
return SaveFile();
}
bool SaveFile ()
{
if (conduiteFile == null)
return false;
// Copie de sauvegarde
if(conduiteFile.Exists)
conduiteFile.CopyTo(string.Format("{0}.{1:yyyyMMdd-HHmm}.bak",conduiteFile.FullName,conduiteFile.LastWriteTime),true);
using (FileStream stream = conduiteFile.Open(FileMode.Create,FileAccess.Write)) {
System.Xml.XmlDocument doc = Conduite.Courante.Save ();
doc.Save (stream);
lastSaveHash = doc.InnerXml.GetHashCode();
stream.Close ();
return true;
}
}
protected void OnOpenActionActivated (object sender, EventArgs e)
{
FileChooserDialog fcd = new FileChooserDialog ("Sauver sous ...", this, FileChooserAction.Open,
"Annuler", ResponseType.Cancel,
"Ouvrir", ResponseType.Accept);
fcd.Filter = new FileFilter ();
fcd.Filter.AddPattern ("*.dmx2");
if ((ResponseType)fcd.Run () == ResponseType.Cancel || fcd.Filename==null) {
fcd.Destroy ();
return;
}
FileInfo file = new FileInfo (fcd.Filename);
fcd.Destroy ();
OpenFile (file);
}
public void OpenFile (FileInfo file)
{
if (!file.Exists)
return;
System.Xml.XmlDocument doc;
try {
using (FileStream stream = file.OpenRead ()) {
doc = new System.Xml.XmlDocument ();
doc.Load (stream);
stream.Close ();
}
new Conduite (doc);
conduiteFile = file;
lastSaveHash = doc.InnerXml.GetHashCode ();
}
catch (Exception) {
//TODO : display error
Conduite.Courante.Dispose();
return;
}
foreach (Sequenceur s in Conduite.Courante.Sequenceurs)
AddSeqUI (s);
MajWidgets ();
NextUpdateFull ();
}
#endregion
#region Gestion des Circuits
protected void OnCircuitsActionActivated (object sender, EventArgs e)
{
GestionCircuits gc= new GestionCircuits(this);
gc.Run();
gc.Destroy();
NextUpdateFull();
}
#endregion
#region Gestion des Sequenceurs
// bonton ajout de sequenceur linéraire
protected void OnSeqLinActionActivated (object sender, EventArgs e)
{
Sequenceur s = new SequenceurLineaire();
Conduite.Courante.AjoutSequenceur(s);
AddSeqUI(s);
NextUpdateFull();
}
void AddSeqUI (Sequenceur s)
{
if (seqCtn is Gtk.Notebook) {
((Gtk.Notebook)seqCtn).AppendPage (s.GetUI (), new Gtk.Label (s.Name));
}
else if (seqCtn is Gtk.VBox) {
((Gtk.VBox)seqCtn).Add(s.GetUI());
}
seqCtn.ShowAll();
}
protected void OnShowAllActionActivated (object sender, EventArgs e)
{
foreach (var widget in seqCtn.Children)
widget.Destroy();
foreach (Sequenceur s in Conduite.Courante.Sequenceurs)
AddSeqUI(s);
}
protected void OnSeqMacroActionActivated (object sender, EventArgs e)
{
Sequenceur s = new SequenceurMacro();
Conduite.Courante.AjoutSequenceur(s);
AddSeqUI(s);
NextUpdateFull();
}
#endregion
#region Gestion de l'affichage
bool updScheduled=false;
bool fullUpdateFlag=false;
public void NextUpdateFull ()
{
fullUpdateFlag=true;
}
public void ScheduleUpdate ()
{
if (updScheduled) {
//Console.WriteLine("{0} Skip !",DateTime.Now);
return;
}
updScheduled=true;
Gtk.Application.Invoke(new EventHandler(Update));
}
void Update (object sender, EventArgs e)
{
lblInfo.Text = Info.GetInfo();
if(Conduite.Courante==null)return;
foreach (var notebookchild in seqCtn.Children) {
SequenceurUI sequi = notebookchild as SequenceurUI;
if(sequi != null) sequi.Update(fullUpdateFlag);
}
MajCircuits(fullUpdateFlag);
timeLabel.LabelProp = string.Format (@"{0:0\.0}", Conduite.Courante.SequenceurMaitre.TimeStamp.TotalMilliseconds / 100);
lblPage.LabelProp = Conduite.Courante.Midi.CurrentPage.ToString();
if(fullUpdateFlag) ConstruitMatriceSeqColumns();
if( Conduite.Courante.SequenceurMaitre.EffetChange() )MatriceUI.QueueDraw();
fullUpdateFlag=false;
masterScale.Value = Conduite.Courante.Master;
updScheduled=false;
}
protected void MajWidgets ()
{
if (Conduite.Courante != null) {
//Activation / Désactivation des boutons en fonction de l'état de la counduite courante
btnAjoutLigne.Sensitive = btnRetireLigne.Sensitive = btnGo.Sensitive = btnGoBack.Sensitive =
showAllAction.Sensitive = universAction.Sensitive = masterScale.Sensitive =
seqLinAction.Sensitive = seqMacroAction.Sensitive = circAction.Sensitive = saveAction.Sensitive =
btnPause.Sensitive = btnBlackOut.Sensitive =
connectAction.Sensitive = midiAction.Sensitive =
saveAsAction.Sensitive = closeAction.Sensitive = true;
openAction.Sensitive = newAction.Sensitive = false;
this.Title = "Loupiottes - " + Conduite.Courante.Name;
ConstruitMatrice();
} else {
btnAjoutLigne.Sensitive = btnRetireLigne.Sensitive = btnGo.Sensitive = btnGoBack.Sensitive =
showAllAction.Sensitive = universAction.Sensitive = masterScale.Sensitive =
seqLinAction.Sensitive = seqMacroAction.Sensitive = circAction.Sensitive = saveAction.Sensitive =
btnPause.Sensitive = btnBlackOut.Sensitive =
connectAction.Sensitive = midiAction.Sensitive =
saveAsAction.Sensitive = closeAction.Sensitive = false;
openAction.Sensitive = newAction.Sensitive = true;
this.Title = "Loupiottes";
DetruitMatrice();
foreach (var widget in vboxCircuits.Children)
vboxCircuits.Remove (widget);
if(seqCtn !=null)
foreach (var notebookvbox in seqCtn.Children)
notebookvbox.Destroy();
}
}
protected void MajCircuits (bool full)
{
// Ajoute une ProgressBar par circuit, met a jour le texte si necessaire
ProgressBar pb;int i = 0;
if (full) {
foreach (var widget in vboxCircuits.Children)
vboxCircuits.Remove (widget);
foreach (var circuit in Conduite.Courante.Circuits) {
vboxCircuits.PackStart (pb=new ProgressBar (),false,false,0);
pb.Text = (++i).ToString() + " - " + circuit.Name;
pb.HeightRequest = 14;
pb.Data[circuitKey] = circuit;
pb.Name ="pb";
}
vboxCircuits.ShowAll ();
}
foreach (var widget in vboxCircuits.Children) {
pb = (ProgressBar)widget;
pb.Fraction = (double) (pb.Data[circuitKey] as Circuit).ValeurCourante / 255;
}
}
#endregion
protected void OnMasterScaleValueChanged (object sender, EventArgs e)
{
if(!updScheduled) Conduite.Courante.Master = (int)(masterScale.Value);
ChangeCouleurInfo();
}
bool isfullscreen=false;
public void ToggleFullscreen ()
{
if (!isfullscreen) {
Fullscreen ();
isfullscreen = true;
fullscreenAction1.StockId = "gtk-leave-fullscreen";
}
else {
Unfullscreen ();
isfullscreen = false;
fullscreenAction1.StockId = "gtk-fullscreen";
}
}
protected void OnFullscreenAction1Activated (object sender, EventArgs e)
{
ToggleFullscreen ();
}
#region Boite dialogue Univers
EditionUnivers uDlg = null;
protected void OnUniversActionActivated (object sender, EventArgs e)
{
if (uDlg != null) {
uDlg.Show();
return;
}
uDlg = new EditionUnivers(this);
uDlg.ShowAll();
uDlg.Destroyed += udlgDestroyed;
}
void udlgDestroyed (object sender, EventArgs e)
{
uDlg=null;
}
#endregion
GestionDriversUI dDlg = null;
protected void OnConnectActionActivated (object sender, EventArgs e)
{
if (dDlg != null) {
dDlg.Show();
return;
}
dDlg = new GestionDriversUI();
dDlg.ShowAll();
dDlg.Destroyed += delegate {
dDlg = null;
};
//Conduite.Courante.Drivers.Add( new DriverBoitierV1());
}
protected void OnBtnPauseToggled (object sender, EventArgs e)
{
Conduite.Courante.Pause = btnPause.Active;
ChangeCouleurInfo();
}
protected void OnBtnBlackOutToggled (object sender, EventArgs e)
{
Conduite.Courante.BlackOut = btnBlackOut.Active;
ChangeCouleurInfo();
}
void ChangeCouleurInfo ()
{
if (Conduite.Courante.BlackOut) {
evInfo.ModifyBg (Gtk.StateType.Normal,new Gdk.Color (255, 100, 100));
return;
}
if (Conduite.Courante.Pause) {
evInfo.ModifyBg (Gtk.StateType.Normal,new Gdk.Color (255, 255, 100));
return;
}
if (Conduite.Courante.Master != 100) {
evInfo.ModifyBg (Gtk.StateType.Normal,new Gdk.Color (205, 205, 255));
return;
}
evInfo.ModifyBg (Gtk.StateType.Normal, this.Style.Background(StateType.Normal) );
}
protected void OnSelectColorActionActivated (object sender, EventArgs e)
{
if(System.IO.File.Exists("style.gtkrc")) Gtk.Rc.Parse("style.gtkrc");
else
using (System.IO.Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("style.gtkrc"))
using (System.IO.TextReader reader = new System.IO.StreamReader(stream))
Gtk.Rc.ParseString (reader.ReadToEnd());
this.ResetRcStyles();
}
protected void OnAboutActionActivated (object sender, EventArgs e)
{
About dlg = new About();
dlg.Show();
dlg.Run ();
}
GestionMidiUI mDlg=null;
protected void OnMidiActionActivated (object sender, EventArgs e)
{
if(Conduite.Courante == null) return;
if (mDlg != null) {
mDlg.Show();
return;
}
mDlg = new GestionMidiUI();
mDlg.ShowAll();
mDlg.Destroyed += delegate {
mDlg= null;
};
}
}
}